1247 lines
37 KiB
Bash
Executable File
1247 lines
37 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
set -u
|
|
|
|
LAUNCHER_DIR="$(
|
|
cd "$(dirname "${BASH_SOURCE[0]}")" &&
|
|
pwd
|
|
)"
|
|
|
|
if [ -n "${MARTE_BENCHMARK_SUITE_ROOT:-}" ]; then
|
|
SUITE="$(cd "$MARTE_BENCHMARK_SUITE_ROOT" && pwd)"
|
|
else
|
|
SUITE="$(cd "$LAUNCHER_DIR/.." && pwd)"
|
|
fi
|
|
|
|
PATCHER_S01="$SUITE/patchers/configuration/build_s01_from_s00.sh"
|
|
PATCHER_S02="$SUITE/patchers/configuration/build_s02_from_s01.sh"
|
|
PATCHER_S03="${MARTE_S03_PATCHER_OVERRIDE:-$SUITE/patchers/configuration/build_s03_from_s02.sh}"
|
|
RUNNER="$SUITE/common/marte_runner.sh"
|
|
VALIDATOR_S01="$SUITE/scenarios/S01_timing_display/validate.sh"
|
|
VALIDATOR_S02="$SUITE/scenarios/S02_binary_recording/validate.sh"
|
|
VALIDATOR_S03="${MARTE_S03_VALIDATOR_OVERRIDE:-$SUITE/scenarios/S03_semantic_sentinels/validate.sh}"
|
|
|
|
S00_CONFIG="$SUITE/configurations/generated/S00/smoke_s0_core.marte"
|
|
S01_PATCHED_CONFIG="$SUITE/configurations/generated/S01/from_patcher/smoke_s1_timing_from_s00.marte"
|
|
S02_PATCHED_CONFIG="$SUITE/configurations/generated/S02/from_patcher/smoke_s2_binary_recording_from_s01.marte"
|
|
S03_PATCHED_CONFIG="${MARTE_S03_CONFIG_OVERRIDE:-$SUITE/configurations/generated/S03/from_patcher/smoke_s3_semantic_sentinels_from_s02.marte}"
|
|
|
|
CONSTANT_GAM_LIB_DIR="$SUITE/../MARTe2-components/Build/x86-linux/Components/GAMs/ConstantGAM"
|
|
if [ -f "$SUITE/common/paths.sh" ]; then
|
|
# Il file espone i percorsi canonici usati dalla suite. Il sourcing non
|
|
# modifica file e permette di rispettare target e root non standard.
|
|
source "$SUITE/common/paths.sh"
|
|
CONSTANT_GAM_LIB_DIR="$MARTE2_COMPONENTS_ROOT/Build/$MARTE_TARGET/Components/GAMs/ConstantGAM"
|
|
fi
|
|
CONSTANT_GAM_LIB="$CONSTANT_GAM_LIB_DIR/ConstantGAM.so"
|
|
|
|
EXPECTED_S00_SHA256="49a9b48595aab88cd8fd11d1e58ace4ab11d7d0a649e9b143bdc25c8866253d5"
|
|
EXPECTED_S01_SHA256="1513e1ca72eba56d53079ac7328908f12ddc72772456e2d75bcbacb6465d2427"
|
|
EXPECTED_S02_SHA256="8ecc8ba55e46e9f6fb8f304404d4070ff4c2ea5b9c783a69113bc08b457859d1"
|
|
EXPECTED_S03_SHA256="0f8916735ff67a9be2b167b52f147687fe131a063f410a81bfbf3bf9ff65f1e4"
|
|
|
|
DEFAULT_DURATION_SECONDS="8"
|
|
|
|
S00_STATUS="NOT_CHECKED"
|
|
S01_STATUS="NOT_CHECKED"
|
|
S02_STATUS="NOT_CHECKED"
|
|
S03_STATUS="NOT_CHECKED"
|
|
S01_PATCHER_RC="NOT_RUN"
|
|
S02_PATCHER_RC="NOT_RUN"
|
|
S03_PATCHER_RC="NOT_RUN"
|
|
|
|
print_usage() {
|
|
printf "Uso:\n"
|
|
printf " %s\n" "$0"
|
|
printf " %s S01 [durata-secondi]\n" "$0"
|
|
printf " %s S02 [durata-secondi]\n" "$0"
|
|
printf " %s S03 [durata-secondi]\n" "$0"
|
|
printf "\n"
|
|
printf "Dipendenze automatiche:\n"
|
|
printf " S01: catena S00 -> S01; esegue e valida S01.\n"
|
|
printf " S02: catena S00 -> S01 -> S02; esegue e valida S02.\n"
|
|
printf " S03: catena S00 -> S01 -> S02 -> S03; valida le sentinelle.\n"
|
|
}
|
|
|
|
fail() {
|
|
code="$1"
|
|
shift
|
|
printf "ERRORE: %s\n" "$*" >&2
|
|
exit "$code"
|
|
}
|
|
|
|
check_executable() {
|
|
file="$1"
|
|
description="$2"
|
|
|
|
if [ ! -x "$file" ]; then
|
|
fail 30 "$description assente o non eseguibile: $file"
|
|
fi
|
|
}
|
|
|
|
validate_duration() {
|
|
duration="$1"
|
|
|
|
case "$duration" in
|
|
*[!0-9]*|"")
|
|
printf "ERRORE: durata non valida: %s\n" "$duration" >&2
|
|
return 1
|
|
;;
|
|
esac
|
|
|
|
if [ "$duration" -le 0 ]; then
|
|
printf "ERRORE: la durata deve essere maggiore di zero.\n" >&2
|
|
return 1
|
|
fi
|
|
|
|
return 0
|
|
}
|
|
|
|
verify_file_hash() {
|
|
file="$1"
|
|
expected_hash="$2"
|
|
description="$3"
|
|
|
|
if [ ! -f "$file" ]; then
|
|
printf "ERRORE: %s assente: %s\n" "$description" "$file" >&2
|
|
return 1
|
|
fi
|
|
|
|
actual_hash="$(sha256sum -- "$file" | awk '{print $1}')"
|
|
|
|
if [ "$actual_hash" != "$expected_hash" ]; then
|
|
printf "ERRORE: hash inatteso per %s.\n" "$description" >&2
|
|
printf "Atteso: %s\n" "$expected_hash" >&2
|
|
printf "Reale: %s\n" "$actual_hash" >&2
|
|
printf "File: %s\n" "$file" >&2
|
|
return 1
|
|
fi
|
|
|
|
printf "%s pronta: %s\n" "$description" "$file"
|
|
printf "SHA-256: %s\n" "$actual_hash"
|
|
return 0
|
|
}
|
|
|
|
ensure_s00() {
|
|
printf "\n============================================================\n"
|
|
printf "DIPENDENZA S00 — CONFIGURAZIONE BASE\n"
|
|
printf "============================================================\n"
|
|
|
|
if ! verify_file_hash \
|
|
"$S00_CONFIG" \
|
|
"$EXPECTED_S00_SHA256" \
|
|
"Configurazione S00"
|
|
then
|
|
S00_STATUS="FAILED"
|
|
return 50
|
|
fi
|
|
|
|
S00_STATUS="READY"
|
|
return 0
|
|
}
|
|
|
|
ensure_s01() {
|
|
ensure_s00
|
|
dependency_rc=$?
|
|
|
|
if [ "$dependency_rc" -ne 0 ]; then
|
|
return "$dependency_rc"
|
|
fi
|
|
|
|
printf "\n============================================================\n"
|
|
printf "DIPENDENZA S01 — PATCH S00 -> S01\n"
|
|
printf "============================================================\n"
|
|
|
|
check_executable "$PATCHER_S01" "Patcher S01"
|
|
|
|
timeout 10s "$PATCHER_S01"
|
|
S01_PATCHER_RC=$?
|
|
|
|
printf "Codice patcher S01: %s\n" "$S01_PATCHER_RC"
|
|
|
|
if [ "$S01_PATCHER_RC" -ne 0 ]; then
|
|
S01_STATUS="FAILED"
|
|
return 51
|
|
fi
|
|
|
|
if ! verify_file_hash \
|
|
"$S01_PATCHED_CONFIG" \
|
|
"$EXPECTED_S01_SHA256" \
|
|
"Configurazione S01"
|
|
then
|
|
S01_STATUS="FAILED"
|
|
return 52
|
|
fi
|
|
|
|
S01_STATUS="READY"
|
|
return 0
|
|
}
|
|
|
|
ensure_s02() {
|
|
ensure_s01
|
|
dependency_rc=$?
|
|
|
|
if [ "$dependency_rc" -ne 0 ]; then
|
|
return "$dependency_rc"
|
|
fi
|
|
|
|
printf "\n============================================================\n"
|
|
printf "DIPENDENZA S02 — PATCH S01 -> S02\n"
|
|
printf "============================================================\n"
|
|
|
|
check_executable "$PATCHER_S02" "Patcher S02"
|
|
|
|
timeout 10s "$PATCHER_S02"
|
|
S02_PATCHER_RC=$?
|
|
|
|
printf "Codice patcher S02: %s\n" "$S02_PATCHER_RC"
|
|
|
|
if [ "$S02_PATCHER_RC" -ne 0 ]; then
|
|
S02_STATUS="FAILED"
|
|
return 53
|
|
fi
|
|
|
|
if ! verify_file_hash \
|
|
"$S02_PATCHED_CONFIG" \
|
|
"$EXPECTED_S02_SHA256" \
|
|
"Configurazione S02"
|
|
then
|
|
S02_STATUS="FAILED"
|
|
return 54
|
|
fi
|
|
|
|
S02_STATUS="READY"
|
|
return 0
|
|
}
|
|
|
|
ensure_s03() {
|
|
ensure_s02
|
|
dependency_rc=$?
|
|
|
|
if [ "$dependency_rc" -ne 0 ]; then
|
|
return "$dependency_rc"
|
|
fi
|
|
|
|
printf "\n============================================================\n"
|
|
printf "DIPENDENZA S03 — PATCH S02 -> S03\n"
|
|
printf "============================================================\n"
|
|
|
|
check_executable "$PATCHER_S03" "Patcher S03"
|
|
check_executable "$VALIDATOR_S03" "Validatore S03"
|
|
|
|
if [ ! -f "$CONSTANT_GAM_LIB" ]; then
|
|
printf "ERRORE: libreria ConstantGAM assente: %s\n" "$CONSTANT_GAM_LIB" >&2
|
|
S03_STATUS="FAILED"
|
|
return 55
|
|
fi
|
|
|
|
case ":${LD_LIBRARY_PATH-}:" in
|
|
*":${CONSTANT_GAM_LIB_DIR}:"*)
|
|
;;
|
|
*)
|
|
if [ -n "${LD_LIBRARY_PATH-}" ]; then
|
|
LD_LIBRARY_PATH="${CONSTANT_GAM_LIB_DIR}:${LD_LIBRARY_PATH}"
|
|
else
|
|
LD_LIBRARY_PATH="$CONSTANT_GAM_LIB_DIR"
|
|
fi
|
|
;;
|
|
esac
|
|
export LD_LIBRARY_PATH
|
|
|
|
timeout 10s "$PATCHER_S03" "$S02_PATCHED_CONFIG" "$S03_PATCHED_CONFIG"
|
|
S03_PATCHER_RC=$?
|
|
|
|
printf "Codice patcher S03: %s\n" "$S03_PATCHER_RC"
|
|
|
|
if [ "$S03_PATCHER_RC" -ne 0 ]; then
|
|
S03_STATUS="FAILED"
|
|
return 56
|
|
fi
|
|
|
|
if ! verify_file_hash \
|
|
"$S03_PATCHED_CONFIG" \
|
|
"$EXPECTED_S03_SHA256" \
|
|
"Configurazione S03"
|
|
then
|
|
S03_STATUS="FAILED"
|
|
return 57
|
|
fi
|
|
|
|
S03_STATUS="READY"
|
|
return 0
|
|
}
|
|
|
|
# ------------------------------------------------------------------
|
|
# S02-H2 — lettura contrattuale di validation.txt
|
|
# ------------------------------------------------------------------
|
|
#
|
|
# parse_validation_field <nome-campo> <file>
|
|
#
|
|
# Richiede ESATTAMENTE una riga "NOME=VALORE" nel file indicato.
|
|
# Il valore ammesso e' un token maiuscolo [A-Z][A-Z0-9_]*.
|
|
#
|
|
# Imposta:
|
|
# PARSED_FIELD_VALUE valore letto, oppure stringa vuota
|
|
# PARSED_FIELD_ERROR MISSING | DUPLICATED | MALFORMED | NO_FILE, oppure vuoto
|
|
#
|
|
# Ritorna 0 se e solo se il campo e' presente una sola volta e ben formato.
|
|
parse_validation_field() {
|
|
field_name="$1"
|
|
field_file="$2"
|
|
|
|
PARSED_FIELD_VALUE=""
|
|
PARSED_FIELD_ERROR=""
|
|
|
|
if [ ! -f "$field_file" ]; then
|
|
PARSED_FIELD_ERROR="NO_FILE"
|
|
return 1
|
|
fi
|
|
|
|
field_occurrences="$(grep -c -- "^${field_name}=" "$field_file" || true)"
|
|
|
|
if [ -z "$field_occurrences" ]; then
|
|
field_occurrences=0
|
|
fi
|
|
|
|
if [ "$field_occurrences" -eq 0 ]; then
|
|
PARSED_FIELD_ERROR="MISSING"
|
|
return 1
|
|
fi
|
|
|
|
if [ "$field_occurrences" -gt 1 ]; then
|
|
PARSED_FIELD_ERROR="DUPLICATED"
|
|
return 1
|
|
fi
|
|
|
|
field_value="$(
|
|
grep -- "^${field_name}=" "$field_file" |
|
|
head -n 1 |
|
|
cut -d '=' -f 2- |
|
|
tr -d '\r'
|
|
)"
|
|
|
|
case "$field_value" in
|
|
""|*[!A-Z0-9_]*)
|
|
PARSED_FIELD_ERROR="MALFORMED"
|
|
return 1
|
|
;;
|
|
esac
|
|
|
|
case "$field_value" in
|
|
[A-Z]*)
|
|
;;
|
|
*)
|
|
PARSED_FIELD_ERROR="MALFORMED"
|
|
return 1
|
|
;;
|
|
esac
|
|
|
|
PARSED_FIELD_VALUE="$field_value"
|
|
return 0
|
|
}
|
|
|
|
# ------------------------------------------------------------------
|
|
# classify_run <validator-rc> <tee-rc> <validation-file> <timing-contract>
|
|
#
|
|
# timing_contract:
|
|
# required lo scenario DEVE esporre FUNCTIONAL_STATUS e TIMING_STATUS
|
|
# not_applicable lo scenario non espone stato temporale (comportamento S01)
|
|
#
|
|
# Imposta:
|
|
# FUNCTIONAL_RESULT esito storico basato sull'exit code del validatore
|
|
# PARSED_FUNCTIONAL_STATUS
|
|
# PARSED_TIMING_STATUS
|
|
# MEASUREMENT_ELIGIBILITY YES | NO | UNKNOWN | NOT_APPLICABLE
|
|
# BLOCK_REASON NONE oppure motivo del blocco
|
|
# FINAL_RESULT
|
|
# FINAL_RC
|
|
# ------------------------------------------------------------------
|
|
classify_run() {
|
|
classify_validator_rc="$1"
|
|
classify_tee_rc="$2"
|
|
classify_validation_file="$3"
|
|
classify_timing_contract="$4"
|
|
|
|
PARSED_FUNCTIONAL_STATUS="NOT_APPLICABLE"
|
|
PARSED_TIMING_STATUS="NOT_APPLICABLE"
|
|
MEASUREMENT_ELIGIBILITY="NOT_APPLICABLE"
|
|
BLOCK_REASON="NONE"
|
|
|
|
# --- Contratto temporale: fail-closed su token sconosciuti (H2-04) ---
|
|
case "$classify_timing_contract" in
|
|
required|not_applicable)
|
|
;;
|
|
*)
|
|
FUNCTIONAL_RESULT="NOT_EVALUATED"
|
|
PARSED_FUNCTIONAL_STATUS="NOT_EVALUATED"
|
|
PARSED_TIMING_STATUS="NOT_EVALUATED"
|
|
MEASUREMENT_ELIGIBILITY="NO"
|
|
BLOCK_REASON="TIMING_CONTRACT_UNRECOGNISED_$classify_timing_contract"
|
|
FINAL_RESULT="INVALID_TIMING_CONTRACT"
|
|
FINAL_RC=24
|
|
return 0
|
|
;;
|
|
esac
|
|
|
|
# --- validation.txt non scritto: nessun parsing possibile ---
|
|
if [ "$classify_tee_rc" -ne 0 ]; then
|
|
FUNCTIONAL_RESULT="FAIL_VALIDATION_LOG"
|
|
FINAL_RESULT="FAIL_VALIDATION_LOG"
|
|
PARSED_FUNCTIONAL_STATUS="NOT_EVALUATED"
|
|
PARSED_TIMING_STATUS="NOT_EVALUATED"
|
|
MEASUREMENT_ELIGIBILITY="NO"
|
|
BLOCK_REASON="VALIDATION_LOG_NOT_WRITTEN"
|
|
FINAL_RC=67
|
|
return 0
|
|
fi
|
|
|
|
# --- Esito funzionale storico, dall'exit code del validatore ---
|
|
case "$classify_validator_rc" in
|
|
0)
|
|
FUNCTIONAL_RESULT="PASS"
|
|
FINAL_RC=0
|
|
FUNCTIONAL_ESTABLISHED=1
|
|
;;
|
|
10)
|
|
FUNCTIONAL_RESULT="PASS_WITH_KNOWN_SHUTDOWN_ANOMALY"
|
|
FINAL_RC=10
|
|
FUNCTIONAL_ESTABLISHED=1
|
|
;;
|
|
11)
|
|
FUNCTIONAL_RESULT="PASS_WITH_UNCLASSIFIED_SHUTDOWN_ANOMALY"
|
|
FINAL_RC=11
|
|
FUNCTIONAL_ESTABLISHED=1
|
|
;;
|
|
20|21)
|
|
FUNCTIONAL_RESULT="INCONCLUSIVE"
|
|
FINAL_RC=20
|
|
FUNCTIONAL_ESTABLISHED=0
|
|
;;
|
|
*)
|
|
FUNCTIONAL_RESULT="FAIL_VALIDATOR"
|
|
FINAL_RC=68
|
|
FUNCTIONAL_ESTABLISHED=0
|
|
;;
|
|
esac
|
|
|
|
FINAL_RESULT="$FUNCTIONAL_RESULT"
|
|
|
|
if [ "$classify_timing_contract" = "not_applicable" ]; then
|
|
return 0
|
|
fi
|
|
|
|
# ------------------------------------------------------------------
|
|
# Contratto temporale richiesto.
|
|
#
|
|
# H2-01: il parsing e' SEMPRE tentato quando il tee della validazione
|
|
# e' riuscito, indipendentemente dall'exit code del validatore. Il
|
|
# validatore H1 stampa FUNCTIONAL_STATUS e TIMING_STATUS anche prima
|
|
# di uscire con 20; nasconderli sarebbe una propagazione falsa.
|
|
#
|
|
# La precedenza numerica resta invece all'exit code del validatore:
|
|
# 20 rimane 20, 68 rimane 68. Il parsing arricchisce il riepilogo,
|
|
# non riscrive un verdetto funzionale gia' emesso.
|
|
# ------------------------------------------------------------------
|
|
|
|
CLASSIFY_PARSE_ERROR="NONE"
|
|
|
|
if parse_validation_field "FUNCTIONAL_STATUS" "$classify_validation_file"; then
|
|
PARSED_FUNCTIONAL_STATUS="$PARSED_FIELD_VALUE"
|
|
else
|
|
PARSED_FUNCTIONAL_STATUS="PARSE_ERROR_$PARSED_FIELD_ERROR"
|
|
CLASSIFY_PARSE_ERROR="FUNCTIONAL_STATUS_$PARSED_FIELD_ERROR"
|
|
fi
|
|
|
|
if parse_validation_field "TIMING_STATUS" "$classify_validation_file"; then
|
|
PARSED_TIMING_STATUS="$PARSED_FIELD_VALUE"
|
|
else
|
|
PARSED_TIMING_STATUS="PARSE_ERROR_$PARSED_FIELD_ERROR"
|
|
if [ "$CLASSIFY_PARSE_ERROR" = "NONE" ]; then
|
|
CLASSIFY_PARSE_ERROR="TIMING_STATUS_$PARSED_FIELD_ERROR"
|
|
fi
|
|
fi
|
|
|
|
# --- Nessuna run puo' essere idonea a una misura prestazionale ---
|
|
MEASUREMENT_ELIGIBILITY="NO"
|
|
|
|
if [ "$CLASSIFY_PARSE_ERROR" != "NONE" ]; then
|
|
BLOCK_REASON="$CLASSIFY_PARSE_ERROR"
|
|
|
|
if [ "$FUNCTIONAL_ESTABLISHED" -eq 1 ]; then
|
|
FINAL_RESULT="INCONCLUSIVE_TIMING_CONTRACT"
|
|
FINAL_RC=22
|
|
fi
|
|
|
|
return 0
|
|
fi
|
|
|
|
if [ "$FUNCTIONAL_ESTABLISHED" -eq 0 ]; then
|
|
# Exit 20/21/altro: il verdetto funzionale prevale, ma i campi
|
|
# realmente presenti sono comunque riportati.
|
|
if [ "$PARSED_FUNCTIONAL_STATUS" = "PASS" ]; then
|
|
BLOCK_REASON="FUNCTIONAL_STATUS_CONFLICT_WITH_EXIT_CODE"
|
|
else
|
|
BLOCK_REASON="FUNCTIONAL_STATUS_NOT_PASS"
|
|
fi
|
|
return 0
|
|
fi
|
|
|
|
if [ "$PARSED_FUNCTIONAL_STATUS" != "PASS" ]; then
|
|
BLOCK_REASON="FUNCTIONAL_STATUS_NOT_PASS"
|
|
FINAL_RESULT="FUNCTIONAL_STATUS_CONFLICT"
|
|
FINAL_RC=23
|
|
return 0
|
|
fi
|
|
|
|
case "$PARSED_TIMING_STATUS" in
|
|
NOT_VALID_*)
|
|
BLOCK_REASON="$PARSED_TIMING_STATUS"
|
|
FINAL_RESULT="FUNCTIONAL_PASS_TIMING_NOT_VALID"
|
|
FINAL_RC=12
|
|
;;
|
|
UNASSESSED_*)
|
|
MEASUREMENT_ELIGIBILITY="UNKNOWN"
|
|
BLOCK_REASON="$PARSED_TIMING_STATUS"
|
|
FINAL_RESULT="FUNCTIONAL_PASS_TIMING_UNASSESSED"
|
|
FINAL_RC=13
|
|
;;
|
|
VALID)
|
|
# H2-05: il vocabolario H1 installato non emette VALID e il
|
|
# PERFORMANCE MEASUREMENT GATE completo non esiste ancora.
|
|
# H2 non autorizza mai da solo l'idoneita' prestazionale.
|
|
BLOCK_REASON="TIMING_STATUS_VALID_NOT_YET_CONTRACTED"
|
|
FINAL_RESULT="INCONCLUSIVE_TIMING_CONTRACT"
|
|
FINAL_RC=22
|
|
;;
|
|
*)
|
|
BLOCK_REASON="TIMING_STATUS_UNRECOGNISED_$PARSED_TIMING_STATUS"
|
|
FINAL_RESULT="INCONCLUSIVE_TIMING_CONTRACT"
|
|
FINAL_RC=22
|
|
;;
|
|
esac
|
|
|
|
return 0
|
|
}
|
|
|
|
# ------------------------------------------------------------------
|
|
# S03 — contratto funzionale, semantico e temporale separato.
|
|
#
|
|
# Exit code candidati (non installati):
|
|
# 14 funzionalita' e semantica PASS, timing non valido
|
|
# 15 funzionalita' e semantica PASS, timing non valutato
|
|
# 20 validatore inconcludente o input mancante
|
|
# 22 contratto S03 non interpretabile / timing VALID non autorizzato
|
|
# 23 conflitto FUNCTIONAL_STATUS
|
|
# 25 conflitto SEMANTIC_STATUS
|
|
# 67 validation.txt non scritto
|
|
# 68 exit code validatore non riconosciuto
|
|
# 69 launcher_summary.txt non scritto
|
|
# ------------------------------------------------------------------
|
|
classify_s03_run() {
|
|
classify_validator_rc="$1"
|
|
classify_tee_rc="$2"
|
|
classify_validation_file="$3"
|
|
|
|
PARSED_FUNCTIONAL_STATUS="NOT_EVALUATED"
|
|
PARSED_SEMANTIC_STATUS="NOT_EVALUATED"
|
|
PARSED_TIMING_STATUS="NOT_EVALUATED"
|
|
PARSED_VALIDATOR_ELIGIBILITY="NOT_EVALUATED"
|
|
MEASUREMENT_ELIGIBILITY="NO"
|
|
BLOCK_REASON="NONE"
|
|
|
|
if [ "$classify_tee_rc" -ne 0 ]; then
|
|
FUNCTIONAL_RESULT="FAIL_VALIDATION_LOG"
|
|
FINAL_RESULT="FAIL_VALIDATION_LOG"
|
|
BLOCK_REASON="VALIDATION_LOG_NOT_WRITTEN"
|
|
FINAL_RC=67
|
|
return 0
|
|
fi
|
|
|
|
case "$classify_validator_rc" in
|
|
0)
|
|
FUNCTIONAL_RESULT="PASS"
|
|
FUNCTIONAL_ESTABLISHED=1
|
|
FINAL_RC=0
|
|
;;
|
|
10)
|
|
FUNCTIONAL_RESULT="PASS_WITH_KNOWN_SHUTDOWN_ANOMALY"
|
|
FUNCTIONAL_ESTABLISHED=1
|
|
FINAL_RC=10
|
|
;;
|
|
11)
|
|
FUNCTIONAL_RESULT="PASS_WITH_UNCLASSIFIED_SHUTDOWN_ANOMALY"
|
|
FUNCTIONAL_ESTABLISHED=1
|
|
FINAL_RC=11
|
|
;;
|
|
20|21)
|
|
FUNCTIONAL_RESULT="INCONCLUSIVE"
|
|
FUNCTIONAL_ESTABLISHED=0
|
|
FINAL_RC=20
|
|
;;
|
|
*)
|
|
FUNCTIONAL_RESULT="FAIL_VALIDATOR"
|
|
FUNCTIONAL_ESTABLISHED=0
|
|
FINAL_RC=68
|
|
;;
|
|
esac
|
|
FINAL_RESULT="$FUNCTIONAL_RESULT"
|
|
|
|
S03_PARSE_ERROR="NONE"
|
|
for field_name in \
|
|
FUNCTIONAL_STATUS \
|
|
SEMANTIC_STATUS \
|
|
TIMING_STATUS \
|
|
MEASUREMENT_ELIGIBILITY
|
|
do
|
|
if parse_validation_field "$field_name" "$classify_validation_file"; then
|
|
case "$field_name" in
|
|
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_VALIDATOR_ELIGIBILITY="$PARSED_FIELD_VALUE"
|
|
;;
|
|
esac
|
|
else
|
|
case "$field_name" in
|
|
FUNCTIONAL_STATUS)
|
|
PARSED_FUNCTIONAL_STATUS="PARSE_ERROR_$PARSED_FIELD_ERROR"
|
|
;;
|
|
SEMANTIC_STATUS)
|
|
PARSED_SEMANTIC_STATUS="PARSE_ERROR_$PARSED_FIELD_ERROR"
|
|
;;
|
|
TIMING_STATUS)
|
|
PARSED_TIMING_STATUS="PARSE_ERROR_$PARSED_FIELD_ERROR"
|
|
;;
|
|
MEASUREMENT_ELIGIBILITY)
|
|
PARSED_VALIDATOR_ELIGIBILITY="PARSE_ERROR_$PARSED_FIELD_ERROR"
|
|
;;
|
|
esac
|
|
if [ "$S03_PARSE_ERROR" = "NONE" ]; then
|
|
S03_PARSE_ERROR="${field_name}_$PARSED_FIELD_ERROR"
|
|
fi
|
|
fi
|
|
done
|
|
|
|
if [ "$S03_PARSE_ERROR" != "NONE" ]; then
|
|
BLOCK_REASON="$S03_PARSE_ERROR"
|
|
FINAL_RESULT="INCONCLUSIVE_S03_CONTRACT"
|
|
if [ "$FUNCTIONAL_ESTABLISHED" -eq 1 ]; then
|
|
FINAL_RC=22
|
|
fi
|
|
return 0
|
|
fi
|
|
|
|
case "$PARSED_FUNCTIONAL_STATUS" in
|
|
PASS|NOT_DEMONSTRATED)
|
|
;;
|
|
*)
|
|
BLOCK_REASON="FUNCTIONAL_STATUS_UNRECOGNISED_$PARSED_FUNCTIONAL_STATUS"
|
|
FINAL_RESULT="INCONCLUSIVE_S03_CONTRACT"
|
|
FINAL_RC=22
|
|
return 0
|
|
;;
|
|
esac
|
|
|
|
case "$PARSED_SEMANTIC_STATUS" in
|
|
PASS|FAIL|NOT_DEMONSTRATED)
|
|
;;
|
|
*)
|
|
BLOCK_REASON="SEMANTIC_STATUS_UNRECOGNISED_$PARSED_SEMANTIC_STATUS"
|
|
FINAL_RESULT="INCONCLUSIVE_S03_CONTRACT"
|
|
FINAL_RC=22
|
|
return 0
|
|
;;
|
|
esac
|
|
|
|
if [ "$PARSED_VALIDATOR_ELIGIBILITY" != "NO" ]; then
|
|
BLOCK_REASON="ELIGIBILITY_CONTRACT_VIOLATION_$PARSED_VALIDATOR_ELIGIBILITY"
|
|
FINAL_RESULT="INCONCLUSIVE_S03_CONTRACT"
|
|
FINAL_RC=22
|
|
return 0
|
|
fi
|
|
|
|
if [ "$FUNCTIONAL_ESTABLISHED" -eq 0 ]; then
|
|
if [ "$PARSED_FUNCTIONAL_STATUS" != "PASS" ]; then
|
|
BLOCK_REASON="FUNCTIONAL_STATUS_NOT_PASS"
|
|
elif [ "$PARSED_SEMANTIC_STATUS" != "PASS" ]; then
|
|
BLOCK_REASON="SEMANTIC_STATUS_$PARSED_SEMANTIC_STATUS"
|
|
else
|
|
BLOCK_REASON="VALIDATOR_EXIT_NOT_PASS"
|
|
fi
|
|
FINAL_RESULT="S03_VALIDATION_INCONCLUSIVE"
|
|
return 0
|
|
fi
|
|
|
|
if [ "$PARSED_FUNCTIONAL_STATUS" != "PASS" ]; then
|
|
BLOCK_REASON="FUNCTIONAL_STATUS_CONFLICT_WITH_EXIT_CODE"
|
|
FINAL_RESULT="FUNCTIONAL_STATUS_CONFLICT"
|
|
FINAL_RC=23
|
|
return 0
|
|
fi
|
|
|
|
if [ "$PARSED_SEMANTIC_STATUS" != "PASS" ]; then
|
|
BLOCK_REASON="SEMANTIC_STATUS_CONFLICT_$PARSED_SEMANTIC_STATUS"
|
|
FINAL_RESULT="SEMANTIC_STATUS_CONFLICT"
|
|
FINAL_RC=25
|
|
return 0
|
|
fi
|
|
|
|
case "$PARSED_TIMING_STATUS" in
|
|
NOT_VALID_*)
|
|
BLOCK_REASON="$PARSED_TIMING_STATUS"
|
|
FINAL_RESULT="FUNCTIONAL_AND_SEMANTIC_PASS_TIMING_NOT_VALID"
|
|
FINAL_RC=14
|
|
;;
|
|
UNASSESSED_*)
|
|
BLOCK_REASON="$PARSED_TIMING_STATUS"
|
|
FINAL_RESULT="FUNCTIONAL_AND_SEMANTIC_PASS_TIMING_UNASSESSED"
|
|
FINAL_RC=15
|
|
;;
|
|
VALID)
|
|
BLOCK_REASON="TIMING_STATUS_VALID_NOT_YET_CONTRACTED"
|
|
FINAL_RESULT="INCONCLUSIVE_TIMING_CONTRACT"
|
|
FINAL_RC=22
|
|
;;
|
|
NOT_EVALUATED)
|
|
BLOCK_REASON="TIMING_STATUS_NOT_EVALUATED"
|
|
FINAL_RESULT="INCONCLUSIVE_TIMING_CONTRACT"
|
|
FINAL_RC=22
|
|
;;
|
|
*)
|
|
BLOCK_REASON="TIMING_STATUS_UNRECOGNISED_$PARSED_TIMING_STATUS"
|
|
FINAL_RESULT="INCONCLUSIVE_TIMING_CONTRACT"
|
|
FINAL_RC=22
|
|
;;
|
|
esac
|
|
|
|
return 0
|
|
}
|
|
|
|
emit_s03_summary() {
|
|
summary_destination="$1"
|
|
|
|
{
|
|
printf "============================================================\n"
|
|
printf "RIEPILOGO LAUNCHER S03 CANDIDATO\n"
|
|
printf "============================================================\n"
|
|
printf "Scenario: S03\n"
|
|
printf "Durata: %s secondi\n" "${duration:-NOT_AVAILABLE}"
|
|
printf "Catena dipendenze: S00 -> S01 -> S02 -> S03\n"
|
|
printf "Stato S00: %s\n" "$S00_STATUS"
|
|
printf "Stato S01: %s\n" "$S01_STATUS"
|
|
printf "Stato S02: %s\n" "$S02_STATUS"
|
|
printf "Stato S03: %s\n" "$S03_STATUS"
|
|
printf "Codice patcher S01: %s\n" "$S01_PATCHER_RC"
|
|
printf "Codice patcher S02: %s\n" "$S02_PATCHER_RC"
|
|
printf "Codice patcher S03: %s\n" "$S03_PATCHER_RC"
|
|
printf "Configurazione: %s\n" "${S03_PATCHED_CONFIG:-NOT_AVAILABLE}"
|
|
printf "Run directory: %s\n" "${RUN_DIR:-NOT_AVAILABLE}"
|
|
printf "Run log: %s\n" "${RUN_LOG:-NOT_AVAILABLE}"
|
|
printf "Validazione: %s\n" "${VALIDATION_LOG:-NOT_AVAILABLE}"
|
|
printf "Codice runner: %s\n" "${RUNNER_RC:-NOT_AVAILABLE}"
|
|
printf "Codice validatore: %s\n" "${VALIDATOR_RC:-NOT_AVAILABLE}"
|
|
printf "Esito storico validatore: %s\n" "${FUNCTIONAL_RESULT:-NOT_AVAILABLE}"
|
|
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=%s\n" "$MEASUREMENT_ELIGIBILITY"
|
|
printf "BLOCK_REASON=%s\n" "$BLOCK_REASON"
|
|
printf "FINAL_RESULT=%s\n" "$FINAL_RESULT"
|
|
printf "FINAL_RC=%s\n" "$FINAL_RC"
|
|
} | tee "$summary_destination"
|
|
|
|
summary_codes=("${PIPESTATUS[@]}")
|
|
if [ "${summary_codes[1]}" -ne 0 ]; then
|
|
return 69
|
|
fi
|
|
return 0
|
|
}
|
|
|
|
run_prepared_s03() {
|
|
duration="$1"
|
|
|
|
check_executable "$RUNNER" "Common runner"
|
|
check_executable "$VALIDATOR_S03" "Validatore S03"
|
|
|
|
CAPTURE="$(mktemp "${TMPDIR:-/tmp}/marte_benchmark_launcher_s03.XXXXXX")" ||
|
|
return 60
|
|
trap 'rm -f -- "$CAPTURE"' EXIT HUP INT TERM
|
|
|
|
printf "\n============================================================\n"
|
|
printf "ESECUZIONE COMMON RUNNER — S03\n"
|
|
printf "============================================================\n"
|
|
|
|
"$RUNNER" \
|
|
"S03_launcher" \
|
|
"$S03_PATCHED_CONFIG" \
|
|
"State1" \
|
|
"$duration" \
|
|
2>&1 | tee "$CAPTURE"
|
|
|
|
RUNNER_CODES=("${PIPESTATUS[@]}")
|
|
RUNNER_RC="${RUNNER_CODES[0]}"
|
|
CAPTURE_TEE_RC="${RUNNER_CODES[1]}"
|
|
|
|
if [ "$RUNNER_RC" -ne 0 ]; then
|
|
printf "RISULTATO FINALE: FAIL_RUNNER\n"
|
|
return 61
|
|
fi
|
|
if [ "$CAPTURE_TEE_RC" -ne 0 ]; then
|
|
printf "RISULTATO FINALE: FAIL_LAUNCHER_LOG\n"
|
|
return 62
|
|
fi
|
|
|
|
RUN_DIR="$(sed -n 's/^RUN_DIR=//p' "$CAPTURE" | tail -n 1)"
|
|
if [ -z "$RUN_DIR" ]; then
|
|
printf "ERRORE: RUN_DIR non individuata.\n" >&2
|
|
return 63
|
|
fi
|
|
if [ ! -d "$RUN_DIR" ]; then
|
|
printf "ERRORE: directory di run assente: %s\n" "$RUN_DIR" >&2
|
|
return 64
|
|
fi
|
|
|
|
RUN_LOG="$RUN_DIR/run.log"
|
|
VALIDATION_LOG="$RUN_DIR/validation.txt"
|
|
LAUNCHER_SUMMARY="$RUN_DIR/launcher_summary.txt"
|
|
|
|
if [ ! -f "$RUN_LOG" ]; then
|
|
printf "ERRORE: run.log assente: %s\n" "$RUN_LOG" >&2
|
|
return 65
|
|
fi
|
|
|
|
printf "\n============================================================\n"
|
|
printf "VALIDAZIONE S03\n"
|
|
printf "============================================================\n"
|
|
|
|
timeout 20s "$VALIDATOR_S03" "$RUN_DIR" 2>&1 | tee "$VALIDATION_LOG"
|
|
VALIDATION_CODES=("${PIPESTATUS[@]}")
|
|
VALIDATOR_RC="${VALIDATION_CODES[0]}"
|
|
VALIDATION_TEE_RC="${VALIDATION_CODES[1]}"
|
|
|
|
classify_s03_run "$VALIDATOR_RC" "$VALIDATION_TEE_RC" "$VALIDATION_LOG"
|
|
|
|
if ! emit_s03_summary "$LAUNCHER_SUMMARY"; then
|
|
FINAL_RESULT="FAIL_LAUNCHER_SUMMARY"
|
|
FINAL_RC=69
|
|
printf "ERRORE: riepilogo launcher S03 non scritto: %s\n" \
|
|
"$LAUNCHER_SUMMARY" >&2
|
|
fi
|
|
|
|
printf "\nRISULTATO FINALE: %s\n" "$FINAL_RESULT"
|
|
printf "Riepilogo: %s\n" "$LAUNCHER_SUMMARY"
|
|
|
|
rm -f -- "$CAPTURE"
|
|
trap - EXIT HUP INT TERM
|
|
return "$FINAL_RC"
|
|
}
|
|
|
|
run_prepared_scenario() {
|
|
scenario_name="$1"
|
|
scenario_id="$2"
|
|
config_file="$3"
|
|
validator="$4"
|
|
validator_input_mode="$5"
|
|
duration="$6"
|
|
dependency_chain="$7"
|
|
timing_contract="$8"
|
|
|
|
check_executable "$RUNNER" "Common runner"
|
|
check_executable "$validator" "Validatore $scenario_name"
|
|
|
|
CAPTURE="$(
|
|
mktemp "${TMPDIR:-/tmp}/marte_benchmark_launcher.XXXXXX"
|
|
)" || return 60
|
|
|
|
trap 'rm -f "$CAPTURE"' EXIT HUP INT TERM
|
|
|
|
printf "\n============================================================\n"
|
|
printf "ESECUZIONE COMMON RUNNER — %s\n" "$scenario_name"
|
|
printf "============================================================\n"
|
|
|
|
"$RUNNER" \
|
|
"${scenario_id}_launcher" \
|
|
"$config_file" \
|
|
"State1" \
|
|
"$duration" \
|
|
2>&1 | tee "$CAPTURE"
|
|
|
|
RUNNER_CODES=("${PIPESTATUS[@]}")
|
|
RUNNER_RC="${RUNNER_CODES[0]}"
|
|
CAPTURE_TEE_RC="${RUNNER_CODES[1]}"
|
|
|
|
printf "\nCodice common runner: %s\n" "$RUNNER_RC"
|
|
printf "Codice tee launcher: %s\n" "$CAPTURE_TEE_RC"
|
|
|
|
if [ "$RUNNER_RC" -ne 0 ]; then
|
|
printf "RISULTATO FINALE: FAIL_RUNNER\n"
|
|
return 61
|
|
fi
|
|
|
|
if [ "$CAPTURE_TEE_RC" -ne 0 ]; then
|
|
printf "RISULTATO FINALE: FAIL_LAUNCHER_LOG\n"
|
|
return 62
|
|
fi
|
|
|
|
RUN_DIR="$(
|
|
sed -n 's/^RUN_DIR=//p' "$CAPTURE" |
|
|
tail -n 1
|
|
)"
|
|
|
|
if [ -z "$RUN_DIR" ]; then
|
|
printf "ERRORE: RUN_DIR non individuata.\n" >&2
|
|
return 63
|
|
fi
|
|
|
|
if [ ! -d "$RUN_DIR" ]; then
|
|
printf "ERRORE: directory di run assente: %s\n" "$RUN_DIR" >&2
|
|
return 64
|
|
fi
|
|
|
|
RUN_LOG="$RUN_DIR/run.log"
|
|
VALIDATION_LOG="$RUN_DIR/validation.txt"
|
|
LAUNCHER_SUMMARY="$RUN_DIR/launcher_summary.txt"
|
|
|
|
if [ ! -f "$RUN_LOG" ]; then
|
|
printf "ERRORE: run.log assente: %s\n" "$RUN_LOG" >&2
|
|
return 65
|
|
fi
|
|
|
|
case "$validator_input_mode" in
|
|
run_log)
|
|
VALIDATOR_INPUT="$RUN_LOG"
|
|
;;
|
|
run_dir)
|
|
VALIDATOR_INPUT="$RUN_DIR"
|
|
;;
|
|
*)
|
|
printf "ERRORE: modalità input validatore non riconosciuta: %s\n" \
|
|
"$validator_input_mode" >&2
|
|
return 66
|
|
;;
|
|
esac
|
|
|
|
printf "\n============================================================\n"
|
|
printf "VALIDAZIONE %s\n" "$scenario_name"
|
|
printf "============================================================\n"
|
|
|
|
timeout 15s "$validator" "$VALIDATOR_INPUT" 2>&1 |
|
|
tee "$VALIDATION_LOG"
|
|
|
|
VALIDATION_CODES=("${PIPESTATUS[@]}")
|
|
VALIDATOR_RC="${VALIDATION_CODES[0]}"
|
|
VALIDATION_TEE_RC="${VALIDATION_CODES[1]}"
|
|
|
|
classify_run \
|
|
"$VALIDATOR_RC" \
|
|
"$VALIDATION_TEE_RC" \
|
|
"$VALIDATION_LOG" \
|
|
"$timing_contract"
|
|
|
|
{
|
|
printf "============================================================\n"
|
|
printf "RIEPILOGO LAUNCHER\n"
|
|
printf "============================================================\n"
|
|
printf "Scenario: %s\n" "$scenario_name"
|
|
printf "Durata: %s secondi\n" "$duration"
|
|
printf "Catena dipendenze: %s\n" "$dependency_chain"
|
|
printf "Stato S00: %s\n" "$S00_STATUS"
|
|
printf "Stato S01: %s\n" "$S01_STATUS"
|
|
printf "Stato S02: %s\n" "$S02_STATUS"
|
|
printf "Codice patcher S01: %s\n" "$S01_PATCHER_RC"
|
|
printf "Codice patcher S02: %s\n" "$S02_PATCHER_RC"
|
|
printf "Configurazione: %s\n" "$config_file"
|
|
printf "Run directory: %s\n" "$RUN_DIR"
|
|
printf "Run log: %s\n" "$RUN_LOG"
|
|
printf "Validazione: %s\n" "$VALIDATION_LOG"
|
|
printf "Codice runner: %s\n" "$RUNNER_RC"
|
|
printf "Codice validatore: %s\n" "$VALIDATOR_RC"
|
|
printf "Esito funzionale: %s\n" "$FUNCTIONAL_RESULT"
|
|
printf "FUNCTIONAL_STATUS: %s\n" "$PARSED_FUNCTIONAL_STATUS"
|
|
printf "TIMING_STATUS: %s\n" "$PARSED_TIMING_STATUS"
|
|
printf "MEASUREMENT_ELIGIBILITY: %s\n" "$MEASUREMENT_ELIGIBILITY"
|
|
printf "Motivo blocco: %s\n" "$BLOCK_REASON"
|
|
printf "Codice finale launcher: %s\n" "$FINAL_RC"
|
|
printf "Risultato finale: %s\n" "$FINAL_RESULT"
|
|
} | tee "$LAUNCHER_SUMMARY"
|
|
|
|
SUMMARY_CODES=("${PIPESTATUS[@]}")
|
|
SUMMARY_TEE_RC="${SUMMARY_CODES[1]}"
|
|
|
|
# H2-06: il riepilogo e' il documento che porta il nuovo contratto.
|
|
# Se non e' stato scritto, il risultato non e' verificabile a posteriori
|
|
# e non puo' essere presentato come esito valido.
|
|
if [ "$SUMMARY_TEE_RC" -ne 0 ]; then
|
|
printf "ERRORE: riepilogo launcher non scritto: %s\n" \
|
|
"$LAUNCHER_SUMMARY" >&2
|
|
FINAL_RESULT="FAIL_LAUNCHER_SUMMARY"
|
|
FINAL_RC=69
|
|
fi
|
|
|
|
printf "\nRISULTATO FINALE: %s\n" "$FINAL_RESULT"
|
|
printf "Riepilogo: %s\n" "$LAUNCHER_SUMMARY"
|
|
|
|
rm -f -- "$CAPTURE"
|
|
trap - EXIT HUP INT TERM
|
|
|
|
return "$FINAL_RC"
|
|
}
|
|
|
|
run_s01() {
|
|
duration="$1"
|
|
|
|
if ! validate_duration "$duration"; then
|
|
return 31
|
|
fi
|
|
|
|
S00_STATUS="NOT_CHECKED"
|
|
S01_STATUS="NOT_CHECKED"
|
|
S02_STATUS="NOT_REQUIRED"
|
|
S03_STATUS="NOT_REQUIRED"
|
|
S01_PATCHER_RC="NOT_RUN"
|
|
S02_PATCHER_RC="NOT_REQUIRED"
|
|
S03_PATCHER_RC="NOT_REQUIRED"
|
|
|
|
printf "============================================================\n"
|
|
printf "SCENARIO S01 — TIMING DISPLAY\n"
|
|
printf "============================================================\n"
|
|
printf "Durata: %s secondi\n" "$duration"
|
|
printf "Catena automatica: S00 -> S01\n"
|
|
|
|
ensure_s01
|
|
PREPARE_RC=$?
|
|
|
|
if [ "$PREPARE_RC" -ne 0 ]; then
|
|
printf "RISULTATO FINALE: FAIL_DEPENDENCY_CHAIN\n"
|
|
return "$PREPARE_RC"
|
|
fi
|
|
|
|
run_prepared_scenario \
|
|
"S01" \
|
|
"S01" \
|
|
"$S01_PATCHED_CONFIG" \
|
|
"$VALIDATOR_S01" \
|
|
"run_log" \
|
|
"$duration" \
|
|
"S00 -> S01" \
|
|
"not_applicable"
|
|
}
|
|
|
|
run_s02() {
|
|
duration="$1"
|
|
|
|
if ! validate_duration "$duration"; then
|
|
return 31
|
|
fi
|
|
|
|
S00_STATUS="NOT_CHECKED"
|
|
S01_STATUS="NOT_CHECKED"
|
|
S02_STATUS="NOT_CHECKED"
|
|
S03_STATUS="NOT_REQUIRED"
|
|
S01_PATCHER_RC="NOT_RUN"
|
|
S02_PATCHER_RC="NOT_RUN"
|
|
S03_PATCHER_RC="NOT_REQUIRED"
|
|
|
|
printf "============================================================\n"
|
|
printf "SCENARIO S02 — BINARY RECORDING\n"
|
|
printf "============================================================\n"
|
|
printf "Durata: %s secondi\n" "$duration"
|
|
printf "Catena automatica: S00 -> S01 -> S02\n"
|
|
|
|
ensure_s02
|
|
PREPARE_RC=$?
|
|
|
|
if [ "$PREPARE_RC" -ne 0 ]; then
|
|
printf "RISULTATO FINALE: FAIL_DEPENDENCY_CHAIN\n"
|
|
return "$PREPARE_RC"
|
|
fi
|
|
|
|
run_prepared_scenario \
|
|
"S02" \
|
|
"S02" \
|
|
"$S02_PATCHED_CONFIG" \
|
|
"$VALIDATOR_S02" \
|
|
"run_dir" \
|
|
"$duration" \
|
|
"S00 -> S01 -> S02" \
|
|
"required"
|
|
}
|
|
|
|
run_s03() {
|
|
duration="$1"
|
|
|
|
if ! validate_duration "$duration"; then
|
|
return 31
|
|
fi
|
|
|
|
S00_STATUS="NOT_CHECKED"
|
|
S01_STATUS="NOT_CHECKED"
|
|
S02_STATUS="NOT_CHECKED"
|
|
S03_STATUS="NOT_CHECKED"
|
|
S01_PATCHER_RC="NOT_RUN"
|
|
S02_PATCHER_RC="NOT_RUN"
|
|
S03_PATCHER_RC="NOT_RUN"
|
|
|
|
printf "============================================================\n"
|
|
printf "SCENARIO S03 — SENTINELLE E VALIDAZIONE SEMANTICA\n"
|
|
printf "============================================================\n"
|
|
printf "Durata: %s secondi\n" "$duration"
|
|
printf "Catena automatica: S00 -> S01 -> S02 -> S03\n"
|
|
printf "Gate prestazionale: CHIUSO\n"
|
|
|
|
ensure_s03
|
|
PREPARE_RC=$?
|
|
|
|
if [ "$PREPARE_RC" -ne 0 ]; then
|
|
printf "RISULTATO FINALE: FAIL_DEPENDENCY_CHAIN\n"
|
|
return "$PREPARE_RC"
|
|
fi
|
|
|
|
run_prepared_s03 "$duration"
|
|
}
|
|
|
|
ask_duration_and_run() {
|
|
scenario="$1"
|
|
|
|
printf "Durata in secondi [%s]: " "$DEFAULT_DURATION_SECONDS"
|
|
|
|
if ! IFS= read -r duration; then
|
|
printf "\nERRORE: input non disponibile.\n" >&2
|
|
return 2
|
|
fi
|
|
|
|
if [ -z "$duration" ]; then
|
|
duration="$DEFAULT_DURATION_SECONDS"
|
|
fi
|
|
|
|
case "$scenario" in
|
|
S01)
|
|
run_s01 "$duration"
|
|
;;
|
|
S02)
|
|
run_s02 "$duration"
|
|
;;
|
|
S03)
|
|
run_s03 "$duration"
|
|
;;
|
|
*)
|
|
printf "ERRORE: scenario interno non riconosciuto: %s\n" "$scenario" >&2
|
|
return 2
|
|
;;
|
|
esac
|
|
}
|
|
|
|
interactive_menu() {
|
|
printf "============================================================\n"
|
|
printf "MARTe2 BENCHMARK SUITE\n"
|
|
printf "============================================================\n"
|
|
printf "1) S01 — catena automatica S00 -> S01, esegue e valida CycleTime\n"
|
|
printf "2) S02 — catena automatica S00 -> S01 -> S02, registra e valida il binario\n"
|
|
printf "3) S03 — catena S00 -> S01 -> S02 -> S03, valida le sentinelle\n"
|
|
printf "0) Esci\n"
|
|
printf "\nSelezione: "
|
|
|
|
if ! IFS= read -r selection; then
|
|
printf "\nERRORE: input non disponibile.\n" >&2
|
|
return 2
|
|
fi
|
|
|
|
case "$selection" in
|
|
1|S01|s01)
|
|
ask_duration_and_run "S01"
|
|
;;
|
|
2|S02|s02)
|
|
ask_duration_and_run "S02"
|
|
;;
|
|
3|S03|s03)
|
|
ask_duration_and_run "S03"
|
|
;;
|
|
0)
|
|
printf "Uscita.\n"
|
|
return 0
|
|
;;
|
|
*)
|
|
printf "Selezione non valida: %s\n" "$selection" >&2
|
|
return 2
|
|
;;
|
|
esac
|
|
}
|
|
|
|
# S02-H2: consente di caricare le sole funzioni (per i test) senza
|
|
# eseguire il menu interattivo o il dispatch degli argomenti.
|
|
#
|
|
# La modalita' e' accettata SOLTANTO quando il file viene caricato con
|
|
# "source". Se il launcher viene eseguito direttamente con la variabile
|
|
# impostata, deve fallire in modo esplicito: un exit 0 senza avere
|
|
# eseguito alcuna run sarebbe un falso successo.
|
|
if [ "${MARTE_LAUNCHER_LIB_ONLY:-0}" = "1" ]; then
|
|
if [ "${BASH_SOURCE[0]}" != "$0" ]; then
|
|
return 0
|
|
fi
|
|
|
|
printf "ERRORE: MARTE_LAUNCHER_LIB_ONLY=1 e' ammesso solo con 'source'.\n" >&2
|
|
printf "Il launcher e' stato eseguito direttamente: nessuna run avviata.\n" >&2
|
|
exit 3
|
|
fi
|
|
|
|
case "$#" in
|
|
0)
|
|
interactive_menu
|
|
exit $?
|
|
;;
|
|
1)
|
|
case "$1" in
|
|
S01|s01)
|
|
run_s01 "$DEFAULT_DURATION_SECONDS"
|
|
exit $?
|
|
;;
|
|
S02|s02)
|
|
run_s02 "$DEFAULT_DURATION_SECONDS"
|
|
exit $?
|
|
;;
|
|
S03|s03)
|
|
run_s03 "$DEFAULT_DURATION_SECONDS"
|
|
exit $?
|
|
;;
|
|
-h|--help)
|
|
print_usage
|
|
exit 0
|
|
;;
|
|
*)
|
|
print_usage >&2
|
|
exit 2
|
|
;;
|
|
esac
|
|
;;
|
|
2)
|
|
case "$1" in
|
|
S01|s01)
|
|
run_s01 "$2"
|
|
exit $?
|
|
;;
|
|
S02|s02)
|
|
run_s02 "$2"
|
|
exit $?
|
|
;;
|
|
S03|s03)
|
|
run_s03 "$2"
|
|
exit $?
|
|
;;
|
|
*)
|
|
print_usage >&2
|
|
exit 2
|
|
;;
|
|
esac
|
|
;;
|
|
*)
|
|
print_usage >&2
|
|
exit 2
|
|
;;
|
|
esac
|