From aa9742723d1d1c883c33aa82b9d07434d06f6a27 Mon Sep 17 00:00:00 2001 From: Jude Melton-Houghton Date: Wed, 1 Jun 2022 14:46:25 -0400 Subject: [PATCH] Add luacontroller tests --- .test_fixtures/mesecons_luacontroller.lua | 12 ++ .../spec/lightweight_interrupt_spec.lua | 38 ++++ mesecons_luacontroller/spec/luac_spec.lua | 184 ++++++++++++++++++ mesecons_luacontroller/spec/mineunit.conf | 1 + 4 files changed, 235 insertions(+) create mode 100644 .test_fixtures/mesecons_luacontroller.lua create mode 100644 mesecons_luacontroller/spec/lightweight_interrupt_spec.lua create mode 100644 mesecons_luacontroller/spec/luac_spec.lua create mode 100644 mesecons_luacontroller/spec/mineunit.conf diff --git a/.test_fixtures/mesecons_luacontroller.lua b/.test_fixtures/mesecons_luacontroller.lua new file mode 100644 index 0000000..9090b47 --- /dev/null +++ b/.test_fixtures/mesecons_luacontroller.lua @@ -0,0 +1,12 @@ +fixture("mesecons") +fixture("mesecons_gamecompat") + +mineunit:set_current_modname("mesecons_luacontroller") +mineunit:set_modpath("mesecons_luacontroller", "../mesecons_luacontroller") +sourcefile("../mesecons_luacontroller/init") + +function mesecon._test_program_luac(pos, code) + local node = minetest.get_node(pos) + assert.equal("mesecons_luacontroller:luacontroller", node.name:sub(1, 36)) + return minetest.registered_nodes[node.name].mesecons.luacontroller.set_program(pos, code) +end diff --git a/mesecons_luacontroller/spec/lightweight_interrupt_spec.lua b/mesecons_luacontroller/spec/lightweight_interrupt_spec.lua new file mode 100644 index 0000000..4d14e02 --- /dev/null +++ b/mesecons_luacontroller/spec/lightweight_interrupt_spec.lua @@ -0,0 +1,38 @@ +require("mineunit") + +-- This test is done in a separate file since it requires different configuration at startup. +mineunit("core") +minetest.settings:set("mesecon.luacontroller_lightweight_interrupts", "true") + +fixture("mesecons_luacontroller") + +describe("LuaController lightweight interrupt", function() + local pos = {x = 0, y = 0, z = 0} + + before_each(function() + mesecon._test_place(pos, "mesecons_luacontroller:luacontroller0000") + mineunit:execute_globalstep() + end) + + after_each(function() + mesecon._test_reset() + world.clear() + end) + + it("works", function() + mesecon._test_program_luac(pos, [[ + if event.type == "program" then + interrupt(5) + interrupt(10) + elseif event.type == "interrupt" then + port.a = not pin.a + end + ]]) + mineunit:execute_globalstep(0.1) + mineunit:execute_globalstep(9) + assert.equal("mesecons_luacontroller:luacontroller0000", world.get_node(pos).name) + mineunit:execute_globalstep(1) + mineunit:execute_globalstep(0.1) + assert.equal("mesecons_luacontroller:luacontroller0001", world.get_node(pos).name) + end) +end) diff --git a/mesecons_luacontroller/spec/luac_spec.lua b/mesecons_luacontroller/spec/luac_spec.lua new file mode 100644 index 0000000..f4ccb9f --- /dev/null +++ b/mesecons_luacontroller/spec/luac_spec.lua @@ -0,0 +1,184 @@ +require("mineunit") + +fixture("mesecons_luacontroller") + +-- Digiline is not tested, since that would require the digiline mod. + +describe("LuaController", function() + local pos = {x = 0, y = 0, z = 0} + local pos_a = {x = -1, y = 0, z = 0} + + before_each(function() + mesecon._test_place(pos, "mesecons_luacontroller:luacontroller0000") + mineunit:execute_globalstep() + end) + + after_each(function() + mesecon._test_reset() + world.clear() + end) + + it("rejects binary code", function() + local ok = mesecon._test_program_luac(pos, string.dump(function() end)) + assert.is_false(ok) + end) + + it("I/O", function() + mesecon._test_place(pos_a, "mesecons:test_receptor_on") + mineunit:execute_globalstep() + mineunit:execute_globalstep() + mesecon._test_program_luac(pos, [[ + port.a = not pin.a + port.b = not pin.b + port.c = not pin.c + port.d = not pin.d + ]]) + mineunit:execute_globalstep() + assert.equal("mesecons_luacontroller:luacontroller1110", world.get_node(pos).name) + mesecon._test_dig(pos_a) + mineunit:execute_globalstep() + mineunit:execute_globalstep() + assert.equal("mesecons_luacontroller:luacontroller0001", world.get_node(pos).name) + end) + + it("memory", function() + mesecon._test_program_luac(pos, [[ + if not mem.x then + mem.x = {} + mem.x[mem.x] = {true, "", 1.2} + else + local b, s, n = unpack(mem.x[mem.x]) + if b == true and s == "" and n == 1.2 then + port.d = true + end + end + ]]) + mineunit:execute_globalstep() + assert.equal("mesecons_luacontroller:luacontroller0000", world.get_node(pos).name) + mesecon._test_place(pos_a, "mesecons:test_receptor_on") + mineunit:execute_globalstep() + mineunit:execute_globalstep() + assert.equal("mesecons_luacontroller:luacontroller1000", world.get_node(pos).name) + end) + + it("interrupts without IDs", function() + mesecon._test_program_luac(pos, [[ + if event.type == "program" then + interrupt(4) + interrupt(8) + elseif event.type == "interrupt" then + port.a = not pin.a + end + ]]) + mineunit:execute_globalstep(0.1) + mineunit:execute_globalstep(3) + assert.equal("mesecons_luacontroller:luacontroller0000", world.get_node(pos).name) + mineunit:execute_globalstep(1) + mineunit:execute_globalstep(0.1) + assert.equal("mesecons_luacontroller:luacontroller0001", world.get_node(pos).name) + mineunit:execute_globalstep(3) + assert.equal("mesecons_luacontroller:luacontroller0001", world.get_node(pos).name) + mineunit:execute_globalstep(1) + mineunit:execute_globalstep(0.1) + assert.equal("mesecons_luacontroller:luacontroller0000", world.get_node(pos).name) + end) + + it("interrupts with IDs", function() + mesecon._test_program_luac(pos, [[ + if event.type == "program" then + interrupt(2, "a") + interrupt(4, "a") + interrupt(16, "b") + elseif event.type == "interrupt" then + if event.iid == "a" then + interrupt(5, "b") + interrupt(4, "b") + end + port.a = not pin.a + end + ]]) + mineunit:execute_globalstep(0.1) + mineunit:execute_globalstep(3) + assert.equal("mesecons_luacontroller:luacontroller0000", world.get_node(pos).name) + mineunit:execute_globalstep(1) + mineunit:execute_globalstep(0.1) + assert.equal("mesecons_luacontroller:luacontroller0001", world.get_node(pos).name) + mineunit:execute_globalstep(3) + assert.equal("mesecons_luacontroller:luacontroller0001", world.get_node(pos).name) + mineunit:execute_globalstep(1) + mineunit:execute_globalstep(0.1) + assert.equal("mesecons_luacontroller:luacontroller0000", world.get_node(pos).name) + end) + + it("limits interrupt ID size", function() + mesecon._test_program_luac(pos, [[ + if event.type == "program" then + interrupt(0, (" "):rep(257)) + elseif event.type == "interrupt" then + port.a = not pin.a + end + ]]) + mineunit:execute_globalstep(3) + mineunit:execute_globalstep(3) + assert.equal("mesecons_luacontroller:luacontroller0000", world.get_node(pos).name) + end) + + it("string.rep", function() + mesecon._test_program_luac(pos, [[ + (" "):rep(64000) + port.a = true + ]]) + mineunit:execute_globalstep() + assert.equal("mesecons_luacontroller:luacontroller0001", world.get_node(pos).name) + mesecon._test_program_luac(pos, [[ + (" "):rep(64001) + port.b = true + ]]) + mineunit:execute_globalstep() + assert.equal("mesecons_luacontroller:luacontroller0000", world.get_node(pos).name) + end) + + it("string.find", function() + mesecon._test_program_luac(pos, [[ + port.a = (" a"):find("a", nil, true) == 2 + ]]) + mineunit:execute_globalstep() + assert.equal("mesecons_luacontroller:luacontroller0001", world.get_node(pos).name) + mesecon._test_program_luac(pos, [[ + (" a"):find("a", nil) + port.b = true + ]]) + mineunit:execute_globalstep() + assert.equal("mesecons_luacontroller:luacontroller0000", world.get_node(pos).name) + end) + + it("overheats", function() + mesecon._test_program_luac(pos, [[ + interrupt(0) + interrupt(0) + ]]) + mineunit:execute_globalstep() + mineunit:execute_globalstep() + mineunit:execute_globalstep() + mineunit:execute_globalstep() + assert.equal("mesecons_luacontroller:luacontroller_burnt", world.get_node(pos).name) + end) + + it("limits memory", function() + mesecon._test_program_luac(pos, [[ + port.a = true + mem.x = (" "):rep(50000) .. (" "):rep(50000) + ]]) + mineunit:execute_globalstep() + assert.equal("mesecons_luacontroller:luacontroller_burnt", world.get_node(pos).name) + end) + + it("limits run time", function() + mesecon._test_program_luac(pos, [[ + port.a = true + while true do end + ]]) + mineunit:execute_globalstep() + assert.equal("mesecons_luacontroller:luacontroller0000", world.get_node(pos).name) + end) +end) diff --git a/mesecons_luacontroller/spec/mineunit.conf b/mesecons_luacontroller/spec/mineunit.conf new file mode 100644 index 0000000..81bd36c --- /dev/null +++ b/mesecons_luacontroller/spec/mineunit.conf @@ -0,0 +1 @@ +fixture_paths = {"../.test_fixtures"}