X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=unittests%2FSupport%2FPath.cpp;h=210b3a04cb2148915f83008a9e0f0745990ea5b7;hb=00552e3875ee5f382db6c98286a241a7d0efe1b8;hp=d4de2735d31e7e7b31b6f4b76dd5dd763044f63e;hpb=8d230cd536cfc00cc58e749f6e9cf58dd138b0bb;p=oota-llvm.git diff --git a/unittests/Support/Path.cpp b/unittests/Support/Path.cpp index d4de2735d31..210b3a04cb2 100644 --- a/unittests/Support/Path.cpp +++ b/unittests/Support/Path.cpp @@ -16,6 +16,7 @@ #include "gtest/gtest.h" #ifdef LLVM_ON_WIN32 +#include #include #endif @@ -167,6 +168,26 @@ TEST(Support, RelativePathIterator) { } } +TEST(Support, RelativePathDotIterator) { + SmallString<64> Path(StringRef(".c/.d/../.")); + typedef SmallVector PathComponents; + PathComponents ExpectedPathComponents; + PathComponents ActualPathComponents; + + StringRef(Path).split(ExpectedPathComponents, "/"); + + for (path::const_iterator I = path::begin(Path), E = path::end(Path); I != E; + ++I) { + ActualPathComponents.push_back(*I); + } + + ASSERT_EQ(ExpectedPathComponents.size(), ActualPathComponents.size()); + + for (size_t i = 0; i Path(StringRef("/c/d/e/foo.txt")); typedef SmallVector PathComponents; @@ -190,6 +211,29 @@ TEST(Support, AbsolutePathIterator) { } } +TEST(Support, AbsolutePathDotIterator) { + SmallString<64> Path(StringRef("/.c/.d/../.")); + typedef SmallVector PathComponents; + PathComponents ExpectedPathComponents; + PathComponents ActualPathComponents; + + StringRef(Path).split(ExpectedPathComponents, "/"); + + // The root path will also be a component when iterating + ExpectedPathComponents[0] = "/"; + + for (path::const_iterator I = path::begin(Path), E = path::end(Path); I != E; + ++I) { + ActualPathComponents.push_back(*I); + } + + ASSERT_EQ(ExpectedPathComponents.size(), ActualPathComponents.size()); + + for (size_t i = 0; i Path(StringRef("c:\\c\\e\\foo.txt")); @@ -261,10 +305,10 @@ TEST(Support, HomeDirectory) { class FileSystemTest : public testing::Test { protected: /// Unique temporary directory in which all created filesystem entities must - /// be placed. It is recursively removed at the end of each test. + /// be placed. It is removed at the end of each test (must be empty). SmallString<128> TestDirectory; - virtual void SetUp() { + void SetUp() override { ASSERT_NO_ERROR( fs::createUniqueDirectory("file-system-test", TestDirectory)); // We don't care about this specific file. @@ -272,9 +316,7 @@ protected: errs().flush(); } - virtual void TearDown() { - ASSERT_NO_ERROR(fs::remove(TestDirectory.str())); - } + void TearDown() override { ASSERT_NO_ERROR(fs::remove(TestDirectory.str())); } }; TEST_F(FileSystemTest, Unique) { @@ -396,8 +438,16 @@ TEST_F(FileSystemTest, TempFiles) { "abcdefghijklmnopqrstuvwxyz5abcdefghijklmnopqrstuvwxyz4" "abcdefghijklmnopqrstuvwxyz3abcdefghijklmnopqrstuvwxyz2" "abcdefghijklmnopqrstuvwxyz1abcdefghijklmnopqrstuvwxyz0"; - EXPECT_EQ(fs::createUniqueFile(Twine(Path270), FileDescriptor, TempPath), - errc::no_such_file_or_directory); + EXPECT_EQ(fs::createUniqueFile(Path270, FileDescriptor, TempPath), + errc::invalid_argument); + // Relative path < 247 chars, no problem. + const char *Path216 = + "abcdefghijklmnopqrstuvwxyz7abcdefghijklmnopqrstuvwxyz6" + "abcdefghijklmnopqrstuvwxyz5abcdefghijklmnopqrstuvwxyz4" + "abcdefghijklmnopqrstuvwxyz3abcdefghijklmnopqrstuvwxyz2" + "abcdefghijklmnopqrstuvwxyz1abcdefghijklmnopqrstuvwxyz0"; + ASSERT_NO_ERROR(fs::createTemporaryFile(Path216, "", TempPath)); + ASSERT_NO_ERROR(fs::remove(Twine(TempPath))); #endif } @@ -407,6 +457,54 @@ TEST_F(FileSystemTest, CreateDir) { ASSERT_EQ(fs::create_directory(Twine(TestDirectory) + "foo", false), errc::file_exists); ASSERT_NO_ERROR(fs::remove(Twine(TestDirectory) + "foo")); + +#ifdef LLVM_ON_WIN32 + // Prove that create_directories() can handle a pathname > 248 characters, + // which is the documented limit for CreateDirectory(). + // (248 is MAX_PATH subtracting room for an 8.3 filename.) + // Generate a directory path guaranteed to fall into that range. + size_t TmpLen = TestDirectory.size(); + const char *OneDir = "\\123456789"; + size_t OneDirLen = strlen(OneDir); + ASSERT_LT(OneDirLen, 12U); + size_t NLevels = ((248 - TmpLen) / OneDirLen) + 1; + SmallString<260> LongDir(TestDirectory); + for (size_t I = 0; I < NLevels; ++I) + LongDir.append(OneDir); + ASSERT_NO_ERROR(fs::create_directories(Twine(LongDir))); + ASSERT_NO_ERROR(fs::create_directories(Twine(LongDir))); + ASSERT_EQ(fs::create_directories(Twine(LongDir), false), + errc::file_exists); + // Tidy up, "recursively" removing the directories. + StringRef ThisDir(LongDir); + for (size_t J = 0; J < NLevels; ++J) { + ASSERT_NO_ERROR(fs::remove(ThisDir)); + ThisDir = path::parent_path(ThisDir); + } + + // Similarly for a relative pathname. Need to set the current directory to + // TestDirectory so that the one we create ends up in the right place. + char PreviousDir[260]; + size_t PreviousDirLen = ::GetCurrentDirectoryA(260, PreviousDir); + ASSERT_GT(PreviousDirLen, 0U); + ASSERT_LT(PreviousDirLen, 260U); + ASSERT_NE(::SetCurrentDirectoryA(TestDirectory.c_str()), 0); + LongDir.clear(); + // Generate a relative directory name with absolute length > 248. + size_t LongDirLen = 249 - TestDirectory.size(); + LongDir.assign(LongDirLen, 'a'); + ASSERT_NO_ERROR(fs::create_directory(Twine(LongDir))); + // While we're here, prove that .. and . handling works in these long paths. + const char *DotDotDirs = "\\..\\.\\b"; + LongDir.append(DotDotDirs); + ASSERT_NO_ERROR(fs::create_directory("b")); + ASSERT_EQ(fs::create_directory(Twine(LongDir), false), errc::file_exists); + // And clean up. + ASSERT_NO_ERROR(fs::remove("b")); + ASSERT_NO_ERROR(fs::remove( + Twine(LongDir.substr(0, LongDir.size() - strlen(DotDotDirs))))); + ASSERT_NE(::SetCurrentDirectoryA(PreviousDir), 0); +#endif } TEST_F(FileSystemTest, DirectoryIteration) { @@ -483,6 +581,8 @@ TEST_F(FileSystemTest, DirectoryIteration) { const char archive[] = "!\x0A"; const char bitcode[] = "\xde\xc0\x17\x0b"; const char coff_object[] = "\x00\x00......"; +const char coff_bigobj[] = "\x00\x00\xff\xff\x00\x02......" + "\xc7\xa1\xba\xd1\xee\xba\xa9\x4b\xaf\x20\xfa\xf6\x6a\xa4\xdc\xb8"; const char coff_import_library[] = "\x00\x00\xff\xff...."; const char elf_relocatable[] = { 0x7f, 'E', 'L', 'F', 1, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }; @@ -498,7 +598,10 @@ const char macho_dynamically_linked_shared_lib[] = const char macho_dynamic_linker[] = "\xfe\xed\xfa\xce..........\x00\x07"; const char macho_bundle[] = "\xfe\xed\xfa\xce..........\x00\x08"; const char macho_dsym_companion[] = "\xfe\xed\xfa\xce..........\x00\x0a"; +const char macho_kext_bundle[] = "\xfe\xed\xfa\xce..........\x00\x0b"; const char windows_resource[] = "\x00\x00\x00\x00\x020\x00\x00\x00\xff"; +const char macho_dynamically_linked_shared_lib_stub[] = + "\xfe\xed\xfa\xce..........\x00\x09"; TEST_F(FileSystemTest, Magic) { struct type { @@ -512,6 +615,7 @@ TEST_F(FileSystemTest, Magic) { DEFINE(archive), DEFINE(bitcode), DEFINE(coff_object), + { "coff_bigobj", coff_bigobj, sizeof(coff_bigobj), fs::file_magic::coff_object }, DEFINE(coff_import_library), DEFINE(elf_relocatable), DEFINE(macho_universal_binary), @@ -523,7 +627,9 @@ TEST_F(FileSystemTest, Magic) { DEFINE(macho_dynamically_linked_shared_lib), DEFINE(macho_dynamic_linker), DEFINE(macho_bundle), + DEFINE(macho_dynamically_linked_shared_lib_stub), DEFINE(macho_dsym_companion), + DEFINE(macho_kext_bundle), DEFINE(windows_resource) #undef DEFINE }; @@ -575,22 +681,31 @@ TEST_F(FileSystemTest, CarriageReturn) { } #endif +TEST_F(FileSystemTest, Resize) { + int FD; + SmallString<64> TempPath; + ASSERT_NO_ERROR(fs::createTemporaryFile("prefix", "temp", FD, TempPath)); + ASSERT_NO_ERROR(fs::resize_file(FD, 123)); + fs::file_status Status; + ASSERT_NO_ERROR(fs::status(FD, Status)); + ASSERT_EQ(Status.getSize(), 123U); +} + TEST_F(FileSystemTest, FileMapping) { // Create a temp file. int FileDescriptor; SmallString<64> TempPath; ASSERT_NO_ERROR( fs::createTemporaryFile("prefix", "temp", FileDescriptor, TempPath)); + unsigned Size = 4096; + ASSERT_NO_ERROR(fs::resize_file(FileDescriptor, Size)); + // Map in temp file and add some content std::error_code EC; StringRef Val("hello there"); { fs::mapped_file_region mfr(FileDescriptor, - true, - fs::mapped_file_region::readwrite, - 4096, - 0, - EC); + fs::mapped_file_region::readwrite, Size, 0, EC); ASSERT_NO_ERROR(EC); std::copy(Val.begin(), Val.end(), mfr.data()); // Explicitly add a 0. @@ -599,27 +714,19 @@ TEST_F(FileSystemTest, FileMapping) { } // Map it back in read-only - fs::mapped_file_region mfr(Twine(TempPath), - fs::mapped_file_region::readonly, - 0, - 0, - EC); + int FD; + EC = fs::openFileForRead(Twine(TempPath), FD); + ASSERT_NO_ERROR(EC); + fs::mapped_file_region mfr(FD, fs::mapped_file_region::readonly, Size, 0, EC); ASSERT_NO_ERROR(EC); // Verify content EXPECT_EQ(StringRef(mfr.const_data()), Val); // Unmap temp file - - fs::mapped_file_region m(Twine(TempPath), - fs::mapped_file_region::readonly, - 0, - 0, - EC); + fs::mapped_file_region m(FD, fs::mapped_file_region::readonly, Size, 0, EC); ASSERT_NO_ERROR(EC); - const char *Data = m.const_data(); - fs::mapped_file_region mfrrv(std::move(m)); - EXPECT_EQ(mfrrv.const_data(), Data); + ASSERT_EQ(close(FD), 0); } TEST(Support, NormalizePath) {