Index: third_party/zlib/google/zip_reader_unittest.cc |
diff --git a/third_party/zlib/google/zip_reader_unittest.cc b/third_party/zlib/google/zip_reader_unittest.cc |
index 09efd9a7a669ec0707853111f8394ed9998a61d9..2033f9fa002c2db2de3510d39a81c5bd39ea27c5 100644 |
--- a/third_party/zlib/google/zip_reader_unittest.cc |
+++ b/third_party/zlib/google/zip_reader_unittest.cc |
@@ -7,12 +7,14 @@ |
#include <set> |
#include <string> |
+#include "base/bind.h" |
#include "base/file_util.h" |
#include "base/files/scoped_temp_dir.h" |
#include "base/logging.h" |
#include "base/md5.h" |
#include "base/path_service.h" |
#include "base/platform_file.h" |
+#include "base/run_loop.h" |
#include "base/strings/utf_string_conversions.h" |
#include "base/time/time.h" |
#include "testing/gtest/include/gtest/gtest.h" |
@@ -21,6 +23,8 @@ |
namespace { |
+const static std::string kQuuxExpectedMD5 = "d1ae4ac8a17a0e09317113ab284b57a6"; |
+ |
// Wrap PlatformFiles in a class so that we don't leak them in tests. |
class PlatformFileWrapper { |
public: |
@@ -61,6 +65,48 @@ class PlatformFileWrapper { |
base::PlatformFile file_; |
}; |
+// A mock that provides methods that can be used as callbacks in asynchronous |
+// unzip functions. Tracks the number of calls and number of bytes reported. |
+// Assumes that progress callbacks will be executed in-order. |
+class MockUnzipListener : public base::SupportsWeakPtr<MockUnzipListener> { |
+ public: |
+ MockUnzipListener() |
+ : success_calls_(0), |
+ failure_calls_(0), |
+ progress_calls_(0), |
+ current_progress_(0) { |
+ } |
+ |
+ // Success callback for async functions. |
+ void OnUnzipSuccess() { |
+ success_calls_++; |
+ } |
+ |
+ // Failure callback for async functions. |
+ void OnUnzipFailure() { |
+ failure_calls_++; |
+ } |
+ |
+ // Progress callback for async functions. |
+ void OnUnzipProgress(int64 progress) { |
+ DCHECK(progress > current_progress_); |
+ progress_calls_++; |
+ current_progress_ = progress; |
+ } |
+ |
+ int success_calls() { return success_calls_; } |
+ int failure_calls() { return failure_calls_; } |
+ int progress_calls() { return progress_calls_; } |
+ int current_progress() { return current_progress_; } |
+ |
+ private: |
+ int success_calls_; |
+ int failure_calls_; |
+ int progress_calls_; |
+ |
+ int64 current_progress_; |
+}; |
+ |
} // namespace |
namespace zip { |
@@ -113,6 +159,16 @@ class ZipReaderTest : public PlatformTest { |
return true; |
} |
+ bool CompareFileAndMD5(const base::FilePath& path, |
+ const std::string expected_md5) { |
+ // Read the output file and compute the MD5. |
+ std::string output; |
+ if (!base::ReadFileToString(path, &output)) |
+ return false; |
+ const std::string md5 = base::MD5String(output); |
+ return expected_md5 == md5; |
+ } |
+ |
// The path to temporary directory used to contain the test operations. |
base::FilePath test_dir_; |
// The path to the test data directory where test.zip etc. are located. |
@@ -128,6 +184,8 @@ class ZipReaderTest : public PlatformTest { |
std::set<base::FilePath> test_zip_contents_; |
base::ScopedTempDir temp_dir_; |
+ |
+ base::MessageLoop message_loop_; |
}; |
TEST_F(ZipReaderTest, Open_ValidZipFile) { |
@@ -220,8 +278,7 @@ TEST_F(ZipReaderTest, ExtractCurrentEntryToFilePath_RegularFile) { |
ASSERT_TRUE(base::ReadFileToString(test_dir_.AppendASCII("quux.txt"), |
&output)); |
const std::string md5 = base::MD5String(output); |
- const std::string kExpectedMD5 = "d1ae4ac8a17a0e09317113ab284b57a6"; |
- EXPECT_EQ(kExpectedMD5, md5); |
+ EXPECT_EQ(kQuuxExpectedMD5, md5); |
// quux.txt should be larger than kZipBufSize so that we can exercise |
// the loop in ExtractCurrentEntry(). |
EXPECT_LT(static_cast<size_t>(internal::kZipBufSize), output.size()); |
@@ -241,8 +298,7 @@ TEST_F(ZipReaderTest, PlatformFileExtractCurrentEntryToFilePath_RegularFile) { |
ASSERT_TRUE(base::ReadFileToString(test_dir_.AppendASCII("quux.txt"), |
&output)); |
const std::string md5 = base::MD5String(output); |
- const std::string kExpectedMD5 = "d1ae4ac8a17a0e09317113ab284b57a6"; |
- EXPECT_EQ(kExpectedMD5, md5); |
+ EXPECT_EQ(kQuuxExpectedMD5, md5); |
// quux.txt should be larger than kZipBufSize so that we can exercise |
// the loop in ExtractCurrentEntry(). |
EXPECT_LT(static_cast<size_t>(internal::kZipBufSize), output.size()); |
@@ -264,8 +320,7 @@ TEST_F(ZipReaderTest, PlatformFileExtractCurrentEntryToFd_RegularFile) { |
ASSERT_TRUE(base::ReadFileToString(test_dir_.AppendASCII("quux.txt"), |
&output)); |
const std::string md5 = base::MD5String(output); |
- const std::string kExpectedMD5 = "d1ae4ac8a17a0e09317113ab284b57a6"; |
- EXPECT_EQ(kExpectedMD5, md5); |
+ EXPECT_EQ(kQuuxExpectedMD5, md5); |
// quux.txt should be larger than kZipBufSize so that we can exercise |
// the loop in ExtractCurrentEntry(). |
EXPECT_LT(static_cast<size_t>(internal::kZipBufSize), output.size()); |
@@ -296,8 +351,7 @@ TEST_F(ZipReaderTest, ExtractCurrentEntryIntoDirectory_RegularFile) { |
ASSERT_TRUE(base::ReadFileToString( |
test_dir_.AppendASCII("foo/bar/quux.txt"), &output)); |
const std::string md5 = base::MD5String(output); |
- const std::string kExpectedMD5 = "d1ae4ac8a17a0e09317113ab284b57a6"; |
- EXPECT_EQ(kExpectedMD5, md5); |
+ EXPECT_EQ(kQuuxExpectedMD5, md5); |
} |
TEST_F(ZipReaderTest, current_entry_info_RegularFile) { |
@@ -428,4 +482,75 @@ TEST_F(ZipReaderTest, OpenFromString) { |
EXPECT_EQ(std::string("This is a test.\n"), actual); |
} |
+// Verifies that the asynchronous extraction to a file works. |
+TEST_F(ZipReaderTest, ExtractToFileAsync_RegularFile) { |
+ MockUnzipListener listener; |
+ |
+ ZipReader reader; |
+ base::FilePath target_file = test_dir_.AppendASCII("quux.txt"); |
+ base::FilePath target_path(FILE_PATH_LITERAL("foo/bar/quux.txt")); |
+ ASSERT_TRUE(reader.Open(test_zip_file_)); |
+ ASSERT_TRUE(reader.LocateAndOpenEntry(target_path)); |
+ reader.ExtractCurrentEntryToFilePathAsync( |
+ target_file, |
+ base::Bind(&MockUnzipListener::OnUnzipSuccess, |
+ listener.AsWeakPtr()), |
+ base::Bind(&MockUnzipListener::OnUnzipFailure, |
+ listener.AsWeakPtr()), |
+ base::Bind(&MockUnzipListener::OnUnzipProgress, |
+ listener.AsWeakPtr())); |
+ |
+ EXPECT_EQ(0, listener.success_calls()); |
+ EXPECT_EQ(0, listener.failure_calls()); |
+ EXPECT_EQ(0, listener.progress_calls()); |
+ |
+ base::RunLoop().RunUntilIdle(); |
+ |
+ EXPECT_EQ(1, listener.success_calls()); |
+ EXPECT_EQ(0, listener.failure_calls()); |
+ EXPECT_LE(1, listener.progress_calls()); |
+ |
+ std::string output; |
+ ASSERT_TRUE(base::ReadFileToString(test_dir_.AppendASCII("quux.txt"), |
+ &output)); |
+ const std::string md5 = base::MD5String(output); |
+ EXPECT_EQ(kQuuxExpectedMD5, md5); |
+ |
+ int64 file_size = 0; |
+ ASSERT_TRUE(base::GetFileSize(target_file, &file_size)); |
+ |
+ EXPECT_EQ(file_size, listener.current_progress()); |
+} |
+ |
+// Verifies that the asynchronous extraction to a file works. |
+TEST_F(ZipReaderTest, ExtractToFileAsync_Directory) { |
+ MockUnzipListener listener; |
+ |
+ ZipReader reader; |
+ base::FilePath target_file = test_dir_.AppendASCII("foo"); |
+ base::FilePath target_path(FILE_PATH_LITERAL("foo/")); |
+ ASSERT_TRUE(reader.Open(test_zip_file_)); |
+ ASSERT_TRUE(reader.LocateAndOpenEntry(target_path)); |
+ reader.ExtractCurrentEntryToFilePathAsync( |
+ target_file, |
+ base::Bind(&MockUnzipListener::OnUnzipSuccess, |
+ listener.AsWeakPtr()), |
+ base::Bind(&MockUnzipListener::OnUnzipFailure, |
+ listener.AsWeakPtr()), |
+ base::Bind(&MockUnzipListener::OnUnzipProgress, |
+ listener.AsWeakPtr())); |
+ |
+ EXPECT_EQ(0, listener.success_calls()); |
+ EXPECT_EQ(0, listener.failure_calls()); |
+ EXPECT_EQ(0, listener.progress_calls()); |
+ |
+ base::RunLoop().RunUntilIdle(); |
+ |
+ EXPECT_EQ(1, listener.success_calls()); |
+ EXPECT_EQ(0, listener.failure_calls()); |
+ EXPECT_GE(0, listener.progress_calls()); |
+ |
+ ASSERT_TRUE(base::DirectoryExists(target_file)); |
+} |
+ |
} // namespace zip |