Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2953)

Unified Diff: base/metrics/persistent_memory_allocator_unittest.cc

Issue 2000523003: Fully support read/write memory-mapped files for persistent memory. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: rebased Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « base/metrics/persistent_memory_allocator.cc ('k') | components/metrics/file_metrics_provider.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: base/metrics/persistent_memory_allocator_unittest.cc
diff --git a/base/metrics/persistent_memory_allocator_unittest.cc b/base/metrics/persistent_memory_allocator_unittest.cc
index 70e13921fabfb2989164648262bd88f2b91cb15c..5125ae6f322a141ff8a7d9e9e400a3a0ef7d264a 100644
--- a/base/metrics/persistent_memory_allocator_unittest.cc
+++ b/base/metrics/persistent_memory_allocator_unittest.cc
@@ -53,7 +53,7 @@ class PersistentMemoryAllocatorTest : public testing::Test {
};
PersistentMemoryAllocatorTest() {
- kAllocAlignment = PersistentMemoryAllocator::kAllocAlignment;
+ kAllocAlignment = GetAllocAlignment();
mem_segment_.reset(new char[TEST_MEMORY_SIZE]);
}
@@ -80,6 +80,10 @@ class PersistentMemoryAllocatorTest : public testing::Test {
return count;
}
+ static uint32_t GetAllocAlignment() {
+ return PersistentMemoryAllocator::kAllocAlignment;
+ }
+
protected:
std::unique_ptr<char[]> mem_segment_;
std::unique_ptr<PersistentMemoryAllocator> allocator_;
@@ -611,7 +615,7 @@ TEST(FilePersistentMemoryAllocatorTest, CreationTest) {
const size_t mmlength = mmfile->length();
EXPECT_GE(meminfo1.total, mmlength);
- FilePersistentMemoryAllocator file(std::move(mmfile), 0, "");
+ FilePersistentMemoryAllocator file(std::move(mmfile), 0, 0, "", true);
EXPECT_TRUE(file.IsReadonly());
EXPECT_EQ(TEST_ID, file.Id());
EXPECT_FALSE(file.IsFull());
@@ -635,10 +639,63 @@ TEST(FilePersistentMemoryAllocatorTest, CreationTest) {
EXPECT_EQ(0U, meminfo2.free);
}
+TEST(FilePersistentMemoryAllocatorTest, ExtendTest) {
+ ScopedTempDir temp_dir;
+ ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
+ FilePath file_path = temp_dir.path().AppendASCII("extend_test");
+ MemoryMappedFile::Region region = {0, 16 << 10}; // 16KiB maximum size.
+
+ // Start with a small but valid file of persistent data.
+ ASSERT_FALSE(PathExists(file_path));
+ {
+ LocalPersistentMemoryAllocator local(TEST_MEMORY_SIZE, TEST_ID, "");
+ local.Allocate(1, 1);
+ local.Allocate(11, 11);
+
+ File writer(file_path, File::FLAG_CREATE | File::FLAG_WRITE);
+ ASSERT_TRUE(writer.IsValid());
+ writer.Write(0, (const char*)local.data(), local.used());
+ }
+ ASSERT_TRUE(PathExists(file_path));
+ int64_t before_size;
+ ASSERT_TRUE(GetFileSize(file_path, &before_size));
+
+ // Map it as an extendable read/write file and append to it.
+ {
+ std::unique_ptr<MemoryMappedFile> mmfile(new MemoryMappedFile());
+ mmfile->Initialize(
+ File(file_path, File::FLAG_OPEN | File::FLAG_READ | File::FLAG_WRITE),
+ region, MemoryMappedFile::READ_WRITE_EXTEND);
+ FilePersistentMemoryAllocator allocator(std::move(mmfile), region.size, 0,
+ "", false);
+ EXPECT_EQ(static_cast<size_t>(before_size), allocator.used());
+
+ allocator.Allocate(111, 111);
+ EXPECT_LT(static_cast<size_t>(before_size), allocator.used());
+ }
+
+ // Validate that append worked.
+ int64_t after_size;
+ ASSERT_TRUE(GetFileSize(file_path, &after_size));
+ EXPECT_LT(before_size, after_size);
+
+ // Verify that it's still an acceptable file.
+ {
+ std::unique_ptr<MemoryMappedFile> mmfile(new MemoryMappedFile());
+ mmfile->Initialize(
+ File(file_path, File::FLAG_OPEN | File::FLAG_READ | File::FLAG_WRITE),
+ region, MemoryMappedFile::READ_WRITE_EXTEND);
+ EXPECT_TRUE(FilePersistentMemoryAllocator::IsFileAcceptable(*mmfile, true));
+ EXPECT_TRUE(
+ FilePersistentMemoryAllocator::IsFileAcceptable(*mmfile, false));
+ }
+}
+
TEST(FilePersistentMemoryAllocatorTest, AcceptableTest) {
+ const uint32_t kAllocAlignment =
+ PersistentMemoryAllocatorTest::GetAllocAlignment();
ScopedTempDir temp_dir;
ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
- FilePath file_path_base = temp_dir.path().AppendASCII("persistent_memory_");
LocalPersistentMemoryAllocator local(TEST_MEMORY_SIZE, TEST_ID, "");
local.MakeIterable(local.Allocate(1, 1));
@@ -660,13 +717,23 @@ TEST(FilePersistentMemoryAllocatorTest, AcceptableTest) {
}
ASSERT_TRUE(PathExists(file_path));
+ // Request read/write access for some sizes that are a multple of the
+ // allocator's alignment size. The allocator is strict about file size
+ // being a multiple of its internal alignment when doing read/write access.
+ const bool read_only = (filesize % (2 * kAllocAlignment)) != 0;
+ const uint32_t file_flags =
+ File::FLAG_OPEN | File::FLAG_READ | (read_only ? 0 : File::FLAG_WRITE);
+ const MemoryMappedFile::Access map_access =
+ read_only ? MemoryMappedFile::READ_ONLY : MemoryMappedFile::READ_WRITE;
+
mmfile.reset(new MemoryMappedFile());
- mmfile->Initialize(file_path);
+ mmfile->Initialize(File(file_path, file_flags), map_access);
EXPECT_EQ(filesize, mmfile->length());
- if (FilePersistentMemoryAllocator::IsFileAcceptable(*mmfile)) {
+ if (FilePersistentMemoryAllocator::IsFileAcceptable(*mmfile, read_only)) {
// Make sure construction doesn't crash. It will, however, cause
// error messages warning about about a corrupted memory segment.
- FilePersistentMemoryAllocator allocator(std::move(mmfile), 0, "");
+ FilePersistentMemoryAllocator allocator(std::move(mmfile), 0, 0, "",
+ read_only);
// Also make sure that iteration doesn't crash.
PersistentMemoryAllocator::Iterator iter(&allocator);
uint32_t type_id;
@@ -680,6 +747,7 @@ TEST(FilePersistentMemoryAllocatorTest, AcceptableTest) {
(void)type;
(void)size;
}
+
// Ensure that short files are detected as corrupt and full files are not.
EXPECT_EQ(filesize != minsize, allocator.IsCorrupt());
} else {
@@ -700,12 +768,13 @@ TEST(FilePersistentMemoryAllocatorTest, AcceptableTest) {
ASSERT_TRUE(PathExists(file_path));
mmfile.reset(new MemoryMappedFile());
- mmfile->Initialize(file_path);
+ mmfile->Initialize(File(file_path, file_flags), map_access);
EXPECT_EQ(filesize, mmfile->length());
- if (FilePersistentMemoryAllocator::IsFileAcceptable(*mmfile)) {
+ if (FilePersistentMemoryAllocator::IsFileAcceptable(*mmfile, read_only)) {
// Make sure construction doesn't crash. It will, however, cause
// error messages warning about about a corrupted memory segment.
- FilePersistentMemoryAllocator allocator(std::move(mmfile), 0, "");
+ FilePersistentMemoryAllocator allocator(std::move(mmfile), 0, 0, "",
+ read_only);
EXPECT_TRUE(allocator.IsCorrupt()); // Garbage data so it should be.
} else {
// For filesize >= minsize, the file must be acceptable. This
« no previous file with comments | « base/metrics/persistent_memory_allocator.cc ('k') | components/metrics/file_metrics_provider.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698