ProgramTest.cpp revision 268adf2a03cf352593b632c5249c83f4fc56956f
1//===- unittest/Support/ProgramTest.cpp -----------------------------------===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9 10#include "llvm/Support/CommandLine.h" 11#include "llvm/Support/Path.h" 12#include "llvm/Support/Program.h" 13#include "gtest/gtest.h" 14 15#include <stdlib.h> 16#if defined(__APPLE__) 17# include <crt_externs.h> 18#elif !defined(_MSC_VER) 19// Forward declare environ in case it's not provided by stdlib.h. 20extern char **environ; 21#endif 22 23namespace { 24 25using namespace llvm; 26using namespace sys; 27 28static cl::opt<std::string> 29ProgramTestStringArg1("program-test-string-arg1"); 30static cl::opt<std::string> 31ProgramTestStringArg2("program-test-string-arg2"); 32 33static void CopyEnvironment(std::vector<const char *> &out) { 34#ifdef __APPLE__ 35 char **envp = *_NSGetEnviron(); 36#else 37 // environ seems to work for Windows and most other Unices. 38 char **envp = environ; 39#endif 40 while (*envp != 0) { 41 out.push_back(*envp); 42 ++envp; 43 } 44} 45 46TEST(ProgramTest, CreateProcessTrailingSlash) { 47 if (getenv("LLVM_PROGRAM_TEST_CHILD")) { 48 if (ProgramTestStringArg1 == "has\\\\ trailing\\" && 49 ProgramTestStringArg2 == "has\\\\ trailing\\") { 50 exit(0); // Success! The arguments were passed and parsed. 51 } 52 exit(1); 53 } 54 55 // FIXME: Hardcoding argv0 here since I don't know a good cross-platform way 56 // to get it. Maybe ParseCommandLineOptions() should save it? 57 Path my_exe = Path::GetMainExecutable("SupportTests", &ProgramTestStringArg1); 58 const char *argv[] = { 59 my_exe.c_str(), 60 "--gtest_filter=ProgramTest.CreateProcessTrailingSlashChild", 61 "-program-test-string-arg1", "has\\\\ trailing\\", 62 "-program-test-string-arg2", "has\\\\ trailing\\", 63 0 64 }; 65 66 // Add LLVM_PROGRAM_TEST_CHILD to the environment of the child. 67 std::vector<const char *> envp; 68 CopyEnvironment(envp); 69 envp.push_back("LLVM_PROGRAM_TEST_CHILD=1"); 70 envp.push_back(0); 71 72 std::string error; 73 bool ExecutionFailed; 74 // Redirect stdout and stdin to NUL, but let stderr through. 75#ifdef LLVM_ON_WIN32 76 Path nul("NUL"); 77#else 78 Path nul("/dev/null"); 79#endif 80 const Path *redirects[] = { &nul, &nul, 0 }; 81 int rc = Program::ExecuteAndWait(my_exe, argv, &envp[0], redirects, 82 /*secondsToWait=*/10, /*memoryLimit=*/0, 83 &error, &ExecutionFailed); 84 EXPECT_FALSE(ExecutionFailed) << error; 85 EXPECT_EQ(0, rc); 86} 87 88} // end anonymous namespace 89