Add tests from vibe-d:core.
This commit is contained in:
parent
99bc332a81
commit
5a8d5a2fea
27
tests/args.d
Normal file
27
tests/args.d
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
/+ dub.json:
|
||||||
|
{
|
||||||
|
"name": "tests",
|
||||||
|
"description": "Command-line argument test",
|
||||||
|
"dependencies": {
|
||||||
|
"vibe-core": {"path": "../"}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
+/
|
||||||
|
module test;
|
||||||
|
|
||||||
|
import vibe.core.args;
|
||||||
|
import vibe.core.log;
|
||||||
|
|
||||||
|
import std.stdio;
|
||||||
|
|
||||||
|
shared static this()
|
||||||
|
{
|
||||||
|
string argtest;
|
||||||
|
readOption("argtest", &argtest, "Test argument");
|
||||||
|
writeln("argtest=", argtest);
|
||||||
|
}
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
finalizeCommandLineOptions();
|
||||||
|
}
|
10
tests/args.sh
Executable file
10
tests/args.sh
Executable file
|
@ -0,0 +1,10 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
set -e
|
||||||
|
die() { echo "$@" 1>&2 ; exit 1; }
|
||||||
|
|
||||||
|
( dub args.d | grep -q '^argtest=$' ) || die "Fail (no argument)"
|
||||||
|
( dub args.d --argtest=aoeu | grep -q '^argtest=aoeu$' ) || die "Fail (with argument)"
|
||||||
|
( ( ! dub args.d --inexisting 2>&1 ) | grep -qF 'Unrecognized command line option' ) || die "Fail (unknown argument)"
|
||||||
|
|
||||||
|
echo 'OK'
|
107
tests/dirwatcher.d
Normal file
107
tests/dirwatcher.d
Normal file
|
@ -0,0 +1,107 @@
|
||||||
|
/+ dub.json:
|
||||||
|
{
|
||||||
|
"name": "tests",
|
||||||
|
"description": "Test for vibe.d's DirectoryWatcher.",
|
||||||
|
"dependencies": {
|
||||||
|
"vibe-core": {"path": "../"}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
+/
|
||||||
|
import vibe.core.core;
|
||||||
|
import vibe.core.file;
|
||||||
|
import vibe.core.log;
|
||||||
|
import vibe.core.path;
|
||||||
|
import std.algorithm : canFind, all;
|
||||||
|
import std.file, std.process;
|
||||||
|
import std.format : format;
|
||||||
|
import std.conv : to;
|
||||||
|
import std.path : buildPath;
|
||||||
|
import std.typecons : No, Yes;
|
||||||
|
import core.exception : AssertError;
|
||||||
|
import core.time : msecs, seconds;
|
||||||
|
|
||||||
|
void runTest()
|
||||||
|
{
|
||||||
|
auto dir = buildPath(tempDir, format("dirwatcher_test_%d", thisProcessID()));
|
||||||
|
mkdir(dir);
|
||||||
|
scope(exit) rmdirRecurse(dir);
|
||||||
|
|
||||||
|
DirectoryWatcher watcher;
|
||||||
|
try watcher = Path(dir).watchDirectory(No.recursive);
|
||||||
|
catch (AssertError e) {
|
||||||
|
logInfo("DirectoryWatcher not yet implemented. Skipping test.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
DirectoryChange[] changes;
|
||||||
|
assert(!watcher.readChanges(changes, 500.msecs));
|
||||||
|
|
||||||
|
auto foo = dir.buildPath("foo");
|
||||||
|
|
||||||
|
alias Type = DirectoryChangeType;
|
||||||
|
static DirectoryChange dc(Type t, string p) { return DirectoryChange(t, Path(p)); }
|
||||||
|
void check(DirectoryChange[] expected)
|
||||||
|
{
|
||||||
|
sleep(100.msecs);
|
||||||
|
assert(watcher.readChanges(changes, 100.msecs), "Could not read changes for " ~ expected.to!string);
|
||||||
|
assert(expected.all!((a)=> changes.canFind(a))(), "Change is not what was expected, got: " ~ changes.to!string ~ " but expected: " ~ expected.to!string);
|
||||||
|
assert(!watcher.readChanges(changes, 0.msecs), "Changes were returned when they shouldn't have, for " ~ expected.to!string);
|
||||||
|
}
|
||||||
|
|
||||||
|
write(foo, null);
|
||||||
|
check([dc(Type.added, foo)]);
|
||||||
|
sleep(1.seconds); // OSX has a second resolution on file modification times
|
||||||
|
write(foo, [0, 1]);
|
||||||
|
check([dc(Type.modified, foo)]);
|
||||||
|
remove(foo);
|
||||||
|
check([dc(Type.removed, foo)]);
|
||||||
|
write(foo, null);
|
||||||
|
sleep(1.seconds);
|
||||||
|
write(foo, [0, 1]);
|
||||||
|
sleep(100.msecs);
|
||||||
|
remove(foo);
|
||||||
|
check([dc(Type.added, foo), dc(Type.modified, foo), dc(Type.removed, foo)]);
|
||||||
|
|
||||||
|
auto subdir = dir.buildPath("subdir");
|
||||||
|
mkdir(subdir);
|
||||||
|
check([dc(Type.added, subdir)]);
|
||||||
|
auto bar = subdir.buildPath("bar");
|
||||||
|
write(bar, null);
|
||||||
|
assert(!watcher.readChanges(changes, 100.msecs));
|
||||||
|
remove(bar);
|
||||||
|
watcher = Path(dir).watchDirectory(Yes.recursive);
|
||||||
|
write(foo, null);
|
||||||
|
sleep(1.seconds);
|
||||||
|
write(foo, [0, 1]);
|
||||||
|
sleep(100.msecs);
|
||||||
|
remove(foo);
|
||||||
|
|
||||||
|
write(bar, null);
|
||||||
|
sleep(1.seconds);
|
||||||
|
write(bar, [0, 1]);
|
||||||
|
sleep(100.msecs);
|
||||||
|
remove(bar);
|
||||||
|
check([dc(Type.added, foo), dc(Type.modified, foo), dc(Type.removed, foo),
|
||||||
|
dc(Type.added, bar), dc(Type.modified, bar), dc(Type.removed, bar)]);
|
||||||
|
|
||||||
|
write(foo, null);
|
||||||
|
sleep(100.msecs);
|
||||||
|
rename(foo, bar);
|
||||||
|
sleep(100.msecs);
|
||||||
|
remove(bar);
|
||||||
|
check([dc(Type.added, foo), dc(Type.removed, foo), dc(Type.added, bar), dc(Type.removed, bar)]);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
runTask({
|
||||||
|
try runTest();
|
||||||
|
catch (Throwable th) {
|
||||||
|
logError("Test failed: %s", th.toString());
|
||||||
|
ret = 1;
|
||||||
|
} finally exitEventLoop(true);
|
||||||
|
});
|
||||||
|
runEventLoop();
|
||||||
|
return ret;
|
||||||
|
}
|
58
tests/vibe.core.concurrency.1408.d
Normal file
58
tests/vibe.core.concurrency.1408.d
Normal file
|
@ -0,0 +1,58 @@
|
||||||
|
/+ dub.sdl:
|
||||||
|
name "tests"
|
||||||
|
description "std.concurrency integration issue"
|
||||||
|
dependency "vibe-core" path="../"
|
||||||
|
versions "VibeDefaultMain"
|
||||||
|
+/
|
||||||
|
module test;
|
||||||
|
|
||||||
|
import vibe.core.concurrency;
|
||||||
|
import vibe.core.core;
|
||||||
|
import vibe.core.log;
|
||||||
|
import core.time : msecs;
|
||||||
|
import std.functional : toDelegate;
|
||||||
|
|
||||||
|
void test()
|
||||||
|
{
|
||||||
|
auto t = runTask({
|
||||||
|
bool gotit;
|
||||||
|
receive((int i) { assert(i == 10); gotit = true; });
|
||||||
|
assert(gotit);
|
||||||
|
sleep(10.msecs);
|
||||||
|
});
|
||||||
|
|
||||||
|
t.tid.send(10);
|
||||||
|
t.tid.send(11); // never received
|
||||||
|
t.join();
|
||||||
|
|
||||||
|
// ensure that recycled fibers will get a clean message queue
|
||||||
|
auto t2 = runTask({
|
||||||
|
bool gotit;
|
||||||
|
receive((int i) { assert(i == 12); gotit = true; });
|
||||||
|
assert(gotit);
|
||||||
|
});
|
||||||
|
t2.tid.send(12);
|
||||||
|
t2.join();
|
||||||
|
|
||||||
|
// test worker tasks
|
||||||
|
auto t3 = runWorkerTaskH({
|
||||||
|
bool gotit;
|
||||||
|
receive((int i) { assert(i == 13); gotit = true; });
|
||||||
|
assert(gotit);
|
||||||
|
});
|
||||||
|
|
||||||
|
t3.tid.send(13);
|
||||||
|
sleep(10.msecs);
|
||||||
|
|
||||||
|
logInfo("Success.");
|
||||||
|
|
||||||
|
exitEventLoop(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
shared static this()
|
||||||
|
{
|
||||||
|
setLogFormat(FileLogger.Format.threadTime, FileLogger.Format.threadTime);
|
||||||
|
runTask(toDelegate(&test));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
59
tests/vibe.core.core.1590.d
Normal file
59
tests/vibe.core.core.1590.d
Normal file
|
@ -0,0 +1,59 @@
|
||||||
|
/+ dub.sdl:
|
||||||
|
name "tests"
|
||||||
|
description "Semaphore hang"
|
||||||
|
dependency "vibe-core" path="../"
|
||||||
|
+/
|
||||||
|
module test;
|
||||||
|
import std.stdio;
|
||||||
|
import std.socket;
|
||||||
|
import std.datetime;
|
||||||
|
import std.functional;
|
||||||
|
import core.time;
|
||||||
|
import vibe.core.core;
|
||||||
|
import vibe.core.log;
|
||||||
|
import vibe.core.concurrency;
|
||||||
|
import vibe.core.connectionpool;
|
||||||
|
|
||||||
|
class Conn {}
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
runTask({
|
||||||
|
// create pool with 2 max connections
|
||||||
|
bool[int] results;
|
||||||
|
auto pool = new ConnectionPool!Conn({ return new Conn; }, 2);
|
||||||
|
auto task = Task.getThis(); // main task
|
||||||
|
void worker(int id) {
|
||||||
|
{
|
||||||
|
auto conn = pool.lockConnection(); // <-- worker(4) hangs here
|
||||||
|
sleep(1.msecs); // <-- important, without sleep everything works fine
|
||||||
|
}
|
||||||
|
task.send(id); // send signal to the main task
|
||||||
|
}
|
||||||
|
// run 4 tasks (2 * pool max connections)
|
||||||
|
runTask(&worker, 1);
|
||||||
|
runTask(&worker, 2);
|
||||||
|
runTask(&worker, 3);
|
||||||
|
runTask(&worker, 4);
|
||||||
|
|
||||||
|
// wait for first signal and run one more task
|
||||||
|
results[receiveOnly!int] = true;
|
||||||
|
runTask(&worker, 5);
|
||||||
|
|
||||||
|
// wait for other signals
|
||||||
|
results[receiveOnly!int] = true;
|
||||||
|
results[receiveOnly!int] = true;
|
||||||
|
results[receiveOnly!int] = true;
|
||||||
|
results[receiveOnly!int] = true;
|
||||||
|
|
||||||
|
foreach (r; results.byKey)
|
||||||
|
assert(r >= 1 && r <= 5);
|
||||||
|
|
||||||
|
exitEventLoop();
|
||||||
|
});
|
||||||
|
|
||||||
|
setTimer(1.seconds, { assert(false, "Test has hung."); });
|
||||||
|
|
||||||
|
runEventLoop();
|
||||||
|
}
|
||||||
|
|
51
tests/vibe.core.core.refcount.d
Normal file
51
tests/vibe.core.core.refcount.d
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
/+ dub.sdl:
|
||||||
|
name "tests"
|
||||||
|
description "Invalid ref count after runTask"
|
||||||
|
dependency "vibe-core" path="../"
|
||||||
|
+/
|
||||||
|
module test;
|
||||||
|
import vibe.core.core;
|
||||||
|
import std.stdio;
|
||||||
|
|
||||||
|
struct RC {
|
||||||
|
int* rc;
|
||||||
|
this(int* rc) { this.rc = rc; }
|
||||||
|
this(this) {
|
||||||
|
if (rc) {
|
||||||
|
(*rc)++;
|
||||||
|
writefln("addref %s", *rc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
~this() {
|
||||||
|
if (rc) {
|
||||||
|
(*rc)--;
|
||||||
|
writefln("release %s", *rc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
int rc = 1;
|
||||||
|
bool done = false;
|
||||||
|
|
||||||
|
{
|
||||||
|
auto s = RC(&rc);
|
||||||
|
assert(rc == 1);
|
||||||
|
runTask((RC st) {
|
||||||
|
assert(rc == 2);
|
||||||
|
st = RC.init;
|
||||||
|
assert(rc == 1);
|
||||||
|
exitEventLoop();
|
||||||
|
done = true;
|
||||||
|
}, s);
|
||||||
|
assert(rc == 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(rc == 1);
|
||||||
|
|
||||||
|
runEventLoop();
|
||||||
|
|
||||||
|
assert(rc == 0);
|
||||||
|
assert(done);
|
||||||
|
}
|
42
tests/vibe.core.net.1376.d
Normal file
42
tests/vibe.core.net.1376.d
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
/+ dub.sdl:
|
||||||
|
name "tests"
|
||||||
|
description "TCP disconnect task issue"
|
||||||
|
dependency "vibe-core" path="../"
|
||||||
|
versions "VibeDefaultMain"
|
||||||
|
+/
|
||||||
|
module test;
|
||||||
|
|
||||||
|
import vibe.core.core;
|
||||||
|
import vibe.core.net;
|
||||||
|
import core.time : msecs;
|
||||||
|
|
||||||
|
shared static this()
|
||||||
|
{
|
||||||
|
listenTCP(11375,(conn){
|
||||||
|
auto td = runTask!TCPConnection((conn) {
|
||||||
|
ubyte [3] buf;
|
||||||
|
try {
|
||||||
|
conn.read(buf);
|
||||||
|
assert(false, "Expected read() to throw an exception.");
|
||||||
|
} catch (Exception) {} // expected
|
||||||
|
}, conn);
|
||||||
|
sleep(10.msecs);
|
||||||
|
conn.close();
|
||||||
|
});
|
||||||
|
|
||||||
|
runTask({
|
||||||
|
try {
|
||||||
|
auto conn = connectTCP("127.0.0.1", 11375);
|
||||||
|
conn.write("a");
|
||||||
|
conn.close();
|
||||||
|
} catch (Exception e) assert(false, e.msg);
|
||||||
|
|
||||||
|
try {
|
||||||
|
auto conn = connectTCP("127.0.0.1", 11375);
|
||||||
|
conn.close();
|
||||||
|
} catch (Exception e) assert(false, e.msg);
|
||||||
|
|
||||||
|
sleep(50.msecs);
|
||||||
|
exitEventLoop();
|
||||||
|
});
|
||||||
|
}
|
Loading…
Reference in a new issue