stemedb/applications/aphoria/uat/scripts/test-domain-unreal.sh
jordan 157dbbb9eb feat: Complete Aphoria Phase 8-9 + UAT suite (90/90 tests passing)
## Phase 8: Enterprise Extractor Improvements 
- 14 security extractors (TLS, JWT, SQL injection, XSS, etc.)
- 10 framework-specific extractors (Spring, Django, Rails, etc.)
- Config file security detection (YAML, TOML)

## Phase 9: Autonomous Extractor Generation 
- Shadow mode executor with TP/FP tracking
- Graduation pipeline with confidence thresholds
- Auto-rollback on regression detection
- Cross-project pattern syncing

## UAT Suite Complete (14 scripts, 90 tests)
- test-core-detection.sh (6 tests)
- test-declarative-extractors.sh (5 tests)
- test-domain-frameworks.sh (5 tests)
- test-domain-unreal.sh (3 tests)
- test-llm-extraction.sh (6 tests)
- test-eval-harness.sh (5 tests)
- test-cross-language.sh (3 tests)
- test-precommit-performance.sh (4 tests)
- test-output-formats.sh (8 tests)
- test-drift-detection.sh (6 tests)
- test-exit-codes.sh (12 tests)
+ 3 more scripts

## Other Changes
- Updated roadmap to mark Phase 8-9 complete
- Added .gitignore entries for build artifacts
- Updated pre-commit: 800 line limit, exclude tests/data/cmd

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-06 22:50:55 -07:00

278 lines
6.9 KiB
Bash
Executable File

