diff --git a/pom.xml b/pom.xml index 510bf70..4f8225f 100644 --- a/pom.xml +++ b/pom.xml @@ -181,6 +181,9 @@ native + + [21, 24] + @@ -209,6 +212,40 @@ + + native-jdk25 + + 25 + + + + + org.graalvm.buildtools + native-maven-plugin + 1.0.0 + true + + + native test + + test + + test + + + + false + + + -J--add-opens=java.base/java.lang=ALL-UNNAMED + --initialize-at-build-time=org.junit.jupiter.engine.discovery.MethodSegmentResolver + -H:+SharedArenaSupport + + + + + + trace diff --git a/src/main/java/com/github/sttk/sabi_redis/RedisDataConn.java b/src/main/java/com/github/sttk/sabi_redis/RedisDataConn.java index 3195a74..6b34498 100644 --- a/src/main/java/com/github/sttk/sabi_redis/RedisDataConn.java +++ b/src/main/java/com/github/sttk/sabi_redis/RedisDataConn.java @@ -14,19 +14,19 @@ /** * The DataConn implementation for Redis in standalone configuration. * - *

This class manages a connection to a Redis server and provides ways to register handlers - * that are executed at certain points in the connection's lifecycle. + *

This class manages a connection to a Redis server and provides ways to register handlers that + * are executed at certain points in the connection's lifecycle. */ public class RedisDataConn implements DataConn { - /// Fields + // Fields private final StatefulRedisConnection connection; private final List preCommits = new ArrayList<>(); private final List postCommits = new ArrayList<>(); private final List forceBacks = new ArrayList<>(); - /// Constructors + // Constructors /** * Constructs a new RedisDataConn with the given Redis connection. @@ -37,7 +37,7 @@ protected RedisDataConn(StatefulRedisConnection connection) { this.connection = connection; } - /// Methods + // Methods /** * Returns the Redis connection. @@ -124,8 +124,8 @@ public boolean shouldForceBack() { } /** - * Rolls back the connection. (Currently does nothing as Redis doesn't have a direct rollback for a - * simple connection) + * Rolls back the connection. (Currently does nothing as Redis doesn't have a direct rollback for + * a simple connection) * * @param ag an asynchronous group. */ @@ -147,9 +147,7 @@ public void forceBack(AsyncGroup ag) { } } - /** - * Closes the connection. - */ + /** Closes the connection. */ @Override public void close() { this.connection.close(); diff --git a/src/main/java/com/github/sttk/sabi_redis/RedisDataSrc.java b/src/main/java/com/github/sttk/sabi_redis/RedisDataSrc.java index 02af00e..db0784d 100644 --- a/src/main/java/com/github/sttk/sabi_redis/RedisDataSrc.java +++ b/src/main/java/com/github/sttk/sabi_redis/RedisDataSrc.java @@ -21,16 +21,12 @@ */ public class RedisDataSrc implements DataSrc { - /// Error reasons + // Error reasons - /** - * The error reason that indicates the {@link RedisDataSrc} is not setup yet. - */ + /** The error reason that indicates the {@link RedisDataSrc} is not setup yet. */ public record NotSetupYet() {} - /** - * The error reason that indicates the {@link RedisDataSrc} is already setup. - */ + /** The error reason that indicates the {@link RedisDataSrc} is already setup. */ public record AlreadySetup() {} /** @@ -41,7 +37,8 @@ public record AlreadySetup() {} public record FailToCreateClientFromUriString(String uri) {} /** - * The error reason that indicates failing to create a {@link RedisClient} from a {@link URI} object. + * The error reason that indicates failing to create a {@link RedisClient} from a {@link URI} + * object. * * @param uri a URI object. */ @@ -55,14 +52,6 @@ public record FailToCreateClientFromURI(URI uri) {} */ public record FailToCreateClientFromRedisURI(RedisURI redisURI) {} - /** - * The error reason that indicates failing to create a {@link RedisClient} from a {@link - * ClientResources} object. - * - * @param clientResources a ClientResources object. - */ - public record FailToCreateClientFromClientResources(ClientResources clientResources) {} - /** * The error reason that indicates failing to create a {@link RedisClient} from a {@link * ClientResources} object and a URI string. @@ -93,12 +82,12 @@ public record FailToCreateClientFromClientResourcesAndURI( public record FailToCreateClientFromClientResourcesAndRedisURI( ClientResources clientResources, RedisURI redisURI) {} - /// Fields + // Fields private RedisClientFactory redisClientFactory; private RedisClient redisClient; - /// Constructors + // Constructors /** * Constructs a new RedisDataSrc with the given URI string. @@ -127,15 +116,6 @@ public RedisDataSrc(RedisURI redisURI) { this.redisClientFactory = new RedisClientFactoryByRedisURI(redisURI); } - /** - * Constructs a new RedisDataSrc with the given {@link ClientResources} object. - * - * @param cr a ClientResources object. - */ - public RedisDataSrc(ClientResources cr) { - this.redisClientFactory = new RedisClientFactoryByClientResources(cr); - } - /** * Constructs a new RedisDataSrc with the given {@link ClientResources} object and URI string. * @@ -168,7 +148,7 @@ public RedisDataSrc(ClientResources cr, RedisURI redisURI) { this.redisClientFactory = new RedisClientFactoryByClientResourcesAndRedisURI(cr, redisURI); } - /// Methods + // Methods /** * Sets up this data source. @@ -188,9 +168,7 @@ public void setup(AsyncGroup ag) throws Err { this.redisClient = factory.create(); } - /** - * Closes this data source and shuts down the {@link RedisClient}. - */ + /** Closes this data source and shuts down the {@link RedisClient}. */ @Override public void close() { if (this.redisClient != null) { @@ -228,9 +206,12 @@ private class RedisClientFactoryByUriString implements RedisClientFactory { } @Override + @SuppressWarnings("try") public RedisClient create() throws Err { try { - return RedisClient.create(this.uri); + var client = RedisClient.create(this.uri); + try (var conn = client.connect()) {} + return client; } catch (Exception e) { throw new Err(new FailToCreateClientFromUriString(this.uri), e); } @@ -245,9 +226,12 @@ private class RedisClientFactoryByUriObject implements RedisClientFactory { } @Override + @SuppressWarnings("try") public RedisClient create() throws Err { try { - return RedisClient.create(this.uri.toString()); + var client = RedisClient.create(this.uri.toString()); + try (var conn = client.connect()) {} + return client; } catch (Exception e) { throw new Err(new FailToCreateClientFromURI(this.uri), e); } @@ -262,32 +246,18 @@ private class RedisClientFactoryByRedisURI implements RedisClientFactory { } @Override + @SuppressWarnings("try") public RedisClient create() throws Err { try { - return RedisClient.create(this.redisURI); + var client = RedisClient.create(this.redisURI); + try (var conn = client.connect()) {} + return client; } catch (Exception e) { throw new Err(new FailToCreateClientFromRedisURI(this.redisURI), e); } } } - private class RedisClientFactoryByClientResources implements RedisClientFactory { - final ClientResources clientResources; - - RedisClientFactoryByClientResources(ClientResources cr) { - this.clientResources = cr; - } - - @Override - public RedisClient create() throws Err { - try { - return RedisClient.create(this.clientResources); - } catch (Exception e) { - throw new Err(new FailToCreateClientFromClientResources(this.clientResources), e); - } - } - } - private class RedisClientFactoryByClientResourcesAndUriString implements RedisClientFactory { final ClientResources clientResources; final String uri; @@ -298,9 +268,12 @@ private class RedisClientFactoryByClientResourcesAndUriString implements RedisCl } @Override + @SuppressWarnings("try") public RedisClient create() throws Err { try { - return RedisClient.create(this.clientResources, this.uri); + var client = RedisClient.create(this.clientResources, this.uri); + try (var conn = client.connect()) {} + return client; } catch (Exception e) { throw new Err( new FailToCreateClientFromClientResourcesAndUriString(this.clientResources, this.uri), @@ -319,9 +292,12 @@ private class RedisClientFactoryByClientResourcesAndUriObject implements RedisCl } @Override + @SuppressWarnings("try") public RedisClient create() throws Err { try { - return RedisClient.create(this.clientResources, this.uri.toString()); + var client = RedisClient.create(this.clientResources, this.uri.toString()); + try (var conn = client.connect()) {} + return client; } catch (Exception e) { throw new Err( new FailToCreateClientFromClientResourcesAndURI(this.clientResources, this.uri), e); @@ -339,9 +315,12 @@ private class RedisClientFactoryByClientResourcesAndRedisURI implements RedisCli } @Override + @SuppressWarnings("try") public RedisClient create() throws Err { try { - return RedisClient.create(this.clientResources, this.redisURI); + var client = RedisClient.create(this.clientResources, this.redisURI); + try (var conn = client.connect()) {} + return client; } catch (Exception e) { throw new Err( new FailToCreateClientFromClientResourcesAndRedisURI( diff --git a/src/test/java/com/github/sttk/sabi_redis/StandaloneAsyncTest.java b/src/test/java/com/github/sttk/sabi_redis/StandaloneAsyncTest.java index 3be19e3..5c26fde 100644 --- a/src/test/java/com/github/sttk/sabi_redis/StandaloneAsyncTest.java +++ b/src/test/java/com/github/sttk/sabi_redis/StandaloneAsyncTest.java @@ -203,45 +203,9 @@ class SampleDataHub extends DataHub implements SampleData, RedisSampleDataAcc {} // - @Test - void test_NewRedisDataSrc() { - var data = new SampleDataHub(); - data.uses("redis", new RedisDataSrc("redis://127.0.0.1:6379/0")); - try { - data.run(sampleLogic); - } catch (Err e) { - fail(e); - } - } - - @Test - void test_FailDueToInvalidAddr() { - var data = new SampleDataHub(); - data.uses("redis", new RedisDataSrc("xxxx")); - try { - data.run(sampleLogic); - } catch (Err err) { - switch (err.getReason()) { - case DataHub.FailToSetupLocalDataSrcs reason -> { - assertThat(reason.errors()).hasSize(1); - var err2 = reason.errors().get("redis"); - switch (err2.getReason()) { - case RedisDataSrc.FailToCreateClientFromUriString reason2 -> { - assertThat(reason2.uri()).isEqualTo("xxxx"); - assertThat(err2.getCause().toString()) - .isEqualTo("java.lang.IllegalArgumentException: URI scheme must not be null"); - } - default -> fail(err); - } - } - default -> fail(err); - } - } - } - @Test void test_TxnAndForceBack() { - var data = new SampleDataHub(); + try (var data = new SampleDataHub()) { data.uses("redis", new RedisDataSrc("redis://127.0.0.1:6379/3")); try { data.txn(sampleLogicWithForceBackOk); @@ -283,11 +247,12 @@ void test_TxnAndForceBack() { cmd.del("sample_force_back_2"); assertThat(s).isNull(); } + } } @Test void test_TxnAndPreCommit() { - var data = new SampleDataHub(); + try (var data = new SampleDataHub()) { data.uses("redis", new RedisDataSrc("redis://127.0.0.1:6379/4")); try { data.txn(sampleLogicWithPreCommit); @@ -304,11 +269,12 @@ void test_TxnAndPreCommit() { cmd.del("sample_pre_commit"); assertThat(s).isEqualTo("Good Evening"); } + } } @Test void test_TxnAndPostCommit() { - var data = new SampleDataHub(); + try (var data = new SampleDataHub()) { data.uses("redis", new RedisDataSrc("redis://127.0.0.1:6379/5")); try { data.txn(sampleLogicWithPostCommit); @@ -325,5 +291,6 @@ void test_TxnAndPostCommit() { cmd.del("sample_post_commit"); assertThat(s).isEqualTo("Good Night"); } + } } } diff --git a/src/test/java/com/github/sttk/sabi_redis/StandaloneSyncTest.java b/src/test/java/com/github/sttk/sabi_redis/StandaloneSyncTest.java index 239a3f9..4e34b47 100644 --- a/src/test/java/com/github/sttk/sabi_redis/StandaloneSyncTest.java +++ b/src/test/java/com/github/sttk/sabi_redis/StandaloneSyncTest.java @@ -106,7 +106,7 @@ default void setSampleKeyWithPostCommit(String val) throws Err { var dc = getDataConn("redis", RedisDataConn.class); var redisConn = dc.getConnection(); - dc.addPreCommit( + dc.addPostCommit( redisConn1 -> { var commands1 = redisConn1.sync(); commands1.set("sample_post_commit", val); @@ -166,45 +166,9 @@ class SampleDataHub extends DataHub implements SampleData, RedisSampleDataAcc {} // - @Test - void test_NewRedisDataSrc() { - var data = new SampleDataHub(); - data.uses("redis", new RedisDataSrc("redis://127.0.0.1:6379/0")); - try { - data.run(sampleLogic); - } catch (Err e) { - fail(e); - } - } - - @Test - void test_FailDueToInvalidAddr() { - var data = new SampleDataHub(); - data.uses("redis", new RedisDataSrc("xxxx")); - try { - data.run(sampleLogic); - } catch (Err err) { - switch (err.getReason()) { - case DataHub.FailToSetupLocalDataSrcs reason -> { - assertThat(reason.errors()).hasSize(1); - var err2 = reason.errors().get("redis"); - switch (err2.getReason()) { - case RedisDataSrc.FailToCreateClientFromUriString reason2 -> { - assertThat(reason2.uri()).isEqualTo("xxxx"); - assertThat(err2.getCause().toString()) - .isEqualTo("java.lang.IllegalArgumentException: URI scheme must not be null"); - } - default -> fail(err); - } - } - default -> fail(err); - } - } - } - @Test void test_TxnAndForceBack() { - var data = new SampleDataHub(); + try (var data = new SampleDataHub()) { data.uses("redis", new RedisDataSrc("redis://127.0.0.1:6379/3")); try { data.txn(sampleLogicWithForceBackOk); @@ -246,11 +210,12 @@ void test_TxnAndForceBack() { cmd.del("sample_force_back_2"); assertThat(s).isNull(); } + } } @Test void test_TxnAndPreCommit() { - var data = new SampleDataHub(); + try (var data = new SampleDataHub()) { data.uses("redis", new RedisDataSrc("redis://127.0.0.1:6379/4")); try { data.txn(sampleLogicWithPreCommit); @@ -267,11 +232,12 @@ void test_TxnAndPreCommit() { cmd.del("sample_pre_commit"); assertThat(s).isEqualTo("Good Evening"); } + } } @Test void test_TxnAndPostCommit() { - var data = new SampleDataHub(); + try (var data = new SampleDataHub()) { data.uses("redis", new RedisDataSrc("redis://127.0.0.1:6379/5")); try { data.txn(sampleLogicWithPostCommit); @@ -288,5 +254,6 @@ void test_TxnAndPostCommit() { cmd.del("sample_post_commit"); assertThat(s).isEqualTo("Good Night"); } + } } } diff --git a/src/test/java/com/github/sttk/sabi_redis/StandaloneTest.java b/src/test/java/com/github/sttk/sabi_redis/StandaloneTest.java new file mode 100644 index 0000000..9b5e47e --- /dev/null +++ b/src/test/java/com/github/sttk/sabi_redis/StandaloneTest.java @@ -0,0 +1,432 @@ +package com.github.sttk.sabi_redis; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.fail; + +import com.github.sttk.errs.Err; +import com.github.sttk.sabi.DataHub; +import com.github.sttk.sabi.AsyncGroup; +import java.net.URI; +import java.net.URISyntaxException; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.Nested; +import io.lettuce.core.RedisURI; +import io.lettuce.core.resource.DefaultClientResources; +import io.lettuce.core.resource.SocketAddressResolver; +import io.lettuce.core.resource.DnsResolver; + +public class StandaloneTest { + private StandaloneTest() {} + + @Test + void test_NewRedisDataSrcWithUriString() { + var data = new DataHub(); + data.uses("redis", new RedisDataSrc("redis://127.0.0.1:6379/0")); + try { + data.run(d -> {}); + } catch (Err e) { + fail(e); + } + } + + @Test + void test_NewRedisDataSrcWithUriStringButInvalidAddr() { + var data = new DataHub(); + data.uses("redis", new RedisDataSrc("xxxx")); + try { + data.run(d -> {}); + fail(); + } catch (Err err) { + switch (err.getReason()) { + case DataHub.FailToSetupLocalDataSrcs reason -> { + assertThat(reason.errors()).hasSize(1); + var err2 = reason.errors().get("redis"); + switch (err2.getReason()) { + case RedisDataSrc.FailToCreateClientFromUriString reason2 -> { + assertThat(reason2.uri()).isEqualTo("xxxx"); + assertThat(err2.getCause().toString()) + .isEqualTo("java.lang.IllegalArgumentException: URI scheme must not be null"); + } + default -> fail(err); + } + } + default -> fail(err); + } + } + } + + @Test + void test_NewRedisDataSrcWithUriStringButNotFoundAddr() { + var data = new DataHub(); + data.uses("redis", new RedisDataSrc("redis://127.0.0.1:9999/0")); + try { + data.run(d -> {}); + fail(); + } catch (Err err) { + switch (err.getReason()) { + case DataHub.FailToSetupLocalDataSrcs reason -> { + assertThat(reason.errors()).hasSize(1); + var err2 = reason.errors().get("redis"); + switch (err2.getReason()) { + case RedisDataSrc.FailToCreateClientFromUriString reason2 -> { + assertThat(reason2.uri()).isEqualTo("redis://127.0.0.1:9999/0"); + assertThat(err2.getCause().toString()) + .isEqualTo("io.lettuce.core.RedisConnectionException: Unable to connect to 127.0.0.1/:9999"); + } + default -> fail(err); + } + } + default -> fail(err); + } + } + } + + @Test + void test_NewRedisDataSrcWithURI() { + var data = new DataHub(); + try { + data.uses("redis", new RedisDataSrc(new URI("redis://127.0.0.1:6379/0"))); + } catch (URISyntaxException e) { + fail(e); + } + try { + data.run(d -> {}); + } catch (Err e) { + fail(e); + } + } + + @Test + void test_NewRedisDataSrcWithURIButInvalidAddr() { + var data = new DataHub(); + try { + data.uses("redis", new RedisDataSrc(new URI("xxxx"))); + } catch (URISyntaxException e) { + fail(e); + } + try { + data.run(d -> {}); + fail(); + } catch (Err err) { + switch (err.getReason()) { + case DataHub.FailToSetupLocalDataSrcs reason -> { + assertThat(reason.errors()).hasSize(1); + var err2 = reason.errors().get("redis"); + switch (err2.getReason()) { + case RedisDataSrc.FailToCreateClientFromURI reason2 -> { + assertThat(reason2.uri().toString()).isEqualTo("xxxx"); + assertThat(err2.getCause().toString()) + .isEqualTo("java.lang.IllegalArgumentException: URI scheme must not be null"); + } + default -> fail(err); + } + } + default -> fail(err); + } + } + } + + @Test + void test_NewRedisDataSrcWithURIButNotFoundAddr() { + var data = new DataHub(); + try { + data.uses("redis", new RedisDataSrc(new URI("redis://127.0.0.1:9999/0"))); + } catch (URISyntaxException e) { + fail(e); + } + try { + data.run(d -> {}); + fail(); + } catch (Err err) { + switch (err.getReason()) { + case DataHub.FailToSetupLocalDataSrcs reason -> { + assertThat(reason.errors()).hasSize(1); + var err2 = reason.errors().get("redis"); + switch (err2.getReason()) { + case RedisDataSrc.FailToCreateClientFromURI reason2 -> { + assertThat(reason2.uri().toString()).isEqualTo("redis://127.0.0.1:9999/0"); + assertThat(err2.getCause().toString()) + .isEqualTo("io.lettuce.core.RedisConnectionException: Unable to connect to 127.0.0.1/:9999"); + } + default -> fail(err); + } + } + default -> fail(err); + } + } + } + + @Test + void test_NewRedisDataSrcWithRedisURI() { + var data = new DataHub(); + data.uses("redis", new RedisDataSrc(RedisURI.create("redis://127.0.0.1:6379/0"))); + try { + data.run(d -> {}); + } catch (Err e) { + fail(e); + } + } + + @Test + void test_NewRedisDataSrcWithRedisURIButInvalidAddr() { + var data = new DataHub(); + data.uses("redis", new RedisDataSrc(RedisURI.create("redis://127.0.0.1:9999/1"))); + try { + data.run(d -> {}); + fail(); + } catch (Err err) { + switch (err.getReason()) { + case DataHub.FailToSetupLocalDataSrcs reason -> { + assertThat(reason.errors()).hasSize(1); + var err2 = reason.errors().get("redis"); + switch (err2.getReason()) { + case RedisDataSrc.FailToCreateClientFromRedisURI reason2 -> { + assertThat(reason2.redisURI().toString()).isEqualTo("redis://127.0.0.1:9999/1"); + assertThat(err2.getCause().toString()) + .isEqualTo("io.lettuce.core.RedisConnectionException: Unable to connect to 127.0.0.1/:9999"); + } + default -> fail(err); + } + } + default -> fail(err); + } + } + } + + @Test + void test_NewRedisDataSrcWithClientResourcesAndUriString() { + var res = DefaultClientResources.create(); + var data = new DataHub(); + data.uses("redis", new RedisDataSrc(res, "redis://127.0.0.1:6379/0")); + try { + data.run(d -> {}); + } catch (Err e) { + fail(e); + } + } + + @Test + void test_NewRedisDataSrcWithClientResourcesAndUriStringButInvalidAddr() { + var res = DefaultClientResources.create(); + var data = new DataHub(); + data.uses("redis", new RedisDataSrc(res, "xxxx")); + try { + data.run(d -> {}); + fail(); + } catch (Err err) { + switch (err.getReason()) { + case DataHub.FailToSetupLocalDataSrcs reason -> { + assertThat(reason.errors()).hasSize(1); + var err2 = reason.errors().get("redis"); + switch (err2.getReason()) { + case RedisDataSrc.FailToCreateClientFromClientResourcesAndUriString reason2 -> { + assertThat(reason2.uri()).isEqualTo("xxxx"); + assertThat(err2.getCause().toString()) + .isEqualTo("java.lang.IllegalArgumentException: URI scheme must not be null"); + } + default -> fail(err); + } + } + default -> fail(err); + } + } + } + + @Test + void test_NewRedisDataSrcWithClientResourcesAndUriStringButNotFoundAddr() { + var res = DefaultClientResources.create(); + var data = new DataHub(); + data.uses("redis", new RedisDataSrc(res, "redis://127.0.0.1:9999/0")); + try { + data.run(d -> {}); + fail(); + } catch (Err err) { + switch (err.getReason()) { + case DataHub.FailToSetupLocalDataSrcs reason -> { + assertThat(reason.errors()).hasSize(1); + var err2 = reason.errors().get("redis"); + switch (err2.getReason()) { + case RedisDataSrc.FailToCreateClientFromClientResourcesAndUriString reason2 -> { + assertThat(reason2.uri()).isEqualTo("redis://127.0.0.1:9999/0"); + assertThat(err2.getCause().toString()) + .isEqualTo("io.lettuce.core.RedisConnectionException: Unable to connect to 127.0.0.1/:9999"); + } + default -> fail(err); + } + } + default -> fail(err); + } + } + } + + @Test + void test_NewRedisDataSrcWithClientResourcesAndURI() { + var res = DefaultClientResources.create(); + var data = new DataHub(); + try { + data.uses("redis", new RedisDataSrc(res, new URI("redis://127.0.0.1:6379/0"))); + } catch (URISyntaxException e) { + fail(e); + } + try { + data.run(d -> {}); + } catch (Err e) { + fail(e); + } + } + + @Test + void test_NewRedisDataSrcWithClientResourcesAndURIButInvalidAddr() { + var res = DefaultClientResources.create(); + var data = new DataHub(); + try { + data.uses("redis", new RedisDataSrc(res, new URI("xxxx"))); + } catch (URISyntaxException e) { + fail(e); + } + try { + data.run(d -> {}); + fail(); + } catch (Err err) { + switch (err.getReason()) { + case DataHub.FailToSetupLocalDataSrcs reason -> { + assertThat(reason.errors()).hasSize(1); + var err2 = reason.errors().get("redis"); + switch (err2.getReason()) { + case RedisDataSrc.FailToCreateClientFromClientResourcesAndURI reason2 -> { + assertThat(reason2.uri().toString()).isEqualTo("xxxx"); + assertThat(err2.getCause().toString()) + .isEqualTo("java.lang.IllegalArgumentException: URI scheme must not be null"); + } + default -> fail(err); + } + } + default -> fail(err); + } + } + } + + @Test + void test_NewRedisDataSrcWithClientResourcesAndURIButNotFoundAddr() { + var res = DefaultClientResources.create(); + var data = new DataHub(); + try { + data.uses("redis", new RedisDataSrc(res, new URI("redis://127.0.0.1:9999/0"))); + } catch (URISyntaxException e) { + fail(e); + } + try { + data.run(d -> {}); + fail(); + } catch (Err err) { + switch (err.getReason()) { + case DataHub.FailToSetupLocalDataSrcs reason -> { + assertThat(reason.errors()).hasSize(1); + var err2 = reason.errors().get("redis"); + switch (err2.getReason()) { + case RedisDataSrc.FailToCreateClientFromClientResourcesAndURI reason2 -> { + assertThat(reason2.uri().toString()).isEqualTo("redis://127.0.0.1:9999/0"); + assertThat(err2.getCause().toString()) + .isEqualTo("io.lettuce.core.RedisConnectionException: Unable to connect to 127.0.0.1/:9999"); + } + default -> fail(err); + } + } + default -> fail(err); + } + } + } + + @Test + void test_NewRedisDataSrcWithClientResourcesAndRedisURI() { + var res = DefaultClientResources.create(); + var data = new DataHub(); + data.uses("redis", new RedisDataSrc(res, RedisURI.create("redis://127.0.0.1:6379/0"))); + try { + data.run(d -> {}); + } catch (Err e) { + fail(e); + } + } + + @Test + void test_NewRedisDataSrcWithClientResourcesAndRedisURIButInvalidAddr() { + var res = DefaultClientResources.create(); + var data = new DataHub(); + data.uses("redis", new RedisDataSrc(res, RedisURI.create("redis://127.0.0.1:9999/1"))); + try { + data.run(d -> {}); + fail(); + } catch (Err err) { + switch (err.getReason()) { + case DataHub.FailToSetupLocalDataSrcs reason -> { + assertThat(reason.errors()).hasSize(1); + var err2 = reason.errors().get("redis"); + switch (err2.getReason()) { + case RedisDataSrc.FailToCreateClientFromClientResourcesAndRedisURI reason2 -> { + assertThat(reason2.redisURI().toString()).isEqualTo("redis://127.0.0.1:9999/1"); + assertThat(err2.getCause().toString()) + .isEqualTo("io.lettuce.core.RedisConnectionException: Unable to connect to 127.0.0.1/:9999"); + } + default -> fail(err); + } + } + default -> fail(err); + } + } + } + + @Nested + class ForCoverage { + @Test + void testRedisDataConn() { + var conn = new RedisDataConn(null); + conn.rollback(null); + + conn.addPreCommit(_conn -> { + throw new Err("bad"); + }); + try { + conn.preCommit(null); + fail(); + } catch (Err err) { + assertThat(err.getReason()).isEqualTo("bad"); + } + + conn.addPostCommit(_conn -> { + throw new Err("bad"); + }); + conn.postCommit(null); + + conn.addForceBack(_conn -> { + throw new Err("bad"); + }); + conn.forceBack(null); + } + + @Test + void testRedisDataSrc() { + var ds = new RedisDataSrc("redis://127.0.0.1:6379/0"); + try { + ds.createDataConn(); + fail(); + } catch (Err err) { + assertThat(err.getReason()).isEqualTo(new RedisDataSrc.NotSetupYet()); + } + ds.close(); + + try { + ds.setup(null); + } catch (Err err) { + fail(err); + } + try { + ds.setup(null); + fail(); + } catch (Err err) { + assertThat(err.getReason()).isEqualTo(new RedisDataSrc.AlreadySetup()); + } + ds.close(); + } + } +}