Files
NeoTachyon/tests/fuzzer_strategy_cli.sh
T

150 lines
5.1 KiB
Bash

#!/usr/bin/env bash
set -eo pipefail
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
TACHYON_LIB="$ROOT_DIR/tachyon/files/usr/lib"
FUZZER="$ROOT_DIR/tachyon/files/usr/lib/diagnostics/fuzzer.uc"
BYEDPI_VALIDATOR="$ROOT_DIR/tachyon/files/usr/lib/providers/byedpi/validator.uc"
ZAPRET_VALIDATOR="$ROOT_DIR/tachyon/files/usr/lib/providers/zapret/validator.uc"
ZAPRET2_VALIDATOR="$ROOT_DIR/tachyon/files/usr/lib/providers/zapret2/validator.uc"
TACHYON_BIN="$ROOT_DIR/tachyon/files/usr/bin/tachyon"
fail() {
printf 'FAIL: %s\n' "$1" >&2
exit 1
}
# 1. Check strategies JSON output
strategies_json="$(ucode -L "$TACHYON_LIB" -- "$FUZZER" strategies)"
[ -n "$strategies_json" ] || fail "fuzzer strategies returned empty output"
# Validate JSON structure using node
JSON_VALUE="$strategies_json" node <<'NODE'
const val = JSON.parse(process.env.JSON_VALUE);
if (typeof val.available_engines !== 'object') {
console.error("Missing available_engines");
process.exit(1);
}
if (!Array.isArray(val.zapret2) || val.zapret2.length === 0) {
console.error("Missing zapret2 strategies");
process.exit(1);
}
if (!Array.isArray(val.zapret) || val.zapret.length === 0) {
console.error("Missing zapret strategies");
process.exit(1);
}
if (!Array.isArray(val.byedpi) || val.byedpi.length === 0) {
console.error("Missing byedpi strategies");
process.exit(1);
}
NODE
# 2. Check each strategy passes its respective engine validator
byedpi_args="$(JSON_VALUE="$strategies_json" node - <<'NODE'
const val = JSON.parse(process.env.JSON_VALUE);
for (const s of val.byedpi) {
console.log(s.args);
}
NODE
)"
while IFS= read -r args; do
[ -n "$args" ] || continue
check="$(ucode -L "$TACHYON_LIB" -- "$BYEDPI_VALIDATOR" validate-json "$args")"
JSON_VALUE="$check" node - <<'NODE'
const val = JSON.parse(process.env.JSON_VALUE);
if (!val.valid) {
console.error("ByeDPI strategy invalid:", val);
process.exit(1);
}
NODE
done <<< "$byedpi_args"
zapret_args="$(JSON_VALUE="$strategies_json" node - <<'NODE'
const val = JSON.parse(process.env.JSON_VALUE);
for (const s of val.zapret) {
console.log(s.args);
}
NODE
)"
while IFS= read -r args; do
[ -n "$args" ] || continue
check="$(ucode -L "$TACHYON_LIB" -- "$ZAPRET_VALIDATOR" validate-json nfqws "$args")"
JSON_VALUE="$check" node - <<'NODE'
const val = JSON.parse(process.env.JSON_VALUE);
if (!val.valid) {
console.error("Zapret strategy invalid:", val);
process.exit(1);
}
NODE
done <<< "$zapret_args"
zapret2_args="$(JSON_VALUE="$strategies_json" node - <<'NODE'
const val = JSON.parse(process.env.JSON_VALUE);
for (const s of val.zapret2) {
console.log(s.args);
}
NODE
)"
while IFS= read -r args; do
[ -n "$args" ] || continue
check="$(ucode -L "$TACHYON_LIB" -- "$ZAPRET2_VALIDATOR" validate-json nfqws2 "$args")"
JSON_VALUE="$check" node - <<'NODE'
const val = JSON.parse(process.env.JSON_VALUE);
if (!val.valid) {
console.error("Zapret2 strategy invalid:", val);
process.exit(1);
}
NODE
done <<< "$zapret2_args"
# 3. Check status returns clean default state
status_json="$(ucode -L "$TACHYON_LIB" -- "$FUZZER" status)"
JSON_VALUE="$status_json" node <<'NODE'
const val = JSON.parse(process.env.JSON_VALUE);
if (val.running !== false) {
console.error("Default fuzzer status should have running: false");
process.exit(1);
}
if (!Array.isArray(val.results)) {
console.error("Results should be an array");
process.exit(1);
}
NODE
# 4. Check tachyon CLI command map contains fuzzer commands
grep -q 'fuzzer_start:' "$TACHYON_BIN" || fail "tachyon CLI missing fuzzer_start"
grep -q 'fuzzer_status:' "$TACHYON_BIN" || fail "tachyon CLI missing fuzzer_status"
grep -q 'fuzzer_stop:' "$TACHYON_BIN" || fail "tachyon CLI missing fuzzer_stop"
grep -q 'fuzzer_apply:' "$TACHYON_BIN" || fail "tachyon CLI missing fuzzer_apply"
grep -q 'fuzzer_strategies:' "$TACHYON_BIN" || fail "tachyon CLI missing fuzzer_strategies"
grep -q 'fuzzer_generate:' "$TACHYON_BIN" || fail "tachyon CLI missing fuzzer_generate"
grep -q 'fuzzer_ai_synthesize:' "$TACHYON_BIN" || fail "tachyon CLI missing fuzzer_ai_synthesize"
# 5. Check combinatorial strategies generation
combo_tmp="$(mktemp "${TMPDIR:-/tmp}/fuzzer_combo_XXXXXX")"
trap 'rm -f "$combo_tmp"' EXIT
ucode -L "$TACHYON_LIB" -- "$FUZZER" strategies combinatorial > "$combo_tmp"
COMBO_FILE="$combo_tmp" node <<'NODE'
const fs = require('fs');
const raw = fs.readFileSync(process.env.COMBO_FILE, 'utf8');
const val = JSON.parse(raw);
if (!Array.isArray(val.zapret2) || val.zapret2.length < 30) {
console.error("Combinatorial zapret2 should have >= 30 strategies, got:", val.zapret2 ? val.zapret2.length : 0);
process.exit(1);
}
if (!Array.isArray(val.zapret) || val.zapret.length < 20) {
console.error("Combinatorial zapret should have >= 20 strategies, got:", val.zapret ? val.zapret.length : 0);
process.exit(1);
}
if (!Array.isArray(val.byedpi) || val.byedpi.length < 20) {
console.error("Combinatorial byedpi should have >= 20 strategies, got:", val.byedpi ? val.byedpi.length : 0);
process.exit(1);
}
console.log("Generated matrix: Zapret2=" + val.zapret2.length + ", Zapret=" + val.zapret.length + ", ByeDPI=" + val.byedpi.length);
NODE
printf 'PASS: fuzzer_strategy_cli\n'