Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(345)

Side by Side Diff: content/browser/appcache/chrome_appcache_service_unittest.cc

Issue 7210006: AppCaches which belong to hosted apps are not protected from deletion (Closed) Base URL: http://git.chromium.org/git/chromium.git@trunk
Patch Set: Minor. Created 9 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "base/file_util.h" 5 #include "base/file_util.h"
6 #include "base/memory/ref_counted.h" 6 #include "base/memory/ref_counted.h"
7 #include "base/message_loop.h" 7 #include "base/message_loop.h"
8 #include "base/scoped_temp_dir.h"
9 #include "chrome/test/testing_browser_process.h" 8 #include "chrome/test/testing_browser_process.h"
10 #include "chrome/test/testing_browser_process_test.h" 9 #include "chrome/test/testing_browser_process_test.h"
11 #include "content/browser/appcache/chrome_appcache_service.h" 10 #include "content/browser/appcache/chrome_appcache_service.h"
12 #include "content/browser/browser_thread.h" 11 #include "content/browser/browser_thread.h"
13 #include "testing/gtest/include/gtest/gtest.h" 12 #include "testing/gtest/include/gtest/gtest.h"
14 #include "webkit/appcache/appcache_storage_impl.h" 13 #include "webkit/appcache/appcache_storage_impl.h"
14 #include "webkit/quota/mock_special_storage_policy.h"
15
16 #include <set>
15 17
16 namespace { 18 namespace {
17 const FilePath::CharType kTestingAppCacheDirname[] = 19
18 FILE_PATH_LITERAL("Application Cache"); 20 // Examples of a protected and an unprotected origin, to be used througout the
21 // test.
22 const GURL kProtectedOrigin("http://www.protected.com/");
23 const GURL kProtectedManifest1("http://www.protected.com/1/cache.manifest");
24 const GURL kProtectedManifest2("http://www.protected.com/2/cache.manifest");
25 const GURL kNormalOrigin("http://www.normal.com/");
26 const GURL kNormalManifest1("http://www.normal.com/1/cache.manifest");
27 const GURL kNormalManifest2("http://www.normal.com/2/cache.manifest");
28
29 } // namespace
30
31 namespace appcache {
32
33 // This subclass overwrites 2 functions (GetAllAppCacheInfo and
34 // DeleteAppcachesForOrigin). It enables unit testing the internal logic of
35 // ChromeAppCacheInfo (deleting only non-protected origins from the app cache).
36 class TestableChromeAppCacheService : public ChromeAppCacheService {
37 public:
38 explicit TestableChromeAppCacheService(quota::QuotaManagerProxy* proxy);
39
40 // Mock implementations.
41 virtual void GetAllAppCacheInfo(AppCacheInfoCollection* collection,
42 net::CompletionCallback* callback);
43 virtual void DeleteAppCacheGroup(const GURL& origin,
44 net::CompletionCallback* callback);
45
46 // Functions for controlling the mock implementations.
47 void set_empty(bool empty);
48 bool GroupDeleted(const GURL& manifest_url);
49
50 private:
51 // Helper function for the mock implementation
52 static void DeferredCallCallback(net::CompletionCallback* callback, int rv);
53
54 std::set<GURL> deleted_groups_;
55 bool empty_;
56 };
57
58 TestableChromeAppCacheService::TestableChromeAppCacheService(
59 quota::QuotaManagerProxy* proxy)
60 : ChromeAppCacheService(proxy), empty_(false) {
19 } 61 }
20 62
21 namespace appcache { 63 void TestableChromeAppCacheService::GetAllAppCacheInfo(
64 AppCacheInfoCollection* collection,
65 net::CompletionCallback* callback) {
66 if (!empty_) {
67 AppCacheInfo info1;
68 info1.manifest_url = kProtectedManifest1;
69 AppCacheInfo info2;
70 info2.manifest_url = kProtectedManifest2;
71 AppCacheInfoVector& info_vector1 =
72 collection->infos_by_origin[kProtectedOrigin];
73 info_vector1.push_back(info1);
74 info_vector1.push_back(info2);
75
76 AppCacheInfo info3;
77 info3.manifest_url = kNormalManifest1;
78 AppCacheInfo info4;
79 info4.manifest_url = kNormalManifest2;
80 AppCacheInfoVector& info_vector2 =
81 collection->infos_by_origin[kNormalOrigin];
82 info_vector2.push_back(info3);
83 info_vector2.push_back(info4);
84 }
85 if (callback)
86 callback->Run(0);
87 }
88
89 void TestableChromeAppCacheService::DeleteAppCacheGroup(
90 const GURL& manifest_url,
91 net::CompletionCallback* callback) {
92 deleted_groups_.insert(manifest_url);
93 // The callback must be called asynchronously, otherwise the code breaks.
94 // Defer to guarentee async completion.
95 MessageLoop::current()->PostTask(
96 FROM_HERE,
97 NewRunnableFunction(&DeferredCallCallback, callback, 0));
98 }
99
100 void TestableChromeAppCacheService::set_empty(bool empty) {
101 empty_ = empty;
102 }
103
104 bool TestableChromeAppCacheService::GroupDeleted(const GURL& manifest_url) {
105 return (deleted_groups_.find(manifest_url) != deleted_groups_.end());
106 }
107
108 void TestableChromeAppCacheService::DeferredCallCallback(
109 net::CompletionCallback* callback, int rv){
110 callback->Run(rv);
111 }
22 112
23 class ChromeAppCacheServiceTest : public TestingBrowserProcessTest { 113 class ChromeAppCacheServiceTest : public TestingBrowserProcessTest {
24 public: 114 public:
25 ChromeAppCacheServiceTest() 115 ChromeAppCacheServiceTest()
26 : message_loop_(MessageLoop::TYPE_IO), 116 : message_loop_(MessageLoop::TYPE_IO),
117 ALLOW_THIS_IN_INITIALIZER_LIST(appcache_cleared_callback_(
118 this, &ChromeAppCacheServiceTest::OnAppCacheCleared)),
119 callback_called_(false),
27 db_thread_(BrowserThread::DB, &message_loop_), 120 db_thread_(BrowserThread::DB, &message_loop_),
28 file_thread_(BrowserThread::FILE, &message_loop_), 121 file_thread_(BrowserThread::FILE, &message_loop_),
29 cache_thread_(BrowserThread::CACHE, &message_loop_), 122 cache_thread_(BrowserThread::CACHE, &message_loop_),
30 io_thread_(BrowserThread::IO, &message_loop_) { 123 io_thread_(BrowserThread::IO, &message_loop_) {
31 } 124 }
32 125
33 protected: 126 protected:
34 MessageLoop message_loop_; 127 MessageLoop message_loop_;
35 ScopedTempDir temp_dir_; 128 net::CompletionCallbackImpl<ChromeAppCacheServiceTest>
129 appcache_cleared_callback_;
130 bool callback_called_;
36 131
37 private: 132 private:
133 void OnAppCacheCleared(int rv);
134
38 BrowserThread db_thread_; 135 BrowserThread db_thread_;
39 BrowserThread file_thread_; 136 BrowserThread file_thread_;
40 BrowserThread cache_thread_; 137 BrowserThread cache_thread_;
41 BrowserThread io_thread_; 138 BrowserThread io_thread_;
42 }; 139 };
43 140
44 TEST_F(ChromeAppCacheServiceTest, KeepOnDestruction) { 141 void ChromeAppCacheServiceTest::OnAppCacheCleared(int rv) {
45 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); 142 callback_called_ = true;
46 FilePath appcache_path = temp_dir_.path().Append(kTestingAppCacheDirname); 143 }
47 scoped_refptr<ChromeAppCacheService> appcache_service = 144
48 new ChromeAppCacheService(NULL); 145 TEST_F(ChromeAppCacheServiceTest, ClearAppCache) {
michaeln 2011/07/14 22:53:16 And if we don't add the ClearAppCache method, we w
marja(google) 2011/07/15 11:03:42 I rewrote the ChromeAppCacheService tests, for tes
146 // Tests ChromeAppCacheService::ClearAppCache(): nonprotected origins should
147 // be deleted an protected origins should not.
148 scoped_refptr<TestableChromeAppCacheService> appcache_service =
149 new TestableChromeAppCacheService(NULL);
49 const content::ResourceContext* resource_context = NULL; 150 const content::ResourceContext* resource_context = NULL;
151 scoped_refptr<quota::MockSpecialStoragePolicy> mock_policy =
152 new quota::MockSpecialStoragePolicy;
153 mock_policy->AddProtected(kProtectedOrigin);
154 // Passing an empty FilePath is ok; nothing will be saved on the disk during
155 // the test.
50 BrowserThread::PostTask( 156 BrowserThread::PostTask(
51 BrowserThread::IO, FROM_HERE, 157 BrowserThread::IO, FROM_HERE,
52 NewRunnableMethod(appcache_service.get(), 158 NewRunnableMethod(appcache_service.get(),
53 &ChromeAppCacheService::InitializeOnIOThread, 159 &ChromeAppCacheService::InitializeOnIOThread,
54 appcache_path, 160 FilePath(),
55 resource_context, 161 resource_context,
56 scoped_refptr<quota::SpecialStoragePolicy>(NULL), 162 mock_policy));
57 false)); 163 // Spin the message loop so that the initialization really happens.
58 // Make the steps needed to initialize the storage of AppCache data.
59 message_loop_.RunAllPending();
60 appcache::AppCacheStorageImpl* storage =
61 static_cast<appcache::AppCacheStorageImpl*>(appcache_service->storage());
62 ASSERT_TRUE(storage->database_->db_connection());
63 ASSERT_EQ(1, storage->NewCacheId());
64 storage->disk_cache();
65 message_loop_.RunAllPending(); 164 message_loop_.RunAllPending();
66 165
67 ASSERT_TRUE(file_util::PathExists(appcache_path)); 166 appcache_service->ClearAppCache(&appcache_cleared_callback_);
68 ASSERT_TRUE(file_util::PathExists(appcache_path.AppendASCII("Index")));
69 167
70 appcache_service = NULL; 168 // Spin the message loop so that the asynchronous operations (mainly, calling
169 // the callback) happen.
71 message_loop_.RunAllPending(); 170 message_loop_.RunAllPending();
72 171
73 ASSERT_TRUE(file_util::PathExists(appcache_path)); 172 // The appcaches of the protected origin weren't deleted, but the appcache of
173 // the normal origin were.
174 EXPECT_FALSE(appcache_service->GroupDeleted(kProtectedManifest1));
175 EXPECT_FALSE(appcache_service->GroupDeleted(kProtectedManifest2));
176 EXPECT_TRUE(appcache_service->GroupDeleted(kNormalManifest1));
177 EXPECT_TRUE(appcache_service->GroupDeleted(kNormalManifest2));
178 EXPECT_TRUE(callback_called_);
74 } 179 }
75 180
76 TEST_F(ChromeAppCacheServiceTest, RemoveOnDestruction) { 181 TEST_F(ChromeAppCacheServiceTest, ClearEmptyAppCache) {
77 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); 182 // Tests ChromeAppCacheService::ClearAppCache(): the callback function should
78 FilePath appcache_path = temp_dir_.path().Append(kTestingAppCacheDirname); 183 // be called even if there are no appcaches to clear.
79 scoped_refptr<ChromeAppCacheService> appcache_service = 184 scoped_refptr<TestableChromeAppCacheService> appcache_service =
80 new ChromeAppCacheService(NULL); 185 new TestableChromeAppCacheService(NULL);
186 appcache_service->set_empty(true);
81 const content::ResourceContext* resource_context = NULL; 187 const content::ResourceContext* resource_context = NULL;
188 scoped_refptr<quota::MockSpecialStoragePolicy> mock_policy =
189 new quota::MockSpecialStoragePolicy;
190 // Passing an empty FilePath is ok; nothing will be saved on the disk during
191 // the test.
82 BrowserThread::PostTask( 192 BrowserThread::PostTask(
83 BrowserThread::IO, FROM_HERE, 193 BrowserThread::IO, FROM_HERE,
84 NewRunnableMethod(appcache_service.get(), 194 NewRunnableMethod(appcache_service.get(),
85 &ChromeAppCacheService::InitializeOnIOThread, 195 &ChromeAppCacheService::InitializeOnIOThread,
86 appcache_path, 196 FilePath(),
87 resource_context, 197 resource_context,
88 scoped_refptr<quota::SpecialStoragePolicy>(NULL), 198 mock_policy));
89 true)); 199 // Spin the message loop so that the initialization really happens.
90 // Make the steps needed to initialize the storage of AppCache data.
91 message_loop_.RunAllPending();
92 appcache::AppCacheStorageImpl* storage =
93 static_cast<appcache::AppCacheStorageImpl*>(appcache_service->storage());
94 ASSERT_TRUE(storage->database_->db_connection());
95 ASSERT_EQ(1, storage->NewCacheId());
96 storage->disk_cache();
97 message_loop_.RunAllPending(); 200 message_loop_.RunAllPending();
98 201
99 ASSERT_TRUE(file_util::PathExists(appcache_path)); 202 appcache_service->ClearAppCache(&appcache_cleared_callback_);
100 ASSERT_TRUE(file_util::PathExists(appcache_path.AppendASCII("Index")));
101 203
102 appcache_service = NULL; 204 // Spin the message loop so that the asynchronous operations (mainly, calling
205 // the callback) happen.
103 message_loop_.RunAllPending(); 206 message_loop_.RunAllPending();
104 207
105 ASSERT_FALSE(file_util::PathExists(appcache_path)); 208 EXPECT_TRUE(callback_called_);
209 }
210
211 TEST_F(ChromeAppCacheServiceTest, ClearAppCacheWithoutCallback) {
212 // Tests ChromeAppCacheService::ClearAppCache(): passing NULL as callback
213 // should be ok and the functionality should be the same as in the case with
214 // the callback.
215 scoped_refptr<TestableChromeAppCacheService> appcache_service =
216 new TestableChromeAppCacheService(NULL);
217 const content::ResourceContext* resource_context = NULL;
218 scoped_refptr<quota::MockSpecialStoragePolicy> mock_policy =
219 new quota::MockSpecialStoragePolicy;
220 mock_policy->AddProtected(kProtectedOrigin);
221 // Passing an empty FilePath is ok; nothing will be saved on the disk during
222 // the test.
223 BrowserThread::PostTask(
224 BrowserThread::IO, FROM_HERE,
225 NewRunnableMethod(appcache_service.get(),
226 &ChromeAppCacheService::InitializeOnIOThread,
227 FilePath(),
228 resource_context,
229 mock_policy));
230 // Spin the message loop so that the initialization really happens.
231 message_loop_.RunAllPending();
232
233 appcache_service->ClearAppCache(NULL);
234
235 // Spin the message loop so that the asynchronous operations have a chance to
236 // happen.
237 message_loop_.RunAllPending();
238
239 // The appcaches of the protected origin weren't deleted, but the appcache of
240 // the normal origin were.
241 EXPECT_FALSE(appcache_service->GroupDeleted(kProtectedManifest1));
242 EXPECT_FALSE(appcache_service->GroupDeleted(kProtectedManifest2));
243 EXPECT_TRUE(appcache_service->GroupDeleted(kNormalManifest1));
244 EXPECT_TRUE(appcache_service->GroupDeleted(kNormalManifest2));
106 } 245 }
107 246
108 } // namespace appcache 247 } // namespace appcache
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698