Viewing: test_battery.exp
📄 test_battery.exp (Read Only) ⬅ To go back
#!/usr/bin/expect -f
#
# AdrOS Test Battery — exercises multi-disk ATA, VFS root= mount,
# and TCP/IP ping in addition to the standard smoke tests.
#
# Usage: expect tests/test_battery.exp [timeout_sec]
#   timeout_sec: max seconds per QEMU run (default: 90)
#
# Exit codes:
#   0 = all checks passed
#   1 = test failure
#   2 = timeout

set timeout_sec [lindex $argv 0]
if {$timeout_sec eq ""} { set timeout_sec 90 }

set iso "adros-x86.iso"
set serial_log "serial.log"
set smp 4

# ---- Helpers ----

proc create_disk {path mb} {
    if {![file exists $path]} {
        exec dd if=/dev/zero of=$path bs=1M count=$mb 2>/dev/null
    }
}

proc run_qemu {iso smp serial_log timeout_sec drive_args} {
    file delete -force $serial_log
    set cmd [list qemu-system-i386 \
        -smp $smp -boot d -cdrom $iso -m 128M -display none \
        -nic user,model=e1000]
    foreach a $drive_args {
        lappend cmd {*}$a
    }
    lappend cmd -serial file:$serial_log -monitor none -no-reboot -no-shutdown
    set pid [exec {*}$cmd &]
    after 1000
    return $pid
}

proc wait_for_patterns {serial_log timeout_sec patterns} {
    set start [clock seconds]
    set total [llength $patterns]
    for {set i 0} {$i < $total} {incr i} {
        set found($i) 0
    }

    while {1} {
        set elapsed [expr {[clock seconds] - $start}]
        if {$elapsed > $timeout_sec} { break }

        if {[file exists $serial_log]} {
            set fd [open $serial_log r]
            set log [read $fd]
            close $fd
        } else {
            set log ""
        }

        if {[regexp {KERNEL PANIC} $log]} {
            return [list -1 "KERNEL PANIC detected"]
        }

        set all 1
        for {set i 0} {$i < $total} {incr i} {
            if {$found($i)} continue
            set pat [lindex [lindex $patterns $i] 1]
            if {[regexp $pat $log]} {
                set found($i) 1
            } else {
                set all 0
            }
        }

        if {$all} {
            set results {}
            for {set i 0} {$i < $total} {incr i} {
                lappend results [list [lindex [lindex $patterns $i] 0] 1]
            }
            return [list 0 $results]
        }

        after 1000
    }

    # Timeout — report what passed/failed
    set results {}
    for {set i 0} {$i < $total} {incr i} {
        lappend results [list [lindex [lindex $patterns $i] 0] $found($i)]
    }
    return [list 1 $results]
}

proc kill_qemu {iso} {
    catch {exec pkill -f "qemu-system-i386.*[file tail $iso]" 2>/dev/null}
    after 500
}

# ================================================================
# Test Suite
# ================================================================

set global_pass 0
set global_fail 0
set global_tests {}

proc report_section {title rc results} {
    upvar global_pass gp
    upvar global_fail gf
    upvar global_tests gt

    puts ""
    puts "--- $title ---"

    if {$rc == -1} {
        puts "  *** $results ***"
        incr gf
        lappend gt [list $title "PANIC"]
        return
    }

    foreach r $results {
        set desc [lindex $r 0]
        set ok   [lindex $r 1]
        if {$ok} {
            puts "  PASS  $desc"
            incr gp
        } else {
            puts "  FAIL  $desc"
            incr gf
        }
        lappend gt [list "$title: $desc" [expr {$ok ? "PASS" : "FAIL"}]]
    }
}

# ================================================================
# TEST 1: Standard smoke + ping (single disk on hda)
# ================================================================
puts "========================================="
puts "  AdrOS Test Battery"
puts "========================================="

create_disk "disk.img" 4

set pid [run_qemu $iso $smp $serial_log $timeout_sec \
    {{-drive file=disk.img,if=ide,format=raw}}]

set patterns {
    {"NET lwIP init"         "\\[NET\\] lwIP initialized"}
    {"PING network OK"       "\\[PING\\] .*received.*network OK"}
    {"ATA /dev/hda"          "\\[ATA\\] /dev/hda detected"}
    {"INITRD found"          "\\[INITRD\\] Found"}
    {"diskfs mount /disk"    "\\[MOUNT\\] diskfs on /dev/hda"}
    {"diskfs test"           "\\[test\\] /disk/test prev="}
    {"diskfs getdents"       "\\[test\\] diskfs getdents OK"}
}

