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 |