blob: 2256ff39a444a0c970e379d339d6af9517240222 [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;
126 RegisterProperty(store, "some property", &property);
127 EXPECT_TRUE(store.ClearProperty("some property", &error));
128}
129
130template<> void PropertyStoreTypedTest<bool>::RegisterProperty(
131 PropertyStore &store, const string &name, bool *storage) {
132 store.RegisterBool(name, storage);
133}
134
135template<> void PropertyStoreTypedTest<int16>::RegisterProperty(
136 PropertyStore &store, const string &name, int16 *storage) {
137 store.RegisterInt16(name, storage);
138}
139
140template<> void PropertyStoreTypedTest<int32>::RegisterProperty(
141 PropertyStore &store, const string &name, int32 *storage) {
142 store.RegisterInt32(name, storage);
143}
144
145template<> void PropertyStoreTypedTest<KeyValueStore>::RegisterProperty(
146 PropertyStore &store, const string &name, KeyValueStore *storage) {
147 // We use |RegisterDerivedKeyValueStore|, because there is no non-derived
148 // version. (And it's not clear that we'll need one, outside of this
149 // test.)
150 store.RegisterDerivedKeyValueStore(
151 name, KeyValueStoreAccessor(
152 new PropertyAccessor<KeyValueStore>(storage)));
153}
154
155template<> void PropertyStoreTypedTest<string>::RegisterProperty(
156 PropertyStore &store, const string &name, string *storage) {
157 store.RegisterString(name, storage);
158}
159
160template<> void PropertyStoreTypedTest<Stringmap>::RegisterProperty(
161 PropertyStore &store, const string &name, Stringmap *storage) {
162 store.RegisterStringmap(name, storage);
163}
164
165template<> void PropertyStoreTypedTest<Stringmaps>::RegisterProperty(
166 PropertyStore &store, const string &name, Stringmaps *storage) {
167 store.RegisterStringmaps(name, storage);
168}
169
170template<> void PropertyStoreTypedTest<Strings>::RegisterProperty(
171 PropertyStore &store, const string &name, Strings *storage) {
172 store.RegisterStrings(name, storage);
173}
174
175template<> void PropertyStoreTypedTest<uint8>::RegisterProperty(
176 PropertyStore &store, const string &name, uint8 *storage) {
177 store.RegisterUint8(name, storage);
178}
179
180template<> void PropertyStoreTypedTest<uint16>::RegisterProperty(
181 PropertyStore &store, const string &name, uint16 *storage) {
182 store.RegisterUint16(name, storage);
183}
184
185template<> void PropertyStoreTypedTest<uint32>::RegisterProperty(
186 PropertyStore &store, const string &name, uint32 *storage) {
187 store.RegisterUint32(name, storage);
188}
189
190TEST_F(PropertyStoreTest, ClearBoolProperty) {
191 // We exercise both possibilities for the default value here,
192 // to ensure that Clear actually resets the property based on
193 // the property's initial value (rather than the language's
194 // default value for the type).
195 static const bool kDefaults[] = {true, false};
196 for (size_t i = 0; i < arraysize(kDefaults); ++i) {
197 PropertyStore store;
198 Error error;
199
200 const bool default_value = kDefaults[i];
201 bool flag = default_value;
202 store.RegisterBool("some bool", &flag);
203
204 EXPECT_TRUE(store.ClearProperty("some bool", &error));
205 EXPECT_EQ(default_value, flag);
206 }
207}
208
209TEST_F(PropertyStoreTest, ClearPropertyNonexistent) {
210 PropertyStore store;
211 Error error;
212
213 EXPECT_FALSE(store.ClearProperty("", &error));
214 EXPECT_EQ(Error::kInvalidProperty, error.type());
215}
216
mukesh agrawalffa3d042011-10-06 15:26:10 -0700217TEST_F(PropertyStoreTest, SetStringmapsProperty) {
218 PropertyStore store;
219 ::DBus::Error error;
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -0800220 EXPECT_FALSE(DBusAdaptor::SetProperty(
mukesh agrawalffa3d042011-10-06 15:26:10 -0700221 &store, "", PropertyStoreTest::kStringmapsV, &error));
222 EXPECT_EQ(internal_error(), error.name());
223}
224
Eric Shienbroodb23d4b92012-02-16 12:32:42 -0500225TEST_F(PropertyStoreTest, SetKeyValueStoreProperty) {
226 PropertyStore store;
227 ::DBus::Error error;
228 EXPECT_FALSE(DBusAdaptor::SetProperty(
229 &store, "", PropertyStoreTest::kKeyValueStoreV, &error));
230 EXPECT_EQ(internal_error(), error.name());
231}
232
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800233TEST_F(PropertyStoreTest, WriteOnlyProperties) {
234 // Test that properties registered as write-only are not returned
235 // when using Get*PropertiesIter().
236 PropertyStore store;
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800237 {
238 const string keys[] = {"boolp1", "boolp2"};
239 bool values[] = {true, true};
240 store.RegisterWriteOnlyBool(keys[0], &values[0]);
241 store.RegisterBool(keys[1], &values[1]);
242
243 ReadablePropertyConstIterator<bool> it = store.GetBoolPropertiesIter();
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800244 EXPECT_FALSE(it.AtEnd());
245 EXPECT_EQ(keys[1], it.Key());
Darin Petkov4682aa82012-05-31 16:24:11 +0200246 EXPECT_TRUE(values[1] == it.value());
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800247 it.Advance();
248 EXPECT_TRUE(it.AtEnd());
249 }
250 {
251 const string keys[] = {"int16p1", "int16p2"};
252 int16 values[] = {127, 128};
253 store.RegisterWriteOnlyInt16(keys[0], &values[0]);
254 store.RegisterInt16(keys[1], &values[1]);
255
256 ReadablePropertyConstIterator<int16> it = store.GetInt16PropertiesIter();
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800257 EXPECT_FALSE(it.AtEnd());
258 EXPECT_EQ(keys[1], it.Key());
Darin Petkov4682aa82012-05-31 16:24:11 +0200259 EXPECT_EQ(values[1], it.value());
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800260 it.Advance();
261 EXPECT_TRUE(it.AtEnd());
262 }
263 {
264 const string keys[] = {"int32p1", "int32p2"};
265 int32 values[] = {127, 128};
266 store.RegisterWriteOnlyInt32(keys[0], &values[0]);
267 store.RegisterInt32(keys[1], &values[1]);
268
269 ReadablePropertyConstIterator<int32> it = store.GetInt32PropertiesIter();
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800270 EXPECT_FALSE(it.AtEnd());
271 EXPECT_EQ(keys[1], it.Key());
Darin Petkov4682aa82012-05-31 16:24:11 +0200272 EXPECT_EQ(values[1], it.value());
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800273 it.Advance();
274 EXPECT_TRUE(it.AtEnd());
275 }
276 {
277 const string keys[] = {"stringp1", "stringp2"};
278 string values[] = {"noooo", "yesss"};
279 store.RegisterWriteOnlyString(keys[0], &values[0]);
280 store.RegisterString(keys[1], &values[1]);
281
282 ReadablePropertyConstIterator<string> it = store.GetStringPropertiesIter();
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800283 EXPECT_FALSE(it.AtEnd());
284 EXPECT_EQ(keys[1], it.Key());
Darin Petkov4682aa82012-05-31 16:24:11 +0200285 EXPECT_EQ(values[1], it.value());
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800286 it.Advance();
287 EXPECT_TRUE(it.AtEnd());
288 }
289 {
290 const string keys[] = {"stringmapp1", "stringmapp2"};
291 Stringmap values[2];
292 values[0]["noooo"] = "yesss";
293 values[1]["yesss"] = "noooo";
294 store.RegisterWriteOnlyStringmap(keys[0], &values[0]);
295 store.RegisterStringmap(keys[1], &values[1]);
296
297 ReadablePropertyConstIterator<Stringmap> it =
298 store.GetStringmapPropertiesIter();
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800299 EXPECT_FALSE(it.AtEnd());
300 EXPECT_EQ(keys[1], it.Key());
Darin Petkov4682aa82012-05-31 16:24:11 +0200301 EXPECT_TRUE(values[1] == it.value());
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800302 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();
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800319 EXPECT_FALSE(it.AtEnd());
320 EXPECT_EQ(keys[1], it.Key());
Darin Petkov4682aa82012-05-31 16:24:11 +0200321 EXPECT_TRUE(values[1] == it.value());
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800322 it.Advance();
323 EXPECT_TRUE(it.AtEnd());
324 }
325 {
326 const string keys[] = {"stringsp1", "stringsp2"};
327 Strings values[2];
328 string element;
329 element = "noooo";
330 values[0].push_back(element);
331 element = "yesss";
332 values[1].push_back(element);
333 store.RegisterWriteOnlyStrings(keys[0], &values[0]);
334 store.RegisterStrings(keys[1], &values[1]);
335
336 ReadablePropertyConstIterator<Strings> it =
337 store.GetStringsPropertiesIter();
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800338 EXPECT_FALSE(it.AtEnd());
339 EXPECT_EQ(keys[1], it.Key());
Darin Petkov4682aa82012-05-31 16:24:11 +0200340 EXPECT_TRUE(values[1] == it.value());
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800341 it.Advance();
342 EXPECT_TRUE(it.AtEnd());
343 }
344 {
345 const string keys[] = {"uint8p1", "uint8p2"};
346 uint8 values[] = {127, 128};
347 store.RegisterWriteOnlyUint8(keys[0], &values[0]);
348 store.RegisterUint8(keys[1], &values[1]);
349
350 ReadablePropertyConstIterator<uint8> it = store.GetUint8PropertiesIter();
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800351 EXPECT_FALSE(it.AtEnd());
352 EXPECT_EQ(keys[1], it.Key());
Darin Petkov4682aa82012-05-31 16:24:11 +0200353 EXPECT_EQ(values[1], it.value());
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800354 it.Advance();
355 EXPECT_TRUE(it.AtEnd());
356 }
357 {
358 const string keys[] = {"uint16p", "uint16p1"};
359 uint16 values[] = {127, 128};
360 store.RegisterWriteOnlyUint16(keys[0], &values[0]);
361 store.RegisterUint16(keys[1], &values[1]);
362
363 ReadablePropertyConstIterator<uint16> it = store.GetUint16PropertiesIter();
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800364 EXPECT_FALSE(it.AtEnd());
365 EXPECT_EQ(keys[1], it.Key());
Darin Petkov4682aa82012-05-31 16:24:11 +0200366 EXPECT_EQ(values[1], it.value());
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800367 it.Advance();
368 EXPECT_TRUE(it.AtEnd());
369 }
370}
371
Chris Masoneb925cc82011-06-22 15:39:57 -0700372} // namespace shill