Home | History | Annotate | Download | only in policy
      1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "chrome/browser/chromeos/policy/user_cloud_policy_store_chromeos.h"
      6 
      7 #include <vector>
      8 
      9 #include "base/basictypes.h"
     10 #include "base/bind.h"
     11 #include "base/file_util.h"
     12 #include "base/files/scoped_temp_dir.h"
     13 #include "base/memory/scoped_ptr.h"
     14 #include "base/message_loop/message_loop.h"
     15 #include "base/threading/sequenced_worker_pool.h"
     16 #include "chrome/browser/policy/cloud/cloud_policy_constants.h"
     17 #include "chrome/browser/policy/cloud/mock_cloud_policy_store.h"
     18 #include "chrome/browser/policy/cloud/policy_builder.h"
     19 #include "chrome/browser/policy/proto/cloud/device_management_local.pb.h"
     20 #include "chromeos/dbus/mock_cryptohome_client.h"
     21 #include "chromeos/dbus/mock_session_manager_client.h"
     22 #include "content/public/test/test_browser_thread.h"
     23 #include "policy/policy_constants.h"
     24 #include "policy/proto/cloud_policy.pb.h"
     25 #include "testing/gmock/include/gmock/gmock.h"
     26 #include "testing/gtest/include/gtest/gtest.h"
     27 
     28 namespace em = enterprise_management;
     29 
     30 using testing::AllOf;
     31 using testing::AnyNumber;
     32 using testing::Eq;
     33 using testing::Mock;
     34 using testing::Property;
     35 using testing::Return;
     36 using testing::SaveArg;
     37 using testing::_;
     38 
     39 namespace policy {
     40 
     41 namespace {
     42 
     43 const char kLegacyDeviceId[] = "legacy-device-id";
     44 const char kLegacyToken[] = "legacy-token";
     45 const char kSanitizedUsername[] = "0123456789ABCDEF0123456789ABCDEF012345678";
     46 const char kDefaultHomepage[] = "http://chromium.org";
     47 
     48 ACTION_P2(SendSanitizedUsername, call_status, sanitized_username) {
     49   base::MessageLoop::current()->PostTask(
     50       FROM_HERE, base::Bind(arg1, call_status, sanitized_username));
     51 }
     52 
     53 class UserCloudPolicyStoreChromeOSTest : public testing::Test {
     54  protected:
     55   UserCloudPolicyStoreChromeOSTest()
     56       : loop_(base::MessageLoop::TYPE_UI),
     57         ui_thread_(content::BrowserThread::UI, &loop_),
     58         file_thread_(content::BrowserThread::FILE, &loop_) {}
     59 
     60   virtual void SetUp() OVERRIDE {
     61     EXPECT_CALL(cryptohome_client_,
     62                 GetSanitizedUsername(PolicyBuilder::kFakeUsername, _))
     63         .Times(AnyNumber())
     64         .WillRepeatedly(
     65             SendSanitizedUsername(chromeos::DBUS_METHOD_CALL_SUCCESS,
     66                                   kSanitizedUsername));
     67 
     68     ASSERT_TRUE(tmp_dir_.CreateUniqueTempDir());
     69     store_.reset(new UserCloudPolicyStoreChromeOS(&cryptohome_client_,
     70                                                   &session_manager_client_,
     71                                                   PolicyBuilder::kFakeUsername,
     72                                                   user_policy_dir(),
     73                                                   token_file(),
     74                                                   policy_file()));
     75     store_->AddObserver(&observer_);
     76 
     77     // Install the initial public key, so that by default the validation of
     78     // the stored/loaded policy blob succeeds.
     79     std::vector<uint8> public_key;
     80     ASSERT_TRUE(policy_.GetSigningKey()->ExportPublicKey(&public_key));
     81     StoreUserPolicyKey(public_key);
     82 
     83     policy_.payload().mutable_homepagelocation()->set_value(kDefaultHomepage);
     84     policy_.Build();
     85   }
     86 
     87   virtual void TearDown() OVERRIDE {
     88     store_->RemoveObserver(&observer_);
     89     store_.reset();
     90     RunUntilIdle();
     91   }
     92 
     93   // Install an expectation on |observer_| for an error code.
     94   void ExpectError(CloudPolicyStore::Status error) {
     95     EXPECT_CALL(observer_,
     96                 OnStoreError(AllOf(Eq(store_.get()),
     97                                    Property(&CloudPolicyStore::status,
     98                                             Eq(error)))));
     99   }
    100 
    101   // Triggers a store_->Load() operation, handles the expected call to
    102   // |session_manager_client_| and sends |response|.
    103   void PerformPolicyLoad(const std::string& response) {
    104     // Issue a load command.
    105     chromeos::SessionManagerClient::RetrievePolicyCallback retrieve_callback;
    106     EXPECT_CALL(session_manager_client_,
    107                 RetrievePolicyForUser(PolicyBuilder::kFakeUsername, _))
    108         .WillOnce(SaveArg<1>(&retrieve_callback));
    109     store_->Load();
    110     RunUntilIdle();
    111     Mock::VerifyAndClearExpectations(&session_manager_client_);
    112     ASSERT_FALSE(retrieve_callback.is_null());
    113 
    114     // Run the callback.
    115     retrieve_callback.Run(response);
    116     RunUntilIdle();
    117   }
    118 
    119   // Verifies that store_->policy_map() has the HomepageLocation entry with
    120   // the |expected_value|.
    121   void VerifyPolicyMap(const char* expected_value) {
    122     EXPECT_EQ(1U, store_->policy_map().size());
    123     const PolicyMap::Entry* entry =
    124         store_->policy_map().Get(key::kHomepageLocation);
    125     ASSERT_TRUE(entry);
    126     EXPECT_TRUE(base::StringValue(expected_value).Equals(entry->value));
    127   }
    128 
    129   void StoreUserPolicyKey(const std::vector<uint8>& public_key) {
    130     ASSERT_TRUE(file_util::CreateDirectory(user_policy_key_file().DirName()));
    131     ASSERT_TRUE(
    132         file_util::WriteFile(user_policy_key_file(),
    133                              reinterpret_cast<const char*>(public_key.data()),
    134                              public_key.size()));
    135   }
    136 
    137   // Stores the current |policy_| and verifies that it is published.
    138   // If |new_public_key| is set then it will be persisted after storing but
    139   // before loading the policy, so that the signature validation can succeed.
    140   // If |previous_value| is set then a previously existing policy with that
    141   // value will be expected; otherwise no previous policy is expected.
    142   // If |new_value| is set then a new policy with that value is expected after
    143   // storing the |policy_| blob.
    144   void PerformStorePolicy(const std::vector<uint8>* new_public_key,
    145                           const char* previous_value,
    146                           const char* new_value) {
    147     chromeos::SessionManagerClient::StorePolicyCallback store_callback;
    148     EXPECT_CALL(session_manager_client_,
    149                 StorePolicyForUser(PolicyBuilder::kFakeUsername,
    150                                    policy_.GetBlob(), _, _))
    151         .WillOnce(SaveArg<3>(&store_callback));
    152     store_->Store(policy_.policy());
    153     RunUntilIdle();
    154     Mock::VerifyAndClearExpectations(&session_manager_client_);
    155     ASSERT_FALSE(store_callback.is_null());
    156 
    157     // The new policy shouldn't be present yet.
    158     PolicyMap previous_policy;
    159     EXPECT_EQ(previous_value != NULL, store_->policy() != NULL);
    160     if (previous_value) {
    161       previous_policy.Set(key::kHomepageLocation,
    162                           POLICY_LEVEL_MANDATORY,
    163                           POLICY_SCOPE_USER,
    164                           base::Value::CreateStringValue(previous_value), NULL);
    165     }
    166     EXPECT_TRUE(previous_policy.Equals(store_->policy_map()));
    167     EXPECT_EQ(CloudPolicyStore::STATUS_OK, store_->status());
    168 
    169     // Store the new public key so that the validation after the retrieve
    170     // operation completes can verify the signature.
    171     if (new_public_key)
    172       StoreUserPolicyKey(*new_public_key);
    173 
    174     // Let the store operation complete.
    175     chromeos::SessionManagerClient::RetrievePolicyCallback retrieve_callback;
    176     EXPECT_CALL(session_manager_client_,
    177                 RetrievePolicyForUser(PolicyBuilder::kFakeUsername, _))
    178         .WillOnce(SaveArg<1>(&retrieve_callback));
    179     store_callback.Run(true);
    180     RunUntilIdle();
    181     EXPECT_TRUE(previous_policy.Equals(store_->policy_map()));
    182     EXPECT_EQ(CloudPolicyStore::STATUS_OK, store_->status());
    183     Mock::VerifyAndClearExpectations(&session_manager_client_);
    184     ASSERT_FALSE(retrieve_callback.is_null());
    185 
    186     // Finish the retrieve callback.
    187     EXPECT_CALL(observer_, OnStoreLoaded(store_.get()));
    188     retrieve_callback.Run(policy_.GetBlob());
    189     RunUntilIdle();
    190     ASSERT_TRUE(store_->policy());
    191     EXPECT_EQ(policy_.policy_data().SerializeAsString(),
    192               store_->policy()->SerializeAsString());
    193     VerifyPolicyMap(new_value);
    194     EXPECT_EQ(CloudPolicyStore::STATUS_OK, store_->status());
    195   }
    196 
    197   void VerifyStoreHasValidationError() {
    198     EXPECT_FALSE(store_->policy());
    199     EXPECT_TRUE(store_->policy_map().empty());
    200     EXPECT_EQ(CloudPolicyStore::STATUS_VALIDATION_ERROR, store_->status());
    201   }
    202 
    203   void RunUntilIdle() {
    204     loop_.RunUntilIdle();
    205     content::BrowserThread::GetBlockingPool()->FlushForTesting();
    206     loop_.RunUntilIdle();
    207   }
    208 
    209   base::FilePath user_policy_dir() {
    210     return tmp_dir_.path().AppendASCII("var_run_user_policy");
    211   }
    212 
    213   base::FilePath user_policy_key_file() {
    214     return user_policy_dir().AppendASCII(kSanitizedUsername)
    215                             .AppendASCII("policy.pub");
    216   }
    217 
    218   base::FilePath token_file() {
    219     return tmp_dir_.path().AppendASCII("token");
    220   }
    221 
    222   base::FilePath policy_file() {
    223     return tmp_dir_.path().AppendASCII("policy");
    224   }
    225 
    226   base::MessageLoop loop_;
    227   chromeos::MockCryptohomeClient cryptohome_client_;
    228   chromeos::MockSessionManagerClient session_manager_client_;
    229   UserPolicyBuilder policy_;
    230   MockCloudPolicyStoreObserver observer_;
    231   scoped_ptr<UserCloudPolicyStoreChromeOS> store_;
    232 
    233  private:
    234   content::TestBrowserThread ui_thread_;
    235   content::TestBrowserThread file_thread_;
    236   base::ScopedTempDir tmp_dir_;
    237 
    238   DISALLOW_COPY_AND_ASSIGN(UserCloudPolicyStoreChromeOSTest);
    239 };
    240 
    241 TEST_F(UserCloudPolicyStoreChromeOSTest, InitialStore) {
    242   // Start without any public key to trigger the initial key checks.
    243   ASSERT_TRUE(base::DeleteFile(user_policy_key_file(), false));
    244   // Make the policy blob contain a new public key.
    245   policy_.SetDefaultNewSigningKey();
    246   policy_.Build();
    247   std::vector<uint8> new_public_key;
    248   ASSERT_TRUE(policy_.GetNewSigningKey()->ExportPublicKey(&new_public_key));
    249   ASSERT_NO_FATAL_FAILURE(
    250       PerformStorePolicy(&new_public_key, NULL, kDefaultHomepage));
    251 }
    252 
    253 TEST_F(UserCloudPolicyStoreChromeOSTest, StoreWithExistingKey) {
    254   ASSERT_NO_FATAL_FAILURE(
    255       PerformStorePolicy(NULL, NULL, kDefaultHomepage));
    256 }
    257 
    258 TEST_F(UserCloudPolicyStoreChromeOSTest, StoreWithRotation) {
    259   // Make the policy blob contain a new public key.
    260   policy_.SetDefaultNewSigningKey();
    261   policy_.Build();
    262   std::vector<uint8> new_public_key;
    263   ASSERT_TRUE(policy_.GetNewSigningKey()->ExportPublicKey(&new_public_key));
    264   ASSERT_NO_FATAL_FAILURE(
    265       PerformStorePolicy(&new_public_key, NULL, kDefaultHomepage));
    266 }
    267 
    268 TEST_F(UserCloudPolicyStoreChromeOSTest, StoreFail) {
    269   // Store policy.
    270   chromeos::SessionManagerClient::StorePolicyCallback store_callback;
    271   EXPECT_CALL(session_manager_client_,
    272               StorePolicyForUser(PolicyBuilder::kFakeUsername,
    273                                  policy_.GetBlob(), _, _))
    274       .WillOnce(SaveArg<3>(&store_callback));
    275   store_->Store(policy_.policy());
    276   RunUntilIdle();
    277   Mock::VerifyAndClearExpectations(&session_manager_client_);
    278   ASSERT_FALSE(store_callback.is_null());
    279 
    280   // Let the store operation complete.
    281   ExpectError(CloudPolicyStore::STATUS_STORE_ERROR);
    282   store_callback.Run(false);
    283   RunUntilIdle();
    284   EXPECT_FALSE(store_->policy());
    285   EXPECT_TRUE(store_->policy_map().empty());
    286   EXPECT_EQ(CloudPolicyStore::STATUS_STORE_ERROR, store_->status());
    287 }
    288 
    289 TEST_F(UserCloudPolicyStoreChromeOSTest, StoreValidationError) {
    290   policy_.policy_data().clear_policy_type();
    291   policy_.Build();
    292 
    293   // Store policy.
    294   chromeos::SessionManagerClient::StorePolicyCallback store_callback;
    295   ExpectError(CloudPolicyStore::STATUS_VALIDATION_ERROR);
    296   EXPECT_CALL(session_manager_client_,
    297               StorePolicyForUser(PolicyBuilder::kFakeUsername,
    298                                  policy_.GetBlob(), _, _))
    299       .Times(0);
    300   store_->Store(policy_.policy());
    301   RunUntilIdle();
    302   Mock::VerifyAndClearExpectations(&session_manager_client_);
    303 }
    304 
    305 TEST_F(UserCloudPolicyStoreChromeOSTest, StoreWithoutPolicyKey) {
    306   // Make the dbus call to cryptohome fail.
    307   Mock::VerifyAndClearExpectations(&cryptohome_client_);
    308   EXPECT_CALL(cryptohome_client_,
    309               GetSanitizedUsername(PolicyBuilder::kFakeUsername, _))
    310       .Times(AnyNumber())
    311       .WillRepeatedly(SendSanitizedUsername(chromeos::DBUS_METHOD_CALL_FAILURE,
    312                                             std::string()));
    313 
    314   // Store policy.
    315   chromeos::SessionManagerClient::StorePolicyCallback store_callback;
    316   ExpectError(CloudPolicyStore::STATUS_VALIDATION_ERROR);
    317   EXPECT_CALL(session_manager_client_,
    318               StorePolicyForUser(PolicyBuilder::kFakeUsername,
    319                                  policy_.GetBlob(), _, _))
    320       .Times(0);
    321   store_->Store(policy_.policy());
    322   RunUntilIdle();
    323   Mock::VerifyAndClearExpectations(&session_manager_client_);
    324 }
    325 
    326 TEST_F(UserCloudPolicyStoreChromeOSTest, StoreWithInvalidSignature) {
    327   // Break the signature.
    328   policy_.policy().mutable_policy_data_signature()->append("garbage");
    329 
    330   // Store policy.
    331   chromeos::SessionManagerClient::StorePolicyCallback store_callback;
    332   ExpectError(CloudPolicyStore::STATUS_VALIDATION_ERROR);
    333   EXPECT_CALL(session_manager_client_,
    334               StorePolicyForUser(PolicyBuilder::kFakeUsername,
    335                                  policy_.GetBlob(), _, _))
    336       .Times(0);
    337   store_->Store(policy_.policy());
    338   RunUntilIdle();
    339   Mock::VerifyAndClearExpectations(&session_manager_client_);
    340 }
    341 
    342 TEST_F(UserCloudPolicyStoreChromeOSTest, Load) {
    343   EXPECT_CALL(observer_, OnStoreLoaded(store_.get()));
    344   ASSERT_NO_FATAL_FAILURE(PerformPolicyLoad(policy_.GetBlob()));
    345   Mock::VerifyAndClearExpectations(&observer_);
    346 
    347   // Verify that the policy has been loaded.
    348   ASSERT_TRUE(store_->policy());
    349   EXPECT_EQ(policy_.policy_data().SerializeAsString(),
    350             store_->policy()->SerializeAsString());
    351   VerifyPolicyMap(kDefaultHomepage);
    352   EXPECT_EQ(CloudPolicyStore::STATUS_OK, store_->status());
    353 }
    354 
    355 TEST_F(UserCloudPolicyStoreChromeOSTest, LoadNoPolicy) {
    356   EXPECT_CALL(observer_, OnStoreLoaded(store_.get()));
    357   ASSERT_NO_FATAL_FAILURE(PerformPolicyLoad(""));
    358   Mock::VerifyAndClearExpectations(&observer_);
    359 
    360   // Verify no policy has been installed.
    361   EXPECT_FALSE(store_->policy());
    362   EXPECT_TRUE(store_->policy_map().empty());
    363   EXPECT_EQ(CloudPolicyStore::STATUS_OK, store_->status());
    364 }
    365 
    366 TEST_F(UserCloudPolicyStoreChromeOSTest, LoadInvalidPolicy) {
    367   ExpectError(CloudPolicyStore::STATUS_PARSE_ERROR);
    368   ASSERT_NO_FATAL_FAILURE(PerformPolicyLoad("invalid"));
    369 
    370   // Verify no policy has been installed.
    371   EXPECT_FALSE(store_->policy());
    372   EXPECT_TRUE(store_->policy_map().empty());
    373   EXPECT_EQ(CloudPolicyStore::STATUS_PARSE_ERROR, store_->status());
    374 }
    375 
    376 TEST_F(UserCloudPolicyStoreChromeOSTest, LoadValidationError) {
    377   policy_.policy_data().clear_policy_type();
    378   policy_.Build();
    379 
    380   ExpectError(CloudPolicyStore::STATUS_VALIDATION_ERROR);
    381   ASSERT_NO_FATAL_FAILURE(PerformPolicyLoad(policy_.GetBlob()));
    382   VerifyStoreHasValidationError();
    383 }
    384 
    385 TEST_F(UserCloudPolicyStoreChromeOSTest, LoadNoKey) {
    386   // The loaded policy can't be verified without the public key.
    387   ASSERT_TRUE(base::DeleteFile(user_policy_key_file(), false));
    388   ExpectError(CloudPolicyStore::STATUS_VALIDATION_ERROR);
    389   ASSERT_NO_FATAL_FAILURE(PerformPolicyLoad(policy_.GetBlob()));
    390   VerifyStoreHasValidationError();
    391 }
    392 
    393 TEST_F(UserCloudPolicyStoreChromeOSTest, LoadInvalidSignature) {
    394   // Break the signature.
    395   policy_.policy().mutable_policy_data_signature()->append("garbage");
    396   ExpectError(CloudPolicyStore::STATUS_VALIDATION_ERROR);
    397   ASSERT_NO_FATAL_FAILURE(PerformPolicyLoad(policy_.GetBlob()));
    398   VerifyStoreHasValidationError();
    399 }
    400 
    401 TEST_F(UserCloudPolicyStoreChromeOSTest, MigrationFull) {
    402   std::string data;
    403 
    404   em::DeviceCredentials credentials;
    405   credentials.set_device_token(kLegacyToken);
    406   credentials.set_device_id(kLegacyDeviceId);
    407   ASSERT_TRUE(credentials.SerializeToString(&data));
    408   ASSERT_NE(-1, file_util::WriteFile(token_file(), data.c_str(), data.size()));
    409 
    410   em::CachedCloudPolicyResponse cached_policy;
    411   cached_policy.mutable_cloud_policy()->CopyFrom(policy_.policy());
    412   ASSERT_TRUE(cached_policy.SerializeToString(&data));
    413   ASSERT_NE(-1, file_util::WriteFile(policy_file(), data.c_str(), data.size()));
    414 
    415   EXPECT_CALL(observer_, OnStoreLoaded(store_.get()));
    416   ASSERT_NO_FATAL_FAILURE(PerformPolicyLoad(""));
    417   Mock::VerifyAndClearExpectations(&observer_);
    418 
    419   // Verify that legacy user policy and token have been loaded.
    420   em::PolicyData expected_policy_data;
    421   EXPECT_TRUE(expected_policy_data.ParseFromString(
    422                   cached_policy.cloud_policy().policy_data()));
    423   expected_policy_data.clear_public_key_version();
    424   expected_policy_data.set_request_token(kLegacyToken);
    425   expected_policy_data.set_device_id(kLegacyDeviceId);
    426   ASSERT_TRUE(store_->policy());
    427   EXPECT_EQ(expected_policy_data.SerializeAsString(),
    428             store_->policy()->SerializeAsString());
    429   VerifyPolicyMap(kDefaultHomepage);
    430   EXPECT_EQ(CloudPolicyStore::STATUS_OK, store_->status());
    431 }
    432 
    433 TEST_F(UserCloudPolicyStoreChromeOSTest, MigrationNoToken) {
    434   std::string data;
    435   testing::Sequence seq;
    436 
    437   em::CachedCloudPolicyResponse cached_policy;
    438   cached_policy.mutable_cloud_policy()->CopyFrom(policy_.policy());
    439   ASSERT_TRUE(cached_policy.SerializeToString(&data));
    440   ASSERT_NE(-1, file_util::WriteFile(policy_file(), data.c_str(), data.size()));
    441 
    442   EXPECT_CALL(observer_, OnStoreLoaded(store_.get()));
    443   ASSERT_NO_FATAL_FAILURE(PerformPolicyLoad(""));
    444   Mock::VerifyAndClearExpectations(&observer_);
    445 
    446   // Verify the legacy cache has been loaded.
    447   em::PolicyData expected_policy_data;
    448   EXPECT_TRUE(expected_policy_data.ParseFromString(
    449                   cached_policy.cloud_policy().policy_data()));
    450   expected_policy_data.clear_public_key_version();
    451   ASSERT_TRUE(store_->policy());
    452   EXPECT_EQ(expected_policy_data.SerializeAsString(),
    453             store_->policy()->SerializeAsString());
    454   VerifyPolicyMap(kDefaultHomepage);
    455   EXPECT_EQ(CloudPolicyStore::STATUS_OK, store_->status());
    456 }
    457 
    458 TEST_F(UserCloudPolicyStoreChromeOSTest, MigrationNoPolicy) {
    459   std::string data;
    460 
    461   em::DeviceCredentials credentials;
    462   credentials.set_device_token(kLegacyToken);
    463   credentials.set_device_id(kLegacyDeviceId);
    464   ASSERT_TRUE(credentials.SerializeToString(&data));
    465   ASSERT_NE(-1, file_util::WriteFile(token_file(), data.c_str(), data.size()));
    466 
    467   EXPECT_CALL(observer_, OnStoreLoaded(store_.get()));
    468   ASSERT_NO_FATAL_FAILURE(PerformPolicyLoad(""));
    469   Mock::VerifyAndClearExpectations(&observer_);
    470 
    471   // Verify that legacy user policy and token have been loaded.
    472   em::PolicyData expected_policy_data;
    473   expected_policy_data.set_request_token(kLegacyToken);
    474   expected_policy_data.set_device_id(kLegacyDeviceId);
    475   ASSERT_TRUE(store_->policy());
    476   EXPECT_EQ(expected_policy_data.SerializeAsString(),
    477             store_->policy()->SerializeAsString());
    478   EXPECT_TRUE(store_->policy_map().empty());
    479   EXPECT_EQ(CloudPolicyStore::STATUS_OK, store_->status());
    480 }
    481 
    482 TEST_F(UserCloudPolicyStoreChromeOSTest, MigrationAndStoreNew) {
    483   // Start without an existing public key.
    484   ASSERT_TRUE(base::DeleteFile(user_policy_key_file(), false));
    485 
    486   std::string data;
    487   em::CachedCloudPolicyResponse cached_policy;
    488   cached_policy.mutable_cloud_policy()->CopyFrom(policy_.policy());
    489   ASSERT_TRUE(cached_policy.SerializeToString(&data));
    490   ASSERT_NE(-1, file_util::WriteFile(policy_file(), data.c_str(), data.size()));
    491 
    492   EXPECT_CALL(observer_, OnStoreLoaded(store_.get()));
    493   ASSERT_NO_FATAL_FAILURE(PerformPolicyLoad(""));
    494   Mock::VerifyAndClearExpectations(&observer_);
    495 
    496   // Verify the legacy cache has been loaded.
    497   em::PolicyData expected_policy_data;
    498   EXPECT_TRUE(expected_policy_data.ParseFromString(
    499                   cached_policy.cloud_policy().policy_data()));
    500   expected_policy_data.clear_public_key_version();
    501   ASSERT_TRUE(store_->policy());
    502   EXPECT_EQ(expected_policy_data.SerializeAsString(),
    503             store_->policy()->SerializeAsString());
    504   VerifyPolicyMap(kDefaultHomepage);
    505   EXPECT_EQ(CloudPolicyStore::STATUS_OK, store_->status());
    506   EXPECT_TRUE(base::PathExists(policy_file()));
    507 
    508   // Now store a new policy using the new homepage location.
    509   const char kNewHomepage[] = "http://google.com";
    510   policy_.payload().mutable_homepagelocation()->set_value(kNewHomepage);
    511   policy_.SetDefaultNewSigningKey();
    512   policy_.Build();
    513   std::vector<uint8> new_public_key;
    514   ASSERT_TRUE(policy_.GetNewSigningKey()->ExportPublicKey(&new_public_key));
    515   ASSERT_NO_FATAL_FAILURE(
    516       PerformStorePolicy(&new_public_key, kDefaultHomepage, kNewHomepage));
    517   VerifyPolicyMap(kNewHomepage);
    518 
    519   // Verify that the legacy cache has been removed.
    520   EXPECT_FALSE(base::PathExists(policy_file()));
    521 }
    522 
    523 TEST_F(UserCloudPolicyStoreChromeOSTest, LoadImmediately) {
    524   EXPECT_CALL(observer_, OnStoreLoaded(store_.get()));
    525   EXPECT_CALL(session_manager_client_,
    526               BlockingRetrievePolicyForUser(PolicyBuilder::kFakeUsername))
    527       .WillOnce(Return(policy_.GetBlob()));
    528   EXPECT_CALL(cryptohome_client_,
    529               BlockingGetSanitizedUsername(PolicyBuilder::kFakeUsername))
    530       .WillOnce(Return(kSanitizedUsername));
    531 
    532   EXPECT_FALSE(store_->policy());
    533   store_->LoadImmediately();
    534   // Note: verify that the |observer_| got notified synchronously, without
    535   // having to spin the current loop. TearDown() will flush the loop so this
    536   // must be done within the test.
    537   Mock::VerifyAndClearExpectations(&observer_);
    538   Mock::VerifyAndClearExpectations(&session_manager_client_);
    539   Mock::VerifyAndClearExpectations(&cryptohome_client_);
    540 
    541   // The policy should become available without having to spin any loops.
    542   ASSERT_TRUE(store_->policy());
    543   EXPECT_EQ(policy_.policy_data().SerializeAsString(),
    544             store_->policy()->SerializeAsString());
    545   VerifyPolicyMap(kDefaultHomepage);
    546   EXPECT_EQ(CloudPolicyStore::STATUS_OK, store_->status());
    547 }
    548 
    549 TEST_F(UserCloudPolicyStoreChromeOSTest, LoadImmediatelyNoPolicy) {
    550   EXPECT_CALL(observer_, OnStoreLoaded(store_.get()));
    551   EXPECT_CALL(session_manager_client_,
    552               BlockingRetrievePolicyForUser(PolicyBuilder::kFakeUsername))
    553       .WillOnce(Return(""));
    554 
    555   EXPECT_FALSE(store_->policy());
    556   store_->LoadImmediately();
    557   Mock::VerifyAndClearExpectations(&observer_);
    558   Mock::VerifyAndClearExpectations(&session_manager_client_);
    559 
    560   EXPECT_FALSE(store_->policy());
    561   EXPECT_TRUE(store_->policy_map().empty());
    562   EXPECT_EQ(CloudPolicyStore::STATUS_OK, store_->status());
    563 }
    564 
    565 TEST_F(UserCloudPolicyStoreChromeOSTest, LoadImmediatelyInvalidBlob) {
    566   EXPECT_CALL(observer_, OnStoreError(store_.get()));
    567   EXPECT_CALL(session_manager_client_,
    568               BlockingRetrievePolicyForUser(PolicyBuilder::kFakeUsername))
    569       .WillOnce(Return("le blob"));
    570 
    571   EXPECT_FALSE(store_->policy());
    572   store_->LoadImmediately();
    573   Mock::VerifyAndClearExpectations(&observer_);
    574   Mock::VerifyAndClearExpectations(&session_manager_client_);
    575 
    576   EXPECT_FALSE(store_->policy());
    577   EXPECT_TRUE(store_->policy_map().empty());
    578   EXPECT_EQ(CloudPolicyStore::STATUS_PARSE_ERROR, store_->status());
    579 }
    580 
    581 TEST_F(UserCloudPolicyStoreChromeOSTest, LoadImmediatelyDBusFailure) {
    582   EXPECT_CALL(observer_, OnStoreError(store_.get()));
    583   EXPECT_CALL(session_manager_client_,
    584               BlockingRetrievePolicyForUser(PolicyBuilder::kFakeUsername))
    585       .WillOnce(Return(policy_.GetBlob()));
    586   EXPECT_CALL(cryptohome_client_,
    587               BlockingGetSanitizedUsername(PolicyBuilder::kFakeUsername))
    588       .WillOnce(Return(""));
    589 
    590   EXPECT_FALSE(store_->policy());
    591   store_->LoadImmediately();
    592   Mock::VerifyAndClearExpectations(&observer_);
    593   Mock::VerifyAndClearExpectations(&session_manager_client_);
    594   Mock::VerifyAndClearExpectations(&cryptohome_client_);
    595 
    596   EXPECT_FALSE(store_->policy());
    597   EXPECT_TRUE(store_->policy_map().empty());
    598   EXPECT_EQ(CloudPolicyStore::STATUS_LOAD_ERROR, store_->status());
    599 }
    600 
    601 TEST_F(UserCloudPolicyStoreChromeOSTest, LoadImmediatelyNoUserPolicyKey) {
    602   EXPECT_CALL(observer_, OnStoreError(store_.get()));
    603   EXPECT_CALL(session_manager_client_,
    604               BlockingRetrievePolicyForUser(PolicyBuilder::kFakeUsername))
    605       .WillOnce(Return(policy_.GetBlob()));
    606   EXPECT_CALL(cryptohome_client_,
    607               BlockingGetSanitizedUsername(PolicyBuilder::kFakeUsername))
    608       .WillOnce(Return("wrong"));
    609 
    610   EXPECT_FALSE(store_->policy());
    611   store_->LoadImmediately();
    612   Mock::VerifyAndClearExpectations(&observer_);
    613   Mock::VerifyAndClearExpectations(&session_manager_client_);
    614   Mock::VerifyAndClearExpectations(&cryptohome_client_);
    615 
    616   EXPECT_FALSE(store_->policy());
    617   EXPECT_TRUE(store_->policy_map().empty());
    618   EXPECT_EQ(CloudPolicyStore::STATUS_VALIDATION_ERROR, store_->status());
    619 }
    620 
    621 }  // namespace
    622 
    623 }  // namespace policy
    624