blob: 79239d001b9536037b02abba4f83e51a5cd6afef [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);
Paul Stewarte18c33b2012-07-10 20:48:44 -070063// static
64const ::DBus::Variant PropertyStoreTest::kUint64V =
65 DBusAdaptor::Uint64ToVariant(0);
Chris Masoneb925cc82011-06-22 15:39:57 -070066
67PropertyStoreTest::PropertyStoreTest()
mukesh agrawalffa3d042011-10-06 15:26:10 -070068 : internal_error_(Error::GetName(Error::kInternalError)),
69 invalid_args_(Error::GetName(Error::kInvalidArguments)),
Chris Masone9d779932011-08-25 16:33:41 -070070 invalid_prop_(Error::GetName(Error::kInvalidProperty)),
71 path_(dir_.CreateUniqueTempDir() ? dir_.path().value() : ""),
Chris Masone2176a882011-09-14 22:29:15 -070072 manager_(control_interface(),
73 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -080074 metrics(),
Chris Masone2176a882011-09-14 22:29:15 -070075 glib(),
Chris Masone9d779932011-08-25 16:33:41 -070076 run_path(),
77 storage_path(),
78 string()) {
Chris Masoneb925cc82011-06-22 15:39:57 -070079}
80
81PropertyStoreTest::~PropertyStoreTest() {}
82
Chris Masone9d779932011-08-25 16:33:41 -070083void PropertyStoreTest::SetUp() {
84 ASSERT_FALSE(run_path().empty());
85 ASSERT_FALSE(storage_path().empty());
86}
87
Chris Masone8a56ad62011-07-02 15:27:57 -070088TEST_P(PropertyStoreTest, TestProperty) {
89 // Ensure that an attempt to write unknown properties returns InvalidProperty.
90 PropertyStore store;
91 ::DBus::Error error;
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -080092 EXPECT_FALSE(DBusAdaptor::SetProperty(&store, "", GetParam(), &error));
Chris Masone9d779932011-08-25 16:33:41 -070093 EXPECT_EQ(invalid_prop(), error.name());
Chris Masone8a56ad62011-07-02 15:27:57 -070094}
95
96INSTANTIATE_TEST_CASE_P(
97 PropertyStoreTestInstance,
98 PropertyStoreTest,
99 Values(PropertyStoreTest::kBoolV,
100 PropertyStoreTest::kByteV,
Chris Masone8a56ad62011-07-02 15:27:57 -0700101 PropertyStoreTest::kInt16V,
102 PropertyStoreTest::kInt32V,
Darin Petkov63138a92012-02-06 14:09:15 +0100103 PropertyStoreTest::kStringV,
Chris Masone8a56ad62011-07-02 15:27:57 -0700104 PropertyStoreTest::kStringmapV,
Chris Masone889666b2011-07-03 12:58:50 -0700105 PropertyStoreTest::kStringsV,
Chris Masone889666b2011-07-03 12:58:50 -0700106 PropertyStoreTest::kUint16V,
Paul Stewarte18c33b2012-07-10 20:48:44 -0700107 PropertyStoreTest::kUint32V,
108 PropertyStoreTest::kUint64V));
Chris Masone8a56ad62011-07-02 15:27:57 -0700109
mukesh agrawal4d260da2012-01-30 11:53:52 -0800110template <typename T>
111class PropertyStoreTypedTest : public PropertyStoreTest {
112 protected:
113 void RegisterProperty(
114 PropertyStore &store, const string &name, T *storage);
115};
116
117typedef ::testing::Types<
118 bool, int16, int32, KeyValueStore, string, Stringmap, Stringmaps, Strings,
119 uint8, uint16, uint32> PropertyTypes;
120TYPED_TEST_CASE(PropertyStoreTypedTest, PropertyTypes);
121
122TYPED_TEST(PropertyStoreTypedTest, ClearProperty) {
123 PropertyStore store;
124 Error error;
125 TypeParam property;
Han Shenfc349252012-08-30 11:36:04 -0700126 // |this| required due to two-phase lookup.
127 this->RegisterProperty(store, "some property", &property);
mukesh agrawal4d260da2012-01-30 11:53:52 -0800128 EXPECT_TRUE(store.ClearProperty("some property", &error));
129}
130
131template<> void PropertyStoreTypedTest<bool>::RegisterProperty(
132 PropertyStore &store, const string &name, bool *storage) {
133 store.RegisterBool(name, storage);
134}
135
136template<> void PropertyStoreTypedTest<int16>::RegisterProperty(
137 PropertyStore &store, const string &name, int16 *storage) {
138 store.RegisterInt16(name, storage);
139}
140
141template<> void PropertyStoreTypedTest<int32>::RegisterProperty(
142 PropertyStore &store, const string &name, int32 *storage) {
143 store.RegisterInt32(name, storage);
144}
145
146template<> void PropertyStoreTypedTest<KeyValueStore>::RegisterProperty(
147 PropertyStore &store, const string &name, KeyValueStore *storage) {
148 // We use |RegisterDerivedKeyValueStore|, because there is no non-derived
149 // version. (And it's not clear that we'll need one, outside of this
150 // test.)
151 store.RegisterDerivedKeyValueStore(
152 name, KeyValueStoreAccessor(
153 new PropertyAccessor<KeyValueStore>(storage)));
154}
155
156template<> void PropertyStoreTypedTest<string>::RegisterProperty(
157 PropertyStore &store, const string &name, string *storage) {
158 store.RegisterString(name, storage);
159}
160
161template<> void PropertyStoreTypedTest<Stringmap>::RegisterProperty(
162 PropertyStore &store, const string &name, Stringmap *storage) {
163 store.RegisterStringmap(name, storage);
164}
165
166template<> void PropertyStoreTypedTest<Stringmaps>::RegisterProperty(
167 PropertyStore &store, const string &name, Stringmaps *storage) {
168 store.RegisterStringmaps(name, storage);
169}
170
171template<> void PropertyStoreTypedTest<Strings>::RegisterProperty(
172 PropertyStore &store, const string &name, Strings *storage) {
173 store.RegisterStrings(name, storage);
174}
175
176template<> void PropertyStoreTypedTest<uint8>::RegisterProperty(
177 PropertyStore &store, const string &name, uint8 *storage) {
178 store.RegisterUint8(name, storage);
179}
180
181template<> void PropertyStoreTypedTest<uint16>::RegisterProperty(
182 PropertyStore &store, const string &name, uint16 *storage) {
183 store.RegisterUint16(name, storage);
184}
185
186template<> void PropertyStoreTypedTest<uint32>::RegisterProperty(
187 PropertyStore &store, const string &name, uint32 *storage) {
188 store.RegisterUint32(name, storage);
189}
190
191TEST_F(PropertyStoreTest, ClearBoolProperty) {
192 // We exercise both possibilities for the default value here,
193 // to ensure that Clear actually resets the property based on
194 // the property's initial value (rather than the language's
195 // default value for the type).
196 static const bool kDefaults[] = {true, false};
197 for (size_t i = 0; i < arraysize(kDefaults); ++i) {
198 PropertyStore store;
199 Error error;
200
201 const bool default_value = kDefaults[i];
202 bool flag = default_value;
203 store.RegisterBool("some bool", &flag);
204
205 EXPECT_TRUE(store.ClearProperty("some bool", &error));
206 EXPECT_EQ(default_value, flag);
207 }
208}
209
210TEST_F(PropertyStoreTest, ClearPropertyNonexistent) {
211 PropertyStore store;
212 Error error;
213
214 EXPECT_FALSE(store.ClearProperty("", &error));
215 EXPECT_EQ(Error::kInvalidProperty, error.type());
216}
217
mukesh agrawalffa3d042011-10-06 15:26:10 -0700218TEST_F(PropertyStoreTest, SetStringmapsProperty) {
219 PropertyStore store;
220 ::DBus::Error error;
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -0800221 EXPECT_FALSE(DBusAdaptor::SetProperty(
mukesh agrawalffa3d042011-10-06 15:26:10 -0700222 &store, "", PropertyStoreTest::kStringmapsV, &error));
223 EXPECT_EQ(internal_error(), error.name());
224}
225
Eric Shienbroodb23d4b92012-02-16 12:32:42 -0500226TEST_F(PropertyStoreTest, SetKeyValueStoreProperty) {
227 PropertyStore store;
228 ::DBus::Error error;
229 EXPECT_FALSE(DBusAdaptor::SetProperty(
230 &store, "", PropertyStoreTest::kKeyValueStoreV, &error));
231 EXPECT_EQ(internal_error(), error.name());
232}
233
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800234TEST_F(PropertyStoreTest, WriteOnlyProperties) {
235 // Test that properties registered as write-only are not returned
236 // when using Get*PropertiesIter().
237 PropertyStore store;
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800238 {
239 const string keys[] = {"boolp1", "boolp2"};
240 bool values[] = {true, true};
241 store.RegisterWriteOnlyBool(keys[0], &values[0]);
242 store.RegisterBool(keys[1], &values[1]);
243
244 ReadablePropertyConstIterator<bool> it = store.GetBoolPropertiesIter();
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800245 EXPECT_FALSE(it.AtEnd());
246 EXPECT_EQ(keys[1], it.Key());
Darin Petkov4682aa82012-05-31 16:24:11 +0200247 EXPECT_TRUE(values[1] == it.value());
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800248 it.Advance();
249 EXPECT_TRUE(it.AtEnd());
250 }
251 {
252 const string keys[] = {"int16p1", "int16p2"};
253 int16 values[] = {127, 128};
254 store.RegisterWriteOnlyInt16(keys[0], &values[0]);
255 store.RegisterInt16(keys[1], &values[1]);
256
257 ReadablePropertyConstIterator<int16> it = store.GetInt16PropertiesIter();
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800258 EXPECT_FALSE(it.AtEnd());
259 EXPECT_EQ(keys[1], it.Key());
Darin Petkov4682aa82012-05-31 16:24:11 +0200260 EXPECT_EQ(values[1], it.value());
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800261 it.Advance();
262 EXPECT_TRUE(it.AtEnd());
263 }
264 {
265 const string keys[] = {"int32p1", "int32p2"};
266 int32 values[] = {127, 128};
267 store.RegisterWriteOnlyInt32(keys[0], &values[0]);
268 store.RegisterInt32(keys[1], &values[1]);
269
270 ReadablePropertyConstIterator<int32> it = store.GetInt32PropertiesIter();
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800271 EXPECT_FALSE(it.AtEnd());
272 EXPECT_EQ(keys[1], it.Key());
Darin Petkov4682aa82012-05-31 16:24:11 +0200273 EXPECT_EQ(values[1], it.value());
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800274 it.Advance();
275 EXPECT_TRUE(it.AtEnd());
276 }
277 {
278 const string keys[] = {"stringp1", "stringp2"};
279 string values[] = {"noooo", "yesss"};
280 store.RegisterWriteOnlyString(keys[0], &values[0]);
281 store.RegisterString(keys[1], &values[1]);
282
283 ReadablePropertyConstIterator<string> it = store.GetStringPropertiesIter();
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800284 EXPECT_FALSE(it.AtEnd());
285 EXPECT_EQ(keys[1], it.Key());
Darin Petkov4682aa82012-05-31 16:24:11 +0200286 EXPECT_EQ(values[1], it.value());
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800287 it.Advance();
288 EXPECT_TRUE(it.AtEnd());
289 }
290 {
291 const string keys[] = {"stringmapp1", "stringmapp2"};
292 Stringmap values[2];
293 values[0]["noooo"] = "yesss";
294 values[1]["yesss"] = "noooo";
295 store.RegisterWriteOnlyStringmap(keys[0], &values[0]);
296 store.RegisterStringmap(keys[1], &values[1]);
297
298 ReadablePropertyConstIterator<Stringmap> it =
299 store.GetStringmapPropertiesIter();
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800300 EXPECT_FALSE(it.AtEnd());
301 EXPECT_EQ(keys[1], it.Key());
Darin Petkov4682aa82012-05-31 16:24:11 +0200302 EXPECT_TRUE(values[1] == it.value());
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800303 it.Advance();
304 EXPECT_TRUE(it.AtEnd());
305 }
306 {
307 const string keys[] = {"stringmapsp1", "stringmapsp2"};
308 Stringmaps values[2];
309 Stringmap element;
310 element["noooo"] = "yesss";
311 values[0].push_back(element);
312 element["yesss"] = "noooo";
313 values[1].push_back(element);
314
315 store.RegisterWriteOnlyStringmaps(keys[0], &values[0]);
316 store.RegisterStringmaps(keys[1], &values[1]);
317
318 ReadablePropertyConstIterator<Stringmaps> it =
319 store.GetStringmapsPropertiesIter();
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800320 EXPECT_FALSE(it.AtEnd());
321 EXPECT_EQ(keys[1], it.Key());
Darin Petkov4682aa82012-05-31 16:24:11 +0200322 EXPECT_TRUE(values[1] == it.value());
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800323 it.Advance();
324 EXPECT_TRUE(it.AtEnd());
325 }
326 {
327 const string keys[] = {"stringsp1", "stringsp2"};
328 Strings values[2];
329 string element;
330 element = "noooo";
331 values[0].push_back(element);
332 element = "yesss";
333 values[1].push_back(element);
334 store.RegisterWriteOnlyStrings(keys[0], &values[0]);
335 store.RegisterStrings(keys[1], &values[1]);
336
337 ReadablePropertyConstIterator<Strings> it =
338 store.GetStringsPropertiesIter();
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800339 EXPECT_FALSE(it.AtEnd());
340 EXPECT_EQ(keys[1], it.Key());
Darin Petkov4682aa82012-05-31 16:24:11 +0200341 EXPECT_TRUE(values[1] == it.value());
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800342 it.Advance();
343 EXPECT_TRUE(it.AtEnd());
344 }
345 {
346 const string keys[] = {"uint8p1", "uint8p2"};
347 uint8 values[] = {127, 128};
348 store.RegisterWriteOnlyUint8(keys[0], &values[0]);
349 store.RegisterUint8(keys[1], &values[1]);
350
351 ReadablePropertyConstIterator<uint8> it = store.GetUint8PropertiesIter();
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800352 EXPECT_FALSE(it.AtEnd());
353 EXPECT_EQ(keys[1], it.Key());
Darin Petkov4682aa82012-05-31 16:24:11 +0200354 EXPECT_EQ(values[1], it.value());
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800355 it.Advance();
356 EXPECT_TRUE(it.AtEnd());
357 }
358 {
359 const string keys[] = {"uint16p", "uint16p1"};
360 uint16 values[] = {127, 128};
361 store.RegisterWriteOnlyUint16(keys[0], &values[0]);
362 store.RegisterUint16(keys[1], &values[1]);
363
364 ReadablePropertyConstIterator<uint16> it = store.GetUint16PropertiesIter();
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800365 EXPECT_FALSE(it.AtEnd());
366 EXPECT_EQ(keys[1], it.Key());
Darin Petkov4682aa82012-05-31 16:24:11 +0200367 EXPECT_EQ(values[1], it.value());
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800368 it.Advance();
369 EXPECT_TRUE(it.AtEnd());
370 }
371}
372
Chris Masoneb925cc82011-06-22 15:39:57 -0700373} // namespace shill