xref: /aosp_15_r20/external/llvm/unittests/Support/ProgramTest.cpp (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker //===- unittest/Support/ProgramTest.cpp -----------------------------------===//
2*9880d681SAndroid Build Coastguard Worker //
3*9880d681SAndroid Build Coastguard Worker //                     The LLVM Compiler Infrastructure
4*9880d681SAndroid Build Coastguard Worker //
5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*9880d681SAndroid Build Coastguard Worker //
8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*9880d681SAndroid Build Coastguard Worker 
10*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/ConvertUTF.h"
11*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/CommandLine.h"
12*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/FileSystem.h"
13*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/Path.h"
14*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/Program.h"
15*9880d681SAndroid Build Coastguard Worker #include "gtest/gtest.h"
16*9880d681SAndroid Build Coastguard Worker #include <stdlib.h>
17*9880d681SAndroid Build Coastguard Worker #if defined(__APPLE__)
18*9880d681SAndroid Build Coastguard Worker # include <crt_externs.h>
19*9880d681SAndroid Build Coastguard Worker #elif !defined(_MSC_VER)
20*9880d681SAndroid Build Coastguard Worker // Forward declare environ in case it's not provided by stdlib.h.
21*9880d681SAndroid Build Coastguard Worker extern char **environ;
22*9880d681SAndroid Build Coastguard Worker #endif
23*9880d681SAndroid Build Coastguard Worker 
24*9880d681SAndroid Build Coastguard Worker #if defined(LLVM_ON_UNIX)
25*9880d681SAndroid Build Coastguard Worker #include <unistd.h>
sleep_for(unsigned int seconds)26*9880d681SAndroid Build Coastguard Worker void sleep_for(unsigned int seconds) {
27*9880d681SAndroid Build Coastguard Worker   sleep(seconds);
28*9880d681SAndroid Build Coastguard Worker }
29*9880d681SAndroid Build Coastguard Worker #elif defined(LLVM_ON_WIN32)
30*9880d681SAndroid Build Coastguard Worker #include <windows.h>
sleep_for(unsigned int seconds)31*9880d681SAndroid Build Coastguard Worker void sleep_for(unsigned int seconds) {
32*9880d681SAndroid Build Coastguard Worker   Sleep(seconds * 1000);
33*9880d681SAndroid Build Coastguard Worker }
34*9880d681SAndroid Build Coastguard Worker #else
35*9880d681SAndroid Build Coastguard Worker #error sleep_for is not implemented on your platform.
36*9880d681SAndroid Build Coastguard Worker #endif
37*9880d681SAndroid Build Coastguard Worker 
38*9880d681SAndroid Build Coastguard Worker #define ASSERT_NO_ERROR(x)                                                     \
39*9880d681SAndroid Build Coastguard Worker   if (std::error_code ASSERT_NO_ERROR_ec = x) {                                \
40*9880d681SAndroid Build Coastguard Worker     SmallString<128> MessageStorage;                                           \
41*9880d681SAndroid Build Coastguard Worker     raw_svector_ostream Message(MessageStorage);                               \
42*9880d681SAndroid Build Coastguard Worker     Message << #x ": did not return errc::success.\n"                          \
43*9880d681SAndroid Build Coastguard Worker             << "error number: " << ASSERT_NO_ERROR_ec.value() << "\n"          \
44*9880d681SAndroid Build Coastguard Worker             << "error message: " << ASSERT_NO_ERROR_ec.message() << "\n";      \
45*9880d681SAndroid Build Coastguard Worker     GTEST_FATAL_FAILURE_(MessageStorage.c_str());                              \
46*9880d681SAndroid Build Coastguard Worker   } else {                                                                     \
47*9880d681SAndroid Build Coastguard Worker   }
48*9880d681SAndroid Build Coastguard Worker // From TestMain.cpp.
49*9880d681SAndroid Build Coastguard Worker extern const char *TestMainArgv0;
50*9880d681SAndroid Build Coastguard Worker 
51*9880d681SAndroid Build Coastguard Worker namespace {
52*9880d681SAndroid Build Coastguard Worker 
53*9880d681SAndroid Build Coastguard Worker using namespace llvm;
54*9880d681SAndroid Build Coastguard Worker using namespace sys;
55*9880d681SAndroid Build Coastguard Worker 
56*9880d681SAndroid Build Coastguard Worker static cl::opt<std::string>
57*9880d681SAndroid Build Coastguard Worker ProgramTestStringArg1("program-test-string-arg1");
58*9880d681SAndroid Build Coastguard Worker static cl::opt<std::string>
59*9880d681SAndroid Build Coastguard Worker ProgramTestStringArg2("program-test-string-arg2");
60*9880d681SAndroid Build Coastguard Worker 
61*9880d681SAndroid Build Coastguard Worker class ProgramEnvTest : public testing::Test {
62*9880d681SAndroid Build Coastguard Worker   std::vector<const char *> EnvTable;
63*9880d681SAndroid Build Coastguard Worker   std::vector<std::string> EnvStorage;
64*9880d681SAndroid Build Coastguard Worker 
65*9880d681SAndroid Build Coastguard Worker protected:
SetUp()66*9880d681SAndroid Build Coastguard Worker   void SetUp() override {
67*9880d681SAndroid Build Coastguard Worker     auto EnvP = [] {
68*9880d681SAndroid Build Coastguard Worker #if defined(LLVM_ON_WIN32)
69*9880d681SAndroid Build Coastguard Worker       _wgetenv(L"TMP"); // Populate _wenviron, initially is null
70*9880d681SAndroid Build Coastguard Worker       return _wenviron;
71*9880d681SAndroid Build Coastguard Worker #elif defined(__APPLE__)
72*9880d681SAndroid Build Coastguard Worker       return *_NSGetEnviron();
73*9880d681SAndroid Build Coastguard Worker #else
74*9880d681SAndroid Build Coastguard Worker       return environ;
75*9880d681SAndroid Build Coastguard Worker #endif
76*9880d681SAndroid Build Coastguard Worker     }();
77*9880d681SAndroid Build Coastguard Worker     ASSERT_TRUE(EnvP);
78*9880d681SAndroid Build Coastguard Worker 
79*9880d681SAndroid Build Coastguard Worker     auto prepareEnvVar = [this](decltype(*EnvP) Var) {
80*9880d681SAndroid Build Coastguard Worker #if defined(LLVM_ON_WIN32)
81*9880d681SAndroid Build Coastguard Worker       // On Windows convert UTF16 encoded variable to UTF8
82*9880d681SAndroid Build Coastguard Worker       auto Len = wcslen(Var);
83*9880d681SAndroid Build Coastguard Worker       ArrayRef<char> Ref{reinterpret_cast<char const *>(Var),
84*9880d681SAndroid Build Coastguard Worker                          Len * sizeof(*Var)};
85*9880d681SAndroid Build Coastguard Worker       EnvStorage.emplace_back();
86*9880d681SAndroid Build Coastguard Worker       auto convStatus = convertUTF16ToUTF8String(Ref, EnvStorage.back());
87*9880d681SAndroid Build Coastguard Worker       EXPECT_TRUE(convStatus);
88*9880d681SAndroid Build Coastguard Worker       return EnvStorage.back().c_str();
89*9880d681SAndroid Build Coastguard Worker #else
90*9880d681SAndroid Build Coastguard Worker       return Var;
91*9880d681SAndroid Build Coastguard Worker #endif
92*9880d681SAndroid Build Coastguard Worker     };
93*9880d681SAndroid Build Coastguard Worker 
94*9880d681SAndroid Build Coastguard Worker     while (*EnvP != nullptr) {
95*9880d681SAndroid Build Coastguard Worker       EnvTable.emplace_back(prepareEnvVar(*EnvP));
96*9880d681SAndroid Build Coastguard Worker       ++EnvP;
97*9880d681SAndroid Build Coastguard Worker     }
98*9880d681SAndroid Build Coastguard Worker   }
99*9880d681SAndroid Build Coastguard Worker 
TearDown()100*9880d681SAndroid Build Coastguard Worker   void TearDown() override {
101*9880d681SAndroid Build Coastguard Worker     EnvTable.clear();
102*9880d681SAndroid Build Coastguard Worker     EnvStorage.clear();
103*9880d681SAndroid Build Coastguard Worker   }
104*9880d681SAndroid Build Coastguard Worker 
addEnvVar(const char * Var)105*9880d681SAndroid Build Coastguard Worker   void addEnvVar(const char *Var) {
106*9880d681SAndroid Build Coastguard Worker     ASSERT_TRUE(EnvTable.empty() || EnvTable.back()) << "Env table sealed";
107*9880d681SAndroid Build Coastguard Worker     EnvTable.emplace_back(Var);
108*9880d681SAndroid Build Coastguard Worker   }
109*9880d681SAndroid Build Coastguard Worker 
getEnviron()110*9880d681SAndroid Build Coastguard Worker   const char **getEnviron() {
111*9880d681SAndroid Build Coastguard Worker     if (EnvTable.back() != nullptr)
112*9880d681SAndroid Build Coastguard Worker       EnvTable.emplace_back(nullptr); // Seal table.
113*9880d681SAndroid Build Coastguard Worker     return &EnvTable[0];
114*9880d681SAndroid Build Coastguard Worker   }
115*9880d681SAndroid Build Coastguard Worker };
116*9880d681SAndroid Build Coastguard Worker 
117*9880d681SAndroid Build Coastguard Worker #ifdef LLVM_ON_WIN32
TEST_F(ProgramEnvTest,CreateProcessLongPath)118*9880d681SAndroid Build Coastguard Worker TEST_F(ProgramEnvTest, CreateProcessLongPath) {
119*9880d681SAndroid Build Coastguard Worker   if (getenv("LLVM_PROGRAM_TEST_LONG_PATH"))
120*9880d681SAndroid Build Coastguard Worker     exit(0);
121*9880d681SAndroid Build Coastguard Worker 
122*9880d681SAndroid Build Coastguard Worker   // getMainExecutable returns an absolute path; prepend the long-path prefix.
123*9880d681SAndroid Build Coastguard Worker   std::string MyAbsExe =
124*9880d681SAndroid Build Coastguard Worker       sys::fs::getMainExecutable(TestMainArgv0, &ProgramTestStringArg1);
125*9880d681SAndroid Build Coastguard Worker   std::string MyExe;
126*9880d681SAndroid Build Coastguard Worker   if (!StringRef(MyAbsExe).startswith("\\\\?\\"))
127*9880d681SAndroid Build Coastguard Worker     MyExe.append("\\\\?\\");
128*9880d681SAndroid Build Coastguard Worker   MyExe.append(MyAbsExe);
129*9880d681SAndroid Build Coastguard Worker 
130*9880d681SAndroid Build Coastguard Worker   const char *ArgV[] = {
131*9880d681SAndroid Build Coastguard Worker     MyExe.c_str(),
132*9880d681SAndroid Build Coastguard Worker     "--gtest_filter=ProgramEnvTest.CreateProcessLongPath",
133*9880d681SAndroid Build Coastguard Worker     nullptr
134*9880d681SAndroid Build Coastguard Worker   };
135*9880d681SAndroid Build Coastguard Worker 
136*9880d681SAndroid Build Coastguard Worker   // Add LLVM_PROGRAM_TEST_LONG_PATH to the environment of the child.
137*9880d681SAndroid Build Coastguard Worker   addEnvVar("LLVM_PROGRAM_TEST_LONG_PATH=1");
138*9880d681SAndroid Build Coastguard Worker 
139*9880d681SAndroid Build Coastguard Worker   // Redirect stdout to a long path.
140*9880d681SAndroid Build Coastguard Worker   SmallString<128> TestDirectory;
141*9880d681SAndroid Build Coastguard Worker   ASSERT_NO_ERROR(
142*9880d681SAndroid Build Coastguard Worker     fs::createUniqueDirectory("program-redirect-test", TestDirectory));
143*9880d681SAndroid Build Coastguard Worker   SmallString<256> LongPath(TestDirectory);
144*9880d681SAndroid Build Coastguard Worker   LongPath.push_back('\\');
145*9880d681SAndroid Build Coastguard Worker   // MAX_PATH = 260
146*9880d681SAndroid Build Coastguard Worker   LongPath.append(260 - TestDirectory.size(), 'a');
147*9880d681SAndroid Build Coastguard Worker   StringRef LongPathRef(LongPath);
148*9880d681SAndroid Build Coastguard Worker 
149*9880d681SAndroid Build Coastguard Worker   std::string Error;
150*9880d681SAndroid Build Coastguard Worker   bool ExecutionFailed;
151*9880d681SAndroid Build Coastguard Worker   const StringRef *Redirects[] = { nullptr, &LongPathRef, nullptr };
152*9880d681SAndroid Build Coastguard Worker   int RC = ExecuteAndWait(MyExe, ArgV, getEnviron(), Redirects,
153*9880d681SAndroid Build Coastguard Worker     /*secondsToWait=*/ 10, /*memoryLimit=*/ 0, &Error,
154*9880d681SAndroid Build Coastguard Worker     &ExecutionFailed);
155*9880d681SAndroid Build Coastguard Worker   EXPECT_FALSE(ExecutionFailed) << Error;
156*9880d681SAndroid Build Coastguard Worker   EXPECT_EQ(0, RC);
157*9880d681SAndroid Build Coastguard Worker 
158*9880d681SAndroid Build Coastguard Worker   // Remove the long stdout.
159*9880d681SAndroid Build Coastguard Worker   ASSERT_NO_ERROR(fs::remove(Twine(LongPath)));
160*9880d681SAndroid Build Coastguard Worker   ASSERT_NO_ERROR(fs::remove(Twine(TestDirectory)));
161*9880d681SAndroid Build Coastguard Worker }
162*9880d681SAndroid Build Coastguard Worker #endif
163*9880d681SAndroid Build Coastguard Worker 
TEST_F(ProgramEnvTest,CreateProcessTrailingSlash)164*9880d681SAndroid Build Coastguard Worker TEST_F(ProgramEnvTest, CreateProcessTrailingSlash) {
165*9880d681SAndroid Build Coastguard Worker   if (getenv("LLVM_PROGRAM_TEST_CHILD")) {
166*9880d681SAndroid Build Coastguard Worker     if (ProgramTestStringArg1 == "has\\\\ trailing\\" &&
167*9880d681SAndroid Build Coastguard Worker         ProgramTestStringArg2 == "has\\\\ trailing\\") {
168*9880d681SAndroid Build Coastguard Worker       exit(0);  // Success!  The arguments were passed and parsed.
169*9880d681SAndroid Build Coastguard Worker     }
170*9880d681SAndroid Build Coastguard Worker     exit(1);
171*9880d681SAndroid Build Coastguard Worker   }
172*9880d681SAndroid Build Coastguard Worker 
173*9880d681SAndroid Build Coastguard Worker   std::string my_exe =
174*9880d681SAndroid Build Coastguard Worker       sys::fs::getMainExecutable(TestMainArgv0, &ProgramTestStringArg1);
175*9880d681SAndroid Build Coastguard Worker   const char *argv[] = {
176*9880d681SAndroid Build Coastguard Worker     my_exe.c_str(),
177*9880d681SAndroid Build Coastguard Worker     "--gtest_filter=ProgramEnvTest.CreateProcessTrailingSlash",
178*9880d681SAndroid Build Coastguard Worker     "-program-test-string-arg1", "has\\\\ trailing\\",
179*9880d681SAndroid Build Coastguard Worker     "-program-test-string-arg2", "has\\\\ trailing\\",
180*9880d681SAndroid Build Coastguard Worker     nullptr
181*9880d681SAndroid Build Coastguard Worker   };
182*9880d681SAndroid Build Coastguard Worker 
183*9880d681SAndroid Build Coastguard Worker   // Add LLVM_PROGRAM_TEST_CHILD to the environment of the child.
184*9880d681SAndroid Build Coastguard Worker   addEnvVar("LLVM_PROGRAM_TEST_CHILD=1");
185*9880d681SAndroid Build Coastguard Worker 
186*9880d681SAndroid Build Coastguard Worker   std::string error;
187*9880d681SAndroid Build Coastguard Worker   bool ExecutionFailed;
188*9880d681SAndroid Build Coastguard Worker   // Redirect stdout and stdin to NUL, but let stderr through.
189*9880d681SAndroid Build Coastguard Worker #ifdef LLVM_ON_WIN32
190*9880d681SAndroid Build Coastguard Worker   StringRef nul("NUL");
191*9880d681SAndroid Build Coastguard Worker #else
192*9880d681SAndroid Build Coastguard Worker   StringRef nul("/dev/null");
193*9880d681SAndroid Build Coastguard Worker #endif
194*9880d681SAndroid Build Coastguard Worker   const StringRef *redirects[] = { &nul, &nul, nullptr };
195*9880d681SAndroid Build Coastguard Worker   int rc = ExecuteAndWait(my_exe, argv, getEnviron(), redirects,
196*9880d681SAndroid Build Coastguard Worker                           /*secondsToWait=*/ 10, /*memoryLimit=*/ 0, &error,
197*9880d681SAndroid Build Coastguard Worker                           &ExecutionFailed);
198*9880d681SAndroid Build Coastguard Worker   EXPECT_FALSE(ExecutionFailed) << error;
199*9880d681SAndroid Build Coastguard Worker   EXPECT_EQ(0, rc);
200*9880d681SAndroid Build Coastguard Worker }
201*9880d681SAndroid Build Coastguard Worker 
TEST_F(ProgramEnvTest,TestExecuteNoWait)202*9880d681SAndroid Build Coastguard Worker TEST_F(ProgramEnvTest, TestExecuteNoWait) {
203*9880d681SAndroid Build Coastguard Worker   using namespace llvm::sys;
204*9880d681SAndroid Build Coastguard Worker 
205*9880d681SAndroid Build Coastguard Worker   if (getenv("LLVM_PROGRAM_TEST_EXECUTE_NO_WAIT")) {
206*9880d681SAndroid Build Coastguard Worker     sleep_for(/*seconds*/ 1);
207*9880d681SAndroid Build Coastguard Worker     exit(0);
208*9880d681SAndroid Build Coastguard Worker   }
209*9880d681SAndroid Build Coastguard Worker 
210*9880d681SAndroid Build Coastguard Worker   std::string Executable =
211*9880d681SAndroid Build Coastguard Worker       sys::fs::getMainExecutable(TestMainArgv0, &ProgramTestStringArg1);
212*9880d681SAndroid Build Coastguard Worker   const char *argv[] = {
213*9880d681SAndroid Build Coastguard Worker     Executable.c_str(),
214*9880d681SAndroid Build Coastguard Worker     "--gtest_filter=ProgramEnvTest.TestExecuteNoWait",
215*9880d681SAndroid Build Coastguard Worker     nullptr
216*9880d681SAndroid Build Coastguard Worker   };
217*9880d681SAndroid Build Coastguard Worker 
218*9880d681SAndroid Build Coastguard Worker   // Add LLVM_PROGRAM_TEST_EXECUTE_NO_WAIT to the environment of the child.
219*9880d681SAndroid Build Coastguard Worker   addEnvVar("LLVM_PROGRAM_TEST_EXECUTE_NO_WAIT=1");
220*9880d681SAndroid Build Coastguard Worker 
221*9880d681SAndroid Build Coastguard Worker   std::string Error;
222*9880d681SAndroid Build Coastguard Worker   bool ExecutionFailed;
223*9880d681SAndroid Build Coastguard Worker   ProcessInfo PI1 = ExecuteNoWait(Executable, argv, getEnviron(), nullptr, 0,
224*9880d681SAndroid Build Coastguard Worker                                   &Error, &ExecutionFailed);
225*9880d681SAndroid Build Coastguard Worker   ASSERT_FALSE(ExecutionFailed) << Error;
226*9880d681SAndroid Build Coastguard Worker   ASSERT_NE(PI1.Pid, ProcessInfo::InvalidPid) << "Invalid process id";
227*9880d681SAndroid Build Coastguard Worker 
228*9880d681SAndroid Build Coastguard Worker   unsigned LoopCount = 0;
229*9880d681SAndroid Build Coastguard Worker 
230*9880d681SAndroid Build Coastguard Worker   // Test that Wait() with WaitUntilTerminates=true works. In this case,
231*9880d681SAndroid Build Coastguard Worker   // LoopCount should only be incremented once.
232*9880d681SAndroid Build Coastguard Worker   while (true) {
233*9880d681SAndroid Build Coastguard Worker     ++LoopCount;
234*9880d681SAndroid Build Coastguard Worker     ProcessInfo WaitResult = llvm::sys::Wait(PI1, 0, true, &Error);
235*9880d681SAndroid Build Coastguard Worker     ASSERT_TRUE(Error.empty());
236*9880d681SAndroid Build Coastguard Worker     if (WaitResult.Pid == PI1.Pid)
237*9880d681SAndroid Build Coastguard Worker       break;
238*9880d681SAndroid Build Coastguard Worker   }
239*9880d681SAndroid Build Coastguard Worker 
240*9880d681SAndroid Build Coastguard Worker   EXPECT_EQ(LoopCount, 1u) << "LoopCount should be 1";
241*9880d681SAndroid Build Coastguard Worker 
242*9880d681SAndroid Build Coastguard Worker   ProcessInfo PI2 = ExecuteNoWait(Executable, argv, getEnviron(), nullptr, 0,
243*9880d681SAndroid Build Coastguard Worker                                   &Error, &ExecutionFailed);
244*9880d681SAndroid Build Coastguard Worker   ASSERT_FALSE(ExecutionFailed) << Error;
245*9880d681SAndroid Build Coastguard Worker   ASSERT_NE(PI2.Pid, ProcessInfo::InvalidPid) << "Invalid process id";
246*9880d681SAndroid Build Coastguard Worker 
247*9880d681SAndroid Build Coastguard Worker   // Test that Wait() with SecondsToWait=0 performs a non-blocking wait. In this
248*9880d681SAndroid Build Coastguard Worker   // cse, LoopCount should be greater than 1 (more than one increment occurs).
249*9880d681SAndroid Build Coastguard Worker   while (true) {
250*9880d681SAndroid Build Coastguard Worker     ++LoopCount;
251*9880d681SAndroid Build Coastguard Worker     ProcessInfo WaitResult = llvm::sys::Wait(PI2, 0, false, &Error);
252*9880d681SAndroid Build Coastguard Worker     ASSERT_TRUE(Error.empty());
253*9880d681SAndroid Build Coastguard Worker     if (WaitResult.Pid == PI2.Pid)
254*9880d681SAndroid Build Coastguard Worker       break;
255*9880d681SAndroid Build Coastguard Worker   }
256*9880d681SAndroid Build Coastguard Worker 
257*9880d681SAndroid Build Coastguard Worker   ASSERT_GT(LoopCount, 1u) << "LoopCount should be >1";
258*9880d681SAndroid Build Coastguard Worker }
259*9880d681SAndroid Build Coastguard Worker 
TEST_F(ProgramEnvTest,TestExecuteAndWaitTimeout)260*9880d681SAndroid Build Coastguard Worker TEST_F(ProgramEnvTest, TestExecuteAndWaitTimeout) {
261*9880d681SAndroid Build Coastguard Worker   using namespace llvm::sys;
262*9880d681SAndroid Build Coastguard Worker 
263*9880d681SAndroid Build Coastguard Worker   if (getenv("LLVM_PROGRAM_TEST_TIMEOUT")) {
264*9880d681SAndroid Build Coastguard Worker     sleep_for(/*seconds*/ 10);
265*9880d681SAndroid Build Coastguard Worker     exit(0);
266*9880d681SAndroid Build Coastguard Worker   }
267*9880d681SAndroid Build Coastguard Worker 
268*9880d681SAndroid Build Coastguard Worker   std::string Executable =
269*9880d681SAndroid Build Coastguard Worker       sys::fs::getMainExecutable(TestMainArgv0, &ProgramTestStringArg1);
270*9880d681SAndroid Build Coastguard Worker   const char *argv[] = {
271*9880d681SAndroid Build Coastguard Worker     Executable.c_str(),
272*9880d681SAndroid Build Coastguard Worker     "--gtest_filter=ProgramEnvTest.TestExecuteAndWaitTimeout",
273*9880d681SAndroid Build Coastguard Worker     nullptr
274*9880d681SAndroid Build Coastguard Worker   };
275*9880d681SAndroid Build Coastguard Worker 
276*9880d681SAndroid Build Coastguard Worker   // Add LLVM_PROGRAM_TEST_TIMEOUT to the environment of the child.
277*9880d681SAndroid Build Coastguard Worker  addEnvVar("LLVM_PROGRAM_TEST_TIMEOUT=1");
278*9880d681SAndroid Build Coastguard Worker 
279*9880d681SAndroid Build Coastguard Worker   std::string Error;
280*9880d681SAndroid Build Coastguard Worker   bool ExecutionFailed;
281*9880d681SAndroid Build Coastguard Worker   int RetCode =
282*9880d681SAndroid Build Coastguard Worker       ExecuteAndWait(Executable, argv, getEnviron(), nullptr, /*secondsToWait=*/1, 0,
283*9880d681SAndroid Build Coastguard Worker                      &Error, &ExecutionFailed);
284*9880d681SAndroid Build Coastguard Worker   ASSERT_EQ(-2, RetCode);
285*9880d681SAndroid Build Coastguard Worker }
286*9880d681SAndroid Build Coastguard Worker 
TEST(ProgramTest,TestExecuteNegative)287*9880d681SAndroid Build Coastguard Worker TEST(ProgramTest, TestExecuteNegative) {
288*9880d681SAndroid Build Coastguard Worker   std::string Executable = "i_dont_exist";
289*9880d681SAndroid Build Coastguard Worker   const char *argv[] = { Executable.c_str(), nullptr };
290*9880d681SAndroid Build Coastguard Worker 
291*9880d681SAndroid Build Coastguard Worker   {
292*9880d681SAndroid Build Coastguard Worker     std::string Error;
293*9880d681SAndroid Build Coastguard Worker     bool ExecutionFailed;
294*9880d681SAndroid Build Coastguard Worker     int RetCode = ExecuteAndWait(Executable, argv, nullptr, nullptr, 0, 0,
295*9880d681SAndroid Build Coastguard Worker                                  &Error, &ExecutionFailed);
296*9880d681SAndroid Build Coastguard Worker     ASSERT_TRUE(RetCode < 0) << "On error ExecuteAndWait should return 0 or "
297*9880d681SAndroid Build Coastguard Worker                                 "positive value indicating the result code";
298*9880d681SAndroid Build Coastguard Worker     ASSERT_TRUE(ExecutionFailed);
299*9880d681SAndroid Build Coastguard Worker     ASSERT_FALSE(Error.empty());
300*9880d681SAndroid Build Coastguard Worker   }
301*9880d681SAndroid Build Coastguard Worker 
302*9880d681SAndroid Build Coastguard Worker   {
303*9880d681SAndroid Build Coastguard Worker     std::string Error;
304*9880d681SAndroid Build Coastguard Worker     bool ExecutionFailed;
305*9880d681SAndroid Build Coastguard Worker     ProcessInfo PI = ExecuteNoWait(Executable, argv, nullptr, nullptr, 0,
306*9880d681SAndroid Build Coastguard Worker                                    &Error, &ExecutionFailed);
307*9880d681SAndroid Build Coastguard Worker     ASSERT_EQ(PI.Pid, ProcessInfo::InvalidPid)
308*9880d681SAndroid Build Coastguard Worker         << "On error ExecuteNoWait should return an invalid ProcessInfo";
309*9880d681SAndroid Build Coastguard Worker     ASSERT_TRUE(ExecutionFailed);
310*9880d681SAndroid Build Coastguard Worker     ASSERT_FALSE(Error.empty());
311*9880d681SAndroid Build Coastguard Worker   }
312*9880d681SAndroid Build Coastguard Worker 
313*9880d681SAndroid Build Coastguard Worker }
314*9880d681SAndroid Build Coastguard Worker 
315*9880d681SAndroid Build Coastguard Worker #ifdef LLVM_ON_WIN32
316*9880d681SAndroid Build Coastguard Worker const char utf16le_text[] =
317*9880d681SAndroid Build Coastguard Worker     "\x6c\x00\x69\x00\x6e\x00\x67\x00\xfc\x00\x69\x00\xe7\x00\x61\x00";
318*9880d681SAndroid Build Coastguard Worker const char utf16be_text[] =
319*9880d681SAndroid Build Coastguard Worker     "\x00\x6c\x00\x69\x00\x6e\x00\x67\x00\xfc\x00\x69\x00\xe7\x00\x61";
320*9880d681SAndroid Build Coastguard Worker #endif
321*9880d681SAndroid Build Coastguard Worker const char utf8_text[] = "\x6c\x69\x6e\x67\xc3\xbc\x69\xc3\xa7\x61";
322*9880d681SAndroid Build Coastguard Worker 
TEST(ProgramTest,TestWriteWithSystemEncoding)323*9880d681SAndroid Build Coastguard Worker TEST(ProgramTest, TestWriteWithSystemEncoding) {
324*9880d681SAndroid Build Coastguard Worker   SmallString<128> TestDirectory;
325*9880d681SAndroid Build Coastguard Worker   ASSERT_NO_ERROR(fs::createUniqueDirectory("program-test", TestDirectory));
326*9880d681SAndroid Build Coastguard Worker   errs() << "Test Directory: " << TestDirectory << '\n';
327*9880d681SAndroid Build Coastguard Worker   errs().flush();
328*9880d681SAndroid Build Coastguard Worker   SmallString<128> file_pathname(TestDirectory);
329*9880d681SAndroid Build Coastguard Worker   path::append(file_pathname, "international-file.txt");
330*9880d681SAndroid Build Coastguard Worker   // Only on Windows we should encode in UTF16. For other systems, use UTF8
331*9880d681SAndroid Build Coastguard Worker   ASSERT_NO_ERROR(sys::writeFileWithEncoding(file_pathname.c_str(), utf8_text,
332*9880d681SAndroid Build Coastguard Worker                                              sys::WEM_UTF16));
333*9880d681SAndroid Build Coastguard Worker   int fd = 0;
334*9880d681SAndroid Build Coastguard Worker   ASSERT_NO_ERROR(fs::openFileForRead(file_pathname.c_str(), fd));
335*9880d681SAndroid Build Coastguard Worker #if defined(LLVM_ON_WIN32)
336*9880d681SAndroid Build Coastguard Worker   char buf[18];
337*9880d681SAndroid Build Coastguard Worker   ASSERT_EQ(::read(fd, buf, 18), 18);
338*9880d681SAndroid Build Coastguard Worker   if (strncmp(buf, "\xfe\xff", 2) == 0) { // UTF16-BE
339*9880d681SAndroid Build Coastguard Worker     ASSERT_EQ(strncmp(&buf[2], utf16be_text, 16), 0);
340*9880d681SAndroid Build Coastguard Worker   } else if (strncmp(buf, "\xff\xfe", 2) == 0) { // UTF16-LE
341*9880d681SAndroid Build Coastguard Worker     ASSERT_EQ(strncmp(&buf[2], utf16le_text, 16), 0);
342*9880d681SAndroid Build Coastguard Worker   } else {
343*9880d681SAndroid Build Coastguard Worker     FAIL() << "Invalid BOM in UTF-16 file";
344*9880d681SAndroid Build Coastguard Worker   }
345*9880d681SAndroid Build Coastguard Worker #else
346*9880d681SAndroid Build Coastguard Worker   char buf[10];
347*9880d681SAndroid Build Coastguard Worker   ASSERT_EQ(::read(fd, buf, 10), 10);
348*9880d681SAndroid Build Coastguard Worker   ASSERT_EQ(strncmp(buf, utf8_text, 10), 0);
349*9880d681SAndroid Build Coastguard Worker #endif
350*9880d681SAndroid Build Coastguard Worker   ::close(fd);
351*9880d681SAndroid Build Coastguard Worker   ASSERT_NO_ERROR(fs::remove(file_pathname.str()));
352*9880d681SAndroid Build Coastguard Worker   ASSERT_NO_ERROR(fs::remove(TestDirectory.str()));
353*9880d681SAndroid Build Coastguard Worker }
354*9880d681SAndroid Build Coastguard Worker 
355*9880d681SAndroid Build Coastguard Worker } // end anonymous namespace
356