aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWilliam Boman <william@redwill.se>2022-07-13 16:21:16 +0200
committerGitHub <noreply@github.com>2022-07-13 16:21:16 +0200
commitfa78d7cf0445083243cdd8feee4923f99d984e30 (patch)
tree79d684df539b3a39dc14742335c38d5b19a0e072
parentfix(api): fix the :MasonUninstall command (#66) (diff)
downloadmason-fa78d7cf0445083243cdd8feee4923f99d984e30.tar
mason-fa78d7cf0445083243cdd8feee4923f99d984e30.tar.gz
mason-fa78d7cf0445083243cdd8feee4923f99d984e30.tar.bz2
mason-fa78d7cf0445083243cdd8feee4923f99d984e30.tar.lz
mason-fa78d7cf0445083243cdd8feee4923f99d984e30.tar.xz
mason-fa78d7cf0445083243cdd8feee4923f99d984e30.tar.zst
mason-fa78d7cf0445083243cdd8feee4923f99d984e30.zip
tests: add some InstallHandle tests (#67)
-rw-r--r--lua/mason-core/installer/context.lua4
-rw-r--r--lua/mason-core/installer/handle.lua68
-rw-r--r--lua/mason/ui/instance.lua8
-rw-r--r--tests/mason-core/installer/handle_spec.lua100
-rw-r--r--tests/mason-core/installer/installer_spec.lua (renamed from tests/mason-core/installer_spec.lua)0
5 files changed, 140 insertions, 40 deletions
diff --git a/lua/mason-core/installer/context.lua b/lua/mason-core/installer/context.lua
index 9dfbb7f1..3e701d8e 100644
--- a/lua/mason-core/installer/context.lua
+++ b/lua/mason-core/installer/context.lua
@@ -26,14 +26,14 @@ function ContextualSpawn.__index(self, cmd)
local captured_handle
args.on_spawn = function(handle, stdio, pid, ...)
captured_handle = handle
- self.handle:push_spawninfo(handle, pid, cmd, spawn._flatten_cmd_args(args))
+ self.handle:register_spawn_handle(handle, pid, cmd, spawn._flatten_cmd_args(args))
if on_spawn then
on_spawn(handle, stdio, pid, ...)
end
end
local function pop_spawn_stack()
if captured_handle then
- self.handle:pop_spawninfo(captured_handle)
+ self.handle:deregister_spawn_handle(captured_handle)
end
end
-- We get_or_throw() here for convenience reasons.
diff --git a/lua/mason-core/installer/handle.lua b/lua/mason-core/installer/handle.lua
index 459e3704..f2e7aa1d 100644
--- a/lua/mason-core/installer/handle.lua
+++ b/lua/mason-core/installer/handle.lua
@@ -15,20 +15,20 @@ local uv = vim.loop
--- | '"ACTIVE"'
--- | '"CLOSED"'
----@class InstallHandleSpawnInfo
----@field handle luv_handle
+---@class InstallHandleSpawnHandle
+---@field uv_handle luv_handle
---@field pid integer
---@field cmd string
---@field args string[]
-local InstallHandleSpawnInfo = {}
-InstallHandleSpawnInfo.__index = InstallHandleSpawnInfo
+local InstallHandleSpawnHandle = {}
+InstallHandleSpawnHandle.__index = InstallHandleSpawnHandle
----@param fields InstallHandleSpawnInfo
-function InstallHandleSpawnInfo.new(fields)
- return setmetatable(fields, InstallHandleSpawnInfo)
+---@param fields InstallHandleSpawnHandle
+function InstallHandleSpawnHandle.new(fields)
+ return setmetatable(fields, InstallHandleSpawnHandle)
end
-function InstallHandleSpawnInfo:__tostring()
+function InstallHandleSpawnHandle:__tostring()
return ("%s %s"):format(self.cmd, table.concat(self.args, " "))
end
@@ -37,7 +37,7 @@ end
---@field state InstallHandleState
---@field stdio { buffers: { stdout: string[], stderr: string[] }, sink: StdioSink }
---@field is_terminated boolean
----@field private spawninfo_stack InstallHandleSpawnInfo[]
+---@field private spawn_handles InstallHandleSpawnHandle[]
local InstallHandle = setmetatable({}, { __index = EventEmitter })
local InstallHandleMt = { __index = InstallHandle }
@@ -64,7 +64,7 @@ function InstallHandle.new(pkg)
local self = EventEmitter.init(setmetatable({}, InstallHandleMt))
self.state = "IDLE"
self.package = pkg
- self.spawninfo_stack = {}
+ self.spawn_handles = {}
self.stdio = new_sink(self)
self.is_terminated = false
return self
@@ -74,34 +74,34 @@ end
---@param pid integer
---@param cmd string
---@param args string[]
-function InstallHandle:push_spawninfo(luv_handle, pid, cmd, args)
- local spawninfo = InstallHandleSpawnInfo.new {
- handle = luv_handle,
+function InstallHandle:register_spawn_handle(luv_handle, pid, cmd, args)
+ local spawn_handles = InstallHandleSpawnHandle.new {
+ uv_handle = luv_handle,
pid = pid,
cmd = cmd,
args = args,
}
- log.fmt_trace("Pushing spawninfo stack for %s: %s (pid: %s)", self, spawninfo, pid)
- self.spawninfo_stack[#self.spawninfo_stack + 1] = spawninfo
- self:emit "spawninfo:change"
+ log.fmt_trace("Pushing spawn_handles stack for %s: %s (pid: %s)", self, spawn_handles, pid)
+ self.spawn_handles[#self.spawn_handles + 1] = spawn_handles
+ self:emit "spawn_handles:change"
end
---@param luv_handle luv_handle
-function InstallHandle:pop_spawninfo(luv_handle)
- for i = #self.spawninfo_stack, 1, -1 do
- if self.spawninfo_stack[i].handle == luv_handle then
- log.fmt_trace("Popping spawninfo stack for %s: %s", self, self.spawninfo_stack[i])
- table.remove(self.spawninfo_stack, i)
- self:emit "spawninfo:change"
+function InstallHandle:deregister_spawn_handle(luv_handle)
+ for i = #self.spawn_handles, 1, -1 do
+ if self.spawn_handles[i].uv_handle == luv_handle then
+ log.fmt_trace("Popping spawn_handles stack for %s: %s", self, self.spawn_handles[i])
+ table.remove(self.spawn_handles, i)
+ self:emit "spawn_handles:change"
return true
end
end
return false
end
----@return Optional @Optional<InstallHandleSpawnInfo>
-function InstallHandle:peek_spawninfo_stack()
- return Optional.of_nilable(self.spawninfo_stack[#self.spawninfo_stack])
+---@return Optional @Optional<InstallHandleSpawnHandle>
+function InstallHandle:peek_spawn_handle()
+ return Optional.of_nilable(self.spawn_handles[#self.spawn_handles])
end
function InstallHandle:is_idle()
@@ -132,8 +132,8 @@ end
function InstallHandle:kill(signal)
assert(not self:is_closed(), "Cannot kill closed handle.")
log.fmt_trace("Sending signal %s to luv handles in %s", signal, self)
- for _, spawninfo in pairs(self.spawninfo_stack) do
- process.kill(spawninfo.handle, signal)
+ for _, spawn_handles in pairs(self.spawn_handles) do
+ process.kill(spawn_handles.uv_handle, signal)
end
self:emit("kill", signal)
end
@@ -157,8 +157,8 @@ function InstallHandle:terminate()
log.fmt_trace("Terminating %s", self)
-- https://github.com/libuv/libuv/issues/1133
if platform.is.win then
- for _, spawninfo in ipairs(self.spawninfo_stack) do
- win_taskkill(spawninfo.pid)
+ for _, spawn_handles in ipairs(self.spawn_handles) do
+ win_taskkill(spawn_handles.pid)
end
else
self:kill(15) -- SIGTERM
@@ -167,8 +167,8 @@ function InstallHandle:terminate()
self:emit "terminate"
local check = uv.new_check()
check:start(function()
- for _, spawninfo in ipairs(self.spawninfo_stack) do
- local luv_handle = spawninfo.handle
+ for _, spawn_handles in ipairs(self.spawn_handles) do
+ local luv_handle = spawn_handles.uv_handle
local ok, is_closing = pcall(luv_handle.is_closing, luv_handle)
if ok and not is_closing then
return
@@ -194,14 +194,14 @@ end
function InstallHandle:close()
log.fmt_trace("Closing %s", self)
assert(not self:is_closed(), "Handle is already closed.")
- for _, spawninfo in ipairs(self.spawninfo_stack) do
- local luv_handle = spawninfo.handle
+ for _, spawn_handles in ipairs(self.spawn_handles) do
+ local luv_handle = spawn_handles.uv_handle
local ok, is_closing = pcall(luv_handle.is_closing, luv_handle)
if ok then
assert(is_closing, "There are open libuv handles.")
end
end
- self.spawninfo_stack = {}
+ self.spawn_handles = {}
self:set_state "CLOSED"
self:emit "closed"
self:clear_event_handlers()
diff --git a/lua/mason/ui/instance.lua b/lua/mason/ui/instance.lua
index beb73705..7a9b98fa 100644
--- a/lua/mason/ui/instance.lua
+++ b/lua/mason/ui/instance.lua
@@ -187,10 +187,10 @@ local function setup_handle(handle)
end
end
- local function handle_spawninfo_change()
+ local function handle_spawnhandle_change()
mutate_state(function(state)
state.packages.states[handle.package.name].latest_spawn =
- handle:peek_spawninfo_stack():map(tostring):or_else(nil)
+ handle:peek_spawn_handle():map(tostring):or_else(nil)
end)
end
@@ -229,14 +229,14 @@ local function setup_handle(handle)
handle:on("terminate", handle_terminate)
handle:on("state:change", handle_state_change)
- handle:on("spawninfo:change", handle_spawninfo_change)
+ handle:on("spawn_handles:change", handle_spawnhandle_change)
handle:on("stdout", handle_output)
handle:on("stderr", handle_output)
-- hydrate initial state
handle_state_change(handle.state)
handle_terminate()
- handle_spawninfo_change()
+ handle_spawnhandle_change()
mutate_state(function(state)
state.packages.states[handle.package.name].tailed_output = {}
end)
diff --git a/tests/mason-core/installer/handle_spec.lua b/tests/mason-core/installer/handle_spec.lua
new file mode 100644
index 00000000..02fcc358
--- /dev/null
+++ b/tests/mason-core/installer/handle_spec.lua
@@ -0,0 +1,100 @@
+local a = require "mason-core.async"
+local mock = require "luassert.mock"
+local stub = require "luassert.stub"
+local spy = require "luassert.spy"
+local InstallHandle = require "mason-core.installer.handle"
+
+describe("installer handle", function()
+ it("should register spawn handle", function()
+ local handle = InstallHandle.new(mock.new {})
+ local spawn_handle_change_handler = spy.new()
+ handle:once("spawn_handles:change", spawn_handle_change_handler)
+ local luv_handle = mock.new {}
+ handle:register_spawn_handle(luv_handle, 1337, "tar", { "-xvf", "file" })
+ assert.same({
+ uv_handle = luv_handle,
+ pid = 1337,
+ cmd = "tar",
+ args = { "-xvf", "file" },
+ }, handle:peek_spawn_handle():get())
+ assert.spy(spawn_handle_change_handler).was_called(1)
+ end)
+
+ it("should deregister spawn handle", function()
+ local handle = InstallHandle.new(mock.new {})
+ local spawn_handle_change_handler = spy.new()
+ handle:once("spawn_handles:change", spawn_handle_change_handler)
+ local luv_handle1 = mock.new {}
+ local luv_handle2 = mock.new {}
+ handle:register_spawn_handle(luv_handle1, 42, "curl", { "someurl" })
+ handle:register_spawn_handle(luv_handle2, 1337, "tar", { "-xvf", "file" })
+ assert.is_true(handle:deregister_spawn_handle(luv_handle1))
+ assert.equals(1, #handle.spawn_handles)
+ assert.same({
+ uv_handle = luv_handle2,
+ pid = 1337,
+ cmd = "tar",
+ args = { "-xvf", "file" },
+ }, handle:peek_spawn_handle():get())
+ assert.spy(spawn_handle_change_handler).was_called(3)
+ end)
+
+ it("should change state", function()
+ local handle = InstallHandle.new(mock.new {})
+ local state_change_handler = spy.new()
+ handle:once("state:change", state_change_handler)
+ handle:set_state "QUEUED"
+ assert.equals("QUEUED", handle.state)
+ assert.spy(state_change_handler).was_called(1)
+ assert.spy(state_change_handler).was_called_with("QUEUED", "IDLE")
+ end)
+
+ it("should send signals to registered handles", function()
+ local process = require "mason-core.process"
+ stub(process, "kill")
+ local uv_handle = {}
+ local handle = InstallHandle.new(mock.new {})
+ local kill_handler = spy.new()
+ handle:once("kill", kill_handler)
+ handle.state = "ACTIVE"
+ handle.spawn_handles = { { uv_handle = uv_handle } }
+
+ handle:kill(9)
+ assert.spy(process.kill).was_called(1)
+ assert.spy(process.kill).was_called_with(uv_handle, 9)
+ assert.spy(kill_handler).was_called(1)
+ assert.spy(kill_handler).was_called_with(9)
+ end)
+
+ it(
+ "should terminate handle",
+ async_test(function()
+ local process = require "mason-core.process"
+ stub(process, "kill")
+ local uv_handle1 = {}
+ local uv_handle2 = {}
+ local handle = InstallHandle.new(mock.new {})
+ local kill_handler = spy.new()
+ local terminate_handler = spy.new()
+ local closed_handler = spy.new()
+ handle:once("kill", kill_handler)
+ handle:once("terminate", terminate_handler)
+ handle:once("closed", closed_handler)
+ handle.state = "ACTIVE"
+ handle.spawn_handles = { { uv_handle = uv_handle2 }, { uv_handle = uv_handle2 } }
+
+ handle:terminate()
+ assert.spy(process.kill).was_called(2)
+ assert.spy(process.kill).was_called_with(uv_handle1, 15)
+ assert.spy(process.kill).was_called_with(uv_handle2, 15)
+ assert.spy(kill_handler).was_called(1)
+ assert.spy(kill_handler).was_called_with(15)
+ assert.spy(terminate_handler).was_called(1)
+ assert.is_true(handle.is_terminated)
+ assert.wait_for(function()
+ assert.is_true(handle:is_closed())
+ assert.spy(closed_handler).was_called(1)
+ end)
+ end)
+ )
+end)
diff --git a/tests/mason-core/installer_spec.lua b/tests/mason-core/installer/installer_spec.lua
index 8dc9b516..8dc9b516 100644
--- a/tests/mason-core/installer_spec.lua
+++ b/tests/mason-core/installer/installer_spec.lua