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

Side by Side Diff: chrome/browser/policy/cloud/cloud_external_data_manager_base_unittest.cc

Issue 19462006: Implement fetching, caching and retrieval of external policy data (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 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
(Empty)
1 // Copyright 2013 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 "chrome/browser/policy/cloud/cloud_external_data_manager_base.h"
6
7 #include <map>
8 #include <string>
9
10 #include "base/bind.h"
11 #include "base/bind_helpers.h"
12 #include "base/files/scoped_temp_dir.h"
13 #include "base/message_loop/message_loop_proxy.h"
14 #include "base/run_loop.h"
15 #include "base/sequenced_task_runner.h"
16 #include "base/sha1.h"
17 #include "base/stl_util.h"
18 #include "base/strings/string_number_conversions.h"
19 #include "base/values.h"
20 #include "chrome/browser/policy/cloud/cloud_external_data_store.h"
21 #include "chrome/browser/policy/cloud/mock_cloud_policy_store.h"
22 #include "chrome/browser/policy/cloud/resource_cache.h"
23 #include "chrome/browser/policy/external_data_fetcher.h"
24 #include "chrome/browser/policy/policy_map.h"
25 #include "chrome/browser/policy/policy_types.h"
26 #include "content/public/test/test_browser_thread_bundle.h"
27 #include "net/url_request/test_url_fetcher_factory.h"
28 #include "net/url_request/url_fetcher.h"
29 #include "net/url_request/url_fetcher_delegate.h"
30 #include "net/url_request/url_fetcher_factory.h"
31 #include "net/url_request/url_request_test_util.h"
32 #include "policy/policy_constants.h"
33 #include "testing/gtest/include/gtest/gtest.h"
34 #include "url/gurl.h"
35
36 namespace policy {
37
38 namespace {
39
40 // A string policy.
41 const char kStringPolicy[] = "StringPolicy";
42 // A policy that may reference up to 10 bytes of external data.
43 const char k10BytePolicy[] = "10BytePolicy";
44 // A policy that may reference up to 20 bytes of external data.
45 const char k20BytePolicy[] = "20BytePolicy";
46 // A nonexistent policy.
47 const char kUnknownPolicy[] = "UnknownPolicy";
48
49 const char k10BytePolicyURL[] = "http://localhost/10_bytes";
50 const char k20BytePolicyURL[] = "http://localhost/20_bytes";
51
52 const char k10ByteData[] = "10 bytes..";
53 const char k20ByteData[] = "20 bytes............";
54
55 const PolicyDefinitionList::Entry kPolicyDefinitionListEntries[] = {
56 { kStringPolicy, base::Value::TYPE_STRING, false, 1, 0 },
57 { k10BytePolicy, base::Value::TYPE_DICTIONARY, false, 2, 10 },
58 { k20BytePolicy, base::Value::TYPE_DICTIONARY, false, 3, 20 },
59 };
60
61 const PolicyDefinitionList kPolicyDefinitionList = {
62 kPolicyDefinitionListEntries,
63 kPolicyDefinitionListEntries + arraysize(kPolicyDefinitionListEntries),
64 };
65
66 const char kCacheKey[] = "data";
67
68 class FetchAttemptBlockingURLFetcherFactory : public net::URLFetcherFactory {
69 public:
70 FetchAttemptBlockingURLFetcherFactory();
71 virtual ~FetchAttemptBlockingURLFetcherFactory();
72
73 bool GetFetchAttempted() const;
74 void ClearFetchAttempted();
Joao da Silva 2013/07/19 11:15:15 IIUC this class is meant to prevent creation of fe
bartfab (slow) 2013/07/19 13:06:30 Done.
75
76 // net::URLFetcherFactory:
77 virtual net::URLFetcher* CreateURLFetcher(
78 int id,
79 const GURL& url,
80 net::URLFetcher::RequestType request_type,
81 net::URLFetcherDelegate* delegate) OVERRIDE;
82
83 private:
84 bool fetch_attempted_;
85
86 DISALLOW_COPY_AND_ASSIGN(FetchAttemptBlockingURLFetcherFactory);
87 };
88
89 FetchAttemptBlockingURLFetcherFactory::FetchAttemptBlockingURLFetcherFactory()
90 : fetch_attempted_(false) {
91 }
92
93 FetchAttemptBlockingURLFetcherFactory::
94 ~FetchAttemptBlockingURLFetcherFactory() {
95 }
96
97 bool FetchAttemptBlockingURLFetcherFactory::GetFetchAttempted() const {
98 return fetch_attempted_;
99 }
100
101 void FetchAttemptBlockingURLFetcherFactory::ClearFetchAttempted() {
102 fetch_attempted_ = false;
103 }
104
105 net::URLFetcher* FetchAttemptBlockingURLFetcherFactory::CreateURLFetcher(
106 int id,
107 const GURL& url,
108 net::URLFetcher::RequestType request_type,
109 net::URLFetcherDelegate* delegate) {
110 fetch_attempted_ = true;
111 return NULL;
112 }
113
114 } // namespace
115
116 class CouldExternalDataManagerBaseTest : public testing::Test {
117 protected:
118 CouldExternalDataManagerBaseTest();
119
120 virtual void SetUp() OVERRIDE;
121 virtual void TearDown() OVERRIDE;
122
123 void SetUpExternalDataManager();
124
125 scoped_ptr<base::DictionaryValue> ConstructMetadata(const std::string& url,
126 const std::string& hash);
127 void SetExternalDataReference(const std::string& policy,
128 scoped_ptr<base::DictionaryValue> metadata);
129
130 ExternalDataFetcher::FetchCallback ConstructFetchCallback(int id);
131 void ResetCallbackData();
132
133 void OnFetchDone(int id, scoped_ptr<std::string> data);
134
135 void FetchAll();
136
137 content::TestBrowserThreadBundle thread_bundle_;
138
139 base::ScopedTempDir temp_dir_;
140 scoped_ptr<ResourceCache> resource_cache_;
141 MockCloudPolicyStore cloud_policy_store_;
142 scoped_refptr<net::TestURLRequestContextGetter> request_content_getter_;
143 FetchAttemptBlockingURLFetcherFactory default_fetcher_factory_;
144 net::FakeURLFetcherFactory fake_fetcher_factory_;
145
146 scoped_ptr<CloudExternalDataManagerBase> external_data_manager_;
147
148 std::map<int, std::string*> callback_data_;
149
150 DISALLOW_COPY_AND_ASSIGN(CouldExternalDataManagerBaseTest);
151 };
152
153 CouldExternalDataManagerBaseTest::CouldExternalDataManagerBaseTest()
154 : thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP),
155 fake_fetcher_factory_(&default_fetcher_factory_) {
156 }
157
158 void CouldExternalDataManagerBaseTest::SetUp() {
159 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
160 resource_cache_.reset(new ResourceCache(temp_dir_.path()));
161 SetUpExternalDataManager();
162
163 // Set |kStringPolicy| to a string value.
164 cloud_policy_store_.policy_map_.Set(kStringPolicy,
165 POLICY_LEVEL_MANDATORY,
166 POLICY_SCOPE_USER,
167 new base::StringValue(std::string()),
168 NULL);
169 // Make |k10BytePolicy| reference 10 bytes of external data.
170 SetExternalDataReference(
171 k10BytePolicy,
172 ConstructMetadata(k10BytePolicyURL, base::SHA1HashString(k10ByteData)));
173 // Make |k20BytePolicy| reference 20 bytes of external data.
174 SetExternalDataReference(
175 k20BytePolicy,
176 ConstructMetadata(k20BytePolicyURL, base::SHA1HashString(k20ByteData)));
177 cloud_policy_store_.NotifyStoreLoaded();
178
179 request_content_getter_ = new net::TestURLRequestContextGetter(
180 base::MessageLoopProxy::current());
181 }
182
183 void CouldExternalDataManagerBaseTest::TearDown() {
184 ResetCallbackData();
185 }
186
187 void CouldExternalDataManagerBaseTest::SetUpExternalDataManager() {
188 external_data_manager_.reset(new CloudExternalDataManagerBase(
189 &kPolicyDefinitionList, base::MessageLoopProxy::current()));
190 external_data_manager_->SetExternalDataStore(make_scoped_ptr(
191 new CloudExternalDataStore(kCacheKey, resource_cache_.get())));
192 external_data_manager_->SetPolicyStore(&cloud_policy_store_);
193 }
194
195 scoped_ptr<base::DictionaryValue>
196 CouldExternalDataManagerBaseTest::ConstructMetadata(
197 const std::string& url,
198 const std::string& hash) {
199 scoped_ptr<base::DictionaryValue> metadata(new base::DictionaryValue);
200 metadata->SetStringWithoutPathExpansion("url", url);
201 metadata->SetStringWithoutPathExpansion("hash", base::HexEncode(hash.c_str(),
202 hash.size()));
203 return metadata.Pass();
204 }
205
206 void CouldExternalDataManagerBaseTest::SetExternalDataReference(
207 const std::string& policy,
208 scoped_ptr<base::DictionaryValue> metadata) {
209 cloud_policy_store_.policy_map_.Set(
210 policy,
211 POLICY_LEVEL_MANDATORY,
212 POLICY_SCOPE_USER,
213 metadata.release(),
214 new ExternalDataFetcher(
215 external_data_manager_->weak_factory_.GetWeakPtr(), policy));
216 }
217
218 ExternalDataFetcher::FetchCallback
219 CouldExternalDataManagerBaseTest::ConstructFetchCallback(int id) {
220 return base::Bind(&CouldExternalDataManagerBaseTest::OnFetchDone,
221 base::Unretained(this),
222 id);
223 }
224
225 void CouldExternalDataManagerBaseTest::ResetCallbackData() {
226 STLDeleteValues(&callback_data_);
227 }
228
229 void CouldExternalDataManagerBaseTest::OnFetchDone(
230 int id,
231 scoped_ptr<std::string> data) {
232 delete callback_data_[id];
233 callback_data_[id] = data.release();
234 }
235
236 void CouldExternalDataManagerBaseTest::FetchAll() {
237 external_data_manager_->FetchAll();
238 }
239
240 // Verifies that when no valid external data reference has been set for a
241 // policy, the attempt to retrieve the external data fails immediately.
242 TEST_F(CouldExternalDataManagerBaseTest, FailToFetchInvalid) {
243 external_data_manager_->Connect(request_content_getter_);
244
245 // Attempt to retrieve external data for |kStringPolicy|, which is a string
246 // policy that does not reference any external data.
247 external_data_manager_->Fetch(kStringPolicy, ConstructFetchCallback(0));
248 base::RunLoop().RunUntilIdle();
249 EXPECT_FALSE(default_fetcher_factory_.GetFetchAttempted());
250 default_fetcher_factory_.ClearFetchAttempted();
251 EXPECT_EQ(1u, callback_data_.size());
252 EXPECT_TRUE(callback_data_.find(0) != callback_data_.end());
253 EXPECT_FALSE(callback_data_[0]);
254 ResetCallbackData();
255
256 // Attempt to retrieve external data for |kUnknownPolicy|, which is not a
257 // known policy.
258 external_data_manager_->Fetch(kUnknownPolicy, ConstructFetchCallback(1));
259 base::RunLoop().RunUntilIdle();
260 EXPECT_FALSE(default_fetcher_factory_.GetFetchAttempted());
261 default_fetcher_factory_.ClearFetchAttempted();
262 EXPECT_EQ(1u, callback_data_.size());
263 EXPECT_TRUE(callback_data_.find(1) != callback_data_.end());
264 EXPECT_FALSE(callback_data_[1]);
265 ResetCallbackData();
266
267 // Set an invalid external data reference for |k10BytePolicy|.
268 SetExternalDataReference(k10BytePolicy,
269 ConstructMetadata(std::string(), std::string()));
270 cloud_policy_store_.NotifyStoreLoaded();
271
272 // Attempt to retrieve external data for |k10BytePolicy|, which now has an
273 // invalid reference.
274 external_data_manager_->Fetch(k10BytePolicy, ConstructFetchCallback(2));
275 base::RunLoop().RunUntilIdle();
276 EXPECT_FALSE(default_fetcher_factory_.GetFetchAttempted());
277 default_fetcher_factory_.ClearFetchAttempted();
278 EXPECT_EQ(1u, callback_data_.size());
279 EXPECT_TRUE(callback_data_.find(2) != callback_data_.end());
280 EXPECT_FALSE(callback_data_[2]);
281 ResetCallbackData();
282 }
283
284 // Verifies that external data referenced by a policy is downloaded and cached
285 // when first requested. Subsequent requests are served from the cache without
286 // further download attempts.
287 TEST_F(CouldExternalDataManagerBaseTest, DownloadAndCache) {
288 // Serve valid external data for |k10BytePolicy|.
289 fake_fetcher_factory_.SetFakeResponse(k10BytePolicyURL, k10ByteData, true);
290 external_data_manager_->Connect(request_content_getter_);
291
292 // Retrieve external data for |k10BytePolicy|. Verify that a download happens
293 // and the callback is invoked with the downloaded data.
294 external_data_manager_->Fetch(k10BytePolicy, ConstructFetchCallback(0));
295 base::RunLoop().RunUntilIdle();
296 EXPECT_FALSE(default_fetcher_factory_.GetFetchAttempted());
297 default_fetcher_factory_.ClearFetchAttempted();
298 EXPECT_EQ(1u, callback_data_.size());
299 ASSERT_TRUE(callback_data_[0]);
300 EXPECT_EQ(k10ByteData, *callback_data_[0]);
301 ResetCallbackData();
302
303 // Stop serving external data for |k10BytePolicy|.
304 fake_fetcher_factory_.ClearFakeResponses();
305
306 // Retrieve external data for |k10BytePolicy| again. Verify that no download
307 // is attempted but the callback is still invoked with the expected data,
308 // served from the cache.
309 external_data_manager_->Fetch(k10BytePolicy, ConstructFetchCallback(1));
310 base::RunLoop().RunUntilIdle();
311 EXPECT_FALSE(default_fetcher_factory_.GetFetchAttempted());
312 default_fetcher_factory_.ClearFetchAttempted();
313 EXPECT_EQ(1u, callback_data_.size());
314 ASSERT_TRUE(callback_data_[1]);
315 EXPECT_EQ(k10ByteData, *callback_data_[1]);
316 ResetCallbackData();
317
318 // Explicitly tell the external_data_manager_ to not make any download
319 // attempts.
320 external_data_manager_->Disconnect();
321
322 // Retrieve external data for |k10BytePolicy| again. Verify that even though
323 // downloads are not allowed, the callback is still invoked with the expected
324 // data, served from the cache.
325 external_data_manager_->Fetch(k10BytePolicy, ConstructFetchCallback(2));
326 base::RunLoop().RunUntilIdle();
327 EXPECT_FALSE(default_fetcher_factory_.GetFetchAttempted());
328 default_fetcher_factory_.ClearFetchAttempted();
329 EXPECT_EQ(1u, callback_data_.size());
330 ASSERT_TRUE(callback_data_[2]);
331 EXPECT_EQ(k10ByteData, *callback_data_[2]);
332 ResetCallbackData();
333
334 // Verify that the downloaded data is present in the cache.
335 external_data_manager_.reset();
336 base::RunLoop().RunUntilIdle();
337 std::string data;
338 EXPECT_TRUE(CloudExternalDataStore(kCacheKey, resource_cache_.get()).Load(
339 k10BytePolicy, base::SHA1HashString(k10ByteData), 10, &data));
340 EXPECT_EQ(k10ByteData, data);
341 }
342
343 // Verifies that a request to download and cache all external data referenced by
344 // policies is carried out correctly. Subsequent requests for the data are
345 // served from the cache without further download attempts.
346 TEST_F(CouldExternalDataManagerBaseTest, DownloadAndCacheAll) {
347 // Serve valid external data for |k10BytePolicy| and |k20BytePolicy|.
348 fake_fetcher_factory_.SetFakeResponse(k10BytePolicyURL, k10ByteData, true);
349 fake_fetcher_factory_.SetFakeResponse(k20BytePolicyURL, k20ByteData, true);
350 external_data_manager_->Connect(request_content_getter_);
351
352 // Request that external data referenced by all policies be downloaded.
353 FetchAll();
354 base::RunLoop().RunUntilIdle();
355 EXPECT_FALSE(default_fetcher_factory_.GetFetchAttempted());
356 default_fetcher_factory_.ClearFetchAttempted();
357
358 // Stop serving external data for |k10BytePolicy| and |k20BytePolicy|.
359 fake_fetcher_factory_.ClearFakeResponses();
360
361 // Retrieve external data for |k10BytePolicy| and |k20BytePolicy|. Verify that
362 // no downloads are attempted but the callbacks are still invoked with the
363 // expected data, served from the cache.
364 external_data_manager_->Fetch(k10BytePolicy, ConstructFetchCallback(0));
365 external_data_manager_->Fetch(k20BytePolicy, ConstructFetchCallback(1));
366 base::RunLoop().RunUntilIdle();
367 EXPECT_FALSE(default_fetcher_factory_.GetFetchAttempted());
368 default_fetcher_factory_.ClearFetchAttempted();
369 EXPECT_EQ(2u, callback_data_.size());
370 ASSERT_TRUE(callback_data_[0]);
371 EXPECT_EQ(k10ByteData, *callback_data_[0]);
372 ASSERT_TRUE(callback_data_[1]);
373 EXPECT_EQ(k20ByteData, *callback_data_[1]);
374 ResetCallbackData();
375
376 // Explicitly tell the external_data_manager_ to not make any download
377 // attempts.
378 external_data_manager_->Disconnect();
379
380 // Retrieve external data for |k10BytePolicy| and |k20BytePolicy|. Verify that
381 // even though downloads are not allowed, the callbacks are still invoked with
382 // the expected data, served from the cache.
383 external_data_manager_->Fetch(k10BytePolicy, ConstructFetchCallback(2));
384 external_data_manager_->Fetch(k20BytePolicy, ConstructFetchCallback(3));
385 base::RunLoop().RunUntilIdle();
386 EXPECT_FALSE(default_fetcher_factory_.GetFetchAttempted());
387 default_fetcher_factory_.ClearFetchAttempted();
388 EXPECT_EQ(2u, callback_data_.size());
389 ASSERT_TRUE(callback_data_[2]);
390 EXPECT_EQ(k10ByteData, *callback_data_[2]);
391 ASSERT_TRUE(callback_data_[3]);
392 EXPECT_EQ(k20ByteData, *callback_data_[3]);
393 ResetCallbackData();
394
395 // Verify that the downloaded data is present in the cache.
396 external_data_manager_.reset();
397 base::RunLoop().RunUntilIdle();
398 CloudExternalDataStore cache(kCacheKey, resource_cache_.get());
399 std::string data;
400 EXPECT_TRUE(cache.Load(k10BytePolicy, base::SHA1HashString(k10ByteData), 10,
401 &data));
402 EXPECT_EQ(k10ByteData, data);
403 EXPECT_TRUE(cache.Load(k20BytePolicy, base::SHA1HashString(k20ByteData), 20,
404 &data));
405 EXPECT_EQ(k20ByteData, data);
406 }
407
408 // Verifies that when the external data referenced by a policy is not present in
409 // the cache and downloads are not allowed, a request to retrieve the data is
410 // enqueued and carried out when downloads become possible.
411 TEST_F(CouldExternalDataManagerBaseTest, DownloadAfterConnect) {
412 // Attempt to retrieve external data for |k10BytePolicy|. Verify that the
413 // callback is not invoked as the request remains pending.
414 external_data_manager_->Fetch(k10BytePolicy, ConstructFetchCallback(0));
415 base::RunLoop().RunUntilIdle();
416 EXPECT_TRUE(callback_data_.empty());
417 ResetCallbackData();
418
419 // Serve valid external data for |k10BytePolicy| and allow the
420 // external_data_manager_ to perform downloads.
421 fake_fetcher_factory_.SetFakeResponse(k10BytePolicyURL, k10ByteData, true);
422 external_data_manager_->Connect(request_content_getter_);
423
424 // Verify that a download happens and the callback is invoked with the
425 // downloaded data.
426 base::RunLoop().RunUntilIdle();
427 EXPECT_FALSE(default_fetcher_factory_.GetFetchAttempted());
428 default_fetcher_factory_.ClearFetchAttempted();
429 EXPECT_EQ(1u, callback_data_.size());
430 ASSERT_TRUE(callback_data_[0]);
431 EXPECT_EQ(k10ByteData, *callback_data_[0]);
432 ResetCallbackData();
433 }
434
435 // Verifies that when the external data referenced by a policy is not present in
436 // the cache and cannot be downloaded at this time, a request to retrieve the
437 // data is enqueued to be retried later.
438 TEST_F(CouldExternalDataManagerBaseTest, DownloadError) {
439 // Make attempts to download the external data for |k20BytePolicy| fail with
440 // an error.
441 fake_fetcher_factory_.SetFakeResponse(k20BytePolicyURL, std::string(), false);
442 external_data_manager_->Connect(request_content_getter_);
443
444 // Attempt to retrieve external data for |k20BytePolicy|. Verify that the
445 // callback is not invoked as the download attempt fails and the request
446 // remains pending.
447 external_data_manager_->Fetch(k20BytePolicy, ConstructFetchCallback(0));
448 base::RunLoop().RunUntilIdle();
449 EXPECT_FALSE(default_fetcher_factory_.GetFetchAttempted());
450 default_fetcher_factory_.ClearFetchAttempted();
451 EXPECT_TRUE(callback_data_.empty());
452 ResetCallbackData();
453
454 // Modify the external data reference for |k20BytePolicy|, allowing the
455 // download to be retried immediately.
456 SetExternalDataReference(
457 k20BytePolicy,
458 ConstructMetadata(k20BytePolicyURL, base::SHA1HashString(k10ByteData)));
459 cloud_policy_store_.NotifyStoreLoaded();
460
461 // Attempt to retrieve external data for |k20BytePolicy| again. Verify that
462 // no callback is invoked still as the download attempt fails again and the
463 // request remains pending.
464 external_data_manager_->Fetch(k20BytePolicy, ConstructFetchCallback(1));
465 base::RunLoop().RunUntilIdle();
466 EXPECT_FALSE(default_fetcher_factory_.GetFetchAttempted());
467 default_fetcher_factory_.ClearFetchAttempted();
468 EXPECT_TRUE(callback_data_.empty());
469 ResetCallbackData();
470
471 // Modify the external data reference for |k20BytePolicy|, allowing the
472 // download to be retried immediately.
473 SetExternalDataReference(
474 k20BytePolicy,
475 ConstructMetadata(k20BytePolicyURL, base::SHA1HashString(k20ByteData)));
476 cloud_policy_store_.NotifyStoreLoaded();
477
478 // Serve external data for |k20BytePolicy| that does not match the hash
479 // specified in its current external data reference.
480 fake_fetcher_factory_.SetFakeResponse(k20BytePolicyURL, k10ByteData, true);
481
482 // Attempt to retrieve external data for |k20BytePolicy| again. Verify that
483 // no callback is invoked still as the downloaded succeeds but returns data
484 // that does not match the external data reference.
485 external_data_manager_->Fetch(k20BytePolicy, ConstructFetchCallback(2));
486 base::RunLoop().RunUntilIdle();
487 EXPECT_FALSE(default_fetcher_factory_.GetFetchAttempted());
488 default_fetcher_factory_.ClearFetchAttempted();
489 EXPECT_TRUE(callback_data_.empty());
490 ResetCallbackData();
491
492 // Modify the external data reference for |k20BytePolicy|, allowing the
493 // download to be retried immediately. The external data reference now matches
494 // the data being served.
495 SetExternalDataReference(
496 k20BytePolicy,
497 ConstructMetadata(k20BytePolicyURL, base::SHA1HashString(k10ByteData)));
498 cloud_policy_store_.NotifyStoreLoaded();
499
500 // Attempt to retrieve external data for |k20BytePolicy| again. Verify that
501 // the current callback and the three previously enqueued callbacks are
502 // invoked with the downloaded data now.
503 external_data_manager_->Fetch(k20BytePolicy, ConstructFetchCallback(3));
504 base::RunLoop().RunUntilIdle();
505 EXPECT_FALSE(default_fetcher_factory_.GetFetchAttempted());
506 default_fetcher_factory_.ClearFetchAttempted();
507 EXPECT_EQ(4u, callback_data_.size());
508 ASSERT_TRUE(callback_data_[0]);
509 EXPECT_EQ(k10ByteData, *callback_data_[0]);
510 ASSERT_TRUE(callback_data_[1]);
511 EXPECT_EQ(k10ByteData, *callback_data_[1]);
512 ASSERT_TRUE(callback_data_[2]);
513 EXPECT_EQ(k10ByteData, *callback_data_[2]);
514 ASSERT_TRUE(callback_data_[3]);
515 EXPECT_EQ(k10ByteData, *callback_data_[3]);
516 ResetCallbackData();
517 }
518
519 // Verifies that when the external data referenced by a policy is present in the
520 // cache, a request to retrieve it is served from the cache without any download
521 // attempts.
522 TEST_F(CouldExternalDataManagerBaseTest, LoadFromCache) {
523 // Store valid external data for |k10BytePolicy| in the cache.
524 external_data_manager_.reset();
525 base::RunLoop().RunUntilIdle();
526 EXPECT_TRUE(CloudExternalDataStore(kCacheKey, resource_cache_.get()).Store(
527 k10BytePolicy, base::SHA1HashString(k10ByteData), k10ByteData));
528
529 // Instantiate an external_data_manager_ that uses the primed cache.
530 SetUpExternalDataManager();
531 external_data_manager_->Connect(request_content_getter_);
532
533 // Retrieve external data for |k10BytePolicy|. Verify that no download is
534 // attempted but the callback is still invoked with the expected data, served
535 // from the cache.
536 external_data_manager_->Fetch(k10BytePolicy, ConstructFetchCallback(0));
537 base::RunLoop().RunUntilIdle();
538 EXPECT_FALSE(default_fetcher_factory_.GetFetchAttempted());
539 default_fetcher_factory_.ClearFetchAttempted();
540 EXPECT_EQ(1u, callback_data_.size());
541 ASSERT_TRUE(callback_data_[0]);
542 EXPECT_EQ(k10ByteData, *callback_data_[0]);
543 ResetCallbackData();
544 }
545
546 // Verifies that cache entries which do not correspond to the external data
547 // referenced by any policy are pruned on startup.
548 TEST_F(CouldExternalDataManagerBaseTest, PruneCacheOnStartup) {
549 external_data_manager_.reset();
550 base::RunLoop().RunUntilIdle();
551 scoped_ptr<CloudExternalDataStore>
552 cache(new CloudExternalDataStore(kCacheKey, resource_cache_.get()));
553 // Store valid external data for |k10BytePolicy| in the cache.
554 EXPECT_TRUE(cache->Store(k10BytePolicy,
555 base::SHA1HashString(k10ByteData),
556 k10ByteData));
557 // Store external data for |k20BytePolicy| that does not match the hash in its
558 // external data reference.
559 EXPECT_TRUE(cache->Store(k20BytePolicy,
560 base::SHA1HashString(k10ByteData),
561 k10ByteData));
562 // Store external data for |kUnknownPolicy|, which is not a known policy and
563 // therefore, cannot be referencing any external data.
564 EXPECT_TRUE(cache->Store(kUnknownPolicy,
565 base::SHA1HashString(k10ByteData),
566 k10ByteData));
567 cache.reset();
568
569 // Instantiate and destroy an ExternalDataManager that uses the primed cache.
570 SetUpExternalDataManager();
571 external_data_manager_.reset();
572 base::RunLoop().RunUntilIdle();
573
574 cache.reset(new CloudExternalDataStore(kCacheKey, resource_cache_.get()));
575 std::string data;
576 // Verify that the valid external data for |k10BytePolicy| is still in the
577 // cache.
578 EXPECT_TRUE(cache->Load(k10BytePolicy, base::SHA1HashString(k10ByteData),
579 10, &data));
580 EXPECT_EQ(k10ByteData, data);
581 // Verify that the external data for |k20BytePolicy| and |kUnknownPolicy| has
582 // been pruned from the cache.
583 EXPECT_FALSE(cache->Load(k20BytePolicy, base::SHA1HashString(k10ByteData),
584 20, &data));
585 EXPECT_FALSE(cache->Load(kUnknownPolicy, base::SHA1HashString(k10ByteData),
586 20, &data));
587 }
588
589 // Verifies that when the external data referenced by a policy is present in the
590 // cache and the reference changes, the old data is pruned from the cache.
591 TEST_F(CouldExternalDataManagerBaseTest, PruneCacheOnChange) {
592 // Store valid external data for |k20BytePolicy| in the cache.
593 external_data_manager_.reset();
594 base::RunLoop().RunUntilIdle();
595 scoped_ptr<CloudExternalDataStore>
596 cache(new CloudExternalDataStore(kCacheKey, resource_cache_.get()));
597 EXPECT_TRUE(cache->Store(k20BytePolicy,
598 base::SHA1HashString(k20ByteData),
599 k20ByteData));
600 cache.reset();
601
602 // Instantiate an ExternalDataManager that uses the primed cache.
603 SetUpExternalDataManager();
604 external_data_manager_->Connect(request_content_getter_);
605
606 // Modify the external data reference for |k20BytePolicy|.
607 SetExternalDataReference(
608 k20BytePolicy,
609 ConstructMetadata(k20BytePolicyURL, base::SHA1HashString(k10ByteData)));
610 cloud_policy_store_.NotifyStoreLoaded();
611
612 // Verify that the old external data for |k20BytePolicy| has been pruned from
613 // the cache.
614 external_data_manager_.reset();
615 base::RunLoop().RunUntilIdle();
616 cache.reset(new CloudExternalDataStore(kCacheKey, resource_cache_.get()));
617 std::string data;
618 EXPECT_FALSE(cache->Load(k20BytePolicy, base::SHA1HashString(k20ByteData), 20,
619 &data));
620 }
621
622 // Verifies that corrupt cache entries are detected and deleted when accessed.
623 TEST_F(CouldExternalDataManagerBaseTest, CacheCorruption) {
624 external_data_manager_.reset();
625 base::RunLoop().RunUntilIdle();
626 scoped_ptr<CloudExternalDataStore>
627 cache(new CloudExternalDataStore(kCacheKey, resource_cache_.get()));
628 // Store external data for |k10BytePolicy| that exceeds the maximal external
629 // data size allowed for that policy.
630 EXPECT_TRUE(cache->Store(k10BytePolicy,
631 base::SHA1HashString(k20ByteData),
632 k20ByteData));
633 // Store external data for |k20BytePolicy| that is corrupted and does not
634 // match the expected hash.
635 EXPECT_TRUE(cache->Store(k20BytePolicy,
636 base::SHA1HashString(k20ByteData),
637 k10ByteData));
638 cache.reset();
639
640 SetUpExternalDataManager();
641 // Serve external data for |k10BytePolicy| that exceeds the maximal external
642 // data size allowed for that policy.
643 fake_fetcher_factory_.SetFakeResponse(k10BytePolicyURL, k20ByteData, true);
644 external_data_manager_->Connect(request_content_getter_);
645
646 // Modify the external data reference for |k10BytePolicy| to match the
647 // external data being served.
648 SetExternalDataReference(
649 k10BytePolicy,
650 ConstructMetadata(k10BytePolicyURL, base::SHA1HashString(k20ByteData)));
651 cloud_policy_store_.NotifyStoreLoaded();
652
653 // Retrieve external data for |k10BytePolicy|. Verify that the callback is
654 // not invoked as the cached and downloaded external data exceed the maximal
655 // size allowed for this policy and the request remains pending.
656 external_data_manager_->Fetch(k10BytePolicy, ConstructFetchCallback(0));
657 base::RunLoop().RunUntilIdle();
658 EXPECT_FALSE(default_fetcher_factory_.GetFetchAttempted());
659 default_fetcher_factory_.ClearFetchAttempted();
660 EXPECT_TRUE(callback_data_.empty());
661 ResetCallbackData();
662
663 // Serve valid external data for |k20BytePolicy|.
664 fake_fetcher_factory_.SetFakeResponse(k20BytePolicyURL, k20ByteData, true);
665
666 // Retrieve external data for |k20BytePolicy|. Verify that the callback is
667 // invoked with the valid downloaded data, not the invalid data in the cache.
668 external_data_manager_->Fetch(k20BytePolicy, ConstructFetchCallback(1));
669 base::RunLoop().RunUntilIdle();
670 EXPECT_FALSE(default_fetcher_factory_.GetFetchAttempted());
671 default_fetcher_factory_.ClearFetchAttempted();
672 EXPECT_EQ(1u, callback_data_.size());
673 ASSERT_TRUE(callback_data_[1]);
674 EXPECT_EQ(k20ByteData, *callback_data_[1]);
675 ResetCallbackData();
676
677 external_data_manager_.reset();
678 base::RunLoop().RunUntilIdle();
679 cache.reset(new CloudExternalDataStore(kCacheKey, resource_cache_.get()));
680 std::string data;
681 // Verify that the invalid external data for |k10BytePolicy| has been pruned
682 // from the cache. Load() will return |false| in two cases:
683 // 1) The cache entry for |k10BytePolicy| has been pruned.
684 // 2) The cache entry for |k10BytePolicy| still exists but the cached data
685 // does not match the expected hash or exceeds the maximum size allowed.
686 // To test for the former, Load() is called with a maximum data size and hash
687 // that would allow the data originally written to the cache to be loaded.
688 // When this fails, it is certain that the original data is no longer present
689 // in the cache.
690 EXPECT_FALSE(cache->Load(k10BytePolicy, base::SHA1HashString(k20ByteData), 20,
691 &data));
692 // Verify that the invalid external data for |k20BytePolicy| has been replaced
693 // with the downloaded valid data in the cache.
694 EXPECT_TRUE(cache->Load(k20BytePolicy, base::SHA1HashString(k20ByteData), 20,
695 &data));
696 EXPECT_EQ(k20ByteData, data);
697 }
698
699 // Verifies that when the external data reference for a policy changes while a
700 // download of the external data for that policy is pending, the download is
701 // immediately retried using the new reference.
702 TEST_F(CouldExternalDataManagerBaseTest, PolicyChangeWhileDownloadPending) {
703 // Make attempts to download the external data for |k10BytePolicy| and
704 // |k20BytePolicy| fail with an error.
705 fake_fetcher_factory_.SetFakeResponse(k10BytePolicyURL, std::string(), false);
706 fake_fetcher_factory_.SetFakeResponse(k20BytePolicyURL, std::string(), false);
707 external_data_manager_->Connect(request_content_getter_);
708
709 // Attempt to retrieve external data for |k10BytePolicy| and |k20BytePolicy|.
710 // Verify that no callbacks are invoked as the download attempts fail and the
711 // requests remain pending.
712 external_data_manager_->Fetch(k10BytePolicy, ConstructFetchCallback(0));
713 external_data_manager_->Fetch(k20BytePolicy, ConstructFetchCallback(1));
714 base::RunLoop().RunUntilIdle();
715 EXPECT_FALSE(default_fetcher_factory_.GetFetchAttempted());
716 default_fetcher_factory_.ClearFetchAttempted();
717 EXPECT_TRUE(callback_data_.empty());
718 ResetCallbackData();
719
720 // Modify the external data reference for |k10BytePolicy| to be invalid.
721 // Verify that the callback is invoked as the policy no longer has a valid
722 // external data reference.
723 cloud_policy_store_.policy_map_.Erase(k10BytePolicy);
724 cloud_policy_store_.NotifyStoreLoaded();
725 base::RunLoop().RunUntilIdle();
726 EXPECT_FALSE(default_fetcher_factory_.GetFetchAttempted());
727 default_fetcher_factory_.ClearFetchAttempted();
728 EXPECT_EQ(1u, callback_data_.size());
729 EXPECT_TRUE(callback_data_.find(0) != callback_data_.end());
730 EXPECT_FALSE(callback_data_[0]);
731 ResetCallbackData();
732
733 // Serve valid external data for |k20BytePolicy|.
734 fake_fetcher_factory_.ClearFakeResponses();
735 fake_fetcher_factory_.SetFakeResponse(k20BytePolicyURL, k10ByteData, true);
736
737 // Modify the external data reference for |k20BytePolicy| to match the
738 // external data now being served. Verify that the callback is invoked with
739 // the downloaded data.
740 SetExternalDataReference(
741 k20BytePolicy,
742 ConstructMetadata(k20BytePolicyURL, base::SHA1HashString(k10ByteData)));
743 cloud_policy_store_.NotifyStoreLoaded();
744 base::RunLoop().RunUntilIdle();
745 EXPECT_FALSE(default_fetcher_factory_.GetFetchAttempted());
746 default_fetcher_factory_.ClearFetchAttempted();
747 EXPECT_EQ(1u, callback_data_.size());
748 ASSERT_TRUE(callback_data_[1]);
749 EXPECT_EQ(k10ByteData, *callback_data_[1]);
750 ResetCallbackData();
751 }
752
753 } // namespace policy
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698