blob: 5ab43d029d13e42b08e22bc807f5b814ec068334 [file] [log] [blame]
/*
* 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/core/histogram.h"
#include <random>
#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<int32_t>(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