1 // Copyright 2021 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 <cstddef>
16 #include <cstring>
17 #include <ostream>
18 #include <string>
19 #include <utility>
20
21 #include "gmock/gmock.h"
22 #include "gtest/gtest.h"
23 #include "absl/base/config.h"
24 #include "absl/strings/cord.h"
25 #include "absl/strings/cord_buffer.h"
26 #include "absl/strings/cord_test_helpers.h"
27 #include "absl/strings/cordz_test_helpers.h"
28 #include "absl/strings/internal/cord_internal.h"
29 #include "absl/strings/internal/cordz_info.h"
30 #include "absl/strings/internal/cordz_sample_token.h"
31 #include "absl/strings/internal/cordz_statistics.h"
32 #include "absl/strings/internal/cordz_update_tracker.h"
33 #include "absl/strings/str_cat.h"
34 #include "absl/strings/string_view.h"
35
36 #ifdef ABSL_INTERNAL_CORDZ_ENABLED
37
38 using testing::Eq;
39 using testing::AnyOf;
40
41 namespace absl {
42 ABSL_NAMESPACE_BEGIN
43
44 using cord_internal::CordzInfo;
45 using cord_internal::CordzSampleToken;
46 using cord_internal::CordzStatistics;
47 using cord_internal::CordzUpdateTracker;
48 using Method = CordzUpdateTracker::MethodIdentifier;
49
50 // Do not print cord contents, we only care about 'size' perhaps.
51 // Note that this method must be inside the named namespace.
PrintTo(const Cord & cord,std::ostream * s)52 inline void PrintTo(const Cord& cord, std::ostream* s) {
53 if (s) *s << "Cord[" << cord.size() << "]";
54 }
55
56 namespace {
57
58 auto constexpr kMaxInline = cord_internal::kMaxInline;
59
60 // Returns a string_view value of the specified length
61 // We do this to avoid 'consuming' large strings in Cord by default.
MakeString(size_t size)62 absl::string_view MakeString(size_t size) {
63 thread_local std::string str;
64 str = std::string(size, '.');
65 return str;
66 }
67
MakeString(TestCordSize size)68 absl::string_view MakeString(TestCordSize size) {
69 return MakeString(Length(size));
70 }
71
72 // Returns a cord with a sampled method of kAppendString.
MakeAppendStringCord(TestCordSize size)73 absl::Cord MakeAppendStringCord(TestCordSize size) {
74 CordzSamplingIntervalHelper always(1);
75 absl::Cord cord;
76 cord.Append(MakeString(size));
77 return cord;
78 }
79
TestParamToString(::testing::TestParamInfo<TestCordSize> size)80 std::string TestParamToString(::testing::TestParamInfo<TestCordSize> size) {
81 return absl::StrCat("On", ToString(size.param), "Cord");
82 }
83
84 class CordzUpdateTest : public testing::TestWithParam<TestCordSize> {
85 public:
cord()86 Cord& cord() { return cord_; }
87
InitialOr(Method method) const88 Method InitialOr(Method method) const {
89 return (GetParam() > TestCordSize::kInlined) ? Method::kConstructorString
90 : method;
91 }
92
93 private:
94 CordzSamplingIntervalHelper sample_every_{1};
95 Cord cord_{MakeString(GetParam())};
96 };
97
98 template <typename T>
ParamToString(::testing::TestParamInfo<T> param)99 std::string ParamToString(::testing::TestParamInfo<T> param) {
100 return std::string(ToString(param.param));
101 }
102
103 INSTANTIATE_TEST_SUITE_P(WithParam, CordzUpdateTest,
104 testing::Values(TestCordSize::kEmpty,
105 TestCordSize::kInlined,
106 TestCordSize::kLarge),
107 TestParamToString);
108
109 class CordzStringTest : public testing::TestWithParam<TestCordSize> {
110 private:
111 CordzSamplingIntervalHelper sample_every_{1};
112 };
113
114 INSTANTIATE_TEST_SUITE_P(WithParam, CordzStringTest,
115 testing::Values(TestCordSize::kInlined,
116 TestCordSize::kStringSso1,
117 TestCordSize::kStringSso2,
118 TestCordSize::kSmall,
119 TestCordSize::kLarge),
120 ParamToString<TestCordSize>);
121
TEST(CordzTest,ConstructSmallArray)122 TEST(CordzTest, ConstructSmallArray) {
123 CordzSamplingIntervalHelper sample_every{1};
124 Cord cord(MakeString(TestCordSize::kSmall));
125 EXPECT_THAT(cord, HasValidCordzInfoOf(Method::kConstructorString));
126 }
127
TEST(CordzTest,ConstructLargeArray)128 TEST(CordzTest, ConstructLargeArray) {
129 CordzSamplingIntervalHelper sample_every{1};
130 Cord cord(MakeString(TestCordSize::kLarge));
131 EXPECT_THAT(cord, HasValidCordzInfoOf(Method::kConstructorString));
132 }
133
TEST_P(CordzStringTest,ConstructString)134 TEST_P(CordzStringTest, ConstructString) {
135 CordzSamplingIntervalHelper sample_every{1};
136 Cord cord(std::string(Length(GetParam()), '.'));
137 if (Length(GetParam()) > kMaxInline) {
138 EXPECT_THAT(cord, HasValidCordzInfoOf(Method::kConstructorString));
139 }
140 }
141
TEST(CordzTest,CopyConstructFromUnsampled)142 TEST(CordzTest, CopyConstructFromUnsampled) {
143 CordzSamplingIntervalHelper sample_every{1};
144 Cord src = UnsampledCord(MakeString(TestCordSize::kLarge));
145 Cord cord(src);
146 EXPECT_THAT(GetCordzInfoForTesting(cord), Eq(nullptr));
147 }
148
TEST(CordzTest,CopyConstructFromSampled)149 TEST(CordzTest, CopyConstructFromSampled) {
150 CordzSamplingIntervalHelper sample_never{99999};
151 Cord src = MakeAppendStringCord(TestCordSize::kLarge);
152 Cord cord(src);
153 ASSERT_THAT(cord, HasValidCordzInfoOf(Method::kConstructorCord));
154 CordzStatistics stats = GetCordzInfoForTesting(cord)->GetCordzStatistics();
155 EXPECT_THAT(stats.parent_method, Eq(Method::kAppendString));
156 EXPECT_THAT(stats.update_tracker.Value(Method::kAppendString), Eq(1));
157 }
158
TEST(CordzTest,MoveConstruct)159 TEST(CordzTest, MoveConstruct) {
160 CordzSamplingIntervalHelper sample_every{1};
161 Cord src(MakeString(TestCordSize::kLarge));
162 Cord cord(std::move(src));
163 EXPECT_THAT(cord, HasValidCordzInfoOf(Method::kConstructorString));
164 }
165
TEST_P(CordzUpdateTest,AssignUnsampledCord)166 TEST_P(CordzUpdateTest, AssignUnsampledCord) {
167 Cord src = UnsampledCord(MakeString(TestCordSize::kLarge));
168 const CordzInfo* info = GetCordzInfoForTesting(cord());
169 cord() = src;
170 EXPECT_THAT(GetCordzInfoForTesting(cord()), Eq(nullptr));
171 EXPECT_FALSE(CordzInfoIsListed(info));
172 }
173
TEST_P(CordzUpdateTest,AssignSampledCord)174 TEST_P(CordzUpdateTest, AssignSampledCord) {
175 Cord src = MakeAppendStringCord(TestCordSize::kLarge);
176 cord() = src;
177 ASSERT_THAT(cord(), HasValidCordzInfoOf(Method::kAssignCord));
178 CordzStatistics stats = GetCordzInfoForTesting(cord())->GetCordzStatistics();
179 EXPECT_THAT(stats.parent_method, Eq(Method::kAppendString));
180 EXPECT_THAT(stats.update_tracker.Value(Method::kAppendString), Eq(1));
181 EXPECT_THAT(stats.update_tracker.Value(Method::kConstructorString), Eq(0));
182 }
183
TEST(CordzUpdateTest,AssignSampledCordToInlined)184 TEST(CordzUpdateTest, AssignSampledCordToInlined) {
185 CordzSamplingIntervalHelper sample_never{99999};
186 Cord cord;
187 Cord src = MakeAppendStringCord(TestCordSize::kLarge);
188 cord = src;
189 ASSERT_THAT(cord, HasValidCordzInfoOf(Method::kAssignCord));
190 CordzStatistics stats = GetCordzInfoForTesting(cord)->GetCordzStatistics();
191 EXPECT_THAT(stats.parent_method, Eq(Method::kAppendString));
192 EXPECT_THAT(stats.update_tracker.Value(Method::kAppendString), Eq(1));
193 EXPECT_THAT(stats.update_tracker.Value(Method::kConstructorString), Eq(0));
194 }
195
TEST(CordzUpdateTest,AssignSampledCordToUnsampledCord)196 TEST(CordzUpdateTest, AssignSampledCordToUnsampledCord) {
197 CordzSamplingIntervalHelper sample_never{99999};
198 Cord cord = UnsampledCord(MakeString(TestCordSize::kLarge));
199 Cord src = MakeAppendStringCord(TestCordSize::kLarge);
200 cord = src;
201 ASSERT_THAT(cord, HasValidCordzInfoOf(Method::kAssignCord));
202 CordzStatistics stats = GetCordzInfoForTesting(cord)->GetCordzStatistics();
203 EXPECT_THAT(stats.parent_method, Eq(Method::kAppendString));
204 EXPECT_THAT(stats.update_tracker.Value(Method::kAppendString), Eq(1));
205 EXPECT_THAT(stats.update_tracker.Value(Method::kConstructorString), Eq(0));
206 }
207
TEST(CordzUpdateTest,AssignUnsampledCordToSampledCordWithoutSampling)208 TEST(CordzUpdateTest, AssignUnsampledCordToSampledCordWithoutSampling) {
209 CordzSamplingIntervalHelper sample_never{99999};
210 Cord cord = MakeAppendStringCord(TestCordSize::kLarge);
211 const CordzInfo* info = GetCordzInfoForTesting(cord);
212 Cord src = UnsampledCord(MakeString(TestCordSize::kLarge));
213 cord = src;
214 EXPECT_THAT(GetCordzInfoForTesting(cord), Eq(nullptr));
215 EXPECT_FALSE(CordzInfoIsListed(info));
216 }
217
TEST(CordzUpdateTest,AssignUnsampledCordToSampledCordWithSampling)218 TEST(CordzUpdateTest, AssignUnsampledCordToSampledCordWithSampling) {
219 CordzSamplingIntervalHelper sample_every{1};
220 Cord cord = MakeAppendStringCord(TestCordSize::kLarge);
221 const CordzInfo* info = GetCordzInfoForTesting(cord);
222 Cord src = UnsampledCord(MakeString(TestCordSize::kLarge));
223 cord = src;
224 EXPECT_THAT(GetCordzInfoForTesting(cord), Eq(nullptr));
225 EXPECT_FALSE(CordzInfoIsListed(info));
226 }
227
TEST(CordzUpdateTest,AssignSampledCordToSampledCord)228 TEST(CordzUpdateTest, AssignSampledCordToSampledCord) {
229 CordzSamplingIntervalHelper sample_every{1};
230 Cord src = MakeAppendStringCord(TestCordSize::kLarge);
231 Cord cord(MakeString(TestCordSize::kLarge));
232 cord = src;
233 ASSERT_THAT(cord, HasValidCordzInfoOf(Method::kAssignCord));
234 CordzStatistics stats = GetCordzInfoForTesting(cord)->GetCordzStatistics();
235 EXPECT_THAT(stats.parent_method, Eq(Method::kAppendString));
236 EXPECT_THAT(stats.update_tracker.Value(Method::kAppendString), Eq(1));
237 EXPECT_THAT(stats.update_tracker.Value(Method::kConstructorString), Eq(0));
238 }
239
TEST(CordzUpdateTest,AssignUnsampledCordToSampledCord)240 TEST(CordzUpdateTest, AssignUnsampledCordToSampledCord) {
241 CordzSamplingIntervalHelper sample_every{1};
242 Cord src = MakeAppendStringCord(TestCordSize::kLarge);
243 Cord cord(MakeString(TestCordSize::kLarge));
244 cord = src;
245 ASSERT_THAT(cord, HasValidCordzInfoOf(Method::kAssignCord));
246 CordzStatistics stats = GetCordzInfoForTesting(cord)->GetCordzStatistics();
247 EXPECT_THAT(stats.parent_method, Eq(Method::kAppendString));
248 EXPECT_THAT(stats.update_tracker.Value(Method::kAppendString), Eq(1));
249 EXPECT_THAT(stats.update_tracker.Value(Method::kConstructorString), Eq(0));
250 }
251
TEST(CordzTest,AssignInlinedCordToSampledCord)252 TEST(CordzTest, AssignInlinedCordToSampledCord) {
253 CordzSampleToken token;
254 CordzSamplingIntervalHelper sample_every{1};
255 Cord cord(MakeString(TestCordSize::kLarge));
256 const CordzInfo* info = GetCordzInfoForTesting(cord);
257 Cord src = UnsampledCord(MakeString(TestCordSize::kInlined));
258 cord = src;
259 EXPECT_THAT(GetCordzInfoForTesting(cord), Eq(nullptr));
260 EXPECT_FALSE(CordzInfoIsListed(info));
261 }
262
TEST(CordzUpdateTest,MoveAssignCord)263 TEST(CordzUpdateTest, MoveAssignCord) {
264 CordzSamplingIntervalHelper sample_every{1};
265 Cord cord;
266 Cord src(MakeString(TestCordSize::kLarge));
267 cord = std::move(src);
268 EXPECT_THAT(cord, HasValidCordzInfoOf(Method::kConstructorString));
269 }
270
TEST_P(CordzUpdateTest,AssignLargeArray)271 TEST_P(CordzUpdateTest, AssignLargeArray) {
272 cord() = MakeString(TestCordSize::kSmall);
273 EXPECT_THAT(cord(), HasValidCordzInfoOf(Method::kAssignString));
274 }
275
TEST_P(CordzUpdateTest,AssignSmallArray)276 TEST_P(CordzUpdateTest, AssignSmallArray) {
277 cord() = MakeString(TestCordSize::kSmall);
278 EXPECT_THAT(cord(), HasValidCordzInfoOf(Method::kAssignString));
279 }
280
TEST_P(CordzUpdateTest,AssignInlinedArray)281 TEST_P(CordzUpdateTest, AssignInlinedArray) {
282 cord() = MakeString(TestCordSize::kInlined);
283 EXPECT_THAT(GetCordzInfoForTesting(cord()), Eq(nullptr));
284 }
285
TEST_P(CordzStringTest,AssignStringToInlined)286 TEST_P(CordzStringTest, AssignStringToInlined) {
287 Cord cord;
288 cord = std::string(Length(GetParam()), '.');
289 if (Length(GetParam()) > kMaxInline) {
290 EXPECT_THAT(cord, HasValidCordzInfoOf(Method::kAssignString));
291 }
292 }
293
TEST_P(CordzStringTest,AssignStringToCord)294 TEST_P(CordzStringTest, AssignStringToCord) {
295 Cord cord(MakeString(TestCordSize::kLarge));
296 cord = std::string(Length(GetParam()), '.');
297 if (Length(GetParam()) > kMaxInline) {
298 EXPECT_THAT(cord, HasValidCordzInfoOf(Method::kConstructorString));
299 EXPECT_THAT(cord, CordzMethodCountEq(Method::kAssignString, 1));
300 }
301 }
302
TEST_P(CordzUpdateTest,AssignInlinedString)303 TEST_P(CordzUpdateTest, AssignInlinedString) {
304 cord() = std::string(Length(TestCordSize::kInlined), '.');
305 EXPECT_THAT(GetCordzInfoForTesting(cord()), Eq(nullptr));
306 }
307
TEST_P(CordzUpdateTest,AppendCord)308 TEST_P(CordzUpdateTest, AppendCord) {
309 Cord src = UnsampledCord(MakeString(TestCordSize::kLarge));
310 cord().Append(src);
311 EXPECT_THAT(cord(), HasValidCordzInfoOf(InitialOr(Method::kAppendCord)));
312 }
313
TEST_P(CordzUpdateTest,MoveAppendCord)314 TEST_P(CordzUpdateTest, MoveAppendCord) {
315 cord().Append(UnsampledCord(MakeString(TestCordSize::kLarge)));
316 EXPECT_THAT(cord(), HasValidCordzInfoOf(InitialOr(Method::kAppendCord)));
317 }
318
TEST_P(CordzUpdateTest,AppendSmallArray)319 TEST_P(CordzUpdateTest, AppendSmallArray) {
320 cord().Append(MakeString(TestCordSize::kSmall));
321 EXPECT_THAT(cord(), HasValidCordzInfoOf(InitialOr(Method::kAppendString)));
322 }
323
TEST_P(CordzUpdateTest,AppendLargeArray)324 TEST_P(CordzUpdateTest, AppendLargeArray) {
325 cord().Append(MakeString(TestCordSize::kLarge));
326 EXPECT_THAT(cord(), HasValidCordzInfoOf(InitialOr(Method::kAppendString)));
327 }
328
TEST_P(CordzStringTest,AppendStringToEmpty)329 TEST_P(CordzStringTest, AppendStringToEmpty) {
330 Cord cord;
331 cord.Append(std::string(Length(GetParam()), '.'));
332 if (Length(GetParam()) > kMaxInline) {
333 EXPECT_THAT(cord, HasValidCordzInfoOf(Method::kAppendString));
334 }
335 }
336
TEST_P(CordzStringTest,AppendStringToInlined)337 TEST_P(CordzStringTest, AppendStringToInlined) {
338 Cord cord(MakeString(TestCordSize::kInlined));
339 cord.Append(std::string(Length(GetParam()), '.'));
340 if (Length(TestCordSize::kInlined) + Length(GetParam()) > kMaxInline) {
341 EXPECT_THAT(cord, HasValidCordzInfoOf(Method::kAppendString));
342 }
343 }
344
TEST_P(CordzStringTest,AppendStringToCord)345 TEST_P(CordzStringTest, AppendStringToCord) {
346 Cord cord(MakeString(TestCordSize::kLarge));
347 cord.Append(std::string(Length(GetParam()), '.'));
348 EXPECT_THAT(cord, HasValidCordzInfoOf(Method::kConstructorString));
349 EXPECT_THAT(cord, CordzMethodCountEq(Method::kAppendString, 1));
350 }
351
TEST(CordzTest,MakeCordFromExternal)352 TEST(CordzTest, MakeCordFromExternal) {
353 CordzSamplingIntervalHelper sample_every{1};
354 Cord cord = MakeCordFromExternal("Hello world", [](absl::string_view) {});
355 EXPECT_THAT(cord, HasValidCordzInfoOf(Method::kMakeCordFromExternal));
356 }
357
TEST(CordzTest,MakeCordFromEmptyExternal)358 TEST(CordzTest, MakeCordFromEmptyExternal) {
359 CordzSamplingIntervalHelper sample_every{1};
360 Cord cord = MakeCordFromExternal({}, [](absl::string_view) {});
361 EXPECT_THAT(GetCordzInfoForTesting(cord), Eq(nullptr));
362 }
363
TEST_P(CordzUpdateTest,PrependCord)364 TEST_P(CordzUpdateTest, PrependCord) {
365 Cord src = UnsampledCord(MakeString(TestCordSize::kLarge));
366 cord().Prepend(src);
367 EXPECT_THAT(cord(), HasValidCordzInfoOf(InitialOr(Method::kPrependCord)));
368 }
369
TEST_P(CordzUpdateTest,PrependSmallArray)370 TEST_P(CordzUpdateTest, PrependSmallArray) {
371 cord().Prepend(MakeString(TestCordSize::kSmall));
372 EXPECT_THAT(cord(), HasValidCordzInfoOf(InitialOr(Method::kPrependString)));
373 }
374
TEST_P(CordzUpdateTest,PrependLargeArray)375 TEST_P(CordzUpdateTest, PrependLargeArray) {
376 cord().Prepend(MakeString(TestCordSize::kLarge));
377 EXPECT_THAT(cord(), HasValidCordzInfoOf(InitialOr(Method::kPrependString)));
378 }
379
TEST_P(CordzStringTest,PrependStringToEmpty)380 TEST_P(CordzStringTest, PrependStringToEmpty) {
381 Cord cord;
382 cord.Prepend(std::string(Length(GetParam()), '.'));
383 if (Length(GetParam()) > kMaxInline) {
384 EXPECT_THAT(cord, HasValidCordzInfoOf(Method::kPrependString));
385 }
386 }
387
TEST_P(CordzStringTest,PrependStringToInlined)388 TEST_P(CordzStringTest, PrependStringToInlined) {
389 Cord cord(MakeString(TestCordSize::kInlined));
390 cord.Prepend(std::string(Length(GetParam()), '.'));
391 if (Length(TestCordSize::kInlined) + Length(GetParam()) > kMaxInline) {
392 EXPECT_THAT(cord, HasValidCordzInfoOf(Method::kPrependString));
393 }
394 }
395
TEST_P(CordzStringTest,PrependStringToCord)396 TEST_P(CordzStringTest, PrependStringToCord) {
397 Cord cord(MakeString(TestCordSize::kLarge));
398 cord.Prepend(std::string(Length(GetParam()), '.'));
399 EXPECT_THAT(cord, HasValidCordzInfoOf(Method::kConstructorString));
400 EXPECT_THAT(cord, CordzMethodCountEq(Method::kPrependString, 1));
401 }
402
TEST(CordzTest,RemovePrefix)403 TEST(CordzTest, RemovePrefix) {
404 CordzSamplingIntervalHelper sample_every(1);
405 Cord cord(MakeString(TestCordSize::kLarge));
406
407 // Half the cord
408 cord.RemovePrefix(cord.size() / 2);
409 EXPECT_THAT(cord, HasValidCordzInfoOf(Method::kConstructorString));
410 EXPECT_THAT(cord, CordzMethodCountEq(Method::kRemovePrefix, 1));
411
412 // TODO(mvels): RemovePrefix does not reset to inlined, except if empty?
413 cord.RemovePrefix(cord.size() - kMaxInline);
414 EXPECT_THAT(cord, HasValidCordzInfoOf(Method::kConstructorString));
415 EXPECT_THAT(cord, CordzMethodCountEq(Method::kRemovePrefix, 2));
416
417 cord.RemovePrefix(cord.size());
418 EXPECT_THAT(GetCordzInfoForTesting(cord), Eq(nullptr));
419 }
420
TEST(CordzTest,RemoveSuffix)421 TEST(CordzTest, RemoveSuffix) {
422 CordzSamplingIntervalHelper sample_every(1);
423 Cord cord(MakeString(TestCordSize::kLarge));
424
425 // Half the cord
426 cord.RemoveSuffix(cord.size() / 2);
427 EXPECT_THAT(cord, HasValidCordzInfoOf(Method::kConstructorString));
428 EXPECT_THAT(cord, CordzMethodCountEq(Method::kRemoveSuffix, 1));
429
430 // TODO(mvels): RemoveSuffix does not reset to inlined, except if empty?
431 cord.RemoveSuffix(cord.size() - kMaxInline);
432 EXPECT_THAT(cord, HasValidCordzInfoOf(Method::kConstructorString));
433 EXPECT_THAT(cord, CordzMethodCountEq(Method::kRemoveSuffix, 2));
434
435 cord.RemoveSuffix(cord.size());
436 EXPECT_THAT(GetCordzInfoForTesting(cord), Eq(nullptr));
437 }
438
TEST(CordzTest,SubCordFromUnsampledCord)439 TEST(CordzTest, SubCordFromUnsampledCord) {
440 CordzSamplingIntervalHelper sample_every{1};
441 Cord src = UnsampledCord(MakeString(TestCordSize::kLarge));
442 Cord cord = src.Subcord(10, src.size() / 2);
443 EXPECT_THAT(GetCordzInfoForTesting(cord), Eq(nullptr));
444 }
445
TEST(CordzTest,SubCordFromSampledCord)446 TEST(CordzTest, SubCordFromSampledCord) {
447 CordzSamplingIntervalHelper sample_never{99999};
448 Cord src = MakeAppendStringCord(TestCordSize::kLarge);
449 Cord cord = src.Subcord(10, src.size() / 2);
450 ASSERT_THAT(cord, HasValidCordzInfoOf(Method::kSubCord));
451 CordzStatistics stats = GetCordzInfoForTesting(cord)->GetCordzStatistics();
452 EXPECT_THAT(stats.parent_method, Eq(Method::kAppendString));
453 EXPECT_THAT(stats.update_tracker.Value(Method::kAppendString), Eq(1));
454 }
455
TEST(CordzTest,SmallSubCord)456 TEST(CordzTest, SmallSubCord) {
457 CordzSamplingIntervalHelper sample_never{99999};
458 Cord src = MakeAppendStringCord(TestCordSize::kLarge);
459 Cord cord = src.Subcord(10, kMaxInline + 1);
460 EXPECT_THAT(cord, HasValidCordzInfoOf(Method::kSubCord));
461 }
462
463 } // namespace
464
465 ABSL_NAMESPACE_END
466 } // namespace absl
467
468 #endif // ABSL_INTERNAL_CORDZ_ENABLED
469