summaryrefslogtreecommitdiffstatshomepage
path: root/3rdparty/luv/tests
diff options
context:
space:
mode:
author ImJezze <jezze@gmx.net>2016-02-21 11:48:45 +0100
committer ImJezze <jezze@gmx.net>2016-02-21 11:48:45 +0100
commitcc24a339d8c0517259084b5c178d784626ba965c (patch)
tree9868e9687b5802ae0a3733712a3bbeb3bc75c953 /3rdparty/luv/tests
parentb5daabda5495dea5c50e17961ecfed2ea8619d76 (diff)
Merge remote-tracking branch 'refs/remotes/mamedev/master'
Second attempt
Diffstat (limited to '3rdparty/luv/tests')
-rw-r--r--3rdparty/luv/tests/manual-test-cluster.lua213
-rw-r--r--3rdparty/luv/tests/run.lua33
-rw-r--r--3rdparty/luv/tests/test-async.lua32
-rw-r--r--3rdparty/luv/tests/test-conversions.lua6
-rw-r--r--3rdparty/luv/tests/test-dns.lua125
-rw-r--r--3rdparty/luv/tests/test-fs.lua90
-rw-r--r--3rdparty/luv/tests/test-leaks.lua186
-rw-r--r--3rdparty/luv/tests/test-misc.lua85
-rw-r--r--3rdparty/luv/tests/test-prepare-check-idle-async.lua49
-rw-r--r--3rdparty/luv/tests/test-process.lua101
-rw-r--r--3rdparty/luv/tests/test-sigchld-after-lua_close.sh45
-rw-r--r--3rdparty/luv/tests/test-signal.lua40
-rw-r--r--3rdparty/luv/tests/test-tcp.lua114
-rw-r--r--3rdparty/luv/tests/test-thread.lua47
-rw-r--r--3rdparty/luv/tests/test-timer.lua87
-rw-r--r--3rdparty/luv/tests/test-work.lua48
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)