From 160d609bd4fb08cd09d16b1abef614f40f113cd5 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Mon, 20 Oct 2014 11:04:14 +0100 Subject: [PATCH] Protect against race condition where output file exists but it is empty MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Previously, there was a timing window where the output file had been created but it was empty. This would cause the test to fail as the output was read from the empty file and didn’t match the expected “Hello World”. This commit updates the test to only process the resources in the output directory when all the resolved resources have a non-zero content length. An @Before method has also been added to delete the output produced by the test so that the outcome of the test isn’t affected by files generated by previous runs. Fixes gh-1735 --- .../SampleIntegrationApplicationTests.java | 27 ++++++++++++++++--- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/spring-boot-samples/spring-boot-sample-integration/src/test/java/sample/integration/consumer/SampleIntegrationApplicationTests.java b/spring-boot-samples/spring-boot-sample-integration/src/test/java/sample/integration/consumer/SampleIntegrationApplicationTests.java index ae019c7e9cc..28e60d07852 100644 --- a/spring-boot-samples/spring-boot-sample-integration/src/test/java/sample/integration/consumer/SampleIntegrationApplicationTests.java +++ b/spring-boot-samples/spring-boot-sample-integration/src/test/java/sample/integration/consumer/SampleIntegrationApplicationTests.java @@ -16,12 +16,15 @@ package sample.integration.consumer; +import java.io.File; +import java.io.IOException; import java.util.concurrent.Callable; import java.util.concurrent.Executors; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; import org.junit.AfterClass; +import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; import org.springframework.boot.SpringApplication; @@ -29,6 +32,7 @@ import org.springframework.context.ConfigurableApplicationContext; import org.springframework.core.io.DefaultResourceLoader; import org.springframework.core.io.Resource; import org.springframework.core.io.support.ResourcePatternUtils; +import org.springframework.util.FileSystemUtils; import org.springframework.util.StreamUtils; import sample.integration.SampleIntegrationApplication; @@ -40,6 +44,7 @@ import static org.junit.Assert.assertTrue; * Basic integration tests for service demo application. * * @author Dave Syer + * @author Andy Wilkinson */ public class SampleIntegrationApplicationTests { @@ -57,6 +62,11 @@ public class SampleIntegrationApplicationTests { } } + @Before + public void deleteOutput() { + FileSystemUtils.deleteRecursively(new File("target/output")); + } + @Test public void testVanillaExchange() throws Exception { SpringApplication.run(ProducerApplication.class, "World"); @@ -69,12 +79,10 @@ public class SampleIntegrationApplicationTests { new Callable() { @Override public String call() throws Exception { - Resource[] resources = new Resource[0]; + Resource[] resources = getResourcesWithContent(); while (resources.length == 0) { Thread.sleep(200); - resources = ResourcePatternUtils.getResourcePatternResolver( - new DefaultResourceLoader()).getResources( - "file:target/output/**"); + resources = getResourcesWithContent(); } StringBuilder builder = new StringBuilder(); for (Resource resource : resources) { @@ -86,4 +94,15 @@ public class SampleIntegrationApplicationTests { }); return future.get(30, TimeUnit.SECONDS); } + + private Resource[] getResourcesWithContent() throws IOException { + Resource[] candidates = ResourcePatternUtils.getResourcePatternResolver( + new DefaultResourceLoader()).getResources("file:target/output/**"); + for (Resource candidate : candidates) { + if (candidate.contentLength() == 0) { + return new Resource[0]; + } + } + return candidates; + } }