blob: ab5fb209126864321c9fe1d4ccff0b5b0c09c3b6 [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 <set>
#include <fs/metrics/histograms.h>
#include <lib/inspect-vmo/inspect.h>
#include <lib/inspect-vmo/types.h>
#include <lib/zx/time.h>
#include <zxtest/zxtest.h>
namespace fs_metrics {
class HistogramsTest : public zxtest::Test {
public:
void SetUp() final {
root_ = inspector_.CreateObject("root-test");
ASSERT_TRUE(static_cast<bool>(root_));
}
protected:
inspect::vmo::Inspector inspector_;
inspect::vmo::Object root_;
};
constexpr zx::duration kDuration = zx::nsec(5);
const std::vector<EventOptions>& GetOptionsSets() {
constexpr uint64_t kBlockCounts[] = {1, 5, 31, 32};
constexpr uint64_t kNodeDepths[] = {1, 2, 4, 8, 16, 32, 64, 128};
constexpr uint64_t kNodeDegrees[] = {1, 2, 4, 8, 16, 32, 64, 128, 1024, 1024 * 1024};
constexpr bool kBuffered[] = {true, false};
constexpr bool kSuccess[] = {true, false};
static std::vector<EventOptions> option_set;
option_set.reserve(fbl::count_of(kBlockCounts) * fbl::count_of(kNodeDepths) *
fbl::count_of(kNodeDegrees) * fbl::count_of(kBuffered) *
fbl::count_of(kSuccess));
for (auto block_count : kBlockCounts) {
for (auto node_depth : kNodeDepths) {
for (auto node_degree : kNodeDegrees) {
for (auto buffered : kBuffered) {
for (auto success : kSuccess) {
EventOptions options;
options.block_count = block_count;
options.node_degree = node_degree;
options.node_depth = node_depth;
options.success = success;
options.buffered = buffered;
option_set.push_back(options);
}
}
}
}
}
return option_set;
}
TEST_F(HistogramsTest, AllOptionsAreValid) {
static constexpr OperationType kOperations[] = {
OperationType::kClose, OperationType::kRead, OperationType::kWrite,
OperationType::kAppend, OperationType::kTruncate, OperationType::kSetAttr,
OperationType::kGetAttr, OperationType::kReadDir, OperationType::kSync,
OperationType::kLookUp, OperationType::kCreate, OperationType::kLink,
OperationType::kUnlink,
};
static_assert(fbl::count_of(kOperations) == kOperationCount, "Untested operation.");
Histograms histograms = Histograms(&root_);
std::set<uint64_t> histogram_ids;
for (auto operation : kOperations) {
uint64_t prev_size = histogram_ids.size();
for (auto option_set : GetOptionsSets()) {
uint64_t histogram_id = histograms.GetHistogramId(operation, option_set);
ASSERT_GE(histogram_id, 0);
ASSERT_LT(histogram_id, histograms.GetHistogramCount());
histogram_ids.insert(histogram_id);
histograms.Record(histogram_id, kDuration);
}
ASSERT_EQ(histograms.GetHistogramCount(operation), histogram_ids.size() - prev_size,
" Operation Histogram Count is wrong. %lu", static_cast<uint64_t>(operation));
}
ASSERT_EQ(histogram_ids.size(), histograms.GetHistogramCount(),
"Failed to cover all histograms with all options set.");
}
TEST_F(HistogramsTest, InvalidOptionsReturnsHistogramCount) {
Histograms histograms = Histograms(&root_);
ASSERT_EQ(
histograms.GetHistogramId(static_cast<OperationType>(kOperationCount), EventOptions()),
histograms.GetHistogramCount());
}
} // namespace fs_metrics