/* * Copyright (C) 2023 The Android Open Source Project * * 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/tracing/service/histogram.h" #include #include "test/gtest_and_gmock.h" namespace perfetto { namespace { TEST(HistogramTest, SingleBucket) { Histogram<8> h; h.Add(0); h.Add(1); h.Add(8); h.Add(10); EXPECT_EQ(h.GetBucketCount(0), 3u); EXPECT_EQ(h.GetBucketSum(0), 9); EXPECT_EQ(h.GetBucketCount(1), 1u); EXPECT_EQ(h.GetBucketSum(1), 10); } TEST(HistogramTest, ThreeBuckets) { Histogram<8, 16, 32> h; EXPECT_EQ(h.GetBucketThres(0), 8); EXPECT_EQ(h.GetBucketThres(1), 16); EXPECT_EQ(h.GetBucketThres(2), 32); for (size_t i = 0; i < h.num_buckets(); i++) { EXPECT_EQ(h.GetBucketCount(i), 0u); EXPECT_EQ(h.GetBucketSum(i), 0); } h.Add(4); h.Add(8); h.Add(15); EXPECT_EQ(h.GetBucketCount(0), 2u); EXPECT_EQ(h.GetBucketSum(0), 4 + 8); EXPECT_EQ(h.GetBucketCount(1), 1u); EXPECT_EQ(h.GetBucketSum(1), 15); EXPECT_EQ(h.GetBucketCount(2), 0u); EXPECT_EQ(h.GetBucketSum(2), 0); h.Add(17); h.Add(31); h.Add(32); EXPECT_EQ(h.GetBucketCount(2), 3u); EXPECT_EQ(h.GetBucketSum(2), 17 + 31 + 32); h.Add(1000); EXPECT_EQ(h.GetBucketCount(3), 1u); EXPECT_EQ(h.GetBucketSum(3), 1000); } TEST(HistogramTest, Merge) { Histogram<8, 16, 32> h, h2; h.Add(4); h.Add(15); h.Add(90); h2.Add(5); h2.Add(30); h2.Add(91); h.Merge(h2); EXPECT_EQ(h.GetBucketCount(0), 2u); EXPECT_EQ(h.GetBucketSum(0), 4 + 5); EXPECT_EQ(h.GetBucketCount(1), 1u); EXPECT_EQ(h.GetBucketSum(1), 15); EXPECT_EQ(h.GetBucketCount(2), 1u); EXPECT_EQ(h.GetBucketSum(2), 30); EXPECT_EQ(h.GetBucketCount(3), 2u); EXPECT_EQ(h.GetBucketSum(3), 90 + 91); } TEST(HistogramTest, CopyAndMoveOperators) { using HistType = Histogram<8, 16, 32>; HistType h1; h1.Add(1); h1.Add(15); h1.Add(30); h1.Add(31); h1.Add(99); auto check_validity = [](const HistType& h) { ASSERT_EQ(h.GetBucketSum(0), 1); ASSERT_EQ(h.GetBucketCount(0), 1u); ASSERT_EQ(h.GetBucketSum(1), 15); ASSERT_EQ(h.GetBucketCount(1), 1u); ASSERT_EQ(h.GetBucketSum(2), 30 + 31); ASSERT_EQ(h.GetBucketCount(2), 2u); ASSERT_EQ(h.GetBucketSum(3), 99); ASSERT_EQ(h.GetBucketCount(3), 1u); }; check_validity(h1); HistType h2(h1); check_validity(h2); check_validity(h1); HistType h3 = h2; check_validity(h3); check_validity(h2); HistType h4(std::move(h3)); check_validity(h4); HistType h5; h5 = std::move(h4); check_validity(h5); } TEST(HistogramTest, Rand) { std::minstd_rand0 rnd_engine(0); Histogram<10, 100, 1000> h; int64_t expected_sum = 0; const uint64_t expected_count = 1000; for (uint64_t i = 0; i < expected_count; i++) { auto value = static_cast(rnd_engine()); expected_sum += value; h.Add(value); } int64_t actual_sum = 0; uint64_t actual_count = 0; for (size_t i = 0; i < h.num_buckets(); i++) { actual_count += h.GetBucketCount(i); actual_sum += h.GetBucketSum(i); } EXPECT_EQ(expected_count, actual_count); EXPECT_EQ(expected_sum, actual_sum); } } // namespace } // namespace perfetto