sequence_local_storage_slot_unittest.cc 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  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 "base/threading/sequence_local_storage_slot.h"
  5. #include <utility>
  6. #include "base/memory/ptr_util.h"
  7. #include "base/threading/sequence_local_storage_map.h"
  8. #include "testing/gtest/include/gtest/gtest.h"
  9. namespace base {
  10. namespace {
  11. class SequenceLocalStorageSlotTest : public testing::Test {
  12. public:
  13. SequenceLocalStorageSlotTest(const SequenceLocalStorageSlotTest&) = delete;
  14. SequenceLocalStorageSlotTest& operator=(const SequenceLocalStorageSlotTest&) =
  15. delete;
  16. protected:
  17. SequenceLocalStorageSlotTest()
  18. : scoped_sequence_local_storage_(&sequence_local_storage_) {}
  19. internal::SequenceLocalStorageMap sequence_local_storage_;
  20. internal::ScopedSetSequenceLocalStorageMapForCurrentThread
  21. scoped_sequence_local_storage_;
  22. };
  23. } // namespace
  24. // Verify that a value stored with Set() can be retrieved with Get().
  25. TEST_F(SequenceLocalStorageSlotTest, GetEmplace) {
  26. SequenceLocalStorageSlot<int> slot;
  27. slot.emplace(5);
  28. EXPECT_EQ(*slot, 5);
  29. }
  30. // Verify that inserting an object in a SequenceLocalStorageSlot creates a copy
  31. // of that object independent of the original one.
  32. TEST_F(SequenceLocalStorageSlotTest, EmplaceObjectIsIndependent) {
  33. bool should_be_false = false;
  34. SequenceLocalStorageSlot<bool> slot;
  35. slot.emplace(should_be_false);
  36. EXPECT_FALSE(*slot);
  37. *slot = true;
  38. EXPECT_TRUE(*slot);
  39. EXPECT_NE(should_be_false, *slot);
  40. }
  41. // Verify that multiple slots work and that calling Get after overwriting
  42. // a value in a slot yields the new value.
  43. TEST_F(SequenceLocalStorageSlotTest, GetEmplaceMultipleSlots) {
  44. SequenceLocalStorageSlot<int> slot1;
  45. SequenceLocalStorageSlot<int> slot2;
  46. SequenceLocalStorageSlot<int> slot3;
  47. EXPECT_FALSE(slot1);
  48. EXPECT_FALSE(slot2);
  49. EXPECT_FALSE(slot3);
  50. slot1.emplace(1);
  51. slot2.emplace(2);
  52. slot3.emplace(3);
  53. EXPECT_TRUE(slot1);
  54. EXPECT_TRUE(slot2);
  55. EXPECT_TRUE(slot3);
  56. EXPECT_EQ(*slot1, 1);
  57. EXPECT_EQ(*slot2, 2);
  58. EXPECT_EQ(*slot3, 3);
  59. slot3.emplace(4);
  60. slot2.emplace(5);
  61. slot1.emplace(6);
  62. EXPECT_EQ(*slot3, 4);
  63. EXPECT_EQ(*slot2, 5);
  64. EXPECT_EQ(*slot1, 6);
  65. }
  66. // Verify that changing the value returned by Get() changes the value
  67. // in sequence local storage.
  68. TEST_F(SequenceLocalStorageSlotTest, GetReferenceModifiable) {
  69. SequenceLocalStorageSlot<bool> slot;
  70. slot.emplace(false);
  71. *slot = true;
  72. EXPECT_TRUE(*slot);
  73. }
  74. // Verify that a move-only type can be stored in sequence local storage.
  75. TEST_F(SequenceLocalStorageSlotTest, EmplaceGetWithMoveOnlyType) {
  76. std::unique_ptr<int> int_unique_ptr = std::make_unique<int>(5);
  77. SequenceLocalStorageSlot<std::unique_ptr<int>> slot;
  78. slot.emplace(std::move(int_unique_ptr));
  79. EXPECT_EQ(*slot->get(), 5);
  80. }
  81. // Verify that a Get() without a previous Set() on a slot returns a
  82. // default-constructed value.
  83. TEST_F(SequenceLocalStorageSlotTest, GetWithoutSetDefaultConstructs) {
  84. struct DefaultConstructable {
  85. int x = 0x12345678;
  86. };
  87. SequenceLocalStorageSlot<DefaultConstructable> slot;
  88. EXPECT_EQ(slot.GetOrCreateValue().x, 0x12345678);
  89. }
  90. // Verify that a GetOrCreateValue() without a previous emplace() on a slot with
  91. // a POD-type returns a default-constructed value.
  92. // Note: this test could be flaky and give a false pass. If it's flaky, the test
  93. // might've "passed" because the memory for the slot happened to be zeroed.
  94. TEST_F(SequenceLocalStorageSlotTest, GetWithoutSetDefaultConstructsPOD) {
  95. SequenceLocalStorageSlot<void*> slot;
  96. EXPECT_EQ(slot.GetOrCreateValue(), nullptr);
  97. }
  98. // Verify that the value of a slot is specific to a SequenceLocalStorageMap
  99. TEST(SequenceLocalStorageSlotMultipleMapTest, EmplaceGetMultipleMapsOneSlot) {
  100. SequenceLocalStorageSlot<unsigned int> slot;
  101. internal::SequenceLocalStorageMap sequence_local_storage_maps[5];
  102. // Set the value of the slot to be the index of the current
  103. // SequenceLocalStorageMaps in the vector
  104. for (unsigned int i = 0; i < std::size(sequence_local_storage_maps); ++i) {
  105. internal::ScopedSetSequenceLocalStorageMapForCurrentThread
  106. scoped_sequence_local_storage(&sequence_local_storage_maps[i]);
  107. slot.emplace(i);
  108. }
  109. for (unsigned int i = 0; i < std::size(sequence_local_storage_maps); ++i) {
  110. internal::ScopedSetSequenceLocalStorageMapForCurrentThread
  111. scoped_sequence_local_storage(&sequence_local_storage_maps[i]);
  112. EXPECT_EQ(*slot, i);
  113. }
  114. }
  115. } // namespace base