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

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

Powered by Google App Engine
This is Rietveld 408576698