Skip to content

Commit cc822c9

Browse files
perf(importers): fetch only needed columns in close_old_findings (#15185)
close_old_findings iterated findings.values() — every column of every finding in the test, including description — just to collect is_mitigated, hash_code and unique_id_from_tool for the exclusion filter. Narrow the values() call to those three columns.
1 parent 12b4d48 commit cc822c9

2 files changed

Lines changed: 57 additions & 1 deletion

File tree

dojo/importers/default_importer.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -402,7 +402,7 @@ def close_old_findings(
402402
# Remove all the findings that are coming from the report already mitigated
403403
new_hash_codes = []
404404
new_unique_ids_from_tool = []
405-
for finding in findings.values():
405+
for finding in findings.values("is_mitigated", "hash_code", "unique_id_from_tool"):
406406
# Do not process closed findings in the report
407407
if finding.get("is_mitigated", False):
408408
continue

unittests/test_importers_closeold.py

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import logging
2+
from unittest import mock
23

34
from django.utils import timezone
45

@@ -12,6 +13,61 @@
1213

1314

1415
class TestDojoCloseOld(DojoTestCase):
16+
# Regression: close_old_findings fetched every Finding column (incl. description) via
17+
# findings.values() just to collect is_mitigated/hash_code/unique_id_from_tool.
18+
def test_close_old_findings_only_fetches_needed_columns(self):
19+
scan_type = "Acunetix Scan"
20+
user, _ = User.objects.get_or_create(username="admin")
21+
product_type, _ = Product_Type.objects.get_or_create(name="closeold")
22+
environment, _ = Development_Environment.objects.get_or_create(name="Development")
23+
product, _ = Product.objects.get_or_create(
24+
name="TestDojoCloseOldColumns",
25+
description="Test",
26+
prod_type=product_type,
27+
)
28+
engagement, _ = Engagement.objects.get_or_create(
29+
name="Close Old Needed Columns",
30+
product=product,
31+
target_start=timezone.now(),
32+
target_end=timezone.now(),
33+
)
34+
import_options = {
35+
"user": user,
36+
"lead": user,
37+
"scan_date": None,
38+
"environment": environment,
39+
"active": True,
40+
"verified": False,
41+
"engagement": engagement,
42+
"scan_type": scan_type,
43+
}
44+
# Seed an older test with 4 findings that the close-old pass should mitigate
45+
with (get_unit_tests_scans_path("acunetix") / "many_findings.xml").open(encoding="utf-8") as many_findings_scan:
46+
importer = DefaultImporter(close_old_findings=False, **import_options)
47+
_, _, len_new_findings, _, _, _, _ = importer.process_scan(many_findings_scan)
48+
self.assertEqual(4, len_new_findings)
49+
# Import a report with a single finding, without closing, to get the new test
50+
with (get_unit_tests_scans_path("acunetix") / "one_finding.xml").open(encoding="utf-8") as single_finding_scan:
51+
importer = DefaultImporter(close_old_findings=False, **import_options)
52+
test, _, len_new_findings, _, _, _, _ = importer.process_scan(single_finding_scan)
53+
self.assertEqual(1, len_new_findings)
54+
# Call close_old_findings directly with the new test's queryset and spy on values()
55+
importer = DefaultImporter(close_old_findings=True, **import_options)
56+
importer.test = test
57+
findings_queryset = test.finding_set.all()
58+
with mock.patch.object(findings_queryset, "values", wraps=findings_queryset.values) as values_spy:
59+
closed_findings = importer.close_old_findings(findings_queryset)
60+
values_spy.assert_called_once_with(
61+
"is_mitigated", "hash_code", "unique_id_from_tool",
62+
)
63+
# Control: narrowing the columns must not change which findings get closed
64+
# (the 4 findings from the older test; dedupe is off, so the overlapping
65+
# finding closes too — same semantics as test_close_old_same_engagement)
66+
self.assertEqual(
67+
4, len(closed_findings),
68+
msg=f"expected 4 old findings closed, got {len(closed_findings)}",
69+
)
70+
1571
def test_close_old_same_engagement(self):
1672
scan_type = "Acunetix Scan"
1773
user, _ = User.objects.get_or_create(username="admin")

0 commit comments

Comments
 (0)