mirror of https://github.com/grpc/grpc.git
commit
d94c9f263e
9 changed files with 306 additions and 280 deletions
@ -1,162 +0,0 @@ |
|||||||
/*
|
|
||||||
* |
|
||||||
* Copyright 2016 gRPC authors. |
|
||||||
* |
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|
||||||
* you may not use this file except in compliance with the License. |
|
||||||
* You may obtain a copy of the License at |
|
||||||
* |
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
* |
|
||||||
* Unless required by applicable law or agreed to in writing, software |
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS, |
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
||||||
* See the License for the specific language governing permissions and |
|
||||||
* limitations under the License. |
|
||||||
* |
|
||||||
*/ |
|
||||||
|
|
||||||
#include "src/core/lib/transport/bdp_estimator.h" |
|
||||||
|
|
||||||
#include <grpc/grpc.h> |
|
||||||
#include <grpc/support/alloc.h> |
|
||||||
#include <grpc/support/log.h> |
|
||||||
#include <grpc/support/string_util.h> |
|
||||||
#include <grpc/support/useful.h> |
|
||||||
#include <limits.h> |
|
||||||
#include "src/core/lib/iomgr/timer_manager.h" |
|
||||||
#include "src/core/lib/support/string.h" |
|
||||||
#include "test/core/util/test_config.h" |
|
||||||
|
|
||||||
extern gpr_timespec (*gpr_now_impl)(gpr_clock_type clock_type); |
|
||||||
|
|
||||||
static int g_clock = 0; |
|
||||||
|
|
||||||
static gpr_timespec fake_gpr_now(gpr_clock_type clock_type) { |
|
||||||
return (gpr_timespec){ |
|
||||||
.tv_sec = g_clock, .tv_nsec = 0, .clock_type = clock_type, |
|
||||||
}; |
|
||||||
} |
|
||||||
|
|
||||||
static void inc_time(void) { g_clock += 30; } |
|
||||||
|
|
||||||
static void test_noop(void) { |
|
||||||
gpr_log(GPR_INFO, "test_noop"); |
|
||||||
grpc_bdp_estimator est; |
|
||||||
grpc_bdp_estimator_init(&est, "test"); |
|
||||||
} |
|
||||||
|
|
||||||
static void test_get_estimate_no_samples(void) { |
|
||||||
gpr_log(GPR_INFO, "test_get_estimate_no_samples"); |
|
||||||
grpc_bdp_estimator est; |
|
||||||
grpc_bdp_estimator_init(&est, "test"); |
|
||||||
int64_t estimate; |
|
||||||
grpc_bdp_estimator_get_estimate(&est, &estimate); |
|
||||||
} |
|
||||||
|
|
||||||
static void add_samples(grpc_bdp_estimator *estimator, int64_t *samples, |
|
||||||
size_t n) { |
|
||||||
grpc_bdp_estimator_add_incoming_bytes(estimator, 1234567); |
|
||||||
inc_time(); |
|
||||||
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; |
|
||||||
GPR_ASSERT(grpc_bdp_estimator_need_ping(&exec_ctx, estimator) == true); |
|
||||||
grpc_bdp_estimator_schedule_ping(estimator); |
|
||||||
grpc_bdp_estimator_start_ping(estimator); |
|
||||||
for (size_t i = 0; i < n; i++) { |
|
||||||
grpc_bdp_estimator_add_incoming_bytes(estimator, samples[i]); |
|
||||||
GPR_ASSERT(grpc_bdp_estimator_need_ping(&exec_ctx, estimator) == false); |
|
||||||
} |
|
||||||
gpr_sleep_until(gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), |
|
||||||
gpr_time_from_millis(1, GPR_TIMESPAN))); |
|
||||||
grpc_bdp_estimator_complete_ping(&exec_ctx, estimator); |
|
||||||
grpc_exec_ctx_finish(&exec_ctx); |
|
||||||
} |
|
||||||
|
|
||||||
static void add_sample(grpc_bdp_estimator *estimator, int64_t sample) { |
|
||||||
add_samples(estimator, &sample, 1); |
|
||||||
} |
|
||||||
|
|
||||||
static void test_get_estimate_1_sample(void) { |
|
||||||
gpr_log(GPR_INFO, "test_get_estimate_1_sample"); |
|
||||||
grpc_bdp_estimator est; |
|
||||||
grpc_bdp_estimator_init(&est, "test"); |
|
||||||
add_sample(&est, 100); |
|
||||||
int64_t estimate; |
|
||||||
grpc_bdp_estimator_get_estimate(&est, &estimate); |
|
||||||
} |
|
||||||
|
|
||||||
static void test_get_estimate_2_samples(void) { |
|
||||||
gpr_log(GPR_INFO, "test_get_estimate_2_samples"); |
|
||||||
grpc_bdp_estimator est; |
|
||||||
grpc_bdp_estimator_init(&est, "test"); |
|
||||||
add_sample(&est, 100); |
|
||||||
add_sample(&est, 100); |
|
||||||
int64_t estimate; |
|
||||||
grpc_bdp_estimator_get_estimate(&est, &estimate); |
|
||||||
} |
|
||||||
|
|
||||||
static int64_t get_estimate(grpc_bdp_estimator *estimator) { |
|
||||||
int64_t out; |
|
||||||
GPR_ASSERT(grpc_bdp_estimator_get_estimate(estimator, &out)); |
|
||||||
return out; |
|
||||||
} |
|
||||||
|
|
||||||
static void test_get_estimate_3_samples(void) { |
|
||||||
gpr_log(GPR_INFO, "test_get_estimate_3_samples"); |
|
||||||
grpc_bdp_estimator est; |
|
||||||
grpc_bdp_estimator_init(&est, "test"); |
|
||||||
add_sample(&est, 100); |
|
||||||
add_sample(&est, 100); |
|
||||||
add_sample(&est, 100); |
|
||||||
int64_t estimate; |
|
||||||
grpc_bdp_estimator_get_estimate(&est, &estimate); |
|
||||||
} |
|
||||||
|
|
||||||
static int64_t next_pow_2(int64_t v) { |
|
||||||
v--; |
|
||||||
v |= v >> 1; |
|
||||||
v |= v >> 2; |
|
||||||
v |= v >> 4; |
|
||||||
v |= v >> 8; |
|
||||||
v |= v >> 16; |
|
||||||
v |= v >> 32; |
|
||||||
v++; |
|
||||||
return v; |
|
||||||
} |
|
||||||
|
|
||||||
static void test_get_estimate_random_values(size_t n) { |
|
||||||
gpr_log(GPR_INFO, "test_get_estimate_random_values(%" PRIdPTR ")", n); |
|
||||||
grpc_bdp_estimator est; |
|
||||||
grpc_bdp_estimator_init(&est, "test"); |
|
||||||
const int kMaxSample = 65535; |
|
||||||
int min = kMaxSample; |
|
||||||
int max = 0; |
|
||||||
for (size_t i = 0; i < n; i++) { |
|
||||||
int sample = rand() % (kMaxSample + 1); |
|
||||||
if (sample < min) min = sample; |
|
||||||
if (sample > max) max = sample; |
|
||||||
add_sample(&est, sample); |
|
||||||
if (i >= 3) { |
|
||||||
gpr_log(GPR_DEBUG, "est:%" PRId64 " min:%d max:%d", get_estimate(&est), |
|
||||||
min, max); |
|
||||||
GPR_ASSERT(get_estimate(&est) <= GPR_MAX(65536, 2 * next_pow_2(max))); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
int main(int argc, char **argv) { |
|
||||||
grpc_test_init(argc, argv); |
|
||||||
gpr_now_impl = fake_gpr_now; |
|
||||||
grpc_init(); |
|
||||||
grpc_timer_manager_set_threading(false); |
|
||||||
test_noop(); |
|
||||||
test_get_estimate_no_samples(); |
|
||||||
test_get_estimate_1_sample(); |
|
||||||
test_get_estimate_2_samples(); |
|
||||||
test_get_estimate_3_samples(); |
|
||||||
for (size_t i = 3; i < 1000; i = i * 3 / 2) { |
|
||||||
test_get_estimate_random_values(i); |
|
||||||
} |
|
||||||
grpc_shutdown(); |
|
||||||
return 0; |
|
||||||
} |
|
@ -0,0 +1,158 @@ |
|||||||
|
/*
|
||||||
|
* |
||||||
|
* Copyright 2016 gRPC authors. |
||||||
|
* |
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||||
|
* you may not use this file except in compliance with the License. |
||||||
|
* You may obtain a copy of the License at |
||||||
|
* |
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
* |
||||||
|
* Unless required by applicable law or agreed to in writing, software |
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, |
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||||
|
* See the License for the specific language governing permissions and |
||||||
|
* limitations under the License. |
||||||
|
* |
||||||
|
*/ |
||||||
|
|
||||||
|
#include "src/core/lib/transport/bdp_estimator.h" |
||||||
|
|
||||||
|
#include <grpc/grpc.h> |
||||||
|
#include <grpc/support/alloc.h> |
||||||
|
#include <grpc/support/log.h> |
||||||
|
#include <grpc/support/string_util.h> |
||||||
|
#include <grpc/support/useful.h> |
||||||
|
#include <gtest/gtest.h> |
||||||
|
#include <limits.h> |
||||||
|
#include "src/core/lib/iomgr/timer_manager.h" |
||||||
|
#include "src/core/lib/support/string.h" |
||||||
|
#include "test/core/util/test_config.h" |
||||||
|
|
||||||
|
extern "C" gpr_timespec (*gpr_now_impl)(gpr_clock_type clock_type); |
||||||
|
|
||||||
|
namespace grpc_core { |
||||||
|
namespace testing { |
||||||
|
namespace { |
||||||
|
int g_clock = 0; |
||||||
|
|
||||||
|
gpr_timespec fake_gpr_now(gpr_clock_type clock_type) { |
||||||
|
return (gpr_timespec){ |
||||||
|
.tv_sec = g_clock, .tv_nsec = 0, .clock_type = clock_type, |
||||||
|
}; |
||||||
|
} |
||||||
|
|
||||||
|
void inc_time(void) { g_clock += 30; } |
||||||
|
} // namespace
|
||||||
|
|
||||||
|
TEST(BdpEstimatorTest, NoOp) { BdpEstimator est("test"); } |
||||||
|
|
||||||
|
TEST(BdpEstimatorTest, EstimateBdpNoSamples) { |
||||||
|
BdpEstimator est("test"); |
||||||
|
int64_t estimate; |
||||||
|
est.EstimateBdp(&estimate); |
||||||
|
} |
||||||
|
|
||||||
|
namespace { |
||||||
|
void AddSamples(BdpEstimator *estimator, int64_t *samples, size_t n) { |
||||||
|
estimator->AddIncomingBytes(1234567); |
||||||
|
inc_time(); |
||||||
|
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; |
||||||
|
EXPECT_TRUE(estimator->NeedPing(&exec_ctx)); |
||||||
|
estimator->SchedulePing(); |
||||||
|
estimator->StartPing(); |
||||||
|
for (size_t i = 0; i < n; i++) { |
||||||
|
estimator->AddIncomingBytes(samples[i]); |
||||||
|
EXPECT_FALSE(estimator->NeedPing(&exec_ctx)); |
||||||
|
} |
||||||
|
gpr_sleep_until(gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), |
||||||
|
gpr_time_from_millis(1, GPR_TIMESPAN))); |
||||||
|
grpc_exec_ctx_invalidate_now(&exec_ctx); |
||||||
|
estimator->CompletePing(&exec_ctx); |
||||||
|
grpc_exec_ctx_finish(&exec_ctx); |
||||||
|
} |
||||||
|
|
||||||
|
void AddSample(BdpEstimator *estimator, int64_t sample) { |
||||||
|
AddSamples(estimator, &sample, 1); |
||||||
|
} |
||||||
|
} // namespace
|
||||||
|
|
||||||
|
TEST(BdpEstimatorTest, GetEstimate1Sample) { |
||||||
|
BdpEstimator est("test"); |
||||||
|
AddSample(&est, 100); |
||||||
|
int64_t estimate; |
||||||
|
est.EstimateBdp(&estimate); |
||||||
|
} |
||||||
|
|
||||||
|
TEST(BdpEstimatorTest, GetEstimate2Samples) { |
||||||
|
BdpEstimator est("test"); |
||||||
|
AddSample(&est, 100); |
||||||
|
AddSample(&est, 100); |
||||||
|
int64_t estimate; |
||||||
|
est.EstimateBdp(&estimate); |
||||||
|
} |
||||||
|
|
||||||
|
TEST(BdpEstimatorTest, GetEstimate3Samples) { |
||||||
|
BdpEstimator est("test"); |
||||||
|
AddSample(&est, 100); |
||||||
|
AddSample(&est, 100); |
||||||
|
AddSample(&est, 100); |
||||||
|
int64_t estimate; |
||||||
|
est.EstimateBdp(&estimate); |
||||||
|
} |
||||||
|
|
||||||
|
namespace { |
||||||
|
static int64_t GetEstimate(const BdpEstimator &estimator) { |
||||||
|
int64_t out; |
||||||
|
EXPECT_TRUE(estimator.EstimateBdp(&out)); |
||||||
|
return out; |
||||||
|
} |
||||||
|
|
||||||
|
int64_t NextPow2(int64_t v) { |
||||||
|
v--; |
||||||
|
v |= v >> 1; |
||||||
|
v |= v >> 2; |
||||||
|
v |= v >> 4; |
||||||
|
v |= v >> 8; |
||||||
|
v |= v >> 16; |
||||||
|
v |= v >> 32; |
||||||
|
v++; |
||||||
|
return v; |
||||||
|
} |
||||||
|
} // namespace
|
||||||
|
|
||||||
|
class BdpEstimatorRandomTest : public ::testing::TestWithParam<size_t> {}; |
||||||
|
|
||||||
|
TEST_P(BdpEstimatorRandomTest, GetEstimateRandomValues) { |
||||||
|
BdpEstimator est("test"); |
||||||
|
const int kMaxSample = 65535; |
||||||
|
int min = kMaxSample; |
||||||
|
int max = 0; |
||||||
|
for (size_t i = 0; i < GetParam(); i++) { |
||||||
|
int sample = rand() % (kMaxSample + 1); |
||||||
|
if (sample < min) min = sample; |
||||||
|
if (sample > max) max = sample; |
||||||
|
AddSample(&est, sample); |
||||||
|
if (i >= 3) { |
||||||
|
EXPECT_LE(GetEstimate(est), GPR_MAX(65536, 2 * NextPow2(max))) |
||||||
|
<< " min:" << min << " max:" << max << " sample:" << sample; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
INSTANTIATE_TEST_CASE_P(TooManyNames, BdpEstimatorRandomTest, |
||||||
|
::testing::Values(3, 4, 6, 9, 13, 19, 28, 42, 63, 94, |
||||||
|
141, 211, 316, 474, 711)); |
||||||
|
} // namespace testing
|
||||||
|
} // namespace grpc_core
|
||||||
|
|
||||||
|
int main(int argc, char **argv) { |
||||||
|
grpc_test_init(argc, argv); |
||||||
|
gpr_now_impl = grpc_core::testing::fake_gpr_now; |
||||||
|
grpc_init(); |
||||||
|
grpc_timer_manager_set_threading(false); |
||||||
|
::testing::InitGoogleTest(&argc, argv); |
||||||
|
int ret = RUN_ALL_TESTS(); |
||||||
|
grpc_shutdown(); |
||||||
|
return ret; |
||||||
|
} |
Loading…
Reference in new issue