From 556c29fd4b14366ef3b5836fc5d0e956bb8ac1bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=ADle=20Ekaterin=20Liszka?= Date: Fri, 12 Jan 2024 23:27:25 -0800 Subject: [PATCH] tests: integrate test files, fix key-walking --- src/xbc/__init__.py | 19 +++++++++- tests/40-invalid1.xbc | 5 --- tests/test_bare.py | 2 +- tests/test_block.py | 2 +- tests/test_files.py | 86 +++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 106 insertions(+), 8 deletions(-) delete mode 100644 tests/40-invalid1.xbc create mode 100644 tests/test_files.py diff --git a/src/xbc/__init__.py b/src/xbc/__init__.py index 9859c57..88cb383 100644 --- a/src/xbc/__init__.py +++ b/src/xbc/__init__.py @@ -164,6 +164,15 @@ def unquote(val): return val[1:-1] return val.strip() +def key_walk(d, key): + split = key.split('.') + + for i in range(len(split) - 1, 0, -1): + x = '.'.join(split[:i]) + print(x) + if x not in d: + d[x] = False + def parse_block(key, seq): if isinstance(seq, list) and len(seq) == 1 and isinstance(seq[0], list): seq = seq[0] @@ -215,6 +224,9 @@ def parse_block(key, seq): assign = assign[0] ret[k] = assign + + if '.' in k: + key_walk(ret, k) elif isinstance(item, Block): value = item.contents @@ -224,7 +236,12 @@ def parse_block(key, seq): if not isinstance(value, list): value = [value] - ret.update(parse_block(k, value)) + d = parse_block(k, value) + + for k, v in d.items(): + if k in ret: + continue + ret[k] = v return ret diff --git a/tests/40-invalid1.xbc b/tests/40-invalid1.xbc deleted file mode 100644 index 26d5379..0000000 --- a/tests/40-invalid1.xbc +++ /dev/null @@ -1,5 +0,0 @@ -foo { - bar = 1 - foo = 2 -} -foo = 4 \ No newline at end of file diff --git a/tests/test_bare.py b/tests/test_bare.py index 74234dc..8b903f4 100644 --- a/tests/test_bare.py +++ b/tests/test_bare.py @@ -19,7 +19,7 @@ def test_keyvalue_space(): assert loads_xbc('a = a b') == {'a': 'a b'} def test_dot_keyvalue(): - assert loads_xbc('a.a = 1') == {'a.a': '1'} + assert loads_xbc('a.a = 1') == {'a': False, 'a.a': '1'} def test_keys(): assert loads_xbc('a;b') == {'a': True, 'b': True} diff --git a/tests/test_block.py b/tests/test_block.py index 4980cd2..de4f72d 100644 --- a/tests/test_block.py +++ b/tests/test_block.py @@ -13,7 +13,7 @@ def test_nested_block(): assert loads_xbc('a { b { c = 1 } }') == {'a.b.c': '1', 'a': False, 'a.b': False} def test_keyvalue_and_block(): - assert loads_xbc('a = 1\na { a = 1 }') == {'a': '1', 'a.a': '1'} + assert loads_xbc('a = 1\na { a = 1 }') == {'a': False, 'a': '1', 'a.a': '1'} def test_reassign_colon(): with pytest.raises(ParseError): diff --git a/tests/test_files.py b/tests/test_files.py new file mode 100644 index 0000000..7a0edcb --- /dev/null +++ b/tests/test_files.py @@ -0,0 +1,86 @@ + +import pytest + +from xbc import load_xbc + +def test_01(): + d = { + 'feature.option': False, + 'feature': False, + 'feature.option.foo': '1', + 'feature.option.bar': '2' + } + assert load_xbc('tests/01-keyvalue.xbc') == d + +def test_02(): + d = { + 'feature.option': False, + 'feature': False, + 'feature.option.foo': '1', + 'feature.option.bar': '2' + } + assert load_xbc('tests/02-block-keyvalue.xbc') == d + +def test_03(): + d = { + 'feature': False, + 'feature.options': ['foo', 'bar'] + } + assert load_xbc('tests/03-keyvalue-string.xbc') == d + +def test_10(): + d = { + 'feature.option': False, + 'feature': False, + 'feature.option.foo': '1', + 'feature.option.bar': '2' + } + assert load_xbc('tests/10-compact.xbc') == d + +def test_11(): + d = { + 'ftrace': False, + 'ftrace.event': False, + 'ftrace.event.task': False, + 'ftrace.event.task.task_newtask': False, + 'ftrace.event.task.task_newtask.filter': "pid < 128", + 'ftrace.event.task.task_newtask.enable': True, + 'ftrace.event.kprobes': False, + 'ftrace.event.kprobes.vfs_read': False, + 'ftrace.event.kprobes.vfs_read.probes': "vfs_read $arg1 $arg2", + 'ftrace.event.kprobes.vfs_read.filter': "common_pid < 200", + 'ftrace.event.kprobes.vfs_read.enable': True, + 'ftrace.event.synthetic': False, + 'ftrace.event.synthetic.initcall_latency': False, + 'ftrace.event.synthetic.initcall_latency.fields': ["unsigned long func", "u64 lat"], + 'ftrace.event.synthetic.initcall_latency.actions': "hist:keys=func.sym,lat:vals=lat:sort=lat", + 'ftrace.event.initcall': False, + 'ftrace.event.initcall.initcall_start': False, + 'ftrace.event.initcall.initcall_start.actions': "hist:keys=func:ts0=common_timestamp.usecs", + 'ftrace.event.initcall.initcall_finish': False, + 'ftrace.event.initcall.initcall_finish.actions': "hist:keys=func:lat=common_timestamp.usecs-$ts0:onmatch(initcall.initcall_start).initcall_latency(func,$lat)" + } + assert load_xbc('tests/11-config.xbc') == d + +def test_12(): + d = { + 'ftrace': False, + 'ftrace.event': False, + 'ftrace.event.synthetic': False, + 'ftrace.event.synthetic.initcall_latency': False, + 'ftrace.event.synthetic.initcall_latency.fields': ["unsigned long func", "u64 lat"], + 'ftrace.event.synthetic.initcall_latency.hist': False, + 'ftrace.event.synthetic.initcall_latency.hist.from': False, + 'ftrace.event.synthetic.initcall_latency.hist.from.event': 'initcall.initcall_start', + 'ftrace.event.synthetic.initcall_latency.hist.from.key': 'func', + 'ftrace.event.synthetic.initcall_latency.hist.from.assigns': "ts0=common_timestamp.usecs", + 'ftrace.event.synthetic.initcall_latency.hist.to': False, + 'ftrace.event.synthetic.initcall_latency.hist.to.event': 'initcall.initcall_finish', + 'ftrace.event.synthetic.initcall_latency.hist.to.key': 'func', + 'ftrace.event.synthetic.initcall_latency.hist.to.assigns': "lat=common_timestamp.usecs-$ts0", + 'ftrace.event.synthetic.initcall_latency.hist.to.onmatch': ['func', '$lat'], + 'ftrace.event.synthetic.initcall_latency.hist.keys': ['func.sym', 'lat'], + 'ftrace.event.synthetic.initcall_latency.hist.vals': 'lat', + 'ftrace.event.synthetic.initcall_latency.hist.sort': 'lat' + } + assert load_xbc('tests/12-config2.xbc') == d