|
| 1 | +import pytest |
| 2 | +from pathlib import Path |
| 3 | + |
| 4 | +from ngraph.lib.graph import StrictMultiDiGraph |
| 5 | +from ngraph.scenario import Scenario |
| 6 | +from ngraph.failure_policy import FailurePolicy |
| 7 | + |
| 8 | + |
| 9 | +def test_scenario_3_build_graph() -> None: |
| 10 | + """ |
| 11 | + Integration test that verifies we can parse scenario_3.yaml, |
| 12 | + run the BuildGraph step, and produce a valid StrictMultiDiGraph. |
| 13 | +
|
| 14 | + Checks: |
| 15 | + - The expected number of expanded nodes and links (two interconnected 3-tier CLOS fabrics). |
| 16 | + - The presence of key expanded nodes. |
| 17 | + - The traffic demands are empty in this scenario. |
| 18 | + - The failure policy is empty by default. |
| 19 | + """ |
| 20 | + # 1) Load the YAML file |
| 21 | + scenario_path = Path(__file__).parent / "scenario_3.yaml" |
| 22 | + yaml_text = scenario_path.read_text() |
| 23 | + |
| 24 | + # 2) Parse into a Scenario object (this calls blueprint expansion) |
| 25 | + scenario = Scenario.from_yaml(yaml_text) |
| 26 | + |
| 27 | + # 3) Run the scenario's workflow (in this YAML, there's only "BuildGraph") |
| 28 | + scenario.run() |
| 29 | + |
| 30 | + # 4) Retrieve the graph built by BuildGraph |
| 31 | + graph = scenario.results.get("build_graph", "graph") |
| 32 | + assert isinstance( |
| 33 | + graph, StrictMultiDiGraph |
| 34 | + ), "Expected a StrictMultiDiGraph in scenario.results under key ('build_graph', 'graph')." |
| 35 | + |
| 36 | + # 5) Verify total node count |
| 37 | + # Each 3-tier CLOS instance has 32 nodes (2 sub-bricks of 8 nodes each + 16 spine), |
| 38 | + # so with 2 instances => 64 nodes total. |
| 39 | + expected_nodes = 64 |
| 40 | + actual_nodes = len(graph.nodes) |
| 41 | + assert ( |
| 42 | + actual_nodes == expected_nodes |
| 43 | + ), f"Expected {expected_nodes} nodes, found {actual_nodes}" |
| 44 | + |
| 45 | + # 6) Verify total physical links before direction is applied to Nx |
| 46 | + # Each 3-tier CLOS has 64 links internally. With 2 instances => 128 links, |
| 47 | + # plus 16 links connecting my_clos1/spine to my_clos2/spine (one_to_one). |
| 48 | + # => total physical links = 128 + 16 = 144 |
| 49 | + # => each link becomes 2 directed edges in MultiDiGraph => 288 edges |
| 50 | + expected_links = 144 |
| 51 | + expected_nx_edges = expected_links * 2 |
| 52 | + actual_edges = len(graph.edges) |
| 53 | + assert ( |
| 54 | + actual_edges == expected_nx_edges |
| 55 | + ), f"Expected {expected_nx_edges} directed edges, found {actual_edges}" |
| 56 | + |
| 57 | + # 7) Verify that there are no traffic demands in this scenario |
| 58 | + assert len(scenario.traffic_demands) == 0, "Expected zero traffic demands." |
| 59 | + |
| 60 | + # 8) Verify the default (empty) failure policy |
| 61 | + policy: FailurePolicy = scenario.failure_policy |
| 62 | + assert len(policy.rules) == 0, "Expected an empty failure policy." |
| 63 | + |
| 64 | + # 9) Check presence of a few key expanded nodes |
| 65 | + # For example: a t1 node in my_clos1/b1 and a spine node in my_clos2. |
| 66 | + assert ( |
| 67 | + "my_clos1/b1/t1/t1-1" in scenario.network.nodes |
| 68 | + ), "Missing expected node 'my_clos1/b1/t1/t1-1' in expanded blueprint." |
| 69 | + assert ( |
| 70 | + "my_clos2/spine/t3-16" in scenario.network.nodes |
| 71 | + ), "Missing expected spine node 'my_clos2/spine/t3-16' in expanded blueprint." |
0 commit comments