Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions secator/runners/_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,8 @@ def __init__(self, config, inputs=[], results=[], run_opts={}, hooks={}, validat

# Runner toggles
self.enable_duplicate_check = self.run_opts.get('enable_duplicate_check', self.enable_duplicate_check)
if self.has_parent and 'enable_duplicate_check' not in self.run_opts: # disable duplicate check on children runners
self.enable_duplicate_check = False
self.enable_profiles = self.run_opts.get('enable_profiles', True)
self.enable_reports = self.run_opts.get('enable_reports', not self.sync) and not self.dry_run and not self.no_process and not self.no_poll # noqa: E501
self.enable_hooks = self.run_opts.get('enable_hooks', True) and not self.dry_run and not self.no_process # noqa: E501
Expand Down
33 changes: 33 additions & 0 deletions tests/unit/test_runners.py
Original file line number Diff line number Diff line change
Expand Up @@ -918,3 +918,36 @@ def test_self_errors_includes_chunk_errors(self):
cmd.unique_name = 'nmap'
cmd.results.append(chunk_error)
self.assertEqual(cmd.self_errors, [chunk_error])


class TestDuplicateCheckGating(unittest.TestCase):
"""Duplicate check must run only on the outermost runner.

A nested runner (has_parent=True) — a task inside a workflow, or a workflow inside
a scan — must NOT run its own dedup pass; the outermost runner does it once over its
fully-aggregated results. See Runner.__init__ in secator/runners/_base.py.
"""

def test_outermost_runner_dedups(self):
"""An outermost runner (has_parent defaults to False) keeps the duplicate check on."""
cmd = MyCommand(TARGETS)
self.assertFalse(cmd.has_parent)
self.assertTrue(cmd.enable_duplicate_check)

def test_nested_runner_does_not_dedup(self):
"""A nested runner (has_parent=True) has its duplicate check disabled by default."""
cmd = MyCommand(TARGETS, has_parent=True)
self.assertTrue(cmd.has_parent)
self.assertFalse(cmd.enable_duplicate_check)

def test_nested_runner_respects_explicit_enable_override(self):
"""An explicit enable_duplicate_check=True override wins even when nested."""
cmd = MyCommand(TARGETS, has_parent=True, enable_duplicate_check=True)
self.assertTrue(cmd.has_parent)
self.assertTrue(cmd.enable_duplicate_check)

def test_outermost_runner_respects_explicit_disable_override(self):
"""An explicit enable_duplicate_check=False override wins on an outermost runner."""
cmd = MyCommand(TARGETS, enable_duplicate_check=False)
self.assertFalse(cmd.has_parent)
self.assertFalse(cmd.enable_duplicate_check)
Loading