second first commit
This commit is contained in:
@@ -0,0 +1,251 @@
|
||||
"""Secrets Manager integration tests."""
|
||||
|
||||
import pytest
|
||||
from botocore.exceptions import ClientError
|
||||
|
||||
|
||||
class TestSecretsManagerSecret:
|
||||
"""Test Secrets Manager secret operations."""
|
||||
|
||||
def test_create_secret(self, secretsmanager_client, unique_name):
|
||||
"""Test CreateSecret creates a secret."""
|
||||
secret_name = f"pytest-secret-{unique_name}"
|
||||
secret_value = "my-super-secret-value"
|
||||
|
||||
try:
|
||||
response = secretsmanager_client.create_secret(
|
||||
Name=secret_name,
|
||||
SecretString=secret_value,
|
||||
Description="Test secret",
|
||||
Tags=[{"Key": "env", "Value": "test"}],
|
||||
)
|
||||
assert response["ARN"]
|
||||
assert secret_name in response["ARN"]
|
||||
assert response["Name"] == secret_name
|
||||
finally:
|
||||
secretsmanager_client.delete_secret(
|
||||
SecretId=secret_name, ForceDeleteWithoutRecovery=True
|
||||
)
|
||||
|
||||
def test_get_secret_value_by_name(self, secretsmanager_client, unique_name):
|
||||
"""Test GetSecretValue by name returns secret."""
|
||||
secret_name = f"pytest-secret-{unique_name}"
|
||||
secret_value = "my-super-secret-value"
|
||||
|
||||
secretsmanager_client.create_secret(Name=secret_name, SecretString=secret_value)
|
||||
try:
|
||||
response = secretsmanager_client.get_secret_value(SecretId=secret_name)
|
||||
assert response["SecretString"] == secret_value
|
||||
assert response["Name"] == secret_name
|
||||
finally:
|
||||
secretsmanager_client.delete_secret(
|
||||
SecretId=secret_name, ForceDeleteWithoutRecovery=True
|
||||
)
|
||||
|
||||
def test_get_secret_value_by_arn(self, secretsmanager_client, unique_name):
|
||||
"""Test GetSecretValue by ARN returns secret."""
|
||||
secret_name = f"pytest-secret-{unique_name}"
|
||||
secret_value = "my-super-secret-value"
|
||||
|
||||
response = secretsmanager_client.create_secret(
|
||||
Name=secret_name, SecretString=secret_value
|
||||
)
|
||||
secret_arn = response["ARN"]
|
||||
|
||||
try:
|
||||
response = secretsmanager_client.get_secret_value(SecretId=secret_arn)
|
||||
assert response["SecretString"] == secret_value
|
||||
finally:
|
||||
secretsmanager_client.delete_secret(
|
||||
SecretId=secret_name, ForceDeleteWithoutRecovery=True
|
||||
)
|
||||
|
||||
def test_put_secret_value(self, secretsmanager_client, unique_name):
|
||||
"""Test PutSecretValue updates secret."""
|
||||
secret_name = f"pytest-secret-{unique_name}"
|
||||
|
||||
response = secretsmanager_client.create_secret(
|
||||
Name=secret_name, SecretString="original"
|
||||
)
|
||||
original_version = response["VersionId"]
|
||||
|
||||
try:
|
||||
response = secretsmanager_client.put_secret_value(
|
||||
SecretId=secret_name, SecretString="updated"
|
||||
)
|
||||
new_version = response["VersionId"]
|
||||
assert new_version
|
||||
assert new_version != original_version
|
||||
|
||||
response = secretsmanager_client.get_secret_value(SecretId=secret_name)
|
||||
assert response["SecretString"] == "updated"
|
||||
finally:
|
||||
secretsmanager_client.delete_secret(
|
||||
SecretId=secret_name, ForceDeleteWithoutRecovery=True
|
||||
)
|
||||
|
||||
def test_describe_secret(self, secretsmanager_client, unique_name):
|
||||
"""Test DescribeSecret returns secret metadata."""
|
||||
secret_name = f"pytest-secret-{unique_name}"
|
||||
|
||||
secretsmanager_client.create_secret(
|
||||
Name=secret_name,
|
||||
SecretString="value",
|
||||
Tags=[{"Key": "env", "Value": "test"}],
|
||||
)
|
||||
|
||||
try:
|
||||
response = secretsmanager_client.describe_secret(SecretId=secret_name)
|
||||
assert response.get("Tags")
|
||||
assert not response.get("RotationEnabled", True)
|
||||
finally:
|
||||
secretsmanager_client.delete_secret(
|
||||
SecretId=secret_name, ForceDeleteWithoutRecovery=True
|
||||
)
|
||||
|
||||
def test_update_secret(self, secretsmanager_client, unique_name):
|
||||
"""Test UpdateSecret updates secret description."""
|
||||
secret_name = f"pytest-secret-{unique_name}"
|
||||
|
||||
secretsmanager_client.create_secret(
|
||||
Name=secret_name, SecretString="value", Description="Original"
|
||||
)
|
||||
|
||||
try:
|
||||
secretsmanager_client.update_secret(
|
||||
SecretId=secret_name, Description="Updated description"
|
||||
)
|
||||
|
||||
response = secretsmanager_client.describe_secret(SecretId=secret_name)
|
||||
assert response.get("Description") == "Updated description"
|
||||
finally:
|
||||
secretsmanager_client.delete_secret(
|
||||
SecretId=secret_name, ForceDeleteWithoutRecovery=True
|
||||
)
|
||||
|
||||
def test_list_secrets(self, secretsmanager_client, unique_name):
|
||||
"""Test ListSecrets includes created secret."""
|
||||
secret_name = f"pytest-secret-{unique_name}"
|
||||
|
||||
secretsmanager_client.create_secret(Name=secret_name, SecretString="value")
|
||||
|
||||
try:
|
||||
response = secretsmanager_client.list_secrets()
|
||||
assert any(s["Name"] == secret_name for s in response["SecretList"])
|
||||
finally:
|
||||
secretsmanager_client.delete_secret(
|
||||
SecretId=secret_name, ForceDeleteWithoutRecovery=True
|
||||
)
|
||||
|
||||
def test_delete_secret(self, secretsmanager_client, unique_name):
|
||||
"""Test DeleteSecret removes secret."""
|
||||
secret_name = f"pytest-secret-{unique_name}"
|
||||
|
||||
secretsmanager_client.create_secret(Name=secret_name, SecretString="value")
|
||||
secretsmanager_client.delete_secret(
|
||||
SecretId=secret_name, ForceDeleteWithoutRecovery=True
|
||||
)
|
||||
|
||||
with pytest.raises(ClientError) as exc_info:
|
||||
secretsmanager_client.get_secret_value(SecretId=secret_name)
|
||||
assert exc_info.value.response["ResponseMetadata"]["HTTPStatusCode"] == 400
|
||||
|
||||
|
||||
class TestSecretsManagerTags:
|
||||
"""Test Secrets Manager tagging operations."""
|
||||
|
||||
def test_tag_resource(self, secretsmanager_client, unique_name):
|
||||
"""Test TagResource adds tags to secret."""
|
||||
secret_name = f"pytest-secret-{unique_name}"
|
||||
|
||||
secretsmanager_client.create_secret(Name=secret_name, SecretString="value")
|
||||
|
||||
try:
|
||||
secretsmanager_client.tag_resource(
|
||||
SecretId=secret_name, Tags=[{"Key": "team", "Value": "backend"}]
|
||||
)
|
||||
|
||||
response = secretsmanager_client.describe_secret(SecretId=secret_name)
|
||||
tags = {t["Key"]: t["Value"] for t in response.get("Tags", [])}
|
||||
assert tags.get("team") == "backend"
|
||||
finally:
|
||||
secretsmanager_client.delete_secret(
|
||||
SecretId=secret_name, ForceDeleteWithoutRecovery=True
|
||||
)
|
||||
|
||||
def test_untag_resource(self, secretsmanager_client, unique_name):
|
||||
"""Test UntagResource removes tags from secret."""
|
||||
secret_name = f"pytest-secret-{unique_name}"
|
||||
|
||||
secretsmanager_client.create_secret(
|
||||
Name=secret_name,
|
||||
SecretString="value",
|
||||
Tags=[{"Key": "team", "Value": "backend"}],
|
||||
)
|
||||
|
||||
try:
|
||||
secretsmanager_client.untag_resource(
|
||||
SecretId=secret_name, TagKeys=["team"]
|
||||
)
|
||||
|
||||
response = secretsmanager_client.describe_secret(SecretId=secret_name)
|
||||
tags = {t["Key"] for t in response.get("Tags", [])}
|
||||
assert "team" not in tags
|
||||
finally:
|
||||
secretsmanager_client.delete_secret(
|
||||
SecretId=secret_name, ForceDeleteWithoutRecovery=True
|
||||
)
|
||||
|
||||
|
||||
class TestSecretsManagerVersions:
|
||||
"""Test Secrets Manager version operations."""
|
||||
|
||||
def test_list_secret_version_ids(self, secretsmanager_client, unique_name):
|
||||
"""Test ListSecretVersionIds returns version stages."""
|
||||
secret_name = f"pytest-secret-{unique_name}"
|
||||
|
||||
secretsmanager_client.create_secret(Name=secret_name, SecretString="v1")
|
||||
secretsmanager_client.put_secret_value(SecretId=secret_name, SecretString="v2")
|
||||
|
||||
try:
|
||||
response = secretsmanager_client.list_secret_version_ids(
|
||||
SecretId=secret_name
|
||||
)
|
||||
stages = [
|
||||
stage for v in response["Versions"] for stage in v.get("VersionStages", [])
|
||||
]
|
||||
assert "AWSCURRENT" in stages
|
||||
assert "AWSPREVIOUS" in stages
|
||||
finally:
|
||||
secretsmanager_client.delete_secret(
|
||||
SecretId=secret_name, ForceDeleteWithoutRecovery=True
|
||||
)
|
||||
|
||||
|
||||
class TestSecretsManagerErrors:
|
||||
"""Test Secrets Manager error handling."""
|
||||
|
||||
def test_create_secret_duplicate(self, secretsmanager_client, unique_name):
|
||||
"""Test CreateSecret returns error for duplicate name."""
|
||||
secret_name = f"pytest-secret-{unique_name}"
|
||||
|
||||
secretsmanager_client.create_secret(Name=secret_name, SecretString="v1")
|
||||
|
||||
try:
|
||||
with pytest.raises(ClientError) as exc_info:
|
||||
secretsmanager_client.create_secret(
|
||||
Name=secret_name, SecretString="v2"
|
||||
)
|
||||
assert exc_info.value.response["ResponseMetadata"]["HTTPStatusCode"] == 400
|
||||
finally:
|
||||
secretsmanager_client.delete_secret(
|
||||
SecretId=secret_name, ForceDeleteWithoutRecovery=True
|
||||
)
|
||||
|
||||
def test_get_secret_value_non_existent(self, secretsmanager_client, unique_name):
|
||||
"""Test GetSecretValue returns error for non-existent secret."""
|
||||
with pytest.raises(ClientError) as exc_info:
|
||||
secretsmanager_client.get_secret_value(
|
||||
SecretId=f"non-existent-secret-{unique_name}"
|
||||
)
|
||||
assert exc_info.value.response["ResponseMetadata"]["HTTPStatusCode"] == 400
|
||||
Reference in New Issue
Block a user