Check-in [cb3a619fe0]
Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Comment: | publish data test (mostly vhost/secrule extraction) |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA3-256: |
cb3a619fe085b6aa7bb0cd4904502a28 |
User & Date: | mario 2020-12-01 20:49:54 |
2020-12-01
| ||
20:52 | Build task for modsec-flameeyes.deb check-in: b362727f15 user: mario tags: trunk | |
20:49 | publish data test (mostly vhost/secrule extraction) check-in: cb3a619fe0 user: mario tags: trunk | |
20:46 | Release as 0.5.0 check-in: 6a7949da87 user: mario tags: trunk, 0.5.0 | |
Added pytest.ini.
> > > > > > > | 1 2 3 4 5 6 7 | [pytest] minversion = 1.0 addopts = -ra -q --ignore=test/util.py --ignore=test/_*.py --ignore=test/__*.py testpaths = test/ python_files = *.py # Yes sure pytest, why not do the obvious thing anyway python_functions = !_* [a-z]* [A-Z]* !_* |
Added test/Makefile.
> > > > > > > > > | 1 2 3 4 5 6 7 8 9 | all: test test: echo "Test data not transferable, due to embedded fn: values." pytest -v -v -v -v clean: rm test/*.out echo "Needs a few pytest reruns to generate .out files" |
Added test/plugin_meta.py.
> > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 | #t:t #d:simple pluginconf read import pluginconf, modseccfg def pluginconf_meta_read(): pluginconf.plugin_meta(module="modseccfg").get("version") def _dear_pytest_this_shall_not_run(): assert False |
Added test/rule.py.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | #t:t #d:basic rule parsing import pytest, util from modseccfg import vhosts def _rule(i): def run(): inp, out = f"test/rule_{i}.inp", f"test/rule_{i}.out" util.run(inp, vhosts.vhost, out) return run rule_1 = _rule(1) rule_2 = _rule(2) rule_3 = _rule(3) rule_4 = _rule(4) rule_5 = _rule(5) rule_6 = _rule(6) rule_7 = _rule(7) rule_8 = _rule(8) rule_9 = _rule(9) rule_10 = _rule(10) rule_11 = _rule(11) rule_12 = _rule(12) rule_20 = _rule(20) rule_21 = _rule(21) rule_22 = _rule(22) rule_25 = _rule(25) |
Added test/rule_1.inp.
> | 1 | SecRule ANY "@always" "id:1,phase:2,block:3,t:four" |
Added test/rule_1.out.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | { "fn": "test", "t": "cfg", "name": "", "logs": [], "cfg": {}, "rulestate": {}, "ruledecl": { "1": { "id": 1, "chained_to": 0, "msg": "ANY @always", "flags": [ "t:four" ], "params": { "phase": "2", "block": "3" }, "tags": [], "tag_primary": "", "ctl": {}, "setvar": {}, "vars": "ANY", "pattern": "@always", "hidden": false, "wrap": false } }, "update": {}, "warn": "", "linemap": { "0": 1 }, "wrap": [] } |
Added test/rule_10.inp.
> > > | 1 2 3 | SecRule DUPLICATE "@x" "id:10,pass" SecRule DUPLICATE "@x" "id:10,deny" |
Added test/rule_10.out.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | { "fn": "test", "t": "cfg", "name": "", "logs": [], "cfg": {}, "rulestate": {}, "ruledecl": { "10": { "id": 10, "chained_to": 0, "msg": "DUPLICATE @x", "flags": [ "deny" ], "params": {}, "tags": [], "tag_primary": "", "ctl": {}, "setvar": {}, "vars": "DUPLICATE", "pattern": "@x", "hidden": false, "wrap": false } }, "update": {}, "warn": "", "linemap": { "0": 10, "2": 10 }, "wrap": [] } |
Added test/rule_11.inp.
> | 1 | SecRule LOOK_NO_QUOTES @eq0 id:11,pass |
Added test/rule_11.out.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | { "fn": "test", "t": "cfg", "name": "", "logs": [], "cfg": {}, "rulestate": {}, "ruledecl": { "11": { "id": 11, "chained_to": 0, "msg": "LOOK_NO_QUOTES @eq0", "flags": [ "pass" ], "params": {}, "tags": [], "tag_primary": "", "ctl": {}, "setvar": {}, "vars": "LOOK_NO_QUOTES", "pattern": "@eq0", "hidden": false, "wrap": false } }, "update": {}, "warn": "", "linemap": { "0": 11 }, "wrap": [] } |
Added test/rule_12.inp.
> | 1 | SecRule "LOOK_SOME_QUOTES" @eq0 'id:12,pass' |
Added test/rule_12.out.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | { "fn": "test", "t": "cfg", "name": "", "logs": [], "cfg": {}, "rulestate": {}, "ruledecl": { "12": { "id": 12, "chained_to": 0, "msg": "LOOK_SOME_QUOTES @eq0", "flags": [ "pass" ], "params": {}, "tags": [], "tag_primary": "", "ctl": {}, "setvar": {}, "vars": "LOOK_SOME_QUOTES", "pattern": "@eq0", "hidden": false, "wrap": false } }, "update": {}, "warn": "", "linemap": { "0": 12 }, "wrap": [] } |
Added test/rule_2.inp.
> | 1 | SecRule AND "@some" "id:2,tag:TWO" |
Added test/rule_2.out.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | { "fn": "test", "t": "cfg", "name": "", "logs": [], "cfg": {}, "rulestate": {}, "ruledecl": { "2": { "id": 2, "chained_to": 0, "msg": "AND @some", "flags": [], "params": {}, "tags": [ "TWO" ], "tag_primary": "", "ctl": {}, "setvar": {}, "vars": "AND", "pattern": "@some", "hidden": false, "wrap": false } }, "update": {}, "warn": "", "linemap": { "0": 2 }, "wrap": [] } |
Added test/rule_20.inp.
> | 1 | SecRule CTL ctl "id:20,ctl:restart=1" |
Added test/rule_20.out.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | { "fn": "test", "t": "cfg", "name": "", "logs": [], "cfg": {}, "rulestate": {}, "ruledecl": { "20": { "id": 20, "chained_to": 0, "msg": "CTL ctl", "flags": [], "params": {}, "tags": [], "tag_primary": "", "ctl": { "restart": "1" }, "setvar": {}, "vars": "CTL", "pattern": "ctl", "hidden": false, "wrap": false } }, "update": {}, "warn": "", "linemap": { "0": 20 }, "wrap": [] } |
Added test/rule_21.inp.
> | 1 | SecRule VAR ctl "id:21,setvar:restart=1" |
Added test/rule_21.out.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | { "fn": "test", "t": "cfg", "name": "", "logs": [], "cfg": {}, "rulestate": {}, "ruledecl": { "21": { "id": 21, "chained_to": 0, "msg": "VAR ctl", "flags": [], "params": {}, "tags": [], "tag_primary": "", "ctl": {}, "setvar": { "restart": "1" }, "vars": "VAR", "pattern": "ctl", "hidden": false, "wrap": false } }, "update": {}, "warn": "", "linemap": { "0": 21 }, "wrap": [] } |
Added test/rule_22.inp.
> | 1 | SecRule PARAMS @pm "id:22,setenv:CRON=x" |
Added test/rule_22.out.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | { "fn": "test", "t": "cfg", "name": "", "logs": [], "cfg": {}, "rulestate": {}, "ruledecl": { "22": { "id": 22, "chained_to": 0, "msg": "PARAMS @pm", "flags": [], "params": { "setenv": "CRON=x" }, "tags": [], "tag_primary": "", "ctl": {}, "setvar": {}, "vars": "PARAMS", "pattern": "@pm", "hidden": false, "wrap": false } }, "update": {}, "warn": "", "linemap": { "0": 22 }, "wrap": [] } |
Added test/rule_25.inp.
> > > > | 1 2 3 4 | SecRule PAIRED p1 "id:25,chain" SecRule PAIRED p2 "pass,chain" SecRule PAIRED p3 "pass,chain" SecRule PAIRED p4 "pass,msg:end" |
Added test/rule_25.out.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 | { "fn": "test", "t": "rules", "name": "", "logs": [], "cfg": {}, "rulestate": {}, "ruledecl": { "25": { "id": 25, "chained_to": 0, "msg": "PAIRED p1", "flags": [ "chain" ], "params": {}, "tags": [], "tag_primary": "", "ctl": {}, "setvar": {}, "vars": "PAIRED", "pattern": "p1", "hidden": false, "wrap": false }, "25.1": { "id": 25.1, "chained_to": 25, "msg": "PAIRED p2", "flags": [ "pass", "chain" ], "params": {}, "tags": [], "tag_primary": "", "ctl": {}, "setvar": {}, "vars": "PAIRED", "pattern": "p2", "hidden": false, "wrap": false }, "25.2": { "id": 25.2, "chained_to": 25, "msg": "PAIRED p3", "flags": [ "pass", "chain" ], "params": {}, "tags": [], "tag_primary": "", "ctl": {}, "setvar": {}, "vars": "PAIRED", "pattern": "p3", "hidden": false, "wrap": false }, "25.3": { "id": 25.3, "chained_to": 25, "msg": "end", "flags": [ "pass" ], "params": {}, "tags": [], "tag_primary": "", "ctl": {}, "setvar": {}, "vars": "PAIRED", "pattern": "p4", "hidden": false, "wrap": false } }, "update": {}, "warn": "", "linemap": { "0": 25 }, "wrap": [] } |
Added test/rule_3.inp.
> | 1 | SecRule OR "@none" "id:3,-" |
Added test/rule_3.out.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | { "fn": "test", "t": "cfg", "name": "", "logs": [], "cfg": {}, "rulestate": {}, "ruledecl": { "3": { "id": 3, "chained_to": 0, "msg": "OR @none", "flags": [], "params": {}, "tags": [], "tag_primary": "", "ctl": {}, "setvar": {}, "vars": "OR", "pattern": "@none", "hidden": false, "wrap": false } }, "update": {}, "warn": "", "linemap": { "0": 3 }, "wrap": [] } |
Added test/rule_30.inp.
> | 1 | SecAction "id:30,pass,setvar:x=2" |
Added test/rule_30.out.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | { "fn": "test", "t": "cfg", "name": "", "logs": [], "cfg": {}, "rulestate": {}, "ruledecl": { "30": { "id": 30, "chained_to": 0, "msg": "@SecAction {'x': '2'}", "flags": [ "pass" ], "params": {}, "tags": [], "tag_primary": "", "ctl": {}, "setvar": { "x": "2" }, "vars": "@SecAction", "pattern": "setvar:", "hidden": false, "wrap": false } }, "update": {}, "warn": "", "linemap": { "0": 30 }, "wrap": [] } |
Added test/rule_4.inp.
> | 1 | SecRule WITH "@out" "id:4,msg:" |
Added test/rule_4.out.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | { "fn": "test", "t": "cfg", "name": "", "logs": [], "cfg": {}, "rulestate": {}, "ruledecl": { "4": { "id": 4, "chained_to": 0, "msg": "WITH @out", "flags": [], "params": {}, "tags": [], "tag_primary": "", "ctl": {}, "setvar": {}, "vars": "WITH", "pattern": "@out", "hidden": false, "wrap": false } }, "update": {}, "warn": "", "linemap": { "0": 4 }, "wrap": [] } |
Added test/rule_5.inp.
> | 1 | SecRule HAS|NO|KEYS "?" "id:5,:" |
Added test/rule_5.out.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | { "fn": "test", "t": "cfg", "name": "", "logs": [], "cfg": {}, "rulestate": {}, "ruledecl": { "5": { "id": 5, "chained_to": 0, "msg": "HAS|NO|KEYS ?", "flags": [], "params": {}, "tags": [], "tag_primary": "", "ctl": {}, "setvar": {}, "vars": "HAS|NO|KEYS", "pattern": "?", "hidden": false, "wrap": false } }, "update": {}, "warn": "", "linemap": { "0": 5 }, "wrap": [] } |
Added test/rule_6.inp.
> | 1 | SecRule &DO,!NOT,CARE: "./." "id:6,deny" |
Added test/rule_6.out.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | { "fn": "test", "t": "cfg", "name": "", "logs": [], "cfg": {}, "rulestate": {}, "ruledecl": { "6": { "id": 6, "chained_to": 0, "msg": "&DO,!NOT,CARE: ./.", "flags": [ "deny" ], "params": {}, "tags": [], "tag_primary": "", "ctl": {}, "setvar": {}, "vars": "&DO,!NOT,CARE:", "pattern": "./.", "hidden": false, "wrap": false } }, "update": {}, "warn": "", "linemap": { "0": 6 }, "wrap": [] } |
Added test/rule_7.inp.
> | 1 | SecRule ARGS:normal "@rx ^.*$" "id:7,logdata:'things'" |
Added test/rule_7.out.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | { "fn": "test", "t": "cfg", "name": "", "logs": [], "cfg": {}, "rulestate": {}, "ruledecl": { "7": { "id": 7, "chained_to": 0, "msg": "things", "flags": [], "params": { "logdata": "things" }, "tags": [], "tag_primary": "", "ctl": {}, "setvar": {}, "vars": "ARGS:normal", "pattern": "@rx ^.*$", "hidden": false, "wrap": false } }, "update": {}, "warn": "", "linemap": { "0": 7 }, "wrap": [] } |
Added test/rule_8.inp.
> | 1 | SecRule ARGS:normal "@pmFromFile file.txt" "id:8,msg:it_is_what_it_is" |
Added test/rule_8.out.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | { "fn": "test", "t": "cfg", "name": "", "logs": [], "cfg": {}, "rulestate": {}, "ruledecl": { "8": { "id": 8, "chained_to": 0, "msg": "it_is_what_it_is", "flags": [], "params": {}, "tags": [], "tag_primary": "", "ctl": {}, "setvar": {}, "vars": "ARGS:normal", "pattern": "@pmFromFile file.txt", "hidden": false, "wrap": false } }, "update": {}, "warn": "", "linemap": { "0": 8 }, "wrap": [] } |
Added test/rule_9.inp.
> | 1 | SecRule ARGS:normal "@pmFromFile file.txt" "id:9,msg:it_is_what_it_is" |
Added test/rule_9.out.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | { "fn": "test", "t": "cfg", "name": "", "logs": [], "cfg": {}, "rulestate": {}, "ruledecl": { "9": { "id": 9, "chained_to": 0, "msg": "it_is_what_it_is", "flags": [], "params": {}, "tags": [], "tag_primary": "", "ctl": {}, "setvar": {}, "vars": "ARGS:normal", "pattern": "@pmFromFile file.txt", "hidden": false, "wrap": false } }, "update": {}, "warn": "", "linemap": { "0": 9 }, "wrap": [] } |
Added test/secdirectives.inp.
> > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | SecRuleRemoveById 123 123 # @SecAction {'tx.crs_setup_version': '320'} SecRuleRemoveById 9001110 # REQUEST_FILENAME @endsWith /core/install.php SecAuditEngine RelevantOnly SecAuditLogType Concurrent SecRuleInheritance On SecRuleEngine DetectionOnly SecDebugLogLevel 8 SecUploadFileMode octal_mode SecPdfProtect Off SecHashEngine On SecHashKey RemoteIP SecAction "id:5999,pass,nolog,noauditlog,t:none, \ setvar:tx.crs_exclusions_xenforo=1, \ ctl:ruleRemoveById=900130, \ setvar:tx.block_spammer_ip=1, \ ctl:ruleRemoveById=900500, \ setvar:tx.do_reput_block=1, \ ctl:ruleRemoveById=900960, \ setvar:tx.crs_exclusions_dokuwiki=1, \ setvar:tx.block_suspicious_ip=1, \ setvar:tx.crs_exclusions_drupal=1, \ setvar:tx.crs_exclusions_nextcloud=1, \ setvar:tx.crs_exclusions_wordpress=1" |
Added test/secdirectives.out.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 | { "fn": "/home/mario/projects/modseccfg/test/secdirectives.inp", "t": "cfg", "name": "", "logs": [], "cfg": { "secauditengine": "RelevantOnly", "secauditlogtype": "Concurrent", "secruleinheritance": "On", "secruleengine": "DetectionOnly", "secdebugloglevel": "8", "secuploadfilemode": "octal_mode", "secpdfprotect": "Off", "sechashengine": "On", "sechashkey": "RemoteIP" }, "rulestate": { "123": "\u274c", "9001110": "\u274c" }, "ruledecl": { "5999": { "id": 5999, "chained_to": 0, "msg": "@SecAction {'tx.crs_exclusions_xenforo': '1', 'tx.block_spammer_ip': '1', 'tx.do_reput_block': '1', 'tx.crs_exclusions_dokuwiki': '1', 'tx.block_suspicious_ip': '1', 'tx.crs_exclusions_drupal': '1', 'tx.crs_exclusions_nextcloud': '1', 'tx.crs_exclusions_wordpress': '1'}", "flags": [ "pass", "nolog", "noauditlog", "t:none" ], "params": {}, "tags": [], "tag_primary": "", "ctl": { "ruleRemoveById": "900960" }, "setvar": { "tx.crs_exclusions_xenforo": "1", "tx.block_spammer_ip": "1", "tx.do_reput_block": "1", "tx.crs_exclusions_dokuwiki": "1", "tx.block_suspicious_ip": "1", "tx.crs_exclusions_drupal": "1", "tx.crs_exclusions_nextcloud": "1", "tx.crs_exclusions_wordpress": "1" }, "vars": "@SecAction", "pattern": "setvar:", "hidden": false, "wrap": false } }, "update": {}, "warn": "", "linemap": { "11": 5999 }, "wrap": [] } |
Added test/secdirectives.py.
> > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 | #t:t #d:lots of SecEngine directives import pytest, util from modseccfg import vhosts @util.io def secdirectives(inp, out): src = util.inp_read(inp) vh = vhosts.vhost(inp, src) util.out_test(vh, out) |
Added test/util.py.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 | # encoding: utf8 # type: decorator # title: test utils # description: data-driven helper code # depends: python (>= 3.4) # # Adds .inp and .out file stubs. # Where .inp usually contains source, and is checked # against an .out JSON representation of whatever # transformation happened. # Mostly for vhost() and secrule() properties. # import pytest, functools, re, os, json __test__ = False # pytest: "Nah, let's not be consistent" # Adds two params (inp, out) with filenames # named after the wrapped function. @functools.singledispatch def io(func): print(func.__name__) def wrapper(): __dir__ = re.sub("[^/]+$", "", __file__) # ought to use funcs` path inp_fn = __dir__ + func.__name__ + ".inp" out_fn = __dir__ + func.__name__ + ".out" return func(inp_fn, out_fn) return wrapper # should have been a decorator too def run(inp, subject, out): src = inp_read(inp) vh = subject(inp, src) if hasattr(vh, "fn"): vh.fn="test" out_test(vh, out) # read def inp_read(inp_fn): return open(inp_fn, "r", encoding="utf8").read() # write output, or compare to existing result def out_test(result, out_fn): # turn e.g. vhost/secrule into dict result = _recurse_obj_to_dict(result) # write current data, and/or read previous dump if not os.path.exists(out_fn): open(out_fn, "w", encoding="utf8").write(json.dumps(result, indent=4)) else: out = json.loads(open(out_fn, "r", encoding="utf8").read()) print (out) print (result) # test assert out == result, f"Output {out_fn} doesn't match current data" passed = 1 # else prepare update (but assert can't double as expr) if not passed: open(out_fn+".new", "w", encoding="utf8").write(json.dumps(result, indent=4)) # flatten objects to dictionaries, keys to strings def _recurse_obj_to_dict(o): if hasattr(o, "__dict__"): o = o.__dict__ if isinstance(o, dict): o = { str(k): _recurse_obj_to_dict(v) for k,v in o.items() } return o |
Added test/vhost.py.
> > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 | #t:t #d:basic rule parsing import pytest, util from modseccfg import vhosts @util.io def vhost_simple(inp, out): util.run(inp, vhosts.vhost, out) @util.io def vhost_list(inp, out): util.run(inp, vhosts.vhost, out) |
Added test/vhost_list.inp.
> > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | # This will just collect one `vhost`, with the first directives sticking, # for server name and documentroot at least. # We don't actually collect vhosts per section, but on per-filename basis. <VirtualHost *> ServerName first DocumentRoot /tmp </VirtualHost> <VirtualHost *> ServerName second DocumentRoot /dev/null </VirtualHost> <VirtualHost *> ServerName third ServerAlias *.localnet DocumentRoot / </VirtualHost> # end |
Added test/vhost_list.out.
> > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | { "fn": "test", "t": "vhost", "name": "first", "logs": [], "cfg": { "documentroot": "/tmp" }, "rulestate": {}, "ruledecl": {}, "update": {}, "warn": "Unreasonable number of <VirtualHost> entries in conf. It probably shouldn't be edited through modseccfg.", "linemap": {}, "wrap": [] } |
Added test/vhost_simple.inp.
> > > | 1 2 3 | # comment ServerName example.com SecRuleDisablyById 12345 |
Added test/vhost_simple.out.
> > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | { "fn": "test", "t": "vhost", "name": "example.com", "logs": [], "cfg": { "secruledisablybyid": "12345" }, "rulestate": {}, "ruledecl": {}, "update": {}, "warn": "", "linemap": {}, "wrap": [] } |
Added tox.ini.
> > > > > > > > > | 1 2 3 4 5 6 7 8 9 | [tox] envlist = py37 [testenv] deps = pytest pluginconf commands = pytest test |