diff --git a/tests/vibe.core.process.d b/tests/vibe.core.process.d index d47c9d7..a773b0c 100644 --- a/tests/vibe.core.process.d +++ b/tests/vibe.core.process.d @@ -9,201 +9,213 @@ import core.thread; import vibe.core.log; import vibe.core.core; import vibe.core.process; +import std.algorithm; import std.array; import std.range; -import std.algorithm; void testEcho() { - foreach (i; 0..100) { - auto procPipes = pipeProcess(["echo", "foo bar"], Redirect.stdout); + foreach (i; 0..100) { + 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.exited); + assert(procPipes.process.wait() == 0); + assert(procPipes.process.exited); - assert(output == "foo bar\n"); - } + assert(output == "foo bar\n"); + } } void testCat() { - auto procPipes = pipeProcess(["cat"]); + auto procPipes = pipeProcess(["cat"]); - string output; - auto outputTask = runTask({ - output = procPipes.stdout.collectOutput(); - }); + 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); - } + 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); + procPipes.stdin.close(); + assert(procPipes.process.wait() == 0); - outputTask.join(); + outputTask.join(); - assert(output == inputs.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); + 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); + // Wait for rdmd to compile + sleep(3.seconds); - string output; - auto outputTask = runTask({ - output = procPipes.stderr.collectOutput(); - }); + 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); - } + 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); + procPipes.stdin.close(); + assert(procPipes.process.wait() == 0); - outputTask.join(); + outputTask.join(); - assert(output == inputs.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]); + 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]); + foreach (i; 0..20) { + auto process = spawnProcess(["rdmd", "--eval", program]); - assert(!process.exited); + assert(!process.exited); - sleep(800.msecs); - try { - process.kill(); - } catch (Exception e) {} - process.wait(); + sleep(800.msecs); + try { + process.kill(); + } catch (Exception e) { + } + process.wait(); - assert(process.exited); - } + assert(process.exited); + } } void testIgnoreSigterm() { - auto program = q{ - import core.thread; - import core.sys.posix.signal; + auto program = q{ + import core.thread; + import core.sys.posix.signal; - signal(SIGINT, SIG_IGN); - signal(SIGTERM, SIG_IGN); + signal(SIGINT, SIG_IGN); + signal(SIGTERM, SIG_IGN); - foreach (line; stdin.byLine()) { - writeln(line); - stdout.flush(); - } + 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); + // 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(); - }); + string output; + auto outputTask = runTask({ + output = procPipes.stdout.collectOutput(); + }); - assert(!procPipes.process.exited); + assert(!procPipes.process.exited); - // Give the program some time to compile and install the signal handler - sleep(4.seconds); + // Give the program some time to compile and install the signal handler + sleep(4.seconds); - procPipes.process.kill(); - procPipes.stdin.write("foo\n"); + procPipes.process.kill(); + 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() { - auto res = executeShell("echo foo"); + auto res = executeShell("echo foo"); - assert(res.status == 0); - assert(res.output == "foo\n"); + 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]); + 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"); + assert(res.status == 0); + assert(res.output == "linux\nos9\rwin\r\n"); } void main() { - // rdmd --eval is only supported in versions >= 2.080 - static if (__VERSION__ >= 2080) { - runTask({ - auto tasks = [ - &testEcho, - &testCat, - &testStderr, - &testRandomDeath, - &testIgnoreSigterm, - &testSimpleShell, - &testLineEndings, - ].map!(fn => runTask({ - try { - fn(); - } catch (Exception e) { - logError("%s", e); - throw e; - } - })); + import core.stdc.stdlib : abort; + import core.time; + import std.meta : AliasSeq; - foreach (task; tasks) { - task.join(); - } + // rdmd --eval is only supported in versions >= 2.080 + 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(); + } }