10b675d88309bdcbb387bbee907c4ef9d98e412a2Reid Kleckner//===- unittest/Support/ProgramTest.cpp -----------------------------------===//
20b675d88309bdcbb387bbee907c4ef9d98e412a2Reid Kleckner//
30b675d88309bdcbb387bbee907c4ef9d98e412a2Reid Kleckner//                     The LLVM Compiler Infrastructure
40b675d88309bdcbb387bbee907c4ef9d98e412a2Reid Kleckner//
50b675d88309bdcbb387bbee907c4ef9d98e412a2Reid Kleckner// This file is distributed under the University of Illinois Open Source
60b675d88309bdcbb387bbee907c4ef9d98e412a2Reid Kleckner// License. See LICENSE.TXT for details.
70b675d88309bdcbb387bbee907c4ef9d98e412a2Reid Kleckner//
80b675d88309bdcbb387bbee907c4ef9d98e412a2Reid Kleckner//===----------------------------------------------------------------------===//
90b675d88309bdcbb387bbee907c4ef9d98e412a2Reid Kleckner
100b675d88309bdcbb387bbee907c4ef9d98e412a2Reid Kleckner#include "llvm/Support/CommandLine.h"
1150188c1f42c122640ab9ccac2134acf371c26b2cRafael Espindola#include "llvm/Support/FileSystem.h"
120b675d88309bdcbb387bbee907c4ef9d98e412a2Reid Kleckner#include "llvm/Support/Path.h"
130b675d88309bdcbb387bbee907c4ef9d98e412a2Reid Kleckner#include "llvm/Support/Program.h"
140b675d88309bdcbb387bbee907c4ef9d98e412a2Reid Kleckner#include "gtest/gtest.h"
150b675d88309bdcbb387bbee907c4ef9d98e412a2Reid Kleckner#include <stdlib.h>
16268adf2a03cf352593b632c5249c83f4fc56956fReid Kleckner#if defined(__APPLE__)
178eca677afee90d6a28487fd3db0bca129bde7186Reid Kleckner# include <crt_externs.h>
18268adf2a03cf352593b632c5249c83f4fc56956fReid Kleckner#elif !defined(_MSC_VER)
198eca677afee90d6a28487fd3db0bca129bde7186Reid Kleckner// Forward declare environ in case it's not provided by stdlib.h.
208eca677afee90d6a28487fd3db0bca129bde7186Reid Klecknerextern char **environ;
218eca677afee90d6a28487fd3db0bca129bde7186Reid Kleckner#endif
220b675d88309bdcbb387bbee907c4ef9d98e412a2Reid Kleckner
23c269c4f505a2dd7c3a88d12706257410ed6c7068Tareq A. Siraj#if defined(LLVM_ON_UNIX)
24c269c4f505a2dd7c3a88d12706257410ed6c7068Tareq A. Siraj#include <unistd.h>
25c269c4f505a2dd7c3a88d12706257410ed6c7068Tareq A. Sirajvoid sleep_for(unsigned int seconds) {
26c269c4f505a2dd7c3a88d12706257410ed6c7068Tareq A. Siraj  sleep(seconds);
27c269c4f505a2dd7c3a88d12706257410ed6c7068Tareq A. Siraj}
28c269c4f505a2dd7c3a88d12706257410ed6c7068Tareq A. Siraj#elif defined(LLVM_ON_WIN32)
29c269c4f505a2dd7c3a88d12706257410ed6c7068Tareq A. Siraj#include <windows.h>
30c269c4f505a2dd7c3a88d12706257410ed6c7068Tareq A. Sirajvoid sleep_for(unsigned int seconds) {
31c269c4f505a2dd7c3a88d12706257410ed6c7068Tareq A. Siraj  Sleep(seconds * 1000);
32c269c4f505a2dd7c3a88d12706257410ed6c7068Tareq A. Siraj}
33c269c4f505a2dd7c3a88d12706257410ed6c7068Tareq A. Siraj#else
34c269c4f505a2dd7c3a88d12706257410ed6c7068Tareq A. Siraj#error sleep_for is not implemented on your platform.
35c269c4f505a2dd7c3a88d12706257410ed6c7068Tareq A. Siraj#endif
36c269c4f505a2dd7c3a88d12706257410ed6c7068Tareq A. Siraj
372a839438559bc7d3067ff2166105f47e0af06b37Reid Kleckner// From TestMain.cpp.
382a839438559bc7d3067ff2166105f47e0af06b37Reid Klecknerextern const char *TestMainArgv0;
392a839438559bc7d3067ff2166105f47e0af06b37Reid Kleckner
400b675d88309bdcbb387bbee907c4ef9d98e412a2Reid Klecknernamespace {
410b675d88309bdcbb387bbee907c4ef9d98e412a2Reid Kleckner
420b675d88309bdcbb387bbee907c4ef9d98e412a2Reid Klecknerusing namespace llvm;
430b675d88309bdcbb387bbee907c4ef9d98e412a2Reid Klecknerusing namespace sys;
440b675d88309bdcbb387bbee907c4ef9d98e412a2Reid Kleckner
450b675d88309bdcbb387bbee907c4ef9d98e412a2Reid Klecknerstatic cl::opt<std::string>
460b675d88309bdcbb387bbee907c4ef9d98e412a2Reid KlecknerProgramTestStringArg1("program-test-string-arg1");
470b675d88309bdcbb387bbee907c4ef9d98e412a2Reid Klecknerstatic cl::opt<std::string>
480b675d88309bdcbb387bbee907c4ef9d98e412a2Reid KlecknerProgramTestStringArg2("program-test-string-arg2");
490b675d88309bdcbb387bbee907c4ef9d98e412a2Reid Kleckner
508eca677afee90d6a28487fd3db0bca129bde7186Reid Klecknerstatic void CopyEnvironment(std::vector<const char *> &out) {
518eca677afee90d6a28487fd3db0bca129bde7186Reid Kleckner#ifdef __APPLE__
528eca677afee90d6a28487fd3db0bca129bde7186Reid Kleckner  char **envp = *_NSGetEnviron();
538eca677afee90d6a28487fd3db0bca129bde7186Reid Kleckner#else
548eca677afee90d6a28487fd3db0bca129bde7186Reid Kleckner  // environ seems to work for Windows and most other Unices.
558eca677afee90d6a28487fd3db0bca129bde7186Reid Kleckner  char **envp = environ;
568eca677afee90d6a28487fd3db0bca129bde7186Reid Kleckner#endif
57cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  while (*envp != nullptr) {
588eca677afee90d6a28487fd3db0bca129bde7186Reid Kleckner    out.push_back(*envp);
598eca677afee90d6a28487fd3db0bca129bde7186Reid Kleckner    ++envp;
608eca677afee90d6a28487fd3db0bca129bde7186Reid Kleckner  }
618eca677afee90d6a28487fd3db0bca129bde7186Reid Kleckner}
628eca677afee90d6a28487fd3db0bca129bde7186Reid Kleckner
630b675d88309bdcbb387bbee907c4ef9d98e412a2Reid KlecknerTEST(ProgramTest, CreateProcessTrailingSlash) {
640b675d88309bdcbb387bbee907c4ef9d98e412a2Reid Kleckner  if (getenv("LLVM_PROGRAM_TEST_CHILD")) {
650b675d88309bdcbb387bbee907c4ef9d98e412a2Reid Kleckner    if (ProgramTestStringArg1 == "has\\\\ trailing\\" &&
660b675d88309bdcbb387bbee907c4ef9d98e412a2Reid Kleckner        ProgramTestStringArg2 == "has\\\\ trailing\\") {
670b675d88309bdcbb387bbee907c4ef9d98e412a2Reid Kleckner      exit(0);  // Success!  The arguments were passed and parsed.
680b675d88309bdcbb387bbee907c4ef9d98e412a2Reid Kleckner    }
690b675d88309bdcbb387bbee907c4ef9d98e412a2Reid Kleckner    exit(1);
700b675d88309bdcbb387bbee907c4ef9d98e412a2Reid Kleckner  }
710b675d88309bdcbb387bbee907c4ef9d98e412a2Reid Kleckner
7250188c1f42c122640ab9ccac2134acf371c26b2cRafael Espindola  std::string my_exe =
7350188c1f42c122640ab9ccac2134acf371c26b2cRafael Espindola      sys::fs::getMainExecutable(TestMainArgv0, &ProgramTestStringArg1);
740b675d88309bdcbb387bbee907c4ef9d98e412a2Reid Kleckner  const char *argv[] = {
750b675d88309bdcbb387bbee907c4ef9d98e412a2Reid Kleckner    my_exe.c_str(),
76f51ecf2ad068f1bcc55940dee8c66acf4a44ed60Tareq A. Siraj    "--gtest_filter=ProgramTest.CreateProcessTrailingSlash",
770b675d88309bdcbb387bbee907c4ef9d98e412a2Reid Kleckner    "-program-test-string-arg1", "has\\\\ trailing\\",
780b675d88309bdcbb387bbee907c4ef9d98e412a2Reid Kleckner    "-program-test-string-arg2", "has\\\\ trailing\\",
79cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    nullptr
800b675d88309bdcbb387bbee907c4ef9d98e412a2Reid Kleckner  };
818eca677afee90d6a28487fd3db0bca129bde7186Reid Kleckner
828eca677afee90d6a28487fd3db0bca129bde7186Reid Kleckner  // Add LLVM_PROGRAM_TEST_CHILD to the environment of the child.
838eca677afee90d6a28487fd3db0bca129bde7186Reid Kleckner  std::vector<const char *> envp;
848eca677afee90d6a28487fd3db0bca129bde7186Reid Kleckner  CopyEnvironment(envp);
858eca677afee90d6a28487fd3db0bca129bde7186Reid Kleckner  envp.push_back("LLVM_PROGRAM_TEST_CHILD=1");
86cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  envp.push_back(nullptr);
878eca677afee90d6a28487fd3db0bca129bde7186Reid Kleckner
880b675d88309bdcbb387bbee907c4ef9d98e412a2Reid Kleckner  std::string error;
890b675d88309bdcbb387bbee907c4ef9d98e412a2Reid Kleckner  bool ExecutionFailed;
900b675d88309bdcbb387bbee907c4ef9d98e412a2Reid Kleckner  // Redirect stdout and stdin to NUL, but let stderr through.
910b675d88309bdcbb387bbee907c4ef9d98e412a2Reid Kleckner#ifdef LLVM_ON_WIN32
92675e0ac0bfd6fb78423d9fbee9f50c1dec62c111Rafael Espindola  StringRef nul("NUL");
930b675d88309bdcbb387bbee907c4ef9d98e412a2Reid Kleckner#else
94675e0ac0bfd6fb78423d9fbee9f50c1dec62c111Rafael Espindola  StringRef nul("/dev/null");
950b675d88309bdcbb387bbee907c4ef9d98e412a2Reid Kleckner#endif
96cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  const StringRef *redirects[] = { &nul, &nul, nullptr };
9750188c1f42c122640ab9ccac2134acf371c26b2cRafael Espindola  int rc = ExecuteAndWait(my_exe, argv, &envp[0], redirects,
98675e0ac0bfd6fb78423d9fbee9f50c1dec62c111Rafael Espindola                          /*secondsToWait=*/ 10, /*memoryLimit=*/ 0, &error,
99675e0ac0bfd6fb78423d9fbee9f50c1dec62c111Rafael Espindola                          &ExecutionFailed);
1000b675d88309bdcbb387bbee907c4ef9d98e412a2Reid Kleckner  EXPECT_FALSE(ExecutionFailed) << error;
1010b675d88309bdcbb387bbee907c4ef9d98e412a2Reid Kleckner  EXPECT_EQ(0, rc);
1020b675d88309bdcbb387bbee907c4ef9d98e412a2Reid Kleckner}
1030b675d88309bdcbb387bbee907c4ef9d98e412a2Reid Kleckner
104c269c4f505a2dd7c3a88d12706257410ed6c7068Tareq A. SirajTEST(ProgramTest, TestExecuteNoWait) {
105c269c4f505a2dd7c3a88d12706257410ed6c7068Tareq A. Siraj  using namespace llvm::sys;
106c269c4f505a2dd7c3a88d12706257410ed6c7068Tareq A. Siraj
107c269c4f505a2dd7c3a88d12706257410ed6c7068Tareq A. Siraj  if (getenv("LLVM_PROGRAM_TEST_EXECUTE_NO_WAIT")) {
108c269c4f505a2dd7c3a88d12706257410ed6c7068Tareq A. Siraj    sleep_for(/*seconds*/ 1);
109c269c4f505a2dd7c3a88d12706257410ed6c7068Tareq A. Siraj    exit(0);
110c269c4f505a2dd7c3a88d12706257410ed6c7068Tareq A. Siraj  }
111c269c4f505a2dd7c3a88d12706257410ed6c7068Tareq A. Siraj
112c269c4f505a2dd7c3a88d12706257410ed6c7068Tareq A. Siraj  std::string Executable =
113c269c4f505a2dd7c3a88d12706257410ed6c7068Tareq A. Siraj      sys::fs::getMainExecutable(TestMainArgv0, &ProgramTestStringArg1);
114c269c4f505a2dd7c3a88d12706257410ed6c7068Tareq A. Siraj  const char *argv[] = {
115c269c4f505a2dd7c3a88d12706257410ed6c7068Tareq A. Siraj    Executable.c_str(),
116c269c4f505a2dd7c3a88d12706257410ed6c7068Tareq A. Siraj    "--gtest_filter=ProgramTest.TestExecuteNoWait",
117cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    nullptr
118c269c4f505a2dd7c3a88d12706257410ed6c7068Tareq A. Siraj  };
119c269c4f505a2dd7c3a88d12706257410ed6c7068Tareq A. Siraj
120c269c4f505a2dd7c3a88d12706257410ed6c7068Tareq A. Siraj  // Add LLVM_PROGRAM_TEST_EXECUTE_NO_WAIT to the environment of the child.
121c269c4f505a2dd7c3a88d12706257410ed6c7068Tareq A. Siraj  std::vector<const char *> envp;
122c269c4f505a2dd7c3a88d12706257410ed6c7068Tareq A. Siraj  CopyEnvironment(envp);
123c269c4f505a2dd7c3a88d12706257410ed6c7068Tareq A. Siraj  envp.push_back("LLVM_PROGRAM_TEST_EXECUTE_NO_WAIT=1");
124cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  envp.push_back(nullptr);
125c269c4f505a2dd7c3a88d12706257410ed6c7068Tareq A. Siraj
126c269c4f505a2dd7c3a88d12706257410ed6c7068Tareq A. Siraj  std::string Error;
127c269c4f505a2dd7c3a88d12706257410ed6c7068Tareq A. Siraj  bool ExecutionFailed;
128cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  ProcessInfo PI1 = ExecuteNoWait(Executable, argv, &envp[0], nullptr, 0,
129cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines                                  &Error, &ExecutionFailed);
130c269c4f505a2dd7c3a88d12706257410ed6c7068Tareq A. Siraj  ASSERT_FALSE(ExecutionFailed) << Error;
131c269c4f505a2dd7c3a88d12706257410ed6c7068Tareq A. Siraj  ASSERT_NE(PI1.Pid, 0) << "Invalid process id";
132c269c4f505a2dd7c3a88d12706257410ed6c7068Tareq A. Siraj
133c269c4f505a2dd7c3a88d12706257410ed6c7068Tareq A. Siraj  unsigned LoopCount = 0;
134c269c4f505a2dd7c3a88d12706257410ed6c7068Tareq A. Siraj
135c269c4f505a2dd7c3a88d12706257410ed6c7068Tareq A. Siraj  // Test that Wait() with WaitUntilTerminates=true works. In this case,
136c269c4f505a2dd7c3a88d12706257410ed6c7068Tareq A. Siraj  // LoopCount should only be incremented once.
137c269c4f505a2dd7c3a88d12706257410ed6c7068Tareq A. Siraj  while (true) {
138c269c4f505a2dd7c3a88d12706257410ed6c7068Tareq A. Siraj    ++LoopCount;
139c269c4f505a2dd7c3a88d12706257410ed6c7068Tareq A. Siraj    ProcessInfo WaitResult = Wait(PI1, 0, true, &Error);
140c269c4f505a2dd7c3a88d12706257410ed6c7068Tareq A. Siraj    ASSERT_TRUE(Error.empty());
141c269c4f505a2dd7c3a88d12706257410ed6c7068Tareq A. Siraj    if (WaitResult.Pid == PI1.Pid)
142c269c4f505a2dd7c3a88d12706257410ed6c7068Tareq A. Siraj      break;
143c269c4f505a2dd7c3a88d12706257410ed6c7068Tareq A. Siraj  }
144c269c4f505a2dd7c3a88d12706257410ed6c7068Tareq A. Siraj
145c269c4f505a2dd7c3a88d12706257410ed6c7068Tareq A. Siraj  EXPECT_EQ(LoopCount, 1u) << "LoopCount should be 1";
146c269c4f505a2dd7c3a88d12706257410ed6c7068Tareq A. Siraj
147cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  ProcessInfo PI2 = ExecuteNoWait(Executable, argv, &envp[0], nullptr, 0,
148cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines                                  &Error, &ExecutionFailed);
149c269c4f505a2dd7c3a88d12706257410ed6c7068Tareq A. Siraj  ASSERT_FALSE(ExecutionFailed) << Error;
150c269c4f505a2dd7c3a88d12706257410ed6c7068Tareq A. Siraj  ASSERT_NE(PI2.Pid, 0) << "Invalid process id";
151c269c4f505a2dd7c3a88d12706257410ed6c7068Tareq A. Siraj
152c269c4f505a2dd7c3a88d12706257410ed6c7068Tareq A. Siraj  // Test that Wait() with SecondsToWait=0 performs a non-blocking wait. In this
153c269c4f505a2dd7c3a88d12706257410ed6c7068Tareq A. Siraj  // cse, LoopCount should be greater than 1 (more than one increment occurs).
154c269c4f505a2dd7c3a88d12706257410ed6c7068Tareq A. Siraj  while (true) {
155c269c4f505a2dd7c3a88d12706257410ed6c7068Tareq A. Siraj    ++LoopCount;
156c269c4f505a2dd7c3a88d12706257410ed6c7068Tareq A. Siraj    ProcessInfo WaitResult = Wait(PI2, 0, false, &Error);
157c269c4f505a2dd7c3a88d12706257410ed6c7068Tareq A. Siraj    ASSERT_TRUE(Error.empty());
158c269c4f505a2dd7c3a88d12706257410ed6c7068Tareq A. Siraj    if (WaitResult.Pid == PI2.Pid)
159c269c4f505a2dd7c3a88d12706257410ed6c7068Tareq A. Siraj      break;
160c269c4f505a2dd7c3a88d12706257410ed6c7068Tareq A. Siraj  }
161c269c4f505a2dd7c3a88d12706257410ed6c7068Tareq A. Siraj
162c269c4f505a2dd7c3a88d12706257410ed6c7068Tareq A. Siraj  ASSERT_GT(LoopCount, 1u) << "LoopCount should be >1";
163c269c4f505a2dd7c3a88d12706257410ed6c7068Tareq A. Siraj}
164c269c4f505a2dd7c3a88d12706257410ed6c7068Tareq A. Siraj
165cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen HinesTEST(ProgramTest, TestExecuteAndWaitTimeout) {
166cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  using namespace llvm::sys;
167cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
168cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  if (getenv("LLVM_PROGRAM_TEST_TIMEOUT")) {
169cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    sleep_for(/*seconds*/ 10);
170cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    exit(0);
171cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  }
172cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
173cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  std::string Executable =
174cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      sys::fs::getMainExecutable(TestMainArgv0, &ProgramTestStringArg1);
175cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  const char *argv[] = {
176cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    Executable.c_str(),
177cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    "--gtest_filter=ProgramTest.TestExecuteAndWaitTimeout",
178cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    nullptr
179cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  };
180cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
181cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  // Add LLVM_PROGRAM_TEST_TIMEOUT to the environment of the child.
182cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  std::vector<const char *> envp;
183cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  CopyEnvironment(envp);
184cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  envp.push_back("LLVM_PROGRAM_TEST_TIMEOUT=1");
185cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  envp.push_back(nullptr);
186cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
187cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  std::string Error;
188cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  bool ExecutionFailed;
189cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  int RetCode =
190cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      ExecuteAndWait(Executable, argv, &envp[0], nullptr, /*secondsToWait=*/1, 0,
191cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines                     &Error, &ExecutionFailed);
192cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  ASSERT_EQ(-2, RetCode);
193cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines}
194cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
195c269c4f505a2dd7c3a88d12706257410ed6c7068Tareq A. SirajTEST(ProgramTest, TestExecuteNegative) {
196c269c4f505a2dd7c3a88d12706257410ed6c7068Tareq A. Siraj  std::string Executable = "i_dont_exist";
197cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  const char *argv[] = { Executable.c_str(), nullptr };
198c269c4f505a2dd7c3a88d12706257410ed6c7068Tareq A. Siraj
199c269c4f505a2dd7c3a88d12706257410ed6c7068Tareq A. Siraj  {
200c269c4f505a2dd7c3a88d12706257410ed6c7068Tareq A. Siraj    std::string Error;
201c269c4f505a2dd7c3a88d12706257410ed6c7068Tareq A. Siraj    bool ExecutionFailed;
202cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    int RetCode = ExecuteAndWait(Executable, argv, nullptr, nullptr, 0, 0,
203cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines                                 &Error, &ExecutionFailed);
204c269c4f505a2dd7c3a88d12706257410ed6c7068Tareq A. Siraj    ASSERT_TRUE(RetCode < 0) << "On error ExecuteAndWait should return 0 or "
205c269c4f505a2dd7c3a88d12706257410ed6c7068Tareq A. Siraj                                "positive value indicating the result code";
206c269c4f505a2dd7c3a88d12706257410ed6c7068Tareq A. Siraj    ASSERT_TRUE(ExecutionFailed);
207c269c4f505a2dd7c3a88d12706257410ed6c7068Tareq A. Siraj    ASSERT_FALSE(Error.empty());
208c269c4f505a2dd7c3a88d12706257410ed6c7068Tareq A. Siraj  }
209c269c4f505a2dd7c3a88d12706257410ed6c7068Tareq A. Siraj
210c269c4f505a2dd7c3a88d12706257410ed6c7068Tareq A. Siraj  {
211c269c4f505a2dd7c3a88d12706257410ed6c7068Tareq A. Siraj    std::string Error;
212c269c4f505a2dd7c3a88d12706257410ed6c7068Tareq A. Siraj    bool ExecutionFailed;
213cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    ProcessInfo PI = ExecuteNoWait(Executable, argv, nullptr, nullptr, 0,
214cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines                                   &Error, &ExecutionFailed);
215c269c4f505a2dd7c3a88d12706257410ed6c7068Tareq A. Siraj    ASSERT_EQ(PI.Pid, 0)
216c269c4f505a2dd7c3a88d12706257410ed6c7068Tareq A. Siraj        << "On error ExecuteNoWait should return an invalid ProcessInfo";
217c269c4f505a2dd7c3a88d12706257410ed6c7068Tareq A. Siraj    ASSERT_TRUE(ExecutionFailed);
218c269c4f505a2dd7c3a88d12706257410ed6c7068Tareq A. Siraj    ASSERT_FALSE(Error.empty());
219c269c4f505a2dd7c3a88d12706257410ed6c7068Tareq A. Siraj  }
220c269c4f505a2dd7c3a88d12706257410ed6c7068Tareq A. Siraj
221c269c4f505a2dd7c3a88d12706257410ed6c7068Tareq A. Siraj}
222c269c4f505a2dd7c3a88d12706257410ed6c7068Tareq A. Siraj
2230b675d88309bdcbb387bbee907c4ef9d98e412a2Reid Kleckner} // end anonymous namespace
224