vibe-core/tests/vibe.core.process.d

207 lines
4.3 KiB
D
Raw Normal View History

/+ 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.array;
import std.range;
import std.algorithm;
void testEcho()
{
foreach (i; 0..100) {
auto procPipes = pipeProcess(["echo", "foo bar"], Redirect.stdout);
assert(!procPipes.process.exited);
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(1.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(2.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()
{
runTask({
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) {
task.join();
}
exitEventLoop();
});
runEventLoop();
}