OLD | NEW |
| (Empty) |
1 // Copyright 2007-2010 Google Inc. | |
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 // | |
16 // Path-utility unit tests. | |
17 | |
18 #include <vector> | |
19 #include "omaha/base/file.h" | |
20 #include "omaha/base/path.h" | |
21 #include "omaha/base/utils.h" | |
22 #include "omaha/testing/unit_test.h" | |
23 | |
24 namespace omaha { | |
25 | |
26 TEST(PathTest, IsAbsolutePath) { | |
27 ASSERT_TRUE(IsAbsolutePath(L"C:\\Foo.bar")); | |
28 ASSERT_TRUE(IsAbsolutePath(L"\\\\user-laptop1\\path")); | |
29 ASSERT_FALSE(IsAbsolutePath(L"windows\\system32")); | |
30 } | |
31 | |
32 // EnclosePath is overzealous and quotes a path even though no spaces exists. | |
33 TEST(PathTest, EnclosePath) { | |
34 CString path; | |
35 EnclosePath(&path); | |
36 EXPECT_STREQ(_T(""), path); | |
37 | |
38 path = _T(""); | |
39 EnclosePath(&path); | |
40 EXPECT_STREQ(_T(""), path); | |
41 | |
42 path = _T("a"); | |
43 EnclosePath(&path); | |
44 EXPECT_STREQ(_T("\"a\""), path); | |
45 | |
46 path = _T("a b"); | |
47 EnclosePath(&path); | |
48 EXPECT_STREQ(_T("\"a b\""), path); | |
49 | |
50 path = " a b "; | |
51 EnclosePath(&path); | |
52 EXPECT_STREQ(_T("\" a b \""), path); | |
53 | |
54 path = _T("\"a b\""); | |
55 EnclosePath(&path); | |
56 EXPECT_STREQ(_T("\"a b\""), path); | |
57 | |
58 path = _T("c:\\Windows\\notepad.exe"); | |
59 EnclosePath(&path); | |
60 EXPECT_STREQ(_T("\"c:\\Windows\\notepad.exe\""), path); | |
61 | |
62 path = _T("c:\\Program Files\\Google\\Common\\Google Update"); | |
63 EnclosePath(&path); | |
64 EXPECT_STREQ(_T("\"c:\\Program Files\\Google\\Common\\Google Update\""), | |
65 path); | |
66 } | |
67 | |
68 // EnclosePath encloses a string that has a quote only at the beginning or end. | |
69 TEST(PathTest, EnclosePath_OnlyOneQuote) { | |
70 ExpectAsserts expect_asserts; | |
71 CString path = _T("\"a b"); | |
72 EnclosePath(&path); | |
73 EXPECT_STREQ(_T("\"\"a b\""), path); | |
74 | |
75 path = _T("a b\""); | |
76 EnclosePath(&path); | |
77 EXPECT_STREQ(_T("\"a b\"\""), path); | |
78 } | |
79 | |
80 // EnclosePath does not look at the middle of the string. | |
81 TEST(PathTest, EnclosePath_QuoteInMiddle) { | |
82 CString path = _T("a\" b"); | |
83 EnclosePath(&path); | |
84 EXPECT_STREQ(_T("\"a\" b\""), path); | |
85 } | |
86 | |
87 TEST(PathTest, EnclosePath_SingleQuotes) { | |
88 CString path = _T("'foo'"); | |
89 EnclosePath(&path); | |
90 EXPECT_STREQ(_T("\"'foo'\""), path); | |
91 } | |
92 | |
93 TEST(PathTest, EnclosePathIfExe) { | |
94 CString original_path; | |
95 CString new_path; | |
96 new_path = EnclosePathIfExe(original_path); | |
97 EXPECT_STREQ(original_path, new_path); | |
98 | |
99 original_path = _T(""); | |
100 new_path = EnclosePathIfExe(original_path); | |
101 EXPECT_STREQ(original_path, new_path); | |
102 | |
103 original_path = _T("a"); | |
104 new_path = EnclosePathIfExe(original_path); | |
105 EXPECT_STREQ(original_path, new_path); | |
106 | |
107 original_path = _T("a b"); | |
108 new_path = EnclosePathIfExe(original_path); | |
109 EXPECT_STREQ(original_path, new_path); | |
110 | |
111 original_path = " a b "; | |
112 new_path = EnclosePathIfExe(original_path); | |
113 EXPECT_STREQ(original_path, new_path); | |
114 | |
115 original_path = _T("\"a b\""); | |
116 new_path = EnclosePathIfExe(original_path); | |
117 EXPECT_STREQ(original_path, new_path); | |
118 | |
119 original_path = _T("c:\\Windows\\notepad.exe"); | |
120 new_path = EnclosePathIfExe(original_path); | |
121 EXPECT_STREQ(_T("\"c:\\Windows\\notepad.exe\""), new_path); | |
122 | |
123 original_path = _T("c:\\Program Files\\Google\\Update"); | |
124 new_path = EnclosePathIfExe(original_path); | |
125 EXPECT_STREQ(original_path, new_path); | |
126 | |
127 original_path = _T("c:\\Progra Files\\Google\\Update\\1.1.1.1\\goopdate.dll"); | |
128 new_path = EnclosePathIfExe(original_path); | |
129 EXPECT_STREQ(original_path, new_path); | |
130 | |
131 original_path = _T("c:\\Prog F\\Googl\\Update\\GoogleUpdate.exe"); | |
132 new_path = EnclosePathIfExe(original_path); | |
133 EXPECT_STREQ(_T("\"c:\\Prog F\\Googl\\Update\\GoogleUpdate.exe\""), new_path); | |
134 } | |
135 | |
136 TEST(PathTest, ConcatenatePath) { | |
137 CString expected_path("C:\\first\\part\\second\\part"); | |
138 | |
139 CString start("C:\\first\\part"); | |
140 CString start_slash("C:\\first\\part\\"); | |
141 CString end("second\\part"); | |
142 CString end_slash("\\second\\part"); | |
143 | |
144 EXPECT_STREQ(expected_path, ConcatenatePath(start, end)); | |
145 EXPECT_STREQ(expected_path, ConcatenatePath(start_slash, end)); | |
146 EXPECT_STREQ(expected_path, ConcatenatePath(start, end_slash)); | |
147 EXPECT_STREQ(expected_path, ConcatenatePath(start_slash, end_slash)); | |
148 } | |
149 | |
150 TEST(PathTest, ConcatenatePath_PathTooLong) { | |
151 CString two_hundred_char_root_path(_T("C:\\reallllllllllllllllllllllllllllllll
llllllllllllllllllllllllllllllllllllllllllllllllllllllllllllly\\looooooooooooooo
oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo
ong")); // NOLINT | |
152 CString two_hundred_char_path(_T("realllllllllllllllllllllllllllllllllllllllll
llllllllllllllllllllllllllllllllllllllllllllllllllllllly\\looooooooooooooooooooo
ooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"))
; // NOLINT | |
153 EXPECT_EQ(200, two_hundred_char_root_path.GetLength()); | |
154 CString fifty_eight_char_name( | |
155 _T("filenaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaame")); | |
156 EXPECT_EQ(58, fifty_eight_char_name.GetLength()); | |
157 CString fifty_nine_char_name( | |
158 _T("filenaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaame")); | |
159 EXPECT_EQ(59, fifty_nine_char_name.GetLength()); | |
160 CString sixty_char_name( | |
161 _T("filenaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaame")); | |
162 EXPECT_EQ(60, sixty_char_name.GetLength()); | |
163 | |
164 // Adding the '\' makes it 259 chars. | |
165 CString result = ConcatenatePath(two_hundred_char_root_path, | |
166 fifty_eight_char_name); | |
167 EXPECT_STREQ(_T("C:\\reallllllllllllllllllllllllllllllllllllllllllllllllllllll
llllllllllllllllllllllllllllllllllllllly\\looooooooooooooooooooooooooooooooooooo
ooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong\\filenaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaame"), // NOLINT | |
168 result); | |
169 | |
170 // Adding the '\' makes it 260 chars. | |
171 ExpectAsserts expect_asserts; | |
172 result = ConcatenatePath(two_hundred_char_root_path, | |
173 fifty_nine_char_name); | |
174 EXPECT_TRUE(result.IsEmpty()); | |
175 | |
176 // Adding the '\' makes it 261 chars. | |
177 result = ConcatenatePath(two_hundred_char_root_path, sixty_char_name); | |
178 EXPECT_TRUE(result.IsEmpty()); | |
179 | |
180 // Test for buffer overflow on long strings. | |
181 } | |
182 | |
183 TEST(PathTest, ConcatenatePath_EmptyString) { | |
184 EXPECT_STREQ(_T("bar.exe"), ConcatenatePath(_T(""), _T("bar.exe"))); | |
185 EXPECT_STREQ(_T("foo"), ConcatenatePath(_T("foo"), _T(""))); | |
186 // This is not what I would expect, but it is what the API does. | |
187 EXPECT_STREQ(_T("\\"), ConcatenatePath(_T(""), _T(""))); | |
188 } | |
189 | |
190 // TODO(omaha): The expected and actual values are reversed throughout. | |
191 | |
192 TEST(PathTest, ShortPathToLongPath) { | |
193 CString expected_path("C:\\Program Files"); | |
194 CString short_path("C:\\Progra~1"); | |
195 | |
196 CString long_path; | |
197 ASSERT_SUCCEEDED(ShortPathToLongPath(short_path, &long_path)); | |
198 ASSERT_STREQ(expected_path, long_path); | |
199 } | |
200 | |
201 TEST(PathTest, FindFilesTest) { | |
202 GUID guid = GUID_NULL; | |
203 ASSERT_SUCCEEDED(::CoCreateGuid(&guid)); | |
204 | |
205 TCHAR path[MAX_PATH] = {0}; | |
206 ASSERT_NE(::GetTempPath(MAX_PATH, path), 0); | |
207 | |
208 CString dir = ConcatenatePath(path, GuidToString(guid)); | |
209 EXPECT_FALSE(dir.IsEmpty()); | |
210 EXPECT_FALSE(File::Exists(dir)); | |
211 | |
212 // Test with non-existent dir. | |
213 std::vector<CString> files; | |
214 EXPECT_FAILED(FindFiles(dir, _T("*.txt"), &files)); | |
215 EXPECT_EQ(files.size(), 0); | |
216 | |
217 // Test with empty dir. | |
218 EXPECT_NE(::CreateDirectory(dir, NULL), 0); | |
219 files.clear(); | |
220 EXPECT_EQ(FindFiles(dir, _T("asdf.txt"), &files), 0x80070002); | |
221 EXPECT_EQ(files.size(), 0); | |
222 | |
223 CString filename1 = _T("one.txt"); | |
224 CString filepath1 = ConcatenatePath(dir, filename1); | |
225 CString filename2 = _T("two_en.txt"); | |
226 CString filepath2 = ConcatenatePath(dir, filename2); | |
227 | |
228 // Test with dir containing one file. | |
229 scoped_hfile handle1(::CreateFile(filepath1, GENERIC_READ, FILE_SHARE_READ, | |
230 NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, | |
231 NULL)); | |
232 EXPECT_TRUE(valid(handle1)); | |
233 files.clear(); | |
234 EXPECT_SUCCEEDED(FindFiles(dir, _T("*.txt"), &files)); | |
235 EXPECT_EQ(files.size(), 1); | |
236 EXPECT_STREQ(files[0], filename1); | |
237 | |
238 files.clear(); | |
239 EXPECT_SUCCEEDED(FindFiles(dir, _T("o*.txt"), &files)); | |
240 EXPECT_EQ(files.size(), 1); | |
241 EXPECT_STREQ(files[0], filename1); | |
242 | |
243 files.clear(); | |
244 EXPECT_SUCCEEDED(FindFiles(dir, filepath1, &files)); | |
245 EXPECT_EQ(files.size(), 1); | |
246 EXPECT_STREQ(files[0], filename1); | |
247 | |
248 files.clear(); | |
249 EXPECT_EQ(FindFiles(dir, _T("t*.txt"), &files), 0x80070002); | |
250 EXPECT_EQ(files.size(), 0); | |
251 | |
252 // Test with dir containing two files. | |
253 scoped_hfile handle2(::CreateFile(filepath2, GENERIC_READ, FILE_SHARE_READ, | |
254 NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, | |
255 NULL)); | |
256 EXPECT_TRUE(valid(handle2)); | |
257 files.clear(); | |
258 EXPECT_SUCCEEDED(FindFiles(dir, _T("*.txt"), &files)); | |
259 EXPECT_EQ(files.size(), 2); | |
260 EXPECT_STREQ(files[0], filename1); | |
261 EXPECT_STREQ(files[1], filename2); | |
262 | |
263 files.clear(); | |
264 EXPECT_SUCCEEDED(FindFiles(dir, _T("o*.txt"), &files)); | |
265 EXPECT_EQ(files.size(), 1); | |
266 EXPECT_STREQ(files[0], filename1); | |
267 | |
268 files.clear(); | |
269 EXPECT_SUCCEEDED(FindFiles(dir, _T("t*.txt"), &files)); | |
270 EXPECT_EQ(files.size(), 1); | |
271 EXPECT_STREQ(files[0], filename2); | |
272 | |
273 files.clear(); | |
274 EXPECT_EQ(FindFiles(dir, _T("asdf.txt"), &files), 0x80070002); | |
275 EXPECT_EQ(files.size(), 0); | |
276 | |
277 reset(handle1); | |
278 EXPECT_SUCCEEDED(File::Remove(filepath1)); | |
279 reset(handle2); | |
280 EXPECT_SUCCEEDED(File::Remove(filepath2)); | |
281 EXPECT_NE(::RemoveDirectory(dir), 0); | |
282 } | |
283 | |
284 namespace detail { | |
285 | |
286 struct Directory { | |
287 Directory() {} | |
288 explicit Directory(const CString& name) : dir_name(name) {} | |
289 | |
290 CString dir_name; | |
291 std::vector<Directory> sub_dirs; | |
292 std::vector<CString> files; | |
293 }; | |
294 | |
295 void ConvertDirectoryStructureToFiles(const Directory& directory, | |
296 const CString& dir_path, | |
297 std::vector<CString>* files) { | |
298 ASSERT_TRUE(files != NULL); | |
299 ASSERT_HRESULT_SUCCEEDED(CreateDir(dir_path, NULL)); | |
300 | |
301 for (size_t i = 0; i < directory.files.size(); ++i) { | |
302 const CString& file = ConcatenatePath(dir_path, directory.files[i]); | |
303 scoped_hfile handle(::CreateFile(file, GENERIC_READ, FILE_SHARE_READ, | |
304 NULL, CREATE_ALWAYS, | |
305 FILE_ATTRIBUTE_NORMAL, | |
306 NULL)); | |
307 EXPECT_TRUE(valid(handle)); | |
308 files->push_back(file); | |
309 } | |
310 | |
311 for (size_t i = 0; i < directory.sub_dirs.size(); ++i) { | |
312 ConvertDirectoryStructureToFiles( | |
313 directory.sub_dirs[i], | |
314 ConcatenatePath(dir_path, directory.sub_dirs[i].dir_name), | |
315 files); | |
316 } | |
317 } | |
318 | |
319 void CreateTestDirectoryStructure(Directory* root_dir) { | |
320 EXPECT_TRUE(root_dir != NULL); | |
321 GUID guid = GUID_NULL; | |
322 ASSERT_HRESULT_SUCCEEDED(::CoCreateGuid(&guid)); | |
323 | |
324 TCHAR path[MAX_PATH] = {0}; | |
325 ASSERT_NE(0, ::GetTempPath(MAX_PATH, path)); | |
326 | |
327 CString dir = ConcatenatePath(path, GuidToString(guid)); | |
328 EXPECT_FALSE(dir.IsEmpty()); | |
329 EXPECT_FALSE(File::Exists(dir)); | |
330 | |
331 root_dir->dir_name = dir; | |
332 root_dir->files.push_back(_T("test1.txt")); | |
333 root_dir->files.push_back(_T("test2.txt")); | |
334 | |
335 Directory sub_dir1_level1(_T("sub_dir1_level1")); | |
336 sub_dir1_level1.files.push_back(_T("sub_dir1_level1_test1.txt")); | |
337 Directory sub_dir1_level2(_T("sub_dir1_level2")); | |
338 sub_dir1_level2.files.push_back(_T("sub_dir1_level2_test1.txt")); | |
339 sub_dir1_level1.sub_dirs.push_back(sub_dir1_level2); | |
340 root_dir->sub_dirs.push_back(sub_dir1_level1); | |
341 | |
342 Directory sub_dir2_level1(_T("sub_dir2_level1")); | |
343 sub_dir2_level1.files.push_back(_T("sub_dir2_level1_test1.txt")); | |
344 root_dir->sub_dirs.push_back(sub_dir2_level1); | |
345 } | |
346 } // detail. | |
347 | |
348 TEST(PathTest, FindFileRecursiveTest) { | |
349 detail::Directory dir; | |
350 detail::CreateTestDirectoryStructure(&dir); | |
351 | |
352 std::vector<CString> expected_files; | |
353 detail::ConvertDirectoryStructureToFiles(dir, dir.dir_name, &expected_files); | |
354 | |
355 // Call the test method. | |
356 std::vector<CString> files; | |
357 ASSERT_HRESULT_SUCCEEDED(FindFileRecursive(dir.dir_name, | |
358 _T("*test*.txt"), | |
359 &files)); | |
360 | |
361 // Validate the results. | |
362 ASSERT_EQ(expected_files.size(), files.size()); | |
363 for (size_t i = 0; i < expected_files.size(); ++i) { | |
364 EXPECT_STREQ(expected_files[i], files[i]); | |
365 } | |
366 | |
367 // Cleanup. | |
368 ASSERT_HRESULT_SUCCEEDED(DeleteDirectory(dir.dir_name)); | |
369 } | |
370 | |
371 TEST(PathTest, FindFileRecursiveTest_Empty) { | |
372 GUID guid = GUID_NULL; | |
373 ASSERT_HRESULT_SUCCEEDED(::CoCreateGuid(&guid)); | |
374 | |
375 TCHAR path[MAX_PATH] = {0}; | |
376 ASSERT_NE(0, ::GetTempPath(MAX_PATH, path)); | |
377 | |
378 CString dir = ConcatenatePath(path, GuidToString(guid)); | |
379 EXPECT_FALSE(dir.IsEmpty()); | |
380 EXPECT_FALSE(File::Exists(dir)); | |
381 | |
382 ASSERT_HRESULT_SUCCEEDED(CreateDir(dir, NULL)); | |
383 | |
384 // Call the test method. | |
385 std::vector<CString> files; | |
386 ASSERT_HRESULT_SUCCEEDED(FindFileRecursive(dir, _T("*test*.txt"), | |
387 &files)); | |
388 | |
389 // Validate results. | |
390 ASSERT_EQ(0, files.size()); | |
391 | |
392 // Cleanup. | |
393 ASSERT_HRESULT_SUCCEEDED(DeleteDirectory(dir)); | |
394 } | |
395 | |
396 TEST(PathTest, FindFileRecursiveTest_DirNotCreated) { | |
397 GUID guid = GUID_NULL; | |
398 ASSERT_HRESULT_SUCCEEDED(::CoCreateGuid(&guid)); | |
399 | |
400 TCHAR path[MAX_PATH] = {0}; | |
401 ASSERT_NE(0, ::GetTempPath(MAX_PATH, path)); | |
402 | |
403 CString dir = ConcatenatePath(path, GuidToString(guid)); | |
404 EXPECT_FALSE(dir.IsEmpty()); | |
405 EXPECT_FALSE(File::Exists(dir)); | |
406 | |
407 // Call the test method. | |
408 std::vector<CString> files; | |
409 ASSERT_HRESULT_FAILED(FindFileRecursive(dir, _T("*test*.txt"), &files)); | |
410 } | |
411 | |
412 } // namespace omaha | |
413 | |
OLD | NEW |