| Index: content/browser/service_worker/service_worker_fetch_stores_manager_unittest.cc
|
| diff --git a/content/browser/service_worker/service_worker_fetch_stores_manager_unittest.cc b/content/browser/service_worker/service_worker_fetch_stores_manager_unittest.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..3c25be448be589594d4482b7f6e089d55333a34c
|
| --- /dev/null
|
| +++ b/content/browser/service_worker/service_worker_fetch_stores_manager_unittest.cc
|
| @@ -0,0 +1,357 @@
|
| +// 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/service_worker/service_worker_fetch_stores_manager.h"
|
| +
|
| +#include "base/files/file_path.h"
|
| +#include "base/files/scoped_temp_dir.h"
|
| +#include "base/message_loop/message_loop_proxy.h"
|
| +#include "base/run_loop.h"
|
| +#include "content/public/browser/browser_thread.h"
|
| +#include "content/public/test/test_browser_thread_bundle.h"
|
| +#include "testing/gtest/include/gtest/gtest.h"
|
| +
|
| +namespace content {
|
| +
|
| +class ServiceWorkerFetchStoresManagerTest : public testing::Test {
|
| + protected:
|
| + ServiceWorkerFetchStoresManagerTest()
|
| + : browser_thread_bundle_(TestBrowserThreadBundle::IO_MAINLOOP),
|
| + callback_bool_(false),
|
| + callback_store_(0),
|
| + callback_error_(ServiceWorkerFetchStores::FETCH_STORES_ERROR_NO_ERROR),
|
| + origin1_("http://example1.com"),
|
| + origin2_("http://example2.com") {}
|
| +
|
| + virtual void SetUp() OVERRIDE {
|
| + if (MemoryOnly()) {
|
| + stores_ = ServiceWorkerFetchStoresManager::Create(
|
| + base::FilePath(), base::MessageLoopProxy::current());
|
| + } else {
|
| + ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
|
| + stores_ = ServiceWorkerFetchStoresManager::Create(
|
| + temp_dir_.path(), base::MessageLoopProxy::current());
|
| + }
|
| + }
|
| +
|
| + virtual bool MemoryOnly() { return false; }
|
| +
|
| + void BoolAndErrorCallback(base::RunLoop* run_loop,
|
| + bool value,
|
| + ServiceWorkerFetchStores::FetchStoresError error) {
|
| + callback_bool_ = value;
|
| + callback_error_ = error;
|
| + run_loop->Quit();
|
| + }
|
| +
|
| + void StoreAndErrorCallback(base::RunLoop* run_loop,
|
| + int store,
|
| + ServiceWorkerFetchStores::FetchStoresError error) {
|
| + callback_store_ = store;
|
| + callback_error_ = error;
|
| + run_loop->Quit();
|
| + }
|
| +
|
| + void StringsAndErrorCallback(
|
| + base::RunLoop* run_loop,
|
| + const std::vector<std::string>& strings,
|
| + ServiceWorkerFetchStores::FetchStoresError error) {
|
| + callback_strings_ = strings;
|
| + callback_error_ = error;
|
| + run_loop->Quit();
|
| + }
|
| +
|
| + bool CreateStore(const GURL& origin, std::string key) {
|
| + scoped_ptr<base::RunLoop> loop(new base::RunLoop());
|
| + stores_->CreateStore(
|
| + origin,
|
| + key,
|
| + base::Bind(&ServiceWorkerFetchStoresManagerTest::StoreAndErrorCallback,
|
| + base::Unretained(this),
|
| + base::Unretained(loop.get())));
|
| + loop->Run();
|
| +
|
| + bool error = callback_error_ !=
|
| + ServiceWorkerFetchStores::FETCH_STORES_ERROR_NO_ERROR;
|
| + if (error)
|
| + EXPECT_EQ(0, callback_store_);
|
| + else
|
| + EXPECT_LT(0, callback_store_);
|
| + return !error;
|
| + }
|
| +
|
| + bool Get(const GURL& origin, std::string key) {
|
| + scoped_ptr<base::RunLoop> loop(new base::RunLoop());
|
| + stores_->GetStore(
|
| + origin,
|
| + key,
|
| + base::Bind(&ServiceWorkerFetchStoresManagerTest::StoreAndErrorCallback,
|
| + base::Unretained(this),
|
| + base::Unretained(loop.get())));
|
| + loop->Run();
|
| +
|
| + bool error = callback_error_ !=
|
| + ServiceWorkerFetchStores::FETCH_STORES_ERROR_NO_ERROR;
|
| + if (error)
|
| + EXPECT_EQ(0, callback_store_);
|
| + else
|
| + EXPECT_LT(0, callback_store_);
|
| + return !error;
|
| + }
|
| +
|
| + bool Has(const GURL& origin, std::string key) {
|
| + scoped_ptr<base::RunLoop> loop(new base::RunLoop());
|
| + stores_->HasStore(
|
| + origin,
|
| + key,
|
| + base::Bind(&ServiceWorkerFetchStoresManagerTest::BoolAndErrorCallback,
|
| + base::Unretained(this),
|
| + base::Unretained(loop.get())));
|
| + loop->Run();
|
| +
|
| + return callback_bool_;
|
| + }
|
| +
|
| + bool Delete(const GURL& origin, std::string key) {
|
| + scoped_ptr<base::RunLoop> loop(new base::RunLoop());
|
| + stores_->DeleteStore(
|
| + origin,
|
| + key,
|
| + base::Bind(&ServiceWorkerFetchStoresManagerTest::BoolAndErrorCallback,
|
| + base::Unretained(this),
|
| + base::Unretained(loop.get())));
|
| + loop->Run();
|
| +
|
| + return callback_bool_;
|
| + }
|
| +
|
| + bool Keys(const GURL& origin) {
|
| + scoped_ptr<base::RunLoop> loop(new base::RunLoop());
|
| + stores_->EnumerateStores(
|
| + origin,
|
| + base::Bind(
|
| + &ServiceWorkerFetchStoresManagerTest::StringsAndErrorCallback,
|
| + base::Unretained(this),
|
| + base::Unretained(loop.get())));
|
| + loop->Run();
|
| +
|
| + bool error = callback_error_ !=
|
| + ServiceWorkerFetchStores::FETCH_STORES_ERROR_NO_ERROR;
|
| + return !error;
|
| + }
|
| +
|
| + bool VerifyKeys(const std::vector<std::string>& expected_keys) {
|
| + if (expected_keys.size() != callback_strings_.size())
|
| + return false;
|
| +
|
| + std::set<std::string> found_set;
|
| + for (int i = 0, max = callback_strings_.size(); i < max; ++i)
|
| + found_set.insert(callback_strings_[i]);
|
| +
|
| + for (int i = 0, max = expected_keys.size(); i < max; ++i) {
|
| + if (found_set.find(expected_keys[i]) == found_set.end())
|
| + return false;
|
| + }
|
| + return true;
|
| + }
|
| +
|
| + protected:
|
| + TestBrowserThreadBundle browser_thread_bundle_;
|
| +
|
| + base::ScopedTempDir temp_dir_;
|
| + scoped_ptr<ServiceWorkerFetchStoresManager> stores_;
|
| +
|
| + int callback_bool_;
|
| + int callback_store_;
|
| + ServiceWorkerFetchStores::FetchStoresError callback_error_;
|
| + std::vector<std::string> callback_strings_;
|
| +
|
| + const GURL origin1_;
|
| + const GURL origin2_;
|
| +
|
| + private:
|
| + DISALLOW_COPY_AND_ASSIGN(ServiceWorkerFetchStoresManagerTest);
|
| +};
|
| +
|
| +class ServiceWorkerFetchStoresManagerMemoryOnlyTest
|
| + : public ServiceWorkerFetchStoresManagerTest {
|
| + virtual bool MemoryOnly() OVERRIDE { return true; }
|
| +};
|
| +
|
| +class ServiceWorkerFetchStoresManagerTestP
|
| + : public ServiceWorkerFetchStoresManagerTest,
|
| + public testing::WithParamInterface<bool> {
|
| + virtual bool MemoryOnly() OVERRIDE { return !GetParam(); }
|
| +};
|
| +
|
| +TEST_F(ServiceWorkerFetchStoresManagerTest, TestsRunOnIOThread) {
|
| + EXPECT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO));
|
| +}
|
| +
|
| +TEST_P(ServiceWorkerFetchStoresManagerTestP, CreateStore) {
|
| + EXPECT_TRUE(CreateStore(origin1_, "foo"));
|
| +}
|
| +
|
| +TEST_P(ServiceWorkerFetchStoresManagerTestP, CreateDuplicateStore) {
|
| + EXPECT_TRUE(CreateStore(origin1_, "foo"));
|
| + EXPECT_FALSE(CreateStore(origin1_, "foo"));
|
| + EXPECT_EQ(ServiceWorkerFetchStores::FETCH_STORES_ERROR_EXISTS,
|
| + callback_error_);
|
| +}
|
| +
|
| +TEST_P(ServiceWorkerFetchStoresManagerTestP, Create2Stores) {
|
| + EXPECT_TRUE(CreateStore(origin1_, "foo"));
|
| + EXPECT_TRUE(CreateStore(origin1_, "bar"));
|
| +}
|
| +
|
| +TEST_P(ServiceWorkerFetchStoresManagerTestP, Create2StoresSameNameDiffSWs) {
|
| + EXPECT_TRUE(CreateStore(origin1_, "foo"));
|
| + EXPECT_TRUE(CreateStore(origin2_, "foo"));
|
| +}
|
| +
|
| +TEST_P(ServiceWorkerFetchStoresManagerTestP, GetStore) {
|
| + EXPECT_TRUE(CreateStore(origin1_, "foo"));
|
| + int store = callback_store_;
|
| + EXPECT_TRUE(Get(origin1_, "foo"));
|
| + EXPECT_EQ(store, callback_store_);
|
| +}
|
| +
|
| +TEST_P(ServiceWorkerFetchStoresManagerTestP, GetNonExistent) {
|
| + EXPECT_FALSE(Get(origin1_, "foo"));
|
| + EXPECT_EQ(ServiceWorkerFetchStores::FETCH_STORES_ERROR_NOT_FOUND,
|
| + callback_error_);
|
| +}
|
| +
|
| +TEST_P(ServiceWorkerFetchStoresManagerTestP, HasStore) {
|
| + EXPECT_TRUE(CreateStore(origin1_, "foo"));
|
| + EXPECT_TRUE(Has(origin1_, "foo"));
|
| + EXPECT_TRUE(callback_bool_);
|
| +}
|
| +
|
| +TEST_P(ServiceWorkerFetchStoresManagerTestP, HasNonExistent) {
|
| + EXPECT_FALSE(Has(origin1_, "foo"));
|
| +}
|
| +
|
| +TEST_P(ServiceWorkerFetchStoresManagerTestP, DeleteStore) {
|
| + EXPECT_TRUE(CreateStore(origin1_, "foo"));
|
| + EXPECT_TRUE(Delete(origin1_, "foo"));
|
| + EXPECT_FALSE(Get(origin1_, "foo"));
|
| + EXPECT_EQ(ServiceWorkerFetchStores::FETCH_STORES_ERROR_NOT_FOUND,
|
| + callback_error_);
|
| +}
|
| +
|
| +TEST_P(ServiceWorkerFetchStoresManagerTestP, DeleteTwice) {
|
| + EXPECT_TRUE(CreateStore(origin1_, "foo"));
|
| + EXPECT_TRUE(Delete(origin1_, "foo"));
|
| + EXPECT_FALSE(Delete(origin1_, "foo"));
|
| + EXPECT_EQ(ServiceWorkerFetchStores::FETCH_STORES_ERROR_NOT_FOUND,
|
| + callback_error_);
|
| +}
|
| +
|
| +TEST_P(ServiceWorkerFetchStoresManagerTestP, EmptyKeys) {
|
| + EXPECT_TRUE(Keys(origin1_));
|
| + EXPECT_TRUE(callback_strings_.empty());
|
| +}
|
| +
|
| +TEST_P(ServiceWorkerFetchStoresManagerTestP, SomeKeys) {
|
| + EXPECT_TRUE(CreateStore(origin1_, "foo"));
|
| + EXPECT_TRUE(CreateStore(origin1_, "bar"));
|
| + EXPECT_TRUE(CreateStore(origin2_, "baz"));
|
| + EXPECT_TRUE(Keys(origin1_));
|
| + EXPECT_EQ(2u, callback_strings_.size());
|
| + std::vector<std::string> expected_keys;
|
| + expected_keys.push_back("foo");
|
| + expected_keys.push_back("bar");
|
| + EXPECT_TRUE(VerifyKeys(expected_keys));
|
| + EXPECT_TRUE(Keys(origin2_));
|
| + EXPECT_EQ(1u, callback_strings_.size());
|
| + EXPECT_STREQ("baz", callback_strings_[0].c_str());
|
| +}
|
| +
|
| +TEST_P(ServiceWorkerFetchStoresManagerTestP, DeletedKeysGone) {
|
| + EXPECT_TRUE(CreateStore(origin1_, "foo"));
|
| + EXPECT_TRUE(CreateStore(origin1_, "bar"));
|
| + EXPECT_TRUE(CreateStore(origin2_, "baz"));
|
| + EXPECT_TRUE(Delete(origin1_, "bar"));
|
| + EXPECT_TRUE(Keys(origin1_));
|
| + EXPECT_EQ(1u, callback_strings_.size());
|
| + EXPECT_STREQ("foo", callback_strings_[0].c_str());
|
| +}
|
| +
|
| +TEST_P(ServiceWorkerFetchStoresManagerTestP, Chinese) {
|
| + EXPECT_TRUE(CreateStore(origin1_, "你好"));
|
| + int store = callback_store_;
|
| + EXPECT_TRUE(Get(origin1_, "你好"));
|
| + EXPECT_EQ(store, callback_store_);
|
| + EXPECT_TRUE(Keys(origin1_));
|
| + EXPECT_EQ(1u, callback_strings_.size());
|
| + EXPECT_TRUE("你好" == callback_strings_[0]);
|
| +}
|
| +
|
| +TEST_F(ServiceWorkerFetchStoresManagerTest, EmptyKey) {
|
| + EXPECT_FALSE(CreateStore(origin1_, ""));
|
| + EXPECT_EQ(ServiceWorkerFetchStores::FETCH_STORES_ERROR_EMPTY_KEY,
|
| + callback_error_);
|
| +
|
| + EXPECT_FALSE(Get(origin1_, ""));
|
| + EXPECT_EQ(ServiceWorkerFetchStores::FETCH_STORES_ERROR_EMPTY_KEY,
|
| + callback_error_);
|
| +
|
| + EXPECT_FALSE(Has(origin1_, ""));
|
| + EXPECT_EQ(ServiceWorkerFetchStores::FETCH_STORES_ERROR_EMPTY_KEY,
|
| + callback_error_);
|
| +
|
| + EXPECT_FALSE(Delete(origin1_, ""));
|
| + EXPECT_EQ(ServiceWorkerFetchStores::FETCH_STORES_ERROR_EMPTY_KEY,
|
| + callback_error_);
|
| +}
|
| +
|
| +TEST_F(ServiceWorkerFetchStoresManagerTest, DataPersists) {
|
| + EXPECT_TRUE(CreateStore(origin1_, "foo"));
|
| + EXPECT_TRUE(CreateStore(origin1_, "bar"));
|
| + EXPECT_TRUE(CreateStore(origin1_, "baz"));
|
| + EXPECT_TRUE(CreateStore(origin2_, "raz"));
|
| + EXPECT_TRUE(Delete(origin1_, "bar"));
|
| + stores_ = ServiceWorkerFetchStoresManager::Create(stores_.get());
|
| + EXPECT_TRUE(Keys(origin1_));
|
| + EXPECT_EQ(2u, callback_strings_.size());
|
| + std::vector<std::string> expected_keys;
|
| + expected_keys.push_back("foo");
|
| + expected_keys.push_back("baz");
|
| + EXPECT_TRUE(VerifyKeys(expected_keys));
|
| +}
|
| +
|
| +TEST_F(ServiceWorkerFetchStoresManagerMemoryOnlyTest, DataLostWhenMemoryOnly) {
|
| + EXPECT_TRUE(CreateStore(origin1_, "foo"));
|
| + EXPECT_TRUE(CreateStore(origin2_, "baz"));
|
| + stores_ = ServiceWorkerFetchStoresManager::Create(stores_.get());
|
| + EXPECT_TRUE(Keys(origin1_));
|
| + EXPECT_EQ(0u, callback_strings_.size());
|
| +}
|
| +
|
| +TEST_F(ServiceWorkerFetchStoresManagerTest, BadStoreName) {
|
| + // Since the implementation writes store names to disk, ensure that we don't
|
| + // escape the directory.
|
| + const std::string bad_name = "../../../../../../../../../../../../../../foo";
|
| + EXPECT_TRUE(CreateStore(origin1_, bad_name));
|
| + EXPECT_TRUE(Keys(origin1_));
|
| + EXPECT_EQ(1u, callback_strings_.size());
|
| + EXPECT_STREQ(bad_name.c_str(), callback_strings_[0].c_str());
|
| +}
|
| +
|
| +TEST_F(ServiceWorkerFetchStoresManagerTest, BadOriginName) {
|
| + // Since the implementation writes origin names to disk, ensure that we don't
|
| + // escape the directory.
|
| + GURL bad_origin("../../../../../../../../../../../../../../foo");
|
| + EXPECT_TRUE(CreateStore(bad_origin, "foo"));
|
| + EXPECT_TRUE(Keys(bad_origin));
|
| + EXPECT_EQ(1u, callback_strings_.size());
|
| + EXPECT_STREQ("foo", callback_strings_[0].c_str());
|
| +}
|
| +
|
| +INSTANTIATE_TEST_CASE_P(ServiceWorkerFetchStoresManagerTests,
|
| + ServiceWorkerFetchStoresManagerTestP,
|
| + ::testing::Values(false, true));
|
| +
|
| +} // namespace content
|
|
|