package org.graalvm.launcher.test;
import static java.nio.file.Files.exists;
import static java.nio.file.Files.readAllBytes;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.lang.reflect.Method;
import java.nio.file.Files;
import java.nio.file.Path;
import org.graalvm.launcher.Launcher;
import org.junit.Before;
import org.junit.Test;
public class LauncherTest {
private Path tmpDir;
private Method newLogStreamMethod;
@Before
public void setUp() throws IOException, ReflectiveOperationException {
tmpDir = Files.createTempDirectory(LauncherTest.class.getName()).toAbsolutePath();
Class<Launcher> launcherClass = Launcher.class;
newLogStreamMethod = launcherClass.getDeclaredMethod("newLogStream", Path.class);
newLogStreamMethod.setAccessible(true);
}
@Test
public void testLogFileNames() throws Exception {
Path testLogName = tmpDir.resolve("test.log");
Path testLog1Name = tmpDir.resolve("test.log1");
Path testLogLockName = tmpDir.resolve("test.log.lck");
Path testLog1LockName = tmpDir.resolve("test.log1.lck");
assertFalse(exists(testLogName));
assertFalse(exists(testLog1Name));
assertFalse(exists(testLogLockName));
assertFalse(exists(testLog1LockName));
int writeCounter = 0;
ByteArrayOutputStream outerExpectedContent = new ByteArrayOutputStream();
try (OutputStream out = new ProxyOutputStream(newLogStream(testLogName), outerExpectedContent)) {
assertTrue(exists(testLogName));
assertTrue(exists(testLogLockName));
assertFalse(exists(testLog1Name));
assertFalse(exists(testLog1LockName));
out.write(++writeCounter);
}
assertTrue(exists(testLogName));
assertFalse(exists(testLogLockName));
assertArrayEquals(outerExpectedContent.toByteArray(), readAllBytes(testLogName));
try (OutputStream out = new ProxyOutputStream(newLogStream(testLogName), outerExpectedContent)) {
assertTrue(exists(testLogName));
assertTrue(exists(testLogLockName));
assertFalse(exists(testLog1Name));
assertFalse(exists(testLog1LockName));
out.write(++writeCounter);
}
assertTrue(exists(testLogName));
assertFalse(exists(testLogLockName));
assertArrayEquals(outerExpectedContent.toByteArray(), readAllBytes(testLogName));
ByteArrayOutputStream innerExpectedContent = new ByteArrayOutputStream();
try (OutputStream out = new ProxyOutputStream(newLogStream(testLogName), outerExpectedContent)) {
try (OutputStream outInner = new ProxyOutputStream(newLogStream(testLogName), innerExpectedContent)) {
assertTrue(exists(testLogName));
assertTrue(exists(testLogLockName));
assertTrue(exists(testLog1Name));
assertTrue(exists(testLog1LockName));
outInner.write(++writeCounter);
}
assertTrue(exists(testLogName));
assertTrue(exists(testLogLockName));
assertTrue(exists(testLog1Name));
assertFalse(exists(testLog1LockName));
out.write(++writeCounter);
}
assertTrue(exists(testLogName));
assertFalse(exists(testLogLockName));
assertTrue(exists(testLog1Name));
assertFalse(exists(testLog1LockName));
assertArrayEquals(outerExpectedContent.toByteArray(), readAllBytes(testLogName));
assertArrayEquals(innerExpectedContent.toByteArray(), readAllBytes(testLog1Name));
}
private OutputStream newLogStream(Path logFile) throws ReflectiveOperationException {
return (OutputStream) newLogStreamMethod.invoke(null, logFile);
}
private static final class ProxyOutputStream extends OutputStream {
private OutputStream[] delegates;
ProxyOutputStream(OutputStream... delegates) {
this.delegates = delegates;
}
@Override
public void write(int b) throws IOException {
for (OutputStream out : delegates) {
out.write(b);
}
}
@Override
public void close() throws IOException {
IOException exception = null;
for (OutputStream out : delegates) {
try {
out.close();
} catch (IOException ioe) {
if (exception == null) {
exception = ioe;
} else {
exception.addSuppressed(ioe);
}
}
}
if (exception != null) {
throw exception;
}
}
}
}