blob: dd619282fd42c9a7c84bd2b5fac5945e2ba56ff0 [file] [log] [blame]
// Copyright 2018 The Chromium 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 "platform/UkmTimeAggregator.h"
#include "components/ukm/test_ukm_recorder.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace blink {
namespace {
struct Timer {
static double GetTime() { return fake_time; }
static double fake_time;
};
double Timer::fake_time = 0;
TEST(UkmTimeAggregatorTest, EmptyEventsNotRecorded) {
Timer::fake_time = 0;
auto original_time_function = SetTimeFunctionsForTesting(&Timer::GetTime);
ukm::TestUkmRecorder recorder;
int64_t source_id = ukm::UkmRecorder::GetNewSourceID();
std::unique_ptr<UkmTimeAggregator> aggregator(
new UkmTimeAggregator("event", source_id, &recorder,
{"metric1", "metric2"}, TimeDelta::FromSeconds(1)));
Timer::fake_time += 10.;
aggregator.reset();
EXPECT_EQ(recorder.sources_count(), 0u);
EXPECT_EQ(recorder.entries_count(), 0u);
SetTimeFunctionsForTesting(original_time_function);
}
TEST(UkmTimeAggregatorTest, EventsRecordedPerSecond) {
Timer::fake_time = 0;
auto original_time_function = SetTimeFunctionsForTesting(&Timer::GetTime);
ukm::TestUkmRecorder recorder;
int64_t source_id = ukm::UkmRecorder::GetNewSourceID();
std::unique_ptr<UkmTimeAggregator> aggregator(
new UkmTimeAggregator("event", source_id, &recorder,
{"metric1", "metric2"}, TimeDelta::FromSeconds(1)));
// Have 100 events 99ms each; if the records are recorded once per second, we
// should expect 9 records to be recorded while the timer ticks. 0-1, 1-2,
// ..., 8-9 seconds.
for (int i = 0; i < 100; ++i) {
auto timer = aggregator->GetScopedTimer(i % 2);
Timer::fake_time += 0.099;
}
EXPECT_EQ(recorder.entries_count(), 9u);
// Once we reset, we record any remaining samples into one more entry, for a
// total of 10.
aggregator.reset();
EXPECT_EQ(recorder.entries_count(), 10u);
auto entries = recorder.GetEntriesByName("event");
EXPECT_EQ(entries.size(), 10u);
for (auto* entry : entries) {
EXPECT_TRUE(ukm::TestUkmRecorder::EntryHasMetric(entry, "metric1.Average"));
const int64_t* metric1_average =
ukm::TestUkmRecorder::GetEntryMetric(entry, "metric1.Average");
EXPECT_NEAR(*metric1_average / 1e6, 0.099, 0.0001);
EXPECT_TRUE(
ukm::TestUkmRecorder::EntryHasMetric(entry, "metric1.WorstCase"));
const int64_t* metric1_worst =
ukm::TestUkmRecorder::GetEntryMetric(entry, "metric1.WorstCase");
EXPECT_NEAR(*metric1_worst / 1e6, 0.099, 0.0001);
EXPECT_TRUE(ukm::TestUkmRecorder::EntryHasMetric(entry, "metric2.Average"));
const int64_t* metric2_average =
ukm::TestUkmRecorder::GetEntryMetric(entry, "metric2.Average");
EXPECT_NEAR(*metric2_average / 1e6, 0.099, 0.0001);
EXPECT_TRUE(
ukm::TestUkmRecorder::EntryHasMetric(entry, "metric2.WorstCase"));
const int64_t* metric2_worst =
ukm::TestUkmRecorder::GetEntryMetric(entry, "metric2.WorstCase");
EXPECT_NEAR(*metric2_worst / 1e6, 0.099, 0.0001);
}
SetTimeFunctionsForTesting(original_time_function);
}
TEST(UkmTimeAggregatorTest, EventsAveragedCorrectly) {
Timer::fake_time = 0;
auto original_time_function = SetTimeFunctionsForTesting(&Timer::GetTime);
ukm::TestUkmRecorder recorder;
int64_t source_id = ukm::UkmRecorder::GetNewSourceID();
std::unique_ptr<UkmTimeAggregator> aggregator(new UkmTimeAggregator(
"event", source_id, &recorder, {"metric1", "metric2"},
TimeDelta::FromSeconds(10000)));
// 1, 2, and 3 seconds.
for (int i = 1; i <= 3; ++i) {
auto timer = aggregator->GetScopedTimer(0);
Timer::fake_time += i;
}
// 3, 3, 3, and then 1 outside of the loop.
for (int i = 0; i < 3; ++i) {
auto timer = aggregator->GetScopedTimer(1);
Timer::fake_time += 3.;
}
{
auto timer = aggregator->GetScopedTimer(1);
Timer::fake_time += 1.;
}
aggregator.reset();
auto entries = recorder.GetEntriesByName("event");
EXPECT_EQ(entries.size(), 1u);
auto* entry = entries[0];
EXPECT_TRUE(ukm::TestUkmRecorder::EntryHasMetric(entry, "metric1.Average"));
const int64_t* metric1_average =
ukm::TestUkmRecorder::GetEntryMetric(entry, "metric1.Average");
// metric1 (1, 2, 3) average is 2
EXPECT_NEAR(*metric1_average / 1e6, 2.0, 0.0001);
EXPECT_TRUE(ukm::TestUkmRecorder::EntryHasMetric(entry, "metric1.WorstCase"));
const int64_t* metric1_worst =
ukm::TestUkmRecorder::GetEntryMetric(entry, "metric1.WorstCase");
// metric1 (1, 2, 3) worst case is 3
EXPECT_NEAR(*metric1_worst / 1e6, 3.0, 0.0001);
EXPECT_TRUE(ukm::TestUkmRecorder::EntryHasMetric(entry, "metric2.Average"));
const int64_t* metric2_average =
ukm::TestUkmRecorder::GetEntryMetric(entry, "metric2.Average");
// metric1 (3, 3, 3, 1) average is 2.5
EXPECT_NEAR(*metric2_average / 1e6, 2.5, 0.0001);
EXPECT_TRUE(ukm::TestUkmRecorder::EntryHasMetric(entry, "metric2.WorstCase"));
const int64_t* metric2_worst =
ukm::TestUkmRecorder::GetEntryMetric(entry, "metric2.WorstCase");
// metric1 (3, 3, 3, 1) worst case is 3
EXPECT_NEAR(*metric2_worst / 1e6, 3.0, 0.0001);
SetTimeFunctionsForTesting(original_time_function);
}
} // namespace
} // namespace blink