1 /* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #include "util/Files.h" 18 19 #include <sstream> 20 21 #include "android-base/stringprintf.h" 22 #include "android-base/utf8.h" 23 24 #include "test/Test.h" 25 26 using ::android::base::StringPrintf; 27 28 namespace aapt { 29 namespace file { 30 31 #ifdef _WIN32 32 constexpr const char sTestDirSep = '\\'; 33 #else 34 constexpr const char sTestDirSep = '/'; 35 #endif 36 37 class FilesTest : public ::testing::Test { 38 public: 39 void SetUp() override { 40 std::stringstream builder; 41 builder << "hello" << sDirSep << "there"; 42 expected_path_ = builder.str(); 43 } 44 45 protected: 46 std::string expected_path_; 47 }; 48 49 TEST_F(FilesTest, AppendPath) { 50 std::string base = "hello"; 51 AppendPath(&base, "there"); 52 EXPECT_EQ(expected_path_, base); 53 } 54 55 TEST_F(FilesTest, AppendPathWithLeadingOrTrailingSeparators) { 56 std::string base = StringPrintf("hello%c", sTestDirSep); 57 AppendPath(&base, "there"); 58 EXPECT_EQ(expected_path_, base); 59 60 base = "hello"; 61 AppendPath(&base, StringPrintf("%cthere", sTestDirSep)); 62 EXPECT_EQ(expected_path_, base); 63 64 base = StringPrintf("hello%c", sTestDirSep); 65 AppendPath(&base, StringPrintf("%cthere", sTestDirSep)); 66 EXPECT_EQ(expected_path_, base); 67 } 68 69 #ifdef _WIN32 70 TEST_F(FilesTest, WindowsMkdirsLongPath) { 71 // Creating directory paths longer than the Windows maximum path length (260 charatcers) should 72 // succeed. 73 const std::string kDirName = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; 74 const size_t kRecursiveDepth = 10u; 75 76 // Recursively create the test file path and clean up the created directories after the files have 77 // been created. 78 std::function<void(std::string, size_t)> CreateResursiveDirs = 79 [&kDirName, &CreateResursiveDirs](std::string current_path, const size_t n) -> void { 80 AppendPath(¤t_path, kDirName); 81 82 if (n == 0) { 83 ASSERT_TRUE(file::mkdirs(current_path)) << "Failed to create path " << current_path; 84 } else { 85 CreateResursiveDirs(current_path, n - 1); 86 } 87 88 // Clean up the created directories. 89 _rmdir(current_path.data()); 90 }; 91 92 CreateResursiveDirs( 93 android::base::StringPrintf(R"(\\?\%s)", android::base::GetExecutableDirectory().data()), 94 kRecursiveDepth); 95 } 96 97 TEST_F(FilesTest, WindowsMkdirsLongPathMissingDrive) { 98 ASSERT_FALSE(file::mkdirs(R"(\\?\local\path\to\file)")); 99 ASSERT_FALSE(file::mkdirs(R"(\\?\:local\path\to\file)")); 100 ASSERT_FALSE(file::mkdirs(R"(\\?\\local\path\to\file)")); 101 } 102 #endif 103 104 } // namespace files 105 } // namespace aapt 106