This skill should be used when creating new integration tests for Breenix kernel features. Use for writing shared QEMU tests with checkpoint signals, creating xtask test commands, adding test workflows, and following Breenix testing patterns.
This skill should be used when creating new integration tests for Breenix kernel features. Use for writing shared QEMU tests with checkpoint signals, creating xtask test commands, adding test workflows, and following Breenix testing patterns.
Integration Test Authoring for Breenix
Create integration tests for kernel features using Breenix testing patterns.
Purpose
Breenix uses integration tests that run the actual kernel in QEMU and verify behavior through serial output. This skill provides patterns for creating robust tests.
Breenix Testing Architecture
Shared QEMU Pattern
Most tests use tests/shared_qemu.rs to share a single QEMU instance:
Benefits:
All tests run in ~45 seconds (vs 10+ minutes for separate QEMU instances)
Tests run in sequence in one kernel boot
Shared setup and teardown
Test Structure:
#[test]fntest_memory_allocation() {
shared_qemu::run_test("memory", "✅ MEMORY TEST COMPLETE");
}
Checkpoint Signals
Tests wait for specific strings in serial output:
Common signals:
🎯 KERNEL_POST_TESTS_COMPLETE 🎯 - All POST tests done
✅ [FEATURE] TEST COMPLETE - Specific test done
USERSPACE OUTPUT: - Userspace execution
Custom markers for specific tests
Creating a New Integration Test
Step 1: Add Kernel-Side Test Code
Location: kernel/src/ (appropriate module)
#[cfg(feature = "testing")]pubfntest_my_feature() {
use crate::serial::serial_println;
serial_println!("=== Testing My Feature ===");
// Test setupletresult = setup_feature();
assert!(result.is_ok(), "Setup failed");
// Test operationsletoutcome = perform_operation();
assert_eq!(outcome, expected_value);
// Signal completion
serial_println!("✅ MY_FEATURE TEST COMPLETE");
}
// Kernel side#[cfg(feature = "testing")]pubfntest_allocator() {
serial_println!("=== Allocator Test ===");
letptr = allocate(1024);
assert!(!ptr.is_null());
deallocate(ptr, 1024);
serial_println!("✅ ALLOCATOR TEST COMPLETE");
}
// Test side#[test]fntest_allocator() {
shared_qemu::run_test("allocator", "✅ ALLOCATOR TEST COMPLETE");
}
Pattern 2: Userspace Test
Use when: Testing userspace execution or syscalls
// Create userspace test program// userspace/tests/my_test.rs#![no_std]#![no_main]use libbreenix::{sys_write, sys_exit};
#[no_mangle]pubextern"C"fn_start() -> ! {
sys_write(1, b"My test output\n");
sys_exit(0);
}
// Build with userspace/tests/build.sh// Kernel side - load and execute#[cfg(feature = "testing")]pubfntest_userspace_my_feature() {
letbinary = include_bytes!("../../userspace/tests/my_test.elf");
create_and_run_process("my_test", binary);
// Process will print "My test output" via syscall
}
// Test side#[test]fntest_userspace_my_feature() {
shared_qemu::run_test("userspace", "My test output");
}
Use when: Preventing a specific bug from returning
// Document the original issue#[cfg(feature = "testing")]pubfntest_page_fault_regression() {
serial_println!("=== Page Fault Regression Test ===");
serial_println!("Tests fix from DIRECT_EXECUTION_FIX.md");
// Reproduce the scenario that used to failletprocess = create_userspace_process();
// This used to cause double fault at int 0x80
process.trigger_syscall();
serial_println!("✅ NO DOUBLE FAULT - Regression test passed");
}
Best Practices
Clear signals: Use unique, greppable completion markers
Descriptive names: Test name should describe what's being tested
Guard with feature flag: All test code behind #[cfg(feature = "testing")]
Serial output: Use serial_println! for test communication
Document purpose: Comment explaining what the test verifies
Handle failures: Use assertions that provide useful error messages
Cleanup: Ensure resources are freed even if test fails
Timeout appropriately: Set realistic timeouts in xtask or CI
Debugging Tests
Test fails locally
# Run with visual output
BREENIX_VISUAL_TEST=1 cargo test test_my_feature
# Use quick debug for iteration
kernel-debug-loop/scripts/quick_debug.py \
--signal "✅ MY_FEATURE TEST COMPLETE" \
--timeout 15
# Check logs
grep "MY_FEATURE" logs/breenix_*.log
Test fails in CI only
# Download CI artifacts# Analyze with ci-failure-analysis
ci-failure-analysis/scripts/analyze_ci_failure.py \
target/xtask_*_output.txt
# Check for environment differences# - Timeout too short for CI# - Missing dependencies# - Timing-dependent behavior
Summary
Integration test authoring requires:
Kernel-side test code with checkpoint signals
Rust integration test using shared QEMU
Optional xtask command for complex tests
Optional CI workflow for automated testing
Clear completion signals
Appropriate timeouts
Comprehensive documentation
Follow existing test patterns in tests/ for consistency.