set res [wait_for_patterns $serial_log $timeout_sec $patterns]
kill_qemu $iso

report_section "Smoke + Ping (1 disk)" [lindex $res 0] [lindex $res 1]

# ================================================================
# TEST 2: Multi-disk ATA detection (hda + hdb + hdd)
# hdc is the CD-ROM (boot device)
# ================================================================

create_disk "hda.img" 4
create_disk "hdb.img" 4
create_disk "hdd.img" 4

set pid [run_qemu $iso $smp $serial_log $timeout_sec \
    {{-drive file=hda.img,if=ide,index=0,format=raw}
     {-drive file=hdb.img,if=ide,index=1,format=raw}
     {-drive file=hdd.img,if=ide,index=3,format=raw}}]

set patterns {
    {"ATA /dev/hda"     "\\[ATA\\] /dev/hda detected"}
    {"ATA /dev/hdb"     "\\[ATA\\] /dev/hdb detected"}
    {"ATA /dev/hdd"     "\\[ATA\\] /dev/hdd detected"}
    {"ATA Ch0 DMA"      "\\[ATA\\] Channel 0: DMA mode"}
    {"ATA Ch1"          "\\[ATA\\] Channel 1:"}
}

set res [wait_for_patterns $serial_log $timeout_sec $patterns]
kill_qemu $iso

report_section "Multi-disk ATA (3 drives)" [lindex $res 0] [lindex $res 1]

# ================================================================
# TEST 3: VFS mount root=/dev/hda (diskfs auto-format)
# ================================================================

create_disk "root_hda.img" 4

set pid [run_qemu $iso $smp $serial_log $timeout_sec \
    {{-drive file=root_hda.img,if=ide,index=0,format=raw}}]

set patterns {
    {"INITRD loaded"       "\\[INITRD\\] Found"}
    {"diskfs mount /disk"  "\\[MOUNT\\] diskfs on /dev/hda"}
}

set res [wait_for_patterns $serial_log $timeout_sec $patterns]
kill_qemu $iso

report_section "VFS mount InitRD + /dev/hda" [lindex $res 0] [lindex $res 1]

# ================================================================
# TEST 4: VFS mount root=/dev/hdb
# ================================================================

create_disk "root_hdb.img" 4

set pid [run_qemu $iso $smp $serial_log $timeout_sec \
    {{-drive file=disk.img,if=ide,index=0,format=raw}
     {-drive file=root_hdb.img,if=ide,index=1,format=raw}}]

set patterns {
    {"ATA /dev/hdb"     "\\[ATA\\] /dev/hdb detected"}
}

set res [wait_for_patterns $serial_log $timeout_sec $patterns]
kill_qemu $iso

report_section "ATA /dev/hdb detection" [lindex $res 0] [lindex $res 1]

# ================================================================
# TEST 5: VFS mount root=/dev/hdd
# ================================================================

create_disk "root_hdd.img" 4

set pid [run_qemu $iso $smp $serial_log $timeout_sec \
    {{-drive file=disk.img,if=ide,index=0,format=raw}
     {-drive file=root_hdd.img,if=ide,index=3,format=raw}}]

set patterns {
    {"ATA /dev/hdd"     "\\[ATA\\] /dev/hdd detected"}
}

set res [wait_for_patterns $serial_log $timeout_sec $patterns]
kill_qemu $iso

report_section "ATA /dev/hdd detection" [lindex $res 0] [lindex $res 1]

# ================================================================
# Final Summary
# ================================================================
set total_tests [expr {$global_pass + $global_fail}]
puts ""
puts "========================================="
puts "  Test Battery Summary"
puts "========================================="
puts "  $global_pass/$total_tests passed, $global_fail failed"

if {$global_fail > 0} {
    puts ""
    puts "  Failed tests:"
    foreach t $global_tests {
        if {[lindex $t 1] ne "PASS"} {
            puts "    - [lindex $t 0]: [lindex $t 1]"
        }
    }
    puts ""
    puts "  RESULT: FAIL"
    exit 1
}

puts ""
puts "  RESULT: PASS"
exit 0