/*
* Copyright (c) 2013-2017 Cinchapi Inc.
*
* 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 com.cinchapi.concourse.server.io.process;
import java.io.IOException;
import java.io.InputStream;
import java.util.concurrent.atomic.AtomicBoolean;
import org.junit.Assert;
import org.junit.Ignore;
import org.junit.Test;
import spark.utils.IOUtils;
import com.cinchapi.concourse.test.ConcourseBaseTest;
import com.cinchapi.concourse.util.Commands;
import com.cinchapi.concourse.util.TestData;
/**
* Unit tests for {@link JavaApp}.
*
* @author Jeff Nelson
*/
public class JavaAppTest extends ConcourseBaseTest {
/**
* The expected out for the {@link #GOOD_SOURCE}.
*/
private static final String EXPECTED_OUTPUT = TestData.getString();
/**
* Source code that should compile and run correctly.
*/
private static final String GOOD_SOURCE = ""
// @formatter:off
+ "public class GoodSource {"
+ " public static void main(String... args) {"
+ " System.out.println(\"" + EXPECTED_OUTPUT + "\");"
+ " }"
+ "}";
// @formatter:on
/**
* Source code that does not compile.
*/
private static final String BAD_SOURCE = ""
// @formatter:off
+ "public class GoodSource {"
+ " public static void main(String... args) {"
+ " Systems.out.println(\"" + EXPECTED_OUTPUT + "\");"
+ " }"
+ "}";
// @formatter:on
@Test
public void testGoodSource() throws InterruptedException, IOException {
JavaApp app = new JavaApp(GOOD_SOURCE);
app.run();
app.waitFor();
Assert.assertEquals(0, app.exitValue());
Assert.assertEquals(EXPECTED_OUTPUT,
IOUtils.toString(app.getInputStream()).trim());
}
@Test(expected = Exception.class)
public void testBadSource() {
JavaApp app = new JavaApp(BAD_SOURCE);
try {
app.compile();
}
catch (Exception e) {
System.out.println("[INFO] You can ignore the error message above");
throw e;
}
}
@Test
@Ignore
public void testPrematureShutdownHandler() {
// See if 'jps' is available
try {
Commands.jps();
}
catch (Exception e) {
Assert.assertTrue(true);
}
int interval = JavaApp.PREMATURE_SHUTDOWN_CHECK_INTERVAL_IN_MILLIS;
try {
JavaApp.PREMATURE_SHUTDOWN_CHECK_INTERVAL_IN_MILLIS = 100;
final AtomicBoolean passed = new AtomicBoolean(false);
final AtomicBoolean ranHook = new AtomicBoolean(false);
JavaApp app = new JavaApp("public class GoodSource {"
+ "public static void main(String... args){"
+ "while(true){continue;}" + "}" + "}");
app.onPrematureShutdown(new PrematureShutdownHandler() {
@Override
public void run(InputStream out, InputStream err) {
passed.set(true);
ranHook.set(true);
}
});
app.run();
String procs = Commands.jps();
String parts[] = procs.split(System.lineSeparator());
String pid = "";
while (pid.isEmpty()) {
for (String part : parts) {
if(part.contains("GoodSource")) {
pid = part.split("GoodSource")[0].trim();
break;
}
}
}
Commands.run("kill -9 " + pid);
long start = System.currentTimeMillis();
while (!ranHook.get()) { // wait for the hook to run
if(System.currentTimeMillis()
- start < JavaApp.PREMATURE_SHUTDOWN_CHECK_INTERVAL_IN_MILLIS
+ 100) {
continue;
}
else {
break;
}
}
Assert.assertTrue(passed.get());
}
finally {
JavaApp.PREMATURE_SHUTDOWN_CHECK_INTERVAL_IN_MILLIS = interval;
}
}
}