blob: 108b0a6ed5454e7bf803b90c9e85715e35132128 [file] [log] [blame]
mukesh agrawal292dc0f2012-01-26 18:02:46 -08001// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
Chris Masone27bf1032011-06-28 17:02:01 -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_accessor.h"
6
7#include <limits>
8#include <map>
9#include <string>
10#include <vector>
11
12#include <base/basictypes.h>
Paul Stewarta61593e2012-03-23 13:06:21 -070013#include <base/stl_util.h>
Chris Masone27bf1032011-06-28 17:02:01 -070014#include <gtest/gtest.h>
15#include <gmock/gmock.h>
16
mukesh agrawalffa3d042011-10-06 15:26:10 -070017#include "shill/error.h"
18
Chris Masone27bf1032011-06-28 17:02:01 -070019using std::map;
20using std::string;
21using std::vector;
22using ::testing::Return;
23using ::testing::Test;
24
25namespace shill {
26
27TEST(PropertyAccessorTest, SignedIntCorrectness) {
Ben Chan7fab8972014-08-10 17:14:46 -070028 int32_t int_store = 0;
Chris Masone27bf1032011-06-28 17:02:01 -070029 {
mukesh agrawalffa3d042011-10-06 15:26:10 -070030 Error error;
Ben Chan7fab8972014-08-10 17:14:46 -070031 int32_t orig_value = int_store;
32 Int32Accessor accessor(new PropertyAccessor<int32_t>(&int_store));
Gaurav Shah1b7a6162011-11-09 11:41:01 -080033 EXPECT_EQ(int_store, accessor->Get(&error));
Chris Masone27bf1032011-06-28 17:02:01 -070034
Ben Chan7fab8972014-08-10 17:14:46 -070035 int32_t expected_int32 = 127;
mukesh agrawalbebf1b82013-04-23 15:06:33 -070036 EXPECT_TRUE(accessor->Set(expected_int32, &error));
mukesh agrawal292dc0f2012-01-26 18:02:46 -080037 EXPECT_TRUE(error.IsSuccess());
Gaurav Shah1b7a6162011-11-09 11:41:01 -080038 EXPECT_EQ(expected_int32, accessor->Get(&error));
mukesh agrawalbebf1b82013-04-23 15:06:33 -070039 // Resetting to the same value should return false, but without
40 // an error.
41 EXPECT_FALSE(accessor->Set(expected_int32, &error));
42 EXPECT_TRUE(error.IsSuccess());
Chris Masone27bf1032011-06-28 17:02:01 -070043
mukesh agrawal292dc0f2012-01-26 18:02:46 -080044 accessor->Clear(&error);
45 EXPECT_TRUE(error.IsSuccess());
46 EXPECT_EQ(orig_value, accessor->Get(&error));
47
Ben Chan7fab8972014-08-10 17:14:46 -070048 int_store = std::numeric_limits<int32_t>::max();
49 EXPECT_EQ(std::numeric_limits<int32_t>::max(), accessor->Get(&error));
Chris Masone27bf1032011-06-28 17:02:01 -070050 }
51 {
mukesh agrawalffa3d042011-10-06 15:26:10 -070052 Error error;
Ben Chan7fab8972014-08-10 17:14:46 -070053 Int32Accessor accessor(new ConstPropertyAccessor<int32_t>(&int_store));
Gaurav Shah1b7a6162011-11-09 11:41:01 -080054 EXPECT_EQ(int_store, accessor->Get(&error));
Chris Masone27bf1032011-06-28 17:02:01 -070055
Ben Chan7fab8972014-08-10 17:14:46 -070056 int32_t expected_int32 = 127;
mukesh agrawalffa3d042011-10-06 15:26:10 -070057 accessor->Set(expected_int32, &error);
58 ASSERT_FALSE(error.IsSuccess());
59 EXPECT_EQ(Error::kInvalidArguments, error.type());
Gaurav Shah1b7a6162011-11-09 11:41:01 -080060 EXPECT_EQ(int_store, accessor->Get(&error));
Chris Masone27bf1032011-06-28 17:02:01 -070061
Ben Chan7fab8972014-08-10 17:14:46 -070062 int_store = std::numeric_limits<int32_t>::max();
63 EXPECT_EQ(std::numeric_limits<int32_t>::max(), accessor->Get(&error));
Gaurav Shah1b7a6162011-11-09 11:41:01 -080064 }
65 {
66 Error error;
Ben Chan7fab8972014-08-10 17:14:46 -070067 Int32Accessor accessor(new ConstPropertyAccessor<int32_t>(&int_store));
mukesh agrawal292dc0f2012-01-26 18:02:46 -080068 accessor->Clear(&error);
69 ASSERT_FALSE(error.IsSuccess());
70 }
71 {
72 Error error;
Ben Chan7fab8972014-08-10 17:14:46 -070073 Int32Accessor accessor(new WriteOnlyPropertyAccessor<int32_t>(&int_store));
Gaurav Shah1b7a6162011-11-09 11:41:01 -080074 accessor->Get(&error);
mukesh agrawal292dc0f2012-01-26 18:02:46 -080075 EXPECT_TRUE(error.IsFailure());
Gaurav Shah1b7a6162011-11-09 11:41:01 -080076 EXPECT_EQ(Error::kPermissionDenied, error.type());
77 }
78 {
79 Error error;
Ben Chan7fab8972014-08-10 17:14:46 -070080 int32_t expected_int32 = 127;
81 WriteOnlyPropertyAccessor<int32_t> accessor(&int_store);
mukesh agrawalbebf1b82013-04-23 15:06:33 -070082 EXPECT_TRUE(accessor.Set(expected_int32, &error));
mukesh agrawal292dc0f2012-01-26 18:02:46 -080083 EXPECT_TRUE(error.IsSuccess());
Gaurav Shah1b7a6162011-11-09 11:41:01 -080084 EXPECT_EQ(expected_int32, *accessor.property_);
mukesh agrawalbebf1b82013-04-23 15:06:33 -070085 // Resetting to the same value should return false, but without
86 // an error.
87 EXPECT_FALSE(accessor.Set(expected_int32, &error));
88 EXPECT_TRUE(error.IsSuccess());
89 // As a write-only, the value can't be read.
Ben Chan7fab8972014-08-10 17:14:46 -070090 EXPECT_EQ(int32_t(), accessor.Get(&error));
Gaurav Shah1b7a6162011-11-09 11:41:01 -080091 ASSERT_FALSE(error.IsSuccess());
92
Ben Chan7fab8972014-08-10 17:14:46 -070093 int_store = std::numeric_limits<int32_t>::max();
94 EXPECT_EQ(std::numeric_limits<int32_t>::max(), *accessor.property_);
Chris Masone27bf1032011-06-28 17:02:01 -070095 }
mukesh agrawal292dc0f2012-01-26 18:02:46 -080096 {
97 Error error;
Ben Chan7fab8972014-08-10 17:14:46 -070098 int32_t orig_value = int_store = 0;
99 WriteOnlyPropertyAccessor<int32_t> accessor(&int_store);
mukesh agrawal292dc0f2012-01-26 18:02:46 -0800100
mukesh agrawalbebf1b82013-04-23 15:06:33 -0700101 EXPECT_TRUE(accessor.Set(127, &error));
mukesh agrawal292dc0f2012-01-26 18:02:46 -0800102 accessor.Clear(&error);
103 EXPECT_TRUE(error.IsSuccess());
104 EXPECT_EQ(orig_value, *accessor.property_);
105 }
Chris Masone27bf1032011-06-28 17:02:01 -0700106}
107
108TEST(PropertyAccessorTest, UnsignedIntCorrectness) {
Ben Chan7fab8972014-08-10 17:14:46 -0700109 uint32_t int_store = 0;
Chris Masone27bf1032011-06-28 17:02:01 -0700110 {
mukesh agrawalffa3d042011-10-06 15:26:10 -0700111 Error error;
Ben Chan7fab8972014-08-10 17:14:46 -0700112 uint32_t orig_value = int_store;
113 Uint32Accessor accessor(new PropertyAccessor<uint32_t>(&int_store));
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800114 EXPECT_EQ(int_store, accessor->Get(&error));
Chris Masone27bf1032011-06-28 17:02:01 -0700115
Ben Chan7fab8972014-08-10 17:14:46 -0700116 uint32_t expected_uint32 = 127;
mukesh agrawalbebf1b82013-04-23 15:06:33 -0700117 EXPECT_TRUE(accessor->Set(expected_uint32, &error));
mukesh agrawal292dc0f2012-01-26 18:02:46 -0800118 EXPECT_TRUE(error.IsSuccess());
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800119 EXPECT_EQ(expected_uint32, accessor->Get(&error));
mukesh agrawalbebf1b82013-04-23 15:06:33 -0700120 // Resetting to the same value should return false, but without
121 // an error.
122 EXPECT_FALSE(accessor->Set(expected_uint32, &error));
123 EXPECT_TRUE(error.IsSuccess());
Chris Masone27bf1032011-06-28 17:02:01 -0700124
mukesh agrawal292dc0f2012-01-26 18:02:46 -0800125 accessor->Clear(&error);
126 EXPECT_TRUE(error.IsSuccess());
127 EXPECT_EQ(orig_value, accessor->Get(&error));
128
Ben Chan7fab8972014-08-10 17:14:46 -0700129 int_store = std::numeric_limits<uint32_t>::max();
130 EXPECT_EQ(std::numeric_limits<uint32_t>::max(), accessor->Get(&error));
Chris Masone27bf1032011-06-28 17:02:01 -0700131 }
132 {
mukesh agrawalffa3d042011-10-06 15:26:10 -0700133 Error error;
Ben Chan7fab8972014-08-10 17:14:46 -0700134 Uint32Accessor accessor(new ConstPropertyAccessor<uint32_t>(&int_store));
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800135 EXPECT_EQ(int_store, accessor->Get(&error));
Chris Masone27bf1032011-06-28 17:02:01 -0700136
Ben Chan7fab8972014-08-10 17:14:46 -0700137 uint32_t expected_uint32 = 127;
mukesh agrawalbebf1b82013-04-23 15:06:33 -0700138 EXPECT_FALSE(accessor->Set(expected_uint32, &error));
mukesh agrawalffa3d042011-10-06 15:26:10 -0700139 ASSERT_FALSE(error.IsSuccess());
140 EXPECT_EQ(Error::kInvalidArguments, error.type());
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800141 EXPECT_EQ(int_store, accessor->Get(&error));
Chris Masone27bf1032011-06-28 17:02:01 -0700142
Ben Chan7fab8972014-08-10 17:14:46 -0700143 int_store = std::numeric_limits<uint32_t>::max();
144 EXPECT_EQ(std::numeric_limits<uint32_t>::max(), accessor->Get(&error));
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800145 }
146 {
147 Error error;
Ben Chan7fab8972014-08-10 17:14:46 -0700148 Uint32Accessor accessor(new ConstPropertyAccessor<uint32_t>(&int_store));
mukesh agrawal292dc0f2012-01-26 18:02:46 -0800149 accessor->Clear(&error);
150 ASSERT_FALSE(error.IsSuccess());
151 }
152 {
153 Error error;
Ben Chan7fab8972014-08-10 17:14:46 -0700154 Uint32Accessor accessor(
155 new WriteOnlyPropertyAccessor<uint32_t>(&int_store));
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800156 accessor->Get(&error);
mukesh agrawal292dc0f2012-01-26 18:02:46 -0800157 EXPECT_TRUE(error.IsFailure());
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800158 EXPECT_EQ(Error::kPermissionDenied, error.type());
159 }
160 {
161 Error error;
Ben Chan7fab8972014-08-10 17:14:46 -0700162 uint32_t expected_uint32 = 127;
163 WriteOnlyPropertyAccessor<uint32_t> accessor(&int_store);
mukesh agrawalbebf1b82013-04-23 15:06:33 -0700164 EXPECT_TRUE(accessor.Set(expected_uint32, &error));
mukesh agrawal292dc0f2012-01-26 18:02:46 -0800165 EXPECT_TRUE(error.IsSuccess());
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800166 EXPECT_EQ(expected_uint32, *accessor.property_);
mukesh agrawalbebf1b82013-04-23 15:06:33 -0700167 // Resetting to the same value should return false, but without
168 // an error.
169 EXPECT_FALSE(accessor.Set(expected_uint32, &error));
170 EXPECT_TRUE(error.IsSuccess());
171 // As a write-only, the value can't be read.
Ben Chan7fab8972014-08-10 17:14:46 -0700172 EXPECT_EQ(uint32_t(), accessor.Get(&error));
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800173 ASSERT_FALSE(error.IsSuccess());
174
Ben Chan7fab8972014-08-10 17:14:46 -0700175 int_store = std::numeric_limits<uint32_t>::max();
176 EXPECT_EQ(std::numeric_limits<uint32_t>::max(), *accessor.property_);
Chris Masone27bf1032011-06-28 17:02:01 -0700177 }
mukesh agrawal292dc0f2012-01-26 18:02:46 -0800178 {
179 Error error;
Ben Chan7fab8972014-08-10 17:14:46 -0700180 uint32_t orig_value = int_store = 0;
181 WriteOnlyPropertyAccessor<uint32_t> accessor(&int_store);
mukesh agrawal292dc0f2012-01-26 18:02:46 -0800182
mukesh agrawalbebf1b82013-04-23 15:06:33 -0700183 EXPECT_TRUE(accessor.Set(127, &error));
mukesh agrawal292dc0f2012-01-26 18:02:46 -0800184 accessor.Clear(&error);
185 EXPECT_TRUE(error.IsSuccess());
186 EXPECT_EQ(orig_value, *accessor.property_);
187 }
Chris Masone27bf1032011-06-28 17:02:01 -0700188}
189
190TEST(PropertyAccessorTest, StringCorrectness) {
191 string storage;
192 {
mukesh agrawalffa3d042011-10-06 15:26:10 -0700193 Error error;
mukesh agrawal292dc0f2012-01-26 18:02:46 -0800194 string orig_value = storage;
Chris Masone27bf1032011-06-28 17:02:01 -0700195 StringAccessor accessor(new PropertyAccessor<string>(&storage));
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800196 EXPECT_EQ(storage, accessor->Get(&error));
Chris Masone27bf1032011-06-28 17:02:01 -0700197
198 string expected_string("what");
mukesh agrawalbebf1b82013-04-23 15:06:33 -0700199 EXPECT_TRUE(accessor->Set(expected_string, &error));
mukesh agrawal292dc0f2012-01-26 18:02:46 -0800200 EXPECT_TRUE(error.IsSuccess());
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800201 EXPECT_EQ(expected_string, accessor->Get(&error));
mukesh agrawalbebf1b82013-04-23 15:06:33 -0700202 // Resetting to the same value should return false, but without
203 // an error.
204 EXPECT_FALSE(accessor->Set(expected_string, &error));
205 EXPECT_TRUE(error.IsSuccess());
Chris Masone27bf1032011-06-28 17:02:01 -0700206
mukesh agrawal292dc0f2012-01-26 18:02:46 -0800207 accessor->Clear(&error);
208 EXPECT_TRUE(error.IsSuccess());
209 EXPECT_EQ(orig_value, accessor->Get(&error));
210
Chris Masone27bf1032011-06-28 17:02:01 -0700211 storage = "nooooo";
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800212 EXPECT_EQ(storage, accessor->Get(&error));
Chris Masone27bf1032011-06-28 17:02:01 -0700213 }
214 {
mukesh agrawalffa3d042011-10-06 15:26:10 -0700215 Error error;
Chris Masone27bf1032011-06-28 17:02:01 -0700216 StringAccessor accessor(new ConstPropertyAccessor<string>(&storage));
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800217 EXPECT_EQ(storage, accessor->Get(&error));
Chris Masone27bf1032011-06-28 17:02:01 -0700218
219 string expected_string("what");
mukesh agrawalbebf1b82013-04-23 15:06:33 -0700220 EXPECT_FALSE(accessor->Set(expected_string, &error));
mukesh agrawalffa3d042011-10-06 15:26:10 -0700221 ASSERT_FALSE(error.IsSuccess());
222 EXPECT_EQ(Error::kInvalidArguments, error.type());
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800223 EXPECT_EQ(storage, accessor->Get(&error));
Chris Masone27bf1032011-06-28 17:02:01 -0700224
225 storage = "nooooo";
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800226 EXPECT_EQ(storage, accessor->Get(&error));
227 }
228 {
229 Error error;
mukesh agrawal292dc0f2012-01-26 18:02:46 -0800230 StringAccessor accessor(new ConstPropertyAccessor<string>(&storage));
231 accessor->Clear(&error);
232 ASSERT_FALSE(error.IsSuccess());
233 }
234 {
235 Error error;
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800236 StringAccessor accessor(new WriteOnlyPropertyAccessor<string>(&storage));
237 accessor->Get(&error);
mukesh agrawal292dc0f2012-01-26 18:02:46 -0800238 EXPECT_TRUE(error.IsFailure());
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800239 EXPECT_EQ(Error::kPermissionDenied, error.type());
240 }
241 {
242 Error error;
243 string expected_string = "what";
mukesh agrawalbebf1b82013-04-23 15:06:33 -0700244 WriteOnlyPropertyAccessor<string> accessor(&storage);
245 EXPECT_TRUE(accessor.Set(expected_string, &error));
mukesh agrawal292dc0f2012-01-26 18:02:46 -0800246 EXPECT_TRUE(error.IsSuccess());
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800247 EXPECT_EQ(expected_string, *accessor.property_);
mukesh agrawalbebf1b82013-04-23 15:06:33 -0700248 // Resetting to the same value should return false, but without
249 // an error.
250 EXPECT_FALSE(accessor.Set(expected_string, &error));
251 EXPECT_TRUE(error.IsSuccess());
252 // As a write-only, the value can't be read.
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800253 EXPECT_EQ(string(), accessor.Get(&error));
254 ASSERT_FALSE(error.IsSuccess());
255
mukesh agrawalbebf1b82013-04-23 15:06:33 -0700256 storage = "nooooo";
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800257 EXPECT_EQ("nooooo", *accessor.property_);
Chris Masone27bf1032011-06-28 17:02:01 -0700258 }
mukesh agrawal292dc0f2012-01-26 18:02:46 -0800259 {
260 Error error;
261 string orig_value = storage = "original value";
262 WriteOnlyPropertyAccessor<string> accessor(&storage);
mukesh agrawalbebf1b82013-04-23 15:06:33 -0700263 EXPECT_TRUE(accessor.Set("new value", &error));
mukesh agrawal292dc0f2012-01-26 18:02:46 -0800264 accessor.Clear(&error);
265 EXPECT_TRUE(error.IsSuccess());
266 EXPECT_EQ(orig_value, *accessor.property_);
267 }
268}
269
270class StringWrapper {
271 public:
272 string Get(Error */*error*/) {
273 return value_;
274 }
Paul Stewart1cf7eb82013-12-03 19:34:36 -0800275 string ConstGet(Error */*error*/) const {
276 return value_;
277 }
mukesh agrawalbebf1b82013-04-23 15:06:33 -0700278 bool Set(const string &value, Error */*error*/) {
279 if (value_ == value) {
280 return false;
281 }
mukesh agrawal292dc0f2012-01-26 18:02:46 -0800282 value_ = value;
mukesh agrawalbebf1b82013-04-23 15:06:33 -0700283 return true;
mukesh agrawal292dc0f2012-01-26 18:02:46 -0800284 }
285 void Clear(Error */*error*/) {
286 value_.clear();
287 }
288
289 string value_;
290};
291
292TEST(PropertyAccessorTest, CustomAccessorCorrectness) {
293 StringWrapper wrapper;
294 {
mukesh agrawalbebf1b82013-04-23 15:06:33 -0700295 // Custom accessor: read, write, write-same, clear, read-updated.
296 // Together, write and write-same verify that the CustomAccessor
297 // template passes through the value from the called function.
mukesh agrawal292dc0f2012-01-26 18:02:46 -0800298 Error error;
299 const string orig_value = wrapper.value_ = "original value";
300 CustomAccessor<StringWrapper, string> accessor(&wrapper,
301 &StringWrapper::Get,
302 &StringWrapper::Set);
303 EXPECT_EQ(orig_value, accessor.Get(&error));
304 EXPECT_TRUE(error.IsSuccess());
305
306 const string expected_string = "new value";
mukesh agrawalbebf1b82013-04-23 15:06:33 -0700307 EXPECT_TRUE(accessor.Set(expected_string, &error));
mukesh agrawal292dc0f2012-01-26 18:02:46 -0800308 EXPECT_TRUE(error.IsSuccess());
309 EXPECT_EQ(expected_string, accessor.Get(&error));
mukesh agrawalbebf1b82013-04-23 15:06:33 -0700310 // Set to same value.
311 EXPECT_FALSE(accessor.Set(expected_string, &error));
312 EXPECT_TRUE(error.IsSuccess());
mukesh agrawal292dc0f2012-01-26 18:02:46 -0800313
314 accessor.Clear(&error);
315 EXPECT_TRUE(error.IsSuccess());
316 EXPECT_EQ(orig_value, accessor.Get(&error));
317
318 wrapper.value_ = "nooooo";
319 EXPECT_EQ(wrapper.value_, accessor.Get(&error));
320 }
321 {
322 // Custom read-only accessor: read, write, read-updated.
323 Error error;
324 CustomAccessor<StringWrapper, string> accessor(&wrapper,
325 &StringWrapper::Get,
326 NULL);
327 EXPECT_EQ(wrapper.value_, accessor.Get(&error));
328
329 const string expected_string = "what";
mukesh agrawalbebf1b82013-04-23 15:06:33 -0700330 EXPECT_FALSE(accessor.Set(expected_string, &error));
mukesh agrawal292dc0f2012-01-26 18:02:46 -0800331 ASSERT_FALSE(error.IsSuccess());
332 EXPECT_EQ(Error::kInvalidArguments, error.type());
333 EXPECT_EQ(wrapper.value_, accessor.Get(&error));
334
335 wrapper.value_ = "nooooo";
336 EXPECT_EQ(wrapper.value_, accessor.Get(&error));
337 }
338 {
339 // Custom read-only accessor: clear.
340 Error error;
341 CustomAccessor<StringWrapper, string> accessor(&wrapper,
342 &StringWrapper::Get,
343 NULL);
344 accessor.Clear(&error);
345 ASSERT_FALSE(error.IsSuccess());
346 }
Paul Stewart985d7d52013-10-16 13:46:09 -0700347 {
348 // Custom read-only accessor with custom clear method.
349 Error error;
350 CustomAccessor<StringWrapper, string> accessor(&wrapper,
351 &StringWrapper::Get,
352 NULL,
353 &StringWrapper::Clear);
354 wrapper.value_ = "empty this";
355 accessor.Clear(&error);
356 ASSERT_TRUE(error.IsSuccess());
357 EXPECT_TRUE(wrapper.value_.empty());
358 }
mukesh agrawal292dc0f2012-01-26 18:02:46 -0800359}
360
361TEST(PropertyAccessorTest, CustomWriteOnlyAccessorWithDefault) {
362 StringWrapper wrapper;
363 {
364 // Test reading.
365 Error error;
366 const string default_value = "default value";
367 CustomWriteOnlyAccessor<StringWrapper, string> accessor(
368 &wrapper, &StringWrapper::Set, NULL, &default_value);
369 wrapper.value_ = "can't read this";
370 EXPECT_EQ(string(), accessor.Get(&error));
371 EXPECT_TRUE(error.IsFailure());
372 EXPECT_EQ(Error::kPermissionDenied, error.type());
373 }
374 {
375 // Test writing.
376 Error error;
377 const string default_value = "default value";
378 const string expected_string = "what";
379 CustomWriteOnlyAccessor<StringWrapper, string> accessor(
380 &wrapper, &StringWrapper::Set, NULL, &default_value);
mukesh agrawalbebf1b82013-04-23 15:06:33 -0700381 EXPECT_TRUE(accessor.Set(expected_string, &error));
mukesh agrawal292dc0f2012-01-26 18:02:46 -0800382 EXPECT_TRUE(error.IsSuccess());
383 EXPECT_EQ(expected_string, wrapper.value_);
mukesh agrawalbebf1b82013-04-23 15:06:33 -0700384 // Set to same value. With the above, this verifies that the
385 // CustomWriteOnlyAccessor template passes through the return
386 // value.
387 EXPECT_FALSE(accessor.Set(expected_string, &error));
388 EXPECT_TRUE(error.IsSuccess());
mukesh agrawal292dc0f2012-01-26 18:02:46 -0800389 }
390 {
391 // Test clearing.
392 Error error;
393 const string default_value = "default value";
394 CustomWriteOnlyAccessor<StringWrapper, string> accessor(
395 &wrapper, &StringWrapper::Set, NULL, &default_value);
396 accessor.Set("new value", &error);
397 EXPECT_EQ("new value", wrapper.value_);
398 accessor.Clear(&error);
399 EXPECT_TRUE(error.IsSuccess());
400 EXPECT_EQ(default_value, wrapper.value_);
401 }
402}
403
404TEST(PropertyAccessorTest, CustomWriteOnlyAccessorWithClear) {
405 StringWrapper wrapper;
406 {
407 // Test reading.
408 Error error;
409 CustomWriteOnlyAccessor<StringWrapper, string> accessor(
410 &wrapper, &StringWrapper::Set, &StringWrapper::Clear, NULL);
411 wrapper.value_ = "can't read this";
412 EXPECT_EQ(string(), accessor.Get(&error));
413 EXPECT_TRUE(error.IsFailure());
414 EXPECT_EQ(Error::kPermissionDenied, error.type());
415 }
416 {
417 // Test writing.
418 Error error;
419 const string expected_string = "what";
420 CustomWriteOnlyAccessor<StringWrapper, string> accessor(
421 &wrapper, &StringWrapper::Set, &StringWrapper::Clear, NULL);
mukesh agrawalbebf1b82013-04-23 15:06:33 -0700422 EXPECT_TRUE(accessor.Set(expected_string, &error));
mukesh agrawal292dc0f2012-01-26 18:02:46 -0800423 EXPECT_TRUE(error.IsSuccess());
424 EXPECT_EQ(expected_string, wrapper.value_);
mukesh agrawalbebf1b82013-04-23 15:06:33 -0700425 // Set to same value. With the above, this verifies that the
426 // CustomWriteOnlyAccessor template passes through the return
427 // value.
428 EXPECT_FALSE(accessor.Set(expected_string, &error));
429 EXPECT_TRUE(error.IsSuccess());
mukesh agrawal292dc0f2012-01-26 18:02:46 -0800430 }
431 {
432 // Test clearing.
433 Error error;
434 CustomWriteOnlyAccessor<StringWrapper, string> accessor(
435 &wrapper, &StringWrapper::Set, &StringWrapper::Clear, NULL);
mukesh agrawalbebf1b82013-04-23 15:06:33 -0700436 EXPECT_TRUE(accessor.Set("new value", &error));
mukesh agrawal292dc0f2012-01-26 18:02:46 -0800437 EXPECT_EQ("new value", wrapper.value_);
438 accessor.Clear(&error);
439 EXPECT_TRUE(error.IsSuccess());
440 EXPECT_EQ("", wrapper.value_);
441 }
Chris Masone27bf1032011-06-28 17:02:01 -0700442}
443
Paul Stewart1cf7eb82013-12-03 19:34:36 -0800444TEST(PropertyAccessorTest, CustomReadOnlyAccessor) {
445 StringWrapper wrapper;
446 CustomReadOnlyAccessor<StringWrapper, string> accessor(
447 &wrapper, &StringWrapper::ConstGet);
448 const string orig_value = wrapper.value_ = "original value";
449 {
450 // Test reading.
451 Error error;
452 EXPECT_EQ(orig_value, accessor.Get(&error));
453 EXPECT_TRUE(error.IsSuccess());
454 }
455 {
456 // Test writing.
457 Error error;
458 EXPECT_FALSE(accessor.Set("new value", &error));
459 EXPECT_EQ(Error::kInvalidArguments, error.type());
460 EXPECT_EQ(orig_value, accessor.Get(&error));
461 }
462 {
463 // Test writing original value -- this also fails.
464 Error error;
465 EXPECT_FALSE(accessor.Set(orig_value, &error));
466 EXPECT_EQ(Error::kInvalidArguments, error.type());
467 EXPECT_EQ(orig_value, accessor.Get(&error));
468 }
469 {
470 // Test clearing.
471 Error error;
472 accessor.Clear(&error);
473 EXPECT_EQ(Error::kInvalidArguments, error.type());
474 EXPECT_EQ(orig_value, accessor.Get(&error));
475 }
476}
477
Paul Stewarta61593e2012-03-23 13:06:21 -0700478class StringMapWrapper {
479 public:
480 void Clear(const string &key, Error */*error*/) {
481 value_.erase(key);
482 }
483 string Get(const string &key, Error */*error*/) {
484 EXPECT_TRUE(ContainsKey(value_, key));
485 return value_[key];
486 }
mukesh agrawalbebf1b82013-04-23 15:06:33 -0700487 bool Set(const string &key, const string &value, Error */*error*/) {
488 if (value_[key] == value) {
489 return false;
490 }
Paul Stewarta61593e2012-03-23 13:06:21 -0700491 value_[key] = value;
mukesh agrawalbebf1b82013-04-23 15:06:33 -0700492 return true;
Paul Stewarta61593e2012-03-23 13:06:21 -0700493 }
494
Alex Vakulenko8a532292014-06-16 17:18:44 -0700495 map<string, string> value_;
Paul Stewarta61593e2012-03-23 13:06:21 -0700496};
497
498TEST(PropertyAccessorTest, CustomMappedAccessor) {
499 const string kKey = "entry_key";
500 const string kValue = "entry_value";
501 {
502 // Test reading.
503 StringMapWrapper wrapper;
504 CustomMappedAccessor<StringMapWrapper, string, string> accessor(
505 &wrapper, &StringMapWrapper::Clear, &StringMapWrapper::Get,
506 &StringMapWrapper::Set, kKey);
507 wrapper.value_[kKey] = kValue;
508 Error error;
509 EXPECT_EQ(kValue, accessor.Get(&error));
510 EXPECT_TRUE(error.IsSuccess());
511 }
512 {
513 // Test writing.
514 StringMapWrapper wrapper;
515 CustomMappedAccessor<StringMapWrapper, string, string> accessor(
516 &wrapper, &StringMapWrapper::Clear, &StringMapWrapper::Get,
517 &StringMapWrapper::Set, kKey);
518 Error error;
mukesh agrawalbebf1b82013-04-23 15:06:33 -0700519 EXPECT_TRUE(accessor.Set(kValue, &error));
Paul Stewarta61593e2012-03-23 13:06:21 -0700520 EXPECT_TRUE(error.IsSuccess());
521 EXPECT_EQ(kValue, wrapper.value_[kKey]);
mukesh agrawalbebf1b82013-04-23 15:06:33 -0700522 // Set to same value. With the above, this verifies that the
523 // CustomMappedAccessor template passes through the return
524 // value.
525 EXPECT_FALSE(accessor.Set(kValue, &error));
526 EXPECT_TRUE(error.IsSuccess());
Paul Stewarta61593e2012-03-23 13:06:21 -0700527 }
528 {
529 // Test clearing.
530 StringMapWrapper wrapper;
531 CustomMappedAccessor<StringMapWrapper, string, string> accessor(
532 &wrapper, &StringMapWrapper::Clear, &StringMapWrapper::Get,
533 &StringMapWrapper::Set, kKey);
534 wrapper.value_[kKey] = kValue;
535 Error error;
536 accessor.Clear(&error);
537 EXPECT_TRUE(error.IsSuccess());
538 EXPECT_FALSE(ContainsKey(wrapper.value_, kKey));
539 }
540}
541
Chris Masone27bf1032011-06-28 17:02:01 -0700542} // namespace shill