diff --git a/src/test/java/org/springframework/data/gemfire/CacheClusterConfigurationIntegrationTest.java b/src/test/java/org/springframework/data/gemfire/CacheClusterConfigurationIntegrationTest.java index a9ca17dd..1ef00476 100644 --- a/src/test/java/org/springframework/data/gemfire/CacheClusterConfigurationIntegrationTest.java +++ b/src/test/java/org/springframework/data/gemfire/CacheClusterConfigurationIntegrationTest.java @@ -24,12 +24,17 @@ import static org.junit.Assert.fail; import java.io.File; import java.io.IOException; import java.util.ArrayList; +import java.util.Collections; import java.util.List; import java.util.concurrent.TimeUnit; import org.junit.AfterClass; import org.junit.BeforeClass; +import org.junit.Rule; import org.junit.Test; +import org.junit.rules.TestRule; +import org.junit.rules.TestWatcher; +import org.junit.runner.Description; import org.springframework.beans.factory.BeanCreationException; import org.springframework.beans.factory.BeanInitializationException; import org.springframework.context.ConfigurableApplicationContext; @@ -37,10 +42,14 @@ import org.springframework.context.support.ClassPathXmlApplicationContext; import org.springframework.core.io.ClassPathResource; import org.springframework.data.gemfire.fork.LocatorProcess; import org.springframework.data.gemfire.process.ProcessExecutor; +import org.springframework.data.gemfire.process.ProcessInputStreamListener; import org.springframework.data.gemfire.process.ProcessWrapper; +import org.springframework.data.gemfire.test.support.FileUtils; import org.springframework.data.gemfire.test.support.ThreadUtils; +import org.springframework.data.gemfire.test.support.ThrowableUtils; import org.springframework.data.gemfire.test.support.ZipUtils; import org.springframework.util.FileSystemUtils; +import org.springframework.util.StringUtils; import com.gemstone.gemfire.cache.DataPolicy; import com.gemstone.gemfire.cache.Region; @@ -67,6 +76,30 @@ public class CacheClusterConfigurationIntegrationTest { private static ProcessWrapper locatorProcess; + private static List locatorProcessOutput = Collections.synchronizedList(new ArrayList()); + + @Rule + public TestRule watchman = new TestWatcher() { + @Override protected void failed(final Throwable t, final Description description) { + try { + System.err.println(String.format("Test '%1$s' failed...", description.getDisplayName())); + System.err.println(ThrowableUtils.toString(t)); + System.err.println("Locator process log file contents were..."); + + String locatorProcessOutputString = StringUtils.collectionToDelimitedString(locatorProcessOutput, + FileUtils.LINE_SEPARATOR, String.format("[%1$s] - ", description.getMethodName()), ""); + + locatorProcessOutputString = (StringUtils.hasText(locatorProcessOutputString) ? + locatorProcessOutputString : locatorProcess.readLogFile()); + + System.err.println(locatorProcessOutputString); + } + catch (IOException e) { + throw new RuntimeException("Failed to read the contents of the Locator process log file!", e); + } + } + }; + @BeforeClass public static void testSuiteSetup() throws IOException { String locatorName = "ClusterConfigLocator"; @@ -88,7 +121,13 @@ public class CacheClusterConfigurationIntegrationTest { locatorProcess.registerShutdownHook(); - waitForLocatorStart(TimeUnit.SECONDS.toMillis(30)); + locatorProcess.register(new ProcessInputStreamListener() { + @Override public void onInput(final String input) { + locatorProcessOutput.add(input); + } + }); + + waitForLocatorStart(TimeUnit.SECONDS.toMillis(60)); //System.out.println("Cluster Configuration Locator should be running!"); } diff --git a/src/test/java/org/springframework/data/gemfire/fork/LocatorProcess.java b/src/test/java/org/springframework/data/gemfire/fork/LocatorProcess.java index 5bc423d5..a6ad1728 100644 --- a/src/test/java/org/springframework/data/gemfire/fork/LocatorProcess.java +++ b/src/test/java/org/springframework/data/gemfire/fork/LocatorProcess.java @@ -94,8 +94,8 @@ public class LocatorProcess { distributedSystemProperties.setProperty(DistributionConfig.LOG_LEVEL_NAME, System.getProperty("spring.gemfire.log-level", DEFAULT_LOG_LEVEL)); - return InternalLocator.startLocator(locatorPort, null, null, null, null, null, distributedSystemProperties, true, true, - hostnameForClients, loadClusterConfigurationFromDirectory); + return InternalLocator.startLocator(locatorPort, null, null, null, null, null, distributedSystemProperties, + true, true, hostnameForClients, loadClusterConfigurationFromDirectory); } private static LocatorLauncher buildLocatorLauncher() { diff --git a/src/test/java/org/springframework/data/gemfire/process/ProcessWrapper.java b/src/test/java/org/springframework/data/gemfire/process/ProcessWrapper.java index 770e6e7f..537c7335 100644 --- a/src/test/java/org/springframework/data/gemfire/process/ProcessWrapper.java +++ b/src/test/java/org/springframework/data/gemfire/process/ProcessWrapper.java @@ -18,6 +18,8 @@ package org.springframework.data.gemfire.process; import java.io.BufferedReader; import java.io.File; +import java.io.FileFilter; +import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; @@ -36,6 +38,8 @@ import java.util.logging.Logger; import org.springframework.data.gemfire.process.support.PidUnavailableException; import org.springframework.data.gemfire.process.support.ProcessUtils; +import org.springframework.data.gemfire.test.support.FileSystemUtils; +import org.springframework.data.gemfire.test.support.FileUtils; import org.springframework.data.gemfire.test.support.IOUtils; import org.springframework.data.gemfire.test.support.ThreadUtils; import org.springframework.data.gemfire.test.support.ThrowableUtils; @@ -74,10 +78,10 @@ public class ProcessWrapper { this.process = process; this.processConfiguration = processConfiguration; - postInit(); + init(); } - private void postInit() { + private void init() { newThread("Process OUT Stream Reader", newProcessInputStreamReader(process.getInputStream())).start(); if (!isRedirectingErrorStream()) { @@ -169,6 +173,26 @@ public class ProcessWrapper { } } + public String readLogFile() throws IOException { + File[] logFiles = FileSystemUtils.listFiles(getWorkingDirectory(), new FileFilter() { + @Override public boolean accept(final File pathname) { + return (pathname != null && (pathname.isDirectory() || pathname.getAbsolutePath().endsWith(".log"))); + } + }); + + if (logFiles.length > 0) { + return readLogFile(logFiles[0]); + } + else { + throw new FileNotFoundException(String.format( + "No log files were found in the process's working directory (%1$s)!", getWorkingDirectory())); + } + } + + public String readLogFile(final File log) throws IOException { + return FileUtils.read(log); + } + public boolean register(final ProcessInputStreamListener listener) { return (listener != null && listeners.add(listener)); } diff --git a/src/test/java/org/springframework/data/gemfire/test/support/FileSystemUtils.java b/src/test/java/org/springframework/data/gemfire/test/support/FileSystemUtils.java new file mode 100644 index 00000000..e217ba5d --- /dev/null +++ b/src/test/java/org/springframework/data/gemfire/test/support/FileSystemUtils.java @@ -0,0 +1,62 @@ +/* + * Copyright 2010-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.data.gemfire.test.support; + +import java.io.File; +import java.io.FileFilter; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import com.gemstone.gemfire.management.internal.cli.util.spring.Assert; + +/** + * The FileSystemUtils class is a utility class encapsulating functionality to process file system directories + * and files collectively. + * + * @author John Blum + * @see java.io.File + * @see org.springframework.data.gemfire.test.support.IOUtils + * @since 1.5.0 + */ +@SuppressWarnings("unused") +public abstract class FileSystemUtils extends IOUtils { + + public static File[] listFiles(final File directory, final FileFilter fileFilter) { + Assert.isTrue(directory != null && directory.isDirectory(), String.format( + "The File (%1$s) does not refer to a valid directory!", directory)); + + List results = new ArrayList(); + + for (File file : safeListFiles(directory, fileFilter)) { + if (file.isDirectory()) { + results.addAll(Arrays.asList(listFiles(file, fileFilter))); + } + else { + results.add(file); + } + } + + return results.toArray(new File[results.size()]); + } + + private static File[] safeListFiles(final File directory, final FileFilter fileFilter) { + File[] files = (directory != null ? directory.listFiles(fileFilter) : new File[0]); + return (files != null ? files : new File[0]); + } + +} diff --git a/src/test/java/org/springframework/data/gemfire/test/support/FileUtils.java b/src/test/java/org/springframework/data/gemfire/test/support/FileUtils.java new file mode 100644 index 00000000..f7791691 --- /dev/null +++ b/src/test/java/org/springframework/data/gemfire/test/support/FileUtils.java @@ -0,0 +1,62 @@ +/* + * Copyright 2010-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.data.gemfire.test.support; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.io.IOException; + +import org.springframework.util.Assert; + +/** + * The FileUtils class is a utility class for processing files, working with java.io.File objects. + * + * @author John Blum + * @see java.io.File + * @see org.springframework.data.gemfire.test.support.IOUtils + * @since 1.5.0 + */ +@SuppressWarnings("unused") +public abstract class FileUtils extends IOUtils { + + public static final String LINE_SEPARATOR = System.getProperty("line.separator"); + + public static String read(final File file) throws IOException { + Assert.isTrue(file != null && file.isFile(), String.format( + "The File reference (%1$s) from which to read the contents is not a valid file!", file)); + + assert file != null; + + BufferedReader fileReader = new BufferedReader(new FileReader(file)); + + try { + StringBuilder buffer = new StringBuilder(); + + for (String line = fileReader.readLine(); line != null; line = fileReader.readLine()) { + buffer.append(line); + buffer.append(LINE_SEPARATOR); + } + + return buffer.toString().trim(); + } + finally { + close(fileReader); + } + } + +} diff --git a/src/test/java/org/springframework/data/gemfire/test/support/IOUtils.java b/src/test/java/org/springframework/data/gemfire/test/support/IOUtils.java index ffef148c..bab1298e 100644 --- a/src/test/java/org/springframework/data/gemfire/test/support/IOUtils.java +++ b/src/test/java/org/springframework/data/gemfire/test/support/IOUtils.java @@ -49,4 +49,5 @@ public abstract class IOUtils { return false; } + }