]> git.ipfire.org Git - thirdparty/rspamd.git/commitdiff
[Test] Add functional tests for logstats and mapstats
authorVsevolod Stakhov <vsevolod@rspamd.com>
Wed, 11 Feb 2026 11:06:54 +0000 (11:06 +0000)
committerVsevolod Stakhov <vsevolod@rspamd.com>
Wed, 11 Feb 2026 11:06:54 +0000 (11:06 +0000)
Robot Framework tests covering:
- logstats: JSON output, text output, symbol filter, alpha_score
  warning, stdin mode, scan time display
- mapstats: map loading, inline comments for plain/IP/regexp maps,
  match counts, regexp matching

Includes test data: sample log files, plain/IP/regexp map files,
and a minimal multimap config.

test/functional/cases/152_rspamadm_logstats.robot [new file with mode: 0644]
test/functional/cases/153_rspamadm_mapstats.robot [new file with mode: 0644]
test/functional/configs/mapstats_test.conf [new file with mode: 0644]
test/functional/data/logstats_test.data [new file with mode: 0644]
test/functional/data/mapstats_ip.map [new file with mode: 0644]
test/functional/data/mapstats_plain.map [new file with mode: 0644]
test/functional/data/mapstats_re.map [new file with mode: 0644]
test/functional/data/mapstats_test.data [new file with mode: 0644]

