From 79bd1739d8ca004ddd0b2fa5e24da4a6f4b776fa Mon Sep 17 00:00:00 2001 From: Hisham Muhammad Date: Wed, 21 Feb 2024 22:30:40 -0300 Subject: tests: introduce quick tests --- .github/workflows/test.yml | 4 +- appveyor.yml | 14 +- spec/build_spec.lua | 40 +---- spec/config_spec.lua | 16 -- spec/list_spec.lua | 5 - spec/quick/build.q | 122 ++++++++++++++ spec/quick/config.q | 17 ++ spec/quick/install.q | 124 +++++++++++++++ spec/quick/list.q | 10 ++ spec/quick_spec.lua | 20 +++ spec/rockspecs_spec.lua | 2 +- spec/util/quick.lua | 384 +++++++++++++++++++++++++++++++++++++++++++++ spec/util/test_env.lua | 16 +- 13 files changed, 706 insertions(+), 68 deletions(-) create mode 100644 spec/quick/build.q create mode 100644 spec/quick/config.q create mode 100644 spec/quick/install.q create mode 100644 spec/quick/list.q create mode 100644 spec/quick_spec.lua create mode 100644 spec/util/quick.lua diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 603a5613..07803faf 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -54,8 +54,8 @@ jobs: - name: Integration Test run: | eval $(luarocks path) - busted -o htest --exclude-tags=ssh,gpg,git,unit --verbose -Xhelper "lua_dir=$(luarocks config variables.LUA_DIR),ci" - busted -o htest --exclude-tags=ssh,gpg,git,unit --verbose -Xhelper "lua_dir=$(luarocks config variables.LUA_DIR),ci,env=full" + busted -o htest --exclude-tags=ssh,gpg,git,unit,quick --verbose -Xhelper "lua_dir=$(luarocks config variables.LUA_DIR),ci" + busted -o htest --exclude-tags=ssh,gpg,git,unit,quick --verbose -Xhelper "lua_dir=$(luarocks config variables.LUA_DIR),ci,env=full" - name: Coverage run: | diff --git a/appveyor.yml b/appveyor.yml index b084cff5..0d350d8a 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -9,17 +9,23 @@ environment: LUAROCKS_VER: 3.0.0 matrix: + # quick tests + - LUAV: "2.1" + LUAT: "luajit" + COMPILER: "vs" + FILES: "" + EXCLUDE: "integration,unit" # Lua 5.4 tests - LUAV: "5.4" LUAT: "lua" COMPILER: "vs" FILES: "" - EXCLUDE: "integration" + EXCLUDE: "integration,quick" - LUAV: "5.4" LUAT: "lua" COMPILER: "vs" FILES: "" - EXCLUDE: "unit" + EXCLUDE: "unit,quick" - LUAV: "5.4" LUAT: "lua" COMPILER: "mingw" @@ -30,12 +36,12 @@ environment: LUAT: "luajit" COMPILER: "vs" FILES: "" - EXCLUDE: "integration" + EXCLUDE: "integration,quick" - LUAV: "2.1" LUAT: "luajit" COMPILER: "vs" FILES: "" - EXCLUDE: "unit" + EXCLUDE: "unit,quick" - LUAV: "2.1" LUAT: "luajit" COMPILER: "mingw" diff --git a/spec/build_spec.lua b/spec/build_spec.lua index 3b33a1aa..5e78aa4f 100644 --- a/spec/build_spec.lua +++ b/spec/build_spec.lua @@ -49,45 +49,7 @@ describe("LuaRocks build #integration", function() test_env.setup_specs(extra_rocks) end) - describe("basic testing set", function() - it("invalid", function() - assert.is_false(run.luarocks_bool("build invalid")) - end) - - it("with no arguments behaves as luarocks make", function() - test_env.run_in_tmp(function(tmpdir) - write_file("c_module-1.0-1.rockspec", [[ - package = "c_module" - version = "1.0-1" - source = { - url = "http://example.com/c_module" - } - build = { - type = "builtin", - modules = { - c_module = { "c_module.c" } - } - } - ]], finally) - write_file("c_module.c", c_module_source, finally) - - assert.is_true(run.luarocks_bool("build")) - assert.truthy(lfs.attributes(tmpdir .. "/c_module." .. test_env.lib_extension)) - end, finally) - end) - end) - describe("building with flags", function() - it("fails if it doesn't have the permissions to access the specified tree #unix", function() - assert.is_false(run.luarocks_bool("build --tree=/usr " .. testing_paths.fixtures_dir .. "/a_rock-1.0.1-rockspec")) - assert.falsy(lfs.attributes(testing_paths.testing_sys_rocks .. "/a_rock/1.0-1/a_rock-1.0-1.rockspec")) - end) - - it("fails if it doesn't have the permissions to access the specified tree's parent #unix", function() - assert.is_false(run.luarocks_bool("build --tree=/usr/invalid " .. testing_paths.fixtures_dir .. "/a_rock-1.0-1.rockspec")) - assert.falsy(lfs.attributes(testing_paths.testing_sys_rocks .. "/a_rock/1.0-1/a_rock-1.0-1.rockspec")) - end) - it("verbose", function() test_env.run_in_tmp(function(tmpdir) write_file("test-1.0-1.rockspec", [[ @@ -429,7 +391,7 @@ describe("LuaRocks build #integration", function() package = "a_rock" version = "1.0-1" source = { - url = "file://]] .. testing_paths.fixtures_dir .. [[/a_rock.lua" + url = "file://]] .. testing_paths.fixtures_dir:gsub("\\", "/") .. [[/a_rock.lua" } description = { summary = "An example rockspec", diff --git a/spec/config_spec.lua b/spec/config_spec.lua index 98fcb24c..9615f050 100644 --- a/spec/config_spec.lua +++ b/spec/config_spec.lua @@ -115,22 +115,6 @@ describe("LuaRocks config tests #integration", function() assert.is_false(run.luarocks_bool("config --system-config")) end) - it("outputs the path of the system config", function() - lfs.mkdir(testing_paths.testing_lrprefix) - lfs.mkdir(testing_paths.testing_lrprefix .. "/etc/") - lfs.mkdir(scdir) - - local sysconfig = io.open(configfile, "w+") - sysconfig:write(" ") - sysconfig:close() - finally(function() - os.remove(configfile) - end) - - local output = run.luarocks("config --system-config") - assert.are.same(configfile, output) - end) - it("fails if system config is invalid", function() lfs.mkdir(testing_paths.testing_lrprefix) lfs.mkdir(testing_paths.testing_lrprefix .. "/etc/") diff --git a/spec/list_spec.lua b/spec/list_spec.lua index 54c63bea..4c7fc776 100644 --- a/spec/list_spec.lua +++ b/spec/list_spec.lua @@ -38,9 +38,4 @@ describe("luarocks list #integration", function() assert.is.truthy(output:find("say")) assert.matches("1.0-1 < ", output, 1, true) end) - - it("invalid tree", function() - local output = run.luarocks("--tree=/some/invalid/tree list") - assert(output:find("Rocks installed for Lua "..test_env.lua_version.." in /some/invalid/tree", 1, true)) - end) end) diff --git a/spec/quick/build.q b/spec/quick/build.q new file mode 100644 index 00000000..c6ca433c --- /dev/null +++ b/spec/quick/build.q @@ -0,0 +1,122 @@ +TEST: luarocks build: fails when given invalid argument +RUN: luarocks build aoesuthaoeusahtoeustnaou --only-server=localhost +EXIT: 1 +STDERR: +-------------------------------------------------------------------------------- +Could not find a result named aoesuthaoeusahtoeustnaou +-------------------------------------------------------------------------------- + + + +================================================================================ +TEST: luarocks build: with no arguments behaves as luarocks make + +FILE: c_module-1.0-1.rockspec +-------------------------------------------------------------------------------- +package = "c_module" +version = "1.0-1" +source = { + url = "http://example.com/c_module" +} +build = { + type = "builtin", + modules = { + c_module = { "c_module.c" } + } +} +-------------------------------------------------------------------------------- +FILE: c_module.c +-------------------------------------------------------------------------------- +#include +#include + +int luaopen_c_module(lua_State* L) { + lua_newtable(L); + lua_pushinteger(L, 1); + lua_setfield(L, -2, "c_module"); + return 1; +} +-------------------------------------------------------------------------------- +RUN: luarocks build +EXISTS: c_module.%{lib_extension} + + + +================================================================================ +TEST: luarocks build: defaults to builtin type + +FILE: a_rock-1.0-1.rockspec +-------------------------------------------------------------------------------- +rockspec_format = "3.0" +package = "a_rock" +version = "1.0-1" +source = { + url = "file://%{url(%{fixtures_dir})}/a_rock.lua" +} +description = { + summary = "An example rockspec", +} +dependencies = { + "lua >= 5.1" +} +build = { + modules = { + build = "a_rock.lua" + }, +} +-------------------------------------------------------------------------------- +RUN: luarocks build a_rock-1.0-1.rockspec +RUN: luarocks show a_rock +STDOUT: +-------------------------------------------------------------------------------- +a_rock 1.0 +-------------------------------------------------------------------------------- + + +================================================================================ +TEST: luarocks build: fails if no permissions to access the specified tree #unix + +RUN: luarocks build --tree=/usr ./a_rock-1.0.1-rockspec +EXIT: 4 +STDERR: +-------------------------------------------------------------------------------- +requires exclusive access +use --force-lock +-------------------------------------------------------------------------------- + +NOT_EXISTS: %{testing_sys_rocks}/a_rock/1.0-1/a_rock-1.0-1.rockspec + +RUN: luarocks build --tree=/usr ./a_rock-1.0.1-rockspec --force-lock +EXIT: 4 +STDERR: +-------------------------------------------------------------------------------- +requires exclusive access +failed to force the lock +-------------------------------------------------------------------------------- + +NOT_EXISTS: %{testing_sys_rocks}/a_rock/1.0-1/a_rock-1.0-1.rockspec + + + +================================================================================ +TEST: luarocks build: fails if no permissions to access the parent #unix + +RUN: luarocks build --tree=/usr/invalid ./a_rock-1.0.1-rockspec +EXIT: 4 +STDERR: +-------------------------------------------------------------------------------- +requires exclusive access +use --force-lock +-------------------------------------------------------------------------------- + +NOT_EXISTS: %{testing_sys_rocks}/a_rock/1.0-1/a_rock-1.0-1.rockspec + +RUN: luarocks build --tree=/usr/invalid ./a_rock-1.0.1-rockspec --force-lock +EXIT: 4 +STDERR: +-------------------------------------------------------------------------------- +requires exclusive access +failed to force the lock +-------------------------------------------------------------------------------- + +NOT_EXISTS: %{testing_sys_rocks}/a_rock/1.0-1/a_rock-1.0-1.rockspec diff --git a/spec/quick/config.q b/spec/quick/config.q new file mode 100644 index 00000000..ec338f98 --- /dev/null +++ b/spec/quick/config.q @@ -0,0 +1,17 @@ +================================================================================ +TEST: luarocks config --system-config shows the path of the system config + +MKDIR: %{testing_lrprefix}/etc/luarocks + +FILE: %{testing_lrprefix}/etc/luarocks/config-%{LUA_VERSION}.lua +-------------------------------------------------------------------------------- + +-------------------------------------------------------------------------------- + +RUN: luarocks config --system-config + +STDOUT: +-------------------------------------------------------------------------------- +%{testing_lrprefix}/etc/luarocks/config-%{LUA_VERSION}.lua +-------------------------------------------------------------------------------- +#TODO: ^^^ %{path()} diff --git a/spec/quick/install.q b/spec/quick/install.q new file mode 100644 index 00000000..2bccf2f1 --- /dev/null +++ b/spec/quick/install.q @@ -0,0 +1,124 @@ +=============================================================================== +TEST: luarocks install: handle versioned modules when installing another version with --keep #268 + +FILE: myrock-1.0-1.rockspec +-------------------------------------------------------------------------------- +rockspec_format = "3.0" +package = "myrock" +version = "1.0-1" +source = { + url = "file://%{url(tmpdir)}/rock.lua" +} +build = { + modules = { rock = "rock.lua" } +} +-------------------------------------------------------------------------------- + +FILE: myrock-2.0-1.rockspec +-------------------------------------------------------------------------------- +rockspec_format = "3.0" +package = "myrock" +version = "2.0-1" +source = { + url = "file://%{url(tmpdir)}/rock.lua" +} +build = { + modules = { rock = "rock.lua" } +} +-------------------------------------------------------------------------------- + +FILE: rock.lua +-------------------------------------------------------------------------------- +return "hello" +-------------------------------------------------------------------------------- + +RUN: luarocks build myrock-1.0-1.rockspec +RUN: luarocks pack myrock +RUN: luarocks remove myrock + +RUN: luarocks build myrock-2.0-1.rockspec +RUN: luarocks pack myrock +RUN: luarocks remove myrock + +RUN: luarocks install ./myrock-2.0-1.all.rock + +EXISTS: %{testing_sys_tree}/share/lua/%{LUA_VERSION}/rock.lua + +RUN: luarocks install ./myrock-1.0-1.all.rock --keep + +EXISTS: %{testing_sys_tree}/share/lua/%{LUA_VERSION}/rock.lua +EXISTS: %{testing_sys_tree}/share/lua/%{LUA_VERSION}/myrock_1_0_1-rock.lua + +RUN: luarocks install ./myrock-2.0-1.all.rock + +EXISTS: %{testing_sys_tree}/share/lua/%{LUA_VERSION}/rock.lua +NOT_EXISTS: %{testing_sys_tree}/share/lua/%{LUA_VERSION}/myrock_1_0_1-rock.lua + + + +=============================================================================== +TEST: luarocks install: handle versioned libraries when installing another version with --keep #268 + +FILE: myrock-1.0-1.rockspec +-------------------------------------------------------------------------------- +rockspec_format = "3.0" +package = "myrock" +version = "1.0-1" +source = { + url = "file://%{url(tmpdir)}/c_module.c" +} +build = { + modules = { + c_module = { "c_module.c" } + } +} +-------------------------------------------------------------------------------- + +FILE: myrock-2.0-1.rockspec +-------------------------------------------------------------------------------- +rockspec_format = "3.0" +package = "myrock" +version = "2.0-1" +source = { + url = "file://%{url(tmpdir)}/c_module.c" +} +build = { + modules = { + c_module = { "c_module.c" } + } +} +-------------------------------------------------------------------------------- +FILE: c_module.c +-------------------------------------------------------------------------------- +#include +#include + +int luaopen_c_module(lua_State* L) { + lua_newtable(L); + lua_pushinteger(L, 1); + lua_setfield(L, -2, "c_module"); + return 1; +} +-------------------------------------------------------------------------------- + +RUN: luarocks build myrock-1.0-1.rockspec +RUN: luarocks pack myrock +RUN: luarocks remove myrock + +RUN: luarocks build myrock-2.0-1.rockspec +RUN: luarocks pack myrock +RUN: luarocks remove myrock + +RUN: luarocks install ./myrock-2.0-1.%{platform}.rock + +EXISTS: %{testing_sys_tree}/lib/lua/%{LUA_VERSION}/c_module.%{lib_extension} + +RUN: luarocks install ./myrock-1.0-1.%{platform}.rock --keep + +EXISTS: %{testing_sys_tree}/lib/lua/%{LUA_VERSION}/c_module.%{lib_extension} +EXISTS: %{testing_sys_tree}/lib/lua/%{LUA_VERSION}/myrock_1_0_1-c_module.%{lib_extension} + +RUN: luarocks install ./myrock-2.0-1.%{platform}.rock + +EXISTS: %{testing_sys_tree}/lib/lua/%{LUA_VERSION}/c_module.%{lib_extension} +NOT_EXISTS: %{testing_sys_tree}/lib/lua/%{LUA_VERSION}/myrock_1_0_1-c_module.%{lib_extension} diff --git a/spec/quick/list.q b/spec/quick/list.q new file mode 100644 index 00000000..7cbdee43 --- /dev/null +++ b/spec/quick/list.q @@ -0,0 +1,10 @@ +================================================================================ +TEST: luarocks list: invalid tree + +RUN: luarocks --tree=%{path(/some/invalid/tree)} list + +STDOUT: +-------------------------------------------------------------------------------- +Rocks installed for Lua %{lua_version} in /some/invalid/tree +-------------------------------------------------------------------------------- +#TODO: ^^^ %{path()} diff --git a/spec/quick_spec.lua b/spec/quick_spec.lua new file mode 100644 index 00000000..8b8206cf --- /dev/null +++ b/spec/quick_spec.lua @@ -0,0 +1,20 @@ +local lfs = require("lfs") +local test_env = require("spec.util.test_env") +local quick = require("spec.util.quick") + +describe("quick tests: #quick", function() + before_each(function() + test_env.setup_specs() + end) + + local spec_quick = test_env.testing_paths.spec_dir .. "/quick" + for f in lfs.dir(spec_quick) do + if f:match("%.q$") then + local tests = quick.compile(spec_quick .. "/" .. f, getfenv and getfenv() or _ENV) + for _, t in ipairs(tests) do + it(t.name, t.fn) + end + end + end +end) + diff --git a/spec/rockspecs_spec.lua b/spec/rockspecs_spec.lua index 76b33f65..5b0573fe 100644 --- a/spec/rockspecs_spec.lua +++ b/spec/rockspecs_spec.lua @@ -4,7 +4,7 @@ local cfg = require("luarocks.core.cfg") local test_env = require("spec.util.test_env") local lfs = require("lfs") -describe("luarocks.rockspecs", function() +describe("luarocks.rockspecs #unit", function() setup(function() cfg.init() diff --git a/spec/util/quick.lua b/spec/util/quick.lua new file mode 100644 index 00000000..c8bfb61a --- /dev/null +++ b/spec/util/quick.lua @@ -0,0 +1,384 @@ +local quick = {} + +local dir_sep = package.config:sub(1, 1) + +local cfg, dir, fs, versions +local initialized = false + +local function initialize() + if initialized then + return + end + initialized = true + + cfg = require("luarocks.core.cfg") + dir = require("luarocks.dir") + fs = require("luarocks.fs") + versions = require("spec.util.versions") + cfg.init() + fs.init() +end + +local function native_slash(pathname) + return (pathname:gsub("[/\\]", dir_sep)) +end + +local function parse_cmd(line) + local cmd, arg = line:match("^%s*([A-Z_]+):%s*(.*)%s*$") + return cmd, arg +end + +local function is_blank(line) + return not not line:match("^%s*$") +end + +local function is_hr(line) + return not not line:match("^%-%-%-%-%-") +end + +local function parse(filename) + local fd = assert(io.open(filename, "r")) + local input = assert(fd:read("*a")) + fd:close() + + initialize() + + local tests = {} + + local cur_line = 0 + local cur_test + local cur_op + local cur_block + local cur_block_name + local stack = { "start" } + + local function start_test(arg) + cur_test = { + name = arg, + ops = {}, + } + cur_op = nil + table.insert(tests, cur_test) + table.insert(stack, "test") + end + + local function fail(msg) + io.stderr:write("Error reading " .. filename .. ":" .. cur_line .. ": " .. msg .. "\n") + os.exit(1) + end + + local function bool_arg(cmd, cur_block, field, arg) + if arg ~= "true" and arg ~= "false" then + fail(cmd .. " argument must be 'true' or 'false'") + end + cur_block[field] = (arg == "true") + end + + local test_env = require("spec.util.test_env") + local function expand_vars(line) + if not line then + return nil + end + return (line:gsub("%%%b{}", function(var) + var = var:sub(3, -2) + local fn, fnarg = var:match("^%s*([a-z_]+)%s*%(%s*([^)]+)%s*%)%s*$") + + local value + if var == "tmpdir" then + value = "%{tmpdir}" + elseif var == "url(tmpdir)" then + value = "%{url(tmpdir)}" + elseif fn == "url" then + value = expand_vars(fnarg) + value = value:gsub("\\", "/") + elseif fn == "path" then + value = expand_vars(fnarg) + value = value:gsub("[/\\]", dir_sep) + elseif fn == "version" then + value = versions[fnarg:lower()] or "" + elseif fn == "version_" then + value = (versions[fnarg:lower()] or ""):gsub("[%.%-]", "_") + else + value = test_env.testing_paths[var] + or test_env.env_variables[var] + or test_env[var] + or "" + end + + return value + end)) + end + + for line in input:gmatch("[^\n]*") do + cur_line = cur_line + 1 + + local state = stack[#stack] + if state == "start" then + local cmd, arg = parse_cmd(line) + if cmd == "TEST" then + start_test(arg) + elseif cmd then + fail("expected TEST, got " .. cmd) + elseif is_blank(line) then + -- skip blank lines and arbitrary text, + -- which is interpreted as a comment + end + elseif state == "test" then + local cmd, arg = parse_cmd(line) + arg = expand_vars(arg) + if cmd == "FILE" then + cur_op = { + op = "FILE", + name = arg, + data = {}, + } + table.insert(cur_test.ops, cur_op) + cur_block = cur_op + cur_block_name = "FILE" + table.insert(stack, "block start") + elseif cmd == "RUN" then + local program, args = arg:match("([^ ]+)%s*(.*)$") + if not program then + fail("expected a program argument in RUN") + end + + cur_op = { + op = "RUN", + exit = 0, + exit_line = cur_line, + line = cur_line, + program = program, + args = args, + } + table.insert(cur_test.ops, cur_op) + elseif cmd == "EXISTS" then + cur_op = { + op = "EXISTS", + file = dir.normalize(arg), + } + table.insert(cur_test.ops, cur_op) + elseif cmd == "NOT_EXISTS" then + cur_op = { + op = "NOT_EXISTS", + file = dir.normalize(arg), + } + table.insert(cur_test.ops, cur_op) + elseif cmd == "MKDIR" then + cur_op = { + op = "MKDIR", + file = dir.normalize(arg), + line = cur_line, + } + table.insert(cur_test.ops, cur_op) + elseif cmd == "EXIT" then + if not cur_op or cur_op.op ~= "RUN" then + fail("EXIT must be given in the context of a RUN") + end + + local code = tonumber(arg) + if not code and not (code >= 0 and code <= 128) then + fail("EXIT code must be a number in the range 0-128, got " .. arg) + end + + cur_op.exit = code + cur_op.exit_line = cur_line + elseif cmd == "STDERR" then + if not cur_op or cur_op.op ~= "RUN" then + fail("STDERR must be given in the context of a RUN") + end + if cur_op.stderr then + fail("STDERR was already declared") + end + + cur_op.stderr = { + data = {} + } + cur_block = cur_op.stderr + cur_block_name = "STDERR" + table.insert(stack, "block start") + elseif cmd == "STDOUT" then + if not cur_op or cur_op.op ~= "RUN" then + fail("STDOUT must be given in the context of a RUN") + end + if cur_op.stdout then + fail("STDOUT was already declared") + end + + cur_op.stdout = { + data = {} + } + cur_block = cur_op.stdout + cur_block_name = "STDOUT" + table.insert(stack, "block start") + elseif cmd == "TEST" then + table.remove(stack) + start_test(arg) + elseif cmd then + fail("expected a command, got " .. cmd) + else + -- skip blank lines and arbitrary text, + -- which is interpreted as a comment + end + elseif state == "block start" then + local cmd, arg = parse_cmd(line) + if is_blank(line) then + -- skip + elseif is_hr(line) then + stack[#stack] = "block data" + cur_block.start = cur_line + elseif cmd == "PLAIN" then + bool_arg("PLAIN", cur_block, "plain", arg) + else + fail("expected '-----' to start " .. cur_block_name .. " block") + end + elseif state == "block data" then + if is_hr(line) then + cur_block = nil + table.remove(stack) + else + if not cur_block.plain then + line = expand_vars(line) + end + table.insert(cur_block.data, line) + end + end + end + + return tests +end + +function quick.compile(filename, env) + local tests = parse(filename) + +-- local dev_null = (package.config:sub(1, 1) == "/") +-- and "/dev/null" +-- or "NUL" + + local cmd_helpers = { + ["luarocks"] = "luarocks_cmd", + ["luarocks-admin"] = "luarocks_admin_cmd", + } + + for tn, t in ipairs(tests) do + local code = {} + local function write(...) + table.insert(code, table.concat({...})) + end + + write([=[ local test_env = require("spec.util.test_env") ]=]) + write([=[ local lfs = require("lfs") ]=]) + write([=[ local fs = require("lfs") ]=]) + write([=[ local dir_sep = package.config:sub(1, 1) ]=]) + write([=[ local luarocks_cmd = test_env.execute_helper(test_env.Q(test_env.testing_paths.lua) .. " " .. test_env.testing_paths.src_dir .. "/bin/luarocks", false, test_env.env_variables):sub(1, -5) ]=]) + write([=[ local luarocks_admin_cmd = test_env.execute_helper(test_env.Q(test_env.testing_paths.lua) .. " " .. test_env.testing_paths.src_dir .. "/bin/luarocks-admin", false, test_env.env_variables):sub(1, -5) ]=]) + + write(([=[ local function error_message(line, msg, input) ]=])) + write(([=[ local out = {"\n\n", %q, ":", line, ": ", msg} ]=]):format(filename)) + write(([=[ if input then ]=])) + write(([=[ if input:match("\n") then ]=])) + write(([=[ table.insert(out, "\n") ]=])) + write(([=[ table.insert(out, ("-"):rep(40)) ]=])) + write(([=[ table.insert(out, "\n") ]=])) + write(([=[ table.insert(out, input) ]=])) + write(([=[ table.insert(out, ("-"):rep(40)) ]=])) + write(([=[ table.insert(out, "\n") ]=])) + write(([=[ else ]=])) + write(([=[ table.insert(out, ": ") ]=])) + write(([=[ table.insert(out, input) ]=])) + write(([=[ end ]=])) + write(([=[ end ]=])) + write(([=[ return table.concat(out) ]=])) + write(([=[ end ]=])) + + write([=[ return function() ]=]) + write([=[ test_env.run_in_tmp(function(tmpdir) ]=]) + write([=[ local function handle_tmpdir(s) ]=]) + write([=[ return (s:gsub("%%{url%(tmpdir%)}", (tmpdir:gsub("\\", "/"))) ]=]) + write([=[ :gsub("%%{tmpdir}", (tmpdir:gsub("[\\/]", dir_sep)))) ]=]) + write([=[ end ]=]) + for _, op in ipairs(t.ops) do + if op.op == "FILE" then + write([=[ test_env.write_file(handle_tmpdir("]=], op.name, [=["), handle_tmpdir([=====[ ]=]) + for _, line in ipairs(op.data) do + write(line) + end + write([=[ ]=====]), finally) ]=]) + elseif op.op == "EXISTS" then + write(([=[ assert.truthy(lfs.attributes(%q)) ]=]):format(op.file)) + elseif op.op == "NOT_EXISTS" then + write(([=[ assert.falsy(lfs.attributes(%q)) ]=]):format(op.file)) + elseif op.op == "MKDIR" then + local bits = {} + op.file = native_slash(op.file) + if op.file:sub(1, 1) == dir_sep then bits[1] = "" end + write([=[ local ok, err ]=]) + for p in op.file:gmatch("[^" .. dir_sep .. "]+") do + table.insert(bits, p) + local d = table.concat(bits, dir_sep) + write(([=[ ok, err = lfs.mkdir(%q) ]=]):format(d, d)) + end + write(([=[ assert.truthy((lfs.attributes(%q) or {}).mode == "directory", error_message(%d, "MKDIR failed: " .. %q .. " - " .. (err or "") )) ]=]):format(op.file, op.line, op.file)) + elseif op.op == "RUN" then + local cmd_helper = cmd_helpers[op.program] or op.program + local redirs = " 1>stdout.txt 2>stderr.txt " + write(([=[ local ok, _, code = os.execute(%s .. " " .. %q .. %q) ]=]):format(cmd_helper, op.args, redirs)) + write([=[ if type(ok) == "number" then code = (ok >= 256 and ok / 256 or ok) end ]=]) + + write([=[ local fd_stderr = assert(io.open("stderr.txt", "r")) ]=]) + write([=[ local stderr_data = fd_stderr:read("*a") ]=]) + write([=[ fd_stderr:close() ]=]) + + write([=[ if stderr_data:match("please report") then ]=]) + write(([=[ assert(false, error_message(%d, "RUN crashed: ", stderr_data)) ]=]):format(op.line)) + write([=[ end ]=]) + + if op.stdout then + write([=[ local fd_stdout = assert(io.open("stdout.txt", "r")) ]=]) + write([=[ local stdout_data = fd_stdout:read("*a") ]=]) + write([=[ fd_stdout:close() ]=]) + + write([=[ do ]=]) + write([=[ local block_at = 1 ]=]) + write([=[ local s, e, line ]=]) + for i, line in ipairs(op.stdout.data) do + write(([=[ line = %q ]=]):format(line)) + write(([=[ s, e = string.find(stdout_data, line, block_at, true) ]=])) + write(([=[ assert(s, error_message(%d, "STDOUT did not match: " .. line, stdout_data)) ]=]):format(op.stdout.start + i)) + write(([=[ block_at = e + 1 ]=]):format(i)) + end + write([=[ end ]=]) + end + + if op.stderr then + write([=[ do ]=]) + write([=[ local block_at = 1 ]=]) + write([=[ local s, e, line ]=]) + for i, line in ipairs(op.stderr.data) do + write(([=[ line = %q ]=]):format(line)) + write(([=[ s, e = string.find(stderr_data, line, block_at, true) ]=])) + write(([=[ assert(s, error_message(%d, "STDERR did not match: " .. line, stderr_data)) ]=]):format(op.stderr.start + i)) + write(([=[ block_at = e + 1 ]=]):format(i)) + end + write([=[ end ]=]) + end + + if op.exit then + write(([=[ assert.same(%d, code, error_message(%d, "EXIT did not match: " .. %d, stderr_data)) ]=]):format(op.exit, op.exit_line, op.exit)) + end + end + end + write([=[ end) ]=]) + write([=[ end ]=]) + + local program = table.concat(code, "\n") + local chunk = assert(load(program, "@" .. filename .. ": test " .. tn, "t", env or _ENV)) + if env and setfenv then + setfenv(chunk, env) + end + t.fn = chunk() + end + + return tests +end + +return quick diff --git a/spec/util/test_env.lua b/spec/util/test_env.lua index f9f83b8c..dcda6311 100644 --- a/spec/util/test_env.lua +++ b/spec/util/test_env.lua @@ -715,6 +715,7 @@ local function create_paths(luaversion_full) testing_paths.util_dir = base_dir .. "/spec/util" testing_paths.testrun_dir = base_dir .. "/testrun" testing_paths.src_dir = base_dir .. "/src" + testing_paths.spec_dir = base_dir .. "/spec" testing_paths.testing_lrprefix = testing_paths.testrun_dir .. "/testing_lrprefix-" .. luaversion_full testing_paths.testing_tree = testing_paths.testrun_dir .. "/testing-" .. luaversion_full testing_paths.testing_tree_copy = testing_paths.testrun_dir .. "/testing_copy-" .. luaversion_full @@ -753,6 +754,16 @@ function test_env.unload_luarocks() end end +local function get_luarocks_platform(variables) + local print_arch_script = "\"" .. + "cfg = require('luarocks.core.cfg');" .. + "cfg.init();" .. + "print(cfg.arch)" .. + "\"" + local cmd = test_env.testing_paths.lua .. " -e " .. print_arch_script + return execute_output(cmd, false, variables) +end + --- Function for initial setup of environment, variables, md5sums for spec files function test_env.setup_specs(extra_rocks) -- if global variable about successful creation of testing environment doesn't exist, build environment @@ -770,11 +781,12 @@ function test_env.setup_specs(extra_rocks) -- preload before meddling with package.path require("spec.util.git_repo") + require("spec.util.quick") package.path = test_env.env_variables.LUA_PATH package.cpath = test_env.env_variables.LUA_CPATH - test_env.platform = execute_output(test_env.testing_paths.lua .. " -e \"cfg = require('luarocks.core.cfg'); cfg.init(); print(cfg.arch)\"", false, test_env.env_variables) + test_env.platform = get_luarocks_platform(test_env.env_variables) test_env.wrapper_extension = test_env.TEST_TARGET_OS == "windows" and ".bat" or "" test_env.md5sums = create_md5sums(test_env.testing_paths) test_env.setup_done = true @@ -1104,5 +1116,7 @@ test_env.env_variables = create_env(test_env.testing_paths) test_env.run = make_run_functions() test_env.exists = exists test_env.V = V +test_env.Q = Q +test_env.platform = get_luarocks_platform(test_env.env_variables) return test_env -- cgit v1.2.3-55-g6feb