1 // Copyright 2017 The Crashpad Authors. All rights reserved.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 #include "util/file/directory_reader.h"
16
17 #include <set>
18
19 #include "base/files/file_path.h"
20 #include "base/strings/stringprintf.h"
21 #include "base/strings/utf_string_conversions.h"
22 #include "gtest/gtest.h"
23 #include "test/filesystem.h"
24 #include "test/scoped_temp_dir.h"
25 #include "util/file/file_io.h"
26 #include "util/file/filesystem.h"
27
28 namespace crashpad {
29 namespace test {
30 namespace {
31
TEST(DirectoryReader,BadPaths)32 TEST(DirectoryReader, BadPaths) {
33 DirectoryReader reader;
34 EXPECT_FALSE(reader.Open(base::FilePath()));
35
36 ScopedTempDir temp_dir;
37 base::FilePath file(temp_dir.path().Append(FILE_PATH_LITERAL("file")));
38 ASSERT_TRUE(CreateFile(file));
39 EXPECT_FALSE(reader.Open(file));
40
41 EXPECT_FALSE(
42 reader.Open(temp_dir.path().Append(FILE_PATH_LITERAL("doesntexist"))));
43 }
44
45 #if !defined(OS_FUCHSIA)
46
TEST(DirectoryReader,BadPaths_SymbolicLinks)47 TEST(DirectoryReader, BadPaths_SymbolicLinks) {
48 if (!CanCreateSymbolicLinks()) {
49 GTEST_SKIP();
50 }
51
52 ScopedTempDir temp_dir;
53 base::FilePath file(temp_dir.path().Append(FILE_PATH_LITERAL("file")));
54 ASSERT_TRUE(CreateFile(file));
55
56 base::FilePath link(temp_dir.path().Append(FILE_PATH_LITERAL("link")));
57 ASSERT_TRUE(CreateSymbolicLink(file, link));
58
59 DirectoryReader reader;
60 EXPECT_FALSE(reader.Open(link));
61
62 ASSERT_TRUE(LoggingRemoveFile(file));
63 EXPECT_FALSE(reader.Open(link));
64 }
65
66 #endif // !OS_FUCHSIA
67
TEST(DirectoryReader,EmptyDirectory)68 TEST(DirectoryReader, EmptyDirectory) {
69 ScopedTempDir temp_dir;
70 DirectoryReader reader;
71
72 ASSERT_TRUE(reader.Open(temp_dir.path()));
73 base::FilePath filename;
74 EXPECT_EQ(reader.NextFile(&filename), DirectoryReader::Result::kNoMoreFiles);
75 }
76
ExpectFiles(const std::set<base::FilePath> & files,const std::set<base::FilePath> & expected)77 void ExpectFiles(const std::set<base::FilePath>& files,
78 const std::set<base::FilePath>& expected) {
79 EXPECT_EQ(files.size(), expected.size());
80
81 for (const auto& filename : expected) {
82 SCOPED_TRACE(
83 base::StringPrintf("Filename: %" PRFilePath, filename.value().c_str()));
84 EXPECT_NE(files.find(filename), files.end());
85 }
86 }
87
TestFilesAndDirectories(bool symbolic_links)88 void TestFilesAndDirectories(bool symbolic_links) {
89 ScopedTempDir temp_dir;
90 std::set<base::FilePath> expected_files;
91
92 base::FilePath file(FILE_PATH_LITERAL("file"));
93 ASSERT_TRUE(CreateFile(temp_dir.path().Append(file)));
94 EXPECT_TRUE(expected_files.insert(file).second);
95
96 base::FilePath directory(FILE_PATH_LITERAL("directory"));
97 ASSERT_TRUE(LoggingCreateDirectory(temp_dir.path().Append(directory),
98 FilePermissions::kWorldReadable,
99 false));
100 EXPECT_TRUE(expected_files.insert(directory).second);
101
102 base::FilePath nested_file(FILE_PATH_LITERAL("nested_file"));
103 ASSERT_TRUE(
104 CreateFile(temp_dir.path().Append(directory).Append(nested_file)));
105
106 #if !defined(OS_FUCHSIA)
107
108 if (symbolic_links) {
109 base::FilePath link(FILE_PATH_LITERAL("link"));
110 ASSERT_TRUE(CreateSymbolicLink(temp_dir.path().Append(file),
111 temp_dir.path().Append(link)));
112 EXPECT_TRUE(expected_files.insert(link).second);
113
114 base::FilePath dangling(FILE_PATH_LITERAL("dangling"));
115 ASSERT_TRUE(
116 CreateSymbolicLink(base::FilePath(FILE_PATH_LITERAL("not_a_file")),
117 temp_dir.path().Append(dangling)));
118 EXPECT_TRUE(expected_files.insert(dangling).second);
119 }
120
121 #endif // !OS_FUCHSIA
122
123 std::set<base::FilePath> files;
124 DirectoryReader reader;
125 ASSERT_TRUE(reader.Open(temp_dir.path()));
126 DirectoryReader::Result result;
127 base::FilePath filename;
128 while ((result = reader.NextFile(&filename)) ==
129 DirectoryReader::Result::kSuccess) {
130 EXPECT_TRUE(files.insert(filename).second);
131 }
132 EXPECT_EQ(result, DirectoryReader::Result::kNoMoreFiles);
133 EXPECT_EQ(reader.NextFile(&filename), DirectoryReader::Result::kNoMoreFiles);
134 ExpectFiles(files, expected_files);
135 }
136
TEST(DirectoryReader,FilesAndDirectories)137 TEST(DirectoryReader, FilesAndDirectories) {
138 TestFilesAndDirectories(false);
139 }
140
141 #if !defined(OS_FUCHSIA)
142
TEST(DirectoryReader,FilesAndDirectories_SymbolicLinks)143 TEST(DirectoryReader, FilesAndDirectories_SymbolicLinks) {
144 if (!CanCreateSymbolicLinks()) {
145 GTEST_SKIP();
146 }
147
148 TestFilesAndDirectories(true);
149 }
150
151 #endif // !OS_FUCHSIA
152
153 } // namespace
154 } // namespace test
155 } // namespace crashpad
156