Home | History | Annotate | Download | only in quota
      1 // Copyright 2014 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include <vector>
      6 
      7 #include "base/files/scoped_temp_dir.h"
      8 #include "base/message_loop/message_loop.h"
      9 #include "base/message_loop/message_loop_proxy.h"
     10 #include "base/run_loop.h"
     11 #include "content/public/test/mock_special_storage_policy.h"
     12 #include "content/public/test/mock_storage_client.h"
     13 #include "net/base/net_util.h"
     14 #include "storage/browser/quota/quota_manager.h"
     15 #include "storage/browser/quota/quota_manager_proxy.h"
     16 #include "storage/browser/quota/storage_monitor.h"
     17 #include "storage/browser/quota/storage_observer.h"
     18 #include "testing/gtest/include/gtest/gtest.h"
     19 
     20 using storage::HostStorageObservers;
     21 using storage::kQuotaErrorNotSupported;
     22 using storage::kQuotaStatusOk;
     23 using storage::kStorageTypePersistent;
     24 using storage::kStorageTypeTemporary;
     25 using storage::QuotaClient;
     26 using storage::QuotaManager;
     27 using storage::QuotaStatusCode;
     28 using storage::SpecialStoragePolicy;
     29 using storage::StorageMonitor;
     30 using storage::StorageObserver;
     31 using storage::StorageObserverList;
     32 using storage::StorageType;
     33 using storage::StorageTypeObservers;
     34 
     35 namespace content {
     36 
     37 namespace {
     38 
     39 const char kDefaultOrigin[] = "http://www.foo.com/";
     40 const char kAlternativeOrigin[] = "http://www.bar.com/";
     41 
     42 class MockObserver : public StorageObserver {
     43  public:
     44   const StorageObserver::Event& LastEvent() const {
     45     CHECK(!events_.empty());
     46     return events_.back();
     47   }
     48 
     49   int EventCount() const {
     50     return events_.size();
     51   }
     52 
     53   // StorageObserver implementation:
     54   virtual void OnStorageEvent(const StorageObserver::Event& event) OVERRIDE {
     55     events_.push_back(event);
     56   }
     57 
     58  private:
     59   std::vector<StorageObserver::Event> events_;
     60 };
     61 
     62 // A mock quota manager for overriding GetUsageAndQuotaForWebApps().
     63 class UsageMockQuotaManager : public QuotaManager {
     64  public:
     65   UsageMockQuotaManager(SpecialStoragePolicy* special_storage_policy)
     66       : QuotaManager(
     67             false,
     68             base::FilePath(),
     69             base::MessageLoopProxy::current().get(),
     70             base::MessageLoopProxy::current().get(),
     71             special_storage_policy),
     72         callback_usage_(0),
     73         callback_quota_(0),
     74         callback_status_(kQuotaStatusOk),
     75         initialized_(false) {
     76   }
     77 
     78   void SetCallbackParams(int64 usage, int64 quota, QuotaStatusCode status) {
     79     initialized_ = true;
     80     callback_quota_ = quota;
     81     callback_usage_ = usage;
     82     callback_status_ = status;
     83   }
     84 
     85   void InvokeCallback() {
     86     delayed_callback_.Run(callback_status_, callback_usage_, callback_quota_);
     87   }
     88 
     89   virtual void GetUsageAndQuotaForWebApps(
     90       const GURL& origin,
     91       StorageType type,
     92       const GetUsageAndQuotaCallback& callback) OVERRIDE {
     93     if (initialized_)
     94       callback.Run(callback_status_, callback_usage_, callback_quota_);
     95     else
     96       delayed_callback_ = callback;
     97   }
     98 
     99  protected:
    100   virtual ~UsageMockQuotaManager() {}
    101 
    102  private:
    103   int64 callback_usage_;
    104   int64 callback_quota_;
    105   QuotaStatusCode callback_status_;
    106   bool initialized_;
    107   GetUsageAndQuotaCallback delayed_callback_;
    108 };
    109 
    110 }  // namespace
    111 
    112 class StorageMonitorTestBase : public testing::Test {
    113  protected:
    114   void DispatchPendingEvents(StorageObserverList& observer_list) {
    115     observer_list.DispatchPendingEvent();
    116   }
    117 
    118   const StorageObserver::Event* GetPendingEvent(
    119       const StorageObserverList& observer_list) {
    120     return observer_list.notification_timer_.IsRunning()
    121                 ? &observer_list.pending_event_ : NULL;
    122   }
    123 
    124   const StorageObserver::Event* GetPendingEvent(
    125       const HostStorageObservers& host_observers) {
    126     return GetPendingEvent(host_observers.observers_);
    127   }
    128 
    129   int GetRequiredUpdatesCount(const StorageObserverList& observer_list) {
    130     int count = 0;
    131     for (StorageObserverList::StorageObserverStateMap::const_iterator it =
    132             observer_list.observers_.begin();
    133          it != observer_list.observers_.end(); ++it) {
    134       if (it->second.requires_update)
    135         ++count;
    136     }
    137 
    138     return count;
    139   }
    140 
    141   int GetRequiredUpdatesCount(const HostStorageObservers& host_observers) {
    142     return GetRequiredUpdatesCount(host_observers.observers_);
    143   }
    144 
    145   void SetLastNotificationTime(StorageObserverList& observer_list,
    146                                StorageObserver* observer) {
    147     ASSERT_TRUE(observer_list.observers_.find(observer) !=
    148                 observer_list.observers_.end());
    149 
    150     StorageObserverList::ObserverState& state =
    151         observer_list.observers_[observer];
    152     state.last_notification_time = base::TimeTicks::Now() - state.rate;
    153   }
    154 
    155   void SetLastNotificationTime(HostStorageObservers& host_observers,
    156                                StorageObserver* observer) {
    157     SetLastNotificationTime(host_observers.observers_, observer);
    158   }
    159 
    160   int GetObserverCount(const HostStorageObservers& host_observers) {
    161     return host_observers.observers_.ObserverCount();
    162   }
    163 };
    164 
    165 class StorageTestWithManagerBase : public StorageMonitorTestBase {
    166  public:
    167   virtual void SetUp() OVERRIDE {
    168     storage_policy_ = new MockSpecialStoragePolicy();
    169     quota_manager_ = new UsageMockQuotaManager(storage_policy_.get());
    170   }
    171 
    172   virtual void TearDown() OVERRIDE {
    173     // This ensures the quota manager is destroyed correctly.
    174     quota_manager_ = NULL;
    175     base::RunLoop().RunUntilIdle();
    176   }
    177 
    178  protected:
    179   base::MessageLoop message_loop_;
    180   scoped_refptr<MockSpecialStoragePolicy> storage_policy_;
    181   scoped_refptr<UsageMockQuotaManager> quota_manager_;
    182 };
    183 
    184 // Tests for StorageObserverList:
    185 
    186 typedef StorageMonitorTestBase StorageObserverListTest;
    187 
    188 // Test dispatching events to one observer.
    189 TEST_F(StorageObserverListTest, DispatchEventToSingleObserver) {
    190   // A message loop is required as StorageObserverList may schedule jobs.
    191   base::MessageLoop loop(base::MessageLoop::TYPE_DEFAULT);
    192 
    193   StorageObserver::MonitorParams params(kStorageTypePersistent,
    194                                         GURL(kDefaultOrigin),
    195                                         base::TimeDelta::FromHours(1),
    196                                         false);
    197   MockObserver mock_observer;
    198   StorageObserverList observer_list;
    199   observer_list.AddObserver(&mock_observer, params);
    200 
    201   StorageObserver::Event event;
    202   event.filter = params.filter;
    203 
    204   // Verify that the first event is dispatched immediately.
    205   event.quota = 1;
    206   event.usage = 1;
    207   observer_list.OnStorageChange(event);
    208   EXPECT_EQ(1, mock_observer.EventCount());
    209   EXPECT_EQ(event, mock_observer.LastEvent());
    210   EXPECT_EQ(NULL, GetPendingEvent(observer_list));
    211   EXPECT_EQ(0, GetRequiredUpdatesCount(observer_list));
    212 
    213   // Verify that the next event is pending.
    214   event.quota = 2;
    215   event.usage = 2;
    216   observer_list.OnStorageChange(event);
    217   EXPECT_EQ(1, mock_observer.EventCount());
    218   ASSERT_TRUE(GetPendingEvent(observer_list));
    219   EXPECT_EQ(event, *GetPendingEvent(observer_list));
    220   EXPECT_EQ(1, GetRequiredUpdatesCount(observer_list));
    221 
    222   // Fake the last notification time so that an event will be dispatched.
    223   SetLastNotificationTime(observer_list, &mock_observer);
    224   event.quota = 3;
    225   event.usage = 3;
    226   observer_list.OnStorageChange(event);
    227   EXPECT_EQ(2, mock_observer.EventCount());
    228   EXPECT_EQ(event, mock_observer.LastEvent());
    229   EXPECT_EQ(NULL, GetPendingEvent(observer_list));
    230   EXPECT_EQ(0, GetRequiredUpdatesCount(observer_list));
    231 
    232   // Remove the observer.
    233   event.quota = 4;
    234   event.usage = 4;
    235   observer_list.RemoveObserver(&mock_observer);
    236   observer_list.OnStorageChange(event);
    237   EXPECT_EQ(2, mock_observer.EventCount());
    238   EXPECT_EQ(NULL, GetPendingEvent(observer_list));
    239 }
    240 
    241 // Test dispatching events to multiple observers.
    242 TEST_F(StorageObserverListTest, DispatchEventToMultipleObservers) {
    243   // A message loop is required as StorageObserverList may schedule jobs.
    244   base::MessageLoop loop(base::MessageLoop::TYPE_DEFAULT);
    245 
    246   MockObserver mock_observer1;
    247   MockObserver mock_observer2;
    248   StorageObserverList observer_list;
    249   StorageObserver::Filter filter(kStorageTypePersistent,
    250                                  GURL(kDefaultOrigin));
    251   observer_list.AddObserver(
    252       &mock_observer1,
    253       StorageObserver::MonitorParams(
    254           filter, base::TimeDelta::FromHours(1), false));
    255   observer_list.AddObserver(
    256       &mock_observer2,
    257       StorageObserver::MonitorParams(
    258           filter, base::TimeDelta::FromHours(2), false));
    259 
    260   StorageObserver::Event event;
    261   event.filter = filter;
    262 
    263   // Verify that the first event is dispatched immediately.
    264   event.quota = 1;
    265   event.usage = 1;
    266   observer_list.OnStorageChange(event);
    267   EXPECT_EQ(1, mock_observer1.EventCount());
    268   EXPECT_EQ(1, mock_observer2.EventCount());
    269   EXPECT_EQ(event, mock_observer1.LastEvent());
    270   EXPECT_EQ(event, mock_observer2.LastEvent());
    271   EXPECT_EQ(NULL, GetPendingEvent(observer_list));
    272   EXPECT_EQ(0, GetRequiredUpdatesCount(observer_list));
    273 
    274   // Fake the last notification time so that observer1 will receive the next
    275   // event, but it will be pending for observer2.
    276   SetLastNotificationTime(observer_list, &mock_observer1);
    277   event.quota = 2;
    278   event.usage = 2;
    279   observer_list.OnStorageChange(event);
    280   EXPECT_EQ(2, mock_observer1.EventCount());
    281   EXPECT_EQ(1, mock_observer2.EventCount());
    282   EXPECT_EQ(event, mock_observer1.LastEvent());
    283   ASSERT_TRUE(GetPendingEvent(observer_list));
    284   EXPECT_EQ(event, *GetPendingEvent(observer_list));
    285   EXPECT_EQ(1, GetRequiredUpdatesCount(observer_list));
    286 
    287   // Now dispatch the pending event to observer2.
    288   SetLastNotificationTime(observer_list, &mock_observer2);
    289   DispatchPendingEvents(observer_list);
    290   EXPECT_EQ(2, mock_observer1.EventCount());
    291   EXPECT_EQ(2, mock_observer2.EventCount());
    292   EXPECT_EQ(event, mock_observer1.LastEvent());
    293   EXPECT_EQ(event, mock_observer2.LastEvent());
    294   EXPECT_EQ(NULL, GetPendingEvent(observer_list));
    295   EXPECT_EQ(0, GetRequiredUpdatesCount(observer_list));
    296 }
    297 
    298 // Ensure that the |origin| field in events match the origin specified by the
    299 // observer on registration.
    300 TEST_F(StorageObserverListTest, ReplaceEventOrigin) {
    301   StorageObserver::MonitorParams params(kStorageTypePersistent,
    302                                         GURL(kDefaultOrigin),
    303                                         base::TimeDelta::FromHours(1),
    304                                         false);
    305   MockObserver mock_observer;
    306   StorageObserverList observer_list;
    307   observer_list.AddObserver(&mock_observer, params);
    308 
    309   StorageObserver::Event dispatched_event;
    310   dispatched_event.filter = params.filter;
    311   dispatched_event.filter.origin = GURL("https://www.foo.com/bar");
    312   observer_list.OnStorageChange(dispatched_event);
    313 
    314   EXPECT_EQ(params.filter.origin, mock_observer.LastEvent().filter.origin);
    315 }
    316 
    317 // Tests for HostStorageObservers:
    318 
    319 typedef StorageTestWithManagerBase HostStorageObserversTest;
    320 
    321 // Verify that HostStorageObservers is initialized after the first usage change.
    322 TEST_F(HostStorageObserversTest, InitializeOnUsageChange) {
    323   StorageObserver::MonitorParams params(kStorageTypePersistent,
    324                                         GURL(kDefaultOrigin),
    325                                         base::TimeDelta::FromHours(1),
    326                                         false);
    327   const int64 kUsage = 324554;
    328   const int64 kQuota = 234354354;
    329   quota_manager_->SetCallbackParams(kUsage, kQuota, kQuotaStatusOk);
    330 
    331   MockObserver mock_observer;
    332   HostStorageObservers host_observers(quota_manager_.get());
    333   host_observers.AddObserver(&mock_observer, params);
    334 
    335   // Verify that HostStorageObservers dispatches the first event correctly.
    336   StorageObserver::Event expected_event(params.filter, kUsage, kQuota);
    337   host_observers.NotifyUsageChange(params.filter, 87324);
    338   EXPECT_EQ(1, mock_observer.EventCount());
    339   EXPECT_EQ(expected_event, mock_observer.LastEvent());
    340   EXPECT_TRUE(host_observers.is_initialized());
    341 
    342   // Verify that HostStorageObservers handles subsequent usage changes
    343   // correctly.
    344   const int64 kDelta = 2345;
    345   expected_event.usage += kDelta;
    346   SetLastNotificationTime(host_observers, &mock_observer);
    347   host_observers.NotifyUsageChange(params.filter, kDelta);
    348   EXPECT_EQ(2, mock_observer.EventCount());
    349   EXPECT_EQ(expected_event, mock_observer.LastEvent());
    350 }
    351 
    352 // Verify that HostStorageObservers is initialized after the adding the first
    353 // observer that elected to receive the initial state.
    354 TEST_F(HostStorageObserversTest, InitializeOnObserver) {
    355   const int64 kUsage = 74387;
    356   const int64 kQuota = 92834743;
    357   quota_manager_->SetCallbackParams(kUsage, kQuota, kQuotaStatusOk);
    358   HostStorageObservers host_observers(quota_manager_.get());
    359 
    360   // |host_observers| should not be initialized after the first observer is
    361   // added because it did not elect to receive the initial state.
    362   StorageObserver::MonitorParams params(kStorageTypePersistent,
    363                                         GURL(kDefaultOrigin),
    364                                         base::TimeDelta::FromHours(1),
    365                                         false);
    366   MockObserver mock_observer1;
    367   host_observers.AddObserver(&mock_observer1, params);
    368   EXPECT_FALSE(host_observers.is_initialized());
    369   EXPECT_EQ(0, mock_observer1.EventCount());
    370 
    371   // |host_observers| should be initialized after the second observer is
    372   // added.
    373   MockObserver mock_observer2;
    374   params.dispatch_initial_state = true;
    375   host_observers.AddObserver(&mock_observer2, params);
    376   StorageObserver::Event expected_event(params.filter, kUsage, kQuota);
    377   EXPECT_EQ(0, mock_observer1.EventCount());
    378   EXPECT_EQ(1, mock_observer2.EventCount());
    379   EXPECT_EQ(expected_event, mock_observer2.LastEvent());
    380   EXPECT_TRUE(host_observers.is_initialized());
    381   EXPECT_EQ(NULL, GetPendingEvent(host_observers));
    382   EXPECT_EQ(0, GetRequiredUpdatesCount(host_observers));
    383 
    384   // Verify that both observers will receive events after a usage change.
    385   const int64 kDelta = 2345;
    386   expected_event.usage += kDelta;
    387   SetLastNotificationTime(host_observers, &mock_observer2);
    388   host_observers.NotifyUsageChange(params.filter, kDelta);
    389   EXPECT_EQ(1, mock_observer1.EventCount());
    390   EXPECT_EQ(2, mock_observer2.EventCount());
    391   EXPECT_EQ(expected_event, mock_observer1.LastEvent());
    392   EXPECT_EQ(expected_event, mock_observer2.LastEvent());
    393   EXPECT_EQ(NULL, GetPendingEvent(host_observers));
    394   EXPECT_EQ(0, GetRequiredUpdatesCount(host_observers));
    395 
    396   // Verify that the addition of a third observer only causes an event to be
    397   // dispatched to the new observer.
    398   MockObserver mock_observer3;
    399   params.dispatch_initial_state = true;
    400   host_observers.AddObserver(&mock_observer3, params);
    401   EXPECT_EQ(1, mock_observer1.EventCount());
    402   EXPECT_EQ(2, mock_observer2.EventCount());
    403   EXPECT_EQ(1, mock_observer3.EventCount());
    404   EXPECT_EQ(expected_event, mock_observer3.LastEvent());
    405 }
    406 
    407 // Verify that negative usage and quota is changed to zero.
    408 TEST_F(HostStorageObserversTest, NegativeUsageAndQuota) {
    409   StorageObserver::MonitorParams params(kStorageTypePersistent,
    410                                         GURL(kDefaultOrigin),
    411                                         base::TimeDelta::FromHours(1),
    412                                         false);
    413   const int64 kUsage = -324554;
    414   const int64 kQuota = -234354354;
    415   quota_manager_->SetCallbackParams(kUsage, kQuota, kQuotaStatusOk);
    416 
    417   MockObserver mock_observer;
    418   HostStorageObservers host_observers(quota_manager_.get());
    419   host_observers.AddObserver(&mock_observer, params);
    420 
    421   StorageObserver::Event expected_event(params.filter, 0, 0);
    422   host_observers.NotifyUsageChange(params.filter, -87324);
    423   EXPECT_EQ(expected_event, mock_observer.LastEvent());
    424 }
    425 
    426 // Verify that HostStorageObservers can recover from a bad initialization.
    427 TEST_F(HostStorageObserversTest, RecoverFromBadUsageInit) {
    428   StorageObserver::MonitorParams params(kStorageTypePersistent,
    429                                         GURL(kDefaultOrigin),
    430                                         base::TimeDelta::FromHours(1),
    431                                         false);
    432   MockObserver mock_observer;
    433   HostStorageObservers host_observers(quota_manager_.get());
    434   host_observers.AddObserver(&mock_observer, params);
    435 
    436   // Set up the quota manager to return an error status.
    437   const int64 kUsage = 6656;
    438   const int64 kQuota = 99585556;
    439   quota_manager_->SetCallbackParams(kUsage, kQuota, kQuotaErrorNotSupported);
    440 
    441   // Verify that |host_observers| is not initialized and an event has not been
    442   // dispatched.
    443   host_observers.NotifyUsageChange(params.filter, 9438);
    444   EXPECT_EQ(0, mock_observer.EventCount());
    445   EXPECT_FALSE(host_observers.is_initialized());
    446   EXPECT_EQ(NULL, GetPendingEvent(host_observers));
    447   EXPECT_EQ(0, GetRequiredUpdatesCount(host_observers));
    448 
    449   // Now ensure that quota manager returns a good status.
    450   quota_manager_->SetCallbackParams(kUsage, kQuota, kQuotaStatusOk);
    451   host_observers.NotifyUsageChange(params.filter, 9048543);
    452   StorageObserver::Event expected_event(params.filter, kUsage, kQuota);
    453   EXPECT_EQ(1, mock_observer.EventCount());
    454   EXPECT_EQ(expected_event, mock_observer.LastEvent());
    455   EXPECT_TRUE(host_observers.is_initialized());
    456 }
    457 
    458 // Verify that HostStorageObservers handle initialization of the cached usage
    459 // and quota correctly.
    460 TEST_F(HostStorageObserversTest, AsyncInitialization) {
    461   StorageObserver::MonitorParams params(kStorageTypePersistent,
    462                                         GURL(kDefaultOrigin),
    463                                         base::TimeDelta::FromHours(1),
    464                                         false);
    465   MockObserver mock_observer;
    466   HostStorageObservers host_observers(quota_manager_.get());
    467   host_observers.AddObserver(&mock_observer, params);
    468 
    469   // Trigger initialization. Leave the mock quota manager uninitialized so that
    470   // the callback is not invoked.
    471   host_observers.NotifyUsageChange(params.filter, 7645);
    472   EXPECT_EQ(0, mock_observer.EventCount());
    473   EXPECT_FALSE(host_observers.is_initialized());
    474   EXPECT_EQ(NULL, GetPendingEvent(host_observers));
    475   EXPECT_EQ(0, GetRequiredUpdatesCount(host_observers));
    476 
    477   // Simulate notifying |host_observers| of a usage change before initialization
    478   // is complete.
    479   const int64 kUsage = 6656;
    480   const int64 kQuota = 99585556;
    481   const int64 kDelta = 327643;
    482   host_observers.NotifyUsageChange(params.filter, kDelta);
    483   EXPECT_EQ(0, mock_observer.EventCount());
    484   EXPECT_FALSE(host_observers.is_initialized());
    485   EXPECT_EQ(NULL, GetPendingEvent(host_observers));
    486   EXPECT_EQ(0, GetRequiredUpdatesCount(host_observers));
    487 
    488   // Simulate an asynchronous callback from QuotaManager.
    489   quota_manager_->SetCallbackParams(kUsage, kQuota, kQuotaStatusOk);
    490   quota_manager_->InvokeCallback();
    491   StorageObserver::Event expected_event(params.filter, kUsage + kDelta, kQuota);
    492   EXPECT_EQ(1, mock_observer.EventCount());
    493   EXPECT_EQ(expected_event, mock_observer.LastEvent());
    494   EXPECT_TRUE(host_observers.is_initialized());
    495   EXPECT_EQ(NULL, GetPendingEvent(host_observers));
    496   EXPECT_EQ(0, GetRequiredUpdatesCount(host_observers));
    497 }
    498 
    499 // Tests for StorageTypeObservers:
    500 
    501 typedef StorageTestWithManagerBase StorageTypeObserversTest;
    502 
    503 // Test adding and removing observers.
    504 TEST_F(StorageTypeObserversTest, AddRemoveObservers) {
    505   StorageTypeObservers type_observers(quota_manager_.get());
    506 
    507   StorageObserver::MonitorParams params1(kStorageTypePersistent,
    508                                          GURL(kDefaultOrigin),
    509                                          base::TimeDelta::FromHours(1),
    510                                          false);
    511   StorageObserver::MonitorParams params2(kStorageTypePersistent,
    512                                          GURL(kAlternativeOrigin),
    513                                          base::TimeDelta::FromHours(1),
    514                                          false);
    515   std::string host1 = net::GetHostOrSpecFromURL(params1.filter.origin);
    516   std::string host2 = net::GetHostOrSpecFromURL(params2.filter.origin);
    517 
    518   MockObserver mock_observer1;
    519   MockObserver mock_observer2;
    520   MockObserver mock_observer3;
    521   type_observers.AddObserver(&mock_observer1, params1);
    522   type_observers.AddObserver(&mock_observer2, params1);
    523 
    524   type_observers.AddObserver(&mock_observer1, params2);
    525   type_observers.AddObserver(&mock_observer2, params2);
    526   type_observers.AddObserver(&mock_observer3, params2);
    527 
    528   // Verify that the observers have been removed correctly.
    529   ASSERT_TRUE(type_observers.GetHostObservers(host1));
    530   ASSERT_TRUE(type_observers.GetHostObservers(host2));
    531   EXPECT_EQ(2, GetObserverCount(*type_observers.GetHostObservers(host1)));
    532   EXPECT_EQ(3, GetObserverCount(*type_observers.GetHostObservers(host2)));
    533 
    534   // Remove an observer for a specific filter.
    535   type_observers.RemoveObserverForFilter(&mock_observer1, params1.filter);
    536   ASSERT_TRUE(type_observers.GetHostObservers(host1));
    537   ASSERT_TRUE(type_observers.GetHostObservers(host2));
    538   EXPECT_EQ(1, GetObserverCount(*type_observers.GetHostObservers(host1)));
    539   EXPECT_EQ(3, GetObserverCount(*type_observers.GetHostObservers(host2)));
    540 
    541   // Remove all instances of an observer.
    542   type_observers.RemoveObserver(&mock_observer2);
    543   ASSERT_TRUE(type_observers.GetHostObservers(host2));
    544   EXPECT_EQ(2, GetObserverCount(*type_observers.GetHostObservers(host2)));
    545   // Observers of host1 has been deleted as it is empty.
    546   EXPECT_FALSE(type_observers.GetHostObservers(host1));
    547 }
    548 
    549 // Tests for StorageMonitor:
    550 
    551 class StorageMonitorTest : public StorageTestWithManagerBase {
    552  public:
    553   StorageMonitorTest()
    554       : storage_monitor_(NULL),
    555         params1_(kStorageTypeTemporary,
    556                  GURL(kDefaultOrigin),
    557                  base::TimeDelta::FromHours(1),
    558                  false),
    559         params2_(kStorageTypePersistent,
    560                  GURL(kDefaultOrigin),
    561                  base::TimeDelta::FromHours(1),
    562                  false) {
    563   }
    564 
    565  protected:
    566   virtual void SetUp() OVERRIDE {
    567     StorageTestWithManagerBase::SetUp();
    568 
    569     storage_monitor_ = quota_manager_->storage_monitor_.get();
    570     host_ = net::GetHostOrSpecFromURL(params1_.filter.origin);
    571 
    572     storage_monitor_->AddObserver(&mock_observer1_, params1_);
    573     storage_monitor_->AddObserver(&mock_observer2_, params1_);
    574 
    575     storage_monitor_->AddObserver(&mock_observer1_, params2_);
    576     storage_monitor_->AddObserver(&mock_observer2_, params2_);
    577     storage_monitor_->AddObserver(&mock_observer3_, params2_);
    578   }
    579 
    580   int GetObserverCount(StorageType storage_type) {
    581     const StorageTypeObservers* type_observers =
    582         storage_monitor_->GetStorageTypeObservers(storage_type);
    583     return StorageMonitorTestBase::GetObserverCount(
    584                 *type_observers->GetHostObservers(host_));
    585   }
    586 
    587   void CheckObserverCount(int expected_temporary, int expected_persistent) {
    588     ASSERT_TRUE(storage_monitor_->GetStorageTypeObservers(
    589                     kStorageTypeTemporary));
    590     ASSERT_TRUE(storage_monitor_->GetStorageTypeObservers(
    591                     kStorageTypeTemporary)->GetHostObservers(host_));
    592     EXPECT_EQ(expected_temporary, GetObserverCount(kStorageTypeTemporary));
    593 
    594     ASSERT_TRUE(storage_monitor_->GetStorageTypeObservers(
    595                     kStorageTypePersistent));
    596     ASSERT_TRUE(storage_monitor_->GetStorageTypeObservers(
    597                     kStorageTypePersistent)->GetHostObservers(host_));
    598     EXPECT_EQ(expected_persistent, GetObserverCount(kStorageTypePersistent));
    599   }
    600 
    601   StorageMonitor* storage_monitor_;
    602   StorageObserver::MonitorParams params1_;
    603   StorageObserver::MonitorParams params2_;
    604   MockObserver mock_observer1_;
    605   MockObserver mock_observer2_;
    606   MockObserver mock_observer3_;
    607   std::string host_;
    608 };
    609 
    610 // Test adding storage observers.
    611 TEST_F(StorageMonitorTest, AddObservers) {
    612   // Verify that the observers are added correctly.
    613   CheckObserverCount(2, 3);
    614 }
    615 
    616 // Test dispatching events to storage observers.
    617 TEST_F(StorageMonitorTest, EventDispatch) {
    618   // Verify dispatch of events.
    619   const int64 kUsage = 5325;
    620   const int64 kQuota = 903845;
    621   quota_manager_->SetCallbackParams(kUsage, kQuota, kQuotaStatusOk);
    622   storage_monitor_->NotifyUsageChange(params1_.filter, 9048543);
    623 
    624   StorageObserver::Event expected_event(params1_.filter, kUsage, kQuota);
    625   EXPECT_EQ(1, mock_observer1_.EventCount());
    626   EXPECT_EQ(1, mock_observer2_.EventCount());
    627   EXPECT_EQ(0, mock_observer3_.EventCount());
    628   EXPECT_EQ(expected_event, mock_observer1_.LastEvent());
    629   EXPECT_EQ(expected_event, mock_observer2_.LastEvent());
    630 }
    631 
    632 // Test removing all instances of an observer.
    633 TEST_F(StorageMonitorTest, RemoveObserver) {
    634   storage_monitor_->RemoveObserver(&mock_observer1_);
    635   CheckObserverCount(1, 2);
    636 }
    637 
    638 // Test removing an observer for a specific filter.
    639 TEST_F(StorageMonitorTest, RemoveObserverForFilter) {
    640   storage_monitor_->RemoveObserverForFilter(&mock_observer1_, params2_.filter);
    641   CheckObserverCount(2, 2);
    642 }
    643 
    644 // Integration test for QuotaManager and StorageMonitor:
    645 
    646 class StorageMonitorIntegrationTest : public testing::Test {
    647  public:
    648   virtual void SetUp() OVERRIDE {
    649     ASSERT_TRUE(data_dir_.CreateUniqueTempDir());
    650     storage_policy_ = new MockSpecialStoragePolicy();
    651     quota_manager_ = new QuotaManager(
    652         false,
    653         data_dir_.path(),
    654         base::MessageLoopProxy::current().get(),
    655         base::MessageLoopProxy::current().get(),
    656         storage_policy_.get());
    657 
    658     client_ = new MockStorageClient(quota_manager_->proxy(),
    659                                     NULL,
    660                                     QuotaClient::kFileSystem,
    661                                     0);
    662 
    663     quota_manager_->proxy()->RegisterClient(client_);
    664   }
    665 
    666   virtual void TearDown() OVERRIDE {
    667     // This ensures the quota manager is destroyed correctly.
    668     quota_manager_ = NULL;
    669     base::RunLoop().RunUntilIdle();
    670   }
    671 
    672  protected:
    673   base::MessageLoop message_loop_;
    674   base::ScopedTempDir data_dir_;
    675   scoped_refptr<MockSpecialStoragePolicy> storage_policy_;
    676   scoped_refptr<QuotaManager> quota_manager_;
    677   MockStorageClient* client_;
    678 };
    679 
    680 // This test simulates a usage change in a quota client and verifies that a
    681 // storage observer will receive a storage event.
    682 TEST_F(StorageMonitorIntegrationTest, NotifyUsageEvent) {
    683   const StorageType kTestStorageType = kStorageTypePersistent;
    684   const int64 kTestUsage = 234743;
    685 
    686   // Register the observer.
    687   StorageObserver::MonitorParams params(kTestStorageType,
    688                                         GURL(kDefaultOrigin),
    689                                         base::TimeDelta::FromHours(1),
    690                                         false);
    691   MockObserver mock_observer;
    692   quota_manager_->AddStorageObserver(&mock_observer, params);
    693 
    694   // Fire a usage change.
    695   client_->AddOriginAndNotify(GURL(kDefaultOrigin),
    696                               kTestStorageType,
    697                               kTestUsage);
    698   base::RunLoop().RunUntilIdle();
    699 
    700   // Verify that the observer receives it.
    701   ASSERT_EQ(1, mock_observer.EventCount());
    702   const StorageObserver::Event& event = mock_observer.LastEvent();
    703   EXPECT_EQ(params.filter, event.filter);
    704   EXPECT_EQ(kTestUsage, event.usage);
    705 }
    706 
    707 }  // namespace content
    708