24 #include <sys/resource.h>
33 const char* kSimpleCommand =
"cmd /c dir \\";
35 const char* kSimpleCommand =
"ls /";
38 struct SubprocessTest :
public testing::Test {
45 TEST_F(SubprocessTest, BadCommandStderr) {
46 Subprocess* subproc = subprocs_.Add(
"cmd /c ninja_no_such_command");
49 while (!subproc->
Done()) {
60 TEST_F(SubprocessTest, NoSuchCommand) {
61 Subprocess* subproc = subprocs_.Add(
"ninja_no_such_command");
64 while (!subproc->
Done()) {
73 ASSERT_EQ(
"CreateProcess failed: The system cannot find the file "
80 TEST_F(SubprocessTest, InterruptChild) {
81 Subprocess* subproc = subprocs_.Add(
"kill -INT $$");
84 while (!subproc->
Done()) {
91 TEST_F(SubprocessTest, InterruptParent) {
92 Subprocess* subproc = subprocs_.Add(
"kill -INT $PPID ; sleep 1");
95 while (!subproc->
Done()) {
96 bool interrupted = subprocs_.DoWork();
101 ASSERT_FALSE(
"We should have been interrupted");
104 TEST_F(SubprocessTest, InterruptChildWithSigTerm) {
105 Subprocess* subproc = subprocs_.Add(
"kill -TERM $$");
108 while (!subproc->
Done()) {
115 TEST_F(SubprocessTest, InterruptParentWithSigTerm) {
116 Subprocess* subproc = subprocs_.Add(
"kill -TERM $PPID ; sleep 1");
119 while (!subproc->
Done()) {
120 bool interrupted = subprocs_.DoWork();
125 ASSERT_FALSE(
"We should have been interrupted");
128 TEST_F(SubprocessTest, InterruptChildWithSigHup) {
129 Subprocess* subproc = subprocs_.Add(
"kill -HUP $$");
132 while (!subproc->
Done()) {
139 TEST_F(SubprocessTest, InterruptParentWithSigHup) {
140 Subprocess* subproc = subprocs_.Add(
"kill -HUP $PPID ; sleep 1");
143 while (!subproc->
Done()) {
144 bool interrupted = subprocs_.DoWork();
149 ASSERT_FALSE(
"We should have been interrupted");
154 if (isatty(0) && isatty(1) && isatty(2)) {
156 subprocs_.Add(
"test -t 0 -a -t 1 -a -t 2",
true);
159 while (!subproc->
Done()) {
170 Subprocess* subproc = subprocs_.Add(kSimpleCommand);
173 while (!subproc->
Done()) {
179 ASSERT_EQ(1u, subprocs_.finished_.size());
184 const char* kCommands[3] = {
195 for (
int i = 0; i < 3; ++i) {
196 processes[i] = subprocs_.Add(kCommands[i]);
200 ASSERT_EQ(3u, subprocs_.running_.size());
201 for (
int i = 0; i < 3; ++i) {
202 ASSERT_FALSE(processes[i]->Done());
203 ASSERT_EQ(
"", processes[i]->GetOutput());
206 while (!processes[0]->Done() || !processes[1]->Done() ||
207 !processes[2]->Done()) {
208 ASSERT_GT(subprocs_.running_.size(), 0u);
212 ASSERT_EQ(0u, subprocs_.running_.size());
213 ASSERT_EQ(3u, subprocs_.finished_.size());
215 for (
int i = 0; i < 3; ++i) {
217 ASSERT_NE(
"", processes[i]->GetOutput());
222 #if defined(USE_PPOLL)
223 TEST_F(SubprocessTest, SetWithLots) {
226 const unsigned kNumProcs = 1025;
230 ASSERT_EQ(0, getrlimit(RLIMIT_NOFILE, &rlim));
231 if (rlim.rlim_cur < kNumProcs) {
232 printf(
"Raise [ulimit -n] above %u (currently %lu) to make this test go\n",
233 kNumProcs,
static_cast<unsigned long>(rlim.rlim_cur));
237 vector<Subprocess*> procs;
238 for (
size_t i = 0; i < kNumProcs; ++i) {
239 Subprocess* subproc = subprocs_.Add(
"/bin/echo");
241 procs.push_back(subproc);
243 while (!subprocs_.running_.empty())
245 for (
size_t i = 0; i < procs.size(); ++i) {
247 ASSERT_NE(
"", procs[i]->GetOutput());
249 ASSERT_EQ(kNumProcs, subprocs_.finished_.size());
260 while (!subproc->
Done()) {
264 ASSERT_EQ(1u, subprocs_.finished_.size());
SubprocessSet runs a ppoll/pselect() loop around a set of Subprocesses.
Subprocess wraps a single async subprocess.
ExitStatus Finish()
Returns ExitSuccess on successful process exit, ExitInterrupted if the process was interrupted,...
const std::string & GetOutput() const
TEST_F(SubprocessTest, BadCommandStderr)