blob: 5a1c2728eb07558e3449ef39844f974de8737fed [file] [log] [blame]
// 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 <stdint.h>
#include <vector>
#include "base/files/scoped_temp_dir.h"
#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "base/threading/thread_task_runner_handle.h"
#include "net/base/url_util.h"
#include "storage/browser/quota/quota_manager.h"
#include "storage/browser/quota/quota_manager_proxy.h"
#include "storage/browser/quota/storage_monitor.h"
#include "storage/browser/quota/storage_observer.h"
#include "storage/browser/test/mock_special_storage_policy.h"
#include "storage/browser/test/mock_storage_client.h"
#include "testing/gtest/include/gtest/gtest.h"
using storage::HostStorageObservers;
using storage::kQuotaErrorNotSupported;
using storage::kQuotaStatusOk;
using storage::kStorageTypePersistent;
using storage::kStorageTypeTemporary;
using storage::QuotaClient;
using storage::QuotaManager;
using storage::QuotaStatusCode;
using storage::SpecialStoragePolicy;
using storage::StorageMonitor;
using storage::StorageObserver;
using storage::StorageObserverList;
using storage::StorageType;
using storage::StorageTypeObservers;
namespace content {
namespace {
const char kDefaultOrigin[] = "http://www.foo.com/";
const char kAlternativeOrigin[] = "http://www.bar.com/";
class MockObserver : public StorageObserver {
public:
const StorageObserver::Event& LastEvent() const {
CHECK(!events_.empty());
return events_.back();
}
int EventCount() const {
return events_.size();
}
// StorageObserver implementation:
void OnStorageEvent(const StorageObserver::Event& event) override {
events_.push_back(event);
}
private:
std::vector<StorageObserver::Event> events_;
};
// A mock quota manager for overriding GetUsageAndQuotaForWebApps().
class UsageMockQuotaManager : public QuotaManager {
public:
UsageMockQuotaManager(SpecialStoragePolicy* special_storage_policy)
: QuotaManager(false,
base::FilePath(),
base::ThreadTaskRunnerHandle::Get().get(),
base::ThreadTaskRunnerHandle::Get().get(),
special_storage_policy,
storage::GetQuotaSettingsFunc()),
callback_usage_(0),
callback_quota_(0),
callback_status_(kQuotaStatusOk),
initialized_(false) {}
void SetCallbackParams(int64_t usage, int64_t quota, QuotaStatusCode status) {
initialized_ = true;
callback_quota_ = quota;
callback_usage_ = usage;
callback_status_ = status;
}
void InvokeCallback() {
delayed_callback_.Run(callback_status_, callback_usage_, callback_quota_);
}
void GetUsageAndQuotaForWebApps(
const GURL& origin,
StorageType type,
const UsageAndQuotaCallback& callback) override {
if (initialized_)
callback.Run(callback_status_, callback_usage_, callback_quota_);
else
delayed_callback_ = callback;
}
protected:
~UsageMockQuotaManager() override {}
private:
int64_t callback_usage_;
int64_t callback_quota_;
QuotaStatusCode callback_status_;
bool initialized_;
UsageAndQuotaCallback delayed_callback_;
};
} // namespace
class StorageMonitorTestBase : public testing::Test {
protected:
void DispatchPendingEvents(StorageObserverList& observer_list) {
observer_list.DispatchPendingEvent();
}
const StorageObserver::Event* GetPendingEvent(
const StorageObserverList& observer_list) {
return observer_list.notification_timer_.IsRunning()
? &observer_list.pending_event_ : NULL;
}
const StorageObserver::Event* GetPendingEvent(
const HostStorageObservers& host_observers) {
return GetPendingEvent(host_observers.observers_);
}
int GetRequiredUpdatesCount(const StorageObserverList& observer_list) {
int count = 0;
for (StorageObserverList::StorageObserverStateMap::const_iterator it =
observer_list.observers_.begin();
it != observer_list.observers_.end(); ++it) {
if (it->second.requires_update)
++count;
}
return count;
}
int GetRequiredUpdatesCount(const HostStorageObservers& host_observers) {
return GetRequiredUpdatesCount(host_observers.observers_);
}
void SetLastNotificationTime(StorageObserverList& observer_list,
StorageObserver* observer) {
ASSERT_TRUE(observer_list.observers_.find(observer) !=
observer_list.observers_.end());
StorageObserverList::ObserverState& state =
observer_list.observers_[observer];
state.last_notification_time = base::TimeTicks::Now() - state.rate;
}
void SetLastNotificationTime(HostStorageObservers& host_observers,
StorageObserver* observer) {
SetLastNotificationTime(host_observers.observers_, observer);
}
int GetObserverCount(const HostStorageObservers& host_observers) {
return host_observers.observers_.ObserverCount();
}
};
class StorageTestWithManagerBase : public StorageMonitorTestBase {
public:
void SetUp() override {
storage_policy_ = new MockSpecialStoragePolicy();
quota_manager_ = new UsageMockQuotaManager(storage_policy_.get());
}
void TearDown() override {
// This ensures the quota manager is destroyed correctly.
quota_manager_ = NULL;
base::RunLoop().RunUntilIdle();
}
protected:
base::MessageLoop message_loop_;
scoped_refptr<MockSpecialStoragePolicy> storage_policy_;
scoped_refptr<UsageMockQuotaManager> quota_manager_;
};
// Tests for StorageObserverList:
typedef StorageMonitorTestBase StorageObserverListTest;
// Test dispatching events to one observer.
TEST_F(StorageObserverListTest, DispatchEventToSingleObserver) {
// A message loop is required as StorageObserverList may schedule jobs.
base::MessageLoop loop(base::MessageLoop::TYPE_DEFAULT);
StorageObserver::MonitorParams params(kStorageTypePersistent,
GURL(kDefaultOrigin),
base::TimeDelta::FromHours(1),
false);
MockObserver mock_observer;
StorageObserverList observer_list;
observer_list.AddObserver(&mock_observer, params);
StorageObserver::Event event;
event.filter = params.filter;
// Verify that the first event is dispatched immediately.
event.quota = 1;
event.usage = 1;
observer_list.OnStorageChange(event);
EXPECT_EQ(1, mock_observer.EventCount());
EXPECT_EQ(event, mock_observer.LastEvent());
EXPECT_EQ(NULL, GetPendingEvent(observer_list));
EXPECT_EQ(0, GetRequiredUpdatesCount(observer_list));
// Verify that the next event is pending.
event.quota = 2;
event.usage = 2;
observer_list.OnStorageChange(event);
EXPECT_EQ(1, mock_observer.EventCount());
ASSERT_TRUE(GetPendingEvent(observer_list));
EXPECT_EQ(event, *GetPendingEvent(observer_list));
EXPECT_EQ(1, GetRequiredUpdatesCount(observer_list));
// Fake the last notification time so that an event will be dispatched.
SetLastNotificationTime(observer_list, &mock_observer);
event.quota = 3;
event.usage = 3;
observer_list.OnStorageChange(event);
EXPECT_EQ(2, mock_observer.EventCount());
EXPECT_EQ(event, mock_observer.LastEvent());
EXPECT_EQ(NULL, GetPendingEvent(observer_list));
EXPECT_EQ(0, GetRequiredUpdatesCount(observer_list));
// Remove the observer.
event.quota = 4;
event.usage = 4;
observer_list.RemoveObserver(&mock_observer);
observer_list.OnStorageChange(event);
EXPECT_EQ(2, mock_observer.EventCount());
EXPECT_EQ(NULL, GetPendingEvent(observer_list));
}
// Test dispatching events to multiple observers.
TEST_F(StorageObserverListTest, DispatchEventToMultipleObservers) {
// A message loop is required as StorageObserverList may schedule jobs.
base::MessageLoop loop(base::MessageLoop::TYPE_DEFAULT);
MockObserver mock_observer1;
MockObserver mock_observer2;
StorageObserverList observer_list;
StorageObserver::Filter filter(kStorageTypePersistent,
GURL(kDefaultOrigin));
observer_list.AddObserver(
&mock_observer1,
StorageObserver::MonitorParams(
filter, base::TimeDelta::FromHours(1), false));
observer_list.AddObserver(
&mock_observer2,
StorageObserver::MonitorParams(
filter, base::TimeDelta::FromHours(2), false));
StorageObserver::Event event;
event.filter = filter;
// Verify that the first event is dispatched immediately.
event.quota = 1;
event.usage = 1;
observer_list.OnStorageChange(event);
EXPECT_EQ(1, mock_observer1.EventCount());
EXPECT_EQ(1, mock_observer2.EventCount());
EXPECT_EQ(event, mock_observer1.LastEvent());
EXPECT_EQ(event, mock_observer2.LastEvent());
EXPECT_EQ(NULL, GetPendingEvent(observer_list));
EXPECT_EQ(0, GetRequiredUpdatesCount(observer_list));
// Fake the last notification time so that observer1 will receive the next
// event, but it will be pending for observer2.
SetLastNotificationTime(observer_list, &mock_observer1);
event.quota = 2;
event.usage = 2;
observer_list.OnStorageChange(event);
EXPECT_EQ(2, mock_observer1.EventCount());
EXPECT_EQ(1, mock_observer2.EventCount());
EXPECT_EQ(event, mock_observer1.LastEvent());
ASSERT_TRUE(GetPendingEvent(observer_list));
EXPECT_EQ(event, *GetPendingEvent(observer_list));
EXPECT_EQ(1, GetRequiredUpdatesCount(observer_list));
// Now dispatch the pending event to observer2.
SetLastNotificationTime(observer_list, &mock_observer2);
DispatchPendingEvents(observer_list);
EXPECT_EQ(2, mock_observer1.EventCount());
EXPECT_EQ(2, mock_observer2.EventCount());
EXPECT_EQ(event, mock_observer1.LastEvent());
EXPECT_EQ(event, mock_observer2.LastEvent());
EXPECT_EQ(NULL, GetPendingEvent(observer_list));
EXPECT_EQ(0, GetRequiredUpdatesCount(observer_list));
}
// Ensure that the |origin| field in events match the origin specified by the
// observer on registration.
TEST_F(StorageObserverListTest, ReplaceEventOrigin) {
StorageObserver::MonitorParams params(kStorageTypePersistent,
GURL(kDefaultOrigin),
base::TimeDelta::FromHours(1),
false);
MockObserver mock_observer;
StorageObserverList observer_list;
observer_list.AddObserver(&mock_observer, params);
StorageObserver::Event dispatched_event;
dispatched_event.filter = params.filter;
dispatched_event.filter.origin = GURL("https://www.foo.com/bar");
observer_list.OnStorageChange(dispatched_event);
EXPECT_EQ(params.filter.origin, mock_observer.LastEvent().filter.origin);
}
// Tests for HostStorageObservers:
typedef StorageTestWithManagerBase HostStorageObserversTest;
// Verify that HostStorageObservers is initialized after the first usage change.
TEST_F(HostStorageObserversTest, InitializeOnUsageChange) {
StorageObserver::MonitorParams params(kStorageTypePersistent,
GURL(kDefaultOrigin),
base::TimeDelta::FromHours(1),
false);
const int64_t kUsage = 324554;
const int64_t kQuota = 234354354;
quota_manager_->SetCallbackParams(kUsage, kQuota, kQuotaStatusOk);
MockObserver mock_observer;
HostStorageObservers host_observers(quota_manager_.get());
host_observers.AddObserver(&mock_observer, params);
// Verify that HostStorageObservers dispatches the first event correctly.
StorageObserver::Event expected_event(params.filter, kUsage, kQuota);
host_observers.NotifyUsageChange(params.filter, 87324);
EXPECT_EQ(1, mock_observer.EventCount());
EXPECT_EQ(expected_event, mock_observer.LastEvent());
EXPECT_TRUE(host_observers.is_initialized());
// Verify that HostStorageObservers handles subsequent usage changes
// correctly.
const int64_t kDelta = 2345;
expected_event.usage += kDelta;
SetLastNotificationTime(host_observers, &mock_observer);
host_observers.NotifyUsageChange(params.filter, kDelta);
EXPECT_EQ(2, mock_observer.EventCount());
EXPECT_EQ(expected_event, mock_observer.LastEvent());
}
// Verify that HostStorageObservers is initialized after the adding the first
// observer that elected to receive the initial state.
TEST_F(HostStorageObserversTest, InitializeOnObserver) {
const int64_t kUsage = 74387;
const int64_t kQuota = 92834743;
quota_manager_->SetCallbackParams(kUsage, kQuota, kQuotaStatusOk);
HostStorageObservers host_observers(quota_manager_.get());
// |host_observers| should not be initialized after the first observer is
// added because it did not elect to receive the initial state.
StorageObserver::MonitorParams params(kStorageTypePersistent,
GURL(kDefaultOrigin),
base::TimeDelta::FromHours(1),
false);
MockObserver mock_observer1;
host_observers.AddObserver(&mock_observer1, params);
EXPECT_FALSE(host_observers.is_initialized());
EXPECT_EQ(0, mock_observer1.EventCount());
// |host_observers| should be initialized after the second observer is
// added.
MockObserver mock_observer2;
params.dispatch_initial_state = true;
host_observers.AddObserver(&mock_observer2, params);
StorageObserver::Event expected_event(params.filter, kUsage, kQuota);
EXPECT_EQ(0, mock_observer1.EventCount());
EXPECT_EQ(1, mock_observer2.EventCount());
EXPECT_EQ(expected_event, mock_observer2.LastEvent());
EXPECT_TRUE(host_observers.is_initialized());
EXPECT_EQ(NULL, GetPendingEvent(host_observers));
EXPECT_EQ(0, GetRequiredUpdatesCount(host_observers));
// Verify that both observers will receive events after a usage change.
const int64_t kDelta = 2345;
expected_event.usage += kDelta;
SetLastNotificationTime(host_observers, &mock_observer2);
host_observers.NotifyUsageChange(params.filter, kDelta);
EXPECT_EQ(1, mock_observer1.EventCount());
EXPECT_EQ(2, mock_observer2.EventCount());
EXPECT_EQ(expected_event, mock_observer1.LastEvent());
EXPECT_EQ(expected_event, mock_observer2.LastEvent());
EXPECT_EQ(NULL, GetPendingEvent(host_observers));
EXPECT_EQ(0, GetRequiredUpdatesCount(host_observers));
// Verify that the addition of a third observer only causes an event to be
// dispatched to the new observer.
MockObserver mock_observer3;
params.dispatch_initial_state = true;
host_observers.AddObserver(&mock_observer3, params);
EXPECT_EQ(1, mock_observer1.EventCount());
EXPECT_EQ(2, mock_observer2.EventCount());
EXPECT_EQ(1, mock_observer3.EventCount());
EXPECT_EQ(expected_event, mock_observer3.LastEvent());
}
// Verify that negative usage and quota is changed to zero.
TEST_F(HostStorageObserversTest, NegativeUsageAndQuota) {
StorageObserver::MonitorParams params(kStorageTypePersistent,
GURL(kDefaultOrigin),
base::TimeDelta::FromHours(1),
false);
const int64_t kUsage = -324554;
const int64_t kQuota = -234354354;
quota_manager_->SetCallbackParams(kUsage, kQuota, kQuotaStatusOk);
MockObserver mock_observer;
HostStorageObservers host_observers(quota_manager_.get());
host_observers.AddObserver(&mock_observer, params);
StorageObserver::Event expected_event(params.filter, 0, 0);
host_observers.NotifyUsageChange(params.filter, -87324);
EXPECT_EQ(expected_event, mock_observer.LastEvent());
}
// Verify that HostStorageObservers can recover from a bad initialization.
TEST_F(HostStorageObserversTest, RecoverFromBadUsageInit) {
StorageObserver::MonitorParams params(kStorageTypePersistent,
GURL(kDefaultOrigin),
base::TimeDelta::FromHours(1),
false);
MockObserver mock_observer;
HostStorageObservers host_observers(quota_manager_.get());
host_observers.AddObserver(&mock_observer, params);
// Set up the quota manager to return an error status.
const int64_t kUsage = 6656;
const int64_t kQuota = 99585556;
quota_manager_->SetCallbackParams(kUsage, kQuota, kQuotaErrorNotSupported);
// Verify that |host_observers| is not initialized and an event has not been
// dispatched.
host_observers.NotifyUsageChange(params.filter, 9438);
EXPECT_EQ(0, mock_observer.EventCount());
EXPECT_FALSE(host_observers.is_initialized());
EXPECT_EQ(NULL, GetPendingEvent(host_observers));
EXPECT_EQ(0, GetRequiredUpdatesCount(host_observers));
// Now ensure that quota manager returns a good status.
quota_manager_->SetCallbackParams(kUsage, kQuota, kQuotaStatusOk);
host_observers.NotifyUsageChange(params.filter, 9048543);
StorageObserver::Event expected_event(params.filter, kUsage, kQuota);
EXPECT_EQ(1, mock_observer.EventCount());
EXPECT_EQ(expected_event, mock_observer.LastEvent());
EXPECT_TRUE(host_observers.is_initialized());
}
// Verify that HostStorageObservers handle initialization of the cached usage
// and quota correctly.
TEST_F(HostStorageObserversTest, AsyncInitialization) {
StorageObserver::MonitorParams params(kStorageTypePersistent,
GURL(kDefaultOrigin),
base::TimeDelta::FromHours(1),
false);
MockObserver mock_observer;
HostStorageObservers host_observers(quota_manager_.get());
host_observers.AddObserver(&mock_observer, params);
// Trigger initialization. Leave the mock quota manager uninitialized so that
// the callback is not invoked.
host_observers.NotifyUsageChange(params.filter, 7645);
EXPECT_EQ(0, mock_observer.EventCount());
EXPECT_FALSE(host_observers.is_initialized());
EXPECT_EQ(NULL, GetPendingEvent(host_observers));
EXPECT_EQ(0, GetRequiredUpdatesCount(host_observers));
// Simulate notifying |host_observers| of a usage change before initialization
// is complete.
const int64_t kUsage = 6656;
const int64_t kQuota = 99585556;
const int64_t kDelta = 327643;
host_observers.NotifyUsageChange(params.filter, kDelta);
EXPECT_EQ(0, mock_observer.EventCount());
EXPECT_FALSE(host_observers.is_initialized());
EXPECT_EQ(NULL, GetPendingEvent(host_observers));
EXPECT_EQ(0, GetRequiredUpdatesCount(host_observers));
// Simulate an asynchronous callback from QuotaManager.
quota_manager_->SetCallbackParams(kUsage, kQuota, kQuotaStatusOk);
quota_manager_->InvokeCallback();
StorageObserver::Event expected_event(params.filter, kUsage + kDelta, kQuota);
EXPECT_EQ(1, mock_observer.EventCount());
EXPECT_EQ(expected_event, mock_observer.LastEvent());
EXPECT_TRUE(host_observers.is_initialized());
EXPECT_EQ(NULL, GetPendingEvent(host_observers));
EXPECT_EQ(0, GetRequiredUpdatesCount(host_observers));
}
// Tests for StorageTypeObservers:
typedef StorageTestWithManagerBase StorageTypeObserversTest;
// Test adding and removing observers.
TEST_F(StorageTypeObserversTest, AddRemoveObservers) {
StorageTypeObservers type_observers(quota_manager_.get());
StorageObserver::MonitorParams params1(kStorageTypePersistent,
GURL(kDefaultOrigin),
base::TimeDelta::FromHours(1),
false);
StorageObserver::MonitorParams params2(kStorageTypePersistent,
GURL(kAlternativeOrigin),
base::TimeDelta::FromHours(1),
false);
std::string host1 = net::GetHostOrSpecFromURL(params1.filter.origin);
std::string host2 = net::GetHostOrSpecFromURL(params2.filter.origin);
MockObserver mock_observer1;
MockObserver mock_observer2;
MockObserver mock_observer3;
type_observers.AddObserver(&mock_observer1, params1);
type_observers.AddObserver(&mock_observer2, params1);
type_observers.AddObserver(&mock_observer1, params2);
type_observers.AddObserver(&mock_observer2, params2);
type_observers.AddObserver(&mock_observer3, params2);
// Verify that the observers have been removed correctly.
ASSERT_TRUE(type_observers.GetHostObservers(host1));
ASSERT_TRUE(type_observers.GetHostObservers(host2));
EXPECT_EQ(2, GetObserverCount(*type_observers.GetHostObservers(host1)));
EXPECT_EQ(3, GetObserverCount(*type_observers.GetHostObservers(host2)));
// Remove all instances of observer1.
type_observers.RemoveObserver(&mock_observer1);
ASSERT_TRUE(type_observers.GetHostObservers(host1));
ASSERT_TRUE(type_observers.GetHostObservers(host2));
EXPECT_EQ(1, GetObserverCount(*type_observers.GetHostObservers(host1)));
EXPECT_EQ(2, GetObserverCount(*type_observers.GetHostObservers(host2)));
// Remove all instances of observer2.
type_observers.RemoveObserver(&mock_observer2);
ASSERT_TRUE(type_observers.GetHostObservers(host2));
EXPECT_EQ(1, GetObserverCount(*type_observers.GetHostObservers(host2)));
// Observers of host1 has been deleted as it is empty.
EXPECT_FALSE(type_observers.GetHostObservers(host1));
}
// Tests for StorageMonitor:
class StorageMonitorTest : public StorageTestWithManagerBase {
public:
StorageMonitorTest()
: storage_monitor_(NULL),
params1_(kStorageTypeTemporary,
GURL(kDefaultOrigin),
base::TimeDelta::FromHours(1),
false),
params2_(kStorageTypePersistent,
GURL(kDefaultOrigin),
base::TimeDelta::FromHours(1),
false) {
}
protected:
void SetUp() override {
StorageTestWithManagerBase::SetUp();
storage_monitor_ = quota_manager_->storage_monitor_.get();
host_ = net::GetHostOrSpecFromURL(params1_.filter.origin);
storage_monitor_->AddObserver(&mock_observer1_, params1_);
storage_monitor_->AddObserver(&mock_observer2_, params1_);
storage_monitor_->AddObserver(&mock_observer1_, params2_);
storage_monitor_->AddObserver(&mock_observer2_, params2_);
storage_monitor_->AddObserver(&mock_observer3_, params2_);
}
int GetObserverCount(StorageType storage_type) {
const StorageTypeObservers* type_observers =
storage_monitor_->GetStorageTypeObservers(storage_type);
return StorageMonitorTestBase::GetObserverCount(
*type_observers->GetHostObservers(host_));
}
void CheckObserverCount(int expected_temporary, int expected_persistent) {
ASSERT_TRUE(storage_monitor_->GetStorageTypeObservers(
kStorageTypeTemporary));
ASSERT_TRUE(storage_monitor_->GetStorageTypeObservers(
kStorageTypeTemporary)->GetHostObservers(host_));
EXPECT_EQ(expected_temporary, GetObserverCount(kStorageTypeTemporary));
ASSERT_TRUE(storage_monitor_->GetStorageTypeObservers(
kStorageTypePersistent));
ASSERT_TRUE(storage_monitor_->GetStorageTypeObservers(
kStorageTypePersistent)->GetHostObservers(host_));
EXPECT_EQ(expected_persistent, GetObserverCount(kStorageTypePersistent));
}
StorageMonitor* storage_monitor_;
StorageObserver::MonitorParams params1_;
StorageObserver::MonitorParams params2_;
MockObserver mock_observer1_;
MockObserver mock_observer2_;
MockObserver mock_observer3_;
std::string host_;
};
// Test adding storage observers.
TEST_F(StorageMonitorTest, AddObservers) {
// Verify that the observers are added correctly.
CheckObserverCount(2, 3);
}
// Test dispatching events to storage observers.
TEST_F(StorageMonitorTest, EventDispatch) {
// Verify dispatch of events.
const int64_t kUsage = 5325;
const int64_t kQuota = 903845;
quota_manager_->SetCallbackParams(kUsage, kQuota, kQuotaStatusOk);
storage_monitor_->NotifyUsageChange(params1_.filter, 9048543);
StorageObserver::Event expected_event(params1_.filter, kUsage, kQuota);
EXPECT_EQ(1, mock_observer1_.EventCount());
EXPECT_EQ(1, mock_observer2_.EventCount());
EXPECT_EQ(0, mock_observer3_.EventCount());
EXPECT_EQ(expected_event, mock_observer1_.LastEvent());
EXPECT_EQ(expected_event, mock_observer2_.LastEvent());
}
// Test removing all instances of an observer.
TEST_F(StorageMonitorTest, RemoveObserver) {
storage_monitor_->RemoveObserver(&mock_observer1_);
CheckObserverCount(1, 2);
}
// Integration test for QuotaManager and StorageMonitor:
class StorageMonitorIntegrationTest : public testing::Test {
public:
void SetUp() override {
ASSERT_TRUE(data_dir_.CreateUniqueTempDir());
storage_policy_ = new MockSpecialStoragePolicy();
quota_manager_ = new QuotaManager(
false, data_dir_.GetPath(), base::ThreadTaskRunnerHandle::Get().get(),
base::ThreadTaskRunnerHandle::Get().get(), storage_policy_.get(),
storage::GetQuotaSettingsFunc());
client_ = new MockStorageClient(quota_manager_->proxy(),
NULL,
QuotaClient::kFileSystem,
0);
quota_manager_->proxy()->RegisterClient(client_);
}
void TearDown() override {
// This ensures the quota manager is destroyed correctly.
quota_manager_ = NULL;
base::RunLoop().RunUntilIdle();
}
protected:
base::MessageLoop message_loop_;
base::ScopedTempDir data_dir_;
scoped_refptr<MockSpecialStoragePolicy> storage_policy_;
scoped_refptr<QuotaManager> quota_manager_;
MockStorageClient* client_;
};
// This test simulates a usage change in a quota client and verifies that a
// storage observer will receive a storage event.
TEST_F(StorageMonitorIntegrationTest, NotifyUsageEvent) {
const StorageType kTestStorageType = kStorageTypePersistent;
const int64_t kTestUsage = 234743;
// Register the observer.
StorageObserver::MonitorParams params(kTestStorageType,
GURL(kDefaultOrigin),
base::TimeDelta::FromHours(1),
false);
MockObserver mock_observer;
quota_manager_->AddStorageObserver(&mock_observer, params);
// Fire a usage change.
client_->AddOriginAndNotify(GURL(kDefaultOrigin),
kTestStorageType,
kTestUsage);
base::RunLoop().RunUntilIdle();
// Verify that the observer receives it.
ASSERT_EQ(1, mock_observer.EventCount());
const StorageObserver::Event& event = mock_observer.LastEvent();
EXPECT_EQ(params.filter, event.filter);
EXPECT_EQ(kTestUsage, event.usage);
}
} // namespace content