Commit 5d7b717c authored by cmumford@chromium.org's avatar cmumford@chromium.org

Cleanup IndexedDBIO unit tests using GoogleMock.

Previous tests had the following limitations:

1. Not all ASSERT/EXPECT's were within the test functions.
2. Not verifying that OpenLevelDB was ever called.
3. Unused MockErrorLevelDBFactory::expect_destroy.
4. Explicitly doing things (like functionXXX called) which we get for
   free by using GoogleMock.

BUG=388012

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

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@283995 0039d316-1c4b-4281-b951-d872f2087c98
parent aded1c52
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
#include "content/browser/indexed_db/indexed_db_value.h" #include "content/browser/indexed_db/indexed_db_value.h"
#include "content/browser/indexed_db/leveldb/leveldb_comparator.h" #include "content/browser/indexed_db/leveldb/leveldb_comparator.h"
#include "content/browser/indexed_db/leveldb/leveldb_database.h" #include "content/browser/indexed_db/leveldb/leveldb_database.h"
#include "content/browser/indexed_db/leveldb/leveldb_factory.h"
#include "content/browser/indexed_db/leveldb/leveldb_iterator.h" #include "content/browser/indexed_db/leveldb/leveldb_iterator.h"
#include "content/browser/indexed_db/leveldb/leveldb_transaction.h" #include "content/browser/indexed_db/leveldb/leveldb_transaction.h"
#include "content/common/indexed_db/indexed_db_key.h" #include "content/common/indexed_db/indexed_db_key.h"
......
...@@ -50,18 +50,9 @@ namespace content { ...@@ -50,18 +50,9 @@ namespace content {
class IndexedDBFactory; class IndexedDBFactory;
class LevelDBComparator; class LevelDBComparator;
class LevelDBDatabase; class LevelDBDatabase;
class LevelDBFactory;
struct IndexedDBValue; struct IndexedDBValue;
class LevelDBFactory {
public:
virtual ~LevelDBFactory() {}
virtual leveldb::Status OpenLevelDB(const base::FilePath& file_name,
const LevelDBComparator* comparator,
scoped_ptr<LevelDBDatabase>* db,
bool* is_disk_full) = 0;
virtual leveldb::Status DestroyLevelDB(const base::FilePath& file_name) = 0;
};
class CONTENT_EXPORT IndexedDBBackingStore class CONTENT_EXPORT IndexedDBBackingStore
: public base::RefCounted<IndexedDBBackingStore> { : public base::RefCounted<IndexedDBBackingStore> {
public: public:
......
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
#include "content/browser/indexed_db/indexed_db_context_impl.h" #include "content/browser/indexed_db/indexed_db_context_impl.h"
#include "content/browser/indexed_db/indexed_db_leveldb_coding.h" #include "content/browser/indexed_db/indexed_db_leveldb_coding.h"
#include "content/browser/indexed_db/indexed_db_value.h" #include "content/browser/indexed_db/indexed_db_value.h"
#include "content/browser/indexed_db/leveldb/leveldb_factory.h"
#include "content/public/test/mock_special_storage_policy.h" #include "content/public/test/mock_special_storage_policy.h"
#include "net/url_request/url_request_test_util.h" #include "net/url_request/url_request_test_util.h"
#include "testing/gtest/include/gtest/gtest.h" #include "testing/gtest/include/gtest/gtest.h"
......
...@@ -11,6 +11,8 @@ ...@@ -11,6 +11,8 @@
#include "base/strings/utf_string_conversions.h" #include "base/strings/utf_string_conversions.h"
#include "content/browser/indexed_db/indexed_db_backing_store.h" #include "content/browser/indexed_db/indexed_db_backing_store.h"
#include "content/browser/indexed_db/leveldb/leveldb_database.h" #include "content/browser/indexed_db/leveldb/leveldb_database.h"
#include "content/browser/indexed_db/leveldb/mock_leveldb_factory.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h" #include "testing/gtest/include/gtest/gtest.h"
#include "third_party/leveldatabase/env_chromium.h" #include "third_party/leveldatabase/env_chromium.h"
...@@ -20,6 +22,9 @@ using content::LevelDBComparator; ...@@ -20,6 +22,9 @@ using content::LevelDBComparator;
using content::LevelDBDatabase; using content::LevelDBDatabase;
using content::LevelDBFactory; using content::LevelDBFactory;
using content::LevelDBSnapshot; using content::LevelDBSnapshot;
using testing::_;
using testing::Exactly;
using testing::Invoke;
namespace base { namespace base {
class TaskRunner; class TaskRunner;
...@@ -54,30 +59,27 @@ class BustedLevelDBDatabase : public LevelDBDatabase { ...@@ -54,30 +59,27 @@ class BustedLevelDBDatabase : public LevelDBDatabase {
DISALLOW_COPY_AND_ASSIGN(BustedLevelDBDatabase); DISALLOW_COPY_AND_ASSIGN(BustedLevelDBDatabase);
}; };
class MockLevelDBFactory : public LevelDBFactory { class BustedLevelDBFactory : public LevelDBFactory {
public: public:
MockLevelDBFactory() : destroy_called_(false) {}
virtual leveldb::Status OpenLevelDB( virtual leveldb::Status OpenLevelDB(
const base::FilePath& file_name, const base::FilePath& file_name,
const LevelDBComparator* comparator, const LevelDBComparator* comparator,
scoped_ptr<LevelDBDatabase>* db, scoped_ptr<LevelDBDatabase>* db,
bool* is_disk_full = 0) OVERRIDE { bool* is_disk_full = 0) OVERRIDE {
if (open_error_.ok())
*db = BustedLevelDBDatabase::Open(file_name, comparator); *db = BustedLevelDBDatabase::Open(file_name, comparator);
return leveldb::Status::OK(); return open_error_;
} }
virtual leveldb::Status DestroyLevelDB(const base::FilePath& file_name) virtual leveldb::Status DestroyLevelDB(
OVERRIDE { const base::FilePath& file_name) OVERRIDE {
EXPECT_FALSE(destroy_called_);
destroy_called_ = true;
return leveldb::Status::IOError("error"); return leveldb::Status::IOError("error");
} }
virtual ~MockLevelDBFactory() { EXPECT_TRUE(destroy_called_); } void SetOpenError(const leveldb::Status& open_error) {
open_error_ = open_error;
private: }
bool destroy_called_;
private: private:
DISALLOW_COPY_AND_ASSIGN(MockLevelDBFactory); leveldb::Status open_error_;
}; };
TEST(IndexedDBIOErrorTest, CleanUpTest) { TEST(IndexedDBIOErrorTest, CleanUpTest) {
...@@ -87,9 +89,17 @@ TEST(IndexedDBIOErrorTest, CleanUpTest) { ...@@ -87,9 +89,17 @@ TEST(IndexedDBIOErrorTest, CleanUpTest) {
ASSERT_TRUE(temp_directory.CreateUniqueTempDir()); ASSERT_TRUE(temp_directory.CreateUniqueTempDir());
const base::FilePath path = temp_directory.path(); const base::FilePath path = temp_directory.path();
net::URLRequestContext* request_context = NULL; net::URLRequestContext* request_context = NULL;
MockLevelDBFactory mock_leveldb_factory;
blink::WebIDBDataLoss data_loss = BustedLevelDBFactory busted_factory;
blink::WebIDBDataLossNone; content::MockLevelDBFactory mock_leveldb_factory;
ON_CALL(mock_leveldb_factory, OpenLevelDB(_, _, _, _)).WillByDefault(
Invoke(&busted_factory, &BustedLevelDBFactory::OpenLevelDB));
ON_CALL(mock_leveldb_factory, DestroyLevelDB(_)).WillByDefault(
Invoke(&busted_factory, &BustedLevelDBFactory::DestroyLevelDB));
EXPECT_CALL(mock_leveldb_factory, OpenLevelDB(_, _, _, _)).Times(Exactly(1));
EXPECT_CALL(mock_leveldb_factory, DestroyLevelDB(_)).Times(Exactly(1));
blink::WebIDBDataLoss data_loss = blink::WebIDBDataLossNone;
std::string data_loss_message; std::string data_loss_message;
bool disk_full = false; bool disk_full = false;
base::TaskRunner* task_runner = NULL; base::TaskRunner* task_runner = NULL;
...@@ -109,41 +119,6 @@ TEST(IndexedDBIOErrorTest, CleanUpTest) { ...@@ -109,41 +119,6 @@ TEST(IndexedDBIOErrorTest, CleanUpTest) {
&s); &s);
} }
// TODO(dgrogan): Remove expect_destroy if we end up not using it again. It is
// currently set to false in all 4 calls below.
template <class T>
class MockErrorLevelDBFactory : public LevelDBFactory {
public:
MockErrorLevelDBFactory(T error, bool expect_destroy)
: error_(error),
expect_destroy_(expect_destroy),
destroy_called_(false) {}
virtual leveldb::Status OpenLevelDB(
const base::FilePath& file_name,
const LevelDBComparator* comparator,
scoped_ptr<LevelDBDatabase>* db,
bool* is_disk_full = 0) OVERRIDE {
return MakeIOError(
"some filename", "some message", leveldb_env::kNewLogger, error_);
}
virtual leveldb::Status DestroyLevelDB(const base::FilePath& file_name)
OVERRIDE {
EXPECT_FALSE(destroy_called_);
destroy_called_ = true;
return leveldb::Status::IOError("error");
}
virtual ~MockErrorLevelDBFactory() {
EXPECT_EQ(expect_destroy_, destroy_called_);
}
private:
T error_;
bool expect_destroy_;
bool destroy_called_;
DISALLOW_COPY_AND_ASSIGN(MockErrorLevelDBFactory);
};
TEST(IndexedDBNonRecoverableIOErrorTest, NuancedCleanupTest) { TEST(IndexedDBNonRecoverableIOErrorTest, NuancedCleanupTest) {
content::IndexedDBFactory* factory = NULL; content::IndexedDBFactory* factory = NULL;
const GURL origin("http://localhost:81"); const GURL origin("http://localhost:81");
...@@ -159,7 +134,18 @@ TEST(IndexedDBNonRecoverableIOErrorTest, NuancedCleanupTest) { ...@@ -159,7 +134,18 @@ TEST(IndexedDBNonRecoverableIOErrorTest, NuancedCleanupTest) {
bool clean_journal = false; bool clean_journal = false;
leveldb::Status s; leveldb::Status s;
MockErrorLevelDBFactory<int> mock_leveldb_factory(ENOSPC, false); BustedLevelDBFactory busted_factory;
content::MockLevelDBFactory mock_leveldb_factory;
ON_CALL(mock_leveldb_factory, OpenLevelDB(_, _, _, _)).WillByDefault(
Invoke(&busted_factory, &BustedLevelDBFactory::OpenLevelDB));
ON_CALL(mock_leveldb_factory, DestroyLevelDB(_)).WillByDefault(
Invoke(&busted_factory, &BustedLevelDBFactory::DestroyLevelDB));
EXPECT_CALL(mock_leveldb_factory, OpenLevelDB(_, _, _, _)).Times(Exactly(4));
EXPECT_CALL(mock_leveldb_factory, DestroyLevelDB(_)).Times(Exactly(0));
busted_factory.SetOpenError(MakeIOError(
"some filename", "some message", leveldb_env::kNewLogger, ENOSPC));
scoped_refptr<IndexedDBBackingStore> backing_store = scoped_refptr<IndexedDBBackingStore> backing_store =
IndexedDBBackingStore::Open(factory, IndexedDBBackingStore::Open(factory,
origin, origin,
...@@ -174,8 +160,10 @@ TEST(IndexedDBNonRecoverableIOErrorTest, NuancedCleanupTest) { ...@@ -174,8 +160,10 @@ TEST(IndexedDBNonRecoverableIOErrorTest, NuancedCleanupTest) {
&s); &s);
ASSERT_TRUE(s.IsIOError()); ASSERT_TRUE(s.IsIOError());
MockErrorLevelDBFactory<base::File::Error> mock_leveldb_factory2( busted_factory.SetOpenError(MakeIOError("some filename",
base::File::FILE_ERROR_NO_MEMORY, false); "some message",
leveldb_env::kNewLogger,
base::File::FILE_ERROR_NO_MEMORY));
scoped_refptr<IndexedDBBackingStore> backing_store2 = scoped_refptr<IndexedDBBackingStore> backing_store2 =
IndexedDBBackingStore::Open(factory, IndexedDBBackingStore::Open(factory,
origin, origin,
...@@ -184,13 +172,14 @@ TEST(IndexedDBNonRecoverableIOErrorTest, NuancedCleanupTest) { ...@@ -184,13 +172,14 @@ TEST(IndexedDBNonRecoverableIOErrorTest, NuancedCleanupTest) {
&data_loss, &data_loss,
&data_loss_reason, &data_loss_reason,
&disk_full, &disk_full,
&mock_leveldb_factory2, &mock_leveldb_factory,
task_runner, task_runner,
clean_journal, clean_journal,
&s); &s);
ASSERT_TRUE(s.IsIOError()); ASSERT_TRUE(s.IsIOError());
MockErrorLevelDBFactory<int> mock_leveldb_factory3(EIO, false); busted_factory.SetOpenError(MakeIOError(
"some filename", "some message", leveldb_env::kNewLogger, EIO));
scoped_refptr<IndexedDBBackingStore> backing_store3 = scoped_refptr<IndexedDBBackingStore> backing_store3 =
IndexedDBBackingStore::Open(factory, IndexedDBBackingStore::Open(factory,
origin, origin,
...@@ -199,14 +188,16 @@ TEST(IndexedDBNonRecoverableIOErrorTest, NuancedCleanupTest) { ...@@ -199,14 +188,16 @@ TEST(IndexedDBNonRecoverableIOErrorTest, NuancedCleanupTest) {
&data_loss, &data_loss,
&data_loss_reason, &data_loss_reason,
&disk_full, &disk_full,
&mock_leveldb_factory3, &mock_leveldb_factory,
task_runner, task_runner,
clean_journal, clean_journal,
&s); &s);
ASSERT_TRUE(s.IsIOError()); ASSERT_TRUE(s.IsIOError());
MockErrorLevelDBFactory<base::File::Error> mock_leveldb_factory4( busted_factory.SetOpenError(MakeIOError("some filename",
base::File::FILE_ERROR_FAILED, false); "some message",
leveldb_env::kNewLogger,
base::File::FILE_ERROR_FAILED));
scoped_refptr<IndexedDBBackingStore> backing_store4 = scoped_refptr<IndexedDBBackingStore> backing_store4 =
IndexedDBBackingStore::Open(factory, IndexedDBBackingStore::Open(factory,
origin, origin,
...@@ -215,7 +206,7 @@ TEST(IndexedDBNonRecoverableIOErrorTest, NuancedCleanupTest) { ...@@ -215,7 +206,7 @@ TEST(IndexedDBNonRecoverableIOErrorTest, NuancedCleanupTest) {
&data_loss, &data_loss,
&data_loss_reason, &data_loss_reason,
&disk_full, &disk_full,
&mock_leveldb_factory4, &mock_leveldb_factory,
task_runner, task_runner,
clean_journal, clean_journal,
&s); &s);
......
// 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 CONTENT_BROWSER_INDEXED_DB_LEVELDB_LEVELDB_FACTORY_H_
#define CONTENT_BROWSER_INDEXED_DB_LEVELDB_LEVELDB_FACTORY_H_
#include "base/memory/scoped_ptr.h"
#include "content/common/content_export.h"
#include "third_party/leveldatabase/src/include/leveldb/status.h"
namespace base {
class FilePath;
}
namespace content {
class LevelDBComparator;
class LevelDBDatabase;
class CONTENT_EXPORT LevelDBFactory {
public:
virtual ~LevelDBFactory() {}
virtual leveldb::Status OpenLevelDB(const base::FilePath& file_name,
const LevelDBComparator* comparator,
scoped_ptr<LevelDBDatabase>* db,
bool* is_disk_full) = 0;
virtual leveldb::Status DestroyLevelDB(const base::FilePath& file_name) = 0;
};
} // namespace content
#endif // CONTENT_BROWSER_INDEXED_DB_LEVELDB_LEVELDB_FACTORY_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 "content/browser/indexed_db/leveldb/mock_leveldb_factory.h"
namespace content {
MockLevelDBFactory::MockLevelDBFactory() {
}
MockLevelDBFactory::~MockLevelDBFactory() {
}
} // namespace content
// 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 CONTENT_BROWSER_INDEXED_DB_LEVELDB_MOCK_LEVELDB_FACTORY_H_
#define CONTENT_BROWSER_INDEXED_DB_LEVELDB_MOCK_LEVELDB_FACTORY_H_
#include "base/files/file_path.h"
#include "content/browser/indexed_db/leveldb/leveldb_factory.h"
#include "testing/gmock/include/gmock/gmock.h"
namespace content {
class MockLevelDBFactory : public LevelDBFactory {
public:
MockLevelDBFactory();
~MockLevelDBFactory();
MOCK_METHOD4(OpenLevelDB,
leveldb::Status(const base::FilePath& file_name,
const LevelDBComparator* comparator,
scoped_ptr<LevelDBDatabase>* db,
bool* is_disk_full));
MOCK_METHOD1(DestroyLevelDB,
leveldb::Status(const base::FilePath& file_name));
};
} // namespace content
#endif // CONTENT_BROWSER_INDEXED_DB_LEVELDB_MOCK_LEVELDB_FACTORY_H_
...@@ -748,6 +748,7 @@ ...@@ -748,6 +748,7 @@
'browser/indexed_db/leveldb/leveldb_comparator.h', 'browser/indexed_db/leveldb/leveldb_comparator.h',
'browser/indexed_db/leveldb/leveldb_database.cc', 'browser/indexed_db/leveldb/leveldb_database.cc',
'browser/indexed_db/leveldb/leveldb_database.h', 'browser/indexed_db/leveldb/leveldb_database.h',
'browser/indexed_db/leveldb/leveldb_factory.h',
'browser/indexed_db/leveldb/leveldb_iterator.h', 'browser/indexed_db/leveldb/leveldb_iterator.h',
'browser/indexed_db/leveldb/leveldb_iterator_impl.cc', 'browser/indexed_db/leveldb/leveldb_iterator_impl.cc',
'browser/indexed_db/leveldb/leveldb_iterator_impl.h', 'browser/indexed_db/leveldb/leveldb_iterator_impl.h',
......
...@@ -502,6 +502,8 @@ ...@@ -502,6 +502,8 @@
'browser/indexed_db/indexed_db_quota_client_unittest.cc', 'browser/indexed_db/indexed_db_quota_client_unittest.cc',
'browser/indexed_db/indexed_db_transaction_unittest.cc', 'browser/indexed_db/indexed_db_transaction_unittest.cc',
'browser/indexed_db/indexed_db_unittest.cc', 'browser/indexed_db/indexed_db_unittest.cc',
'browser/indexed_db/leveldb/mock_leveldb_factory.cc',
'browser/indexed_db/leveldb/mock_leveldb_factory.h',
'browser/indexed_db/mock_indexed_db_callbacks.cc', 'browser/indexed_db/mock_indexed_db_callbacks.cc',
'browser/indexed_db/mock_indexed_db_callbacks.h', 'browser/indexed_db/mock_indexed_db_callbacks.h',
'browser/indexed_db/mock_indexed_db_database_callbacks.cc', 'browser/indexed_db/mock_indexed_db_database_callbacks.cc',
......
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