mirror of
https://github.com/bryanthaboi/gen1recomp
synced 2026-10-03 08:07:07 -04:00
123 lines
5.5 KiB
Lua
123 lines
5.5 KiB
Lua
package.path = "./?.lua;./?/init.lua;" .. package.path
|
|
if package.config:sub(1, 1) == "\\" then
|
|
print("[skip] Ubuntu CI runner requires a POSIX shell")
|
|
os.exit(0)
|
|
end
|
|
local T = require("tests.harness")
|
|
local Runner = require("tests.tier_runner")
|
|
local Groups = require("tests.save_compat._groups")
|
|
|
|
local function capture(command)
|
|
local pipe = assert(io.popen(command))
|
|
local text = pipe:read("*a")
|
|
pipe:close()
|
|
return text
|
|
end
|
|
|
|
local names = {}
|
|
for name in capture("bash scripts/test.sh --list-groups"):gmatch("[^\r\n]+") do
|
|
names[#names + 1] = name
|
|
end
|
|
T.eq(#names, 8, "eight named ROM-free groups")
|
|
local workflow = assert(io.open(".github/workflows/ci.yml", "rb"))
|
|
local text = workflow:read("*a")
|
|
workflow:close()
|
|
local aggregate = assert(text:match(" headless:\n(.-) headless%-groups:"))
|
|
T.check(aggregate:find("name: headless suites (no ROM)", 1, true), "required branch check keeps its name")
|
|
T.check(aggregate:find("needs: headless-groups", 1, true), "required check waits for every matrix child")
|
|
T.check(aggregate:find("if: ${{ always() }}", 1, true), "required check runs after failed or skipped groups")
|
|
T.check(aggregate:find("HEADLESS_RESULT: ${{ needs.headless-groups.result }}", 1, true),
|
|
"required check reads the combined matrix result")
|
|
local gate = assert(aggregate:match(" run: |\n(.*)")):gsub("\n ", "\n"):gsub("^ ", "")
|
|
local gatePath = os.tmpname()
|
|
local gateFile = assert(io.open(gatePath, "wb"))
|
|
gateFile:write(gate)
|
|
gateFile:close()
|
|
for _, status in ipairs({ "success", "failure", "cancelled", "skipped" }) do
|
|
local result = os.execute("HEADLESS_RESULT=" .. status .. " bash " .. gatePath .. " >/dev/null 2>&1")
|
|
T.eq(result == 0 or result == true, status == "success", "required check handles " .. status)
|
|
end
|
|
os.remove(gatePath)
|
|
local headless = assert(text:match(" headless%-groups:\n(.-) fixture%-dataset:"))
|
|
local configured = {}
|
|
for name in headless:gmatch("%- group: ([%w%-]+)") do
|
|
T.check(not configured[name], "CI group occurs once: " .. name)
|
|
configured[name] = true
|
|
end
|
|
T.check(headless:find('run: ./scripts/test.sh --group "${{ matrix.group }}"', 1, true),
|
|
"CI executes the selected group")
|
|
T.check(headless:find("fail-fast: false", 1, true), "one failing group does not cancel the others")
|
|
|
|
local prefix = "POKEPORT_TEST_CACHES=/tmp/no-headless-group-cache POKEPORT_IDENTITY=ci-group-plan "
|
|
.. "RED_CACHE= BLUE_CACHE= YELLOW_CACHE= GOLD_CACHE= SILVER_CACHE= CRYSTAL_CACHE= "
|
|
local function plan(group)
|
|
local result = {}
|
|
local output = capture(prefix .. "bash scripts/test.sh --quick --list --group " .. group)
|
|
T.check(output:find("tests were not run", 1, true), "listing does not execute tests: " .. group)
|
|
for label in output:gmatch("%[tier%] ([^\r\n]+)") do
|
|
T.check(not result[label], "tier occurs once in " .. group .. ": " .. label)
|
|
result[label] = true
|
|
end
|
|
return result
|
|
end
|
|
local all, assigned = plan("all"), {}
|
|
for _, name in ipairs(names) do
|
|
T.check(configured[name], "CI includes " .. name)
|
|
configured[name] = nil
|
|
local selected = plan(name)
|
|
T.check(next(selected) ~= nil, "group is not empty: " .. name)
|
|
for label in pairs(selected) do
|
|
T.check(all[label], "group tier belongs to the full suite: " .. label)
|
|
T.check(not assigned[label], "tier belongs to exactly one CI group: " .. label)
|
|
assigned[label] = name
|
|
end
|
|
end
|
|
T.check(next(configured) == nil, "CI has no unknown groups")
|
|
for label in pairs(all) do
|
|
T.check(assigned[label], "full ROM-free tier is covered in CI: " .. label)
|
|
end
|
|
|
|
local counts, seen = {}, {}
|
|
for _, path in ipairs(Runner.suites("tests/save_compat")) do
|
|
local group = Groups.of(path)
|
|
T.check(Groups.valid[group], "every save suite has a group: " .. path)
|
|
counts[group] = (counts[group] or 0) + 1
|
|
seen[path:match("([^/]+)%.lua$")] = true
|
|
end
|
|
for name in pairs(Groups.named) do
|
|
T.check(seen[name], "named save suite exists: " .. name)
|
|
end
|
|
for group in pairs(Groups.valid) do
|
|
T.check((counts[group] or 0) > 0, "save group is not empty: " .. group)
|
|
end
|
|
T.eq(Groups.of("tests/save_compat/future_codec_test.lua"), "codecs", "new save tests remain covered")
|
|
local invalid = os.execute("bash scripts/test.sh --group nonexistent >/dev/null 2>&1")
|
|
T.check(invalid ~= 0 and invalid ~= true, "unknown group fails instead of running the full suite")
|
|
invalid = os.execute("luajit tests/run_save_compat.lua --group nonexistent >/dev/null 2>&1")
|
|
T.check(invalid ~= 0 and invalid ~= true, "unknown save group fails")
|
|
|
|
-- Exercise real child-process success, failure and an empty filter.
|
|
local dir = os.tmpname()
|
|
os.remove(dir)
|
|
assert(os.execute("mkdir -p " .. dir) == 0)
|
|
for name, exitCode in pairs({ pass = 0, fail = 7 }) do
|
|
local file = assert(io.open(dir .. "/" .. name .. ".lua", "wb"))
|
|
file:write("exit " .. exitCode .. "\n")
|
|
file:close()
|
|
end
|
|
local oldInterpreter, oldPrint = arg[-1], print
|
|
arg[-1], print = "sh", function() end
|
|
local passed, passedTotal = Runner.run({ dir }, "filtered pass", function(p) return p:match("/pass%.lua$") end)
|
|
local failed, failedTotal = Runner.run({ dir }, "filtered fail", function(p) return p:match("/fail%.lua$") end)
|
|
local empty = Runner.run({ dir }, "empty", function() return false end)
|
|
arg[-1], print = oldInterpreter, oldPrint
|
|
T.eq(passed, 0, "successful selected child passes")
|
|
T.eq(passedTotal, 1, "unselected failing child is not run")
|
|
T.eq(failed, 1, "selected child failure propagates")
|
|
T.eq(failedTotal, 1, "failure reports the selected count")
|
|
T.eq(empty, 1, "empty group cannot pass vacuously")
|
|
os.remove(dir .. "/pass.lua")
|
|
os.remove(dir .. "/fail.lua")
|
|
os.execute("rmdir " .. dir)
|
|
T.finish("headless CI groups")
|