S03-H3 CLOSED baseline

This commit is contained in:
2026-08-27 11:12:22 +02:00
commit 4b5fbb6c23
30 changed files with 10130 additions and 0 deletions
+347
View File
@@ -0,0 +1,347 @@
#!/usr/bin/env bash
set -u
EXPECTED_S03_CONFIG_SHA256="0f8916735ff67a9be2b167b52f147687fe131a063f410a81bfbf3bf9ff65f1e4"
MINIMUM_SAMPLES="50"
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PARSER="$SCRIPT_DIR/parse_s03_binary.py"
FUNCTIONAL_STATUS="NOT_DEMONSTRATED"
SEMANTIC_STATUS="NOT_DEMONSTRATED"
TIMING_STATUS="NOT_EVALUATED"
MEASUREMENT_ELIGIBILITY="NO"
emit_contract() {
printf "FUNCTIONAL_STATUS=%s\n" "$FUNCTIONAL_STATUS"
printf "SEMANTIC_STATUS=%s\n" "$SEMANTIC_STATUS"
printf "TIMING_STATUS=%s\n" "$TIMING_STATUS"
printf "MEASUREMENT_ELIGIBILITY=%s\n" "$MEASUREMENT_ELIGIBILITY"
}
fail_early() {
code="$1"
shift
printf "[NON DIMOSTRATO] %s\n" "$*" >&2
emit_contract
printf "VALIDATION_RESULT=FAIL_REQUIRED_INPUT\n"
exit "$code"
}
if [ "$#" -ne 1 ]; then
printf "Uso: %s <directory-run|run.log>\n" "$0" >&2
emit_contract
exit 2
fi
INPUT_PATH="$1"
if [ -d "$INPUT_PATH" ]; then
RUN_DIR="$(cd "$INPUT_PATH" && pwd)"
RUN_LOG="$RUN_DIR/run.log"
elif [ -f "$INPUT_PATH" ]; then
RUN_LOG="$(cd "$(dirname "$INPUT_PATH")" && pwd)/$(basename "$INPUT_PATH")"
RUN_DIR="$(dirname "$RUN_LOG")"
else
fail_early 21 "Percorso di validazione non trovato: $INPUT_PATH"
fi
RUN_CONFIG="$RUN_DIR/configuration.marte"
OUTPUT_FILE="$RUN_DIR/s03_output.bin"
RUNNER_SUMMARY="$RUN_DIR/runner_summary.txt"
RUN_HASHES="$RUN_DIR/hashes.sha256"
if [ ! -x "$PARSER" ]; then
fail_early 21 "Parser S03 assente o non eseguibile: $PARSER"
fi
for required_file in \
"$RUN_LOG" \
"$RUN_CONFIG" \
"$OUTPUT_FILE" \
"$RUNNER_SUMMARY" \
"$RUN_HASHES"
do
if [ ! -f "$required_file" ]; then
fail_early 21 "File richiesto assente: $required_file"
fi
done
if [ ! -s "$RUN_HASHES" ]; then
fail_early 21 "Manifest hash assente o vuoto: $RUN_HASHES"
fi
count_lines() {
pattern="$1"
file="$2"
grep -Ec "$pattern" "$file" || true
}
START_LINES="$(count_lines '^\[Information - RealTimeLoader\.cpp:[0-9]+\]: Started application in state State1[[:space:]]*$' "$RUN_LOG")"
APPLICATION_START_LINES="$(count_lines '^\[Information - MARTeApp\.cpp:[0-9]+\]: Application starting[[:space:]]*$' "$RUN_LOG")"
FILE_OPEN_LINES="$(count_lines '^\[Information - FileWriter\.cpp:[0-9]+\]: Going to open file with name ' "$RUN_LOG")"
SIGINT_LINES="$(count_lines '^\[Information - Bootstrap\.cpp:[0-9]+\]: Application recieved SIGINT\.[[:space:]]*$' "$RUN_LOG")"
STOP_OK_LINES="$(count_lines '^\[Information - Bootstrap\.cpp:[0-9]+\]: Application successfully stopped\.[[:space:]]*$' "$RUN_LOG")"
TERMINATED_LINES="$(count_lines '^\[NoError - MARTeApp\.cpp:[0-9]+\]: Application terminated[[:space:]]*$' "$RUN_LOG")"
STARTUP_ERROR_LINES="$(count_lines 'Failed dlopen|Failed CreateByName|Failed to Initialise object|Failed to initialise the ObjectRegistryDatabase|Could not Initialise the loader' "$RUN_LOG")"
FATAL_ERROR_LINES="$(count_lines '^\[FatalError ' "$RUN_LOG")"
OS_ERROR_LINES="$(count_lines '^\[OSError ' "$RUN_LOG")"
ERROR_LINES="$(count_lines '^\[Error ' "$RUN_LOG")"
INITIALISATION_ERROR_LINES="$(count_lines '^\[InitialisationEr ' "$RUN_LOG")"
WARNING_LINES="$(count_lines '^\[Warning ' "$RUN_LOG")"
PRIORITY_CLIP_LINES="$(count_lines '^\[Warning - Threads\.cpp:[0-9]+\]: Requested a thread priority that is higher than ' "$RUN_LOG")"
PRIORITY_FAIL_LINES="$(count_lines '^\[Warning - Threads\.cpp:[0-9]+\]: Failed to change the thread priority' "$RUN_LOG")"
LINUX_TIMER_DEFAULT_WARNING_LINES="$(count_lines '^\[Warning - LinuxTimer\.cpp:[0-9]+\]: (ExecutionMode|CPUMask|StackSize) not specified using: ' "$RUN_LOG")"
CONFIG_DB_NODE_WARNING_LINES="$(count_lines '^\[Warning - MARTeApp\.cpp:[0-9]+\]: \[ConfigurationDatabaseNode\] - instances: [0-9]+[[:space:]]*$' "$RUN_LOG")"
UNCLASSIFIED_WARNING_LINES=$((
WARNING_LINES -
PRIORITY_CLIP_LINES -
PRIORITY_FAIL_LINES -
LINUX_TIMER_DEFAULT_WARNING_LINES -
CONFIG_DB_NODE_WARNING_LINES
))
if [ "$UNCLASSIFIED_WARNING_LINES" -lt 0 ]; then
UNCLASSIFIED_WARNING_LINES=0
fi
DOUBLE_STOP_LINES="$(count_lines '^\[FatalError - RealTimeApplication\.cpp:[0-9]+\]: Could not stop the RealTimeApplication\. Was it ever started\?[[:space:]]*$' "$RUN_LOG")"
ASYNC_EVENTSEM_CLOSE_LINES="$(count_lines '^\[FatalError - MemoryMapAsyncOutputBroker\.cpp:[0-9]+\]: Could not Close the EventSem\.[[:space:]]*$' "$RUN_LOG")"
PTHREAD_MUTEX_DESTROY_LINES="$(count_lines '^\[OSError - EventSem\.cpp:[0-9]+\]: Error: pthread_mutex_destroy\(\)[[:space:]]*$' "$RUN_LOG")"
UNCLASSIFIED_FATAL_LINES=$((FATAL_ERROR_LINES - DOUBLE_STOP_LINES - ASYNC_EVENTSEM_CLOSE_LINES))
UNCLASSIFIED_OS_ERROR_LINES=$((OS_ERROR_LINES - PTHREAD_MUTEX_DESTROY_LINES))
if [ "$UNCLASSIFIED_FATAL_LINES" -lt 0 ]; then
UNCLASSIFIED_FATAL_LINES=0
fi
if [ "$UNCLASSIFIED_OS_ERROR_LINES" -lt 0 ]; then
UNCLASSIFIED_OS_ERROR_LINES=0
fi
CONFIG_REPORT="$(mktemp "${TMPDIR:-/tmp}/s03_validator_config_XXXXXX.log")" || exit 22
BINARY_REPORT="$(mktemp "${TMPDIR:-/tmp}/s03_validator_binary_XXXXXX.log")" || exit 22
HASH_REPORT="$(mktemp "${TMPDIR:-/tmp}/s03_validator_hashes_XXXXXX.log")" || exit 22
trap 'rm -f -- "$CONFIG_REPORT" "$BINARY_REPORT" "$HASH_REPORT"' EXIT HUP INT TERM
EXPECTED_FILENAME="$RUN_DIR/s03_output.bin"
PYTHONHASHSEED=0 python3 - \
"$RUN_CONFIG" \
"$EXPECTED_FILENAME" \
"$EXPECTED_S03_CONFIG_SHA256" \
>"$CONFIG_REPORT" 2>&1 <<'PY_S03_CONFIG'
import hashlib
import sys
from pathlib import Path
config_path = Path(sys.argv[1])
expected_filename = sys.argv[2]
expected_hash = sys.argv[3]
text = config_path.read_text(encoding="utf-8")
expected_line = f' Filename = "{expected_filename}"'
placeholder_line = ' Filename = "__MARTE_RUN_DIR__/s03_output.bin"'
filename_count = sum(1 for line in text.splitlines() if line == expected_line)
placeholder_count = text.count("__MARTE_RUN_DIR__")
canonical = text.replace(expected_line, placeholder_line, 1)
canonical_hash = hashlib.sha256(canonical.encode("utf-8")).hexdigest()
checks = {
"EXPECTED_FILENAME_COUNT": filename_count,
"PLACEHOLDER_COUNT": placeholder_count,
"FILEWRITER_CLASS_COUNT": text.count("Class = FileDataSource::FileWriter"),
"PLAIN_FILEWRITER_CLASS_COUNT": text.count("Class = FileWriter"),
"CONSTANT_GAM_COUNT": text.count("Class = ConstantGAM"),
"SENTINEL_SCALAR_A_DECLARATION_COUNT": text.count("SentinelScalarA ="),
"SENTINEL_SCALAR_B_DECLARATION_COUNT": text.count("SentinelScalarB ="),
"SENTINEL_VECTOR_DECLARATION_COUNT": text.count("SentinelVector ="),
"VECTOR_DIMENSION_COUNT": text.count("NumberOfDimensions = 1"),
"VECTOR_CARDINALITY_COUNT": text.count("NumberOfElements = 3"),
"THREAD_ORDER_COUNT": text.count(
"Functions = {GAMTimer SentinelProducer GAMDisplay IOGAM_Writer}"
),
}
expected_checks = {
"EXPECTED_FILENAME_COUNT": 1,
"PLACEHOLDER_COUNT": 0,
"FILEWRITER_CLASS_COUNT": 1,
"PLAIN_FILEWRITER_CLASS_COUNT": 0,
"CONSTANT_GAM_COUNT": 1,
"SENTINEL_SCALAR_A_DECLARATION_COUNT": 4,
"SENTINEL_SCALAR_B_DECLARATION_COUNT": 4,
"SENTINEL_VECTOR_DECLARATION_COUNT": 4,
"VECTOR_DIMENSION_COUNT": 4,
"VECTOR_CARDINALITY_COUNT": 4,
"THREAD_ORDER_COUNT": 1,
}
for key in sorted(checks):
print(f"{key}={checks[key]}")
print(f"CANONICAL_CONFIG_SHA256={canonical_hash}")
print(f"EXPECTED_CONFIG_SHA256={expected_hash}")
if checks == expected_checks and canonical_hash == expected_hash:
print("CONFIG_STATUS=PASS")
sys.exit(0)
print("CONFIG_STATUS=FAIL")
sys.exit(1)
PY_S03_CONFIG
CONFIG_RC=$?
PYTHONHASHSEED=0 "$PARSER" "$OUTPUT_FILE" --min-samples "$MINIMUM_SAMPLES" \
>"$BINARY_REPORT" 2>&1
PARSER_RC=$?
sha256sum -c --strict "$RUN_HASHES" >"$HASH_REPORT" 2>&1
HASH_RC=$?
report_value() {
key="$1"
file="$2"
sed -n "s/^${key}=//p" "$file" | tail -n 1
}
CONFIG_STATUS="$(report_value CONFIG_STATUS "$CONFIG_REPORT")"
FUNCTIONAL_BINARY_STATUS="$(report_value FUNCTIONAL_BINARY_STATUS "$BINARY_REPORT")"
SEMANTIC_BINARY_STATUS="$(report_value SEMANTIC_BINARY_STATUS "$BINARY_REPORT")"
BINARY_STATUS="$(report_value BINARY_STATUS "$BINARY_REPORT")"
FIRST_ERROR_CODE="$(report_value FIRST_ERROR_CODE "$BINARY_REPORT")"
COMPLETE_SAMPLE_COUNT="$(report_value COMPLETE_SAMPLE_COUNT "$BINARY_REPORT")"
HEADER_BYTES="$(report_value OBSERVED_HEADER_BYTES "$BINARY_REPORT")"
RECORD_BYTES="$(report_value OBSERVED_RECORD_BYTES_FROM_HEADER "$BINARY_REPORT")"
PAYLOAD_BYTES="$(report_value PAYLOAD_BYTES "$BINARY_REPORT")"
PAYLOAD_REMAINDER_BYTES="$(report_value PAYLOAD_REMAINDER_BYTES "$BINARY_REPORT")"
MARTE_EXIT_CODE="$(sed -n 's/^Exit code MARTe:[[:space:]]*//p' "$RUNNER_SUMMARY" | tail -n 1)"
TEE_EXIT_CODE="$(sed -n 's/^Exit code tee:[[:space:]]*//p' "$RUNNER_SUMMARY" | tail -n 1)"
if [ -z "$MARTE_EXIT_CODE" ]; then
MARTE_EXIT_CODE="NOT_AVAILABLE"
fi
if [ -z "$TEE_EXIT_CODE" ]; then
TEE_EXIT_CODE="NOT_AVAILABLE"
fi
case "$MARTE_EXIT_CODE" in
137)
TIMING_STATUS="NOT_VALID_EXIT_137_SIGKILL"
;;
*)
if [ "$PRIORITY_FAIL_LINES" -ge 1 ]; then
TIMING_STATUS="NOT_VALID_PRIORITY_NOT_APPLIED"
else
TIMING_STATUS="UNASSESSED_DT_SEMANTICS"
fi
;;
esac
FUNCTIONAL_OK=0
if [ "$START_LINES" -ge 1 ] &&
[ "$APPLICATION_START_LINES" -ge 1 ] &&
[ "$FILE_OPEN_LINES" -ge 1 ] &&
[ "$STARTUP_ERROR_LINES" -eq 0 ] &&
[ "$CONFIG_RC" -eq 0 ] &&
[ "$CONFIG_STATUS" = "PASS" ] &&
[ "$FUNCTIONAL_BINARY_STATUS" = "PASS" ] &&
[ "$HASH_RC" -eq 0 ] &&
[ "$TEE_EXIT_CODE" = "0" ] &&
[ "$UNCLASSIFIED_FATAL_LINES" -eq 0 ] &&
[ "$UNCLASSIFIED_OS_ERROR_LINES" -eq 0 ] &&
[ "$ERROR_LINES" -eq 0 ] &&
[ "$INITIALISATION_ERROR_LINES" -eq 0 ]; then
FUNCTIONAL_OK=1
fi
if [ "$FUNCTIONAL_OK" -eq 1 ]; then
FUNCTIONAL_STATUS="PASS"
fi
if [ "$CONFIG_STATUS" = "PASS" ] && [ "$SEMANTIC_BINARY_STATUS" = "PASS" ]; then
SEMANTIC_STATUS="PASS"
elif [ "$SEMANTIC_BINARY_STATUS" = "FAIL" ]; then
SEMANTIC_STATUS="FAIL"
else
SEMANTIC_STATUS="NOT_DEMONSTRATED"
fi
printf "============================================================\n"
printf "VALIDAZIONE S03 - SENTINELLE SEMANTICHE\n"
printf "============================================================\n"
printf "Run directory: %s\n" "$RUN_DIR"
printf "Configurazione: %s\n" "$RUN_CONFIG"
printf "File binario: %s\n" "$OUTPUT_FILE"
printf "Manifest hash: %s\n" "$RUN_HASHES"
printf "Configurazione canonica: %s (rc=%s)\n" "${CONFIG_STATUS:-NOT_AVAILABLE}" "$CONFIG_RC"
printf "Verifica manifest hash: %s (rc=%s)\n" "$( [ "$HASH_RC" -eq 0 ] && printf PASS || printf FAIL )" "$HASH_RC"
printf "Parser binario: %s (rc=%s)\n" "${BINARY_STATUS:-NOT_AVAILABLE}" "$PARSER_RC"
printf "Primo errore parser: %s\n" "${FIRST_ERROR_CODE:-NOT_AVAILABLE}"
printf "Header osservato: %s byte\n" "${HEADER_BYTES:-NOT_AVAILABLE}"
printf "Record da header: %s byte\n" "${RECORD_BYTES:-NOT_AVAILABLE}"
printf "Payload: %s byte\n" "${PAYLOAD_BYTES:-NOT_AVAILABLE}"
printf "Residuo payload: %s byte\n" "${PAYLOAD_REMAINDER_BYTES:-NOT_AVAILABLE}"
printf "Campioni completi: %s\n" "${COMPLETE_SAMPLE_COUNT:-NOT_AVAILABLE}"
printf "Avvii State1: %s\n" "$START_LINES"
printf "Application starting: %s\n" "$APPLICATION_START_LINES"
printf "Aperture FileWriter: %s\n" "$FILE_OPEN_LINES"
printf "Exit code MARTe: %s\n" "$MARTE_EXIT_CODE"
printf "Exit code tee: %s\n" "$TEE_EXIT_CODE"
printf "Warning priorita' non applic.: %s\n" "$PRIORITY_FAIL_LINES"
printf "Warning non classificati: %s\n" "$UNCLASSIFIED_WARNING_LINES"
printf "FatalError non classificati: %s\n" "$UNCLASSIFIED_FATAL_LINES"
printf "OSError non classificati: %s\n" "$UNCLASSIFIED_OS_ERROR_LINES"
printf "Error non classificati: %s\n" "$ERROR_LINES"
printf "InitialisationError: %s\n" "$INITIALISATION_ERROR_LINES"
printf "\n--- DETTAGLIO CONFIGURAZIONE ---\n"
cat -- "$CONFIG_REPORT"
printf "\n--- DETTAGLIO PARSER BINARIO ---\n"
cat -- "$BINARY_REPORT"
printf "\n--- VERIFICA HASH ---\n"
cat -- "$HASH_REPORT"
printf "\n--- CONTRATTO S03 ---\n"
emit_contract
if [ "$FUNCTIONAL_STATUS" != "PASS" ]; then
printf "VALIDATION_RESULT=FUNCTIONAL_NOT_DEMONSTRATED\n"
exit 20
fi
if [ "$SEMANTIC_STATUS" != "PASS" ]; then
printf "VALIDATION_RESULT=SEMANTIC_VALIDATION_FAILED\n"
exit 20
fi
if [ "$SIGINT_LINES" -ge 1 ] &&
[ "$STOP_OK_LINES" -ge 1 ] &&
[ "$TERMINATED_LINES" -ge 1 ] &&
[ "$FATAL_ERROR_LINES" -eq 0 ] &&
[ "$OS_ERROR_LINES" -eq 0 ] &&
[ "$ERROR_LINES" -eq 0 ] &&
[ "$INITIALISATION_ERROR_LINES" -eq 0 ]; then
printf "VALIDATION_RESULT=PASS_CLEAN_SHUTDOWN\n"
exit 0
fi
KNOWN_SHUTDOWN_TOTAL=$((
DOUBLE_STOP_LINES +
ASYNC_EVENTSEM_CLOSE_LINES +
PTHREAD_MUTEX_DESTROY_LINES
))
if [ "$SIGINT_LINES" -ge 1 ] &&
[ "$STOP_OK_LINES" -ge 1 ] &&
[ "$TERMINATED_LINES" -ge 1 ] &&
[ "$KNOWN_SHUTDOWN_TOTAL" -ge 1 ] &&
[ "$UNCLASSIFIED_FATAL_LINES" -eq 0 ] &&
[ "$UNCLASSIFIED_OS_ERROR_LINES" -eq 0 ] &&
[ "$ERROR_LINES" -eq 0 ] &&
[ "$INITIALISATION_ERROR_LINES" -eq 0 ]; then
printf "VALIDATION_RESULT=PASS_KNOWN_SHUTDOWN_ANOMALY\n"
exit 10
fi
printf "VALIDATION_RESULT=PASS_UNCLASSIFIED_SHUTDOWN_ANOMALY\n"
exit 11