From d6279f9392073cb1422d76c57baf3fd283ed954e Mon Sep 17 00:00:00 2001 From: bfredl Date: Tue, 31 Jan 2023 23:35:04 +0100 Subject: refactor(tests): move lua-client into core and use it for functionaltests Eliminates lua-client and non-static libluv as test time dependencies Note: the API for a public lua-client is not yet finished. The interface needs to be adjusted to work in the embedded loop of a nvim instance (to use it to talk between instances) --- test/client/uv_stream.lua | 164 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 164 insertions(+) create mode 100644 test/client/uv_stream.lua (limited to 'test/client/uv_stream.lua') diff --git a/test/client/uv_stream.lua b/test/client/uv_stream.lua new file mode 100644 index 0000000000..1f4414c934 --- /dev/null +++ b/test/client/uv_stream.lua @@ -0,0 +1,164 @@ +local uv = require('luv') + +local StdioStream = {} +StdioStream.__index = StdioStream + +function StdioStream.open() + local self = setmetatable({ + _in = uv.new_pipe(false), + _out = uv.new_pipe(false) + }, StdioStream) + self._in:open(0) + self._out:open(1) + return self +end + +function StdioStream:write(data) + self._out:write(data) +end + +function StdioStream:read_start(cb) + self._in:read_start(function(err, chunk) + if err then + error(err) + end + cb(chunk) + end) +end + +function StdioStream:read_stop() + self._in:read_stop() +end + +function StdioStream:close() + self._in:close() + self._out:close() +end + +local SocketStream = {} +SocketStream.__index = SocketStream + +function SocketStream.open(file) + local socket = uv.new_pipe(false) + local self = setmetatable({ + _socket = socket, + _stream_error = nil + }, SocketStream) + uv.pipe_connect(socket, file, function (err) + self._stream_error = self._stream_error or err + end) + return self +end + +function SocketStream.connect(host, port) + local socket = uv.new_tcp() + local self = setmetatable({ + _socket = socket, + _stream_error = nil + }, SocketStream) + uv.tcp_connect(socket, host, port, function (err) + self._stream_error = self._stream_error or err + end) + return self +end + + +function SocketStream:write(data) + if self._stream_error then + error(self._stream_error) + end + uv.write(self._socket, data, function(err) + if err then + error(self._stream_error or err) + end + end) +end + +function SocketStream:read_start(cb) + if self._stream_error then + error(self._stream_error) + end + uv.read_start(self._socket, function(err, chunk) + if err then + error(err) + end + cb(chunk) + end) +end + +function SocketStream:read_stop() + if self._stream_error then + error(self._stream_error) + end + uv.read_stop(self._socket) +end + +function SocketStream:close() + uv.close(self._socket) +end + +local ChildProcessStream = {} +ChildProcessStream.__index = ChildProcessStream + +function ChildProcessStream.spawn(argv, env, io_extra) + local self = setmetatable({ + _child_stdin = uv.new_pipe(false), + _child_stdout = uv.new_pipe(false) + }, ChildProcessStream) + local prog = argv[1] + local args = {} + for i = 2, #argv do + args[#args + 1] = argv[i] + end + self._proc, self._pid = uv.spawn(prog, { + stdio = {self._child_stdin, self._child_stdout, 2, io_extra}, + args = args, + env = env, + }, function() + self:close() + end) + + if not self._proc then + local err = self._pid + error(err) + end + + return self +end + +function ChildProcessStream:write(data) + self._child_stdin:write(data) +end + +function ChildProcessStream:read_start(cb) + self._child_stdout:read_start(function(err, chunk) + if err then + error(err) + end + cb(chunk) + end) +end + +function ChildProcessStream:read_stop() + self._child_stdout:read_stop() +end + +function ChildProcessStream:close(signal) + if self._closed then + return + end + self._closed = true + self:read_stop() + self._child_stdin:close() + self._child_stdout:close() + if type(signal) == 'string' then + self._proc:kill('sig'..signal) + end + uv.run('nowait') +end + +return { + StdioStream = StdioStream; + ChildProcessStream = ChildProcessStream; + SocketStream = SocketStream; +} -- cgit From 0837980db4958baca96449869d31120f349f3500 Mon Sep 17 00:00:00 2001 From: bfredl Date: Fri, 10 Feb 2023 10:26:18 +0100 Subject: fix(client): wait for session to exit This replicates the old native.pid_wait(self._pid) call, except using the proper libuv pattern (run loop unitil exit callback) --- test/client/uv_stream.lua | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) (limited to 'test/client/uv_stream.lua') diff --git a/test/client/uv_stream.lua b/test/client/uv_stream.lua index 1f4414c934..cea77f0dbd 100644 --- a/test/client/uv_stream.lua +++ b/test/client/uv_stream.lua @@ -102,8 +102,9 @@ ChildProcessStream.__index = ChildProcessStream function ChildProcessStream.spawn(argv, env, io_extra) local self = setmetatable({ - _child_stdin = uv.new_pipe(false), - _child_stdout = uv.new_pipe(false) + _child_stdin = uv.new_pipe(false); + _child_stdout = uv.new_pipe(false); + _exiting = false; }, ChildProcessStream) local prog = argv[1] local args = {} @@ -114,8 +115,9 @@ function ChildProcessStream.spawn(argv, env, io_extra) stdio = {self._child_stdin, self._child_stdout, 2, io_extra}, args = args, env = env, - }, function() - self:close() + }, function(status, signal) + self.status = status + self.signal = signal end) if not self._proc then @@ -154,7 +156,10 @@ function ChildProcessStream:close(signal) if type(signal) == 'string' then self._proc:kill('sig'..signal) end - uv.run('nowait') + while self.status == nil do + uv.run 'once' + end + return self.status, self.signal end return { -- cgit