Merge branch 'master' of github.com:vibe-d/vibe-core
This commit is contained in:
commit
531398e28d
|
@ -459,11 +459,12 @@ struct FileStream {
|
|||
}
|
||||
|
||||
size_t read(ubyte[] dst, IOMode mode)
|
||||
{
|
||||
{
|
||||
auto res = asyncAwait!(FileIOCallback,
|
||||
cb => eventDriver.files.read(m_fd, ctx.ptr, dst, mode, cb),
|
||||
cb => eventDriver.files.cancelRead(m_fd)
|
||||
);
|
||||
ctx.ptr += res[2];
|
||||
enforce(res[1] == IOStatus.ok, "Failed to read data from disk.");
|
||||
return res[2];
|
||||
}
|
||||
|
|
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;
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
/++ dub.sdl:
|
||||
/+ dub.sdl:
|
||||
name "test"
|
||||
description "Tests vibe.d's std.concurrency integration"
|
||||
dependency "vibe-core" path="../"
|
||||
|
|
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);
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
/++ dub.sdl:
|
||||
/+ dub.sdl:
|
||||
name "test"
|
||||
dependency "vibe-core" path=".."
|
||||
+/
|
||||
|
@ -12,16 +12,23 @@ void main()
|
|||
{
|
||||
auto f = openFile("test.dat", FileMode.createTrunc);
|
||||
assert(f.size == 0);
|
||||
assert(f.tell == 0);
|
||||
f.write(bytes!(1, 2, 3, 4, 5));
|
||||
assert(f.size == 5);
|
||||
assert(f.tell == 5);
|
||||
f.seek(0);
|
||||
assert(f.tell == 0);
|
||||
f.write(bytes!(1, 2, 3, 4, 5));
|
||||
assert(f.size == 5);
|
||||
assert(f.tell == 5);
|
||||
f.write(bytes!(6, 7, 8, 9, 10));
|
||||
assert(f.size == 10);
|
||||
assert(f.tell == 10);
|
||||
ubyte[5] dst;
|
||||
f.seek(2);
|
||||
assert(f.tell == 2);
|
||||
f.read(dst);
|
||||
assert(f.tell == 7);
|
||||
assert(dst[] == bytes!(3, 4, 5, 6, 7));
|
||||
f.close();
|
||||
|
||||
|
|
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();
|
||||
});
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
/++ dub.sdl:
|
||||
/+ dub.sdl:
|
||||
name "test"
|
||||
description "TCP disconnect task issue"
|
||||
dependency "vibe-core" path="../"
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/++ dub.sdl:
|
||||
/+ dub.sdl:
|
||||
name "test"
|
||||
description "TCP disconnect task issue"
|
||||
dependency "vibe-core" path="../"
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
/++ dub.sdl:
|
||||
/+ dub.sdl:
|
||||
name "test"
|
||||
description "Invalid memory operation on TCP connection leakage at shutdown"
|
||||
dependency "vibe-core" path="../"
|
||||
debugVersions "VibeAsyncLog"
|
||||
+/
|
||||
module test;
|
||||
|
||||
|
|
10
travis-ci.sh
10
travis-ci.sh
|
@ -21,7 +21,13 @@ if [ ${BUILD_EXAMPLE=1} -eq 1 ]; then
|
|||
fi
|
||||
if [ ${RUN_TEST=1} -eq 1 ]; then
|
||||
for ex in `\ls -1 tests/*.d`; do
|
||||
echo "[INFO] Running test $ex"
|
||||
dub --temp-build --compiler=$DC --single $ex # --override-config vibe-core/$CONFIG
|
||||
script="${ex:0:-2}.sh"
|
||||
if [ -e "$script" ]; then
|
||||
echo "[INFO] Running test scipt $script"
|
||||
(cd tests && "./${script:6}")
|
||||
else
|
||||
echo "[INFO] Running test $ex"
|
||||
dub --temp-build --compiler=$DC --single $ex # --override-config vibe-core/$CONFIG
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
|
Loading…
Reference in a new issue