1
0
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:
Jiajie Chen 2019-03-26 16:03:32 +08:00
parent dc19d38dc7
commit 5c33191765
13 changed files with 66 additions and 40 deletions

View File

@ -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 ..

View File

@ -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

View File

@ -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

View File

@ -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);
} }

View File

@ -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());
}

View File

@ -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
View File

@ -0,0 +1 @@
stdout

View File

@ -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
View File

@ -0,0 +1 @@
rust/hello_rust

3
tests/hello_rust.out Normal file
View File

@ -0,0 +1,3 @@
Hello Rust uCore!
I am process 0.
hello pass.

View File

@ -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"

View File

@ -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

@ -1 +1 @@
Subproject commit e60682ae3241dd6c18798a411051f7209d60a9ba Subproject commit 586e682f064ca124a353d992cdf365e0d8234cb7