Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(4)

Side by Side Diff: third_party/zlib/google/zip_reader_unittest.cc

Issue 92873003: Adds asynchronous unzip functions to ZipReader (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Uses the correct target for directory test. Created 6 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « third_party/zlib/google/zip_reader.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "third_party/zlib/google/zip_reader.h" 5 #include "third_party/zlib/google/zip_reader.h"
6 6
7 #include <set> 7 #include <set>
8 #include <string> 8 #include <string>
9 9
10 #include "base/bind.h"
10 #include "base/file_util.h" 11 #include "base/file_util.h"
11 #include "base/files/scoped_temp_dir.h" 12 #include "base/files/scoped_temp_dir.h"
12 #include "base/logging.h" 13 #include "base/logging.h"
13 #include "base/md5.h" 14 #include "base/md5.h"
14 #include "base/path_service.h" 15 #include "base/path_service.h"
15 #include "base/platform_file.h" 16 #include "base/platform_file.h"
17 #include "base/run_loop.h"
16 #include "base/strings/utf_string_conversions.h" 18 #include "base/strings/utf_string_conversions.h"
17 #include "base/time/time.h" 19 #include "base/time/time.h"
18 #include "testing/gtest/include/gtest/gtest.h" 20 #include "testing/gtest/include/gtest/gtest.h"
19 #include "testing/platform_test.h" 21 #include "testing/platform_test.h"
20 #include "third_party/zlib/google/zip_internal.h" 22 #include "third_party/zlib/google/zip_internal.h"
21 23
22 namespace { 24 namespace {
23 25
26 const static std::string kQuuxExpectedMD5 = "d1ae4ac8a17a0e09317113ab284b57a6";
27
24 // Wrap PlatformFiles in a class so that we don't leak them in tests. 28 // Wrap PlatformFiles in a class so that we don't leak them in tests.
25 class PlatformFileWrapper { 29 class PlatformFileWrapper {
26 public: 30 public:
27 typedef enum { 31 typedef enum {
28 READ_ONLY, 32 READ_ONLY,
29 READ_WRITE 33 READ_WRITE
30 } AccessMode; 34 } AccessMode;
31 35
32 PlatformFileWrapper(const base::FilePath& file, AccessMode mode) 36 PlatformFileWrapper(const base::FilePath& file, AccessMode mode)
33 : file_(base::kInvalidPlatformFileValue) { 37 : file_(base::kInvalidPlatformFileValue) {
(...skipping 20 matching lines...) Expand all
54 ~PlatformFileWrapper() { 58 ~PlatformFileWrapper() {
55 base::ClosePlatformFile(file_); 59 base::ClosePlatformFile(file_);
56 } 60 }
57 61
58 base::PlatformFile platform_file() { return file_; } 62 base::PlatformFile platform_file() { return file_; }
59 63
60 private: 64 private:
61 base::PlatformFile file_; 65 base::PlatformFile file_;
62 }; 66 };
63 67
68 // A mock that provides methods that can be used as callbacks in asynchronous
69 // unzip functions. Tracks the number of calls and number of bytes reported.
70 // Assumes that progress callbacks will be executed in-order.
71 class MockUnzipListener : public base::SupportsWeakPtr<MockUnzipListener> {
72 public:
73 MockUnzipListener()
74 : success_calls_(0),
75 failure_calls_(0),
76 progress_calls_(0),
77 current_progress_(0) {
78 }
79
80 // Success callback for async functions.
81 void OnUnzipSuccess() {
82 success_calls_++;
83 }
84
85 // Failure callback for async functions.
86 void OnUnzipFailure() {
87 failure_calls_++;
88 }
89
90 // Progress callback for async functions.
91 void OnUnzipProgress(int64 progress) {
92 DCHECK(progress > current_progress_);
93 progress_calls_++;
94 current_progress_ = progress;
95 }
96
97 int success_calls() { return success_calls_; }
98 int failure_calls() { return failure_calls_; }
99 int progress_calls() { return progress_calls_; }
100 int current_progress() { return current_progress_; }
101
102 private:
103 int success_calls_;
104 int failure_calls_;
105 int progress_calls_;
106
107 int64 current_progress_;
108 };
109
64 } // namespace 110 } // namespace
65 111
66 namespace zip { 112 namespace zip {
67 113
68 // Make the test a PlatformTest to setup autorelease pools properly on Mac. 114 // Make the test a PlatformTest to setup autorelease pools properly on Mac.
69 class ZipReaderTest : public PlatformTest { 115 class ZipReaderTest : public PlatformTest {
70 protected: 116 protected:
71 virtual void SetUp() { 117 virtual void SetUp() {
72 PlatformTest::SetUp(); 118 PlatformTest::SetUp();
73 119
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
106 if (!success) 152 if (!success)
107 return false; 153 return false;
108 *path = path->AppendASCII("third_party"); 154 *path = path->AppendASCII("third_party");
109 *path = path->AppendASCII("zlib"); 155 *path = path->AppendASCII("zlib");
110 *path = path->AppendASCII("google"); 156 *path = path->AppendASCII("google");
111 *path = path->AppendASCII("test"); 157 *path = path->AppendASCII("test");
112 *path = path->AppendASCII("data"); 158 *path = path->AppendASCII("data");
113 return true; 159 return true;
114 } 160 }
115 161
162 bool CompareFileAndMD5(const base::FilePath& path,
163 const std::string expected_md5) {
164 // Read the output file and compute the MD5.
165 std::string output;
166 if (!base::ReadFileToString(path, &output))
167 return false;
168 const std::string md5 = base::MD5String(output);
169 return expected_md5 == md5;
170 }
171
116 // The path to temporary directory used to contain the test operations. 172 // The path to temporary directory used to contain the test operations.
117 base::FilePath test_dir_; 173 base::FilePath test_dir_;
118 // The path to the test data directory where test.zip etc. are located. 174 // The path to the test data directory where test.zip etc. are located.
119 base::FilePath test_data_dir_; 175 base::FilePath test_data_dir_;
120 // The path to test.zip in the test data directory. 176 // The path to test.zip in the test data directory.
121 base::FilePath test_zip_file_; 177 base::FilePath test_zip_file_;
122 // The path to evil.zip in the test data directory. 178 // The path to evil.zip in the test data directory.
123 base::FilePath evil_zip_file_; 179 base::FilePath evil_zip_file_;
124 // The path to evil_via_invalid_utf8.zip in the test data directory. 180 // The path to evil_via_invalid_utf8.zip in the test data directory.
125 base::FilePath evil_via_invalid_utf8_zip_file_; 181 base::FilePath evil_via_invalid_utf8_zip_file_;
126 // The path to evil_via_absolute_file_name.zip in the test data directory. 182 // The path to evil_via_absolute_file_name.zip in the test data directory.
127 base::FilePath evil_via_absolute_file_name_zip_file_; 183 base::FilePath evil_via_absolute_file_name_zip_file_;
128 std::set<base::FilePath> test_zip_contents_; 184 std::set<base::FilePath> test_zip_contents_;
129 185
130 base::ScopedTempDir temp_dir_; 186 base::ScopedTempDir temp_dir_;
187
188 base::MessageLoop message_loop_;
131 }; 189 };
132 190
133 TEST_F(ZipReaderTest, Open_ValidZipFile) { 191 TEST_F(ZipReaderTest, Open_ValidZipFile) {
134 ZipReader reader; 192 ZipReader reader;
135 ASSERT_TRUE(reader.Open(test_zip_file_)); 193 ASSERT_TRUE(reader.Open(test_zip_file_));
136 } 194 }
137 195
138 TEST_F(ZipReaderTest, Open_ValidZipPlatformFile) { 196 TEST_F(ZipReaderTest, Open_ValidZipPlatformFile) {
139 ZipReader reader; 197 ZipReader reader;
140 PlatformFileWrapper zip_fd_wrapper(test_zip_file_, 198 PlatformFileWrapper zip_fd_wrapper(test_zip_file_,
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
213 ASSERT_TRUE(reader.Open(test_zip_file_)); 271 ASSERT_TRUE(reader.Open(test_zip_file_));
214 base::FilePath target_path(FILE_PATH_LITERAL("foo/bar/quux.txt")); 272 base::FilePath target_path(FILE_PATH_LITERAL("foo/bar/quux.txt"));
215 ASSERT_TRUE(reader.LocateAndOpenEntry(target_path)); 273 ASSERT_TRUE(reader.LocateAndOpenEntry(target_path));
216 ASSERT_TRUE(reader.ExtractCurrentEntryToFilePath( 274 ASSERT_TRUE(reader.ExtractCurrentEntryToFilePath(
217 test_dir_.AppendASCII("quux.txt"))); 275 test_dir_.AppendASCII("quux.txt")));
218 // Read the output file ans compute the MD5. 276 // Read the output file ans compute the MD5.
219 std::string output; 277 std::string output;
220 ASSERT_TRUE(base::ReadFileToString(test_dir_.AppendASCII("quux.txt"), 278 ASSERT_TRUE(base::ReadFileToString(test_dir_.AppendASCII("quux.txt"),
221 &output)); 279 &output));
222 const std::string md5 = base::MD5String(output); 280 const std::string md5 = base::MD5String(output);
223 const std::string kExpectedMD5 = "d1ae4ac8a17a0e09317113ab284b57a6"; 281 EXPECT_EQ(kQuuxExpectedMD5, md5);
224 EXPECT_EQ(kExpectedMD5, md5);
225 // quux.txt should be larger than kZipBufSize so that we can exercise 282 // quux.txt should be larger than kZipBufSize so that we can exercise
226 // the loop in ExtractCurrentEntry(). 283 // the loop in ExtractCurrentEntry().
227 EXPECT_LT(static_cast<size_t>(internal::kZipBufSize), output.size()); 284 EXPECT_LT(static_cast<size_t>(internal::kZipBufSize), output.size());
228 } 285 }
229 286
230 TEST_F(ZipReaderTest, PlatformFileExtractCurrentEntryToFilePath_RegularFile) { 287 TEST_F(ZipReaderTest, PlatformFileExtractCurrentEntryToFilePath_RegularFile) {
231 ZipReader reader; 288 ZipReader reader;
232 PlatformFileWrapper zip_fd_wrapper(test_zip_file_, 289 PlatformFileWrapper zip_fd_wrapper(test_zip_file_,
233 PlatformFileWrapper::READ_ONLY); 290 PlatformFileWrapper::READ_ONLY);
234 ASSERT_TRUE(reader.OpenFromPlatformFile(zip_fd_wrapper.platform_file())); 291 ASSERT_TRUE(reader.OpenFromPlatformFile(zip_fd_wrapper.platform_file()));
235 base::FilePath target_path(FILE_PATH_LITERAL("foo/bar/quux.txt")); 292 base::FilePath target_path(FILE_PATH_LITERAL("foo/bar/quux.txt"));
236 ASSERT_TRUE(reader.LocateAndOpenEntry(target_path)); 293 ASSERT_TRUE(reader.LocateAndOpenEntry(target_path));
237 ASSERT_TRUE(reader.ExtractCurrentEntryToFilePath( 294 ASSERT_TRUE(reader.ExtractCurrentEntryToFilePath(
238 test_dir_.AppendASCII("quux.txt"))); 295 test_dir_.AppendASCII("quux.txt")));
239 // Read the output file and compute the MD5. 296 // Read the output file and compute the MD5.
240 std::string output; 297 std::string output;
241 ASSERT_TRUE(base::ReadFileToString(test_dir_.AppendASCII("quux.txt"), 298 ASSERT_TRUE(base::ReadFileToString(test_dir_.AppendASCII("quux.txt"),
242 &output)); 299 &output));
243 const std::string md5 = base::MD5String(output); 300 const std::string md5 = base::MD5String(output);
244 const std::string kExpectedMD5 = "d1ae4ac8a17a0e09317113ab284b57a6"; 301 EXPECT_EQ(kQuuxExpectedMD5, md5);
245 EXPECT_EQ(kExpectedMD5, md5);
246 // quux.txt should be larger than kZipBufSize so that we can exercise 302 // quux.txt should be larger than kZipBufSize so that we can exercise
247 // the loop in ExtractCurrentEntry(). 303 // the loop in ExtractCurrentEntry().
248 EXPECT_LT(static_cast<size_t>(internal::kZipBufSize), output.size()); 304 EXPECT_LT(static_cast<size_t>(internal::kZipBufSize), output.size());
249 } 305 }
250 306
251 #if defined(OS_POSIX) 307 #if defined(OS_POSIX)
252 TEST_F(ZipReaderTest, PlatformFileExtractCurrentEntryToFd_RegularFile) { 308 TEST_F(ZipReaderTest, PlatformFileExtractCurrentEntryToFd_RegularFile) {
253 ZipReader reader; 309 ZipReader reader;
254 PlatformFileWrapper zip_fd_wrapper(test_zip_file_, 310 PlatformFileWrapper zip_fd_wrapper(test_zip_file_,
255 PlatformFileWrapper::READ_ONLY); 311 PlatformFileWrapper::READ_ONLY);
256 ASSERT_TRUE(reader.OpenFromPlatformFile(zip_fd_wrapper.platform_file())); 312 ASSERT_TRUE(reader.OpenFromPlatformFile(zip_fd_wrapper.platform_file()));
257 base::FilePath target_path(FILE_PATH_LITERAL("foo/bar/quux.txt")); 313 base::FilePath target_path(FILE_PATH_LITERAL("foo/bar/quux.txt"));
258 base::FilePath out_path = test_dir_.AppendASCII("quux.txt"); 314 base::FilePath out_path = test_dir_.AppendASCII("quux.txt");
259 PlatformFileWrapper out_fd_w(out_path, PlatformFileWrapper::READ_WRITE); 315 PlatformFileWrapper out_fd_w(out_path, PlatformFileWrapper::READ_WRITE);
260 ASSERT_TRUE(reader.LocateAndOpenEntry(target_path)); 316 ASSERT_TRUE(reader.LocateAndOpenEntry(target_path));
261 ASSERT_TRUE(reader.ExtractCurrentEntryToFd(out_fd_w.platform_file())); 317 ASSERT_TRUE(reader.ExtractCurrentEntryToFd(out_fd_w.platform_file()));
262 // Read the output file and compute the MD5. 318 // Read the output file and compute the MD5.
263 std::string output; 319 std::string output;
264 ASSERT_TRUE(base::ReadFileToString(test_dir_.AppendASCII("quux.txt"), 320 ASSERT_TRUE(base::ReadFileToString(test_dir_.AppendASCII("quux.txt"),
265 &output)); 321 &output));
266 const std::string md5 = base::MD5String(output); 322 const std::string md5 = base::MD5String(output);
267 const std::string kExpectedMD5 = "d1ae4ac8a17a0e09317113ab284b57a6"; 323 EXPECT_EQ(kQuuxExpectedMD5, md5);
268 EXPECT_EQ(kExpectedMD5, md5);
269 // quux.txt should be larger than kZipBufSize so that we can exercise 324 // quux.txt should be larger than kZipBufSize so that we can exercise
270 // the loop in ExtractCurrentEntry(). 325 // the loop in ExtractCurrentEntry().
271 EXPECT_LT(static_cast<size_t>(internal::kZipBufSize), output.size()); 326 EXPECT_LT(static_cast<size_t>(internal::kZipBufSize), output.size());
272 } 327 }
273 #endif 328 #endif
274 329
275 TEST_F(ZipReaderTest, ExtractCurrentEntryToFilePath_Directory) { 330 TEST_F(ZipReaderTest, ExtractCurrentEntryToFilePath_Directory) {
276 ZipReader reader; 331 ZipReader reader;
277 ASSERT_TRUE(reader.Open(test_zip_file_)); 332 ASSERT_TRUE(reader.Open(test_zip_file_));
278 base::FilePath target_path(FILE_PATH_LITERAL("foo/")); 333 base::FilePath target_path(FILE_PATH_LITERAL("foo/"));
(...skipping 10 matching lines...) Expand all
289 base::FilePath target_path(FILE_PATH_LITERAL("foo/bar/quux.txt")); 344 base::FilePath target_path(FILE_PATH_LITERAL("foo/bar/quux.txt"));
290 ASSERT_TRUE(reader.LocateAndOpenEntry(target_path)); 345 ASSERT_TRUE(reader.LocateAndOpenEntry(target_path));
291 ASSERT_TRUE(reader.ExtractCurrentEntryIntoDirectory(test_dir_)); 346 ASSERT_TRUE(reader.ExtractCurrentEntryIntoDirectory(test_dir_));
292 // Sub directories should be created. 347 // Sub directories should be created.
293 ASSERT_TRUE(base::DirectoryExists(test_dir_.AppendASCII("foo/bar"))); 348 ASSERT_TRUE(base::DirectoryExists(test_dir_.AppendASCII("foo/bar")));
294 // And the file should be created. 349 // And the file should be created.
295 std::string output; 350 std::string output;
296 ASSERT_TRUE(base::ReadFileToString( 351 ASSERT_TRUE(base::ReadFileToString(
297 test_dir_.AppendASCII("foo/bar/quux.txt"), &output)); 352 test_dir_.AppendASCII("foo/bar/quux.txt"), &output));
298 const std::string md5 = base::MD5String(output); 353 const std::string md5 = base::MD5String(output);
299 const std::string kExpectedMD5 = "d1ae4ac8a17a0e09317113ab284b57a6"; 354 EXPECT_EQ(kQuuxExpectedMD5, md5);
300 EXPECT_EQ(kExpectedMD5, md5);
301 } 355 }
302 356
303 TEST_F(ZipReaderTest, current_entry_info_RegularFile) { 357 TEST_F(ZipReaderTest, current_entry_info_RegularFile) {
304 ZipReader reader; 358 ZipReader reader;
305 ASSERT_TRUE(reader.Open(test_zip_file_)); 359 ASSERT_TRUE(reader.Open(test_zip_file_));
306 base::FilePath target_path(FILE_PATH_LITERAL("foo/bar/quux.txt")); 360 base::FilePath target_path(FILE_PATH_LITERAL("foo/bar/quux.txt"));
307 ASSERT_TRUE(reader.LocateAndOpenEntry(target_path)); 361 ASSERT_TRUE(reader.LocateAndOpenEntry(target_path));
308 ZipReader::EntryInfo* current_entry_info = reader.current_entry_info(); 362 ZipReader::EntryInfo* current_entry_info = reader.current_entry_info();
309 363
310 EXPECT_EQ(target_path, current_entry_info->file_path()); 364 EXPECT_EQ(target_path, current_entry_info->file_path());
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
421 ASSERT_TRUE(reader.LocateAndOpenEntry(target_path)); 475 ASSERT_TRUE(reader.LocateAndOpenEntry(target_path));
422 ASSERT_TRUE(reader.ExtractCurrentEntryToFilePath( 476 ASSERT_TRUE(reader.ExtractCurrentEntryToFilePath(
423 test_dir_.AppendASCII("test.txt"))); 477 test_dir_.AppendASCII("test.txt")));
424 478
425 std::string actual; 479 std::string actual;
426 ASSERT_TRUE(base::ReadFileToString( 480 ASSERT_TRUE(base::ReadFileToString(
427 test_dir_.AppendASCII("test.txt"), &actual)); 481 test_dir_.AppendASCII("test.txt"), &actual));
428 EXPECT_EQ(std::string("This is a test.\n"), actual); 482 EXPECT_EQ(std::string("This is a test.\n"), actual);
429 } 483 }
430 484
485 // Verifies that the asynchronous extraction to a file works.
486 TEST_F(ZipReaderTest, ExtractToFileAsync_RegularFile) {
487 MockUnzipListener listener;
488
489 ZipReader reader;
490 base::FilePath target_file = test_dir_.AppendASCII("quux.txt");
491 base::FilePath target_path(FILE_PATH_LITERAL("foo/bar/quux.txt"));
492 ASSERT_TRUE(reader.Open(test_zip_file_));
493 ASSERT_TRUE(reader.LocateAndOpenEntry(target_path));
494 reader.ExtractCurrentEntryToFilePathAsync(
495 target_file,
496 base::Bind(&MockUnzipListener::OnUnzipSuccess,
497 listener.AsWeakPtr()),
498 base::Bind(&MockUnzipListener::OnUnzipFailure,
499 listener.AsWeakPtr()),
500 base::Bind(&MockUnzipListener::OnUnzipProgress,
501 listener.AsWeakPtr()));
502
503 EXPECT_EQ(0, listener.success_calls());
504 EXPECT_EQ(0, listener.failure_calls());
505 EXPECT_EQ(0, listener.progress_calls());
506
507 base::RunLoop().RunUntilIdle();
508
509 EXPECT_EQ(1, listener.success_calls());
510 EXPECT_EQ(0, listener.failure_calls());
511 EXPECT_LE(1, listener.progress_calls());
512
513 std::string output;
514 ASSERT_TRUE(base::ReadFileToString(test_dir_.AppendASCII("quux.txt"),
515 &output));
516 const std::string md5 = base::MD5String(output);
517 EXPECT_EQ(kQuuxExpectedMD5, md5);
518
519 int64 file_size = 0;
520 ASSERT_TRUE(base::GetFileSize(target_file, &file_size));
521
522 EXPECT_EQ(file_size, listener.current_progress());
523 }
524
525 // Verifies that the asynchronous extraction to a file works.
526 TEST_F(ZipReaderTest, ExtractToFileAsync_Directory) {
527 MockUnzipListener listener;
528
529 ZipReader reader;
530 base::FilePath target_file = test_dir_.AppendASCII("foo");
531 base::FilePath target_path(FILE_PATH_LITERAL("foo/"));
532 ASSERT_TRUE(reader.Open(test_zip_file_));
533 ASSERT_TRUE(reader.LocateAndOpenEntry(target_path));
534 reader.ExtractCurrentEntryToFilePathAsync(
535 target_file,
536 base::Bind(&MockUnzipListener::OnUnzipSuccess,
537 listener.AsWeakPtr()),
538 base::Bind(&MockUnzipListener::OnUnzipFailure,
539 listener.AsWeakPtr()),
540 base::Bind(&MockUnzipListener::OnUnzipProgress,
541 listener.AsWeakPtr()));
542
543 EXPECT_EQ(0, listener.success_calls());
544 EXPECT_EQ(0, listener.failure_calls());
545 EXPECT_EQ(0, listener.progress_calls());
546
547 base::RunLoop().RunUntilIdle();
548
549 EXPECT_EQ(1, listener.success_calls());
550 EXPECT_EQ(0, listener.failure_calls());
551 EXPECT_GE(0, listener.progress_calls());
552
553 ASSERT_TRUE(base::DirectoryExists(target_file));
554 }
555
431 } // namespace zip 556 } // namespace zip
OLDNEW
« no previous file with comments | « third_party/zlib/google/zip_reader.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698