From: Vsevolod Stakhov Date: Wed, 11 Feb 2026 11:06:54 +0000 (+0000) Subject: [Test] Add functional tests for logstats and mapstats X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=4878834f42ffcdee27975f37b173f2cfa0848ba0;p=thirdparty%2Frspamd.git [Test] Add functional tests for logstats and mapstats 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. --- diff --git a/test/functional/cases/152_rspamadm_logstats.robot b/test/functional/cases/152_rspamadm_logstats.robot new file mode 100644 index 0000000000..2d5985f452 --- /dev/null +++ b/test/functional/cases/152_rspamadm_logstats.robot @@ -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 index 0000000000..8c402de263 --- /dev/null +++ b/test/functional/cases/153_rspamadm_mapstats.robot @@ -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 index 0000000000..63864e440b --- /dev/null +++ b/test/functional/configs/mapstats_test.conf @@ -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 index 0000000000..27fa37add8 --- /dev/null +++ b/test/functional/data/logstats_test.data @@ -0,0 +1,10 @@ +2026-02-01 10:00:01.100 #1001(normal) ; rspamd_task_write_log: id: , qid: , 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) ; rspamd_task_write_log: id: , qid: , 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) ; rspamd_task_write_log: id: , qid: , 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) ; rspamd_task_write_log: id: , qid: , 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) ; rspamd_task_write_log: id: , qid: , 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) ; rspamd_task_write_log: id: , qid: , 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) ; rspamd_task_write_log: id: , qid: , 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) ; rspamd_task_write_log: id: , qid: , 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) ; rspamd_task_write_log: id: , qid: , 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) ; rspamd_task_write_log: id: , qid: , 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 index 0000000000..98237fe604 --- /dev/null +++ b/test/functional/data/mapstats_ip.map @@ -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 index 0000000000..0aedbe2e29 --- /dev/null +++ b/test/functional/data/mapstats_plain.map @@ -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 index 0000000000..f9093c9fa0 --- /dev/null +++ b/test/functional/data/mapstats_re.map @@ -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 index 0000000000..37d8533fd8 --- /dev/null +++ b/test/functional/data/mapstats_test.data @@ -0,0 +1,5 @@ +2026-02-01 10:00:01.100 #1001(normal) ; rspamd_task_write_log: id: , qid: , 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) ; rspamd_task_write_log: id: , qid: , 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) ; rspamd_task_write_log: id: , qid: , 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) ; rspamd_task_write_log: id: , qid: , 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) ; rspamd_task_write_log: id: , qid: , ip: 10.5.3.1, (no action): [2.0/15.0] [TEST_IP(2.0){10.5.3.1;}], len: 5000, time: 7.00ms