Chromium Code Reviews| Index: chrome/browser/component_updater/test/component_patcher_unittest.cc |
| diff --git a/chrome/browser/component_updater/test/component_patcher_unittest.cc b/chrome/browser/component_updater/test/component_patcher_unittest.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..7259624be65a429f099aa1ccd4e69ec040a02777 |
| --- /dev/null |
| +++ b/chrome/browser/component_updater/test/component_patcher_unittest.cc |
| @@ -0,0 +1,239 @@ |
| +// Copyright (c) 2013 The Chromium Authors. All rights reserved. |
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +#include "base/compiler_specific.h" |
| +#include "base/file_util.h" |
| +#include "base/files/file_path.h" |
| +#include "base/path_service.h" |
| +#include "base/values.h" |
| +#include "chrome/browser/component_updater/component_patcher.h" |
| +#include "chrome/browser/component_updater/component_patcher_internal.h" |
| +#include "chrome/browser/component_updater/component_updater_service.h" |
| +#include "chrome/browser/component_updater/test/component_patcher_mock.h" |
| +#include "chrome/common/chrome_paths.h" |
| +#include "courgette/courgette.h" |
| +#include "courgette/third_party/bsdiff.h" |
| +#include "testing/gtest/include/gtest/gtest.h" |
| + |
| +const char binary_output_hash[] = |
| + "599aba6d15a7da390621ef1bacb66601ed6aed04dadc1f9b445dcfe31296142a"; |
| + |
| +const int kCourgetteErrorOffset = 300; |
| +const int kBsdiffErrorOffset = 600; |
|
robertshield
2013/06/17 17:47:00
These should be taken from util_constants.h when t
waffles
2013/06/17 23:51:07
As per off-line discussion, we're leaving it and a
|
| + |
| +base::FilePath test_file(const char* file); |
| + |
| +class DummyInstaller : public ComponentInstaller { |
|
erikwright (departed)
2013/06/17 17:24:28
Please consider de-duping this class into a dummy_
waffles
2013/06/17 22:17:49
Done, although it didn't quite have the same behav
|
| + public: |
| + explicit DummyInstaller(const base::FilePath& installed_dir); |
| + |
| + virtual void OnUpdateError(int error) OVERRIDE; |
| + |
| + virtual bool Install(const base::DictionaryValue& manifest, |
| + const base::FilePath& unpack_path) OVERRIDE; |
| + |
| + virtual bool GetInstalledFile(const std::string& file, |
| + base::FilePath* installed_file) OVERRIDE; |
| + |
| + private: |
| + base::FilePath installed_dir_; |
| + |
| + DISALLOW_COPY_AND_ASSIGN(DummyInstaller); |
| +}; |
| + |
| +class ComponentPatcherOperationTest : public testing::Test { |
| + public: |
| + ComponentPatcherOperationTest(); |
| + |
| + virtual ~ComponentPatcherOperationTest(); |
| + |
| + protected: |
| + base::FilePath input_dir_; |
| + base::FilePath installed_dir_; |
| + base::FilePath unpack_dir_; |
| + scoped_ptr<MockComponentPatcher> patcher_; |
| + scoped_ptr<DummyInstaller> installer_; |
| +}; |
| + |
| +base::FilePath test_file(const char* file) { |
| + base::FilePath path; |
| + PathService::Get(chrome::DIR_TEST_DATA, &path); |
| + return path.AppendASCII("components").AppendASCII(file); |
| +} |
| + |
| +ComponentPatcherOperationTest::ComponentPatcherOperationTest() { |
| + file_util::CreateNewTempDirectory(FILE_PATH_LITERAL("TEST_"), &unpack_dir_); |
| + file_util::CreateNewTempDirectory(FILE_PATH_LITERAL("TEST_"), &input_dir_); |
| + file_util::CreateNewTempDirectory(FILE_PATH_LITERAL("TEST_"), |
| + &installed_dir_); |
| + patcher_.reset(new MockComponentPatcher()); |
| + installer_.reset(new DummyInstaller(installed_dir_)); |
| +} |
| + |
| +ComponentPatcherOperationTest::~ComponentPatcherOperationTest() { |
| + file_util::Delete(unpack_dir_, true); |
| + file_util::Delete(input_dir_, true); |
| + file_util::Delete(installed_dir_, true); |
| +} |
| + |
| +DummyInstaller::DummyInstaller(const base::FilePath& installed_dir) |
| + : installed_dir_(installed_dir) { |
| +} |
| + |
| +void DummyInstaller::OnUpdateError(int error) {} |
| + |
| +bool DummyInstaller::Install(const base::DictionaryValue& manifest, |
| + const base::FilePath& unpack_path) { |
| + return false; |
| +} |
| + |
| +bool DummyInstaller::GetInstalledFile(const std::string& file, |
| + base::FilePath* installed_file) { |
| + *installed_file = installed_dir_.AppendASCII(file); |
| + return true; |
| +} |
| + |
| +ComponentUnpacker::Error MockComponentPatcher::Patch( |
| + PatchType patch_type, |
| + const base::FilePath& input_file, |
| + const base::FilePath& patch_file, |
| + const base::FilePath& output_file, |
| + int* error) { |
| + *error = 0; |
| + int exit_code; |
| + if (patch_type == kPatchTypeCourgette) { |
| + exit_code = courgette::ApplyEnsemblePatch(input_file.value().c_str(), |
| + patch_file.value().c_str(), |
| + output_file.value().c_str()); |
| + if (exit_code == courgette::C_OK) |
| + return ComponentUnpacker::kNone; |
| + *error = exit_code + kCourgetteErrorOffset; |
| + } else if (patch_type == kPatchTypeBsdiff) { |
| + exit_code = courgette::ApplyBinaryPatch(input_file, |
| + patch_file, |
| + output_file); |
| + if (exit_code == courgette::OK) |
| + return ComponentUnpacker::kNone; |
| + *error = exit_code + kBsdiffErrorOffset; |
| + } |
| + return ComponentUnpacker::kDeltaOperationFailure; |
| +} |
| + |
| +// Verify that a 'create' delta update operation works correctly. |
| +TEST_F(ComponentPatcherOperationTest, CheckCreateOperation) { |
| + EXPECT_TRUE(file_util::CopyFile( |
| + test_file("binary_output.bin"), |
| + input_dir_.Append(FILE_PATH_LITERAL("binary_output.bin")))); |
| + |
| + scoped_ptr<base::DictionaryValue> command_args(new base::DictionaryValue()); |
| + command_args->SetString("output", "output.bin"); |
| + command_args->SetString("sha256", binary_output_hash); |
| + command_args->SetString("op", "create"); |
| + command_args->SetString("patch", "binary_output.bin"); |
| + |
| + int error = 0; |
| + scoped_ptr<DeltaUpdateOp> op(new DeltaUpdateOpCreate()); |
| + ComponentUnpacker::Error result = op->Run(command_args.get(), |
| + input_dir_, |
| + unpack_dir_, |
| + patcher_.get(), |
| + NULL, |
| + &error); |
| + |
| + EXPECT_EQ(ComponentUnpacker::kNone, result); |
| + EXPECT_EQ(0, error); |
| + EXPECT_TRUE(file_util::ContentsEqual( |
| + unpack_dir_.Append(FILE_PATH_LITERAL("output.bin")), |
| + test_file("binary_output.bin"))); |
| +} |
| + |
| +// Verify that a 'copy' delta update operation works correctly. |
| +TEST_F(ComponentPatcherOperationTest, CheckCopyOperation) { |
| + EXPECT_TRUE(file_util::CopyFile( |
| + test_file("binary_output.bin"), |
| + installed_dir_.Append(FILE_PATH_LITERAL("binary_output.bin")))); |
| + |
| + scoped_ptr<base::DictionaryValue> command_args(new base::DictionaryValue()); |
| + command_args->SetString("output", "output.bin"); |
| + command_args->SetString("sha256", binary_output_hash); |
| + command_args->SetString("op", "copy"); |
| + command_args->SetString("input", "binary_output.bin"); |
| + |
| + int error = 0; |
| + scoped_ptr<DeltaUpdateOp> op(new DeltaUpdateOpCopy()); |
| + ComponentUnpacker::Error result = op->Run(command_args.get(), |
| + input_dir_, |
| + unpack_dir_, |
| + patcher_.get(), |
| + installer_.get(), |
| + &error); |
| + EXPECT_EQ(ComponentUnpacker::kNone, result); |
| + EXPECT_EQ(0, error); |
| + EXPECT_TRUE(file_util::ContentsEqual( |
| + unpack_dir_.Append(FILE_PATH_LITERAL("output.bin")), |
| + test_file("binary_output.bin"))); |
| +} |
| + |
| +// Verify that a 'courgette' delta update operation works correctly. |
| +TEST_F(ComponentPatcherOperationTest, CheckCourgetteOperation) { |
| + EXPECT_TRUE(file_util::CopyFile( |
| + test_file("binary_input.bin"), |
| + installed_dir_.Append(FILE_PATH_LITERAL("binary_input.bin")))); |
| + EXPECT_TRUE(file_util::CopyFile( |
| + test_file("binary_courgette_patch.bin"), |
| + input_dir_.Append(FILE_PATH_LITERAL("binary_courgette_patch.bin")))); |
| + |
| + scoped_ptr<base::DictionaryValue> command_args(new base::DictionaryValue()); |
| + command_args->SetString("output", "output.bin"); |
| + command_args->SetString("sha256", binary_output_hash); |
| + command_args->SetString("op", "courgette"); |
| + command_args->SetString("input", "binary_input.bin"); |
| + command_args->SetString("patch", "binary_courgette_patch.bin"); |
| + |
| + int error = 0; |
| + scoped_ptr<DeltaUpdateOp> op(new DeltaUpdateOpPatchCourgette()); |
| + ComponentUnpacker::Error result = op->Run(command_args.get(), |
| + input_dir_, |
| + unpack_dir_, |
| + patcher_.get(), |
| + installer_.get(), |
| + &error); |
| + EXPECT_EQ(ComponentUnpacker::kNone, result); |
| + EXPECT_EQ(0, error); |
| + EXPECT_TRUE(file_util::ContentsEqual( |
| + unpack_dir_.Append(FILE_PATH_LITERAL("output.bin")), |
| + test_file("binary_output.bin"))); |
| +} |
| + |
| +// Verify that a 'bsdiff' delta update operation works correctly. |
| +TEST_F(ComponentPatcherOperationTest, CheckBsdiffOperation) { |
| + EXPECT_TRUE(file_util::CopyFile( |
| + test_file("binary_input.bin"), |
| + installed_dir_.Append(FILE_PATH_LITERAL("binary_input.bin")))); |
| + EXPECT_TRUE(file_util::CopyFile( |
| + test_file("binary_bsdiff_patch.bin"), |
| + input_dir_.Append(FILE_PATH_LITERAL("binary_bsdiff_patch.bin")))); |
| + |
| + scoped_ptr<base::DictionaryValue> command_args(new base::DictionaryValue()); |
| + command_args->SetString("output", "output.bin"); |
| + command_args->SetString("sha256", binary_output_hash); |
| + command_args->SetString("op", "courgette"); |
| + command_args->SetString("input", "binary_input.bin"); |
| + command_args->SetString("patch", "binary_bsdiff_patch.bin"); |
| + |
| + int error = 0; |
| + scoped_ptr<DeltaUpdateOp> op(new DeltaUpdateOpPatchBsdiff()); |
| + ComponentUnpacker::Error result = op->Run(command_args.get(), |
| + input_dir_, |
| + unpack_dir_, |
| + patcher_.get(), |
| + installer_.get(), |
| + &error); |
| + EXPECT_EQ(ComponentUnpacker::kNone, result); |
| + EXPECT_EQ(0, error); |
| + EXPECT_TRUE(file_util::ContentsEqual( |
| + unpack_dir_.Append(FILE_PATH_LITERAL("output.bin")), |
| + test_file("binary_output.bin"))); |
| +} |
| + |