]>
git.proxmox.com Git - ceph.git/blob - ceph/src/test/test_subprocess.cc
29c7b94acd7f4f521e9f29d883da698f08124117
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"
25 bool read_from_fd(int fd
, std::string
&out
) {
28 ssize_t n
= safe_read(fd
, buf
, sizeof(buf
) - 1);
36 TEST(SubProcess
, True
)
39 ASSERT_EQ(p
.spawn(), 0);
40 ASSERT_EQ(p
.join(), 0);
41 ASSERT_TRUE(p
.err().c_str()[0] == '\0');
44 TEST(SubProcess
, False
)
46 SubProcess
p("false");
47 ASSERT_EQ(p
.spawn(), 0);
48 ASSERT_EQ(p
.join(), 1);
49 ASSERT_FALSE(p
.err().c_str()[0] == '\0');
52 TEST(SubProcess
, NotFound
)
54 SubProcess
p("NOTEXISTENTBINARY", SubProcess::CLOSE
, SubProcess::CLOSE
, SubProcess::PIPE
);
55 ASSERT_EQ(p
.spawn(), 0);
57 ASSERT_TRUE(read_from_fd(p
.get_stderr(), buf
));
58 std::cerr
<< "stderr: " << buf
;
59 ASSERT_EQ(p
.join(), 1);
60 std::cerr
<< "err: " << p
.err() << std::endl
;
61 ASSERT_FALSE(p
.err().c_str()[0] == '\0');
64 TEST(SubProcess
, Echo
)
66 SubProcess
echo("echo", SubProcess::CLOSE
, SubProcess::PIPE
);
67 echo
.add_cmd_args("1", "2", "3", NULL
);
69 ASSERT_EQ(echo
.spawn(), 0);
71 ASSERT_TRUE(read_from_fd(echo
.get_stdout(), buf
));
72 std::cerr
<< "stdout: " << buf
;
73 ASSERT_EQ(buf
, "1 2 3\n");
74 ASSERT_EQ(echo
.join(), 0);
75 ASSERT_TRUE(echo
.err().c_str()[0] == '\0');
80 SubProcess
cat("cat", SubProcess::PIPE
, SubProcess::PIPE
, SubProcess::PIPE
);
82 ASSERT_EQ(cat
.spawn(), 0);
83 std::string
msg("to my, trociny!");
84 int n
= write(cat
.get_stdin(), msg
.c_str(), msg
.size());
85 ASSERT_EQ(n
, (int)msg
.size());
88 ASSERT_TRUE(read_from_fd(cat
.get_stdout(), buf
));
89 std::cerr
<< "stdout: " << buf
<< std::endl
;
91 ASSERT_TRUE(read_from_fd(cat
.get_stderr(), buf
));
93 ASSERT_EQ(cat
.join(), 0);
94 ASSERT_TRUE(cat
.err().c_str()[0] == '\0');
97 TEST(SubProcess
, CatDevNull
)
99 SubProcess
cat("cat", SubProcess::PIPE
, SubProcess::PIPE
, SubProcess::PIPE
);
100 cat
.add_cmd_arg("/dev/null");
102 ASSERT_EQ(cat
.spawn(), 0);
104 ASSERT_TRUE(read_from_fd(cat
.get_stdout(), buf
));
106 ASSERT_TRUE(read_from_fd(cat
.get_stderr(), buf
));
108 ASSERT_EQ(cat
.join(), 0);
109 ASSERT_TRUE(cat
.err().c_str()[0] == '\0');
112 TEST(SubProcess
, Killed
)
114 SubProcessTimed
cat("cat", SubProcess::PIPE
, SubProcess::PIPE
);
116 ASSERT_EQ(cat
.spawn(), 0);
118 ASSERT_EQ(cat
.join(), 128 + SIGTERM
);
119 std::cerr
<< "err: " << cat
.err() << std::endl
;
120 ASSERT_FALSE(cat
.err().c_str()[0] == '\0');
123 TEST(SubProcess
, CatWithArgs
)
125 SubProcess
cat("cat", SubProcess::PIPE
, SubProcess::PIPE
, SubProcess::PIPE
);
126 cat
.add_cmd_args("/dev/stdin", "/dev/null", "/NOTEXIST", NULL
);
128 ASSERT_EQ(cat
.spawn(), 0);
129 std::string
msg("Hello, Word!");
130 int n
= write(cat
.get_stdin(), msg
.c_str(), msg
.size());
131 ASSERT_EQ(n
, (int)msg
.size());
134 ASSERT_TRUE(read_from_fd(cat
.get_stdout(), buf
));
135 std::cerr
<< "stdout: " << buf
<< std::endl
;
137 ASSERT_TRUE(read_from_fd(cat
.get_stderr(), buf
));
138 std::cerr
<< "stderr: " << buf
;
139 ASSERT_FALSE(buf
.empty());
140 ASSERT_EQ(cat
.join(), 1);
141 std::cerr
<< "err: " << cat
.err() << std::endl
;
142 ASSERT_FALSE(cat
.err().c_str()[0] == '\0');
145 TEST(SubProcess
, Subshell
)
147 SubProcess
sh("/bin/sh", SubProcess::PIPE
, SubProcess::PIPE
, SubProcess::PIPE
);
148 sh
.add_cmd_args("-c",
151 "echo 'error from subshell' >&2; "
152 "/bin/sh -c 'exit 13'", NULL
);
153 ASSERT_EQ(sh
.spawn(), 0);
154 std::string
msg("hello via subshell");
155 int n
= write(sh
.get_stdin(), msg
.c_str(), msg
.size());
156 ASSERT_EQ(n
, (int)msg
.size());
159 ASSERT_TRUE(read_from_fd(sh
.get_stdout(), buf
));
160 std::cerr
<< "stdout: " << buf
<< std::endl
;
162 ASSERT_TRUE(read_from_fd(sh
.get_stderr(), buf
));
163 std::cerr
<< "stderr: " << buf
;
164 ASSERT_EQ(buf
, "error from subshell\n");
165 ASSERT_EQ(sh
.join(), 13);
166 std::cerr
<< "err: " << sh
.err() << std::endl
;
167 ASSERT_FALSE(sh
.err().c_str()[0] == '\0');
170 TEST(SubProcessTimed
, True
)
172 SubProcessTimed
p("true", SubProcess::CLOSE
, SubProcess::CLOSE
, SubProcess::CLOSE
, 10);
173 ASSERT_EQ(p
.spawn(), 0);
174 ASSERT_EQ(p
.join(), 0);
175 ASSERT_TRUE(p
.err().c_str()[0] == '\0');
178 TEST(SubProcessTimed
, SleepNoTimeout
)
180 SubProcessTimed
sleep("sleep", SubProcess::CLOSE
, SubProcess::CLOSE
, SubProcess::CLOSE
, 0);
181 sleep
.add_cmd_arg("1");
183 ASSERT_EQ(sleep
.spawn(), 0);
184 ASSERT_EQ(sleep
.join(), 0);
185 ASSERT_TRUE(sleep
.err().c_str()[0] == '\0');
188 TEST(SubProcessTimed
, Killed
)
190 SubProcessTimed
cat("cat", SubProcess::PIPE
, SubProcess::PIPE
, SubProcess::PIPE
, 5);
192 ASSERT_EQ(cat
.spawn(), 0);
195 ASSERT_TRUE(read_from_fd(cat
.get_stdout(), buf
));
196 ASSERT_TRUE(buf
.empty());
197 ASSERT_TRUE(read_from_fd(cat
.get_stderr(), buf
));
198 ASSERT_TRUE(buf
.empty());
199 ASSERT_EQ(cat
.join(), 128 + SIGTERM
);
200 std::cerr
<< "err: " << cat
.err() << std::endl
;
201 ASSERT_FALSE(cat
.err().c_str()[0] == '\0');
204 TEST(SubProcessTimed
, SleepTimedout
)
206 SubProcessTimed
sleep("sleep", SubProcess::CLOSE
, SubProcess::CLOSE
, SubProcess::PIPE
, 1);
207 sleep
.add_cmd_arg("10");
209 ASSERT_EQ(sleep
.spawn(), 0);
211 ASSERT_TRUE(read_from_fd(sleep
.get_stderr(), buf
));
212 std::cerr
<< "stderr: " << buf
;
213 ASSERT_FALSE(buf
.empty());
214 ASSERT_EQ(sleep
.join(), 128 + SIGKILL
);
215 std::cerr
<< "err: " << sleep
.err() << std::endl
;
216 ASSERT_FALSE(sleep
.err().c_str()[0] == '\0');
219 TEST(SubProcessTimed
, SubshellNoTimeout
)
221 SubProcessTimed
sh("/bin/sh", SubProcess::PIPE
, SubProcess::PIPE
, SubProcess::PIPE
, 0);
222 sh
.add_cmd_args("-c", "cat >&2", NULL
);
223 ASSERT_EQ(sh
.spawn(), 0);
224 std::string
msg("the quick brown fox jumps over the lazy dog");
225 int n
= write(sh
.get_stdin(), msg
.c_str(), msg
.size());
226 ASSERT_EQ(n
, (int)msg
.size());
229 ASSERT_TRUE(read_from_fd(sh
.get_stdout(), buf
));
230 std::cerr
<< "stdout: " << buf
<< std::endl
;
231 ASSERT_TRUE(buf
.empty());
232 ASSERT_TRUE(read_from_fd(sh
.get_stderr(), buf
));
233 std::cerr
<< "stderr: " << buf
<< std::endl
;
235 ASSERT_EQ(sh
.join(), 0);
236 ASSERT_TRUE(sh
.err().c_str()[0] == '\0');
239 TEST(SubProcessTimed
, SubshellKilled
)
241 SubProcessTimed
sh("/bin/sh", SubProcess::PIPE
, SubProcess::PIPE
, SubProcess::PIPE
, 10);
242 sh
.add_cmd_args("-c", "sh -c cat", NULL
);
243 ASSERT_EQ(sh
.spawn(), 0);
244 std::string
msg("etaoin shrdlu");
245 int n
= write(sh
.get_stdin(), msg
.c_str(), msg
.size());
246 ASSERT_EQ(n
, (int)msg
.size());
249 ASSERT_TRUE(read_from_fd(sh
.get_stderr(), buf
));
250 ASSERT_TRUE(buf
.empty());
251 ASSERT_EQ(sh
.join(), 128 + SIGTERM
);
252 std::cerr
<< "err: " << sh
.err() << std::endl
;
253 ASSERT_FALSE(sh
.err().c_str()[0] == '\0');
256 TEST(SubProcessTimed
, SubshellTimedout
)
258 SubProcessTimed
sh("/bin/sh", SubProcess::PIPE
, SubProcess::PIPE
, SubProcess::PIPE
, 1, SIGTERM
);
259 sh
.add_cmd_args("-c", "sleep 1000& cat; NEVER REACHED", NULL
);
260 ASSERT_EQ(sh
.spawn(), 0);
262 ASSERT_TRUE(read_from_fd(sh
.get_stderr(), buf
));
263 std::cerr
<< "stderr: " << buf
;
264 ASSERT_FALSE(buf
.empty());
265 ASSERT_EQ(sh
.join(), 128 + SIGTERM
);
266 std::cerr
<< "err: " << sh
.err() << std::endl
;
267 ASSERT_FALSE(sh
.err().c_str()[0] == '\0');