OLD | NEW |
---|---|
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" |
13 #include "webkit/appcache/appcache_database.h" | |
14 #include "webkit/appcache/appcache_storage_impl.h" | 14 #include "webkit/appcache/appcache_storage_impl.h" |
15 #include "webkit/quota/mock_special_storage_policy.h" | |
16 | |
17 #include <set> | |
15 | 18 |
16 namespace { | 19 namespace { |
17 const FilePath::CharType kTestingAppCacheDirname[] = | 20 const FilePath::CharType kTestingAppCacheDirname[] = |
michaeln
2011/07/07 19:06:51
is this needed anymore?
marja(google)
2011/07/13 11:13:16
Done.
| |
18 FILE_PATH_LITERAL("Application Cache"); | 21 FILE_PATH_LITERAL("Application Cache"); |
22 | |
23 // Examples of a protected and an unprotected origin, to be used througout the | |
24 // test. | |
25 const GURL kProtectedOrigin("http://www.protected.com/"); | |
26 const GURL kNormalOrigin("http://www.normal.com/"); | |
27 | |
28 } // unnamed namespace | |
29 | |
30 namespace appcache { | |
31 | |
32 // This subclass overwrites 2 functions (GetAllAppCacheInfo and | |
33 // DeleteAppcachesForOrigin). It enables unit testing the internal logic of | |
34 // ChromeAppCacheInfo (deleting only non-protected origins from the app cache). | |
35 class TestableChromeAppCacheService : public ChromeAppCacheService | |
36 { | |
37 public: | |
38 explicit TestableChromeAppCacheService(quota::QuotaManagerProxy* proxy); | |
39 | |
40 // Mock implementations | |
41 virtual void GetAllAppCacheInfo(AppCacheInfoCollection* collection, | |
42 net::CompletionCallback* callback); | |
43 | |
44 virtual void DeleteAppCachesForOrigin(const GURL& origin, | |
45 net::CompletionCallback* callback); | |
46 | |
47 // public so that the test program can read it | |
48 std::set<GURL> deleted_origins_; | |
49 bool callback_called_; | |
50 private: | |
51 // Helper function for the mock implementation | |
52 static void DeferredCallCallback(net::CompletionCallback* callback, int rv); | |
53 }; | |
54 | |
55 TestableChromeAppCacheService::TestableChromeAppCacheService( | |
56 quota::QuotaManagerProxy* proxy) | |
57 : ChromeAppCacheService(proxy), callback_called_(false) | |
58 { | |
michaeln
2011/07/07 19:06:51
style nit: bracket goes on the previous line
| |
19 } | 59 } |
20 | 60 |
21 namespace appcache { | 61 void TestableChromeAppCacheService::GetAllAppCacheInfo( |
62 AppCacheInfoCollection* collection, | |
63 net::CompletionCallback* callback) | |
64 { | |
michaeln
2011/07/07 19:06:51
style nit: bracket goes on the previous line
marja(google)
2011/07/13 11:13:16
Done.
| |
65 AppCacheInfoVector info_vector; | |
66 collection->infos_by_origin[kProtectedOrigin]; | |
michaeln
2011/07/07 19:06:51
Did you mean to make an assignment here to info_ve
marja(google)
2011/07/13 11:13:16
Done.
I rewrote this func; now there shouldn't be
| |
67 collection->infos_by_origin[kNormalOrigin]; | |
68 callback->Run(0); | |
69 } | |
70 | |
71 void TestableChromeAppCacheService::DeleteAppCachesForOrigin( | |
72 const GURL& origin, | |
73 net::CompletionCallback* callback) | |
74 { | |
michaeln
2011/07/07 19:06:51
style nit: bracket goes on the previous line
marja(google)
2011/07/13 11:13:16
Done.
| |
75 deleted_origins_.insert(origin); | |
76 // The callback must be called asynchronously, otherwise the code breaks. | |
77 // Defer to guarentee async completion. | |
78 MessageLoop::current()->PostTask( | |
79 FROM_HERE, | |
michaeln
2011/07/07 19:06:51
style nit: indent the params by 2 more spaces
marja(google)
2011/07/13 11:13:16
Done.
| |
80 NewRunnableFunction(&DeferredCallCallback, callback, 0)); | |
81 } | |
82 | |
83 void TestableChromeAppCacheService::DeferredCallCallback( | |
84 net::CompletionCallback* callback, int rv){ | |
85 callback->Run(rv); | |
86 } | |
22 | 87 |
23 class ChromeAppCacheServiceTest : public TestingBrowserProcessTest { | 88 class ChromeAppCacheServiceTest : public TestingBrowserProcessTest { |
24 public: | 89 public: |
25 ChromeAppCacheServiceTest() | 90 ChromeAppCacheServiceTest() |
26 : message_loop_(MessageLoop::TYPE_IO), | 91 : message_loop_(MessageLoop::TYPE_IO), |
92 ALLOW_THIS_IN_INITIALIZER_LIST(appcache_cleared_callback_( | |
93 this, &ChromeAppCacheServiceTest::OnAppCacheCleared)), | |
94 callback_called_(false), | |
27 db_thread_(BrowserThread::DB, &message_loop_), | 95 db_thread_(BrowserThread::DB, &message_loop_), |
28 file_thread_(BrowserThread::FILE, &message_loop_), | 96 file_thread_(BrowserThread::FILE, &message_loop_), |
29 cache_thread_(BrowserThread::CACHE, &message_loop_), | 97 cache_thread_(BrowserThread::CACHE, &message_loop_), |
30 io_thread_(BrowserThread::IO, &message_loop_) { | 98 io_thread_(BrowserThread::IO, &message_loop_) { |
31 } | 99 } |
32 | 100 |
33 protected: | 101 protected: |
34 MessageLoop message_loop_; | 102 MessageLoop message_loop_; |
35 ScopedTempDir temp_dir_; | 103 net::CompletionCallbackImpl<ChromeAppCacheServiceTest> |
104 appcache_cleared_callback_; | |
105 bool callback_called_; | |
36 | 106 |
37 private: | 107 private: |
108 void OnAppCacheCleared(int rv); | |
109 | |
38 BrowserThread db_thread_; | 110 BrowserThread db_thread_; |
39 BrowserThread file_thread_; | 111 BrowserThread file_thread_; |
40 BrowserThread cache_thread_; | 112 BrowserThread cache_thread_; |
41 BrowserThread io_thread_; | 113 BrowserThread io_thread_; |
42 }; | 114 }; |
43 | 115 |
44 TEST_F(ChromeAppCacheServiceTest, KeepOnDestruction) { | 116 void ChromeAppCacheServiceTest::OnAppCacheCleared(int rv) |
45 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); | 117 { |
michaeln
2011/07/07 19:06:51
style nit: bracket goes on the previous line
marja(google)
2011/07/13 11:13:16
Done.
| |
46 FilePath appcache_path = temp_dir_.path().Append(kTestingAppCacheDirname); | 118 callback_called_ = true; |
47 scoped_refptr<ChromeAppCacheService> appcache_service = | 119 } |
48 new ChromeAppCacheService(NULL); | 120 |
121 TEST_F(ChromeAppCacheServiceTest, ClearAppCache) { | |
122 // Tests ChromeAppCacheService::ClearAppCache(): nonprotected origins should | |
123 // be deleted an protected origins should not. | |
124 scoped_refptr<TestableChromeAppCacheService> appcache_service = | |
125 new TestableChromeAppCacheService(NULL); | |
49 const content::ResourceContext* resource_context = NULL; | 126 const content::ResourceContext* resource_context = NULL; |
127 scoped_refptr<quota::MockSpecialStoragePolicy> mock_policy = | |
128 new quota::MockSpecialStoragePolicy; | |
129 mock_policy->AddProtected(kProtectedOrigin); | |
130 // Passing an empty FilePath is ok; nothing will be saved on the disk during | |
131 // the test. | |
50 BrowserThread::PostTask( | 132 BrowserThread::PostTask( |
51 BrowserThread::IO, FROM_HERE, | 133 BrowserThread::IO, FROM_HERE, |
52 NewRunnableMethod(appcache_service.get(), | 134 NewRunnableMethod(appcache_service.get(), |
53 &ChromeAppCacheService::InitializeOnIOThread, | 135 &ChromeAppCacheService::InitializeOnIOThread, |
54 appcache_path, | 136 FilePath(""), |
55 resource_context, | 137 resource_context, |
56 scoped_refptr<quota::SpecialStoragePolicy>(NULL), | 138 mock_policy)); |
57 false)); | 139 // 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(); | 140 message_loop_.RunAllPending(); |
66 | 141 |
67 ASSERT_TRUE(file_util::PathExists(appcache_path)); | 142 appcache_service->ClearAppCache(&appcache_cleared_callback_); |
68 ASSERT_TRUE(file_util::PathExists(appcache_path.AppendASCII("Index"))); | |
69 | 143 |
70 appcache_service = NULL; | 144 // Spin the message loop so that the asynchronous operations (mainly, calling |
145 // the callback) happen. | |
71 message_loop_.RunAllPending(); | 146 message_loop_.RunAllPending(); |
72 | 147 |
73 ASSERT_TRUE(file_util::PathExists(appcache_path)); | 148 // The appcache of the protected origin wasn't deleted, but the appcache of |
149 // the normal origin was. | |
150 ASSERT_EQ(appcache_service->deleted_origins_.find(kProtectedOrigin), | |
151 appcache_service->deleted_origins_.end()); | |
152 ASSERT_NE(appcache_service->deleted_origins_.find(kNormalOrigin), | |
153 appcache_service->deleted_origins_.end()); | |
154 ASSERT_TRUE(callback_called_); | |
74 } | 155 } |
75 | 156 |
76 TEST_F(ChromeAppCacheServiceTest, RemoveOnDestruction) { | 157 TEST_F(ChromeAppCacheServiceTest, ClearEmptyAppCache) { |
77 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); | 158 // Tests ChromeAppCacheService::ClearAppCache(): the callback function should |
78 FilePath appcache_path = temp_dir_.path().Append(kTestingAppCacheDirname); | 159 // be called even if there are no appcaches to clear. |
79 scoped_refptr<ChromeAppCacheService> appcache_service = | 160 scoped_refptr<TestableChromeAppCacheService> appcache_service = |
80 new ChromeAppCacheService(NULL); | 161 new TestableChromeAppCacheService(NULL); |
81 const content::ResourceContext* resource_context = NULL; | 162 const content::ResourceContext* resource_context = NULL; |
163 scoped_refptr<quota::MockSpecialStoragePolicy> mock_policy = | |
164 new quota::MockSpecialStoragePolicy; | |
165 // Passing an empty FilePath is ok; nothing will be saved on the disk during | |
166 // the test. | |
82 BrowserThread::PostTask( | 167 BrowserThread::PostTask( |
83 BrowserThread::IO, FROM_HERE, | 168 BrowserThread::IO, FROM_HERE, |
84 NewRunnableMethod(appcache_service.get(), | 169 NewRunnableMethod(appcache_service.get(), |
85 &ChromeAppCacheService::InitializeOnIOThread, | 170 &ChromeAppCacheService::InitializeOnIOThread, |
86 appcache_path, | 171 FilePath(""), |
87 resource_context, | 172 resource_context, |
88 scoped_refptr<quota::SpecialStoragePolicy>(NULL), | 173 mock_policy)); |
89 true)); | 174 // 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(); | 175 message_loop_.RunAllPending(); |
98 | 176 |
99 ASSERT_TRUE(file_util::PathExists(appcache_path)); | 177 appcache_service->ClearAppCache(&appcache_cleared_callback_); |
100 ASSERT_TRUE(file_util::PathExists(appcache_path.AppendASCII("Index"))); | |
101 | 178 |
102 appcache_service = NULL; | 179 // Spin the message loop so that the asynchronous operations (mainly, calling |
180 // the callback) happen. | |
103 message_loop_.RunAllPending(); | 181 message_loop_.RunAllPending(); |
104 | 182 |
105 ASSERT_FALSE(file_util::PathExists(appcache_path)); | 183 ASSERT_TRUE(callback_called_); |
184 } | |
185 | |
186 TEST_F(ChromeAppCacheServiceTest, ClearAppCacheWithoutCallback) { | |
187 // Tests ChromeAppCacheService::ClearAppCache(): passing NULL as callback | |
188 // should be ok and the functionality should be the same as in the case with | |
189 // the callback. | |
190 scoped_refptr<TestableChromeAppCacheService> appcache_service = | |
191 new TestableChromeAppCacheService(NULL); | |
192 const content::ResourceContext* resource_context = NULL; | |
193 scoped_refptr<quota::MockSpecialStoragePolicy> mock_policy = | |
194 new quota::MockSpecialStoragePolicy; | |
195 mock_policy->AddProtected(kProtectedOrigin); | |
196 // Passing an empty FilePath is ok; nothing will be saved on the disk during | |
197 // the test. | |
198 BrowserThread::PostTask( | |
199 BrowserThread::IO, FROM_HERE, | |
200 NewRunnableMethod(appcache_service.get(), | |
201 &ChromeAppCacheService::InitializeOnIOThread, | |
202 FilePath(""), | |
michaeln
2011/07/07 19:06:51
i think the default ctor would work here (and else
marja(google)
2011/07/13 11:13:16
Done.
| |
203 resource_context, | |
204 mock_policy)); | |
205 // Spin the message loop so that the initialization really happens. | |
206 message_loop_.RunAllPending(); | |
207 | |
208 appcache_service->ClearAppCache(NULL); | |
209 | |
210 // Spin the message loop so that the asynchronous operations have a chance to | |
211 // happen. | |
212 message_loop_.RunAllPending(); | |
213 | |
214 // The appcache of the protected origin wasn't deleted, but the appcache of | |
215 // the normal origin was. | |
216 ASSERT_EQ(appcache_service->deleted_origins_.find(kProtectedOrigin), | |
217 appcache_service->deleted_origins_.end()); | |
218 ASSERT_NE(appcache_service->deleted_origins_.find(kNormalOrigin), | |
219 appcache_service->deleted_origins_.end()); | |
220 ASSERT_FALSE(callback_called_); | |
106 } | 221 } |
107 | 222 |
108 } // namespace appcache | 223 } // namespace appcache |
OLD | NEW |