Adds ImageWriterPrivate.destroyPartitions operation.
BUG=328246
Review URL: https://codereview.chromium.org/109793006
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@242452 0039d316-1c4b-4281-b951-d872f2087c98
diff --git a/chrome/browser/extensions/api/image_writer_private/destroy_partitions_operation.cc b/chrome/browser/extensions/api/image_writer_private/destroy_partitions_operation.cc
new file mode 100644
index 0000000..127b3b0
--- /dev/null
+++ b/chrome/browser/extensions/api/image_writer_private/destroy_partitions_operation.cc
@@ -0,0 +1,51 @@
+// Copyright 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/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
diff --git a/chrome/browser/extensions/api/image_writer_private/destroy_partitions_operation.h b/chrome/browser/extensions/api/image_writer_private/destroy_partitions_operation.h
new file mode 100644
index 0000000..1da35da
--- /dev/null
+++ b/chrome/browser/extensions/api/image_writer_private/destroy_partitions_operation.h
@@ -0,0 +1,33 @@
+// Copyright 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.
+
+#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_
diff --git a/chrome/browser/extensions/api/image_writer_private/destroy_partitions_operation_unittest.cc b/chrome/browser/extensions/api/image_writer_private/destroy_partitions_operation_unittest.cc
new file mode 100644
index 0000000..1e1e48e
--- /dev/null
+++ b/chrome/browser/extensions/api/image_writer_private/destroy_partitions_operation_unittest.cc
@@ -0,0 +1,66 @@
+// Copyright 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/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
diff --git a/chrome/browser/extensions/api/image_writer_private/image_writer_private_api.cc b/chrome/browser/extensions/api/image_writer_private/image_writer_private_api.cc
index fffd1ac..3d7fd42 100644
--- a/chrome/browser/extensions/api/image_writer_private/image_writer_private_api.cc
+++ b/chrome/browser/extensions/api/image_writer_private/image_writer_private_api.cc
@@ -151,10 +151,25 @@
image_writer_api::DestroyPartitions::Params::Create(*args_));
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;
}
+void ImageWriterPrivateDestroyPartitionsFunction::OnDestroyComplete(
+ bool success,
+ const std::string& error) {
+ if (!success) {
+ error_ = error;
+ }
+
+ SendResponse(success);
+}
+
ImageWriterPrivateListRemovableStorageDevicesFunction::
ImageWriterPrivateListRemovableStorageDevicesFunction() {
}
diff --git a/chrome/browser/extensions/api/image_writer_private/image_writer_private_api.h b/chrome/browser/extensions/api/image_writer_private/image_writer_private_api.h
index 4789d18..9cccd0fc 100644
--- a/chrome/browser/extensions/api/image_writer_private/image_writer_private_api.h
+++ b/chrome/browser/extensions/api/image_writer_private/image_writer_private_api.h
@@ -59,6 +59,7 @@
private:
virtual ~ImageWriterPrivateDestroyPartitionsFunction();
virtual bool RunImpl() OVERRIDE;
+ void OnDestroyComplete(bool success, const std::string& error);
};
class ImageWriterPrivateListRemovableStorageDevicesFunction
diff --git a/chrome/browser/extensions/api/image_writer_private/operation.cc b/chrome/browser/extensions/api/image_writer_private/operation.cc
index 743f797..4a57c7d2 100644
--- a/chrome/browser/extensions/api/image_writer_private/operation.cc
+++ b/chrome/browser/extensions/api/image_writer_private/operation.cc
@@ -32,6 +32,7 @@
: manager_(manager),
extension_id_(extension_id),
storage_unit_id_(storage_unit_id),
+ verify_write_(true),
stage_(image_writer_api::STAGE_UNKNOWN),
progress_(0) {
}
diff --git a/chrome/browser/extensions/api/image_writer_private/operation.h b/chrome/browser/extensions/api/image_writer_private/operation.h
index 7e45fe1..ce62f65d 100644
--- a/chrome/browser/extensions/api/image_writer_private/operation.h
+++ b/chrome/browser/extensions/api/image_writer_private/operation.h
@@ -110,6 +110,9 @@
base::FilePath image_path_;
const std::string storage_unit_id_;
+ // Whether or not to run the final verification step.
+ bool verify_write_;
+
private:
friend class base::RefCountedThreadSafe<Operation>;
diff --git a/chrome/browser/extensions/api/image_writer_private/operation_linux.cc b/chrome/browser/extensions/api/image_writer_private/operation_linux.cc
index 798dea3..df34834b 100644
--- a/chrome/browser/extensions/api/image_writer_private/operation_linux.cc
+++ b/chrome/browser/extensions/api/image_writer_private/operation_linux.cc
@@ -138,11 +138,15 @@
DVLOG(2) << "Completed write of " << image_path_.value();
SetProgress(kProgressComplete);
- BrowserThread::PostTask(
- BrowserThread::FILE,
- FROM_HERE,
- base::Bind(&Operation::VerifyWriteStart,
- this));
+ if (verify_write_) {
+ BrowserThread::PostTask(BrowserThread::FILE,
+ FROM_HERE,
+ base::Bind(&Operation::VerifyWriteStart, this));
+ } else {
+ BrowserThread::PostTask(BrowserThread::FILE,
+ FROM_HERE,
+ base::Bind(&Operation::Finish, this));
+ }
}
void Operation::VerifyWriteStart() {
diff --git a/chrome/browser/extensions/api/image_writer_private/operation_manager.cc b/chrome/browser/extensions/api/image_writer_private/operation_manager.cc
index b1b1c44..2b525e56 100644
--- a/chrome/browser/extensions/api/image_writer_private/operation_manager.cc
+++ b/chrome/browser/extensions/api/image_writer_private/operation_manager.cc
@@ -5,6 +5,7 @@
#include "base/lazy_instance.h"
#include "chrome/browser/browser_process.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/operation.h"
#include "chrome/browser/extensions/api/image_writer_private/operation_manager.h"
@@ -63,7 +64,6 @@
bool saveImageAsDownload,
const std::string& storage_unit_id,
const Operation::StartWriteCallback& callback) {
-
OperationMap::iterator existing_operation = operations_.find(extension_id);
if (existing_operation != operations_.end()) {
@@ -78,14 +78,10 @@
hash,
saveImageAsDownload,
storage_unit_id));
-
operations_[extension_id] = operation;
-
BrowserThread::PostTask(BrowserThread::FILE,
FROM_HERE,
- base::Bind(&Operation::Start,
- operation.get()));
-
+ base::Bind(&Operation::Start, operation));
callback.Run(true, "");
}
@@ -105,14 +101,10 @@
extension_id,
path,
storage_unit_id));
-
operations_[extension_id] = operation;
-
BrowserThread::PostTask(BrowserThread::FILE,
FROM_HERE,
- base::Bind(&Operation::Start,
- operation.get()));
-
+ base::Bind(&Operation::Start, operation));
callback.Run(true, "");
}
@@ -132,6 +124,27 @@
}
}
+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,
image_writer_api::Stage stage,
int progress) {
diff --git a/chrome/browser/extensions/api/image_writer_private/operation_manager.h b/chrome/browser/extensions/api/image_writer_private/operation_manager.h
index 56655fcb..00489bc 100644
--- a/chrome/browser/extensions/api/image_writer_private/operation_manager.h
+++ b/chrome/browser/extensions/api/image_writer_private/operation_manager.h
@@ -61,6 +61,11 @@
void CancelWrite(const ExtensionId& extension_id,
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.
virtual void OnProgress(const ExtensionId& extension_id,
image_writer_api::Stage stage,
diff --git a/chrome/browser/extensions/api/image_writer_private/operation_manager_unittest.cc b/chrome/browser/extensions/api/image_writer_private/operation_manager_unittest.cc
index ed9c3f3..80ccfa6 100644
--- a/chrome/browser/extensions/api/image_writer_private/operation_manager_unittest.cc
+++ b/chrome/browser/extensions/api/image_writer_private/operation_manager_unittest.cc
@@ -5,8 +5,8 @@
#include "base/command_line.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/operation_manager.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/test_extension_system.h"
#include "chrome/test/base/testing_profile.h"
@@ -25,6 +25,8 @@
using testing::AnyNumber;
using testing::AtLeast;
+namespace {
+
class ImageWriterOperationManagerTest
: public ImageWriterUnitTestBase {
public:
@@ -68,8 +70,8 @@
manager.StartWriteFromFile(
kDummyExtensionId,
- test_image_,
- test_device_.AsUTF8Unsafe(),
+ test_image_path_,
+ test_device_path_.AsUTF8Unsafe(),
base::Bind(&ImageWriterOperationManagerTest::StartCallback,
base::Unretained(this)));
@@ -78,5 +80,20 @@
EXPECT_EQ("", start_error_);
}
-} // namespace image_writer
-} // namespace extensions
+TEST_F(ImageWriterOperationManagerTest, DestroyPartitions) {
+ 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
diff --git a/chrome/browser/extensions/api/image_writer_private/operation_unittest.cc b/chrome/browser/extensions/api/image_writer_private/operation_unittest.cc
index 0df18fb..49ccd88 100644
--- a/chrome/browser/extensions/api/image_writer_private/operation_unittest.cc
+++ b/chrome/browser/extensions/api/image_writer_private/operation_unittest.cc
@@ -8,6 +8,7 @@
namespace extensions {
namespace image_writer {
+namespace {
class ImageWriterOperationTest : public ImageWriterUnitTestBase {
};
@@ -25,13 +26,15 @@
TEST_F(ImageWriterOperationTest, Create) {
MockOperationManager manager;
- scoped_refptr<Operation> op(new DummyOperation(manager.AsWeakPtr(),
- kDummyExtensionId,
- test_device_.AsUTF8Unsafe()));
+ scoped_refptr<Operation> op(
+ new DummyOperation(manager.AsWeakPtr(),
+ kDummyExtensionId,
+ test_device_path_.AsUTF8Unsafe()));
EXPECT_EQ(0, op->GetProgress());
EXPECT_EQ(image_writer_api::STAGE_UNKNOWN, op->GetStage());
}
+} // namespace
} // namespace image_writer
} // namespace extensions
diff --git a/chrome/browser/extensions/api/image_writer_private/test_utils.cc b/chrome/browser/extensions/api/image_writer_private/test_utils.cc
index 651ce0a..caef818c 100644
--- a/chrome/browser/extensions/api/image_writer_private/test_utils.cc
+++ b/chrome/browser/extensions/api/image_writer_private/test_utils.cc
@@ -4,26 +4,119 @@
#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 image_writer {
-MockOperationManager::MockOperationManager()
- : OperationManager(NULL) {
-}
+#if defined(OS_CHROMEOS)
+namespace {
-MockOperationManager::~MockOperationManager() {
-}
+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()
+ : OperationManager(NULL) {}
+
+MockOperationManager::~MockOperationManager() {}
+
+ImageWriterUnitTestBase::ImageWriterUnitTestBase() {}
+ImageWriterUnitTestBase::~ImageWriterUnitTestBase() {}
void ImageWriterUnitTestBase::SetUp() {
- ASSERT_TRUE(base::CreateTemporaryFile(&test_image_));
- ASSERT_TRUE(base::CreateTemporaryFile(&test_device_));
+ testing::Test::SetUp();
+ 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() {
- base::DeleteFile(test_image_, false);
- base::DeleteFile(test_device_, false);
+void ImageWriterUnitTestBase::TearDown() {}
+
+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
diff --git a/chrome/browser/extensions/api/image_writer_private/test_utils.h b/chrome/browser/extensions/api/image_writer_private/test_utils.h
index 88ccf492..b290e88 100644
--- a/chrome/browser/extensions/api/image_writer_private/test_utils.h
+++ b/chrome/browser/extensions/api/image_writer_private/test_utils.h
@@ -6,6 +6,7 @@
#define CHROME_BROWSER_EXTENSIONS_API_IMAGE_WRITER_PRIVATE_TEST_UTILS_H_
#include "base/file_util.h"
+#include "base/files/scoped_temp_dir.h"
#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "chrome/browser/extensions/api/image_writer_private/operation_manager.h"
@@ -17,8 +18,16 @@
namespace image_writer {
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 {
public:
MockOperationManager();
@@ -37,15 +46,32 @@
const std::string& error_message));
};
+// Base class for unit tests that manages creating image and device files.
class ImageWriterUnitTestBase : public testing::Test {
public:
+ ImageWriterUnitTestBase();
+ virtual ~ImageWriterUnitTestBase();
+
+ protected:
virtual void SetUp() OVERRIDE;
virtual void TearDown() OVERRIDE;
- base::FilePath test_image_;
- base::FilePath test_device_;
+ // Compare the image and device files, returning true if they are the same,
+ // false if different.
+ bool CompareImageAndDevice();
+
+ base::ScopedTempDir temp_dir_;
+ base::FilePath test_image_path_;
+ base::FilePath test_device_path_;
+
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_;
};
diff --git a/chrome/browser/extensions/api/image_writer_private/write_from_file_operation_unittest.cc b/chrome/browser/extensions/api/image_writer_private/write_from_file_operation_unittest.cc
index c24484d..223d731 100644
--- a/chrome/browser/extensions/api/image_writer_private/write_from_file_operation_unittest.cc
+++ b/chrome/browser/extensions/api/image_writer_private/write_from_file_operation_unittest.cc
@@ -23,10 +23,10 @@
scoped_refptr<WriteFromFileOperation> op = new WriteFromFileOperation(
manager.AsWeakPtr(),
kDummyExtensionId,
- test_image_,
- test_device_.AsUTF8Unsafe());
+ test_image_path_,
+ 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, OnComplete(kDummyExtensionId)).Times(0);
diff --git a/chrome/chrome_browser_extensions.gypi b/chrome/chrome_browser_extensions.gypi
index d0e586d..0b3797fc 100644
--- a/chrome/chrome_browser_extensions.gypi
+++ b/chrome/chrome_browser_extensions.gypi
@@ -319,9 +319,11 @@
'browser/extensions/api/idltest/idltest_api.h',
'browser/extensions/api/image_writer_private/error_messages.cc',
'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_chromeos.cc',
'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_mac.cc',
'browser/extensions/api/image_writer_private/operation_manager.cc',
diff --git a/chrome/chrome_tests_unit.gypi b/chrome/chrome_tests_unit.gypi
index a182db3..45ebdfb 100644
--- a/chrome/chrome_tests_unit.gypi
+++ b/chrome/chrome_tests_unit.gypi
@@ -848,6 +848,7 @@
'browser/extensions/api/identity/gaia_web_auth_flow_unittest.cc',
'browser/extensions/api/identity/identity_mint_queue_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_unittest.cc',
'browser/extensions/api/image_writer_private/test_utils.cc',
diff --git a/chrome/common/extensions/api/image_writer_private.idl b/chrome/common/extensions/api/image_writer_private.idl
index e46eefe..9fcd3d2 100644
--- a/chrome/common/extensions/api/image_writer_private.idl
+++ b/chrome/common/extensions/api/image_writer_private.idl
@@ -101,11 +101,11 @@
// 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
- // progress information. However, it can fail and call the callback with
- // an error.
+ // progress information, just a write phase.
//
// |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,
DestroyPartitionsCallback callback);