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 30using std::map; 31using std::string; 32using std::vector; 33using ::testing::Return; 34using ::testing::Test; 35 36namespace shill { 37 38TEST(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 119TEST(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 201TEST(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 281TEST(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 366class StringWrapper { 367 public: 368 string Get(Error* /*error*/) { 369 return value_; 370 } 371 string ConstGet(Error* /*error*/) const { 372 return value_; 373 } 374 bool Set(const string& value, Error* /*error*/) { 375 if (value_ == value) { 376 return false; 377 } 378 value_ = value; 379 return true; 380 } 381 void Clear(Error* /*error*/) { 382 value_.clear(); 383 } 384 385 string value_; 386}; 387 388TEST(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 457TEST(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 500TEST(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 540TEST(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 574class StringMapWrapper { 575 public: 576 void Clear(const string& key, Error* /*error*/) { 577 value_.erase(key); 578 } 579 string Get(const string& key, Error* /*error*/) { 580 EXPECT_TRUE(ContainsKey(value_, key)); 581 return value_[key]; 582 } 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 594TEST(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