1e60f2cbdSMichael Jones //===-- Unittests for WrapperGen ------------------------------------------===//
2e60f2cbdSMichael Jones //
3e60f2cbdSMichael Jones // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4e60f2cbdSMichael Jones // See https://llvm.org/LICENSE.txt for license information.
5e60f2cbdSMichael Jones // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6e60f2cbdSMichael Jones //
7e60f2cbdSMichael Jones //===----------------------------------------------------------------------===//
8e60f2cbdSMichael Jones 
9e60f2cbdSMichael Jones #include "llvm/ADT/SmallString.h"
10e60f2cbdSMichael Jones #include "llvm/ADT/StringRef.h"
11e60f2cbdSMichael Jones #include "llvm/ADT/Twine.h"
12e60f2cbdSMichael Jones #include "llvm/Support/CommandLine.h"
13e60f2cbdSMichael Jones #include "llvm/Support/Error.h"
14e60f2cbdSMichael Jones #include "llvm/Support/FileSystem.h"
159ab6c1a9SSiva Chandra Reddy #include "llvm/Support/FileUtilities.h"
16e60f2cbdSMichael Jones #include "llvm/Support/MemoryBuffer.h"
17e60f2cbdSMichael Jones #include "llvm/Support/Program.h"
18e60f2cbdSMichael Jones #include "llvm/Support/raw_ostream.h"
19e60f2cbdSMichael Jones #include "gmock/gmock.h"
20e60f2cbdSMichael Jones #include "gtest/gtest.h"
21e60f2cbdSMichael Jones #include <unistd.h>
22e60f2cbdSMichael Jones 
23e60f2cbdSMichael Jones llvm::cl::opt<std::string>
24e60f2cbdSMichael Jones     LibcPath("path", llvm::cl::desc("Path to the top level libc directory."),
25e60f2cbdSMichael Jones              llvm::cl::value_desc("<path to libc>"), llvm::cl::Required);
26e60f2cbdSMichael Jones llvm::cl::opt<std::string>
27e60f2cbdSMichael Jones     ToolPath("tool", llvm::cl::desc("Path to the tool executable."),
28e60f2cbdSMichael Jones              llvm::cl::value_desc("<path to tool>"), llvm::cl::Required);
29e60f2cbdSMichael Jones llvm::cl::opt<std::string>
30e60f2cbdSMichael Jones     APIPath("api",
31e60f2cbdSMichael Jones             llvm::cl::desc("Path to the api tablegen file used by the tests."),
32e60f2cbdSMichael Jones             llvm::cl::value_desc("<path to testapi.td>"), llvm::cl::Required);
33e60f2cbdSMichael Jones 
34e60f2cbdSMichael Jones class WrapperGenTest : public ::testing::Test {
35e60f2cbdSMichael Jones public:
36e60f2cbdSMichael Jones   std::string IncludeArg;
37e60f2cbdSMichael Jones   std::string APIArg;
38e60f2cbdSMichael Jones   llvm::StringRef ProgPath;
39e60f2cbdSMichael Jones   llvm::Expected<llvm::sys::fs::TempFile> STDOutFile =
40e60f2cbdSMichael Jones       llvm::sys::fs::TempFile::create("wrappergen-stdout-%%-%%-%%-%%.txt");
41e60f2cbdSMichael Jones   llvm::Expected<llvm::sys::fs::TempFile> STDErrFile =
42e60f2cbdSMichael Jones       llvm::sys::fs::TempFile::create("wrappergen-stderr-%%-%%-%%-%%.txt");
43e60f2cbdSMichael Jones 
44e60f2cbdSMichael Jones protected:
SetUp()45e60f2cbdSMichael Jones   void SetUp() override {
46e60f2cbdSMichael Jones     IncludeArg = "-I=";
47e60f2cbdSMichael Jones     IncludeArg.append(LibcPath);
48e60f2cbdSMichael Jones     APIArg = APIPath;
49e60f2cbdSMichael Jones     ProgPath = llvm::StringRef(ToolPath);
50e60f2cbdSMichael Jones 
51e60f2cbdSMichael Jones     if (!STDOutFile) {
52e60f2cbdSMichael Jones       llvm::errs() << "Error: " << llvm::toString(STDOutFile.takeError())
53e60f2cbdSMichael Jones                    << "\n";
54e60f2cbdSMichael Jones       llvm::report_fatal_error(
55e60f2cbdSMichael Jones           "Temporary file failed to initialize for libc-wrappergen tests.");
56e60f2cbdSMichael Jones     }
57e60f2cbdSMichael Jones     if (!STDErrFile) {
58e60f2cbdSMichael Jones       llvm::errs() << "Error: " << llvm::toString(STDErrFile.takeError())
59e60f2cbdSMichael Jones                    << "\n";
60e60f2cbdSMichael Jones       llvm::report_fatal_error(
61e60f2cbdSMichael Jones           "Temporary file failed to initialize for libc-wrappergen tests.");
62e60f2cbdSMichael Jones     }
63e60f2cbdSMichael Jones   }
TearDown()64e60f2cbdSMichael Jones   void TearDown() override {
65e60f2cbdSMichael Jones     llvm::consumeError(STDOutFile.get().discard());
66e60f2cbdSMichael Jones     llvm::consumeError(STDErrFile.get().discard());
67e60f2cbdSMichael Jones   }
68e60f2cbdSMichael Jones };
69e60f2cbdSMichael Jones 
70*1df0dbfcSMichael Jones using LlvmLibcWrapperGenTest = WrapperGenTest;
71*1df0dbfcSMichael Jones 
TEST_F(LlvmLibcWrapperGenTest,RunWrapperGenAndGetNoErrors)72*1df0dbfcSMichael Jones TEST_F(LlvmLibcWrapperGenTest, RunWrapperGenAndGetNoErrors) {
73e60f2cbdSMichael Jones   llvm::Optional<llvm::StringRef> Redirects[] = {
74e60f2cbdSMichael Jones       llvm::None, llvm::StringRef(STDOutFile.get().TmpName),
75e60f2cbdSMichael Jones       llvm::StringRef(STDErrFile.get().TmpName)};
76e60f2cbdSMichael Jones 
77bf03eba1SSiva Chandra Reddy   llvm::StringRef ArgV[] = {ProgPath,
78bf03eba1SSiva Chandra Reddy                             llvm::StringRef(IncludeArg),
79bf03eba1SSiva Chandra Reddy                             llvm::StringRef(APIArg),
80bf03eba1SSiva Chandra Reddy                             "--gen-wrapper",
81bf03eba1SSiva Chandra Reddy                             "--name",
82bf03eba1SSiva Chandra Reddy                             "strlen"};
83e60f2cbdSMichael Jones 
84e60f2cbdSMichael Jones   int ExitCode =
85e60f2cbdSMichael Jones       llvm::sys::ExecuteAndWait(ProgPath, ArgV, llvm::None, Redirects);
86e60f2cbdSMichael Jones 
87e60f2cbdSMichael Jones   EXPECT_EQ(ExitCode, 0);
88e60f2cbdSMichael Jones 
89e60f2cbdSMichael Jones   auto STDErrOrError = llvm::MemoryBuffer::getFile(STDErrFile.get().TmpName);
90e60f2cbdSMichael Jones   std::string STDErrOutput = STDErrOrError.get()->getBuffer().str();
91e60f2cbdSMichael Jones   ASSERT_EQ(STDErrOutput, "");
92e60f2cbdSMichael Jones }
93e60f2cbdSMichael Jones 
TEST_F(LlvmLibcWrapperGenTest,RunWrapperGenOnStrlen)94*1df0dbfcSMichael Jones TEST_F(LlvmLibcWrapperGenTest, RunWrapperGenOnStrlen) {
95e60f2cbdSMichael Jones   llvm::Optional<llvm::StringRef> Redirects[] = {
96e60f2cbdSMichael Jones       llvm::None, llvm::StringRef(STDOutFile.get().TmpName),
97e60f2cbdSMichael Jones       llvm::StringRef(STDErrFile.get().TmpName)};
98e60f2cbdSMichael Jones 
99bf03eba1SSiva Chandra Reddy   llvm::StringRef ArgV[] = {ProgPath,
100bf03eba1SSiva Chandra Reddy                             llvm::StringRef(IncludeArg),
101bf03eba1SSiva Chandra Reddy                             llvm::StringRef(APIArg),
102bf03eba1SSiva Chandra Reddy                             "--gen-wrapper",
103bf03eba1SSiva Chandra Reddy                             "--name",
104bf03eba1SSiva Chandra Reddy                             "strlen"};
105e60f2cbdSMichael Jones 
106e60f2cbdSMichael Jones   int ExitCode =
107e60f2cbdSMichael Jones       llvm::sys::ExecuteAndWait(ProgPath, ArgV, llvm::None, Redirects);
108e60f2cbdSMichael Jones 
109e60f2cbdSMichael Jones   EXPECT_EQ(ExitCode, 0);
110e60f2cbdSMichael Jones 
111e60f2cbdSMichael Jones   auto STDErrOrError = llvm::MemoryBuffer::getFile(STDErrFile.get().TmpName);
112e60f2cbdSMichael Jones   std::string STDErrOutput = STDErrOrError.get()->getBuffer().str();
113e60f2cbdSMichael Jones 
114e60f2cbdSMichael Jones   ASSERT_EQ(STDErrOutput, "");
115e60f2cbdSMichael Jones 
116e60f2cbdSMichael Jones   auto STDOutOrError = llvm::MemoryBuffer::getFile(STDOutFile.get().TmpName);
117e60f2cbdSMichael Jones   std::string STDOutOutput = STDOutOrError.get()->getBuffer().str();
118e60f2cbdSMichael Jones 
119e60f2cbdSMichael Jones   ASSERT_EQ(STDOutOutput, "#include \"src/string/strlen.h\"\n"
120e60f2cbdSMichael Jones                           "extern \"C\" size_t strlen(const char * __arg0) {\n"
121e60f2cbdSMichael Jones                           "  return __llvm_libc::strlen(__arg0);\n"
122e60f2cbdSMichael Jones                           "}\n");
123e60f2cbdSMichael Jones   // TODO:(michaelrj) Figure out how to make this output comparison
124e60f2cbdSMichael Jones   // less brittle. Currently it's just comparing the output of the program
125e60f2cbdSMichael Jones   // to an exact string, this means that even a small formatting change
126e60f2cbdSMichael Jones   // would break this test.
127e60f2cbdSMichael Jones }
128e60f2cbdSMichael Jones 
TEST_F(LlvmLibcWrapperGenTest,GenAliasForStrlen)129*1df0dbfcSMichael Jones TEST_F(LlvmLibcWrapperGenTest, GenAliasForStrlen) {
130e60f2cbdSMichael Jones   llvm::Optional<llvm::StringRef> Redirects[] = {
131e60f2cbdSMichael Jones       llvm::None, llvm::StringRef(STDOutFile.get().TmpName),
132e60f2cbdSMichael Jones       llvm::StringRef(STDErrFile.get().TmpName)};
133e60f2cbdSMichael Jones 
134e60f2cbdSMichael Jones   llvm::StringRef ArgV[] = {ProgPath,
135e60f2cbdSMichael Jones                             llvm::StringRef(IncludeArg),
136e60f2cbdSMichael Jones                             llvm::StringRef(APIArg),
137bf03eba1SSiva Chandra Reddy                             "--gen-alias",
138bf03eba1SSiva Chandra Reddy                             "--mangled-name",
139bf03eba1SSiva Chandra Reddy                             "__llvm_libc_strlen_mangled_name",
1409ab6c1a9SSiva Chandra Reddy                             "--name",
1419ab6c1a9SSiva Chandra Reddy                             "strlen"};
1429ab6c1a9SSiva Chandra Reddy 
1439ab6c1a9SSiva Chandra Reddy   int ExitCode =
1449ab6c1a9SSiva Chandra Reddy       llvm::sys::ExecuteAndWait(ProgPath, ArgV, llvm::None, Redirects);
1459ab6c1a9SSiva Chandra Reddy 
1469ab6c1a9SSiva Chandra Reddy   EXPECT_EQ(ExitCode, 0);
1479ab6c1a9SSiva Chandra Reddy 
1489ab6c1a9SSiva Chandra Reddy   auto STDErrOrError = llvm::MemoryBuffer::getFile(STDErrFile.get().TmpName);
1499ab6c1a9SSiva Chandra Reddy   std::string STDErrOutput = STDErrOrError.get()->getBuffer().str();
1509ab6c1a9SSiva Chandra Reddy 
1519ab6c1a9SSiva Chandra Reddy   ASSERT_EQ(STDErrOutput, "");
1529ab6c1a9SSiva Chandra Reddy 
1539ab6c1a9SSiva Chandra Reddy   auto STDOutOrError = llvm::MemoryBuffer::getFile(STDOutFile.get().TmpName);
1549ab6c1a9SSiva Chandra Reddy   std::string STDOutOutput = STDOutOrError.get()->getBuffer().str();
1559ab6c1a9SSiva Chandra Reddy 
1569ab6c1a9SSiva Chandra Reddy   ASSERT_EQ(STDOutOutput,
1579ab6c1a9SSiva Chandra Reddy             "extern \"C\" size_t strlen(const char * __arg0) "
158bf03eba1SSiva Chandra Reddy             "__attribute__((alias(\"__llvm_libc_strlen_mangled_name\")));\n");
159bf03eba1SSiva Chandra Reddy   // TODO:(michaelrj) Figure out how to make this output comparison
160bf03eba1SSiva Chandra Reddy   // less brittle. Currently it's just comparing the output of the program
161bf03eba1SSiva Chandra Reddy   // to an exact string, this means that even a small formatting change
162bf03eba1SSiva Chandra Reddy   // would break this test.
163bf03eba1SSiva Chandra Reddy }
164bf03eba1SSiva Chandra Reddy 
TEST_F(LlvmLibcWrapperGenTest,DeclStrlenAliasUsingMangledNameFile)165*1df0dbfcSMichael Jones TEST_F(LlvmLibcWrapperGenTest, DeclStrlenAliasUsingMangledNameFile) {
166bf03eba1SSiva Chandra Reddy   llvm::Optional<llvm::StringRef> Redirects[] = {
167bf03eba1SSiva Chandra Reddy       llvm::None, llvm::StringRef(STDOutFile.get().TmpName),
168bf03eba1SSiva Chandra Reddy       llvm::StringRef(STDErrFile.get().TmpName)};
169bf03eba1SSiva Chandra Reddy 
170bf03eba1SSiva Chandra Reddy   const char *MangledNameFileContent =
171bf03eba1SSiva Chandra Reddy       "abc\nxyz__llvm_libc_strlen_mangled_name\nijk\n";
172bf03eba1SSiva Chandra Reddy   llvm::SmallVector<char> MangledNameFilePath;
173bf03eba1SSiva Chandra Reddy   auto MangledNameFileCreateError = llvm::sys::fs::createUniqueFile(
174bf03eba1SSiva Chandra Reddy       "libc-wrappergen-test-aliasee-file-%%-%%-%%-%%.txt", MangledNameFilePath);
175bf03eba1SSiva Chandra Reddy   ASSERT_FALSE(MangledNameFileCreateError);
176bf03eba1SSiva Chandra Reddy   auto MangledNameFileWriteError = llvm::writeFileAtomically(
177bf03eba1SSiva Chandra Reddy       "libc-wrappergen-temp-test-aliasee-file-%%-%%-%%-%%.txt",
178bf03eba1SSiva Chandra Reddy       llvm::StringRef(MangledNameFilePath.data()),
179bf03eba1SSiva Chandra Reddy       llvm::StringRef(MangledNameFileContent));
180bf03eba1SSiva Chandra Reddy   ASSERT_FALSE(MangledNameFileWriteError);
181bf03eba1SSiva Chandra Reddy 
182bf03eba1SSiva Chandra Reddy   llvm::StringRef ArgV[] = {ProgPath,
183bf03eba1SSiva Chandra Reddy                             llvm::StringRef(IncludeArg),
184bf03eba1SSiva Chandra Reddy                             llvm::StringRef(APIArg),
185bf03eba1SSiva Chandra Reddy                             "--gen-alias",
186bf03eba1SSiva Chandra Reddy                             "--mangled-name-file",
187bf03eba1SSiva Chandra Reddy                             llvm::StringRef(MangledNameFilePath.data()),
188bf03eba1SSiva Chandra Reddy                             "--name",
189bf03eba1SSiva Chandra Reddy                             "strlen"};
190bf03eba1SSiva Chandra Reddy 
191bf03eba1SSiva Chandra Reddy   int ExitCode =
192bf03eba1SSiva Chandra Reddy       llvm::sys::ExecuteAndWait(ProgPath, ArgV, llvm::None, Redirects);
193bf03eba1SSiva Chandra Reddy 
194bf03eba1SSiva Chandra Reddy   EXPECT_EQ(ExitCode, 0);
195bf03eba1SSiva Chandra Reddy 
196bf03eba1SSiva Chandra Reddy   auto STDErrOrError = llvm::MemoryBuffer::getFile(STDErrFile.get().TmpName);
197bf03eba1SSiva Chandra Reddy   std::string STDErrOutput = STDErrOrError.get()->getBuffer().str();
198bf03eba1SSiva Chandra Reddy 
199bf03eba1SSiva Chandra Reddy   ASSERT_EQ(STDErrOutput, "");
200bf03eba1SSiva Chandra Reddy 
201bf03eba1SSiva Chandra Reddy   auto STDOutOrError = llvm::MemoryBuffer::getFile(STDOutFile.get().TmpName);
202bf03eba1SSiva Chandra Reddy   std::string STDOutOutput = STDOutOrError.get()->getBuffer().str();
203bf03eba1SSiva Chandra Reddy 
204bf03eba1SSiva Chandra Reddy   ASSERT_EQ(
205bf03eba1SSiva Chandra Reddy       STDOutOutput,
206bf03eba1SSiva Chandra Reddy       "extern \"C\" size_t strlen(const char * __arg0) "
207bf03eba1SSiva Chandra Reddy       "__attribute__((alias(\"xyz__llvm_libc_strlen_mangled_name\")));\n");
2089ab6c1a9SSiva Chandra Reddy }
2099ab6c1a9SSiva Chandra Reddy 
2109ab6c1a9SSiva Chandra Reddy /////////////////////////////////////////////////////////////////////
211e60f2cbdSMichael Jones /////////////////////////////////////////////////////////////////////
212e60f2cbdSMichael Jones // BAD INPUT TESTS
213e60f2cbdSMichael Jones // all of the tests after this point are testing inputs that should
214e60f2cbdSMichael Jones // return errors
215e60f2cbdSMichael Jones /////////////////////////////////////////////////////////////////////
216e60f2cbdSMichael Jones 
TEST_F(LlvmLibcWrapperGenTest,RunWrapperGenOnStrlenWithMangledNameAndMangledNameFile)217*1df0dbfcSMichael Jones TEST_F(LlvmLibcWrapperGenTest,
218*1df0dbfcSMichael Jones        RunWrapperGenOnStrlenWithMangledNameAndMangledNameFile) {
219e60f2cbdSMichael Jones   llvm::Optional<llvm::StringRef> Redirects[] = {
220e60f2cbdSMichael Jones       llvm::None, llvm::StringRef(STDOutFile.get().TmpName),
221e60f2cbdSMichael Jones       llvm::StringRef(STDErrFile.get().TmpName)};
222e60f2cbdSMichael Jones 
223e60f2cbdSMichael Jones   llvm::StringRef ArgV[] = {ProgPath,
224e60f2cbdSMichael Jones                             llvm::StringRef(IncludeArg),
225e60f2cbdSMichael Jones                             llvm::StringRef(APIArg),
226bf03eba1SSiva Chandra Reddy                             "--gen-alias",
227bf03eba1SSiva Chandra Reddy                             "--mangled-name",
228bf03eba1SSiva Chandra Reddy                             "__llvm_libc_strlen_mangled_name",
229bf03eba1SSiva Chandra Reddy                             "--mangled-name-file",
230bf03eba1SSiva Chandra Reddy                             "non-existant-mangled-name-file.txt",
231e60f2cbdSMichael Jones                             "--name",
232e60f2cbdSMichael Jones                             "strlen"};
233e60f2cbdSMichael Jones 
234e60f2cbdSMichael Jones   int ExitCode =
235e60f2cbdSMichael Jones       llvm::sys::ExecuteAndWait(ProgPath, ArgV, llvm::None, Redirects);
236e60f2cbdSMichael Jones 
237e60f2cbdSMichael Jones   EXPECT_EQ(ExitCode, 1);
238e60f2cbdSMichael Jones 
239e60f2cbdSMichael Jones   auto STDErrOrError = llvm::MemoryBuffer::getFile(STDErrFile.get().TmpName);
240e60f2cbdSMichael Jones   std::string STDErrOutput = STDErrOrError.get()->getBuffer().str();
241e60f2cbdSMichael Jones 
242bf03eba1SSiva Chandra Reddy   ASSERT_EQ(STDErrOutput,
243bf03eba1SSiva Chandra Reddy             "error: The options 'mangled-name' and 'mangled-name-file' "
244e1a5b234SSiva Chandra Reddy             "cannot be specified simultaneously.\n");
245e60f2cbdSMichael Jones 
246e60f2cbdSMichael Jones   auto STDOutOrError = llvm::MemoryBuffer::getFile(STDOutFile.get().TmpName);
247e60f2cbdSMichael Jones   std::string STDOutOutput = STDOutOrError.get()->getBuffer().str();
248e60f2cbdSMichael Jones 
249e60f2cbdSMichael Jones   ASSERT_EQ(STDOutOutput, "");
250e60f2cbdSMichael Jones }
251e60f2cbdSMichael Jones 
TEST_F(LlvmLibcWrapperGenTest,RunWrapperGenOnBadFuncName)252*1df0dbfcSMichael Jones TEST_F(LlvmLibcWrapperGenTest, RunWrapperGenOnBadFuncName) {
253e60f2cbdSMichael Jones   llvm::Optional<llvm::StringRef> Redirects[] = {
254e60f2cbdSMichael Jones       llvm::None, llvm::StringRef(STDOutFile.get().TmpName),
255e60f2cbdSMichael Jones       llvm::StringRef(STDErrFile.get().TmpName)};
256e60f2cbdSMichael Jones 
257e60f2cbdSMichael Jones   llvm::StringRef BadFuncName = "FAKE_TEST_FUNC";
258e60f2cbdSMichael Jones 
259bf03eba1SSiva Chandra Reddy   llvm::StringRef ArgV[] = {ProgPath,
260bf03eba1SSiva Chandra Reddy                             llvm::StringRef(IncludeArg),
261bf03eba1SSiva Chandra Reddy                             llvm::StringRef(APIArg),
262bf03eba1SSiva Chandra Reddy                             "--gen-wrapper",
263bf03eba1SSiva Chandra Reddy                             "--name",
264bf03eba1SSiva Chandra Reddy                             BadFuncName};
265e60f2cbdSMichael Jones 
266e60f2cbdSMichael Jones   int ExitCode =
267e60f2cbdSMichael Jones       llvm::sys::ExecuteAndWait(ProgPath, ArgV, llvm::None, Redirects);
268e60f2cbdSMichael Jones 
269e60f2cbdSMichael Jones   EXPECT_EQ(ExitCode, 1);
270e60f2cbdSMichael Jones 
271e60f2cbdSMichael Jones   auto STDErrOrError = llvm::MemoryBuffer::getFile(STDErrFile.get().TmpName);
272e60f2cbdSMichael Jones   std::string STDErrOutput = STDErrOrError.get()->getBuffer().str();
273e60f2cbdSMichael Jones 
274e60f2cbdSMichael Jones   ASSERT_EQ(STDErrOutput, ("error: Function '" + BadFuncName +
275e60f2cbdSMichael Jones                            "' not found in any standard spec.\n")
276e60f2cbdSMichael Jones                               .str());
277e60f2cbdSMichael Jones 
278e60f2cbdSMichael Jones   auto STDOutOrError = llvm::MemoryBuffer::getFile(STDOutFile.get().TmpName);
279e60f2cbdSMichael Jones   std::string STDOutOutput = STDOutOrError.get()->getBuffer().str();
280e60f2cbdSMichael Jones 
281e60f2cbdSMichael Jones   ASSERT_EQ(STDOutOutput, "");
282e60f2cbdSMichael Jones }
283e60f2cbdSMichael Jones 
TEST_F(LlvmLibcWrapperGenTest,RunWrapperGenOnStrlenWithBadMangledNameFile)284*1df0dbfcSMichael Jones TEST_F(LlvmLibcWrapperGenTest, RunWrapperGenOnStrlenWithBadMangledNameFile) {
285e60f2cbdSMichael Jones   llvm::Optional<llvm::StringRef> Redirects[] = {
286e60f2cbdSMichael Jones       llvm::None, llvm::StringRef(STDOutFile.get().TmpName),
287e60f2cbdSMichael Jones       llvm::StringRef(STDErrFile.get().TmpName)};
288e60f2cbdSMichael Jones 
289bf03eba1SSiva Chandra Reddy   llvm::StringRef BadMangledNameFileName = "FILE_THAT_DOESNT_EXIST.txt";
290e60f2cbdSMichael Jones 
291bf03eba1SSiva Chandra Reddy   llvm::StringRef ArgV[] = {ProgPath,
292bf03eba1SSiva Chandra Reddy                             llvm::StringRef(IncludeArg),
293bf03eba1SSiva Chandra Reddy                             llvm::StringRef(APIArg),
294bf03eba1SSiva Chandra Reddy                             "--gen-alias",
295bf03eba1SSiva Chandra Reddy                             "--mangled-name-file",
296bf03eba1SSiva Chandra Reddy                             BadMangledNameFileName,
297bf03eba1SSiva Chandra Reddy                             "--name",
298e60f2cbdSMichael Jones                             "strlen"};
299e60f2cbdSMichael Jones 
300e60f2cbdSMichael Jones   int ExitCode =
301e60f2cbdSMichael Jones       llvm::sys::ExecuteAndWait(ProgPath, ArgV, llvm::None, Redirects);
302e60f2cbdSMichael Jones 
303e60f2cbdSMichael Jones   EXPECT_EQ(ExitCode, 1);
304e60f2cbdSMichael Jones 
305e60f2cbdSMichael Jones   auto STDErrOrError = llvm::MemoryBuffer::getFile(STDErrFile.get().TmpName);
306e60f2cbdSMichael Jones   std::string STDErrOutput = STDErrOrError.get()->getBuffer().str();
307e60f2cbdSMichael Jones 
308bf03eba1SSiva Chandra Reddy   ASSERT_EQ(STDErrOutput, ("error: Unable to read the mangled name file " +
309bf03eba1SSiva Chandra Reddy                            BadMangledNameFileName + "\n")
310e60f2cbdSMichael Jones                               .str());
311e60f2cbdSMichael Jones 
312e60f2cbdSMichael Jones   auto STDOutOrError = llvm::MemoryBuffer::getFile(STDOutFile.get().TmpName);
313e60f2cbdSMichael Jones   std::string STDOutOutput = STDOutOrError.get()->getBuffer().str();
314e60f2cbdSMichael Jones 
315e60f2cbdSMichael Jones   ASSERT_EQ(STDOutOutput, "");
316e60f2cbdSMichael Jones }
3179ab6c1a9SSiva Chandra Reddy 
TEST_F(LlvmLibcWrapperGenTest,RunWithMangledNameFileMissingLLVMLibcName)318*1df0dbfcSMichael Jones TEST_F(LlvmLibcWrapperGenTest, RunWithMangledNameFileMissingLLVMLibcName) {
3199ab6c1a9SSiva Chandra Reddy   llvm::Optional<llvm::StringRef> Redirects[] = {
3209ab6c1a9SSiva Chandra Reddy       llvm::None, llvm::StringRef(STDOutFile.get().TmpName),
3219ab6c1a9SSiva Chandra Reddy       llvm::StringRef(STDErrFile.get().TmpName)};
3229ab6c1a9SSiva Chandra Reddy 
323bf03eba1SSiva Chandra Reddy   llvm::SmallVector<char> MangledNameFilePath;
324bf03eba1SSiva Chandra Reddy   auto MangledNameFileCreateError = llvm::sys::fs::createUniqueFile(
325bf03eba1SSiva Chandra Reddy       "libc-wrappergen-test-mangled-name-file-%%-%%-%%-%%.txt",
326bf03eba1SSiva Chandra Reddy       MangledNameFilePath);
327bf03eba1SSiva Chandra Reddy   ASSERT_FALSE(MangledNameFileCreateError);
3289ab6c1a9SSiva Chandra Reddy 
3299ab6c1a9SSiva Chandra Reddy   llvm::StringRef ArgV[] = {ProgPath,
3309ab6c1a9SSiva Chandra Reddy                             llvm::StringRef(IncludeArg),
3319ab6c1a9SSiva Chandra Reddy                             llvm::StringRef(APIArg),
332bf03eba1SSiva Chandra Reddy                             "--gen-alias",
333bf03eba1SSiva Chandra Reddy                             "--mangled-name-file",
334bf03eba1SSiva Chandra Reddy                             llvm::StringRef(MangledNameFilePath.data()),
3359ab6c1a9SSiva Chandra Reddy                             "--name",
3369ab6c1a9SSiva Chandra Reddy                             "strlen"};
3379ab6c1a9SSiva Chandra Reddy 
3389ab6c1a9SSiva Chandra Reddy   int ExitCode =
3399ab6c1a9SSiva Chandra Reddy       llvm::sys::ExecuteAndWait(ProgPath, ArgV, llvm::None, Redirects);
3409ab6c1a9SSiva Chandra Reddy 
3419ab6c1a9SSiva Chandra Reddy   EXPECT_NE(ExitCode, 0);
3429ab6c1a9SSiva Chandra Reddy 
3439ab6c1a9SSiva Chandra Reddy   auto STDErrOrError = llvm::MemoryBuffer::getFile(STDErrFile.get().TmpName);
3449ab6c1a9SSiva Chandra Reddy   std::string STDErrOutput = STDErrOrError.get()->getBuffer().str();
3459ab6c1a9SSiva Chandra Reddy 
3469ab6c1a9SSiva Chandra Reddy   ASSERT_EQ(STDErrOutput, ("error: Did not find an LLVM libc mangled name in " +
347bf03eba1SSiva Chandra Reddy                            MangledNameFilePath + "\n")
3489ab6c1a9SSiva Chandra Reddy                               .str());
3499ab6c1a9SSiva Chandra Reddy }
350