tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

cordz_test.cc (17139B)


      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.
     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.
     62 absl::string_view MakeString(size_t size) {
     63  thread_local std::string str;
     64  str = std::string(size, '.');
     65  return str;
     66 }
     67 
     68 absl::string_view MakeString(TestCordSize size) {
     69  return MakeString(Length(size));
     70 }
     71 
     72 // Returns a cord with a sampled method of kAppendString.
     73 absl::Cord MakeAppendStringCord(TestCordSize size) {
     74  CordzSamplingIntervalHelper always(1);
     75  absl::Cord cord;
     76  cord.Append(MakeString(size));
     77  return cord;
     78 }
     79 
     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:
     86  Cord& cord() { return cord_; }
     87 
     88  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>
     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 
    122 TEST(CordzTest, ConstructSmallArray) {
    123  CordzSamplingIntervalHelper sample_every{1};
    124  Cord cord(MakeString(TestCordSize::kSmall));
    125  EXPECT_THAT(cord, HasValidCordzInfoOf(Method::kConstructorString));
    126 }
    127 
    128 TEST(CordzTest, ConstructLargeArray) {
    129  CordzSamplingIntervalHelper sample_every{1};
    130  Cord cord(MakeString(TestCordSize::kLarge));
    131  EXPECT_THAT(cord, HasValidCordzInfoOf(Method::kConstructorString));
    132 }
    133 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    271 TEST_P(CordzUpdateTest, AssignLargeArray) {
    272  cord() = MakeString(TestCordSize::kSmall);
    273  EXPECT_THAT(cord(), HasValidCordzInfoOf(Method::kAssignString));
    274 }
    275 
    276 TEST_P(CordzUpdateTest, AssignSmallArray) {
    277  cord() = MakeString(TestCordSize::kSmall);
    278  EXPECT_THAT(cord(), HasValidCordzInfoOf(Method::kAssignString));
    279 }
    280 
    281 TEST_P(CordzUpdateTest, AssignInlinedArray) {
    282  cord() = MakeString(TestCordSize::kInlined);
    283  EXPECT_THAT(GetCordzInfoForTesting(cord()), Eq(nullptr));
    284 }
    285 
    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 
    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 
    303 TEST_P(CordzUpdateTest, AssignInlinedString) {
    304  cord() = std::string(Length(TestCordSize::kInlined), '.');
    305  EXPECT_THAT(GetCordzInfoForTesting(cord()), Eq(nullptr));
    306 }
    307 
    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 
    314 TEST_P(CordzUpdateTest, MoveAppendCord) {
    315  cord().Append(UnsampledCord(MakeString(TestCordSize::kLarge)));
    316  EXPECT_THAT(cord(), HasValidCordzInfoOf(InitialOr(Method::kAppendCord)));
    317 }
    318 
    319 TEST_P(CordzUpdateTest, AppendSmallArray) {
    320  cord().Append(MakeString(TestCordSize::kSmall));
    321  EXPECT_THAT(cord(), HasValidCordzInfoOf(InitialOr(Method::kAppendString)));
    322 }
    323 
    324 TEST_P(CordzUpdateTest, AppendLargeArray) {
    325  cord().Append(MakeString(TestCordSize::kLarge));
    326  EXPECT_THAT(cord(), HasValidCordzInfoOf(InitialOr(Method::kAppendString)));
    327 }
    328 
    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 
    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 
    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 
    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 
    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 
    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 
    370 TEST_P(CordzUpdateTest, PrependSmallArray) {
    371  cord().Prepend(MakeString(TestCordSize::kSmall));
    372  EXPECT_THAT(cord(), HasValidCordzInfoOf(InitialOr(Method::kPrependString)));
    373 }
    374 
    375 TEST_P(CordzUpdateTest, PrependLargeArray) {
    376  cord().Prepend(MakeString(TestCordSize::kLarge));
    377  EXPECT_THAT(cord(), HasValidCordzInfoOf(InitialOr(Method::kPrependString)));
    378 }
    379 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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