Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / content / browser / quota / storage_monitor_unittest.cc
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