package org.jenkinsci.plugins.unity3d.io;
import hudson.Launcher;
import hudson.remoting.Callable;
import hudson.remoting.Future;
import hudson.remoting.VirtualChannel;
import hudson.slaves.DumbSlave;
import hudson.util.StreamCopyThread;
import hudson.util.StreamTaskListener;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.Serializable;
import java.nio.charset.Charset;
import java.util.concurrent.ExecutionException;
import org.jvnet.hudson.test.HudsonTestCase;
/**
* This test was written to find a solution to the piping issue.
* The Pipe class in Jenkins 1.446 doesn't work properly with asyncCall if the master and slave are on the same machine.
*
* See ProcTest in Jenkins for similar tests.
*
* @author Jerome Lacoste
*/
public class PipeTest extends HudsonTestCase implements Serializable {
private VirtualChannel createSlaveChannel() throws Exception {
DumbSlave s = createSlave();
s.toComputer().connect(false).get();
VirtualChannel ch=null;
while (ch==null) {
ch = s.toComputer().getChannel();
Thread.sleep(100);
}
return ch;
}
public void testPipingFromRemoteWithLocalLaunch() throws Exception {
doPipingFromRemoteTest(new Launcher.LocalLauncher(
new StreamTaskListener(System.out, Charset.defaultCharset())));
}
private static boolean isRunningOnWindows() {
return System.getProperty("os.name").toLowerCase().startsWith("windows");
}
public void testPipingFromRemoteWithRemoteLaunch() throws Exception {
// Windows cant delete open log files, so ignore this test because of
// java.io.IOException: Unable to delete <templogfile>...
if (isRunningOnWindows())
return;
doPipingFromRemoteTest(new Launcher.RemoteLauncher(
new StreamTaskListener(System.out, Charset.defaultCharset()),
createSlaveChannel(), true));
}
private void doPipingFromRemoteTest(Launcher l) throws IOException, InterruptedException, ExecutionException {
Pipe pipe = Pipe.createRemoteToLocal(l);
Future<String> piping = l.getChannel().callAsync(new PipingCallable(pipe.getOut()));
ByteArrayOutputStream os = new ByteArrayOutputStream();
Thread t = new StreamCopyThread("Test", pipe.getIn(), os);
t.start();
assertEquals("DONE", piping.get());
t.join();
assertEquals("Hello", os.toString());
}
private static class PipingCallable implements Callable<String, Throwable>, Serializable {
private final OutputStream out;
public PipingCallable(OutputStream out) {
this.out = out;
}
public String call() throws Throwable {
if (out == null) {
throw new IllegalStateException("null output");
}
out.write("Hello".getBytes());
out.close();
return "DONE";
}
}
}