diff --git a/scripts/detect_duplicate_features.py b/scripts/detect_duplicate_features.py index a72688c0..ff21fd0b 100644 --- a/scripts/detect_duplicate_features.py +++ b/scripts/detect_duplicate_features.py @@ -48,14 +48,14 @@ def get_features(rule_path: str) -> list: feature_list = get_child_features(new_rule.statement) except Exception as e: logger.error("Error: New rule " + rule_path + " " + str(type(e)) + " " + str(e)) - sys.exit(1) + sys.exit(-1) return feature_list def find_overlapping_rules(new_rule_path, rules_path): if not new_rule_path.endswith(".yml"): logger.error("FileNotFoundError ! New rule file name doesn't end with .yml") - sys.exit(1) + sys.exit(-1) # Loads features of new rule in a list. new_rule_features = get_features(new_rule_path) diff --git a/tests/test_scripts.py b/tests/test_scripts.py index ce8f01c3..3936ed59 100644 --- a/tests/test_scripts.py +++ b/tests/test_scripts.py @@ -14,8 +14,6 @@ import subprocess import pytest from fixtures import * -import capa.main - CD = os.path.dirname(__file__) @@ -88,41 +86,73 @@ def test_proto_conversion(tmpdir): assert p.stdout.startswith(b'{\n "meta": ') or p.stdout.startswith(b'{\r\n "meta": ') -def run_detect_duplicate_features(rule_path): +def run_detect_duplicate_features(rule_dir, rule_path): # rule_path = "collection/credit-card/parse-credit-card-information.yml" - args = [get_rules_path(), rule_path] + args = [rule_dir, rule_path] script_path = get_script_path("detect_duplicate_features.py") args = [sys.executable] + [script_path] + args print(f"running: '{args}'") return subprocess.run(args) -def test_detect_duplicate_features(z9324d_extractor, tmpdir): - RULE_CONTENT = textwrap.dedent( - """ - rule: - meta: - name: Test Rule - scope: function - features: - - string: "sites.ini" - """ - ) - expected_overlaps = 3 - path = z9324d_extractor.path - rule_file = tmpdir.mkdir("capa").join("rule.yml") - rule_file.write(RULE_CONTENT) - assert ( - capa.main.main( - [ - path, - "-v", - "-r", - rule_file.strpath, - ] - ) - == 0 - ) - # tests if number of overlaps found are correct. - overlaps_found = run_detect_duplicate_features(rule_file.strpath).returncode - assert overlaps_found == expected_overlaps +def test_detect_duplicate_features(tmpdir): + RULESET = { + "rule_1": textwrap.dedent( + """ + rule: + meta: + name: Test Rule 1 + scope: function + features: + - or: + - string: "sites.ini" + - number: 0xEDB88320 + """ + ), + "rule_2": textwrap.dedent( + """ + rule: + meta: + name: Test Rule 2 + scope: function + features: + - and: + - string: "sites.ini" + - number: 8 + """ + ), + "rule_3": textwrap.dedent( + """ + rule: + meta: + name: Test Rule 3 + scope: function + features: + - not: + - number: 0xEDB88320 + """ + ), + "rule_4": textwrap.dedent( + """ + rule: + meta: + name: Test Rule 4 + scope: function + features: + - not: + - number: 4 + """ + ), + } + + rule_dir = tmpdir.mkdir("capa_rule_overlap_test") + rule_overlaps = [3, 2, 2, 1] + rule_paths = [] + for rule_name, RULE_CONTENT in RULESET.items(): + rule_file = rule_dir.join("%s.yml" % rule_name) + rule_file.write(RULE_CONTENT) + rule_paths.append(rule_file.strpath) + # tests if number of overlaps for rules in RULESET found are correct. + for expected_overlaps, rule_path in zip(rule_overlaps, rule_paths): + overlaps_found = run_detect_duplicate_features(rule_dir.strpath, rule_path) + assert overlaps_found.returncode == expected_overlaps