DATAGEODE-180 - Add null, no-op Appender to JUL, Log4j and Logback logging configuration.

Speed up GemFireDataSourceUsingNonSpringConifguredGemFireServerIntegationTests.

Refactor test framework supporting classes.
This commit is contained in:
John Blum
2019-04-10 20:53:38 -07:00
parent 626076b05e
commit a7d7b430eb
8 changed files with 75 additions and 69 deletions

View File

@@ -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<String> 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<String> customClasspath = new ArrayList<String>(classpathElements.length);
List<String> 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());
}
}

View File

@@ -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) {

View File

@@ -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<ProcessInputStreamListener> 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<String> getCommand() {
return processConfiguration.getCommand();
}
/* (non-Javadoc) */
public String getCommandString() {
return processConfiguration.getCommandString();
}
/* (non-Javadoc) */
public Map<String, String> 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);
}

View File

@@ -51,7 +51,6 @@ public abstract class ProcessUtils {
protected static final String TERM_TOKEN = "<TERM/>";
/* (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");
}
}
}

View File

@@ -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();
}

View File

@@ -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

View File

@@ -6,11 +6,14 @@
<File name="File" fileName="build/logs/spring-test.log">
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{1.} - %msg%n"/>
</File>
<Null name="nop"/>
</Appenders>
<Loggers>
<Logger name="org.apache.geode" level="error"/>
<Logger name="org.springframework" level="error"/>
<Logger name="org.springframework.data.gemfire.support.SpringContextBootstrappingInitializer" level="off"/>
<Logger name="org.springframework.data.gemfire.support.SpringContextBootstrappingInitializer" level="off">
<AppenderRef ref="nop"/>
</Logger>
<Root level="error">
<AppenderRef ref="Console"/>
<!--AppenderRef ref="File" /-->

View File

@@ -9,6 +9,8 @@
</encoder>
</appender>
<appender name="nop" class="ch.qos.logback.core.helpers.NOPAppender"/>
<appender name="testAppender" class="org.springframework.data.gemfire.test.logging.slf4j.logback.TestAppender">
<encoder>
<pattern>TEST - %m%n</pattern>
@@ -23,6 +25,10 @@
<appender-ref ref="testAppender"/>
</logger>
<logger name="org.springframework.data.gemfire.support.SpringContextBootstrappingInitializer" level="off">
<appender-ref ref="nop"/>
</logger>
<root level="${logback.log.level:-ERROR}">
<appender-ref ref="console"/>
</root>