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 using ::testing::ElementsAre;
29 using ::testing::UnorderedElementsAre;
30
31 namespace aapt {
32 namespace file {
33
34 #ifdef _WIN32
35 constexpr const char sTestDirSep = '\\';
36 #else
37 constexpr const char sTestDirSep = '/';
38 #endif
39
40 class FilesTest : public TestDirectoryFixture {
41 public:
SetUp()42 void SetUp() override {
43 TestDirectoryFixture::SetUp();
44
45 std::stringstream builder;
46 builder << "hello" << sDirSep << "there";
47 expected_path_ = builder.str();
48 }
49
50 protected:
51 std::string expected_path_;
52 };
53
TEST_F(FilesTest,AppendPath)54 TEST_F(FilesTest, AppendPath) {
55 std::string base = "hello";
56 AppendPath(&base, "there");
57 EXPECT_EQ(expected_path_, base);
58 }
59
TEST_F(FilesTest,AppendPathWithLeadingOrTrailingSeparators)60 TEST_F(FilesTest, AppendPathWithLeadingOrTrailingSeparators) {
61 std::string base = StringPrintf("hello%c", sTestDirSep);
62 AppendPath(&base, "there");
63 EXPECT_EQ(expected_path_, base);
64
65 base = "hello";
66 AppendPath(&base, StringPrintf("%cthere", sTestDirSep));
67 EXPECT_EQ(expected_path_, base);
68
69 base = StringPrintf("hello%c", sTestDirSep);
70 AppendPath(&base, StringPrintf("%cthere", sTestDirSep));
71 EXPECT_EQ(expected_path_, base);
72 }
73
TEST_F(FilesTest,AppendArgsFromFile)74 TEST_F(FilesTest, AppendArgsFromFile) {
75 const std::string args_file = GetTestPath("args.txt");
76 WriteFile(args_file,
77 " \n"
78 "arg1 arg2 arg3 \n"
79 " arg4 arg5");
80 std::vector<std::string> args;
81 std::string error;
82 ASSERT_TRUE(AppendArgsFromFile(args_file, &args, &error));
83 EXPECT_THAT(args, ElementsAre("arg1", "arg2", "arg3", "arg4", "arg5"));
84 }
85
TEST_F(FilesTest,AppendArgsFromFile_InvalidFile)86 TEST_F(FilesTest, AppendArgsFromFile_InvalidFile) {
87 std::vector<std::string> args;
88 std::string error;
89 ASSERT_FALSE(AppendArgsFromFile(GetTestPath("not_found.txt"), &args, &error));
90 }
91
TEST_F(FilesTest,AppendSetArgsFromFile)92 TEST_F(FilesTest, AppendSetArgsFromFile) {
93 const std::string args_file = GetTestPath("args.txt");
94 WriteFile(args_file,
95 " \n"
96 "arg2 arg4 arg1 \n"
97 " arg5 arg3");
98 std::unordered_set<std::string> args;
99 std::string error;
100 ASSERT_TRUE(AppendSetArgsFromFile(args_file, &args, &error));
101 EXPECT_THAT(args, UnorderedElementsAre("arg1", "arg2", "arg3", "arg4", "arg5"));
102 }
103
TEST_F(FilesTest,AppendSetArgsFromFile_InvalidFile)104 TEST_F(FilesTest, AppendSetArgsFromFile_InvalidFile) {
105 std::unordered_set<std::string> args;
106 std::string error;
107 ASSERT_FALSE(AppendSetArgsFromFile(GetTestPath("not_found.txt"), &args, &error));
108 }
109
110 #ifdef _WIN32
TEST_F(FilesTest,WindowsMkdirsLongPath)111 TEST_F(FilesTest, WindowsMkdirsLongPath) {
112 // Creating directory paths longer than the Windows maximum path length (260 charatcers) should
113 // succeed.
114 const std::string kDirName = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
115 const size_t kRecursiveDepth = 10u;
116
117 // Recursively create the test file path and clean up the created directories after the files have
118 // been created.
119 std::function<void(std::string, size_t)> CreateResursiveDirs =
120 [&kDirName, &CreateResursiveDirs](std::string current_path, const size_t n) -> void {
121 AppendPath(¤t_path, kDirName);
122
123 if (n == 0) {
124 ASSERT_TRUE(file::mkdirs(current_path)) << "Failed to create path " << current_path;
125 } else {
126 CreateResursiveDirs(current_path, n - 1);
127 }
128
129 // Clean up the created directories.
130 _rmdir(current_path.data());
131 };
132
133 CreateResursiveDirs(
134 android::base::StringPrintf(R"(\\?\%s)", android::base::GetExecutableDirectory().data()),
135 kRecursiveDepth);
136 }
137
TEST_F(FilesTest,WindowsMkdirsLongPathMissingDrive)138 TEST_F(FilesTest, WindowsMkdirsLongPathMissingDrive) {
139 ASSERT_FALSE(file::mkdirs(R"(\\?\local\path\to\file)"));
140 ASSERT_FALSE(file::mkdirs(R"(\\?\:local\path\to\file)"));
141 ASSERT_FALSE(file::mkdirs(R"(\\?\\local\path\to\file)"));
142 }
143 #endif
144
145 } // namespace files
146 } // namespace aapt
147