1 extern crate libc;
2 extern crate tempdir;
3 
4 use std::ffi::OsStr;
5 use std::io::prelude::*;
6 
7 use tempdir::TempDir;
8 
run<S: AsRef<OsStr>>(cmd: S, args: &[S]) -> u329 fn run<S: AsRef<OsStr>>(cmd: S, args: &[S]) -> u32 {
10     let mut cmd = std::process::Command::new(cmd);
11     for arg in args {
12         cmd.arg(arg);
13     }
14     let mut child = cmd.spawn().unwrap();
15     let pid = child.id();
16     child.wait().unwrap();
17 
18     std::thread::sleep(std::time::Duration::from_millis(100));
19     pid
20 }
21 
22 #[test]
test_umask_chdir()23 fn test_umask_chdir() {
24     let tmpdir = TempDir::new("chdir").unwrap();
25 
26     // third argument is the umask: 255 == 0o377
27     let args = vec![tmpdir.path().to_str().unwrap(), "test", "255"];
28     run("target/debug/examples/test_chdir", &args);
29 
30     let filename = tmpdir.path().join("test");
31     let mut data = Vec::new();
32     std::fs::File::open(&filename)
33         .unwrap()
34         .read_to_end(&mut data)
35         .unwrap();
36     assert!(data == b"test");
37     // due to the umask, the file should have been created with -w
38     assert!(filename.metadata().unwrap().permissions().readonly());
39 }
40 
41 #[test]
test_pid()42 fn test_pid() {
43     let tmpdir = TempDir::new("chdir").unwrap();
44     let pid_file = tmpdir.path().join("pid");
45 
46     let args = vec![pid_file.to_str().unwrap()];
47     let child_pid = run("target/debug/examples/test_pid", &args);
48 
49     let mut data = String::new();
50     std::fs::File::open(&pid_file)
51         .unwrap()
52         .read_to_string(&mut data)
53         .unwrap();
54     let pid: u32 = data.parse().unwrap();
55     assert!(pid != child_pid)
56 }
57 
58 #[test]
double_run()59 fn double_run() {
60     let tmpdir = TempDir::new("double_run").unwrap();
61     let pid_file = tmpdir.path().join("pid");
62     let first_result = tmpdir.path().join("first");
63     let second_result = tmpdir.path().join("second");
64 
65     for file in &[&first_result, &second_result] {
66         let args = vec![pid_file.to_str().unwrap(), file.to_str().unwrap()];
67         run("target/debug/examples/test_double_run", &args);
68     }
69     std::thread::sleep(std::time::Duration::from_millis(100));
70 
71     {
72         let mut data = String::new();
73         std::fs::File::open(&first_result)
74             .unwrap()
75             .read_to_string(&mut data)
76             .unwrap();
77         assert!(data == "ok")
78     }
79 
80     {
81         let mut data = String::new();
82         std::fs::File::open(&second_result)
83             .unwrap()
84             .read_to_string(&mut data)
85             .unwrap();
86         assert!(data == "error")
87     }
88 }
89 
90 #[test]
91 #[cfg(target_os = "macos")]
test_uid_gid()92 fn test_uid_gid() {
93     let tmpdir = TempDir::new("uid_gid").unwrap();
94     let result_file = tmpdir.path().join("result");
95 
96     let args = vec!["nobody", "daemon", &result_file.to_str().unwrap()];
97     run("target/debug/examples/test_uid_gid", &args);
98 
99     let own_uid_gid_string = unsafe { format!("{} {}", libc::getuid(), libc::getgid()) };
100 
101     let mut data = String::new();
102     std::fs::File::open(&result_file)
103         .unwrap()
104         .read_to_string(&mut data)
105         .unwrap();
106     assert!(!data.is_empty());
107     assert!(data != own_uid_gid_string)
108 }
109 
110 #[test]
test_redirect_streams()111 fn test_redirect_streams() {
112     let tmpdir = TempDir::new("redirect").unwrap();
113     let stdout_file = tmpdir.path().join("stdout");
114     let stderr_file = tmpdir.path().join("stderr");
115 
116     let args = vec![stdout_file.to_str().unwrap(), stderr_file.to_str().unwrap()];
117     run("target/debug/examples/test_redirect_streams", &args);
118 
119     std::thread::sleep(std::time::Duration::from_millis(100));
120 
121     let mut stdout = String::new();
122     std::fs::File::open(&stdout_file)
123         .unwrap()
124         .read_to_string(&mut stdout)
125         .unwrap();
126 
127     let mut stderr = String::new();
128     std::fs::File::open(&stderr_file)
129         .unwrap()
130         .read_to_string(&mut stderr)
131         .unwrap();
132 
133     assert_eq!(stdout, "stdout\nnewline\n");
134     assert_eq!(stderr, "stderr\nnewline\n");
135 }
136