ProgramTest.cpp revision 0af5493701f9982d7451c8b3c1b7699cc84ac94c
1a09ec19a332de34de493b2c4da2b89b46fadc370Barry Warsaw//===- unittest/Support/ProgramTest.cpp -----------------------------------===// 2cd112f5546256a752f56b3bf6ce0ff19ff30a981Fred Drake// 3cd112f5546256a752f56b3bf6ce0ff19ff30a981Fred Drake// The LLVM Compiler Infrastructure 404f357cffef6d764f2f0ff2671dabde75ec250d1Barry Warsaw// 5cd112f5546256a752f56b3bf6ce0ff19ff30a981Fred Drake// This file is distributed under the University of Illinois Open Source 6fd163f92cee2aa8189879bd43670782f4cfd2cf8Armin Rigo// License. See LICENSE.TXT for details. 7fd163f92cee2aa8189879bd43670782f4cfd2cf8Armin Rigo// 8fd163f92cee2aa8189879bd43670782f4cfd2cf8Armin Rigo//===----------------------------------------------------------------------===// 9fd163f92cee2aa8189879bd43670782f4cfd2cf8Armin Rigo 10fd163f92cee2aa8189879bd43670782f4cfd2cf8Armin Rigo#include "llvm/Support/CommandLine.h" 11fd163f92cee2aa8189879bd43670782f4cfd2cf8Armin Rigo#include "llvm/Support/Path.h" 12fd163f92cee2aa8189879bd43670782f4cfd2cf8Armin Rigo#include "llvm/Support/Program.h" 13fd163f92cee2aa8189879bd43670782f4cfd2cf8Armin Rigo#include "gtest/gtest.h" 14fd163f92cee2aa8189879bd43670782f4cfd2cf8Armin Rigo 15fd163f92cee2aa8189879bd43670782f4cfd2cf8Armin Rigo#include <stdlib.h> 16fd163f92cee2aa8189879bd43670782f4cfd2cf8Armin Rigo 17fd163f92cee2aa8189879bd43670782f4cfd2cf8Armin Rigonamespace { 18fd163f92cee2aa8189879bd43670782f4cfd2cf8Armin Rigo 19fd163f92cee2aa8189879bd43670782f4cfd2cf8Armin Rigousing namespace llvm; 20fd163f92cee2aa8189879bd43670782f4cfd2cf8Armin Rigousing namespace sys; 21fd163f92cee2aa8189879bd43670782f4cfd2cf8Armin Rigo 22fd163f92cee2aa8189879bd43670782f4cfd2cf8Armin Rigostatic cl::opt<std::string> 23fd163f92cee2aa8189879bd43670782f4cfd2cf8Armin RigoProgramTestStringArg1("program-test-string-arg1"); 24fd163f92cee2aa8189879bd43670782f4cfd2cf8Armin Rigostatic cl::opt<std::string> 25fd163f92cee2aa8189879bd43670782f4cfd2cf8Armin RigoProgramTestStringArg2("program-test-string-arg2"); 26fd163f92cee2aa8189879bd43670782f4cfd2cf8Armin Rigo 27fd163f92cee2aa8189879bd43670782f4cfd2cf8Armin Rigostatic void CopyEnvironment(std::vector<const char *> &out) { 28fd163f92cee2aa8189879bd43670782f4cfd2cf8Armin Rigo // environ appears to be pretty portable. 29fd163f92cee2aa8189879bd43670782f4cfd2cf8Armin Rigo char **envp = environ; 30fd163f92cee2aa8189879bd43670782f4cfd2cf8Armin Rigo while (*envp != 0) { 31fd163f92cee2aa8189879bd43670782f4cfd2cf8Armin Rigo out.push_back(*envp); 32fd163f92cee2aa8189879bd43670782f4cfd2cf8Armin Rigo ++envp; 33fd163f92cee2aa8189879bd43670782f4cfd2cf8Armin Rigo } 34cd112f5546256a752f56b3bf6ce0ff19ff30a981Fred Drake} 35cd112f5546256a752f56b3bf6ce0ff19ff30a981Fred Drake 36cd112f5546256a752f56b3bf6ce0ff19ff30a981Fred DrakeTEST(ProgramTest, CreateProcessTrailingSlash) { 37bb9c739806b9f0251fa4a564986e2cb5e92e766eWalter Dörwald if (getenv("LLVM_PROGRAM_TEST_CHILD")) { 38bb9c739806b9f0251fa4a564986e2cb5e92e766eWalter Dörwald if (ProgramTestStringArg1 == "has\\\\ trailing\\" && 39cd112f5546256a752f56b3bf6ce0ff19ff30a981Fred Drake ProgramTestStringArg2 == "has\\\\ trailing\\") { 40cd112f5546256a752f56b3bf6ce0ff19ff30a981Fred Drake exit(0); // Success! The arguments were passed and parsed. 41cd112f5546256a752f56b3bf6ce0ff19ff30a981Fred Drake } 42cd112f5546256a752f56b3bf6ce0ff19ff30a981Fred Drake exit(1); 43cd112f5546256a752f56b3bf6ce0ff19ff30a981Fred Drake } 44cd112f5546256a752f56b3bf6ce0ff19ff30a981Fred Drake 45cd112f5546256a752f56b3bf6ce0ff19ff30a981Fred Drake // FIXME: Hardcoding argv0 here since I don't know a good cross-platform way 46cd112f5546256a752f56b3bf6ce0ff19ff30a981Fred Drake // to get it. Maybe ParseCommandLineOptions() should save it? 47bb9c739806b9f0251fa4a564986e2cb5e92e766eWalter Dörwald Path my_exe = Path::GetMainExecutable("SupportTests", &ProgramTestStringArg1); 48bb9c739806b9f0251fa4a564986e2cb5e92e766eWalter Dörwald const char *argv[] = { 49cd112f5546256a752f56b3bf6ce0ff19ff30a981Fred Drake my_exe.c_str(), 50cd112f5546256a752f56b3bf6ce0ff19ff30a981Fred Drake "--gtest_filter=ProgramTest.CreateProcessTrailingSlashChild", 51cd112f5546256a752f56b3bf6ce0ff19ff30a981Fred Drake "-program-test-string-arg1", "has\\\\ trailing\\", 52cd112f5546256a752f56b3bf6ce0ff19ff30a981Fred Drake "-program-test-string-arg2", "has\\\\ trailing\\", 53cd112f5546256a752f56b3bf6ce0ff19ff30a981Fred Drake 0 54cd112f5546256a752f56b3bf6ce0ff19ff30a981Fred Drake }; 55cd112f5546256a752f56b3bf6ce0ff19ff30a981Fred Drake 56cd112f5546256a752f56b3bf6ce0ff19ff30a981Fred Drake // Add LLVM_PROGRAM_TEST_CHILD to the environment of the child. 57bb9c739806b9f0251fa4a564986e2cb5e92e766eWalter Dörwald std::vector<const char *> envp; 58bb9c739806b9f0251fa4a564986e2cb5e92e766eWalter Dörwald CopyEnvironment(envp); 59bb9c739806b9f0251fa4a564986e2cb5e92e766eWalter Dörwald envp.push_back("LLVM_PROGRAM_TEST_CHILD=1"); 60bb9c739806b9f0251fa4a564986e2cb5e92e766eWalter Dörwald envp.push_back(0); 61bb9c739806b9f0251fa4a564986e2cb5e92e766eWalter Dörwald 62cd112f5546256a752f56b3bf6ce0ff19ff30a981Fred Drake std::string error; 63cd112f5546256a752f56b3bf6ce0ff19ff30a981Fred Drake bool ExecutionFailed; 64cd112f5546256a752f56b3bf6ce0ff19ff30a981Fred Drake // Redirect stdout and stdin to NUL, but let stderr through. 65cd112f5546256a752f56b3bf6ce0ff19ff30a981Fred Drake#ifdef LLVM_ON_WIN32 66cd112f5546256a752f56b3bf6ce0ff19ff30a981Fred Drake Path nul("NUL"); 67cd112f5546256a752f56b3bf6ce0ff19ff30a981Fred Drake#else 68cd112f5546256a752f56b3bf6ce0ff19ff30a981Fred Drake Path nul("/dev/null"); 69cd112f5546256a752f56b3bf6ce0ff19ff30a981Fred Drake#endif 70bb9c739806b9f0251fa4a564986e2cb5e92e766eWalter Dörwald const Path *redirects[] = { &nul, &nul, 0 }; 71bb9c739806b9f0251fa4a564986e2cb5e92e766eWalter Dörwald int rc = Program::ExecuteAndWait(my_exe, argv, &envp[0], redirects, 72bb9c739806b9f0251fa4a564986e2cb5e92e766eWalter Dörwald /*secondsToWait=*/10, /*memoryLimit=*/0, 73bb9c739806b9f0251fa4a564986e2cb5e92e766eWalter Dörwald &error, &ExecutionFailed); 74bb9c739806b9f0251fa4a564986e2cb5e92e766eWalter Dörwald EXPECT_FALSE(ExecutionFailed) << error; 75cd112f5546256a752f56b3bf6ce0ff19ff30a981Fred Drake EXPECT_EQ(0, rc); 76cd112f5546256a752f56b3bf6ce0ff19ff30a981Fred Drake} 77cd112f5546256a752f56b3bf6ce0ff19ff30a981Fred Drake 78cd112f5546256a752f56b3bf6ce0ff19ff30a981Fred Drake} // end anonymous namespace 79cd112f5546256a752f56b3bf6ce0ff19ff30a981Fred Drake