mirror of
https://github.com/bybrooklyn/openbitdo.git
synced 2026-03-19 04:12:56 -04:00
release prep: rc.1 baseline and gating updates
This commit is contained in:
@@ -3,37 +3,234 @@ set -euo pipefail
|
||||
|
||||
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||
cd "$ROOT"
|
||||
LAB_CONFIG="${ROOT}/../harness/lab/device_lab.yaml"
|
||||
|
||||
if [[ ! -f "$LAB_CONFIG" ]]; then
|
||||
echo "missing lab config: $LAB_CONFIG" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
REPORT_DIR="${ROOT}/../harness/reports"
|
||||
mkdir -p "$REPORT_DIR"
|
||||
TS="$(date +%Y%m%d-%H%M%S)"
|
||||
REPORT_PATH="${1:-$REPORT_DIR/hardware_smoke_${TS}.json}"
|
||||
|
||||
LIST_JSON="$(cargo run -q -p bitdoctl -- --json list 2>/dev/null || echo '[]')"
|
||||
SUITE="${BITDO_REQUIRED_SUITE:-family}"
|
||||
REQUIRED_FAMILIES="${BITDO_REQUIRED_FAMILIES:-Standard64,DInput}"
|
||||
|
||||
TEST_OUTPUT_FILE="$(mktemp)"
|
||||
PARSE_OUTPUT="$(mktemp)"
|
||||
set +e
|
||||
BITDO_HARDWARE=1 cargo test --workspace --test hardware_smoke -- --ignored >"$TEST_OUTPUT_FILE" 2>&1
|
||||
TEST_STATUS=$?
|
||||
python3 - <<'PY' "$LAB_CONFIG" "$SUITE" "$REQUIRED_FAMILIES" >"$PARSE_OUTPUT"
|
||||
import pathlib
|
||||
import re
|
||||
import sys
|
||||
|
||||
config_path = pathlib.Path(sys.argv[1])
|
||||
suite = sys.argv[2].strip()
|
||||
required_families = [item.strip() for item in sys.argv[3].split(",") if item.strip()]
|
||||
lines = config_path.read_text().splitlines()
|
||||
|
||||
devices = []
|
||||
current = None
|
||||
in_devices = False
|
||||
|
||||
def parse_scalar(text: str):
|
||||
value = text.split("#", 1)[0].strip()
|
||||
if not value:
|
||||
return value
|
||||
if value.startswith(("0x", "0X")):
|
||||
return int(value, 16)
|
||||
try:
|
||||
return int(value)
|
||||
except ValueError:
|
||||
return value
|
||||
|
||||
for line in lines:
|
||||
stripped = line.strip()
|
||||
if stripped.startswith("devices:"):
|
||||
in_devices = True
|
||||
continue
|
||||
if not in_devices:
|
||||
continue
|
||||
if stripped.startswith("policies:"):
|
||||
if current:
|
||||
devices.append(current)
|
||||
current = None
|
||||
break
|
||||
|
||||
if re.match(r"^\s*-\s+", line):
|
||||
if current:
|
||||
devices.append(current)
|
||||
current = {}
|
||||
continue
|
||||
|
||||
if current is None:
|
||||
continue
|
||||
|
||||
field_match = re.match(r"^\s*([A-Za-z0-9_]+)\s*:\s*(.+)$", line)
|
||||
if not field_match:
|
||||
continue
|
||||
|
||||
key = field_match.group(1)
|
||||
value = parse_scalar(field_match.group(2))
|
||||
current[key] = value
|
||||
|
||||
if current:
|
||||
devices.append(current)
|
||||
|
||||
if not devices:
|
||||
sys.stderr.write(f"no devices found in {config_path}\n")
|
||||
sys.exit(1)
|
||||
|
||||
family_to_pid = {}
|
||||
fixture_to_pid = {}
|
||||
for device in devices:
|
||||
family = device.get("protocol_family")
|
||||
pid = device.get("pid")
|
||||
fixture_id = device.get("fixture_id")
|
||||
if isinstance(family, str) and isinstance(pid, int) and family not in family_to_pid:
|
||||
family_to_pid[family] = pid
|
||||
if isinstance(fixture_id, str) and isinstance(pid, int) and fixture_id not in fixture_to_pid:
|
||||
fixture_to_pid[fixture_id] = pid
|
||||
|
||||
if suite == "family":
|
||||
missing = [fam for fam in required_families if fam not in family_to_pid]
|
||||
if missing:
|
||||
available = ", ".join(sorted(family_to_pid.keys())) if family_to_pid else "none"
|
||||
sys.stderr.write(
|
||||
f"missing required family fixtures in {config_path}: {', '.join(missing)}; available: {available}\n"
|
||||
)
|
||||
sys.exit(1)
|
||||
for fam in required_families:
|
||||
print(f"FAMILY:{fam}={family_to_pid[fam]:#06x}")
|
||||
elif suite == "ultimate2":
|
||||
if "ultimate2" not in fixture_to_pid:
|
||||
available = ", ".join(sorted(fixture_to_pid.keys())) if fixture_to_pid else "none"
|
||||
sys.stderr.write(
|
||||
f"missing fixture_id=ultimate2 in {config_path}; available fixture_ids: {available}\n"
|
||||
)
|
||||
sys.exit(1)
|
||||
print(f"FIXTURE:ultimate2={fixture_to_pid['ultimate2']:#06x}")
|
||||
elif suite == "108jp":
|
||||
if "108jp" not in fixture_to_pid:
|
||||
available = ", ".join(sorted(fixture_to_pid.keys())) if fixture_to_pid else "none"
|
||||
sys.stderr.write(
|
||||
f"missing fixture_id=108jp in {config_path}; available fixture_ids: {available}\n"
|
||||
)
|
||||
sys.exit(1)
|
||||
print(f"FIXTURE:108jp={fixture_to_pid['108jp']:#06x}")
|
||||
else:
|
||||
sys.stderr.write(f"unsupported BITDO_REQUIRED_SUITE value: {suite}\n")
|
||||
sys.exit(1)
|
||||
PY
|
||||
PARSE_STATUS=$?
|
||||
set -e
|
||||
|
||||
python3 - <<'PY' "$REPORT_PATH" "$TEST_STATUS" "$TEST_OUTPUT_FILE" "$LIST_JSON"
|
||||
if [[ $PARSE_STATUS -ne 0 ]]; then
|
||||
rm -f "$PARSE_OUTPUT"
|
||||
exit $PARSE_STATUS
|
||||
fi
|
||||
|
||||
while IFS='=' read -r key pid_hex; do
|
||||
[[ -z "$key" ]] && continue
|
||||
if [[ "$key" == FAMILY:* ]]; then
|
||||
family="${key#FAMILY:}"
|
||||
case "$family" in
|
||||
DInput) export BITDO_EXPECT_DINPUT_PID="$pid_hex" ;;
|
||||
Standard64) export BITDO_EXPECT_STANDARD64_PID="$pid_hex" ;;
|
||||
JpHandshake) export BITDO_EXPECT_JPHANDSHAKE_PID="$pid_hex" ;;
|
||||
*)
|
||||
echo "unsupported family in parsed lab config: $family" >&2
|
||||
rm -f "$PARSE_OUTPUT"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
elif [[ "$key" == FIXTURE:* ]]; then
|
||||
fixture="${key#FIXTURE:}"
|
||||
case "$fixture" in
|
||||
ultimate2) export BITDO_EXPECT_ULTIMATE2_PID="$pid_hex" ;;
|
||||
108jp) export BITDO_EXPECT_108JP_PID="$pid_hex" ;;
|
||||
*)
|
||||
echo "unsupported fixture in parsed lab config: $fixture" >&2
|
||||
rm -f "$PARSE_OUTPUT"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
done <"$PARSE_OUTPUT"
|
||||
rm -f "$PARSE_OUTPUT"
|
||||
|
||||
TEST_OUTPUT_FILE="$(mktemp)"
|
||||
TEST_STATUS=0
|
||||
|
||||
run_test() {
|
||||
local test_name="$1"
|
||||
set +e
|
||||
BITDO_HARDWARE=1 cargo test --workspace --test hardware_smoke -- --ignored --exact "$test_name" >>"$TEST_OUTPUT_FILE" 2>&1
|
||||
local status=$?
|
||||
set -e
|
||||
if [[ $status -ne 0 ]]; then
|
||||
TEST_STATUS=$status
|
||||
fi
|
||||
}
|
||||
|
||||
run_test "hardware_smoke_detect_devices"
|
||||
|
||||
case "$SUITE" in
|
||||
family)
|
||||
IFS=',' read -r -a FAMILY_LIST <<<"$REQUIRED_FAMILIES"
|
||||
for family in "${FAMILY_LIST[@]}"; do
|
||||
case "$family" in
|
||||
DInput) run_test "hardware_smoke_dinput_family" ;;
|
||||
Standard64) run_test "hardware_smoke_standard64_family" ;;
|
||||
JpHandshake) run_test "hardware_smoke_jphandshake_family" ;;
|
||||
*)
|
||||
echo "unsupported required family for tests: $family" >>"$TEST_OUTPUT_FILE"
|
||||
TEST_STATUS=1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
;;
|
||||
ultimate2)
|
||||
run_test "hardware_smoke_ultimate2_core_ops"
|
||||
;;
|
||||
108jp)
|
||||
run_test "hardware_smoke_108jp_dedicated_ops"
|
||||
;;
|
||||
*)
|
||||
echo "unsupported suite: $SUITE" >>"$TEST_OUTPUT_FILE"
|
||||
TEST_STATUS=1
|
||||
;;
|
||||
esac
|
||||
|
||||
python3 - <<'PY' "$REPORT_PATH" "$TEST_STATUS" "$TEST_OUTPUT_FILE" "$SUITE" "$REQUIRED_FAMILIES" "${BITDO_EXPECT_STANDARD64_PID:-}" "${BITDO_EXPECT_DINPUT_PID:-}" "${BITDO_EXPECT_JPHANDSHAKE_PID:-}" "${BITDO_EXPECT_ULTIMATE2_PID:-}" "${BITDO_EXPECT_108JP_PID:-}"
|
||||
import json, sys, pathlib, datetime
|
||||
report_path = pathlib.Path(sys.argv[1])
|
||||
test_status = int(sys.argv[2])
|
||||
output_file = pathlib.Path(sys.argv[3])
|
||||
list_json_raw = sys.argv[4]
|
||||
|
||||
try:
|
||||
devices = json.loads(list_json_raw)
|
||||
except Exception:
|
||||
devices = []
|
||||
suite = sys.argv[4]
|
||||
required_families = [x for x in sys.argv[5].split(",") if x]
|
||||
expected_standard64 = sys.argv[6]
|
||||
expected_dinput = sys.argv[7]
|
||||
expected_jphandshake = sys.argv[8]
|
||||
expected_ultimate2 = sys.argv[9]
|
||||
expected_108jp = sys.argv[10]
|
||||
|
||||
report = {
|
||||
"timestamp_utc": datetime.datetime.utcnow().isoformat() + "Z",
|
||||
"suite": suite,
|
||||
"test_status": test_status,
|
||||
"tests_passed": test_status == 0,
|
||||
"devices": devices,
|
||||
"required_families": required_families,
|
||||
"required_family_fixtures": {
|
||||
"Standard64": expected_standard64,
|
||||
"DInput": expected_dinput,
|
||||
"JpHandshake": expected_jphandshake,
|
||||
},
|
||||
"required_device_fixtures": {
|
||||
"ultimate2": expected_ultimate2,
|
||||
"108jp": expected_108jp,
|
||||
},
|
||||
"raw_test_output": output_file.read_text(errors="replace"),
|
||||
}
|
||||
|
||||
@@ -43,3 +240,4 @@ PY
|
||||
|
||||
rm -f "$TEST_OUTPUT_FILE"
|
||||
echo "hardware smoke report written: $REPORT_PATH"
|
||||
exit "$TEST_STATUS"
|
||||
|
||||
Reference in New Issue
Block a user