diff options
Diffstat (limited to 'unittests/Support')
-rw-r--r-- | unittests/Support/CMakeLists.txt | 2 | ||||
-rw-r--r-- | unittests/Support/CommandLineTest.cpp | 52 | ||||
-rw-r--r-- | unittests/Support/CompressionTest.cpp | 68 | ||||
-rw-r--r-- | unittests/Support/Path.cpp | 12 | ||||
-rw-r--r-- | unittests/Support/ProgramTest.cpp | 89 |
5 files changed, 221 insertions, 2 deletions
diff --git a/unittests/Support/CMakeLists.txt b/unittests/Support/CMakeLists.txt index b4b982f..e6cafbc 100644 --- a/unittests/Support/CMakeLists.txt +++ b/unittests/Support/CMakeLists.txt @@ -10,6 +10,7 @@ add_llvm_unittest(SupportTests BlockFrequencyTest.cpp Casting.cpp CommandLineTest.cpp + CompressionTest.cpp ConstantRangeTest.cpp DataExtractorTest.cpp EndianTest.cpp @@ -23,6 +24,7 @@ add_llvm_unittest(SupportTests MemoryTest.cpp Path.cpp ProcessTest.cpp + ProgramTest.cpp RegexTest.cpp SwapByteOrderTest.cpp TimeValue.cpp diff --git a/unittests/Support/CommandLineTest.cpp b/unittests/Support/CommandLineTest.cpp index 43c8cbd..cd235d2 100644 --- a/unittests/Support/CommandLineTest.cpp +++ b/unittests/Support/CommandLineTest.cpp @@ -41,6 +41,45 @@ class TempEnvVar { const char *const name; }; +cl::OptionCategory TestCategory("Test Options", "Description"); +cl::opt<int> TestOption("test-option", cl::desc("old description")); +TEST(CommandLineTest, ModifyExisitingOption) { + const char Description[] = "New description"; + const char ArgString[] = "new-test-option"; + const char ValueString[] = "Integer"; + + StringMap<cl::Option*> Map; + cl::getRegisteredOptions(Map); + + ASSERT_TRUE(Map.count("test-option") == 1) << + "Could not find option in map."; + + cl::Option *Retrieved = Map["test-option"]; + ASSERT_EQ(&TestOption, Retrieved) << "Retrieved wrong option."; + + ASSERT_EQ(&cl::GeneralCategory,Retrieved->Category) << + "Incorrect default option category."; + + Retrieved->setCategory(TestCategory); + ASSERT_EQ(&TestCategory,Retrieved->Category) << + "Failed to modify option's option category."; + + Retrieved->setDescription(Description); + ASSERT_STREQ(Retrieved->HelpStr, Description) << + "Changing option description failed."; + + Retrieved->setArgStr(ArgString); + ASSERT_STREQ(ArgString, Retrieved->ArgStr) << + "Failed to modify option's Argument string."; + + Retrieved->setValueStr(ValueString); + ASSERT_STREQ(Retrieved->ValueStr, ValueString) << + "Failed to modify option's Value string."; + + Retrieved->setHiddenFlag(cl::Hidden); + ASSERT_EQ(cl::Hidden, TestOption.getOptionHiddenFlag()) << + "Failed to modify option's hidden flag."; +} #ifndef SKIP_ENVIRONMENT_TESTS const char test_env_var[] = "LLVM_TEST_COMMAND_LINE_FLAGS"; @@ -55,6 +94,12 @@ TEST(CommandLineTest, ParseEnvironment) { // This test used to make valgrind complain // ("Conditional jump or move depends on uninitialised value(s)") +// +// Warning: Do not run any tests after this one that try to gain access to +// registered command line options because this will likely result in a +// SEGFAULT. This can occur because the cl::opt in the test below is declared +// on the stack which will be destroyed after the test completes but the +// command line system will still hold a pointer to a deallocated cl::Option. TEST(CommandLineTest, ParseEnvironmentToLocalVar) { // Put cl::opt on stack to check for proper initialization of fields. cl::opt<std::string> EnvironmentTestOptionLocal("env-test-opt-local"); @@ -66,4 +111,11 @@ TEST(CommandLineTest, ParseEnvironmentToLocalVar) { #endif // SKIP_ENVIRONMENT_TESTS +TEST(CommandLineTest, UseOptionCategory) { + cl::opt<int> TestOption2("test-option", cl::cat(TestCategory)); + + ASSERT_EQ(&TestCategory,TestOption2.Category) << "Failed to assign Option " + "Category."; +} + } // anonymous namespace diff --git a/unittests/Support/CompressionTest.cpp b/unittests/Support/CompressionTest.cpp new file mode 100644 index 0000000..c8e2cd9 --- /dev/null +++ b/unittests/Support/CompressionTest.cpp @@ -0,0 +1,68 @@ +//===- llvm/unittest/Support/CompressionTest.cpp - Compression tests ------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file implements unit tests for the Compression functions. +// +//===----------------------------------------------------------------------===// + +#include "llvm/Support/Compression.h" +#include "llvm/ADT/OwningPtr.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/Config/config.h" +#include "llvm/Support/MemoryBuffer.h" +#include "gtest/gtest.h" + +using namespace llvm; + +namespace { + +#if LLVM_ENABLE_ZLIB == 1 && HAVE_LIBZ + +void TestZlibCompression(StringRef Input, zlib::CompressionLevel Level) { + OwningPtr<MemoryBuffer> Compressed; + OwningPtr<MemoryBuffer> Uncompressed; + EXPECT_EQ(zlib::StatusOK, zlib::compress(Input, Compressed, Level)); + // Check that uncompressed buffer is the same as original. + EXPECT_EQ(zlib::StatusOK, zlib::uncompress(Compressed->getBuffer(), + Uncompressed, Input.size())); + EXPECT_EQ(Input.size(), Uncompressed->getBufferSize()); + EXPECT_EQ(0, + memcmp(Input.data(), Uncompressed->getBufferStart(), Input.size())); + if (Input.size() > 0) { + // Uncompression fails if expected length is too short. + EXPECT_EQ(zlib::StatusBufferTooShort, + zlib::uncompress(Compressed->getBuffer(), Uncompressed, + Input.size() - 1)); + } +} + +TEST(CompressionTest, Zlib) { + TestZlibCompression("", zlib::DefaultCompression); + + TestZlibCompression("hello, world!", zlib::NoCompression); + TestZlibCompression("hello, world!", zlib::BestSizeCompression); + TestZlibCompression("hello, world!", zlib::BestSpeedCompression); + TestZlibCompression("hello, world!", zlib::DefaultCompression); + + const size_t kSize = 1024; + char BinaryData[kSize]; + for (size_t i = 0; i < kSize; ++i) { + BinaryData[i] = i & 255; + } + StringRef BinaryDataStr(BinaryData, kSize); + + TestZlibCompression(BinaryDataStr, zlib::NoCompression); + TestZlibCompression(BinaryDataStr, zlib::BestSizeCompression); + TestZlibCompression(BinaryDataStr, zlib::BestSpeedCompression); + TestZlibCompression(BinaryDataStr, zlib::DefaultCompression); +} + +#endif + +} diff --git a/unittests/Support/Path.cpp b/unittests/Support/Path.cpp index 4511259..eec8c62 100644 --- a/unittests/Support/Path.cpp +++ b/unittests/Support/Path.cpp @@ -298,12 +298,19 @@ TEST_F(FileSystemTest, DirectoryIteration) { ASSERT_LT(z0, za1); } +const char elf[] = {0x7f, 'E', 'L', 'F', 1, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}; + TEST_F(FileSystemTest, Magic) { struct type { const char *filename; const char *magic_str; - size_t magic_str_len; - } types [] = {{"magic.archive", "!<arch>\x0A", 8}}; + size_t magic_str_len; + fs::file_magic magic; + } types [] = { + {"magic.archive", "!<arch>\x0A", 8, fs::file_magic::archive}, + {"magic.elf", elf, sizeof(elf), + fs::file_magic::elf_relocatable} + }; // Create some files filled with magic. for (type *i = types, *e = types + (sizeof(types) / sizeof(type)); i != e; @@ -320,6 +327,7 @@ TEST_F(FileSystemTest, Magic) { bool res = false; ASSERT_NO_ERROR(fs::has_magic(file_pathname.c_str(), magic, res)); EXPECT_TRUE(res); + EXPECT_EQ(i->magic, fs::identify_magic(magic)); } } diff --git a/unittests/Support/ProgramTest.cpp b/unittests/Support/ProgramTest.cpp new file mode 100644 index 0000000..6cbb054 --- /dev/null +++ b/unittests/Support/ProgramTest.cpp @@ -0,0 +1,89 @@ +//===- unittest/Support/ProgramTest.cpp -----------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "llvm/Support/CommandLine.h" +#include "llvm/Support/Path.h" +#include "llvm/Support/Program.h" +#include "gtest/gtest.h" + +#include <stdlib.h> +#if defined(__APPLE__) +# include <crt_externs.h> +#elif !defined(_MSC_VER) +// Forward declare environ in case it's not provided by stdlib.h. +extern char **environ; +#endif + +// From TestMain.cpp. +extern const char *TestMainArgv0; + +namespace { + +using namespace llvm; +using namespace sys; + +static cl::opt<std::string> +ProgramTestStringArg1("program-test-string-arg1"); +static cl::opt<std::string> +ProgramTestStringArg2("program-test-string-arg2"); + +static void CopyEnvironment(std::vector<const char *> &out) { +#ifdef __APPLE__ + char **envp = *_NSGetEnviron(); +#else + // environ seems to work for Windows and most other Unices. + char **envp = environ; +#endif + while (*envp != 0) { + out.push_back(*envp); + ++envp; + } +} + +TEST(ProgramTest, CreateProcessTrailingSlash) { + if (getenv("LLVM_PROGRAM_TEST_CHILD")) { + if (ProgramTestStringArg1 == "has\\\\ trailing\\" && + ProgramTestStringArg2 == "has\\\\ trailing\\") { + exit(0); // Success! The arguments were passed and parsed. + } + exit(1); + } + + Path my_exe = Path::GetMainExecutable(TestMainArgv0, &ProgramTestStringArg1); + const char *argv[] = { + my_exe.c_str(), + "--gtest_filter=ProgramTest.CreateProcessTrailingSlashChild", + "-program-test-string-arg1", "has\\\\ trailing\\", + "-program-test-string-arg2", "has\\\\ trailing\\", + 0 + }; + + // Add LLVM_PROGRAM_TEST_CHILD to the environment of the child. + std::vector<const char *> envp; + CopyEnvironment(envp); + envp.push_back("LLVM_PROGRAM_TEST_CHILD=1"); + envp.push_back(0); + + std::string error; + bool ExecutionFailed; + // Redirect stdout and stdin to NUL, but let stderr through. +#ifdef LLVM_ON_WIN32 + Path nul("NUL"); +#else + Path nul("/dev/null"); +#endif + const Path *redirects[] = { &nul, &nul, 0 }; + int rc = Program::ExecuteAndWait(my_exe, argv, &envp[0], redirects, + /*secondsToWait=*/10, /*memoryLimit=*/0, + &error, &ExecutionFailed); + EXPECT_FALSE(ExecutionFailed) << error; + EXPECT_EQ(0, rc); +} + +} // end anonymous namespace |