blob: b52fe1927b78e0f664df54770e874d8dad6a5d19 [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) {
28 int32 int_store = 0;
29 {
mukesh agrawalffa3d042011-10-06 15:26:10 -070030 Error error;
mukesh agrawal292dc0f2012-01-26 18:02:46 -080031 int32 orig_value = int_store;
Chris Masone27bf1032011-06-28 17:02:01 -070032 Int32Accessor accessor(new PropertyAccessor<int32>(&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
35 int32 expected_int32 = 127;
mukesh agrawalffa3d042011-10-06 15:26:10 -070036 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));
Chris Masone27bf1032011-06-28 17:02:01 -070039
mukesh agrawal292dc0f2012-01-26 18:02:46 -080040 accessor->Clear(&error);
41 EXPECT_TRUE(error.IsSuccess());
42 EXPECT_EQ(orig_value, accessor->Get(&error));
43
Chris Masone27bf1032011-06-28 17:02:01 -070044 int_store = std::numeric_limits<int32>::max();
Gaurav Shah1b7a6162011-11-09 11:41:01 -080045 EXPECT_EQ(std::numeric_limits<int32>::max(), accessor->Get(&error));
Chris Masone27bf1032011-06-28 17:02:01 -070046 }
47 {
mukesh agrawalffa3d042011-10-06 15:26:10 -070048 Error error;
Chris Masone27bf1032011-06-28 17:02:01 -070049 Int32Accessor accessor(new ConstPropertyAccessor<int32>(&int_store));
Gaurav Shah1b7a6162011-11-09 11:41:01 -080050 EXPECT_EQ(int_store, accessor->Get(&error));
Chris Masone27bf1032011-06-28 17:02:01 -070051
52 int32 expected_int32 = 127;
mukesh agrawalffa3d042011-10-06 15:26:10 -070053 accessor->Set(expected_int32, &error);
54 ASSERT_FALSE(error.IsSuccess());
55 EXPECT_EQ(Error::kInvalidArguments, error.type());
Gaurav Shah1b7a6162011-11-09 11:41:01 -080056 EXPECT_EQ(int_store, accessor->Get(&error));
Chris Masone27bf1032011-06-28 17:02:01 -070057
58 int_store = std::numeric_limits<int32>::max();
Gaurav Shah1b7a6162011-11-09 11:41:01 -080059 EXPECT_EQ(std::numeric_limits<int32>::max(), accessor->Get(&error));
60 }
61 {
62 Error error;
mukesh agrawal292dc0f2012-01-26 18:02:46 -080063 Int32Accessor accessor(new ConstPropertyAccessor<int32>(&int_store));
64 accessor->Clear(&error);
65 ASSERT_FALSE(error.IsSuccess());
66 }
67 {
68 Error error;
Gaurav Shah1b7a6162011-11-09 11:41:01 -080069 Int32Accessor accessor(new WriteOnlyPropertyAccessor<int32>(&int_store));
70 accessor->Get(&error);
mukesh agrawal292dc0f2012-01-26 18:02:46 -080071 EXPECT_TRUE(error.IsFailure());
Gaurav Shah1b7a6162011-11-09 11:41:01 -080072 EXPECT_EQ(Error::kPermissionDenied, error.type());
73 }
74 {
75 Error error;
76 int32 expected_int32 = 127;
mukesh agrawal6b883fe2012-01-30 16:38:15 -080077 WriteOnlyPropertyAccessor<int32> accessor(&int_store);
Gaurav Shah1b7a6162011-11-09 11:41:01 -080078 accessor.Set(expected_int32, &error);
mukesh agrawal292dc0f2012-01-26 18:02:46 -080079 EXPECT_TRUE(error.IsSuccess());
Gaurav Shah1b7a6162011-11-09 11:41:01 -080080 EXPECT_EQ(expected_int32, *accessor.property_);
81 EXPECT_EQ(int32(), accessor.Get(&error));
82 ASSERT_FALSE(error.IsSuccess());
83
mukesh agrawal6b883fe2012-01-30 16:38:15 -080084 int_store = std::numeric_limits<int32>::max();
Gaurav Shah1b7a6162011-11-09 11:41:01 -080085 EXPECT_EQ(std::numeric_limits<int32>::max(), *accessor.property_);
Chris Masone27bf1032011-06-28 17:02:01 -070086 }
mukesh agrawal292dc0f2012-01-26 18:02:46 -080087 {
88 Error error;
89 int32 orig_value = int_store = 0;
90 WriteOnlyPropertyAccessor<int32> accessor(&int_store);
91
92 accessor.Set(127, &error);
93 accessor.Clear(&error);
94 EXPECT_TRUE(error.IsSuccess());
95 EXPECT_EQ(orig_value, *accessor.property_);
96 }
Chris Masone27bf1032011-06-28 17:02:01 -070097}
98
99TEST(PropertyAccessorTest, UnsignedIntCorrectness) {
100 uint32 int_store = 0;
101 {
mukesh agrawalffa3d042011-10-06 15:26:10 -0700102 Error error;
mukesh agrawal292dc0f2012-01-26 18:02:46 -0800103 uint32 orig_value = int_store;
Chris Masone27bf1032011-06-28 17:02:01 -0700104 Uint32Accessor accessor(new PropertyAccessor<uint32>(&int_store));
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800105 EXPECT_EQ(int_store, accessor->Get(&error));
Chris Masone27bf1032011-06-28 17:02:01 -0700106
107 uint32 expected_uint32 = 127;
mukesh agrawalffa3d042011-10-06 15:26:10 -0700108 accessor->Set(expected_uint32, &error);
mukesh agrawal292dc0f2012-01-26 18:02:46 -0800109 EXPECT_TRUE(error.IsSuccess());
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800110 EXPECT_EQ(expected_uint32, accessor->Get(&error));
Chris Masone27bf1032011-06-28 17:02:01 -0700111
mukesh agrawal292dc0f2012-01-26 18:02:46 -0800112 accessor->Clear(&error);
113 EXPECT_TRUE(error.IsSuccess());
114 EXPECT_EQ(orig_value, accessor->Get(&error));
115
Chris Masone27bf1032011-06-28 17:02:01 -0700116 int_store = std::numeric_limits<uint32>::max();
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800117 EXPECT_EQ(std::numeric_limits<uint32>::max(), accessor->Get(&error));
Chris Masone27bf1032011-06-28 17:02:01 -0700118 }
119 {
mukesh agrawalffa3d042011-10-06 15:26:10 -0700120 Error error;
Chris Masone27bf1032011-06-28 17:02:01 -0700121 Uint32Accessor accessor(new ConstPropertyAccessor<uint32>(&int_store));
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800122 EXPECT_EQ(int_store, accessor->Get(&error));
Chris Masone27bf1032011-06-28 17:02:01 -0700123
124 uint32 expected_uint32 = 127;
mukesh agrawalffa3d042011-10-06 15:26:10 -0700125 accessor->Set(expected_uint32, &error);
126 ASSERT_FALSE(error.IsSuccess());
127 EXPECT_EQ(Error::kInvalidArguments, error.type());
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800128 EXPECT_EQ(int_store, accessor->Get(&error));
Chris Masone27bf1032011-06-28 17:02:01 -0700129
130 int_store = std::numeric_limits<uint32>::max();
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800131 EXPECT_EQ(std::numeric_limits<uint32>::max(), accessor->Get(&error));
132 }
133 {
134 Error error;
mukesh agrawal292dc0f2012-01-26 18:02:46 -0800135 Uint32Accessor accessor(new ConstPropertyAccessor<uint32>(&int_store));
136 accessor->Clear(&error);
137 ASSERT_FALSE(error.IsSuccess());
138 }
139 {
140 Error error;
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800141 Uint32Accessor accessor(new WriteOnlyPropertyAccessor<uint32>(&int_store));
142 accessor->Get(&error);
mukesh agrawal292dc0f2012-01-26 18:02:46 -0800143 EXPECT_TRUE(error.IsFailure());
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800144 EXPECT_EQ(Error::kPermissionDenied, error.type());
145 }
146 {
147 Error error;
148 uint32 expected_uint32 = 127;
mukesh agrawal6b883fe2012-01-30 16:38:15 -0800149 WriteOnlyPropertyAccessor<uint32> accessor(&int_store);
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800150 accessor.Set(expected_uint32, &error);
mukesh agrawal292dc0f2012-01-26 18:02:46 -0800151 EXPECT_TRUE(error.IsSuccess());
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800152 EXPECT_EQ(expected_uint32, *accessor.property_);
153 EXPECT_EQ(uint32(), accessor.Get(&error));
154 ASSERT_FALSE(error.IsSuccess());
155
mukesh agrawal6b883fe2012-01-30 16:38:15 -0800156 int_store = std::numeric_limits<uint32>::max();
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800157 EXPECT_EQ(std::numeric_limits<uint32>::max(), *accessor.property_);
Chris Masone27bf1032011-06-28 17:02:01 -0700158 }
mukesh agrawal292dc0f2012-01-26 18:02:46 -0800159 {
160 Error error;
161 uint32 orig_value = int_store = 0;
162 WriteOnlyPropertyAccessor<uint32> accessor(&int_store);
163
164 accessor.Set(127, &error);
165 accessor.Clear(&error);
166 EXPECT_TRUE(error.IsSuccess());
167 EXPECT_EQ(orig_value, *accessor.property_);
168 }
Chris Masone27bf1032011-06-28 17:02:01 -0700169}
170
171TEST(PropertyAccessorTest, StringCorrectness) {
172 string storage;
173 {
mukesh agrawalffa3d042011-10-06 15:26:10 -0700174 Error error;
mukesh agrawal292dc0f2012-01-26 18:02:46 -0800175 string orig_value = storage;
Chris Masone27bf1032011-06-28 17:02:01 -0700176 StringAccessor accessor(new PropertyAccessor<string>(&storage));
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800177 EXPECT_EQ(storage, accessor->Get(&error));
Chris Masone27bf1032011-06-28 17:02:01 -0700178
179 string expected_string("what");
mukesh agrawalffa3d042011-10-06 15:26:10 -0700180 accessor->Set(expected_string, &error);
mukesh agrawal292dc0f2012-01-26 18:02:46 -0800181 EXPECT_TRUE(error.IsSuccess());
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800182 EXPECT_EQ(expected_string, accessor->Get(&error));
Chris Masone27bf1032011-06-28 17:02:01 -0700183
mukesh agrawal292dc0f2012-01-26 18:02:46 -0800184 accessor->Clear(&error);
185 EXPECT_TRUE(error.IsSuccess());
186 EXPECT_EQ(orig_value, accessor->Get(&error));
187
Chris Masone27bf1032011-06-28 17:02:01 -0700188 storage = "nooooo";
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800189 EXPECT_EQ(storage, accessor->Get(&error));
Chris Masone27bf1032011-06-28 17:02:01 -0700190 }
191 {
mukesh agrawalffa3d042011-10-06 15:26:10 -0700192 Error error;
Chris Masone27bf1032011-06-28 17:02:01 -0700193 StringAccessor accessor(new ConstPropertyAccessor<string>(&storage));
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800194 EXPECT_EQ(storage, accessor->Get(&error));
Chris Masone27bf1032011-06-28 17:02:01 -0700195
196 string expected_string("what");
mukesh agrawalffa3d042011-10-06 15:26:10 -0700197 accessor->Set(expected_string, &error);
198 ASSERT_FALSE(error.IsSuccess());
199 EXPECT_EQ(Error::kInvalidArguments, error.type());
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800200 EXPECT_EQ(storage, accessor->Get(&error));
Chris Masone27bf1032011-06-28 17:02:01 -0700201
202 storage = "nooooo";
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800203 EXPECT_EQ(storage, accessor->Get(&error));
204 }
205 {
206 Error error;
mukesh agrawal292dc0f2012-01-26 18:02:46 -0800207 StringAccessor accessor(new ConstPropertyAccessor<string>(&storage));
208 accessor->Clear(&error);
209 ASSERT_FALSE(error.IsSuccess());
210 }
211 {
212 Error error;
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800213 StringAccessor accessor(new WriteOnlyPropertyAccessor<string>(&storage));
214 accessor->Get(&error);
mukesh agrawal292dc0f2012-01-26 18:02:46 -0800215 EXPECT_TRUE(error.IsFailure());
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800216 EXPECT_EQ(Error::kPermissionDenied, error.type());
217 }
218 {
219 Error error;
220 string expected_string = "what";
221 WriteOnlyPropertyAccessor<string> accessor(&expected_string);
222 accessor.Set(expected_string, &error);
mukesh agrawal292dc0f2012-01-26 18:02:46 -0800223 EXPECT_TRUE(error.IsSuccess());
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800224 EXPECT_EQ(expected_string, *accessor.property_);
225 EXPECT_EQ(string(), accessor.Get(&error));
226 ASSERT_FALSE(error.IsSuccess());
227
228 expected_string = "nooooo";
229 EXPECT_EQ("nooooo", *accessor.property_);
Chris Masone27bf1032011-06-28 17:02:01 -0700230 }
mukesh agrawal292dc0f2012-01-26 18:02:46 -0800231 {
232 Error error;
233 string orig_value = storage = "original value";
234 WriteOnlyPropertyAccessor<string> accessor(&storage);
235 accessor.Set("new value", &error);
236 accessor.Clear(&error);
237 EXPECT_TRUE(error.IsSuccess());
238 EXPECT_EQ(orig_value, *accessor.property_);
239 }
240}
241
242class StringWrapper {
243 public:
244 string Get(Error */*error*/) {
245 return value_;
246 }
247 void Set(const string &value, Error */*error*/) {
248 value_ = value;
249 }
250 void Clear(Error */*error*/) {
251 value_.clear();
252 }
253
254 string value_;
255};
256
257TEST(PropertyAccessorTest, CustomAccessorCorrectness) {
258 StringWrapper wrapper;
259 {
260 // Custom accessor: read, write, clear, read-updated.
261 Error error;
262 const string orig_value = wrapper.value_ = "original value";
263 CustomAccessor<StringWrapper, string> accessor(&wrapper,
264 &StringWrapper::Get,
265 &StringWrapper::Set);
266 EXPECT_EQ(orig_value, accessor.Get(&error));
267 EXPECT_TRUE(error.IsSuccess());
268
269 const string expected_string = "new value";
270 accessor.Set(expected_string, &error);
271 EXPECT_TRUE(error.IsSuccess());
272 EXPECT_EQ(expected_string, accessor.Get(&error));
273
274 accessor.Clear(&error);
275 EXPECT_TRUE(error.IsSuccess());
276 EXPECT_EQ(orig_value, accessor.Get(&error));
277
278 wrapper.value_ = "nooooo";
279 EXPECT_EQ(wrapper.value_, accessor.Get(&error));
280 }
281 {
282 // Custom read-only accessor: read, write, read-updated.
283 Error error;
284 CustomAccessor<StringWrapper, string> accessor(&wrapper,
285 &StringWrapper::Get,
286 NULL);
287 EXPECT_EQ(wrapper.value_, accessor.Get(&error));
288
289 const string expected_string = "what";
290 accessor.Set(expected_string, &error);
291 ASSERT_FALSE(error.IsSuccess());
292 EXPECT_EQ(Error::kInvalidArguments, error.type());
293 EXPECT_EQ(wrapper.value_, accessor.Get(&error));
294
295 wrapper.value_ = "nooooo";
296 EXPECT_EQ(wrapper.value_, accessor.Get(&error));
297 }
298 {
299 // Custom read-only accessor: clear.
300 Error error;
301 CustomAccessor<StringWrapper, string> accessor(&wrapper,
302 &StringWrapper::Get,
303 NULL);
304 accessor.Clear(&error);
305 ASSERT_FALSE(error.IsSuccess());
306 }
307}
308
309TEST(PropertyAccessorTest, CustomWriteOnlyAccessorWithDefault) {
310 StringWrapper wrapper;
311 {
312 // Test reading.
313 Error error;
314 const string default_value = "default value";
315 CustomWriteOnlyAccessor<StringWrapper, string> accessor(
316 &wrapper, &StringWrapper::Set, NULL, &default_value);
317 wrapper.value_ = "can't read this";
318 EXPECT_EQ(string(), accessor.Get(&error));
319 EXPECT_TRUE(error.IsFailure());
320 EXPECT_EQ(Error::kPermissionDenied, error.type());
321 }
322 {
323 // Test writing.
324 Error error;
325 const string default_value = "default value";
326 const string expected_string = "what";
327 CustomWriteOnlyAccessor<StringWrapper, string> accessor(
328 &wrapper, &StringWrapper::Set, NULL, &default_value);
329 accessor.Set(expected_string, &error);
330 EXPECT_TRUE(error.IsSuccess());
331 EXPECT_EQ(expected_string, wrapper.value_);
332 }
333 {
334 // Test clearing.
335 Error error;
336 const string default_value = "default value";
337 CustomWriteOnlyAccessor<StringWrapper, string> accessor(
338 &wrapper, &StringWrapper::Set, NULL, &default_value);
339 accessor.Set("new value", &error);
340 EXPECT_EQ("new value", wrapper.value_);
341 accessor.Clear(&error);
342 EXPECT_TRUE(error.IsSuccess());
343 EXPECT_EQ(default_value, wrapper.value_);
344 }
345}
346
347TEST(PropertyAccessorTest, CustomWriteOnlyAccessorWithClear) {
348 StringWrapper wrapper;
349 {
350 // Test reading.
351 Error error;
352 CustomWriteOnlyAccessor<StringWrapper, string> accessor(
353 &wrapper, &StringWrapper::Set, &StringWrapper::Clear, NULL);
354 wrapper.value_ = "can't read this";
355 EXPECT_EQ(string(), accessor.Get(&error));
356 EXPECT_TRUE(error.IsFailure());
357 EXPECT_EQ(Error::kPermissionDenied, error.type());
358 }
359 {
360 // Test writing.
361 Error error;
362 const string expected_string = "what";
363 CustomWriteOnlyAccessor<StringWrapper, string> accessor(
364 &wrapper, &StringWrapper::Set, &StringWrapper::Clear, NULL);
365 accessor.Set(expected_string, &error);
366 EXPECT_TRUE(error.IsSuccess());
367 EXPECT_EQ(expected_string, wrapper.value_);
368 }
369 {
370 // Test clearing.
371 Error error;
372 CustomWriteOnlyAccessor<StringWrapper, string> accessor(
373 &wrapper, &StringWrapper::Set, &StringWrapper::Clear, NULL);
374 accessor.Set("new value", &error);
375 EXPECT_EQ("new value", wrapper.value_);
376 accessor.Clear(&error);
377 EXPECT_TRUE(error.IsSuccess());
378 EXPECT_EQ("", wrapper.value_);
379 }
Chris Masone27bf1032011-06-28 17:02:01 -0700380}
381
Paul Stewarta61593e2012-03-23 13:06:21 -0700382class StringMapWrapper {
383 public:
384 void Clear(const string &key, Error */*error*/) {
385 value_.erase(key);
386 }
387 string Get(const string &key, Error */*error*/) {
388 EXPECT_TRUE(ContainsKey(value_, key));
389 return value_[key];
390 }
391 void Set(const string &value, const string &key, Error */*error*/) {
392 value_[key] = value;
393 }
394
395 map<string,string> value_;
396};
397
398TEST(PropertyAccessorTest, CustomMappedAccessor) {
399 const string kKey = "entry_key";
400 const string kValue = "entry_value";
401 {
402 // Test reading.
403 StringMapWrapper wrapper;
404 CustomMappedAccessor<StringMapWrapper, string, string> accessor(
405 &wrapper, &StringMapWrapper::Clear, &StringMapWrapper::Get,
406 &StringMapWrapper::Set, kKey);
407 wrapper.value_[kKey] = kValue;
408 Error error;
409 EXPECT_EQ(kValue, accessor.Get(&error));
410 EXPECT_TRUE(error.IsSuccess());
411 }
412 {
413 // Test writing.
414 StringMapWrapper wrapper;
415 CustomMappedAccessor<StringMapWrapper, string, string> accessor(
416 &wrapper, &StringMapWrapper::Clear, &StringMapWrapper::Get,
417 &StringMapWrapper::Set, kKey);
418 Error error;
419 accessor.Set(kValue, &error);
420 EXPECT_TRUE(error.IsSuccess());
421 EXPECT_EQ(kValue, wrapper.value_[kKey]);
422 }
423 {
424 // Test clearing.
425 StringMapWrapper wrapper;
426 CustomMappedAccessor<StringMapWrapper, string, string> accessor(
427 &wrapper, &StringMapWrapper::Clear, &StringMapWrapper::Get,
428 &StringMapWrapper::Set, kKey);
429 wrapper.value_[kKey] = kValue;
430 Error error;
431 accessor.Clear(&error);
432 EXPECT_TRUE(error.IsSuccess());
433 EXPECT_FALSE(ContainsKey(wrapper.value_, kKey));
434 }
435}
436
Chris Masone27bf1032011-06-28 17:02:01 -0700437} // namespace shill