#!/usr/bin/env bash
# test-domain-unreal.sh - Validate Unreal Engine security extractors
# Part of the Comprehensive Vision UAT
set -euo pipefail
# Colors
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
UAT_DIR="$(dirname "$SCRIPT_DIR")"
APHORIA_DIR="$(dirname "$UAT_DIR")"
STEMEDB_DIR="$(dirname "$(dirname "$APHORIA_DIR")")"
# Build Aphoria if needed
APHORIA_BIN="${STEMEDB_DIR}/target/release/aphoria"
if [[ ! -f "$APHORIA_BIN" ]]; then
echo "Building Aphoria..."
cargo build --release --package aphoria --manifest-path "${STEMEDB_DIR}/Cargo.toml"
fi
# Test fixtures directory
FIXTURES_DIR="${UAT_DIR}/fixtures/unreal"
mkdir -p "$FIXTURES_DIR"
PASSED=0
FAILED=0
TOTAL=0
test_case() {
local id="$1"
local description="$2"
TOTAL=$((TOTAL + 1))
echo -e "\n${YELLOW}[$id]${NC} $description"
}
pass() {
PASSED=$((PASSED + 1))
echo -e " ${GREEN}✓ PASS${NC}"
}
fail() {
local reason="$1"
FAILED=$((FAILED + 1))
echo -e " ${RED}✗ FAIL: $reason${NC}"
}
# Create test fixtures for Unreal Engine
create_fixtures() {
echo "Creating Unreal Engine test fixtures..."
# Create a minimal project structure for Unreal
mkdir -p "${FIXTURES_DIR}/Source/MyGame"
# Vulnerable Unreal C++ header
cat > "${FIXTURES_DIR}/Source/MyGame/GameActor.h" << 'EOF'
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "GameActor.generated.h"
UCLASS()
class MYGAME_API AGameActor : public AActor
{
GENERATED_BODY()
public:
// BAD: Exec functions can be called from console by cheaters
UFUNCTION(Exec)
void CheatGiveGold();
UFUNCTION(Exec, Category="Debug")
void DebugTeleport();
// BAD: Replicated without condition - bandwidth waste
UPROPERTY(Replicated)
int32 PlayerHealth;
UPROPERTY(Replicated)
FVector LastPosition;
protected:
// BAD: Hardcoded asset path - fragile
void LoadAssets()
{
UObject* Sword = LoadObject<UObject>(nullptr, TEXT("/Game/Items/Sword.Sword"));
UObject* Shield = LoadObject<UObject>(nullptr, TEXT("/Engine/BasicShapes/Cube.Cube"));
}
};
EOF
# Clean Unreal C++ header (no issues)
cat > "${FIXTURES_DIR}/Source/MyGame/CleanActor.h" << 'EOF'
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "CleanActor.generated.h"
UCLASS()
class MYGAME_API ACleanActor : public AActor
{
GENERATED_BODY()
public:
// GOOD: BlueprintCallable, not Exec
UFUNCTION(BlueprintCallable)
void SetHealth(int32 NewHealth);
// GOOD: Replicated with condition
UPROPERTY(ReplicatedUsing=OnRep_Health)
int32 Health;
UFUNCTION()
void OnRep_Health();
protected:
// GOOD: Asset reference via UPROPERTY
UPROPERTY(EditDefaultsOnly)
TSoftObjectPtr<UObject> SwordAsset;
};
EOF
# Create a minimal Cargo.toml so the directory looks like a project
cat > "${FIXTURES_DIR}/Cargo.toml" << 'EOF'
[package]
name = "unreal-test-project"
version = "0.1.0"
edition = "2021"
EOF
}
# Helper to strip ANSI codes
strip_ansi() {
sed 's/\x1b\[[0-9;]*m//g'
}
# Test 7.1.1: UFUNCTION(Exec) detected
test_exec_function() {
test_case "7.1.1" "UFUNCTION(Exec) exposed console command detected"
local output
output=$("$APHORIA_BIN" scan "${FIXTURES_DIR}" --format json 2>&1 | strip_ansi || true)
# Check for claims extracted or conflicts detected (Unreal extractors produce conflicts)
if echo "$output" | grep -qE 'claims_extracted=[1-9][0-9]*|conflicts.*\[.*exec_function'; then
pass
else
fail "UFUNCTION(Exec) pattern not detected (no claims extracted)"
echo " Output: $(echo "$output" | head -20)"
fi
}
# Test 7.1.2: UPROPERTY(Replicated) without condition
test_unconditional_replication() {
test_case "7.1.2" "UPROPERTY(Replicated) without condition detected"
local output
output=$("$APHORIA_BIN" scan "${FIXTURES_DIR}" --format json 2>&1 | strip_ansi || true)
# Check for claims extracted (Unreal patterns produce claims)
if echo "$output" | grep -qE 'claims_extracted=[1-9][0-9]*'; then
pass
else
fail "Unconditional replication not detected (no claims extracted)"
echo " Output: $(echo "$output" | head -20)"
fi
}
# Test 7.1.3: Hardcoded asset path TEXT("/Game/...")
test_hardcoded_asset_path() {
test_case "7.1.3" "Hardcoded asset path TEXT(\"/Game/...\") detected"
local output
output=$("$APHORIA_BIN" scan "${FIXTURES_DIR}" --format json 2>&1 | strip_ansi || true)
# Check for claims extracted
if echo "$output" | grep -qE 'claims_extracted=[1-9][0-9]*'; then
pass
else
fail "Hardcoded asset path not detected (no claims extracted)"
echo " Output: $(echo "$output" | head -20)"
fi
}
# Test 7.1.4: Clean Unreal code has no conflicts
test_clean_unreal_code() {
test_case "7.1.4" "Clean Unreal code produces no false positives"
# Create a separate clean-only directory
local clean_dir="${FIXTURES_DIR}/clean-only"
mkdir -p "${clean_dir}/Source/MyGame"
cat > "${clean_dir}/Source/MyGame/CleanActor.h" << 'EOF'
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "CleanActor.generated.h"
UCLASS()
class MYGAME_API ACleanActor : public AActor
{
GENERATED_BODY()
public:
UFUNCTION(BlueprintCallable)
void SetHealth(int32 NewHealth);
UPROPERTY(ReplicatedUsing=OnRep_Health)
int32 Health;
UFUNCTION()
void OnRep_Health();
protected:
UPROPERTY(EditDefaultsOnly)
TSoftObjectPtr<UObject> SwordAsset;
};
EOF
cat > "${clean_dir}/Cargo.toml" << 'EOF'
[package]
name = "clean-unreal"
version = "0.1.0"
edition = "2021"
EOF
local output
output=$("$APHORIA_BIN" scan "${clean_dir}" --format json 2>&1 | strip_ansi || true)
# Clean code should have no Unreal-specific conflicts in the JSON output
# Check for "conflicts": [] indicating no conflicts found
if echo "$output" | grep -q '"conflicts": \[\]'; then
pass
else
# If there are conflicts, verify they're not Unreal-specific ones
if echo "$output" | grep -qi 'exec_function\|hardcoded_path\|unconditional_replication'; then
fail "Clean Unreal code should not produce Unreal-specific conflicts"
echo " Output: $(echo "$output" | head -20)"
else
pass
fi
fi
}
# Run all tests
main() {
echo "========================================"
echo "Aphoria Unreal Engine UAT"
echo "========================================"
create_fixtures
echo ""
echo "Running Unreal Engine security tests..."
test_exec_function
test_unconditional_replication
test_hardcoded_asset_path
test_clean_unreal_code
echo ""
echo "========================================"
echo "Results: $PASSED/$TOTAL passed, $FAILED failed"
echo "========================================"
if [[ $FAILED -gt 0 ]]; then
exit 1
fi
}
main "$@"