Skip to content

Commit 42887b9

Browse files
author
Victor Valbuena
committed
FIX: TargetInitializer propagates config.tags to registry entries
1 parent 6290bbe commit 42887b9

2 files changed

Lines changed: 102 additions & 0 deletions

File tree

pyrit/setup/initializers/components/targets.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -600,6 +600,8 @@ def _register_target(self, config: TargetConfig) -> None:
600600
target = config.target_class(**kwargs)
601601
registry = TargetRegistry.get_registry_singleton()
602602
registry.register_instance(target, name=config.registry_name)
603+
if config.tags:
604+
registry.add_tags(name=config.registry_name, tags=list(config.tags))
603605
if config.default_objective_target:
604606
registry.add_tags(name=config.registry_name, tags=[TargetInitializerTags.DEFAULT_OBJECTIVE_TARGET])
605607
logger.info(f"Registered target: {config.registry_name}")

tests/unit/setup/test_targets_initializer.py

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -400,3 +400,103 @@ async def test_other_targets_not_tagged_as_default(self) -> None:
400400
assert config.default_objective_target is False, (
401401
f"Target {config.registry_name} should not have default_objective_target=True"
402402
)
403+
404+
405+
@pytest.mark.usefixtures("patch_central_database")
406+
class TestTargetInitializerConfigTagPropagation:
407+
"""Tests for TargetInitializer propagating ``TargetConfig.tags`` to the registry (F1c)."""
408+
409+
def setup_method(self) -> None:
410+
"""Reset registry before each test."""
411+
TargetRegistry.reset_instance()
412+
413+
def teardown_method(self) -> None:
414+
"""Clean up after each test."""
415+
TargetRegistry.reset_instance()
416+
for var in [
417+
"ADVERSARIAL_CHAT_ENDPOINT",
418+
"ADVERSARIAL_CHAT_KEY",
419+
"ADVERSARIAL_CHAT_MODEL",
420+
"OPENAI_CHAT_ENDPOINT",
421+
"OPENAI_CHAT_KEY",
422+
"OPENAI_CHAT_MODEL",
423+
]:
424+
os.environ.pop(var, None)
425+
426+
async def test_register_target_propagates_config_tags(self) -> None:
427+
"""
428+
``TargetConfig.tags`` should be added to the registry entry so the entire
429+
``TargetInitializerTags`` enum is queryable post-registration.
430+
"""
431+
from pyrit.setup.initializers.components.targets import TargetInitializerTags
432+
433+
os.environ["ADVERSARIAL_CHAT_ENDPOINT"] = "https://test.openai.azure.com"
434+
os.environ["ADVERSARIAL_CHAT_KEY"] = "test_key"
435+
os.environ["ADVERSARIAL_CHAT_MODEL"] = "gpt-4o"
436+
437+
init = TargetInitializer()
438+
await init.initialize_async()
439+
440+
registry = TargetRegistry.get_registry_singleton()
441+
assert "adversarial_chat" in registry
442+
443+
adversarial_entries = registry.get_by_tag(tag=TargetInitializerTags.ADVERSARIAL)
444+
assert any(entry.name == "adversarial_chat" for entry in adversarial_entries), (
445+
"adversarial_chat should be discoverable by the ADVERSARIAL tag after F1c"
446+
)
447+
448+
default_entries = registry.get_by_tag(tag=TargetInitializerTags.DEFAULT)
449+
assert any(entry.name == "adversarial_chat" for entry in default_entries), (
450+
"adversarial_chat declares both DEFAULT and ADVERSARIAL tags; both must propagate"
451+
)
452+
453+
async def test_register_target_no_tags_in_config_no_extra_add_tags(self) -> None:
454+
"""An empty ``config.tags`` list must not trigger an ``add_tags`` call (no spurious empty-list passes)."""
455+
from unittest.mock import MagicMock, patch
456+
457+
from pyrit.setup.initializers.components.targets import TargetConfig, TargetInitializer
458+
459+
config = TargetConfig(
460+
registry_name="empty_tags_target",
461+
target_class=MagicMock(return_value=MagicMock()),
462+
endpoint_var="EMPTY_TAGS_ENDPOINT",
463+
key_var="",
464+
tags=[],
465+
)
466+
467+
os.environ["EMPTY_TAGS_ENDPOINT"] = "https://example.com"
468+
469+
try:
470+
mock_registry = MagicMock()
471+
with patch.object(TargetRegistry, "get_registry_singleton", return_value=mock_registry):
472+
init = TargetInitializer()
473+
init._register_target(config)
474+
475+
mock_registry.register_instance.assert_called_once()
476+
mock_registry.add_tags.assert_not_called()
477+
finally:
478+
os.environ.pop("EMPTY_TAGS_ENDPOINT", None)
479+
480+
async def test_register_target_default_objective_tag_still_applied(self) -> None:
481+
"""
482+
Regression: ``default_objective_target=True`` must still add the ``DEFAULT_OBJECTIVE_TARGET``
483+
tag alongside any ``config.tags``.
484+
"""
485+
from pyrit.setup.initializers.components.targets import TargetInitializerTags
486+
487+
os.environ["OPENAI_CHAT_ENDPOINT"] = "https://api.openai.com/v1"
488+
os.environ["OPENAI_CHAT_KEY"] = "test_key"
489+
os.environ["OPENAI_CHAT_MODEL"] = "gpt-4o"
490+
491+
init = TargetInitializer()
492+
await init.initialize_async()
493+
494+
registry = TargetRegistry.get_registry_singleton()
495+
default_objective_entries = registry.get_by_tag(tag=TargetInitializerTags.DEFAULT_OBJECTIVE_TARGET)
496+
assert len(default_objective_entries) == 1
497+
assert default_objective_entries[0].name == "openai_chat"
498+
499+
default_entries = registry.get_by_tag(tag=TargetInitializerTags.DEFAULT)
500+
assert any(entry.name == "openai_chat" for entry in default_entries), (
501+
"openai_chat's config.tags=[DEFAULT] must propagate even when default_objective_target=True"
502+
)

0 commit comments

Comments
 (0)