cmake: add a simple does-the-os-boot-successfully test
the test will repeated boot the operating system and use the serial log to determine if the boot was successful. if a problem is detected, a debugger is automatically started and attached.
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
include(System-Disk)
|
||||
include(QEMU)
|
||||
include(Bochs)
|
||||
include(Test)
|
||||
|
||||
35
arch/x86_64/Test.cmake
Normal file
35
arch/x86_64/Test.cmake
Normal file
@@ -0,0 +1,35 @@
|
||||
find_package(Python COMPONENTS Interpreter)
|
||||
if (NOT Python_EXECUTABLE)
|
||||
message(STATUS "QEMU: Cannot find python. Direct-kernel boot testing unavailable")
|
||||
return()
|
||||
endif ()
|
||||
|
||||
find_program(QEMU qemu-system-${TARGET_ARCH} REQUIRED)
|
||||
if (NOT QEMU)
|
||||
message(STATUS "QEMU: Cannot find qemu-system-${TARGET_ARCH}. Direct-kernel boot testing unavailable")
|
||||
return()
|
||||
endif ()
|
||||
|
||||
set(patched_kernel ${CMAKE_CURRENT_BINARY_DIR}/kernel/${kernel_name}.elf32)
|
||||
set(generic_flags -m 1G -cpu qemu64,+rdrand)
|
||||
set(this_dir ${CMAKE_SOURCE_DIR}/arch/${CMAKE_SYSTEM_PROCESSOR})
|
||||
set(no_debug_flags)
|
||||
|
||||
if (${CMAKE_HOST_SYSTEM_NAME} STREQUAL "Linux")
|
||||
message(STATUS "QEMU: Enabling KVM acceleration")
|
||||
set(no_debug_flags ${no_debug_flags} -enable-kvm)
|
||||
else ()
|
||||
message(STATUS "QEMU: Host system is not Linux. KVM acceleration unavailable")
|
||||
endif ()
|
||||
|
||||
message(STATUS "Test: Enable direct-kernel boot testing with QEMU")
|
||||
add_custom_target(test-successful-boot
|
||||
COMMAND
|
||||
${this_dir}/test/successful-boot
|
||||
${Python_EXECUTABLE}
|
||||
${this_dir}/test/check-results
|
||||
${QEMU}
|
||||
${patched_kernel}
|
||||
${sys_dir}/${bsp_name}
|
||||
USES_TERMINAL
|
||||
DEPENDS ${patched_kernel} bsp)
|
||||
52
arch/x86_64/test/check-results
Normal file
52
arch/x86_64/test/check-results
Normal file
@@ -0,0 +1,52 @@
|
||||
#!/usr/bin/env python3
|
||||
# vim: ft=python
|
||||
import sys
|
||||
|
||||
def log(f, msg):
|
||||
print(msg)
|
||||
f.write(msg)
|
||||
f.write('\n')
|
||||
|
||||
def successful_boot(boot_log, out):
|
||||
nr_panic = boot_log.count("---[ kernel panic")
|
||||
if nr_panic == 1:
|
||||
log(out, "Kernel panic!")
|
||||
return 1
|
||||
if nr_panic > 1:
|
||||
log(out, "Multiple kernel panics!")
|
||||
return 1
|
||||
|
||||
nr_boots = boot_log.count('Mango kernel version')
|
||||
if nr_boots == 0:
|
||||
log(out, "Kernel didn't start!")
|
||||
return 1
|
||||
if nr_boots > 1:
|
||||
log(out, "Kernel rebooted during test!")
|
||||
return 1
|
||||
|
||||
nr_finish = boot_log.count("ld finished")
|
||||
if nr_finish == 0:
|
||||
log(out, "Didn't reach end of boot sequence!")
|
||||
return 1
|
||||
if nr_finish > 1:
|
||||
log(out, "Boot sequence performed multiple times!")
|
||||
return 1
|
||||
|
||||
return 0
|
||||
|
||||
|
||||
tests = {
|
||||
'successful-boot': successful_boot,
|
||||
}
|
||||
|
||||
test_name = sys.argv[1]
|
||||
boot_log_path = sys.argv[2]
|
||||
out_path = sys.argv[3]
|
||||
|
||||
boot_log_file = open(boot_log_path, 'r')
|
||||
boot_log = boot_log_file.read()
|
||||
boot_log_file.close()
|
||||
|
||||
out_file = open(out_path, 'a')
|
||||
|
||||
exit(tests[test_name](boot_log, out_file))
|
||||
69
arch/x86_64/test/successful-boot
Executable file
69
arch/x86_64/test/successful-boot
Executable file
@@ -0,0 +1,69 @@
|
||||
#!/bin/bash
|
||||
# vim: ft=bash
|
||||
|
||||
|
||||
log_dir="test-results/successful-boot"
|
||||
rm -rf $log_dir
|
||||
mkdir -p $log_dir
|
||||
|
||||
logfile="$log_dir/main.log"
|
||||
|
||||
log() {
|
||||
if [ -n "$logfile" ]; then
|
||||
printf '%s\n' "$@" >> "$logfile"
|
||||
fi
|
||||
|
||||
printf '%s\n' "$@"
|
||||
}
|
||||
|
||||
log "Running boot test. Press Ctrl+\\ to stop."
|
||||
|
||||
declare -i result
|
||||
declare -i count
|
||||
declare -i pass
|
||||
declare -i fail
|
||||
count=0
|
||||
pass=0
|
||||
fail=0
|
||||
python=$1
|
||||
validation_script=$2
|
||||
qemu=$3
|
||||
kernel=$4
|
||||
initrd=$5
|
||||
|
||||
while true; do
|
||||
log "Test $count"
|
||||
result_file="$log_dir/$count.log"
|
||||
$qemu \
|
||||
-kernel $kernel \
|
||||
-initrd $initrd \
|
||||
-serial file:$result_file \
|
||||
-cpu qemu64,+rdrand \
|
||||
--append kernel.early-console=ttyS0 -s > /dev/null &
|
||||
qemu_id=$!
|
||||
|
||||
sleep 1.2
|
||||
|
||||
$python $validation_script successful-boot $result_file $logfile
|
||||
result=$?
|
||||
|
||||
count=$count+1
|
||||
|
||||
if [ $result -eq 0 ]; then
|
||||
pass=$pass+1
|
||||
else
|
||||
mv $result_file "$result_file.FAIL"
|
||||
fail=$fail+1
|
||||
lldb \
|
||||
-o "file kernel/mango_kernel.debug" \
|
||||
-o "gdb-remote localhost:1234"
|
||||
fi
|
||||
|
||||
kill -INT $qemu_id
|
||||
|
||||
log "---------------"
|
||||
log "Total tests: $count"
|
||||
log "Pass: $pass"
|
||||
log "Fail: $fail"
|
||||
log "---------------"
|
||||
done
|
||||
Reference in New Issue
Block a user