@@ -10,6 +10,9 @@ ORIG_PATH="$PATH"
1010PASS_COUNT=0
1111FAIL_COUNT=0
1212
13+ # Start time of whole suite for total duration measurement
14+ SUITE_START_NS=$( date +%s%N)
15+
1316# Capture detailed results for JSON export
1417declare -a TEST_NAMES=()
1518declare -a TEST_STATUSES=()
8689set -euo pipefail
8790log_dir="${SHIELDX_STUB_LOG_DIR:?}"
8891mkdir -p "$log_dir"
89- printf '%s\n' "curl $*" >>"$log_dir/curl.log"
92+ start_ns=$(date +%s%N)
9093url=""
91- for arg in "$@"; do
92- if [[ "$arg " == http://* || "$arg " == https://* ]]; then
93- url="$arg "
94+ for a in "$@"; do
95+ if [[ "$a " == http://* || "$a " == https://* ]]; then
96+ url="$a "
9497 fi
9598done
9699pattern="${SHIELDX_CURL_FAIL_PATTERN:-}"
100+ should_fail=0
97101if [[ -n "$pattern" && -n "$url" && "$url" == *"$pattern"* ]]; then
98- if [[ "${SHIELDX_CURL_FAIL_ALWAYS:-0}" != "0" ]]; then
99- exit "${SHIELDX_CURL_EXIT_CODE:-56}"
100- fi
101- limit="${SHIELDX_CURL_FAIL_UNTIL:-0}"
102- state_file="$log_dir/curl-fail-count"
103- count=0
104- if [[ -f "$state_file" ]]; then
105- read -r count <"$state_file"
102+ if [[ "${SHIELDX_CURL_FAIL_ALWAYS:-0}" == "1" ]]; then
103+ should_fail=1
104+ else
105+ limit="${SHIELDX_CURL_FAIL_UNTIL:-0}"
106+ state_file="$log_dir/curl-fail-count"
107+ count=0
108+ [[ -f "$state_file" ]] && read -r count <"$state_file"
109+ if (( count < limit )); then
110+ echo $((count+1)) >"$state_file"
111+ should_fail=1
112+ fi
106113 fi
107- if (( count < limit )); then
108- echo $((count + 1)) >"$state_file"
109- exit "${SHIELDX_CURL_EXIT_CODE:-56}"
114+ fi
115+ exit_code=0
116+ curl_extra=""
117+ if [[ "${SHIELDX_REAL_CURL:-0}" == "1" ]]; then
118+ if (( should_fail )); then
119+ exit_code="${SHIELDX_CURL_EXIT_CODE:-56}"
120+ else
121+ # Use real curl for timing; ignore body
122+ if command -v /usr/bin/curl >/dev/null 2>&1; then
123+ curl_extra=$(/usr/bin/curl -o /dev/null -s -w ' time_total=%{time_total}' "$@" 2>/dev/null || true)
124+ test ${PIPESTATUS[0]} -ne 0 && exit_code=${SHIELDX_CURL_EXIT_CODE:-56}
125+ fi
110126 fi
127+ else
128+ (( should_fail )) && exit_code="${SHIELDX_CURL_EXIT_CODE:-56}" || true
111129fi
112- exit 0
130+ end_ns=$(date +%s%N)
131+ duration_ms=$(( (end_ns - start_ns)/1000000 ))
132+ printf 'curl %s duration_ms=%s exit_code=%s%s\n' "$*" "$duration_ms" "$exit_code" "$curl_extra" >>"$log_dir/curl.log"
133+ exit "$exit_code"
113134EOF
114135 chmod +x " $fixture /stubs/curl"
115136
@@ -328,21 +349,55 @@ test_quick_runtime_with_skip() {
328349}
329350
330351write_results_json () {
331- local out tmp
332- tmp=" ${RESULT_JSON_PATH} .tmp"
352+ local tmp=" ${RESULT_JSON_PATH} .tmp"
353+ local suite_end_ns suite_ms
354+ suite_end_ns=$( date +%s%N)
355+ suite_ms=$(( (suite_end_ns - SUITE_START_NS)/ 1000000 ))
356+
357+ # Collect API call logs from fixtures
358+ local api_entries=()
359+ for p in " ${CLEANUP_PATHS[@]} " ; do
360+ if [[ -f " $p /.state/curl.log" ]]; then
361+ while IFS= read -r line; do
362+ local dur ec url time_total
363+ dur=$( grep -oE ' duration_ms=[0-9]+' <<< " $line" | cut -d= -f2 || echo 0)
364+ ec=$( grep -oE ' exit_code=[0-9]+' <<< " $line" | cut -d= -f2 || echo 0)
365+ url=$( grep -oE ' (http|https)://[^ ]+' <<< " $line" | tail -1 || echo ' ' )
366+ time_total=$( grep -oE ' time_total=[0-9. ]+' <<< " $line" | cut -d= -f2 | xargs || true)
367+ if [[ -n " $url " ]]; then
368+ local obj=" {\" url\" :\" $url \" , \" duration_ms\" :$dur , \" exit_code\" :$ec "
369+ if [[ -n " $time_total " ]]; then
370+ obj+=" ,\" time_total_s\" :$time_total "
371+ fi
372+ obj+=" }"
373+ api_entries+=(" $obj " )
374+ fi
375+ done < " $p /.state/curl.log"
376+ fi
377+ done
378+
333379 {
334380 echo ' {'
335381 echo ' "summary": {'
336382 echo " \" passed\" : $PASS_COUNT ,"
337383 echo " \" failed\" : $FAIL_COUNT ,"
338- echo " \" total\" : $(( PASS_COUNT+ FAIL_COUNT)) "
384+ echo " \" total\" : $(( PASS_COUNT+ FAIL_COUNT)) ,"
385+ echo " \" suite_duration_ms\" : $suite_ms ,"
386+ echo " \" generated_at\" : \" $( date -u +%Y-%m-%dT%H:%M:%SZ) \" "
339387 echo ' },'
340388 echo ' "tests": ['
341389 local i last=$(( ${# TEST_NAMES[@]} - 1 ))
342390 for i in " ${! TEST_NAMES[@]} " ; do
343391 printf ' {"name": %q, "status": %q, "duration_ms": %s}' " ${TEST_NAMES[$i]} " " ${TEST_STATUSES[$i]} " " ${TEST_DURATIONS_MS[$i]} "
344392 if (( i < last )) ; then echo ' ,' ; else echo ; fi
345393 done
394+ echo ' ],'
395+ echo ' "api_calls": ['
396+ local j last2=$(( ${# api_entries[@]} - 1 ))
397+ for j in " ${! api_entries[@]} " ; do
398+ printf ' %s' " ${api_entries[$j]} "
399+ if (( j < last2 )) ; then echo ' ,' ; else echo ; fi
400+ done
346401 echo ' ]'
347402 echo ' }'
348403 } > " $tmp "
0 commit comments