blob: 15039fc66eb0218be90a1733e3d249fcfcd5e82c [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::kStringV,
Chris Masone8a56ad62011-07-02 15:27:57 -0700101 PropertyStoreTest::kStringmapV,
Chris Masone889666b2011-07-03 12:58:50 -0700102 PropertyStoreTest::kStringsV,
Chris Masone889666b2011-07-03 12:58:50 -0700103 PropertyStoreTest::kUint16V,
104 PropertyStoreTest::kUint32V));
Chris Masone8a56ad62011-07-02 15:27:57 -0700105
mukesh agrawal4d260da2012-01-30 11:53:52 -0800106template <typename T>
107class PropertyStoreTypedTest : public PropertyStoreTest {
108 protected:
109 void RegisterProperty(
110 PropertyStore &store, const string &name, T *storage);
111};
112
113typedef ::testing::Types<
114 bool, int16, int32, KeyValueStore, string, Stringmap, Stringmaps, Strings,
115 uint8, uint16, uint32> PropertyTypes;
116TYPED_TEST_CASE(PropertyStoreTypedTest, PropertyTypes);
117
118TYPED_TEST(PropertyStoreTypedTest, ClearProperty) {
119 PropertyStore store;
120 Error error;
121 TypeParam property;
122 RegisterProperty(store, "some property", &property);
123 EXPECT_TRUE(store.ClearProperty("some property", &error));
124}
125
126template<> void PropertyStoreTypedTest<bool>::RegisterProperty(
127 PropertyStore &store, const string &name, bool *storage) {
128 store.RegisterBool(name, storage);
129}
130
131template<> void PropertyStoreTypedTest<int16>::RegisterProperty(
132 PropertyStore &store, const string &name, int16 *storage) {
133 store.RegisterInt16(name, storage);
134}
135
136template<> void PropertyStoreTypedTest<int32>::RegisterProperty(
137 PropertyStore &store, const string &name, int32 *storage) {
138 store.RegisterInt32(name, storage);
139}
140
141template<> void PropertyStoreTypedTest<KeyValueStore>::RegisterProperty(
142 PropertyStore &store, const string &name, KeyValueStore *storage) {
143 // We use |RegisterDerivedKeyValueStore|, because there is no non-derived
144 // version. (And it's not clear that we'll need one, outside of this
145 // test.)
146 store.RegisterDerivedKeyValueStore(
147 name, KeyValueStoreAccessor(
148 new PropertyAccessor<KeyValueStore>(storage)));
149}
150
151template<> void PropertyStoreTypedTest<string>::RegisterProperty(
152 PropertyStore &store, const string &name, string *storage) {
153 store.RegisterString(name, storage);
154}
155
156template<> void PropertyStoreTypedTest<Stringmap>::RegisterProperty(
157 PropertyStore &store, const string &name, Stringmap *storage) {
158 store.RegisterStringmap(name, storage);
159}
160
161template<> void PropertyStoreTypedTest<Stringmaps>::RegisterProperty(
162 PropertyStore &store, const string &name, Stringmaps *storage) {
163 store.RegisterStringmaps(name, storage);
164}
165
166template<> void PropertyStoreTypedTest<Strings>::RegisterProperty(
167 PropertyStore &store, const string &name, Strings *storage) {
168 store.RegisterStrings(name, storage);
169}
170
171template<> void PropertyStoreTypedTest<uint8>::RegisterProperty(
172 PropertyStore &store, const string &name, uint8 *storage) {
173 store.RegisterUint8(name, storage);
174}
175
176template<> void PropertyStoreTypedTest<uint16>::RegisterProperty(
177 PropertyStore &store, const string &name, uint16 *storage) {
178 store.RegisterUint16(name, storage);
179}
180
181template<> void PropertyStoreTypedTest<uint32>::RegisterProperty(
182 PropertyStore &store, const string &name, uint32 *storage) {
183 store.RegisterUint32(name, storage);
184}
185
186TEST_F(PropertyStoreTest, ClearBoolProperty) {
187 // We exercise both possibilities for the default value here,
188 // to ensure that Clear actually resets the property based on
189 // the property's initial value (rather than the language's
190 // default value for the type).
191 static const bool kDefaults[] = {true, false};
192 for (size_t i = 0; i < arraysize(kDefaults); ++i) {
193 PropertyStore store;
194 Error error;
195
196 const bool default_value = kDefaults[i];
197 bool flag = default_value;
198 store.RegisterBool("some bool", &flag);
199
200 EXPECT_TRUE(store.ClearProperty("some bool", &error));
201 EXPECT_EQ(default_value, flag);
202 }
203}
204
205TEST_F(PropertyStoreTest, ClearPropertyNonexistent) {
206 PropertyStore store;
207 Error error;
208
209 EXPECT_FALSE(store.ClearProperty("", &error));
210 EXPECT_EQ(Error::kInvalidProperty, error.type());
211}
212
mukesh agrawalffa3d042011-10-06 15:26:10 -0700213TEST_F(PropertyStoreTest, SetStringmapsProperty) {
214 PropertyStore store;
215 ::DBus::Error error;
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -0800216 EXPECT_FALSE(DBusAdaptor::SetProperty(
mukesh agrawalffa3d042011-10-06 15:26:10 -0700217 &store, "", PropertyStoreTest::kStringmapsV, &error));
218 EXPECT_EQ(internal_error(), error.name());
219}
220
Eric Shienbroodb23d4b92012-02-16 12:32:42 -0500221TEST_F(PropertyStoreTest, SetKeyValueStoreProperty) {
222 PropertyStore store;
223 ::DBus::Error error;
224 EXPECT_FALSE(DBusAdaptor::SetProperty(
225 &store, "", PropertyStoreTest::kKeyValueStoreV, &error));
226 EXPECT_EQ(internal_error(), error.name());
227}
228
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800229TEST_F(PropertyStoreTest, WriteOnlyProperties) {
230 // Test that properties registered as write-only are not returned
231 // when using Get*PropertiesIter().
232 PropertyStore store;
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800233 {
234 const string keys[] = {"boolp1", "boolp2"};
235 bool values[] = {true, true};
236 store.RegisterWriteOnlyBool(keys[0], &values[0]);
237 store.RegisterBool(keys[1], &values[1]);
238
239 ReadablePropertyConstIterator<bool> it = store.GetBoolPropertiesIter();
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800240 EXPECT_FALSE(it.AtEnd());
241 EXPECT_EQ(keys[1], it.Key());
Darin Petkov4682aa82012-05-31 16:24:11 +0200242 EXPECT_TRUE(values[1] == it.value());
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800243 it.Advance();
244 EXPECT_TRUE(it.AtEnd());
245 }
246 {
247 const string keys[] = {"int16p1", "int16p2"};
248 int16 values[] = {127, 128};
249 store.RegisterWriteOnlyInt16(keys[0], &values[0]);
250 store.RegisterInt16(keys[1], &values[1]);
251
252 ReadablePropertyConstIterator<int16> it = store.GetInt16PropertiesIter();
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800253 EXPECT_FALSE(it.AtEnd());
254 EXPECT_EQ(keys[1], it.Key());
Darin Petkov4682aa82012-05-31 16:24:11 +0200255 EXPECT_EQ(values[1], it.value());
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800256 it.Advance();
257 EXPECT_TRUE(it.AtEnd());
258 }
259 {
260 const string keys[] = {"int32p1", "int32p2"};
261 int32 values[] = {127, 128};
262 store.RegisterWriteOnlyInt32(keys[0], &values[0]);
263 store.RegisterInt32(keys[1], &values[1]);
264
265 ReadablePropertyConstIterator<int32> it = store.GetInt32PropertiesIter();
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800266 EXPECT_FALSE(it.AtEnd());
267 EXPECT_EQ(keys[1], it.Key());
Darin Petkov4682aa82012-05-31 16:24:11 +0200268 EXPECT_EQ(values[1], it.value());
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800269 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();
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800279 EXPECT_FALSE(it.AtEnd());
280 EXPECT_EQ(keys[1], it.Key());
Darin Petkov4682aa82012-05-31 16:24:11 +0200281 EXPECT_EQ(values[1], it.value());
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800282 it.Advance();
283 EXPECT_TRUE(it.AtEnd());
284 }
285 {
286 const string keys[] = {"stringmapp1", "stringmapp2"};
287 Stringmap values[2];
288 values[0]["noooo"] = "yesss";
289 values[1]["yesss"] = "noooo";
290 store.RegisterWriteOnlyStringmap(keys[0], &values[0]);
291 store.RegisterStringmap(keys[1], &values[1]);
292
293 ReadablePropertyConstIterator<Stringmap> it =
294 store.GetStringmapPropertiesIter();
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800295 EXPECT_FALSE(it.AtEnd());
296 EXPECT_EQ(keys[1], it.Key());
Darin Petkov4682aa82012-05-31 16:24:11 +0200297 EXPECT_TRUE(values[1] == it.value());
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800298 it.Advance();
299 EXPECT_TRUE(it.AtEnd());
300 }
301 {
302 const string keys[] = {"stringmapsp1", "stringmapsp2"};
303 Stringmaps values[2];
304 Stringmap element;
305 element["noooo"] = "yesss";
306 values[0].push_back(element);
307 element["yesss"] = "noooo";
308 values[1].push_back(element);
309
310 store.RegisterWriteOnlyStringmaps(keys[0], &values[0]);
311 store.RegisterStringmaps(keys[1], &values[1]);
312
313 ReadablePropertyConstIterator<Stringmaps> it =
314 store.GetStringmapsPropertiesIter();
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800315 EXPECT_FALSE(it.AtEnd());
316 EXPECT_EQ(keys[1], it.Key());
Darin Petkov4682aa82012-05-31 16:24:11 +0200317 EXPECT_TRUE(values[1] == it.value());
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800318 it.Advance();
319 EXPECT_TRUE(it.AtEnd());
320 }
321 {
322 const string keys[] = {"stringsp1", "stringsp2"};
323 Strings values[2];
324 string element;
325 element = "noooo";
326 values[0].push_back(element);
327 element = "yesss";
328 values[1].push_back(element);
329 store.RegisterWriteOnlyStrings(keys[0], &values[0]);
330 store.RegisterStrings(keys[1], &values[1]);
331
332 ReadablePropertyConstIterator<Strings> it =
333 store.GetStringsPropertiesIter();
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800334 EXPECT_FALSE(it.AtEnd());
335 EXPECT_EQ(keys[1], it.Key());
Darin Petkov4682aa82012-05-31 16:24:11 +0200336 EXPECT_TRUE(values[1] == it.value());
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800337 it.Advance();
338 EXPECT_TRUE(it.AtEnd());
339 }
340 {
341 const string keys[] = {"uint8p1", "uint8p2"};
342 uint8 values[] = {127, 128};
343 store.RegisterWriteOnlyUint8(keys[0], &values[0]);
344 store.RegisterUint8(keys[1], &values[1]);
345
346 ReadablePropertyConstIterator<uint8> it = store.GetUint8PropertiesIter();
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800347 EXPECT_FALSE(it.AtEnd());
348 EXPECT_EQ(keys[1], it.Key());
Darin Petkov4682aa82012-05-31 16:24:11 +0200349 EXPECT_EQ(values[1], it.value());
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800350 it.Advance();
351 EXPECT_TRUE(it.AtEnd());
352 }
353 {
354 const string keys[] = {"uint16p", "uint16p1"};
355 uint16 values[] = {127, 128};
356 store.RegisterWriteOnlyUint16(keys[0], &values[0]);
357 store.RegisterUint16(keys[1], &values[1]);
358
359 ReadablePropertyConstIterator<uint16> it = store.GetUint16PropertiesIter();
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800360 EXPECT_FALSE(it.AtEnd());
361 EXPECT_EQ(keys[1], it.Key());
Darin Petkov4682aa82012-05-31 16:24:11 +0200362 EXPECT_EQ(values[1], it.value());
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800363 it.Advance();
364 EXPECT_TRUE(it.AtEnd());
365 }
366}
367
Chris Masoneb925cc82011-06-22 15:39:57 -0700368} // namespace shill