From e294e69f25865c4a0d15bfdc33c8adf15fff3e74 Mon Sep 17 00:00:00 2001 From: Willi Ballenthin Date: Tue, 21 Apr 2026 17:04:41 +0300 Subject: [PATCH] tests: inline more test logic --- tests/fixtures.py | 99 +---------------------------------- tests/test_capabilities.py | 4 +- tests/test_proto.py | 48 ++++++++--------- tests/test_result_document.py | 18 +++---- 4 files changed, 37 insertions(+), 132 deletions(-) diff --git a/tests/fixtures.py b/tests/fixtures.py index ea445c3c..f9b8a56b 100644 --- a/tests/fixtures.py +++ b/tests/fixtures.py @@ -44,8 +44,7 @@ from capa.features.extractors.dnfile.extractor import DnfileFeatureExtractor logger = logging.getLogger(__name__) CD = Path(__file__).resolve().parent FIXTURE_MANIFEST_DIR = CD / "fixtures" / "features" -DOTNET_DIR = CD / "data" / "dotnet" -DNFILE_TESTFILES = DOTNET_DIR / "dnfile-testfiles" +DNFILE_TESTFILES = CD / "data" / "dotnet" / "dnfile-testfiles" def parse_feature_string(s: str) -> Feature | ceng.Range | ceng.Statement: @@ -366,44 +365,6 @@ def run_feature_fixture( assert actual == fixture.expected, msg -@contextlib.contextmanager -def xfail(condition, reason: str = ""): - """ - context manager that wraps a block that is expected to fail in some cases. - when it does fail (and is expected), then mark this as pytest.xfail. - if its unexpected, raise an exception, so the test fails. - - example:: - - # this test: - # - passes on Linux if foo() works - # - fails on Linux if foo() fails - # - xfails on Windows if foo() fails - # - fails on Windows if foo() works - with xfail(sys.platform == "win32", reason="doesn't work on Windows"): - foo() - """ - try: - # do the block - yield - except Exception: - if condition: - # we expected the test to fail, so raise and register this via pytest - pytest.xfail(reason or "") - else: - # we don't expect an exception, so the test should fail - raise - else: - if not condition: - # here we expect the block to run successfully, - # and we've received no exception, - # so this is good - pass - else: - # we expected an exception, but didn't find one. that's an error. - raise RuntimeError("expected to fail, but didn't") - - def extract_global_features(extractor): features = collections.defaultdict(set) for feature, va in extractor.extract_global_features(): @@ -671,11 +632,6 @@ def resolve_scope(scope): raise ValueError("unexpected scope fixture") -@pytest.fixture -def scope(request): - return resolve_scope(request.param) - - def make_test_id(values): return "-".join(map(str, values)) @@ -692,58 +648,7 @@ def parametrize(params, values, **kwargs): return pytest.mark.parametrize(params, values, ids=ids, **kwargs) -def get_result_doc(path: Path): - return capa.render.result_document.ResultDocument.from_file(path) - - -@pytest.fixture -def pma0101_rd(): - # python -m capa.main tests/data/Practical\ Malware\ Analysis\ Lab\ 01-01.dll_ --json > tests/data/rd/Practical\ Malware\ Analysis\ Lab\ 01-01.dll_.json - return get_result_doc(CD / "data" / "rd" / "Practical Malware Analysis Lab 01-01.dll_.json") - - -@pytest.fixture -def dotnet_1c444e_rd(): - # .NET sample - # python -m capa.main tests/data/dotnet/1c444ebeba24dcba8628b7dfe5fec7c6.exe_ --json > tests/data/rd/1c444ebeba24dcba8628b7dfe5fec7c6.exe_.json - return get_result_doc(CD / "data" / "rd" / "1c444ebeba24dcba8628b7dfe5fec7c6.exe_.json") - - -@pytest.fixture -def a3f3bbc_rd(): - # python -m capa.main tests/data/3f3bbcf8fd90bdcdcdc5494314ed4225.exe_ --json > tests/data/rd/3f3bbcf8fd90bdcdcdc5494314ed4225.exe_.json - return get_result_doc(CD / "data" / "rd" / "3f3bbcf8fd90bdcdcdc5494314ed4225.exe_.json") - - -@pytest.fixture -def al_khaserx86_rd(): - # python -m capa.main tests/data/al-khaser_x86.exe_ --json > tests/data/rd/al-khaser_x86.exe_.json - return get_result_doc(CD / "data" / "rd" / "al-khaser_x86.exe_.json") - - -@pytest.fixture -def al_khaserx64_rd(): - # python -m capa.main tests/data/al-khaser_x64.exe_ --json > tests/data/rd/al-khaser_x64.exe_.json - return get_result_doc(CD / "data" / "rd" / "al-khaser_x64.exe_.json") - - -@pytest.fixture -def a076114_rd(): - # python -m capa.main tests/data/0761142efbda6c4b1e801223de723578.dll_ --json > tests/data/rd/0761142efbda6c4b1e801223de723578.dll_.json - return get_result_doc(CD / "data" / "rd" / "0761142efbda6c4b1e801223de723578.dll_.json") - - -@pytest.fixture -def dynamic_a0000a6_rd(): - # python -m capa.main tests/data/dynamic/cape/v2.2/0000a65749f5902c4d82ffa701198038f0b4870b00a27cfca109f8f933476d82.json --json > tests/data/rd/0000a65749f5902c4d82ffa701198038f0b4870b00a27cfca109f8f933476d82.json - # gzip tests/data/rd/0000a65749f5902c4d82ffa701198038f0b4870b00a27cfca109f8f933476d82.json - return get_result_doc( - CD / "data" / "rd" / "0000a65749f5902c4d82ffa701198038f0b4870b00a27cfca109f8f933476d82.json.gz" - ) - - PMA1601 = CD / "data" / "Practical Malware Analysis Lab 16-01.exe_" -z9324 = CD / "data" / "9324d1a8ae37a36ae560c37448c9705a.exe_" # used by test_viv_features @@ -786,7 +691,7 @@ def get_viv_extractor(path: Path): @pytest.fixture def z9324d_extractor(): - return get_viv_extractor(z9324) + return get_viv_extractor(CD / "data" / "9324d1a8ae37a36ae560c37448c9705a.exe_") @pytest.fixture diff --git a/tests/test_capabilities.py b/tests/test_capabilities.py index c9cb6464..3539a524 100644 --- a/tests/test_capabilities.py +++ b/tests/test_capabilities.py @@ -14,10 +14,10 @@ import textwrap -import capa.rules -import capa.features.common import fixtures +import capa.rules +import capa.features.common import capa.capabilities.common import capa.features.extractors.null from capa.features.address import AbsoluteVirtualAddress diff --git a/tests/test_proto.py b/tests/test_proto.py index b0dc1060..2523e22b 100644 --- a/tests/test_proto.py +++ b/tests/test_proto.py @@ -14,6 +14,7 @@ import copy from typing import Any +from pathlib import Path import pytest @@ -28,20 +29,21 @@ import capa.render.result_document as rd import capa.features.freeze.features from capa.helpers import assert_never +CD = Path(__file__).resolve().parent -@pytest.mark.parametrize( - "rd_file", - [ - pytest.param("a3f3bbc_rd"), - pytest.param("al_khaserx86_rd"), - pytest.param("al_khaserx64_rd"), - pytest.param("a076114_rd"), - pytest.param("pma0101_rd"), - pytest.param("dotnet_1c444e_rd"), - ], -) -def test_doc_to_pb2(request, rd_file): - src: rd.ResultDocument = request.getfixturevalue(rd_file) +STATIC_RD_FILES = [ + pytest.param(CD / "data" / "rd" / "3f3bbcf8fd90bdcdcdc5494314ed4225.exe_.json", id="a3f3bbc"), + pytest.param(CD / "data" / "rd" / "al-khaser_x86.exe_.json", id="al_khaserx86"), + pytest.param(CD / "data" / "rd" / "al-khaser_x64.exe_.json", id="al_khaserx64"), + pytest.param(CD / "data" / "rd" / "0761142efbda6c4b1e801223de723578.dll_.json", id="a076114"), + pytest.param(CD / "data" / "rd" / "Practical Malware Analysis Lab 01-01.dll_.json", id="pma0101"), + pytest.param(CD / "data" / "rd" / "1c444ebeba24dcba8628b7dfe5fec7c6.exe_.json", id="dotnet_1c444e"), +] + + +@pytest.mark.parametrize("rd_path", STATIC_RD_FILES) +def test_doc_to_pb2(rd_path): + src = rd.ResultDocument.from_file(rd_path) dst = capa.render.proto.doc_to_pb2(src) assert_meta(src.meta, dst.meta) @@ -401,17 +403,15 @@ def assert_round_trip(doc: rd.ResultDocument): @pytest.mark.parametrize( - "rd_file", - [ - pytest.param("a3f3bbc_rd"), - pytest.param("al_khaserx86_rd"), - pytest.param("al_khaserx64_rd"), - pytest.param("a076114_rd"), - pytest.param("pma0101_rd"), - pytest.param("dotnet_1c444e_rd"), - pytest.param("dynamic_a0000a6_rd"), + "rd_path", + STATIC_RD_FILES + + [ + pytest.param( + CD / "data" / "rd" / "0000a65749f5902c4d82ffa701198038f0b4870b00a27cfca109f8f933476d82.json.gz", + id="dynamic_a0000a6", + ), ], ) -def test_round_trip(request, rd_file): - doc: rd.ResultDocument = request.getfixturevalue(rd_file) +def test_round_trip(rd_path): + doc = rd.ResultDocument.from_file(rd_path) assert_round_trip(doc) diff --git a/tests/test_result_document.py b/tests/test_result_document.py index 89f0a12d..0d8aa560 100644 --- a/tests/test_result_document.py +++ b/tests/test_result_document.py @@ -268,18 +268,18 @@ def assert_round_trip(rd: rdoc.ResultDocument): @pytest.mark.parametrize( - "rd_file", + "rd_path", [ - pytest.param("a3f3bbc_rd"), - pytest.param("al_khaserx86_rd"), - pytest.param("al_khaserx64_rd"), - pytest.param("a076114_rd"), - pytest.param("pma0101_rd"), - pytest.param("dotnet_1c444e_rd"), + pytest.param(fixtures.CD / "data" / "rd" / "3f3bbcf8fd90bdcdcdc5494314ed4225.exe_.json", id="a3f3bbc"), + pytest.param(fixtures.CD / "data" / "rd" / "al-khaser_x86.exe_.json", id="al_khaserx86"), + pytest.param(fixtures.CD / "data" / "rd" / "al-khaser_x64.exe_.json", id="al_khaserx64"), + pytest.param(fixtures.CD / "data" / "rd" / "0761142efbda6c4b1e801223de723578.dll_.json", id="a076114"), + pytest.param(fixtures.CD / "data" / "rd" / "Practical Malware Analysis Lab 01-01.dll_.json", id="pma0101"), + pytest.param(fixtures.CD / "data" / "rd" / "1c444ebeba24dcba8628b7dfe5fec7c6.exe_.json", id="dotnet_1c444e"), ], ) -def test_round_trip(request, rd_file): - rd: rdoc.ResultDocument = request.getfixturevalue(rd_file) +def test_round_trip(rd_path): + rd = rdoc.ResultDocument.from_file(rd_path) assert_round_trip(rd)