]>
git.proxmox.com Git - ceph.git/blob - ceph/src/test/test_subprocess.cc
1 // -*- mode:C; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
4 * Ceph distributed storage system
6 * Copyright (C) 2015 Mirantis Inc
8 * Author: Mykola Golub <mgolub@mirantis.com>
10 * This library is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU Lesser General Public
12 * License as published by the Free Software Foundation; either
13 * version 2.1 of the License, or (at your option) any later version.
21 #include "common/SubProcess.h"
22 #include "common/safe_io.h"
23 #include "gtest/gtest.h"
24 #include "common/fork_function.h"
26 bool read_from_fd(int fd
, std::string
&out
) {
29 ssize_t n
= safe_read(fd
, buf
, sizeof(buf
) - 1);
37 TEST(SubProcess
, True
)
40 ASSERT_EQ(p
.spawn(), 0);
41 ASSERT_EQ(p
.join(), 0);
42 ASSERT_TRUE(p
.err().c_str()[0] == '\0');
45 TEST(SubProcess
, False
)
47 SubProcess
p("false");
48 ASSERT_EQ(p
.spawn(), 0);
49 ASSERT_EQ(p
.join(), 1);
50 ASSERT_FALSE(p
.err().c_str()[0] == '\0');
53 TEST(SubProcess
, NotFound
)
55 SubProcess
p("NOTEXISTENTBINARY", SubProcess::CLOSE
, SubProcess::CLOSE
, SubProcess::PIPE
);
56 ASSERT_EQ(p
.spawn(), 0);
58 ASSERT_TRUE(read_from_fd(p
.get_stderr(), buf
));
59 std::cerr
<< "stderr: " << buf
;
60 ASSERT_EQ(p
.join(), 1);
61 std::cerr
<< "err: " << p
.err() << std::endl
;
62 ASSERT_FALSE(p
.err().c_str()[0] == '\0');
65 TEST(SubProcess
, Echo
)
67 SubProcess
echo("echo", SubProcess::CLOSE
, SubProcess::PIPE
);
68 echo
.add_cmd_args("1", "2", "3", NULL
);
70 ASSERT_EQ(echo
.spawn(), 0);
72 ASSERT_TRUE(read_from_fd(echo
.get_stdout(), buf
));
73 std::cerr
<< "stdout: " << buf
;
74 ASSERT_EQ(buf
, "1 2 3\n");
75 ASSERT_EQ(echo
.join(), 0);
76 ASSERT_TRUE(echo
.err().c_str()[0] == '\0');
81 SubProcess
cat("cat", SubProcess::PIPE
, SubProcess::PIPE
, SubProcess::PIPE
);
83 ASSERT_EQ(cat
.spawn(), 0);
84 std::string
msg("to my, trociny!");
85 int n
= write(cat
.get_stdin(), msg
.c_str(), msg
.size());
86 ASSERT_EQ(n
, (int)msg
.size());
89 ASSERT_TRUE(read_from_fd(cat
.get_stdout(), buf
));
90 std::cerr
<< "stdout: " << buf
<< std::endl
;
92 ASSERT_TRUE(read_from_fd(cat
.get_stderr(), buf
));
94 ASSERT_EQ(cat
.join(), 0);
95 ASSERT_TRUE(cat
.err().c_str()[0] == '\0');
98 TEST(SubProcess
, CatDevNull
)
100 SubProcess
cat("cat", SubProcess::PIPE
, SubProcess::PIPE
, SubProcess::PIPE
);
101 cat
.add_cmd_arg("/dev/null");
103 ASSERT_EQ(cat
.spawn(), 0);
105 ASSERT_TRUE(read_from_fd(cat
.get_stdout(), buf
));
107 ASSERT_TRUE(read_from_fd(cat
.get_stderr(), buf
));
109 ASSERT_EQ(cat
.join(), 0);
110 ASSERT_TRUE(cat
.err().c_str()[0] == '\0');
113 TEST(SubProcess
, Killed
)
115 SubProcessTimed
cat("cat", SubProcess::PIPE
, SubProcess::PIPE
);
117 ASSERT_EQ(cat
.spawn(), 0);
119 ASSERT_EQ(cat
.join(), 128 + SIGTERM
);
120 std::cerr
<< "err: " << cat
.err() << std::endl
;
121 ASSERT_FALSE(cat
.err().c_str()[0] == '\0');
124 TEST(SubProcess
, CatWithArgs
)
126 SubProcess
cat("cat", SubProcess::PIPE
, SubProcess::PIPE
, SubProcess::PIPE
);
127 cat
.add_cmd_args("/dev/stdin", "/dev/null", "/NOTEXIST", NULL
);
129 ASSERT_EQ(cat
.spawn(), 0);
130 std::string
msg("Hello, Word!");
131 int n
= write(cat
.get_stdin(), msg
.c_str(), msg
.size());
132 ASSERT_EQ(n
, (int)msg
.size());
135 ASSERT_TRUE(read_from_fd(cat
.get_stdout(), buf
));
136 std::cerr
<< "stdout: " << buf
<< std::endl
;
138 ASSERT_TRUE(read_from_fd(cat
.get_stderr(), buf
));
139 std::cerr
<< "stderr: " << buf
;
140 ASSERT_FALSE(buf
.empty());
141 ASSERT_EQ(cat
.join(), 1);
142 std::cerr
<< "err: " << cat
.err() << std::endl
;
143 ASSERT_FALSE(cat
.err().c_str()[0] == '\0');
146 TEST(SubProcess
, Subshell
)
148 SubProcess
sh("/bin/sh", SubProcess::PIPE
, SubProcess::PIPE
, SubProcess::PIPE
);
149 sh
.add_cmd_args("-c",
152 "echo 'error from subshell' >&2; "
153 "/bin/sh -c 'exit 13'", NULL
);
154 ASSERT_EQ(sh
.spawn(), 0);
155 std::string
msg("hello via subshell");
156 int n
= write(sh
.get_stdin(), msg
.c_str(), msg
.size());
157 ASSERT_EQ(n
, (int)msg
.size());
160 ASSERT_TRUE(read_from_fd(sh
.get_stdout(), buf
));
161 std::cerr
<< "stdout: " << buf
<< std::endl
;
163 ASSERT_TRUE(read_from_fd(sh
.get_stderr(), buf
));
164 std::cerr
<< "stderr: " << buf
;
165 ASSERT_EQ(buf
, "error from subshell\n");
166 ASSERT_EQ(sh
.join(), 13);
167 std::cerr
<< "err: " << sh
.err() << std::endl
;
168 ASSERT_FALSE(sh
.err().c_str()[0] == '\0');
171 TEST(SubProcessTimed
, True
)
173 SubProcessTimed
p("true", SubProcess::CLOSE
, SubProcess::CLOSE
, SubProcess::CLOSE
, 10);
174 ASSERT_EQ(p
.spawn(), 0);
175 ASSERT_EQ(p
.join(), 0);
176 ASSERT_TRUE(p
.err().c_str()[0] == '\0');
179 TEST(SubProcessTimed
, SleepNoTimeout
)
181 SubProcessTimed
sleep("sleep", SubProcess::CLOSE
, SubProcess::CLOSE
, SubProcess::CLOSE
, 0);
182 sleep
.add_cmd_arg("1");
184 ASSERT_EQ(sleep
.spawn(), 0);
185 ASSERT_EQ(sleep
.join(), 0);
186 ASSERT_TRUE(sleep
.err().c_str()[0] == '\0');
189 TEST(SubProcessTimed
, Killed
)
191 SubProcessTimed
cat("cat", SubProcess::PIPE
, SubProcess::PIPE
, SubProcess::PIPE
, 5);
193 ASSERT_EQ(cat
.spawn(), 0);
196 ASSERT_TRUE(read_from_fd(cat
.get_stdout(), buf
));
197 ASSERT_TRUE(buf
.empty());
198 ASSERT_TRUE(read_from_fd(cat
.get_stderr(), buf
));
199 ASSERT_TRUE(buf
.empty());
200 ASSERT_EQ(cat
.join(), 128 + SIGTERM
);
201 std::cerr
<< "err: " << cat
.err() << std::endl
;
202 ASSERT_FALSE(cat
.err().c_str()[0] == '\0');
205 TEST(SubProcessTimed
, SleepTimedout
)
207 SubProcessTimed
sleep("sleep", SubProcess::CLOSE
, SubProcess::CLOSE
, SubProcess::PIPE
, 1);
208 sleep
.add_cmd_arg("10");
210 ASSERT_EQ(sleep
.spawn(), 0);
212 ASSERT_TRUE(read_from_fd(sleep
.get_stderr(), buf
));
213 std::cerr
<< "stderr: " << buf
;
214 ASSERT_FALSE(buf
.empty());
215 ASSERT_EQ(sleep
.join(), 128 + SIGKILL
);
216 std::cerr
<< "err: " << sleep
.err() << std::endl
;
217 ASSERT_FALSE(sleep
.err().c_str()[0] == '\0');
220 TEST(SubProcessTimed
, SubshellNoTimeout
)
222 SubProcessTimed
sh("/bin/sh", SubProcess::PIPE
, SubProcess::PIPE
, SubProcess::PIPE
, 0);
223 sh
.add_cmd_args("-c", "cat >&2", NULL
);
224 ASSERT_EQ(sh
.spawn(), 0);
225 std::string
msg("the quick brown fox jumps over the lazy dog");
226 int n
= write(sh
.get_stdin(), msg
.c_str(), msg
.size());
227 ASSERT_EQ(n
, (int)msg
.size());
230 ASSERT_TRUE(read_from_fd(sh
.get_stdout(), buf
));
231 std::cerr
<< "stdout: " << buf
<< std::endl
;
232 ASSERT_TRUE(buf
.empty());
233 ASSERT_TRUE(read_from_fd(sh
.get_stderr(), buf
));
234 std::cerr
<< "stderr: " << buf
<< std::endl
;
236 ASSERT_EQ(sh
.join(), 0);
237 ASSERT_TRUE(sh
.err().c_str()[0] == '\0');
240 TEST(SubProcessTimed
, SubshellKilled
)
242 SubProcessTimed
sh("/bin/sh", SubProcess::PIPE
, SubProcess::PIPE
, SubProcess::PIPE
, 10);
243 sh
.add_cmd_args("-c", "sh -c cat", NULL
);
244 ASSERT_EQ(sh
.spawn(), 0);
245 std::string
msg("etaoin shrdlu");
246 int n
= write(sh
.get_stdin(), msg
.c_str(), msg
.size());
247 ASSERT_EQ(n
, (int)msg
.size());
250 ASSERT_TRUE(read_from_fd(sh
.get_stderr(), buf
));
251 ASSERT_TRUE(buf
.empty());
252 ASSERT_EQ(sh
.join(), 128 + SIGTERM
);
253 std::cerr
<< "err: " << sh
.err() << std::endl
;
254 ASSERT_FALSE(sh
.err().c_str()[0] == '\0');
257 TEST(SubProcessTimed
, SubshellTimedout
)
259 SubProcessTimed
sh("/bin/sh", SubProcess::PIPE
, SubProcess::PIPE
, SubProcess::PIPE
, 1, SIGTERM
);
260 sh
.add_cmd_args("-c", "sleep 1000& cat; NEVER REACHED", NULL
);
261 ASSERT_EQ(sh
.spawn(), 0);
263 ASSERT_TRUE(read_from_fd(sh
.get_stderr(), buf
));
264 std::cerr
<< "stderr: " << buf
;
265 ASSERT_FALSE(buf
.empty());
266 ASSERT_EQ(sh
.join(), 128 + SIGTERM
);
267 std::cerr
<< "err: " << sh
.err() << std::endl
;
268 ASSERT_FALSE(sh
.err().c_str()[0] == '\0');
271 TEST(fork_function
, normal
)
273 ASSERT_EQ(0, fork_function(10, std::cerr
, [&]() { return 0; }));
274 ASSERT_EQ(1, fork_function(10, std::cerr
, [&]() { return 1; }));
275 ASSERT_EQ(13, fork_function(10, std::cerr
, [&]() { return 13; }));
276 ASSERT_EQ(-1, fork_function(10, std::cerr
, [&]() { return -1; }));
277 ASSERT_EQ(-13, fork_function(10, std::cerr
, [&]() { return -13; }));
278 ASSERT_EQ(-ETIMEDOUT
,
279 fork_function(10, std::cerr
, [&]() { return -ETIMEDOUT
; }));
282 TEST(fork_function
, timeout
)
284 ASSERT_EQ(-ETIMEDOUT
, fork_function(2, std::cerr
, [&]() {
287 ASSERT_EQ(-ETIMEDOUT
, fork_function(2, std::cerr
, [&]() {
290 ASSERT_EQ(-ETIMEDOUT
, fork_function(2, std::cerr
, [&]() {