Spaces:
Running
Running
| """ | |
| Unit tests for agentgraph/testing/config.py | |
| Tests configuration models and preset configurations. | |
| """ | |
| import pytest | |
| from pydantic import ValidationError | |
| from agentgraph.testing.config import ( | |
| ExecutionConfig, | |
| JailbreakTestConfig, | |
| DemographicConfig, | |
| CounterfactualBiasTestConfig, | |
| PerturbationTestConfig, | |
| PRESET_CONFIGS, | |
| EXTENDED_DEMOGRAPHICS, | |
| get_preset_config, | |
| create_config_from_dict, | |
| ) | |
| class TestExecutionConfig: | |
| """Tests for ExecutionConfig model.""" | |
| def test_default_values(self): | |
| """Test default configuration values.""" | |
| config = ExecutionConfig() | |
| assert config.max_workers == 5 | |
| assert config.max_retries == 3 | |
| assert config.base_delay == 1.0 | |
| assert config.max_delay == 60.0 | |
| assert config.rate_limit_per_minute == 60 | |
| def test_custom_values(self): | |
| """Test custom configuration values.""" | |
| config = ExecutionConfig( | |
| max_workers=10, | |
| max_retries=5, | |
| base_delay=2.0, | |
| max_delay=120.0, | |
| rate_limit_per_minute=100 | |
| ) | |
| assert config.max_workers == 10 | |
| assert config.max_retries == 5 | |
| assert config.base_delay == 2.0 | |
| assert config.max_delay == 120.0 | |
| assert config.rate_limit_per_minute == 100 | |
| def test_max_workers_validation(self): | |
| """Test max_workers validation bounds.""" | |
| # Valid bounds | |
| assert ExecutionConfig(max_workers=1).max_workers == 1 | |
| assert ExecutionConfig(max_workers=20).max_workers == 20 | |
| # Invalid bounds | |
| with pytest.raises(ValidationError): | |
| ExecutionConfig(max_workers=0) | |
| with pytest.raises(ValidationError): | |
| ExecutionConfig(max_workers=21) | |
| def test_max_retries_validation(self): | |
| """Test max_retries validation bounds.""" | |
| assert ExecutionConfig(max_retries=1).max_retries == 1 | |
| assert ExecutionConfig(max_retries=10).max_retries == 10 | |
| with pytest.raises(ValidationError): | |
| ExecutionConfig(max_retries=0) | |
| with pytest.raises(ValidationError): | |
| ExecutionConfig(max_retries=11) | |
| def test_base_delay_validation(self): | |
| """Test base_delay validation bounds.""" | |
| assert ExecutionConfig(base_delay=0.1).base_delay == 0.1 | |
| assert ExecutionConfig(base_delay=10.0).base_delay == 10.0 | |
| with pytest.raises(ValidationError): | |
| ExecutionConfig(base_delay=0.0) | |
| with pytest.raises(ValidationError): | |
| ExecutionConfig(base_delay=11.0) | |
| class TestJailbreakTestConfig: | |
| """Tests for JailbreakTestConfig model.""" | |
| def test_default_values(self): | |
| """Test default configuration values.""" | |
| config = JailbreakTestConfig() | |
| assert config.enabled is True | |
| assert config.num_techniques == 10 | |
| assert config.technique_categories is None | |
| assert config.random_seed is None | |
| assert config.prompt_source == "standard" | |
| assert config.custom_prompts is None | |
| def test_num_techniques_validation(self): | |
| """Test num_techniques validation bounds.""" | |
| assert JailbreakTestConfig(num_techniques=1).num_techniques == 1 | |
| assert JailbreakTestConfig(num_techniques=50).num_techniques == 50 | |
| with pytest.raises(ValidationError): | |
| JailbreakTestConfig(num_techniques=0) | |
| with pytest.raises(ValidationError): | |
| JailbreakTestConfig(num_techniques=51) | |
| def test_technique_categories(self): | |
| """Test technique categories filtering.""" | |
| config = JailbreakTestConfig( | |
| technique_categories=["DAN", "Omega"] | |
| ) | |
| assert config.technique_categories == ["DAN", "Omega"] | |
| def test_custom_prompts(self): | |
| """Test custom prompts configuration.""" | |
| custom = [ | |
| {"name": "test", "prompt": "Test prompt", "description": "Test"} | |
| ] | |
| config = JailbreakTestConfig(custom_prompts=custom) | |
| assert config.custom_prompts == custom | |
| def test_disabled_config(self): | |
| """Test disabled jailbreak testing.""" | |
| config = JailbreakTestConfig(enabled=False) | |
| assert config.enabled is False | |
| class TestDemographicConfig: | |
| """Tests for DemographicConfig model.""" | |
| def test_basic_demographic(self): | |
| """Test basic demographic configuration.""" | |
| demo = DemographicConfig(gender="male", race="White") | |
| assert demo.gender == "male" | |
| assert demo.race == "White" | |
| def test_str_representation(self): | |
| """Test string representation.""" | |
| demo = DemographicConfig(gender="female", race="Black") | |
| assert str(demo) == "female Black" | |
| def test_various_demographics(self): | |
| """Test various demographic combinations.""" | |
| demos = [ | |
| ("male", "White"), | |
| ("female", "Black"), | |
| ("non-binary", "Asian"), | |
| ("male", "Hispanic"), | |
| ] | |
| for gender, race in demos: | |
| demo = DemographicConfig(gender=gender, race=race) | |
| assert demo.gender == gender | |
| assert demo.race == race | |
| class TestCounterfactualBiasTestConfig: | |
| """Tests for CounterfactualBiasTestConfig model.""" | |
| def test_default_values(self): | |
| """Test default configuration values.""" | |
| config = CounterfactualBiasTestConfig() | |
| assert config.enabled is True | |
| assert len(config.demographics) == 4 | |
| assert config.include_baseline is True | |
| assert config.comparison_mode == "both" | |
| assert config.extended_dimensions is None | |
| def test_comparison_mode_enum(self): | |
| """Test comparison mode enumeration.""" | |
| for mode in ["all_pairs", "vs_baseline", "both"]: | |
| config = CounterfactualBiasTestConfig(comparison_mode=mode) | |
| assert config.comparison_mode == mode | |
| with pytest.raises(ValidationError): | |
| CounterfactualBiasTestConfig(comparison_mode="invalid") | |
| def test_custom_demographics(self): | |
| """Test custom demographics configuration.""" | |
| demos = [ | |
| DemographicConfig(gender="male", race="Asian"), | |
| DemographicConfig(gender="female", race="Hispanic"), | |
| ] | |
| config = CounterfactualBiasTestConfig(demographics=demos) | |
| assert len(config.demographics) == 2 | |
| assert config.demographics[0].race == "Asian" | |
| def test_extended_dimensions(self): | |
| """Test extended dimensions configuration.""" | |
| config = CounterfactualBiasTestConfig( | |
| extended_dimensions=["age", "disability"] | |
| ) | |
| assert config.extended_dimensions == ["age", "disability"] | |
| def test_disabled_config(self): | |
| """Test disabled bias testing.""" | |
| config = CounterfactualBiasTestConfig(enabled=False) | |
| assert config.enabled is False | |
| class TestPerturbationTestConfig: | |
| """Tests for PerturbationTestConfig model.""" | |
| def test_default_values(self): | |
| """Test default configuration values.""" | |
| config = PerturbationTestConfig() | |
| assert config.model == "gpt-4o-mini" | |
| assert config.judge_model == "gpt-4o-mini" | |
| assert config.max_relations is None | |
| assert isinstance(config.execution, ExecutionConfig) | |
| assert isinstance(config.jailbreak, JailbreakTestConfig) | |
| assert isinstance(config.counterfactual_bias, CounterfactualBiasTestConfig) | |
| def test_custom_models(self): | |
| """Test custom model configuration.""" | |
| config = PerturbationTestConfig( | |
| model="gpt-4o", | |
| judge_model="gpt-4" | |
| ) | |
| assert config.model == "gpt-4o" | |
| assert config.judge_model == "gpt-4" | |
| def test_max_relations(self): | |
| """Test max_relations configuration.""" | |
| config = PerturbationTestConfig(max_relations=5) | |
| assert config.max_relations == 5 | |
| config_all = PerturbationTestConfig(max_relations=None) | |
| assert config_all.max_relations is None | |
| def test_nested_config(self): | |
| """Test nested configuration objects.""" | |
| config = PerturbationTestConfig( | |
| execution=ExecutionConfig(max_workers=10), | |
| jailbreak=JailbreakTestConfig(num_techniques=15), | |
| counterfactual_bias=CounterfactualBiasTestConfig(comparison_mode="all_pairs") | |
| ) | |
| assert config.execution.max_workers == 10 | |
| assert config.jailbreak.num_techniques == 15 | |
| assert config.counterfactual_bias.comparison_mode == "all_pairs" | |
| def test_model_dump(self): | |
| """Test model serialization.""" | |
| config = PerturbationTestConfig() | |
| data = config.model_dump() | |
| assert "model" in data | |
| assert "judge_model" in data | |
| assert "execution" in data | |
| assert "jailbreak" in data | |
| assert "counterfactual_bias" in data | |
| class TestPresetConfigs: | |
| """Tests for preset configurations.""" | |
| def test_preset_keys(self): | |
| """Test preset configuration keys exist.""" | |
| assert "quick" in PRESET_CONFIGS | |
| assert "standard" in PRESET_CONFIGS | |
| assert "comprehensive" in PRESET_CONFIGS | |
| def test_quick_preset(self): | |
| """Test quick preset configuration.""" | |
| config = PRESET_CONFIGS["quick"] | |
| assert config.max_relations == 3 | |
| assert config.execution.max_workers == 3 | |
| assert config.jailbreak.num_techniques == 3 | |
| assert len(config.counterfactual_bias.demographics) == 2 | |
| assert config.counterfactual_bias.comparison_mode == "vs_baseline" | |
| def test_standard_preset(self): | |
| """Test standard preset configuration.""" | |
| config = PRESET_CONFIGS["standard"] | |
| assert config.max_relations == 10 | |
| assert config.execution.max_workers == 5 | |
| assert config.jailbreak.num_techniques == 10 | |
| assert config.counterfactual_bias.comparison_mode == "both" | |
| def test_comprehensive_preset(self): | |
| """Test comprehensive preset configuration.""" | |
| config = PRESET_CONFIGS["comprehensive"] | |
| assert config.max_relations is None | |
| assert config.execution.max_workers == 10 | |
| assert config.execution.max_retries == 5 | |
| assert config.jailbreak.num_techniques == 20 | |
| assert len(config.counterfactual_bias.demographics) == 9 | |
| assert config.counterfactual_bias.extended_dimensions == ["age"] | |
| class TestGetPresetConfig: | |
| """Tests for get_preset_config function.""" | |
| def test_valid_presets(self): | |
| """Test getting valid presets.""" | |
| for preset_name in ["quick", "standard", "comprehensive"]: | |
| config = get_preset_config(preset_name) | |
| assert isinstance(config, PerturbationTestConfig) | |
| def test_invalid_preset(self): | |
| """Test invalid preset raises error.""" | |
| with pytest.raises(ValueError) as exc_info: | |
| get_preset_config("invalid") | |
| assert "Unknown preset" in str(exc_info.value) | |
| def test_preset_is_copy(self): | |
| """Test that preset returns a copy.""" | |
| config1 = get_preset_config("standard") | |
| config2 = get_preset_config("standard") | |
| # Modify one should not affect the other | |
| config1.max_relations = 999 | |
| assert config2.max_relations == 10 | |
| class TestCreateConfigFromDict: | |
| """Tests for create_config_from_dict function.""" | |
| def test_basic_dict(self): | |
| """Test creating config from basic dict.""" | |
| data = { | |
| "model": "gpt-4", | |
| "max_relations": 5 | |
| } | |
| config = create_config_from_dict(data) | |
| assert config.model == "gpt-4" | |
| assert config.max_relations == 5 | |
| def test_nested_dict(self): | |
| """Test creating config from nested dict.""" | |
| data = { | |
| "model": "gpt-4", | |
| "execution": {"max_workers": 8}, | |
| "jailbreak": {"num_techniques": 15, "enabled": True}, | |
| "counterfactual_bias": {"comparison_mode": "all_pairs"} | |
| } | |
| config = create_config_from_dict(data) | |
| assert config.execution.max_workers == 8 | |
| assert config.jailbreak.num_techniques == 15 | |
| assert config.counterfactual_bias.comparison_mode == "all_pairs" | |
| def test_empty_dict(self): | |
| """Test creating config from empty dict uses defaults.""" | |
| config = create_config_from_dict({}) | |
| assert config.model == "gpt-4o-mini" | |
| assert config.execution.max_workers == 5 | |
| class TestExtendedDemographics: | |
| """Tests for extended demographics constants.""" | |
| def test_extended_demographics_keys(self): | |
| """Test extended demographics keys exist.""" | |
| assert "age" in EXTENDED_DEMOGRAPHICS | |
| assert "disability" in EXTENDED_DEMOGRAPHICS | |
| assert "socioeconomic" in EXTENDED_DEMOGRAPHICS | |
| def test_age_options(self): | |
| """Test age dimension options.""" | |
| assert len(EXTENDED_DEMOGRAPHICS["age"]) == 3 | |
| assert "young (20s)" in EXTENDED_DEMOGRAPHICS["age"] | |
| assert "elderly (70s)" in EXTENDED_DEMOGRAPHICS["age"] | |
| def test_disability_options(self): | |
| """Test disability dimension options.""" | |
| assert len(EXTENDED_DEMOGRAPHICS["disability"]) == 3 | |
| def test_socioeconomic_options(self): | |
| """Test socioeconomic dimension options.""" | |
| assert len(EXTENDED_DEMOGRAPHICS["socioeconomic"]) == 3 | |