Disable view source for Developer Tools.
[chromium-blink-merge.git] / chrome / browser / chromeos / policy / cloud_external_data_manager_base_unittest.cc
blob8636f2fa2696151165bedad7f5b6697cc7d2f3d5
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.
5 #include "chrome/browser/chromeos/policy/cloud_external_data_manager_base.h"
7 #include <map>
8 #include <string>
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.h"
14 #include "base/message_loop/message_loop_proxy.h"
15 #include "base/run_loop.h"
16 #include "base/sha1.h"
17 #include "base/stl_util.h"
18 #include "base/strings/string_number_conversions.h"
19 #include "base/test/test_simple_task_runner.h"
20 #include "base/values.h"
21 #include "chrome/browser/chromeos/policy/cloud_external_data_store.h"
22 #include "components/policy/core/common/cloud/mock_cloud_policy_store.h"
23 #include "components/policy/core/common/cloud/resource_cache.h"
24 #include "components/policy/core/common/external_data_fetcher.h"
25 #include "components/policy/core/common/policy_map.h"
26 #include "components/policy/core/common/policy_test_utils.h"
27 #include "components/policy/core/common/policy_types.h"
28 #include "net/http/http_status_code.h"
29 #include "net/url_request/test_url_fetcher_factory.h"
30 #include "net/url_request/url_fetcher.h"
31 #include "net/url_request/url_fetcher_delegate.h"
32 #include "net/url_request/url_request_status.h"
33 #include "net/url_request/url_request_test_util.h"
34 #include "testing/gtest/include/gtest/gtest.h"
35 #include "url/gurl.h"
37 namespace policy {
39 namespace {
41 // A string policy.
42 const char kStringPolicy[] = "StringPolicy";
43 // A policy that may reference up to 10 bytes of external data.
44 const char k10BytePolicy[] = "10BytePolicy";
45 // A policy that may reference up to 20 bytes of external data.
46 const char k20BytePolicy[] = "20BytePolicy";
47 // A nonexistent policy.
48 const char kUnknownPolicy[] = "UnknownPolicy";
50 const char k10BytePolicyURL[] = "http://localhost/10_bytes";
51 const char k20BytePolicyURL[] = "http://localhost/20_bytes";
53 const char k10ByteData[] = "10 bytes..";
54 const char k20ByteData[] = "20 bytes............";
56 const PolicyDetails kPolicyDetails[] = {
57 // is_deprecated is_device_policy id max_external_data_size
58 { false, false, 1, 0 },
59 { false, false, 2, 10 },
60 { false, false, 3, 20 },
63 const char kCacheKey[] = "data";
65 // A variant of net::FakeURLFetcherFactory that makes it an error to request a
66 // fetcher for an unknown URL.
67 class FakeURLFetcherFactory : public net::FakeURLFetcherFactory {
68 public:
69 FakeURLFetcherFactory();
70 virtual ~FakeURLFetcherFactory();
72 // net::FakeURLFetcherFactory:
73 virtual net::URLFetcher* CreateURLFetcher(
74 int id,
75 const GURL& url,
76 net::URLFetcher::RequestType request_type,
77 net::URLFetcherDelegate* delegate) OVERRIDE;
79 private:
80 DISALLOW_COPY_AND_ASSIGN(FakeURLFetcherFactory);
83 FakeURLFetcherFactory::FakeURLFetcherFactory()
84 : net::FakeURLFetcherFactory(NULL) {
87 FakeURLFetcherFactory::~FakeURLFetcherFactory() {
90 net::URLFetcher* FakeURLFetcherFactory::CreateURLFetcher(
91 int id,
92 const GURL& url,
93 net::URLFetcher::RequestType request_type,
94 net::URLFetcherDelegate* delegate) {
95 net::URLFetcher* fetcher = net::FakeURLFetcherFactory::CreateURLFetcher(
96 id, url, request_type, delegate);
97 EXPECT_TRUE(fetcher);
98 return fetcher;
101 } // namespace
103 class CloudExternalDataManagerBaseTest : public testing::Test {
104 protected:
105 CloudExternalDataManagerBaseTest();
107 virtual void SetUp() OVERRIDE;
108 virtual void TearDown() OVERRIDE;
110 void SetUpExternalDataManager();
112 scoped_ptr<base::DictionaryValue> ConstructMetadata(const std::string& url,
113 const std::string& hash);
114 void SetExternalDataReference(const std::string& policy,
115 scoped_ptr<base::DictionaryValue> metadata);
117 ExternalDataFetcher::FetchCallback ConstructFetchCallback(int id);
118 void ResetCallbackData();
120 void OnFetchDone(int id, scoped_ptr<std::string> data);
122 void FetchAll();
124 void SetFakeResponse(const std::string& url,
125 const std::string& repsonse_data,
126 net::HttpStatusCode response_code,
127 net::URLRequestStatus::Status status);
129 base::MessageLoop message_loop_;
130 base::ScopedTempDir temp_dir_;
131 scoped_ptr<ResourceCache> resource_cache_;
132 MockCloudPolicyStore cloud_policy_store_;
133 scoped_refptr<net::TestURLRequestContextGetter> request_content_getter_;
134 FakeURLFetcherFactory fetcher_factory_;
136 scoped_ptr<CloudExternalDataManagerBase> external_data_manager_;
138 std::map<int, std::string*> callback_data_;
139 PolicyDetailsMap policy_details_;
141 DISALLOW_COPY_AND_ASSIGN(CloudExternalDataManagerBaseTest);
144 CloudExternalDataManagerBaseTest::CloudExternalDataManagerBaseTest() {
147 void CloudExternalDataManagerBaseTest::SetUp() {
148 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
149 resource_cache_.reset(new ResourceCache(temp_dir_.path(),
150 message_loop_.message_loop_proxy()));
151 SetUpExternalDataManager();
153 // Set |kStringPolicy| to a string value.
154 cloud_policy_store_.policy_map_.Set(kStringPolicy,
155 POLICY_LEVEL_MANDATORY,
156 POLICY_SCOPE_USER,
157 new base::StringValue(std::string()),
158 NULL);
159 // Make |k10BytePolicy| reference 10 bytes of external data.
160 SetExternalDataReference(
161 k10BytePolicy,
162 ConstructMetadata(k10BytePolicyURL, base::SHA1HashString(k10ByteData)));
163 // Make |k20BytePolicy| reference 20 bytes of external data.
164 SetExternalDataReference(
165 k20BytePolicy,
166 ConstructMetadata(k20BytePolicyURL, base::SHA1HashString(k20ByteData)));
167 cloud_policy_store_.NotifyStoreLoaded();
169 request_content_getter_ = new net::TestURLRequestContextGetter(
170 base::MessageLoopProxy::current());
172 policy_details_.SetDetails(kStringPolicy, &kPolicyDetails[0]);
173 policy_details_.SetDetails(k10BytePolicy, &kPolicyDetails[1]);
174 policy_details_.SetDetails(k20BytePolicy, &kPolicyDetails[2]);
177 void CloudExternalDataManagerBaseTest::TearDown() {
178 external_data_manager_.reset();
179 base::RunLoop().RunUntilIdle();
180 ResetCallbackData();
183 void CloudExternalDataManagerBaseTest::SetUpExternalDataManager() {
184 external_data_manager_.reset(new CloudExternalDataManagerBase(
185 policy_details_.GetCallback(),
186 message_loop_.message_loop_proxy(),
187 message_loop_.message_loop_proxy()));
188 external_data_manager_->SetExternalDataStore(make_scoped_ptr(
189 new CloudExternalDataStore(kCacheKey,
190 message_loop_.message_loop_proxy(),
191 resource_cache_.get())));
192 external_data_manager_->SetPolicyStore(&cloud_policy_store_);
195 scoped_ptr<base::DictionaryValue>
196 CloudExternalDataManagerBaseTest::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();
206 void CloudExternalDataManagerBaseTest::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));
218 ExternalDataFetcher::FetchCallback
219 CloudExternalDataManagerBaseTest::ConstructFetchCallback(int id) {
220 return base::Bind(&CloudExternalDataManagerBaseTest::OnFetchDone,
221 base::Unretained(this),
222 id);
225 void CloudExternalDataManagerBaseTest::ResetCallbackData() {
226 STLDeleteValues(&callback_data_);
229 void CloudExternalDataManagerBaseTest::OnFetchDone(
230 int id,
231 scoped_ptr<std::string> data) {
232 delete callback_data_[id];
233 callback_data_[id] = data.release();
236 void CloudExternalDataManagerBaseTest::FetchAll() {
237 external_data_manager_->FetchAll();
240 void CloudExternalDataManagerBaseTest::SetFakeResponse(
241 const std::string& url,
242 const std::string& response_data,
243 net::HttpStatusCode response_code,
244 net::URLRequestStatus::Status status) {
245 fetcher_factory_.SetFakeResponse(
246 GURL(url), response_data, response_code, status);
249 // Verifies that when no valid external data reference has been set for a
250 // policy, the attempt to retrieve the external data fails immediately.
251 TEST_F(CloudExternalDataManagerBaseTest, FailToFetchInvalid) {
252 external_data_manager_->Connect(request_content_getter_);
254 // Attempt to retrieve external data for |kStringPolicy|, which is a string
255 // policy that does not reference any external data.
256 external_data_manager_->Fetch(kStringPolicy, ConstructFetchCallback(0));
257 base::RunLoop().RunUntilIdle();
258 EXPECT_EQ(1u, callback_data_.size());
259 EXPECT_TRUE(callback_data_.find(0) != callback_data_.end());
260 EXPECT_FALSE(callback_data_[0]);
261 ResetCallbackData();
263 // Attempt to retrieve external data for |kUnknownPolicy|, which is not a
264 // known policy.
265 external_data_manager_->Fetch(kUnknownPolicy, ConstructFetchCallback(1));
266 base::RunLoop().RunUntilIdle();
267 EXPECT_EQ(1u, callback_data_.size());
268 EXPECT_TRUE(callback_data_.find(1) != callback_data_.end());
269 EXPECT_FALSE(callback_data_[1]);
270 ResetCallbackData();
272 // Set an invalid external data reference for |k10BytePolicy|.
273 SetExternalDataReference(k10BytePolicy,
274 ConstructMetadata(std::string(), std::string()));
275 cloud_policy_store_.NotifyStoreLoaded();
277 // Attempt to retrieve external data for |k10BytePolicy|, which now has an
278 // invalid reference.
279 external_data_manager_->Fetch(k10BytePolicy, ConstructFetchCallback(2));
280 base::RunLoop().RunUntilIdle();
281 EXPECT_EQ(1u, callback_data_.size());
282 EXPECT_TRUE(callback_data_.find(2) != callback_data_.end());
283 EXPECT_FALSE(callback_data_[2]);
284 ResetCallbackData();
287 // Verifies that external data referenced by a policy is downloaded and cached
288 // when first requested. Subsequent requests are served from the cache without
289 // further download attempts.
290 TEST_F(CloudExternalDataManagerBaseTest, DownloadAndCache) {
291 // Serve valid external data for |k10BytePolicy|.
292 SetFakeResponse(k10BytePolicyURL, k10ByteData, net::HTTP_OK,
293 net::URLRequestStatus::SUCCESS);
294 external_data_manager_->Connect(request_content_getter_);
296 // Retrieve external data for |k10BytePolicy|. Verify that a download happens
297 // and the callback is invoked with the downloaded data.
298 external_data_manager_->Fetch(k10BytePolicy, ConstructFetchCallback(0));
299 base::RunLoop().RunUntilIdle();
300 EXPECT_EQ(1u, callback_data_.size());
301 ASSERT_TRUE(callback_data_[0]);
302 EXPECT_EQ(k10ByteData, *callback_data_[0]);
303 ResetCallbackData();
305 // Stop serving external data for |k10BytePolicy|.
306 fetcher_factory_.ClearFakeResponses();
308 // Retrieve external data for |k10BytePolicy| again. Verify that no download
309 // is attempted but the callback is still invoked with the expected data,
310 // served from the cache.
311 external_data_manager_->Fetch(k10BytePolicy, ConstructFetchCallback(1));
312 base::RunLoop().RunUntilIdle();
313 EXPECT_EQ(1u, callback_data_.size());
314 ASSERT_TRUE(callback_data_[1]);
315 EXPECT_EQ(k10ByteData, *callback_data_[1]);
316 ResetCallbackData();
318 // Explicitly tell the external_data_manager_ to not make any download
319 // attempts.
320 external_data_manager_->Disconnect();
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_EQ(1u, callback_data_.size());
328 ASSERT_TRUE(callback_data_[2]);
329 EXPECT_EQ(k10ByteData, *callback_data_[2]);
330 ResetCallbackData();
332 // Verify that the downloaded data is present in the cache.
333 external_data_manager_.reset();
334 base::RunLoop().RunUntilIdle();
335 std::string data;
336 EXPECT_TRUE(CloudExternalDataStore(kCacheKey,
337 message_loop_.message_loop_proxy(),
338 resource_cache_.get()).Load(
339 k10BytePolicy, base::SHA1HashString(k10ByteData), 10, &data));
340 EXPECT_EQ(k10ByteData, data);
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(CloudExternalDataManagerBaseTest, DownloadAndCacheAll) {
347 // Serve valid external data for |k10BytePolicy| and |k20BytePolicy|.
348 SetFakeResponse(k10BytePolicyURL, k10ByteData, net::HTTP_OK,
349 net::URLRequestStatus::SUCCESS);
350 SetFakeResponse(k20BytePolicyURL, k20ByteData, net::HTTP_OK,
351 net::URLRequestStatus::SUCCESS);
352 external_data_manager_->Connect(request_content_getter_);
354 // Request that external data referenced by all policies be downloaded.
355 FetchAll();
356 base::RunLoop().RunUntilIdle();
358 // Stop serving external data for |k10BytePolicy| and |k20BytePolicy|.
359 fetcher_factory_.ClearFakeResponses();
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_EQ(2u, callback_data_.size());
368 ASSERT_TRUE(callback_data_[0]);
369 EXPECT_EQ(k10ByteData, *callback_data_[0]);
370 ASSERT_TRUE(callback_data_[1]);
371 EXPECT_EQ(k20ByteData, *callback_data_[1]);
372 ResetCallbackData();
374 // Explicitly tell the external_data_manager_ to not make any download
375 // attempts.
376 external_data_manager_->Disconnect();
378 // Retrieve external data for |k10BytePolicy| and |k20BytePolicy|. Verify that
379 // even though downloads are not allowed, the callbacks are still invoked with
380 // the expected data, served from the cache.
381 external_data_manager_->Fetch(k10BytePolicy, ConstructFetchCallback(2));
382 external_data_manager_->Fetch(k20BytePolicy, ConstructFetchCallback(3));
383 base::RunLoop().RunUntilIdle();
384 EXPECT_EQ(2u, callback_data_.size());
385 ASSERT_TRUE(callback_data_[2]);
386 EXPECT_EQ(k10ByteData, *callback_data_[2]);
387 ASSERT_TRUE(callback_data_[3]);
388 EXPECT_EQ(k20ByteData, *callback_data_[3]);
389 ResetCallbackData();
391 // Verify that the downloaded data is present in the cache.
392 external_data_manager_.reset();
393 base::RunLoop().RunUntilIdle();
394 CloudExternalDataStore cache(kCacheKey,
395 message_loop_.message_loop_proxy(),
396 resource_cache_.get());
397 std::string data;
398 EXPECT_TRUE(cache.Load(k10BytePolicy, base::SHA1HashString(k10ByteData), 10,
399 &data));
400 EXPECT_EQ(k10ByteData, data);
401 EXPECT_TRUE(cache.Load(k20BytePolicy, base::SHA1HashString(k20ByteData), 20,
402 &data));
403 EXPECT_EQ(k20ByteData, data);
406 // Verifies that when the external data referenced by a policy is not present in
407 // the cache and downloads are not allowed, a request to retrieve the data is
408 // enqueued and carried out when downloads become possible.
409 TEST_F(CloudExternalDataManagerBaseTest, DownloadAfterConnect) {
410 // Attempt to retrieve external data for |k10BytePolicy|. Verify that the
411 // callback is not invoked as the request remains pending.
412 external_data_manager_->Fetch(k10BytePolicy, ConstructFetchCallback(0));
413 base::RunLoop().RunUntilIdle();
414 EXPECT_TRUE(callback_data_.empty());
415 ResetCallbackData();
417 // Serve valid external data for |k10BytePolicy| and allow the
418 // external_data_manager_ to perform downloads.
419 SetFakeResponse(k10BytePolicyURL, k10ByteData, net::HTTP_OK,
420 net::URLRequestStatus::SUCCESS);
421 external_data_manager_->Connect(request_content_getter_);
423 // Verify that a download happens and the callback is invoked with the
424 // downloaded data.
425 base::RunLoop().RunUntilIdle();
426 EXPECT_EQ(1u, callback_data_.size());
427 ASSERT_TRUE(callback_data_[0]);
428 EXPECT_EQ(k10ByteData, *callback_data_[0]);
429 ResetCallbackData();
432 // Verifies that when the external data referenced by a policy is not present in
433 // the cache and cannot be downloaded at this time, a request to retrieve the
434 // data is enqueued to be retried later.
435 TEST_F(CloudExternalDataManagerBaseTest, DownloadError) {
436 // Make attempts to download the external data for |k20BytePolicy| fail with
437 // an error.
438 SetFakeResponse(k20BytePolicyURL, std::string(),
439 net::HTTP_INTERNAL_SERVER_ERROR,
440 net::URLRequestStatus::FAILED);
441 external_data_manager_->Connect(request_content_getter_);
443 // Attempt to retrieve external data for |k20BytePolicy|. Verify that the
444 // callback is not invoked as the download attempt fails and the request
445 // remains pending.
446 external_data_manager_->Fetch(k20BytePolicy, ConstructFetchCallback(0));
447 base::RunLoop().RunUntilIdle();
448 EXPECT_TRUE(callback_data_.empty());
449 ResetCallbackData();
451 // Modify the external data reference for |k20BytePolicy|, allowing the
452 // download to be retried immediately.
453 SetExternalDataReference(
454 k20BytePolicy,
455 ConstructMetadata(k20BytePolicyURL, base::SHA1HashString(k10ByteData)));
456 cloud_policy_store_.NotifyStoreLoaded();
458 // Attempt to retrieve external data for |k20BytePolicy| again. Verify that
459 // no callback is invoked still as the download attempt fails again and the
460 // request remains pending.
461 external_data_manager_->Fetch(k20BytePolicy, ConstructFetchCallback(1));
462 base::RunLoop().RunUntilIdle();
463 EXPECT_TRUE(callback_data_.empty());
464 ResetCallbackData();
466 // Modify the external data reference for |k20BytePolicy|, allowing the
467 // download to be retried immediately.
468 SetExternalDataReference(
469 k20BytePolicy,
470 ConstructMetadata(k20BytePolicyURL, base::SHA1HashString(k20ByteData)));
471 cloud_policy_store_.NotifyStoreLoaded();
473 // Serve external data for |k20BytePolicy| that does not match the hash
474 // specified in its current external data reference.
475 SetFakeResponse(k20BytePolicyURL, k10ByteData, net::HTTP_OK,
476 net::URLRequestStatus::SUCCESS);
478 // Attempt to retrieve external data for |k20BytePolicy| again. Verify that
479 // no callback is invoked still as the downloaded succeeds but returns data
480 // that does not match the external data reference.
481 external_data_manager_->Fetch(k20BytePolicy, ConstructFetchCallback(2));
482 base::RunLoop().RunUntilIdle();
483 EXPECT_TRUE(callback_data_.empty());
484 ResetCallbackData();
486 // Modify the external data reference for |k20BytePolicy|, allowing the
487 // download to be retried immediately. The external data reference now matches
488 // the data being served.
489 SetExternalDataReference(
490 k20BytePolicy,
491 ConstructMetadata(k20BytePolicyURL, base::SHA1HashString(k10ByteData)));
492 cloud_policy_store_.NotifyStoreLoaded();
494 // Attempt to retrieve external data for |k20BytePolicy| again. Verify that
495 // the current callback and the three previously enqueued callbacks are
496 // invoked with the downloaded data now.
497 external_data_manager_->Fetch(k20BytePolicy, ConstructFetchCallback(3));
498 base::RunLoop().RunUntilIdle();
499 EXPECT_EQ(4u, callback_data_.size());
500 ASSERT_TRUE(callback_data_[0]);
501 EXPECT_EQ(k10ByteData, *callback_data_[0]);
502 ASSERT_TRUE(callback_data_[1]);
503 EXPECT_EQ(k10ByteData, *callback_data_[1]);
504 ASSERT_TRUE(callback_data_[2]);
505 EXPECT_EQ(k10ByteData, *callback_data_[2]);
506 ASSERT_TRUE(callback_data_[3]);
507 EXPECT_EQ(k10ByteData, *callback_data_[3]);
508 ResetCallbackData();
511 // Verifies that when the external data referenced by a policy is present in the
512 // cache, a request to retrieve it is served from the cache without any download
513 // attempts.
514 TEST_F(CloudExternalDataManagerBaseTest, LoadFromCache) {
515 // Store valid external data for |k10BytePolicy| in the cache.
516 external_data_manager_.reset();
517 base::RunLoop().RunUntilIdle();
518 EXPECT_TRUE(CloudExternalDataStore(kCacheKey,
519 message_loop_.message_loop_proxy(),
520 resource_cache_.get()).Store(
521 k10BytePolicy, base::SHA1HashString(k10ByteData), k10ByteData));
523 // Instantiate an external_data_manager_ that uses the primed cache.
524 SetUpExternalDataManager();
525 external_data_manager_->Connect(request_content_getter_);
527 // Retrieve external data for |k10BytePolicy|. Verify that no download is
528 // attempted but the callback is still invoked with the expected data, served
529 // from the cache.
530 external_data_manager_->Fetch(k10BytePolicy, ConstructFetchCallback(0));
531 base::RunLoop().RunUntilIdle();
532 EXPECT_EQ(1u, callback_data_.size());
533 ASSERT_TRUE(callback_data_[0]);
534 EXPECT_EQ(k10ByteData, *callback_data_[0]);
535 ResetCallbackData();
538 // Verifies that cache entries which do not correspond to the external data
539 // referenced by any policy are pruned on startup.
540 TEST_F(CloudExternalDataManagerBaseTest, PruneCacheOnStartup) {
541 external_data_manager_.reset();
542 base::RunLoop().RunUntilIdle();
543 scoped_ptr<CloudExternalDataStore>
544 cache(new CloudExternalDataStore(kCacheKey,
545 message_loop_.message_loop_proxy(),
546 resource_cache_.get()));
547 // Store valid external data for |k10BytePolicy| in the cache.
548 EXPECT_TRUE(cache->Store(k10BytePolicy,
549 base::SHA1HashString(k10ByteData),
550 k10ByteData));
551 // Store external data for |k20BytePolicy| that does not match the hash in its
552 // external data reference.
553 EXPECT_TRUE(cache->Store(k20BytePolicy,
554 base::SHA1HashString(k10ByteData),
555 k10ByteData));
556 // Store external data for |kUnknownPolicy|, which is not a known policy and
557 // therefore, cannot be referencing any external data.
558 EXPECT_TRUE(cache->Store(kUnknownPolicy,
559 base::SHA1HashString(k10ByteData),
560 k10ByteData));
561 cache.reset();
563 // Instantiate and destroy an ExternalDataManager that uses the primed cache.
564 SetUpExternalDataManager();
565 external_data_manager_.reset();
566 base::RunLoop().RunUntilIdle();
568 cache.reset(new CloudExternalDataStore(kCacheKey,
569 message_loop_.message_loop_proxy(),
570 resource_cache_.get()));
571 std::string data;
572 // Verify that the valid external data for |k10BytePolicy| is still in the
573 // cache.
574 EXPECT_TRUE(cache->Load(k10BytePolicy, base::SHA1HashString(k10ByteData),
575 10, &data));
576 EXPECT_EQ(k10ByteData, data);
577 // Verify that the external data for |k20BytePolicy| and |kUnknownPolicy| has
578 // been pruned from the cache.
579 EXPECT_FALSE(cache->Load(k20BytePolicy, base::SHA1HashString(k10ByteData),
580 20, &data));
581 EXPECT_FALSE(cache->Load(kUnknownPolicy, base::SHA1HashString(k10ByteData),
582 20, &data));
585 // Verifies that when the external data referenced by a policy is present in the
586 // cache and the reference changes, the old data is pruned from the cache.
587 TEST_F(CloudExternalDataManagerBaseTest, PruneCacheOnChange) {
588 // Store valid external data for |k20BytePolicy| in the cache.
589 external_data_manager_.reset();
590 base::RunLoop().RunUntilIdle();
591 scoped_ptr<CloudExternalDataStore>
592 cache(new CloudExternalDataStore(kCacheKey,
593 message_loop_.message_loop_proxy(),
594 resource_cache_.get()));
595 EXPECT_TRUE(cache->Store(k20BytePolicy,
596 base::SHA1HashString(k20ByteData),
597 k20ByteData));
598 cache.reset();
600 // Instantiate an ExternalDataManager that uses the primed cache.
601 SetUpExternalDataManager();
602 external_data_manager_->Connect(request_content_getter_);
604 // Modify the external data reference for |k20BytePolicy|.
605 SetExternalDataReference(
606 k20BytePolicy,
607 ConstructMetadata(k20BytePolicyURL, base::SHA1HashString(k10ByteData)));
608 cloud_policy_store_.NotifyStoreLoaded();
610 // Verify that the old external data for |k20BytePolicy| has been pruned from
611 // the cache.
612 external_data_manager_.reset();
613 base::RunLoop().RunUntilIdle();
614 cache.reset(new CloudExternalDataStore(kCacheKey,
615 message_loop_.message_loop_proxy(),
616 resource_cache_.get()));
617 std::string data;
618 EXPECT_FALSE(cache->Load(k20BytePolicy, base::SHA1HashString(k20ByteData), 20,
619 &data));
622 // Verifies that corrupt cache entries are detected and deleted when accessed.
623 TEST_F(CloudExternalDataManagerBaseTest, CacheCorruption) {
624 external_data_manager_.reset();
625 base::RunLoop().RunUntilIdle();
626 scoped_ptr<CloudExternalDataStore>
627 cache(new CloudExternalDataStore(kCacheKey,
628 message_loop_.message_loop_proxy(),
629 resource_cache_.get()));
630 // Store external data for |k10BytePolicy| that exceeds the maximal external
631 // data size allowed for that policy.
632 EXPECT_TRUE(cache->Store(k10BytePolicy,
633 base::SHA1HashString(k20ByteData),
634 k20ByteData));
635 // Store external data for |k20BytePolicy| that is corrupted and does not
636 // match the expected hash.
637 EXPECT_TRUE(cache->Store(k20BytePolicy,
638 base::SHA1HashString(k20ByteData),
639 k10ByteData));
640 cache.reset();
642 SetUpExternalDataManager();
643 // Serve external data for |k10BytePolicy| that exceeds the maximal external
644 // data size allowed for that policy.
645 SetFakeResponse(k10BytePolicyURL, k20ByteData, net::HTTP_OK,
646 net::URLRequestStatus::SUCCESS);
647 external_data_manager_->Connect(request_content_getter_);
649 // Modify the external data reference for |k10BytePolicy| to match the
650 // external data being served.
651 SetExternalDataReference(
652 k10BytePolicy,
653 ConstructMetadata(k10BytePolicyURL, base::SHA1HashString(k20ByteData)));
654 cloud_policy_store_.NotifyStoreLoaded();
656 // Retrieve external data for |k10BytePolicy|. Verify that the callback is
657 // not invoked as the cached and downloaded external data exceed the maximal
658 // size allowed for this policy and the request remains pending.
659 external_data_manager_->Fetch(k10BytePolicy, ConstructFetchCallback(0));
660 base::RunLoop().RunUntilIdle();
661 EXPECT_TRUE(callback_data_.empty());
662 ResetCallbackData();
664 // Serve valid external data for |k20BytePolicy|.
665 SetFakeResponse(k20BytePolicyURL, k20ByteData, net::HTTP_OK,
666 net::URLRequestStatus::SUCCESS);
668 // Retrieve external data for |k20BytePolicy|. Verify that the callback is
669 // invoked with the valid downloaded data, not the invalid data in the cache.
670 external_data_manager_->Fetch(k20BytePolicy, ConstructFetchCallback(1));
671 base::RunLoop().RunUntilIdle();
672 EXPECT_EQ(1u, callback_data_.size());
673 ASSERT_TRUE(callback_data_[1]);
674 EXPECT_EQ(k20ByteData, *callback_data_[1]);
675 ResetCallbackData();
677 external_data_manager_.reset();
678 base::RunLoop().RunUntilIdle();
679 cache.reset(new CloudExternalDataStore(kCacheKey,
680 message_loop_.message_loop_proxy(),
681 resource_cache_.get()));
682 std::string data;
683 // Verify that the invalid external data for |k10BytePolicy| has been pruned
684 // from the cache. Load() will return |false| in two cases:
685 // 1) The cache entry for |k10BytePolicy| has been pruned.
686 // 2) The cache entry for |k10BytePolicy| still exists but the cached data
687 // does not match the expected hash or exceeds the maximum size allowed.
688 // To test for the former, Load() is called with a maximum data size and hash
689 // that would allow the data originally written to the cache to be loaded.
690 // When this fails, it is certain that the original data is no longer present
691 // in the cache.
692 EXPECT_FALSE(cache->Load(k10BytePolicy, base::SHA1HashString(k20ByteData), 20,
693 &data));
694 // Verify that the invalid external data for |k20BytePolicy| has been replaced
695 // with the downloaded valid data in the cache.
696 EXPECT_TRUE(cache->Load(k20BytePolicy, base::SHA1HashString(k20ByteData), 20,
697 &data));
698 EXPECT_EQ(k20ByteData, data);
701 // Verifies that when the external data reference for a policy changes while a
702 // download of the external data for that policy is pending, the download is
703 // immediately retried using the new reference.
704 TEST_F(CloudExternalDataManagerBaseTest, PolicyChangeWhileDownloadPending) {
705 // Make attempts to download the external data for |k10BytePolicy| and
706 // |k20BytePolicy| fail with an error.
707 SetFakeResponse(k10BytePolicyURL, std::string(),
708 net::HTTP_INTERNAL_SERVER_ERROR,
709 net::URLRequestStatus::FAILED);
710 SetFakeResponse(k20BytePolicyURL, std::string(),
711 net::HTTP_INTERNAL_SERVER_ERROR,
712 net::URLRequestStatus::FAILED);
713 external_data_manager_->Connect(request_content_getter_);
715 // Attempt to retrieve external data for |k10BytePolicy| and |k20BytePolicy|.
716 // Verify that no callbacks are invoked as the download attempts fail and the
717 // requests remain pending.
718 external_data_manager_->Fetch(k10BytePolicy, ConstructFetchCallback(0));
719 external_data_manager_->Fetch(k20BytePolicy, ConstructFetchCallback(1));
720 base::RunLoop().RunUntilIdle();
721 EXPECT_TRUE(callback_data_.empty());
722 ResetCallbackData();
724 // Modify the external data reference for |k10BytePolicy| to be invalid.
725 // Verify that the callback is invoked as the policy no longer has a valid
726 // external data reference.
727 cloud_policy_store_.policy_map_.Erase(k10BytePolicy);
728 cloud_policy_store_.NotifyStoreLoaded();
729 base::RunLoop().RunUntilIdle();
730 EXPECT_EQ(1u, callback_data_.size());
731 EXPECT_TRUE(callback_data_.find(0) != callback_data_.end());
732 EXPECT_FALSE(callback_data_[0]);
733 ResetCallbackData();
735 // Serve valid external data for |k20BytePolicy|.
736 fetcher_factory_.ClearFakeResponses();
737 SetFakeResponse(k20BytePolicyURL, k10ByteData, net::HTTP_OK,
738 net::URLRequestStatus::SUCCESS);
740 // Modify the external data reference for |k20BytePolicy| to match the
741 // external data now being served. Verify that the callback is invoked with
742 // the downloaded data.
743 SetExternalDataReference(
744 k20BytePolicy,
745 ConstructMetadata(k20BytePolicyURL, base::SHA1HashString(k10ByteData)));
746 cloud_policy_store_.NotifyStoreLoaded();
747 base::RunLoop().RunUntilIdle();
748 EXPECT_EQ(1u, callback_data_.size());
749 ASSERT_TRUE(callback_data_[1]);
750 EXPECT_EQ(k10ByteData, *callback_data_[1]);
751 ResetCallbackData();
754 } // namespace policy