// This test case has historical not fail consistently so
// execute it 10 times
for (int i = 0; i < 10; i++) {
File dir = Files.createTempDir();
final Repository repo = Repository.create(REPO_CONF, dir);
GenericCommand cmd = new GenericCommand(repo, "javahg-hang");
Thread executioner = new Thread() {
/**
* Sleep 1/2 seconds to allow cmd to exit normally if
* the 'javahg-hang' doesn't make it hang and then
* kill server process
*/
@Override
public void run() {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
throw Utils.asRuntime(e);
}
getFirstServer(repo).getProcess().destroy();
}
};
executioner.start();
try {
cmd.execute();
assertFailedExecution(cmd);
} catch (UnexpectedServerTerminationException e) {
// When process is kill we get an IOException with
// Stream closed, it is a
// BlockInputStream.InvalidStreamException exception
Throwable cause = e.getCause();
if (cause instanceof IOException) {
String msg = ((IOException) cause).getMessage();
Assert.assertTrue(
"Unexpected message. Got \"" + msg + "\"",
msg.equals("Bad file descriptor")
|| msg.equals("Stream Closed")
|| msg.equals("Stream closed"));
} else {
Assert.assertEquals(BlockInputStream.InvalidStreamException.class, cause.getClass());
}
} catch (ExecutionException e) {
// System.err.println("Got 'killed!' on 'e' channel");
Assert.assertEquals("killed!", e.getMessage());
}
// TODO There seems to be some kind of race condition.
// Sometimes an UnexpectedServerTerminationException is
// thrown, and sometimes an ExecutionException
// Analysis so far: Mercurial server process writes
// 'killed!' when the process is destroyed, sometimes it
// writes it to
// the actual stderr stream (typically case, gives
// UnexpectedServerTerminationException), and
// sometimes to the 'e'
// channel (rare case, gives ExecutionException).
//
// TODO also try to access the server on stdout and stdin
repo.close();
deleteTempDir(dir);
}
}