Revert of Add button to add new FSP services to Files app. (patchset #8 id:140001...
[chromium-blink-merge.git] / chrome / browser / chromeos / policy / cloud_external_data_manager_base_unittest.cc
blob24396491e281791d2e0f79aaf6d03c4e39d88020
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 ~FakeURLFetcherFactory() override;
72 // net::FakeURLFetcherFactory:
73 net::URLFetcher* CreateURLFetcher(int id,
74 const GURL& url,
75 net::URLFetcher::RequestType request_type,
76 net::URLFetcherDelegate* delegate) override;
78 private:
79 DISALLOW_COPY_AND_ASSIGN(FakeURLFetcherFactory);
82 FakeURLFetcherFactory::FakeURLFetcherFactory()
83 : net::FakeURLFetcherFactory(NULL) {
86 FakeURLFetcherFactory::~FakeURLFetcherFactory() {
89 net::URLFetcher* FakeURLFetcherFactory::CreateURLFetcher(
90 int id,
91 const GURL& url,
92 net::URLFetcher::RequestType request_type,
93 net::URLFetcherDelegate* delegate) {
94 net::URLFetcher* fetcher = net::FakeURLFetcherFactory::CreateURLFetcher(
95 id, url, request_type, delegate);
96 EXPECT_TRUE(fetcher);
97 return fetcher;
100 } // namespace
102 class CloudExternalDataManagerBaseTest : public testing::Test {
103 protected:
104 CloudExternalDataManagerBaseTest();
106 void SetUp() override;
107 void TearDown() override;
109 void SetUpExternalDataManager();
111 scoped_ptr<base::DictionaryValue> ConstructMetadata(const std::string& url,
112 const std::string& hash);
113 void SetExternalDataReference(const std::string& policy,
114 scoped_ptr<base::DictionaryValue> metadata);
116 ExternalDataFetcher::FetchCallback ConstructFetchCallback(int id);
117 void ResetCallbackData();
119 void OnFetchDone(int id, scoped_ptr<std::string> data);
121 void FetchAll();
123 void SetFakeResponse(const std::string& url,
124 const std::string& repsonse_data,
125 net::HttpStatusCode response_code,
126 net::URLRequestStatus::Status status);
128 base::MessageLoop message_loop_;
129 base::ScopedTempDir temp_dir_;
130 scoped_ptr<ResourceCache> resource_cache_;
131 MockCloudPolicyStore cloud_policy_store_;
132 scoped_refptr<net::TestURLRequestContextGetter> request_content_getter_;
133 FakeURLFetcherFactory fetcher_factory_;
135 scoped_ptr<CloudExternalDataManagerBase> external_data_manager_;
137 std::map<int, std::string*> callback_data_;
138 PolicyDetailsMap policy_details_;
140 private:
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,
163 crypto::SHA256HashString(k10ByteData)));
164 // Make |k20BytePolicy| reference 20 bytes of external data.
165 SetExternalDataReference(
166 k20BytePolicy,
167 ConstructMetadata(k20BytePolicyURL,
168 crypto::SHA256HashString(k20ByteData)));
169 cloud_policy_store_.NotifyStoreLoaded();
171 request_content_getter_ = new net::TestURLRequestContextGetter(
172 base::MessageLoopProxy::current());
174 policy_details_.SetDetails(kStringPolicy, &kPolicyDetails[0]);
175 policy_details_.SetDetails(k10BytePolicy, &kPolicyDetails[1]);
176 policy_details_.SetDetails(k20BytePolicy, &kPolicyDetails[2]);
179 void CloudExternalDataManagerBaseTest::TearDown() {
180 external_data_manager_.reset();
181 base::RunLoop().RunUntilIdle();
182 ResetCallbackData();
185 void CloudExternalDataManagerBaseTest::SetUpExternalDataManager() {
186 external_data_manager_.reset(new CloudExternalDataManagerBase(
187 policy_details_.GetCallback(),
188 message_loop_.message_loop_proxy(),
189 message_loop_.message_loop_proxy()));
190 external_data_manager_->SetExternalDataStore(make_scoped_ptr(
191 new CloudExternalDataStore(kCacheKey,
192 message_loop_.message_loop_proxy(),
193 resource_cache_.get())));
194 external_data_manager_->SetPolicyStore(&cloud_policy_store_);
197 scoped_ptr<base::DictionaryValue>
198 CloudExternalDataManagerBaseTest::ConstructMetadata(
199 const std::string& url,
200 const std::string& hash) {
201 scoped_ptr<base::DictionaryValue> metadata(new base::DictionaryValue);
202 metadata->SetStringWithoutPathExpansion("url", url);
203 metadata->SetStringWithoutPathExpansion("hash", base::HexEncode(hash.c_str(),
204 hash.size()));
205 return metadata.Pass();
208 void CloudExternalDataManagerBaseTest::SetExternalDataReference(
209 const std::string& policy,
210 scoped_ptr<base::DictionaryValue> metadata) {
211 cloud_policy_store_.policy_map_.Set(
212 policy,
213 POLICY_LEVEL_MANDATORY,
214 POLICY_SCOPE_USER,
215 metadata.release(),
216 new ExternalDataFetcher(
217 external_data_manager_->weak_factory_.GetWeakPtr(), policy));
220 ExternalDataFetcher::FetchCallback
221 CloudExternalDataManagerBaseTest::ConstructFetchCallback(int id) {
222 return base::Bind(&CloudExternalDataManagerBaseTest::OnFetchDone,
223 base::Unretained(this),
224 id);
227 void CloudExternalDataManagerBaseTest::ResetCallbackData() {
228 STLDeleteValues(&callback_data_);
231 void CloudExternalDataManagerBaseTest::OnFetchDone(
232 int id,
233 scoped_ptr<std::string> data) {
234 delete callback_data_[id];
235 callback_data_[id] = data.release();
238 void CloudExternalDataManagerBaseTest::FetchAll() {
239 external_data_manager_->FetchAll();
242 void CloudExternalDataManagerBaseTest::SetFakeResponse(
243 const std::string& url,
244 const std::string& response_data,
245 net::HttpStatusCode response_code,
246 net::URLRequestStatus::Status status) {
247 fetcher_factory_.SetFakeResponse(
248 GURL(url), response_data, response_code, status);
251 // Verifies that when no valid external data reference has been set for a
252 // policy, the attempt to retrieve the external data fails immediately.
253 TEST_F(CloudExternalDataManagerBaseTest, FailToFetchInvalid) {
254 external_data_manager_->Connect(request_content_getter_);
256 // Attempt to retrieve external data for |kStringPolicy|, which is a string
257 // policy that does not reference any external data.
258 external_data_manager_->Fetch(kStringPolicy, ConstructFetchCallback(0));
259 base::RunLoop().RunUntilIdle();
260 EXPECT_EQ(1u, callback_data_.size());
261 EXPECT_TRUE(callback_data_.find(0) != callback_data_.end());
262 EXPECT_FALSE(callback_data_[0]);
263 ResetCallbackData();
265 // Attempt to retrieve external data for |kUnknownPolicy|, which is not a
266 // known policy.
267 external_data_manager_->Fetch(kUnknownPolicy, ConstructFetchCallback(1));
268 base::RunLoop().RunUntilIdle();
269 EXPECT_EQ(1u, callback_data_.size());
270 EXPECT_TRUE(callback_data_.find(1) != callback_data_.end());
271 EXPECT_FALSE(callback_data_[1]);
272 ResetCallbackData();
274 // Set an invalid external data reference for |k10BytePolicy|.
275 SetExternalDataReference(k10BytePolicy,
276 ConstructMetadata(std::string(), std::string()));
277 cloud_policy_store_.NotifyStoreLoaded();
279 // Attempt to retrieve external data for |k10BytePolicy|, which now has an
280 // invalid reference.
281 external_data_manager_->Fetch(k10BytePolicy, ConstructFetchCallback(2));
282 base::RunLoop().RunUntilIdle();
283 EXPECT_EQ(1u, callback_data_.size());
284 EXPECT_TRUE(callback_data_.find(2) != callback_data_.end());
285 EXPECT_FALSE(callback_data_[2]);
286 ResetCallbackData();
289 // Verifies that external data referenced by a policy is downloaded and cached
290 // when first requested. Subsequent requests are served from the cache without
291 // further download attempts.
292 TEST_F(CloudExternalDataManagerBaseTest, DownloadAndCache) {
293 // Serve valid external data for |k10BytePolicy|.
294 SetFakeResponse(k10BytePolicyURL, k10ByteData, net::HTTP_OK,
295 net::URLRequestStatus::SUCCESS);
296 external_data_manager_->Connect(request_content_getter_);
298 // Retrieve external data for |k10BytePolicy|. Verify that a download happens
299 // and the callback is invoked with the downloaded data.
300 external_data_manager_->Fetch(k10BytePolicy, ConstructFetchCallback(0));
301 base::RunLoop().RunUntilIdle();
302 EXPECT_EQ(1u, callback_data_.size());
303 ASSERT_TRUE(callback_data_[0]);
304 EXPECT_EQ(k10ByteData, *callback_data_[0]);
305 ResetCallbackData();
307 // Stop serving external data for |k10BytePolicy|.
308 fetcher_factory_.ClearFakeResponses();
310 // Retrieve external data for |k10BytePolicy| again. Verify that no download
311 // is attempted but the callback is still invoked with the expected data,
312 // served from the cache.
313 external_data_manager_->Fetch(k10BytePolicy, ConstructFetchCallback(1));
314 base::RunLoop().RunUntilIdle();
315 EXPECT_EQ(1u, callback_data_.size());
316 ASSERT_TRUE(callback_data_[1]);
317 EXPECT_EQ(k10ByteData, *callback_data_[1]);
318 ResetCallbackData();
320 // Explicitly tell the external_data_manager_ to not make any download
321 // attempts.
322 external_data_manager_->Disconnect();
324 // Retrieve external data for |k10BytePolicy| again. Verify that even though
325 // downloads are not allowed, the callback is still invoked with the expected
326 // data, served from the cache.
327 external_data_manager_->Fetch(k10BytePolicy, ConstructFetchCallback(2));
328 base::RunLoop().RunUntilIdle();
329 EXPECT_EQ(1u, callback_data_.size());
330 ASSERT_TRUE(callback_data_[2]);
331 EXPECT_EQ(k10ByteData, *callback_data_[2]);
332 ResetCallbackData();
334 // Verify that the downloaded data is present in the cache.
335 external_data_manager_.reset();
336 base::RunLoop().RunUntilIdle();
337 std::string data;
338 EXPECT_TRUE(CloudExternalDataStore(kCacheKey,
339 message_loop_.message_loop_proxy(),
340 resource_cache_.get()).Load(
341 k10BytePolicy, crypto::SHA256HashString(k10ByteData), 10, &data));
342 EXPECT_EQ(k10ByteData, data);
345 // Verifies that a request to download and cache all external data referenced by
346 // policies is carried out correctly. Subsequent requests for the data are
347 // served from the cache without further download attempts.
348 TEST_F(CloudExternalDataManagerBaseTest, DownloadAndCacheAll) {
349 // Serve valid external data for |k10BytePolicy| and |k20BytePolicy|.
350 SetFakeResponse(k10BytePolicyURL, k10ByteData, net::HTTP_OK,
351 net::URLRequestStatus::SUCCESS);
352 SetFakeResponse(k20BytePolicyURL, k20ByteData, net::HTTP_OK,
353 net::URLRequestStatus::SUCCESS);
354 external_data_manager_->Connect(request_content_getter_);
356 // Request that external data referenced by all policies be downloaded.
357 FetchAll();
358 base::RunLoop().RunUntilIdle();
360 // Stop serving external data for |k10BytePolicy| and |k20BytePolicy|.
361 fetcher_factory_.ClearFakeResponses();
363 // Retrieve external data for |k10BytePolicy| and |k20BytePolicy|. Verify that
364 // no downloads are attempted but the callbacks are still invoked with the
365 // expected data, served from the cache.
366 external_data_manager_->Fetch(k10BytePolicy, ConstructFetchCallback(0));
367 external_data_manager_->Fetch(k20BytePolicy, ConstructFetchCallback(1));
368 base::RunLoop().RunUntilIdle();
369 EXPECT_EQ(2u, callback_data_.size());
370 ASSERT_TRUE(callback_data_[0]);
371 EXPECT_EQ(k10ByteData, *callback_data_[0]);
372 ASSERT_TRUE(callback_data_[1]);
373 EXPECT_EQ(k20ByteData, *callback_data_[1]);
374 ResetCallbackData();
376 // Explicitly tell the external_data_manager_ to not make any download
377 // attempts.
378 external_data_manager_->Disconnect();
380 // Retrieve external data for |k10BytePolicy| and |k20BytePolicy|. Verify that
381 // even though downloads are not allowed, the callbacks are still invoked with
382 // the expected data, served from the cache.
383 external_data_manager_->Fetch(k10BytePolicy, ConstructFetchCallback(2));
384 external_data_manager_->Fetch(k20BytePolicy, ConstructFetchCallback(3));
385 base::RunLoop().RunUntilIdle();
386 EXPECT_EQ(2u, callback_data_.size());
387 ASSERT_TRUE(callback_data_[2]);
388 EXPECT_EQ(k10ByteData, *callback_data_[2]);
389 ASSERT_TRUE(callback_data_[3]);
390 EXPECT_EQ(k20ByteData, *callback_data_[3]);
391 ResetCallbackData();
393 // Verify that the downloaded data is present in the cache.
394 external_data_manager_.reset();
395 base::RunLoop().RunUntilIdle();
396 CloudExternalDataStore cache(kCacheKey,
397 message_loop_.message_loop_proxy(),
398 resource_cache_.get());
399 std::string data;
400 EXPECT_TRUE(cache.Load(k10BytePolicy,
401 crypto::SHA256HashString(k10ByteData),
403 &data));
404 EXPECT_EQ(k10ByteData, data);
405 EXPECT_TRUE(cache.Load(k20BytePolicy,
406 crypto::SHA256HashString(k20ByteData),
408 &data));
409 EXPECT_EQ(k20ByteData, data);
412 // Verifies that when the external data referenced by a policy is not present in
413 // the cache and downloads are not allowed, a request to retrieve the data is
414 // enqueued and carried out when downloads become possible.
415 TEST_F(CloudExternalDataManagerBaseTest, DownloadAfterConnect) {
416 // Attempt to retrieve external data for |k10BytePolicy|. Verify that the
417 // callback is not invoked as the request remains pending.
418 external_data_manager_->Fetch(k10BytePolicy, ConstructFetchCallback(0));
419 base::RunLoop().RunUntilIdle();
420 EXPECT_TRUE(callback_data_.empty());
421 ResetCallbackData();
423 // Serve valid external data for |k10BytePolicy| and allow the
424 // external_data_manager_ to perform downloads.
425 SetFakeResponse(k10BytePolicyURL, k10ByteData, net::HTTP_OK,
426 net::URLRequestStatus::SUCCESS);
427 external_data_manager_->Connect(request_content_getter_);
429 // Verify that a download happens and the callback is invoked with the
430 // downloaded data.
431 base::RunLoop().RunUntilIdle();
432 EXPECT_EQ(1u, callback_data_.size());
433 ASSERT_TRUE(callback_data_[0]);
434 EXPECT_EQ(k10ByteData, *callback_data_[0]);
435 ResetCallbackData();
438 // Verifies that when the external data referenced by a policy is not present in
439 // the cache and cannot be downloaded at this time, a request to retrieve the
440 // data is enqueued to be retried later.
441 TEST_F(CloudExternalDataManagerBaseTest, DownloadError) {
442 // Make attempts to download the external data for |k20BytePolicy| fail with
443 // an error.
444 SetFakeResponse(k20BytePolicyURL, std::string(),
445 net::HTTP_INTERNAL_SERVER_ERROR,
446 net::URLRequestStatus::FAILED);
447 external_data_manager_->Connect(request_content_getter_);
449 // Attempt to retrieve external data for |k20BytePolicy|. Verify that the
450 // callback is not invoked as the download attempt fails and the request
451 // remains pending.
452 external_data_manager_->Fetch(k20BytePolicy, ConstructFetchCallback(0));
453 base::RunLoop().RunUntilIdle();
454 EXPECT_TRUE(callback_data_.empty());
455 ResetCallbackData();
457 // Modify the external data reference for |k20BytePolicy|, allowing the
458 // download to be retried immediately.
459 SetExternalDataReference(
460 k20BytePolicy,
461 ConstructMetadata(k20BytePolicyURL,
462 crypto::SHA256HashString(k10ByteData)));
463 cloud_policy_store_.NotifyStoreLoaded();
465 // Attempt to retrieve external data for |k20BytePolicy| again. Verify that
466 // no callback is invoked still as the download attempt fails again and the
467 // request remains pending.
468 external_data_manager_->Fetch(k20BytePolicy, ConstructFetchCallback(1));
469 base::RunLoop().RunUntilIdle();
470 EXPECT_TRUE(callback_data_.empty());
471 ResetCallbackData();
473 // Modify the external data reference for |k20BytePolicy|, allowing the
474 // download to be retried immediately.
475 SetExternalDataReference(
476 k20BytePolicy,
477 ConstructMetadata(k20BytePolicyURL,
478 crypto::SHA256HashString(k20ByteData)));
479 cloud_policy_store_.NotifyStoreLoaded();
481 // Serve external data for |k20BytePolicy| that does not match the hash
482 // specified in its current external data reference.
483 SetFakeResponse(k20BytePolicyURL, k10ByteData, net::HTTP_OK,
484 net::URLRequestStatus::SUCCESS);
486 // Attempt to retrieve external data for |k20BytePolicy| again. Verify that
487 // no callback is invoked still as the downloaded succeeds but returns data
488 // that does not match the external data reference.
489 external_data_manager_->Fetch(k20BytePolicy, ConstructFetchCallback(2));
490 base::RunLoop().RunUntilIdle();
491 EXPECT_TRUE(callback_data_.empty());
492 ResetCallbackData();
494 // Modify the external data reference for |k20BytePolicy|, allowing the
495 // download to be retried immediately. The external data reference now matches
496 // the data being served.
497 SetExternalDataReference(
498 k20BytePolicy,
499 ConstructMetadata(k20BytePolicyURL,
500 crypto::SHA256HashString(k10ByteData)));
501 cloud_policy_store_.NotifyStoreLoaded();
503 // Attempt to retrieve external data for |k20BytePolicy| again. Verify that
504 // the current callback and the three previously enqueued callbacks are
505 // invoked with the downloaded data now.
506 external_data_manager_->Fetch(k20BytePolicy, ConstructFetchCallback(3));
507 base::RunLoop().RunUntilIdle();
508 EXPECT_EQ(4u, callback_data_.size());
509 ASSERT_TRUE(callback_data_[0]);
510 EXPECT_EQ(k10ByteData, *callback_data_[0]);
511 ASSERT_TRUE(callback_data_[1]);
512 EXPECT_EQ(k10ByteData, *callback_data_[1]);
513 ASSERT_TRUE(callback_data_[2]);
514 EXPECT_EQ(k10ByteData, *callback_data_[2]);
515 ASSERT_TRUE(callback_data_[3]);
516 EXPECT_EQ(k10ByteData, *callback_data_[3]);
517 ResetCallbackData();
520 // Verifies that when the external data referenced by a policy is present in the
521 // cache, a request to retrieve it is served from the cache without any download
522 // attempts.
523 TEST_F(CloudExternalDataManagerBaseTest, LoadFromCache) {
524 // Store valid external data for |k10BytePolicy| in the cache.
525 external_data_manager_.reset();
526 base::RunLoop().RunUntilIdle();
527 EXPECT_TRUE(CloudExternalDataStore(kCacheKey,
528 message_loop_.message_loop_proxy(),
529 resource_cache_.get()).Store(
530 k10BytePolicy, crypto::SHA256HashString(k10ByteData), k10ByteData));
532 // Instantiate an external_data_manager_ that uses the primed cache.
533 SetUpExternalDataManager();
534 external_data_manager_->Connect(request_content_getter_);
536 // Retrieve external data for |k10BytePolicy|. Verify that no download is
537 // attempted but the callback is still invoked with the expected data, served
538 // from the cache.
539 external_data_manager_->Fetch(k10BytePolicy, ConstructFetchCallback(0));
540 base::RunLoop().RunUntilIdle();
541 EXPECT_EQ(1u, callback_data_.size());
542 ASSERT_TRUE(callback_data_[0]);
543 EXPECT_EQ(k10ByteData, *callback_data_[0]);
544 ResetCallbackData();
547 // Verifies that cache entries which do not correspond to the external data
548 // referenced by any policy are pruned on startup.
549 TEST_F(CloudExternalDataManagerBaseTest, PruneCacheOnStartup) {
550 external_data_manager_.reset();
551 base::RunLoop().RunUntilIdle();
552 scoped_ptr<CloudExternalDataStore>
553 cache(new CloudExternalDataStore(kCacheKey,
554 message_loop_.message_loop_proxy(),
555 resource_cache_.get()));
556 // Store valid external data for |k10BytePolicy| in the cache.
557 EXPECT_TRUE(cache->Store(k10BytePolicy,
558 crypto::SHA256HashString(k10ByteData),
559 k10ByteData));
560 // Store external data for |k20BytePolicy| that does not match the hash in its
561 // external data reference.
562 EXPECT_TRUE(cache->Store(k20BytePolicy,
563 crypto::SHA256HashString(k10ByteData),
564 k10ByteData));
565 // Store external data for |kUnknownPolicy|, which is not a known policy and
566 // therefore, cannot be referencing any external data.
567 EXPECT_TRUE(cache->Store(kUnknownPolicy,
568 crypto::SHA256HashString(k10ByteData),
569 k10ByteData));
570 cache.reset();
572 // Instantiate and destroy an ExternalDataManager that uses the primed cache.
573 SetUpExternalDataManager();
574 external_data_manager_.reset();
575 base::RunLoop().RunUntilIdle();
577 cache.reset(new CloudExternalDataStore(kCacheKey,
578 message_loop_.message_loop_proxy(),
579 resource_cache_.get()));
580 std::string data;
581 // Verify that the valid external data for |k10BytePolicy| is still in the
582 // cache.
583 EXPECT_TRUE(cache->Load(k10BytePolicy,
584 crypto::SHA256HashString(k10ByteData),
586 &data));
587 EXPECT_EQ(k10ByteData, data);
588 // Verify that the external data for |k20BytePolicy| and |kUnknownPolicy| has
589 // been pruned from the cache.
590 EXPECT_FALSE(cache->Load(k20BytePolicy,
591 crypto::SHA256HashString(k10ByteData),
593 &data));
594 EXPECT_FALSE(cache->Load(kUnknownPolicy,
595 crypto::SHA256HashString(k10ByteData),
597 &data));
600 // Verifies that when the external data referenced by a policy is present in the
601 // cache and the reference changes, the old data is pruned from the cache.
602 TEST_F(CloudExternalDataManagerBaseTest, PruneCacheOnChange) {
603 // Store valid external data for |k20BytePolicy| in the cache.
604 external_data_manager_.reset();
605 base::RunLoop().RunUntilIdle();
606 scoped_ptr<CloudExternalDataStore>
607 cache(new CloudExternalDataStore(kCacheKey,
608 message_loop_.message_loop_proxy(),
609 resource_cache_.get()));
610 EXPECT_TRUE(cache->Store(k20BytePolicy,
611 crypto::SHA256HashString(k20ByteData),
612 k20ByteData));
613 cache.reset();
615 // Instantiate an ExternalDataManager that uses the primed cache.
616 SetUpExternalDataManager();
617 external_data_manager_->Connect(request_content_getter_);
619 // Modify the external data reference for |k20BytePolicy|.
620 SetExternalDataReference(
621 k20BytePolicy,
622 ConstructMetadata(k20BytePolicyURL,
623 crypto::SHA256HashString(k10ByteData)));
624 cloud_policy_store_.NotifyStoreLoaded();
626 // Verify that the old external data for |k20BytePolicy| has been pruned from
627 // the cache.
628 external_data_manager_.reset();
629 base::RunLoop().RunUntilIdle();
630 cache.reset(new CloudExternalDataStore(kCacheKey,
631 message_loop_.message_loop_proxy(),
632 resource_cache_.get()));
633 std::string data;
634 EXPECT_FALSE(cache->Load(k20BytePolicy,
635 crypto::SHA256HashString(k20ByteData),
637 &data));
640 // Verifies that corrupt cache entries are detected and deleted when accessed.
641 TEST_F(CloudExternalDataManagerBaseTest, CacheCorruption) {
642 external_data_manager_.reset();
643 base::RunLoop().RunUntilIdle();
644 scoped_ptr<CloudExternalDataStore>
645 cache(new CloudExternalDataStore(kCacheKey,
646 message_loop_.message_loop_proxy(),
647 resource_cache_.get()));
648 // Store external data for |k10BytePolicy| that exceeds the maximal external
649 // data size allowed for that policy.
650 EXPECT_TRUE(cache->Store(k10BytePolicy,
651 crypto::SHA256HashString(k20ByteData),
652 k20ByteData));
653 // Store external data for |k20BytePolicy| that is corrupted and does not
654 // match the expected hash.
655 EXPECT_TRUE(cache->Store(k20BytePolicy,
656 crypto::SHA256HashString(k20ByteData),
657 k10ByteData));
658 cache.reset();
660 SetUpExternalDataManager();
661 // Serve external data for |k10BytePolicy| that exceeds the maximal external
662 // data size allowed for that policy.
663 SetFakeResponse(k10BytePolicyURL, k20ByteData, net::HTTP_OK,
664 net::URLRequestStatus::SUCCESS);
665 external_data_manager_->Connect(request_content_getter_);
667 // Modify the external data reference for |k10BytePolicy| to match the
668 // external data being served.
669 SetExternalDataReference(
670 k10BytePolicy,
671 ConstructMetadata(k10BytePolicyURL,
672 crypto::SHA256HashString(k20ByteData)));
673 cloud_policy_store_.NotifyStoreLoaded();
675 // Retrieve external data for |k10BytePolicy|. Verify that the callback is
676 // not invoked as the cached and downloaded external data exceed the maximal
677 // size allowed for this policy and the request remains pending.
678 external_data_manager_->Fetch(k10BytePolicy, ConstructFetchCallback(0));
679 base::RunLoop().RunUntilIdle();
680 EXPECT_TRUE(callback_data_.empty());
681 ResetCallbackData();
683 // Serve valid external data for |k20BytePolicy|.
684 SetFakeResponse(k20BytePolicyURL, k20ByteData, net::HTTP_OK,
685 net::URLRequestStatus::SUCCESS);
687 // Retrieve external data for |k20BytePolicy|. Verify that the callback is
688 // invoked with the valid downloaded data, not the invalid data in the cache.
689 external_data_manager_->Fetch(k20BytePolicy, ConstructFetchCallback(1));
690 base::RunLoop().RunUntilIdle();
691 EXPECT_EQ(1u, callback_data_.size());
692 ASSERT_TRUE(callback_data_[1]);
693 EXPECT_EQ(k20ByteData, *callback_data_[1]);
694 ResetCallbackData();
696 external_data_manager_.reset();
697 base::RunLoop().RunUntilIdle();
698 cache.reset(new CloudExternalDataStore(kCacheKey,
699 message_loop_.message_loop_proxy(),
700 resource_cache_.get()));
701 std::string data;
702 // Verify that the invalid external data for |k10BytePolicy| has been pruned
703 // from the cache. Load() will return |false| in two cases:
704 // 1) The cache entry for |k10BytePolicy| has been pruned.
705 // 2) The cache entry for |k10BytePolicy| still exists but the cached data
706 // does not match the expected hash or exceeds the maximum size allowed.
707 // To test for the former, Load() is called with a maximum data size and hash
708 // that would allow the data originally written to the cache to be loaded.
709 // When this fails, it is certain that the original data is no longer present
710 // in the cache.
711 EXPECT_FALSE(cache->Load(k10BytePolicy,
712 crypto::SHA256HashString(k20ByteData),
714 &data));
715 // Verify that the invalid external data for |k20BytePolicy| has been replaced
716 // with the downloaded valid data in the cache.
717 EXPECT_TRUE(cache->Load(k20BytePolicy,
718 crypto::SHA256HashString(k20ByteData),
720 &data));
721 EXPECT_EQ(k20ByteData, data);
724 // Verifies that when the external data reference for a policy changes while a
725 // download of the external data for that policy is pending, the download is
726 // immediately retried using the new reference.
727 TEST_F(CloudExternalDataManagerBaseTest, PolicyChangeWhileDownloadPending) {
728 // Make attempts to download the external data for |k10BytePolicy| and
729 // |k20BytePolicy| fail with an error.
730 SetFakeResponse(k10BytePolicyURL, std::string(),
731 net::HTTP_INTERNAL_SERVER_ERROR,
732 net::URLRequestStatus::FAILED);
733 SetFakeResponse(k20BytePolicyURL, std::string(),
734 net::HTTP_INTERNAL_SERVER_ERROR,
735 net::URLRequestStatus::FAILED);
736 external_data_manager_->Connect(request_content_getter_);
738 // Attempt to retrieve external data for |k10BytePolicy| and |k20BytePolicy|.
739 // Verify that no callbacks are invoked as the download attempts fail and the
740 // requests remain pending.
741 external_data_manager_->Fetch(k10BytePolicy, ConstructFetchCallback(0));
742 external_data_manager_->Fetch(k20BytePolicy, ConstructFetchCallback(1));
743 base::RunLoop().RunUntilIdle();
744 EXPECT_TRUE(callback_data_.empty());
745 ResetCallbackData();
747 // Modify the external data reference for |k10BytePolicy| to be invalid.
748 // Verify that the callback is invoked as the policy no longer has a valid
749 // external data reference.
750 cloud_policy_store_.policy_map_.Erase(k10BytePolicy);
751 cloud_policy_store_.NotifyStoreLoaded();
752 base::RunLoop().RunUntilIdle();
753 EXPECT_EQ(1u, callback_data_.size());
754 EXPECT_TRUE(callback_data_.find(0) != callback_data_.end());
755 EXPECT_FALSE(callback_data_[0]);
756 ResetCallbackData();
758 // Serve valid external data for |k20BytePolicy|.
759 fetcher_factory_.ClearFakeResponses();
760 SetFakeResponse(k20BytePolicyURL, k10ByteData, net::HTTP_OK,
761 net::URLRequestStatus::SUCCESS);
763 // Modify the external data reference for |k20BytePolicy| to match the
764 // external data now being served. Verify that the callback is invoked with
765 // the downloaded data.
766 SetExternalDataReference(
767 k20BytePolicy,
768 ConstructMetadata(k20BytePolicyURL,
769 crypto::SHA256HashString(k10ByteData)));
770 cloud_policy_store_.NotifyStoreLoaded();
771 base::RunLoop().RunUntilIdle();
772 EXPECT_EQ(1u, callback_data_.size());
773 ASSERT_TRUE(callback_data_[1]);
774 EXPECT_EQ(k10ByteData, *callback_data_[1]);
775 ResetCallbackData();
778 } // namespace policy