| 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 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 466 ASSERT_TRUE(writer.IsValid()); | 557 ASSERT_TRUE(writer.IsValid()); |
| 467 writer.Write(0, (const char*)local.data(), filesize); | 558 writer.Write(0, (const char*)local.data(), filesize); |
| 468 } | 559 } |
| 469 ASSERT_TRUE(PathExists(file_path)); | 560 ASSERT_TRUE(PathExists(file_path)); |
| 470 | 561 |
| 471 mmfile.reset(new MemoryMappedFile()); | 562 mmfile.reset(new MemoryMappedFile()); |
| 472 mmfile->Initialize(file_path); | 563 mmfile->Initialize(file_path); |
| 473 EXPECT_EQ(filesize, mmfile->length()); | 564 EXPECT_EQ(filesize, mmfile->length()); |
| 474 if (FilePersistentMemoryAllocator::IsFileAcceptable(*mmfile)) { | 565 if (FilePersistentMemoryAllocator::IsFileAcceptable(*mmfile)) { |
| 475 // Just need to make sure it doesn't crash. | 566 // Just need to make sure it doesn't crash. |
| 476 FilePersistentMemoryAllocator allocator(mmfile.release(), 0, ""); | 567 FilePersistentMemoryAllocator allocator(std::move(mmfile), 0, ""); |
| 477 (void)allocator; // Ensure compiler can't optimize-out above variable. | 568 (void)allocator; // Ensure compiler can't optimize-out above variable. |
| 478 } else { | 569 } else { |
| 479 // For filesize >= minsize, the file must be acceptable. This | 570 // For filesize >= minsize, the file must be acceptable. This |
| 480 // else clause (file-not-acceptable) should be reached only if | 571 // else clause (file-not-acceptable) should be reached only if |
| 481 // filesize < minsize. | 572 // filesize < minsize. |
| 482 EXPECT_LT(filesize, minsize); | 573 EXPECT_LT(filesize, minsize); |
| 483 } | 574 } |
| 484 | 575 |
| 485 #if !DCHECK_IS_ON() // DCHECK builds will die at a NOTREACHED(). | 576 #if !DCHECK_IS_ON() // DCHECK builds will die at a NOTREACHED(). |
| 486 strings::SafeSPrintf(filename, "memory_%d_B", filesize); | 577 strings::SafeSPrintf(filename, "memory_%d_B", filesize); |
| 487 file_path = temp_dir.path().AppendASCII(filename); | 578 file_path = temp_dir.path().AppendASCII(filename); |
| 488 ASSERT_FALSE(PathExists(file_path)); | 579 ASSERT_FALSE(PathExists(file_path)); |
| 489 { | 580 { |
| 490 File writer(file_path, File::FLAG_CREATE | File::FLAG_WRITE); | 581 File writer(file_path, File::FLAG_CREATE | File::FLAG_WRITE); |
| 491 ASSERT_TRUE(writer.IsValid()); | 582 ASSERT_TRUE(writer.IsValid()); |
| 492 writer.Write(0, (const char*)garbage.get(), filesize); | 583 writer.Write(0, (const char*)garbage.get(), filesize); |
| 493 } | 584 } |
| 494 ASSERT_TRUE(PathExists(file_path)); | 585 ASSERT_TRUE(PathExists(file_path)); |
| 495 | 586 |
| 496 mmfile.reset(new MemoryMappedFile()); | 587 mmfile.reset(new MemoryMappedFile()); |
| 497 mmfile->Initialize(file_path); | 588 mmfile->Initialize(file_path); |
| 498 EXPECT_EQ(filesize, mmfile->length()); | 589 EXPECT_EQ(filesize, mmfile->length()); |
| 499 if (FilePersistentMemoryAllocator::IsFileAcceptable(*mmfile)) { | 590 if (FilePersistentMemoryAllocator::IsFileAcceptable(*mmfile)) { |
| 500 // Just need to make sure it doesn't crash. | 591 // Just need to make sure it doesn't crash. |
| 501 FilePersistentMemoryAllocator allocator(mmfile.release(), 0, "") ; | 592 FilePersistentMemoryAllocator allocator(std::move(mmfile), 0, ""); |
| 502 EXPECT_TRUE(allocator.IsCorrupt()); // Garbage data so it should be. | 593 EXPECT_TRUE(allocator.IsCorrupt()); // Garbage data so it should be. |
| 503 } else { | 594 } else { |
| 504 // For filesize >= minsize, the file must be acceptable. This | 595 // For filesize >= minsize, the file must be acceptable. This |
| 505 // else clause (file-not-acceptable) should be reached only if | 596 // else clause (file-not-acceptable) should be reached only if |
| 506 // filesize < minsize. | 597 // filesize < minsize. |
| 507 EXPECT_GT(minsize, filesize); | 598 EXPECT_GT(minsize, filesize); |
| 508 } | 599 } |
| 509 #endif | 600 #endif |
| 510 } | 601 } |
| 511 } | 602 } |
| 512 | 603 |
| 513 } // namespace base | 604 } // namespace base |
| OLD | NEW |