[Android] Allow multiple --install in bb_device_steps.py.
[chromium-blink-merge.git] / chrome / browser / chromeos / policy / cloud_external_data_manager_base_unittest.cc
blob8ba07da267f7ad4239c4b03d098438ec8d0d244c
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/stl_util.h"
17 #include "base/strings/string_number_conversions.h"
18 #include "base/test/test_simple_task_runner.h"
19 #include "base/values.h"
20 #include "chrome/browser/chromeos/policy/cloud_external_data_store.h"
21 #include "components/policy/core/common/cloud/mock_cloud_policy_store.h"
22 #include "components/policy/core/common/cloud/resource_cache.h"
23 #include "components/policy/core/common/external_data_fetcher.h"
24 #include "components/policy/core/common/policy_map.h"
25 #include "components/policy/core/common/policy_test_utils.h"
26 #include "components/policy/core/common/policy_types.h"
27 #include "crypto/sha2.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 private:
142 DISALLOW_COPY_AND_ASSIGN(CloudExternalDataManagerBaseTest);
145 CloudExternalDataManagerBaseTest::CloudExternalDataManagerBaseTest() {
148 void CloudExternalDataManagerBaseTest::SetUp() {
149 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
150 resource_cache_.reset(new ResourceCache(temp_dir_.path(),
151 message_loop_.message_loop_proxy()));
152 SetUpExternalDataManager();
154 // Set |kStringPolicy| to a string value.
155 cloud_policy_store_.policy_map_.Set(kStringPolicy,
156 POLICY_LEVEL_MANDATORY,
157 POLICY_SCOPE_USER,
158 new base::StringValue(std::string()),
159 NULL);
160 // Make |k10BytePolicy| reference 10 bytes of external data.
161 SetExternalDataReference(
162 k10BytePolicy,
163 ConstructMetadata(k10BytePolicyURL,
164 crypto::SHA256HashString(k10ByteData)));
165 // Make |k20BytePolicy| reference 20 bytes of external data.
166 SetExternalDataReference(
167 k20BytePolicy,
168 ConstructMetadata(k20BytePolicyURL,
169 crypto::SHA256HashString(k20ByteData)));
170 cloud_policy_store_.NotifyStoreLoaded();
172 request_content_getter_ = new net::TestURLRequestContextGetter(
173 base::MessageLoopProxy::current());
175 policy_details_.SetDetails(kStringPolicy, &kPolicyDetails[0]);
176 policy_details_.SetDetails(k10BytePolicy, &kPolicyDetails[1]);
177 policy_details_.SetDetails(k20BytePolicy, &kPolicyDetails[2]);
180 void CloudExternalDataManagerBaseTest::TearDown() {
181 external_data_manager_.reset();
182 base::RunLoop().RunUntilIdle();
183 ResetCallbackData();
186 void CloudExternalDataManagerBaseTest::SetUpExternalDataManager() {
187 external_data_manager_.reset(new CloudExternalDataManagerBase(
188 policy_details_.GetCallback(),
189 message_loop_.message_loop_proxy(),
190 message_loop_.message_loop_proxy()));
191 external_data_manager_->SetExternalDataStore(make_scoped_ptr(
192 new CloudExternalDataStore(kCacheKey,
193 message_loop_.message_loop_proxy(),
194 resource_cache_.get())));
195 external_data_manager_->SetPolicyStore(&cloud_policy_store_);
198 scoped_ptr<base::DictionaryValue>
199 CloudExternalDataManagerBaseTest::ConstructMetadata(
200 const std::string& url,
201 const std::string& hash) {
202 scoped_ptr<base::DictionaryValue> metadata(new base::DictionaryValue);
203 metadata->SetStringWithoutPathExpansion("url", url);
204 metadata->SetStringWithoutPathExpansion("hash", base::HexEncode(hash.c_str(),
205 hash.size()));
206 return metadata.Pass();
209 void CloudExternalDataManagerBaseTest::SetExternalDataReference(
210 const std::string& policy,
211 scoped_ptr<base::DictionaryValue> metadata) {
212 cloud_policy_store_.policy_map_.Set(
213 policy,
214 POLICY_LEVEL_MANDATORY,
215 POLICY_SCOPE_USER,
216 metadata.release(),
217 new ExternalDataFetcher(
218 external_data_manager_->weak_factory_.GetWeakPtr(), policy));
221 ExternalDataFetcher::FetchCallback
222 CloudExternalDataManagerBaseTest::ConstructFetchCallback(int id) {
223 return base::Bind(&CloudExternalDataManagerBaseTest::OnFetchDone,
224 base::Unretained(this),
225 id);
228 void CloudExternalDataManagerBaseTest::ResetCallbackData() {
229 STLDeleteValues(&callback_data_);
232 void CloudExternalDataManagerBaseTest::OnFetchDone(
233 int id,
234 scoped_ptr<std::string> data) {
235 delete callback_data_[id];
236 callback_data_[id] = data.release();
239 void CloudExternalDataManagerBaseTest::FetchAll() {
240 external_data_manager_->FetchAll();
243 void CloudExternalDataManagerBaseTest::SetFakeResponse(
244 const std::string& url,
245 const std::string& response_data,
246 net::HttpStatusCode response_code,
247 net::URLRequestStatus::Status status) {
248 fetcher_factory_.SetFakeResponse(
249 GURL(url), response_data, response_code, status);
252 // Verifies that when no valid external data reference has been set for a
253 // policy, the attempt to retrieve the external data fails immediately.
254 TEST_F(CloudExternalDataManagerBaseTest, FailToFetchInvalid) {
255 external_data_manager_->Connect(request_content_getter_);
257 // Attempt to retrieve external data for |kStringPolicy|, which is a string
258 // policy that does not reference any external data.
259 external_data_manager_->Fetch(kStringPolicy, ConstructFetchCallback(0));
260 base::RunLoop().RunUntilIdle();
261 EXPECT_EQ(1u, callback_data_.size());
262 EXPECT_TRUE(callback_data_.find(0) != callback_data_.end());
263 EXPECT_FALSE(callback_data_[0]);
264 ResetCallbackData();
266 // Attempt to retrieve external data for |kUnknownPolicy|, which is not a
267 // known policy.
268 external_data_manager_->Fetch(kUnknownPolicy, ConstructFetchCallback(1));
269 base::RunLoop().RunUntilIdle();
270 EXPECT_EQ(1u, callback_data_.size());
271 EXPECT_TRUE(callback_data_.find(1) != callback_data_.end());
272 EXPECT_FALSE(callback_data_[1]);
273 ResetCallbackData();
275 // Set an invalid external data reference for |k10BytePolicy|.
276 SetExternalDataReference(k10BytePolicy,
277 ConstructMetadata(std::string(), std::string()));
278 cloud_policy_store_.NotifyStoreLoaded();
280 // Attempt to retrieve external data for |k10BytePolicy|, which now has an
281 // invalid reference.
282 external_data_manager_->Fetch(k10BytePolicy, ConstructFetchCallback(2));
283 base::RunLoop().RunUntilIdle();
284 EXPECT_EQ(1u, callback_data_.size());
285 EXPECT_TRUE(callback_data_.find(2) != callback_data_.end());
286 EXPECT_FALSE(callback_data_[2]);
287 ResetCallbackData();
290 // Verifies that external data referenced by a policy is downloaded and cached
291 // when first requested. Subsequent requests are served from the cache without
292 // further download attempts.
293 TEST_F(CloudExternalDataManagerBaseTest, DownloadAndCache) {
294 // Serve valid external data for |k10BytePolicy|.
295 SetFakeResponse(k10BytePolicyURL, k10ByteData, net::HTTP_OK,
296 net::URLRequestStatus::SUCCESS);
297 external_data_manager_->Connect(request_content_getter_);
299 // Retrieve external data for |k10BytePolicy|. Verify that a download happens
300 // and the callback is invoked with the downloaded data.
301 external_data_manager_->Fetch(k10BytePolicy, ConstructFetchCallback(0));
302 base::RunLoop().RunUntilIdle();
303 EXPECT_EQ(1u, callback_data_.size());
304 ASSERT_TRUE(callback_data_[0]);
305 EXPECT_EQ(k10ByteData, *callback_data_[0]);
306 ResetCallbackData();
308 // Stop serving external data for |k10BytePolicy|.
309 fetcher_factory_.ClearFakeResponses();
311 // Retrieve external data for |k10BytePolicy| again. Verify that no download
312 // is attempted but the callback is still invoked with the expected data,
313 // served from the cache.
314 external_data_manager_->Fetch(k10BytePolicy, ConstructFetchCallback(1));
315 base::RunLoop().RunUntilIdle();
316 EXPECT_EQ(1u, callback_data_.size());
317 ASSERT_TRUE(callback_data_[1]);
318 EXPECT_EQ(k10ByteData, *callback_data_[1]);
319 ResetCallbackData();
321 // Explicitly tell the external_data_manager_ to not make any download
322 // attempts.
323 external_data_manager_->Disconnect();
325 // Retrieve external data for |k10BytePolicy| again. Verify that even though
326 // downloads are not allowed, the callback is still invoked with the expected
327 // data, served from the cache.
328 external_data_manager_->Fetch(k10BytePolicy, ConstructFetchCallback(2));
329 base::RunLoop().RunUntilIdle();
330 EXPECT_EQ(1u, callback_data_.size());
331 ASSERT_TRUE(callback_data_[2]);
332 EXPECT_EQ(k10ByteData, *callback_data_[2]);
333 ResetCallbackData();
335 // Verify that the downloaded data is present in the cache.
336 external_data_manager_.reset();
337 base::RunLoop().RunUntilIdle();
338 std::string data;
339 EXPECT_TRUE(CloudExternalDataStore(kCacheKey,
340 message_loop_.message_loop_proxy(),
341 resource_cache_.get()).Load(
342 k10BytePolicy, crypto::SHA256HashString(k10ByteData), 10, &data));
343 EXPECT_EQ(k10ByteData, data);
346 // Verifies that a request to download and cache all external data referenced by
347 // policies is carried out correctly. Subsequent requests for the data are
348 // served from the cache without further download attempts.
349 TEST_F(CloudExternalDataManagerBaseTest, DownloadAndCacheAll) {
350 // Serve valid external data for |k10BytePolicy| and |k20BytePolicy|.
351 SetFakeResponse(k10BytePolicyURL, k10ByteData, net::HTTP_OK,
352 net::URLRequestStatus::SUCCESS);
353 SetFakeResponse(k20BytePolicyURL, k20ByteData, net::HTTP_OK,
354 net::URLRequestStatus::SUCCESS);
355 external_data_manager_->Connect(request_content_getter_);
357 // Request that external data referenced by all policies be downloaded.
358 FetchAll();
359 base::RunLoop().RunUntilIdle();
361 // Stop serving external data for |k10BytePolicy| and |k20BytePolicy|.
362 fetcher_factory_.ClearFakeResponses();
364 // Retrieve external data for |k10BytePolicy| and |k20BytePolicy|. Verify that
365 // no downloads are attempted but the callbacks are still invoked with the
366 // expected data, served from the cache.
367 external_data_manager_->Fetch(k10BytePolicy, ConstructFetchCallback(0));
368 external_data_manager_->Fetch(k20BytePolicy, ConstructFetchCallback(1));
369 base::RunLoop().RunUntilIdle();
370 EXPECT_EQ(2u, callback_data_.size());
371 ASSERT_TRUE(callback_data_[0]);
372 EXPECT_EQ(k10ByteData, *callback_data_[0]);
373 ASSERT_TRUE(callback_data_[1]);
374 EXPECT_EQ(k20ByteData, *callback_data_[1]);
375 ResetCallbackData();
377 // Explicitly tell the external_data_manager_ to not make any download
378 // attempts.
379 external_data_manager_->Disconnect();
381 // Retrieve external data for |k10BytePolicy| and |k20BytePolicy|. Verify that
382 // even though downloads are not allowed, the callbacks are still invoked with
383 // the expected data, served from the cache.
384 external_data_manager_->Fetch(k10BytePolicy, ConstructFetchCallback(2));
385 external_data_manager_->Fetch(k20BytePolicy, ConstructFetchCallback(3));
386 base::RunLoop().RunUntilIdle();
387 EXPECT_EQ(2u, callback_data_.size());
388 ASSERT_TRUE(callback_data_[2]);
389 EXPECT_EQ(k10ByteData, *callback_data_[2]);
390 ASSERT_TRUE(callback_data_[3]);
391 EXPECT_EQ(k20ByteData, *callback_data_[3]);
392 ResetCallbackData();
394 // Verify that the downloaded data is present in the cache.
395 external_data_manager_.reset();
396 base::RunLoop().RunUntilIdle();
397 CloudExternalDataStore cache(kCacheKey,
398 message_loop_.message_loop_proxy(),
399 resource_cache_.get());
400 std::string data;
401 EXPECT_TRUE(cache.Load(k10BytePolicy,
402 crypto::SHA256HashString(k10ByteData),
404 &data));
405 EXPECT_EQ(k10ByteData, data);
406 EXPECT_TRUE(cache.Load(k20BytePolicy,
407 crypto::SHA256HashString(k20ByteData),
409 &data));
410 EXPECT_EQ(k20ByteData, data);
413 // Verifies that when the external data referenced by a policy is not present in
414 // the cache and downloads are not allowed, a request to retrieve the data is
415 // enqueued and carried out when downloads become possible.
416 TEST_F(CloudExternalDataManagerBaseTest, DownloadAfterConnect) {
417 // Attempt to retrieve external data for |k10BytePolicy|. Verify that the
418 // callback is not invoked as the request remains pending.
419 external_data_manager_->Fetch(k10BytePolicy, ConstructFetchCallback(0));
420 base::RunLoop().RunUntilIdle();
421 EXPECT_TRUE(callback_data_.empty());
422 ResetCallbackData();
424 // Serve valid external data for |k10BytePolicy| and allow the
425 // external_data_manager_ to perform downloads.
426 SetFakeResponse(k10BytePolicyURL, k10ByteData, net::HTTP_OK,
427 net::URLRequestStatus::SUCCESS);
428 external_data_manager_->Connect(request_content_getter_);
430 // Verify that a download happens and the callback is invoked with the
431 // downloaded data.
432 base::RunLoop().RunUntilIdle();
433 EXPECT_EQ(1u, callback_data_.size());
434 ASSERT_TRUE(callback_data_[0]);
435 EXPECT_EQ(k10ByteData, *callback_data_[0]);
436 ResetCallbackData();
439 // Verifies that when the external data referenced by a policy is not present in
440 // the cache and cannot be downloaded at this time, a request to retrieve the
441 // data is enqueued to be retried later.
442 TEST_F(CloudExternalDataManagerBaseTest, DownloadError) {
443 // Make attempts to download the external data for |k20BytePolicy| fail with
444 // an error.
445 SetFakeResponse(k20BytePolicyURL, std::string(),
446 net::HTTP_INTERNAL_SERVER_ERROR,
447 net::URLRequestStatus::FAILED);
448 external_data_manager_->Connect(request_content_getter_);
450 // Attempt to retrieve external data for |k20BytePolicy|. Verify that the
451 // callback is not invoked as the download attempt fails and the request
452 // remains pending.
453 external_data_manager_->Fetch(k20BytePolicy, ConstructFetchCallback(0));
454 base::RunLoop().RunUntilIdle();
455 EXPECT_TRUE(callback_data_.empty());
456 ResetCallbackData();
458 // Modify the external data reference for |k20BytePolicy|, allowing the
459 // download to be retried immediately.
460 SetExternalDataReference(
461 k20BytePolicy,
462 ConstructMetadata(k20BytePolicyURL,
463 crypto::SHA256HashString(k10ByteData)));
464 cloud_policy_store_.NotifyStoreLoaded();
466 // Attempt to retrieve external data for |k20BytePolicy| again. Verify that
467 // no callback is invoked still as the download attempt fails again and the
468 // request remains pending.
469 external_data_manager_->Fetch(k20BytePolicy, ConstructFetchCallback(1));
470 base::RunLoop().RunUntilIdle();
471 EXPECT_TRUE(callback_data_.empty());
472 ResetCallbackData();
474 // Modify the external data reference for |k20BytePolicy|, allowing the
475 // download to be retried immediately.
476 SetExternalDataReference(
477 k20BytePolicy,
478 ConstructMetadata(k20BytePolicyURL,
479 crypto::SHA256HashString(k20ByteData)));
480 cloud_policy_store_.NotifyStoreLoaded();
482 // Serve external data for |k20BytePolicy| that does not match the hash
483 // specified in its current external data reference.
484 SetFakeResponse(k20BytePolicyURL, k10ByteData, net::HTTP_OK,
485 net::URLRequestStatus::SUCCESS);
487 // Attempt to retrieve external data for |k20BytePolicy| again. Verify that
488 // no callback is invoked still as the downloaded succeeds but returns data
489 // that does not match the external data reference.
490 external_data_manager_->Fetch(k20BytePolicy, ConstructFetchCallback(2));
491 base::RunLoop().RunUntilIdle();
492 EXPECT_TRUE(callback_data_.empty());
493 ResetCallbackData();
495 // Modify the external data reference for |k20BytePolicy|, allowing the
496 // download to be retried immediately. The external data reference now matches
497 // the data being served.
498 SetExternalDataReference(
499 k20BytePolicy,
500 ConstructMetadata(k20BytePolicyURL,
501 crypto::SHA256HashString(k10ByteData)));
502 cloud_policy_store_.NotifyStoreLoaded();
504 // Attempt to retrieve external data for |k20BytePolicy| again. Verify that
505 // the current callback and the three previously enqueued callbacks are
506 // invoked with the downloaded data now.
507 external_data_manager_->Fetch(k20BytePolicy, ConstructFetchCallback(3));
508 base::RunLoop().RunUntilIdle();
509 EXPECT_EQ(4u, callback_data_.size());
510 ASSERT_TRUE(callback_data_[0]);
511 EXPECT_EQ(k10ByteData, *callback_data_[0]);
512 ASSERT_TRUE(callback_data_[1]);
513 EXPECT_EQ(k10ByteData, *callback_data_[1]);
514 ASSERT_TRUE(callback_data_[2]);
515 EXPECT_EQ(k10ByteData, *callback_data_[2]);
516 ASSERT_TRUE(callback_data_[3]);
517 EXPECT_EQ(k10ByteData, *callback_data_[3]);
518 ResetCallbackData();
521 // Verifies that when the external data referenced by a policy is present in the
522 // cache, a request to retrieve it is served from the cache without any download
523 // attempts.
524 TEST_F(CloudExternalDataManagerBaseTest, LoadFromCache) {
525 // Store valid external data for |k10BytePolicy| in the cache.
526 external_data_manager_.reset();
527 base::RunLoop().RunUntilIdle();
528 EXPECT_TRUE(CloudExternalDataStore(kCacheKey,
529 message_loop_.message_loop_proxy(),
530 resource_cache_.get()).Store(
531 k10BytePolicy, crypto::SHA256HashString(k10ByteData), k10ByteData));
533 // Instantiate an external_data_manager_ that uses the primed cache.
534 SetUpExternalDataManager();
535 external_data_manager_->Connect(request_content_getter_);
537 // Retrieve external data for |k10BytePolicy|. Verify that no download is
538 // attempted but the callback is still invoked with the expected data, served
539 // from the cache.
540 external_data_manager_->Fetch(k10BytePolicy, ConstructFetchCallback(0));
541 base::RunLoop().RunUntilIdle();
542 EXPECT_EQ(1u, callback_data_.size());
543 ASSERT_TRUE(callback_data_[0]);
544 EXPECT_EQ(k10ByteData, *callback_data_[0]);
545 ResetCallbackData();
548 // Verifies that cache entries which do not correspond to the external data
549 // referenced by any policy are pruned on startup.
550 TEST_F(CloudExternalDataManagerBaseTest, PruneCacheOnStartup) {
551 external_data_manager_.reset();
552 base::RunLoop().RunUntilIdle();
553 scoped_ptr<CloudExternalDataStore>
554 cache(new CloudExternalDataStore(kCacheKey,
555 message_loop_.message_loop_proxy(),
556 resource_cache_.get()));
557 // Store valid external data for |k10BytePolicy| in the cache.
558 EXPECT_TRUE(cache->Store(k10BytePolicy,
559 crypto::SHA256HashString(k10ByteData),
560 k10ByteData));
561 // Store external data for |k20BytePolicy| that does not match the hash in its
562 // external data reference.
563 EXPECT_TRUE(cache->Store(k20BytePolicy,
564 crypto::SHA256HashString(k10ByteData),
565 k10ByteData));
566 // Store external data for |kUnknownPolicy|, which is not a known policy and
567 // therefore, cannot be referencing any external data.
568 EXPECT_TRUE(cache->Store(kUnknownPolicy,
569 crypto::SHA256HashString(k10ByteData),
570 k10ByteData));
571 cache.reset();
573 // Instantiate and destroy an ExternalDataManager that uses the primed cache.
574 SetUpExternalDataManager();
575 external_data_manager_.reset();
576 base::RunLoop().RunUntilIdle();
578 cache.reset(new CloudExternalDataStore(kCacheKey,
579 message_loop_.message_loop_proxy(),
580 resource_cache_.get()));
581 std::string data;
582 // Verify that the valid external data for |k10BytePolicy| is still in the
583 // cache.
584 EXPECT_TRUE(cache->Load(k10BytePolicy,
585 crypto::SHA256HashString(k10ByteData),
587 &data));
588 EXPECT_EQ(k10ByteData, data);
589 // Verify that the external data for |k20BytePolicy| and |kUnknownPolicy| has
590 // been pruned from the cache.
591 EXPECT_FALSE(cache->Load(k20BytePolicy,
592 crypto::SHA256HashString(k10ByteData),
594 &data));
595 EXPECT_FALSE(cache->Load(kUnknownPolicy,
596 crypto::SHA256HashString(k10ByteData),
598 &data));
601 // Verifies that when the external data referenced by a policy is present in the
602 // cache and the reference changes, the old data is pruned from the cache.
603 TEST_F(CloudExternalDataManagerBaseTest, PruneCacheOnChange) {
604 // Store valid external data for |k20BytePolicy| in the cache.
605 external_data_manager_.reset();
606 base::RunLoop().RunUntilIdle();
607 scoped_ptr<CloudExternalDataStore>
608 cache(new CloudExternalDataStore(kCacheKey,
609 message_loop_.message_loop_proxy(),
610 resource_cache_.get()));
611 EXPECT_TRUE(cache->Store(k20BytePolicy,
612 crypto::SHA256HashString(k20ByteData),
613 k20ByteData));
614 cache.reset();
616 // Instantiate an ExternalDataManager that uses the primed cache.
617 SetUpExternalDataManager();
618 external_data_manager_->Connect(request_content_getter_);
620 // Modify the external data reference for |k20BytePolicy|.
621 SetExternalDataReference(
622 k20BytePolicy,
623 ConstructMetadata(k20BytePolicyURL,
624 crypto::SHA256HashString(k10ByteData)));
625 cloud_policy_store_.NotifyStoreLoaded();
627 // Verify that the old external data for |k20BytePolicy| has been pruned from
628 // the cache.
629 external_data_manager_.reset();
630 base::RunLoop().RunUntilIdle();
631 cache.reset(new CloudExternalDataStore(kCacheKey,
632 message_loop_.message_loop_proxy(),
633 resource_cache_.get()));
634 std::string data;
635 EXPECT_FALSE(cache->Load(k20BytePolicy,
636 crypto::SHA256HashString(k20ByteData),
638 &data));
641 // Verifies that corrupt cache entries are detected and deleted when accessed.
642 TEST_F(CloudExternalDataManagerBaseTest, CacheCorruption) {
643 external_data_manager_.reset();
644 base::RunLoop().RunUntilIdle();
645 scoped_ptr<CloudExternalDataStore>
646 cache(new CloudExternalDataStore(kCacheKey,
647 message_loop_.message_loop_proxy(),
648 resource_cache_.get()));
649 // Store external data for |k10BytePolicy| that exceeds the maximal external
650 // data size allowed for that policy.
651 EXPECT_TRUE(cache->Store(k10BytePolicy,
652 crypto::SHA256HashString(k20ByteData),
653 k20ByteData));
654 // Store external data for |k20BytePolicy| that is corrupted and does not
655 // match the expected hash.
656 EXPECT_TRUE(cache->Store(k20BytePolicy,
657 crypto::SHA256HashString(k20ByteData),
658 k10ByteData));
659 cache.reset();
661 SetUpExternalDataManager();
662 // Serve external data for |k10BytePolicy| that exceeds the maximal external
663 // data size allowed for that policy.
664 SetFakeResponse(k10BytePolicyURL, k20ByteData, net::HTTP_OK,
665 net::URLRequestStatus::SUCCESS);
666 external_data_manager_->Connect(request_content_getter_);
668 // Modify the external data reference for |k10BytePolicy| to match the
669 // external data being served.
670 SetExternalDataReference(
671 k10BytePolicy,
672 ConstructMetadata(k10BytePolicyURL,
673 crypto::SHA256HashString(k20ByteData)));
674 cloud_policy_store_.NotifyStoreLoaded();
676 // Retrieve external data for |k10BytePolicy|. Verify that the callback is
677 // not invoked as the cached and downloaded external data exceed the maximal
678 // size allowed for this policy and the request remains pending.
679 external_data_manager_->Fetch(k10BytePolicy, ConstructFetchCallback(0));
680 base::RunLoop().RunUntilIdle();
681 EXPECT_TRUE(callback_data_.empty());
682 ResetCallbackData();
684 // Serve valid external data for |k20BytePolicy|.
685 SetFakeResponse(k20BytePolicyURL, k20ByteData, net::HTTP_OK,
686 net::URLRequestStatus::SUCCESS);
688 // Retrieve external data for |k20BytePolicy|. Verify that the callback is
689 // invoked with the valid downloaded data, not the invalid data in the cache.
690 external_data_manager_->Fetch(k20BytePolicy, ConstructFetchCallback(1));
691 base::RunLoop().RunUntilIdle();
692 EXPECT_EQ(1u, callback_data_.size());
693 ASSERT_TRUE(callback_data_[1]);
694 EXPECT_EQ(k20ByteData, *callback_data_[1]);
695 ResetCallbackData();
697 external_data_manager_.reset();
698 base::RunLoop().RunUntilIdle();
699 cache.reset(new CloudExternalDataStore(kCacheKey,
700 message_loop_.message_loop_proxy(),
701 resource_cache_.get()));
702 std::string data;
703 // Verify that the invalid external data for |k10BytePolicy| has been pruned
704 // from the cache. Load() will return |false| in two cases:
705 // 1) The cache entry for |k10BytePolicy| has been pruned.
706 // 2) The cache entry for |k10BytePolicy| still exists but the cached data
707 // does not match the expected hash or exceeds the maximum size allowed.
708 // To test for the former, Load() is called with a maximum data size and hash
709 // that would allow the data originally written to the cache to be loaded.
710 // When this fails, it is certain that the original data is no longer present
711 // in the cache.
712 EXPECT_FALSE(cache->Load(k10BytePolicy,
713 crypto::SHA256HashString(k20ByteData),
715 &data));
716 // Verify that the invalid external data for |k20BytePolicy| has been replaced
717 // with the downloaded valid data in the cache.
718 EXPECT_TRUE(cache->Load(k20BytePolicy,
719 crypto::SHA256HashString(k20ByteData),
721 &data));
722 EXPECT_EQ(k20ByteData, data);
725 // Verifies that when the external data reference for a policy changes while a
726 // download of the external data for that policy is pending, the download is
727 // immediately retried using the new reference.
728 TEST_F(CloudExternalDataManagerBaseTest, PolicyChangeWhileDownloadPending) {
729 // Make attempts to download the external data for |k10BytePolicy| and
730 // |k20BytePolicy| fail with an error.
731 SetFakeResponse(k10BytePolicyURL, std::string(),
732 net::HTTP_INTERNAL_SERVER_ERROR,
733 net::URLRequestStatus::FAILED);
734 SetFakeResponse(k20BytePolicyURL, std::string(),
735 net::HTTP_INTERNAL_SERVER_ERROR,
736 net::URLRequestStatus::FAILED);
737 external_data_manager_->Connect(request_content_getter_);
739 // Attempt to retrieve external data for |k10BytePolicy| and |k20BytePolicy|.
740 // Verify that no callbacks are invoked as the download attempts fail and the
741 // requests remain pending.
742 external_data_manager_->Fetch(k10BytePolicy, ConstructFetchCallback(0));
743 external_data_manager_->Fetch(k20BytePolicy, ConstructFetchCallback(1));
744 base::RunLoop().RunUntilIdle();
745 EXPECT_TRUE(callback_data_.empty());
746 ResetCallbackData();
748 // Modify the external data reference for |k10BytePolicy| to be invalid.
749 // Verify that the callback is invoked as the policy no longer has a valid
750 // external data reference.
751 cloud_policy_store_.policy_map_.Erase(k10BytePolicy);
752 cloud_policy_store_.NotifyStoreLoaded();
753 base::RunLoop().RunUntilIdle();
754 EXPECT_EQ(1u, callback_data_.size());
755 EXPECT_TRUE(callback_data_.find(0) != callback_data_.end());
756 EXPECT_FALSE(callback_data_[0]);
757 ResetCallbackData();
759 // Serve valid external data for |k20BytePolicy|.
760 fetcher_factory_.ClearFakeResponses();
761 SetFakeResponse(k20BytePolicyURL, k10ByteData, net::HTTP_OK,
762 net::URLRequestStatus::SUCCESS);
764 // Modify the external data reference for |k20BytePolicy| to match the
765 // external data now being served. Verify that the callback is invoked with
766 // the downloaded data.
767 SetExternalDataReference(
768 k20BytePolicy,
769 ConstructMetadata(k20BytePolicyURL,
770 crypto::SHA256HashString(k10ByteData)));
771 cloud_policy_store_.NotifyStoreLoaded();
772 base::RunLoop().RunUntilIdle();
773 EXPECT_EQ(1u, callback_data_.size());
774 ASSERT_TRUE(callback_data_[1]);
775 EXPECT_EQ(k10ByteData, *callback_data_[1]);
776 ResetCallbackData();
779 } // namespace policy