1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87
|
// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "components/reporting/util/rate_limiter_leaky_bucket.h"
#include <cstddef>
#include "base/rand_util.h"
#include "base/test/task_environment.h"
#include "base/time/time.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace reporting {
namespace {
constexpr size_t kMaxLevel = 1024u;
constexpr base::TimeDelta kFillingTime = base::Seconds(16);
constexpr base::TimeDelta kFillingPeriod = base::Seconds(2);
constexpr size_t kEventCount = 8;
class RateLimiterLeakyBucketTest : public ::testing::Test {
protected:
base::test::TaskEnvironment task_environment_{
base::test::TaskEnvironment::TimeSource::MOCK_TIME};
RateLimiterLeakyBucket rate_limiter_{kMaxLevel, kFillingTime, kFillingPeriod};
};
TEST_F(RateLimiterLeakyBucketTest, SingularEvent) {
// Initially - not even 1-byte event can be accepted.
ASSERT_FALSE(rate_limiter_.Acquire(1u));
// Same when bucket is almost full.
task_environment_.FastForwardBy(kFillingTime - kFillingPeriod);
ASSERT_FALSE(rate_limiter_.Acquire(1u));
// Accept only once it is full.
task_environment_.FastForwardBy(kFillingPeriod);
ASSERT_TRUE(rate_limiter_.Acquire(kMaxLevel));
ASSERT_FALSE(rate_limiter_.Acquire(1u));
}
TEST_F(RateLimiterLeakyBucketTest, SteadyEventsStream) {
// Let the bucket fill in.
task_environment_.FastForwardBy(kFillingTime);
// Drop one event every `kFillingPeriod` sec,
// allowing one event through and no more.
for (size_t i = 0; i < kEventCount; ++i) {
ASSERT_TRUE(rate_limiter_.Acquire(1u));
ASSERT_FALSE(rate_limiter_.Acquire(1u));
// We only used 1 byte, will fill in again in 1 period.
task_environment_.FastForwardBy(kFillingPeriod);
}
}
TEST_F(RateLimiterLeakyBucketTest, RandomizedEventsStream) {
// Let the bucket fill in.
task_environment_.FastForwardBy(kFillingTime);
// Drop one event every `kFillingPeriod + random` sec,
// allowing one event through and no more.
for (size_t i = 0; i < kEventCount; ++i) {
ASSERT_TRUE(rate_limiter_.Acquire(1u));
ASSERT_FALSE(rate_limiter_.Acquire(1u));
// We only used 1 byte, will fill in again in 1 period, plus add a random.
task_environment_.FastForwardBy(kFillingPeriod +
base::Milliseconds(base::RandInt(0, 100)));
}
}
TEST_F(RateLimiterLeakyBucketTest, LargeEventsStream) {
// Let the bucket fill in.
task_environment_.FastForwardBy(kFillingTime);
// Drop one event every `kFillingTime` sec,
// allowing one event through and no more.
for (size_t i = 0; i < kEventCount; ++i) {
// See that it was enough for maximum event size, but no more.
ASSERT_TRUE(rate_limiter_.Acquire(kMaxLevel));
ASSERT_FALSE(rate_limiter_.Acquire(1u));
// `kFillingPeriod` is not sufficient now.
task_environment_.FastForwardBy(kFillingPeriod);
ASSERT_FALSE(rate_limiter_.Acquire(1u));
// Let the bucket fill in.
task_environment_.FastForwardBy(kFillingTime - kFillingPeriod);
}
}
} // namespace
} // namespace reporting
|