From: Vsevolod Stakhov Date: Tue, 5 May 2026 19:43:53 +0000 (+0100) Subject: [Test] Functional test for lua_extras two-phase loader X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=ebd16ed3383173e9d4d258aed9840244b06c43ce;p=thirdparty%2Frspamd.git [Test] Functional test for lua_extras two-phase loader Adds Functional.Cases.001_Merged.271_Lua_Extras with two cases: * the deferred-selector regexp fires when the From-domain is present in the map captured by the selector factory; * the same regexp stays silent when the From-domain is absent. The companion lua_extras_test.lua stages a tree under TMPDIR with maps, selectors and regexps subdirectories, then calls lua_extras.load_extras on it. The selector entry is wrapped in lua_extras.deferred so the factory captures rspamd_maps[name] at registration time, exercising the maps -> selectors -> regexps phase 2 ordering and the re_selector auto-binding into the regexp DSL. Also wires the new lua file into merged.conf alongside selector_test.lua. --- diff --git a/test/functional/cases/001_merged/271_lua_extras.robot b/test/functional/cases/001_merged/271_lua_extras.robot new file mode 100644 index 0000000000..8f84142add --- /dev/null +++ b/test/functional/cases/001_merged/271_lua_extras.robot @@ -0,0 +1,19 @@ +*** Settings *** +Library ${RSPAMD_TESTDIR}/lib/rspamd.py +Resource ${RSPAMD_TESTDIR}/lib/rspamd.robot +Variables ${RSPAMD_TESTDIR}/lib/vars.py + +*** Variables *** +${MSG_IN_MAP} ${RSPAMD_TESTDIR}/messages/lua_extras_in_map.eml +${MSG_NOT_IN_MAP} ${RSPAMD_TESTDIR}/messages/lua_extras_not_in_map.eml + +*** Test Cases *** +Lua_extras deferred selector fires regexp when From in map + Scan File ${MSG_IN_MAP} + ... Settings={symbols_enabled = [TEST_EXTRAS_LOCAL_FROM]} + Expect Symbol TEST_EXTRAS_LOCAL_FROM + +Lua_extras deferred selector silent when From not in map + Scan File ${MSG_NOT_IN_MAP} + ... Settings={symbols_enabled = [TEST_EXTRAS_LOCAL_FROM]} + Do Not Expect Symbol TEST_EXTRAS_LOCAL_FROM diff --git a/test/functional/configs/merged.conf b/test/functional/configs/merged.conf index a2c2963f14..6e270432a5 100644 --- a/test/functional/configs/merged.conf +++ b/test/functional/configs/merged.conf @@ -25,6 +25,9 @@ lua = "{= env.TESTDIR =}/lua/dns.lua" # 270_selector lua = "{= env.TESTDIR =}/lua/selector_test.lua" +# 271_lua_extras +lua = "{= env.TESTDIR =}/lua/lua_extras_test.lua" + # 281_fnames lua = "{= env.TESTDIR =}/lua/test_fname.lua" diff --git a/test/functional/lua/lua_extras_test.lua b/test/functional/lua/lua_extras_test.lua new file mode 100644 index 0000000000..e8421bea71 --- /dev/null +++ b/test/functional/lua/lua_extras_test.lua @@ -0,0 +1,74 @@ +-- Functional test for the structured lua.local.d/{maps,selectors,regexps} +-- loader (lua_extras). Stages a small tree under TMPDIR and calls +-- lua_extras.load_extras() to register a map, a deferred selector that +-- captures rspamd_maps[name] in its factory, and a regexp using that +-- selector through the regexp DSL. The companion robot test then asserts +-- the symbol fires only when the From-domain is present in the map. + +local lua_extras = require "lua_extras" + +local tmpdir = os.getenv('TMPDIR') or '/tmp' +local base = tmpdir .. '/lua_extras_test' + +-- Always start clean +os.execute('rm -rf "' .. base .. '"') +os.execute('mkdir -p "' .. base .. '/maps" "' .. base .. '/selectors" "' .. base .. '/regexps"') + +local function write_file(path, content) + local f = assert(io.open(path, 'w')) + f:write(content) + f:close() +end + +-- Map data +local map_list = base .. '/local_domains.list' +write_file(map_list, 'example.com\nlocal.test\n') + +-- Map definition +write_file(base .. '/maps/test_extras.lua', string.format([[ +return { + example_local_domains = { + type = 'set', + description = 'TEST: local domains', + url = '%s', + }, +} +]], map_list)) + +-- Deferred selector capturing the map ref at registration time. This is the +-- whole point of the two-phase loader: by the time this factory runs, the +-- map above has already been registered and rspamd_maps[name] is populated. +write_file(base .. '/selectors/test_extras.lua', [[ +local lua_extras = require "lua_extras" +return { + test_extras_local_domain = lua_extras.deferred(function() + local domains = rspamd_maps.example_local_domains + return { + description = 'TEST: From-domain when present in example_local_domains map', + re_selector = true, + get_value = function(task) + local from = task:get_from('mime') + local dom = from and from[1] and from[1].domain or nil + if dom and domains and domains:get_key(dom) then + return dom, 'string' + end + return nil + end, + } + end), +} +]]) + +-- Regexp symbol firing when the deferred selector resolves a non-nil value. +write_file(base .. '/regexps/test_extras.lua', [[ +return { + TEST_EXTRAS_LOCAL_FROM = { + re = 'test_extras_local_domain=/.+/{selector}', + score = 0.1, + description = 'TEST: From present in example_local_domains map', + }, +} +]]) + +-- Trigger the structured loader on our staged tree. +lua_extras.load_extras(rspamd_config, base) diff --git a/test/functional/messages/lua_extras_in_map.eml b/test/functional/messages/lua_extras_in_map.eml new file mode 100644 index 0000000000..e22132c88c --- /dev/null +++ b/test/functional/messages/lua_extras_in_map.eml @@ -0,0 +1,5 @@ +From: alice@example.com +To: bob@elsewhere.test +Subject: in map + +body diff --git a/test/functional/messages/lua_extras_not_in_map.eml b/test/functional/messages/lua_extras_not_in_map.eml new file mode 100644 index 0000000000..866e6bc9d3 --- /dev/null +++ b/test/functional/messages/lua_extras_not_in_map.eml @@ -0,0 +1,5 @@ +From: alice@unknown.test +To: bob@elsewhere.test +Subject: not in map + +body