indexed_db_leveldb_coding_unittest.cc revision eb525c5499e34cc9c4b825d6d9e75bb07cc06ace
1// Copyright (c) 2013 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 "content/browser/indexed_db/indexed_db_leveldb_coding.h" 6 7#include <limits> 8#include <string> 9#include <vector> 10 11#include "base/basictypes.h" 12#include "base/strings/string16.h" 13#include "base/strings/string_piece.h" 14#include "base/strings/utf_string_conversions.h" 15#include "content/browser/indexed_db/leveldb/leveldb_slice.h" 16#include "content/common/indexed_db/indexed_db_key.h" 17#include "content/common/indexed_db/indexed_db_key_path.h" 18#include "testing/gtest/include/gtest/gtest.h" 19 20using base::StringPiece; 21using WebKit::WebIDBKey; 22using WebKit::WebIDBKeyPath; 23 24namespace content { 25 26namespace { 27 28static IndexedDBKey CreateArrayIDBKey() { 29 return IndexedDBKey(IndexedDBKey::KeyArray()); 30} 31 32static IndexedDBKey CreateArrayIDBKey(const IndexedDBKey& key1) { 33 IndexedDBKey::KeyArray array; 34 array.push_back(key1); 35 return IndexedDBKey(array); 36} 37 38static IndexedDBKey CreateArrayIDBKey(const IndexedDBKey& key1, 39 const IndexedDBKey& key2) { 40 IndexedDBKey::KeyArray array; 41 array.push_back(key1); 42 array.push_back(key2); 43 return IndexedDBKey(array); 44} 45 46static std::vector<char> WrappedEncodeByte(char value) { 47 std::vector<char> buffer; 48 EncodeByte(value, &buffer); 49 return buffer; 50} 51 52TEST(IndexedDBLevelDBCodingTest, EncodeByte) { 53 std::vector<char> expected; 54 expected.push_back(0); 55 unsigned char c; 56 57 c = 0; 58 expected[0] = c; 59 EXPECT_EQ(expected, WrappedEncodeByte(c)); 60 61 c = 1; 62 expected[0] = c; 63 EXPECT_EQ(expected, WrappedEncodeByte(c)); 64 65 c = 255; 66 expected[0] = c; 67 EXPECT_EQ(expected, WrappedEncodeByte(c)); 68} 69 70TEST(IndexedDBLevelDBCodingTest, DecodeByte) { 71 std::vector<unsigned char> test_cases; 72 test_cases.push_back(0); 73 test_cases.push_back(1); 74 test_cases.push_back(255); 75 76 for (size_t i = 0; i < test_cases.size(); ++i) { 77 unsigned char n = test_cases[i]; 78 std::vector<char> v; 79 EncodeByte(n, &v); 80 81 unsigned char res; 82 ASSERT_GT(v.size(), static_cast<size_t>(0)); 83 StringPiece slice(&*v.begin(), v.size()); 84 EXPECT_TRUE(DecodeByte(&slice, &res)); 85 EXPECT_EQ(n, res); 86 EXPECT_TRUE(slice.empty()); 87 } 88 89 { 90 StringPiece slice; 91 unsigned char value; 92 EXPECT_FALSE(DecodeByte(&slice, &value)); 93 } 94} 95 96static std::vector<char> WrappedEncodeBool(bool value) { 97 std::vector<char> buffer; 98 EncodeBool(value, &buffer); 99 return buffer; 100} 101 102TEST(IndexedDBLevelDBCodingTest, EncodeBool) { 103 { 104 std::vector<char> expected; 105 expected.push_back(1); 106 EXPECT_EQ(expected, WrappedEncodeBool(true)); 107 } 108 { 109 std::vector<char> expected; 110 expected.push_back(0); 111 EXPECT_EQ(expected, WrappedEncodeBool(false)); 112 } 113} 114 115static int CompareKeys(const std::vector<char>& a, const std::vector<char>& b) { 116 bool ok; 117 int result = CompareEncodedIDBKeys(a, b, &ok); 118 EXPECT_TRUE(ok); 119 return result; 120} 121 122TEST(IndexedDBLevelDBCodingTest, MaxIDBKey) { 123 std::vector<char> max_key = MaxIDBKey(); 124 125 std::vector<char> min_key = MinIDBKey(); 126 std::vector<char> array_key; 127 EncodeIDBKey(IndexedDBKey(IndexedDBKey::KeyArray()), &array_key); 128 std::vector<char> string_key; 129 EncodeIDBKey(IndexedDBKey(ASCIIToUTF16("Hello world")), &string_key); 130 std::vector<char> number_key; 131 EncodeIDBKey(IndexedDBKey(3.14, WebIDBKey::NumberType), &number_key); 132 std::vector<char> date_key; 133 EncodeIDBKey(IndexedDBKey(1000000, WebIDBKey::DateType), &date_key); 134 135 EXPECT_GT(CompareKeys(max_key, min_key), 0); 136 EXPECT_GT(CompareKeys(max_key, array_key), 0); 137 EXPECT_GT(CompareKeys(max_key, string_key), 0); 138 EXPECT_GT(CompareKeys(max_key, number_key), 0); 139 EXPECT_GT(CompareKeys(max_key, date_key), 0); 140} 141 142TEST(IndexedDBLevelDBCodingTest, MinIDBKey) { 143 std::vector<char> min_key = MinIDBKey(); 144 145 std::vector<char> max_key = MaxIDBKey(); 146 std::vector<char> array_key; 147 EncodeIDBKey(IndexedDBKey(IndexedDBKey::KeyArray()), &array_key); 148 std::vector<char> string_key; 149 EncodeIDBKey(IndexedDBKey(ASCIIToUTF16("Hello world")), &string_key); 150 std::vector<char> number_key; 151 EncodeIDBKey(IndexedDBKey(3.14, WebIDBKey::NumberType), &number_key); 152 std::vector<char> date_key; 153 EncodeIDBKey(IndexedDBKey(1000000, WebIDBKey::DateType), &date_key); 154 155 EXPECT_LT(CompareKeys(min_key, max_key), 0); 156 EXPECT_LT(CompareKeys(min_key, array_key), 0); 157 EXPECT_LT(CompareKeys(min_key, string_key), 0); 158 EXPECT_LT(CompareKeys(min_key, number_key), 0); 159 EXPECT_LT(CompareKeys(min_key, date_key), 0); 160} 161 162static std::vector<char> WrappedEncodeInt(int64 value) { 163 std::vector<char> buffer; 164 EncodeInt(value, &buffer); 165 return buffer; 166} 167 168TEST(IndexedDBLevelDBCodingTest, EncodeInt) { 169 EXPECT_EQ(static_cast<size_t>(1), WrappedEncodeInt(0).size()); 170 EXPECT_EQ(static_cast<size_t>(1), WrappedEncodeInt(1).size()); 171 EXPECT_EQ(static_cast<size_t>(1), WrappedEncodeInt(255).size()); 172 EXPECT_EQ(static_cast<size_t>(2), WrappedEncodeInt(256).size()); 173 EXPECT_EQ(static_cast<size_t>(4), WrappedEncodeInt(0xffffffff).size()); 174#ifdef NDEBUG 175 EXPECT_EQ(static_cast<size_t>(8), WrappedEncodeInt(-1).size()); 176#endif 177} 178 179TEST(IndexedDBLevelDBCodingTest, DecodeBool) { 180 { 181 std::vector<char> encoded; 182 encoded.push_back(1); 183 StringPiece slice(&*encoded.begin(), encoded.size()); 184 bool value; 185 EXPECT_TRUE(DecodeBool(&slice, &value)); 186 EXPECT_TRUE(value); 187 EXPECT_TRUE(slice.empty()); 188 } 189 { 190 std::vector<char> encoded; 191 encoded.push_back(0); 192 StringPiece slice(&*encoded.begin(), encoded.size()); 193 bool value; 194 EXPECT_TRUE(DecodeBool(&slice, &value)); 195 EXPECT_FALSE(value); 196 EXPECT_TRUE(slice.empty()); 197 } 198 { 199 StringPiece slice; 200 bool value; 201 EXPECT_FALSE(DecodeBool(&slice, &value)); 202 } 203} 204 205TEST(IndexedDBLevelDBCodingTest, DecodeInt) { 206 std::vector<int64> test_cases; 207 test_cases.push_back(0); 208 test_cases.push_back(1); 209 test_cases.push_back(255); 210 test_cases.push_back(256); 211 test_cases.push_back(65535); 212 test_cases.push_back(655536); 213 test_cases.push_back(7711192431755665792ll); 214 test_cases.push_back(0x7fffffffffffffffll); 215#ifdef NDEBUG 216 test_cases.push_back(-3); 217#endif 218 219 for (size_t i = 0; i < test_cases.size(); ++i) { 220 int64 n = test_cases[i]; 221 std::vector<char> v = WrappedEncodeInt(n); 222 ASSERT_GT(v.size(), static_cast<size_t>(0)); 223 StringPiece slice(&*v.begin(), v.size()); 224 int64 value; 225 EXPECT_TRUE(DecodeInt(&slice, &value)); 226 EXPECT_EQ(n, value); 227 EXPECT_TRUE(slice.empty()); 228 229 // Verify decoding at an offset, to detect unaligned memory access. 230 v.insert(v.begin(), static_cast<size_t>(1), static_cast<char>(0)); 231 slice = StringPiece(&*v.begin() + 1, v.size() - 1); 232 EXPECT_TRUE(DecodeInt(&slice, &value)); 233 EXPECT_EQ(n, value); 234 EXPECT_TRUE(slice.empty()); 235 } 236 { 237 StringPiece slice; 238 int64 value; 239 EXPECT_FALSE(DecodeInt(&slice, &value)); 240 } 241} 242 243static std::vector<char> WrappedEncodeVarInt(int64 value) { 244 std::vector<char> buffer; 245 EncodeVarInt(value, &buffer); 246 return buffer; 247} 248 249TEST(IndexedDBLevelDBCodingTest, EncodeVarInt) { 250 EXPECT_EQ(static_cast<size_t>(1), WrappedEncodeVarInt(0).size()); 251 EXPECT_EQ(static_cast<size_t>(1), WrappedEncodeVarInt(1).size()); 252 EXPECT_EQ(static_cast<size_t>(2), WrappedEncodeVarInt(255).size()); 253 EXPECT_EQ(static_cast<size_t>(2), WrappedEncodeVarInt(256).size()); 254 EXPECT_EQ(static_cast<size_t>(5), WrappedEncodeVarInt(0xffffffff).size()); 255 EXPECT_EQ(static_cast<size_t>(8), 256 WrappedEncodeVarInt(0xfffffffffffffLL).size()); 257 EXPECT_EQ(static_cast<size_t>(9), 258 WrappedEncodeVarInt(0x7fffffffffffffffLL).size()); 259#ifdef NDEBUG 260 EXPECT_EQ(static_cast<size_t>(10), WrappedEncodeVarInt(-100).size()); 261#endif 262} 263 264TEST(IndexedDBLevelDBCodingTest, DecodeVarInt) { 265 std::vector<int64> test_cases; 266 test_cases.push_back(0); 267 test_cases.push_back(1); 268 test_cases.push_back(255); 269 test_cases.push_back(256); 270 test_cases.push_back(65535); 271 test_cases.push_back(655536); 272 test_cases.push_back(7711192431755665792ll); 273 test_cases.push_back(0x7fffffffffffffffll); 274#ifdef NDEBUG 275 test_cases.push_back(-3); 276#endif 277 278 for (size_t i = 0; i < test_cases.size(); ++i) { 279 int64 n = test_cases[i]; 280 std::vector<char> v = WrappedEncodeVarInt(n); 281 ASSERT_GT(v.size(), static_cast<size_t>(0)); 282 StringPiece slice(&*v.begin(), v.size()); 283 int64 res; 284 EXPECT_TRUE(DecodeVarInt(&slice, &res)); 285 EXPECT_EQ(n, res); 286 EXPECT_TRUE(slice.empty()); 287 288 slice = StringPiece(&*v.begin(), v.size() - 1); 289 EXPECT_FALSE(DecodeVarInt(&slice, &res)); 290 291 slice = StringPiece(&*v.begin(), static_cast<size_t>(0)); 292 EXPECT_FALSE(DecodeVarInt(&slice, &res)); 293 294 // Verify decoding at an offset, to detect unaligned memory access. 295 v.insert(v.begin(), static_cast<size_t>(1), static_cast<char>(0)); 296 slice = StringPiece(&*v.begin() + 1, v.size() - 1); 297 EXPECT_TRUE(DecodeVarInt(&slice, &res)); 298 EXPECT_EQ(n, res); 299 EXPECT_TRUE(slice.empty()); 300 } 301} 302 303static std::vector<char> WrappedEncodeString(string16 value) { 304 std::vector<char> buffer; 305 EncodeString(value, &buffer); 306 return buffer; 307} 308 309TEST(IndexedDBLevelDBCodingTest, EncodeString) { 310 const char16 test_string_a[] = {'f', 'o', 'o', '\0'}; 311 const char16 test_string_b[] = {0xdead, 0xbeef, '\0'}; 312 313 EXPECT_EQ(static_cast<size_t>(0), 314 WrappedEncodeString(ASCIIToUTF16("")).size()); 315 EXPECT_EQ(static_cast<size_t>(2), 316 WrappedEncodeString(ASCIIToUTF16("a")).size()); 317 EXPECT_EQ(static_cast<size_t>(6), 318 WrappedEncodeString(ASCIIToUTF16("foo")).size()); 319 EXPECT_EQ(static_cast<size_t>(6), 320 WrappedEncodeString(string16(test_string_a)).size()); 321 EXPECT_EQ(static_cast<size_t>(4), 322 WrappedEncodeString(string16(test_string_b)).size()); 323} 324 325TEST(IndexedDBLevelDBCodingTest, DecodeString) { 326 const char16 test_string_a[] = {'f', 'o', 'o', '\0'}; 327 const char16 test_string_b[] = {0xdead, 0xbeef, '\0'}; 328 329 std::vector<string16> test_cases; 330 test_cases.push_back(string16()); 331 test_cases.push_back(ASCIIToUTF16("a")); 332 test_cases.push_back(ASCIIToUTF16("foo")); 333 test_cases.push_back(test_string_a); 334 test_cases.push_back(test_string_b); 335 336 for (size_t i = 0; i < test_cases.size(); ++i) { 337 const string16& test_case = test_cases[i]; 338 std::vector<char> v = WrappedEncodeString(test_case); 339 340 StringPiece slice; 341 if (v.size()) { 342 slice = StringPiece(&*v.begin(), v.size()); 343 } 344 345 string16 result; 346 EXPECT_TRUE(DecodeString(&slice, &result)); 347 EXPECT_EQ(test_case, result); 348 EXPECT_TRUE(slice.empty()); 349 350 // Verify decoding at an offset, to detect unaligned memory access. 351 v.insert(v.begin(), static_cast<size_t>(1), static_cast<char>(0)); 352 slice = StringPiece(&*v.begin() + 1, v.size() - 1); 353 EXPECT_TRUE(DecodeString(&slice, &result)); 354 EXPECT_EQ(test_case, result); 355 EXPECT_TRUE(slice.empty()); 356 } 357} 358 359static std::vector<char> WrappedEncodeStringWithLength(string16 value) { 360 std::vector<char> buffer; 361 EncodeStringWithLength(value, &buffer); 362 return buffer; 363} 364 365TEST(IndexedDBLevelDBCodingTest, EncodeStringWithLength) { 366 const char16 test_string_a[] = {'f', 'o', 'o', '\0'}; 367 const char16 test_string_b[] = {0xdead, 0xbeef, '\0'}; 368 369 EXPECT_EQ(static_cast<size_t>(1), 370 WrappedEncodeStringWithLength(string16()).size()); 371 EXPECT_EQ(static_cast<size_t>(3), 372 WrappedEncodeStringWithLength(ASCIIToUTF16("a")).size()); 373 EXPECT_EQ(static_cast<size_t>(7), 374 WrappedEncodeStringWithLength(string16(test_string_a)).size()); 375 EXPECT_EQ(static_cast<size_t>(5), 376 WrappedEncodeStringWithLength(string16(test_string_b)).size()); 377} 378 379TEST(IndexedDBLevelDBCodingTest, DecodeStringWithLength) { 380 const char16 test_string_a[] = {'f', 'o', 'o', '\0'}; 381 const char16 test_string_b[] = {0xdead, 0xbeef, '\0'}; 382 383 const int kLongStringLen = 1234; 384 char16 long_string[kLongStringLen + 1]; 385 for (int i = 0; i < kLongStringLen; ++i) 386 long_string[i] = i; 387 long_string[kLongStringLen] = 0; 388 389 std::vector<string16> test_cases; 390 test_cases.push_back(ASCIIToUTF16("")); 391 test_cases.push_back(ASCIIToUTF16("a")); 392 test_cases.push_back(ASCIIToUTF16("foo")); 393 test_cases.push_back(string16(test_string_a)); 394 test_cases.push_back(string16(test_string_b)); 395 test_cases.push_back(string16(long_string)); 396 397 for (size_t i = 0; i < test_cases.size(); ++i) { 398 string16 s = test_cases[i]; 399 std::vector<char> v = WrappedEncodeStringWithLength(s); 400 ASSERT_GT(v.size(), static_cast<size_t>(0)); 401 StringPiece slice(&*v.begin(), v.size()); 402 string16 res; 403 EXPECT_TRUE(DecodeStringWithLength(&slice, &res)); 404 EXPECT_EQ(s, res); 405 EXPECT_TRUE(slice.empty()); 406 407 slice = StringPiece(&*v.begin(), v.size() - 1); 408 EXPECT_FALSE(DecodeStringWithLength(&slice, &res)); 409 410 slice = StringPiece(&*v.begin(), static_cast<size_t>(0)); 411 EXPECT_FALSE(DecodeStringWithLength(&slice, &res)); 412 413 // Verify decoding at an offset, to detect unaligned memory access. 414 v.insert(v.begin(), static_cast<size_t>(1), static_cast<char>(0)); 415 slice = StringPiece(&*v.begin() + 1, v.size() - 1); 416 EXPECT_TRUE(DecodeStringWithLength(&slice, &res)); 417 EXPECT_EQ(s, res); 418 EXPECT_TRUE(slice.empty()); 419 } 420} 421 422static int CompareStrings(const std::vector<char>& p, 423 const std::vector<char>& q) { 424 bool ok; 425 DCHECK(!p.empty()); 426 DCHECK(!q.empty()); 427 StringPiece slice_p(&*p.begin(), p.size()); 428 StringPiece slice_q(&*q.begin(), q.size()); 429 int result = CompareEncodedStringsWithLength(&slice_p, &slice_q, &ok); 430 EXPECT_TRUE(ok); 431 EXPECT_TRUE(slice_p.empty()); 432 EXPECT_TRUE(slice_q.empty()); 433 return result; 434} 435 436TEST(IndexedDBLevelDBCodingTest, CompareEncodedStringsWithLength) { 437 const char16 test_string_a[] = {0x1000, 0x1000, '\0'}; 438 const char16 test_string_b[] = {0x1000, 0x1000, 0x1000, '\0'}; 439 const char16 test_string_c[] = {0x1000, 0x1000, 0x1001, '\0'}; 440 const char16 test_string_d[] = {0x1001, 0x1000, 0x1000, '\0'}; 441 const char16 test_string_e[] = {0xd834, 0xdd1e, '\0'}; 442 const char16 test_string_f[] = {0xfffd, '\0'}; 443 444 std::vector<string16> test_cases; 445 test_cases.push_back(ASCIIToUTF16("")); 446 test_cases.push_back(ASCIIToUTF16("a")); 447 test_cases.push_back(ASCIIToUTF16("b")); 448 test_cases.push_back(ASCIIToUTF16("baaa")); 449 test_cases.push_back(ASCIIToUTF16("baab")); 450 test_cases.push_back(ASCIIToUTF16("c")); 451 test_cases.push_back(string16(test_string_a)); 452 test_cases.push_back(string16(test_string_b)); 453 test_cases.push_back(string16(test_string_c)); 454 test_cases.push_back(string16(test_string_d)); 455 test_cases.push_back(string16(test_string_e)); 456 test_cases.push_back(string16(test_string_f)); 457 458 for (size_t i = 0; i < test_cases.size() - 1; ++i) { 459 string16 a = test_cases[i]; 460 string16 b = test_cases[i + 1]; 461 462 EXPECT_LT(a.compare(b), 0); 463 EXPECT_GT(b.compare(a), 0); 464 EXPECT_EQ(a.compare(a), 0); 465 EXPECT_EQ(b.compare(b), 0); 466 467 std::vector<char> encoded_a = WrappedEncodeStringWithLength(a); 468 EXPECT_TRUE(encoded_a.size()); 469 std::vector<char> encoded_b = WrappedEncodeStringWithLength(b); 470 EXPECT_TRUE(encoded_a.size()); 471 472 EXPECT_LT(CompareStrings(encoded_a, encoded_b), 0); 473 EXPECT_GT(CompareStrings(encoded_b, encoded_a), 0); 474 EXPECT_EQ(CompareStrings(encoded_a, encoded_a), 0); 475 EXPECT_EQ(CompareStrings(encoded_b, encoded_b), 0); 476 } 477} 478 479static std::vector<char> WrappedEncodeDouble(double value) { 480 std::vector<char> buffer; 481 EncodeDouble(value, &buffer); 482 return buffer; 483} 484 485TEST(IndexedDBLevelDBCodingTest, EncodeDouble) { 486 EXPECT_EQ(static_cast<size_t>(8), WrappedEncodeDouble(0).size()); 487 EXPECT_EQ(static_cast<size_t>(8), WrappedEncodeDouble(3.14).size()); 488} 489 490TEST(IndexedDBLevelDBCodingTest, DecodeDouble) { 491 std::vector<double> test_cases; 492 test_cases.push_back(3.14); 493 test_cases.push_back(-3.14); 494 495 for (size_t i = 0; i < test_cases.size(); ++i) { 496 double value = test_cases[i]; 497 std::vector<char> v = WrappedEncodeDouble(value); 498 ASSERT_GT(v.size(), static_cast<size_t>(0)); 499 StringPiece slice(&*v.begin(), v.size()); 500 double result; 501 EXPECT_TRUE(DecodeDouble(&slice, &result)); 502 EXPECT_EQ(value, result); 503 EXPECT_TRUE(slice.empty()); 504 505 slice = StringPiece(&*v.begin(), v.size() - 1); 506 EXPECT_FALSE(DecodeDouble(&slice, &result)); 507 508 slice = StringPiece(&*v.begin(), static_cast<size_t>(0)); 509 EXPECT_FALSE(DecodeDouble(&slice, &result)); 510 511 // Verify decoding at an offset, to detect unaligned memory access. 512 v.insert(v.begin(), static_cast<size_t>(1), static_cast<char>(0)); 513 slice = StringPiece(&*v.begin() + 1, v.size() - 1); 514 EXPECT_TRUE(DecodeDouble(&slice, &result)); 515 EXPECT_EQ(value, result); 516 EXPECT_TRUE(slice.empty()); 517 } 518} 519 520TEST(IndexedDBLevelDBCodingTest, EncodeDecodeIDBKey) { 521 IndexedDBKey expected_key; 522 scoped_ptr<IndexedDBKey> decoded_key; 523 std::vector<char> v; 524 StringPiece slice; 525 526 std::vector<IndexedDBKey> test_cases; 527 test_cases.push_back(IndexedDBKey(1234, WebIDBKey::NumberType)); 528 test_cases.push_back(IndexedDBKey(7890, WebIDBKey::DateType)); 529 test_cases.push_back(IndexedDBKey(ASCIIToUTF16("Hello World!"))); 530 test_cases.push_back(IndexedDBKey(IndexedDBKey::KeyArray())); 531 532 IndexedDBKey::KeyArray array; 533 array.push_back(IndexedDBKey(1234, WebIDBKey::NumberType)); 534 array.push_back(IndexedDBKey(7890, WebIDBKey::DateType)); 535 array.push_back(IndexedDBKey(ASCIIToUTF16("Hello World!"))); 536 array.push_back(IndexedDBKey(IndexedDBKey::KeyArray())); 537 test_cases.push_back(IndexedDBKey(array)); 538 539 for (size_t i = 0; i < test_cases.size(); ++i) { 540 expected_key = test_cases[i]; 541 v.clear(); 542 EncodeIDBKey(expected_key, &v); 543 slice = StringPiece(&*v.begin(), v.size()); 544 EXPECT_TRUE(DecodeIDBKey(&slice, &decoded_key)); 545 EXPECT_TRUE(decoded_key->IsEqual(expected_key)); 546 EXPECT_TRUE(slice.empty()); 547 548 slice = StringPiece(&*v.begin(), v.size() - 1); 549 EXPECT_FALSE(DecodeIDBKey(&slice, &decoded_key)); 550 551 slice = StringPiece(&*v.begin(), static_cast<size_t>(0)); 552 EXPECT_FALSE(DecodeIDBKey(&slice, &decoded_key)); 553 } 554} 555 556static std::vector<char> WrappedEncodeIDBKeyPath( 557 const IndexedDBKeyPath& value) { 558 std::vector<char> buffer; 559 EncodeIDBKeyPath(value, &buffer); 560 return buffer; 561} 562 563TEST(IndexedDBLevelDBCodingTest, EncodeDecodeIDBKeyPath) { 564 std::vector<IndexedDBKeyPath> key_paths; 565 std::vector<std::vector<char> > encoded_paths; 566 567 { 568 key_paths.push_back(IndexedDBKeyPath()); 569 char expected[] = {0, 0, // Header 570 0 // Type is null 571 }; 572 encoded_paths.push_back( 573 std::vector<char>(expected, expected + arraysize(expected))); 574 } 575 576 { 577 key_paths.push_back(IndexedDBKeyPath(string16())); 578 char expected[] = {0, 0, // Header 579 1, // Type is string 580 0 // Length is 0 581 }; 582 encoded_paths.push_back( 583 std::vector<char>(expected, expected + arraysize(expected))); 584 } 585 586 { 587 key_paths.push_back(IndexedDBKeyPath(ASCIIToUTF16("foo"))); 588 char expected[] = {0, 0, // Header 589 1, // Type is string 590 3, 0, 'f', 0, 'o', 0, 'o' // String length 3, UTF-16BE 591 }; 592 encoded_paths.push_back( 593 std::vector<char>(expected, expected + arraysize(expected))); 594 } 595 596 { 597 key_paths.push_back(IndexedDBKeyPath(ASCIIToUTF16("foo.bar"))); 598 char expected[] = {0, 0, // Header 599 1, // Type is string 600 7, 0, 'f', 0, 'o', 0, 'o', 0, '.', 0, 'b', 0, 'a', 0, 601 'r' // String length 7, UTF-16BE 602 }; 603 encoded_paths.push_back( 604 std::vector<char>(expected, expected + arraysize(expected))); 605 } 606 607 { 608 std::vector<string16> array; 609 array.push_back(string16()); 610 array.push_back(ASCIIToUTF16("foo")); 611 array.push_back(ASCIIToUTF16("foo.bar")); 612 613 key_paths.push_back(IndexedDBKeyPath(array)); 614 char expected[] = {0, 0, // Header 615 2, 3, // Type is array, length is 3 616 0, // Member 1 (String length 0) 617 3, 0, 'f', 0, 'o', 0, 'o', // Member 2 (String length 3) 618 7, 0, 'f', 0, 'o', 0, 'o', 0, '.', 0, 'b', 0, 'a', 0, 619 'r' // Member 3 (String length 7) 620 }; 621 encoded_paths.push_back( 622 std::vector<char>(expected, expected + arraysize(expected))); 623 } 624 625 ASSERT_EQ(key_paths.size(), encoded_paths.size()); 626 for (size_t i = 0; i < key_paths.size(); ++i) { 627 IndexedDBKeyPath key_path = key_paths[i]; 628 std::vector<char> encoded = encoded_paths[i]; 629 630 std::vector<char> v = WrappedEncodeIDBKeyPath(key_path); 631 EXPECT_EQ(encoded, v); 632 633 StringPiece slice(&*encoded.begin(), encoded.size()); 634 IndexedDBKeyPath decoded; 635 EXPECT_TRUE(DecodeIDBKeyPath(&slice, &decoded)); 636 EXPECT_EQ(key_path, decoded); 637 EXPECT_TRUE(slice.empty()); 638 } 639} 640 641TEST(IndexedDBLevelDBCodingTest, DecodeLegacyIDBKeyPath) { 642 // Legacy encoding of string key paths. 643 std::vector<IndexedDBKeyPath> key_paths; 644 std::vector<std::string> encoded_paths; 645 646 { 647 key_paths.push_back(IndexedDBKeyPath(string16())); 648 encoded_paths.push_back(std::string()); 649 } 650 { 651 key_paths.push_back(IndexedDBKeyPath(ASCIIToUTF16("foo"))); 652 char expected[] = {0, 'f', 0, 'o', 0, 'o'}; 653 encoded_paths.push_back(std::string(expected, arraysize(expected))); 654 } 655 { 656 key_paths.push_back(IndexedDBKeyPath(ASCIIToUTF16("foo.bar"))); 657 char expected[] = {0, 'f', 0, 'o', 0, 'o', 0, '.', 0, 'b', 0, 'a', 0, 'r'}; 658 encoded_paths.push_back(std::string(expected, arraysize(expected))); 659 } 660 661 ASSERT_EQ(key_paths.size(), encoded_paths.size()); 662 for (size_t i = 0; i < key_paths.size(); ++i) { 663 IndexedDBKeyPath key_path = key_paths[i]; 664 std::string encoded = encoded_paths[i]; 665 666 StringPiece slice(encoded); 667 IndexedDBKeyPath decoded; 668 EXPECT_TRUE(DecodeIDBKeyPath(&slice, &decoded)); 669 EXPECT_EQ(key_path, decoded); 670 EXPECT_TRUE(slice.empty()); 671 } 672} 673 674TEST(IndexedDBLevelDBCodingTest, ExtractAndCompareIDBKeys) { 675 std::vector<IndexedDBKey> keys; 676 677 keys.push_back(IndexedDBKey(-10, WebIDBKey::NumberType)); 678 keys.push_back(IndexedDBKey(0, WebIDBKey::NumberType)); 679 keys.push_back(IndexedDBKey(3.14, WebIDBKey::NumberType)); 680 681 keys.push_back(IndexedDBKey(0, WebIDBKey::DateType)); 682 keys.push_back(IndexedDBKey(100, WebIDBKey::DateType)); 683 keys.push_back(IndexedDBKey(100000, WebIDBKey::DateType)); 684 685 keys.push_back(IndexedDBKey(ASCIIToUTF16(""))); 686 keys.push_back(IndexedDBKey(ASCIIToUTF16("a"))); 687 keys.push_back(IndexedDBKey(ASCIIToUTF16("b"))); 688 keys.push_back(IndexedDBKey(ASCIIToUTF16("baaa"))); 689 keys.push_back(IndexedDBKey(ASCIIToUTF16("baab"))); 690 keys.push_back(IndexedDBKey(ASCIIToUTF16("c"))); 691 692 keys.push_back(CreateArrayIDBKey()); 693 keys.push_back(CreateArrayIDBKey(IndexedDBKey(0, WebIDBKey::NumberType))); 694 keys.push_back(CreateArrayIDBKey(IndexedDBKey(0, WebIDBKey::NumberType), 695 IndexedDBKey(3.14, WebIDBKey::NumberType))); 696 keys.push_back(CreateArrayIDBKey(IndexedDBKey(0, WebIDBKey::DateType))); 697 keys.push_back(CreateArrayIDBKey(IndexedDBKey(0, WebIDBKey::DateType), 698 IndexedDBKey(0, WebIDBKey::DateType))); 699 keys.push_back(CreateArrayIDBKey(IndexedDBKey(ASCIIToUTF16("")))); 700 keys.push_back(CreateArrayIDBKey(IndexedDBKey(ASCIIToUTF16("")), 701 IndexedDBKey(ASCIIToUTF16("a")))); 702 keys.push_back(CreateArrayIDBKey(CreateArrayIDBKey())); 703 keys.push_back(CreateArrayIDBKey(CreateArrayIDBKey(), CreateArrayIDBKey())); 704 keys.push_back(CreateArrayIDBKey(CreateArrayIDBKey(CreateArrayIDBKey()))); 705 keys.push_back(CreateArrayIDBKey( 706 CreateArrayIDBKey(CreateArrayIDBKey(CreateArrayIDBKey())))); 707 708 for (size_t i = 0; i < keys.size() - 1; ++i) { 709 const IndexedDBKey& key_a = keys[i]; 710 const IndexedDBKey& key_b = keys[i + 1]; 711 712 EXPECT_TRUE(key_a.IsLessThan(key_b)); 713 714 std::vector<char> encoded_a; 715 EncodeIDBKey(key_a, &encoded_a); 716 EXPECT_TRUE(encoded_a.size()); 717 std::vector<char> encoded_b; 718 EncodeIDBKey(key_b, &encoded_b); 719 EXPECT_TRUE(encoded_b.size()); 720 721 std::vector<char> extracted_a; 722 std::vector<char> extracted_b; 723 StringPiece slice; 724 725 slice = StringPiece(&*encoded_a.begin(), encoded_a.size()); 726 EXPECT_TRUE(ExtractEncodedIDBKey(&slice, &extracted_a)); 727 EXPECT_TRUE(slice.empty()); 728 EXPECT_EQ(encoded_a, extracted_a); 729 730 slice = StringPiece(&*encoded_b.begin(), encoded_b.size()); 731 EXPECT_TRUE(ExtractEncodedIDBKey(&slice, &extracted_b)); 732 EXPECT_TRUE(slice.empty()); 733 EXPECT_EQ(encoded_b, extracted_b); 734 735 EXPECT_LT(CompareKeys(extracted_a, extracted_b), 0); 736 EXPECT_GT(CompareKeys(extracted_b, extracted_a), 0); 737 EXPECT_EQ(CompareKeys(extracted_a, extracted_a), 0); 738 EXPECT_EQ(CompareKeys(extracted_b, extracted_b), 0); 739 740 slice = StringPiece(&*encoded_a.begin(), encoded_a.size() - 1); 741 EXPECT_FALSE(ExtractEncodedIDBKey(&slice, &extracted_a)); 742 } 743} 744 745TEST(IndexedDBLevelDBCodingTest, ComparisonTest) { 746 std::vector<std::vector<char> > keys; 747 keys.push_back(SchemaVersionKey::Encode()); 748 keys.push_back(MaxDatabaseIdKey::Encode()); 749 keys.push_back(DatabaseFreeListKey::Encode(0)); 750 keys.push_back(DatabaseFreeListKey::EncodeMaxKey()); 751 keys.push_back(DatabaseNameKey::Encode("", ASCIIToUTF16(""))); 752 keys.push_back(DatabaseNameKey::Encode("", ASCIIToUTF16("a"))); 753 keys.push_back(DatabaseNameKey::Encode("a", ASCIIToUTF16("a"))); 754 keys.push_back( 755 DatabaseMetaDataKey::Encode(1, DatabaseMetaDataKey::ORIGIN_NAME)); 756 keys.push_back( 757 DatabaseMetaDataKey::Encode(1, DatabaseMetaDataKey::DATABASE_NAME)); 758 keys.push_back( 759 DatabaseMetaDataKey::Encode(1, DatabaseMetaDataKey::USER_VERSION)); 760 keys.push_back( 761 DatabaseMetaDataKey::Encode(1, DatabaseMetaDataKey::MAX_OBJECT_STORE_ID)); 762 keys.push_back( 763 DatabaseMetaDataKey::Encode(1, DatabaseMetaDataKey::USER_INT_VERSION)); 764 keys.push_back( 765 ObjectStoreMetaDataKey::Encode(1, 1, ObjectStoreMetaDataKey::NAME)); 766 keys.push_back( 767 ObjectStoreMetaDataKey::Encode(1, 1, ObjectStoreMetaDataKey::KEY_PATH)); 768 keys.push_back(ObjectStoreMetaDataKey::Encode( 769 1, 1, ObjectStoreMetaDataKey::AUTO_INCREMENT)); 770 keys.push_back( 771 ObjectStoreMetaDataKey::Encode(1, 1, ObjectStoreMetaDataKey::EVICTABLE)); 772 keys.push_back(ObjectStoreMetaDataKey::Encode( 773 1, 1, ObjectStoreMetaDataKey::LAST_VERSION)); 774 keys.push_back(ObjectStoreMetaDataKey::Encode( 775 1, 1, ObjectStoreMetaDataKey::MAX_INDEX_ID)); 776 keys.push_back(ObjectStoreMetaDataKey::Encode( 777 1, 1, ObjectStoreMetaDataKey::HAS_KEY_PATH)); 778 keys.push_back(ObjectStoreMetaDataKey::Encode( 779 1, 1, ObjectStoreMetaDataKey::KEY_GENERATOR_CURRENT_NUMBER)); 780 keys.push_back(ObjectStoreMetaDataKey::EncodeMaxKey(1, 1)); 781 keys.push_back(ObjectStoreMetaDataKey::EncodeMaxKey(1, 2)); 782 keys.push_back(ObjectStoreMetaDataKey::EncodeMaxKey(1)); 783 keys.push_back(IndexMetaDataKey::Encode(1, 1, 30, IndexMetaDataKey::NAME)); 784 keys.push_back(IndexMetaDataKey::Encode(1, 1, 30, IndexMetaDataKey::UNIQUE)); 785 keys.push_back( 786 IndexMetaDataKey::Encode(1, 1, 30, IndexMetaDataKey::KEY_PATH)); 787 keys.push_back( 788 IndexMetaDataKey::Encode(1, 1, 30, IndexMetaDataKey::MULTI_ENTRY)); 789 keys.push_back(IndexMetaDataKey::Encode(1, 1, 31, 0)); 790 keys.push_back(IndexMetaDataKey::Encode(1, 1, 31, 1)); 791 keys.push_back(IndexMetaDataKey::EncodeMaxKey(1, 1, 31)); 792 keys.push_back(IndexMetaDataKey::EncodeMaxKey(1, 1, 32)); 793 keys.push_back(IndexMetaDataKey::EncodeMaxKey(1, 1)); 794 keys.push_back(IndexMetaDataKey::EncodeMaxKey(1, 2)); 795 keys.push_back(ObjectStoreFreeListKey::Encode(1, 1)); 796 keys.push_back(ObjectStoreFreeListKey::EncodeMaxKey(1)); 797 keys.push_back(IndexFreeListKey::Encode(1, 1, kMinimumIndexId)); 798 keys.push_back(IndexFreeListKey::EncodeMaxKey(1, 1)); 799 keys.push_back(IndexFreeListKey::Encode(1, 2, kMinimumIndexId)); 800 keys.push_back(IndexFreeListKey::EncodeMaxKey(1, 2)); 801 keys.push_back(ObjectStoreNamesKey::Encode(1, ASCIIToUTF16(""))); 802 keys.push_back(ObjectStoreNamesKey::Encode(1, ASCIIToUTF16("a"))); 803 keys.push_back(IndexNamesKey::Encode(1, 1, ASCIIToUTF16(""))); 804 keys.push_back(IndexNamesKey::Encode(1, 1, ASCIIToUTF16("a"))); 805 keys.push_back(IndexNamesKey::Encode(1, 2, ASCIIToUTF16("a"))); 806 keys.push_back(ObjectStoreDataKey::Encode(1, 1, MinIDBKey())); 807 keys.push_back(ObjectStoreDataKey::Encode(1, 1, MaxIDBKey())); 808 keys.push_back(ExistsEntryKey::Encode(1, 1, MinIDBKey())); 809 keys.push_back(ExistsEntryKey::Encode(1, 1, MaxIDBKey())); 810 keys.push_back(IndexDataKey::Encode(1, 1, 30, MinIDBKey(), MinIDBKey(), 0)); 811 keys.push_back(IndexDataKey::Encode(1, 1, 30, MinIDBKey(), MinIDBKey(), 1)); 812 keys.push_back(IndexDataKey::Encode(1, 1, 30, MinIDBKey(), MaxIDBKey(), 0)); 813 keys.push_back(IndexDataKey::Encode(1, 1, 30, MinIDBKey(), MaxIDBKey(), 1)); 814 keys.push_back(IndexDataKey::Encode(1, 1, 30, MaxIDBKey(), MinIDBKey(), 0)); 815 keys.push_back(IndexDataKey::Encode(1, 1, 30, MaxIDBKey(), MinIDBKey(), 1)); 816 keys.push_back(IndexDataKey::Encode(1, 1, 30, MaxIDBKey(), MaxIDBKey(), 0)); 817 keys.push_back(IndexDataKey::Encode(1, 1, 30, MaxIDBKey(), MaxIDBKey(), 1)); 818 keys.push_back(IndexDataKey::Encode(1, 1, 31, MinIDBKey(), MinIDBKey(), 0)); 819 keys.push_back(IndexDataKey::Encode(1, 2, 30, MinIDBKey(), MinIDBKey(), 0)); 820 keys.push_back( 821 IndexDataKey::EncodeMaxKey(1, 2, std::numeric_limits<int32>::max() - 1)); 822 823 for (size_t i = 0; i < keys.size(); ++i) { 824 const LevelDBSlice key_a(keys[i]); 825 EXPECT_EQ(Compare(key_a, key_a, false), 0); 826 827 for (size_t j = i + 1; j < keys.size(); ++j) { 828 const LevelDBSlice key_b(keys[j]); 829 EXPECT_LT(Compare(key_a, key_b, false), 0); 830 EXPECT_GT(Compare(key_b, key_a, false), 0); 831 } 832 } 833} 834 835TEST(IndexedDBLevelDBCodingTest, EncodeVarIntVSEncodeByteTest) { 836 std::vector<unsigned char> test_cases; 837 test_cases.push_back(0); 838 test_cases.push_back(1); 839 test_cases.push_back(127); 840 841 for (size_t i = 0; i < test_cases.size(); ++i) { 842 unsigned char n = test_cases[i]; 843 844 std::vector<char> vA = WrappedEncodeByte(n); 845 std::vector<char> vB = WrappedEncodeVarInt(static_cast<int64>(n)); 846 847 EXPECT_EQ(vA.size(), vB.size()); 848 EXPECT_EQ(*vA.begin(), *vB.begin()); 849 } 850} 851 852} // namespace 853 854} // namespace content 855