diff --git a/test/functional/cases/152_rspamadm_logstats.robot b/test/functional/cases/152_rspamadm_logstats.robot
new file mode 100644 (file)
index 0000000..2d5985f
--- /dev/null
@@ -0,0 +1,60 @@
+*** Settings ***
+Suite Setup     Rspamadm Setup
+Suite Teardown  Rspamadm Teardown
+Library         ${RSPAMD_TESTDIR}/lib/rspamd.py
+Resource        ${RSPAMD_TESTDIR}/lib/rspamd.robot
+Test Timeout    1 minute
+
+*** Variables ***
+${LOGSTATS_LOG}    ${RSPAMD_TESTDIR}/data/logstats_test.data
+
+*** Test Cases ***
+Logstats JSON output
+  ${result} =  Rspamadm  logstats  --json  ${LOGSTATS_LOG}
+  Should Be Equal As Integers  ${result.rc}  0
+  Should Contain  ${result.stdout}  "total"
+  Should Contain  ${result.stdout}  "no action"
+  Should Contain  ${result.stdout}  "reject"
+  Should Contain  ${result.stdout}  "add header"
+  Should Contain  ${result.stdout}  "greylist"
+  Should Contain  ${result.stdout}  "symbols"
+
+Logstats text output
+  ${result} =  Rspamadm  logstats  ${LOGSTATS_LOG}
+  Should Be Equal As Integers  ${result.rc}  0
+  Should Contain  ${result.stdout}  Messages scanned: 10
+  Should Contain  ${result.stdout}  === Summary
+  Should Contain  ${result.stdout}  no action
+  Should Contain  ${result.stdout}  reject
+  Should Contain  ${result.stdout}  add header
+  Should Contain  ${result.stdout}  greylist
+
+Logstats symbol filter
+  ${result} =  Rspamadm  logstats  -s  BAYES_SPAM  ${LOGSTATS_LOG}
+  Should Be Equal As Integers  ${result.rc}  0
+  Should Contain  ${result.stdout}  BAYES_SPAM
+  Should Not Contain  ${result.stdout}  R_SPF_ALLOW
+  Should Contain  ${result.stdout}  Messages scanned: 10
+
+Logstats alpha score warning
+  ${result} =  Rspamadm  logstats  ${LOGSTATS_LOG}
+  Should Be Equal As Integers  ${result.rc}  0
+  Should Contain  ${result.stdout}  WARNING:
+  Should Contain  ${result.stdout}  DKIM_TRACE
+  Should Contain  ${result.stdout}  alpha_score
+
+Logstats stdin
+  ${result} =  Run Process  ${RSPAMADM}
+  ...  --var\=TMPDIR\=${RSPAMADM_TMPDIR}
+  ...  --var\=DBDIR\=${RSPAMADM_TMPDIR}
+  ...  --var\=LOCAL_CONFDIR\=/nonexistent
+  ...  logstats  --json  -
+  ...  stdin=${LOGSTATS_LOG}
+  Should Be Equal As Integers  ${result.rc}  0
+  Should Contain  ${result.stdout}  "total"
+  Should Contain  ${result.stdout}  "no action"
+
+Logstats scan time
+  ${result} =  Rspamadm  logstats  ${LOGSTATS_LOG}
+  Should Be Equal As Integers  ${result.rc}  0
+  Should Contain  ${result.stdout}  scan time min/avg/max
diff --git a/test/functional/cases/153_rspamadm_mapstats.robot b/test/functional/cases/153_rspamadm_mapstats.robot
new file mode 100644 (file)
index 0000000..8c402de
--- /dev/null
@@ -0,0 +1,52 @@
+*** Settings ***
+Suite Setup     Rspamadm Setup
+Suite Teardown  Rspamadm Teardown
+Library         ${RSPAMD_TESTDIR}/lib/rspamd.py
+Resource        ${RSPAMD_TESTDIR}/lib/rspamd.robot
+Test Timeout    1 minute
+
+*** Variables ***
+${MAPSTATS_LOG}     ${RSPAMD_TESTDIR}/data/mapstats_test.data
+${MAPSTATS_CONF}    ${RSPAMD_TESTDIR}/configs/mapstats_test.conf
+
+*** Test Cases ***
+Mapstats map loading
+  ${result} =  Run Mapstats
+  Should Be Equal As Integers  ${result.rc}  0
+  Should Contain  ${result.stdout}  TEST_PLAIN
+  Should Contain  ${result.stdout}  TEST_IP
+  Should Contain  ${result.stdout}  TEST_RE
+  Should Contain  ${result.stdout}  [OK]
+
+Mapstats plain map comments
+  ${result} =  Run Mapstats
+  Should Be Equal As Integers  ${result.rc}  0
+  Should Contain  ${result.stdout}  \# Test domain
+  Should Contain  ${result.stdout}  \# Scored entry
+
+Mapstats IP map comments
+  ${result} =  Run Mapstats
+  Should Be Equal As Integers  ${result.rc}  0
+  Should Contain  ${result.stdout}  \# Private network
+  Should Contain  ${result.stdout}  \# Internal
+
+Mapstats regexp map comments
+  ${result} =  Run Mapstats
+  Should Be Equal As Integers  ${result.rc}  0
+  Should Contain  ${result.stdout}  \# Test pattern
+
+Mapstats plain match counts
+  ${result} =  Run Mapstats
+  Should Be Equal As Integers  ${result.rc}  0
+  Should Contain  ${result.stdout}  example.com
+  Should Contain  ${result.stdout}  test.org
+
+Mapstats regexp match
+  ${result} =  Run Mapstats
+  Should Be Equal As Integers  ${result.rc}  0
+  Should Contain  ${result.stdout}  test-string-
+
+*** Keywords ***
+Run Mapstats
+  ${result} =  Rspamadm  --var\=TESTDIR\=${RSPAMD_TESTDIR}  mapstats  -c  ${MAPSTATS_CONF}  ${MAPSTATS_LOG}
+  RETURN  ${result}
diff --git a/test/functional/configs/mapstats_test.conf b/test/functional/configs/mapstats_test.conf
new file mode 100644 (file)
index 0000000..63864e4
--- /dev/null
@@ -0,0 +1,15 @@
+multimap {
+  TEST_PLAIN {
+    type = "from";
+    map = "{= env.TESTDIR =}/data/mapstats_plain.map";
+  }
+  TEST_IP {
+    type = "ip";
+    map = "{= env.TESTDIR =}/data/mapstats_ip.map";
+  }
+  TEST_RE {
+    type = "from";
+    regexp = true;
+    map = "{= env.TESTDIR =}/data/mapstats_re.map";
+  }
+}
diff --git a/test/functional/data/logstats_test.data b/test/functional/data/logstats_test.data
new file mode 100644 (file)
index 0000000..27fa37a
--- /dev/null
@@ -0,0 +1,10 @@
+2026-02-01 10:00:01.100 #1001(normal) <a1b2c3>; rspamd_task_write_log: id: <msg001@test.com>, qid: <Q001>, ip: 10.0.0.1, (no action): [1.5/15.0] [R_SPF_ALLOW(-1.0),BAYES_HAM(-3.0),MIME_GOOD(-0.1),DKIM_TRACE(0.0)], len: 1234, time: 5.20ms
+2026-02-01 10:00:02.200 #1001(normal) <d4e5f6>; rspamd_task_write_log: id: <msg002@test.com>, qid: <Q002>, ip: 10.0.0.2, (reject): [18.5/15.0] [BAYES_SPAM(5.0),RBL_SPAMHAUS(4.0),SURBL_MULTI(5.5),FORGED_SENDER(3.0),MISSING_MID(1.0)], len: 2345, time: 15.30ms
+2026-02-01 10:00:03.300 #1001(normal) <g7h8i9>; rspamd_task_write_log: id: <msg003@test.com>, qid: <Q003>, ip: 10.0.0.3, (add header): [8.2/15.0] [BAYES_SPAM(5.0),RBL_SPAMHAUS(4.0),R_SPF_SOFTFAIL(1.0),MISSING_MID(1.0)], len: 3456, time: 12.10ms
+2026-02-01 10:00:04.400 #1001(normal) <j0k1l2>; rspamd_task_write_log: id: <msg004@test.com>, qid: <Q004>, ip: 10.0.0.4, (no action): [0.5/15.0] [R_SPF_ALLOW(-1.0),R_DKIM_ALLOW(-0.5),MIME_GOOD(-0.1),DKIM_TRACE(0.0)], len: 4567, time: 3.80ms
+2026-02-01 10:00:05.500 #1001(normal) <m3n4o5>; rspamd_task_write_log: id: <msg005@test.com>, qid: <Q005>, ip: 10.0.0.5, (reject): [22.0/15.0] [BAYES_SPAM(5.0),RBL_SPAMHAUS(4.0),SURBL_MULTI(5.5),FORGED_SENDER(3.0),MISSING_MID(1.0),GTUBE(3.5)], len: 5678, time: 20.50ms
+2026-02-01 10:00:06.600 #1001(normal) <p6q7r8>; rspamd_task_write_log: id: <msg006@test.com>, qid: <Q006>, ip: 10.0.0.6, (greylist): [4.5/15.0] [BAYES_SPAM(5.0),R_SPF_ALLOW(-1.0),MIME_GOOD(-0.1)], len: 6789, time: 8.40ms
+2026-02-01 10:00:07.700 #1001(normal) <s9t0u1>; rspamd_task_write_log: id: <msg007@test.com>, qid: <Q007>, ip: 10.0.0.7, (no action): [-1.0/15.0] [R_SPF_ALLOW(-1.0),R_DKIM_ALLOW(-0.5),BAYES_HAM(-3.0),MIME_GOOD(-0.1),DKIM_TRACE(0.0)], len: 7890, time: 4.60ms
+2026-02-01 10:00:08.800 #1001(normal) <v2w3x4>; rspamd_task_write_log: id: <msg008@test.com>, qid: <Q008>, ip: 10.0.0.8, (add header): [9.1/15.0] [BAYES_SPAM(5.0),SURBL_MULTI(5.5),R_SPF_SOFTFAIL(1.0)], len: 8901, time: 18.20ms
+2026-02-01 10:00:09.900 #1001(normal) <y5z6a7>; rspamd_task_write_log: id: <msg009@test.com>, qid: <Q009>, ip: 10.0.0.9, (no action): [2.0/15.0] [FORGED_SENDER(3.0),R_SPF_ALLOW(-1.0)], len: 9012, time: 6.30ms
+2026-02-01 10:00:10.100 #1001(normal) <b8c9d0>; rspamd_task_write_log: id: <msg010@test.com>, qid: <Q010>, ip: 10.0.0.10, (reject): [16.0/15.0] [BAYES_SPAM(5.0),RBL_SPAMHAUS(4.0),FORGED_SENDER(3.0),SURBL_MULTI(5.5),MISSING_MID(1.0)], len: 1023, time: 14.70ms
diff --git a/test/functional/data/mapstats_ip.map b/test/functional/data/mapstats_ip.map
new file mode 100644 (file)
index 0000000..98237fe
--- /dev/null
@@ -0,0 +1,4 @@
+192.168.1.0/24 # Private network
+10.0.0.0/8 # Internal
+# Comment line
+172.16.0.0/12 # Other private
diff --git a/test/functional/data/mapstats_plain.map b/test/functional/data/mapstats_plain.map
new file mode 100644 (file)
index 0000000..0aedbe2
--- /dev/null
@@ -0,0 +1,5 @@
+example.com # Test domain
+test.org 1.5 # Scored entry
+foo.bar
+# This is a comment line
+unmatched.example # Won't be hit
diff --git a/test/functional/data/mapstats_re.map b/test/functional/data/mapstats_re.map
new file mode 100644 (file)
index 0000000..f9093c9
--- /dev/null
@@ -0,0 +1,4 @@
+/test-string-\d+/i # Test pattern
+/^foobar$/ # Exact match
+# Comment line
+/unused-pattern/ # Won't match
diff --git a/test/functional/data/mapstats_test.data b/test/functional/data/mapstats_test.data
new file mode 100644 (file)
index 0000000..37d8533
--- /dev/null
@@ -0,0 +1,5 @@
+2026-02-01 10:00:01.100 #1001(normal) <a1b2c3>; rspamd_task_write_log: id: <msg001@test.com>, qid: <Q001>, ip: 10.0.0.1, (no action): [2.0/15.0] [TEST_PLAIN(1.0){example.com;},R_SPF_ALLOW(-1.0)], len: 1000, time: 5.00ms
+2026-02-01 10:00:02.200 #1001(normal) <d4e5f6>; rspamd_task_write_log: id: <msg002@test.com>, qid: <Q002>, ip: 192.168.1.100, (no action): [3.0/15.0] [TEST_PLAIN(1.0){test.org;},TEST_IP(2.0){192.168.1.100;}], len: 2000, time: 8.00ms
+2026-02-01 10:00:03.300 #1001(normal) <g7h8i9>; rspamd_task_write_log: id: <msg003@test.com>, qid: <Q003>, ip: 10.0.0.3, (no action): [1.5/15.0] [TEST_RE(1.5){test-string-123;}], len: 3000, time: 6.00ms
+2026-02-01 10:00:04.400 #1001(normal) <j0k1l2>; rspamd_task_write_log: id: <msg004@test.com>, qid: <Q004>, ip: 10.0.0.4, (no action): [1.0/15.0] [TEST_PLAIN(1.0){example.com;}], len: 4000, time: 4.00ms
+2026-02-01 10:00:05.500 #1001(normal) <m3n4o5>; rspamd_task_write_log: id: <msg005@test.com>, qid: <Q005>, ip: 10.5.3.1, (no action): [2.0/15.0] [TEST_IP(2.0){10.5.3.1;}], len: 5000, time: 7.00ms