]> git.ipfire.org Git - thirdparty/rspamd.git/commitdiff
[Fix] Preserve metatables in shallowcopy and save test configs
authorVsevolod Stakhov <vsevolod@rspamd.com>
Wed, 19 Nov 2025 12:44:15 +0000 (12:44 +0000)
committerVsevolod Stakhov <vsevolod@rspamd.com>
Wed, 19 Nov 2025 12:44:15 +0000 (12:44 +0000)
- Fix shallowcopy to preserve metatables when copying schema objects
- Ensure configdump output and input config are always saved to robot-save
  even if configdump crashes with assertion failure

lualib/lua_shape/core.lua
lualib/lua_shape/registry.lua
test/functional/lib/rspamd.robot

index 528f08f1be4183def2b0a9c1f9aaeb3842016ac5..9afeeb4b9adcfd611e1fab816d36042a82216a93 100644 (file)
@@ -25,6 +25,11 @@ local function shallowcopy(t)
   for k, v in pairs(t) do
     result[k] = v
   end
+  -- Preserve metatable if present
+  local mt = getmetatable(t)
+  if mt then
+    setmetatable(result, mt)
+  end
   return result
 end
 
index 01409988505832ec0f93604739316d15f72b6451..e5118a92a87ed79e79d1fe7efc4db35bd4c2d464 100644 (file)
@@ -26,6 +26,11 @@ local function shallowcopy(t)
   for k, v in pairs(t) do
     result[k] = v
   end
+  -- Preserve metatable if present
+  local mt = getmetatable(t)
+  if mt then
+    setmetatable(result, mt)
+  end
   return result
 end
 
index 1bda5e5c2ece062603438db28ee2c8d084903ad8..eb69fed4efb8e24bcbdfaad70d18ca9a5a04753c 100644 (file)
@@ -321,6 +321,9 @@ Run Rspamd
   [Arguments]  ${check_port}=${RSPAMD_PORT_NORMAL}
   Export Rspamd Variables To Environment
 
+  # Copy config file to TMPDIR so it gets saved on teardown
+  Copy File  ${CONFIG}  ${RSPAMD_TMPDIR}/rspamd.conf
+
   # Dump templated config or errors to log
   ${result} =  Run Process  ${RSPAMADM}
   ...  --var\=TMPDIR\=${RSPAMD_TMPDIR}
@@ -336,10 +339,37 @@ Run Rspamd
   ...  env:ASAN_OPTIONS=quarantine_size_mb=2048:malloc_context_size=20:fast_unwind_on_malloc=0:log_path=${RSPAMD_TMPDIR}/rspamd-asan
   # We need to send output to files (or discard output) to avoid hanging Robot
   ...  stdout=${RSPAMD_TMPDIR}/configdump.stdout  stderr=${RSPAMD_TMPDIR}/configdump.stderr
+
+  # Always save configdump output to files, even if it failed
+  # First save process output directly to ensure we have something even if files weren't created
+  ${stdout_exists} =  Run Keyword And Return Status  File Should Exist  ${RSPAMD_TMPDIR}/configdump.stdout
+  ${stderr_exists} =  Run Keyword And Return Status  File Should Exist  ${RSPAMD_TMPDIR}/configdump.stderr
+
+  IF  not ${stdout_exists}
+    # File wasn't created, use process stdout if available
+    ${stdout_len} =  Get Length  ${result.stdout}
+    IF  ${stdout_len} > 0
+      Create File  ${RSPAMD_TMPDIR}/configdump.stdout  ${result.stdout}
+    ELSE
+      Create File  ${RSPAMD_TMPDIR}/configdump.stdout  <configdump stdout not created, process crashed?>
+    END
+  END
+
+  IF  not ${stderr_exists}
+    # File wasn't created, use process stderr if available
+    ${stderr_len} =  Get Length  ${result.stderr}
+    IF  ${stderr_len} > 0
+      Create File  ${RSPAMD_TMPDIR}/configdump.stderr  ${result.stderr}
+    ELSE
+      Create File  ${RSPAMD_TMPDIR}/configdump.stderr  <configdump stderr not created, process crashed?>
+    END
+  END
+
   IF  ${result.rc} == 0
     ${configdump} =  Get File  ${RSPAMD_TMPDIR}/configdump.stdout  encoding_errors=ignore
   ELSE
     ${configdump} =  Get File  ${RSPAMD_TMPDIR}/configdump.stderr  encoding_errors=ignore
+    Log  Configdump failed with rc=${result.rc}  level=WARN
   END
   Log  ${configdump}