diff --git a/os/src/lang_items.rs b/os/src/lang_items.rs index 6788148a..a33943a1 100644 --- a/os/src/lang_items.rs +++ b/os/src/lang_items.rs @@ -18,7 +18,7 @@ fn panic(info: &PanicInfo) -> ! { unsafe { backtrace(); } - shutdown() + shutdown(255) } unsafe fn backtrace() { diff --git a/os/src/sbi.rs b/os/src/sbi.rs index 75b2f432..a402b91a 100644 --- a/os/src/sbi.rs +++ b/os/src/sbi.rs @@ -39,7 +39,7 @@ pub fn console_getchar() -> usize { sbi_call(SBI_CONSOLE_GETCHAR, 0, 0, 0) } -pub fn shutdown() -> ! { +pub fn shutdown(exit_code: usize) -> ! { sbi_call(SBI_SHUTDOWN, 0, 0, 0); panic!("It should shutdown!"); } diff --git a/os/src/task/mod.rs b/os/src/task/mod.rs index 9f8e3b10..07ebc81a 100644 --- a/os/src/task/mod.rs +++ b/os/src/task/mod.rs @@ -74,8 +74,15 @@ pub fn exit_current_and_run_next(exit_code: i32) { if tid == 0 { let pid = process.getpid(); if pid == IDLE_PID { - println!("[kernel] Idle process exit ..."); - crate::sbi::shutdown(); + println!( + "[kernel] Idle process exit with exit_code {} ...", + exit_code + ); + if exit_code != 0 { + crate::sbi::shutdown(255); //255 == -1 for err hint + } else { + crate::sbi::shutdown(0); //0 for success hint + } } remove_from_pid2process(pid); let mut process_inner = process.inner_exclusive_access(); diff --git a/user/src/bin/race_adder_arg.rs b/user/src/bin/race_adder_arg.rs index 7c8b7074..ba99b62f 100644 --- a/user/src/bin/race_adder_arg.rs +++ b/user/src/bin/race_adder_arg.rs @@ -34,7 +34,10 @@ pub fn main(argc: usize, argv: &[&str]) -> i32 { } else if argc == 2 { count = argv[1].to_string().parse::().unwrap(); } else { - println!("ERROR in argv"); + println!( + "ERROR in argv, argc is {}, argv[0] {} , argv[1] {} , argv[2] {}", + argc, argv[0], argv[1], argv[2] + ); exit(-1); } diff --git a/user/src/bin/run_pipe_test.rs b/user/src/bin/run_pipe_test.rs index ea99b6a7..5f50b0d6 100644 --- a/user/src/bin/run_pipe_test.rs +++ b/user/src/bin/run_pipe_test.rs @@ -8,7 +8,7 @@ use user_lib::{exec, fork, wait}; #[no_mangle] pub fn main() -> i32 { - for i in 0..1000 { + for i in 0..50 { if fork() == 0 { exec("pipe_large_test\0", &[core::ptr::null::()]); } else { diff --git a/user/src/bin/usertests.rs b/user/src/bin/usertests.rs index 7d104d27..0a8ca1c9 100644 --- a/user/src/bin/usertests.rs +++ b/user/src/bin/usertests.rs @@ -3,75 +3,125 @@ #[macro_use] extern crate user_lib; - -static SUCC_TESTS: &[&str] = &[ - "matrix\0", - "exit\0", - "fantastic_text\0", - "filetest_simple\0", - "forktest_simple\0", - "forktest\0", - "forktest2\0", - "forktree\0", - "hello_world\0", - "huge_write\0", - "mpsc_sem\0", - "phil_din_mutex\0", - "pipe_large_test\0", - "pipetest\0", - "race_adder_atomic\0", - "race_adder_mutex_blocking\0", - "race_adder_mutex_spin\0", - "race_adder_arg\0", - "sleep_simple\0", - "sleep\0", - "sleep_simple\0", - "sync_sem\0", - "test_condvar\0", - "threads_arg\0", - "threads\0", - "yield\0", - "run_pipe_test\0", +// item of TESTS : app_name(argv_0), argv_1, argv_2, argv_3, exit_code +static SUCC_TESTS: &[(&str, &str, &str, &str, i32)] = &[ + ("cmdline_args\0", "1\0", "2\0", "\0", 0), + ("cmdline_args\0", "1\0", "2\0", "3\0", 0), + ("matrix\0", "\0", "\0", "\0", 0), + ("exit\0", "\0", "\0", "\0", 0), + ("fantastic_text\0", "\0", "\0", "\0", 0), + ("filetest_simple\0", "\0", "\0", "\0", 0), + ("forktest_simple\0", "\0", "\0", "\0", 0), + ("forktest\0", "\0", "\0", "\0", 0), + ("forktest2\0", "\0", "\0", "\0", 0), + ("forktree\0", "\0", "\0", "\0", 0), + ("hello_world\0", "\0", "\0", "\0", 0), + ("huge_write\0", "\0", "\0", "\0", 0), + ("mpsc_sem\0", "\0", "\0", "\0", 0), + ("phil_din_mutex\0", "\0", "\0", "\0", 0), + ("pipe_large_test\0", "\0", "\0", "\0", 0), + ("pipetest\0", "\0", "\0", "\0", 0), + ("race_adder_atomic\0", "\0", "\0", "\0", 0), + ("race_adder_mutex_blocking\0", "\0", "\0", "\0", 0), + ("race_adder_mutex_spin\0", "\0", "\0", "\0", 0), + ("race_adder_arg\0", "3\0", "\0", "\0", 0), + ("sleep_simple\0", "\0", "\0", "\0", 0), + ("sleep\0", "\0", "\0", "\0", 0), + ("sleep_simple\0", "\0", "\0", "\0", 0), + ("sync_sem\0", "\0", "\0", "\0", 0), + ("test_condvar\0", "\0", "\0", "\0", 0), + ("threads_arg\0", "\0", "\0", "\0", 0), + ("threads\0", "\0", "\0", "\0", 0), + ("yield\0", "\0", "\0", "\0", 0), + ("run_pipe_test\0", "\0", "\0", "\0", 0), ]; - -static FAIL_TESTS: &[&str] = &[ - "stack_overflow\0", - "race_adder_loop\0", - "priv_csr\0", - "priv_inst\0", - "store_fault\0", - "until_timeout\0", - "stack_overflow\0", - "race_adder\0", - "huge_write_mt\0", + +static FAIL_TESTS: &[(&str, &str, &str, &str, i32)] = &[ + ("stack_overflow\0", "\0", "\0", "\0", -11), + ("race_adder_loop\0", "\0", "\0", "\0", -6), + ("priv_csr\0", "\0", "\0", "\0", -4), + ("priv_inst\0", "\0", "\0", "\0", -4), + ("store_fault\0", "\0", "\0", "\0", -11), + ("until_timeout\0", "\0", "\0", "\0", -6), + ("race_adder\0", "\0", "\0", "\0", -6), + ("huge_write_mt\0", "\0", "\0", "\0", -6), ]; use user_lib::{exec, fork, waitpid}; -fn run_tests(tests: &[&str], judge: F) { +fn run_tests(tests: &[(&str, &str, &str, &str, i32)]) -> i32 { + let mut pass_num = 0; + let mut arr: [*const u8; 3] = [ + core::ptr::null::(), + core::ptr::null::(), + core::ptr::null::(), + ]; + for test in tests { - println!("Usertests: Running {}", test); + println!("Usertests: Running {}", test.0); + + if test.1 != "\0" { + arr[0] = test.1.as_ptr(); + if test.2 != "\0" { + arr[1] = test.2.as_ptr(); + if test.3 != "\0" { + arr[2] = test.3.as_ptr(); + } else { + arr[2] = core::ptr::null::(); + } + } else { + arr[1] = core::ptr::null::(); + arr[2] = core::ptr::null::(); + } + } else { + arr[0] = core::ptr::null::(); + arr[1] = core::ptr::null::(); + arr[2] = core::ptr::null::(); + } + let pid = fork(); if pid == 0 { - exec(*test, &[core::ptr::null::()]); + exec(test.0, &arr[..]); panic!("unreachable!"); } else { let mut exit_code: i32 = Default::default(); let wait_pid = waitpid(pid as usize, &mut exit_code); assert_eq!(pid, wait_pid); - judge(exit_code); + if exit_code == test.4 { + // summary apps with exit_code + pass_num = pass_num + 1; + } println!( "\x1b[32mUsertests: Test {} in Process {} exited with code {}\x1b[0m", - test, pid, exit_code + test.0, pid, exit_code ); } } + pass_num } #[no_mangle] pub fn main() -> i32 { - run_tests(SUCC_TESTS, |code| assert!(code == 0)); - run_tests(FAIL_TESTS, |code| assert!(code != 0)); - println!("Usertests passed!"); - 0 + let succ_num = run_tests(SUCC_TESTS); + let err_num = run_tests(FAIL_TESTS); + if succ_num == SUCC_TESTS.len() as i32 && err_num == FAIL_TESTS.len() as i32 { + println!("Usertests passed!"); + return 0; + } + if succ_num != SUCC_TESTS.len() as i32 { + println!( + "all successed app_num is {} , but only passed {}", + SUCC_TESTS.len(), + succ_num + ); + } + if err_num != FAIL_TESTS.len() as i32 { + println!( + "all failed app_num is {} , but only passed {}", + FAIL_TESTS.len(), + err_num + ); + } + println!("Usertests failed!"); + return -1; }