diff --git a/src/test/java/org/springframework/data/gemfire/client/GemFireDataSourceUsingNonSpringConfiguredGemFireServerIntegrationTest.java b/src/test/java/org/springframework/data/gemfire/client/GemFireDataSourceUsingNonSpringConfiguredGemFireServerIntegrationTest.java index 5c942a31..c8bc5349 100644 --- a/src/test/java/org/springframework/data/gemfire/client/GemFireDataSourceUsingNonSpringConfiguredGemFireServerIntegrationTest.java +++ b/src/test/java/org/springframework/data/gemfire/client/GemFireDataSourceUsingNonSpringConfiguredGemFireServerIntegrationTest.java @@ -93,26 +93,29 @@ public class GemFireDataSourceUsingNonSpringConfiguredGemFireServerIntegrationTe File serverWorkingDirectory = new File(FileSystemUtils.WORKING_DIRECTORY, serverName.toLowerCase()); - Assert.isTrue(serverWorkingDirectory.isDirectory() || serverWorkingDirectory.mkdirs()); + Assert.isTrue(serverWorkingDirectory.isDirectory() || serverWorkingDirectory.mkdirs(), + String.format("Server working directory [%s] does not exist and could not be created", serverWorkingDirectory)); writeAsCacheXmlFileToDirectory("gemfire-datasource-integration-test-cache.xml", serverWorkingDirectory); - Assert.isTrue(new File(serverWorkingDirectory, "cache.xml").isFile(), String.format( - "Expected a cache.xml file to exist in directory (%1$s)!", serverWorkingDirectory)); + Assert.isTrue(new File(serverWorkingDirectory, "cache.xml").isFile(), + String.format("Expected a cache.xml file to exist in directory [%s]", serverWorkingDirectory)); List arguments = new ArrayList<>(5); arguments.add(ServerLauncher.Command.START.getName()); - arguments.add(String.format("-Dgemfire.name=%1$s", serverName)); - arguments.add(String.format("-Dgemfire.log-level=%1$s", "error")); + arguments.add(String.format("-Dgemfire.name=%s", serverName)); + arguments.add(String.format("-Dgemfire.log-level=%s", GEMFIRE_LOG_LEVEL)); - gemfireServer = ProcessExecutor.launch(serverWorkingDirectory, customClasspath(), ServerLauncher.class, - arguments.toArray(new String[arguments.size()])); + gemfireServer = ProcessExecutor.launch(serverWorkingDirectory, customClasspath(), + GemFireBasedServerProcess.class, arguments.toArray(new String[0])); - waitForProcessStart(TimeUnit.SECONDS.toMillis(20), gemfireServer, GemFireBasedServerProcess.getServerProcessControlFilename()); + waitForProcessStart(TimeUnit.SECONDS.toMillis(20), gemfireServer, + GemFireBasedServerProcess.getServerProcessControlFilename()); } private static void writeAsCacheXmlFileToDirectory(String classpathResource, File serverWorkingDirectory) throws IOException { + FileCopyUtils.copy(new ClassPathResource(classpathResource).getInputStream(), new FileOutputStream(new File(serverWorkingDirectory, "cache.xml"))); } @@ -121,7 +124,7 @@ public class GemFireDataSourceUsingNonSpringConfiguredGemFireServerIntegrationTe String[] classpathElements = ProcessExecutor.JAVA_CLASSPATH.split(File.pathSeparator); - List customClasspath = new ArrayList(classpathElements.length); + List customClasspath = new ArrayList<>(classpathElements.length); for (String classpathElement : classpathElements) { if (!classpathElement.contains("spring-data-gemfire")) { @@ -132,12 +135,14 @@ public class GemFireDataSourceUsingNonSpringConfiguredGemFireServerIntegrationTe return StringUtils.collectionToDelimitedString(customClasspath, File.pathSeparator); } - private static void waitForProcessStart(final long milliseconds, final ProcessWrapper process, final String processControlFilename) { + private static void waitForProcessStart(long milliseconds, ProcessWrapper process, String processControlFilename) { ThreadUtils.timedWait(milliseconds, TimeUnit.MILLISECONDS.toMillis(500), new ThreadUtils.WaitCondition() { + private File processControlFile = new File(process.getWorkingDirectory(), processControlFilename); - @Override public boolean waiting() { + @Override + public boolean waiting() { return !processControlFile.isFile(); } }); @@ -148,7 +153,7 @@ public class GemFireDataSourceUsingNonSpringConfiguredGemFireServerIntegrationTe gemfireServer.shutdown(); - if (Boolean.valueOf(System.getProperty("spring.gemfire.fork.clean", Boolean.TRUE.toString()))) { + if (Boolean.valueOf(System.getProperty("spring.gemfire.fork.clean", String.valueOf(true)))) { org.springframework.util.FileSystemUtils.deleteRecursively(gemfireServer.getWorkingDirectory()); } } diff --git a/src/test/java/org/springframework/data/gemfire/fork/GemFireBasedServerProcess.java b/src/test/java/org/springframework/data/gemfire/fork/GemFireBasedServerProcess.java index 3b24a6e9..51ba94ae 100644 --- a/src/test/java/org/springframework/data/gemfire/fork/GemFireBasedServerProcess.java +++ b/src/test/java/org/springframework/data/gemfire/fork/GemFireBasedServerProcess.java @@ -34,11 +34,12 @@ import org.springframework.data.gemfire.test.support.FileSystemUtils; public class GemFireBasedServerProcess { private static final String GEMFIRE_HTTP_SERVICE_PORT = "0"; - private static final String GEMFIRE_LOG_LEVEL = "warning"; + private static final String GEMFIRE_LOG_LEVEL = "error"; private static final String GEMIRE_NAME = "SpringDataGemFireServer"; private static final String GEMFIRE_USE_CLUSTER_CONFIGURATION = "false"; public static void main(String[] args) throws Throwable { + runServer(args); registerShutdownHook(); @@ -50,6 +51,7 @@ public class GemFireBasedServerProcess { } private static ServerLauncher runServer(String[] args) { + ServerLauncher serverLauncher = buildServerLauncher(args); // start the GemFire Server process... @@ -59,6 +61,7 @@ public class GemFireBasedServerProcess { } private static ServerLauncher buildServerLauncher(String[] args) { + return new ServerLauncher.Builder(args) .setMemberName(getProperty("gemfire.name", GEMIRE_NAME)) .setCommand(ServerLauncher.Command.START) @@ -80,7 +83,9 @@ public class GemFireBasedServerProcess { } private static void registerShutdownHook() { + Runtime.getRuntime().addShutdownHook(new Thread(() -> { + ServerLauncher serverLauncher = ServerLauncher.getInstance(); if (serverLauncher != null) { 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 eac46dd1..42bf8566 100644 --- a/src/test/java/org/springframework/data/gemfire/process/ProcessWrapper.java +++ b/src/test/java/org/springframework/data/gemfire/process/ProcessWrapper.java @@ -58,7 +58,7 @@ public class ProcessWrapper { protected static final boolean DEFAULT_DAEMON_THREAD = true; - protected static final long DEFAULT_WAIT_TIME_MILLISECONDS = TimeUnit.SECONDS.toMillis(15); + protected static final long DEFAULT_WAIT_TIME_MILLISECONDS = TimeUnit.SECONDS.toMillis(5); private final List listeners = new CopyOnWriteArrayList<>(); @@ -67,8 +67,8 @@ public class ProcessWrapper { private final Process process; private final ProcessConfiguration processConfiguration; - /* (non-Javadoc) */ public ProcessWrapper(Process process, ProcessConfiguration processConfiguration) { + Assert.notNull(process, "Process must not be null"); Assert.notNull(processConfiguration, "The context and configuration meta-data providing details" @@ -81,8 +81,8 @@ public class ProcessWrapper { init(); } - /* (non-Javadoc) */ private void init() { + newThread("Process OUT Stream Reader Thread", newProcessInputStreamReaderRunnable(process.getInputStream())).start(); @@ -92,9 +92,10 @@ public class ProcessWrapper { } } - /* (non-Javadoc) */ protected Runnable newProcessInputStreamReaderRunnable(InputStream in) { + return () -> { + if (isRunning()) { BufferedReader inputReader = new BufferedReader(new InputStreamReader(in)); @@ -116,8 +117,8 @@ public class ProcessWrapper { }; } - /* (non-Javadoc) */ protected Thread newThread(String name, Runnable task) { + Assert.hasText(name, "Thread name must be specified"); Assert.notNull(task, "Thread task must not be null"); @@ -129,38 +130,32 @@ public class ProcessWrapper { return thread; } - /* (non-Javadoc) */ public boolean isAlive() { return ProcessUtils.isAlive(process); } - /* (non-Javadoc) */ public boolean isNotAlive() { return !isAlive(); } - /* (non-Javadoc) */ public List getCommand() { return processConfiguration.getCommand(); } - /* (non-Javadoc) */ public String getCommandString() { return processConfiguration.getCommandString(); } - /* (non-Javadoc) */ public Map getEnvironment() { return processConfiguration.getEnvironment(); } - /* (non-Javadoc) */ public int getPid() { return ProcessUtils.findAndReadPid(getWorkingDirectory()); } - /* (non-Javadoc) */ public int safeGetPid() { + try { return getPid(); } @@ -169,33 +164,28 @@ public class ProcessWrapper { } } - /* (non-Javadoc) */ public boolean isRedirectingErrorStream() { return processConfiguration.isRedirectingErrorStream(); } - /* (non-Javadoc) */ public boolean isNotRunning() { return !isRunning(); } - /* (non-Javadoc) */ public boolean isRunning() { return ProcessUtils.isRunning(process); } - /* (non-Javadoc) */ public File getWorkingDirectory() { return processConfiguration.getWorkingDirectory(); } - /* (non-Javadoc) */ public int exitValue() { return process.exitValue(); } - /* (non-Javadoc) */ public int safeExitValue() { + try { return exitValue(); } @@ -204,10 +194,10 @@ public class ProcessWrapper { } } - /* (non-Javadoc) */ public String readLogFile() throws IOException { + File[] logFiles = FileSystemUtils.listFiles(getWorkingDirectory(), - (path) -> (path != null && (path.isDirectory() || path.getAbsolutePath().endsWith(".log")))); + (path) -> path != null && (path.isDirectory() || path.getAbsolutePath().endsWith(".log"))); if (logFiles.length > 0) { return readLogFile(logFiles[0]); @@ -219,63 +209,63 @@ public class ProcessWrapper { } } - /* (non-Javadoc) */ public String readLogFile(File log) throws IOException { return FileUtils.read(log); } - /* (non-Javadoc) */ public boolean register(ProcessInputStreamListener listener) { return (listener != null && listeners.add(listener)); } - /* (non-Javadoc) */ public void registerShutdownHook() { Runtime.getRuntime().addShutdownHook(new Thread(this::shutdown)); } - /* (non-Javadoc) */ public void signal() { + try { OutputStream outputStream = process.getOutputStream(); outputStream.write("\n".getBytes()); outputStream.flush(); } - catch (IOException e) { + catch (IOException cause) { + log.warning("Failed to signal process"); if (log.isLoggable(Level.FINE)) { - log.fine(ThrowableUtils.toString(e)); + log.fine(ThrowableUtils.toString(cause)); } } } - /* (non-Javadoc) */ public void signalStop() { + try { ProcessUtils.signalStop(process); } - catch (IOException e) { + catch (IOException cause) { + log.warning("Failed to signal the process to stop"); if (log.isLoggable(Level.FINE)) { - log.fine(ThrowableUtils.toString(e)); + log.fine(ThrowableUtils.toString(cause)); } } } - /* (non-Javadoc) */ public int stop() { return stop(DEFAULT_WAIT_TIME_MILLISECONDS); } - /* (non-Javadoc) */ public int stop(long milliseconds) { + if (isRunning()) { + boolean interrupted = false; int exitValue = -1; int pid = safeGetPid(); - long timeout = (System.currentTimeMillis() + milliseconds); + long timeout = System.currentTimeMillis() + milliseconds; + AtomicBoolean exited = new AtomicBoolean(false); ExecutorService executorService = Executors.newSingleThreadExecutor(); @@ -307,6 +297,7 @@ public class ProcessWrapper { // handles CancellationException, ExecutionException } finally { + executorService.shutdownNow(); if (interrupted) { @@ -321,8 +312,8 @@ public class ProcessWrapper { } } - /* (non-Javadoc) */ public int shutdown() { + if (isRunning()) { log.info(String.format("Stopping process [%d]...%n", safeGetPid())); signalStop(); @@ -332,17 +323,14 @@ public class ProcessWrapper { return stop(); } - /* (non-Javadoc) */ public boolean unregister(ProcessInputStreamListener listener) { return listeners.remove(listener); } - /* (non-Javadoc) */ public void waitFor() { waitFor(DEFAULT_WAIT_TIME_MILLISECONDS); } - /* (non-Javadoc) */ public void waitFor(long milliseconds) { ThreadUtils.timedWait(milliseconds, 500, this::isRunning); } diff --git a/src/test/java/org/springframework/data/gemfire/process/support/ProcessUtils.java b/src/test/java/org/springframework/data/gemfire/process/support/ProcessUtils.java index 1bd49414..12c2c830 100644 --- a/src/test/java/org/springframework/data/gemfire/process/support/ProcessUtils.java +++ b/src/test/java/org/springframework/data/gemfire/process/support/ProcessUtils.java @@ -51,7 +51,6 @@ public abstract class ProcessUtils { protected static final String TERM_TOKEN = ""; - /* (non-Javadoc) */ public static int currentPid() { RuntimeMXBean runtimeMXBean = ManagementFactory.getRuntimeMXBean(); String runtimeMXBeanName = runtimeMXBean.getName(); @@ -75,13 +74,12 @@ public abstract class ProcessUtils { cause); } - /* (non-Javadoc) */ public static boolean isAlive(Process process) { - return (process != null && process.isAlive()); + return process != null && process.isAlive(); } - /* (non-Javadoc) */ public static boolean isRunning(int processId) { + /* for (VirtualMachineDescriptor vmDescriptor : VirtualMachine.list()) { if (String.valueOf(processId).equals(vmDescriptor.id())) { @@ -95,8 +93,8 @@ public abstract class ProcessUtils { throw new UnsupportedOperationException("operation not supported"); } - /* (non-Javadoc) */ public static boolean isRunning(Process process) { + try { process.exitValue(); return false; @@ -106,8 +104,8 @@ public abstract class ProcessUtils { } } - /* (non-Javadoc) */ public static void signalStop(Process process) throws IOException { + if (isRunning(process)) { OutputStream processOutputStream = process.getOutputStream(); processOutputStream.write(TERM_TOKEN.concat("\n").getBytes()); @@ -115,14 +113,12 @@ public abstract class ProcessUtils { } } - /* (non-Javadoc) */ @SuppressWarnings("all") public static void waitForStopSignal() { Scanner in = new Scanner(System.in); while (!TERM_TOKEN.equals(in.next())); } - /* (non-Javadoc) */ public static int findAndReadPid(File workingDirectory) { File pidFile = findPidFile(workingDirectory); @@ -135,9 +131,9 @@ public abstract class ProcessUtils { return readPid(pidFile); } - /* (non-Javadoc) */ @SuppressWarnings("all") protected static File findPidFile(File workingDirectory) { + Assert.isTrue(FileSystemUtils.isDirectory(workingDirectory), String.format( "File [%s] is not a valid directory", workingDirectory)); @@ -154,9 +150,9 @@ public abstract class ProcessUtils { return null; } - /* (non-Javadoc) */ @SuppressWarnings("all") public static int readPid(File pidFile) { + Assert.isTrue(pidFile != null && pidFile.isFile(), String.format( "File [%s] is not a valid file", pidFile)); @@ -184,9 +180,9 @@ public abstract class ProcessUtils { } } - /* (non-Javadoc) */ @SuppressWarnings("all") public static void writePid(File pidFile, int pid) throws IOException { + Assert.isTrue(pidFile != null && (pidFile.isFile() || pidFile.createNewFile()), String.format( "File [%s] is not a valid file", pidFile)); @@ -203,7 +199,6 @@ public abstract class ProcessUtils { } } - /* (non-Javadoc) */ protected static class DirectoryPidFileFilter extends PidFileFilter { protected static final DirectoryPidFileFilter INSTANCE = new DirectoryPidFileFilter(); @@ -213,11 +208,10 @@ public abstract class ProcessUtils { */ @Override public boolean accept(File path) { - return (path != null && (path.isDirectory() || super.accept(path))); + return path != null && (path.isDirectory() || super.accept(path)); } } - /* (non-Javadoc) */ protected static class PidFileFilter implements FileFilter { protected static final PidFileFilter INSTANCE = new PidFileFilter(); @@ -227,7 +221,7 @@ public abstract class ProcessUtils { */ @Override public boolean accept(File path) { - return (path != null && path.isFile() && path.getName().toLowerCase().endsWith(".pid")); + return path != null && path.isFile() && path.getName().toLowerCase().endsWith(".pid"); } } } diff --git a/src/test/java/org/springframework/data/gemfire/test/support/ThreadUtils.java b/src/test/java/org/springframework/data/gemfire/test/support/ThreadUtils.java index decdf9b5..0e68a273 100644 --- a/src/test/java/org/springframework/data/gemfire/test/support/ThreadUtils.java +++ b/src/test/java/org/springframework/data/gemfire/test/support/ThreadUtils.java @@ -28,7 +28,6 @@ import java.util.concurrent.TimeUnit; @SuppressWarnings("unused") public abstract class ThreadUtils { - /* (non-Javadoc) */ public static boolean sleep(long milliseconds) { try { Thread.sleep(milliseconds); @@ -54,18 +53,19 @@ public abstract class ThreadUtils { @SuppressWarnings("all") public static boolean timedWait(long duration, long interval, WaitCondition waitCondition) { - final long timeout = (System.currentTimeMillis() + duration); + + final long timeout = System.currentTimeMillis() + duration; interval = Math.min(interval, duration); try { - while (waitCondition.waiting() && (System.currentTimeMillis() < timeout)) { + while (waitCondition.waiting() && System.currentTimeMillis() < timeout) { synchronized (waitCondition) { TimeUnit.MILLISECONDS.timedWait(waitCondition, interval); } } } - catch (InterruptedException e) { + catch (InterruptedException cause) { Thread.currentThread().interrupt(); } diff --git a/src/test/resources/java-util-logging.properties b/src/test/resources/java-util-logging.properties index 97056764..011b9cb4 100644 --- a/src/test/resources/java-util-logging.properties +++ b/src/test/resources/java-util-logging.properties @@ -1,4 +1,9 @@ # java.util.logging (JUL) configuration +java.util.logging.MemoryHandler.level=OFF +java.util.logging.MemoryHandler.size=1 + org.apache=ERROR org.springframework=ERROR +org.springframework.data.gemfire.support.SpringContextBootstrappingInitializer=OFF +org.springframework.data.gemfire.support.SpringContextBootstrappingInitializer.handlers=java.util.logging.MemoryHandler diff --git a/src/test/resources/log4j2-test.xml b/src/test/resources/log4j2-test.xml index 3a1dd86e..2463dda8 100644 --- a/src/test/resources/log4j2-test.xml +++ b/src/test/resources/log4j2-test.xml @@ -6,11 +6,14 @@ + - + + + diff --git a/src/test/resources/logback.xml b/src/test/resources/logback.xml index 098263de..6581b16f 100644 --- a/src/test/resources/logback.xml +++ b/src/test/resources/logback.xml @@ -9,6 +9,8 @@ + + TEST - %m%n @@ -23,6 +25,10 @@ + + + +