|
| 1 | +import pytest |
| 2 | + |
| 3 | +from infrahub.core import registry |
| 4 | +from infrahub.core.branch import Branch |
| 5 | +from infrahub.core.constants import SchemaPathType |
| 6 | +from infrahub.core.migrations.graph.m062_remove_generic_generate_template import Migration062 |
| 7 | +from infrahub.core.migrations.schema.node_attribute_add import NodeAttributeAddMigration |
| 8 | +from infrahub.core.migrations.shared import InternalSchemaMigration, MigrationInput |
| 9 | +from infrahub.core.path import SchemaPath |
| 10 | +from infrahub.core.timestamp import Timestamp |
| 11 | +from infrahub.database import InfrahubDatabase |
| 12 | + |
| 13 | +COUNT_GENERATE_TEMPLATE_ON_GENERICS = """ |
| 14 | +MATCH (sg:SchemaGeneric)-[r:HAS_ATTRIBUTE]->(attr:Attribute {name: "generate_template"}) |
| 15 | +WHERE r.status = "active" AND r.to IS NULL |
| 16 | +RETURN count(attr) AS count |
| 17 | +""" |
| 18 | + |
| 19 | +COUNT_GENERATE_TEMPLATE_SCHEMA_ATTRIBUTE = """ |
| 20 | +MATCH p1 = (sn:SchemaNode)-[:HAS_ATTRIBUTE]->(:Attribute {name: "name"}) |
| 21 | + -[:HAS_VALUE]->(:AttributeValueIndexed {value: "Generic"}) |
| 22 | +WHERE all(r IN relationships(p1) WHERE r.status = "active" AND r.to IS NULL) |
| 23 | +MATCH p2 = (sn)-[:HAS_ATTRIBUTE]->(:Attribute {name: "namespace"}) |
| 24 | + -[:HAS_VALUE]->(:AttributeValueIndexed {value: "Schema"}) |
| 25 | +WHERE all(r IN relationships(p2) WHERE r.status = "active" AND r.to IS NULL) |
| 26 | +WITH sn |
| 27 | +LIMIT 1 |
| 28 | +MATCH p3 = (sn)-[:IS_RELATED]-(:Relationship {name: "schema__node__attributes"}) |
| 29 | + -[:IS_RELATED]-(sa:SchemaAttribute) |
| 30 | + -[:HAS_ATTRIBUTE]->(:Attribute {name: "name"}) |
| 31 | + -[:HAS_VALUE]->(:AttributeValueIndexed {value: "generate_template"}) |
| 32 | +WHERE all(r IN relationships(p3) WHERE r.status = "active" AND r.to IS NULL) |
| 33 | +RETURN count(sa) AS count |
| 34 | +""" |
| 35 | + |
| 36 | + |
| 37 | +@pytest.fixture |
| 38 | +async def migration_062_data( |
| 39 | + db: InfrahubDatabase, reset_registry: None, default_branch: Branch, register_core_schema_db: None |
| 40 | +) -> None: |
| 41 | + """Add generate_template attribute to SchemaGeneric nodes, simulating the old DB state.""" |
| 42 | + internal_schema_branch = InternalSchemaMigration.get_internal_schema() |
| 43 | + schema_node = internal_schema_branch.get_node(name="SchemaNode") |
| 44 | + schema_generic = internal_schema_branch.get_node(name="SchemaGeneric") |
| 45 | + |
| 46 | + # Build a SchemaGeneric definition that includes generate_template |
| 47 | + schema_generic_with_attr = internal_schema_branch.get_node(name="SchemaGeneric") |
| 48 | + generate_template_attr = schema_node.get_attribute(name="generate_template") |
| 49 | + schema_generic_with_attr.attributes.append(generate_template_attr) |
| 50 | + |
| 51 | + add_migration = NodeAttributeAddMigration( |
| 52 | + new_node_schema=schema_generic_with_attr, |
| 53 | + previous_node_schema=schema_generic, |
| 54 | + schema_path=SchemaPath( |
| 55 | + schema_kind="SchemaGeneric", path_type=SchemaPathType.ATTRIBUTE, field_name="generate_template" |
| 56 | + ), |
| 57 | + ) |
| 58 | + await add_migration.execute(migration_input=MigrationInput(db=db), branch=default_branch) |
| 59 | + |
| 60 | + # Also add generate_template SchemaAttribute to the SchemaGeneric type definition |
| 61 | + # This simulates the old DB state where update_core_schema stored the attribute definition |
| 62 | + schema_generic_def = registry.schema.get(name="SchemaGeneric", branch=default_branch, duplicate=True) |
| 63 | + gt_attr = generate_template_attr.duplicate() |
| 64 | + gt_attr.id = None |
| 65 | + schema_generic_def.attributes.append(gt_attr) |
| 66 | + await registry.schema.update_node_in_db( |
| 67 | + node=schema_generic_def, branch=default_branch, db=db, at=Timestamp(), user_id="migration-test" |
| 68 | + ) |
| 69 | + |
| 70 | + |
| 71 | +async def test_migration_062( |
| 72 | + db: InfrahubDatabase, reset_registry: None, default_branch: Branch, migration_062_data: None |
| 73 | +) -> None: |
| 74 | + result_before = await db.execute_query(query=COUNT_GENERATE_TEMPLATE_ON_GENERICS) |
| 75 | + assert result_before[0].get("count") > 0 |
| 76 | + |
| 77 | + schema_attr_before = await db.execute_query(query=COUNT_GENERATE_TEMPLATE_SCHEMA_ATTRIBUTE) |
| 78 | + assert schema_attr_before[0].get("count") > 0 |
| 79 | + |
| 80 | + migration = Migration062.init() |
| 81 | + execution_result = await migration.execute(migration_input=MigrationInput(db=db)) |
| 82 | + assert not execution_result.errors |
| 83 | + |
| 84 | + validation_result = await migration.validate_migration(db=db) |
| 85 | + assert not validation_result.errors |
| 86 | + |
| 87 | + result_after = await db.execute_query(query=COUNT_GENERATE_TEMPLATE_ON_GENERICS) |
| 88 | + assert result_after[0].get("count") == 0 |
| 89 | + |
| 90 | + schema_attr_after = await db.execute_query(query=COUNT_GENERATE_TEMPLATE_SCHEMA_ATTRIBUTE) |
| 91 | + assert schema_attr_after[0].get("count") == 0 |
0 commit comments