Skip to content

Commit 3790c4c

Browse files
committed
Add generator correctness and end-to-end tests
1 parent 2dd69cf commit 3790c4c

2 files changed

Lines changed: 138 additions & 0 deletions

File tree

htsim/README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,12 @@ The SlimFly generator script is adapted from the SPCL topology-generation toolin
154154

155155
Note: topology generation scripts require Python packages `networkx` and `sympy`.
156156

157+
Quick generator validation (small checks + end-to-end SOURCE runs for Dragonfly and SlimFly):
158+
159+
```bash
160+
bash tests/run_generator_tests.sh
161+
```
162+
157163
### Traffic Matrix Format
158164

159165
All topologies use the same traffic matrix format:

tests/run_generator_tests.sh

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
#!/usr/bin/env bash
2+
set -euo pipefail
3+
4+
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
5+
DF_GEN="$ROOT_DIR/htsim/sim/datacenter/topologies/dragonfly/generate_dragonfly_assets.py"
6+
SF_GEN="$ROOT_DIR/htsim/sim/datacenter/topologies/slimfly/generate_slimfly_assets.py"
7+
DF_BIN="$ROOT_DIR/htsim/sim/datacenter/htsim_uec_df"
8+
SF_BIN="$ROOT_DIR/htsim/sim/datacenter/htsim_uec_sf"
9+
10+
REF_DF="$ROOT_DIR/htsim/sim/datacenter/topologies/dragonfly/p2a4h2"
11+
12+
PASS=0
13+
FAIL=0
14+
15+
fail() {
16+
echo "FAIL: $1"
17+
FAIL=$((FAIL + 1))
18+
}
19+
20+
pass() {
21+
echo "PASS: $1"
22+
PASS=$((PASS + 1))
23+
}
24+
25+
require_file() {
26+
local path="$1"
27+
local msg="$2"
28+
if [[ -f "$path" ]]; then
29+
pass "$msg"
30+
else
31+
fail "$msg (missing: $path)"
32+
fi
33+
}
34+
35+
require_dir() {
36+
local path="$1"
37+
local msg="$2"
38+
if [[ -d "$path" ]]; then
39+
pass "$msg"
40+
else
41+
fail "$msg (missing: $path)"
42+
fi
43+
}
44+
45+
echo "=== Generator tests (small + end-to-end) ==="
46+
47+
if ! python3 -c "import networkx, sympy" >/dev/null 2>&1; then
48+
echo "ERROR: missing Python dependencies. Install with: pip install networkx sympy"
49+
exit 1
50+
fi
51+
52+
if [[ ! -x "$DF_BIN" || ! -x "$SF_BIN" ]]; then
53+
echo "ERROR: missing simulator binaries. Build HTSIM first (cmake --build ...)."
54+
exit 1
55+
fi
56+
57+
TMP_DIR="$(mktemp -d)"
58+
trap 'rm -rf "$TMP_DIR"' EXIT
59+
60+
echo "Using temp directory: $TMP_DIR"
61+
62+
DF_OUT="$TMP_DIR/dragonfly_p2a1h1"
63+
DF_LOG="$TMP_DIR/dragonfly_compare.log"
64+
python3 "$DF_GEN" -p 2 -a 1 -H 1 --out "$DF_OUT" >/dev/null
65+
66+
require_file "$DF_OUT/dragonfly.topo" "Dragonfly generator writes dragonfly.topo"
67+
require_file "$DF_OUT/dragonfly.adjlist" "Dragonfly generator writes dragonfly.adjlist"
68+
require_dir "$DF_OUT/host_table" "Dragonfly generator writes host_table directory"
69+
require_file "$DF_OUT/host_table/0.lt" "Dragonfly host table includes switch 0"
70+
require_file "$DF_OUT/host_table/1.lt" "Dragonfly host table includes switch 1"
71+
72+
if [[ -d "$REF_DF/host_table" ]]; then
73+
python3 "$DF_GEN" -p 2 -a 4 -H 2 --out "$TMP_DIR/dragonfly_p2a4h2" --compare-ref "$REF_DF" >"$DF_LOG"
74+
fi
75+
76+
if [[ ! -d "$REF_DF/host_table" ]]; then
77+
pass "Dragonfly compare-ref skipped (no host_table in $REF_DF)"
78+
elif grep -q "generated pairs subset of reference: yes" "$DF_LOG" && grep -q "average generated-pair coverage in reference: 1.000" "$DF_LOG"; then
79+
pass "Dragonfly generator matches reference host-table coverage"
80+
else
81+
fail "Dragonfly compare-ref coverage check"
82+
fi
83+
84+
cat >"$TMP_DIR/df_1flow.tm" <<'EOF'
85+
Nodes 4
86+
Connections 1
87+
0->3 start 0 size 4096
88+
EOF
89+
90+
"$DF_BIN" -basepath "$DF_OUT" -routing SOURCE -tm "$TMP_DIR/df_1flow.tm" >"$TMP_DIR/df_run.out" 2>&1 || true
91+
if grep -q "Done" "$TMP_DIR/df_run.out" && [[ "$(grep -c 'finished at' "$TMP_DIR/df_run.out")" -eq 1 ]]; then
92+
pass "Dragonfly SOURCE end-to-end run succeeds with generated assets"
93+
else
94+
fail "Dragonfly SOURCE end-to-end run"
95+
fi
96+
97+
SF_OUT="$TMP_DIR/slimfly_p2q3"
98+
python3 "$SF_GEN" -p 2 -q 3 --out "$SF_OUT" -n 1 >/dev/null
99+
100+
require_file "$SF_OUT/slimfly.topo" "SlimFly generator writes slimfly.topo"
101+
require_file "$SF_OUT/slimfly.adjlist" "SlimFly generator writes slimfly.adjlist"
102+
require_dir "$SF_OUT/fib" "SlimFly generator writes fib directory"
103+
require_dir "$SF_OUT/host_table" "SlimFly generator writes host_table directory"
104+
105+
FIB_COUNT="$(ls "$SF_OUT"/fib/*.fib 2>/dev/null | wc -l | tr -d ' ')"
106+
HT_COUNT="$(ls "$SF_OUT"/host_table/*.lt 2>/dev/null | wc -l | tr -d ' ')"
107+
if [[ "$FIB_COUNT" -eq 18 && "$HT_COUNT" -eq 18 ]]; then
108+
pass "SlimFly generator writes expected fib/host_table file counts for q=3"
109+
else
110+
fail "SlimFly output counts (fib=$FIB_COUNT host_table=$HT_COUNT, expected 18/18)"
111+
fi
112+
113+
cat >"$TMP_DIR/sf_1flow.tm" <<'EOF'
114+
Nodes 36
115+
Connections 1
116+
0->35 start 0 size 4096
117+
EOF
118+
119+
"$SF_BIN" -topo "$SF_OUT" -routing SOURCE -tm "$TMP_DIR/sf_1flow.tm" >"$TMP_DIR/sf_run.out" 2>&1 || true
120+
if grep -q "Done" "$TMP_DIR/sf_run.out" && [[ "$(grep -c 'finished at' "$TMP_DIR/sf_run.out")" -eq 1 ]]; then
121+
pass "SlimFly SOURCE end-to-end run succeeds with generated assets"
122+
else
123+
fail "SlimFly SOURCE end-to-end run"
124+
fi
125+
126+
echo "========================================="
127+
echo "Generator tests: PASS=$PASS FAIL=$FAIL"
128+
echo "========================================="
129+
130+
if [[ "$FAIL" -gt 0 ]]; then
131+
exit 1
132+
fi

0 commit comments

Comments
 (0)