| // 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 |