From ffc65ff8681613669839df6b89e21d987d3114a6 Mon Sep 17 00:00:00 2001 From: Maciej Modzelewski Date: Sun, 1 Oct 2023 12:18:53 +0200 Subject: [PATCH] Refactor tests so they can be reused for all transport protocols --- src/main/java/rs/iggy/IggyClient.java | 30 +++++++ .../java/rs/iggy/http/IggyHttpClient.java | 11 ++- ...egrationTest.java => IntegrationTest.java} | 25 ++++-- .../http/BaseHttpClientIntegrationTest.java | 16 ---- .../java/rs/iggy/http/HttpClientFactory.java | 14 +++ .../rs/iggy/http/MessagesHttpClientTest.java | 85 ++---------------- .../iggy/http/PartitionsHttpClientTest.java | 44 ++-------- .../rs/iggy/http/StreamHttpClientTest.java | 37 ++------ .../rs/iggy/http/TopicsHttpClientTest.java | 38 ++------ .../iggy/message/MessagesClientBaseTest.java | 86 +++++++++++++++++++ .../partition/PartitionsClientBaseTest.java | 45 ++++++++++ .../rs/iggy/stream/StreamClientBaseTest.java | 38 ++++++++ .../rs/iggy/topic/TopicsClientBaseTest.java | 39 +++++++++ 13 files changed, 304 insertions(+), 204 deletions(-) create mode 100644 src/main/java/rs/iggy/IggyClient.java rename src/test/java/rs/iggy/{BaseIntegrationTest.java => IntegrationTest.java} (58%) delete mode 100644 src/test/java/rs/iggy/http/BaseHttpClientIntegrationTest.java create mode 100644 src/test/java/rs/iggy/http/HttpClientFactory.java create mode 100644 src/test/java/rs/iggy/message/MessagesClientBaseTest.java create mode 100644 src/test/java/rs/iggy/partition/PartitionsClientBaseTest.java create mode 100644 src/test/java/rs/iggy/stream/StreamClientBaseTest.java create mode 100644 src/test/java/rs/iggy/topic/TopicsClientBaseTest.java diff --git a/src/main/java/rs/iggy/IggyClient.java b/src/main/java/rs/iggy/IggyClient.java new file mode 100644 index 0000000..7744657 --- /dev/null +++ b/src/main/java/rs/iggy/IggyClient.java @@ -0,0 +1,30 @@ +package rs.iggy; + +import rs.iggy.consumergroup.ConsumerGroupsClient; +import rs.iggy.consumeroffset.ConsumerOffsetsClient; +import rs.iggy.message.MessagesClient; +import rs.iggy.partition.PartitionsClient; +import rs.iggy.stream.StreamsClient; +import rs.iggy.system.SystemClient; +import rs.iggy.topic.TopicsClient; +import rs.iggy.user.UsersClient; + +public interface IggyClient { + + SystemClient system(); + + StreamsClient streams(); + + UsersClient users(); + + TopicsClient topics(); + + PartitionsClient partitions(); + + ConsumerGroupsClient consumerGroups(); + + ConsumerOffsetsClient consumerOffsets(); + + MessagesClient messages(); + +} diff --git a/src/main/java/rs/iggy/http/IggyHttpClient.java b/src/main/java/rs/iggy/http/IggyHttpClient.java index c95e4ec..369a30f 100644 --- a/src/main/java/rs/iggy/http/IggyHttpClient.java +++ b/src/main/java/rs/iggy/http/IggyHttpClient.java @@ -1,5 +1,6 @@ package rs.iggy.http; +import rs.iggy.IggyClient; import rs.iggy.consumergroup.ConsumerGroupsClient; import rs.iggy.consumeroffset.ConsumerOffsetsClient; import rs.iggy.message.MessagesClient; @@ -9,7 +10,7 @@ import rs.iggy.topic.TopicsClient; import rs.iggy.user.UsersClient; -public class IggyHttpClient { +public class IggyHttpClient implements IggyClient { private final SystemHttpClient systemClient; private final StreamsHttpClient streamsClient; @@ -32,34 +33,42 @@ public IggyHttpClient(String url) { messagesClient = new MessagesHttpClient(httpClient); } + @Override public SystemClient system() { return systemClient; } + @Override public StreamsClient streams() { return streamsClient; } + @Override public UsersClient users() { return usersClient; } + @Override public TopicsClient topics() { return topicsClient; } + @Override public PartitionsClient partitions() { return partitionsClient; } + @Override public ConsumerGroupsClient consumerGroups() { return consumerGroupsClient; } + @Override public ConsumerOffsetsClient consumerOffsets() { return consumerOffsetsClient; } + @Override public MessagesClient messages() { return messagesClient; } diff --git a/src/test/java/rs/iggy/BaseIntegrationTest.java b/src/test/java/rs/iggy/IntegrationTest.java similarity index 58% rename from src/test/java/rs/iggy/BaseIntegrationTest.java rename to src/test/java/rs/iggy/IntegrationTest.java index 1d3a085..bd6d320 100644 --- a/src/test/java/rs/iggy/BaseIntegrationTest.java +++ b/src/test/java/rs/iggy/IntegrationTest.java @@ -1,29 +1,40 @@ package rs.iggy; +import org.junit.jupiter.api.BeforeEach; import org.testcontainers.containers.GenericContainer; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; import org.testcontainers.utility.DockerImageName; -import rs.iggy.http.IggyHttpClient; import static java.util.Optional.empty; @Testcontainers -public abstract class BaseIntegrationTest { +public abstract class IntegrationTest { + + public static final int HTTP_PORT = 3000; @Container protected final GenericContainer iggyServer = new GenericContainer( - DockerImageName.parse("iggyrs/iggy:latest")).withExposedPorts(3000); + DockerImageName.parse("iggyrs/iggy:latest")).withExposedPorts(HTTP_PORT); + + protected IggyClient client; + + @BeforeEach + void beforeEachIntegrationTest() { + client = getClient(); + } + + abstract protected IggyClient getClient(); - protected void setUpStream(IggyHttpClient client) { + protected void setUpStream() { client.streams().createStream(42L, "test-stream"); } - protected void setUpStreamAndTopic(IggyHttpClient client) { - setUpStream(client); + protected void setUpStreamAndTopic() { + setUpStream(); client.topics().createTopic(42L, 42L, 1L, empty(), "test-topic"); } - protected void login(IggyHttpClient client) { + protected void login() { client.users().login("iggy", "iggy"); } diff --git a/src/test/java/rs/iggy/http/BaseHttpClientIntegrationTest.java b/src/test/java/rs/iggy/http/BaseHttpClientIntegrationTest.java deleted file mode 100644 index 0ced907..0000000 --- a/src/test/java/rs/iggy/http/BaseHttpClientIntegrationTest.java +++ /dev/null @@ -1,16 +0,0 @@ -package rs.iggy.http; - -import org.junit.jupiter.api.BeforeEach; -import rs.iggy.BaseIntegrationTest; - -abstract class BaseHttpClientIntegrationTest extends BaseIntegrationTest { - - protected IggyHttpClient client; - - @BeforeEach - void beforeEachBase() { - String address = iggyServer.getHost(); - Integer port = iggyServer.getFirstMappedPort(); - client = new IggyHttpClient("http://" + address + ":" + port); - } -} diff --git a/src/test/java/rs/iggy/http/HttpClientFactory.java b/src/test/java/rs/iggy/http/HttpClientFactory.java new file mode 100644 index 0000000..5fcd254 --- /dev/null +++ b/src/test/java/rs/iggy/http/HttpClientFactory.java @@ -0,0 +1,14 @@ +package rs.iggy.http; + +import org.testcontainers.containers.GenericContainer; +import static rs.iggy.IntegrationTest.HTTP_PORT; + +class HttpClientFactory { + + static IggyHttpClient create(GenericContainer iggyServer) { + String address = iggyServer.getHost(); + Integer port = iggyServer.getMappedPort(HTTP_PORT); + return new IggyHttpClient("http://" + address + ":" + port); + } + +} diff --git a/src/test/java/rs/iggy/http/MessagesHttpClientTest.java b/src/test/java/rs/iggy/http/MessagesHttpClientTest.java index 756c0ad..cab4d5d 100644 --- a/src/test/java/rs/iggy/http/MessagesHttpClientTest.java +++ b/src/test/java/rs/iggy/http/MessagesHttpClientTest.java @@ -1,86 +1,13 @@ package rs.iggy.http; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import rs.iggy.message.*; -import java.math.BigInteger; -import java.nio.ByteBuffer; -import java.util.List; -import java.util.UUID; -import static java.util.Optional.empty; -import static org.assertj.core.api.Assertions.assertThat; +import rs.iggy.IggyClient; +import rs.iggy.message.MessagesClientBaseTest; -class MessagesHttpClientTest extends BaseHttpClientIntegrationTest { +class MessagesHttpClientTest extends MessagesClientBaseTest { - MessagesClient messagesClient; - - @BeforeEach - void beforeEach() { - messagesClient = client.messages(); - - login(client); - } - - @Test - void shouldSendAndGetMessages() { - // given - setUpStreamAndTopic(client); - - // when - String text = "message from java sdk"; - messagesClient.sendMessages(42L, 42L, Partitioning.partitionId(1L), - List.of(new MessageToSend(getRandomId(), text.getBytes(), empty()))); - - var polledMessages = messagesClient.pollMessages(42L, 42L, empty(), 0L, - new PollingStrategy(PollingKind.Last, BigInteger.TEN), 10L, false); - - // then - assertThat(polledMessages.messages()).hasSize(1); - } - - @Test - void shouldSendMessageWithBalancedPartitioning() { - // given - setUpStreamAndTopic(client); - - // when - String text = "message from java sdk"; - messagesClient.sendMessages(42L, 42L, Partitioning.balanced(), - List.of(new MessageToSend(getRandomId(), text.getBytes(), empty()))); - - var polledMessages = messagesClient.pollMessages(42L, 42L, empty(), 0L, - new PollingStrategy(PollingKind.Last, BigInteger.TEN), 10L, false); - - // then - assertThat(polledMessages.messages()).hasSize(1); - } - - @Test - void shouldSendMessageWithMessageKeyPartitioning() { - // given - setUpStreamAndTopic(client); - - // when - String text = "message from java sdk"; - messagesClient.sendMessages(42L, 42L, Partitioning.messagesKey("test-key"), - List.of(new MessageToSend(getRandomId(), text.getBytes(), empty()))); - - var polledMessages = messagesClient.pollMessages(42L, 42L, empty(), 0L, - new PollingStrategy(PollingKind.Last, BigInteger.TEN), 10L, false); - - // then - assertThat(polledMessages.messages()).hasSize(1); - } - - private static BigInteger getRandomId() { - return new BigInteger(1, uuidToBytes(UUID.randomUUID())); - } - - private static byte[] uuidToBytes(UUID uuid) { - ByteBuffer byteBuffer = ByteBuffer.wrap(new byte[16]); - byteBuffer.putLong(uuid.getMostSignificantBits()); - byteBuffer.putLong(uuid.getLeastSignificantBits()); - return byteBuffer.array(); + @Override + protected IggyClient getClient() { + return HttpClientFactory.create(iggyServer); } } diff --git a/src/test/java/rs/iggy/http/PartitionsHttpClientTest.java b/src/test/java/rs/iggy/http/PartitionsHttpClientTest.java index 654a439..5eb1aa8 100644 --- a/src/test/java/rs/iggy/http/PartitionsHttpClientTest.java +++ b/src/test/java/rs/iggy/http/PartitionsHttpClientTest.java @@ -1,45 +1,13 @@ package rs.iggy.http; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import rs.iggy.partition.PartitionsClient; -import rs.iggy.topic.TopicDetails; -import rs.iggy.topic.TopicsClient; -import static org.assertj.core.api.Assertions.assertThat; +import rs.iggy.IggyClient; +import rs.iggy.partition.PartitionsClientBaseTest; -class PartitionsHttpClientTest extends BaseHttpClientIntegrationTest { +class PartitionsHttpClientTest extends PartitionsClientBaseTest { - TopicsClient topicsClient; - PartitionsClient partitionsClient; - - @BeforeEach - void beforeEach() { - topicsClient = client.topics(); - partitionsClient = client.partitions(); - - login(client); - setUpStreamAndTopic(client); - } - - - @Test - void shouldCreateAndDeletePartitions() { - // given - assert topicsClient.getTopic(42L, 42L).partitionsCount() == 1L; - - // when - partitionsClient.createPartitions(42L, 42L, 10L); - - // then - TopicDetails topic = topicsClient.getTopic(42L, 42L); - assertThat(topic.partitionsCount()).isEqualTo(11L); - - // when - partitionsClient.deletePartitions(42L, 42L, 10L); - - // then - topic = topicsClient.getTopic(42L, 42L); - assertThat(topic.partitionsCount()).isEqualTo(1L); + @Override + protected IggyClient getClient() { + return HttpClientFactory.create(iggyServer); } } diff --git a/src/test/java/rs/iggy/http/StreamHttpClientTest.java b/src/test/java/rs/iggy/http/StreamHttpClientTest.java index 0388a7f..bc330c2 100644 --- a/src/test/java/rs/iggy/http/StreamHttpClientTest.java +++ b/src/test/java/rs/iggy/http/StreamHttpClientTest.java @@ -1,38 +1,13 @@ package rs.iggy.http; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import rs.iggy.stream.StreamsClient; -import static org.assertj.core.api.Assertions.assertThat; +import rs.iggy.IggyClient; +import rs.iggy.stream.StreamClientBaseTest; -class StreamHttpClientTest extends BaseHttpClientIntegrationTest { +class StreamHttpClientTest extends StreamClientBaseTest { - StreamsClient streamsClient; - - @BeforeEach - void beforeEach() { - streamsClient = client.streams(); - - login(client); - } - - @Test - void shouldCreateAndDeleteStream() { - // when - streamsClient.createStream(42L, "test-stream"); - var stream = streamsClient.getStream(42L); - - // then - assertThat(stream).isNotNull(); - assertThat(stream.id()).isEqualTo(42L); - assertThat(stream.name()).isEqualTo("test-stream"); - - // when - streamsClient.deleteStream(42L); - var streams = streamsClient.getStreams(); - - // then - assertThat(streams).isEmpty(); + @Override + protected IggyClient getClient() { + return HttpClientFactory.create(iggyServer); } } diff --git a/src/test/java/rs/iggy/http/TopicsHttpClientTest.java b/src/test/java/rs/iggy/http/TopicsHttpClientTest.java index 1300aac..0c7e345 100644 --- a/src/test/java/rs/iggy/http/TopicsHttpClientTest.java +++ b/src/test/java/rs/iggy/http/TopicsHttpClientTest.java @@ -1,39 +1,13 @@ package rs.iggy.http; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import rs.iggy.topic.TopicsClient; -import static java.util.Optional.empty; -import static org.assertj.core.api.Assertions.assertThat; +import rs.iggy.IggyClient; +import rs.iggy.topic.TopicsClientBaseTest; -class TopicsHttpClientTest extends BaseHttpClientIntegrationTest { +class TopicsHttpClientTest extends TopicsClientBaseTest { - TopicsClient topicsClient; - - @BeforeEach - void beforeEach() { - topicsClient = client.topics(); - - login(client); - setUpStream(client); - } - - @Test - void shouldCreateAndDeleteTopic() { - // when - topicsClient.createTopic(42L, 42L, 1L, empty(), "test-topic"); - var topic = topicsClient.getTopic(42L, 42L); - - // then - assertThat(topic).isNotNull(); - assertThat(topic.id()).isEqualTo(42L); - assertThat(topic.name()).isEqualTo("test-topic"); - - // when - topicsClient.deleteTopic(42L, 42L); - - // then - assertThat(topicsClient.getTopics(42L)).isEmpty(); + @Override + protected IggyClient getClient() { + return HttpClientFactory.create(iggyServer); } } diff --git a/src/test/java/rs/iggy/message/MessagesClientBaseTest.java b/src/test/java/rs/iggy/message/MessagesClientBaseTest.java new file mode 100644 index 0000000..b7c899e --- /dev/null +++ b/src/test/java/rs/iggy/message/MessagesClientBaseTest.java @@ -0,0 +1,86 @@ +package rs.iggy.message; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import rs.iggy.IntegrationTest; +import java.math.BigInteger; +import java.nio.ByteBuffer; +import java.util.List; +import java.util.UUID; +import static java.util.Optional.empty; +import static org.assertj.core.api.Assertions.assertThat; + +public abstract class MessagesClientBaseTest extends IntegrationTest { + + protected MessagesClient messagesClient; + + @BeforeEach + void beforeEachBase() { + messagesClient = client.messages(); + + login(); + } + + @Test + void shouldSendAndGetMessages() { + // given + setUpStreamAndTopic(); + + // when + String text = "message from java sdk"; + messagesClient.sendMessages(42L, 42L, Partitioning.partitionId(1L), + List.of(new MessageToSend(getRandomId(), text.getBytes(), empty()))); + + var polledMessages = messagesClient.pollMessages(42L, 42L, empty(), 0L, + new PollingStrategy(PollingKind.Last, BigInteger.TEN), 10L, false); + + // then + assertThat(polledMessages.messages()).hasSize(1); + } + + @Test + void shouldSendMessageWithBalancedPartitioning() { + // given + setUpStreamAndTopic(); + + // when + String text = "message from java sdk"; + messagesClient.sendMessages(42L, 42L, Partitioning.balanced(), + List.of(new MessageToSend(getRandomId(), text.getBytes(), empty()))); + + var polledMessages = messagesClient.pollMessages(42L, 42L, empty(), 0L, + new PollingStrategy(PollingKind.Last, BigInteger.TEN), 10L, false); + + // then + assertThat(polledMessages.messages()).hasSize(1); + } + + @Test + void shouldSendMessageWithMessageKeyPartitioning() { + // given + setUpStreamAndTopic(); + + // when + String text = "message from java sdk"; + messagesClient.sendMessages(42L, 42L, Partitioning.messagesKey("test-key"), + List.of(new MessageToSend(getRandomId(), text.getBytes(), empty()))); + + var polledMessages = messagesClient.pollMessages(42L, 42L, empty(), 0L, + new PollingStrategy(PollingKind.Last, BigInteger.TEN), 10L, false); + + // then + assertThat(polledMessages.messages()).hasSize(1); + } + + private static BigInteger getRandomId() { + return new BigInteger(1, uuidToBytes(UUID.randomUUID())); + } + + private static byte[] uuidToBytes(UUID uuid) { + ByteBuffer byteBuffer = ByteBuffer.wrap(new byte[16]); + byteBuffer.putLong(uuid.getMostSignificantBits()); + byteBuffer.putLong(uuid.getLeastSignificantBits()); + return byteBuffer.array(); + } + +} diff --git a/src/test/java/rs/iggy/partition/PartitionsClientBaseTest.java b/src/test/java/rs/iggy/partition/PartitionsClientBaseTest.java new file mode 100644 index 0000000..236a2bb --- /dev/null +++ b/src/test/java/rs/iggy/partition/PartitionsClientBaseTest.java @@ -0,0 +1,45 @@ +package rs.iggy.partition; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import rs.iggy.IntegrationTest; +import rs.iggy.topic.TopicDetails; +import rs.iggy.topic.TopicsClient; +import static org.assertj.core.api.Assertions.assertThat; + +public abstract class PartitionsClientBaseTest extends IntegrationTest { + + TopicsClient topicsClient; + PartitionsClient partitionsClient; + + @BeforeEach + void beforeEachBase() { + topicsClient = client.topics(); + partitionsClient = client.partitions(); + + login(); + setUpStreamAndTopic(); + } + + + @Test + void shouldCreateAndDeletePartitions() { + // given + assert topicsClient.getTopic(42L, 42L).partitionsCount() == 1L; + + // when + partitionsClient.createPartitions(42L, 42L, 10L); + + // then + TopicDetails topic = topicsClient.getTopic(42L, 42L); + assertThat(topic.partitionsCount()).isEqualTo(11L); + + // when + partitionsClient.deletePartitions(42L, 42L, 10L); + + // then + topic = topicsClient.getTopic(42L, 42L); + assertThat(topic.partitionsCount()).isEqualTo(1L); + } + +} diff --git a/src/test/java/rs/iggy/stream/StreamClientBaseTest.java b/src/test/java/rs/iggy/stream/StreamClientBaseTest.java new file mode 100644 index 0000000..f26ea6a --- /dev/null +++ b/src/test/java/rs/iggy/stream/StreamClientBaseTest.java @@ -0,0 +1,38 @@ +package rs.iggy.stream; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import rs.iggy.IntegrationTest; +import static org.assertj.core.api.Assertions.assertThat; + +public abstract class StreamClientBaseTest extends IntegrationTest { + + StreamsClient streamsClient; + + @BeforeEach + void beforeEachBase() { + streamsClient = client.streams(); + + login(); + } + + @Test + void shouldCreateAndDeleteStream() { + // when + streamsClient.createStream(42L, "test-stream"); + var stream = streamsClient.getStream(42L); + + // then + assertThat(stream).isNotNull(); + assertThat(stream.id()).isEqualTo(42L); + assertThat(stream.name()).isEqualTo("test-stream"); + + // when + streamsClient.deleteStream(42L); + var streams = streamsClient.getStreams(); + + // then + assertThat(streams).isEmpty(); + } + +} diff --git a/src/test/java/rs/iggy/topic/TopicsClientBaseTest.java b/src/test/java/rs/iggy/topic/TopicsClientBaseTest.java new file mode 100644 index 0000000..83c1a3c --- /dev/null +++ b/src/test/java/rs/iggy/topic/TopicsClientBaseTest.java @@ -0,0 +1,39 @@ +package rs.iggy.topic; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import rs.iggy.IntegrationTest; +import static java.util.Optional.empty; +import static org.assertj.core.api.Assertions.assertThat; + +public abstract class TopicsClientBaseTest extends IntegrationTest { + + protected TopicsClient topicsClient; + + @BeforeEach + void beforeEachBase() { + topicsClient = client.topics(); + + login(); + setUpStream(); + } + + @Test + void shouldCreateAndDeleteTopic() { + // when + topicsClient.createTopic(42L, 42L, 1L, empty(), "test-topic"); + var topic = topicsClient.getTopic(42L, 42L); + + // then + assertThat(topic).isNotNull(); + assertThat(topic.id()).isEqualTo(42L); + assertThat(topic.name()).isEqualTo("test-topic"); + + // when + topicsClient.deleteTopic(42L, 42L); + + // then + assertThat(topicsClient.getTopics(42L)).isEmpty(); + } + +}