Add watchdog and log output to vibe.core.process test.

This commit is contained in:
Sönke Ludwig 2019-07-05 10:45:07 +02:00
parent c74ce47cc9
commit 3e619560af

View file

@ -9,201 +9,213 @@ import core.thread;
import vibe.core.log; import vibe.core.log;
import vibe.core.core; import vibe.core.core;
import vibe.core.process; import vibe.core.process;
import std.algorithm;
import std.array; import std.array;
import std.range; import std.range;
import std.algorithm;
void testEcho() void testEcho()
{ {
foreach (i; 0..100) { foreach (i; 0..100) {
auto procPipes = pipeProcess(["echo", "foo bar"], Redirect.stdout); auto procPipes = pipeProcess(["echo", "foo bar"], Redirect.stdout);
assert(!procPipes.process.exited); assert(!procPipes.process.exited);
auto output = procPipes.stdout.collectOutput(); auto output = procPipes.stdout.collectOutput();
assert(procPipes.process.wait() == 0); assert(procPipes.process.wait() == 0);
assert(procPipes.process.exited); assert(procPipes.process.exited);
assert(output == "foo bar\n"); assert(output == "foo bar\n");
} }
} }
void testCat() void testCat()
{ {
auto procPipes = pipeProcess(["cat"]); auto procPipes = pipeProcess(["cat"]);
string output; string output;
auto outputTask = runTask({ auto outputTask = runTask({
output = procPipes.stdout.collectOutput(); output = procPipes.stdout.collectOutput();
}); });
auto inputs = ["1", "2", "3", "4", "5", "6", "7", "8", "9", "0"] auto inputs = ["1", "2", "3", "4", "5", "6", "7", "8", "9", "0"]
.map!(s => s ~ "\n") .map!(s => s ~ "\n")
.repeat(4000).join.array; .repeat(4000).join.array;
foreach (input; inputs) { foreach (input; inputs) {
procPipes.stdin.write(input); procPipes.stdin.write(input);
} }
procPipes.stdin.close(); procPipes.stdin.close();
assert(procPipes.process.wait() == 0); assert(procPipes.process.wait() == 0);
outputTask.join(); outputTask.join();
assert(output == inputs.join()); assert(output == inputs.join());
} }
void testStderr() void testStderr()
{ {
auto program = q{ auto program = q{
foreach (line; stdin.byLine()) foreach (line; stdin.byLine())
stderr.writeln(line); stderr.writeln(line);
}; };
auto procPipes = pipeProcess(["rdmd", "--eval", program], Redirect.stdin | Redirect.stderr); auto procPipes = pipeProcess(["rdmd", "--eval", program], Redirect.stdin | Redirect.stderr);
// Wait for rdmd to compile // Wait for rdmd to compile
sleep(3.seconds); sleep(3.seconds);
string output; string output;
auto outputTask = runTask({ auto outputTask = runTask({
output = procPipes.stderr.collectOutput(); output = procPipes.stderr.collectOutput();
}); });
auto inputs = ["1", "2", "3", "4", "5", "6", "7", "8", "9", "0"] auto inputs = ["1", "2", "3", "4", "5", "6", "7", "8", "9", "0"]
.map!(s => s ~ "\n") .map!(s => s ~ "\n")
.repeat(4000).join.array; .repeat(4000).join.array;
foreach (input; inputs) { foreach (input; inputs) {
procPipes.stdin.write(input); procPipes.stdin.write(input);
} }
procPipes.stdin.close(); procPipes.stdin.close();
assert(procPipes.process.wait() == 0); assert(procPipes.process.wait() == 0);
outputTask.join(); outputTask.join();
assert(output == inputs.join); assert(output == inputs.join);
} }
void testRandomDeath() void testRandomDeath()
{ {
auto program = q{ auto program = q{
import core.thread; import core.thread;
import std.random; import std.random;
Thread.sleep(dur!"msecs"(uniform(0, 1000))); Thread.sleep(dur!"msecs"(uniform(0, 1000)));
}; };
// Prime rdmd // Prime rdmd
execute(["rdmd", "--eval", program]); execute(["rdmd", "--eval", program]);
foreach (i; 0..20) { foreach (i; 0..20) {
auto process = spawnProcess(["rdmd", "--eval", program]); auto process = spawnProcess(["rdmd", "--eval", program]);
assert(!process.exited); assert(!process.exited);
sleep(800.msecs); sleep(800.msecs);
try { try {
process.kill(); process.kill();
} catch (Exception e) {} } catch (Exception e) {
process.wait(); }
process.wait();
assert(process.exited); assert(process.exited);
} }
} }
void testIgnoreSigterm() void testIgnoreSigterm()
{ {
auto program = q{ auto program = q{
import core.thread; import core.thread;
import core.sys.posix.signal; import core.sys.posix.signal;
signal(SIGINT, SIG_IGN); signal(SIGINT, SIG_IGN);
signal(SIGTERM, SIG_IGN); signal(SIGTERM, SIG_IGN);
foreach (line; stdin.byLine()) { foreach (line; stdin.byLine()) {
writeln(line); writeln(line);
stdout.flush(); stdout.flush();
} }
// Zombie // Zombie
while (true) Thread.sleep(100.dur!"msecs"); while (true) Thread.sleep(100.dur!"msecs");
}; };
auto procPipes = pipeProcess( auto procPipes = pipeProcess(
["rdmd", "--eval", program], ["rdmd", "--eval", program],
Redirect.stdin | Redirect.stdout | Redirect.stderrToStdout); Redirect.stdin | Redirect.stdout | Redirect.stderrToStdout);
string output; string output;
auto outputTask = runTask({ auto outputTask = runTask({
output = procPipes.stdout.collectOutput(); output = procPipes.stdout.collectOutput();
}); });
assert(!procPipes.process.exited); assert(!procPipes.process.exited);
// Give the program some time to compile and install the signal handler // Give the program some time to compile and install the signal handler
sleep(4.seconds); sleep(4.seconds);
procPipes.process.kill(); procPipes.process.kill();
procPipes.stdin.write("foo\n"); procPipes.stdin.write("foo\n");
assert(!procPipes.process.exited); assert(!procPipes.process.exited);
assert(procPipes.process.waitOrForceKill(2.seconds) == 9); assert(procPipes.process.waitOrForceKill(2.seconds) == 9);
assert(procPipes.process.exited); assert(procPipes.process.exited);
outputTask.join(); outputTask.join();
assert(output == "foo\n"); assert(output == "foo\n");
} }
void testSimpleShell() void testSimpleShell()
{ {
auto res = executeShell("echo foo"); auto res = executeShell("echo foo");
assert(res.status == 0); assert(res.status == 0);
assert(res.output == "foo\n"); assert(res.output == "foo\n");
} }
void testLineEndings() void testLineEndings()
{ {
auto program = q{ auto program = q{
write("linux\n"); write("linux\n");
write("os9\r"); write("os9\r");
write("win\r\n"); write("win\r\n");
}; };
auto res = execute(["rdmd", "--eval", program]); auto res = execute(["rdmd", "--eval", program]);
assert(res.status == 0); assert(res.status == 0);
assert(res.output == "linux\nos9\rwin\r\n"); assert(res.output == "linux\nos9\rwin\r\n");
} }
void main() void main()
{ {
// rdmd --eval is only supported in versions >= 2.080 import core.stdc.stdlib : abort;
static if (__VERSION__ >= 2080) { import core.time;
runTask({ import std.meta : AliasSeq;
auto tasks = [
&testEcho,
&testCat,
&testStderr,
&testRandomDeath,
&testIgnoreSigterm,
&testSimpleShell,
&testLineEndings,
].map!(fn => runTask({
try {
fn();
} catch (Exception e) {
logError("%s", e);
throw e;
}
}));
foreach (task; tasks) { // rdmd --eval is only supported in versions >= 2.080
task.join(); static if (__VERSION__ >= 2080) {
} runTask({
alias Tasks = AliasSeq!(
testEcho,
testCat,
testStderr,
testRandomDeath,
testIgnoreSigterm,
testSimpleShell,
testLineEndings
);
exitEventLoop(); static foreach (alias task; Tasks) {{
}); auto t = runTask({
logInfo("Running test %s...", __traits(identifier, task));
auto tm = setTimer(60.seconds, {
logError("Test %s timed out!", __traits(identifier, task));
abort();
});
try {
task();
} catch (Exception e) {
logError("Test %s failed: %s", __traits(identifier, task), e);
abort();
}
tm.stop();
});
t.join();
}}
runEventLoop(); exitEventLoop();
} });
runEventLoop();
}
} }