mirror of
https://github.com/mandiant/capa.git
synced 2026-04-28 11:53:20 -07:00
tests: inline more test logic
This commit is contained in:
@@ -44,8 +44,7 @@ from capa.features.extractors.dnfile.extractor import DnfileFeatureExtractor
|
|||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
CD = Path(__file__).resolve().parent
|
CD = Path(__file__).resolve().parent
|
||||||
FIXTURE_MANIFEST_DIR = CD / "fixtures" / "features"
|
FIXTURE_MANIFEST_DIR = CD / "fixtures" / "features"
|
||||||
DOTNET_DIR = CD / "data" / "dotnet"
|
DNFILE_TESTFILES = CD / "data" / "dotnet" / "dnfile-testfiles"
|
||||||
DNFILE_TESTFILES = DOTNET_DIR / "dnfile-testfiles"
|
|
||||||
|
|
||||||
|
|
||||||
def parse_feature_string(s: str) -> Feature | ceng.Range | ceng.Statement:
|
def parse_feature_string(s: str) -> Feature | ceng.Range | ceng.Statement:
|
||||||
@@ -366,44 +365,6 @@ def run_feature_fixture(
|
|||||||
assert actual == fixture.expected, msg
|
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):
|
def extract_global_features(extractor):
|
||||||
features = collections.defaultdict(set)
|
features = collections.defaultdict(set)
|
||||||
for feature, va in extractor.extract_global_features():
|
for feature, va in extractor.extract_global_features():
|
||||||
@@ -671,11 +632,6 @@ def resolve_scope(scope):
|
|||||||
raise ValueError("unexpected scope fixture")
|
raise ValueError("unexpected scope fixture")
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
|
||||||
def scope(request):
|
|
||||||
return resolve_scope(request.param)
|
|
||||||
|
|
||||||
|
|
||||||
def make_test_id(values):
|
def make_test_id(values):
|
||||||
return "-".join(map(str, values))
|
return "-".join(map(str, values))
|
||||||
|
|
||||||
@@ -692,58 +648,7 @@ def parametrize(params, values, **kwargs):
|
|||||||
return pytest.mark.parametrize(params, values, ids=ids, **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_"
|
PMA1601 = CD / "data" / "Practical Malware Analysis Lab 16-01.exe_"
|
||||||
z9324 = CD / "data" / "9324d1a8ae37a36ae560c37448c9705a.exe_"
|
|
||||||
|
|
||||||
|
|
||||||
# used by test_viv_features
|
# used by test_viv_features
|
||||||
@@ -786,7 +691,7 @@ def get_viv_extractor(path: Path):
|
|||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
def z9324d_extractor():
|
def z9324d_extractor():
|
||||||
return get_viv_extractor(z9324)
|
return get_viv_extractor(CD / "data" / "9324d1a8ae37a36ae560c37448c9705a.exe_")
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
|
|||||||
@@ -14,10 +14,10 @@
|
|||||||
|
|
||||||
import textwrap
|
import textwrap
|
||||||
|
|
||||||
import capa.rules
|
|
||||||
import capa.features.common
|
|
||||||
import fixtures
|
import fixtures
|
||||||
|
|
||||||
|
import capa.rules
|
||||||
|
import capa.features.common
|
||||||
import capa.capabilities.common
|
import capa.capabilities.common
|
||||||
import capa.features.extractors.null
|
import capa.features.extractors.null
|
||||||
from capa.features.address import AbsoluteVirtualAddress
|
from capa.features.address import AbsoluteVirtualAddress
|
||||||
|
|||||||
@@ -14,6 +14,7 @@
|
|||||||
|
|
||||||
import copy
|
import copy
|
||||||
from typing import Any
|
from typing import Any
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
@@ -28,20 +29,21 @@ import capa.render.result_document as rd
|
|||||||
import capa.features.freeze.features
|
import capa.features.freeze.features
|
||||||
from capa.helpers import assert_never
|
from capa.helpers import assert_never
|
||||||
|
|
||||||
|
CD = Path(__file__).resolve().parent
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
STATIC_RD_FILES = [
|
||||||
"rd_file",
|
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("a3f3bbc_rd"),
|
pytest.param(CD / "data" / "rd" / "al-khaser_x64.exe_.json", id="al_khaserx64"),
|
||||||
pytest.param("al_khaserx86_rd"),
|
pytest.param(CD / "data" / "rd" / "0761142efbda6c4b1e801223de723578.dll_.json", id="a076114"),
|
||||||
pytest.param("al_khaserx64_rd"),
|
pytest.param(CD / "data" / "rd" / "Practical Malware Analysis Lab 01-01.dll_.json", id="pma0101"),
|
||||||
pytest.param("a076114_rd"),
|
pytest.param(CD / "data" / "rd" / "1c444ebeba24dcba8628b7dfe5fec7c6.exe_.json", id="dotnet_1c444e"),
|
||||||
pytest.param("pma0101_rd"),
|
]
|
||||||
pytest.param("dotnet_1c444e_rd"),
|
|
||||||
],
|
|
||||||
)
|
@pytest.mark.parametrize("rd_path", STATIC_RD_FILES)
|
||||||
def test_doc_to_pb2(request, rd_file):
|
def test_doc_to_pb2(rd_path):
|
||||||
src: rd.ResultDocument = request.getfixturevalue(rd_file)
|
src = rd.ResultDocument.from_file(rd_path)
|
||||||
dst = capa.render.proto.doc_to_pb2(src)
|
dst = capa.render.proto.doc_to_pb2(src)
|
||||||
|
|
||||||
assert_meta(src.meta, dst.meta)
|
assert_meta(src.meta, dst.meta)
|
||||||
@@ -401,17 +403,15 @@ def assert_round_trip(doc: rd.ResultDocument):
|
|||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
"rd_file",
|
"rd_path",
|
||||||
[
|
STATIC_RD_FILES
|
||||||
pytest.param("a3f3bbc_rd"),
|
+ [
|
||||||
pytest.param("al_khaserx86_rd"),
|
pytest.param(
|
||||||
pytest.param("al_khaserx64_rd"),
|
CD / "data" / "rd" / "0000a65749f5902c4d82ffa701198038f0b4870b00a27cfca109f8f933476d82.json.gz",
|
||||||
pytest.param("a076114_rd"),
|
id="dynamic_a0000a6",
|
||||||
pytest.param("pma0101_rd"),
|
),
|
||||||
pytest.param("dotnet_1c444e_rd"),
|
|
||||||
pytest.param("dynamic_a0000a6_rd"),
|
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
def test_round_trip(request, rd_file):
|
def test_round_trip(rd_path):
|
||||||
doc: rd.ResultDocument = request.getfixturevalue(rd_file)
|
doc = rd.ResultDocument.from_file(rd_path)
|
||||||
assert_round_trip(doc)
|
assert_round_trip(doc)
|
||||||
|
|||||||
@@ -268,18 +268,18 @@ def assert_round_trip(rd: rdoc.ResultDocument):
|
|||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
"rd_file",
|
"rd_path",
|
||||||
[
|
[
|
||||||
pytest.param("a3f3bbc_rd"),
|
pytest.param(fixtures.CD / "data" / "rd" / "3f3bbcf8fd90bdcdcdc5494314ed4225.exe_.json", id="a3f3bbc"),
|
||||||
pytest.param("al_khaserx86_rd"),
|
pytest.param(fixtures.CD / "data" / "rd" / "al-khaser_x86.exe_.json", id="al_khaserx86"),
|
||||||
pytest.param("al_khaserx64_rd"),
|
pytest.param(fixtures.CD / "data" / "rd" / "al-khaser_x64.exe_.json", id="al_khaserx64"),
|
||||||
pytest.param("a076114_rd"),
|
pytest.param(fixtures.CD / "data" / "rd" / "0761142efbda6c4b1e801223de723578.dll_.json", id="a076114"),
|
||||||
pytest.param("pma0101_rd"),
|
pytest.param(fixtures.CD / "data" / "rd" / "Practical Malware Analysis Lab 01-01.dll_.json", id="pma0101"),
|
||||||
pytest.param("dotnet_1c444e_rd"),
|
pytest.param(fixtures.CD / "data" / "rd" / "1c444ebeba24dcba8628b7dfe5fec7c6.exe_.json", id="dotnet_1c444e"),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
def test_round_trip(request, rd_file):
|
def test_round_trip(rd_path):
|
||||||
rd: rdoc.ResultDocument = request.getfixturevalue(rd_file)
|
rd = rdoc.ResultDocument.from_file(rd_path)
|
||||||
assert_round_trip(rd)
|
assert_round_trip(rd)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user