1// Copyright 2018 The Fuchsia Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include <float.h> 6#include <math.h> 7#include <stdint.h> 8#include <unistd.h> 9 10#include <cobalt-client/cpp/histogram-options.h> 11#include <unittest/unittest.h> 12 13namespace cobalt_client { 14namespace { 15 16bool TestMakeExponentialOptions() { 17 BEGIN_TEST; 18 HistogramOptions options = 19 HistogramOptions::Exponential(/*bucket_count=*/3, /*base=*/4, /*scalar=*/2, /*offset=*/-10); 20 ASSERT_EQ(options.bucket_count, 3); 21 ASSERT_EQ(options.base, 4); 22 ASSERT_EQ(options.scalar, 2); 23 // the calculated offset is such that it guarantees that it matches the lower bound of the first 24 // bucket(excluding underflow bucket). This is to take in account: 25 // offset = scalar * base ^(0) + calculated_offset 26 // calculated_offset = offset - scalar. 27 ASSERT_EQ(options.offset, -12); 28 ASSERT_EQ(options.type, HistogramOptions::Type::kExponential); 29 ASSERT_TRUE(options.IsValid()); 30 END_TEST; 31} 32 33bool TestExponentialInvalidBucketCount() { 34 BEGIN_TEST; 35 HistogramOptions options = 36 HistogramOptions::Exponential(/*bucket_count=*/0, /*base=*/1, /*scalar=*/2, /*offset=*/-10); 37 ASSERT_FALSE(options.IsValid()); 38 END_TEST; 39} 40 41bool TestExponentialInvalidBase() { 42 BEGIN_TEST; 43 HistogramOptions options = 44 HistogramOptions::Exponential(/*bucket_count=*/1, /*base=*/0, /*scalar=*/2, /*offset=*/-10); 45 ASSERT_FALSE(options.IsValid()); 46 END_TEST; 47} 48 49bool TestExponentialInvalidScalar() { 50 BEGIN_TEST; 51 HistogramOptions options = 52 HistogramOptions::Exponential(/*bucket_count=*/1, /*base=*/1, /*scalar=*/0, /*offset=*/-10); 53 ASSERT_FALSE(options.IsValid()); 54 END_TEST; 55} 56 57// Verify correct buckect assignment along the boundaries and points within the bucket for 58// exponential bucket width. 59bool TestExponentialMap() { 60 BEGIN_TEST; 61 // This generates the following histogram: 62 // | | | | | | 63 // -inf 5 8 14 26 +inf 64 HistogramOptions options = 65 HistogramOptions::Exponential(/*bucket_count=*/3, /*base=*/2, /*scalar=*/3, /*offset=*/5); 66 EXPECT_EQ(options.map_fn(/*value=*/4, options), 0); 67 EXPECT_EQ(options.map_fn(nextafter(5, 4), options), 0); 68 EXPECT_EQ(options.map_fn(5, options), 1); 69 EXPECT_EQ(options.map_fn(7.5, options), 1); 70 EXPECT_EQ(options.map_fn(nextafter(8, 7), options), 1); 71 EXPECT_EQ(options.map_fn(8, options), 2); 72 EXPECT_EQ(options.map_fn(12, options), 2); 73 EXPECT_EQ(options.map_fn(nextafter(12, 11), options), 2); 74 EXPECT_EQ(options.map_fn(14, options), 3); 75 EXPECT_EQ(options.map_fn(18, options), 3); 76 EXPECT_EQ(options.map_fn(nextafter(26, 25), options), 3); 77 EXPECT_EQ(options.map_fn(26, options), 4); 78 END_TEST; 79} 80 81bool TestExponentialReverseMap() { 82 BEGIN_TEST; 83 // This generates the following histogram: 84 // | | | | | | 85 // -inf 5 8 14 26 +inf 86 HistogramOptions options = 87 HistogramOptions::Exponential(/*bucket_count=*/3, /*base=*/2, /*scalar=*/3, /*offset=*/5); 88 EXPECT_EQ(options.reverse_map_fn(/*bucket_index=*/0, options), -DBL_MAX); 89 EXPECT_EQ(options.reverse_map_fn(1, options), 5); 90 EXPECT_EQ(options.reverse_map_fn(2, options), 8); 91 EXPECT_EQ(options.reverse_map_fn(3, options), 14); 92 EXPECT_EQ(options.reverse_map_fn(4, options), 26); 93 END_TEST; 94} 95 96bool TestMakeLinearOptions() { 97 BEGIN_TEST; 98 HistogramOptions options = 99 HistogramOptions::Linear(/*bucket_count=*/3, /*scalar=*/2, /*offset=*/-10); 100 ASSERT_EQ(options.bucket_count, 3); 101 ASSERT_EQ(options.base, 1); 102 ASSERT_EQ(options.scalar, 2); 103 ASSERT_EQ(options.offset, -10); 104 ASSERT_EQ(options.type, HistogramOptions::Type::kLinear); 105 ASSERT_TRUE(options.map_fn); 106 ASSERT_TRUE(options.reverse_map_fn); 107 ASSERT_TRUE(options.IsValid()); 108 END_TEST; 109} 110 111bool TestLinearInvalidBucketCount() { 112 BEGIN_TEST; 113 HistogramOptions options = 114 HistogramOptions::Linear(/*bucket_count=*/0, /*scalar=*/2, /*offset=*/-10); 115 ASSERT_FALSE(options.IsValid()); 116 END_TEST; 117} 118 119bool TestLinearInvalidScalar() { 120 BEGIN_TEST; 121 HistogramOptions options = 122 HistogramOptions::Linear(/*bucket_count=*/1, /*scalar=*/0, /*offset=*/-10); 123 ASSERT_FALSE(options.IsValid()); 124 END_TEST; 125} 126 127// Verify correct bucket assignment along the boundaries and points within the bucket for 128// linear bucket width. 129bool TestLinearMap() { 130 BEGIN_TEST; 131 // This generates the following histogram: 132 // | | | | | | 133 // -inf -10 -8 -6 -4 +inf 134 HistogramOptions options = 135 HistogramOptions::Linear(/*bucket_count=*/3, /*scalar=*/2, /*offset=*/-10); 136 EXPECT_EQ(options.map_fn(/*value=*/-15, options), 0); 137 EXPECT_EQ(options.map_fn(nextafter(-10.0, -11), options), 0); 138 EXPECT_EQ(options.map_fn(-10.0, options), 1); 139 EXPECT_EQ(options.map_fn(-9.0, options), 1); 140 EXPECT_EQ(options.map_fn(-8.0, options), 2); 141 EXPECT_EQ(options.map_fn(-7.0, options), 2); 142 EXPECT_EQ(options.map_fn(-6.0, options), 3); 143 EXPECT_EQ(options.map_fn(-5.0, options), 3); 144 EXPECT_EQ(options.map_fn(nexttoward(-4.0, -5.0), options), 3); 145 EXPECT_EQ(options.map_fn(-4.0, options), 4); 146 END_TEST; 147} 148 149bool TestLinearReverseMap() { 150 BEGIN_TEST; 151 // This generates the following histogram: 152 // | | | | | | 153 // -inf -10 -8 -6 -4 +inf 154 HistogramOptions options = 155 HistogramOptions::Linear(/*bucket_count=*/3, /*scalar=*/2, /*offset=*/-10); 156 EXPECT_EQ(options.reverse_map_fn(/*bucket_index=*/0, options), -DBL_MAX); 157 EXPECT_EQ(options.reverse_map_fn(1, options), -10); 158 EXPECT_EQ(options.reverse_map_fn(2, options), -8); 159 EXPECT_EQ(options.reverse_map_fn(3, options), -6); 160 EXPECT_EQ(options.reverse_map_fn(4, options), -4); 161 END_TEST; 162} 163 164BEGIN_TEST_CASE(HistogramOptionsTest) 165RUN_TEST(TestMakeExponentialOptions) 166RUN_TEST(TestExponentialInvalidBucketCount) 167RUN_TEST(TestExponentialInvalidBase) 168RUN_TEST(TestExponentialInvalidScalar) 169RUN_TEST(TestExponentialMap) 170RUN_TEST(TestExponentialReverseMap) 171RUN_TEST(TestMakeLinearOptions) 172RUN_TEST(TestLinearInvalidBucketCount) 173RUN_TEST(TestLinearInvalidScalar) 174RUN_TEST(TestLinearMap) 175RUN_TEST(TestLinearReverseMap) 176END_TEST_CASE(HistogramOptionsTest) 177} // namespace 178} // namespace cobalt_client 179