diff --git a/pom.xml b/pom.xml index 5c9636c3d..cbea20479 100644 --- a/pom.xml +++ b/pom.xml @@ -30,9 +30,10 @@ spring-cloud-stream-rxjava spring-cloud-stream-samples spring-cloud-stream-module-launcher - docs spring-cloud-stream-test-support + spring-cloud-stream-test-support-internal spring-cloud-stream-configuration-metadata + docs @@ -118,6 +119,16 @@ spring-cloud-stream-test-support 1.0.0.BUILD-SNAPSHOT + + org.springframework.cloud + spring-cloud-stream-test-support-internal + ${project.version} + + + org.springframework.cloud + spring-cloud-stream-module-test-support + ${project.version} + org.springframework.integration spring-integration-core diff --git a/spring-cloud-stream-binders/spring-cloud-stream-binder-kafka/pom.xml b/spring-cloud-stream-binders/spring-cloud-stream-binder-kafka/pom.xml index eb2f0eb31..5292af0d4 100644 --- a/spring-cloud-stream-binders/spring-cloud-stream-binder-kafka/pom.xml +++ b/spring-cloud-stream-binders/spring-cloud-stream-binder-kafka/pom.xml @@ -14,7 +14,6 @@ - UTF-8 0.8.2.1 1.2.0.RELEASE 1.0.0 @@ -44,6 +43,11 @@ spring-cloud-stream-binder-test test + + org.springframework.cloud + spring-cloud-stream-test-support-internal + test + org.springframework.integration spring-integration-kafka diff --git a/spring-cloud-stream-binders/spring-cloud-stream-binder-kafka/src/test/java/org/springframework/cloud/stream/binder/kafka/KafkaBinderTests.java b/spring-cloud-stream-binders/spring-cloud-stream-binder-kafka/src/test/java/org/springframework/cloud/stream/binder/kafka/KafkaBinderTests.java index 3e40080b7..29327a06c 100644 --- a/spring-cloud-stream-binders/spring-cloud-stream-binder-kafka/src/test/java/org/springframework/cloud/stream/binder/kafka/KafkaBinderTests.java +++ b/spring-cloud-stream-binders/spring-cloud-stream-binder-kafka/src/test/java/org/springframework/cloud/stream/binder/kafka/KafkaBinderTests.java @@ -36,6 +36,7 @@ import org.junit.Ignore; import org.junit.Test; import org.springframework.cloud.stream.binder.PartitionCapableBinderTests; +import org.springframework.cloud.stream.test.junit.kafka.KafkaTestSupport; import org.springframework.integration.channel.DirectChannel; import org.springframework.integration.channel.QueueChannel; import org.springframework.integration.kafka.core.KafkaMessage; diff --git a/spring-cloud-stream-binders/spring-cloud-stream-binder-kafka/src/test/java/org/springframework/cloud/stream/binder/kafka/KafkaTestBinder.java b/spring-cloud-stream-binders/spring-cloud-stream-binder-kafka/src/test/java/org/springframework/cloud/stream/binder/kafka/KafkaTestBinder.java index 4939c6159..9f46d337d 100644 --- a/spring-cloud-stream-binders/spring-cloud-stream-binder-kafka/src/test/java/org/springframework/cloud/stream/binder/kafka/KafkaTestBinder.java +++ b/spring-cloud-stream-binders/spring-cloud-stream-binder-kafka/src/test/java/org/springframework/cloud/stream/binder/kafka/KafkaTestBinder.java @@ -22,6 +22,8 @@ import com.esotericsoftware.kryo.Kryo; import com.esotericsoftware.kryo.Registration; import org.springframework.cloud.stream.binder.AbstractTestBinder; +import org.springframework.cloud.stream.test.junit.kafka.KafkaTestSupport; +import org.springframework.cloud.stream.test.junit.kafka.TestKafkaCluster; import org.springframework.context.support.GenericApplicationContext; import org.springframework.integration.codec.Codec; import org.springframework.integration.codec.kryo.KryoRegistrar; diff --git a/spring-cloud-stream-binders/spring-cloud-stream-binder-rabbit/pom.xml b/spring-cloud-stream-binders/spring-cloud-stream-binder-rabbit/pom.xml index f84b607e4..615056ab2 100644 --- a/spring-cloud-stream-binders/spring-cloud-stream-binder-rabbit/pom.xml +++ b/spring-cloud-stream-binders/spring-cloud-stream-binder-rabbit/pom.xml @@ -46,6 +46,11 @@ spring-cloud-stream-binder-test test + + org.springframework.cloud + spring-cloud-stream-test-support-internal + test + org.springframework.boot spring-boot-starter-amqp diff --git a/spring-cloud-stream-binders/spring-cloud-stream-binder-rabbit/src/test/java/org/springframework/cloud/stream/binder/rabbit/LocalizedQueueConnectionFactoryIntegrationTests.java b/spring-cloud-stream-binders/spring-cloud-stream-binder-rabbit/src/test/java/org/springframework/cloud/stream/binder/rabbit/LocalizedQueueConnectionFactoryIntegrationTests.java index 5dcd55d6a..2548e07b4 100644 --- a/spring-cloud-stream-binders/spring-cloud-stream-binder-rabbit/src/test/java/org/springframework/cloud/stream/binder/rabbit/LocalizedQueueConnectionFactoryIntegrationTests.java +++ b/spring-cloud-stream-binders/spring-cloud-stream-binder-rabbit/src/test/java/org/springframework/cloud/stream/binder/rabbit/LocalizedQueueConnectionFactoryIntegrationTests.java @@ -29,6 +29,7 @@ import org.springframework.amqp.rabbit.connection.CachingConnectionFactory; import org.springframework.amqp.rabbit.connection.ConnectionFactory; import org.springframework.amqp.rabbit.core.RabbitAdmin; import org.springframework.amqp.rabbit.core.RabbitTemplate; +import org.springframework.cloud.stream.test.junit.rabbit.RabbitTestSupport; /** diff --git a/spring-cloud-stream-binders/spring-cloud-stream-binder-rabbit/src/test/java/org/springframework/cloud/stream/binder/rabbit/RabbitAdminTestSupport.java b/spring-cloud-stream-binders/spring-cloud-stream-binder-rabbit/src/test/java/org/springframework/cloud/stream/binder/rabbit/RabbitAdminTestSupport.java deleted file mode 100644 index 776ac835e..000000000 --- a/spring-cloud-stream-binders/spring-cloud-stream-binder-rabbit/src/test/java/org/springframework/cloud/stream/binder/rabbit/RabbitAdminTestSupport.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright 2015 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.stream.binder.rabbit; - - -import org.springframework.http.HttpStatus; -import org.springframework.web.client.HttpClientErrorException; -import org.springframework.web.client.RestTemplate; -import org.springframework.cloud.stream.binder.AbstractExternalResourceTestSupport; - -import java.util.Map; - -/** - * JUnit {@link org.junit.Rule} that detects the fact that RabbitMQ is available on localhost with - * the management plugin enabled. - * - * @author Gary Russell - * @since 1.2 - */ -public class RabbitAdminTestSupport extends AbstractExternalResourceTestSupport { - - public RabbitAdminTestSupport() { - super("RABBITADMIN"); - } - - @Override - protected void obtainResource() throws Exception { - resource = new RestTemplate(); - try { - resource.getForObject("http://localhost:15672/api/overview", Map.class); - } - catch (HttpClientErrorException e) { - if (e.getStatusCode() != HttpStatus.UNAUTHORIZED) { - throw e; - } - } - } - - @Override - protected void cleanupResource() throws Exception { - } - -} diff --git a/spring-cloud-stream-binders/spring-cloud-stream-binder-rabbit/src/test/java/org/springframework/cloud/stream/binder/rabbit/RabbitBinderCleanerTests.java b/spring-cloud-stream-binders/spring-cloud-stream-binder-rabbit/src/test/java/org/springframework/cloud/stream/binder/rabbit/RabbitBinderCleanerTests.java index 3b9164b57..bf61401d2 100644 --- a/spring-cloud-stream-binders/spring-cloud-stream-binder-rabbit/src/test/java/org/springframework/cloud/stream/binder/rabbit/RabbitBinderCleanerTests.java +++ b/spring-cloud-stream-binders/spring-cloud-stream-binder-rabbit/src/test/java/org/springframework/cloud/stream/binder/rabbit/RabbitBinderCleanerTests.java @@ -35,6 +35,7 @@ import org.springframework.amqp.rabbit.connection.CachingConnectionFactory; import org.springframework.amqp.rabbit.core.ChannelCallback; import org.springframework.amqp.rabbit.core.RabbitAdmin; import org.springframework.amqp.rabbit.core.RabbitTemplate; +import org.springframework.cloud.stream.test.junit.rabbit.RabbitTestSupport; import org.springframework.web.client.RestTemplate; import org.springframework.web.util.UriComponentsBuilder; import org.springframework.cloud.stream.binder.BinderUtils; @@ -57,10 +58,7 @@ public class RabbitBinderCleanerTests { private static final String BINDER_PREFIX = "binder.rabbit."; @Rule - public RabbitAdminTestSupport adminTest = new RabbitAdminTestSupport(); - - @Rule - public RabbitTestSupport test = new RabbitTestSupport(); + public RabbitTestSupport rabbitWithMgmtEnabled = new RabbitTestSupport(true); @Test public void testCleanStream() { @@ -93,7 +91,7 @@ public class RabbitBinderCleanerTests { .buildAndExpand("/", MessageChannelBinderSupport.constructDLQName(queue1Name)).encode().toUri(); template.put(uri, new AmqpQueue(false, true)); } - CachingConnectionFactory connectionFactory = test.getResource(); + CachingConnectionFactory connectionFactory = rabbitWithMgmtEnabled.getResource(); RabbitAdmin rabbitAdmin = new RabbitAdmin(connectionFactory); final FanoutExchange fanout1 = new FanoutExchange( MessageChannelBinderSupport.applyPrefix(BINDER_PREFIX, MessageChannelBinderSupport.applyPubSub( diff --git a/spring-cloud-stream-binders/spring-cloud-stream-binder-rabbit/src/test/java/org/springframework/cloud/stream/binder/rabbit/RabbitBinderTests.java b/spring-cloud-stream-binders/spring-cloud-stream-binder-rabbit/src/test/java/org/springframework/cloud/stream/binder/rabbit/RabbitBinderTests.java index 66afadc96..f39056a09 100644 --- a/spring-cloud-stream-binders/spring-cloud-stream-binder-rabbit/src/test/java/org/springframework/cloud/stream/binder/rabbit/RabbitBinderTests.java +++ b/spring-cloud-stream-binders/spring-cloud-stream-binder-rabbit/src/test/java/org/springframework/cloud/stream/binder/rabbit/RabbitBinderTests.java @@ -46,6 +46,7 @@ import org.springframework.cloud.stream.binder.BinderProperties; import org.springframework.cloud.stream.binder.Binding; import org.springframework.cloud.stream.binder.PartitionCapableBinderTests; import org.springframework.cloud.stream.binder.Spy; +import org.springframework.cloud.stream.test.junit.rabbit.RabbitTestSupport; import org.springframework.expression.spel.standard.SpelExpression; import org.springframework.integration.channel.DirectChannel; import org.springframework.integration.channel.QueueChannel; diff --git a/spring-cloud-stream-binders/spring-cloud-stream-binder-redis/pom.xml b/spring-cloud-stream-binders/spring-cloud-stream-binder-redis/pom.xml index c2e8f5642..1e16457e1 100644 --- a/spring-cloud-stream-binders/spring-cloud-stream-binder-redis/pom.xml +++ b/spring-cloud-stream-binders/spring-cloud-stream-binder-redis/pom.xml @@ -46,6 +46,11 @@ spring-cloud-stream-binder-test test + + org.springframework.cloud + spring-cloud-stream-test-support-internal + test + org.springframework.boot spring-boot-starter-redis diff --git a/spring-cloud-stream-binders/spring-cloud-stream-binder-redis/src/test/java/org/springframework/cloud/stream/binder/redis/RedisBinderTests.java b/spring-cloud-stream-binders/spring-cloud-stream-binder-redis/src/test/java/org/springframework/cloud/stream/binder/redis/RedisBinderTests.java index ac16192d1..6f0008cd4 100644 --- a/spring-cloud-stream-binders/spring-cloud-stream-binder-redis/src/test/java/org/springframework/cloud/stream/binder/redis/RedisBinderTests.java +++ b/spring-cloud-stream-binders/spring-cloud-stream-binder-redis/src/test/java/org/springframework/cloud/stream/binder/redis/RedisBinderTests.java @@ -38,6 +38,7 @@ import org.junit.Rule; import org.junit.Test; import org.springframework.cloud.stream.binder.PartitionCapableBinderTests; +import org.springframework.cloud.stream.test.junit.redis.RedisTestSupport; import org.springframework.data.redis.connection.RedisConnectionFactory; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.serializer.StringRedisSerializer; diff --git a/spring-cloud-stream-binders/spring-cloud-stream-binder-redis/src/test/java/org/springframework/cloud/stream/binder/redis/RedisPublishingMessageHandlerTests.java b/spring-cloud-stream-binders/spring-cloud-stream-binder-redis/src/test/java/org/springframework/cloud/stream/binder/redis/RedisPublishingMessageHandlerTests.java index ea0f3c367..898918522 100644 --- a/spring-cloud-stream-binders/spring-cloud-stream-binder-redis/src/test/java/org/springframework/cloud/stream/binder/redis/RedisPublishingMessageHandlerTests.java +++ b/spring-cloud-stream-binders/spring-cloud-stream-binder-redis/src/test/java/org/springframework/cloud/stream/binder/redis/RedisPublishingMessageHandlerTests.java @@ -27,6 +27,7 @@ import org.junit.Rule; import org.junit.Test; import org.springframework.cloud.stream.binder.BinderTestUtils; +import org.springframework.cloud.stream.test.junit.redis.RedisTestSupport; import org.springframework.data.redis.connection.RedisConnectionFactory; import org.springframework.data.redis.listener.ChannelTopic; import org.springframework.data.redis.listener.RedisMessageListenerContainer; diff --git a/spring-cloud-stream-binders/spring-cloud-stream-binder-redis/src/test/java/org/springframework/cloud/stream/binder/redis/RedisQueueInboundChannelAdapterTests.java b/spring-cloud-stream-binders/spring-cloud-stream-binder-redis/src/test/java/org/springframework/cloud/stream/binder/redis/RedisQueueInboundChannelAdapterTests.java index 766fd487f..e740d5a2d 100644 --- a/spring-cloud-stream-binders/spring-cloud-stream-binder-redis/src/test/java/org/springframework/cloud/stream/binder/redis/RedisQueueInboundChannelAdapterTests.java +++ b/spring-cloud-stream-binders/spring-cloud-stream-binder-redis/src/test/java/org/springframework/cloud/stream/binder/redis/RedisQueueInboundChannelAdapterTests.java @@ -31,6 +31,7 @@ import org.junit.Rule; import org.junit.Test; import org.springframework.cloud.stream.binder.BinderTestUtils; +import org.springframework.cloud.stream.test.junit.redis.RedisTestSupport; import org.springframework.data.redis.connection.RedisConnectionFactory; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.serializer.GenericToStringSerializer; diff --git a/spring-cloud-stream-binders/spring-cloud-stream-binder-redis/src/test/java/org/springframework/cloud/stream/binder/redis/RedisQueueOutboundChannelAdapterTests.java b/spring-cloud-stream-binders/spring-cloud-stream-binder-redis/src/test/java/org/springframework/cloud/stream/binder/redis/RedisQueueOutboundChannelAdapterTests.java index 1be1de96d..f43402561 100644 --- a/spring-cloud-stream-binders/spring-cloud-stream-binder-redis/src/test/java/org/springframework/cloud/stream/binder/redis/RedisQueueOutboundChannelAdapterTests.java +++ b/spring-cloud-stream-binders/spring-cloud-stream-binder-redis/src/test/java/org/springframework/cloud/stream/binder/redis/RedisQueueOutboundChannelAdapterTests.java @@ -27,6 +27,7 @@ import org.junit.Rule; import org.junit.Test; import org.springframework.cloud.stream.binder.BinderTestUtils; +import org.springframework.cloud.stream.test.junit.redis.RedisTestSupport; import org.springframework.data.redis.connection.RedisConnectionFactory; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.core.StringRedisTemplate; diff --git a/spring-cloud-stream-binders/spring-cloud-stream-binder-test/src/main/java/org/springframework/cloud/stream/binder/AbstractExternalResourceTestSupport.java b/spring-cloud-stream-binders/spring-cloud-stream-binder-test/src/main/java/org/springframework/cloud/stream/binder/AbstractExternalResourceTestSupport.java deleted file mode 100644 index b8f811b56..000000000 --- a/spring-cloud-stream-binders/spring-cloud-stream-binder-test/src/main/java/org/springframework/cloud/stream/binder/AbstractExternalResourceTestSupport.java +++ /dev/null @@ -1,134 +0,0 @@ -/* - * Copyright 2013 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.stream.binder; - -import static org.junit.Assert.fail; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.junit.Assume; -import org.junit.Rule; -import org.junit.rules.TestRule; -import org.junit.runner.Description; -import org.junit.runners.model.Statement; - -import org.springframework.util.Assert; - - -/** - * Abstract base class for JUnit {@link Rule}s that detect the presence of some external resource. If the resource is - * indeed present, it will be available during the test lifecycle through {@link #getResource()}. If it is not, tests - * will either fail or be skipped, depending on the value of system property {@value #XD_EXTERNAL_SERVERS_REQUIRED}. - * - * @author Eric Bottard - * @author Gary Russell - */ -public abstract class AbstractExternalResourceTestSupport implements TestRule { - - public static final String XD_EXTERNAL_SERVERS_REQUIRED = "XD_EXTERNAL_SERVERS_REQUIRED"; - - protected R resource; - - private String resourceDescription; - - protected final Logger logger = LoggerFactory.getLogger(this.getClass()); - - protected AbstractExternalResourceTestSupport(String resourceDescription) { - Assert.hasText(resourceDescription, "resourceDescription is required"); - this.resourceDescription = resourceDescription; - } - - @Override - public Statement apply(final Statement base, Description description) { - try { - obtainResource(); - } - catch (Exception e) { - maybeCleanup(); - - return failOrSkip(e); - } - - return new Statement() { - - @Override - public void evaluate() throws Throwable { - try { - base.evaluate(); - } - finally { - try { - cleanupResource(); - } - catch (Exception ignored) { - logger.warn("Exception while trying to cleanup proper resource", ignored); - } - } - } - - }; - } - - private Statement failOrSkip(final Exception e) { - String serversRequired = System.getenv(XD_EXTERNAL_SERVERS_REQUIRED); - if ("true".equalsIgnoreCase(serversRequired)) { - logger.error(resourceDescription + " IS REQUIRED BUT NOT AVAILABLE", e); - fail(resourceDescription + " IS NOT AVAILABLE"); - // Never reached, here to satisfy method signature - return null; - } - else { - logger.error(resourceDescription + " IS NOT AVAILABLE, SKIPPING TESTS", e); - return new Statement() { - - @Override - public void evaluate() throws Throwable { - Assume.assumeTrue("Skipping test due to " + resourceDescription + " not being available " + e, false); - } - }; - } - } - - private void maybeCleanup() { - if (resource != null) { - try { - cleanupResource(); - } - catch (Exception ignored) { - logger.warn("Exception while trying to cleanup failed resource", ignored); - } - } - } - - public R getResource() { - return resource; - } - - /** - * Perform cleanup of the {@link #resource} field, which is guaranteed to be non null. - * - * @throws Exception any exception thrown by this method will be logged and swallowed - */ - protected abstract void cleanupResource() throws Exception; - - /** - * Try to obtain and validate a resource. Implementors should either set the {@link #resource} field with a valid - * resource and return normally, or throw an exception. - */ - protected abstract void obtainResource() throws Exception; - -} diff --git a/spring-cloud-stream-test-support-internal/pom.xml b/spring-cloud-stream-test-support-internal/pom.xml new file mode 100644 index 000000000..a5d81bb37 --- /dev/null +++ b/spring-cloud-stream-test-support-internal/pom.xml @@ -0,0 +1,74 @@ + + + 4.0.0 + + org.springframework.cloud + spring-cloud-stream-parent + 1.0.0.BUILD-SNAPSHOT + + spring-cloud-stream-test-support-internal + Set of classes and utility code that may assist in testing both + spring-cloud-stream itself, and also modules. + + 0.8.2.1 + 2.6.0 + + + + junit + junit + compile + + + org.springframework.boot + spring-boot-starter-logging + + + org.springframework + spring-core + + + + + + org.springframework.boot + spring-boot-starter-redis + true + + + + org.apache.curator + curator-recipes + ${curator.version} + true + + + org.apache.kafka + kafka_2.10 + ${kafka.version} + true + + + org.apache.kafka + kafka_2.10 + test + ${kafka.version} + true + + + org.apache.curator + curator-test + ${curator.version} + true + + + + org.springframework.boot + spring-boot-starter-amqp + true + + + + diff --git a/spring-cloud-stream-test-support-internal/src/main/java/org/springframework/cloud/stream/test/junit/AbstractExternalResourceTestSupport.java b/spring-cloud-stream-test-support-internal/src/main/java/org/springframework/cloud/stream/test/junit/AbstractExternalResourceTestSupport.java new file mode 100644 index 000000000..2379397c6 --- /dev/null +++ b/spring-cloud-stream-test-support-internal/src/main/java/org/springframework/cloud/stream/test/junit/AbstractExternalResourceTestSupport.java @@ -0,0 +1,133 @@ +/* + * Copyright 2015 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.stream.test.junit; + +import static org.junit.Assert.fail; + +import org.junit.Assume; +import org.junit.Rule; +import org.junit.rules.TestRule; +import org.junit.runner.Description; +import org.junit.runners.model.Statement; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import org.springframework.util.Assert; + +/** + * Abstract base class for JUnit {@link Rule}s that detect the presence of some external resource. If the resource is + * indeed present, it will be available during the test lifecycle through {@link #getResource()}. If it is not, tests + * will either fail or be skipped, depending on the value of system property {@value #SCS_EXTERNAL_SERVERS_REQUIRED}. + * + * @author Eric Bottard + * @author Gary Russell + */ +public abstract class AbstractExternalResourceTestSupport implements TestRule { + + public static final String SCS_EXTERNAL_SERVERS_REQUIRED = "SCS_EXTERNAL_SERVERS_REQUIRED"; + + protected R resource; + + private String resourceDescription; + + protected final Logger logger = LoggerFactory.getLogger(this.getClass()); + + protected AbstractExternalResourceTestSupport(String resourceDescription) { + Assert.hasText(resourceDescription, "resourceDescription is required"); + this.resourceDescription = resourceDescription; + } + + @Override + public Statement apply(final Statement base, Description description) { + try { + obtainResource(); + } + catch (Exception e) { + maybeCleanup(); + + return failOrSkip(e); + } + + return new Statement() { + + @Override + public void evaluate() throws Throwable { + try { + base.evaluate(); + } + finally { + try { + cleanupResource(); + } + catch (Exception ignored) { + logger.warn("Exception while trying to cleanup proper resource", ignored); + } + } + } + + }; + } + + private Statement failOrSkip(final Exception e) { + String serversRequired = System.getenv(SCS_EXTERNAL_SERVERS_REQUIRED); + if ("true".equalsIgnoreCase(serversRequired)) { + logger.error(resourceDescription + " IS REQUIRED BUT NOT AVAILABLE", e); + fail(resourceDescription + " IS NOT AVAILABLE"); + // Never reached, here to satisfy method signature + return null; + } + else { + logger.error(resourceDescription + " IS NOT AVAILABLE, SKIPPING TESTS", e); + return new Statement() { + + @Override + public void evaluate() throws Throwable { + Assume.assumeTrue("Skipping test due to " + resourceDescription + " not being available " + e, false); + } + }; + } + } + + private void maybeCleanup() { + if (resource != null) { + try { + cleanupResource(); + } + catch (Exception ignored) { + logger.warn("Exception while trying to cleanup failed resource", ignored); + } + } + } + + public R getResource() { + return resource; + } + + /** + * Perform cleanup of the {@link #resource} field, which is guaranteed to be non null. + * + * @throws Exception any exception thrown by this method will be logged and swallowed + */ + protected abstract void cleanupResource() throws Exception; + + /** + * Try to obtain and validate a resource. Implementors should either set the {@link #resource} field with a valid + * resource and return normally, or throw an exception. + */ + protected abstract void obtainResource() throws Exception; + +} diff --git a/spring-cloud-stream-binders/spring-cloud-stream-binder-kafka/src/test/java/org/springframework/cloud/stream/binder/kafka/EmbeddedZookeeper.java b/spring-cloud-stream-test-support-internal/src/main/java/org/springframework/cloud/stream/test/junit/kafka/EmbeddedZookeeper.java similarity index 97% rename from spring-cloud-stream-binders/spring-cloud-stream-binder-kafka/src/test/java/org/springframework/cloud/stream/binder/kafka/EmbeddedZookeeper.java rename to spring-cloud-stream-test-support-internal/src/main/java/org/springframework/cloud/stream/test/junit/kafka/EmbeddedZookeeper.java index 907986982..78778d1cf 100644 --- a/spring-cloud-stream-binders/spring-cloud-stream-binder-kafka/src/test/java/org/springframework/cloud/stream/binder/kafka/EmbeddedZookeeper.java +++ b/spring-cloud-stream-test-support-internal/src/main/java/org/springframework/cloud/stream/test/junit/kafka/EmbeddedZookeeper.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.cloud.stream.binder.kafka; +package org.springframework.cloud.stream.test.junit.kafka; import java.io.File; import java.net.InetSocketAddress; diff --git a/spring-cloud-stream-binders/spring-cloud-stream-binder-kafka/src/test/java/org/springframework/cloud/stream/binder/kafka/KafkaTestSupport.java b/spring-cloud-stream-test-support-internal/src/main/java/org/springframework/cloud/stream/test/junit/kafka/KafkaTestSupport.java similarity index 97% rename from spring-cloud-stream-binders/spring-cloud-stream-binder-kafka/src/test/java/org/springframework/cloud/stream/binder/kafka/KafkaTestSupport.java rename to spring-cloud-stream-test-support-internal/src/main/java/org/springframework/cloud/stream/test/junit/kafka/KafkaTestSupport.java index 6dafd8a0d..ba26b9901 100644 --- a/spring-cloud-stream-binders/spring-cloud-stream-binder-kafka/src/test/java/org/springframework/cloud/stream/binder/kafka/KafkaTestSupport.java +++ b/spring-cloud-stream-test-support-internal/src/main/java/org/springframework/cloud/stream/test/junit/kafka/KafkaTestSupport.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.cloud.stream.binder.kafka; +package org.springframework.cloud.stream.test.junit.kafka; import java.util.Properties; @@ -34,7 +34,8 @@ import org.junit.Rule; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.cloud.stream.binder.AbstractExternalResourceTestSupport; +import org.springframework.cloud.stream.test.junit.AbstractExternalResourceTestSupport; + /** * JUnit {@link Rule} that starts an embedded Kafka server (with an associated Zookeeper) diff --git a/spring-cloud-stream-binders/spring-cloud-stream-binder-kafka/src/test/java/org/springframework/cloud/stream/binder/kafka/TestKafkaCluster.java b/spring-cloud-stream-test-support-internal/src/main/java/org/springframework/cloud/stream/test/junit/kafka/TestKafkaCluster.java similarity index 52% rename from spring-cloud-stream-binders/spring-cloud-stream-binder-kafka/src/test/java/org/springframework/cloud/stream/binder/kafka/TestKafkaCluster.java rename to spring-cloud-stream-test-support-internal/src/main/java/org/springframework/cloud/stream/test/junit/kafka/TestKafkaCluster.java index 6a609aab3..e96598f0d 100644 --- a/spring-cloud-stream-binders/spring-cloud-stream-binder-kafka/src/test/java/org/springframework/cloud/stream/binder/kafka/TestKafkaCluster.java +++ b/spring-cloud-stream-test-support-internal/src/main/java/org/springframework/cloud/stream/test/junit/kafka/TestKafkaCluster.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.cloud.stream.binder.kafka; +package org.springframework.cloud.stream.test.junit.kafka; import kafka.admin.AdminUtils; import kafka.consumer.Consumer; @@ -85,87 +85,9 @@ public class TestKafkaCluster { } - /** - * See XD-2293. This is used to reproduce Kafka rebalance issues. - */ - public static void main(String[] args) throws Exception { - TestKafkaCluster cluster = new TestKafkaCluster(); - ZkClient client = new ZkClient(cluster.getZkConnectString(), 10000, 10000, KafkaMessageChannelBinder.utf8Serializer); - int partitions = 5; - int replication = 1; - AdminUtils.createTopic(client, "mytopic", partitions, replication, new Properties()); - - Properties props = new Properties(); - props.put("zookeeper.connect", cluster.getZkConnectString()); - props.put("group.id", "foo"); - props.put("rebalance.backoff.ms", "2000"); - props.put("rebalance.max.retries", "2000"); - ConsumerConfig config = new ConsumerConfig(props); - - - CuratorFramework curator = CuratorFrameworkFactory.newClient(cluster.getZkConnectString(), new RetryUntilElapsed(1000, 100)); - curator.start(); - - RebalanceListener listener = null; - for (int i = 0; i < 5; i++) { - System.out.format("%nCreating consumer #%d%n", i + 1); - ConsumerConnector connector = Consumer.createJavaConsumerConnector(config); - connector.createMessageStreams(Collections.singletonMap("mytopic", 1)); - if (i == 0) { - PathChildrenCache cache = new PathChildrenCache(curator, "/consumers/foo/owners/mytopic", true); - listener = new RebalanceListener(5); - cache.getListenable().addListener(listener); - cache.start(PathChildrenCache.StartMode.POST_INITIALIZED_EVENT); - } - - synchronized (listener) { - System.out.println("******** Waiting for rebalance..."); - listener.wait(); - } - - } - - System.out.println(); - - } public String getZkConnectString() { return zkServer.getConnectString(); } - private static class RebalanceListener implements PathChildrenCacheListener { - - private int expected; - - private int actual; - - private boolean ready; - - public RebalanceListener(int expected) { - this.expected = expected; - } - - @Override - public synchronized void childEvent(CuratorFramework client, PathChildrenCacheEvent event) throws Exception { - System.out.println(event); - System.out.println(event.getData() != null ? new String(event.getData().getData()) : "no data"); - switch (event.getType()) { - case CHILD_ADDED: - actual++; - if (ready && actual == expected) { - System.out.println("*** Moving on... "); - this.notify(); - } - break; - case CHILD_REMOVED: - actual--; - break; - case INITIALIZED: - Assert.isTrue(actual == expected); - ready = true; - this.notify(); - break; - } - } - } } diff --git a/spring-cloud-stream-binders/spring-cloud-stream-binder-rabbit/src/test/java/org/springframework/cloud/stream/binder/rabbit/RabbitTestSupport.java b/spring-cloud-stream-test-support-internal/src/main/java/org/springframework/cloud/stream/test/junit/rabbit/RabbitTestSupport.java similarity index 88% rename from spring-cloud-stream-binders/spring-cloud-stream-binder-rabbit/src/test/java/org/springframework/cloud/stream/binder/rabbit/RabbitTestSupport.java rename to spring-cloud-stream-test-support-internal/src/main/java/org/springframework/cloud/stream/test/junit/rabbit/RabbitTestSupport.java index fc27def0c..84f597dc1 100644 --- a/spring-cloud-stream-binders/spring-cloud-stream-binder-rabbit/src/test/java/org/springframework/cloud/stream/binder/rabbit/RabbitTestSupport.java +++ b/spring-cloud-stream-test-support-internal/src/main/java/org/springframework/cloud/stream/test/junit/rabbit/RabbitTestSupport.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2015 the original author or authors. + * Copyright 2015 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,14 +14,14 @@ * limitations under the License. */ -package org.springframework.cloud.stream.binder.rabbit; +package org.springframework.cloud.stream.test.junit.rabbit; - -import org.springframework.amqp.rabbit.connection.CachingConnectionFactory; -import org.springframework.cloud.stream.binder.AbstractExternalResourceTestSupport; +import java.net.Socket; import javax.net.SocketFactory; -import java.net.Socket; + +import org.springframework.amqp.rabbit.connection.CachingConnectionFactory; +import org.springframework.cloud.stream.test.junit.AbstractExternalResourceTestSupport; /** * JUnit {@link org.junit.Rule} that detects the fact that RabbitMQ is available on localhost. diff --git a/spring-cloud-stream-binders/spring-cloud-stream-binder-redis/src/test/java/org/springframework/cloud/stream/binder/redis/RedisTestSupport.java b/spring-cloud-stream-test-support-internal/src/main/java/org/springframework/cloud/stream/test/junit/redis/RedisTestSupport.java similarity index 78% rename from spring-cloud-stream-binders/spring-cloud-stream-binder-redis/src/test/java/org/springframework/cloud/stream/binder/redis/RedisTestSupport.java rename to spring-cloud-stream-test-support-internal/src/main/java/org/springframework/cloud/stream/test/junit/redis/RedisTestSupport.java index 4db9c8ca7..8aeab0245 100644 --- a/spring-cloud-stream-binders/spring-cloud-stream-binder-redis/src/test/java/org/springframework/cloud/stream/binder/redis/RedisTestSupport.java +++ b/spring-cloud-stream-test-support-internal/src/main/java/org/springframework/cloud/stream/test/junit/redis/RedisTestSupport.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2015 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,15 +14,13 @@ * limitations under the License. */ -package org.springframework.cloud.stream.binder.redis; - -import org.junit.Rule; +package org.springframework.cloud.stream.test.junit.redis; +import org.springframework.cloud.stream.test.junit.AbstractExternalResourceTestSupport; import org.springframework.data.redis.connection.jedis.JedisConnectionFactory; -import org.springframework.cloud.stream.binder.AbstractExternalResourceTestSupport; /** - * JUnit {@link Rule} that detects the fact that a Redis server is running on localhost. + * JUnit {@link org.junit.Rule} that detects the fact that a Redis server is running on localhost. * * @author Gary Russell * @author Eric Bottard diff --git a/spring-cloud-stream-test-support/pom.xml b/spring-cloud-stream-test-support/pom.xml index d94053bd0..49266d3ee 100644 --- a/spring-cloud-stream-test-support/pom.xml +++ b/spring-cloud-stream-test-support/pom.xml @@ -6,12 +6,8 @@ spring-cloud-stream-parent 1.0.0.BUILD-SNAPSHOT - org.springframework.cloud - spring-cloud-stream-test-support - Spring Cloud Stream Test Support - - UTF-8 - + spring-cloud-stream-module-test-support + A set of classes to ease testing of Spring Cloud Stream modules. org.springframework.boot