bloaty/third_party/abseil-cpp/absl/strings/internal/cordz_sample_token_test.cc
Go to the documentation of this file.
1 // Copyright 2019 The Abseil Authors.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include "absl/strings/internal/cordz_sample_token.h"
16 
17 #include <memory>
18 #include <type_traits>
19 #include <vector>
20 
21 #include "gmock/gmock.h"
22 #include "gtest/gtest.h"
23 #include "absl/memory/memory.h"
24 #include "absl/random/random.h"
25 #include "absl/strings/cordz_test_helpers.h"
26 #include "absl/strings/internal/cord_rep_flat.h"
27 #include "absl/strings/internal/cordz_handle.h"
28 #include "absl/strings/internal/cordz_info.h"
29 #include "absl/synchronization/internal/thread_pool.h"
30 #include "absl/synchronization/notification.h"
31 #include "absl/time/clock.h"
32 #include "absl/time/time.h"
33 
34 namespace absl {
36 namespace cord_internal {
37 namespace {
38 
42 
43 // Used test values
44 auto constexpr kTrackCordMethod = CordzUpdateTracker::kConstructorString;
45 
46 TEST(CordzSampleTokenTest, IteratorTraits) {
48  "");
51  "");
53  static_assert(
54  std::is_same<
55  std::iterator_traits<CordzSampleToken::Iterator>::iterator_category,
56  std::input_iterator_tag>::value,
57  "");
58  static_assert(
60  const CordzInfo&>::value,
61  "");
62  static_assert(
63  std::is_same<
64  std::iterator_traits<CordzSampleToken::Iterator>::difference_type,
65  ptrdiff_t>::value,
66  "");
67  static_assert(
68  std::is_same<std::iterator_traits<CordzSampleToken::Iterator>::pointer,
69  const CordzInfo*>::value,
70  "");
71  static_assert(
72  std::is_same<std::iterator_traits<CordzSampleToken::Iterator>::reference,
73  const CordzInfo&>::value,
74  "");
75 }
76 
77 TEST(CordzSampleTokenTest, IteratorEmpty) {
78  CordzSampleToken token;
79  EXPECT_THAT(token.begin(), Eq(token.end()));
80 }
81 
82 TEST(CordzSampleTokenTest, Iterator) {
83  TestCordData cord1, cord2, cord3;
84  CordzInfo::TrackCord(cord1.data, kTrackCordMethod);
85  CordzInfo* info1 = cord1.data.cordz_info();
86  CordzInfo::TrackCord(cord2.data, kTrackCordMethod);
87  CordzInfo* info2 = cord2.data.cordz_info();
88  CordzInfo::TrackCord(cord3.data, kTrackCordMethod);
89  CordzInfo* info3 = cord3.data.cordz_info();
90 
91  CordzSampleToken token;
92  std::vector<const CordzInfo*> found;
93  for (const CordzInfo& cord_info : token) {
94  found.push_back(&cord_info);
95  }
96 
97  EXPECT_THAT(found, ElementsAre(info3, info2, info1));
98 
99  info1->Untrack();
100  info2->Untrack();
101  info3->Untrack();
102 }
103 
104 TEST(CordzSampleTokenTest, IteratorEquality) {
105  TestCordData cord1;
106  TestCordData cord2;
107  TestCordData cord3;
108  CordzInfo::TrackCord(cord1.data, kTrackCordMethod);
109  CordzInfo* info1 = cord1.data.cordz_info();
110 
111  CordzSampleToken token1;
112  // lhs starts with the CordzInfo corresponding to cord1 at the head.
113  CordzSampleToken::Iterator lhs = token1.begin();
114 
115  CordzInfo::TrackCord(cord2.data, kTrackCordMethod);
116  CordzInfo* info2 = cord2.data.cordz_info();
117 
118  CordzSampleToken token2;
119  // rhs starts with the CordzInfo corresponding to cord2 at the head.
120  CordzSampleToken::Iterator rhs = token2.begin();
121 
122  CordzInfo::TrackCord(cord3.data, kTrackCordMethod);
123  CordzInfo* info3 = cord3.data.cordz_info();
124 
125  // lhs is on cord1 while rhs is on cord2.
126  EXPECT_THAT(lhs, Ne(rhs));
127 
128  rhs++;
129  // lhs and rhs are both on cord1, but they didn't come from the same
130  // CordzSampleToken.
131  EXPECT_THAT(lhs, Ne(rhs));
132 
133  lhs++;
134  rhs++;
135  // Both lhs and rhs are done, so they are on nullptr.
136  EXPECT_THAT(lhs, Eq(rhs));
137 
138  info1->Untrack();
139  info2->Untrack();
140  info3->Untrack();
141 }
142 
143 TEST(CordzSampleTokenTest, MultiThreaded) {
144  Notification stop;
145  static constexpr int kNumThreads = 4;
146  static constexpr int kNumCords = 3;
147  static constexpr int kNumTokens = 3;
149 
150  for (int i = 0; i < kNumThreads; ++i) {
151  pool.Schedule([&stop]() {
153  TestCordData cords[kNumCords];
154  std::unique_ptr<CordzSampleToken> tokens[kNumTokens];
155 
156  while (!stop.HasBeenNotified()) {
157  // Randomly perform one of five actions:
158  // 1) Untrack
159  // 2) Track
160  // 3) Iterate over Cords visible to a token.
161  // 4) Unsample
162  // 5) Sample
163  int index = absl::Uniform(gen, 0, kNumCords);
164  if (absl::Bernoulli(gen, 0.5)) {
165  TestCordData& cord = cords[index];
166  // Track/untrack.
167  if (cord.data.is_profiled()) {
168  // 1) Untrack
169  cord.data.cordz_info()->Untrack();
170  cord.data.clear_cordz_info();;
171  } else {
172  // 2) Track
173  CordzInfo::TrackCord(cord.data, kTrackCordMethod);
174  }
175  } else {
176  std::unique_ptr<CordzSampleToken>& token = tokens[index];
177  if (token) {
178  if (absl::Bernoulli(gen, 0.5)) {
179  // 3) Iterate over Cords visible to a token.
180  for (const CordzInfo& info : *token) {
181  // This is trivial work to allow us to compile the loop.
182  EXPECT_THAT(info.Next(*token), Ne(&info));
183  }
184  } else {
185  // 4) Unsample
186  token = nullptr;
187  }
188  } else {
189  // 5) Sample
190  token = absl::make_unique<CordzSampleToken>();
191  }
192  }
193  }
194  for (TestCordData& cord : cords) {
195  CordzInfo::MaybeUntrackCord(cord.data.cordz_info());
196  }
197  });
198  }
199  // The threads will hammer away. Give it a little bit of time for tsan to
200  // spot errors.
202  stop.Notify();
203 }
204 
205 } // namespace
206 } // namespace cord_internal
208 } // namespace absl
absl::synchronization_internal::ThreadPool
Definition: third_party/abseil-cpp/absl/synchronization/internal/thread_pool.h:33
EXPECT_THAT
#define EXPECT_THAT(value, matcher)
testing::Ne
internal::NeMatcher< Rhs > Ne(Rhs x)
Definition: cares/cares/test/gmock-1.8.0/gmock/gmock.h:8609
absl::TEST
TEST(NotificationTest, SanityTest)
Definition: abseil-cpp/absl/synchronization/notification_test.cc:126
absl::SleepFor
void SleepFor(absl::Duration duration)
Definition: abseil-cpp/absl/time/clock.h:70
ABSL_NAMESPACE_END
#define ABSL_NAMESPACE_END
Definition: third_party/abseil-cpp/absl/base/config.h:171
testing::ElementsAre
internal::ElementsAreMatcher< ::testing::tuple<> > ElementsAre()
Definition: cares/cares/test/gmock-1.8.0/gmock/gmock.h:13040
absl::cord_internal::CordzUpdateTracker::kConstructorString
@ kConstructorString
Definition: abseil-cpp/absl/strings/internal/cordz_update_tracker.h:50
ABSL_NAMESPACE_BEGIN
#define ABSL_NAMESPACE_BEGIN
Definition: third_party/abseil-cpp/absl/base/config.h:170
gen_stats_data.found
bool found
Definition: gen_stats_data.py:61
absl::cord_internal::CordzInfo::MaybeUntrackCord
static void MaybeUntrackCord(CordzInfo *info)
Definition: abseil-cpp/absl/strings/internal/cordz_info.h:269
testing::Eq
internal::EqMatcher< T > Eq(T x)
Definition: cares/cares/test/gmock-1.8.0/gmock/gmock.h:8561
absl::compare_internal::value_type
int8_t value_type
Definition: abseil-cpp/absl/types/compare.h:45
gen
OPENSSL_EXPORT GENERAL_NAME * gen
Definition: x509v3.h:495
value
const char * value
Definition: hpack_parser_table.cc:165
absl::Seconds
constexpr Duration Seconds(T n)
Definition: third_party/abseil-cpp/absl/time/time.h:419
kNumThreads
const int kNumThreads
Definition: thread_stress_test.cc:46
absl::random_internal::NonsecureURBGBase< random_internal::randen_engine< uint64_t > >
absl::inlined_vector_internal::Iterator
Pointer< A > Iterator
Definition: abseil-cpp/absl/container/internal/inlined_vector.h:64
pool
InternalDescriptorPool * pool
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/protobuf.h:807
stop
static const char stop[]
Definition: benchmark-async-pummel.c:35
absl
Definition: abseil-cpp/absl/algorithm/algorithm.h:31
absl::cord_internal::CordzInfo::TrackCord
static void TrackCord(InlineData &cord, MethodIdentifier method)
Definition: abseil-cpp/absl/strings/internal/cordz_info.cc:254
i
uint64_t i
Definition: abseil-cpp/absl/container/btree_benchmark.cc:230


grpc
Author(s):
autogenerated on Fri May 16 2025 02:58:04