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