mirror of
https://github.com/rcore-os/rCore.git
synced 2024-11-21 23:56:18 +04:00
Implement automatic tests using kernel cmdline
This commit is contained in:
parent
dc19d38dc7
commit
5c33191765
@ -83,3 +83,4 @@ before_script:
|
|||||||
script:
|
script:
|
||||||
- cd user && make sfsimg arch=$ARCH && cd ..
|
- cd user && make sfsimg arch=$ARCH && cd ..
|
||||||
- cd kernel && make build arch=$ARCH $OPTS && cd ..
|
- cd kernel && make build arch=$ARCH $OPTS && cd ..
|
||||||
|
- cd tests && ./test.sh && cd ..
|
||||||
|
@ -26,6 +26,8 @@ board_raspi3 = ["bcm2837", "link_user"]
|
|||||||
raspi3_use_generic_timer = ["bcm2837/use_generic_timer"]
|
raspi3_use_generic_timer = ["bcm2837/use_generic_timer"]
|
||||||
# Hard link user program
|
# Hard link user program
|
||||||
link_user = []
|
link_user = []
|
||||||
|
# Run cmdline instead of user shell, useful for automatic testing
|
||||||
|
run_cmdline = []
|
||||||
|
|
||||||
[profile.dev]
|
[profile.dev]
|
||||||
# MUST >= 1 : Enable RVO to avoid stack overflow
|
# MUST >= 1 : Enable RVO to avoid stack overflow
|
||||||
|
@ -2,6 +2,12 @@
|
|||||||
# make build Build
|
# make build Build
|
||||||
# make run Build and run in QEMU
|
# make run Build and run in QEMU
|
||||||
# make justrun Run the last build
|
# make justrun Run the last build
|
||||||
|
# make runnet Build and run in QEMU with nic
|
||||||
|
# make justrunnet Run the last build with nic
|
||||||
|
# make runui Build and run in QEMU with gui
|
||||||
|
# make justrunui Run the last build with gui
|
||||||
|
# make runtest Build and run in QEMU with specified program
|
||||||
|
# make justruntest Run the last build with specified program
|
||||||
# make doc Generate docs
|
# make doc Generate docs
|
||||||
# make asm Open the deassemble file of the last build
|
# make asm Open the deassemble file of the last build
|
||||||
# make header Open 'objdump -h' of the last build
|
# make header Open 'objdump -h' of the last build
|
||||||
@ -19,7 +25,8 @@
|
|||||||
# board = none Running on QEMU
|
# board = none Running on QEMU
|
||||||
# | u540 Only available on riscv64, run on HiFive U540, use Sv39
|
# | u540 Only available on riscv64, run on HiFive U540, use Sv39
|
||||||
# | raspi3 Only available on aarch64, run on Raspberry Pi 3 Model B/B+
|
# | raspi3 Only available on aarch64, run on Raspberry Pi 3 Model B/B+
|
||||||
# pci_passthru Only available on x86_64, passthrough the specified PCI device
|
# pci_passthru = 0000:00:00.1 Only available on x86_64, passthrough the specified PCI device
|
||||||
|
# init = /bin/ls Only available on riscv64, run specified program instead of user shell
|
||||||
|
|
||||||
arch ?= riscv64
|
arch ?= riscv64
|
||||||
board ?= none
|
board ?= none
|
||||||
@ -28,6 +35,7 @@ LOG ?= debug
|
|||||||
graphic ?= off
|
graphic ?= off
|
||||||
smp ?= 4
|
smp ?= 4
|
||||||
pci_passthru ?=
|
pci_passthru ?=
|
||||||
|
init ?=
|
||||||
|
|
||||||
target := $(arch)
|
target := $(arch)
|
||||||
build_path := target/$(target)/$(mode)
|
build_path := target/$(target)/$(mode)
|
||||||
@ -54,7 +62,8 @@ endif
|
|||||||
|
|
||||||
### qemu options ###
|
### qemu options ###
|
||||||
qemu_opts := \
|
qemu_opts := \
|
||||||
-smp cores=$(smp)
|
-smp cores=$(smp) \
|
||||||
|
-append "test=biscuit/fork"
|
||||||
qemu_net_opts := \
|
qemu_net_opts := \
|
||||||
-netdev type=tap,id=net0,script=no,downscript=no
|
-netdev type=tap,id=net0,script=no,downscript=no
|
||||||
|
|
||||||
@ -112,6 +121,10 @@ ifneq ($(graphic), on)
|
|||||||
features += nographic
|
features += nographic
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ifneq ($(init), )
|
||||||
|
features += run_cmdline
|
||||||
|
endif
|
||||||
|
|
||||||
ifeq ($(board), raspi3)
|
ifeq ($(board), raspi3)
|
||||||
# qemu only has generic timer
|
# qemu only has generic timer
|
||||||
# TODO: configure system/generic timer automatically
|
# TODO: configure system/generic timer automatically
|
||||||
@ -162,7 +175,7 @@ gdb := $(prefix)gdb
|
|||||||
strip := $(prefix)strip
|
strip := $(prefix)strip
|
||||||
export CC = $(cc)
|
export CC = $(cc)
|
||||||
|
|
||||||
.PHONY: all clean run build asm doc justrun debug kernel sfsimg install runnet
|
.PHONY: all clean build asm doc debug kernel sfsimg install run justrun runnet justrunnet runui justrunui runtest justruntest
|
||||||
|
|
||||||
all: kernel
|
all: kernel
|
||||||
|
|
||||||
@ -177,6 +190,7 @@ doc:
|
|||||||
run: build justrun
|
run: build justrun
|
||||||
runnet: build justrunnet
|
runnet: build justrunnet
|
||||||
runui: build justrunui
|
runui: build justrunui
|
||||||
|
runtest: build justruntest
|
||||||
|
|
||||||
justrun:
|
justrun:
|
||||||
@qemu-system-$(arch) $(qemu_opts)
|
@qemu-system-$(arch) $(qemu_opts)
|
||||||
@ -189,6 +203,9 @@ justrunui: build
|
|||||||
-device virtio-gpu-device \
|
-device virtio-gpu-device \
|
||||||
-device virtio-mouse-device
|
-device virtio-mouse-device
|
||||||
|
|
||||||
|
justruntest: build
|
||||||
|
@qemu-system-$(arch) $(qemu_opts) --append $(init) -serial file:../tests/stdout -monitor null
|
||||||
|
|
||||||
debug: $(kernel) $(kernel_img)
|
debug: $(kernel) $(kernel_img)
|
||||||
@qemu-system-$(arch) $(qemu_opts) -s -S &
|
@qemu-system-$(arch) $(qemu_opts) -s -S &
|
||||||
@sleep 1
|
@sleep 1
|
||||||
|
@ -1,8 +1,10 @@
|
|||||||
use core::slice;
|
use core::slice;
|
||||||
|
use alloc::string::String;
|
||||||
|
|
||||||
use device_tree::{DeviceTree, Node};
|
use device_tree::{DeviceTree, Node};
|
||||||
|
|
||||||
use super::bus::virtio_mmio::virtio_probe;
|
use super::bus::virtio_mmio::virtio_probe;
|
||||||
|
use super::CMDLINE;
|
||||||
|
|
||||||
const DEVICE_TREE_MAGIC: u32 = 0xd00dfeed;
|
const DEVICE_TREE_MAGIC: u32 = 0xd00dfeed;
|
||||||
|
|
||||||
@ -13,6 +15,12 @@ fn walk_dt_node(dt: &Node) {
|
|||||||
virtio_probe(dt);
|
virtio_probe(dt);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if let Ok(bootargs) = dt.prop_str("bootargs") {
|
||||||
|
if bootargs.len() > 0 {
|
||||||
|
info!("Kernel cmdline: {}", bootargs);
|
||||||
|
*CMDLINE.write() = String::from(bootargs);
|
||||||
|
}
|
||||||
|
}
|
||||||
for child in dt.children.iter() {
|
for child in dt.children.iter() {
|
||||||
walk_dt_node(child);
|
walk_dt_node(child);
|
||||||
}
|
}
|
||||||
|
@ -86,3 +86,8 @@ pub fn init(dtb: usize) {
|
|||||||
pub fn init() {
|
pub fn init() {
|
||||||
bus::pci::init();
|
bus::pci::init();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
lazy_static! {
|
||||||
|
// Write only once at boot
|
||||||
|
pub static ref CMDLINE: RwLock<String> = RwLock::new(String::new());
|
||||||
|
}
|
@ -4,7 +4,9 @@ use alloc::string::String;
|
|||||||
use alloc::vec::Vec;
|
use alloc::vec::Vec;
|
||||||
use crate::fs::{ROOT_INODE, INodeExt};
|
use crate::fs::{ROOT_INODE, INodeExt};
|
||||||
use crate::process::*;
|
use crate::process::*;
|
||||||
|
use crate::drivers::CMDLINE;
|
||||||
|
|
||||||
|
#[cfg(not(feature = "run_cmdline"))]
|
||||||
pub fn run_user_shell() {
|
pub fn run_user_shell() {
|
||||||
if let Ok(inode) = ROOT_INODE.lookup("rust/sh") {
|
if let Ok(inode) = ROOT_INODE.lookup("rust/sh") {
|
||||||
let data = inode.read_as_vec().unwrap();
|
let data = inode.read_as_vec().unwrap();
|
||||||
@ -14,6 +16,14 @@ pub fn run_user_shell() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "run_cmdline")]
|
||||||
|
pub fn run_user_shell() {
|
||||||
|
let cmdline = CMDLINE.read();
|
||||||
|
let inode = ROOT_INODE.lookup(&cmdline).unwrap();
|
||||||
|
let data = inode.read_as_vec().unwrap();
|
||||||
|
processor().manager().add(Thread::new_user(data.as_slice(), cmdline.split(' ')));
|
||||||
|
}
|
||||||
|
|
||||||
pub extern fn shell(_arg: usize) -> ! {
|
pub extern fn shell(_arg: usize) -> ! {
|
||||||
let files = ROOT_INODE.list().unwrap();
|
let files = ROOT_INODE.list().unwrap();
|
||||||
println!("Available programs: {:?}", files);
|
println!("Available programs: {:?}", files);
|
||||||
|
1
tests/.gitignore
vendored
Normal file
1
tests/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
stdout
|
@ -1,17 +0,0 @@
|
|||||||
set timeout -1
|
|
||||||
set send_slow {1 .1}
|
|
||||||
proc send {ignore arg} {
|
|
||||||
sleep .1
|
|
||||||
exp_send -s -- $arg
|
|
||||||
}
|
|
||||||
|
|
||||||
cd ../kernel
|
|
||||||
spawn make run arch=x86_64
|
|
||||||
sleep 2
|
|
||||||
expect ">>"
|
|
||||||
sleep 2
|
|
||||||
send -- "biscuit/fork\r"
|
|
||||||
sleep 5
|
|
||||||
expect "hello from 100"
|
|
||||||
expect "parent done!"
|
|
||||||
send -- "busybox halt -f\r"
|
|
1
tests/hello_rust.cmd
Normal file
1
tests/hello_rust.cmd
Normal file
@ -0,0 +1 @@
|
|||||||
|
rust/hello_rust
|
3
tests/hello_rust.out
Normal file
3
tests/hello_rust.out
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
Hello Rust uCore!
|
||||||
|
I am process 0.
|
||||||
|
hello pass.
|
@ -1,16 +0,0 @@
|
|||||||
set timeout -1
|
|
||||||
set send_slow {1 .1}
|
|
||||||
proc send {ignore arg} {
|
|
||||||
sleep .1
|
|
||||||
exp_send -s -- $arg
|
|
||||||
}
|
|
||||||
|
|
||||||
cd ../kernel
|
|
||||||
spawn make run arch=x86_64
|
|
||||||
sleep 2
|
|
||||||
expect ">>"
|
|
||||||
sleep 2
|
|
||||||
send -- "biscuit/killtest\r"
|
|
||||||
sleep 2
|
|
||||||
expect "success"
|
|
||||||
send -- "busybox halt -f\r"
|
|
@ -1,6 +1,17 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
for f in *.exp
|
for f in *.cmd
|
||||||
do
|
do
|
||||||
echo run $f
|
echo testing $f begin
|
||||||
timeout 30s expect $f
|
(
|
||||||
|
cd ../kernel
|
||||||
|
exec timeout 10s make runtest arch=riscv64 init=$(cat ../tests/$f)
|
||||||
|
) &
|
||||||
|
|
||||||
|
pid=$!
|
||||||
|
|
||||||
|
wait $pid
|
||||||
|
|
||||||
|
diff -I 'bbl loader' -I 'Hello RISCV! in hart' -u ${f%.cmd}.out stdout || { echo 'testing failed for' $f; exit 1; }
|
||||||
|
|
||||||
|
echo testing $f pass
|
||||||
done
|
done
|
||||||
|
2
user
2
user
@ -1 +1 @@
|
|||||||
Subproject commit e60682ae3241dd6c18798a411051f7209d60a9ba
|
Subproject commit 586e682f064ca124a353d992cdf365e0d8234cb7
|
Loading…
Reference in New Issue
Block a user