#!/usr/bin/env bash # Execute the immutable self-contained apphost through the cached Linux VSTest controller. set -euo pipefail umask 077 app=ZB.MOM.WW.OtOpcUa.OpcUaServer.IntegrationTests test_class="$app.Sdk2LifecycleSoakTests" mkdir -p /task/tmp /task/data /task/cli /task/results export TMPDIR=/task/tmp XDG_DATA_HOME=/task/data DOTNET_CLI_HOME=/task/cli export OTOPCUA_SDK2_SOAK=1 OTOPCUA_SDK2_SOAK_MODE=late-slope OTOPCUA_SDK2_SOAK_SECONDS=7200 export OTOPCUA_SDK2_SOAK_OUTPUT=/task/resources.jsonl OPCUA_CERTIFICATE_LEAK_TRACKING=1 export DOTNET_CLI_TELEMETRY_OPTOUT=1 DOTNET_NOLOGO=1 [[ $(uname -s) == Linux && $(uname -m) == aarch64 && -d /proc/self/fd ]] [[ ${OTOPCUA_SOAK_BUILD_SHA:-} =~ ^[0-9a-f]{40}$ ]] dotnet --info > /task/controller-runtime.txt dotnet vstest "/app/$app.dll" \ --TestCaseFilter:"FullyQualifiedName~$test_class.Descriptor_probe_" \ --ResultsDirectory:/task/results '--Logger:trx;LogFileName=descriptor-controls.trx' > /task/descriptor-controls.log 2>&1 # Verify actual execution before starting the long test. The host parses the complete TRX independently. controls=/task/results/descriptor-controls.trx counters=$(grep -E '^[[:space:]]*/dev/null || true; fi } trap cleanup EXIT dotnet vstest "/app/$app.dll" \ --TestCaseFilter:"FullyQualifiedName=$test_class.Repeated_lifecycles_return_resources_to_a_steady_baseline" \ --ResultsDirectory:/task/results '--Logger:trx;LogFileName=late-slope.trx' > /task/test.log 2>&1 & vstest_pid=$! # The canonical startup deadline is 120 seconds. Allow controller startup before observing its first complete row. proof_deadline=$((SECONDS + 150)) observed=0 while ((SECONDS < proof_deadline)) && kill -0 "$vstest_pid" 2>/dev/null; do if [[ -s /task/resources.jsonl ]] && IFS= read -r header < /task/resources.jsonl; then [[ $header == *'"kind":"start"'* && $header == *'"mode":"late-slope"'* ]] pid=$(sed -n 's/.*"processId":\([1-9][0-9]*\),.*/\1/p' <<< "$header") [[ $pid =~ ^[1-9][0-9]*$ ]] executable=$(readlink "/proc/$pid/exe") [[ $executable == "/app/$app" ]] runtime=$(awk '$6 ~ /\/libcoreclr.so$/ {print $6}' "/proc/$pid/maps" | sort -u) [[ $runtime == /app/libcoreclr.so ]] runtime_hash=$(sha256sum "$runtime") printf 'targetPid=%s\nactualExecutable=%s\nmappedCoreClr=%s\ncoreClrSha256=%s\n' \ "$pid" "$executable" "$runtime" "${runtime_hash%% *}" > /task/target-runtime.txt observed=1 break fi sleep 0.1 done if [[ $observed != 1 ]]; then kill "$vstest_pid" 2>/dev/null || true; fi test_status=0 wait "$vstest_pid" || test_status=$? vstest_pid= printf '%s\n' "$test_status" > /task/test-exit-status.txt if [[ $test_status != 0 ]]; then exit "$test_status"; fi [[ $observed == 1 ]]