13240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch// Copyright 2013 The Chromium Authors. All rights reserved.
23240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch// Use of this source code is governed by a BSD-style license that can be
33240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch// found in the LICENSE file.
43240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
5d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "chrome/browser/chromeos/policy/cloud_external_data_manager_base.h"
63240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
73240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch#include <map>
83240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch#include <string>
93240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
103240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch#include "base/bind.h"
113240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch#include "base/bind_helpers.h"
123240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch#include "base/files/scoped_temp_dir.h"
13d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "base/message_loop/message_loop.h"
143240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch#include "base/message_loop/message_loop_proxy.h"
153240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch#include "base/run_loop.h"
163240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch#include "base/stl_util.h"
173240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch#include "base/strings/string_number_conversions.h"
18d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "base/test/test_simple_task_runner.h"
193240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch#include "base/values.h"
20d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "chrome/browser/chromeos/policy/cloud_external_data_store.h"
21a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "components/policy/core/common/cloud/mock_cloud_policy_store.h"
22a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "components/policy/core/common/cloud/resource_cache.h"
23f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "components/policy/core/common/external_data_fetcher.h"
24f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "components/policy/core/common/policy_map.h"
25a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "components/policy/core/common/policy_test_utils.h"
26f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "components/policy/core/common/policy_types.h"
275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "crypto/sha2.h"
280f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#include "net/http/http_status_code.h"
293240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch#include "net/url_request/test_url_fetcher_factory.h"
303240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch#include "net/url_request/url_fetcher.h"
313240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch#include "net/url_request/url_fetcher_delegate.h"
32f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "net/url_request/url_request_status.h"
333240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch#include "net/url_request/url_request_test_util.h"
343240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch#include "testing/gtest/include/gtest/gtest.h"
353240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch#include "url/gurl.h"
363240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
373240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdochnamespace policy {
383240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
393240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdochnamespace {
403240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
413240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch// A string policy.
423240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdochconst char kStringPolicy[] = "StringPolicy";
433240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch// A policy that may reference up to 10 bytes of external data.
443240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdochconst char k10BytePolicy[] = "10BytePolicy";
453240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch// A policy that may reference up to 20 bytes of external data.
463240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdochconst char k20BytePolicy[] = "20BytePolicy";
473240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch// A nonexistent policy.
483240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdochconst char kUnknownPolicy[] = "UnknownPolicy";
493240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
503240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdochconst char k10BytePolicyURL[] = "http://localhost/10_bytes";
513240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdochconst char k20BytePolicyURL[] = "http://localhost/20_bytes";
523240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
533240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdochconst char k10ByteData[] = "10 bytes..";
543240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdochconst char k20ByteData[] = "20 bytes............";
553240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
56f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)const PolicyDetails kPolicyDetails[] = {
57f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)//  is_deprecated  is_device_policy  id    max_external_data_size
58f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  { false,         false,             1,                        0 },
59f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  { false,         false,             2,                       10 },
60f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  { false,         false,             3,                       20 },
613240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch};
623240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
633240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdochconst char kCacheKey[] = "data";
643240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
653240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch// A variant of net::FakeURLFetcherFactory that makes it an error to request a
663240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch// fetcher for an unknown URL.
673240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdochclass FakeURLFetcherFactory : public net::FakeURLFetcherFactory {
683240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch public:
693240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  FakeURLFetcherFactory();
703240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  virtual ~FakeURLFetcherFactory();
713240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
723240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  // net::FakeURLFetcherFactory:
733240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  virtual net::URLFetcher* CreateURLFetcher(
743240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch      int id,
753240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch      const GURL& url,
763240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch      net::URLFetcher::RequestType request_type,
773240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch      net::URLFetcherDelegate* delegate) OVERRIDE;
783240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
793240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch private:
803240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  DISALLOW_COPY_AND_ASSIGN(FakeURLFetcherFactory);
813240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch};
823240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
833240926e260ce088908e02ac07a6cf7b0c0cbf44Ben MurdochFakeURLFetcherFactory::FakeURLFetcherFactory()
843240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    : net::FakeURLFetcherFactory(NULL) {
853240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch}
863240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
873240926e260ce088908e02ac07a6cf7b0c0cbf44Ben MurdochFakeURLFetcherFactory::~FakeURLFetcherFactory() {
883240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch}
893240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
903240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdochnet::URLFetcher* FakeURLFetcherFactory::CreateURLFetcher(
913240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    int id,
923240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    const GURL& url,
933240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    net::URLFetcher::RequestType request_type,
943240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    net::URLFetcherDelegate* delegate) {
953240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  net::URLFetcher* fetcher = net::FakeURLFetcherFactory::CreateURLFetcher(
963240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch      id, url, request_type, delegate);
973240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  EXPECT_TRUE(fetcher);
983240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  return fetcher;
993240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch}
1003240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
1013240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch}  // namespace
1023240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
1034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)class CloudExternalDataManagerBaseTest : public testing::Test {
1043240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch protected:
1054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  CloudExternalDataManagerBaseTest();
1063240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
1073240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  virtual void SetUp() OVERRIDE;
1083240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  virtual void TearDown() OVERRIDE;
1093240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
1103240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  void SetUpExternalDataManager();
1113240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
1123240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  scoped_ptr<base::DictionaryValue> ConstructMetadata(const std::string& url,
1133240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch                                                      const std::string& hash);
1143240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  void SetExternalDataReference(const std::string& policy,
1153240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch                                scoped_ptr<base::DictionaryValue> metadata);
1163240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
1173240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  ExternalDataFetcher::FetchCallback ConstructFetchCallback(int id);
1183240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  void ResetCallbackData();
1193240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
1203240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  void OnFetchDone(int id, scoped_ptr<std::string> data);
1213240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
1223240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  void FetchAll();
1233240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
1244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  void SetFakeResponse(const std::string& url,
1254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                       const std::string& repsonse_data,
126f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                       net::HttpStatusCode response_code,
127f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                       net::URLRequestStatus::Status status);
1284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
129d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  base::MessageLoop message_loop_;
1303240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  base::ScopedTempDir temp_dir_;
1313240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  scoped_ptr<ResourceCache> resource_cache_;
1323240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  MockCloudPolicyStore cloud_policy_store_;
1333240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  scoped_refptr<net::TestURLRequestContextGetter> request_content_getter_;
1343240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  FakeURLFetcherFactory fetcher_factory_;
1353240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
1363240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  scoped_ptr<CloudExternalDataManagerBase> external_data_manager_;
1373240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
1383240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  std::map<int, std::string*> callback_data_;
139f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  PolicyDetailsMap policy_details_;
1403240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
1414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(CloudExternalDataManagerBaseTest);
1423240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch};
1433240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
1444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)CloudExternalDataManagerBaseTest::CloudExternalDataManagerBaseTest() {
1453240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch}
1463240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
1474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void CloudExternalDataManagerBaseTest::SetUp() {
1483240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
149d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  resource_cache_.reset(new ResourceCache(temp_dir_.path(),
150d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                                          message_loop_.message_loop_proxy()));
1513240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  SetUpExternalDataManager();
1523240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
1533240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  // Set |kStringPolicy| to a string value.
1543240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  cloud_policy_store_.policy_map_.Set(kStringPolicy,
1553240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch                                      POLICY_LEVEL_MANDATORY,
1563240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch                                      POLICY_SCOPE_USER,
1573240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch                                      new base::StringValue(std::string()),
1583240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch                                      NULL);
1593240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  // Make |k10BytePolicy| reference 10 bytes of external data.
1603240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  SetExternalDataReference(
1613240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch      k10BytePolicy,
1625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      ConstructMetadata(k10BytePolicyURL,
1635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                        crypto::SHA256HashString(k10ByteData)));
1643240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  // Make |k20BytePolicy| reference 20 bytes of external data.
1653240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  SetExternalDataReference(
1663240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch      k20BytePolicy,
1675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      ConstructMetadata(k20BytePolicyURL,
1685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                        crypto::SHA256HashString(k20ByteData)));
1693240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  cloud_policy_store_.NotifyStoreLoaded();
1703240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
1713240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  request_content_getter_ = new net::TestURLRequestContextGetter(
1723240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch      base::MessageLoopProxy::current());
173f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
174f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  policy_details_.SetDetails(kStringPolicy, &kPolicyDetails[0]);
175f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  policy_details_.SetDetails(k10BytePolicy, &kPolicyDetails[1]);
176f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  policy_details_.SetDetails(k20BytePolicy, &kPolicyDetails[2]);
1773240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch}
1783240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
1794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void CloudExternalDataManagerBaseTest::TearDown() {
180d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  external_data_manager_.reset();
1813240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  base::RunLoop().RunUntilIdle();
1823240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  ResetCallbackData();
1833240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch}
1843240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
1854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void CloudExternalDataManagerBaseTest::SetUpExternalDataManager() {
1863240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  external_data_manager_.reset(new CloudExternalDataManagerBase(
187f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      policy_details_.GetCallback(),
188d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      message_loop_.message_loop_proxy(),
189d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      message_loop_.message_loop_proxy()));
1903240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  external_data_manager_->SetExternalDataStore(make_scoped_ptr(
191d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      new CloudExternalDataStore(kCacheKey,
192d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                                 message_loop_.message_loop_proxy(),
193d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                                 resource_cache_.get())));
1943240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  external_data_manager_->SetPolicyStore(&cloud_policy_store_);
1953240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch}
1963240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
1973240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdochscoped_ptr<base::DictionaryValue>
1984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    CloudExternalDataManagerBaseTest::ConstructMetadata(
1993240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch        const std::string& url,
2003240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch        const std::string& hash) {
2013240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  scoped_ptr<base::DictionaryValue> metadata(new base::DictionaryValue);
2023240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  metadata->SetStringWithoutPathExpansion("url", url);
2033240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  metadata->SetStringWithoutPathExpansion("hash", base::HexEncode(hash.c_str(),
2043240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch                                                                  hash.size()));
2053240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  return metadata.Pass();
2063240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch}
2073240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
2084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void CloudExternalDataManagerBaseTest::SetExternalDataReference(
2093240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    const std::string& policy,
2103240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    scoped_ptr<base::DictionaryValue> metadata) {
2113240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  cloud_policy_store_.policy_map_.Set(
2123240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch      policy,
2133240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch      POLICY_LEVEL_MANDATORY,
2143240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch      POLICY_SCOPE_USER,
2153240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch      metadata.release(),
2163240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch      new ExternalDataFetcher(
2173240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch          external_data_manager_->weak_factory_.GetWeakPtr(), policy));
2183240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch}
2193240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
2203240926e260ce088908e02ac07a6cf7b0c0cbf44Ben MurdochExternalDataFetcher::FetchCallback
2214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)CloudExternalDataManagerBaseTest::ConstructFetchCallback(int id) {
2224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  return base::Bind(&CloudExternalDataManagerBaseTest::OnFetchDone,
2233240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch                    base::Unretained(this),
2243240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch                    id);
2253240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch}
2263240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
2274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void CloudExternalDataManagerBaseTest::ResetCallbackData() {
2283240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  STLDeleteValues(&callback_data_);
2293240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch}
2303240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
2314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void CloudExternalDataManagerBaseTest::OnFetchDone(
2323240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    int id,
2333240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    scoped_ptr<std::string> data) {
2343240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  delete callback_data_[id];
2353240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  callback_data_[id] = data.release();
2363240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch}
2373240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
2384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void CloudExternalDataManagerBaseTest::FetchAll() {
2393240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  external_data_manager_->FetchAll();
2403240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch}
2413240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
2424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void CloudExternalDataManagerBaseTest::SetFakeResponse(
2434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    const std::string& url,
2444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    const std::string& response_data,
245f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    net::HttpStatusCode response_code,
246f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    net::URLRequestStatus::Status status) {
247f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  fetcher_factory_.SetFakeResponse(
248f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      GURL(url), response_data, response_code, status);
2494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
2504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2513240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch// Verifies that when no valid external data reference has been set for a
2523240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch// policy, the attempt to retrieve the external data fails immediately.
2534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)TEST_F(CloudExternalDataManagerBaseTest, FailToFetchInvalid) {
2543240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  external_data_manager_->Connect(request_content_getter_);
2553240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
2563240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  // Attempt to retrieve external data for |kStringPolicy|, which is a string
2573240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  // policy that does not reference any external data.
2583240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  external_data_manager_->Fetch(kStringPolicy, ConstructFetchCallback(0));
2593240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  base::RunLoop().RunUntilIdle();
2603240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  EXPECT_EQ(1u, callback_data_.size());
2613240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  EXPECT_TRUE(callback_data_.find(0) != callback_data_.end());
2623240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  EXPECT_FALSE(callback_data_[0]);
2633240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  ResetCallbackData();
2643240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
2653240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  // Attempt to retrieve external data for |kUnknownPolicy|, which is not a
2663240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  // known policy.
2673240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  external_data_manager_->Fetch(kUnknownPolicy, ConstructFetchCallback(1));
2683240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  base::RunLoop().RunUntilIdle();
2693240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  EXPECT_EQ(1u, callback_data_.size());
2703240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  EXPECT_TRUE(callback_data_.find(1) != callback_data_.end());
2713240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  EXPECT_FALSE(callback_data_[1]);
2723240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  ResetCallbackData();
2733240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
2743240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  // Set an invalid external data reference for |k10BytePolicy|.
2753240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  SetExternalDataReference(k10BytePolicy,
2763240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch                           ConstructMetadata(std::string(), std::string()));
2773240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  cloud_policy_store_.NotifyStoreLoaded();
2783240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
2793240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  // Attempt to retrieve external data for |k10BytePolicy|, which now has an
2803240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  // invalid reference.
2813240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  external_data_manager_->Fetch(k10BytePolicy, ConstructFetchCallback(2));
2823240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  base::RunLoop().RunUntilIdle();
2833240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  EXPECT_EQ(1u, callback_data_.size());
2843240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  EXPECT_TRUE(callback_data_.find(2) != callback_data_.end());
2853240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  EXPECT_FALSE(callback_data_[2]);
2863240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  ResetCallbackData();
2873240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch}
2883240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
2893240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch// Verifies that external data referenced by a policy is downloaded and cached
2903240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch// when first requested. Subsequent requests are served from the cache without
2913240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch// further download attempts.
2924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)TEST_F(CloudExternalDataManagerBaseTest, DownloadAndCache) {
2933240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  // Serve valid external data for |k10BytePolicy|.
294f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  SetFakeResponse(k10BytePolicyURL, k10ByteData, net::HTTP_OK,
295f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                  net::URLRequestStatus::SUCCESS);
2963240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  external_data_manager_->Connect(request_content_getter_);
2973240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
2983240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  // Retrieve external data for |k10BytePolicy|. Verify that a download happens
2993240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  // and the callback is invoked with the downloaded data.
3003240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  external_data_manager_->Fetch(k10BytePolicy, ConstructFetchCallback(0));
3013240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  base::RunLoop().RunUntilIdle();
3023240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  EXPECT_EQ(1u, callback_data_.size());
3033240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  ASSERT_TRUE(callback_data_[0]);
3043240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  EXPECT_EQ(k10ByteData, *callback_data_[0]);
3053240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  ResetCallbackData();
3063240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
3073240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  // Stop serving external data for |k10BytePolicy|.
3083240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  fetcher_factory_.ClearFakeResponses();
3093240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
3103240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  // Retrieve external data for |k10BytePolicy| again. Verify that no download
3113240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  // is attempted but the callback is still invoked with the expected data,
3123240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  // served from the cache.
3133240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  external_data_manager_->Fetch(k10BytePolicy, ConstructFetchCallback(1));
3143240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  base::RunLoop().RunUntilIdle();
3153240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  EXPECT_EQ(1u, callback_data_.size());
3163240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  ASSERT_TRUE(callback_data_[1]);
3173240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  EXPECT_EQ(k10ByteData, *callback_data_[1]);
3183240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  ResetCallbackData();
3193240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
3203240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  // Explicitly tell the external_data_manager_ to not make any download
3213240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  // attempts.
3223240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  external_data_manager_->Disconnect();
3233240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
3243240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  // Retrieve external data for |k10BytePolicy| again. Verify that even though
3253240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  // downloads are not allowed, the callback is still invoked with the expected
3263240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  // data, served from the cache.
3273240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  external_data_manager_->Fetch(k10BytePolicy, ConstructFetchCallback(2));
3283240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  base::RunLoop().RunUntilIdle();
3293240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  EXPECT_EQ(1u, callback_data_.size());
3303240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  ASSERT_TRUE(callback_data_[2]);
3313240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  EXPECT_EQ(k10ByteData, *callback_data_[2]);
3323240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  ResetCallbackData();
3333240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
3343240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  // Verify that the downloaded data is present in the cache.
3353240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  external_data_manager_.reset();
3363240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  base::RunLoop().RunUntilIdle();
3373240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  std::string data;
338d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  EXPECT_TRUE(CloudExternalDataStore(kCacheKey,
339d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                                     message_loop_.message_loop_proxy(),
340d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                                     resource_cache_.get()).Load(
3415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      k10BytePolicy, crypto::SHA256HashString(k10ByteData), 10, &data));
3423240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  EXPECT_EQ(k10ByteData, data);
3433240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch}
3443240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
3453240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch// Verifies that a request to download and cache all external data referenced by
3463240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch// policies is carried out correctly. Subsequent requests for the data are
3473240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch// served from the cache without further download attempts.
3484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)TEST_F(CloudExternalDataManagerBaseTest, DownloadAndCacheAll) {
3493240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  // Serve valid external data for |k10BytePolicy| and |k20BytePolicy|.
350f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  SetFakeResponse(k10BytePolicyURL, k10ByteData, net::HTTP_OK,
351f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                  net::URLRequestStatus::SUCCESS);
352f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  SetFakeResponse(k20BytePolicyURL, k20ByteData, net::HTTP_OK,
353f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                  net::URLRequestStatus::SUCCESS);
3543240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  external_data_manager_->Connect(request_content_getter_);
3553240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
3563240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  // Request that external data referenced by all policies be downloaded.
3573240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  FetchAll();
3583240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  base::RunLoop().RunUntilIdle();
3593240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
3603240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  // Stop serving external data for |k10BytePolicy| and |k20BytePolicy|.
3613240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  fetcher_factory_.ClearFakeResponses();
3623240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
3633240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  // Retrieve external data for |k10BytePolicy| and |k20BytePolicy|. Verify that
3643240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  // no downloads are attempted but the callbacks are still invoked with the
3653240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  // expected data, served from the cache.
3663240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  external_data_manager_->Fetch(k10BytePolicy, ConstructFetchCallback(0));
3673240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  external_data_manager_->Fetch(k20BytePolicy, ConstructFetchCallback(1));
3683240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  base::RunLoop().RunUntilIdle();
3693240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  EXPECT_EQ(2u, callback_data_.size());
3703240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  ASSERT_TRUE(callback_data_[0]);
3713240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  EXPECT_EQ(k10ByteData, *callback_data_[0]);
3723240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  ASSERT_TRUE(callback_data_[1]);
3733240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  EXPECT_EQ(k20ByteData, *callback_data_[1]);
3743240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  ResetCallbackData();
3753240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
3763240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  // Explicitly tell the external_data_manager_ to not make any download
3773240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  // attempts.
3783240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  external_data_manager_->Disconnect();
3793240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
3803240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  // Retrieve external data for |k10BytePolicy| and |k20BytePolicy|. Verify that
3813240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  // even though downloads are not allowed, the callbacks are still invoked with
3823240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  // the expected data, served from the cache.
3833240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  external_data_manager_->Fetch(k10BytePolicy, ConstructFetchCallback(2));
3843240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  external_data_manager_->Fetch(k20BytePolicy, ConstructFetchCallback(3));
3853240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  base::RunLoop().RunUntilIdle();
3863240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  EXPECT_EQ(2u, callback_data_.size());
3873240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  ASSERT_TRUE(callback_data_[2]);
3883240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  EXPECT_EQ(k10ByteData, *callback_data_[2]);
3893240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  ASSERT_TRUE(callback_data_[3]);
3903240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  EXPECT_EQ(k20ByteData, *callback_data_[3]);
3913240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  ResetCallbackData();
3923240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
3933240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  // Verify that the downloaded data is present in the cache.
3943240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  external_data_manager_.reset();
3953240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  base::RunLoop().RunUntilIdle();
396d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  CloudExternalDataStore cache(kCacheKey,
397d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                               message_loop_.message_loop_proxy(),
398d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                               resource_cache_.get());
3993240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  std::string data;
4005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(cache.Load(k10BytePolicy,
4015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                         crypto::SHA256HashString(k10ByteData),
4025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                         10,
4033240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch                         &data));
4043240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  EXPECT_EQ(k10ByteData, data);
4055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(cache.Load(k20BytePolicy,
4065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                         crypto::SHA256HashString(k20ByteData),
4075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                         20,
4083240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch                         &data));
4093240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  EXPECT_EQ(k20ByteData, data);
4103240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch}
4113240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
4123240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch// Verifies that when the external data referenced by a policy is not present in
4133240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch// the cache and downloads are not allowed, a request to retrieve the data is
4143240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch// enqueued and carried out when downloads become possible.
4154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)TEST_F(CloudExternalDataManagerBaseTest, DownloadAfterConnect) {
4163240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  // Attempt to retrieve external data for |k10BytePolicy|. Verify that the
4173240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  // callback is not invoked as the request remains pending.
4183240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  external_data_manager_->Fetch(k10BytePolicy, ConstructFetchCallback(0));
4193240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  base::RunLoop().RunUntilIdle();
4203240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  EXPECT_TRUE(callback_data_.empty());
4213240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  ResetCallbackData();
4223240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
4233240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  // Serve valid external data for |k10BytePolicy| and allow the
4243240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  // external_data_manager_ to perform downloads.
425f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  SetFakeResponse(k10BytePolicyURL, k10ByteData, net::HTTP_OK,
426f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                  net::URLRequestStatus::SUCCESS);
4273240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  external_data_manager_->Connect(request_content_getter_);
4283240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
4293240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  // Verify that a download happens and the callback is invoked with the
4303240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  // downloaded data.
4313240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  base::RunLoop().RunUntilIdle();
4323240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  EXPECT_EQ(1u, callback_data_.size());
4333240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  ASSERT_TRUE(callback_data_[0]);
4343240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  EXPECT_EQ(k10ByteData, *callback_data_[0]);
4353240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  ResetCallbackData();
4363240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch}
4373240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
4383240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch// Verifies that when the external data referenced by a policy is not present in
4393240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch// the cache and cannot be downloaded at this time, a request to retrieve the
4403240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch// data is enqueued to be retried later.
4414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)TEST_F(CloudExternalDataManagerBaseTest, DownloadError) {
4423240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  // Make attempts to download the external data for |k20BytePolicy| fail with
4433240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  // an error.
4440f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  SetFakeResponse(k20BytePolicyURL, std::string(),
445f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                  net::HTTP_INTERNAL_SERVER_ERROR,
446f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                  net::URLRequestStatus::FAILED);
4473240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  external_data_manager_->Connect(request_content_getter_);
4483240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
4493240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  // Attempt to retrieve external data for |k20BytePolicy|. Verify that the
4503240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  // callback is not invoked as the download attempt fails and the request
4513240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  // remains pending.
4523240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  external_data_manager_->Fetch(k20BytePolicy, ConstructFetchCallback(0));
4533240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  base::RunLoop().RunUntilIdle();
4543240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  EXPECT_TRUE(callback_data_.empty());
4553240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  ResetCallbackData();
4563240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
4573240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  // Modify the external data reference for |k20BytePolicy|, allowing the
4583240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  // download to be retried immediately.
4593240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  SetExternalDataReference(
4603240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch      k20BytePolicy,
4615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      ConstructMetadata(k20BytePolicyURL,
4625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                        crypto::SHA256HashString(k10ByteData)));
4633240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  cloud_policy_store_.NotifyStoreLoaded();
4643240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
4653240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  // Attempt to retrieve external data for |k20BytePolicy| again. Verify that
4663240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  // no callback is invoked still as the download attempt fails again and the
4673240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  // request remains pending.
4683240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  external_data_manager_->Fetch(k20BytePolicy, ConstructFetchCallback(1));
4693240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  base::RunLoop().RunUntilIdle();
4703240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  EXPECT_TRUE(callback_data_.empty());
4713240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  ResetCallbackData();
4723240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
4733240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  // Modify the external data reference for |k20BytePolicy|, allowing the
4743240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  // download to be retried immediately.
4753240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  SetExternalDataReference(
4763240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch      k20BytePolicy,
4775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      ConstructMetadata(k20BytePolicyURL,
4785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                        crypto::SHA256HashString(k20ByteData)));
4793240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  cloud_policy_store_.NotifyStoreLoaded();
4803240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
4813240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  // Serve external data for |k20BytePolicy| that does not match the hash
4823240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  // specified in its current external data reference.
483f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  SetFakeResponse(k20BytePolicyURL, k10ByteData, net::HTTP_OK,
484f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                  net::URLRequestStatus::SUCCESS);
4853240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
4863240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  // Attempt to retrieve external data for |k20BytePolicy| again. Verify that
4873240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  // no callback is invoked still as the downloaded succeeds but returns data
4883240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  // that does not match the external data reference.
4893240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  external_data_manager_->Fetch(k20BytePolicy, ConstructFetchCallback(2));
4903240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  base::RunLoop().RunUntilIdle();
4913240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  EXPECT_TRUE(callback_data_.empty());
4923240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  ResetCallbackData();
4933240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
4943240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  // Modify the external data reference for |k20BytePolicy|, allowing the
4953240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  // download to be retried immediately. The external data reference now matches
4963240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  // the data being served.
4973240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  SetExternalDataReference(
4983240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch      k20BytePolicy,
4995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      ConstructMetadata(k20BytePolicyURL,
5005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                        crypto::SHA256HashString(k10ByteData)));
5013240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  cloud_policy_store_.NotifyStoreLoaded();
5023240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
5033240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  // Attempt to retrieve external data for |k20BytePolicy| again. Verify that
5043240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  // the current callback and the three previously enqueued callbacks are
5053240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  // invoked with the downloaded data now.
5063240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  external_data_manager_->Fetch(k20BytePolicy, ConstructFetchCallback(3));
5073240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  base::RunLoop().RunUntilIdle();
5083240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  EXPECT_EQ(4u, callback_data_.size());
5093240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  ASSERT_TRUE(callback_data_[0]);
5103240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  EXPECT_EQ(k10ByteData, *callback_data_[0]);
5113240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  ASSERT_TRUE(callback_data_[1]);
5123240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  EXPECT_EQ(k10ByteData, *callback_data_[1]);
5133240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  ASSERT_TRUE(callback_data_[2]);
5143240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  EXPECT_EQ(k10ByteData, *callback_data_[2]);
5153240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  ASSERT_TRUE(callback_data_[3]);
5163240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  EXPECT_EQ(k10ByteData, *callback_data_[3]);
5173240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  ResetCallbackData();
5183240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch}
5193240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
5203240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch// Verifies that when the external data referenced by a policy is present in the
5213240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch// cache, a request to retrieve it is served from the cache without any download
5223240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch// attempts.
5234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)TEST_F(CloudExternalDataManagerBaseTest, LoadFromCache) {
5243240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  // Store valid external data for |k10BytePolicy| in the cache.
5253240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  external_data_manager_.reset();
5263240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  base::RunLoop().RunUntilIdle();
527d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  EXPECT_TRUE(CloudExternalDataStore(kCacheKey,
528d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                                     message_loop_.message_loop_proxy(),
529d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                                     resource_cache_.get()).Store(
5305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      k10BytePolicy, crypto::SHA256HashString(k10ByteData), k10ByteData));
5313240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
5323240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  // Instantiate an external_data_manager_ that uses the primed cache.
5333240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  SetUpExternalDataManager();
5343240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  external_data_manager_->Connect(request_content_getter_);
5353240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
5363240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  // Retrieve external data for |k10BytePolicy|. Verify that no download is
5373240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  // attempted but the callback is still invoked with the expected data, served
5383240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  // from the cache.
5393240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  external_data_manager_->Fetch(k10BytePolicy, ConstructFetchCallback(0));
5403240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  base::RunLoop().RunUntilIdle();
5413240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  EXPECT_EQ(1u, callback_data_.size());
5423240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  ASSERT_TRUE(callback_data_[0]);
5433240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  EXPECT_EQ(k10ByteData, *callback_data_[0]);
5443240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  ResetCallbackData();
5453240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch}
5463240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
5473240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch// Verifies that cache entries which do not correspond to the external data
5483240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch// referenced by any policy are pruned on startup.
5494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)TEST_F(CloudExternalDataManagerBaseTest, PruneCacheOnStartup) {
5503240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  external_data_manager_.reset();
5513240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  base::RunLoop().RunUntilIdle();
5523240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  scoped_ptr<CloudExternalDataStore>
553d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      cache(new CloudExternalDataStore(kCacheKey,
554d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                                       message_loop_.message_loop_proxy(),
555d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                                       resource_cache_.get()));
5563240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  // Store valid external data for |k10BytePolicy| in the cache.
5573240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  EXPECT_TRUE(cache->Store(k10BytePolicy,
5585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                           crypto::SHA256HashString(k10ByteData),
5593240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch                           k10ByteData));
5603240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  // Store external data for |k20BytePolicy| that does not match the hash in its
5613240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  // external data reference.
5623240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  EXPECT_TRUE(cache->Store(k20BytePolicy,
5635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                           crypto::SHA256HashString(k10ByteData),
5643240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch                           k10ByteData));
5653240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  // Store external data for |kUnknownPolicy|, which is not a known policy and
5663240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  // therefore, cannot be referencing any external data.
5673240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  EXPECT_TRUE(cache->Store(kUnknownPolicy,
5685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                           crypto::SHA256HashString(k10ByteData),
5693240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch                           k10ByteData));
5703240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  cache.reset();
5713240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
5723240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  // Instantiate and destroy an ExternalDataManager that uses the primed cache.
5733240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  SetUpExternalDataManager();
5743240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  external_data_manager_.reset();
5753240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  base::RunLoop().RunUntilIdle();
5763240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
577d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  cache.reset(new CloudExternalDataStore(kCacheKey,
578d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                                         message_loop_.message_loop_proxy(),
579d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                                         resource_cache_.get()));
5803240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  std::string data;
5813240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  // Verify that the valid external data for |k10BytePolicy| is still in the
5823240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  // cache.
5835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(cache->Load(k10BytePolicy,
5845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                          crypto::SHA256HashString(k10ByteData),
5855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                          10,
5865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                          &data));
5873240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  EXPECT_EQ(k10ByteData, data);
5883240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  // Verify that the external data for |k20BytePolicy| and |kUnknownPolicy| has
5893240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  // been pruned from the cache.
5905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_FALSE(cache->Load(k20BytePolicy,
5915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                           crypto::SHA256HashString(k10ByteData),
5925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                           20,
5935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                           &data));
5945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_FALSE(cache->Load(kUnknownPolicy,
5955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                           crypto::SHA256HashString(k10ByteData),
5965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                           20,
5975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                           &data));
5983240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch}
5993240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
6003240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch// Verifies that when the external data referenced by a policy is present in the
6013240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch// cache and the reference changes, the old data is pruned from the cache.
6024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)TEST_F(CloudExternalDataManagerBaseTest, PruneCacheOnChange) {
6033240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  // Store valid external data for |k20BytePolicy| in the cache.
6043240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  external_data_manager_.reset();
6053240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  base::RunLoop().RunUntilIdle();
6063240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  scoped_ptr<CloudExternalDataStore>
607d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      cache(new CloudExternalDataStore(kCacheKey,
608d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                                       message_loop_.message_loop_proxy(),
609d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                                       resource_cache_.get()));
6103240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  EXPECT_TRUE(cache->Store(k20BytePolicy,
6115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                           crypto::SHA256HashString(k20ByteData),
6123240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch                           k20ByteData));
6133240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  cache.reset();
6143240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
6153240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  // Instantiate an ExternalDataManager that uses the primed cache.
6163240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  SetUpExternalDataManager();
6173240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  external_data_manager_->Connect(request_content_getter_);
6183240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
6193240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  // Modify the external data reference for |k20BytePolicy|.
6203240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  SetExternalDataReference(
6213240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch      k20BytePolicy,
6225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      ConstructMetadata(k20BytePolicyURL,
6235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                        crypto::SHA256HashString(k10ByteData)));
6243240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  cloud_policy_store_.NotifyStoreLoaded();
6253240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
6263240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  // Verify that the old external data for |k20BytePolicy| has been pruned from
6273240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  // the cache.
6283240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  external_data_manager_.reset();
6293240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  base::RunLoop().RunUntilIdle();
630d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  cache.reset(new CloudExternalDataStore(kCacheKey,
631d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                                         message_loop_.message_loop_proxy(),
632d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                                         resource_cache_.get()));
6333240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  std::string data;
6345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_FALSE(cache->Load(k20BytePolicy,
6355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                           crypto::SHA256HashString(k20ByteData),
6365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                           20,
6373240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch                           &data));
6383240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch}
6393240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
6403240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch// Verifies that corrupt cache entries are detected and deleted when accessed.
6414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)TEST_F(CloudExternalDataManagerBaseTest, CacheCorruption) {
6423240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  external_data_manager_.reset();
6433240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  base::RunLoop().RunUntilIdle();
6443240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  scoped_ptr<CloudExternalDataStore>
645d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      cache(new CloudExternalDataStore(kCacheKey,
646d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                                       message_loop_.message_loop_proxy(),
647d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                                       resource_cache_.get()));
6483240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  // Store external data for |k10BytePolicy| that exceeds the maximal external
6493240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  // data size allowed for that policy.
6503240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  EXPECT_TRUE(cache->Store(k10BytePolicy,
6515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                           crypto::SHA256HashString(k20ByteData),
6523240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch                           k20ByteData));
6533240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  // Store external data for |k20BytePolicy| that is corrupted and does not
6543240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  // match the expected hash.
6553240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  EXPECT_TRUE(cache->Store(k20BytePolicy,
6565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                           crypto::SHA256HashString(k20ByteData),
6573240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch                           k10ByteData));
6583240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  cache.reset();
6593240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
6603240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  SetUpExternalDataManager();
6613240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  // Serve external data for |k10BytePolicy| that exceeds the maximal external
6623240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  // data size allowed for that policy.
663f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  SetFakeResponse(k10BytePolicyURL, k20ByteData, net::HTTP_OK,
664f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                  net::URLRequestStatus::SUCCESS);
6653240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  external_data_manager_->Connect(request_content_getter_);
6663240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
6673240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  // Modify the external data reference for |k10BytePolicy| to match the
6683240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  // external data being served.
6693240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  SetExternalDataReference(
6703240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch      k10BytePolicy,
6715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      ConstructMetadata(k10BytePolicyURL,
6725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                        crypto::SHA256HashString(k20ByteData)));
6733240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  cloud_policy_store_.NotifyStoreLoaded();
6743240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
6753240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  // Retrieve external data for |k10BytePolicy|. Verify that the callback is
6763240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  // not invoked as the cached and downloaded external data exceed the maximal
6773240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  // size allowed for this policy and the request remains pending.
6783240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  external_data_manager_->Fetch(k10BytePolicy, ConstructFetchCallback(0));
6793240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  base::RunLoop().RunUntilIdle();
6803240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  EXPECT_TRUE(callback_data_.empty());
6813240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  ResetCallbackData();
6823240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
6833240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  // Serve valid external data for |k20BytePolicy|.
684f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  SetFakeResponse(k20BytePolicyURL, k20ByteData, net::HTTP_OK,
685f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                  net::URLRequestStatus::SUCCESS);
6863240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
6873240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  // Retrieve external data for |k20BytePolicy|. Verify that the callback is
6883240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  // invoked with the valid downloaded data, not the invalid data in the cache.
6893240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  external_data_manager_->Fetch(k20BytePolicy, ConstructFetchCallback(1));
6903240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  base::RunLoop().RunUntilIdle();
6913240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  EXPECT_EQ(1u, callback_data_.size());
6923240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  ASSERT_TRUE(callback_data_[1]);
6933240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  EXPECT_EQ(k20ByteData, *callback_data_[1]);
6943240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  ResetCallbackData();
6953240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
6963240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  external_data_manager_.reset();
6973240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  base::RunLoop().RunUntilIdle();
698d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  cache.reset(new CloudExternalDataStore(kCacheKey,
699d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                                         message_loop_.message_loop_proxy(),
700d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                                         resource_cache_.get()));
7013240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  std::string data;
7023240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  // Verify that the invalid external data for |k10BytePolicy| has been pruned
7033240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  // from the cache. Load() will return |false| in two cases:
7043240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  // 1) The cache entry for |k10BytePolicy| has been pruned.
7053240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  // 2) The cache entry for |k10BytePolicy| still exists but the cached data
7063240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  //    does not match the expected hash or exceeds the maximum size allowed.
7073240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  // To test for the former, Load() is called with a maximum data size and hash
7083240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  // that would allow the data originally written to the cache to be loaded.
7093240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  // When this fails, it is certain that the original data is no longer present
7103240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  // in the cache.
7115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_FALSE(cache->Load(k10BytePolicy,
7125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                           crypto::SHA256HashString(k20ByteData),
7135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                           20,
7143240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch                           &data));
7153240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  // Verify that the invalid external data for |k20BytePolicy| has been replaced
7163240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  // with the downloaded valid data in the cache.
7175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(cache->Load(k20BytePolicy,
7185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                          crypto::SHA256HashString(k20ByteData),
7195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                          20,
7203240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch                          &data));
7213240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  EXPECT_EQ(k20ByteData, data);
7223240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch}
7233240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
7243240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch// Verifies that when the external data reference for a policy changes while a
7253240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch// download of the external data for that policy is pending, the download is
7263240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch// immediately retried using the new reference.
7274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)TEST_F(CloudExternalDataManagerBaseTest, PolicyChangeWhileDownloadPending) {
7283240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  // Make attempts to download the external data for |k10BytePolicy| and
7293240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  // |k20BytePolicy| fail with an error.
7300f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  SetFakeResponse(k10BytePolicyURL, std::string(),
731f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                  net::HTTP_INTERNAL_SERVER_ERROR,
732f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                  net::URLRequestStatus::FAILED);
7330f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  SetFakeResponse(k20BytePolicyURL, std::string(),
734f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                  net::HTTP_INTERNAL_SERVER_ERROR,
735f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                  net::URLRequestStatus::FAILED);
7363240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  external_data_manager_->Connect(request_content_getter_);
7373240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
7383240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  // Attempt to retrieve external data for |k10BytePolicy| and |k20BytePolicy|.
7393240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  // Verify that no callbacks are invoked as the download attempts fail and the
7403240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  // requests remain pending.
7413240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  external_data_manager_->Fetch(k10BytePolicy, ConstructFetchCallback(0));
7423240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  external_data_manager_->Fetch(k20BytePolicy, ConstructFetchCallback(1));
7433240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  base::RunLoop().RunUntilIdle();
7443240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  EXPECT_TRUE(callback_data_.empty());
7453240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  ResetCallbackData();
7463240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
7473240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  // Modify the external data reference for |k10BytePolicy| to be invalid.
7483240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  // Verify that the callback is invoked as the policy no longer has a valid
7493240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  // external data reference.
7503240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  cloud_policy_store_.policy_map_.Erase(k10BytePolicy);
7513240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  cloud_policy_store_.NotifyStoreLoaded();
7523240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  base::RunLoop().RunUntilIdle();
7533240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  EXPECT_EQ(1u, callback_data_.size());
7543240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  EXPECT_TRUE(callback_data_.find(0) != callback_data_.end());
7553240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  EXPECT_FALSE(callback_data_[0]);
7563240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  ResetCallbackData();
7573240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
7583240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  // Serve valid external data for |k20BytePolicy|.
7593240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  fetcher_factory_.ClearFakeResponses();
760f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  SetFakeResponse(k20BytePolicyURL, k10ByteData, net::HTTP_OK,
761f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                  net::URLRequestStatus::SUCCESS);
7623240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
7633240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  // Modify the external data reference for |k20BytePolicy| to match the
7643240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  // external data now being served. Verify that the callback is invoked with
7653240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  // the downloaded data.
7663240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  SetExternalDataReference(
7673240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch      k20BytePolicy,
7685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      ConstructMetadata(k20BytePolicyURL,
7695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                        crypto::SHA256HashString(k10ByteData)));
7703240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  cloud_policy_store_.NotifyStoreLoaded();
7713240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  base::RunLoop().RunUntilIdle();
7723240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  EXPECT_EQ(1u, callback_data_.size());
7733240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  ASSERT_TRUE(callback_data_[1]);
7743240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  EXPECT_EQ(k10ByteData, *callback_data_[1]);
7753240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  ResetCallbackData();
7763240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch}
7773240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
7783240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch}  // namespace policy
779