• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2022 The ChromiumOS Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #[cfg(unix)]
6 mod test {
7     use std::thread;
8     use std::time::Duration;
9 
10     use base::getpid;
11     use base::unix::process::fork_process;
12     use base::AsRawDescriptor;
13     use base::Tube;
14     use minijail::Minijail;
15 
pid_diff()16     pub fn pid_diff() {
17         let (tube, fork_tube) = Tube::pair().expect("failed to create tube");
18         let jail = Minijail::new().unwrap();
19         let keep_rds = vec![fork_tube.as_raw_descriptor()];
20 
21         let pid = getpid();
22         let child = fork_process(jail, keep_rds, None, || {
23             // checks that this is a genuine fork with a new PID
24             if pid != getpid() {
25                 fork_tube.send(&1).unwrap()
26             } else {
27                 fork_tube.send(&2).unwrap()
28             }
29         })
30         .expect("failed to fork");
31 
32         assert_eq!(tube.recv::<u32>().unwrap(), 1);
33         child.wait().unwrap();
34     }
35 
thread_name()36     pub fn thread_name() {
37         let (tube, fork_tube) = Tube::pair().expect("failed to create tube");
38         let jail = Minijail::new().unwrap();
39         let keep_rds = vec![fork_tube.as_raw_descriptor()];
40         let thread_name = String::from("thread_name");
41 
42         let child = fork_process(jail, keep_rds, Some(thread_name.clone()), || {
43             fork_tube.send::<u32>(&1).unwrap();
44             thread::sleep(Duration::from_secs(10));
45         })
46         .expect("failed to fork");
47 
48         // wait the forked process running.
49         tube.recv::<u32>().unwrap();
50         let thread_comm =
51             std::fs::read_to_string(format!("/proc/{0}/task/{0}/comm", child.pid)).unwrap();
52 
53         assert_eq!(thread_comm, thread_name + "\n");
54 
55         unsafe { libc::kill(child.pid, libc::SIGKILL) };
56         child.wait().unwrap();
57     }
58 
thread_name_trimmed()59     pub fn thread_name_trimmed() {
60         let (tube, fork_tube) = Tube::pair().expect("failed to create tube");
61         let jail = Minijail::new().unwrap();
62         let keep_rds = vec![fork_tube.as_raw_descriptor()];
63         let thread_name = String::from("12345678901234567890");
64 
65         let child = fork_process(jail, keep_rds, Some(thread_name), || {
66             fork_tube.send::<u32>(&1).unwrap();
67             thread::sleep(Duration::from_secs(10));
68         })
69         .expect("failed to fork");
70 
71         // wait the forked process running.
72         tube.recv::<u32>().unwrap();
73         let thread_comm =
74             std::fs::read_to_string(format!("/proc/{0}/task/{0}/comm", child.pid)).unwrap();
75 
76         assert_eq!(thread_comm, "123456789012345\n");
77 
78         unsafe { libc::kill(child.pid, libc::SIGKILL) };
79         child.wait().unwrap();
80     }
81 
wait_for_success()82     pub fn wait_for_success() {
83         let jail = Minijail::new().unwrap();
84         let child = fork_process(jail, vec![], None, || {
85             // exit successfully
86         })
87         .expect("failed to fork");
88 
89         assert_eq!(child.wait().unwrap(), 0);
90     }
91 
wait_for_panic()92     pub fn wait_for_panic() {
93         let jail = Minijail::new().unwrap();
94         let child = fork_process(jail, vec![], None, || {
95             panic!("fails");
96         })
97         .expect("failed to fork");
98 
99         assert_eq!(child.wait().unwrap(), 101);
100     }
101 }
102 
main()103 fn main() {
104     let args = libtest_mimic::Arguments {
105         // Force single-threaded execution to allow safe use of libc::fork in these tests.
106         test_threads: Some(1),
107         ..libtest_mimic::Arguments::from_args()
108     };
109 
110     let tests = vec![
111         #[cfg(unix)]
112         libtest_mimic::Trial::test("pid_diff", move || {
113             test::pid_diff();
114             Ok(())
115         }),
116         #[cfg(unix)]
117         libtest_mimic::Trial::test("thread_name", move || {
118             test::thread_name();
119             Ok(())
120         }),
121         #[cfg(unix)]
122         libtest_mimic::Trial::test("thread_name_trimmed", move || {
123             test::thread_name_trimmed();
124             Ok(())
125         }),
126         #[cfg(unix)]
127         libtest_mimic::Trial::test("wait_for_success", move || {
128             test::wait_for_success();
129             Ok(())
130         }),
131         #[cfg(unix)]
132         libtest_mimic::Trial::test("wait_for_panic", move || {
133             test::wait_for_panic();
134             Ok(())
135         }),
136     ];
137     libtest_mimic::run(&args, tests).exit();
138 }
139