Commit a5b1abd6 authored by haven@chromium.org's avatar haven@chromium.org

Resubmit of imageWriterPrivate.destroyPartitions.

Previous CL: https://codereview.chromium.org/109793006/

BUG=328246

Review URL: https://codereview.chromium.org/115973007

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@243191 0039d316-1c4b-4281-b951-d872f2087c98
parent 896c881a
// Copyright 2014 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/file_util.h"
#include "chrome/browser/extensions/api/image_writer_private/destroy_partitions_operation.h"
#include "chrome/browser/extensions/api/image_writer_private/error_messages.h"
namespace extensions {
namespace image_writer {
// Number of bytes for the maximum partition table size. By wiping this many
// bytes we can essentially guarantee the header and associated information will
// be wiped. See http://crbug.com/328246 for more information.
const int kPartitionTableSize = 1 * 1024;
DestroyPartitionsOperation::DestroyPartitionsOperation(
base::WeakPtr<OperationManager> manager,
const ExtensionId& extension_id,
const std::string& storage_unit_id)
: Operation(manager, extension_id, storage_unit_id) {
verify_write_ = false;
}
DestroyPartitionsOperation::~DestroyPartitionsOperation() {}
void DestroyPartitionsOperation::Start() {
if (!temp_dir_.CreateUniqueTempDir()) {
Error(error::kTempDirError);
return;
}
if (!base::CreateTemporaryFileInDir(temp_dir_.path(), &image_path_)) {
Error(error::kTempFileError);
return;
}
scoped_ptr<char[]> buffer(new char[kPartitionTableSize]);
memset(buffer.get(), 0, kPartitionTableSize);
if (file_util::WriteFile(image_path_, buffer.get(), kPartitionTableSize) !=
kPartitionTableSize) {
Error(error::kTempFileError);
return;
}
WriteStart();
}
} // namespace image_writer
} // namespace extensions
// Copyright 2014 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.
#ifndef CHROME_BROWSER_EXTENSIONS_API_IMAGE_WRITER_PRIVATE_DESTROY_PARTITIONS_OPERATION_H_
#define CHROME_BROWSER_EXTENSIONS_API_IMAGE_WRITER_PRIVATE_DESTROY_PARTITIONS_OPERATION_H_
#include "base/files/scoped_temp_dir.h"
#include "chrome/browser/extensions/api/image_writer_private/operation.h"
namespace extensions {
namespace image_writer {
extern const int kPartitionTableSize;
// Encapsulates an operation for destroying partitions. This is achieved by
// creating a dummy blank image which is then burned to the disk.
class DestroyPartitionsOperation : public Operation {
public:
DestroyPartitionsOperation(base::WeakPtr<OperationManager> manager,
const ExtensionId& extension_id,
const std::string& storage_unit_id);
virtual void Start() OVERRIDE;
private:
virtual ~DestroyPartitionsOperation();
base::ScopedTempDir temp_dir_;
};
} // namespace image_writer
} // namespace extensions
#endif // CHROME_BROWSER_EXTENSIONS_API_IMAGE_WRITER_PRIVATE_DESTROY_PARTITIONS_OPERATION_H_
// Copyright 2014 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/run_loop.h"
#include "chrome/browser/extensions/api/image_writer_private/destroy_partitions_operation.h"
#include "chrome/browser/extensions/api/image_writer_private/error_messages.h"
#include "chrome/browser/extensions/api/image_writer_private/test_utils.h"
namespace extensions {
namespace image_writer {
using testing::_;
using testing::AnyNumber;
namespace {
class ImageWriterDestroyPartitionsOperationTest
: public ImageWriterUnitTestBase {
};
// Tests that the DestroyPartitionsOperation can successfully zero the first
// kPartitionTableSize bytes of an image.
TEST_F(ImageWriterDestroyPartitionsOperationTest, DestroyPartitions) {
MockOperationManager manager;
base::RunLoop loop;
scoped_refptr<DestroyPartitionsOperation> operation(
new DestroyPartitionsOperation(manager.AsWeakPtr(),
kDummyExtensionId,
test_device_path_.AsUTF8Unsafe()));
#if defined(OS_LINUX) || defined(OS_CHROMEOS)
EXPECT_CALL(manager, OnProgress(kDummyExtensionId, _, _)).Times(0);
EXPECT_CALL(manager, OnProgress(kDummyExtensionId,
image_writer_api::STAGE_WRITE,
_)).Times(AnyNumber());
EXPECT_CALL(manager, OnComplete(kDummyExtensionId)).Times(1);
EXPECT_CALL(manager, OnError(kDummyExtensionId, _, _, _)).Times(0);
#else
EXPECT_CALL(manager, OnProgress(kDummyExtensionId, _, _)).Times(0);
EXPECT_CALL(manager, OnComplete(kDummyExtensionId)).Times(0);
EXPECT_CALL(manager, OnError(kDummyExtensionId,
_,
_,
error::kUnsupportedOperation)).Times(1);
#endif
operation->Start();
loop.RunUntilIdle();
#if defined(OS_LINUX) && !defined(OS_CHROMEOS)
scoped_ptr<char[]> image_data(new char[kPartitionTableSize]);
scoped_ptr<char[]> zeroes(new char[kPartitionTableSize]);
memset(zeroes.get(), 0, kPartitionTableSize);
ASSERT_EQ(kPartitionTableSize, base::ReadFile(test_device_path_,
image_data.get(),
kPartitionTableSize));
EXPECT_EQ(0, memcmp(image_data.get(), zeroes.get(), kPartitionTableSize));
#endif
}
} // namespace
} // namespace image_writer
} // namespace extensions
...@@ -151,10 +151,25 @@ bool ImageWriterPrivateDestroyPartitionsFunction::RunImpl() { ...@@ -151,10 +151,25 @@ bool ImageWriterPrivateDestroyPartitionsFunction::RunImpl() {
image_writer_api::DestroyPartitions::Params::Create(*args_)); image_writer_api::DestroyPartitions::Params::Create(*args_));
EXTENSION_FUNCTION_VALIDATE(params.get()); EXTENSION_FUNCTION_VALIDATE(params.get());
SendResponse(true); image_writer::OperationManager::Get(GetProfile())->DestroyPartitions(
extension_id(),
params->storage_unit_id,
base::Bind(
&ImageWriterPrivateDestroyPartitionsFunction::OnDestroyComplete,
this));
return true; return true;
} }
void ImageWriterPrivateDestroyPartitionsFunction::OnDestroyComplete(
bool success,
const std::string& error) {
if (!success) {
error_ = error;
}
SendResponse(success);
}
ImageWriterPrivateListRemovableStorageDevicesFunction:: ImageWriterPrivateListRemovableStorageDevicesFunction::
ImageWriterPrivateListRemovableStorageDevicesFunction() { ImageWriterPrivateListRemovableStorageDevicesFunction() {
} }
......
...@@ -59,6 +59,7 @@ class ImageWriterPrivateDestroyPartitionsFunction ...@@ -59,6 +59,7 @@ class ImageWriterPrivateDestroyPartitionsFunction
private: private:
virtual ~ImageWriterPrivateDestroyPartitionsFunction(); virtual ~ImageWriterPrivateDestroyPartitionsFunction();
virtual bool RunImpl() OVERRIDE; virtual bool RunImpl() OVERRIDE;
void OnDestroyComplete(bool success, const std::string& error);
}; };
class ImageWriterPrivateListRemovableStorageDevicesFunction class ImageWriterPrivateListRemovableStorageDevicesFunction
......
...@@ -32,6 +32,7 @@ Operation::Operation(base::WeakPtr<OperationManager> manager, ...@@ -32,6 +32,7 @@ Operation::Operation(base::WeakPtr<OperationManager> manager,
: manager_(manager), : manager_(manager),
extension_id_(extension_id), extension_id_(extension_id),
storage_unit_id_(storage_unit_id), storage_unit_id_(storage_unit_id),
verify_write_(true),
stage_(image_writer_api::STAGE_UNKNOWN), stage_(image_writer_api::STAGE_UNKNOWN),
progress_(0) { progress_(0) {
} }
......
...@@ -110,6 +110,9 @@ class Operation ...@@ -110,6 +110,9 @@ class Operation
base::FilePath image_path_; base::FilePath image_path_;
const std::string storage_unit_id_; const std::string storage_unit_id_;
// Whether or not to run the final verification step.
bool verify_write_;
private: private:
friend class base::RefCountedThreadSafe<Operation>; friend class base::RefCountedThreadSafe<Operation>;
......
...@@ -138,11 +138,15 @@ void Operation::WriteComplete() { ...@@ -138,11 +138,15 @@ void Operation::WriteComplete() {
DVLOG(2) << "Completed write of " << image_path_.value(); DVLOG(2) << "Completed write of " << image_path_.value();
SetProgress(kProgressComplete); SetProgress(kProgressComplete);
BrowserThread::PostTask( if (verify_write_) {
BrowserThread::FILE, BrowserThread::PostTask(BrowserThread::FILE,
FROM_HERE, FROM_HERE,
base::Bind(&Operation::VerifyWriteStart, base::Bind(&Operation::VerifyWriteStart, this));
this)); } else {
BrowserThread::PostTask(BrowserThread::FILE,
FROM_HERE,
base::Bind(&Operation::Finish, this));
}
} }
void Operation::VerifyWriteStart() { void Operation::VerifyWriteStart() {
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
#include "base/lazy_instance.h" #include "base/lazy_instance.h"
#include "chrome/browser/browser_process.h" #include "chrome/browser/browser_process.h"
#include "chrome/browser/chrome_notification_types.h" #include "chrome/browser/chrome_notification_types.h"
#include "chrome/browser/extensions/api/image_writer_private/destroy_partitions_operation.h"
#include "chrome/browser/extensions/api/image_writer_private/error_messages.h" #include "chrome/browser/extensions/api/image_writer_private/error_messages.h"
#include "chrome/browser/extensions/api/image_writer_private/operation.h" #include "chrome/browser/extensions/api/image_writer_private/operation.h"
#include "chrome/browser/extensions/api/image_writer_private/operation_manager.h" #include "chrome/browser/extensions/api/image_writer_private/operation_manager.h"
...@@ -63,7 +64,6 @@ void OperationManager::StartWriteFromUrl( ...@@ -63,7 +64,6 @@ void OperationManager::StartWriteFromUrl(
bool saveImageAsDownload, bool saveImageAsDownload,
const std::string& storage_unit_id, const std::string& storage_unit_id,
const Operation::StartWriteCallback& callback) { const Operation::StartWriteCallback& callback) {
OperationMap::iterator existing_operation = operations_.find(extension_id); OperationMap::iterator existing_operation = operations_.find(extension_id);
if (existing_operation != operations_.end()) { if (existing_operation != operations_.end()) {
...@@ -78,14 +78,10 @@ void OperationManager::StartWriteFromUrl( ...@@ -78,14 +78,10 @@ void OperationManager::StartWriteFromUrl(
hash, hash,
saveImageAsDownload, saveImageAsDownload,
storage_unit_id)); storage_unit_id));
operations_[extension_id] = operation; operations_[extension_id] = operation;
BrowserThread::PostTask(BrowserThread::FILE, BrowserThread::PostTask(BrowserThread::FILE,
FROM_HERE, FROM_HERE,
base::Bind(&Operation::Start, base::Bind(&Operation::Start, operation));
operation.get()));
callback.Run(true, ""); callback.Run(true, "");
} }
...@@ -105,14 +101,10 @@ void OperationManager::StartWriteFromFile( ...@@ -105,14 +101,10 @@ void OperationManager::StartWriteFromFile(
extension_id, extension_id,
path, path,
storage_unit_id)); storage_unit_id));
operations_[extension_id] = operation; operations_[extension_id] = operation;
BrowserThread::PostTask(BrowserThread::FILE, BrowserThread::PostTask(BrowserThread::FILE,
FROM_HERE, FROM_HERE,
base::Bind(&Operation::Start, base::Bind(&Operation::Start, operation));
operation.get()));
callback.Run(true, ""); callback.Run(true, "");
} }
...@@ -132,6 +124,27 @@ void OperationManager::CancelWrite( ...@@ -132,6 +124,27 @@ void OperationManager::CancelWrite(
} }
} }
void OperationManager::DestroyPartitions(
const ExtensionId& extension_id,
const std::string& storage_unit_id,
const Operation::StartWriteCallback& callback) {
OperationMap::iterator existing_operation = operations_.find(extension_id);
if (existing_operation != operations_.end()) {
return callback.Run(false, error::kOperationAlreadyInProgress);
}
scoped_refptr<Operation> operation(
new DestroyPartitionsOperation(weak_factory_.GetWeakPtr(),
extension_id,
storage_unit_id));
operations_[extension_id] = operation;
BrowserThread::PostTask(BrowserThread::FILE,
FROM_HERE,
base::Bind(&Operation::Start, operation));
callback.Run(true, "");
}
void OperationManager::OnProgress(const ExtensionId& extension_id, void OperationManager::OnProgress(const ExtensionId& extension_id,
image_writer_api::Stage stage, image_writer_api::Stage stage,
int progress) { int progress) {
......
...@@ -61,6 +61,11 @@ class OperationManager ...@@ -61,6 +61,11 @@ class OperationManager
void CancelWrite(const ExtensionId& extension_id, void CancelWrite(const ExtensionId& extension_id,
const Operation::CancelWriteCallback& callback); const Operation::CancelWriteCallback& callback);
// Starts a write that removes the partition table.
void DestroyPartitions(const ExtensionId& extension_id,
const std::string& storage_unit_id,
const Operation::StartWriteCallback& callback);
// Callback for progress events. // Callback for progress events.
virtual void OnProgress(const ExtensionId& extension_id, virtual void OnProgress(const ExtensionId& extension_id,
image_writer_api::Stage stage, image_writer_api::Stage stage,
......
...@@ -5,8 +5,8 @@ ...@@ -5,8 +5,8 @@
#include "base/command_line.h" #include "base/command_line.h"
#include "chrome/browser/chromeos/login/user_manager.h" #include "chrome/browser/chromeos/login/user_manager.h"
#include "chrome/browser/extensions/api/image_writer_private/error_messages.h" #include "chrome/browser/extensions/api/image_writer_private/error_messages.h"
#include "chrome/browser/extensions/api/image_writer_private/operation_manager.h"
#include "chrome/browser/extensions/api/image_writer_private/test_utils.h" #include "chrome/browser/extensions/api/image_writer_private/test_utils.h"
#include "chrome/browser/extensions/api/image_writer_private/write_from_file_operation.h"
#include "chrome/browser/extensions/extension_service.h" #include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/extensions/test_extension_system.h" #include "chrome/browser/extensions/test_extension_system.h"
#include "chrome/test/base/testing_profile.h" #include "chrome/test/base/testing_profile.h"
...@@ -25,6 +25,8 @@ using testing::Lt; ...@@ -25,6 +25,8 @@ using testing::Lt;
using testing::AnyNumber; using testing::AnyNumber;
using testing::AtLeast; using testing::AtLeast;
namespace {
class ImageWriterOperationManagerTest class ImageWriterOperationManagerTest
: public ImageWriterUnitTestBase { : public ImageWriterUnitTestBase {
public: public:
...@@ -68,8 +70,8 @@ TEST_F(ImageWriterOperationManagerTest, WriteFromFile) { ...@@ -68,8 +70,8 @@ TEST_F(ImageWriterOperationManagerTest, WriteFromFile) {
manager.StartWriteFromFile( manager.StartWriteFromFile(
kDummyExtensionId, kDummyExtensionId,
test_image_, test_image_path_,
test_device_.AsUTF8Unsafe(), test_device_path_.AsUTF8Unsafe(),
base::Bind(&ImageWriterOperationManagerTest::StartCallback, base::Bind(&ImageWriterOperationManagerTest::StartCallback,
base::Unretained(this))); base::Unretained(this)));
...@@ -78,5 +80,20 @@ TEST_F(ImageWriterOperationManagerTest, WriteFromFile) { ...@@ -78,5 +80,20 @@ TEST_F(ImageWriterOperationManagerTest, WriteFromFile) {
EXPECT_EQ("", start_error_); EXPECT_EQ("", start_error_);
} }
} // namespace image_writer TEST_F(ImageWriterOperationManagerTest, DestroyPartitions) {
} // namespace extensions OperationManager manager(&test_profile_);
manager.DestroyPartitions(
kDummyExtensionId,
test_device_path_.AsUTF8Unsafe(),
base::Bind(&ImageWriterOperationManagerTest::StartCallback,
base::Unretained(this)));
EXPECT_TRUE(started_);
EXPECT_TRUE(start_success_);
EXPECT_EQ("", start_error_);
}
} // namespace
} // namespace image_writer
} // namespace extensions
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
namespace extensions { namespace extensions {
namespace image_writer { namespace image_writer {
namespace {
class ImageWriterOperationTest : public ImageWriterUnitTestBase { class ImageWriterOperationTest : public ImageWriterUnitTestBase {
}; };
...@@ -25,13 +26,15 @@ class DummyOperation : public Operation { ...@@ -25,13 +26,15 @@ class DummyOperation : public Operation {
TEST_F(ImageWriterOperationTest, Create) { TEST_F(ImageWriterOperationTest, Create) {
MockOperationManager manager; MockOperationManager manager;
scoped_refptr<Operation> op(new DummyOperation(manager.AsWeakPtr(), scoped_refptr<Operation> op(
kDummyExtensionId, new DummyOperation(manager.AsWeakPtr(),
test_device_.AsUTF8Unsafe())); kDummyExtensionId,
test_device_path_.AsUTF8Unsafe()));
EXPECT_EQ(0, op->GetProgress()); EXPECT_EQ(0, op->GetProgress());
EXPECT_EQ(image_writer_api::STAGE_UNKNOWN, op->GetStage()); EXPECT_EQ(image_writer_api::STAGE_UNKNOWN, op->GetStage());
} }
} // namespace
} // namespace image_writer } // namespace image_writer
} // namespace extensions } // namespace extensions
...@@ -4,26 +4,119 @@ ...@@ -4,26 +4,119 @@
#include "chrome/browser/extensions/api/image_writer_private/test_utils.h" #include "chrome/browser/extensions/api/image_writer_private/test_utils.h"
#if defined(OS_CHROMEOS)
#include "chromeos/dbus/dbus_thread_manager.h"
#include "chromeos/dbus/fake_dbus_thread_manager.h"
#include "chromeos/dbus/fake_image_burner_client.h"
#endif
namespace extensions { namespace extensions {
namespace image_writer { namespace image_writer {
#if defined(OS_CHROMEOS)
namespace {
class ImageWriterFakeImageBurnerClient
: public chromeos::FakeImageBurnerClient {
public:
ImageWriterFakeImageBurnerClient() {}
virtual ~ImageWriterFakeImageBurnerClient() {}
virtual void SetEventHandlers(
const BurnFinishedHandler& burn_finished_handler,
const BurnProgressUpdateHandler& burn_progress_update_handler) OVERRIDE {
burn_finished_handler_ = burn_finished_handler;
burn_progress_update_handler_ = burn_progress_update_handler;
}
virtual void BurnImage(const std::string& from_path,
const std::string& to_path,
const ErrorCallback& error_callback) OVERRIDE {
base::MessageLoop::current()->PostTask(FROM_HERE,
base::Bind(burn_progress_update_handler_, to_path, 0, 100));
base::MessageLoop::current()->PostTask(FROM_HERE,
base::Bind(burn_progress_update_handler_, to_path, 50, 100));
base::MessageLoop::current()->PostTask(FROM_HERE,
base::Bind(burn_progress_update_handler_, to_path, 100, 100));
base::MessageLoop::current()->PostTask(FROM_HERE,
base::Bind(burn_finished_handler_, to_path, true, ""));
}
private:
BurnFinishedHandler burn_finished_handler_;
BurnProgressUpdateHandler burn_progress_update_handler_;
};
} // namespace
#endif
MockOperationManager::MockOperationManager() MockOperationManager::MockOperationManager()
: OperationManager(NULL) { : OperationManager(NULL) {}
}
MockOperationManager::~MockOperationManager() { MockOperationManager::~MockOperationManager() {}
}
ImageWriterUnitTestBase::ImageWriterUnitTestBase() {}
ImageWriterUnitTestBase::~ImageWriterUnitTestBase() {}
void ImageWriterUnitTestBase::SetUp() { void ImageWriterUnitTestBase::SetUp() {
ASSERT_TRUE(base::CreateTemporaryFile(&test_image_)); testing::Test::SetUp();
ASSERT_TRUE(base::CreateTemporaryFile(&test_device_)); ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
ASSERT_EQ(32, file_util::WriteFile(test_image_, kTestData, 32)); ASSERT_TRUE(base::CreateTemporaryFileInDir(temp_dir_.path(),
&test_image_path_));
ASSERT_TRUE(base::CreateTemporaryFileInDir(temp_dir_.path(),
&test_device_path_));
ASSERT_TRUE(FillFile(test_image_path_, kImagePattern, kTestFileSize));
ASSERT_TRUE(FillFile(test_device_path_, kDevicePattern, kTestFileSize));
#if defined(OS_CHROMEOS)
if (!chromeos::DBusThreadManager::IsInitialized()) {
chromeos::FakeDBusThreadManager* fake_dbus_thread_manager =
new chromeos::FakeDBusThreadManager;
scoped_ptr<chromeos::ImageBurnerClient>
image_burner_fake(new ImageWriterFakeImageBurnerClient());
fake_dbus_thread_manager->SetImageBurnerClient(image_burner_fake.Pass());
chromeos::DBusThreadManager::InitializeForTesting(fake_dbus_thread_manager);
}
#endif
} }
void ImageWriterUnitTestBase::TearDown() { void ImageWriterUnitTestBase::TearDown() {}
base::DeleteFile(test_image_, false);
base::DeleteFile(test_device_, false); bool ImageWriterUnitTestBase::CompareImageAndDevice() {
scoped_ptr<char[]> image_buffer(new char[kTestFileSize]);
scoped_ptr<char[]> device_buffer(new char[kTestFileSize]);
while (true) {
int image_bytes_read = ReadFile(test_image_path_,
image_buffer.get(),
kTestFileSize);
int device_bytes_read = ReadFile(test_device_path_,
device_buffer.get(),
kTestFileSize);
if (image_bytes_read != device_bytes_read)
return false;
if (image_bytes_read == 0)
return true;
if (memcmp(image_buffer.get(), device_buffer.get(), image_bytes_read) != 0)
return false;
}
return false;
}
bool ImageWriterUnitTestBase::FillFile(const base::FilePath& file,
const int pattern,
const int length) {
scoped_ptr<char[]> buffer(new char[length]);
memset(buffer.get(), pattern, length);
return file_util::WriteFile(file, buffer.get(), length) == length;
} }
} // namespace image_writer } // namespace image_writer
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
#define CHROME_BROWSER_EXTENSIONS_API_IMAGE_WRITER_PRIVATE_TEST_UTILS_H_ #define CHROME_BROWSER_EXTENSIONS_API_IMAGE_WRITER_PRIVATE_TEST_UTILS_H_
#include "base/file_util.h" #include "base/file_util.h"
#include "base/files/scoped_temp_dir.h"
#include "base/message_loop/message_loop.h" #include "base/message_loop/message_loop.h"
#include "base/run_loop.h" #include "base/run_loop.h"
#include "chrome/browser/extensions/api/image_writer_private/operation_manager.h" #include "chrome/browser/extensions/api/image_writer_private/operation_manager.h"
...@@ -17,8 +18,16 @@ namespace extensions { ...@@ -17,8 +18,16 @@ namespace extensions {
namespace image_writer { namespace image_writer {
const char kDummyExtensionId[] = "DummyExtension"; const char kDummyExtensionId[] = "DummyExtension";
const char kTestData[] = "This is some test data, padded. ";
// Default file size to use in tests. Currently 32kB.
const int kTestFileSize = 32 * 1024;
// Pattern to use in the image file.
const int kImagePattern = 0x55555555; // 01010101
// Pattern to use in the device file.
const int kDevicePattern = 0xAAAAAAAA; // 10101010
// A mock around the operation manager for tracking callbacks. Note that there
// are non-virtual methods on this class that should not be called in tests.
class MockOperationManager : public OperationManager { class MockOperationManager : public OperationManager {
public: public:
MockOperationManager(); MockOperationManager();
...@@ -37,15 +46,32 @@ class MockOperationManager : public OperationManager { ...@@ -37,15 +46,32 @@ class MockOperationManager : public OperationManager {
const std::string& error_message)); const std::string& error_message));
}; };
// Base class for unit tests that manages creating image and device files.
class ImageWriterUnitTestBase : public testing::Test { class ImageWriterUnitTestBase : public testing::Test {
public: public:
ImageWriterUnitTestBase();
virtual ~ImageWriterUnitTestBase();
protected:
virtual void SetUp() OVERRIDE; virtual void SetUp() OVERRIDE;
virtual void TearDown() OVERRIDE; virtual void TearDown() OVERRIDE;
base::FilePath test_image_; // Compare the image and device files, returning true if they are the same,
base::FilePath test_device_; // false if different.
bool CompareImageAndDevice();
base::ScopedTempDir temp_dir_;
base::FilePath test_image_path_;
base::FilePath test_device_path_;
private: private:
// Fills |file| with |length| bytes of |pattern|, overwriting any existing
// data.
bool FillFile(const base::FilePath& file,
const int pattern,
const int length);
content::TestBrowserThreadBundle thread_bundle_; content::TestBrowserThreadBundle thread_bundle_;
}; };
......
...@@ -23,10 +23,10 @@ TEST_F(ImageWriterFromFileTest, InvalidFile) { ...@@ -23,10 +23,10 @@ TEST_F(ImageWriterFromFileTest, InvalidFile) {
scoped_refptr<WriteFromFileOperation> op = new WriteFromFileOperation( scoped_refptr<WriteFromFileOperation> op = new WriteFromFileOperation(
manager.AsWeakPtr(), manager.AsWeakPtr(),
kDummyExtensionId, kDummyExtensionId,
test_image_, test_image_path_,
test_device_.AsUTF8Unsafe()); test_device_path_.AsUTF8Unsafe());
base::DeleteFile(test_image_, false); base::DeleteFile(test_image_path_, false);
EXPECT_CALL(manager, OnProgress(kDummyExtensionId, _, _)).Times(0); EXPECT_CALL(manager, OnProgress(kDummyExtensionId, _, _)).Times(0);
EXPECT_CALL(manager, OnComplete(kDummyExtensionId)).Times(0); EXPECT_CALL(manager, OnComplete(kDummyExtensionId)).Times(0);
......
...@@ -319,9 +319,11 @@ ...@@ -319,9 +319,11 @@
'browser/extensions/api/idltest/idltest_api.h', 'browser/extensions/api/idltest/idltest_api.h',
'browser/extensions/api/image_writer_private/error_messages.cc', 'browser/extensions/api/image_writer_private/error_messages.cc',
'browser/extensions/api/image_writer_private/error_messages.h', 'browser/extensions/api/image_writer_private/error_messages.h',
'browser/extensions/api/image_writer_private/destroy_partitions_operation.cc',
'browser/extensions/api/image_writer_private/destroy_partitions_operation.h',
'browser/extensions/api/image_writer_private/operation.cc', 'browser/extensions/api/image_writer_private/operation.cc',
'browser/extensions/api/image_writer_private/operation_chromeos.cc',
'browser/extensions/api/image_writer_private/operation.h', 'browser/extensions/api/image_writer_private/operation.h',
'browser/extensions/api/image_writer_private/operation_chromeos.cc',
'browser/extensions/api/image_writer_private/operation_linux.cc', 'browser/extensions/api/image_writer_private/operation_linux.cc',
'browser/extensions/api/image_writer_private/operation_mac.cc', 'browser/extensions/api/image_writer_private/operation_mac.cc',
'browser/extensions/api/image_writer_private/operation_manager.cc', 'browser/extensions/api/image_writer_private/operation_manager.cc',
......
...@@ -841,6 +841,7 @@ ...@@ -841,6 +841,7 @@
'browser/extensions/api/identity/gaia_web_auth_flow_unittest.cc', 'browser/extensions/api/identity/gaia_web_auth_flow_unittest.cc',
'browser/extensions/api/identity/identity_mint_queue_unittest.cc', 'browser/extensions/api/identity/identity_mint_queue_unittest.cc',
'browser/extensions/api/idle/idle_api_unittest.cc', 'browser/extensions/api/idle/idle_api_unittest.cc',
'browser/extensions/api/image_writer_private/destroy_partitions_operation_unittest.cc',
'browser/extensions/api/image_writer_private/operation_manager_unittest.cc', 'browser/extensions/api/image_writer_private/operation_manager_unittest.cc',
'browser/extensions/api/image_writer_private/operation_unittest.cc', 'browser/extensions/api/image_writer_private/operation_unittest.cc',
'browser/extensions/api/image_writer_private/test_utils.cc', 'browser/extensions/api/image_writer_private/test_utils.cc',
......
...@@ -101,11 +101,11 @@ ...@@ -101,11 +101,11 @@
// Destroys the partition table of a disk, effectively erasing it. This is // Destroys the partition table of a disk, effectively erasing it. This is
// a fairly quick operation and so it does not have complex stages or // a fairly quick operation and so it does not have complex stages or
// progress information. However, it can fail and call the callback with // progress information, just a write phase.
// an error.
// //
// |storageUnitId|: The identifier of the storage unit to wipe // |storageUnitId|: The identifier of the storage unit to wipe
// |callback|: A callback which is called when the operation is complete. // |callback|: A callback that triggers when the operation has been
// successfully started.
static void destroyPartitions(DOMString storageUnitId, static void destroyPartitions(DOMString storageUnitId,
DestroyPartitionsCallback callback); DestroyPartitionsCallback callback);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment