# Blackbox Test Scenarios ## BT-DSF: Dataset Formation ### BT-DSF-01: 70/20/10 split ratio - **Input**: 100 images + labels in data/ dir - **Action**: Run `form_dataset()` with patched paths - **Expected**: train: 70 images+labels, valid: 20, test: 10 - **Traces**: AC: Dataset split 70/20/10 ### BT-DSF-02: Split directories structure - **Input**: 100 images + labels - **Action**: Run `form_dataset()` - **Expected**: Created: `train/images/`, `train/labels/`, `valid/images/`, `valid/labels/`, `test/images/`, `test/labels/` - **Traces**: AC: YOLO dataset directory structure ### BT-DSF-03: Total files preserved across splits - **Input**: 100 valid images + labels - **Action**: Run `form_dataset()` - **Expected**: `count(train) + count(valid) + count(test) == 100` (no data loss) - **Traces**: AC: Dataset integrity ### BT-DSF-04: Corrupted labels moved to corrupted directory - **Input**: 95 valid + 5 corrupted labels (coords > 1.0) - **Action**: Run `form_dataset()` with patched paths - **Expected**: 5 images+labels in `data-corrupted/`; 95 across train/valid/test splits - **Traces**: AC: Corrupted labels filtered --- ## BT-LBL: Label Validation ### BT-LBL-01: Valid label accepted - **Input**: Label file: `0 0.5 0.5 0.1 0.1` - **Action**: Call `check_label(path)` - **Expected**: Returns `True` - **Traces**: AC: Valid YOLO label format ### BT-LBL-02: Label with x > 1.0 rejected - **Input**: Label file: `0 1.5 0.5 0.1 0.1` - **Action**: Call `check_label(path)` - **Expected**: Returns `False` - **Traces**: AC: Corrupted labels detected ### BT-LBL-03: Label with height > 1.0 rejected - **Input**: Label file: `0 0.5 0.5 0.1 1.2` - **Action**: Call `check_label(path)` - **Expected**: Returns `False` - **Traces**: AC: Corrupted labels detected ### BT-LBL-04: Missing label file rejected - **Input**: Non-existent file path - **Action**: Call `check_label(path)` - **Expected**: Returns `False` - **Traces**: AC: Missing labels handled ### BT-LBL-05: Multi-line label with one corrupted line - **Input**: Label file: `0 0.5 0.5 0.1 0.1\n3 0.5 0.5 0.1 1.5` - **Action**: Call `check_label(path)` - **Expected**: Returns `False` (any corrupted line fails the whole file) - **Traces**: AC: Corrupted labels detected --- ## BT-ENC: Encryption ### BT-ENC-01: Encrypt-decrypt roundtrip (arbitrary data) - **Input**: 1024 random bytes, key "test-key" - **Action**: `decrypt_to(encrypt_to(data, key), key)` - **Expected**: Output equals input bytes exactly - **Traces**: AC: AES-256-CBC encryption ### BT-ENC-02: Encrypt-decrypt roundtrip (ONNX model) - **Input**: `azaion.onnx` bytes, model encryption key - **Action**: `decrypt_to(encrypt_to(model_bytes, key), key)` - **Expected**: Output equals input bytes exactly - **Traces**: AC: Model encryption ### BT-ENC-03: Empty input roundtrip - **Input**: `b""`, key "test-key" - **Action**: `decrypt_to(encrypt_to(b"", key), key)` - **Expected**: Output equals `b""` - **Traces**: AC: Edge case handling ### BT-ENC-04: Single byte roundtrip - **Input**: `b"\x00"`, key "test-key" - **Action**: `decrypt_to(encrypt_to(b"\x00", key), key)` - **Expected**: Output equals `b"\x00"` - **Traces**: AC: Edge case handling ### BT-ENC-05: Different keys produce different ciphertext - **Input**: Same 1024 bytes, keys "key-a" and "key-b" - **Action**: `encrypt_to(data, "key-a")` vs `encrypt_to(data, "key-b")` - **Expected**: Ciphertexts differ - **Traces**: AC: Key-dependent encryption ### BT-ENC-06: Wrong key fails decryption - **Input**: Encrypted with "key-a", decrypt with "key-b" - **Action**: `decrypt_to(encrypted, "key-b")` - **Expected**: Output does NOT equal original input - **Traces**: AC: Key-dependent encryption --- ## BT-SPL: Model Split Storage ### BT-SPL-01: Split respects size constraint - **Input**: 10000 encrypted bytes - **Action**: Split into small + big per `SMALL_SIZE_KB = 3` logic - **Expected**: small ≤ max(3072 bytes, 20% of total); big = remainder - **Traces**: AC: Model split ≤3KB or 20% ### BT-SPL-02: Reassembly produces original - **Input**: 10000 encrypted bytes → split → reassemble - **Action**: `small + big` - **Expected**: Equals original encrypted bytes - **Traces**: AC: Split model integrity --- ## BT-CLS: Annotation Class Loading ### BT-CLS-01: Load 17 base classes - **Input**: `classes.json` - **Action**: `AnnotationClass.read_json()` - **Expected**: Dict with 17 unique class entries (base IDs) - **Traces**: AC: 17 base classes ### BT-CLS-02: Weather mode expansion - **Input**: `classes.json` - **Action**: `AnnotationClass.read_json()` - **Expected**: Same class at offset 0 (Norm), 20 (Wint), 40 (Night); e.g., ID 0, 20, 40 all represent ArmorVehicle - **Traces**: AC: 3 weather modes ### BT-CLS-03: YAML generation produces 80 class names - **Input**: `classes.json` + dataset path - **Action**: `create_yaml()` with patched paths - **Expected**: data.yaml contains `nc: 80`, 17 named classes + 63 `Class-N` placeholders - **Traces**: AC: 80 total class slots --- ## BT-HSH: Hardware Hash ### BT-HSH-01: Deterministic output - **Input**: "test-hardware-info" - **Action**: `Security.get_hw_hash()` called twice - **Expected**: Both calls return identical string - **Traces**: AC: Hardware fingerprinting determinism ### BT-HSH-02: Different inputs produce different hashes - **Input**: "hw-a" and "hw-b" - **Action**: `Security.get_hw_hash()` on each - **Expected**: Results differ - **Traces**: AC: Hardware-bound uniqueness ### BT-HSH-03: Output is valid base64 - **Input**: "test-hardware-info" - **Action**: `Security.get_hw_hash()` - **Expected**: Matches regex `^[A-Za-z0-9+/]+=*$` - **Traces**: AC: Hash format --- ## BT-INF: ONNX Inference ### BT-INF-01: Model loads successfully - **Input**: `azaion.onnx` bytes - **Action**: `OnnxEngine(model_bytes)` - **Expected**: No exception; engine object created with valid input_shape and batch_size - **Traces**: AC: ONNX inference capability ### BT-INF-02: Inference returns output - **Input**: ONNX engine + 1 preprocessed image - **Action**: `engine.run(input_blob)` - **Expected**: Returns list of numpy arrays; first array has shape [batch, N, 6+] - **Traces**: AC: ONNX inference produces results ### BT-INF-03: Postprocessing returns valid detections - **Input**: ONNX engine output from real image - **Action**: `Inference.postprocess()` - **Expected**: Returns list of Annotation objects; each Detection has x,y,w,h ∈ [0,1], cls ∈ [0,79], confidence ∈ [0,1] - **Traces**: AC: Detection format validity --- ## BT-NMS: Overlap Removal ### BT-NMS-01: Overlapping detections — keep higher confidence - **Input**: 2 Detection objects at same position, confidence 0.9 and 0.5, IoU > 0.3 - **Action**: `remove_overlapping_detections()` - **Expected**: 1 detection returned (confidence 0.9) - **Traces**: AC: NMS IoU threshold 0.3 ### BT-NMS-02: Non-overlapping detections — keep both - **Input**: 2 Detection objects at distant positions, IoU < 0.3 - **Action**: `remove_overlapping_detections()` - **Expected**: 2 detections returned - **Traces**: AC: NMS preserves non-overlapping ### BT-NMS-03: Chain overlap resolution - **Input**: 3 Detection objects: A overlaps B (IoU > 0.3), B overlaps C (IoU > 0.3), A doesn't overlap C - **Action**: `remove_overlapping_detections()` - **Expected**: ≤ 2 detections; highest confidence per overlapping pair kept - **Traces**: AC: NMS handles chains --- ## BT-AQM: Annotation Queue Message Parsing ### BT-AQM-01: Parse Created annotation message - **Input**: Msgpack bytes matching AnnotationMessage schema (status=Created, role=Validator) - **Action**: Decode and construct AnnotationMessage - **Expected**: All fields populated: name, detections, image bytes, status == "Created", role == "Validator" - **Traces**: AC: Annotation message parsing ### BT-AQM-02: Parse Validated bulk message - **Input**: Msgpack bytes with status=Validated, list of names - **Action**: Decode and construct AnnotationBulkMessage - **Expected**: Status == "Validated", names list matches input - **Traces**: AC: Bulk validation parsing ### BT-AQM-03: Parse Deleted bulk message - **Input**: Msgpack bytes with status=Deleted, list of names - **Action**: Decode and construct AnnotationBulkMessage - **Expected**: Status == "Deleted", names list matches input - **Traces**: AC: Bulk deletion parsing ### BT-AQM-04: Malformed message raises exception - **Input**: Invalid msgpack bytes - **Action**: Attempt to decode - **Expected**: Exception raised - **Traces**: AC: Error handling for malformed messages