Home | History | Annotate | Download | only in cloud
      1 // Copyright 2013 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "chrome/browser/policy/cloud/cloud_external_data_store.h"
      6 
      7 #include "base/compiler_specific.h"
      8 #include "base/files/scoped_temp_dir.h"
      9 #include "base/memory/scoped_ptr.h"
     10 #include "base/sha1.h"
     11 #include "chrome/browser/policy/cloud/resource_cache.h"
     12 #include "testing/gtest/include/gtest/gtest.h"
     13 
     14 namespace policy {
     15 
     16 namespace {
     17 
     18 const char kKey1[] = "Key 1";
     19 const char kKey2[] = "Key 2";
     20 const char kPolicy1[] = "Test policy 1";
     21 const char kPolicy2[] = "Test policy 2";
     22 const char kData1[] = "Testing data 1";
     23 const char kData2[] = "Testing data 2";
     24 const char kURL[] = "http://localhost";
     25 const size_t kMaxSize = 100;
     26 
     27 }  // namespace
     28 
     29 class CouldExternalDataStoreTest : public testing::Test {
     30  public:
     31   CouldExternalDataStoreTest();
     32 
     33   virtual void SetUp() OVERRIDE;
     34 
     35  protected:
     36   const std::string kData1Hash;
     37   const std::string kData2Hash;
     38 
     39   base::ScopedTempDir temp_dir_;
     40   scoped_ptr<ResourceCache> resource_cache_;
     41 
     42   DISALLOW_COPY_AND_ASSIGN(CouldExternalDataStoreTest);
     43 };
     44 
     45 CouldExternalDataStoreTest::CouldExternalDataStoreTest()
     46     : kData1Hash(base::SHA1HashString(kData1)),
     47       kData2Hash(base::SHA1HashString(kData2)) {
     48 }
     49 
     50 void CouldExternalDataStoreTest::SetUp() {
     51   ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
     52   resource_cache_.reset(new ResourceCache(temp_dir_.path()));
     53 }
     54 
     55 TEST_F(CouldExternalDataStoreTest, StoreAndLoad) {
     56   // Write an entry to a store.
     57   CloudExternalDataStore store(kKey1, resource_cache_.get());
     58   EXPECT_TRUE(store.Store(kPolicy1, kData1Hash, kData1));
     59 
     60   // Check that loading and verifying the entry against an invalid hash fails.
     61   std::string data;
     62   EXPECT_FALSE(store.Load(kPolicy1, kData2Hash, kMaxSize, &data));
     63 
     64   // Check that loading and verifying the entry against its hash succeeds.
     65   EXPECT_TRUE(store.Load(kPolicy1, kData1Hash, kMaxSize, &data));
     66   EXPECT_EQ(kData1, data);
     67 }
     68 
     69 TEST_F(CouldExternalDataStoreTest, StoreTooLargeAndLoad) {
     70   // Write an entry to a store.
     71   CloudExternalDataStore store(kKey1, resource_cache_.get());
     72   EXPECT_TRUE(store.Store(kPolicy1, kData1Hash, kData2));
     73 
     74   // Check that the entry has been written to the resource cache backing the
     75   // store.
     76   std::map<std::string, std::string> contents;
     77   resource_cache_->LoadAllSubkeys(kKey1, &contents);
     78   ASSERT_EQ(1u, contents.size());
     79   EXPECT_EQ(kData2, contents.begin()->second);
     80 
     81   // Check that loading the entry fails when the maximum allowed data size is
     82   // smaller than the entry size.
     83   std::string data;
     84   EXPECT_FALSE(store.Load(kPolicy1, kData1Hash, 1, &data));
     85 
     86   // Verify that the oversized entry has been detected and removed from the
     87   // resource cache.
     88   resource_cache_->LoadAllSubkeys(kKey1, &contents);
     89   EXPECT_TRUE(contents.empty());
     90 }
     91 
     92 TEST_F(CouldExternalDataStoreTest, StoreInvalidAndLoad) {
     93   // Construct a store entry whose hash and contents do not match.
     94   CloudExternalDataStore store(kKey1, resource_cache_.get());
     95   EXPECT_TRUE(store.Store(kPolicy1, kData1Hash, kData2));
     96 
     97   // Check that the entry has been written to the resource cache backing the
     98   // store.
     99   std::map<std::string, std::string> contents;
    100   resource_cache_->LoadAllSubkeys(kKey1, &contents);
    101   ASSERT_EQ(1u, contents.size());
    102   EXPECT_EQ(kData2, contents.begin()->second);
    103 
    104   // Check that loading and verifying the entry against its hash fails.
    105   std::string data;
    106   EXPECT_FALSE(store.Load(kPolicy1, kData1Hash, kMaxSize, &data));
    107 
    108   // Verify that the corrupted entry has been detected and removed from the
    109   // resource cache.
    110   resource_cache_->LoadAllSubkeys(kKey1, &contents);
    111   EXPECT_TRUE(contents.empty());
    112 }
    113 
    114 TEST_F(CouldExternalDataStoreTest, Prune) {
    115   // Write two entries to a store.
    116   CloudExternalDataStore store(kKey1, resource_cache_.get());
    117   EXPECT_TRUE(store.Store(kPolicy1, kData1Hash, kData1));
    118   EXPECT_TRUE(store.Store(kPolicy2, kData2Hash, kData2));
    119 
    120   // Check that loading and verifying the entries against their hashes succeeds.
    121   std::string data;
    122   EXPECT_TRUE(store.Load(kPolicy1, kData1Hash, kMaxSize, &data));
    123   EXPECT_EQ(kData1, data);
    124   EXPECT_TRUE(store.Load(kPolicy2, kData2Hash, kMaxSize, &data));
    125   EXPECT_EQ(kData2, data);
    126 
    127   // Prune the store, allowing only an entry for the first policy with its
    128   // current hash to be kept.
    129   CloudExternalDataManager::Metadata metadata;
    130   metadata[kPolicy1] =
    131       CloudExternalDataManager::MetadataEntry(kURL, kData1Hash);
    132   store.Prune(metadata);
    133 
    134   // Check that the entry for the second policy has been removed from the
    135   // resource cache backing the store.
    136   std::map<std::string, std::string> contents;
    137   resource_cache_->LoadAllSubkeys(kKey1, &contents);
    138   ASSERT_EQ(1u, contents.size());
    139   EXPECT_EQ(kData1, contents.begin()->second);
    140 
    141   // Prune the store, allowing only an entry for the first policy with a
    142   // different hash to be kept.
    143   metadata[kPolicy1] =
    144       CloudExternalDataManager::MetadataEntry(kURL, kData2Hash);
    145   store.Prune(metadata);
    146 
    147   // Check that the entry for the first policy has been removed from the
    148   // resource cache.
    149   resource_cache_->LoadAllSubkeys(kKey1, &contents);
    150   EXPECT_TRUE(contents.empty());
    151 }
    152 
    153 TEST_F(CouldExternalDataStoreTest, SharedCache) {
    154   // Write entries to two stores for two different cache_keys sharing a cache.
    155   CloudExternalDataStore store1(kKey1, resource_cache_.get());
    156   EXPECT_TRUE(store1.Store(kPolicy1, kData1Hash, kData1));
    157   CloudExternalDataStore store2(kKey2, resource_cache_.get());
    158   EXPECT_TRUE(store2.Store(kPolicy2, kData2Hash, kData2));
    159 
    160   // Check that the entries have been assigned to the correct keys in the
    161   // resource cache backing the stores.
    162   std::map<std::string, std::string> contents;
    163   resource_cache_->LoadAllSubkeys(kKey1, &contents);
    164   ASSERT_EQ(1u, contents.size());
    165   EXPECT_EQ(kData1, contents.begin()->second);
    166   resource_cache_->LoadAllSubkeys(kKey2, &contents);
    167   ASSERT_EQ(1u, contents.size());
    168   EXPECT_EQ(kData2, contents.begin()->second);
    169 
    170   // Check that each entry can be loaded from the correct store.
    171   std::string data;
    172   EXPECT_TRUE(store1.Load(kPolicy1, kData1Hash, kMaxSize, &data));
    173   EXPECT_EQ(kData1, data);
    174   EXPECT_FALSE(store1.Load(kPolicy2, kData2Hash, kMaxSize, &data));
    175 
    176   EXPECT_FALSE(store2.Load(kPolicy1, kData1Hash, kMaxSize, &data));
    177   EXPECT_TRUE(store2.Load(kPolicy2, kData2Hash, kMaxSize, &data));
    178   EXPECT_EQ(kData2, data);
    179 
    180   // Prune the first store, allowing no entries to be kept.
    181   CloudExternalDataManager::Metadata metadata;
    182   store1.Prune(metadata);
    183 
    184   // Check that the part of the resource cache backing the first store is empty.
    185   resource_cache_->LoadAllSubkeys(kKey1, &contents);
    186   EXPECT_TRUE(contents.empty());
    187 
    188   // Check that the part of the resource cache backing the second store is
    189   // unaffected.
    190   resource_cache_->LoadAllSubkeys(kKey2, &contents);
    191   ASSERT_EQ(1u, contents.size());
    192   EXPECT_EQ(kData2, contents.begin()->second);
    193 }
    194 
    195 }  // namespace policy
    196