Skip to content

Commit d239d49

Browse files
committed
expanding tests with another scenario
1 parent 9220b7c commit d239d49

File tree

6 files changed

+142
-7
lines changed

6 files changed

+142
-7
lines changed

ngraph/network.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ class Link:
6666

6767
def __post_init__(self) -> None:
6868
"""Auto-generates a unique link ID by combining the source, target, and a random Base64-encoded UUID."""
69-
self.id = f"{self.source}-{self.target}-{new_base64_uuid()}"
69+
self.id = f"{self.source}|{self.target}|{new_base64_uuid()}"
7070

7171

7272
@dataclass(slots=True)

tests/scenarios/scenario_3.yaml

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
blueprints:
2+
brick_2tier:
3+
groups:
4+
t1:
5+
node_count: 4
6+
name_template: t1-{node_num}
7+
t2:
8+
node_count: 4
9+
name_template: t2-{node_num}
10+
11+
adjacency:
12+
- source: /t1
13+
target: /t2
14+
pattern: mesh
15+
link_params:
16+
capacity: 1
17+
cost: 1
18+
19+
3tier_clos:
20+
groups:
21+
b1:
22+
use_blueprint: brick_2tier
23+
b2:
24+
use_blueprint: brick_2tier
25+
spine:
26+
node_count: 16
27+
name_template: t3-{node_num}
28+
29+
adjacency:
30+
- source: b1/t2
31+
target: spine
32+
pattern: one_to_one
33+
link_params:
34+
capacity: 1
35+
cost: 1
36+
- source: b2/t2
37+
target: spine
38+
pattern: one_to_one
39+
link_params:
40+
capacity: 1
41+
cost: 1
42+
network:
43+
name: "3tier_clos_network"
44+
version: 1.0
45+
46+
groups:
47+
my_clos1:
48+
use_blueprint: 3tier_clos
49+
50+
my_clos2:
51+
use_blueprint: 3tier_clos
52+
53+
adjacency:
54+
- source: my_clos1/spine
55+
target: my_clos2/spine
56+
pattern: one_to_one
57+
link_params:
58+
capacity: 1
59+
cost: 1
60+
61+
62+
workflow:
63+
- step_type: BuildGraph
64+
name: build_graph

tests/scenarios/test_scenario_1.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
def test_scenario_1_build_graph() -> None:
1010
"""
1111
Integration test that verifies we can parse scenario_1.yaml,
12-
run the BuildGraph step, and produce a valid NetworkX MultiDiGraph.
12+
run the BuildGraph step, and produce a valid StrictMultiDiGraph.
1313
Checks:
1414
- The expected number of nodes and links are correctly parsed.
1515
- The traffic demands are loaded.

tests/scenarios/test_scenario_2.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
def test_scenario_2_build_graph() -> None:
1010
"""
1111
Integration test that verifies we can parse scenario_2.yaml,
12-
run the BuildGraph step, and produce a valid NetworkX MultiDiGraph.
12+
run the BuildGraph step, and produce a valid StrictMultiDiGraph.
1313
1414
Checks:
1515
- The expected number of expanded nodes and links (including blueprint subgroups).

tests/scenarios/test_scenario_3.py

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
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."

tests/test_network.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -55,9 +55,9 @@ def test_link_defaults_and_id_generation():
5555
assert link.cost == 1.0
5656
assert link.attrs == {}
5757

58-
# ID should start with 'A-B-' and have a random suffix
59-
assert link.id.startswith("A-B-")
60-
assert len(link.id) > len("A-B-")
58+
# ID should start with 'A|B|' and have a random suffix
59+
assert link.id.startswith("A|B|")
60+
assert len(link.id) > len("A|B|")
6161

6262

6363
def test_link_custom_values():
@@ -73,7 +73,7 @@ def test_link_custom_values():
7373
assert link.capacity == 2.0
7474
assert link.cost == 4.0
7575
assert link.attrs == custom_attrs
76-
assert link.id.startswith("X-Y-")
76+
assert link.id.startswith("X|Y|")
7777

7878

7979
def test_link_id_uniqueness():

0 commit comments

Comments
 (0)