blob: b44978f9fe807816ed7df3c10e826ff2b1654920 [file] [log] [blame]
// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "src/registry/buckets_config.h"
#include "gflags/gflags.h"
#include "src/logging.h"
#include "third_party/googletest/googletest/include/gtest/gtest.h"
namespace cobalt::config {
// Test the case in which no buckets configuration was set.
TEST(IntegerBucketConfigTest, BucketsNotSetTest) {
IntegerBuckets int_buckets_proto;
std::unique_ptr<IntegerBucketConfig> int_bucket_config =
IntegerBucketConfig::CreateFromProto(int_buckets_proto);
EXPECT_FALSE(int_bucket_config) << "If no buckets are set, we must return a "
<< "nullptr.";
}
// We do not support 0 buckets.
TEST(IntegerBucketConfigTest, LinearZeroBucketsTest) {
IntegerBuckets int_buckets_proto;
LinearIntegerBuckets* linear = int_buckets_proto.mutable_linear();
linear->set_floor(10);
linear->set_num_buckets(0);
linear->set_step_size(2);
std::unique_ptr<IntegerBucketConfig> int_bucket_config =
IntegerBucketConfig::CreateFromProto(int_buckets_proto);
EXPECT_FALSE(int_bucket_config) << "Zero buckets is not allowed.";
}
// We do not allow a 0 step size.
TEST(IntegerBucketConfigTest, LinearZeroStepSizeTest) {
IntegerBuckets int_buckets_proto;
LinearIntegerBuckets* linear = int_buckets_proto.mutable_linear();
linear->set_floor(10);
linear->set_num_buckets(10);
linear->set_step_size(0);
std::unique_ptr<IntegerBucketConfig> int_bucket_config =
IntegerBucketConfig::CreateFromProto(int_buckets_proto);
EXPECT_FALSE(int_bucket_config) << "Zero step size is not allowed.";
}
// Test the normal linear buckets case.
TEST(IntegerBucketConfigTest, LinearTest) {
IntegerBuckets int_buckets_proto;
LinearIntegerBuckets* linear = int_buckets_proto.mutable_linear();
linear->set_floor(10);
linear->set_num_buckets(3);
linear->set_step_size(2);
std::unique_ptr<IntegerBucketConfig> int_bucket_config =
IntegerBucketConfig::CreateFromProto(int_buckets_proto);
// Check the underflow and overflow bucket indices.
EXPECT_EQ(uint32_t(0), int_bucket_config->UnderflowBucket());
EXPECT_EQ(uint32_t(4), int_bucket_config->OverflowBucket());
// Check the underflow bucket.
EXPECT_EQ(uint32_t(0), int_bucket_config->BucketIndex(-100));
EXPECT_EQ(uint32_t(0), int_bucket_config->BucketIndex(9));
// Check the normal buckets.
EXPECT_EQ(uint32_t(1), int_bucket_config->BucketIndex(10));
EXPECT_EQ(uint32_t(1), int_bucket_config->BucketIndex(11));
EXPECT_EQ(uint32_t(2), int_bucket_config->BucketIndex(12));
EXPECT_EQ(uint32_t(2), int_bucket_config->BucketIndex(13));
EXPECT_EQ(uint32_t(3), int_bucket_config->BucketIndex(14));
EXPECT_EQ(uint32_t(3), int_bucket_config->BucketIndex(15));
// Check the overflow buckets.
EXPECT_EQ(uint32_t(4), int_bucket_config->BucketIndex(16));
EXPECT_EQ(uint32_t(4), int_bucket_config->BucketIndex(20));
}
// We do not support 0 buckets.
TEST(IntegerBucketConfigTest, ExponentialZeroBucketsTest) {
IntegerBuckets int_buckets_proto;
ExponentialIntegerBuckets* exp = int_buckets_proto.mutable_exponential();
exp->set_floor(10);
exp->set_num_buckets(0);
exp->set_initial_step(5);
exp->set_step_multiplier(7);
std::unique_ptr<IntegerBucketConfig> int_bucket_config =
IntegerBucketConfig::CreateFromProto(int_buckets_proto);
EXPECT_FALSE(int_bucket_config) << "Zero buckets is not allowed.";
}
// We do not support a 0 initial step.
TEST(IntegerBucketConfigTest, ExponentialZeroInitialStepTest) {
IntegerBuckets int_buckets_proto;
ExponentialIntegerBuckets* exp = int_buckets_proto.mutable_exponential();
exp->set_floor(10);
exp->set_num_buckets(3);
exp->set_initial_step(0);
exp->set_step_multiplier(7);
std::unique_ptr<IntegerBucketConfig> int_bucket_config =
IntegerBucketConfig::CreateFromProto(int_buckets_proto);
EXPECT_FALSE(int_bucket_config) << "Zero initial step is not allowed.";
}
// We do not support a 0 step multiplier.
TEST(IntegerBucketConfigTest, ExponentialZeroStepMultiplierTest) {
IntegerBuckets int_buckets_proto;
ExponentialIntegerBuckets* exp = int_buckets_proto.mutable_exponential();
exp->set_floor(10);
exp->set_num_buckets(3);
exp->set_initial_step(10);
exp->set_step_multiplier(0);
std::unique_ptr<IntegerBucketConfig> int_bucket_config =
IntegerBucketConfig::CreateFromProto(int_buckets_proto);
EXPECT_FALSE(int_bucket_config) << "Zero step multiplier is not allowed.";
}
// Test the normal exponential buckets case.
TEST(IntegerBucketConfigTest, ExponentialTest) {
IntegerBuckets int_buckets_proto;
ExponentialIntegerBuckets* exp = int_buckets_proto.mutable_exponential();
exp->set_floor(10);
exp->set_num_buckets(3);
exp->set_initial_step(5);
exp->set_step_multiplier(7);
std::unique_ptr<IntegerBucketConfig> int_bucket_config =
IntegerBucketConfig::CreateFromProto(int_buckets_proto);
// Check the underflow and overflow bucket indices.
EXPECT_EQ(uint32_t(0), int_bucket_config->UnderflowBucket());
EXPECT_EQ(uint32_t(4), int_bucket_config->OverflowBucket());
// The expected buckets are:
// (-infinity, 10), [10, 15), [15, 45), [45, 255), [255, infinity)
// Check the underflow bucket.
EXPECT_EQ(uint32_t(0), int_bucket_config->BucketIndex(-100));
EXPECT_EQ(uint32_t(0), int_bucket_config->BucketIndex(9));
// Check the normal buckets.
EXPECT_EQ(uint32_t(1), int_bucket_config->BucketIndex(10));
EXPECT_EQ(uint32_t(1), int_bucket_config->BucketIndex(14));
EXPECT_EQ(uint32_t(2), int_bucket_config->BucketIndex(15));
EXPECT_EQ(uint32_t(2), int_bucket_config->BucketIndex(44));
EXPECT_EQ(uint32_t(3), int_bucket_config->BucketIndex(45));
EXPECT_EQ(uint32_t(3), int_bucket_config->BucketIndex(244));
// Check the overflow buckets.
EXPECT_EQ(uint32_t(4), int_bucket_config->BucketIndex(255));
EXPECT_EQ(uint32_t(4), int_bucket_config->BucketIndex(256));
EXPECT_EQ(uint32_t(4), int_bucket_config->BucketIndex(300));
}
// This is a very likely-to-be-used logarithmic scale, so we test it explicitly.
TEST(IntegerBucketConfigTest, ExponentialTestCommon) {
IntegerBuckets int_buckets_proto;
ExponentialIntegerBuckets* exp = int_buckets_proto.mutable_exponential();
exp->set_floor(0);
exp->set_num_buckets(3);
exp->set_initial_step(10);
exp->set_step_multiplier(10);
std::unique_ptr<IntegerBucketConfig> int_bucket_config =
IntegerBucketConfig::CreateFromProto(int_buckets_proto);
// Check the underflow and overflow bucket indices.
EXPECT_EQ(uint32_t(0), int_bucket_config->UnderflowBucket());
EXPECT_EQ(uint32_t(4), int_bucket_config->OverflowBucket());
// The expected buckets are:
// (-infinity, 0), [0, 10), [10, 100), [100, 1000), [1000, +inifinity)
// Check the underflow bucket.
EXPECT_EQ(uint32_t(0), int_bucket_config->BucketIndex(-100));
EXPECT_EQ(uint32_t(0), int_bucket_config->BucketIndex(-1));
// Check the normal buckets.
EXPECT_EQ(uint32_t(1), int_bucket_config->BucketIndex(0));
EXPECT_EQ(uint32_t(1), int_bucket_config->BucketIndex(9));
EXPECT_EQ(uint32_t(2), int_bucket_config->BucketIndex(10));
EXPECT_EQ(uint32_t(2), int_bucket_config->BucketIndex(99));
EXPECT_EQ(uint32_t(3), int_bucket_config->BucketIndex(100));
EXPECT_EQ(uint32_t(3), int_bucket_config->BucketIndex(999));
// Check the overflow buckets.
EXPECT_EQ(uint32_t(4), int_bucket_config->BucketIndex(1000));
EXPECT_EQ(uint32_t(4), int_bucket_config->BucketIndex(1001));
EXPECT_EQ(uint32_t(4), int_bucket_config->BucketIndex(1000000));
}
// Test that bucket sizes that would overflow an int32 but not an int64 works
// correctly.
TEST(IntegerBucketConfigTest, ExponentialTestLarge) {
IntegerBuckets int_buckets_proto;
ExponentialIntegerBuckets* exp = int_buckets_proto.mutable_exponential();
exp->set_floor(0);
exp->set_num_buckets(17);
exp->set_initial_step(1000000);
exp->set_step_multiplier(2);
std::unique_ptr<IntegerBucketConfig> int_bucket_config =
IntegerBucketConfig::CreateFromProto(int_buckets_proto);
// Check the underflow and overflow bucket indices.
EXPECT_EQ(uint32_t(0), int_bucket_config->UnderflowBucket());
EXPECT_EQ(uint32_t(18), int_bucket_config->OverflowBucket());
// The expected buckets are:
// (-infinity, 0), [0, 1000000), [1000000, 2000000), [2000000, 4000000),
// [4000000, 8000000), [8000000, 16000000), [16000000, 32000000),
// [32000000, 64000000), [64000000, 128000000), [128000000, 256000000),
// [256000000, 512000000), [512000000, 1024000000), [1024000000, 2048000000)
// [2048000000, 4096000000), [4096000000, 8192000000),
// [8192000000, 16384000000), [16384000000, 32768000000),
// [32768000000, 65536000000), [65536000000, +infinity)
// Check the underflow bucket.
EXPECT_EQ(uint32_t(0), int_bucket_config->BucketIndex(-100));
EXPECT_EQ(uint32_t(0), int_bucket_config->BucketIndex(-1));
// Check the normal buckets.
EXPECT_EQ(uint32_t(1), int_bucket_config->BucketIndex(0));
EXPECT_EQ(uint32_t(1), int_bucket_config->BucketIndex(999999));
EXPECT_EQ(uint32_t(2), int_bucket_config->BucketIndex(1000000));
EXPECT_EQ(uint32_t(2), int_bucket_config->BucketIndex(1999999));
EXPECT_EQ(uint32_t(3), int_bucket_config->BucketIndex(2000000));
EXPECT_EQ(uint32_t(3), int_bucket_config->BucketIndex(3999999));
EXPECT_EQ(uint32_t(4), int_bucket_config->BucketIndex(4000000));
EXPECT_EQ(uint32_t(4), int_bucket_config->BucketIndex(7999999));
EXPECT_EQ(uint32_t(5), int_bucket_config->BucketIndex(8000000));
EXPECT_EQ(uint32_t(5), int_bucket_config->BucketIndex(15999999));
EXPECT_EQ(uint32_t(6), int_bucket_config->BucketIndex(16000000));
EXPECT_EQ(uint32_t(6), int_bucket_config->BucketIndex(31999999));
EXPECT_EQ(uint32_t(7), int_bucket_config->BucketIndex(32000000));
EXPECT_EQ(uint32_t(7), int_bucket_config->BucketIndex(63999999));
EXPECT_EQ(uint32_t(8), int_bucket_config->BucketIndex(64000000));
EXPECT_EQ(uint32_t(8), int_bucket_config->BucketIndex(127999999));
EXPECT_EQ(uint32_t(9), int_bucket_config->BucketIndex(128000000));
EXPECT_EQ(uint32_t(9), int_bucket_config->BucketIndex(255999999));
EXPECT_EQ(uint32_t(10), int_bucket_config->BucketIndex(256000000));
EXPECT_EQ(uint32_t(10), int_bucket_config->BucketIndex(511999999));
EXPECT_EQ(uint32_t(11), int_bucket_config->BucketIndex(512000000));
EXPECT_EQ(uint32_t(11), int_bucket_config->BucketIndex(1023999999));
EXPECT_EQ(uint32_t(12), int_bucket_config->BucketIndex(1024000000));
EXPECT_EQ(uint32_t(12), int_bucket_config->BucketIndex(2047999999));
EXPECT_EQ(uint32_t(13), int_bucket_config->BucketIndex(2048000000));
EXPECT_EQ(uint32_t(13), int_bucket_config->BucketIndex(4095999999));
EXPECT_EQ(uint32_t(14), int_bucket_config->BucketIndex(4096000000));
EXPECT_EQ(uint32_t(14), int_bucket_config->BucketIndex(8191999999));
EXPECT_EQ(uint32_t(15), int_bucket_config->BucketIndex(8192000000));
EXPECT_EQ(uint32_t(15), int_bucket_config->BucketIndex(16383999999));
EXPECT_EQ(uint32_t(16), int_bucket_config->BucketIndex(16384000000));
EXPECT_EQ(uint32_t(16), int_bucket_config->BucketIndex(32767999999));
EXPECT_EQ(uint32_t(17), int_bucket_config->BucketIndex(32768000000));
EXPECT_EQ(uint32_t(17), int_bucket_config->BucketIndex(65535999999));
// Check the overflow buckets.
EXPECT_EQ(uint32_t(18), int_bucket_config->BucketIndex(65536000000));
EXPECT_EQ(uint32_t(18), int_bucket_config->BucketIndex(65536000001));
EXPECT_EQ(uint32_t(18), int_bucket_config->BucketIndex(1994356000000));
}
} // namespace cobalt::config