Files
crun/lua/luacrun_spec.lua

206 lines
7.3 KiB
Lua
Raw Permalink Normal View History

local dkjson = require "dkjson"
local posix = require "posix"
local stdlib = require "posix.stdlib"
local unistd = require "posix.unistd"
local libgen = require "posix.libgen"
local function is_file_exists(path)
local f = io.open(path, 'rb')
if f then
f:close()
return true
else
return false
end
end
local function makedirs(path)
if not is_file_exists(path) then
makedirs(libgen.dirname(path))
local path, errmsg = posix.mkdir(path)
assert(path, errmsg)
end
end
local function cp(src, dest)
local stat, exitm, retc = os.execute(
string.format("cp \"%s\" \"%s\"", src, dest))
return retc
end
local function mktestenv()
local format = string.format
local init_path = os.getenv("INIT")
assert(type(init_path) == "string" and #init_path > 0, "no INIT env var for init program")
local path, errmsg = stdlib.mkdtemp("/tmp/luacrun-test-XXXXXX")
assert(path, errmsg)
local rootfs_path = string.format("%s/%s", path, "rootfs")
makedirs(rootfs_path)
for i, p in ipairs({
"usr/bin", "etc", "var", "lib", "lib64", "usr/share/zoneinfo/Europe",
"proc", "sys", "dev"
}) do makedirs(string.format("%s/%s", rootfs_path, p)) end
local sbin_path = string.format("%s/%s", rootfs_path, "sbin")
makedirs(sbin_path)
local retc = cp(init_path, format("%s/%s", rootfs_path, "init"))
assert(retc == 0, "cp init to rootfs return " .. retc)
local retc = cp(init_path, format("%s/%s", sbin_path, "init"))
assert(retc == 0, "cp init to sbin return " .. retc)
unistd.link("../usr/share/zoneinfo/Europe/Rome",
format("%s/%s", rootfs_path, "etc/localtime"))
local passwd, errmsg = io.open(format("%s/%s", rootfs_path,
"usr/share/passwd"), "w")
assert(passwd, errmsg)
passwd, errmsg = passwd:write("root:x:0:0:root:/root:/bin/bash\n")
assert(passwd, errmsg)
passwd:close()
unistd.link("../usr/share/passwd",
format("%s/%s", rootfs_path, "etc/passwd"))
return path
end
insulate("luacrun", function()
local luacrun = require "luacrun"
describe("container_spec", function()
it("returns a string", function()
local s = luacrun.container_spec()
assert.are.equals("string", type(s))
end)
it("returns a json object", function()
local s = luacrun.container_spec()
local t = dkjson.decode(s)
assert.are.equals("table", type(t))
end)
end)
describe("new_ctx", function()
it("can create context with only id", function()
local ctx = luacrun.new_ctx {id = "luacrun-test"}
assert.are.equals("userdata", type(ctx))
end)
end)
describe("new_container_from_string", function()
it("can create container object from json string", function()
local spec = dkjson.decode(luacrun.container_spec())
spec.root.path = "/"
spec.process.args = {'/bin/echo', "Hello World!"}
local cont, err = luacrun.new_container_from_string(dkjson.encode(
spec))
assert(cont, err)
end)
end)
describe("create_container", function()
it("is same to ctx.create", function()
local ctx = luacrun.new_ctx {id = "luacrun-test"}
assert.are.equals(ctx.create, luacrun.create_container)
end)
end)
it("can create container and delete container", function()
local temproot = mktestenv()
local ctx = luacrun.new_ctx {state_root = temproot, id = "luacrun-test"}
assert(ctx)
local spec =
dkjson.decode(luacrun.container_spec(unistd.geteuid() == 0))
spec.root = {
path = string.format("%s/%s", temproot, "rootfs"),
readonly = true
}
spec.process.args = {'/init', "true"}
spec.process.terminal = false
spec.process.user = {uid = unistd.geteuid(), gid = unistd.getegid()}
spec.linux.rootfsPropagation = "rprivate"
local json_spec = dkjson.encode(spec)
local cont, err = luacrun.new_container_from_string(json_spec)
assert(cont, err)
local stat, err = luacrun.create_container(ctx, cont)
assert(stat == 0, string.format("%s, %d", err, stat))
local names = {}
for i, name in ctx:iter_names() do names[#names + 1] = name end
assert(#names == 1, string.format("names length is %d", #names))
local status, err = ctx:status(names[1])
assert(status, err)
assert.are.equals("created", status.status)
local stat, err = ctx:start(names[1])
assert(stat, err)
local status, err = ctx:status(names[1])
assert(status, err)
assert.are.equals("running", status.status)
while true do -- wait for container exited
local status, err = ctx:status(names[1])
assert(status, err)
if status.status == "created" or status.status == "stopped" then
break
end
end
local stat, err = luacrun.delete_container(ctx, names[1])
assert(stat, err)
-- Make sure no container after deleted
local names_after_deleted = {}
for i, name in ctx:iter_names() do names_after_deleted[#names_after_deleted + 1] = name end
assert(#names_after_deleted == 0, string.format("names length is %d", #names))
end)
describe("new_ctx()", function ()
it("error if the argument has invalid type", function ()
for i, v in ipairs({1, 1.0, false}) do
assert.has_error((function ()
luacrun.new_ctx(v)
end))
end
end)
end)
describe("Ctx", function()
it("id() can get id", function()
local ctx = luacrun.new_ctx {id = "luacrun-test"}
assert.are.equals("luacrun-test", ctx:id())
end)
it("id() can read the id set by set_id()", function()
local ctx = luacrun.new_ctx {id = "luacrun-test1"}
assert.are.equals("luacrun-test1", ctx:id())
ctx:set_id("luacrun-test2")
assert.are.equals("luacrun-test2", ctx:id())
end)
it("systemd_cgroup() can get a boolean", function()
local ctx = luacrun.new_ctx {id = "luacrun-test"}
assert.are.equals("boolean", type(ctx:systemd_cgroup()))
end)
it("systemd_cgroup() can read the value set by set_system_cgroupd()",
function()
local ctx = luacrun.new_ctx {
id = "luacrun-test",
systemd_cgroup = false
}
assert.is_false(ctx:systemd_cgroup())
ctx:set_systemd_cgroup(true)
assert.is_true(ctx:systemd_cgroup())
end)
describe("iter_names()", function ()
it("acts as empty iterator if no container", function ()
local touch = false
local ctx = luacrun.new_ctx {
id = "luacrun-test-empty",
}
for i, name in ctx:iter_names() do
touch = true
end
assert.is_false(touch)
end)
end)
end)
end)