Files
onyx-prebootstrap/test/integration_test.sh

345 lines
9.1 KiB
Bash
Executable File

#!/bin/bash
# Don't exit on first error - we want to run all tests and report results
set +e
# Onyx Milestone 2 Integration Test
# This script tests all core functionality of transparent versioning and save/undo commands
# Color codes for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# Test counters
TESTS_PASSED=0
TESTS_FAILED=0
TESTS_TOTAL=0
# Logging functions
log_info() {
echo -e "${BLUE}[INFO]${NC} $1"
}
log_success() {
echo -e "${GREEN}[PASS]${NC} $1"
((TESTS_PASSED++))
((TESTS_TOTAL++))
}
log_error() {
echo -e "${RED}[FAIL]${NC} $1"
((TESTS_FAILED++))
((TESTS_TOTAL++))
}
log_section() {
echo ""
echo -e "${YELLOW}=====================================${NC}"
echo -e "${YELLOW}$1${NC}"
echo -e "${YELLOW}=====================================${NC}"
}
# Assertion functions
assert_file_exists() {
if [ -f "$1" ]; then
log_success "File exists: $1"
else
log_error "File does not exist: $1"
return 1
fi
}
assert_dir_exists() {
if [ -d "$1" ]; then
log_success "Directory exists: $1"
else
log_error "Directory does not exist: $1"
return 1
fi
}
assert_file_contains() {
if grep -q "$2" "$1" 2>/dev/null; then
log_success "File $1 contains '$2'"
else
log_error "File $1 does not contain '$2'"
return 1
fi
}
assert_command_success() {
if eval "$1" >/dev/null 2>&1; then
log_success "Command succeeded: $1"
else
log_error "Command failed: $1"
return 1
fi
}
assert_ref_exists() {
if git show-ref "$1" >/dev/null 2>&1; then
log_success "Git ref exists: $1"
else
log_error "Git ref does not exist: $1"
return 1
fi
}
assert_ref_not_exists() {
if ! git show-ref "$1" >/dev/null 2>&1; then
log_success "Git ref does not exist (as expected): $1"
else
log_error "Git ref exists (should be deleted): $1"
return 1
fi
}
# Get the absolute path to onx and onxd binaries
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(dirname "$SCRIPT_DIR")"
ONX_BIN="$PROJECT_ROOT/bin/onx"
ONXD_BIN="$PROJECT_ROOT/bin/onxd"
# Verify binaries exist
if [ ! -f "$ONX_BIN" ]; then
echo -e "${RED}Error: onx binary not found at $ONX_BIN${NC}"
echo "Please run 'make build' first"
exit 1
fi
if [ ! -f "$ONXD_BIN" ]; then
echo -e "${RED}Error: onxd binary not found at $ONXD_BIN${NC}"
echo "Please run 'make build' first"
exit 1
fi
# Create test directory in /tmp
TIMESTAMP=$(date +%s)
TEST_DIR="/tmp/onyx-repo-test-$TIMESTAMP"
log_section "Setting up test environment"
log_info "Test directory: $TEST_DIR"
log_info "Onyx binary: $ONX_BIN"
log_info "Daemon binary: $ONXD_BIN"
# Create test directory
mkdir -p "$TEST_DIR"
cd "$TEST_DIR"
# Cleanup function
cleanup() {
log_section "Cleaning up"
cd /tmp
# Stop daemon if running
if [ -f "$TEST_DIR/.onx/daemon.pid" ]; then
log_info "Stopping daemon..."
"$ONX_BIN" daemon stop 2>/dev/null || true
fi
# Remove test directory
if [ -d "$TEST_DIR" ]; then
log_info "Removing test directory: $TEST_DIR"
rm -rf "$TEST_DIR"
fi
}
# Set trap for cleanup
trap cleanup EXIT
# ============================================
# Test 1: Repository Initialization
# ============================================
log_section "Test 1: Repository Initialization"
log_info "Initializing Onyx repository..."
"$ONX_BIN" init
assert_dir_exists ".git"
assert_dir_exists ".onx"
assert_file_exists ".onx/oplog"
assert_file_exists ".onx/workstreams.json"
assert_file_exists ".gitignore"
assert_file_contains ".onx/workstreams.json" '{"workstreams":{}}'
# ============================================
# Test 2: Daemon Startup
# ============================================
log_section "Test 2: Daemon Startup"
log_info "Starting daemon..."
"$ONX_BIN" daemon start
sleep 1
assert_file_exists ".onx/daemon.pid"
assert_command_success "$ONX_BIN daemon status | grep -q 'is running'"
PID=$(cat .onx/daemon.pid)
log_info "Daemon running with PID: $PID"
# ============================================
# Test 3: Automatic Snapshot Creation
# ============================================
log_section "Test 3: Automatic Snapshot Creation"
log_info "Creating test file..."
echo 'print("hello world")' > main.py
log_info "Waiting for automatic snapshot (3 seconds)..."
sleep 3
assert_file_exists ".onx/workspace"
assert_file_contains ".onx/workspace" "current_commit_sha"
assert_ref_exists "refs/onyx/workspaces/current"
SNAPSHOT_SHA=$(git show-ref refs/onyx/workspaces/current | awk '{print $1}')
log_info "Snapshot created: $SNAPSHOT_SHA"
# ============================================
# Test 4: Save Command (requires workstream)
# ============================================
log_section "Test 4: Save Command"
# First, we need to create an initial Git commit for the base branch
log_info "Creating initial Git commit..."
git config user.email "test@example.com"
git config user.name "Test User"
git add main.py
git commit -m "Initial commit" >/dev/null 2>&1
log_info "Creating workstream using onx new..."
"$ONX_BIN" new test-feature
log_info "Saving first commit..."
"$ONX_BIN" save -m "Add hello world program"
assert_file_contains ".onx/workstreams.json" "Add hello world program"
assert_ref_exists "refs/onyx/workstreams/test-feature/commit-1"
COMMIT1_SHA=$(git show-ref refs/onyx/workstreams/test-feature/commit-1 | awk '{print $1}')
log_info "First commit created: $COMMIT1_SHA"
# ============================================
# Test 5: Second Save (test commit chain)
# ============================================
log_section "Test 5: Second Save and Commit Chain"
log_info "Modifying file..."
echo 'print("goodbye")' >> main.py
log_info "Waiting for automatic snapshot..."
sleep 3
log_info "Saving second commit..."
"$ONX_BIN" save -m "Add goodbye message"
assert_file_contains ".onx/workstreams.json" "Add goodbye message"
assert_ref_exists "refs/onyx/workstreams/test-feature/commit-2"
# Verify parent-child relationship in workstreams.json
if grep -q "parent_sha" .onx/workstreams.json; then
log_success "Parent-child relationship established in commits"
((TESTS_PASSED++))
((TESTS_TOTAL++))
else
log_error "No parent_sha found in workstreams.json"
((TESTS_FAILED++))
((TESTS_TOTAL++))
fi
COMMIT2_SHA=$(git show-ref refs/onyx/workstreams/test-feature/commit-2 | awk '{print $1}')
log_info "Second commit created: $COMMIT2_SHA"
# ============================================
# Test 6: Undo Command
# ============================================
log_section "Test 6: Undo Command"
log_info "Checking state before undo..."
log_info "File content: $(cat main.py | wc -l) lines"
log_info "Commits in workstream: $(grep -o "commit-" .onx/workstreams.json | wc -l)"
log_info "Executing undo..."
"$ONX_BIN" undo
# Verify commit-2 ref was removed (Git state reverted)
# Note: workstreams.json may still have the entry, undo only reverts Git state
log_info "Verifying undo operation..."
# Check that oplog has the undo entry
assert_file_contains ".onx/oplog" "undo"
# Verify oplog has state_before (the fix we implemented)
if xxd .onx/oplog | grep -q "state_before"; then
# Check for non-null state_before
if xxd .onx/oplog | grep -A 5 "state_before" | grep -v "state_before\":null" | grep -q "state_before"; then
log_success "Oplog contains non-null state_before (undo fix working)"
((TESTS_PASSED++))
((TESTS_TOTAL++))
else
log_error "Oplog has null state_before"
((TESTS_FAILED++))
((TESTS_TOTAL++))
fi
else
log_error "Oplog missing state_before"
((TESTS_FAILED++))
((TESTS_TOTAL++))
fi
# ============================================
# Test 7: Daemon Stop
# ============================================
log_section "Test 7: Daemon Cleanup"
log_info "Stopping daemon..."
"$ONX_BIN" daemon stop
sleep 1
if [ -f ".onx/daemon.pid" ]; then
log_error "PID file still exists after daemon stop"
((TESTS_FAILED++))
((TESTS_TOTAL++))
else
log_success "PID file removed after daemon stop"
((TESTS_PASSED++))
((TESTS_TOTAL++))
fi
if "$ONX_BIN" daemon status 2>&1 | grep -q "not running"; then
log_success "Daemon status shows not running"
((TESTS_PASSED++))
((TESTS_TOTAL++))
else
log_error "Daemon status does not show not running"
((TESTS_FAILED++))
((TESTS_TOTAL++))
fi
# ============================================
# Final Report
# ============================================
log_section "Integration Test Results"
echo ""
echo -e "${BLUE}Total Tests:${NC} $TESTS_TOTAL"
echo -e "${GREEN}Passed:${NC} $TESTS_PASSED"
echo -e "${RED}Failed:${NC} $TESTS_FAILED"
echo ""
if [ $TESTS_FAILED -eq 0 ]; then
echo -e "${GREEN}========================================${NC}"
echo -e "${GREEN} ALL TESTS PASSED! ✓${NC}"
echo -e "${GREEN}========================================${NC}"
exit 0
else
echo -e "${RED}========================================${NC}"
echo -e "${RED} SOME TESTS FAILED! ✗${NC}"
echo -e "${RED}========================================${NC}"
exit 1
fi