persistent_system_profile_unittest.cc 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. // Copyright 2017 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. #include "components/metrics/persistent_system_profile.h"
  5. #include <memory>
  6. #include "base/check_op.h"
  7. #include "base/metrics/persistent_memory_allocator.h"
  8. #include "base/rand_util.h"
  9. #include "components/variations/hashing.h"
  10. #include "testing/gtest/include/gtest/gtest.h"
  11. namespace metrics {
  12. class PersistentSystemProfileTest : public testing::Test {
  13. public:
  14. const int32_t kAllocatorMemorySize = 1 << 20; // 1 MiB
  15. PersistentSystemProfileTest() {}
  16. PersistentSystemProfileTest(const PersistentSystemProfileTest&) = delete;
  17. PersistentSystemProfileTest& operator=(const PersistentSystemProfileTest&) =
  18. delete;
  19. ~PersistentSystemProfileTest() override {}
  20. void SetUp() override {
  21. memory_allocator_ = std::make_unique<base::LocalPersistentMemoryAllocator>(
  22. kAllocatorMemorySize, 0, "");
  23. records_ = std::make_unique<PersistentSystemProfile::RecordAllocator>(
  24. memory_allocator_.get());
  25. persistent_profile_.RegisterPersistentAllocator(memory_allocator_.get());
  26. }
  27. void TearDown() override {
  28. persistent_profile_.DeregisterPersistentAllocator(memory_allocator_.get());
  29. records_.reset();
  30. memory_allocator_.reset();
  31. }
  32. void WriteRecord(uint8_t type, const std::string& record) {
  33. persistent_profile_.allocators_[0].Write(
  34. static_cast<PersistentSystemProfile::RecordType>(type), record);
  35. }
  36. bool ReadRecord(uint8_t* type, std::string* record) {
  37. PersistentSystemProfile::RecordType rec_type;
  38. bool success = records_->Read(&rec_type, record);
  39. *type = rec_type; // Convert to uint8_t for testing.
  40. return success;
  41. }
  42. base::PersistentMemoryAllocator* memory_allocator() {
  43. return memory_allocator_.get();
  44. }
  45. PersistentSystemProfile* persistent_profile() { return &persistent_profile_; }
  46. private:
  47. PersistentSystemProfile persistent_profile_;
  48. std::unique_ptr<base::PersistentMemoryAllocator> memory_allocator_;
  49. std::unique_ptr<PersistentSystemProfile::RecordAllocator> records_;
  50. };
  51. TEST_F(PersistentSystemProfileTest, Create) {
  52. uint32_t type;
  53. base::PersistentMemoryAllocator::Iterator iter(memory_allocator());
  54. base::PersistentMemoryAllocator::Reference ref = iter.GetNext(&type);
  55. DCHECK(ref);
  56. DCHECK_NE(0U, type);
  57. }
  58. TEST_F(PersistentSystemProfileTest, RecordSplitting) {
  59. const size_t kRecordSize = 100 << 10; // 100 KiB
  60. std::vector<char> buffer;
  61. buffer.resize(kRecordSize);
  62. base::RandBytes(&buffer[0], kRecordSize);
  63. WriteRecord(42, std::string(&buffer[0], kRecordSize));
  64. uint8_t type;
  65. std::string record;
  66. ASSERT_TRUE(ReadRecord(&type, &record));
  67. EXPECT_EQ(42U, type);
  68. ASSERT_EQ(kRecordSize, record.size());
  69. for (size_t i = 0; i < kRecordSize; ++i)
  70. EXPECT_EQ(buffer[i], record[i]);
  71. }
  72. TEST_F(PersistentSystemProfileTest, ProfileStorage) {
  73. SystemProfileProto proto1;
  74. SystemProfileProto::FieldTrial* trial = proto1.add_field_trial();
  75. trial->set_name_id(123);
  76. trial->set_group_id(456);
  77. persistent_profile()->SetSystemProfile(proto1, false);
  78. SystemProfileProto proto2;
  79. ASSERT_TRUE(PersistentSystemProfile::HasSystemProfile(*memory_allocator()));
  80. ASSERT_TRUE(
  81. PersistentSystemProfile::GetSystemProfile(*memory_allocator(), &proto2));
  82. ASSERT_EQ(1, proto2.field_trial_size());
  83. EXPECT_EQ(123U, proto2.field_trial(0).name_id());
  84. EXPECT_EQ(456U, proto2.field_trial(0).group_id());
  85. // Check that the profile can be overwritten by another incomplete profile.
  86. trial = proto1.add_field_trial();
  87. trial->set_name_id(34);
  88. trial->set_group_id(50);
  89. persistent_profile()->SetSystemProfile(proto1, false);
  90. ASSERT_TRUE(
  91. PersistentSystemProfile::GetSystemProfile(*memory_allocator(), &proto2));
  92. ASSERT_EQ(2, proto2.field_trial_size());
  93. EXPECT_EQ(123U, proto2.field_trial(0).name_id());
  94. EXPECT_EQ(456U, proto2.field_trial(0).group_id());
  95. EXPECT_EQ(34U, proto2.field_trial(1).name_id());
  96. EXPECT_EQ(50U, proto2.field_trial(1).group_id());
  97. // Check that the profile can be overwritten by a complete profile.
  98. trial = proto1.add_field_trial();
  99. trial->set_name_id(78);
  100. trial->set_group_id(90);
  101. persistent_profile()->SetSystemProfile(proto1, true);
  102. ASSERT_TRUE(
  103. PersistentSystemProfile::GetSystemProfile(*memory_allocator(), &proto2));
  104. ASSERT_EQ(3, proto2.field_trial_size());
  105. EXPECT_EQ(123U, proto2.field_trial(0).name_id());
  106. EXPECT_EQ(456U, proto2.field_trial(0).group_id());
  107. EXPECT_EQ(34U, proto2.field_trial(1).name_id());
  108. EXPECT_EQ(50U, proto2.field_trial(1).group_id());
  109. EXPECT_EQ(78U, proto2.field_trial(2).name_id());
  110. EXPECT_EQ(90U, proto2.field_trial(2).group_id());
  111. // Check that the profile won't be overwritten by a new non-complete profile.
  112. trial = proto1.add_field_trial();
  113. trial->set_name_id(0xC0DE);
  114. trial->set_group_id(0xFEED);
  115. persistent_profile()->SetSystemProfile(proto1, false);
  116. ASSERT_TRUE(
  117. PersistentSystemProfile::GetSystemProfile(*memory_allocator(), &proto2));
  118. ASSERT_EQ(3, proto2.field_trial_size());
  119. EXPECT_EQ(123U, proto2.field_trial(0).name_id());
  120. EXPECT_EQ(456U, proto2.field_trial(0).group_id());
  121. EXPECT_EQ(34U, proto2.field_trial(1).name_id());
  122. EXPECT_EQ(50U, proto2.field_trial(1).group_id());
  123. EXPECT_EQ(78U, proto2.field_trial(2).name_id());
  124. EXPECT_EQ(90U, proto2.field_trial(2).group_id());
  125. }
  126. TEST_F(PersistentSystemProfileTest, ProfileExtensions) {
  127. persistent_profile()->AddFieldTrial("sna", "foo");
  128. SystemProfileProto fetched;
  129. ASSERT_FALSE(
  130. PersistentSystemProfile::GetSystemProfile(*memory_allocator(), &fetched));
  131. SystemProfileProto proto;
  132. SystemProfileProto::FieldTrial* trial = proto.add_field_trial();
  133. trial->set_name_id(123);
  134. trial->set_group_id(456);
  135. // The system profile should now start fresh. In practice, field trials should
  136. // already be properly updated in subsequent system profiles.
  137. persistent_profile()->SetSystemProfile(proto, false);
  138. ASSERT_TRUE(
  139. PersistentSystemProfile::GetSystemProfile(*memory_allocator(), &fetched));
  140. ASSERT_EQ(1, fetched.field_trial_size());
  141. EXPECT_EQ(123U, fetched.field_trial(0).name_id());
  142. EXPECT_EQ(456U, fetched.field_trial(0).group_id());
  143. persistent_profile()->AddFieldTrial("foo", "bar");
  144. ASSERT_TRUE(
  145. PersistentSystemProfile::GetSystemProfile(*memory_allocator(), &fetched));
  146. ASSERT_EQ(2, fetched.field_trial_size());
  147. EXPECT_EQ(123U, fetched.field_trial(0).name_id());
  148. EXPECT_EQ(456U, fetched.field_trial(0).group_id());
  149. EXPECT_EQ(variations::HashName("foo"), fetched.field_trial(1).name_id());
  150. EXPECT_EQ(variations::HashName("bar"), fetched.field_trial(1).group_id());
  151. }
  152. } // namespace metrics