11#! /bin/bash
22
3- # Echo Protocol Interoperability Tests
4- # Uses the existing test-plans framework
5-
3+ # run in strict failure mode
64set -euo pipefail
75
8- SCRIPT_DIR=" $( cd " $( dirname " ${BASH_SOURCE[0]} " ) " && pwd) "
9- ROOT_DIR=" $( cd " ${SCRIPT_DIR} /.." && pwd) "
6+ # ╔═══╗ ╔═══╗ ╔╗ ╔╗ ╔═══╗
7+ # ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ ║╔══╝ ║╔═╗║ ║║ ║║ ║╔═╗║ ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁
8+ # ═══════════════════════════════ ║╚══╗ ║║ ║║ ║╚══╝║ ║║ ║║ ═════════════════════════════════
9+ # ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ ╚═══╝ ╚╝ ╚╝ ╚════╝ ╚╝ ╚╝ ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
10+
11+ # =============================================================================
12+ # STEP 1: BOOTSTRAP: Load inputs.yaml BEFORE setting SCRIPT_LIB_DIR
13+ # -----------------------------------------------------------------------------
14+ # This allows for the re-creation of the environment and command line arguments
15+ # from a previous test run. If the inputs.yaml file doesn't exist, then this
16+ # script will run from a default environment. Any command line arguments passed
17+ # will override any command line arguments loaded from inputs.yaml, however the
18+ # environment variables in inputs.yaml will override the ones initialized in
19+ # the shell executing this script.
20+ # =============================================================================
21+
22+ # Capture original arguments for inputs.yaml generation
23+ ORIGINAL_ARGS=(" $@ " )
24+
25+ # Change to script directory
26+ cd " $( dirname " $0 " ) "
27+
28+ # Loads and exports the environment variables from the inputs yaml file
29+ load_inputs_yaml_inline () {
30+ local inputs_file=" ${1:- inputs.yaml} "
31+
32+ # Look for the inputs file if it exists
33+ if [ ! -f " ${inputs_file} " ]; then
34+ return 1
35+ fi
36+
37+ echo " → Loading configuration from ${inputs_file} "
38+
39+ # Load and export the environment variables from the inputs file
40+ while IFS=' =' read -r key value; do
41+ if [ -n " ${key} " ] && [ -n " ${value} " ]; then
42+ export " ${key} " =" ${value} "
43+ fi
44+ done < <( yq eval ' .environmentVariables | to_entries | .[] | .key + "=" + .value' " ${inputs_file} " 2> /dev/null)
45+
46+ return 0
47+ }
48+
49+ # Loads the command line arguments from the inputs yaml file
50+ load_inputs_yaml_args_inline () {
51+ local inputs_file=" ${1:- inputs.yaml} "
52+
53+ # Look for the inputs file if it exists
54+ if [ ! -f " ${inputs_file} " ]; then
55+ return 1
56+ fi
57+
58+ # Load the command line arguments from the inputs file
59+ readarray -t LOADED_ARGS < <( yq eval ' .commandLineArguments[]' " ${inputs_file} " 2> /dev/null)
60+
61+ return 0
62+ }
63+
64+ # Try to load inputs.yaml if it exists
65+ LOADED_ARGS=()
66+ if load_inputs_yaml_inline " inputs.yaml" ; then
67+ load_inputs_yaml_args_inline " inputs.yaml"
68+ fi
69+
70+ # =============================================================================
71+ # STEP 2: ENVIRONMENT SETUP
72+ # =============================================================================
73+
74+ # Set up paths
75+ export TEST_ROOT=" $( pwd) "
76+ export SCRIPT_LIB_DIR=" ${TEST_ROOT} /../lib"
77+ export CACHE_DIR=" ${CACHE_DIR:-/ srv/ cache} "
78+ export IMAGES_YAML=" ${TEST_ROOT} /images.yaml"
79+
80+ # Test configuration
81+ export TEST_TYPE=" echo"
82+ export WORKERS=" ${WORKERS:- $(nproc)} "
83+ export DEBUG=" ${DEBUG:- false} "
84+
85+ # Filter configuration
86+ export IMPL_SELECT=" ${IMPL_SELECT:- } "
87+ export IMPL_IGNORE=" ${IMPL_IGNORE:- } "
88+ export TRANSPORT_SELECT=" ${TRANSPORT_SELECT:- } "
89+ export TRANSPORT_IGNORE=" ${TRANSPORT_IGNORE:- } "
90+ export SECURE_SELECT=" ${SECURE_SELECT:- } "
91+ export SECURE_IGNORE=" ${SECURE_IGNORE:- } "
92+ export MUXER_SELECT=" ${MUXER_SELECT:- } "
93+ export MUXER_IGNORE=" ${MUXER_IGNORE:- } "
94+ export TEST_SELECT=" ${TEST_SELECT:- } "
95+ export TEST_IGNORE=" ${TEST_IGNORE:- } "
96+
97+ # =============================================================================
98+ # STEP 3: ARGUMENT PARSING
99+ # =============================================================================
100+
101+ # Merge loaded args with command line args (command line takes precedence)
102+ ALL_ARGS=(" ${LOADED_ARGS[@]} " " $@ " )
103+
104+ # Parse arguments
105+ while [[ $# -gt 0 ]]; do
106+ case $1 in
107+ --impl-select)
108+ IMPL_SELECT=" $2 "
109+ shift 2
110+ ;;
111+ --impl-ignore)
112+ IMPL_IGNORE=" $2 "
113+ shift 2
114+ ;;
115+ --transport-select)
116+ TRANSPORT_SELECT=" $2 "
117+ shift 2
118+ ;;
119+ --transport-ignore)
120+ TRANSPORT_IGNORE=" $2 "
121+ shift 2
122+ ;;
123+ --secure-select)
124+ SECURE_SELECT=" $2 "
125+ shift 2
126+ ;;
127+ --secure-ignore)
128+ SECURE_IGNORE=" $2 "
129+ shift 2
130+ ;;
131+ --muxer-select)
132+ MUXER_SELECT=" $2 "
133+ shift 2
134+ ;;
135+ --muxer-ignore)
136+ MUXER_IGNORE=" $2 "
137+ shift 2
138+ ;;
139+ --test-select)
140+ TEST_SELECT=" $2 "
141+ shift 2
142+ ;;
143+ --test-ignore)
144+ TEST_IGNORE=" $2 "
145+ shift 2
146+ ;;
147+ --workers)
148+ WORKERS=" $2 "
149+ shift 2
150+ ;;
151+ --debug)
152+ DEBUG=" true"
153+ shift
154+ ;;
155+ --check-deps)
156+ exec " ${SCRIPT_LIB_DIR} /check-dependencies.sh"
157+ ;;
158+ --help|-h)
159+ echo " Echo Protocol Interoperability Tests"
160+ echo " "
161+ echo " Usage: $0 [options]"
162+ echo " "
163+ echo " Filtering Options:"
164+ echo " --impl-select FILTER Select implementations (e.g., 'js-libp2p')"
165+ echo " --impl-ignore FILTER Ignore implementations (e.g., '!py-libp2p')"
166+ echo " --transport-select FILTER Select transports (e.g., 'tcp')"
167+ echo " --transport-ignore FILTER Ignore transports"
168+ echo " --secure-select FILTER Select secure channels (e.g., 'noise')"
169+ echo " --secure-ignore FILTER Ignore secure channels"
170+ echo " --muxer-select FILTER Select muxers (e.g., 'yamux')"
171+ echo " --muxer-ignore FILTER Ignore muxers"
172+ echo " --test-select FILTER Select specific tests"
173+ echo " --test-ignore FILTER Ignore specific tests"
174+ echo " "
175+ echo " Execution Options:"
176+ echo " --workers N Number of parallel workers (default: $( nproc) )"
177+ echo " --debug Enable debug output"
178+ echo " "
179+ echo " Utility Options:"
180+ echo " --check-deps Check system dependencies"
181+ echo " --help, -h Show this help"
182+ echo " "
183+ echo " Examples:"
184+ echo " $0 # Run all tests"
185+ echo " $0 --impl-select js-libp2p # Test only js-libp2p"
186+ echo " $0 --transport-ignore '!tcp' # Test only TCP transport"
187+ echo " $0 --debug --workers 1 # Debug mode, single worker"
188+ exit 0
189+ ;;
190+ * )
191+ echo " Unknown option: $1 " >&2
192+ echo " Use --help for usage information" >&2
193+ exit 1
194+ ;;
195+ esac
196+ done
197+
198+ # =============================================================================
199+ # STEP 4: DEPENDENCY CHECKS
200+ # =============================================================================
201+
202+ # Source common libraries
203+ source " ${SCRIPT_LIB_DIR} /lib-common-init.sh"
204+ source " ${SCRIPT_LIB_DIR} /lib-output-formatting.sh"
205+
206+ # Check dependencies
207+ " ${SCRIPT_LIB_DIR} /check-dependencies.sh" || exit 1
208+
209+ # =============================================================================
210+ # STEP 5: GENERATE INPUTS.YAML
211+ # =============================================================================
212+
213+ source " ${SCRIPT_LIB_DIR} /lib-inputs-yaml.sh"
214+ generate_inputs_yaml " ${TEST_ROOT} /inputs.yaml" " ${TEST_TYPE} " " ${ORIGINAL_ARGS[@]} "
215+
216+ # =============================================================================
217+ # STEP 6: GENERATE TEST MATRIX
218+ # =============================================================================
219+
220+ print_message " Generating Echo protocol test matrix..."
221+ " ${TEST_ROOT} /lib/generate-tests.sh"
222+
223+ # =============================================================================
224+ # STEP 7: BUILD IMAGES
225+ # =============================================================================
226+
227+ print_message " Building Docker images..."
228+ source " ${SCRIPT_LIB_DIR} /lib-image-building.sh"
229+ build_all_images
230+
231+ # =============================================================================
232+ # STEP 8: GENERATE DOCKER COMPOSE FILES
233+ # =============================================================================
234+
235+ print_message " Generating Docker Compose files..."
236+ source " ${SCRIPT_LIB_DIR} /lib-test-caching.sh"
237+
238+ CACHE_KEY=$( compute_test_cache_key)
239+ TEST_MATRIX_FILE=" ${CACHE_DIR} /test-matrix/echo-${CACHE_KEY} .yaml"
240+
241+ # Generate compose files for each test
242+ while IFS= read -r test_name; do
243+ COMPOSE_FILE=" ${CACHE_DIR} /test-docker-compose/echo-${CACHE_KEY} -${test_name} .yaml"
244+ mkdir -p " $( dirname " ${COMPOSE_FILE} " ) "
245+
246+ # Generate basic compose file (simplified for echo tests)
247+ cat > " ${COMPOSE_FILE} " << EOF
248+ version: '3.8'
249+ services:
250+ redis:
251+ image: redis:alpine
252+ networks:
253+ - echo-test
254+
255+ server:
256+ image: \$ {SERVER_IMAGE}
257+ depends_on:
258+ - redis
259+ environment:
260+ - REDIS_ADDR=redis://redis:6379
261+ networks:
262+ - echo-test
263+
264+ client:
265+ image: \$ {CLIENT_IMAGE}
266+ depends_on:
267+ - server
268+ environment:
269+ - REDIS_ADDR=redis://redis:6379
270+ networks:
271+ - echo-test
272+
273+ networks:
274+ echo-test:
275+ driver: bridge
276+ EOF
277+ done < <( yq eval ' .tests[].name' " ${TEST_MATRIX_FILE} " )
278+
279+ # =============================================================================
280+ # STEP 9: RUN TESTS
281+ # =============================================================================
282+
283+ print_message " Running Echo protocol tests..."
284+
285+ # Create results directory
286+ RESULTS_DIR=" ${TEST_ROOT} /results"
287+ mkdir -p " ${RESULTS_DIR} "
288+
289+ # Run tests in parallel
290+ export -f run_single_test
291+ readarray -t test_names < <( yq eval ' .tests[].name' " ${TEST_MATRIX_FILE} " )
292+
293+ if [[ " ${WORKERS} " -eq 1 ]] || [[ " ${DEBUG} " == " true" ]]; then
294+ # Sequential execution for debugging
295+ for test_name in " ${test_names[@]} " ; do
296+ run_single_test " ${test_name} "
297+ done
298+ else
299+ # Parallel execution
300+ printf ' %s\n' " ${test_names[@]} " | xargs -P " ${WORKERS} " -I {} bash -c ' run_single_test "$@"' _ {}
301+ fi
302+
303+ # =============================================================================
304+ # STEP 10: GENERATE DASHBOARD
305+ # =============================================================================
306+
307+ print_message " Generating test dashboard..."
308+ " ${TEST_ROOT} /lib/generate-dashboard.sh" " ${RESULTS_DIR} "
309+
310+ # =============================================================================
311+ # STEP 11: SUMMARY
312+ # =============================================================================
313+
314+ TOTAL_TESTS=$( find " ${RESULTS_DIR} " -name " *.json" | wc -l)
315+ PASSED_TESTS=$( find " ${RESULTS_DIR} " -name " *.json" -exec grep -l ' "result": "PASS"' {} \; | wc -l)
316+ FAILED_TESTS=$(( TOTAL_TESTS - PASSED_TESTS))
317+
318+ print_message " Echo Protocol Test Results:"
319+ print_message " Total: ${TOTAL_TESTS} "
320+ print_message " Passed: ${PASSED_TESTS} "
321+ print_message " Failed: ${FAILED_TESTS} "
322+
323+ if [[ " ${FAILED_TESTS} " -gt 0 ]]; then
324+ print_message " ❌ Some tests failed - check ${RESULTS_DIR} /echo-dashboard.html"
325+ exit 1
326+ else
327+ print_message " ✅ All tests passed!"
328+ exit 0
329+ fi
10330
11- # Source the test-plans library functions
12- source " ${ROOT_DIR} /lib/lib-common-init.sh "
13- source " ${ROOT_DIR} /lib/lib-test-execution.sh "
331+ # =============================================================================
332+ # HELPER FUNCTIONS
333+ # =============================================================================
14334
15- # Run echo protocol tests using existing framework
16- exec " ${ROOT_DIR} /lib/lib-test-execution.sh" \
17- --test-dir " ${SCRIPT_DIR} " \
18- --images-file " ${SCRIPT_DIR} /images.yaml" \
19- " $@ "
335+ run_single_test () {
336+ local test_name=" $1 "
337+ " ${TEST_ROOT} /lib/run-single-test.sh" " ${test_name} " > " ${RESULTS_DIR} /${test_name} .json"
338+ }
0 commit comments