1 //
2 // Copyright (C) 2012 The Android Open Source Project
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 // http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 //
16
17 #include "shill/property_accessor.h"
18
19 #include <limits>
20 #include <map>
21 #include <string>
22 #include <vector>
23
24 #include <base/stl_util.h>
25 #include <gtest/gtest.h>
26 #include <gmock/gmock.h>
27
28 #include "shill/error.h"
29
30 using std::map;
31 using std::string;
32 using std::vector;
33 using ::testing::Return;
34 using ::testing::Test;
35
36 namespace shill {
37
TEST(PropertyAccessorTest,SignedIntCorrectness)38 TEST(PropertyAccessorTest, SignedIntCorrectness) {
39 int32_t int_store = 0;
40 {
41 Error error;
42 int32_t orig_value = int_store;
43 Int32Accessor accessor(new PropertyAccessor<int32_t>(&int_store));
44 EXPECT_EQ(int_store, accessor->Get(&error));
45
46 int32_t expected_int32 = 127;
47 EXPECT_TRUE(accessor->Set(expected_int32, &error));
48 EXPECT_TRUE(error.IsSuccess());
49 EXPECT_EQ(expected_int32, accessor->Get(&error));
50 // Resetting to the same value should return false, but without
51 // an error.
52 EXPECT_FALSE(accessor->Set(expected_int32, &error));
53 EXPECT_TRUE(error.IsSuccess());
54
55 accessor->Clear(&error);
56 EXPECT_TRUE(error.IsSuccess());
57 EXPECT_EQ(orig_value, accessor->Get(&error));
58
59 int_store = std::numeric_limits<int32_t>::max();
60 EXPECT_EQ(std::numeric_limits<int32_t>::max(), accessor->Get(&error));
61 }
62 {
63 Error error;
64 Int32Accessor accessor(new ConstPropertyAccessor<int32_t>(&int_store));
65 EXPECT_EQ(int_store, accessor->Get(&error));
66
67 int32_t expected_int32 = 127;
68 accessor->Set(expected_int32, &error);
69 ASSERT_FALSE(error.IsSuccess());
70 EXPECT_EQ(Error::kInvalidArguments, error.type());
71 EXPECT_EQ(int_store, accessor->Get(&error));
72
73 int_store = std::numeric_limits<int32_t>::max();
74 EXPECT_EQ(std::numeric_limits<int32_t>::max(), accessor->Get(&error));
75 }
76 {
77 Error error;
78 Int32Accessor accessor(new ConstPropertyAccessor<int32_t>(&int_store));
79 accessor->Clear(&error);
80 ASSERT_FALSE(error.IsSuccess());
81 }
82 {
83 Error error;
84 Int32Accessor accessor(new WriteOnlyPropertyAccessor<int32_t>(&int_store));
85 accessor->Get(&error);
86 EXPECT_TRUE(error.IsFailure());
87 EXPECT_EQ(Error::kPermissionDenied, error.type());
88 }
89 {
90 Error error;
91 int32_t expected_int32 = 127;
92 WriteOnlyPropertyAccessor<int32_t> accessor(&int_store);
93 EXPECT_TRUE(accessor.Set(expected_int32, &error));
94 EXPECT_TRUE(error.IsSuccess());
95 EXPECT_EQ(expected_int32, *accessor.property_);
96 // Resetting to the same value should return false, but without
97 // an error.
98 EXPECT_FALSE(accessor.Set(expected_int32, &error));
99 EXPECT_TRUE(error.IsSuccess());
100 // As a write-only, the value can't be read.
101 EXPECT_EQ(int32_t(), accessor.Get(&error));
102 ASSERT_FALSE(error.IsSuccess());
103
104 int_store = std::numeric_limits<int32_t>::max();
105 EXPECT_EQ(std::numeric_limits<int32_t>::max(), *accessor.property_);
106 }
107 {
108 Error error;
109 int32_t orig_value = int_store = 0;
110 WriteOnlyPropertyAccessor<int32_t> accessor(&int_store);
111
112 EXPECT_TRUE(accessor.Set(127, &error));
113 accessor.Clear(&error);
114 EXPECT_TRUE(error.IsSuccess());
115 EXPECT_EQ(orig_value, *accessor.property_);
116 }
117 }
118
TEST(PropertyAccessorTest,UnsignedIntCorrectness)119 TEST(PropertyAccessorTest, UnsignedIntCorrectness) {
120 uint32_t int_store = 0;
121 {
122 Error error;
123 uint32_t orig_value = int_store;
124 Uint32Accessor accessor(new PropertyAccessor<uint32_t>(&int_store));
125 EXPECT_EQ(int_store, accessor->Get(&error));
126
127 uint32_t expected_uint32 = 127;
128 EXPECT_TRUE(accessor->Set(expected_uint32, &error));
129 EXPECT_TRUE(error.IsSuccess());
130 EXPECT_EQ(expected_uint32, accessor->Get(&error));
131 // Resetting to the same value should return false, but without
132 // an error.
133 EXPECT_FALSE(accessor->Set(expected_uint32, &error));
134 EXPECT_TRUE(error.IsSuccess());
135
136 accessor->Clear(&error);
137 EXPECT_TRUE(error.IsSuccess());
138 EXPECT_EQ(orig_value, accessor->Get(&error));
139
140 int_store = std::numeric_limits<uint32_t>::max();
141 EXPECT_EQ(std::numeric_limits<uint32_t>::max(), accessor->Get(&error));
142 }
143 {
144 Error error;
145 Uint32Accessor accessor(new ConstPropertyAccessor<uint32_t>(&int_store));
146 EXPECT_EQ(int_store, accessor->Get(&error));
147
148 uint32_t expected_uint32 = 127;
149 EXPECT_FALSE(accessor->Set(expected_uint32, &error));
150 ASSERT_FALSE(error.IsSuccess());
151 EXPECT_EQ(Error::kInvalidArguments, error.type());
152 EXPECT_EQ(int_store, accessor->Get(&error));
153
154 int_store = std::numeric_limits<uint32_t>::max();
155 EXPECT_EQ(std::numeric_limits<uint32_t>::max(), accessor->Get(&error));
156 }
157 {
158 Error error;
159 Uint32Accessor accessor(new ConstPropertyAccessor<uint32_t>(&int_store));
160 accessor->Clear(&error);
161 ASSERT_FALSE(error.IsSuccess());
162 }
163 {
164 Error error;
165 Uint32Accessor accessor(
166 new WriteOnlyPropertyAccessor<uint32_t>(&int_store));
167 accessor->Get(&error);
168 EXPECT_TRUE(error.IsFailure());
169 EXPECT_EQ(Error::kPermissionDenied, error.type());
170 }
171 {
172 Error error;
173 uint32_t expected_uint32 = 127;
174 WriteOnlyPropertyAccessor<uint32_t> accessor(&int_store);
175 EXPECT_TRUE(accessor.Set(expected_uint32, &error));
176 EXPECT_TRUE(error.IsSuccess());
177 EXPECT_EQ(expected_uint32, *accessor.property_);
178 // Resetting to the same value should return false, but without
179 // an error.
180 EXPECT_FALSE(accessor.Set(expected_uint32, &error));
181 EXPECT_TRUE(error.IsSuccess());
182 // As a write-only, the value can't be read.
183 EXPECT_EQ(uint32_t(), accessor.Get(&error));
184 ASSERT_FALSE(error.IsSuccess());
185
186 int_store = std::numeric_limits<uint32_t>::max();
187 EXPECT_EQ(std::numeric_limits<uint32_t>::max(), *accessor.property_);
188 }
189 {
190 Error error;
191 uint32_t orig_value = int_store = 0;
192 WriteOnlyPropertyAccessor<uint32_t> accessor(&int_store);
193
194 EXPECT_TRUE(accessor.Set(127, &error));
195 accessor.Clear(&error);
196 EXPECT_TRUE(error.IsSuccess());
197 EXPECT_EQ(orig_value, *accessor.property_);
198 }
199 }
200
TEST(PropertyAccessorTest,StringCorrectness)201 TEST(PropertyAccessorTest, StringCorrectness) {
202 string storage;
203 {
204 Error error;
205 string orig_value = storage;
206 StringAccessor accessor(new PropertyAccessor<string>(&storage));
207 EXPECT_EQ(storage, accessor->Get(&error));
208
209 string expected_string("what");
210 EXPECT_TRUE(accessor->Set(expected_string, &error));
211 EXPECT_TRUE(error.IsSuccess());
212 EXPECT_EQ(expected_string, accessor->Get(&error));
213 // Resetting to the same value should return false, but without
214 // an error.
215 EXPECT_FALSE(accessor->Set(expected_string, &error));
216 EXPECT_TRUE(error.IsSuccess());
217
218 accessor->Clear(&error);
219 EXPECT_TRUE(error.IsSuccess());
220 EXPECT_EQ(orig_value, accessor->Get(&error));
221
222 storage = "nooooo";
223 EXPECT_EQ(storage, accessor->Get(&error));
224 }
225 {
226 Error error;
227 StringAccessor accessor(new ConstPropertyAccessor<string>(&storage));
228 EXPECT_EQ(storage, accessor->Get(&error));
229
230 string expected_string("what");
231 EXPECT_FALSE(accessor->Set(expected_string, &error));
232 ASSERT_FALSE(error.IsSuccess());
233 EXPECT_EQ(Error::kInvalidArguments, error.type());
234 EXPECT_EQ(storage, accessor->Get(&error));
235
236 storage = "nooooo";
237 EXPECT_EQ(storage, accessor->Get(&error));
238 }
239 {
240 Error error;
241 StringAccessor accessor(new ConstPropertyAccessor<string>(&storage));
242 accessor->Clear(&error);
243 ASSERT_FALSE(error.IsSuccess());
244 }
245 {
246 Error error;
247 StringAccessor accessor(new WriteOnlyPropertyAccessor<string>(&storage));
248 accessor->Get(&error);
249 EXPECT_TRUE(error.IsFailure());
250 EXPECT_EQ(Error::kPermissionDenied, error.type());
251 }
252 {
253 Error error;
254 string expected_string = "what";
255 WriteOnlyPropertyAccessor<string> accessor(&storage);
256 EXPECT_TRUE(accessor.Set(expected_string, &error));
257 EXPECT_TRUE(error.IsSuccess());
258 EXPECT_EQ(expected_string, *accessor.property_);
259 // Resetting to the same value should return false, but without
260 // an error.
261 EXPECT_FALSE(accessor.Set(expected_string, &error));
262 EXPECT_TRUE(error.IsSuccess());
263 // As a write-only, the value can't be read.
264 EXPECT_EQ(string(), accessor.Get(&error));
265 ASSERT_FALSE(error.IsSuccess());
266
267 storage = "nooooo";
268 EXPECT_EQ("nooooo", *accessor.property_);
269 }
270 {
271 Error error;
272 string orig_value = storage = "original value";
273 WriteOnlyPropertyAccessor<string> accessor(&storage);
274 EXPECT_TRUE(accessor.Set("new value", &error));
275 accessor.Clear(&error);
276 EXPECT_TRUE(error.IsSuccess());
277 EXPECT_EQ(orig_value, *accessor.property_);
278 }
279 }
280
TEST(PropertyAccessorTest,ByteArrayCorrectness)281 TEST(PropertyAccessorTest, ByteArrayCorrectness) {
282 ByteArray byteArray;
283 {
284 Error error;
285 ByteArray orig_byteArray = byteArray;
286 ByteArrayAccessor accessor(new PropertyAccessor<ByteArray>(&byteArray));
287 EXPECT_EQ(byteArray, accessor->Get(&error));
288
289 ByteArray expected_byteArray({ 0x01, 0x7F, 0x80, 0xFF });
290 EXPECT_TRUE(accessor->Set(expected_byteArray, &error));
291 EXPECT_TRUE(error.IsSuccess());
292 EXPECT_EQ(expected_byteArray, accessor->Get(&error));
293
294 // Resetting to the same value should return false, but without
295 // an error.
296 EXPECT_FALSE(accessor->Set(expected_byteArray, &error));
297 EXPECT_TRUE(error.IsSuccess());
298
299 accessor->Clear(&error);
300 EXPECT_TRUE(error.IsSuccess());
301 EXPECT_EQ(orig_byteArray, accessor->Get(&error));
302
303 byteArray = ByteArray({ 0xFF, 0x7F, 0x80, 0x00 });
304 EXPECT_EQ(byteArray, accessor->Get(&error));
305 }
306 {
307 Error error;
308 ByteArrayAccessor accessor(new ConstPropertyAccessor<ByteArray>(&byteArray));
309 EXPECT_EQ(byteArray, accessor->Get(&error));
310
311 ByteArray expected_byteArray({ 0x01, 0x7F, 0x80, 0xFF });
312 EXPECT_FALSE(accessor->Set(expected_byteArray, &error));
313 ASSERT_FALSE(error.IsSuccess());
314 EXPECT_EQ(Error::kInvalidArguments, error.type());
315 EXPECT_EQ(byteArray, accessor->Get(&error));
316
317 byteArray = ByteArray({ 0xFF, 0x7F, 0x80, 0x00 });
318 EXPECT_EQ(byteArray, accessor->Get(&error));
319 }
320 {
321 Error error;
322 ByteArrayAccessor accessor(new ConstPropertyAccessor<ByteArray>(&byteArray));
323 accessor->Clear(&error);
324 ASSERT_FALSE(error.IsSuccess());
325 }
326 {
327 Error error;
328 ByteArrayAccessor accessor(new WriteOnlyPropertyAccessor<ByteArray>(&byteArray));
329 accessor->Get(&error);
330 EXPECT_TRUE(error.IsFailure());
331 EXPECT_EQ(Error::kPermissionDenied, error.type());
332 }
333 {
334 Error error;
335 ByteArray expected_byteArray({ 0x01, 0x7F, 0x80, 0xFF });
336 WriteOnlyPropertyAccessor<ByteArray> accessor(&byteArray);
337
338 EXPECT_TRUE(accessor.Set(expected_byteArray, &error));
339 EXPECT_TRUE(error.IsSuccess());
340 EXPECT_EQ(expected_byteArray, *accessor.property_);
341
342 // Resetting to the same value should return false, but without
343 // an error.
344 EXPECT_FALSE(accessor.Set(expected_byteArray, &error));
345 EXPECT_TRUE(error.IsSuccess());
346
347 // As a write-only, the value can't be read.
348 EXPECT_EQ(ByteArray(), accessor.Get(&error));
349 EXPECT_FALSE(error.IsSuccess());
350
351 byteArray = ByteArray({ 0xFF, 0x7F, 0x80, 0x00 });
352 EXPECT_EQ(ByteArray({ 0xFF, 0x7F, 0x80, 0x00 }), *accessor.property_);
353 }
354 {
355 Error error;
356 ByteArray orig_byteArray = byteArray = ByteArray({ 0x00, 0x7F, 0x80, 0xFF });
357 WriteOnlyPropertyAccessor<ByteArray> accessor(&byteArray);
358
359 EXPECT_TRUE(accessor.Set(ByteArray({ 0xFF, 0x7F, 0x80, 0x00 }), &error));
360 accessor.Clear(&error);
361 EXPECT_TRUE(error.IsSuccess());
362 EXPECT_EQ(orig_byteArray, *accessor.property_);
363 }
364 }
365
366 class StringWrapper {
367 public:
Get(Error *)368 string Get(Error* /*error*/) {
369 return value_;
370 }
ConstGet(Error *) const371 string ConstGet(Error* /*error*/) const {
372 return value_;
373 }
Set(const string & value,Error *)374 bool Set(const string& value, Error* /*error*/) {
375 if (value_ == value) {
376 return false;
377 }
378 value_ = value;
379 return true;
380 }
Clear(Error *)381 void Clear(Error* /*error*/) {
382 value_.clear();
383 }
384
385 string value_;
386 };
387
TEST(PropertyAccessorTest,CustomAccessorCorrectness)388 TEST(PropertyAccessorTest, CustomAccessorCorrectness) {
389 StringWrapper wrapper;
390 {
391 // Custom accessor: read, write, write-same, clear, read-updated.
392 // Together, write and write-same verify that the CustomAccessor
393 // template passes through the value from the called function.
394 Error error;
395 const string orig_value = wrapper.value_ = "original value";
396 CustomAccessor<StringWrapper, string> accessor(&wrapper,
397 &StringWrapper::Get,
398 &StringWrapper::Set);
399 EXPECT_EQ(orig_value, accessor.Get(&error));
400 EXPECT_TRUE(error.IsSuccess());
401
402 const string expected_string = "new value";
403 EXPECT_TRUE(accessor.Set(expected_string, &error));
404 EXPECT_TRUE(error.IsSuccess());
405 EXPECT_EQ(expected_string, accessor.Get(&error));
406 // Set to same value.
407 EXPECT_FALSE(accessor.Set(expected_string, &error));
408 EXPECT_TRUE(error.IsSuccess());
409
410 accessor.Clear(&error);
411 EXPECT_TRUE(error.IsSuccess());
412 EXPECT_EQ(orig_value, accessor.Get(&error));
413
414 wrapper.value_ = "nooooo";
415 EXPECT_EQ(wrapper.value_, accessor.Get(&error));
416 }
417 {
418 // Custom read-only accessor: read, write, read-updated.
419 Error error;
420 CustomAccessor<StringWrapper, string> accessor(&wrapper,
421 &StringWrapper::Get,
422 nullptr);
423 EXPECT_EQ(wrapper.value_, accessor.Get(&error));
424
425 const string expected_string = "what";
426 EXPECT_FALSE(accessor.Set(expected_string, &error));
427 ASSERT_FALSE(error.IsSuccess());
428 EXPECT_EQ(Error::kInvalidArguments, error.type());
429 EXPECT_EQ(wrapper.value_, accessor.Get(&error));
430
431 wrapper.value_ = "nooooo";
432 EXPECT_EQ(wrapper.value_, accessor.Get(&error));
433 }
434 {
435 // Custom read-only accessor: clear.
436 Error error;
437 CustomAccessor<StringWrapper, string> accessor(&wrapper,
438 &StringWrapper::Get,
439 nullptr);
440 accessor.Clear(&error);
441 ASSERT_FALSE(error.IsSuccess());
442 }
443 {
444 // Custom read-only accessor with custom clear method.
445 Error error;
446 CustomAccessor<StringWrapper, string> accessor(&wrapper,
447 &StringWrapper::Get,
448 nullptr,
449 &StringWrapper::Clear);
450 wrapper.value_ = "empty this";
451 accessor.Clear(&error);
452 ASSERT_TRUE(error.IsSuccess());
453 EXPECT_TRUE(wrapper.value_.empty());
454 }
455 }
456
TEST(PropertyAccessorTest,CustomWriteOnlyAccessorWithDefault)457 TEST(PropertyAccessorTest, CustomWriteOnlyAccessorWithDefault) {
458 StringWrapper wrapper;
459 {
460 // Test reading.
461 Error error;
462 const string default_value = "default value";
463 CustomWriteOnlyAccessor<StringWrapper, string> accessor(
464 &wrapper, &StringWrapper::Set, nullptr, &default_value);
465 wrapper.value_ = "can't read this";
466 EXPECT_EQ(string(), accessor.Get(&error));
467 EXPECT_TRUE(error.IsFailure());
468 EXPECT_EQ(Error::kPermissionDenied, error.type());
469 }
470 {
471 // Test writing.
472 Error error;
473 const string default_value = "default value";
474 const string expected_string = "what";
475 CustomWriteOnlyAccessor<StringWrapper, string> accessor(
476 &wrapper, &StringWrapper::Set, nullptr, &default_value);
477 EXPECT_TRUE(accessor.Set(expected_string, &error));
478 EXPECT_TRUE(error.IsSuccess());
479 EXPECT_EQ(expected_string, wrapper.value_);
480 // Set to same value. With the above, this verifies that the
481 // CustomWriteOnlyAccessor template passes through the return
482 // value.
483 EXPECT_FALSE(accessor.Set(expected_string, &error));
484 EXPECT_TRUE(error.IsSuccess());
485 }
486 {
487 // Test clearing.
488 Error error;
489 const string default_value = "default value";
490 CustomWriteOnlyAccessor<StringWrapper, string> accessor(
491 &wrapper, &StringWrapper::Set, nullptr, &default_value);
492 accessor.Set("new value", &error);
493 EXPECT_EQ("new value", wrapper.value_);
494 accessor.Clear(&error);
495 EXPECT_TRUE(error.IsSuccess());
496 EXPECT_EQ(default_value, wrapper.value_);
497 }
498 }
499
TEST(PropertyAccessorTest,CustomWriteOnlyAccessorWithClear)500 TEST(PropertyAccessorTest, CustomWriteOnlyAccessorWithClear) {
501 StringWrapper wrapper;
502 {
503 // Test reading.
504 Error error;
505 CustomWriteOnlyAccessor<StringWrapper, string> accessor(
506 &wrapper, &StringWrapper::Set, &StringWrapper::Clear, nullptr);
507 wrapper.value_ = "can't read this";
508 EXPECT_EQ(string(), accessor.Get(&error));
509 EXPECT_TRUE(error.IsFailure());
510 EXPECT_EQ(Error::kPermissionDenied, error.type());
511 }
512 {
513 // Test writing.
514 Error error;
515 const string expected_string = "what";
516 CustomWriteOnlyAccessor<StringWrapper, string> accessor(
517 &wrapper, &StringWrapper::Set, &StringWrapper::Clear, nullptr);
518 EXPECT_TRUE(accessor.Set(expected_string, &error));
519 EXPECT_TRUE(error.IsSuccess());
520 EXPECT_EQ(expected_string, wrapper.value_);
521 // Set to same value. With the above, this verifies that the
522 // CustomWriteOnlyAccessor template passes through the return
523 // value.
524 EXPECT_FALSE(accessor.Set(expected_string, &error));
525 EXPECT_TRUE(error.IsSuccess());
526 }
527 {
528 // Test clearing.
529 Error error;
530 CustomWriteOnlyAccessor<StringWrapper, string> accessor(
531 &wrapper, &StringWrapper::Set, &StringWrapper::Clear, nullptr);
532 EXPECT_TRUE(accessor.Set("new value", &error));
533 EXPECT_EQ("new value", wrapper.value_);
534 accessor.Clear(&error);
535 EXPECT_TRUE(error.IsSuccess());
536 EXPECT_EQ("", wrapper.value_);
537 }
538 }
539
TEST(PropertyAccessorTest,CustomReadOnlyAccessor)540 TEST(PropertyAccessorTest, CustomReadOnlyAccessor) {
541 StringWrapper wrapper;
542 CustomReadOnlyAccessor<StringWrapper, string> accessor(
543 &wrapper, &StringWrapper::ConstGet);
544 const string orig_value = wrapper.value_ = "original value";
545 {
546 // Test reading.
547 Error error;
548 EXPECT_EQ(orig_value, accessor.Get(&error));
549 EXPECT_TRUE(error.IsSuccess());
550 }
551 {
552 // Test writing.
553 Error error;
554 EXPECT_FALSE(accessor.Set("new value", &error));
555 EXPECT_EQ(Error::kInvalidArguments, error.type());
556 EXPECT_EQ(orig_value, accessor.Get(&error));
557 }
558 {
559 // Test writing original value -- this also fails.
560 Error error;
561 EXPECT_FALSE(accessor.Set(orig_value, &error));
562 EXPECT_EQ(Error::kInvalidArguments, error.type());
563 EXPECT_EQ(orig_value, accessor.Get(&error));
564 }
565 {
566 // Test clearing.
567 Error error;
568 accessor.Clear(&error);
569 EXPECT_EQ(Error::kInvalidArguments, error.type());
570 EXPECT_EQ(orig_value, accessor.Get(&error));
571 }
572 }
573
574 class StringMapWrapper {
575 public:
Clear(const string & key,Error *)576 void Clear(const string& key, Error* /*error*/) {
577 value_.erase(key);
578 }
Get(const string & key,Error *)579 string Get(const string& key, Error* /*error*/) {
580 EXPECT_TRUE(ContainsKey(value_, key));
581 return value_[key];
582 }
Set(const string & key,const string & value,Error *)583 bool Set(const string& key, const string& value, Error* /*error*/) {
584 if (value_[key] == value) {
585 return false;
586 }
587 value_[key] = value;
588 return true;
589 }
590
591 map<string, string> value_;
592 };
593
TEST(PropertyAccessorTest,CustomMappedAccessor)594 TEST(PropertyAccessorTest, CustomMappedAccessor) {
595 const string kKey = "entry_key";
596 const string kValue = "entry_value";
597 {
598 // Test reading.
599 StringMapWrapper wrapper;
600 CustomMappedAccessor<StringMapWrapper, string, string> accessor(
601 &wrapper, &StringMapWrapper::Clear, &StringMapWrapper::Get,
602 &StringMapWrapper::Set, kKey);
603 wrapper.value_[kKey] = kValue;
604 Error error;
605 EXPECT_EQ(kValue, accessor.Get(&error));
606 EXPECT_TRUE(error.IsSuccess());
607 }
608 {
609 // Test writing.
610 StringMapWrapper wrapper;
611 CustomMappedAccessor<StringMapWrapper, string, string> accessor(
612 &wrapper, &StringMapWrapper::Clear, &StringMapWrapper::Get,
613 &StringMapWrapper::Set, kKey);
614 Error error;
615 EXPECT_TRUE(accessor.Set(kValue, &error));
616 EXPECT_TRUE(error.IsSuccess());
617 EXPECT_EQ(kValue, wrapper.value_[kKey]);
618 // Set to same value. With the above, this verifies that the
619 // CustomMappedAccessor template passes through the return
620 // value.
621 EXPECT_FALSE(accessor.Set(kValue, &error));
622 EXPECT_TRUE(error.IsSuccess());
623 }
624 {
625 // Test clearing.
626 StringMapWrapper wrapper;
627 CustomMappedAccessor<StringMapWrapper, string, string> accessor(
628 &wrapper, &StringMapWrapper::Clear, &StringMapWrapper::Get,
629 &StringMapWrapper::Set, kKey);
630 wrapper.value_[kKey] = kValue;
631 Error error;
632 accessor.Clear(&error);
633 EXPECT_TRUE(error.IsSuccess());
634 EXPECT_FALSE(ContainsKey(wrapper.value_, kKey));
635 }
636 }
637
638 } // namespace shill
639