blob: a27346e98b172eefbac50611991643bb7183d8a3 [file] [log] [blame]
// Copyright 2019 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 <vector>
#include <fs/metrics/histograms.h>
#include <lib/fzl/time.h>
#include <lib/zx/time.h>
#include <zxtest/zxtest.h>
namespace fs_metrics {
namespace {
class FakeClock {
public:
static zx::ticks now() { return now_; }
static void set_now(zx::ticks ticks) { now_ = ticks; }
private:
static zx::ticks now_;
};
struct HistogramEntry {
uint64_t histogram_id;
zx::duration duration;
};
zx::ticks FakeClock::now_;
class FakeHistograms {
public:
FakeHistograms() : histogram_id_(-1) {}
uint64_t GetHistogramId(OperationType operation, const EventOptions& options) {
return histogram_id_;
}
void Record(uint64_t histogram_id, zx::duration duration) {
collected_data_.push_back({histogram_id, duration});
}
void SetHistogramId(uint64_t id) { histogram_id_ = id; }
const std::vector<HistogramEntry>& collected_data() const { return collected_data_; }
private:
uint64_t histogram_id_;
std::vector<HistogramEntry> collected_data_;
};
using FakeLatencyEvent = internal::LatencyEventInternal<FakeHistograms, FakeClock>;
constexpr OperationType kOperation = OperationType::kRead;
constexpr zx::ticks kStartTime = zx::ticks(5);
constexpr zx::ticks kEventTicks = zx::ticks(45);
// Cannot be constexpr because fzl::TicksToNs is not constexpr.
const zx::duration kEventDuration = fzl::TicksToNs(kEventTicks);
// Fixture for resetting time between each test.
class LatencyEventTest : public zxtest::Test {
public:
void SetUp() override { FakeClock::set_now(kStartTime); }
void TearDown() override { FakeClock::set_now(kStartTime); }
};
TEST_F(LatencyEventTest, RecordZero) {
FakeHistograms histograms;
FakeClock::set_now(zx::ticks(0));
FakeLatencyEvent event(&histograms, kOperation);
event.Record();
ASSERT_TRUE(histograms.collected_data().empty());
}
TEST_F(LatencyEventTest, RecordNonZeroDelta) {
FakeHistograms histograms;
EventOptions options;
FakeLatencyEvent event(&histograms, kOperation);
*event.mutable_options() = options;
FakeClock::set_now(kEventTicks + kStartTime);
event.Record();
ASSERT_EQ(histograms.collected_data().size(), 1);
HistogramEntry entry = histograms.collected_data()[0];
ASSERT_EQ(entry.histogram_id, histograms.GetHistogramId(kOperation, options));
ASSERT_EQ(entry.duration, kEventDuration);
}
TEST_F(LatencyEventTest, RecordCancelledEventIsIgnored) {
FakeHistograms histograms;
FakeLatencyEvent event(&histograms, kOperation);
event.Cancel();
FakeClock::set_now(kEventTicks + kStartTime);
event.Record();
ASSERT_TRUE(histograms.collected_data().empty());
}
TEST_F(LatencyEventTest, RecordZeroOnDestruction) {
FakeHistograms histograms;
FakeClock::set_now(zx::ticks(0));
{ FakeLatencyEvent event(&histograms, kOperation); }
ASSERT_TRUE(histograms.collected_data().empty());
}
TEST_F(LatencyEventTest, RecordNonZeroDeltaOnDestruction) {
FakeHistograms histograms;
EventOptions options;
{
FakeLatencyEvent event(&histograms, kOperation);
*event.mutable_options() = options;
FakeClock::set_now(kEventTicks + kStartTime);
event.Record();
}
ASSERT_EQ(histograms.collected_data().size(), 1);
auto entry = histograms.collected_data()[0];
ASSERT_EQ(entry.histogram_id, histograms.GetHistogramId(kOperation, options));
ASSERT_EQ(entry.duration.get(), kEventDuration.get());
}
TEST_F(LatencyEventTest, RecordCancelledEventIsIgnoredonDestruction) {
FakeHistograms histograms;
{
FakeLatencyEvent event(&histograms, kOperation);
FakeClock::set_now(kEventTicks + kStartTime);
event.Cancel();
event.Record();
}
ASSERT_TRUE(histograms.collected_data().empty());
}
} // namespace
} // namespace fs_metrics