OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "base/metrics/persistent_memory_allocator.h" | 5 #include "base/metrics/persistent_memory_allocator.h" |
6 | 6 |
7 #include "base/files/file.h" | 7 #include "base/files/file.h" |
8 #include "base/files/file_util.h" | 8 #include "base/files/file_util.h" |
9 #include "base/files/memory_mapped_file.h" | 9 #include "base/files/memory_mapped_file.h" |
10 #include "base/files/scoped_temp_dir.h" | 10 #include "base/files/scoped_temp_dir.h" |
11 #include "base/memory/scoped_ptr.h" | 11 #include "base/memory/scoped_ptr.h" |
| 12 #include "base/memory/shared_memory.h" |
12 #include "base/metrics/histogram.h" | 13 #include "base/metrics/histogram.h" |
13 #include "base/rand_util.h" | 14 #include "base/rand_util.h" |
14 #include "base/strings/safe_sprintf.h" | 15 #include "base/strings/safe_sprintf.h" |
15 #include "base/threading/simple_thread.h" | 16 #include "base/threading/simple_thread.h" |
16 #include "testing/gmock/include/gmock/gmock.h" | 17 #include "testing/gmock/include/gmock/gmock.h" |
17 | 18 |
18 namespace { | 19 namespace { |
19 | 20 |
20 const uint32_t TEST_MEMORY_SIZE = 1 << 20; // 1 MiB | 21 const uint32_t TEST_MEMORY_SIZE = 1 << 20; // 1 MiB |
21 const uint32_t TEST_MEMORY_PAGE = 64 << 10; // 64 KiB | 22 const uint32_t TEST_MEMORY_PAGE = 64 << 10; // 64 KiB |
(...skipping 358 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
380 | 381 |
381 TEST(LocalPersistentMemoryAllocatorTest, CreationTest) { | 382 TEST(LocalPersistentMemoryAllocatorTest, CreationTest) { |
382 LocalPersistentMemoryAllocator allocator(TEST_MEMORY_SIZE, 42, ""); | 383 LocalPersistentMemoryAllocator allocator(TEST_MEMORY_SIZE, 42, ""); |
383 EXPECT_EQ(42U, allocator.Id()); | 384 EXPECT_EQ(42U, allocator.Id()); |
384 EXPECT_NE(0U, allocator.Allocate(24, 1)); | 385 EXPECT_NE(0U, allocator.Allocate(24, 1)); |
385 EXPECT_FALSE(allocator.IsFull()); | 386 EXPECT_FALSE(allocator.IsFull()); |
386 EXPECT_FALSE(allocator.IsCorrupt()); | 387 EXPECT_FALSE(allocator.IsCorrupt()); |
387 } | 388 } |
388 | 389 |
389 | 390 |
| 391 //----- SharedPersistentMemoryAllocator ---------------------------------------- |
| 392 |
| 393 TEST(SharedPersistentMemoryAllocatorTest, CreationTest) { |
| 394 SharedMemoryHandle shared_handle; |
| 395 |
| 396 PersistentMemoryAllocator::MemoryInfo meminfo1; |
| 397 Reference r123, r456, r789; |
| 398 { |
| 399 scoped_ptr<SharedMemory> shmem1(new SharedMemory()); |
| 400 ASSERT_TRUE(shmem1->CreateAndMapAnonymous(TEST_MEMORY_SIZE)); |
| 401 SharedPersistentMemoryAllocator local(std::move(shmem1), TEST_ID, "", |
| 402 false); |
| 403 EXPECT_FALSE(local.IsReadonly()); |
| 404 r123 = local.Allocate(123, 123); |
| 405 r456 = local.Allocate(456, 456); |
| 406 r789 = local.Allocate(789, 789); |
| 407 local.MakeIterable(r123); |
| 408 local.SetType(r456, 654); |
| 409 local.MakeIterable(r789); |
| 410 local.GetMemoryInfo(&meminfo1); |
| 411 EXPECT_FALSE(local.IsFull()); |
| 412 EXPECT_FALSE(local.IsCorrupt()); |
| 413 |
| 414 ASSERT_TRUE(local.shared_memory()->ShareToProcess( |
| 415 GetCurrentProcessHandle(), |
| 416 &shared_handle)); |
| 417 } |
| 418 |
| 419 // Read-only test. |
| 420 scoped_ptr<SharedMemory> shmem2(new SharedMemory(shared_handle, |
| 421 /*readonly=*/true)); |
| 422 ASSERT_TRUE(shmem2->Map(TEST_MEMORY_SIZE)); |
| 423 |
| 424 SharedPersistentMemoryAllocator shalloc2(std::move(shmem2), 0, "", true); |
| 425 EXPECT_TRUE(shalloc2.IsReadonly()); |
| 426 EXPECT_EQ(TEST_ID, shalloc2.Id()); |
| 427 EXPECT_FALSE(shalloc2.IsFull()); |
| 428 EXPECT_FALSE(shalloc2.IsCorrupt()); |
| 429 |
| 430 PersistentMemoryAllocator::Iterator iter2; |
| 431 uint32_t type; |
| 432 shalloc2.CreateIterator(&iter2); |
| 433 EXPECT_EQ(r123, shalloc2.GetNextIterable(&iter2, &type)); |
| 434 EXPECT_EQ(r789, shalloc2.GetNextIterable(&iter2, &type)); |
| 435 EXPECT_EQ(0U, shalloc2.GetNextIterable(&iter2, &type)); |
| 436 |
| 437 EXPECT_EQ(123U, shalloc2.GetType(r123)); |
| 438 EXPECT_EQ(654U, shalloc2.GetType(r456)); |
| 439 EXPECT_EQ(789U, shalloc2.GetType(r789)); |
| 440 |
| 441 PersistentMemoryAllocator::MemoryInfo meminfo2; |
| 442 shalloc2.GetMemoryInfo(&meminfo2); |
| 443 EXPECT_EQ(meminfo1.total, meminfo2.total); |
| 444 EXPECT_EQ(meminfo1.free, meminfo2.free); |
| 445 |
| 446 // Read/write test. |
| 447 scoped_ptr<SharedMemory> shmem3(new SharedMemory(shared_handle, |
| 448 /*readonly=*/false)); |
| 449 ASSERT_TRUE(shmem3->Map(TEST_MEMORY_SIZE)); |
| 450 |
| 451 SharedPersistentMemoryAllocator shalloc3(std::move(shmem3), 0, "", false); |
| 452 EXPECT_FALSE(shalloc3.IsReadonly()); |
| 453 EXPECT_EQ(TEST_ID, shalloc3.Id()); |
| 454 EXPECT_FALSE(shalloc3.IsFull()); |
| 455 EXPECT_FALSE(shalloc3.IsCorrupt()); |
| 456 |
| 457 PersistentMemoryAllocator::Iterator iter3; |
| 458 shalloc3.CreateIterator(&iter3); |
| 459 EXPECT_EQ(r123, shalloc3.GetNextIterable(&iter3, &type)); |
| 460 EXPECT_EQ(r789, shalloc3.GetNextIterable(&iter3, &type)); |
| 461 EXPECT_EQ(0U, shalloc3.GetNextIterable(&iter3, &type)); |
| 462 |
| 463 EXPECT_EQ(123U, shalloc3.GetType(r123)); |
| 464 EXPECT_EQ(654U, shalloc3.GetType(r456)); |
| 465 EXPECT_EQ(789U, shalloc3.GetType(r789)); |
| 466 |
| 467 PersistentMemoryAllocator::MemoryInfo meminfo3; |
| 468 shalloc3.GetMemoryInfo(&meminfo3); |
| 469 EXPECT_EQ(meminfo1.total, meminfo3.total); |
| 470 EXPECT_EQ(meminfo1.free, meminfo3.free); |
| 471 |
| 472 // Interconnectivity test. |
| 473 Reference obj = shalloc3.Allocate(42, 42); |
| 474 ASSERT_TRUE(obj); |
| 475 shalloc3.MakeIterable(obj); |
| 476 EXPECT_EQ(obj, shalloc2.GetNextIterable(&iter2, &type)); |
| 477 EXPECT_EQ(42U, type); |
| 478 } |
| 479 |
| 480 |
390 //----- FilePersistentMemoryAllocator ------------------------------------------ | 481 //----- FilePersistentMemoryAllocator ------------------------------------------ |
391 | 482 |
392 TEST(FilePersistentMemoryAllocatorTest, CreationTest) { | 483 TEST(FilePersistentMemoryAllocatorTest, CreationTest) { |
393 ScopedTempDir temp_dir; | 484 ScopedTempDir temp_dir; |
394 ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); | 485 ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); |
395 FilePath file_path = temp_dir.path().AppendASCII("persistent_memory"); | 486 FilePath file_path = temp_dir.path().AppendASCII("persistent_memory"); |
396 | 487 |
397 PersistentMemoryAllocator::MemoryInfo meminfo1; | 488 PersistentMemoryAllocator::MemoryInfo meminfo1; |
398 Reference r123, r456, r789; | 489 Reference r123, r456, r789; |
399 { | 490 { |
(...skipping 13 matching lines...) Expand all Loading... |
413 ASSERT_TRUE(writer.IsValid()); | 504 ASSERT_TRUE(writer.IsValid()); |
414 writer.Write(0, (const char*)local.data(), local.used()); | 505 writer.Write(0, (const char*)local.data(), local.used()); |
415 } | 506 } |
416 | 507 |
417 scoped_ptr<MemoryMappedFile> mmfile(new MemoryMappedFile()); | 508 scoped_ptr<MemoryMappedFile> mmfile(new MemoryMappedFile()); |
418 mmfile->Initialize(file_path); | 509 mmfile->Initialize(file_path); |
419 EXPECT_TRUE(mmfile->IsValid()); | 510 EXPECT_TRUE(mmfile->IsValid()); |
420 const size_t mmlength = mmfile->length(); | 511 const size_t mmlength = mmfile->length(); |
421 EXPECT_GE(meminfo1.total, mmlength); | 512 EXPECT_GE(meminfo1.total, mmlength); |
422 | 513 |
423 FilePersistentMemoryAllocator file(mmfile.release(), 0, ""); | 514 FilePersistentMemoryAllocator file(std::move(mmfile), 0, ""); |
424 EXPECT_TRUE(file.IsReadonly()); | 515 EXPECT_TRUE(file.IsReadonly()); |
425 EXPECT_EQ(TEST_ID, file.Id()); | 516 EXPECT_EQ(TEST_ID, file.Id()); |
426 EXPECT_FALSE(file.IsFull()); | 517 EXPECT_FALSE(file.IsFull()); |
427 EXPECT_FALSE(file.IsCorrupt()); | 518 EXPECT_FALSE(file.IsCorrupt()); |
428 | 519 |
429 PersistentMemoryAllocator::Iterator iter; | 520 PersistentMemoryAllocator::Iterator iter; |
430 uint32_t type; | 521 uint32_t type; |
431 file.CreateIterator(&iter); | 522 file.CreateIterator(&iter); |
432 EXPECT_EQ(r123, file.GetNextIterable(&iter, &type)); | 523 EXPECT_EQ(r123, file.GetNextIterable(&iter, &type)); |
433 EXPECT_EQ(r789, file.GetNextIterable(&iter, &type)); | 524 EXPECT_EQ(r789, file.GetNextIterable(&iter, &type)); |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
468 ASSERT_TRUE(writer.IsValid()); | 559 ASSERT_TRUE(writer.IsValid()); |
469 writer.Write(0, (const char*)local.data(), filesize); | 560 writer.Write(0, (const char*)local.data(), filesize); |
470 } | 561 } |
471 ASSERT_TRUE(PathExists(file_path)); | 562 ASSERT_TRUE(PathExists(file_path)); |
472 | 563 |
473 mmfile.reset(new MemoryMappedFile()); | 564 mmfile.reset(new MemoryMappedFile()); |
474 mmfile->Initialize(file_path); | 565 mmfile->Initialize(file_path); |
475 EXPECT_EQ(filesize, mmfile->length()); | 566 EXPECT_EQ(filesize, mmfile->length()); |
476 if (FilePersistentMemoryAllocator::IsFileAcceptable(*mmfile)) { | 567 if (FilePersistentMemoryAllocator::IsFileAcceptable(*mmfile)) { |
477 // Make sure construction doesn't crash. | 568 // Make sure construction doesn't crash. |
478 FilePersistentMemoryAllocator allocator(mmfile.release(), 0, ""); | 569 FilePersistentMemoryAllocator allocator(std::move(mmfile), 0, ""); |
479 // Also make sure that iteration doesn't crash. | 570 // Also make sure that iteration doesn't crash. |
480 PersistentMemoryAllocator::Iterator iter; | 571 PersistentMemoryAllocator::Iterator iter; |
481 allocator.CreateIterator(&iter); | 572 allocator.CreateIterator(&iter); |
482 for (;;) { | 573 for (;;) { |
483 Reference ref = allocator.GetNextIterable(&iter, 0); | 574 Reference ref = allocator.GetNextIterable(&iter, 0); |
484 if (!ref) | 575 if (!ref) |
485 break; | 576 break; |
486 const char* data = allocator.GetAsObject<char>(ref, 0); | 577 const char* data = allocator.GetAsObject<char>(ref, 0); |
487 uint32_t type = allocator.GetType(ref); | 578 uint32_t type = allocator.GetType(ref); |
488 size_t size = allocator.GetAllocSize(ref); | 579 size_t size = allocator.GetAllocSize(ref); |
(...skipping 19 matching lines...) Expand all Loading... |
508 ASSERT_TRUE(writer.IsValid()); | 599 ASSERT_TRUE(writer.IsValid()); |
509 writer.Write(0, (const char*)garbage.get(), filesize); | 600 writer.Write(0, (const char*)garbage.get(), filesize); |
510 } | 601 } |
511 ASSERT_TRUE(PathExists(file_path)); | 602 ASSERT_TRUE(PathExists(file_path)); |
512 | 603 |
513 mmfile.reset(new MemoryMappedFile()); | 604 mmfile.reset(new MemoryMappedFile()); |
514 mmfile->Initialize(file_path); | 605 mmfile->Initialize(file_path); |
515 EXPECT_EQ(filesize, mmfile->length()); | 606 EXPECT_EQ(filesize, mmfile->length()); |
516 if (FilePersistentMemoryAllocator::IsFileAcceptable(*mmfile)) { | 607 if (FilePersistentMemoryAllocator::IsFileAcceptable(*mmfile)) { |
517 // Just need to make sure it doesn't crash. | 608 // Just need to make sure it doesn't crash. |
518 FilePersistentMemoryAllocator allocator(mmfile.release(), 0, "") ; | 609 FilePersistentMemoryAllocator allocator(std::move(mmfile), 0, ""); |
519 EXPECT_TRUE(allocator.IsCorrupt()); // Garbage data so it should be. | 610 EXPECT_TRUE(allocator.IsCorrupt()); // Garbage data so it should be. |
520 } else { | 611 } else { |
521 // For filesize >= minsize, the file must be acceptable. This | 612 // For filesize >= minsize, the file must be acceptable. This |
522 // else clause (file-not-acceptable) should be reached only if | 613 // else clause (file-not-acceptable) should be reached only if |
523 // filesize < minsize. | 614 // filesize < minsize. |
524 EXPECT_GT(minsize, filesize); | 615 EXPECT_GT(minsize, filesize); |
525 } | 616 } |
526 } | 617 } |
527 } | 618 } |
528 | 619 |
529 } // namespace base | 620 } // namespace base |
OLD | NEW |