|
1 | 1 | import pytest |
2 | 2 |
|
| 3 | +from infrahub.core import registry |
3 | 4 | from infrahub.core.branch import Branch |
4 | | -from infrahub.core.constants import DiffAction, RelationshipCardinality |
| 5 | +from infrahub.core.constants import DiffAction, InfrahubKind, RelationshipCardinality |
5 | 6 | from infrahub.core.constants.database import DatabaseEdgeType |
6 | 7 | from infrahub.core.diff.calculator import DiffCalculator |
7 | 8 | from infrahub.core.diff.model.path import NodeFieldSpecifier |
@@ -2283,3 +2284,146 @@ async def test_property_update_then_relationship_deleted( |
2283 | 2284 |
|
2284 | 2285 | base_diff_root = calculated_diffs.base_branch_diff |
2285 | 2286 | assert base_diff_root.nodes == [] |
| 2287 | + |
| 2288 | + |
| 2289 | +async def test_hierarchy_with_same_kind_parent_and_child( |
| 2290 | + db: InfrahubDatabase, |
| 2291 | + default_branch: Branch, |
| 2292 | + register_core_models_schema: SchemaBranch, |
| 2293 | + register_ipam_schema: SchemaBranch, |
| 2294 | +): |
| 2295 | + prefix_schema = registry.schema.get_node_schema(name="IpamIPPrefix") |
| 2296 | + ip_namespace = await Node.init(db=db, schema=InfrahubKind.NAMESPACE) |
| 2297 | + await ip_namespace.new(db=db, name="ns1") |
| 2298 | + await ip_namespace.save(db=db) |
| 2299 | + top_node = await Node.init(db=db, schema=prefix_schema) |
| 2300 | + await top_node.new(db=db, prefix="10.0.0.0/7", ip_namespace=ip_namespace) |
| 2301 | + await top_node.save(db=db) |
| 2302 | + mid_node = await Node.init(db=db, schema=prefix_schema) |
| 2303 | + await mid_node.new(db=db, prefix="10.0.0.0/8", ip_namespace=ip_namespace) |
| 2304 | + await mid_node.save(db=db) |
| 2305 | + bottom_node = await Node.init(db=db, schema=prefix_schema) |
| 2306 | + await bottom_node.new(db=db, prefix="10.0.0.0/9", ip_namespace=ip_namespace) |
| 2307 | + await bottom_node.save(db=db) |
| 2308 | + branch = await create_branch(db=db, branch_name="branch2") |
| 2309 | + from_time = Timestamp() |
| 2310 | + mid_branch = await NodeManager.get_one(db=db, branch=branch, id=mid_node.id) |
| 2311 | + await mid_branch.parent.update(db=db, data=top_node.id) |
| 2312 | + await mid_branch.save(db=db) |
| 2313 | + bottom_branch = await NodeManager.get_one(db=db, branch=branch, id=bottom_node.id) |
| 2314 | + await bottom_branch.parent.update(db=db, data=mid_node.id) |
| 2315 | + await bottom_branch.save(db=db) |
| 2316 | + |
| 2317 | + diff_calculator = DiffCalculator(db=db) |
| 2318 | + calculated_diffs = await diff_calculator.calculate_diff( |
| 2319 | + base_branch=default_branch, diff_branch=branch, from_time=from_time, to_time=Timestamp() |
| 2320 | + ) |
| 2321 | + |
| 2322 | + branch_root_path = calculated_diffs.diff_branch_diff |
| 2323 | + assert branch_root_path.branch == branch.name |
| 2324 | + nodes_by_id = {n.uuid: n for n in branch_root_path.nodes} |
| 2325 | + assert set(nodes_by_id.keys()) == {top_node.id, mid_node.id, bottom_node.id} |
| 2326 | + # top node |
| 2327 | + node_diff = nodes_by_id[top_node.id] |
| 2328 | + assert node_diff.action is DiffAction.UPDATED |
| 2329 | + assert len(node_diff.attributes) == 0 |
| 2330 | + rels_by_name = {r.name: r for r in node_diff.relationships} |
| 2331 | + assert set(rels_by_name.keys()) == {"children"} |
| 2332 | + children_rel = rels_by_name["children"] |
| 2333 | + assert children_rel.action is DiffAction.UPDATED |
| 2334 | + assert len(children_rel.relationships) == 1 |
| 2335 | + child_element = children_rel.relationships[0] |
| 2336 | + assert child_element.action is DiffAction.ADDED |
| 2337 | + assert child_element.peer_id == mid_node.id |
| 2338 | + properties_by_type = {p.property_type: p for p in child_element.properties} |
| 2339 | + assert set(properties_by_type.keys()) == { |
| 2340 | + DatabaseEdgeType.IS_RELATED, |
| 2341 | + DatabaseEdgeType.IS_PROTECTED, |
| 2342 | + DatabaseEdgeType.IS_VISIBLE, |
| 2343 | + } |
| 2344 | + for prop_type, new_value in ( |
| 2345 | + (DatabaseEdgeType.IS_RELATED, mid_node.id), |
| 2346 | + (DatabaseEdgeType.IS_PROTECTED, False), |
| 2347 | + (DatabaseEdgeType.IS_VISIBLE, True), |
| 2348 | + ): |
| 2349 | + diff_prop = properties_by_type[prop_type] |
| 2350 | + assert diff_prop.action is DiffAction.ADDED |
| 2351 | + assert diff_prop.previous_value is None |
| 2352 | + assert diff_prop.new_value == new_value |
| 2353 | + |
| 2354 | + # middle node |
| 2355 | + node_diff = nodes_by_id[mid_node.id] |
| 2356 | + assert node_diff.action is DiffAction.UPDATED |
| 2357 | + assert len(node_diff.attributes) == 0 |
| 2358 | + rels_by_name = {r.name: r for r in node_diff.relationships} |
| 2359 | + assert set(rels_by_name.keys()) == {"parent", "children"} |
| 2360 | + parent_rel = rels_by_name["parent"] |
| 2361 | + assert parent_rel.action is DiffAction.ADDED |
| 2362 | + assert len(parent_rel.relationships) == 1 |
| 2363 | + parent_element = parent_rel.relationships[0] |
| 2364 | + assert parent_element.action is DiffAction.ADDED |
| 2365 | + assert parent_element.peer_id == top_node.id |
| 2366 | + properties_by_type = {p.property_type: p for p in parent_element.properties} |
| 2367 | + assert set(properties_by_type.keys()) == { |
| 2368 | + DatabaseEdgeType.IS_RELATED, |
| 2369 | + DatabaseEdgeType.IS_PROTECTED, |
| 2370 | + DatabaseEdgeType.IS_VISIBLE, |
| 2371 | + } |
| 2372 | + for prop_type, new_value in ( |
| 2373 | + (DatabaseEdgeType.IS_RELATED, top_node.id), |
| 2374 | + (DatabaseEdgeType.IS_PROTECTED, False), |
| 2375 | + (DatabaseEdgeType.IS_VISIBLE, True), |
| 2376 | + ): |
| 2377 | + diff_prop = properties_by_type[prop_type] |
| 2378 | + assert diff_prop.action is DiffAction.ADDED |
| 2379 | + assert diff_prop.previous_value is None |
| 2380 | + assert diff_prop.new_value == new_value |
| 2381 | + children_rel = rels_by_name["children"] |
| 2382 | + assert children_rel.action is DiffAction.UPDATED |
| 2383 | + assert len(children_rel.relationships) == 1 |
| 2384 | + child_element = children_rel.relationships[0] |
| 2385 | + assert child_element.action is DiffAction.ADDED |
| 2386 | + assert child_element.peer_id == bottom_node.id |
| 2387 | + properties_by_type = {p.property_type: p for p in child_element.properties} |
| 2388 | + assert set(properties_by_type.keys()) == { |
| 2389 | + DatabaseEdgeType.IS_RELATED, |
| 2390 | + DatabaseEdgeType.IS_PROTECTED, |
| 2391 | + DatabaseEdgeType.IS_VISIBLE, |
| 2392 | + } |
| 2393 | + for prop_type, new_value in ( |
| 2394 | + (DatabaseEdgeType.IS_RELATED, bottom_node.id), |
| 2395 | + (DatabaseEdgeType.IS_PROTECTED, False), |
| 2396 | + (DatabaseEdgeType.IS_VISIBLE, True), |
| 2397 | + ): |
| 2398 | + diff_prop = properties_by_type[prop_type] |
| 2399 | + assert diff_prop.action is DiffAction.ADDED |
| 2400 | + assert diff_prop.previous_value is None |
| 2401 | + assert diff_prop.new_value == new_value |
| 2402 | + |
| 2403 | + # bottom node |
| 2404 | + node_diff = nodes_by_id[bottom_node.id] |
| 2405 | + assert node_diff.action is DiffAction.UPDATED |
| 2406 | + assert len(node_diff.attributes) == 0 |
| 2407 | + rels_by_name = {r.name: r for r in node_diff.relationships} |
| 2408 | + assert set(rels_by_name.keys()) == {"parent"} |
| 2409 | + parent_rel = rels_by_name["parent"] |
| 2410 | + assert parent_rel.action is DiffAction.ADDED |
| 2411 | + assert len(parent_rel.relationships) == 1 |
| 2412 | + parent_element = parent_rel.relationships[0] |
| 2413 | + assert parent_element.action is DiffAction.ADDED |
| 2414 | + assert parent_element.peer_id == mid_node.id |
| 2415 | + properties_by_type = {p.property_type: p for p in parent_element.properties} |
| 2416 | + assert set(properties_by_type.keys()) == { |
| 2417 | + DatabaseEdgeType.IS_RELATED, |
| 2418 | + DatabaseEdgeType.IS_PROTECTED, |
| 2419 | + DatabaseEdgeType.IS_VISIBLE, |
| 2420 | + } |
| 2421 | + for prop_type, new_value in ( |
| 2422 | + (DatabaseEdgeType.IS_RELATED, mid_node.id), |
| 2423 | + (DatabaseEdgeType.IS_PROTECTED, False), |
| 2424 | + (DatabaseEdgeType.IS_VISIBLE, True), |
| 2425 | + ): |
| 2426 | + diff_prop = properties_by_type[prop_type] |
| 2427 | + assert diff_prop.action is DiffAction.ADDED |
| 2428 | + assert diff_prop.previous_value is None |
| 2429 | + assert diff_prop.new_value == new_value |
0 commit comments