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 "testing/gtest/include/gtest/gtest.h" 15 #include "webkit/browser/quota/quota_manager.h" 16 #include "webkit/browser/quota/quota_manager_proxy.h" 17 #include "webkit/browser/quota/storage_monitor.h" 18 #include "webkit/browser/quota/storage_observer.h" 19 20 using quota::HostStorageObservers; 21 using quota::kQuotaErrorNotSupported; 22 using quota::kQuotaStatusOk; 23 using quota::kStorageTypePersistent; 24 using quota::kStorageTypeTemporary; 25 using quota::QuotaClient; 26 using quota::QuotaManager; 27 using quota::QuotaStatusCode; 28 using quota::SpecialStoragePolicy; 29 using quota::StorageMonitor; 30 using quota::StorageObserver; 31 using quota::StorageObserverList; 32 using quota::StorageType; 33 using quota::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