Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / content / browser / appcache / appcache_group_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 <string>
6
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"
15
16 namespace {
17
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) {
23   }
24
25   virtual void OnCacheSelected(
26       int host_id, const content::AppCacheInfo& info) OVERRIDE {
27     last_host_id_ = host_id;
28     last_cache_id_ = info.cache_id;
29     last_status_ = info.status;
30   }
31
32   virtual void OnStatusChanged(const std::vector<int>& host_ids,
33                                content::AppCacheStatus status) OVERRIDE {
34   }
35
36   virtual void OnEventRaised(const std::vector<int>& host_ids,
37                              content::AppCacheEventID event_id) OVERRIDE {
38   }
39
40   virtual void OnErrorEventRaised(const std::vector<int>& host_ids,
41                                   const content::AppCacheErrorDetails& details)
42       OVERRIDE {}
43
44   virtual void OnProgressEventRaised(const std::vector<int>& host_ids,
45                                      const GURL& url,
46                                      int num_total, int num_complete) OVERRIDE {
47   }
48
49   virtual void OnLogMessage(int host_id, content::AppCacheLogLevel log_level,
50                             const std::string& message) OVERRIDE {
51   }
52
53   virtual void OnContentBlocked(int host_id,
54                                 const GURL& manifest_url) OVERRIDE {
55   }
56
57   int last_host_id_;
58   int64 last_cache_id_;
59   content::AppCacheStatus last_status_;
60 };
61
62 }  // namespace anon
63
64 namespace content {
65
66 class TestUpdateObserver : public AppCacheGroup::UpdateObserver {
67  public:
68   TestUpdateObserver() : update_completed_(false), group_has_cache_(false) {
69   }
70
71   virtual void OnUpdateComplete(AppCacheGroup* group) OVERRIDE {
72     update_completed_ = true;
73     group_has_cache_ = group->HasCache();
74   }
75
76   virtual void OnContentBlocked(AppCacheGroup* group) {
77   }
78
79   bool update_completed_;
80   bool group_has_cache_;
81 };
82
83 class TestAppCacheHost : public AppCacheHost {
84  public:
85   TestAppCacheHost(int host_id, AppCacheFrontend* frontend,
86                    AppCacheServiceImpl* service)
87       : AppCacheHost(host_id, frontend, service),
88         update_completed_(false) {
89   }
90
91   virtual void OnUpdateComplete(AppCacheGroup* group) OVERRIDE {
92     update_completed_ = true;
93   }
94
95   bool update_completed_;
96 };
97
98 class AppCacheGroupTest : public testing::Test {
99  private:
100   base::MessageLoop message_loop_;
101 };
102
103 TEST_F(AppCacheGroupTest, AddRemoveCache) {
104   MockAppCacheService service;
105   scoped_refptr<AppCacheGroup> group(
106       new AppCacheGroup(service.storage(), GURL("http://foo.com"), 111));
107
108   base::Time now = base::Time::Now();
109
110   scoped_refptr<AppCache> cache1(new AppCache(service.storage(), 111));
111   cache1->set_complete(true);
112   cache1->set_update_time(now);
113   group->AddCache(cache1.get());
114   EXPECT_EQ(cache1, group->newest_complete_cache());
115
116   // Adding older cache does not change newest complete cache.
117   scoped_refptr<AppCache> cache2(new AppCache(service.storage(), 222));
118   cache2->set_complete(true);
119   cache2->set_update_time(now - base::TimeDelta::FromDays(1));
120   group->AddCache(cache2.get());
121   EXPECT_EQ(cache1, group->newest_complete_cache());
122
123   // Adding newer cache does change newest complete cache.
124   scoped_refptr<AppCache> cache3(new AppCache(service.storage(), 333));
125   cache3->set_complete(true);
126   cache3->set_update_time(now + base::TimeDelta::FromDays(1));
127   group->AddCache(cache3.get());
128   EXPECT_EQ(cache3, group->newest_complete_cache());
129
130   // Adding cache with same update time uses one with larger ID.
131   scoped_refptr<AppCache> cache4(new AppCache(service.storage(), 444));
132   cache4->set_complete(true);
133   cache4->set_update_time(now + base::TimeDelta::FromDays(1));  // same as 3
134   group->AddCache(cache4.get());
135   EXPECT_EQ(cache4, group->newest_complete_cache());
136
137   // smaller id
138   scoped_refptr<AppCache> cache5(new AppCache(service.storage(), 55));
139   cache5->set_complete(true);
140   cache5->set_update_time(now + base::TimeDelta::FromDays(1));  // same as 4
141   group->AddCache(cache5.get());
142   EXPECT_EQ(cache4, group->newest_complete_cache());  // no change
143
144   // Old caches can always be removed.
145   group->RemoveCache(cache1.get());
146   EXPECT_FALSE(cache1->owning_group());
147   EXPECT_EQ(cache4, group->newest_complete_cache());  // newest unchanged
148
149   // Remove rest of caches.
150   group->RemoveCache(cache2.get());
151   EXPECT_FALSE(cache2->owning_group());
152   EXPECT_EQ(cache4, group->newest_complete_cache());  // newest unchanged
153   group->RemoveCache(cache3.get());
154   EXPECT_FALSE(cache3->owning_group());
155   EXPECT_EQ(cache4, group->newest_complete_cache());  // newest unchanged
156   group->RemoveCache(cache5.get());
157   EXPECT_FALSE(cache5->owning_group());
158   EXPECT_EQ(cache4, group->newest_complete_cache());  // newest unchanged
159   group->RemoveCache(cache4.get());                   // newest removed
160   EXPECT_FALSE(cache4->owning_group());
161   EXPECT_FALSE(group->newest_complete_cache());       // no more newest cache
162
163   // Can remove newest cache if there are older caches.
164   group->AddCache(cache1.get());
165   EXPECT_EQ(cache1, group->newest_complete_cache());
166   group->AddCache(cache4.get());
167   EXPECT_EQ(cache4, group->newest_complete_cache());
168   group->RemoveCache(cache4.get());  // remove newest
169   EXPECT_FALSE(cache4->owning_group());
170   EXPECT_FALSE(group->newest_complete_cache());  // newest removed
171 }
172
173 TEST_F(AppCacheGroupTest, CleanupUnusedGroup) {
174   MockAppCacheService service;
175   TestAppCacheFrontend frontend;
176   AppCacheGroup* group =
177       new AppCacheGroup(service.storage(), GURL("http://foo.com"), 111);
178
179   AppCacheHost host1(1, &frontend, &service);
180   AppCacheHost host2(2, &frontend, &service);
181
182   base::Time now = base::Time::Now();
183
184   AppCache* cache1 = new AppCache(service.storage(), 111);
185   cache1->set_complete(true);
186   cache1->set_update_time(now);
187   group->AddCache(cache1);
188   EXPECT_EQ(cache1, group->newest_complete_cache());
189
190   host1.AssociateCompleteCache(cache1);
191   EXPECT_EQ(frontend.last_host_id_, host1.host_id());
192   EXPECT_EQ(frontend.last_cache_id_, cache1->cache_id());
193   EXPECT_EQ(frontend.last_status_, APPCACHE_STATUS_IDLE);
194
195   host2.AssociateCompleteCache(cache1);
196   EXPECT_EQ(frontend.last_host_id_, host2.host_id());
197   EXPECT_EQ(frontend.last_cache_id_, cache1->cache_id());
198   EXPECT_EQ(frontend.last_status_, APPCACHE_STATUS_IDLE);
199
200   AppCache* cache2 = new AppCache(service.storage(), 222);
201   cache2->set_complete(true);
202   cache2->set_update_time(now + base::TimeDelta::FromDays(1));
203   group->AddCache(cache2);
204   EXPECT_EQ(cache2, group->newest_complete_cache());
205
206   // Unassociate all hosts from older cache.
207   host1.AssociateNoCache(GURL());
208   host2.AssociateNoCache(GURL());
209   EXPECT_EQ(frontend.last_host_id_, host2.host_id());
210   EXPECT_EQ(frontend.last_cache_id_, kAppCacheNoCacheId);
211   EXPECT_EQ(frontend.last_status_, APPCACHE_STATUS_UNCACHED);
212 }
213
214 TEST_F(AppCacheGroupTest, StartUpdate) {
215   MockAppCacheService service;
216   scoped_refptr<AppCacheGroup> group(
217       new AppCacheGroup(service.storage(), GURL("http://foo.com"), 111));
218
219   // Set state to checking to prevent update job from executing fetches.
220   group->update_status_ = AppCacheGroup::CHECKING;
221   group->StartUpdate();
222   AppCacheUpdateJob* update = group->update_job_;
223   EXPECT_TRUE(update != NULL);
224
225   // Start another update, check that same update job is in use.
226   group->StartUpdateWithHost(NULL);
227   EXPECT_EQ(update, group->update_job_);
228
229   // Deleting the update should restore the group to APPCACHE_STATUS_IDLE.
230   delete update;
231   EXPECT_TRUE(group->update_job_ == NULL);
232   EXPECT_EQ(AppCacheGroup::IDLE, group->update_status());
233 }
234
235 TEST_F(AppCacheGroupTest, CancelUpdate) {
236   MockAppCacheService service;
237   scoped_refptr<AppCacheGroup> group(
238       new AppCacheGroup(service.storage(), GURL("http://foo.com"), 111));
239
240   // Set state to checking to prevent update job from executing fetches.
241   group->update_status_ = AppCacheGroup::CHECKING;
242   group->StartUpdate();
243   AppCacheUpdateJob* update = group->update_job_;
244   EXPECT_TRUE(update != NULL);
245
246   // Deleting the group should cancel the update.
247   TestUpdateObserver observer;
248   group->AddUpdateObserver(&observer);
249   group = NULL;  // causes group to be deleted
250   EXPECT_TRUE(observer.update_completed_);
251   EXPECT_FALSE(observer.group_has_cache_);
252 }
253
254 TEST_F(AppCacheGroupTest, QueueUpdate) {
255   MockAppCacheService service;
256   scoped_refptr<AppCacheGroup> group(
257       new AppCacheGroup(service.storage(), GURL("http://foo.com"), 111));
258
259   // Set state to checking to prevent update job from executing fetches.
260   group->update_status_ = AppCacheGroup::CHECKING;
261   group->StartUpdate();
262   EXPECT_TRUE(group->update_job_);
263
264   // Pretend group's update job is terminating so that next update is queued.
265   group->update_job_->internal_state_ = AppCacheUpdateJob::REFETCH_MANIFEST;
266   EXPECT_TRUE(group->update_job_->IsTerminating());
267
268   TestAppCacheFrontend frontend;
269   TestAppCacheHost host(1, &frontend, &service);
270   host.new_master_entry_url_ = GURL("http://foo.com/bar.txt");
271   group->StartUpdateWithNewMasterEntry(&host, host.new_master_entry_url_);
272   EXPECT_FALSE(group->queued_updates_.empty());
273
274   group->AddUpdateObserver(&host);
275   EXPECT_FALSE(group->FindObserver(&host, group->observers_));
276   EXPECT_TRUE(group->FindObserver(&host, group->queued_observers_));
277
278   // Delete update to cause it to complete. Verify no update complete notice
279   // sent to host.
280   delete group->update_job_;
281   EXPECT_EQ(AppCacheGroup::IDLE, group->update_status_);
282   EXPECT_FALSE(group->restart_update_task_.IsCancelled());
283   EXPECT_FALSE(host.update_completed_);
284
285   // Start another update. Cancels task and will run queued updates.
286   group->update_status_ = AppCacheGroup::CHECKING;  // prevent actual fetches
287   group->StartUpdate();
288   EXPECT_TRUE(group->update_job_);
289   EXPECT_TRUE(group->restart_update_task_.IsCancelled());
290   EXPECT_TRUE(group->queued_updates_.empty());
291   EXPECT_FALSE(group->update_job_->pending_master_entries_.empty());
292   EXPECT_FALSE(group->FindObserver(&host, group->queued_observers_));
293   EXPECT_TRUE(group->FindObserver(&host, group->observers_));
294
295   // Delete update to cause it to complete. Verify host is notified.
296   delete group->update_job_;
297   EXPECT_EQ(AppCacheGroup::IDLE, group->update_status_);
298   EXPECT_TRUE(group->restart_update_task_.IsCancelled());
299   EXPECT_TRUE(host.update_completed_);
300 }
301
302 }  // namespace content