YugabyteDB (2.13.0.0-b42, bfc6a6643e7399ac8a0e81d06a3ee6d6571b33ab)

Coverage Report

Created: 2022-03-09 17:30

/Users/deen/code/yugabyte-db/src/yb/util/mt-hdr_histogram-test.cc
Line
Count
Source
1
// Licensed to the Apache Software Foundation (ASF) under one
2
// or more contributor license agreements.  See the NOTICE file
3
// distributed with this work for additional information
4
// regarding copyright ownership.  The ASF licenses this file
5
// to you under the Apache License, Version 2.0 (the
6
// "License"); you may not use this file except in compliance
7
// with the License.  You may obtain a copy of the License at
8
//
9
//   http://www.apache.org/licenses/LICENSE-2.0
10
//
11
// Unless required by applicable law or agreed to in writing,
12
// software distributed under the License is distributed on an
13
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14
// KIND, either express or implied.  See the License for the
15
// specific language governing permissions and limitations
16
// under the License.
17
//
18
// The following only applies to changes made to this file as part of YugaByte development.
19
//
20
// Portions Copyright (c) YugaByte, Inc.
21
//
22
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
23
// in compliance with the License.  You may obtain a copy of the License at
24
//
25
// http://www.apache.org/licenses/LICENSE-2.0
26
//
27
// Unless required by applicable law or agreed to in writing, software distributed under the License
28
// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
29
// or implied.  See the License for the specific language governing permissions and limitations
30
// under the License.
31
//
32
#include <vector>
33
34
#include <gtest/gtest.h>
35
36
#include "yb/gutil/ref_counted.h"
37
#include "yb/gutil/stl_util.h"
38
#include "yb/util/hdr_histogram.h"
39
#include "yb/util/status.h"
40
#include "yb/util/status_log.h"
41
#include "yb/util/test_util.h"
42
#include "yb/util/thread.h"
43
44
DEFINE_int32(histogram_test_num_threads, 16,
45
    "Number of threads to spawn for mt-hdr_histogram test");
46
DEFINE_uint64(histogram_test_num_increments_per_thread, 100000LU,
47
    "Number of times to call Increment() per thread in mt-hdr_histogram test");
48
49
using std::vector;
50
51
namespace yb {
52
53
class MtHdrHistogramTest : public YBTest {
54
 public:
55
2
  MtHdrHistogramTest() {
56
2
    num_threads_ = FLAGS_histogram_test_num_threads;
57
2
    num_times_ = FLAGS_histogram_test_num_increments_per_thread;
58
2
  }
59
60
 protected:
61
  int num_threads_;
62
  uint64_t num_times_;
63
};
64
65
// Increment a counter a bunch of times in the same bucket
66
32
static void IncrementSameHistValue(HdrHistogram* hist, uint64_t value, uint64_t times) {
67
1.48M
  for (uint64_t i = 0; i < times; i++) {
68
1.48M
    hist->Increment(value);
69
1.48M
  }
70
32
}
71
72
1
TEST_F(MtHdrHistogramTest, ConcurrentWriteTest) {
73
1
  const uint64_t kValue = 1LU;
74
75
1
  HdrHistogram hist(100000LU, 3);
76
77
1
  auto threads = new scoped_refptr<yb::Thread>[num_threads_];
78
17
  for (int i = 0; i < num_threads_; i++) {
79
16
    CHECK_OK(yb::Thread::Create("test", strings::Substitute("thread-$0", i),
80
16
        IncrementSameHistValue, &hist, kValue, num_times_, &threads[i]));
81
16
  }
82
17
  for (int i = 0; i < num_threads_; i++) {
83
16
    CHECK_OK(ThreadJoiner(threads[i].get()).Join());
84
16
  }
85
86
1
  HdrHistogram snapshot(hist);
87
1
  ASSERT_EQ(num_threads_ * num_times_, snapshot.CountInBucketForValue(kValue));
88
89
1
  delete[] threads;
90
1
}
91
92
// Copy while writing, then iterate to ensure copies are consistent.
93
1
TEST_F(MtHdrHistogramTest, ConcurrentCopyWhileWritingTest) {
94
1
  const int kNumCopies = 10;
95
1
  const uint64_t kValue = 1;
96
97
1
  HdrHistogram hist(100000LU, 3);
98
99
1
  auto threads = new scoped_refptr<yb::Thread>[num_threads_];
100
17
  for (int i = 0; i < num_threads_; i++) {
101
16
    CHECK_OK(yb::Thread::Create("test", strings::Substitute("thread-$0", i),
102
16
        IncrementSameHistValue, &hist, kValue, num_times_, &threads[i]));
103
16
  }
104
105
  // This is somewhat racy but the goal is to catch this issue at least
106
  // most of the time. At the time of this writing, before fixing a bug where
107
  // the total count stored in a copied histogram may not match its internal
108
  // counts (under concurrent writes), this test fails for me on 100/100 runs.
109
1
  vector<HdrHistogram *> snapshots;
110
1
  ElementDeleter deleter(&snapshots);
111
11
  for (int i = 0; i < kNumCopies; i++) {
112
10
    snapshots.push_back(new HdrHistogram(hist));
113
10
    SleepFor(MonoDelta::FromMicroseconds(100));
114
10
  }
115
11
  for (int i = 0; i < kNumCopies; i++) {
116
10
    snapshots[i]->MeanValue(); // Will crash if underlying iterator is inconsistent.
117
10
  }
118
119
17
  for (int i = 0; i < num_threads_; i++) {
120
16
    CHECK_OK(ThreadJoiner(threads[i].get()).Join());
121
16
  }
122
123
1
  delete[] threads;
124
1
}
125
126
} // namespace yb