/**
* Copyright (C) 2012-2017 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 ninja.build;
import com.google.code.tempusfugit.temporal.Condition;
import com.google.code.tempusfugit.temporal.Duration;
import com.google.code.tempusfugit.temporal.Timeout;
import static com.google.code.tempusfugit.temporal.WaitFor.waitOrTimeout;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import org.junit.Test;
import org.junit.runner.RunWith;
import static org.junit.Assert.*;
import org.mockito.runners.MockitoJUnitRunner;
import org.zeroturnaround.exec.ProcessResult;
import org.zeroturnaround.exec.StartedProcess;
@RunWith(MockitoJUnitRunner.class)
public class RunClassInSeparateJvmMachineTest {
public List<String> getOurClassPath() throws IOException {
String classpath = System.getProperty("java.class.path");
String[] classpathEntries = classpath.split(File.pathSeparator);
return Arrays.asList(classpathEntries);
}
public Condition fakeDaemonCondition(final ByteArrayOutputStream baos) {
return new Condition() {
@Override
public boolean isSatisfied() {
try {
return baos.toString("UTF-8").trim().equals("Hello, i am a fake daemon");
} catch (UnsupportedEncodingException ex) {
throw new RuntimeException(ex);
}
}
};
}
public boolean isAlive(Process p) {
try {
p.exitValue();
return false;
} catch (Exception e) {
// exception only thrown if process has not yet terminated
return true;
}
}
@Test
public void startProcess() throws Exception {
RunClassInSeparateJvmMachine rcsjm = new RunClassInSeparateJvmMachine (
"FakeDaemon",
FakeDaemonMain.class.getName(),
getOurClassPath(),
Collections.EMPTY_LIST,
new File(".")
);
// override output so we can capture it
final ByteArrayOutputStream baos = new ByteArrayOutputStream();
rcsjm.setOutput(baos);
StartedProcess startedProcess = rcsjm.startProcess();
assertTrue(isAlive(startedProcess.getProcess()));
waitOrTimeout(fakeDaemonCondition(baos), Timeout.timeout(Duration.millis(10000)));
startedProcess.getProcess().destroy();
ProcessResult processResult = startedProcess.getFuture().get();
}
@Test
public void restart() throws Exception {
RunClassInSeparateJvmMachine rcsjm = new RunClassInSeparateJvmMachine (
"FakeDaemon",
FakeDaemonMain.class.getName(),
getOurClassPath(),
Collections.EMPTY_LIST,
new File(".")
);
// override output so we can capture it
final ByteArrayOutputStream baos1 = new ByteArrayOutputStream();
rcsjm.setOutput(baos1);
rcsjm.restart();
StartedProcess startedProcess1 = rcsjm.getActiveProcess();
assertTrue(isAlive(startedProcess1.getProcess()));
waitOrTimeout(fakeDaemonCondition(baos1), Timeout.timeout(Duration.millis(10000)));
// override output so we can capture it
final ByteArrayOutputStream baos2 = new ByteArrayOutputStream();
rcsjm.setOutput(baos2);
rcsjm.restart();
StartedProcess startedProcess2 = rcsjm.getActiveProcess();
assertTrue(isAlive(startedProcess2.getProcess()));
assertFalse(isAlive(startedProcess1.getProcess()));
assertFalse(startedProcess1.equals(startedProcess2));
waitOrTimeout(fakeDaemonCondition(baos2), Timeout.timeout(Duration.millis(10000)));
}
@Test
public void multipleRestartsReallyQuickly() throws Exception {
RunClassInSeparateJvmMachine rcsjm = new RunClassInSeparateJvmMachine (
"FakeDaemon",
FakeDaemonMain.class.getName(),
getOurClassPath(),
Collections.EMPTY_LIST,
new File(".")
);
// override output so we can capture it
final ByteArrayOutputStream baos1 = new ByteArrayOutputStream();
rcsjm.setOutput(baos1);
rcsjm.restart();
StartedProcess startedProcess1 = rcsjm.getActiveProcess();
rcsjm.restart();
StartedProcess startedProcess2 = rcsjm.getActiveProcess();
rcsjm.restart();
StartedProcess startedProcess3 = rcsjm.getActiveProcess();
rcsjm.restart();
StartedProcess startedProcess4 = rcsjm.getActiveProcess();
assertTrue(isAlive(startedProcess4.getProcess()));
assertFalse(isAlive(startedProcess1.getProcess()));
assertFalse(isAlive(startedProcess2.getProcess()));
assertFalse(isAlive(startedProcess3.getProcess()));
assertFalse(startedProcess1.equals(startedProcess2));
}
}