1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "chrome/browser/value_store/value_store_unittest.h" 6 7 #include "base/json/json_writer.h" 8 #include "base/values.h" 9 10 using content::BrowserThread; 11 12 namespace { 13 14 // To save typing ValueStore::DEFAULTS everywhere. 15 const ValueStore::WriteOptions DEFAULTS = ValueStore::DEFAULTS; 16 17 // Gets the pretty-printed JSON for a value. 18 std::string GetJSON(const Value& value) { 19 std::string json; 20 base::JSONWriter::WriteWithOptions(&value, 21 base::JSONWriter::OPTIONS_PRETTY_PRINT, 22 &json); 23 return json; 24 } 25 26 } // namespace 27 28 // Compares two possibly NULL values for equality, filling |error| with an 29 // appropriate error message if they're different. 30 bool ValuesEqual( 31 const Value* expected, const Value* actual, std::string* error) { 32 if (expected == actual) { 33 return true; 34 } 35 if (expected && !actual) { 36 *error = "Expected: " + GetJSON(*expected) + ", actual: NULL"; 37 return false; 38 } 39 if (actual && !expected) { 40 *error = "Expected: NULL, actual: " + GetJSON(*actual); 41 return false; 42 } 43 if (!expected->Equals(actual)) { 44 *error = 45 "Expected: " + GetJSON(*expected) + ", actual: " + GetJSON(*actual); 46 return false; 47 } 48 return true; 49 } 50 51 // Returns whether the read result of a storage operation has the expected 52 // settings. 53 testing::AssertionResult SettingsEq( 54 const char* _1, const char* _2, 55 const DictionaryValue& expected, 56 ValueStore::ReadResult actual_result) { 57 if (actual_result->HasError()) { 58 return testing::AssertionFailure() << 59 "Result has error: " << actual_result->error(); 60 } 61 62 std::string error; 63 if (!ValuesEqual(&expected, actual_result->settings().get(), &error)) { 64 return testing::AssertionFailure() << error; 65 } 66 67 return testing::AssertionSuccess(); 68 } 69 70 // Returns whether the write result of a storage operation has the expected 71 // changes. 72 testing::AssertionResult ChangesEq( 73 const char* _1, const char* _2, 74 const ValueStoreChangeList& expected, 75 ValueStore::WriteResult actual_result) { 76 if (actual_result->HasError()) { 77 return testing::AssertionFailure() << 78 "Result has error: " << actual_result->error(); 79 } 80 81 const ValueStoreChangeList& actual = actual_result->changes(); 82 if (expected.size() != actual.size()) { 83 return testing::AssertionFailure() << 84 "Actual has wrong size, expecting " << expected.size() << 85 " but was " << actual.size(); 86 } 87 88 std::map<std::string, linked_ptr<ValueStoreChange> > expected_as_map; 89 for (ValueStoreChangeList::const_iterator it = expected.begin(); 90 it != expected.end(); ++it) { 91 expected_as_map[it->key()] = 92 linked_ptr<ValueStoreChange>(new ValueStoreChange(*it)); 93 } 94 95 std::set<std::string> keys_seen; 96 97 for (ValueStoreChangeList::const_iterator it = actual.begin(); 98 it != actual.end(); ++it) { 99 if (keys_seen.count(it->key())) { 100 return testing::AssertionFailure() << 101 "Multiple changes seen for key: " << it->key(); 102 } 103 keys_seen.insert(it->key()); 104 105 if (!expected_as_map.count(it->key())) { 106 return testing::AssertionFailure() << 107 "Actual has unexpected change for key: " << it->key(); 108 } 109 110 ValueStoreChange expected_change = *expected_as_map[it->key()]; 111 std::string error; 112 if (!ValuesEqual(expected_change.new_value(), it->new_value(), &error)) { 113 return testing::AssertionFailure() << 114 "New value for " << it->key() << " was unexpected: " << error; 115 } 116 if (!ValuesEqual(expected_change.old_value(), it->old_value(), &error)) { 117 return testing::AssertionFailure() << 118 "Old value for " << it->key() << " was unexpected: " << error; 119 } 120 } 121 122 return testing::AssertionSuccess(); 123 } 124 125 ValueStoreTest::ValueStoreTest() 126 : key1_("foo"), 127 key2_("bar"), 128 key3_("baz"), 129 empty_dict_(new DictionaryValue()), 130 dict1_(new DictionaryValue()), 131 dict3_(new DictionaryValue()), 132 dict12_(new DictionaryValue()), 133 dict123_(new DictionaryValue()), 134 ui_thread_(BrowserThread::UI, base::MessageLoop::current()), 135 file_thread_(BrowserThread::FILE, base::MessageLoop::current()) { 136 val1_.reset(Value::CreateStringValue(key1_ + "Value")); 137 val2_.reset(Value::CreateStringValue(key2_ + "Value")); 138 val3_.reset(Value::CreateStringValue(key3_ + "Value")); 139 140 list1_.push_back(key1_); 141 list2_.push_back(key2_); 142 list3_.push_back(key3_); 143 list12_.push_back(key1_); 144 list12_.push_back(key2_); 145 list13_.push_back(key1_); 146 list13_.push_back(key3_); 147 list123_.push_back(key1_); 148 list123_.push_back(key2_); 149 list123_.push_back(key3_); 150 151 set1_.insert(list1_.begin(), list1_.end()); 152 set2_.insert(list2_.begin(), list2_.end()); 153 set3_.insert(list3_.begin(), list3_.end()); 154 set12_.insert(list12_.begin(), list12_.end()); 155 set13_.insert(list13_.begin(), list13_.end()); 156 set123_.insert(list123_.begin(), list123_.end()); 157 158 dict1_->Set(key1_, val1_->DeepCopy()); 159 dict3_->Set(key3_, val3_->DeepCopy()); 160 dict12_->Set(key1_, val1_->DeepCopy()); 161 dict12_->Set(key2_, val2_->DeepCopy()); 162 dict123_->Set(key1_, val1_->DeepCopy()); 163 dict123_->Set(key2_, val2_->DeepCopy()); 164 dict123_->Set(key3_, val3_->DeepCopy()); 165 } 166 167 ValueStoreTest::~ValueStoreTest() {} 168 169 void ValueStoreTest::SetUp() { 170 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); 171 storage_.reset((GetParam())(temp_dir_.path().AppendASCII("dbName"))); 172 ASSERT_TRUE(storage_.get()); 173 } 174 175 void ValueStoreTest::TearDown() { 176 storage_.reset(); 177 } 178 179 TEST_P(ValueStoreTest, GetWhenEmpty) { 180 EXPECT_PRED_FORMAT2(SettingsEq, *empty_dict_, storage_->Get(key1_)); 181 EXPECT_PRED_FORMAT2(SettingsEq, *empty_dict_, storage_->Get(empty_list_)); 182 EXPECT_PRED_FORMAT2(SettingsEq, *empty_dict_, storage_->Get(list123_)); 183 EXPECT_PRED_FORMAT2(SettingsEq, *empty_dict_, storage_->Get()); 184 } 185 186 TEST_P(ValueStoreTest, GetWithSingleValue) { 187 { 188 ValueStoreChangeList changes; 189 changes.push_back(ValueStoreChange(key1_, NULL, val1_->DeepCopy())); 190 EXPECT_PRED_FORMAT2(ChangesEq, 191 changes, storage_->Set(DEFAULTS, key1_, *val1_)); 192 } 193 194 EXPECT_PRED_FORMAT2(SettingsEq, *dict1_, storage_->Get(key1_)); 195 EXPECT_PRED_FORMAT2(SettingsEq, *empty_dict_, storage_->Get(key2_)); 196 EXPECT_PRED_FORMAT2(SettingsEq, *empty_dict_, storage_->Get(key3_)); 197 EXPECT_PRED_FORMAT2(SettingsEq, *empty_dict_, storage_->Get(empty_list_)); 198 EXPECT_PRED_FORMAT2(SettingsEq, *dict1_, storage_->Get(list123_)); 199 EXPECT_PRED_FORMAT2(SettingsEq, *dict1_, storage_->Get()); 200 } 201 202 TEST_P(ValueStoreTest, GetWithMultipleValues) { 203 { 204 ValueStoreChangeList changes; 205 changes.push_back(ValueStoreChange(key1_, NULL, val1_->DeepCopy())); 206 changes.push_back(ValueStoreChange(key2_, NULL, val2_->DeepCopy())); 207 EXPECT_PRED_FORMAT2(ChangesEq, changes, storage_->Set(DEFAULTS, *dict12_)); 208 } 209 210 EXPECT_PRED_FORMAT2(SettingsEq, *dict1_, storage_->Get(key1_)); 211 EXPECT_PRED_FORMAT2(SettingsEq, *empty_dict_, storage_->Get(key3_)); 212 EXPECT_PRED_FORMAT2(SettingsEq, *empty_dict_, storage_->Get(empty_list_)); 213 EXPECT_PRED_FORMAT2(SettingsEq, *dict12_, storage_->Get(list123_)); 214 EXPECT_PRED_FORMAT2(SettingsEq, *dict12_, storage_->Get()); 215 } 216 217 TEST_P(ValueStoreTest, RemoveWhenEmpty) { 218 EXPECT_PRED_FORMAT2(ChangesEq, ValueStoreChangeList(), 219 storage_->Remove(key1_)); 220 221 EXPECT_PRED_FORMAT2(SettingsEq, *empty_dict_, storage_->Get(key1_)); 222 EXPECT_PRED_FORMAT2(SettingsEq, *empty_dict_, storage_->Get(list1_)); 223 EXPECT_PRED_FORMAT2(SettingsEq, *empty_dict_, storage_->Get()); 224 } 225 226 TEST_P(ValueStoreTest, RemoveWithSingleValue) { 227 storage_->Set(DEFAULTS, *dict1_); 228 { 229 ValueStoreChangeList changes; 230 changes.push_back(ValueStoreChange(key1_, val1_->DeepCopy(), NULL)); 231 EXPECT_PRED_FORMAT2(ChangesEq, changes, storage_->Remove(key1_)); 232 } 233 234 EXPECT_PRED_FORMAT2(SettingsEq, *empty_dict_, storage_->Get(key1_)); 235 EXPECT_PRED_FORMAT2(SettingsEq, *empty_dict_, storage_->Get(key2_)); 236 EXPECT_PRED_FORMAT2(SettingsEq, *empty_dict_, storage_->Get(list1_)); 237 EXPECT_PRED_FORMAT2(SettingsEq, *empty_dict_, storage_->Get(list12_)); 238 EXPECT_PRED_FORMAT2(SettingsEq, *empty_dict_, storage_->Get()); 239 } 240 241 TEST_P(ValueStoreTest, RemoveWithMultipleValues) { 242 storage_->Set(DEFAULTS, *dict123_); 243 { 244 ValueStoreChangeList changes; 245 changes.push_back(ValueStoreChange(key3_, val3_->DeepCopy(), NULL)); 246 EXPECT_PRED_FORMAT2(ChangesEq, changes, storage_->Remove(key3_)); 247 } 248 249 EXPECT_PRED_FORMAT2(SettingsEq, *dict1_, storage_->Get(key1_)); 250 EXPECT_PRED_FORMAT2(SettingsEq, *empty_dict_, storage_->Get(key3_)); 251 EXPECT_PRED_FORMAT2(SettingsEq, *empty_dict_, storage_->Get(empty_list_)); 252 EXPECT_PRED_FORMAT2(SettingsEq, *dict1_, storage_->Get(list1_)); 253 EXPECT_PRED_FORMAT2(SettingsEq, *dict12_, storage_->Get(list12_)); 254 EXPECT_PRED_FORMAT2(SettingsEq, *dict1_, storage_->Get(list13_)); 255 EXPECT_PRED_FORMAT2(SettingsEq, *dict12_, storage_->Get(list123_)); 256 EXPECT_PRED_FORMAT2(SettingsEq, *dict12_, storage_->Get()); 257 258 { 259 ValueStoreChangeList changes; 260 changes.push_back(ValueStoreChange(key1_, val1_->DeepCopy(), NULL)); 261 changes.push_back(ValueStoreChange(key2_, val2_->DeepCopy(), NULL)); 262 EXPECT_PRED_FORMAT2(ChangesEq, changes, storage_->Remove(list12_)); 263 } 264 265 EXPECT_PRED_FORMAT2(SettingsEq, *empty_dict_, storage_->Get(key1_)); 266 EXPECT_PRED_FORMAT2(SettingsEq, *empty_dict_, storage_->Get(key3_)); 267 EXPECT_PRED_FORMAT2(SettingsEq, *empty_dict_, storage_->Get(empty_list_)); 268 EXPECT_PRED_FORMAT2(SettingsEq, *empty_dict_, storage_->Get(list1_)); 269 EXPECT_PRED_FORMAT2(SettingsEq, *empty_dict_, storage_->Get(list12_)); 270 EXPECT_PRED_FORMAT2(SettingsEq, *empty_dict_, storage_->Get(list13_)); 271 EXPECT_PRED_FORMAT2(SettingsEq, *empty_dict_, storage_->Get(list123_)); 272 EXPECT_PRED_FORMAT2(SettingsEq, *empty_dict_, storage_->Get()); 273 } 274 275 TEST_P(ValueStoreTest, SetWhenOverwriting) { 276 storage_->Set(DEFAULTS, key1_, *val2_); 277 { 278 ValueStoreChangeList changes; 279 changes.push_back( 280 ValueStoreChange(key1_, val2_->DeepCopy(), val1_->DeepCopy())); 281 changes.push_back(ValueStoreChange(key2_, NULL, val2_->DeepCopy())); 282 EXPECT_PRED_FORMAT2(ChangesEq, changes, storage_->Set(DEFAULTS, *dict12_)); 283 } 284 285 EXPECT_PRED_FORMAT2(SettingsEq, *dict1_, storage_->Get(key1_)); 286 EXPECT_PRED_FORMAT2(SettingsEq, *empty_dict_, storage_->Get(key3_)); 287 EXPECT_PRED_FORMAT2(SettingsEq, *empty_dict_, storage_->Get(empty_list_)); 288 EXPECT_PRED_FORMAT2(SettingsEq, *dict1_, storage_->Get(list1_)); 289 EXPECT_PRED_FORMAT2(SettingsEq, *dict12_, storage_->Get(list12_)); 290 EXPECT_PRED_FORMAT2(SettingsEq, *dict1_, storage_->Get(list13_)); 291 EXPECT_PRED_FORMAT2(SettingsEq, *dict12_, storage_->Get(list123_)); 292 EXPECT_PRED_FORMAT2(SettingsEq, *dict12_, storage_->Get()); 293 } 294 295 TEST_P(ValueStoreTest, ClearWhenEmpty) { 296 EXPECT_PRED_FORMAT2(ChangesEq, ValueStoreChangeList(), storage_->Clear()); 297 298 EXPECT_PRED_FORMAT2(SettingsEq, *empty_dict_, storage_->Get(key1_)); 299 EXPECT_PRED_FORMAT2(SettingsEq, *empty_dict_, storage_->Get(empty_list_)); 300 EXPECT_PRED_FORMAT2(SettingsEq, *empty_dict_, storage_->Get(list123_)); 301 EXPECT_PRED_FORMAT2(SettingsEq, *empty_dict_, storage_->Get()); 302 } 303 304 TEST_P(ValueStoreTest, ClearWhenNotEmpty) { 305 storage_->Set(DEFAULTS, *dict12_); 306 { 307 ValueStoreChangeList changes; 308 changes.push_back(ValueStoreChange(key1_, val1_->DeepCopy(), NULL)); 309 changes.push_back(ValueStoreChange(key2_, val2_->DeepCopy(), NULL)); 310 EXPECT_PRED_FORMAT2(ChangesEq, changes, storage_->Clear()); 311 } 312 313 EXPECT_PRED_FORMAT2(SettingsEq, *empty_dict_, storage_->Get(key1_)); 314 EXPECT_PRED_FORMAT2(SettingsEq, *empty_dict_, storage_->Get(empty_list_)); 315 EXPECT_PRED_FORMAT2(SettingsEq, *empty_dict_, storage_->Get(list123_)); 316 EXPECT_PRED_FORMAT2(SettingsEq, *empty_dict_, storage_->Get()); 317 } 318 319 // Dots should be allowed in key names; they shouldn't be interpreted as 320 // indexing into a dictionary. 321 TEST_P(ValueStoreTest, DotsInKeyNames) { 322 std::string dot_key("foo.bar"); 323 StringValue dot_value("baz.qux"); 324 std::vector<std::string> dot_list; 325 dot_list.push_back(dot_key); 326 DictionaryValue dot_dict; 327 dot_dict.SetWithoutPathExpansion(dot_key, dot_value.DeepCopy()); 328 329 EXPECT_PRED_FORMAT2(SettingsEq, *empty_dict_, storage_->Get(dot_key)); 330 331 { 332 ValueStoreChangeList changes; 333 changes.push_back( 334 ValueStoreChange(dot_key, NULL, dot_value.DeepCopy())); 335 EXPECT_PRED_FORMAT2(ChangesEq, 336 changes, storage_->Set(DEFAULTS, dot_key, dot_value)); 337 } 338 EXPECT_PRED_FORMAT2(ChangesEq, 339 ValueStoreChangeList(), storage_->Set(DEFAULTS, dot_key, dot_value)); 340 341 EXPECT_PRED_FORMAT2(SettingsEq, dot_dict, storage_->Get(dot_key)); 342 343 { 344 ValueStoreChangeList changes; 345 changes.push_back( 346 ValueStoreChange(dot_key, dot_value.DeepCopy(), NULL)); 347 EXPECT_PRED_FORMAT2(ChangesEq, changes, storage_->Remove(dot_key)); 348 } 349 EXPECT_PRED_FORMAT2(ChangesEq, 350 ValueStoreChangeList(), storage_->Remove(dot_key)); 351 { 352 ValueStoreChangeList changes; 353 changes.push_back( 354 ValueStoreChange(dot_key, NULL, dot_value.DeepCopy())); 355 EXPECT_PRED_FORMAT2(ChangesEq, changes, storage_->Set(DEFAULTS, dot_dict)); 356 } 357 358 EXPECT_PRED_FORMAT2(SettingsEq, dot_dict, storage_->Get(dot_list)); 359 EXPECT_PRED_FORMAT2(SettingsEq, dot_dict, storage_->Get()); 360 361 { 362 ValueStoreChangeList changes; 363 changes.push_back( 364 ValueStoreChange(dot_key, dot_value.DeepCopy(), NULL)); 365 EXPECT_PRED_FORMAT2(ChangesEq, changes, storage_->Remove(dot_list)); 366 } 367 368 EXPECT_PRED_FORMAT2(SettingsEq, *empty_dict_, storage_->Get(dot_key)); 369 EXPECT_PRED_FORMAT2(SettingsEq, *empty_dict_, storage_->Get()); 370 } 371 372 TEST_P(ValueStoreTest, DotsInKeyNamesWithDicts) { 373 DictionaryValue outer_dict; 374 DictionaryValue* inner_dict = new DictionaryValue(); 375 outer_dict.Set("foo", inner_dict); 376 inner_dict->SetString("bar", "baz"); 377 378 { 379 ValueStoreChangeList changes; 380 changes.push_back( 381 ValueStoreChange("foo", NULL, inner_dict->DeepCopy())); 382 EXPECT_PRED_FORMAT2(ChangesEq, 383 changes, storage_->Set(DEFAULTS, outer_dict)); 384 } 385 386 EXPECT_PRED_FORMAT2(SettingsEq, outer_dict, storage_->Get("foo")); 387 EXPECT_PRED_FORMAT2(SettingsEq, *empty_dict_, storage_->Get("foo.bar")); 388 } 389 390 TEST_P(ValueStoreTest, ComplexChangedKeysScenarios) { 391 // Test: 392 // - Setting over missing/changed/same keys, combinations. 393 // - Removing over missing and present keys, combinations. 394 // - Clearing. 395 std::vector<std::string> complex_list; 396 DictionaryValue complex_changed_dict; 397 398 storage_->Set(DEFAULTS, key1_, *val1_); 399 EXPECT_PRED_FORMAT2(ChangesEq, 400 ValueStoreChangeList(), storage_->Set(DEFAULTS, key1_, *val1_)); 401 { 402 ValueStoreChangeList changes; 403 changes.push_back(ValueStoreChange( 404 key1_, val1_->DeepCopy(), val2_->DeepCopy())); 405 EXPECT_PRED_FORMAT2(ChangesEq, 406 changes, storage_->Set(DEFAULTS, key1_, *val2_)); 407 } 408 { 409 ValueStoreChangeList changes; 410 changes.push_back(ValueStoreChange(key1_, val2_->DeepCopy(), NULL)); 411 EXPECT_PRED_FORMAT2(ChangesEq, changes, storage_->Remove(key1_)); 412 EXPECT_PRED_FORMAT2(ChangesEq, 413 ValueStoreChangeList(), storage_->Remove(key1_)); 414 } 415 { 416 ValueStoreChangeList changes; 417 changes.push_back(ValueStoreChange(key1_, NULL, val1_->DeepCopy())); 418 EXPECT_PRED_FORMAT2(ChangesEq, 419 changes, storage_->Set(DEFAULTS, key1_, *val1_)); 420 } 421 { 422 ValueStoreChangeList changes; 423 changes.push_back(ValueStoreChange(key1_, val1_->DeepCopy(), NULL)); 424 EXPECT_PRED_FORMAT2(ChangesEq, changes, storage_->Clear()); 425 EXPECT_PRED_FORMAT2(ChangesEq, ValueStoreChangeList(), storage_->Clear()); 426 } 427 428 { 429 ValueStoreChangeList changes; 430 changes.push_back(ValueStoreChange(key1_, NULL, val1_->DeepCopy())); 431 changes.push_back(ValueStoreChange(key2_, NULL, val2_->DeepCopy())); 432 EXPECT_PRED_FORMAT2(ChangesEq, changes, storage_->Set(DEFAULTS, *dict12_)); 433 EXPECT_PRED_FORMAT2(ChangesEq, 434 ValueStoreChangeList(), storage_->Set(DEFAULTS, *dict12_)); 435 } 436 { 437 ValueStoreChangeList changes; 438 changes.push_back(ValueStoreChange(key3_, NULL, val3_->DeepCopy())); 439 EXPECT_PRED_FORMAT2(ChangesEq, changes, storage_->Set(DEFAULTS, *dict123_)); 440 } 441 { 442 DictionaryValue to_set; 443 to_set.Set(key1_, val2_->DeepCopy()); 444 to_set.Set(key2_, val2_->DeepCopy()); 445 to_set.Set("asdf", val1_->DeepCopy()); 446 to_set.Set("qwerty", val3_->DeepCopy()); 447 448 ValueStoreChangeList changes; 449 changes.push_back( 450 ValueStoreChange(key1_, val1_->DeepCopy(), val2_->DeepCopy())); 451 changes.push_back(ValueStoreChange("asdf", NULL, val1_->DeepCopy())); 452 changes.push_back( 453 ValueStoreChange("qwerty", NULL, val3_->DeepCopy())); 454 EXPECT_PRED_FORMAT2(ChangesEq, changes, storage_->Set(DEFAULTS, to_set)); 455 } 456 { 457 ValueStoreChangeList changes; 458 changes.push_back(ValueStoreChange(key1_, val2_->DeepCopy(), NULL)); 459 changes.push_back(ValueStoreChange(key2_, val2_->DeepCopy(), NULL)); 460 EXPECT_PRED_FORMAT2(ChangesEq, changes, storage_->Remove(list12_)); 461 } 462 { 463 std::vector<std::string> to_remove; 464 to_remove.push_back(key1_); 465 to_remove.push_back("asdf"); 466 467 ValueStoreChangeList changes; 468 changes.push_back(ValueStoreChange("asdf", val1_->DeepCopy(), NULL)); 469 EXPECT_PRED_FORMAT2(ChangesEq, changes, storage_->Remove(to_remove)); 470 } 471 { 472 ValueStoreChangeList changes; 473 changes.push_back(ValueStoreChange(key3_, val3_->DeepCopy(), NULL)); 474 changes.push_back( 475 ValueStoreChange("qwerty", val3_->DeepCopy(), NULL)); 476 EXPECT_PRED_FORMAT2(ChangesEq, changes, storage_->Clear()); 477 EXPECT_PRED_FORMAT2(ChangesEq, ValueStoreChangeList(), storage_->Clear()); 478 } 479 } 480