Files
marte-benchmark-suite/launcher/marte_benchmark_launcher_s03h3.sh
T
2026-08-27 11:12:22 +02:00

670 lines
25 KiB
Bash
Executable File

#!/usr/bin/env bash
set -u
set -o pipefail
LAUNCHER_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd -P)"
INSTALLED_SUITE="$(cd -- "$LAUNCHER_DIR/.." && pwd -P)"
WORK_ROOT=""
print_usage() {
printf 'Uso:\n'
printf ' %s S03H3 <durata-secondi> MINIMAL\n' "$0"
printf ' %s S03H3 <durata-secondi> TEST\n' "$0"
printf ' %s S03H3 <durata-secondi> DIAGNOSTIC\n' "$0"
}
fail() {
local code="$1"
local reason="$2"
printf 'S03_H3_LAUNCHER_STATUS=FAIL\n' >&2
printf 'BLOCK_REASON=%s\n' "$reason" >&2
exit "$code"
}
is_positive_decimal() {
local value="$1"
[[ "$value" =~ ^[0-9]+$ ]] && [[ "$value" =~ [1-9] ]]
}
verify_hash() {
local file="$1"
local expected="$2"
local label="$3"
local actual
if [ ! -f "$file" ]; then
printf 'HASH_CHECK=%s STATUS=MISSING FILE=%s\n' "$label" "$file" >&2
return 1
fi
actual="$(sha256sum -- "$file" | awk '{print $1}')" || return 1
printf 'HASH_CHECK=%s EXPECTED=%s ACTUAL=%s FILE=%s\n' \
"$label" "$expected" "$actual" "$file"
[ "$actual" = "$expected" ]
}
readonly -a HISTORICAL_RELATIVE_PATHS=(
"launcher/marte_benchmark_launcher.sh"
"configurations/generated/S00/smoke_s0_core.marte"
"configurations/generated/S01/from_patcher/smoke_s1_timing_from_s00.marte"
"configurations/generated/S02/from_patcher/smoke_s2_binary_recording_from_s01.marte"
"configurations/generated/S03/from_patcher/smoke_s3_semantic_sentinels_from_s02.marte"
"patchers/configuration/build_s01_from_s00.sh"
"patchers/configuration/build_s02_from_s01.sh"
"patchers/configuration/build_s03_from_s02.sh"
"scenarios/S02_binary_recording/validate.sh"
"scenarios/S03_semantic_sentinels/validate.sh"
"scenarios/S03_semantic_sentinels/parse_s03_binary.py"
"common/marte_runner.sh"
"common/paths.sh"
"common/environment.sh"
"launcher/marte_benchmark_launcher_s03h1.sh"
"patchers/configuration/build_s03h1_from_s02.sh"
"scenarios/S03H1_execution_profiles/validate.sh"
"scenarios/S03H1_execution_profiles/verify_s03h1_config.py"
"scenarios/S03H1_execution_profiles/export_s03_csv.py"
"configurations/generated/S03H1/from_patcher/smoke_s03h1_execution_profiles_test_from_s02.marte"
"configurations/generated/S03H1/from_patcher/smoke_s03h1_execution_profiles_diagnostic_from_s02.marte"
)
readonly -a HISTORICAL_EXPECTED_HASHES=(
"7ef0419826c85c0364aad2403db4b8340cd815e9d9ce17edfbe5da8e6fbf2683"
"49a9b48595aab88cd8fd11d1e58ace4ab11d7d0a649e9b143bdc25c8866253d5"
"1513e1ca72eba56d53079ac7328908f12ddc72772456e2d75bcbacb6465d2427"
"8ecc8ba55e46e9f6fb8f304404d4070ff4c2ea5b9c783a69113bc08b457859d1"
"0f8916735ff67a9be2b167b52f147687fe131a063f410a81bfbf3bf9ff65f1e4"
"a8cced1ea1711806863606e27c3ba52a3e72794dbe8c36c253570709ce3f7ccb"
"8ac51d09f6f7984af3522e373bab59e2553775c418f69a53ccb93d8d1b893391"
"96c778ba6a15353fd969b19960706d7c0ca810c0c6fd61a14b5f88960e4e2b7a"
"7cd29b216b5edc3c72750a3326aebe5a9fdfb3b7522f1d7a6e8b0a1a97b3d60a"
"95caf207c4d29037c4973d756ff5a7004a3360aad9656d068948e222a4ba0c98"
"91c4d66770197e1986ed91eb6a4870e7da7df5a522ffdf4329b6d9250f238307"
"9e4f1a6b0dabc244fd0726fd18bf07e86b29a9fc6a76d54fcaf61c79f13c9633"
"468d92c3eb048b7137ea52a768f459d2d1f26f83f5a5c174d3333d032c9583c6"
"b1faa567e480c326c72107b886f387f108907900804621337524f1f856f056ac"
"f420afdff1f0a96026d14820662a4257c0da4924a491fe00182f838414e06152"
"5db5f71db4ab8f007b2e78230c2506bed4c62a8e502fb1c08ca04eb14b645b82"
"748f403a045f9dbed64910de67e75ba5529c02ab5894417a866225518c10b5e5"
"2f1c41b186bd2e79a9fb51fab0461a7a0dce104bf0852c0ec1ade2c55a017443"
"b413ad113e188141891b61b930a607890b8468051e8a61cb0f0454c519a51fb7"
"d037561b32760fbd0e2aec9f1eefc5efda27b1918eca4742c89092a8a2f7e92e"
"cd999ff249452298d650a22c8fe5b0b03bf48c0735f4630befdec8209cbb13a3"
)
readonly -a S03H3_ADD_RELATIVE_PATHS=(
"launcher/marte_benchmark_launcher_s03h3.sh"
"patchers/configuration/build_s03h3_minimal_from_s03h1_test.sh"
"scenarios/S03H3_execution_profiles/validate.sh"
"scenarios/S03H3_execution_profiles/verify_s03h3_minimal_structure.py"
"configurations/generated/S03H3/from_patcher/smoke_s03h3_execution_profiles_minimal_from_s03h1_test.marte"
)
readonly EXPECTED_PATCHER_SHA256="b3ba3c195b33a028e7ae21ba92b90a070a5e3526b455f9e3dbcebe023af05e2e"
readonly EXPECTED_VALIDATOR_SHA256="8574636315340c785f41dca37eaac097cd3b59958e7fd1160444b9c21768f2d5"
readonly EXPECTED_MINIMAL_VERIFIER_SHA256="c8d2d4880ed9cb0e8f23427617e989f5f70e82a990a49489f2863a7b3fc2cb95"
readonly EXPECTED_MINIMAL_CONFIG_SHA256="2ee67c48d748e79ec7fdbc748bc4371eb02590d7522b41990d5cb2a3649796ec"
readonly EXPECTED_TEST_CONFIG_SHA256="d037561b32760fbd0e2aec9f1eefc5efda27b1918eca4742c89092a8a2f7e92e"
readonly EXPECTED_DIAGNOSTIC_CONFIG_SHA256="cd999ff249452298d650a22c8fe5b0b03bf48c0735f4630befdec8209cbb13a3"
resolve_suite() {
if [ -n "${MARTE_BENCHMARK_SUITE_ROOT:-}" ]; then
[[ "$MARTE_BENCHMARK_SUITE_ROOT" = /* ]] || \
fail 50 "TEST_OVERRIDE_NOT_ABSOLUTE"
[ -d "$MARTE_BENCHMARK_SUITE_ROOT" ] || \
fail 50 "TEST_OVERRIDE_ROOT_MISSING"
SUITE="$(cd -- "$MARTE_BENCHMARK_SUITE_ROOT" && pwd -P)"
[ -n "$SUITE" ] && [ "$SUITE" != "/" ] || \
fail 50 "TEST_OVERRIDE_ROOT_UNSAFE"
if [ "$SUITE" != "$INSTALLED_SUITE" ]; then
[ "${S03H3_TEST_ONLY_OVERRIDE:-NO}" = "YES" ] || \
fail 50 "TEST_OVERRIDE_NOT_ACKNOWLEDGED"
fi
elif [ "${S03H3_TEST_ONLY_OVERRIDE:-NO}" = "YES" ]; then
fail 50 "TEST_OVERRIDE_ROOT_NOT_PROVIDED"
else
SUITE="$INSTALLED_SUITE"
fi
readonly SUITE
}
verify_historical_baseline() {
local index=0
while [ "$index" -lt "${#HISTORICAL_RELATIVE_PATHS[@]}" ]; do
verify_hash \
"$SUITE/${HISTORICAL_RELATIVE_PATHS[$index]}" \
"${HISTORICAL_EXPECTED_HASHES[$index]}" \
"HISTORICAL_${index}" || return 1
index=$((index + 1))
done
}
verify_candidate_components() {
verify_hash "$PATCHER" "$EXPECTED_PATCHER_SHA256" "S03H3_PATCHER" || return 1
verify_hash "$VALIDATOR" "$EXPECTED_VALIDATOR_SHA256" "S03H3_VALIDATOR" || return 1
verify_hash "$MINIMAL_VERIFIER" "$EXPECTED_MINIMAL_VERIFIER_SHA256" "S03H3_MINIMAL_VERIFIER" || return 1
verify_hash "$MINIMAL_CONFIG" "$EXPECTED_MINIMAL_CONFIG_SHA256" "S03H3_MINIMAL_CONFIG" || return 1
}
build_protected_paths() {
PROTECTED_PATHS=()
local relative
for relative in "${HISTORICAL_RELATIVE_PATHS[@]}"; do
PROTECTED_PATHS+=("$SUITE/$relative")
done
for relative in "${S03H3_ADD_RELATIVE_PATHS[@]}"; do
PROTECTED_PATHS+=("$SUITE/$relative")
done
PROTECTED_PATHS+=("$SUITE/launcher/marte_benchmark_menu.sh")
}
write_protected_snapshot() {
local destination="$1"
[ "${#PROTECTED_PATHS[@]}" -eq 27 ] || return 1
sha256sum -- "${PROTECTED_PATHS[@]}" >"$destination"
}
write_protected_path_list() {
local destination="$1"
printf '%s\n' "${PROTECTED_PATHS[@]}" >"$destination"
}
parse_contract_field() {
local field="$1"
local file="$2"
local count
PARSED_FIELD_VALUE=""
PARSED_FIELD_ERROR=""
count="$(grep -Ec "^${field}=" "$file" || true)"
if [ "$count" -eq 0 ]; then
PARSED_FIELD_ERROR="MISSING"
return 1
fi
if [ "$count" -ne 1 ]; then
PARSED_FIELD_ERROR="DUPLICATED"
return 1
fi
PARSED_FIELD_VALUE="$(sed -n "s/^${field}=//p" "$file")"
[ -n "$PARSED_FIELD_VALUE" ] || {
PARSED_FIELD_ERROR="MALFORMED"
return 1
}
}
classify_s03h3_run() {
local validator_rc="$1"
local validation_tee_rc="$2"
local validation_file="$3"
local csv_rc="$4"
local invariance_status="$5"
local dependency_status="$6"
local requested_mode="$7"
local field
FINAL_RC=22
FINAL_RESULT="INCONCLUSIVE_S03H3_CONTRACT"
BLOCK_REASON="NOT_EVALUATED"
PARSED_MODE_STATUS="NOT_EVALUATED"
PARSED_PROFILE_CONFIG_STATUS="NOT_EVALUATED"
PARSED_PROFILE_RUNTIME_STATUS="NOT_EVALUATED"
PARSED_OBSERVABILITY_STATUS="NOT_EVALUATED"
PARSED_FUNCTIONAL_STATUS="NOT_EVALUATED"
PARSED_SEMANTIC_STATUS="NOT_EVALUATED"
PARSED_TIMING_STATUS="NOT_EVALUATED"
PARSED_MEASUREMENT_ELIGIBILITY="NOT_EVALUATED"
PARSED_COMPLETE_SAMPLE_COUNT="NOT_EVALUATED"
if [ "$dependency_status" != "PASS" ]; then
FINAL_RC=51
FINAL_RESULT="FAIL_DEPENDENCY_INTEGRITY"
BLOCK_REASON="DEPENDENCY_INTEGRITY_NOT_PASS"
return 0
fi
if [ "$validation_tee_rc" -ne 0 ]; then
FINAL_RC=67
FINAL_RESULT="FAIL_VALIDATION_LOG"
BLOCK_REASON="VALIDATION_LOG_NOT_WRITTEN"
return 0
fi
case "$validator_rc" in
0|10|11|20|21) ;;
*)
FINAL_RC=68
FINAL_RESULT="FAIL_VALIDATOR_EXIT"
BLOCK_REASON="UNRECOGNIZED_VALIDATOR_RC_${validator_rc}"
return 0
;;
esac
if [ "$csv_rc" -ne 0 ]; then
FINAL_RC=70
FINAL_RESULT="FAIL_DERIVED_CSV_EXPORT"
BLOCK_REASON="CSV_EXPORT_RC_${csv_rc}"
return 0
fi
if [ "$invariance_status" != "PASS" ]; then
FINAL_RC=71
FINAL_RESULT="FAIL_PROTECTED_BASELINE_CHANGED"
BLOCK_REASON="PROTECTED_BASELINE_INVARIANCE_${invariance_status}"
return 0
fi
CONTRACT_PARSE_ERROR="NONE"
for field in \
MODE \
MODE_STATUS \
PROFILE_CONFIG_STATUS \
PROFILE_RUNTIME_STATUS \
OBSERVABILITY_STATUS \
OBSERVABILITY_REASON \
FUNCTIONAL_STATUS \
SEMANTIC_STATUS \
TIMING_STATUS \
MEASUREMENT_ELIGIBILITY \
COMPLETE_SAMPLE_COUNT \
VALIDATION_RESULT
do
if parse_contract_field "$field" "$validation_file"; then
case "$field" in
MODE) PARSED_MODE="$PARSED_FIELD_VALUE" ;;
MODE_STATUS) PARSED_MODE_STATUS="$PARSED_FIELD_VALUE" ;;
PROFILE_CONFIG_STATUS) PARSED_PROFILE_CONFIG_STATUS="$PARSED_FIELD_VALUE" ;;
PROFILE_RUNTIME_STATUS) PARSED_PROFILE_RUNTIME_STATUS="$PARSED_FIELD_VALUE" ;;
OBSERVABILITY_STATUS) PARSED_OBSERVABILITY_STATUS="$PARSED_FIELD_VALUE" ;;
OBSERVABILITY_REASON) PARSED_OBSERVABILITY_REASON="$PARSED_FIELD_VALUE" ;;
FUNCTIONAL_STATUS) PARSED_FUNCTIONAL_STATUS="$PARSED_FIELD_VALUE" ;;
SEMANTIC_STATUS) PARSED_SEMANTIC_STATUS="$PARSED_FIELD_VALUE" ;;
TIMING_STATUS) PARSED_TIMING_STATUS="$PARSED_FIELD_VALUE" ;;
MEASUREMENT_ELIGIBILITY) PARSED_MEASUREMENT_ELIGIBILITY="$PARSED_FIELD_VALUE" ;;
COMPLETE_SAMPLE_COUNT) PARSED_COMPLETE_SAMPLE_COUNT="$PARSED_FIELD_VALUE" ;;
VALIDATION_RESULT) PARSED_VALIDATION_RESULT="$PARSED_FIELD_VALUE" ;;
esac
elif [ "$CONTRACT_PARSE_ERROR" = "NONE" ]; then
CONTRACT_PARSE_ERROR="${field}_${PARSED_FIELD_ERROR}"
fi
done
if [ "$CONTRACT_PARSE_ERROR" = "NONE" ]; then
[ "$PARSED_MODE" = "$requested_mode" ] || CONTRACT_PARSE_ERROR="MODE_MISMATCH"
for field in \
"$PARSED_MODE_STATUS" \
"$PARSED_PROFILE_CONFIG_STATUS" \
"$PARSED_PROFILE_RUNTIME_STATUS" \
"$PARSED_OBSERVABILITY_STATUS" \
"$PARSED_FUNCTIONAL_STATUS" \
"$PARSED_SEMANTIC_STATUS"
do
case "$field" in
PASS|FAIL|NOT_DEMONSTRATED) ;;
*) CONTRACT_PARSE_ERROR="STATUS_VOCABULARY_INVALID"; break ;;
esac
done
fi
if [ "$CONTRACT_PARSE_ERROR" = "NONE" ]; then
[[ "$PARSED_OBSERVABILITY_REASON" =~ ^[A-Z][A-Z0-9_]*$ ]] || \
CONTRACT_PARSE_ERROR="OBSERVABILITY_REASON_MALFORMED"
[[ "$PARSED_TIMING_STATUS" =~ ^(NOT_VALID_|UNASSESSED_)[A-Z0-9_]+$ ]] || \
CONTRACT_PARSE_ERROR="TIMING_STATUS_UNRECOGNIZED"
[ "$PARSED_MEASUREMENT_ELIGIBILITY" = "NO" ] || \
CONTRACT_PARSE_ERROR="ELIGIBILITY_CONTRACT_VIOLATION"
[[ "$PARSED_COMPLETE_SAMPLE_COUNT" =~ ^[0-9]+$ ]] || \
CONTRACT_PARSE_ERROR="COMPLETE_SAMPLE_COUNT_MALFORMED"
[[ "$PARSED_VALIDATION_RESULT" =~ ^[A-Z][A-Z0-9_]*$ ]] || \
CONTRACT_PARSE_ERROR="VALIDATION_RESULT_MALFORMED"
if [ "$PARSED_OBSERVABILITY_STATUS" = "PASS" ]; then
[ "$PARSED_OBSERVABILITY_REASON" = "NONE" ] || \
CONTRACT_PARSE_ERROR="OBSERVABILITY_REASON_CONFLICT"
else
[ "$PARSED_OBSERVABILITY_REASON" != "NONE" ] || \
CONTRACT_PARSE_ERROR="OBSERVABILITY_REASON_MISSING"
fi
case "$validator_rc:$PARSED_VALIDATION_RESULT" in
0:PASS_CLEAN_SHUTDOWN|\
10:PASS_KNOWN_SHUTDOWN_ANOMALY|\
11:PASS_UNCLASSIFIED_SHUTDOWN_ANOMALY|\
20:FUNCTIONAL_OR_SEMANTIC_NOT_DEMONSTRATED|\
21:FAIL_REQUIRED_INPUT)
;;
*)
CONTRACT_PARSE_ERROR="VALIDATION_RESULT_RC_CONFLICT"
;;
esac
fi
if [ "$requested_mode" = "MINIMAL" ]; then
for field in \
CANONICAL_STRUCTURAL_COMPLETENESS_STATUS \
MINIMAL_RUNTIME_CONFIG_STATUS
do
if parse_contract_field "$field" "$validation_file"; then
[ "$PARSED_FIELD_VALUE" = "PASS" ] || \
CONTRACT_PARSE_ERROR="${field}_NOT_PASS"
else
CONTRACT_PARSE_ERROR="${field}_${PARSED_FIELD_ERROR}"
fi
done
fi
if [ "$CONTRACT_PARSE_ERROR" != "NONE" ]; then
FINAL_RC=22
FINAL_RESULT="INCONCLUSIVE_S03H3_CONTRACT"
BLOCK_REASON="$CONTRACT_PARSE_ERROR"
return 0
fi
case "$validator_rc" in
11|20|21)
FINAL_RC=20
FINAL_RESULT="S03H3_VALIDATION_INCONCLUSIVE"
BLOCK_REASON="VALIDATOR_RC_${validator_rc}"
return 0
;;
esac
for field in \
"$PARSED_MODE_STATUS" \
"$PARSED_PROFILE_CONFIG_STATUS" \
"$PARSED_PROFILE_RUNTIME_STATUS" \
"$PARSED_OBSERVABILITY_STATUS" \
"$PARSED_FUNCTIONAL_STATUS" \
"$PARSED_SEMANTIC_STATUS"
do
if [ "$field" != "PASS" ]; then
FINAL_RC=25
FINAL_RESULT="S03H3_CONTRACT_STATUS_NOT_PASS"
BLOCK_REASON="MANDATORY_STATUS_NOT_PASS"
return 0
fi
done
case "$PARSED_TIMING_STATUS" in
NOT_VALID_*)
FINAL_RC=14
FINAL_RESULT="FUNCTIONAL_AND_SEMANTIC_PASS_TIMING_NOT_VALID"
BLOCK_REASON="$PARSED_TIMING_STATUS"
;;
UNASSESSED_*)
FINAL_RC=15
FINAL_RESULT="FUNCTIONAL_AND_SEMANTIC_PASS_TIMING_UNASSESSED"
BLOCK_REASON="$PARSED_TIMING_STATUS"
;;
*)
FINAL_RC=22
FINAL_RESULT="INCONCLUSIVE_S03H3_CONTRACT"
BLOCK_REASON="TIMING_STATUS_UNRECOGNIZED"
;;
esac
}
run_s03h3() {
local duration="$1"
MODE="$2"
local expected_selected_hash
local patcher_log
local protected_before
local capture
local run_dir
local validation_log
local csv_report
local launcher_summary
local protected_after
local invariance_report
local protected_path_list
resolve_suite
[ -d "$SUITE" ] || return 50
PATCHER="$SUITE/patchers/configuration/build_s03h3_minimal_from_s03h1_test.sh"
VALIDATOR="$SUITE/scenarios/S03H3_execution_profiles/validate.sh"
MINIMAL_VERIFIER="$SUITE/scenarios/S03H3_execution_profiles/verify_s03h3_minimal_structure.py"
MINIMAL_CONFIG="$SUITE/configurations/generated/S03H3/from_patcher/smoke_s03h3_execution_profiles_minimal_from_s03h1_test.marte"
TEST_CONFIG="$SUITE/configurations/generated/S03H1/from_patcher/smoke_s03h1_execution_profiles_test_from_s02.marte"
DIAGNOSTIC_CONFIG="$SUITE/configurations/generated/S03H1/from_patcher/smoke_s03h1_execution_profiles_diagnostic_from_s02.marte"
RUNNER="$SUITE/common/marte_runner.sh"
LIVE_PATHS="$SUITE/common/paths.sh"
CSV_EXPORTER="$SUITE/scenarios/S03H1_execution_profiles/export_s03_csv.py"
PARSER="$SUITE/scenarios/S03_semantic_sentinels/parse_s03_binary.py"
case "$MODE" in
MINIMAL)
SELECTED_CONFIG="$MINIMAL_CONFIG"
expected_selected_hash="$EXPECTED_MINIMAL_CONFIG_SHA256"
;;
TEST)
SELECTED_CONFIG="$TEST_CONFIG"
expected_selected_hash="$EXPECTED_TEST_CONFIG_SHA256"
;;
DIAGNOSTIC)
SELECTED_CONFIG="$DIAGNOSTIC_CONFIG"
expected_selected_hash="$EXPECTED_DIAGNOSTIC_CONFIG_SHA256"
;;
*) return 2 ;;
esac
verify_historical_baseline || return 52
verify_candidate_components || return 51
verify_hash "$SELECTED_CONFIG" "$expected_selected_hash" "SELECTED_${MODE}_CONFIG" || return 51
build_protected_paths
local protected_path
for protected_path in "${PROTECTED_PATHS[@]}"; do
[ -f "$protected_path" ] || return 51
done
WORK_ROOT="$(mktemp -d "${TMPDIR:-/tmp}/s03h3_launcher.XXXXXX")" || return 53
trap 'rm -rf -- "$WORK_ROOT"' EXIT HUP INT TERM
patcher_log="$WORK_ROOT/patcher.log"
protected_before="$WORK_ROOT/protected_before.sha256"
capture="$WORK_ROOT/runner_capture.log"
"$PATCHER" >"$patcher_log" 2>&1
PATCHER_RC=$?
[ "$PATCHER_RC" -eq 0 ] || return 54
verify_hash "$MINIMAL_CONFIG" "$EXPECTED_MINIMAL_CONFIG_SHA256" "MINIMAL_REGENERATION" || return 55
python3 "$MINIMAL_VERIFIER" CANONICAL "$TEST_CONFIG" "$MINIMAL_CONFIG" >/dev/null 2>&1 || return 55
write_protected_snapshot "$protected_before" || return 56
[ -f "$LIVE_PATHS" ] || return 57
# shellcheck source=/dev/null
source "$LIVE_PATHS" || return 57
CONSTANT_GAM_LIB_DIR="$MARTE2_COMPONENTS_ROOT/Build/$MARTE_TARGET/Components/GAMs/ConstantGAM"
CONSTANT_GAM_LIB="$CONSTANT_GAM_LIB_DIR/ConstantGAM.so"
[ -f "$CONSTANT_GAM_LIB" ] || return 58
case ":${LD_LIBRARY_PATH-}:" in
*":${CONSTANT_GAM_LIB_DIR}:"*) ;;
*) LD_LIBRARY_PATH="${CONSTANT_GAM_LIB_DIR}${LD_LIBRARY_PATH:+:${LD_LIBRARY_PATH}}" ;;
esac
export LD_LIBRARY_PATH
printf '============================================================\n'
printf 'S03-H3 EXECUTION PROFILES\n'
printf '============================================================\n'
printf 'MODE=%s\n' "$MODE"
printf 'DURATION=%s\n' "$duration"
printf 'DEPENDENCY_INTEGRITY_STATUS=PASS\n'
"$RUNNER" "S03H3_${MODE}_launcher" "$SELECTED_CONFIG" "State1" "$duration" \
2>&1 | tee "$capture"
RUNNER_CODES=("${PIPESTATUS[@]}")
RUNNER_RC="${RUNNER_CODES[0]}"
CAPTURE_TEE_RC="${RUNNER_CODES[1]}"
[ "$RUNNER_RC" -eq 0 ] || return 60
[ "$CAPTURE_TEE_RC" -eq 0 ] || return 61
run_dir="$(sed -n 's/^RUN_DIR=//p' "$capture" | tail -n 1)"
case "$run_dir" in
"$SUITE"/runs/*_S03H3_${MODE}_launcher) ;;
*) return 62 ;;
esac
[ -d "$run_dir" ] || return 62
RUN_LOG="$run_dir/run.log"
RUN_CONFIG="$run_dir/configuration.marte"
RUNNER_SUMMARY="$run_dir/runner_summary.txt"
RUN_HASHES="$run_dir/hashes.sha256"
OUTPUT_FILE="$run_dir/s03_output.bin"
CSV_FILE="$run_dir/s03_output.csv"
MODE_FILE="$run_dir/s03h3_mode.txt"
validation_log="$run_dir/validation.txt"
csv_report="$run_dir/csv_export.txt"
launcher_summary="$run_dir/launcher_summary.txt"
PROTECTED_BEFORE_RUN="$run_dir/protected_baseline_before.sha256"
protected_after="$run_dir/protected_baseline_after.sha256"
invariance_report="$run_dir/protected_baseline_invariance.txt"
protected_path_list="$run_dir/protected_successor_paths.txt"
for protected_path in "$RUN_LOG" "$RUN_CONFIG" "$RUNNER_SUMMARY" "$RUN_HASHES" "$OUTPUT_FILE"; do
[ -f "$protected_path" ] || return 63
done
cp -- "$protected_before" "$PROTECTED_BEFORE_RUN" || return 64
write_protected_path_list "$protected_path_list" || return 64
{
printf 'SCENARIO=S03H3\n'
printf 'MODE=%s\n' "$MODE"
printf 'SELECTED_CONFIG_SHA256=%s\n' "$expected_selected_hash"
} >"$MODE_FILE" || return 64
sha256sum -- \
"$MODE_FILE" \
"${BASH_SOURCE[0]}" \
"$PATCHER" \
"$VALIDATOR" \
"$MINIMAL_VERIFIER" \
"$CSV_EXPORTER" \
"$PARSER" \
"$RUN_LOG" \
"$RUNNER_SUMMARY" \
"$OUTPUT_FILE" \
"$PROTECTED_BEFORE_RUN" \
"$protected_path_list" \
"${PROTECTED_PATHS[@]}" \
>>"$RUN_HASHES" || return 64
timeout 30s "$VALIDATOR" "$MODE" "$run_dir" 2>&1 | tee "$validation_log"
VALIDATION_CODES=("${PIPESTATUS[@]}")
VALIDATOR_RC="${VALIDATION_CODES[0]}"
VALIDATION_TEE_RC="${VALIDATION_CODES[1]}"
"$CSV_EXPORTER" "$OUTPUT_FILE" "$CSV_FILE" >"$csv_report" 2>&1
CSV_EXPORT_RC=$?
if [ "$CSV_EXPORT_RC" -eq 0 ]; then
CSV_EXPORT_STATUS="PASS"
else
CSV_EXPORT_STATUS="FAIL"
fi
if write_protected_snapshot "$protected_after" && \
cmp -s -- "$PROTECTED_BEFORE_RUN" "$protected_after"; then
PROTECTED_BASELINE_INVARIANCE="PASS"
else
PROTECTED_BASELINE_INVARIANCE="FAIL"
fi
{
printf 'PROTECTED_BASELINE_INVARIANCE=%s\n' "$PROTECTED_BASELINE_INVARIANCE"
printf 'PROTECTED_SUCCESSOR_BASELINE_COUNT=27\n'
} >"$invariance_report"
for protected_path in "$validation_log" "$csv_report" "$protected_after" "$invariance_report"; do
[ -f "$protected_path" ] && sha256sum -- "$protected_path" >>"$RUN_HASHES"
done
[ -f "$CSV_FILE" ] && sha256sum -- "$CSV_FILE" >>"$RUN_HASHES"
classify_s03h3_run \
"$VALIDATOR_RC" \
"$VALIDATION_TEE_RC" \
"$validation_log" \
"$CSV_EXPORT_RC" \
"$PROTECTED_BASELINE_INVARIANCE" \
"PASS" \
"$MODE"
{
printf '============================================================\n'
printf 'RIEPILOGO LAUNCHER S03-H3\n'
printf '============================================================\n'
printf 'SCENARIO=S03H3\n'
printf 'MODE=%s\n' "$MODE"
printf 'DURATION=%s\n' "$duration"
printf 'RUN_DIR=%s\n' "$run_dir"
printf 'RUNNER_RC=%s\n' "$RUNNER_RC"
printf 'VALIDATOR_RC=%s\n' "$VALIDATOR_RC"
printf 'CSV_EXPORT_RC=%s\n' "$CSV_EXPORT_RC"
printf 'DEPENDENCY_INTEGRITY_STATUS=PASS\n'
printf 'PROTECTED_BASELINE_INVARIANCE=%s\n' "$PROTECTED_BASELINE_INVARIANCE"
printf 'CSV_EXPORT_STATUS=%s\n' "$CSV_EXPORT_STATUS"
printf 'MODE_STATUS=%s\n' "$PARSED_MODE_STATUS"
printf 'PROFILE_CONFIG_STATUS=%s\n' "$PARSED_PROFILE_CONFIG_STATUS"
printf 'PROFILE_RUNTIME_STATUS=%s\n' "$PARSED_PROFILE_RUNTIME_STATUS"
printf 'OBSERVABILITY_STATUS=%s\n' "$PARSED_OBSERVABILITY_STATUS"
printf 'FUNCTIONAL_STATUS=%s\n' "$PARSED_FUNCTIONAL_STATUS"
printf 'SEMANTIC_STATUS=%s\n' "$PARSED_SEMANTIC_STATUS"
printf 'TIMING_STATUS=%s\n' "$PARSED_TIMING_STATUS"
printf 'MEASUREMENT_ELIGIBILITY=NO\n'
printf 'BLOCK_REASON=%s\n' "$BLOCK_REASON"
printf 'FINAL_RESULT=%s\n' "$FINAL_RESULT"
printf 'FINAL_RC=%s\n' "$FINAL_RC"
printf 'PERFORMANCE_MEASUREMENT_AUTHORIZED=NO\n'
printf 'S04_AUTHORIZED=NO\n'
printf 'MD00_AUTHORIZED=NO\n'
} | tee "$launcher_summary"
SUMMARY_CODES=("${PIPESTATUS[@]}")
if [ "${SUMMARY_CODES[1]}" -ne 0 ]; then
FINAL_RC=69
FINAL_RESULT="FAIL_LAUNCHER_SUMMARY"
BLOCK_REASON="LAUNCHER_SUMMARY_NOT_WRITTEN"
else
sha256sum -- "$launcher_summary" >>"$RUN_HASHES"
fi
printf 'RUN_DIR=%s\n' "$run_dir"
printf 'FINAL_RESULT=%s\n' "$FINAL_RESULT"
printf 'FINAL_RC=%s\n' "$FINAL_RC"
rm -rf -- "$WORK_ROOT"
WORK_ROOT=""
trap - EXIT HUP INT TERM
return "$FINAL_RC"
}
if [ "${S03H3_LAUNCHER_LIB_ONLY:-0}" = "1" ]; then
if [ "${BASH_SOURCE[0]}" != "$0" ]; then
return 0
fi
printf 'S03H3_LAUNCHER_LIB_ONLY=1 richiede source.\n' >&2
exit 3
fi
case "$#" in
1)
case "$1" in
-h|--help)
print_usage
exit 0
;;
*)
print_usage >&2
exit 2
;;
esac
;;
3)
[ "$1" = "S03H3" ] || {
print_usage >&2
exit 2
}
is_positive_decimal "$2" || {
printf 'Durata non valida: %s\n' "$2" >&2
exit 2
}
case "$3" in
MINIMAL|TEST|DIAGNOSTIC) ;;
*)
printf 'Profilo non riconosciuto: %s\n' "$3" >&2
exit 2
;;
esac
run_s03h3 "$2" "$3"
exit $?
;;
*)
print_usage >&2
exit 2
;;
esac