blob: 33a77f6cd99c137f756653bdd714c28bf59dfddf [file] [log] [blame]
Thieu Le3426c8f2012-01-11 17:35:11 -08001// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
Chris Masoneb925cc82011-06-22 15:39:57 -07002// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "shill/property_store_unittest.h"
6
7#include <map>
8#include <string>
Chris Masone889666b2011-07-03 12:58:50 -07009#include <utility>
Chris Masoneb925cc82011-06-22 15:39:57 -070010#include <vector>
11
mukesh agrawal4d260da2012-01-30 11:53:52 -080012#include <base/basictypes.h>
Chris Masoneb925cc82011-06-22 15:39:57 -070013#include <dbus-c++/dbus.h>
14#include <gtest/gtest.h>
15#include <gmock/gmock.h>
16
17#include "shill/dbus_adaptor.h"
18#include "shill/error.h"
Paul Stewart26b327e2011-10-19 11:38:09 -070019#include "shill/event_dispatcher.h"
Chris Masoneb925cc82011-06-22 15:39:57 -070020#include "shill/manager.h"
21#include "shill/mock_control.h"
mukesh agrawal4d260da2012-01-30 11:53:52 -080022#include "shill/property_accessor.h"
Chris Masoneb925cc82011-06-22 15:39:57 -070023#include "shill/property_store.h"
Chris Masoneb925cc82011-06-22 15:39:57 -070024
Chris Masoneb925cc82011-06-22 15:39:57 -070025using std::map;
Chris Masone889666b2011-07-03 12:58:50 -070026using std::string;
Chris Masoneb925cc82011-06-22 15:39:57 -070027using std::vector;
Chris Masone8a56ad62011-07-02 15:27:57 -070028using ::testing::Values;
Chris Masoneb925cc82011-06-22 15:39:57 -070029
30namespace shill {
31
32// static
33const ::DBus::Variant PropertyStoreTest::kBoolV = DBusAdaptor::BoolToVariant(0);
34// static
35const ::DBus::Variant PropertyStoreTest::kByteV = DBusAdaptor::ByteToVariant(0);
36// static
37const ::DBus::Variant PropertyStoreTest::kInt16V =
38 DBusAdaptor::Int16ToVariant(0);
39// static
40const ::DBus::Variant PropertyStoreTest::kInt32V =
41 DBusAdaptor::Int32ToVariant(0);
42// static
Darin Petkov63138a92012-02-06 14:09:15 +010043const ::DBus::Variant PropertyStoreTest::kKeyValueStoreV =
44 DBusAdaptor::KeyValueStoreToVariant(KeyValueStore());
45// static
Chris Masoneb925cc82011-06-22 15:39:57 -070046const ::DBus::Variant PropertyStoreTest::kStringV =
47 DBusAdaptor::StringToVariant("");
48// static
49const ::DBus::Variant PropertyStoreTest::kStringmapV =
Chris Masonea8a2c252011-06-27 22:16:30 -070050 DBusAdaptor::StringmapToVariant(Stringmap());
Chris Masoneb925cc82011-06-22 15:39:57 -070051// static
52const ::DBus::Variant PropertyStoreTest::kStringmapsV =
Chris Masone889666b2011-07-03 12:58:50 -070053 DBusAdaptor::StringmapsToVariant(Stringmaps());
Chris Masoneb925cc82011-06-22 15:39:57 -070054// static
55const ::DBus::Variant PropertyStoreTest::kStringsV =
Chris Masonea8a2c252011-06-27 22:16:30 -070056 DBusAdaptor::StringsToVariant(Strings(1, ""));
Chris Masoneb925cc82011-06-22 15:39:57 -070057// static
58const ::DBus::Variant PropertyStoreTest::kUint16V =
59 DBusAdaptor::Uint16ToVariant(0);
60// static
61const ::DBus::Variant PropertyStoreTest::kUint32V =
62 DBusAdaptor::Uint32ToVariant(0);
63
64PropertyStoreTest::PropertyStoreTest()
mukesh agrawalffa3d042011-10-06 15:26:10 -070065 : internal_error_(Error::GetName(Error::kInternalError)),
66 invalid_args_(Error::GetName(Error::kInvalidArguments)),
Chris Masone9d779932011-08-25 16:33:41 -070067 invalid_prop_(Error::GetName(Error::kInvalidProperty)),
68 path_(dir_.CreateUniqueTempDir() ? dir_.path().value() : ""),
Chris Masone2176a882011-09-14 22:29:15 -070069 manager_(control_interface(),
70 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -080071 metrics(),
Chris Masone2176a882011-09-14 22:29:15 -070072 glib(),
Chris Masone9d779932011-08-25 16:33:41 -070073 run_path(),
74 storage_path(),
75 string()) {
Chris Masoneb925cc82011-06-22 15:39:57 -070076}
77
78PropertyStoreTest::~PropertyStoreTest() {}
79
Chris Masone9d779932011-08-25 16:33:41 -070080void PropertyStoreTest::SetUp() {
81 ASSERT_FALSE(run_path().empty());
82 ASSERT_FALSE(storage_path().empty());
83}
84
Chris Masone8a56ad62011-07-02 15:27:57 -070085TEST_P(PropertyStoreTest, TestProperty) {
86 // Ensure that an attempt to write unknown properties returns InvalidProperty.
87 PropertyStore store;
88 ::DBus::Error error;
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -080089 EXPECT_FALSE(DBusAdaptor::SetProperty(&store, "", GetParam(), &error));
Chris Masone9d779932011-08-25 16:33:41 -070090 EXPECT_EQ(invalid_prop(), error.name());
Chris Masone8a56ad62011-07-02 15:27:57 -070091}
92
93INSTANTIATE_TEST_CASE_P(
94 PropertyStoreTestInstance,
95 PropertyStoreTest,
96 Values(PropertyStoreTest::kBoolV,
97 PropertyStoreTest::kByteV,
Chris Masone8a56ad62011-07-02 15:27:57 -070098 PropertyStoreTest::kInt16V,
99 PropertyStoreTest::kInt32V,
Darin Petkov63138a92012-02-06 14:09:15 +0100100 PropertyStoreTest::kKeyValueStoreV,
101 PropertyStoreTest::kStringV,
Chris Masone8a56ad62011-07-02 15:27:57 -0700102 PropertyStoreTest::kStringmapV,
Chris Masone889666b2011-07-03 12:58:50 -0700103 PropertyStoreTest::kStringsV,
Chris Masone889666b2011-07-03 12:58:50 -0700104 PropertyStoreTest::kUint16V,
105 PropertyStoreTest::kUint32V));
Chris Masone8a56ad62011-07-02 15:27:57 -0700106
mukesh agrawal4d260da2012-01-30 11:53:52 -0800107template <typename T>
108class PropertyStoreTypedTest : public PropertyStoreTest {
109 protected:
110 void RegisterProperty(
111 PropertyStore &store, const string &name, T *storage);
112};
113
114typedef ::testing::Types<
115 bool, int16, int32, KeyValueStore, string, Stringmap, Stringmaps, Strings,
116 uint8, uint16, uint32> PropertyTypes;
117TYPED_TEST_CASE(PropertyStoreTypedTest, PropertyTypes);
118
119TYPED_TEST(PropertyStoreTypedTest, ClearProperty) {
120 PropertyStore store;
121 Error error;
122 TypeParam property;
123 RegisterProperty(store, "some property", &property);
124 EXPECT_TRUE(store.ClearProperty("some property", &error));
125}
126
127template<> void PropertyStoreTypedTest<bool>::RegisterProperty(
128 PropertyStore &store, const string &name, bool *storage) {
129 store.RegisterBool(name, storage);
130}
131
132template<> void PropertyStoreTypedTest<int16>::RegisterProperty(
133 PropertyStore &store, const string &name, int16 *storage) {
134 store.RegisterInt16(name, storage);
135}
136
137template<> void PropertyStoreTypedTest<int32>::RegisterProperty(
138 PropertyStore &store, const string &name, int32 *storage) {
139 store.RegisterInt32(name, storage);
140}
141
142template<> void PropertyStoreTypedTest<KeyValueStore>::RegisterProperty(
143 PropertyStore &store, const string &name, KeyValueStore *storage) {
144 // We use |RegisterDerivedKeyValueStore|, because there is no non-derived
145 // version. (And it's not clear that we'll need one, outside of this
146 // test.)
147 store.RegisterDerivedKeyValueStore(
148 name, KeyValueStoreAccessor(
149 new PropertyAccessor<KeyValueStore>(storage)));
150}
151
152template<> void PropertyStoreTypedTest<string>::RegisterProperty(
153 PropertyStore &store, const string &name, string *storage) {
154 store.RegisterString(name, storage);
155}
156
157template<> void PropertyStoreTypedTest<Stringmap>::RegisterProperty(
158 PropertyStore &store, const string &name, Stringmap *storage) {
159 store.RegisterStringmap(name, storage);
160}
161
162template<> void PropertyStoreTypedTest<Stringmaps>::RegisterProperty(
163 PropertyStore &store, const string &name, Stringmaps *storage) {
164 store.RegisterStringmaps(name, storage);
165}
166
167template<> void PropertyStoreTypedTest<Strings>::RegisterProperty(
168 PropertyStore &store, const string &name, Strings *storage) {
169 store.RegisterStrings(name, storage);
170}
171
172template<> void PropertyStoreTypedTest<uint8>::RegisterProperty(
173 PropertyStore &store, const string &name, uint8 *storage) {
174 store.RegisterUint8(name, storage);
175}
176
177template<> void PropertyStoreTypedTest<uint16>::RegisterProperty(
178 PropertyStore &store, const string &name, uint16 *storage) {
179 store.RegisterUint16(name, storage);
180}
181
182template<> void PropertyStoreTypedTest<uint32>::RegisterProperty(
183 PropertyStore &store, const string &name, uint32 *storage) {
184 store.RegisterUint32(name, storage);
185}
186
187TEST_F(PropertyStoreTest, ClearBoolProperty) {
188 // We exercise both possibilities for the default value here,
189 // to ensure that Clear actually resets the property based on
190 // the property's initial value (rather than the language's
191 // default value for the type).
192 static const bool kDefaults[] = {true, false};
193 for (size_t i = 0; i < arraysize(kDefaults); ++i) {
194 PropertyStore store;
195 Error error;
196
197 const bool default_value = kDefaults[i];
198 bool flag = default_value;
199 store.RegisterBool("some bool", &flag);
200
201 EXPECT_TRUE(store.ClearProperty("some bool", &error));
202 EXPECT_EQ(default_value, flag);
203 }
204}
205
206TEST_F(PropertyStoreTest, ClearPropertyNonexistent) {
207 PropertyStore store;
208 Error error;
209
210 EXPECT_FALSE(store.ClearProperty("", &error));
211 EXPECT_EQ(Error::kInvalidProperty, error.type());
212}
213
mukesh agrawalffa3d042011-10-06 15:26:10 -0700214TEST_F(PropertyStoreTest, SetStringmapsProperty) {
215 PropertyStore store;
216 ::DBus::Error error;
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -0800217 EXPECT_FALSE(DBusAdaptor::SetProperty(
mukesh agrawalffa3d042011-10-06 15:26:10 -0700218 &store, "", PropertyStoreTest::kStringmapsV, &error));
219 EXPECT_EQ(internal_error(), error.name());
220}
221
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800222TEST_F(PropertyStoreTest, WriteOnlyProperties) {
223 // Test that properties registered as write-only are not returned
224 // when using Get*PropertiesIter().
225 PropertyStore store;
226 Error error;
227 {
228 const string keys[] = {"boolp1", "boolp2"};
229 bool values[] = {true, true};
230 store.RegisterWriteOnlyBool(keys[0], &values[0]);
231 store.RegisterBool(keys[1], &values[1]);
232
233 ReadablePropertyConstIterator<bool> it = store.GetBoolPropertiesIter();
234 error.Reset();
235 EXPECT_FALSE(it.AtEnd());
236 EXPECT_EQ(keys[1], it.Key());
237 EXPECT_TRUE(values[1] == it.Value(&error));
238 EXPECT_TRUE(error.IsSuccess());
239 it.Advance();
240 EXPECT_TRUE(it.AtEnd());
241 }
242 {
243 const string keys[] = {"int16p1", "int16p2"};
244 int16 values[] = {127, 128};
245 store.RegisterWriteOnlyInt16(keys[0], &values[0]);
246 store.RegisterInt16(keys[1], &values[1]);
247
248 ReadablePropertyConstIterator<int16> it = store.GetInt16PropertiesIter();
249 error.Reset();
250 EXPECT_FALSE(it.AtEnd());
251 EXPECT_EQ(keys[1], it.Key());
252 EXPECT_EQ(values[1], it.Value(&error));
253 EXPECT_TRUE(error.IsSuccess());
254 it.Advance();
255 EXPECT_TRUE(it.AtEnd());
256 }
257 {
258 const string keys[] = {"int32p1", "int32p2"};
259 int32 values[] = {127, 128};
260 store.RegisterWriteOnlyInt32(keys[0], &values[0]);
261 store.RegisterInt32(keys[1], &values[1]);
262
263 ReadablePropertyConstIterator<int32> it = store.GetInt32PropertiesIter();
264 error.Reset();
265 EXPECT_FALSE(it.AtEnd());
266 EXPECT_EQ(keys[1], it.Key());
267 EXPECT_EQ(values[1], it.Value(&error));
268 EXPECT_TRUE(error.IsSuccess());
269 it.Advance();
270 EXPECT_TRUE(it.AtEnd());
271 }
272 {
273 const string keys[] = {"stringp1", "stringp2"};
274 string values[] = {"noooo", "yesss"};
275 store.RegisterWriteOnlyString(keys[0], &values[0]);
276 store.RegisterString(keys[1], &values[1]);
277
278 ReadablePropertyConstIterator<string> it = store.GetStringPropertiesIter();
279 error.Reset();
280 EXPECT_FALSE(it.AtEnd());
281 EXPECT_EQ(keys[1], it.Key());
282 EXPECT_EQ(values[1], it.Value(&error));
283 EXPECT_TRUE(error.IsSuccess());
284 it.Advance();
285 EXPECT_TRUE(it.AtEnd());
286 }
287 {
288 const string keys[] = {"stringmapp1", "stringmapp2"};
289 Stringmap values[2];
290 values[0]["noooo"] = "yesss";
291 values[1]["yesss"] = "noooo";
292 store.RegisterWriteOnlyStringmap(keys[0], &values[0]);
293 store.RegisterStringmap(keys[1], &values[1]);
294
295 ReadablePropertyConstIterator<Stringmap> it =
296 store.GetStringmapPropertiesIter();
297 error.Reset();
298 EXPECT_FALSE(it.AtEnd());
299 EXPECT_EQ(keys[1], it.Key());
300 EXPECT_TRUE(values[1] == it.Value(&error));
301 EXPECT_TRUE(error.IsSuccess());
302 it.Advance();
303 EXPECT_TRUE(it.AtEnd());
304 }
305 {
306 const string keys[] = {"stringmapsp1", "stringmapsp2"};
307 Stringmaps values[2];
308 Stringmap element;
309 element["noooo"] = "yesss";
310 values[0].push_back(element);
311 element["yesss"] = "noooo";
312 values[1].push_back(element);
313
314 store.RegisterWriteOnlyStringmaps(keys[0], &values[0]);
315 store.RegisterStringmaps(keys[1], &values[1]);
316
317 ReadablePropertyConstIterator<Stringmaps> it =
318 store.GetStringmapsPropertiesIter();
319 error.Reset();
320 EXPECT_FALSE(it.AtEnd());
321 EXPECT_EQ(keys[1], it.Key());
322 EXPECT_TRUE(values[1] == it.Value(&error));
323 EXPECT_TRUE(error.IsSuccess());
324 it.Advance();
325 EXPECT_TRUE(it.AtEnd());
326 }
327 {
328 const string keys[] = {"stringsp1", "stringsp2"};
329 Strings values[2];
330 string element;
331 element = "noooo";
332 values[0].push_back(element);
333 element = "yesss";
334 values[1].push_back(element);
335 store.RegisterWriteOnlyStrings(keys[0], &values[0]);
336 store.RegisterStrings(keys[1], &values[1]);
337
338 ReadablePropertyConstIterator<Strings> it =
339 store.GetStringsPropertiesIter();
340 error.Reset();
341 EXPECT_FALSE(it.AtEnd());
342 EXPECT_EQ(keys[1], it.Key());
343 EXPECT_TRUE(values[1] == it.Value(&error));
344 EXPECT_TRUE(error.IsSuccess());
345 it.Advance();
346 EXPECT_TRUE(it.AtEnd());
347 }
348 {
349 const string keys[] = {"uint8p1", "uint8p2"};
350 uint8 values[] = {127, 128};
351 store.RegisterWriteOnlyUint8(keys[0], &values[0]);
352 store.RegisterUint8(keys[1], &values[1]);
353
354 ReadablePropertyConstIterator<uint8> it = store.GetUint8PropertiesIter();
355 error.Reset();
356 EXPECT_FALSE(it.AtEnd());
357 EXPECT_EQ(keys[1], it.Key());
358 EXPECT_EQ(values[1], it.Value(&error));
359 EXPECT_TRUE(error.IsSuccess());
360 it.Advance();
361 EXPECT_TRUE(it.AtEnd());
362 }
363 {
364 const string keys[] = {"uint16p", "uint16p1"};
365 uint16 values[] = {127, 128};
366 store.RegisterWriteOnlyUint16(keys[0], &values[0]);
367 store.RegisterUint16(keys[1], &values[1]);
368
369 ReadablePropertyConstIterator<uint16> it = store.GetUint16PropertiesIter();
370 error.Reset();
371 EXPECT_FALSE(it.AtEnd());
372 EXPECT_EQ(keys[1], it.Key());
373 EXPECT_EQ(values[1], it.Value(&error));
374 EXPECT_TRUE(error.IsSuccess());
375 it.Advance();
376 EXPECT_TRUE(it.AtEnd());
377 }
378}
379
Chris Masoneb925cc82011-06-22 15:39:57 -0700380} // namespace shill