1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/browser/chromeos/policy/cloud_external_data_store.h"
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 "base/test/test_simple_task_runner.h"
12 #include "components/policy/core/common/cloud/resource_cache.h"
13 #include "testing/gtest/include/gtest/gtest.h"
19 const char kKey1
[] = "Key 1";
20 const char kKey2
[] = "Key 2";
21 const char kPolicy1
[] = "Test policy 1";
22 const char kPolicy2
[] = "Test policy 2";
23 const char kData1
[] = "Testing data 1";
24 const char kData2
[] = "Testing data 2";
25 const char kURL
[] = "http://localhost";
26 const size_t kMaxSize
= 100;
30 class CouldExternalDataStoreTest
: public testing::Test
{
32 CouldExternalDataStoreTest();
34 virtual void SetUp() OVERRIDE
;
37 const std::string kData1Hash
;
38 const std::string kData2Hash
;
40 scoped_refptr
<base::TestSimpleTaskRunner
> task_runner_
;
41 base::ScopedTempDir temp_dir_
;
42 scoped_ptr
<ResourceCache
> resource_cache_
;
44 DISALLOW_COPY_AND_ASSIGN(CouldExternalDataStoreTest
);
47 CouldExternalDataStoreTest::CouldExternalDataStoreTest()
48 : kData1Hash(base::SHA1HashString(kData1
)),
49 kData2Hash(base::SHA1HashString(kData2
)),
50 task_runner_(new base::TestSimpleTaskRunner
) {
53 void CouldExternalDataStoreTest::SetUp() {
54 ASSERT_TRUE(temp_dir_
.CreateUniqueTempDir());
55 resource_cache_
.reset(new ResourceCache(temp_dir_
.path(), task_runner_
));
58 TEST_F(CouldExternalDataStoreTest
, StoreAndLoad
) {
59 // Write an entry to a store.
60 CloudExternalDataStore
store(kKey1
, task_runner_
, resource_cache_
.get());
61 EXPECT_TRUE(store
.Store(kPolicy1
, kData1Hash
, kData1
));
63 // Check that loading and verifying the entry against an invalid hash fails.
65 EXPECT_FALSE(store
.Load(kPolicy1
, kData2Hash
, kMaxSize
, &data
));
67 // Check that loading and verifying the entry against its hash succeeds.
68 EXPECT_TRUE(store
.Load(kPolicy1
, kData1Hash
, kMaxSize
, &data
));
69 EXPECT_EQ(kData1
, data
);
72 TEST_F(CouldExternalDataStoreTest
, StoreTooLargeAndLoad
) {
73 // Write an entry to a store.
74 CloudExternalDataStore
store(kKey1
, task_runner_
, resource_cache_
.get());
75 EXPECT_TRUE(store
.Store(kPolicy1
, kData1Hash
, kData2
));
77 // Check that the entry has been written to the resource cache backing the
79 std::map
<std::string
, std::string
> contents
;
80 resource_cache_
->LoadAllSubkeys(kKey1
, &contents
);
81 ASSERT_EQ(1u, contents
.size());
82 EXPECT_EQ(kData2
, contents
.begin()->second
);
84 // Check that loading the entry fails when the maximum allowed data size is
85 // smaller than the entry size.
87 EXPECT_FALSE(store
.Load(kPolicy1
, kData1Hash
, 1, &data
));
89 // Verify that the oversized entry has been detected and removed from the
91 resource_cache_
->LoadAllSubkeys(kKey1
, &contents
);
92 EXPECT_TRUE(contents
.empty());
95 TEST_F(CouldExternalDataStoreTest
, StoreInvalidAndLoad
) {
96 // Construct a store entry whose hash and contents do not match.
97 CloudExternalDataStore
store(kKey1
, task_runner_
, resource_cache_
.get());
98 EXPECT_TRUE(store
.Store(kPolicy1
, kData1Hash
, kData2
));
100 // Check that the entry has been written to the resource cache backing the
102 std::map
<std::string
, std::string
> contents
;
103 resource_cache_
->LoadAllSubkeys(kKey1
, &contents
);
104 ASSERT_EQ(1u, contents
.size());
105 EXPECT_EQ(kData2
, contents
.begin()->second
);
107 // Check that loading and verifying the entry against its hash fails.
109 EXPECT_FALSE(store
.Load(kPolicy1
, kData1Hash
, kMaxSize
, &data
));
111 // Verify that the corrupted entry has been detected and removed from the
113 resource_cache_
->LoadAllSubkeys(kKey1
, &contents
);
114 EXPECT_TRUE(contents
.empty());
117 TEST_F(CouldExternalDataStoreTest
, Prune
) {
118 // Write two entries to a store.
119 CloudExternalDataStore
store(kKey1
, task_runner_
, resource_cache_
.get());
120 EXPECT_TRUE(store
.Store(kPolicy1
, kData1Hash
, kData1
));
121 EXPECT_TRUE(store
.Store(kPolicy2
, kData2Hash
, kData2
));
123 // Check that loading and verifying the entries against their hashes succeeds.
125 EXPECT_TRUE(store
.Load(kPolicy1
, kData1Hash
, kMaxSize
, &data
));
126 EXPECT_EQ(kData1
, data
);
127 EXPECT_TRUE(store
.Load(kPolicy2
, kData2Hash
, kMaxSize
, &data
));
128 EXPECT_EQ(kData2
, data
);
130 // Prune the store, allowing only an entry for the first policy with its
131 // current hash to be kept.
132 CloudExternalDataManager::Metadata metadata
;
134 CloudExternalDataManager::MetadataEntry(kURL
, kData1Hash
);
135 store
.Prune(metadata
);
137 // Check that the entry for the second policy has been removed from the
138 // resource cache backing the store.
139 std::map
<std::string
, std::string
> contents
;
140 resource_cache_
->LoadAllSubkeys(kKey1
, &contents
);
141 ASSERT_EQ(1u, contents
.size());
142 EXPECT_EQ(kData1
, contents
.begin()->second
);
144 // Prune the store, allowing only an entry for the first policy with a
145 // different hash to be kept.
147 CloudExternalDataManager::MetadataEntry(kURL
, kData2Hash
);
148 store
.Prune(metadata
);
150 // Check that the entry for the first policy has been removed from the
152 resource_cache_
->LoadAllSubkeys(kKey1
, &contents
);
153 EXPECT_TRUE(contents
.empty());
156 TEST_F(CouldExternalDataStoreTest
, SharedCache
) {
157 // Write entries to two stores for two different cache_keys sharing a cache.
158 CloudExternalDataStore
store1(kKey1
, task_runner_
, resource_cache_
.get());
159 EXPECT_TRUE(store1
.Store(kPolicy1
, kData1Hash
, kData1
));
160 CloudExternalDataStore
store2(kKey2
, task_runner_
, resource_cache_
.get());
161 EXPECT_TRUE(store2
.Store(kPolicy2
, kData2Hash
, kData2
));
163 // Check that the entries have been assigned to the correct keys in the
164 // resource cache backing the stores.
165 std::map
<std::string
, std::string
> contents
;
166 resource_cache_
->LoadAllSubkeys(kKey1
, &contents
);
167 ASSERT_EQ(1u, contents
.size());
168 EXPECT_EQ(kData1
, contents
.begin()->second
);
169 resource_cache_
->LoadAllSubkeys(kKey2
, &contents
);
170 ASSERT_EQ(1u, contents
.size());
171 EXPECT_EQ(kData2
, contents
.begin()->second
);
173 // Check that each entry can be loaded from the correct store.
175 EXPECT_TRUE(store1
.Load(kPolicy1
, kData1Hash
, kMaxSize
, &data
));
176 EXPECT_EQ(kData1
, data
);
177 EXPECT_FALSE(store1
.Load(kPolicy2
, kData2Hash
, kMaxSize
, &data
));
179 EXPECT_FALSE(store2
.Load(kPolicy1
, kData1Hash
, kMaxSize
, &data
));
180 EXPECT_TRUE(store2
.Load(kPolicy2
, kData2Hash
, kMaxSize
, &data
));
181 EXPECT_EQ(kData2
, data
);
183 // Prune the first store, allowing no entries to be kept.
184 CloudExternalDataManager::Metadata metadata
;
185 store1
.Prune(metadata
);
187 // Check that the part of the resource cache backing the first store is empty.
188 resource_cache_
->LoadAllSubkeys(kKey1
, &contents
);
189 EXPECT_TRUE(contents
.empty());
191 // Check that the part of the resource cache backing the second store is
193 resource_cache_
->LoadAllSubkeys(kKey2
, &contents
);
194 ASSERT_EQ(1u, contents
.size());
195 EXPECT_EQ(kData2
, contents
.begin()->second
);
198 } // namespace policy