• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 //
3 // Copyright 2016 gRPC authors.
4 //
5 // Licensed under the Apache License, Version 2.0 (the "License");
6 // you may not use this file except in compliance with the License.
7 // 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, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
16 //
17 //
18 
19 #include "src/core/lib/transport/bdp_estimator.h"
20 
21 #include <grpc/grpc.h>
22 #include <stdlib.h>
23 
24 #include <algorithm>
25 #include <atomic>
26 
27 #include "gtest/gtest.h"
28 #include "src/core/lib/iomgr/exec_ctx.h"
29 #include "src/core/lib/iomgr/timer_manager.h"
30 #include "test/core/test_util/test_config.h"
31 
32 extern gpr_timespec (*gpr_now_impl)(gpr_clock_type clock_type);
33 
34 namespace grpc_core {
35 namespace testing {
36 namespace {
37 std::atomic<int> g_clock{123};
38 
fake_gpr_now(gpr_clock_type clock_type)39 gpr_timespec fake_gpr_now(gpr_clock_type clock_type) {
40   gpr_timespec ts;
41   ts.tv_sec = g_clock.load();
42   ts.tv_nsec = 0;
43   ts.clock_type = clock_type;
44   return ts;
45 }
46 
inc_time(void)47 void inc_time(void) { g_clock.fetch_add(30); }
48 }  // namespace
49 
TEST(BdpEstimatorTest,NoOp)50 TEST(BdpEstimatorTest, NoOp) { BdpEstimator est("test"); }
51 
TEST(BdpEstimatorTest,EstimateBdpNoSamples)52 TEST(BdpEstimatorTest, EstimateBdpNoSamples) {
53   BdpEstimator est("test");
54   est.EstimateBdp();
55 }
56 
57 namespace {
AddSamples(BdpEstimator * estimator,int64_t * samples,size_t n)58 void AddSamples(BdpEstimator* estimator, int64_t* samples, size_t n) {
59   estimator->AddIncomingBytes(1234567);
60   inc_time();
61   ExecCtx exec_ctx;
62   estimator->SchedulePing();
63   estimator->StartPing();
64   for (size_t i = 0; i < n; i++) {
65     estimator->AddIncomingBytes(samples[i]);
66   }
67   gpr_sleep_until(gpr_time_add(gpr_now(GPR_CLOCK_REALTIME),
68                                gpr_time_from_millis(1, GPR_TIMESPAN)));
69   ExecCtx::Get()->InvalidateNow();
70   estimator->CompletePing();
71 }
72 
AddSample(BdpEstimator * estimator,int64_t sample)73 void AddSample(BdpEstimator* estimator, int64_t sample) {
74   AddSamples(estimator, &sample, 1);
75 }
76 }  // namespace
77 
TEST(BdpEstimatorTest,GetEstimate1Sample)78 TEST(BdpEstimatorTest, GetEstimate1Sample) {
79   BdpEstimator est("test");
80   AddSample(&est, 100);
81   est.EstimateBdp();
82 }
83 
TEST(BdpEstimatorTest,GetEstimate2Samples)84 TEST(BdpEstimatorTest, GetEstimate2Samples) {
85   BdpEstimator est("test");
86   AddSample(&est, 100);
87   AddSample(&est, 100);
88   est.EstimateBdp();
89 }
90 
TEST(BdpEstimatorTest,GetEstimate3Samples)91 TEST(BdpEstimatorTest, GetEstimate3Samples) {
92   BdpEstimator est("test");
93   AddSample(&est, 100);
94   AddSample(&est, 100);
95   AddSample(&est, 100);
96   est.EstimateBdp();
97 }
98 
99 namespace {
NextPow2(int64_t v)100 int64_t NextPow2(int64_t v) {
101   v--;
102   v |= v >> 1;
103   v |= v >> 2;
104   v |= v >> 4;
105   v |= v >> 8;
106   v |= v >> 16;
107   v |= v >> 32;
108   v++;
109   return v;
110 }
111 }  // namespace
112 
113 class BdpEstimatorRandomTest : public ::testing::TestWithParam<size_t> {};
114 
TEST_P(BdpEstimatorRandomTest,GetEstimateRandomValues)115 TEST_P(BdpEstimatorRandomTest, GetEstimateRandomValues) {
116   BdpEstimator est("test");
117   const int kMaxSample = 65535;
118   int min = kMaxSample;
119   int max = 0;
120   for (size_t i = 0; i < GetParam(); i++) {
121     int sample = rand() % (kMaxSample + 1);
122     if (sample < min) min = sample;
123     if (sample > max) max = sample;
124     AddSample(&est, sample);
125     if (i >= 3) {
126       EXPECT_LE(est.EstimateBdp(), std::max(int64_t(65536), 2 * NextPow2(max)))
127           << " min:" << min << " max:" << max << " sample:" << sample;
128     }
129   }
130 }
131 
132 INSTANTIATE_TEST_SUITE_P(TooManyNames, BdpEstimatorRandomTest,
133                          ::testing::Values(3, 4, 6, 9, 13, 19, 28, 42, 63, 94,
134                                            141, 211, 316, 474, 711));
135 
136 }  // namespace testing
137 }  // namespace grpc_core
138 
main(int argc,char ** argv)139 int main(int argc, char** argv) {
140   grpc::testing::TestEnvironment env(&argc, argv);
141   gpr_now_impl = grpc_core::testing::fake_gpr_now;
142   grpc_init();
143   grpc_timer_manager_set_threading(false);
144   ::testing::InitGoogleTest(&argc, argv);
145   int ret = RUN_ALL_TESTS();
146   grpc_shutdown();
147   return ret;
148 }
149