Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / content / browser / appcache / appcache_group_unittest.cc
blob64e321d5525270ba5794564f76f7ea24ab85abe0
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.
5 #include <string>
7 #include "base/message_loop/message_loop.h"
8 #include "content/browser/appcache/appcache.h"
9 #include "content/browser/appcache/appcache_group.h"
10 #include "content/browser/appcache/appcache_host.h"
11 #include "content/browser/appcache/appcache_update_job.h"
12 #include "content/browser/appcache/mock_appcache_service.h"
13 #include "content/common/appcache_interfaces.h"
14 #include "testing/gtest/include/gtest/gtest.h"
16 namespace {
18 class TestAppCacheFrontend : public content::AppCacheFrontend {
19 public:
20 TestAppCacheFrontend()
21 : last_host_id_(-1), last_cache_id_(-1),
22 last_status_(content::APPCACHE_STATUS_OBSOLETE) {
25 void OnCacheSelected(int host_id,
26 const content::AppCacheInfo& info) override {
27 last_host_id_ = host_id;
28 last_cache_id_ = info.cache_id;
29 last_status_ = info.status;
32 void OnStatusChanged(const std::vector<int>& host_ids,
33 content::AppCacheStatus status) override {}
35 void OnEventRaised(const std::vector<int>& host_ids,
36 content::AppCacheEventID event_id) override {}
38 void OnErrorEventRaised(
39 const std::vector<int>& host_ids,
40 const content::AppCacheErrorDetails& details) override {}
42 void OnProgressEventRaised(const std::vector<int>& host_ids,
43 const GURL& url,
44 int num_total,
45 int num_complete) override {}
47 void OnLogMessage(int host_id,
48 content::AppCacheLogLevel log_level,
49 const std::string& message) override {}
51 void OnContentBlocked(int host_id, const GURL& manifest_url) override {}
53 int last_host_id_;
54 int64 last_cache_id_;
55 content::AppCacheStatus last_status_;
58 } // namespace anon
60 namespace content {
62 class TestUpdateObserver : public AppCacheGroup::UpdateObserver {
63 public:
64 TestUpdateObserver() : update_completed_(false), group_has_cache_(false) {
67 void OnUpdateComplete(AppCacheGroup* group) override {
68 update_completed_ = true;
69 group_has_cache_ = group->HasCache();
72 virtual void OnContentBlocked(AppCacheGroup* group) {
75 bool update_completed_;
76 bool group_has_cache_;
79 class TestAppCacheHost : public AppCacheHost {
80 public:
81 TestAppCacheHost(int host_id, AppCacheFrontend* frontend,
82 AppCacheServiceImpl* service)
83 : AppCacheHost(host_id, frontend, service),
84 update_completed_(false) {
87 void OnUpdateComplete(AppCacheGroup* group) override {
88 update_completed_ = true;
91 bool update_completed_;
94 class AppCacheGroupTest : public testing::Test {
95 private:
96 base::MessageLoop message_loop_;
99 TEST_F(AppCacheGroupTest, AddRemoveCache) {
100 MockAppCacheService service;
101 scoped_refptr<AppCacheGroup> group(
102 new AppCacheGroup(service.storage(), GURL("http://foo.com"), 111));
104 base::Time now = base::Time::Now();
106 scoped_refptr<AppCache> cache1(new AppCache(service.storage(), 111));
107 cache1->set_complete(true);
108 cache1->set_update_time(now);
109 group->AddCache(cache1.get());
110 EXPECT_EQ(cache1.get(), group->newest_complete_cache());
112 // Adding older cache does not change newest complete cache.
113 scoped_refptr<AppCache> cache2(new AppCache(service.storage(), 222));
114 cache2->set_complete(true);
115 cache2->set_update_time(now - base::TimeDelta::FromDays(1));
116 group->AddCache(cache2.get());
117 EXPECT_EQ(cache1.get(), group->newest_complete_cache());
119 // Adding newer cache does change newest complete cache.
120 scoped_refptr<AppCache> cache3(new AppCache(service.storage(), 333));
121 cache3->set_complete(true);
122 cache3->set_update_time(now + base::TimeDelta::FromDays(1));
123 group->AddCache(cache3.get());
124 EXPECT_EQ(cache3.get(), group->newest_complete_cache());
126 // Adding cache with same update time uses one with larger ID.
127 scoped_refptr<AppCache> cache4(new AppCache(service.storage(), 444));
128 cache4->set_complete(true);
129 cache4->set_update_time(now + base::TimeDelta::FromDays(1)); // same as 3
130 group->AddCache(cache4.get());
131 EXPECT_EQ(cache4.get(), group->newest_complete_cache());
133 // smaller id
134 scoped_refptr<AppCache> cache5(new AppCache(service.storage(), 55));
135 cache5->set_complete(true);
136 cache5->set_update_time(now + base::TimeDelta::FromDays(1)); // same as 4
137 group->AddCache(cache5.get());
138 EXPECT_EQ(cache4.get(), group->newest_complete_cache()); // no change
140 // Old caches can always be removed.
141 group->RemoveCache(cache1.get());
142 EXPECT_FALSE(cache1->owning_group());
143 EXPECT_EQ(cache4.get(), group->newest_complete_cache()); // newest unchanged
145 // Remove rest of caches.
146 group->RemoveCache(cache2.get());
147 EXPECT_FALSE(cache2->owning_group());
148 EXPECT_EQ(cache4.get(), group->newest_complete_cache()); // newest unchanged
149 group->RemoveCache(cache3.get());
150 EXPECT_FALSE(cache3->owning_group());
151 EXPECT_EQ(cache4.get(), group->newest_complete_cache()); // newest unchanged
152 group->RemoveCache(cache5.get());
153 EXPECT_FALSE(cache5->owning_group());
154 EXPECT_EQ(cache4.get(), group->newest_complete_cache()); // newest unchanged
155 group->RemoveCache(cache4.get()); // newest removed
156 EXPECT_FALSE(cache4->owning_group());
157 EXPECT_FALSE(group->newest_complete_cache()); // no more newest cache
159 // Can remove newest cache if there are older caches.
160 group->AddCache(cache1.get());
161 EXPECT_EQ(cache1.get(), group->newest_complete_cache());
162 group->AddCache(cache4.get());
163 EXPECT_EQ(cache4.get(), group->newest_complete_cache());
164 group->RemoveCache(cache4.get()); // remove newest
165 EXPECT_FALSE(cache4->owning_group());
166 EXPECT_FALSE(group->newest_complete_cache()); // newest removed
169 TEST_F(AppCacheGroupTest, CleanupUnusedGroup) {
170 MockAppCacheService service;
171 TestAppCacheFrontend frontend;
172 AppCacheGroup* group =
173 new AppCacheGroup(service.storage(), GURL("http://foo.com"), 111);
175 AppCacheHost host1(1, &frontend, &service);
176 AppCacheHost host2(2, &frontend, &service);
178 base::Time now = base::Time::Now();
180 AppCache* cache1 = new AppCache(service.storage(), 111);
181 cache1->set_complete(true);
182 cache1->set_update_time(now);
183 group->AddCache(cache1);
184 EXPECT_EQ(cache1, group->newest_complete_cache());
186 host1.AssociateCompleteCache(cache1);
187 EXPECT_EQ(frontend.last_host_id_, host1.host_id());
188 EXPECT_EQ(frontend.last_cache_id_, cache1->cache_id());
189 EXPECT_EQ(frontend.last_status_, APPCACHE_STATUS_IDLE);
191 host2.AssociateCompleteCache(cache1);
192 EXPECT_EQ(frontend.last_host_id_, host2.host_id());
193 EXPECT_EQ(frontend.last_cache_id_, cache1->cache_id());
194 EXPECT_EQ(frontend.last_status_, APPCACHE_STATUS_IDLE);
196 AppCache* cache2 = new AppCache(service.storage(), 222);
197 cache2->set_complete(true);
198 cache2->set_update_time(now + base::TimeDelta::FromDays(1));
199 group->AddCache(cache2);
200 EXPECT_EQ(cache2, group->newest_complete_cache());
202 // Unassociate all hosts from older cache.
203 host1.AssociateNoCache(GURL());
204 host2.AssociateNoCache(GURL());
205 EXPECT_EQ(frontend.last_host_id_, host2.host_id());
206 EXPECT_EQ(frontend.last_cache_id_, kAppCacheNoCacheId);
207 EXPECT_EQ(frontend.last_status_, APPCACHE_STATUS_UNCACHED);
210 TEST_F(AppCacheGroupTest, StartUpdate) {
211 MockAppCacheService service;
212 scoped_refptr<AppCacheGroup> group(
213 new AppCacheGroup(service.storage(), GURL("http://foo.com"), 111));
215 // Set state to checking to prevent update job from executing fetches.
216 group->update_status_ = AppCacheGroup::CHECKING;
217 group->StartUpdate();
218 AppCacheUpdateJob* update = group->update_job_;
219 EXPECT_TRUE(update != NULL);
221 // Start another update, check that same update job is in use.
222 group->StartUpdateWithHost(NULL);
223 EXPECT_EQ(update, group->update_job_);
225 // Deleting the update should restore the group to APPCACHE_STATUS_IDLE.
226 delete update;
227 EXPECT_TRUE(group->update_job_ == NULL);
228 EXPECT_EQ(AppCacheGroup::IDLE, group->update_status());
231 TEST_F(AppCacheGroupTest, CancelUpdate) {
232 MockAppCacheService service;
233 scoped_refptr<AppCacheGroup> group(
234 new AppCacheGroup(service.storage(), GURL("http://foo.com"), 111));
236 // Set state to checking to prevent update job from executing fetches.
237 group->update_status_ = AppCacheGroup::CHECKING;
238 group->StartUpdate();
239 AppCacheUpdateJob* update = group->update_job_;
240 EXPECT_TRUE(update != NULL);
242 // Deleting the group should cancel the update.
243 TestUpdateObserver observer;
244 group->AddUpdateObserver(&observer);
245 group = NULL; // causes group to be deleted
246 EXPECT_TRUE(observer.update_completed_);
247 EXPECT_FALSE(observer.group_has_cache_);
250 TEST_F(AppCacheGroupTest, QueueUpdate) {
251 MockAppCacheService service;
252 scoped_refptr<AppCacheGroup> group(
253 new AppCacheGroup(service.storage(), GURL("http://foo.com"), 111));
255 // Set state to checking to prevent update job from executing fetches.
256 group->update_status_ = AppCacheGroup::CHECKING;
257 group->StartUpdate();
258 EXPECT_TRUE(group->update_job_);
260 // Pretend group's update job is terminating so that next update is queued.
261 group->update_job_->internal_state_ = AppCacheUpdateJob::REFETCH_MANIFEST;
262 EXPECT_TRUE(group->update_job_->IsTerminating());
264 TestAppCacheFrontend frontend;
265 TestAppCacheHost host(1, &frontend, &service);
266 host.new_master_entry_url_ = GURL("http://foo.com/bar.txt");
267 group->StartUpdateWithNewMasterEntry(&host, host.new_master_entry_url_);
268 EXPECT_FALSE(group->queued_updates_.empty());
270 group->AddUpdateObserver(&host);
271 EXPECT_FALSE(group->FindObserver(&host, group->observers_));
272 EXPECT_TRUE(group->FindObserver(&host, group->queued_observers_));
274 // Delete update to cause it to complete. Verify no update complete notice
275 // sent to host.
276 delete group->update_job_;
277 EXPECT_EQ(AppCacheGroup::IDLE, group->update_status_);
278 EXPECT_FALSE(group->restart_update_task_.IsCancelled());
279 EXPECT_FALSE(host.update_completed_);
281 // Start another update. Cancels task and will run queued updates.
282 group->update_status_ = AppCacheGroup::CHECKING; // prevent actual fetches
283 group->StartUpdate();
284 EXPECT_TRUE(group->update_job_);
285 EXPECT_TRUE(group->restart_update_task_.IsCancelled());
286 EXPECT_TRUE(group->queued_updates_.empty());
287 EXPECT_FALSE(group->update_job_->pending_master_entries_.empty());
288 EXPECT_FALSE(group->FindObserver(&host, group->queued_observers_));
289 EXPECT_TRUE(group->FindObserver(&host, group->observers_));
291 // Delete update to cause it to complete. Verify host is notified.
292 delete group->update_job_;
293 EXPECT_EQ(AppCacheGroup::IDLE, group->update_status_);
294 EXPECT_TRUE(group->restart_update_task_.IsCancelled());
295 EXPECT_TRUE(host.update_completed_);
298 } // namespace content