// Copyright 2022 The ChromiumOS Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. use std::thread; use std::time::Duration; use base::getpid; use base::unix::process::fork_process; use base::AsRawDescriptor; use base::Tube; use minijail::Minijail; #[test] fn pid_diff() { let (tube, fork_tube) = Tube::pair().expect("failed to create tube"); let jail = Minijail::new().unwrap(); let keep_rds = vec![fork_tube.as_raw_descriptor()]; let pid = getpid(); let child = fork_process(jail, keep_rds, None, || { // checks that this is a genuine fork with a new PID if pid != getpid() { fork_tube.send(&1).unwrap() } else { fork_tube.send(&2).unwrap() } }) .expect("failed to fork"); assert_eq!(tube.recv::().unwrap(), 1); child.wait().unwrap(); } #[test] fn thread_name() { let (tube, fork_tube) = Tube::pair().expect("failed to create tube"); let jail = Minijail::new().unwrap(); let keep_rds = vec![fork_tube.as_raw_descriptor()]; let thread_name = String::from("thread_name"); let child = fork_process(jail, keep_rds, Some(thread_name.clone()), || { fork_tube.send::(&1).unwrap(); thread::sleep(Duration::from_secs(10)); }) .expect("failed to fork"); // wait the forked process running. tube.recv::().unwrap(); let thread_comm = std::fs::read_to_string(format!("/proc/{0}/task/{0}/comm", child.pid)).unwrap(); assert_eq!(thread_comm, thread_name + "\n"); unsafe { libc::kill(child.pid, libc::SIGKILL) }; child.wait().unwrap(); } #[test] fn thread_name_trimmed() { let (tube, fork_tube) = Tube::pair().expect("failed to create tube"); let jail = Minijail::new().unwrap(); let keep_rds = vec![fork_tube.as_raw_descriptor()]; let thread_name = String::from("12345678901234567890"); let child = fork_process(jail, keep_rds, Some(thread_name), || { fork_tube.send::(&1).unwrap(); thread::sleep(Duration::from_secs(10)); }) .expect("failed to fork"); // wait the forked process running. tube.recv::().unwrap(); let thread_comm = std::fs::read_to_string(format!("/proc/{0}/task/{0}/comm", child.pid)).unwrap(); assert_eq!(thread_comm, "123456789012345\n"); unsafe { libc::kill(child.pid, libc::SIGKILL) }; child.wait().unwrap(); } #[test] fn wait_for_success() { let jail = Minijail::new().unwrap(); let child = fork_process(jail, vec![], None, || { // exit successfully }) .expect("failed to fork"); assert_eq!(child.wait().unwrap(), 0); } #[test] fn wait_for_panic() { let jail = Minijail::new().unwrap(); let child = fork_process(jail, vec![], None, || { panic!("fails"); }) .expect("failed to fork"); assert_eq!(child.wait().unwrap(), 101); }