vibe-core/tests/vibe.core.process.d
2019-08-24 10:19:29 +02:00

220 lines
4.1 KiB
D

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