diff options
Diffstat (limited to '3rdparty/luv/tests')
-rw-r--r-- | 3rdparty/luv/tests/manual-test-cluster.lua | 213 | ||||
-rw-r--r-- | 3rdparty/luv/tests/run.lua | 33 | ||||
-rw-r--r-- | 3rdparty/luv/tests/test-async.lua | 32 | ||||
-rw-r--r-- | 3rdparty/luv/tests/test-conversions.lua | 6 | ||||
-rw-r--r-- | 3rdparty/luv/tests/test-dns.lua | 125 | ||||
-rw-r--r-- | 3rdparty/luv/tests/test-fs.lua | 90 | ||||
-rw-r--r-- | 3rdparty/luv/tests/test-leaks.lua | 186 | ||||
-rw-r--r-- | 3rdparty/luv/tests/test-misc.lua | 85 | ||||
-rw-r--r-- | 3rdparty/luv/tests/test-prepare-check-idle-async.lua | 49 | ||||
-rw-r--r-- | 3rdparty/luv/tests/test-process.lua | 101 | ||||
-rw-r--r-- | 3rdparty/luv/tests/test-sigchld-after-lua_close.sh | 45 | ||||
-rw-r--r-- | 3rdparty/luv/tests/test-signal.lua | 40 | ||||
-rw-r--r-- | 3rdparty/luv/tests/test-tcp.lua | 114 | ||||
-rw-r--r-- | 3rdparty/luv/tests/test-thread.lua | 47 | ||||
-rw-r--r-- | 3rdparty/luv/tests/test-timer.lua | 87 | ||||
-rw-r--r-- | 3rdparty/luv/tests/test-work.lua | 48 |
16 files changed, 1301 insertions, 0 deletions
diff --git a/3rdparty/luv/tests/manual-test-cluster.lua b/3rdparty/luv/tests/manual-test-cluster.lua new file mode 100644 index 00000000000..304e4be634d --- /dev/null +++ b/3rdparty/luv/tests/manual-test-cluster.lua @@ -0,0 +1,213 @@ +-- This is quite the involved test. Basically it binds +-- to a tcp port, spawns n children (one per CPU core) +-- who all listen on the same shared port and act as a +-- load balancing cluster. +-- Then N clients are spawned that connect to the cluster +-- The application itself kills the worker upon connection +-- All N workers should accept exactly one request and all close. + +return require('lib/tap')(function (test) + + -- This function will be run in a child process + local worker_code = string.dump(function () + local dump = require('lib/utils').dump + + local function print(...) + local n = select('#', ...) + local arguments = {...} + for i = 1, n do + arguments[i] = tostring(arguments[i]) + end + + local text = table.concat(arguments, "\t") + text = " " .. string.gsub(text, "\n", "\n ") + _G.print(text) + end + + local function p(...) + local n = select('#', ...) + local arguments = { ... } + + for i = 1, n do + arguments[i] = dump(arguments[i]) + end + + print(table.concat(arguments, "\t")) + end + + local uv = require('luv') + local answer = -1 + + -- The parent is going to pass us the server handle over a pipe + -- This will be our local file descriptor at PIPE_FD + local pipe = uv.new_pipe(true) + local pipe_fd = tonumber(os.getenv("PIPE_FD")) + assert(uv.pipe_open(pipe, pipe_fd)) + + -- Configure the server handle + local server = uv.new_tcp() + local done = false + local function onconnection() + print("NOT ACCEPTING, already done") + if done then return end + local client = uv.new_tcp() + assert(uv.accept(server, client)) + p("New TCP", client, "on", server) + p{client=client} + assert(uv.write(client, "BYE!\n")); + assert(uv.shutdown(client, function () + uv.close(client) + uv.unref(server) + done = true + answer = 42 + end)) + end + + -- Read the server handle from the parent + local function onread(err, data) + p("onread", {err=err,data=data}) + assert(not err, err) + if uv.pipe_pending_count(pipe) > 0 then + local pending_type = uv.pipe_pending_type(pipe) + p("pending_type", pending_type) + assert(pending_type == "tcp") + assert(uv.accept(pipe, server)) + assert(uv.listen(server, 0, onconnection)) + p("Received server handle from parent process", server) + elseif data then + p("ondata", data) + else + p("onend", data) + end + end + uv.read_start(pipe, onread) + + -- Start the event loop! + uv.run() + + os.exit(answer) + end) + + local client_code = string.dump(function () + local dump = require('lib/utils').dump + + local function print(...) + local n = select('#', ...) + local arguments = {...} + for i = 1, n do + arguments[i] = tostring(arguments[i]) + end + + local text = table.concat(arguments, "\t") + text = " " .. string.gsub(text, "\n", "\n ") + _G.print(text) + end + + local function p(...) + local n = select('#', ...) + local arguments = { ... } + + for i = 1, n do + arguments[i] = dump(arguments[i]) + end + + print(table.concat(arguments, "\t")) + end + + local uv = require('luv') + + local host = os.getenv("HOST") + local port = tonumber(os.getenv("PORT")) + + local socket = uv.new_tcp() + + assert(uv.tcp_connect(socket, host, port, function (err) + p("client connected", {err=err}) + assert(not err, err) + end)) + + -- Start the event loop! + uv.run() + end) + + test("tcp cluster", function (print, p, expect, uv) + + local exepath = assert(uv.exepath()) + local cpu_count = # assert(uv.cpu_info()) + local left = cpu_count + + local server = uv.new_tcp() + assert(uv.tcp_bind(server, "::1", 0)) + + local address = uv.tcp_getsockname(server) + p{server=server,address=address} + + print("Master process bound to TCP port " .. address.port .. " on " .. address.ip) + + local function spawnWorker() + local pipe = uv.new_pipe(true) + local input = uv.new_pipe(false) + local child, pid + child, pid = assert(uv.spawn(exepath, { + cwd = uv.cwd(), + stdio = {input,1,2,pipe}, + env= {"PIPE_FD=3"} + }, expect(function (status, signal) + p("Worker exited", {status=status,signal=signal}) + assert(status == 42, "worker should return 42") + assert(signal == 0) + left = left - 1 + uv.close(child) + uv.close(input) + uv.close(pipe) + if left == 0 then + p("All workers are now dead") + uv.close(server) + end + end))) + p("Spawned worker", pid, "and sending handle", server) + assert(uv.write(input, worker_code)) + assert(uv.write2(pipe, "123", server)) + assert(uv.shutdown(input)) + assert(uv.shutdown(pipe)) + end + + local function spawnClient() + local input = uv.new_pipe(false) + local child, pid + child, pid = assert(uv.spawn(exepath, { + stdio = {input,1,2}, + cwd = uv.cwd(), + env= { + "HOST=" .. address.ip, + "PORT=" .. address.port, + } + }, expect(function (status, signal) + p("Client exited", {status=status,signal=signal}) + assert(status == 0) + assert(signal == 0) + uv.close(child) + end, left))) + p("Spawned client", pid) + assert(uv.write(input, client_code)) + assert(uv.shutdown(input)) + uv.close(input) + end + + -- Spawn a child process for each CPU core + for _ = 1, cpu_count do + spawnWorker() + end + + -- Spawn the clients after a short delay + local timer = uv.new_timer() + uv.timer_start(timer, 1000, 0, expect(function () + for _ = 1, cpu_count do + spawnClient() + end + uv.close(timer) + end)) + + end) +end) + diff --git a/3rdparty/luv/tests/run.lua b/3rdparty/luv/tests/run.lua new file mode 100644 index 00000000000..ea94e9bd58b --- /dev/null +++ b/3rdparty/luv/tests/run.lua @@ -0,0 +1,33 @@ +-- Run this from the parent directory as +-- +-- luajit tests/run.lua +-- + +local tap = require("lib/tap") +local uv = require("luv") + +local isWindows +if jit and jit.os then + -- Luajit provides explicit platform detection + isWindows = jit.os == "Windows" +else + -- Normal lua will only have \ for path separator on windows. + isWindows = package.config:find("\\") and true or false +end +_G.isWindows = isWindows + +local req = uv.fs_scandir("tests") + +while true do + local name = uv.fs_scandir_next(req) + if not name then break end + local match = string.match(name, "^test%-(.*).lua$") + if match then + local path = "tests/test-" .. match + tap(match) + require(path) + end +end + +-- run the tests! +tap(true) diff --git a/3rdparty/luv/tests/test-async.lua b/3rdparty/luv/tests/test-async.lua new file mode 100644 index 00000000000..88527cdb88d --- /dev/null +++ b/3rdparty/luv/tests/test-async.lua @@ -0,0 +1,32 @@ +return require('lib/tap')(function (test) + + test("test pass async between threads", function(p, p, expect, uv) + local before = os.time() + local async + async = uv.new_async(expect(function (a,b,c) + p('in async notify callback') + p(a,b,c) + assert(a=='a') + assert(b==true) + assert(c==250) + uv.close(async) + end)) + local args = {500, 'string', nil, false, 5, "helloworld",async} + local unpack = unpack or table.unpack + uv.new_thread(function(num,s,null,bool,five,hw,asy) + local uv = require'luv' + assert(type(num) == "number") + assert(type(s) == "string") + assert(null == nil) + assert(bool == false) + assert(five == 5) + assert(hw == 'helloworld') + assert(type(asy)=='userdata') + assert(uv.async_send(asy,'a',true,250)==0) + uv.sleep(1000) + end, unpack(args)):join() + local elapsed = (os.time() - before) * 1000 + assert(elapsed >= 1000, "elapsed should be at least delay ") + end) + +end) diff --git a/3rdparty/luv/tests/test-conversions.lua b/3rdparty/luv/tests/test-conversions.lua new file mode 100644 index 00000000000..f14056ddfb5 --- /dev/null +++ b/3rdparty/luv/tests/test-conversions.lua @@ -0,0 +1,6 @@ +return require('lib/tap')(function (test) + test("basic 64bit conversions", function (print, p, expect, uv) + assert(string.format("%x", 29913653248) == "6f6fe2000") + assert(string.format("%x", 32207650816) == "77fb9c000") + end) +end) diff --git a/3rdparty/luv/tests/test-dns.lua b/3rdparty/luv/tests/test-dns.lua new file mode 100644 index 00000000000..c24adba7164 --- /dev/null +++ b/3rdparty/luv/tests/test-dns.lua @@ -0,0 +1,125 @@ +return require('lib/tap')(function (test) + + test("Get all local http addresses", function (print, p, expect, uv) + assert(uv.getaddrinfo(nil, "http", nil, expect(function (err, res) + p(res, #res) + assert(not err, err) + assert(res[1].port == 80) + end))) + end) + + test("Get all local http addresses sync", function (print, p, expect, uv) + local res = assert(uv.getaddrinfo(nil, "http")) + p(res, #res) + assert(res[1].port == 80) + end) + + test("Get only ipv4 tcp adresses for luvit.io", function (print, p, expect, uv) + assert(uv.getaddrinfo("luvit.io", nil, { + socktype = "stream", + family = "inet", + }, expect(function (err, res) + assert(not err, err) + p(res, #res) + assert(#res == 1) + end))) + end) + + -- FIXME: this test always fails on AppVeyor for some reason + if _G.isWindows and not os.getenv'APPVEYOR' then + test("Get only ipv6 tcp adresses for luvit.io", function (print, p, expect, uv) + assert(uv.getaddrinfo("luvit.io", nil, { + socktype = "stream", + family = "inet6", + }, expect(function (err, res) + assert(not err, err) + p(res, #res) + assert(#res == 1) + end))) + end) + end + + test("Get ipv4 and ipv6 tcp adresses for luvit.io", function (print, p, expect, uv) + assert(uv.getaddrinfo("luvit.io", nil, { + socktype = "stream", + }, expect(function (err, res) + assert(not err, err) + p(res, #res) + assert(#res > 0) + end))) + end) + + test("Get all adresses for luvit.io", function (print, p, expect, uv) + assert(uv.getaddrinfo("luvit.io", nil, nil, expect(function (err, res) + assert(not err, err) + p(res, #res) + assert(#res > 0) + end))) + end) + + test("Lookup local ipv4 address", function (print, p, expect, uv) + assert(uv.getnameinfo({ + family = "inet", + }, expect(function (err, hostname, service) + p{err=err,hostname=hostname,service=service} + assert(not err, err) + assert(hostname) + assert(service) + end))) + end) + + test("Lookup local ipv4 address sync", function (print, p, expect, uv) + local hostname, service = assert(uv.getnameinfo({ + family = "inet", + })) + p{hostname=hostname,service=service} + assert(hostname) + assert(service) + end) + + test("Lookup local 127.0.0.1 ipv4 address", function (print, p, expect, uv) + assert(uv.getnameinfo({ + ip = "127.0.0.1", + }, expect(function (err, hostname, service) + p{err=err,hostname=hostname,service=service} + assert(not err, err) + assert(hostname) + assert(service) + end))) + end) + + test("Lookup local ipv6 address", function (print, p, expect, uv) + assert(uv.getnameinfo({ + family = "inet6", + }, expect(function (err, hostname, service) + p{err=err,hostname=hostname,service=service} + assert(not err, err) + assert(hostname) + assert(service) + end))) + end) + + test("Lookup local ::1 ipv6 address", function (print, p, expect, uv) + assert(uv.getnameinfo({ + ip = "::1", + }, expect(function (err, hostname, service) + p{err=err,hostname=hostname,service=service} + assert(not err, err) + assert(hostname) + assert(service) + end))) + end) + + test("Lookup local port 80 service", function (print, p, expect, uv) + assert(uv.getnameinfo({ + port = 80, + family = "inet6", + }, expect(function (err, hostname, service) + p{err=err,hostname=hostname,service=service} + assert(not err, err) + assert(hostname) + assert(service == "http") + end))) + end) + +end) diff --git a/3rdparty/luv/tests/test-fs.lua b/3rdparty/luv/tests/test-fs.lua new file mode 100644 index 00000000000..4bfd67e6578 --- /dev/null +++ b/3rdparty/luv/tests/test-fs.lua @@ -0,0 +1,90 @@ +return require('lib/tap')(function (test) + + test("read a file sync", function (print, p, expect, uv) + local fd = assert(uv.fs_open('README.md', 'r', tonumber('644', 8))) + p{fd=fd} + local stat = assert(uv.fs_fstat(fd)) + p{stat=stat} + local chunk = assert(uv.fs_read(fd, stat.size, 0)) + assert(#chunk == stat.size) + assert(uv.fs_close(fd)) + end) + + test("read a file async", function (print, p, expect, uv) + uv.fs_open('README.md', 'r', tonumber('644', 8), expect(function (err, fd) + assert(not err, err) + p{fd=fd} + uv.fs_fstat(fd, expect(function (err, stat) + assert(not err, err) + p{stat=stat} + uv.fs_read(fd, stat.size, 0, expect(function (err, chunk) + assert(not err, err) + p{chunk=#chunk} + assert(#chunk == stat.size) + uv.fs_close(fd, expect(function (err) + assert(not err, err) + end)) + end)) + end)) + end)) + end) + + test("fs.write", function (print, p, expect, uv) + local path = "_test_" + local fd = assert(uv.fs_open(path, "w", 438)) + uv.fs_write(fd, "Hello World\n", -1) + uv.fs_write(fd, {"with\n", "more\n", "lines\n"}, -1) + uv.fs_close(fd) + uv.fs_unlink(path) + end) + + test("fs.stat sync", function (print, p, expect, uv) + local stat = assert(uv.fs_stat("README.md")) + assert(stat.size) + end) + + test("fs.stat async", function (print, p, expect, uv) + assert(uv.fs_stat("README.md", expect(function (err, stat) + assert(not err, err) + assert(stat.size) + end))) + end) + + test("fs.stat sync error", function (print, p, expect, uv) + local stat, err, code = uv.fs_stat("BAD_FILE!") + p{err=err,code=code,stat=stat} + assert(not stat) + assert(err) + assert(code == "ENOENT") + end) + + test("fs.stat async error", function (print, p, expect, uv) + assert(uv.fs_stat("BAD_FILE@", expect(function (err, stat) + p{err=err,stat=stat} + assert(err) + assert(not stat) + end))) + end) + + test("fs.scandir", function (print, p, expect, uv) + local req = uv.fs_scandir('.') + local function iter() + return uv.fs_scandir_next(req) + end + for name, ftype in iter do + p{name=name, ftype=ftype} + assert(name) + -- ftype is not available in all filesystems; for example it's + -- provided for HFS+ (OSX), NTFS (Windows) but not for ext4 (Linux). + end + end) + + test("fs.realpath", function (print, p, expect, uv) + p(assert(uv.fs_realpath('.'))) + assert(uv.fs_realpath('.', expect(function (err, path) + assert(not err, err) + p(path) + end))) + end) + +end) diff --git a/3rdparty/luv/tests/test-leaks.lua b/3rdparty/luv/tests/test-leaks.lua new file mode 100644 index 00000000000..06c6e49a0cf --- /dev/null +++ b/3rdparty/luv/tests/test-leaks.lua @@ -0,0 +1,186 @@ +return require('lib/tap')(function (test) + + local function bench(uv, p, count, fn) + collectgarbage() + local before + local notify = count / 8 + for i = 1, count do + fn() + if i % notify == 0 then + uv.run() + collectgarbage() + local now = uv.resident_set_memory() + if not before then before = now end + p(i, now) + end + end + uv.run() + collectgarbage() + local after = uv.resident_set_memory() + p{ + before = before, + after = after, + } + assert(after < before * 1.5) + end + + test("fs-write", function (print, p, expect, uv) + bench(uv, p, 0x7000, function () + local path = "_test_" + local fd = assert(uv.fs_open(path, "w", 438)) + uv.fs_write(fd, "Hello World\n", -1) + uv.fs_write(fd, {"with\n", "more\n", "lines\n"}, -1) + uv.fs_close(fd) + uv.fs_unlink(path) + end) + end) + + test("lots-o-timers", function (print, p, expect, uv) + bench(uv, p, 0x10000, function () + local timer = uv.new_timer() + uv.close(timer) + end) + end) + + test("lots-o-timers with canceled callbacks", function (print, p, expect, uv) + bench(uv, p, 0x10000, function () + local timer = uv.new_timer() + uv.timer_start(timer, 100, 100, function () + end) + uv.timer_stop(timer) + uv.close(timer, function () + end) + uv.run() + end) + end) + + test("lots-o-timers with real timeouts", function (print, p, expect, uv) + bench(uv, p, 0x500, function () + local timer = uv.new_timer() + uv.timer_start(timer, 10, 0, expect(function () + uv.timer_stop(timer) + uv.close(timer, function () + end) + end)) + end) + end) + + test("reading file async", function (print, p, expect, uv) + local mode = tonumber("644", 8) + bench(uv, p, 0x500, function () + local onOpen, onStat, onRead, onClose + local fd, stat + + onOpen = expect(function (err, result) + assert(not err, err) + fd = result + uv.fs_fstat(fd, onStat) + end) + + onStat = expect(function (err, result) + assert(not err, err) + stat = result + uv.fs_read(fd, stat.size, 0, onRead) + end) + + onRead = expect(function (err, data) + assert(not err, err) + assert(#data == stat.size) + uv.fs_close(fd, onClose) + end) + + onClose = expect(function (err) + assert(not err, err) + end) + + assert(uv.fs_open("README.md", "r", mode, onOpen)) + end) + end) + + test("reading file sync", function (print, p, expect, uv) + local mode = tonumber("644", 8) + bench(uv, p, 0x2000, function () + local fd = assert(uv.fs_open("README.md", "r", mode)) + local stat = assert(uv.fs_fstat(fd)) + local data = assert(uv.fs_read(fd, stat.size, 0)) + assert(#data == stat.size) + assert(uv.fs_close(fd)) + end) + end) + + test("invalid file", function (print, p, expect, uv) + local mode = tonumber("644", 8) + bench(uv, p, 0x1500, function () + local req = uv.fs_open("BAD_FILE", "r", mode, expect(function (err, fd) + assert(not fd) + assert(err) + end)) + end) + end) + + test("invalid file sync", function (print, p, expect, uv) + local mode = tonumber("644", 8) + bench(uv, p, 0x20000, function () + local fd, err = uv.fs_open("BAD_FILE", "r", mode) + assert(not fd) + assert(err) + end) + end) + + test("invalid spawn args", function (print, p, expect, uv) + -- Regression test for #73 + bench(uv, p, 0x10000, function () + local ret, err = pcall(function () + return uv.spawn("ls", { + args = {"-l", "-h"}, + stdio = {0, 1, 2}, + env = {"EXTRA=true"}, + gid = false, -- Should be integer + }) + end) + assert(not ret) + assert(err) + end) + end) + + test("stream writing with string and array", function (print, p, expect, uv) + local port = 0 + local server = uv.new_tcp() + local data + local count = 0x800 + server:unref() + server:bind("127.0.0.1", port) + server:listen(128, expect(function (err) + assert(not err, err) + local client = uv.new_tcp() + server:accept(client) + client:write(data) + client:read_start(expect(function (err, data) + assert(not err, err) + assert(data) + client:close() + end)) + end, count)) + local address = server:getsockname() + bench(uv, p, count, function () + data = string.rep("Hello", 500) + local socket = uv.new_tcp() + socket:connect(address.ip, address.port, expect(function (err) + assert(not err, err) + socket:read_start(expect(function (err, chunk) + assert(not err, err) + assert(chunk) + local data = {} + for i = 0, 100 do + data[i + 1] = string.rep(string.char(i), 100) + end + socket:write(data) + socket:close() + end)) + end)) + uv.run() + end) + server:close() + end) + +end) diff --git a/3rdparty/luv/tests/test-misc.lua b/3rdparty/luv/tests/test-misc.lua new file mode 100644 index 00000000000..72a7b30785e --- /dev/null +++ b/3rdparty/luv/tests/test-misc.lua @@ -0,0 +1,85 @@ +return require('lib/tap')(function (test) + + test("uv.guess_handle", function (print, p, expect, uv) + local types = { + [0] = assert(uv.guess_handle(0)), + assert(uv.guess_handle(1)), + assert(uv.guess_handle(2)), + } + p("stdio fd types", types) + end) + + test("uv.version and uv.version_string", function (print, p, expect, uv) + local version = assert(uv.version()) + local version_string = assert(uv.version_string()) + p{version=version, version_string=version_string} + assert(type(version) == "number") + assert(type(version_string) == "string") + end) + + test("memory size", function (print, p, expect, uv) + local rss = uv.resident_set_memory() + local total = uv.get_total_memory() + local free = uv.get_free_memory() + p{rss=rss,total=total,free=free} + assert(rss < total) + end) + + test("uv.uptime", function (print, p, expect, uv) + local uptime = assert(uv.uptime()) + p{uptime=uptime} + end) + + test("uv.getrusage", function (print, p, expect, uv) + local rusage = assert(uv.getrusage()) + p(rusage) + end) + + test("uv.cpu_info", function (print, p, expect, uv) + local info = assert(uv.cpu_info()) + p(info) + end) + + test("uv.interface_addresses", function (print, p, expect, uv) + local addresses = assert(uv.interface_addresses()) + for name, info in pairs(addresses) do + p(name, addresses[name]) + end + end) + + test("uv.loadavg", function (print, p, expect, uv) + local avg = {assert(uv.loadavg())} + p(avg) + assert(#avg == 3) + end) + + test("uv.exepath", function (print, p, expect, uv) + local path = assert(uv.exepath()) + p(path) + end) + + test("uv.os_homedir", function (print, p, expect, uv) + local path = assert(uv.os_homedir()) + p(path) + end) + + test("uv.cwd and uv.chdir", function (print, p, expect, uv) + local old = assert(uv.cwd()) + p(old) + assert(uv.chdir("/")) + local cwd = assert(uv.cwd()) + p(cwd) + assert(cwd ~= old) + assert(uv.chdir(old)) + end) + + test("uv.hrtime", function (print, p, expect, uv) + local time = assert(uv.hrtime()) + p(time) + end) + + test("test_getpid", function (print, p, expect, uv) + assert(uv.getpid()) + end) + +end) diff --git a/3rdparty/luv/tests/test-prepare-check-idle-async.lua b/3rdparty/luv/tests/test-prepare-check-idle-async.lua new file mode 100644 index 00000000000..389c2633efb --- /dev/null +++ b/3rdparty/luv/tests/test-prepare-check-idle-async.lua @@ -0,0 +1,49 @@ +return require('lib/tap')(function (test) + + test("simple prepare", function (print, p, expect, uv) + local prepare = uv.new_prepare() + uv.prepare_start(prepare, expect(function () + p("prepare", prepare) + uv.prepare_stop(prepare) + uv.close(prepare, expect(function () + end)) + end)) + end) + + test("simple check", function (print, p, expect, uv) + local check = uv.new_check() + uv.check_start(check, expect(function () + p("check", check) + uv.check_stop(check) + uv.close(check, expect(function () + end)) + end)) + + -- Trigger with a timer + local timer = uv.new_timer() + uv.timer_start(timer, 10, 0, expect(function() + p("timeout", timer) + uv.timer_stop(timer) + uv.close(timer) + end)) + end) + + test("simple idle", function (print, p, expect, uv) + local idle = uv.new_idle() + uv.idle_start(idle, expect(function () + p("idle", idle) + uv.idle_stop(idle) + uv.close(idle, expect(function () + end)) + end)) + end) + + test("simple async", function (print, p, expect, uv) + local async + async = uv.new_async(expect(function () + uv.close(async) + end)) + uv.async_send(async) + end) + +end) diff --git a/3rdparty/luv/tests/test-process.lua b/3rdparty/luv/tests/test-process.lua new file mode 100644 index 00000000000..4d2b6fbfdab --- /dev/null +++ b/3rdparty/luv/tests/test-process.lua @@ -0,0 +1,101 @@ +return require('lib/tap')(function (test) + + test("test disable_stdio_inheritance", function (print, p, expect, uv) + uv.disable_stdio_inheritance() + end) + + test("process stdout", function (print, p, expect, uv) + local stdout = uv.new_pipe(false) + + local handle, pid + handle, pid = uv.spawn(uv.exepath(), { + args = {"-e", "print 'Hello World'"}, + stdio = {nil, stdout}, + }, expect(function (code, signal) + p("exit", {code=code, signal=signal}) + uv.close(handle) + end)) + + p{ + handle=handle, + pid=pid + } + + uv.read_start(stdout, expect(function (err, chunk) + p("stdout", {err=err,chunk=chunk}) + assert(not err, err) + uv.close(stdout) + end)) + + end) + + if _G.isWindows then return end + + test("spawn and kill by pid", function (print, p, expect, uv) + local handle, pid + handle, pid = uv.spawn("sleep", { + args = {1}, + }, expect(function (status, signal) + p("exit", handle, {status=status,signal=signal}) + assert(status == 0) + assert(signal == 2) + uv.close(handle) + end)) + p{handle=handle,pid=pid} + uv.kill(pid, "sigint") + end) + + test("spawn and kill by handle", function (print, p, expect, uv) + local handle, pid + handle, pid = uv.spawn("sleep", { + args = {1}, + }, expect(function (status, signal) + p("exit", handle, {status=status,signal=signal}) + assert(status == 0) + assert(signal == 15) + uv.close(handle) + end)) + p{handle=handle,pid=pid} + uv.process_kill(handle, "sigterm") + end) + + test("invalid command", function (print, p, expect, uv) + local handle, err + handle, err = uv.spawn("ksjdfksjdflkjsflksdf", {}, function(exit, code) + assert(false) + end) + assert(handle == nil) + assert(err) + end) + + test("process stdio", function (print, p, expect, uv) + local stdin = uv.new_pipe(false) + local stdout = uv.new_pipe(false) + + local handle, pid + handle, pid = uv.spawn("cat", { + stdio = {stdin, stdout}, + }, expect(function (code, signal) + p("exit", {code=code, signal=signal}) + uv.close(handle) + end)) + + p{ + handle=handle, + pid=pid + } + + uv.read_start(stdout, expect(function (err, chunk) + p("stdout", {err=err,chunk=chunk}) + assert(not err, err) + uv.close(stdout) + end)) + + uv.write(stdin, "Hello World") + uv.shutdown(stdin, expect(function () + uv.close(stdin) + end)) + + end) + +end) diff --git a/3rdparty/luv/tests/test-sigchld-after-lua_close.sh b/3rdparty/luv/tests/test-sigchld-after-lua_close.sh new file mode 100644 index 00000000000..e7d22d3df36 --- /dev/null +++ b/3rdparty/luv/tests/test-sigchld-after-lua_close.sh @@ -0,0 +1,45 @@ +#!/bin/sh +# Verifies that luv will cleanup libuv process handles correctly even if +# not done by "userspace". +# Details: https://github.com/luvit/luv/issues/193 + +# This test modifies one of the examples to skip libuv process cleanup, +# purposely making it leave SIGCHLD signal handler. +# +patch -p1 << "EOF" +diff --git a/examples/talking-to-children.lua b/examples/talking-to-children.lua +index 10a53ef..6c6c53f 100644 +--- a/examples/talking-to-children.lua ++++ b/examples/talking-to-children.lua +@@ -41,7 +41,3 @@ uv.read_start(stdout, onread) + uv.read_start(stderr, onread) + uv.write(stdin, "Hello World") + uv.shutdown(stdin, onshutdown) +- +-uv.run() +-uv.walk(uv.close) +-uv.run() +EOF + +# It also requires a patched lua standalone interpreter that sends SIGCHLD to +# itself after calling lua_close, which would have freed all memory of the libuv +# event loop associated with the lua state. +( +cd deps/lua +patch -p1 << "EOF" +diff --git a/src/lua.c b/src/lua.c +index 7a47582..4dc19d5 100644 +--- a/src/lua.c ++++ b/src/lua.c +@@ -608,6 +608,7 @@ int main (int argc, char **argv) { + result = lua_toboolean(L, -1); /* get result */ + report(L, status); + lua_close(L); ++ kill(0, SIGCHLD); + return (result && status == LUA_OK) ? EXIT_SUCCESS : EXIT_FAILURE; + } +EOF +) + +WITH_LUA_ENGINE=Lua make +./build/lua examples/talking-to-children.lua diff --git a/3rdparty/luv/tests/test-signal.lua b/3rdparty/luv/tests/test-signal.lua new file mode 100644 index 00000000000..c05db77c888 --- /dev/null +++ b/3rdparty/luv/tests/test-signal.lua @@ -0,0 +1,40 @@ +local child_code = string.dump(function () + local uv = require('luv') + local signal = uv.new_signal() + uv.ref(signal) + uv.signal_start(signal, "sigint", function () + uv.unref(signal) + end) + uv.run() + os.exit(7) +end) + +return require('lib/tap')(function (test) + + if _G.isWindows then return end + + test("Catch SIGINT", function (print, p, expect, uv) + local child, pid + local input = uv.new_pipe(false) + child, pid = assert(uv.spawn(uv.exepath(), { + args = {"-"}, + -- cwd = uv.cwd(), + stdio = {input,1,2} + }, expect(function (code, signal) + p("exit", {pid=pid,code=code,signal=signal}) + assert(code == 7) + assert(signal == 0) + uv.close(input) + uv.close(child) + end))) + uv.write(input, child_code) + uv.shutdown(input) + local timer = uv.new_timer() + uv.timer_start(timer, 200, 0, expect(function () + print("Sending child SIGINT") + uv.process_kill(child, "sigint") + uv.close(timer) + end)) + end) + +end) diff --git a/3rdparty/luv/tests/test-tcp.lua b/3rdparty/luv/tests/test-tcp.lua new file mode 100644 index 00000000000..885d381ebce --- /dev/null +++ b/3rdparty/luv/tests/test-tcp.lua @@ -0,0 +1,114 @@ +return require('lib/tap')(function (test) + test("basic tcp server and client", function (print, p, expect, uv) + local server = uv.new_tcp() + uv.tcp_bind(server, "::", 0) + uv.listen(server, 128, expect(function (err) + p("server on connection", server) + assert(not err, err) + uv.close(server) + end)) + + local address = uv.tcp_getsockname(server) + p{server=server,address=address} + + local client = uv.new_tcp() + local req = uv.tcp_connect(client, "::1", address.port, expect(function (err) + p("client on connect", client, err) + assert(not err, err) + uv.shutdown(client, expect(function (err) + p("client on shutdown", client, err) + assert(not err, err) + uv.close(client, expect(function () + p("client on close", client) + end)) + end)) + end)) + p{client=client,req=req} + end) + + test("tcp echo server and client", function (print, p, expect, uv) + local server = uv.new_tcp() + assert(uv.tcp_bind(server, "127.0.0.1", 0)) + assert(uv.listen(server, 1, expect(function () + local client = uv.new_tcp() + assert(uv.accept(server, client)) + assert(uv.read_start(client, expect(function (err, data) + p("server read", {err=err,data=data}) + assert(not err, err) + if data then + assert(uv.write(client, data)) + else + assert(uv.read_stop(client)) + uv.close(client) + uv.close(server) + end + end, 2))) + end))) + + local address = uv.tcp_getsockname(server) + p{server=server,address=address} + + local socket = assert(uv.new_tcp()) + assert(uv.tcp_connect(socket, "127.0.0.1", address.port, expect(function () + assert(uv.read_start(socket, expect(function (err, data) + p("client read", {err=err,data=data}) + assert(not err, err) + assert(uv.read_stop(socket)) + uv.close(socket) + end))) + local req = assert(uv.write(socket, "Hello", function (err) + p("client onwrite", socket, err) + assert(not err, err) + end)) + p{socket=socket,req=req} + end))) + end) + + test("tcp echo server and client with methods", function (print, p, expect, uv) + local server = uv.new_tcp() + assert(server:bind("127.0.0.1", 0)) + assert(server:listen(1, expect(function () + local client = uv.new_tcp() + assert(server:accept(client)) + assert(client:read_start(expect(function (err, data) + p("server read", {err=err,data=data}) + assert(not err, err) + if data then + assert(client:write(data)) + else + assert(client:read_stop()) + client:close() + server:close() + end + end, 2))) + end))) + + local address = server:getsockname() + p{server=server,address=address} + + local socket = assert(uv.new_tcp()) + assert(socket:connect("127.0.0.1", address.port, expect(function () + assert(socket:read_start(expect(function (err, data) + p("client read", {err=err,data=data}) + assert(not err, err) + assert(socket:read_stop()) + socket:close() + end))) + local req = assert(socket:write("Hello", function (err) + p("client onwrite", socket, err) + assert(not err, err) + end)) + p{socket=socket,req=req} + end))) + end) + + test("tcp invalid ip address", function (print, p, expect, uv) + local ip = '127.0.0.100005' + local server = uv.new_tcp() + local status, err = pcall(function() uv.tcp_bind(server, ip, 1000) end) + assert(not status) + p(err) + assert(err:find(ip)) + uv.close(server) + end) +end) diff --git a/3rdparty/luv/tests/test-thread.lua b/3rdparty/luv/tests/test-thread.lua new file mode 100644 index 00000000000..838b51e4fff --- /dev/null +++ b/3rdparty/luv/tests/test-thread.lua @@ -0,0 +1,47 @@ +return require('lib/tap')(function (test) + + test("test thread create", function(print, p, expect, uv) + local delay = 1000 + local before = os.time() + local thread = uv.new_thread(function(delay) + require('luv').sleep(delay) + end,delay) + uv.thread_join(thread) + local elapsed = (os.time() - before) * 1000 + p({ + delay = delay, + elapsed = elapsed + }) + assert(elapsed >= delay, "elapsed should be at least delay ") + end) + + test("test thread create with arguments", function(print, p, expect, uv) + local before = os.time() + local args = {500, 'string', nil, false, 5, "helloworld"} + local unpack = unpack or table.unpack + uv.new_thread(function(num,s,null,bool,five,hw) + assert(type(num) == "number") + assert(type(s) == "string") + assert(null == nil) + assert(bool == false) + assert(five == 5) + assert(hw == 'helloworld') + require('luv').sleep(1000) + end, unpack(args)):join() + local elapsed = (os.time() - before) * 1000 + assert(elapsed >= 1000, "elapsed should be at least delay ") + end) + + test("test thread sleep msecs in main thread", function(print, p, expect, uv) + local delay = 1000 + local before = os.time() + uv.sleep(delay) + local elapsed = (os.time() - before) * 1000 + p({ + delay = delay, + elapsed = elapsed + }) + assert(elapsed >= delay, "elapsed should be at least delay ") + end) + +end) diff --git a/3rdparty/luv/tests/test-timer.lua b/3rdparty/luv/tests/test-timer.lua new file mode 100644 index 00000000000..f9eb9d89c5f --- /dev/null +++ b/3rdparty/luv/tests/test-timer.lua @@ -0,0 +1,87 @@ +return require('lib/tap')(function (test) + + -- This tests using timers for a simple timeout. + -- It also tests the handle close callback and + test("simple timeout", function (print, p, expect, uv) + local timer = uv.new_timer() + local function onclose() + p("closed", timer) + end + local function ontimeout() + p("timeout", timer) + uv.close(timer, expect(onclose)) + end + uv.timer_start(timer, 10, 0, expect(ontimeout)) + end) + + -- This is like the previous test, but using repeat. + test("simple interval", function (print, p, expect, uv) + local timer = uv.new_timer() + local count = 3 + local onclose = expect(function () + p("closed", timer) + end) + local function oninterval() + p("interval", timer) + count = count - 1 + if count == 0 then + uv.close(timer, onclose) + end + end + uv.timer_start(timer, 10, 10, oninterval) + end) + + -- Test two concurrent timers + -- There is a small race condition, but there are 100ms of wiggle room. + -- 400ms is halfway between 100+200ms and 100+400ms + test("timeout with interval", function (print, p, expect, uv) + local a = uv.new_timer() + local b = uv.new_timer() + uv.timer_start(a, 400, 0, expect(function () + p("timeout", a) + uv.timer_stop(b) + uv.close(a) + uv.close(b) + end)) + uv.timer_start(b, 100, 200, expect(function () + p("interval", b) + end, 2)) + end) + + -- This advanced test uses the rest of the uv_timer_t functions + -- to create an interval that shrinks over time. + test("shrinking interval", function (print, p, expect, uv) + local timer = uv.new_timer() + uv.timer_start(timer, 10, 0, expect(function () + local r = uv.timer_get_repeat(timer) + p("interval", timer, r) + if r == 0 then + uv.timer_set_repeat(timer, 8) + uv.timer_again(timer) + elseif r == 2 then + uv.timer_stop(timer) + uv.close(timer) + else + uv.timer_set_repeat(timer, r / 2) + end + end, 4)) + end) + + test("shrinking interval using methods", function (print, p, expect, uv) + local timer = uv.new_timer() + timer:start(10, 0, expect(function () + local r = timer:get_repeat() + p("interval", timer, r) + if r == 0 then + timer:set_repeat(8) + timer:again() + elseif r == 2 then + timer:stop() + timer:close() + else + timer:set_repeat(r / 2) + end + end, 4)) + end) + +end) diff --git a/3rdparty/luv/tests/test-work.lua b/3rdparty/luv/tests/test-work.lua new file mode 100644 index 00000000000..3a98b15e6bc --- /dev/null +++ b/3rdparty/luv/tests/test-work.lua @@ -0,0 +1,48 @@ +return require('lib/tap')(function (test) + test("test threadpool", function(print,p,expect,_uv) + p('Please be patient, the test cost a lots of time') + local count = 1000 --for memleaks dected + local step = 0 + local ctx + ctx = _uv.new_work( + function(n,s) --work,in threadpool + local uv = require('luv') + local t = uv.thread_self() + uv.sleep(100) + return n,n*n, tostring(uv.thread_self()),s + end, + function(n,r,id, s) + assert(n*n==r) + if step < count then + _uv.queue_work(ctx,n,s) + step = step + 1 + if (step % 100==0) then + p(string.format('run %d%%', math.floor(step*100/count))) + end + end + end --after work, in loop thread + ) + local ls = string.rep('-',4096) + + _uv.queue_work(ctx,2,ls) + _uv.queue_work(ctx,4,ls) + _uv.queue_work(ctx,6,ls) + _uv.queue_work(ctx,-2,ls) + _uv.queue_work(ctx,-11,ls) + _uv.queue_work(ctx,2,ls) + _uv.queue_work(ctx,4,ls) + _uv.queue_work(ctx,6,ls) + _uv.queue_work(ctx,-2,ls) + _uv.queue_work(ctx,-11,ls) + _uv.queue_work(ctx,2,ls) + _uv.queue_work(ctx,4,ls) + _uv.queue_work(ctx,6,ls) + _uv.queue_work(ctx,-2,ls) + _uv.queue_work(ctx,-11,ls) + _uv.queue_work(ctx,2,ls) + _uv.queue_work(ctx,4,ls) + _uv.queue_work(ctx,6,ls) + _uv.queue_work(ctx,-2,ls) + _uv.queue_work(ctx,-11,ls) + end) +end) |