lune/tests/process/spawn.luau
2023-08-22 20:00:58 -05:00

145 lines
3.9 KiB
Lua

local process = require("@lune/process")
local stdio = require("@lune/stdio")
local task = require("@lune/task")
-- Spawning a child process should work, with options
local thread = task.delay(1, function()
stdio.ewrite("Spawning a process should take a reasonable amount of time\n")
task.wait(1)
process.exit(1)
end)
local result = process.spawn("ls", {
"-a",
})
task.cancel(thread)
assert(result.ok, "Failed to spawn child process")
assert(result.stderr == "", "Stderr was not empty")
assert(result.stdout ~= "", "Stdout was empty")
assert(string.find(result.stdout, "Cargo.toml") ~= nil, "Missing Cargo.toml in output")
assert(string.find(result.stdout, ".gitignore") ~= nil, "Missing .gitignore in output")
-- It should also work the same when spawned using a shell
local shellResult = process.spawn("ls", {
"-a",
}, {
shell = true,
})
assert(shellResult.ok, "Failed to spawn child process (shell)")
assert(shellResult.stderr == "", "Stderr was not empty (shell)")
assert(shellResult.stdout ~= "", "Stdout was empty (shell)")
assert(string.find(shellResult.stdout, "Cargo.toml") ~= nil, "Missing Cargo.toml in output (shell)")
assert(string.find(shellResult.stdout, ".gitignore") ~= nil, "Missing .gitignore in output (shell)")
-- Make sure the cwd option actually uses the directory we want
local rootPwd = process.spawn("pwd", {}, {
cwd = "/",
}).stdout
rootPwd = string.gsub(rootPwd, "^%s+", "")
rootPwd = string.gsub(rootPwd, "%s+$", "")
if rootPwd ~= "/" then
error(
string.format(
"Current working directory for child process was not set correctly!"
.. "\nExpected '/', got '%s'",
rootPwd
)
)
end
-- Setting cwd should not change the cwd of this process
local pwdBefore = process.spawn("pwd").stdout
process.spawn("ls", {}, {
cwd = "/",
shell = true,
})
local pwdAfter = process.spawn("pwd").stdout
assert(pwdBefore == pwdAfter, "Current working directory changed after running child process")
--[[
Setting the cwd on a child process should properly
replace any leading ~ with the users real home dir
]]
local homeDir1 = process.spawn("echo $HOME", nil, {
shell = true,
}).stdout
local homeDir2 = process.spawn("pwd", nil, {
shell = true,
cwd = "~",
}).stdout
assert(#homeDir1 > 0, "Home dir from echo was empty")
assert(#homeDir2 > 0, "Home dir from pwd was empty")
assert(homeDir1 == homeDir2, "Home dirs did not match when performing tilde substitution")
-- FIXME: The below tests with sleeping do not work properly and block
-- indefinitely, causing cargo test to timeout, for now we error prematurely
error("FIXME")
--[[
Spawning a process should not block any lua thread(s)
We test this by sleeping more than once concurrently
and then ensuring that the total time slept is more
than a single sleep but also less than 1.5 sleeps
]]
local SLEEP_DURATION = 1 / 4
local SLEEP_SAMPLES = 2
local thread2 = task.delay(SLEEP_DURATION * 1.5, function()
stdio.ewrite("Spawning a sleep process should take a reasonable amount of time\n")
task.wait(1)
process.exit(1)
end)
local sleepStart = os.clock()
local sleepCounter = 0
for i = 1, SLEEP_SAMPLES, 1 do
task.spawn(function()
process.spawn("sleep", { tostring(SLEEP_DURATION) })
sleepCounter += 1
end)
end
while sleepCounter < SLEEP_SAMPLES do
task.wait()
end
task.cancel(thread2)
local sleepElapsed = os.clock() - sleepStart
assert(
sleepElapsed >= SLEEP_DURATION,
"Spawning a process that does blocking sleep did not sleep enough"
)
assert(
sleepElapsed < SLEEP_DURATION * 1.5,
"Coroutine yielded the main lua thread during process yield"
)
-- Inheriting stdio & environment variables should work
local echoMessage = "Hello from child process!"
local echoResult = process.spawn("echo", {
'"$TEST_VAR"',
}, {
env = { TEST_VAR = echoMessage },
shell = "bash",
stdio = "inherit",
})
assert(
echoResult.stdout == (echoMessage .. "\n"), -- Note that echo adds a newline
"Inheriting stdio did not return proper output"
)