Created IAC reverse generator
This commit is contained in:
681
tests/unit/test_state_builder.py
Normal file
681
tests/unit/test_state_builder.py
Normal file
@@ -0,0 +1,681 @@
|
||||
"""Unit tests for the StateBuilder."""
|
||||
|
||||
import json
|
||||
import uuid
|
||||
|
||||
import pytest
|
||||
|
||||
from iac_reverse.models import (
|
||||
CodeGenerationResult,
|
||||
CpuArchitecture,
|
||||
DependencyGraph,
|
||||
DiscoveredResource,
|
||||
GeneratedFile,
|
||||
PlatformCategory,
|
||||
ProviderType,
|
||||
ResourceRelationship,
|
||||
StateEntry,
|
||||
StateFile,
|
||||
)
|
||||
from iac_reverse.state_builder import StateBuilder
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Helpers / Fixtures
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
|
||||
def make_resource(
|
||||
resource_type: str = "kubernetes_deployment",
|
||||
unique_id: str = "apps/v1/deployments/default/nginx",
|
||||
name: str = "nginx",
|
||||
raw_references: list[str] | None = None,
|
||||
attributes: dict | None = None,
|
||||
provider: ProviderType = ProviderType.KUBERNETES,
|
||||
platform_category: PlatformCategory = PlatformCategory.CONTAINER_ORCHESTRATION,
|
||||
) -> DiscoveredResource:
|
||||
"""Create a sample DiscoveredResource for testing."""
|
||||
return DiscoveredResource(
|
||||
resource_type=resource_type,
|
||||
unique_id=unique_id,
|
||||
name=name,
|
||||
provider=provider,
|
||||
platform_category=platform_category,
|
||||
architecture=CpuArchitecture.AARCH64,
|
||||
endpoint="https://k8s-api.local:6443",
|
||||
attributes=attributes or {"replicas": 3, "image": "nginx:1.25"},
|
||||
raw_references=raw_references or [],
|
||||
)
|
||||
|
||||
|
||||
def make_code_generation_result() -> CodeGenerationResult:
|
||||
"""Create a minimal CodeGenerationResult for testing."""
|
||||
return CodeGenerationResult(
|
||||
resource_files=[
|
||||
GeneratedFile(
|
||||
filename="kubernetes_deployment.tf",
|
||||
content='resource "kubernetes_deployment" "nginx" {}',
|
||||
resource_count=1,
|
||||
)
|
||||
],
|
||||
variables_file=GeneratedFile(
|
||||
filename="variables.tf", content="", resource_count=0
|
||||
),
|
||||
provider_file=GeneratedFile(
|
||||
filename="providers.tf", content="", resource_count=0
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
def make_dependency_graph(
|
||||
resources: list[DiscoveredResource],
|
||||
relationships: list[ResourceRelationship] | None = None,
|
||||
) -> DependencyGraph:
|
||||
"""Create a DependencyGraph from resources and optional relationships."""
|
||||
return DependencyGraph(
|
||||
resources=resources,
|
||||
relationships=relationships or [],
|
||||
topological_order=[r.unique_id for r in resources],
|
||||
cycles=[],
|
||||
unresolved_references=[],
|
||||
)
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Tests: Single resource produces valid state entry
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
|
||||
class TestSingleResource:
|
||||
"""Tests for state generation with a single resource."""
|
||||
|
||||
def test_single_resource_produces_one_state_entry(self):
|
||||
"""A single resource in the graph produces exactly one state entry."""
|
||||
resource = make_resource()
|
||||
graph = make_dependency_graph([resource])
|
||||
code_result = make_code_generation_result()
|
||||
|
||||
builder = StateBuilder()
|
||||
state = builder.build(code_result, graph, provider_version="3.2.1")
|
||||
|
||||
assert len(state.resources) == 1
|
||||
|
||||
def test_state_entry_has_correct_resource_type(self):
|
||||
"""State entry resource_type matches the discovered resource type."""
|
||||
resource = make_resource(resource_type="kubernetes_deployment")
|
||||
graph = make_dependency_graph([resource])
|
||||
code_result = make_code_generation_result()
|
||||
|
||||
builder = StateBuilder()
|
||||
state = builder.build(code_result, graph, provider_version="1.0.0")
|
||||
|
||||
assert state.resources[0].resource_type == "kubernetes_deployment"
|
||||
|
||||
def test_state_entry_has_sanitized_resource_name(self):
|
||||
"""State entry resource_name is a valid Terraform identifier."""
|
||||
resource = make_resource(name="my-nginx-app")
|
||||
graph = make_dependency_graph([resource])
|
||||
code_result = make_code_generation_result()
|
||||
|
||||
builder = StateBuilder()
|
||||
state = builder.build(code_result, graph, provider_version="1.0.0")
|
||||
|
||||
# Hyphens should be replaced with underscores
|
||||
assert state.resources[0].resource_name == "my_nginx_app"
|
||||
|
||||
def test_state_entry_provider_id_is_unique_id(self):
|
||||
"""State entry provider_id is the live infrastructure unique_id."""
|
||||
resource = make_resource(unique_id="apps/v1/deployments/default/nginx")
|
||||
graph = make_dependency_graph([resource])
|
||||
code_result = make_code_generation_result()
|
||||
|
||||
builder = StateBuilder()
|
||||
state = builder.build(code_result, graph, provider_version="1.0.0")
|
||||
|
||||
assert state.resources[0].provider_id == "apps/v1/deployments/default/nginx"
|
||||
|
||||
def test_state_entry_attributes_from_discovery(self):
|
||||
"""State entry attributes contain the full discovery attribute set."""
|
||||
attrs = {"replicas": 3, "image": "nginx:1.25", "namespace": "default"}
|
||||
resource = make_resource(attributes=attrs)
|
||||
graph = make_dependency_graph([resource])
|
||||
code_result = make_code_generation_result()
|
||||
|
||||
builder = StateBuilder()
|
||||
state = builder.build(code_result, graph, provider_version="1.0.0")
|
||||
|
||||
assert state.resources[0].attributes == attrs
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Tests: Multiple resources produce multiple state entries
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
|
||||
class TestMultipleResources:
|
||||
"""Tests for state generation with multiple resources."""
|
||||
|
||||
def test_multiple_resources_produce_multiple_entries(self):
|
||||
"""Each resource in the graph produces a corresponding state entry."""
|
||||
resources = [
|
||||
make_resource(
|
||||
resource_type="kubernetes_deployment",
|
||||
unique_id="deploy/nginx",
|
||||
name="nginx",
|
||||
),
|
||||
make_resource(
|
||||
resource_type="kubernetes_service",
|
||||
unique_id="svc/nginx-svc",
|
||||
name="nginx-svc",
|
||||
),
|
||||
make_resource(
|
||||
resource_type="kubernetes_namespace",
|
||||
unique_id="ns/default",
|
||||
name="default",
|
||||
),
|
||||
]
|
||||
graph = make_dependency_graph(resources)
|
||||
code_result = make_code_generation_result()
|
||||
|
||||
builder = StateBuilder()
|
||||
state = builder.build(code_result, graph, provider_version="2.0.0")
|
||||
|
||||
assert len(state.resources) == 3
|
||||
|
||||
def test_multiple_resources_have_distinct_entries(self):
|
||||
"""Each state entry corresponds to a different resource."""
|
||||
resources = [
|
||||
make_resource(
|
||||
resource_type="kubernetes_deployment",
|
||||
unique_id="deploy/nginx",
|
||||
name="nginx",
|
||||
),
|
||||
make_resource(
|
||||
resource_type="kubernetes_service",
|
||||
unique_id="svc/redis",
|
||||
name="redis",
|
||||
),
|
||||
]
|
||||
graph = make_dependency_graph(resources)
|
||||
code_result = make_code_generation_result()
|
||||
|
||||
builder = StateBuilder()
|
||||
state = builder.build(code_result, graph, provider_version="1.0.0")
|
||||
|
||||
types = {e.resource_type for e in state.resources}
|
||||
assert "kubernetes_deployment" in types
|
||||
assert "kubernetes_service" in types
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Tests: Lineage is a valid UUID
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
|
||||
class TestLineage:
|
||||
"""Tests for state file lineage UUID generation."""
|
||||
|
||||
def test_lineage_is_valid_uuid(self):
|
||||
"""The state file lineage is a valid UUID string."""
|
||||
resource = make_resource()
|
||||
graph = make_dependency_graph([resource])
|
||||
code_result = make_code_generation_result()
|
||||
|
||||
builder = StateBuilder()
|
||||
state = builder.build(code_result, graph, provider_version="1.0.0")
|
||||
|
||||
# Should not raise ValueError
|
||||
parsed = uuid.UUID(state.lineage)
|
||||
assert str(parsed) == state.lineage
|
||||
|
||||
def test_lineage_is_unique_per_build(self):
|
||||
"""Each build produces a different lineage UUID."""
|
||||
resource = make_resource()
|
||||
graph = make_dependency_graph([resource])
|
||||
code_result = make_code_generation_result()
|
||||
|
||||
builder = StateBuilder()
|
||||
state1 = builder.build(code_result, graph, provider_version="1.0.0")
|
||||
state2 = builder.build(code_result, graph, provider_version="1.0.0")
|
||||
|
||||
assert state1.lineage != state2.lineage
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Tests: Dependencies are included as Terraform resource addresses
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
|
||||
class TestDependencies:
|
||||
"""Tests for dependency references in state entries."""
|
||||
|
||||
def test_dependencies_as_terraform_addresses(self):
|
||||
"""Dependencies are formatted as resource_type.resource_name."""
|
||||
namespace = make_resource(
|
||||
resource_type="kubernetes_namespace",
|
||||
unique_id="ns/default",
|
||||
name="default",
|
||||
)
|
||||
deployment = make_resource(
|
||||
resource_type="kubernetes_deployment",
|
||||
unique_id="deploy/nginx",
|
||||
name="nginx",
|
||||
raw_references=["ns/default"],
|
||||
)
|
||||
relationship = ResourceRelationship(
|
||||
source_id="deploy/nginx",
|
||||
target_id="ns/default",
|
||||
relationship_type="dependency",
|
||||
source_attribute="namespace",
|
||||
)
|
||||
graph = make_dependency_graph(
|
||||
[namespace, deployment], relationships=[relationship]
|
||||
)
|
||||
code_result = make_code_generation_result()
|
||||
|
||||
builder = StateBuilder()
|
||||
state = builder.build(code_result, graph, provider_version="1.0.0")
|
||||
|
||||
# Find the deployment entry
|
||||
deploy_entry = next(
|
||||
e for e in state.resources if e.resource_type == "kubernetes_deployment"
|
||||
)
|
||||
assert "kubernetes_namespace.default" in deploy_entry.dependencies
|
||||
|
||||
def test_resource_without_dependencies_has_empty_list(self):
|
||||
"""A resource with no relationships has an empty dependencies list."""
|
||||
resource = make_resource()
|
||||
graph = make_dependency_graph([resource])
|
||||
code_result = make_code_generation_result()
|
||||
|
||||
builder = StateBuilder()
|
||||
state = builder.build(code_result, graph, provider_version="1.0.0")
|
||||
|
||||
assert state.resources[0].dependencies == []
|
||||
|
||||
def test_multiple_dependencies_all_included(self):
|
||||
"""All dependency relationships are included in the state entry."""
|
||||
ns = make_resource(
|
||||
resource_type="kubernetes_namespace",
|
||||
unique_id="ns/default",
|
||||
name="default",
|
||||
)
|
||||
svc = make_resource(
|
||||
resource_type="kubernetes_service",
|
||||
unique_id="svc/nginx-svc",
|
||||
name="nginx-svc",
|
||||
)
|
||||
deployment = make_resource(
|
||||
resource_type="kubernetes_deployment",
|
||||
unique_id="deploy/nginx",
|
||||
name="nginx",
|
||||
)
|
||||
relationships = [
|
||||
ResourceRelationship(
|
||||
source_id="deploy/nginx",
|
||||
target_id="ns/default",
|
||||
relationship_type="dependency",
|
||||
source_attribute="namespace",
|
||||
),
|
||||
ResourceRelationship(
|
||||
source_id="deploy/nginx",
|
||||
target_id="svc/nginx-svc",
|
||||
relationship_type="reference",
|
||||
source_attribute="service",
|
||||
),
|
||||
]
|
||||
graph = make_dependency_graph([ns, svc, deployment], relationships=relationships)
|
||||
code_result = make_code_generation_result()
|
||||
|
||||
builder = StateBuilder()
|
||||
state = builder.build(code_result, graph, provider_version="1.0.0")
|
||||
|
||||
deploy_entry = next(
|
||||
e for e in state.resources if e.resource_type == "kubernetes_deployment"
|
||||
)
|
||||
assert len(deploy_entry.dependencies) == 2
|
||||
assert "kubernetes_namespace.default" in deploy_entry.dependencies
|
||||
assert "kubernetes_service.nginx_svc" in deploy_entry.dependencies
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Tests: Sensitive attributes are marked
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
|
||||
class TestSensitiveAttributes:
|
||||
"""Tests for sensitive attribute detection."""
|
||||
|
||||
def test_password_attribute_marked_sensitive(self):
|
||||
"""Attributes containing 'password' are marked sensitive."""
|
||||
resource = make_resource(
|
||||
attributes={"db_password": "secret123", "name": "mydb"}
|
||||
)
|
||||
graph = make_dependency_graph([resource])
|
||||
code_result = make_code_generation_result()
|
||||
|
||||
builder = StateBuilder()
|
||||
state = builder.build(code_result, graph, provider_version="1.0.0")
|
||||
|
||||
assert "db_password" in state.resources[0].sensitive_attributes
|
||||
|
||||
def test_token_attribute_marked_sensitive(self):
|
||||
"""Attributes containing 'token' are marked sensitive."""
|
||||
resource = make_resource(
|
||||
attributes={"api_token": "abc123", "endpoint": "https://api.local"}
|
||||
)
|
||||
graph = make_dependency_graph([resource])
|
||||
code_result = make_code_generation_result()
|
||||
|
||||
builder = StateBuilder()
|
||||
state = builder.build(code_result, graph, provider_version="1.0.0")
|
||||
|
||||
assert "api_token" in state.resources[0].sensitive_attributes
|
||||
|
||||
def test_secret_attribute_marked_sensitive(self):
|
||||
"""Attributes containing 'secret' are marked sensitive."""
|
||||
resource = make_resource(
|
||||
attributes={"client_secret": "xyz", "client_id": "app1"}
|
||||
)
|
||||
graph = make_dependency_graph([resource])
|
||||
code_result = make_code_generation_result()
|
||||
|
||||
builder = StateBuilder()
|
||||
state = builder.build(code_result, graph, provider_version="1.0.0")
|
||||
|
||||
assert "client_secret" in state.resources[0].sensitive_attributes
|
||||
|
||||
def test_key_attribute_marked_sensitive(self):
|
||||
"""Attributes containing 'key' are marked sensitive."""
|
||||
resource = make_resource(
|
||||
attributes={"private_key": "-----BEGIN RSA KEY-----", "name": "cert1"}
|
||||
)
|
||||
graph = make_dependency_graph([resource])
|
||||
code_result = make_code_generation_result()
|
||||
|
||||
builder = StateBuilder()
|
||||
state = builder.build(code_result, graph, provider_version="1.0.0")
|
||||
|
||||
assert "private_key" in state.resources[0].sensitive_attributes
|
||||
|
||||
def test_certificate_attribute_marked_sensitive(self):
|
||||
"""Attributes containing 'certificate' are marked sensitive."""
|
||||
resource = make_resource(
|
||||
attributes={"tls_certificate": "cert-data", "port": 443}
|
||||
)
|
||||
graph = make_dependency_graph([resource])
|
||||
code_result = make_code_generation_result()
|
||||
|
||||
builder = StateBuilder()
|
||||
state = builder.build(code_result, graph, provider_version="1.0.0")
|
||||
|
||||
assert "tls_certificate" in state.resources[0].sensitive_attributes
|
||||
|
||||
def test_non_sensitive_attributes_not_marked(self):
|
||||
"""Attributes without sensitive patterns are not marked."""
|
||||
resource = make_resource(
|
||||
attributes={"replicas": 3, "image": "nginx:1.25", "namespace": "default"}
|
||||
)
|
||||
graph = make_dependency_graph([resource])
|
||||
code_result = make_code_generation_result()
|
||||
|
||||
builder = StateBuilder()
|
||||
state = builder.build(code_result, graph, provider_version="1.0.0")
|
||||
|
||||
assert state.resources[0].sensitive_attributes == []
|
||||
|
||||
def test_nested_sensitive_attributes_detected(self):
|
||||
"""Sensitive attributes in nested dicts are detected."""
|
||||
resource = make_resource(
|
||||
attributes={
|
||||
"config": {"database_password": "secret", "host": "localhost"}
|
||||
}
|
||||
)
|
||||
graph = make_dependency_graph([resource])
|
||||
code_result = make_code_generation_result()
|
||||
|
||||
builder = StateBuilder()
|
||||
state = builder.build(code_result, graph, provider_version="1.0.0")
|
||||
|
||||
assert "config.database_password" in state.resources[0].sensitive_attributes
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Tests: Schema version is set from provider_version
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
|
||||
class TestSchemaVersion:
|
||||
"""Tests for schema_version setting from provider_version."""
|
||||
|
||||
def test_schema_version_from_major_version(self):
|
||||
"""Schema version is the major version number from provider_version."""
|
||||
resource = make_resource()
|
||||
graph = make_dependency_graph([resource])
|
||||
code_result = make_code_generation_result()
|
||||
|
||||
builder = StateBuilder()
|
||||
state = builder.build(code_result, graph, provider_version="3.2.1")
|
||||
|
||||
assert state.resources[0].schema_version == 3
|
||||
|
||||
def test_schema_version_single_digit(self):
|
||||
"""Schema version works with a single digit version string."""
|
||||
resource = make_resource()
|
||||
graph = make_dependency_graph([resource])
|
||||
code_result = make_code_generation_result()
|
||||
|
||||
builder = StateBuilder()
|
||||
state = builder.build(code_result, graph, provider_version="1")
|
||||
|
||||
assert state.resources[0].schema_version == 1
|
||||
|
||||
def test_schema_version_defaults_to_zero_on_invalid(self):
|
||||
"""Schema version defaults to 0 if provider_version is unparseable."""
|
||||
resource = make_resource()
|
||||
graph = make_dependency_graph([resource])
|
||||
code_result = make_code_generation_result()
|
||||
|
||||
builder = StateBuilder()
|
||||
state = builder.build(code_result, graph, provider_version="invalid")
|
||||
|
||||
assert state.resources[0].schema_version == 0
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Tests: to_json() produces valid JSON with correct structure
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
|
||||
class TestToJson:
|
||||
"""Tests for state file JSON serialization."""
|
||||
|
||||
def test_to_json_produces_valid_json(self):
|
||||
"""to_json() output is valid JSON."""
|
||||
resource = make_resource(
|
||||
attributes={"replicas": 3, "image": "nginx:1.25"}
|
||||
)
|
||||
graph = make_dependency_graph([resource])
|
||||
code_result = make_code_generation_result()
|
||||
|
||||
builder = StateBuilder()
|
||||
state = builder.build(code_result, graph, provider_version="1.0.0")
|
||||
|
||||
json_str = state.to_json()
|
||||
parsed = json.loads(json_str)
|
||||
assert isinstance(parsed, dict)
|
||||
|
||||
def test_to_json_has_version_4(self):
|
||||
"""JSON output has version field set to 4."""
|
||||
resource = make_resource()
|
||||
graph = make_dependency_graph([resource])
|
||||
code_result = make_code_generation_result()
|
||||
|
||||
builder = StateBuilder()
|
||||
state = builder.build(code_result, graph, provider_version="1.0.0")
|
||||
|
||||
parsed = json.loads(state.to_json())
|
||||
assert parsed["version"] == 4
|
||||
|
||||
def test_to_json_has_serial_1(self):
|
||||
"""JSON output has serial field set to 1."""
|
||||
resource = make_resource()
|
||||
graph = make_dependency_graph([resource])
|
||||
code_result = make_code_generation_result()
|
||||
|
||||
builder = StateBuilder()
|
||||
state = builder.build(code_result, graph, provider_version="1.0.0")
|
||||
|
||||
parsed = json.loads(state.to_json())
|
||||
assert parsed["serial"] == 1
|
||||
|
||||
def test_to_json_has_terraform_version(self):
|
||||
"""JSON output includes the terraform_version."""
|
||||
resource = make_resource()
|
||||
graph = make_dependency_graph([resource])
|
||||
code_result = make_code_generation_result()
|
||||
|
||||
builder = StateBuilder(terraform_version="1.7.0")
|
||||
state = builder.build(code_result, graph, provider_version="1.0.0")
|
||||
|
||||
parsed = json.loads(state.to_json())
|
||||
assert parsed["terraform_version"] == "1.7.0"
|
||||
|
||||
def test_to_json_has_valid_lineage_uuid(self):
|
||||
"""JSON output lineage is a valid UUID."""
|
||||
resource = make_resource()
|
||||
graph = make_dependency_graph([resource])
|
||||
code_result = make_code_generation_result()
|
||||
|
||||
builder = StateBuilder()
|
||||
state = builder.build(code_result, graph, provider_version="1.0.0")
|
||||
|
||||
parsed = json.loads(state.to_json())
|
||||
# Should not raise ValueError
|
||||
uuid.UUID(parsed["lineage"])
|
||||
|
||||
def test_to_json_resources_have_correct_structure(self):
|
||||
"""JSON resources have mode, type, name, provider, and instances."""
|
||||
resource = make_resource(
|
||||
resource_type="kubernetes_deployment",
|
||||
name="nginx",
|
||||
attributes={"replicas": 3},
|
||||
)
|
||||
graph = make_dependency_graph([resource])
|
||||
code_result = make_code_generation_result()
|
||||
|
||||
builder = StateBuilder()
|
||||
state = builder.build(code_result, graph, provider_version="2.0.0")
|
||||
|
||||
parsed = json.loads(state.to_json())
|
||||
assert len(parsed["resources"]) == 1
|
||||
|
||||
res = parsed["resources"][0]
|
||||
assert res["mode"] == "managed"
|
||||
assert res["type"] == "kubernetes_deployment"
|
||||
assert res["name"] == "nginx"
|
||||
assert "provider" in res
|
||||
assert len(res["instances"]) == 1
|
||||
|
||||
def test_to_json_instance_has_attributes_with_id(self):
|
||||
"""JSON instance attributes include the provider_id as 'id'."""
|
||||
resource = make_resource(
|
||||
unique_id="apps/v1/deployments/default/nginx",
|
||||
attributes={"replicas": 3},
|
||||
)
|
||||
graph = make_dependency_graph([resource])
|
||||
code_result = make_code_generation_result()
|
||||
|
||||
builder = StateBuilder()
|
||||
state = builder.build(code_result, graph, provider_version="1.0.0")
|
||||
|
||||
parsed = json.loads(state.to_json())
|
||||
instance = parsed["resources"][0]["instances"][0]
|
||||
assert instance["attributes"]["id"] == "apps/v1/deployments/default/nginx"
|
||||
assert instance["attributes"]["replicas"] == 3
|
||||
|
||||
def test_to_json_instance_has_schema_version(self):
|
||||
"""JSON instance includes schema_version."""
|
||||
resource = make_resource()
|
||||
graph = make_dependency_graph([resource])
|
||||
code_result = make_code_generation_result()
|
||||
|
||||
builder = StateBuilder()
|
||||
state = builder.build(code_result, graph, provider_version="3.0.0")
|
||||
|
||||
parsed = json.loads(state.to_json())
|
||||
instance = parsed["resources"][0]["instances"][0]
|
||||
assert instance["schema_version"] == 3
|
||||
|
||||
def test_to_json_instance_has_dependencies(self):
|
||||
"""JSON instance includes dependencies list."""
|
||||
ns = make_resource(
|
||||
resource_type="kubernetes_namespace",
|
||||
unique_id="ns/default",
|
||||
name="default",
|
||||
)
|
||||
deployment = make_resource(
|
||||
resource_type="kubernetes_deployment",
|
||||
unique_id="deploy/nginx",
|
||||
name="nginx",
|
||||
)
|
||||
relationship = ResourceRelationship(
|
||||
source_id="deploy/nginx",
|
||||
target_id="ns/default",
|
||||
relationship_type="dependency",
|
||||
source_attribute="namespace",
|
||||
)
|
||||
graph = make_dependency_graph([ns, deployment], relationships=[relationship])
|
||||
code_result = make_code_generation_result()
|
||||
|
||||
builder = StateBuilder()
|
||||
state = builder.build(code_result, graph, provider_version="1.0.0")
|
||||
|
||||
parsed = json.loads(state.to_json())
|
||||
deploy_res = next(
|
||||
r for r in parsed["resources"] if r["type"] == "kubernetes_deployment"
|
||||
)
|
||||
instance = deploy_res["instances"][0]
|
||||
assert "kubernetes_namespace.default" in instance["dependencies"]
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Tests: State file metadata
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
|
||||
class TestStateFileMetadata:
|
||||
"""Tests for state file top-level metadata."""
|
||||
|
||||
def test_version_is_4(self):
|
||||
"""State file version is always 4."""
|
||||
resource = make_resource()
|
||||
graph = make_dependency_graph([resource])
|
||||
code_result = make_code_generation_result()
|
||||
|
||||
builder = StateBuilder()
|
||||
state = builder.build(code_result, graph, provider_version="1.0.0")
|
||||
|
||||
assert state.version == 4
|
||||
|
||||
def test_serial_is_1(self):
|
||||
"""State file serial is 1 for initial generation."""
|
||||
resource = make_resource()
|
||||
graph = make_dependency_graph([resource])
|
||||
code_result = make_code_generation_result()
|
||||
|
||||
builder = StateBuilder()
|
||||
state = builder.build(code_result, graph, provider_version="1.0.0")
|
||||
|
||||
assert state.serial == 1
|
||||
|
||||
def test_custom_terraform_version(self):
|
||||
"""StateBuilder accepts a custom terraform_version."""
|
||||
resource = make_resource()
|
||||
graph = make_dependency_graph([resource])
|
||||
code_result = make_code_generation_result()
|
||||
|
||||
builder = StateBuilder(terraform_version="1.8.0")
|
||||
state = builder.build(code_result, graph, provider_version="1.0.0")
|
||||
|
||||
assert state.terraform_version == "1.8.0"
|
||||
Reference in New Issue
Block a user