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