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 |