test: only set fresh vars via FRESH_VARS_FOR_DYNACONF as that's the only actual way to use it with pr-agent

This commit is contained in:
Patrick Decat 2025-11-15 09:25:15 +01:00
parent 979bc6788e
commit d3878ef412
No known key found for this signature in database
GPG key ID: FD55B9BD5687D8FF

View file

@ -23,7 +23,7 @@ from pr_agent.config_loader import get_settings # noqa: F401
# Module-level helper function # Module-level helper function
def create_dynaconf_with_custom_loader(temp_dir, secrets_file, fresh_vars=None): def create_dynaconf_with_custom_loader(temp_dir, secrets_file):
""" """
Create a Dynaconf instance matching the production configuration. Create a Dynaconf instance matching the production configuration.
@ -32,28 +32,25 @@ def create_dynaconf_with_custom_loader(temp_dir, secrets_file, fresh_vars=None):
- custom_merge_loader and env_loader enabled - custom_merge_loader and env_loader enabled
- merge_enabled = True - merge_enabled = True
Note: fresh_vars should be configured via FRESH_VARS_FOR_DYNACONF environment variable,
which is the only way to configure it in pr-agent.
Args: Args:
temp_dir: Temporary directory path temp_dir: Temporary directory path
secrets_file: Path to secrets file secrets_file: Path to secrets file
fresh_vars: List of section names to mark as fresh (e.g., ["GITLAB"])
Returns: Returns:
Dynaconf instance configured like production Dynaconf instance configured like production
""" """
kwargs = { return Dynaconf(
"core_loaders": [], core_loaders=[],
"loaders": ["pr_agent.custom_merge_loader", "dynaconf.loaders.env_loader"], loaders=["pr_agent.custom_merge_loader", "dynaconf.loaders.env_loader"],
"root_path": temp_dir, root_path=temp_dir,
"merge_enabled": True, merge_enabled=True,
"envvar_prefix": False, envvar_prefix=False,
"load_dotenv": False, load_dotenv=False,
"settings_files": [str(secrets_file)], settings_files=[str(secrets_file)],
} )
if fresh_vars:
kwargs["fresh_vars"] = fresh_vars
return Dynaconf(**kwargs)
class TestFreshVarsGitLabScenario: class TestFreshVarsGitLabScenario:
@ -104,8 +101,10 @@ shared_secret = "{shared_secret}"
# Create initial secrets file # Create initial secrets file
self.create_secrets_toml(personal_access_token="token_v1", shared_secret="secret_v1") self.create_secrets_toml(personal_access_token="token_v1", shared_secret="secret_v1")
# Create Dynaconf with GITLAB marked as fresh # Set FRESH_VARS_FOR_DYNACONF environment variable (the only way to configure fresh_vars in pr-agent)
settings = create_dynaconf_with_custom_loader(self.temp_dir, self.secrets_file, fresh_vars=["GITLAB"]) with patch.dict(os.environ, {"FRESH_VARS_FOR_DYNACONF": '["GITLAB"]'}):
# Create Dynaconf with GITLAB marked as fresh via env var
settings = create_dynaconf_with_custom_loader(self.temp_dir, self.secrets_file)
# First access - should return initial value # First access - should return initial value
first_token = settings.GITLAB.PERSONAL_ACCESS_TOKEN first_token = settings.GITLAB.PERSONAL_ACCESS_TOKEN
@ -123,35 +122,6 @@ shared_secret = "{shared_secret}"
# Verify the values are different (fresh_vars working) # Verify the values are different (fresh_vars working)
assert first_token != second_token, "fresh_vars should cause values to be reloaded, not cached" assert first_token != second_token, "fresh_vars should cause values to be reloaded, not cached"
def test_gitlab_shared_secret_reload(self):
"""
Test that gitlab.shared_secret is reloaded when GITLAB is marked as fresh.
Verifies that fresh_vars applies to all fields in the GITLAB section,
not just personal_access_token.
"""
# Create initial secrets file
self.create_secrets_toml(personal_access_token="token_v1", shared_secret="secret_v1")
# Create Dynaconf with GITLAB marked as fresh
settings = create_dynaconf_with_custom_loader(self.temp_dir, self.secrets_file, fresh_vars=["GITLAB"])
# First access
first_secret = settings.GITLAB.SHARED_SECRET
assert first_secret == "secret_v1", "Initial shared_secret should be 'secret_v1'"
# Modify the secrets file
self.create_secrets_toml(personal_access_token="token_v1", shared_secret="secret_v2_updated")
# Second access - should return NEW value
second_secret = settings.GITLAB.SHARED_SECRET
assert second_secret == "secret_v2_updated", (
"After file modification, shared_secret should be reloaded to 'secret_v2_updated'"
)
# Verify fresh_vars is working
assert first_secret != second_secret, "fresh_vars should cause shared_secret to be reloaded"
def test_gitlab_multiple_fields_reload(self): def test_gitlab_multiple_fields_reload(self):
""" """
Test that both gitlab fields reload together when GITLAB is marked as fresh. Test that both gitlab fields reload together when GITLAB is marked as fresh.
@ -162,8 +132,10 @@ shared_secret = "{shared_secret}"
# Create initial secrets file # Create initial secrets file
self.create_secrets_toml(personal_access_token="token_v1", shared_secret="secret_v1") self.create_secrets_toml(personal_access_token="token_v1", shared_secret="secret_v1")
# Create Dynaconf with GITLAB marked as fresh # Set FRESH_VARS_FOR_DYNACONF environment variable
settings = create_dynaconf_with_custom_loader(self.temp_dir, self.secrets_file, fresh_vars=["GITLAB"]) with patch.dict(os.environ, {"FRESH_VARS_FOR_DYNACONF": '["GITLAB"]'}):
# Create Dynaconf with GITLAB marked as fresh via env var
settings = create_dynaconf_with_custom_loader(self.temp_dir, self.secrets_file)
# First access - both fields # First access - both fields
first_token = settings.GITLAB.PERSONAL_ACCESS_TOKEN first_token = settings.GITLAB.PERSONAL_ACCESS_TOKEN
@ -172,7 +144,9 @@ shared_secret = "{shared_secret}"
assert first_secret == "secret_v1" assert first_secret == "secret_v1"
# Modify both fields in the secrets file # Modify both fields in the secrets file
self.create_secrets_toml(personal_access_token="token_v2_both_updated", shared_secret="secret_v2_both_updated") self.create_secrets_toml(
personal_access_token="token_v2_both_updated", shared_secret="secret_v2_both_updated"
)
# Second access - both fields should be updated # Second access - both fields should be updated
second_token = settings.GITLAB.PERSONAL_ACCESS_TOKEN second_token = settings.GITLAB.PERSONAL_ACCESS_TOKEN
@ -229,8 +203,10 @@ shared_secret = "{shared_secret}"
# Create initial secrets file # Create initial secrets file
self.create_secrets_toml(personal_access_token="token_before_bug_test") self.create_secrets_toml(personal_access_token="token_before_bug_test")
# Create Dynaconf WITHOUT core loaders but WITH fresh_vars # Set FRESH_VARS_FOR_DYNACONF environment variable
settings = create_dynaconf_with_custom_loader(self.temp_dir, self.secrets_file, fresh_vars=["GITLAB"]) with patch.dict(os.environ, {"FRESH_VARS_FOR_DYNACONF": '["GITLAB"]'}):
# Create Dynaconf WITHOUT core loaders but WITH fresh_vars via env var
settings = create_dynaconf_with_custom_loader(self.temp_dir, self.secrets_file)
# First access # First access
first_value = settings.GITLAB.PERSONAL_ACCESS_TOKEN first_value = settings.GITLAB.PERSONAL_ACCESS_TOKEN
@ -265,8 +241,10 @@ user_token = "github_token_v1"
""" """
self.secrets_file.write_text(content) self.secrets_file.write_text(content)
# Create Dynaconf with only GITLAB marked as fresh # Set FRESH_VARS_FOR_DYNACONF environment variable (only GITLAB)
settings = create_dynaconf_with_custom_loader(self.temp_dir, self.secrets_file, fresh_vars=["GITLAB"]) with patch.dict(os.environ, {"FRESH_VARS_FOR_DYNACONF": '["GITLAB"]'}):
# Create Dynaconf with only GITLAB marked as fresh via env var
settings = create_dynaconf_with_custom_loader(self.temp_dir, self.secrets_file)
# Access both sections # Access both sections
gitlab_token_1 = settings.GITLAB.PERSONAL_ACCESS_TOKEN gitlab_token_1 = settings.GITLAB.PERSONAL_ACCESS_TOKEN
@ -321,34 +299,6 @@ personal_access_token = "{personal_access_token}"
""" """
self.secrets_file.write_text(content) self.secrets_file.write_text(content)
def test_fresh_vars_from_environment_variable(self):
"""
Test that fresh_vars can be set via FRESH_VARS_FOR_DYNACONF environment variable.
This tests the common use case where fresh_vars is configured through
an environment variable rather than in code.
"""
# Create initial secrets file
self.create_secrets_toml(personal_access_token="env_token_v1")
# Set FRESH_VARS_FOR_DYNACONF environment variable
with patch.dict(os.environ, {"FRESH_VARS_FOR_DYNACONF": '["GITLAB"]'}):
# Create Dynaconf (should pick up fresh_vars from env)
settings = create_dynaconf_with_custom_loader(self.temp_dir, self.secrets_file)
# First access
first_value = settings.GITLAB.PERSONAL_ACCESS_TOKEN
assert first_value == "env_token_v1"
# Modify file
self.create_secrets_toml(personal_access_token="env_token_v2")
# Second access - should be reloaded
second_value = settings.GITLAB.PERSONAL_ACCESS_TOKEN
assert second_value == "env_token_v2", "fresh_vars from environment variable should cause reload"
assert first_value != second_value, "Values should be different when fresh_vars is set via env var"
def test_gitlab_credentials_not_cached_when_fresh(self): def test_gitlab_credentials_not_cached_when_fresh(self):
""" """
Test that GitLab credentials are not cached when marked as fresh. Test that GitLab credentials are not cached when marked as fresh.
@ -360,8 +310,10 @@ personal_access_token = "{personal_access_token}"
# Create initial secrets file # Create initial secrets file
self.create_secrets_toml(personal_access_token="no_cache_v1") self.create_secrets_toml(personal_access_token="no_cache_v1")
# Create Dynaconf with GITLAB marked as fresh # Set FRESH_VARS_FOR_DYNACONF environment variable
settings = create_dynaconf_with_custom_loader(self.temp_dir, self.secrets_file, fresh_vars=["GITLAB"]) with patch.dict(os.environ, {"FRESH_VARS_FOR_DYNACONF": '["GITLAB"]'}):
# Create Dynaconf with GITLAB marked as fresh via env var
settings = create_dynaconf_with_custom_loader(self.temp_dir, self.secrets_file)
# Access the token multiple times before modification # Access the token multiple times before modification
access_1 = settings.GITLAB.PERSONAL_ACCESS_TOKEN access_1 = settings.GITLAB.PERSONAL_ACCESS_TOKEN