blob: 8c4bdef0f7015b7c4b5ebe2e9927b25ef8c5cba1 [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.
#ifndef LIB_INSPECT_TESTING_INSPECT_H_
#define LIB_INSPECT_TESTING_INSPECT_H_
#include <lib/inspect/inspect.h>
#include <lib/inspect/reader.h>
#include "fuchsia/inspect/cpp/fidl.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
namespace inspect {
namespace hierarchy {
// Printers for inspect types.
void PrintTo(const Metric& metric, std::ostream* os);
void PrintTo(const Property& property, std::ostream* os);
void PrintTo(const Node& node, std::ostream* os);
} // namespace hierarchy
// Printer for ObjectHierarchy wrapper.
void PrintTo(const ObjectHierarchy& hierarchy, std::ostream* os);
namespace testing {
// Type for a matcher matching a Node.
using NodeMatcher = ::testing::Matcher<const hierarchy::Node&>;
// Type for a matcher matching a vector of metrics.
using MetricsMatcher =
::testing::Matcher<const std::vector<hierarchy::Metric>&>;
// Type for a matcher matching a vector of properties.
using PropertiesMatcher =
::testing::Matcher<const std::vector<hierarchy::Property>&>;
// Type for a matcher that matches a base path on an |ObjectHierarchy|.
using PrefixPathMatcher = ::testing::Matcher<const std::vector<std::string>&>;
// Type for a matcher that matches a vector of |ObjectHierarchy| children.
using ChildrenMatcher = ::testing::Matcher<const std::vector<ObjectHierarchy>&>;
namespace internal {
// Matcher interface to check the name of an inspect Nodes.
class NameMatchesMatcher
: public ::testing::MatcherInterface<const hierarchy::Node&> {
public:
NameMatchesMatcher(std::string name);
bool MatchAndExplain(const hierarchy::Node& obj,
::testing::MatchResultListener* listener) const override;
void DescribeTo(::std::ostream* os) const override;
void DescribeNegationTo(::std::ostream* os) const override;
private:
std::string name_;
};
// Matcher interface to check the list of Node metrics.
class MetricListMatcher
: public ::testing::MatcherInterface<const hierarchy::Node&> {
public:
MetricListMatcher(MetricsMatcher matcher);
bool MatchAndExplain(const hierarchy::Node& obj,
::testing::MatchResultListener* listener) const override;
void DescribeTo(::std::ostream* os) const override;
void DescribeNegationTo(::std::ostream* os) const override;
private:
MetricsMatcher matcher_;
};
// Matcher interface to check the list of Node properties.
class PropertyListMatcher
: public ::testing::MatcherInterface<const hierarchy::Node&> {
public:
PropertyListMatcher(PropertiesMatcher matcher);
bool MatchAndExplain(const hierarchy::Node& obj,
::testing::MatchResultListener* listener) const override;
void DescribeTo(::std::ostream* os) const override;
void DescribeNegationTo(::std::ostream* os) const override;
private:
PropertiesMatcher matcher_;
};
} // namespace internal
// Matches against the name of an Inspect Node.
// Example:
// EXPECT_THAT(node, NameMatches("objects"));
::testing::Matcher<const hierarchy::Node&> NameMatches(std::string name);
// Matches against the metric list of an Inspect Node.
// Example:
// EXPECT_THAT(node, AllOf(MetricList(::testing::IsEmpty())));
::testing::Matcher<const hierarchy::Node&> MetricList(MetricsMatcher matcher);
// Matches against the property list of an Inspect Node.
// Example:
// EXPECT_THAT(node, AllOf(PropertyList(::testing::IsEmpty())));
::testing::Matcher<const hierarchy::Node&> PropertyList(
PropertiesMatcher matcher);
// Matches a particular StringProperty with the given name and value.
::testing::Matcher<const hierarchy::Property&> StringPropertyIs(
const std::string& name, const std::string& value);
// Matches a particular ByteVectorProperty with the given name and value.
::testing::Matcher<const hierarchy::Property&> ByteVectorPropertyIs(
const std::string& name, const VectorValue& value);
// Matches a particular IntMetric with the given name and value.
::testing::Matcher<const hierarchy::Metric&> IntMetricIs(
const std::string& name, int64_t value);
// Matches a particular UIntMetric with the given name and value.
::testing::Matcher<const hierarchy::Metric&> UIntMetricIs(
const std::string& name, uint64_t value);
// Matches a particular DoubleMetric with the given name and value.
::testing::Matcher<const hierarchy::Metric&> DoubleMetricIs(
const std::string& name, double value);
// Matches the values of an integer array.
::testing::Matcher<const hierarchy::Metric&> IntArrayIs(
const std::string& name, ::testing::Matcher<std::vector<int64_t>>);
// Matches the values of an unsigned integer array.
::testing::Matcher<const hierarchy::Metric&> UIntArrayIs(
const std::string& name, ::testing::Matcher<std::vector<uint64_t>>);
// Matches the values of a double width floating point number array.
::testing::Matcher<const hierarchy::Metric&> DoubleArrayIs(
const std::string& name, ::testing::Matcher<std::vector<double>>);
// Matches the display format of a numeric array value.
::testing::Matcher<const hierarchy::Metric&> ArrayDisplayFormatIs(
hierarchy::ArrayDisplayFormat format);
// Matcher for the object inside an ObjectHierarchy.
::testing::Matcher<const ObjectHierarchy&> NodeMatches(NodeMatcher matcher);
// DEPRECATED: Compatibility for downstream clients.
// TODO(CF-702): Remove this.
::testing::Matcher<const ObjectHierarchy&> ObjectMatches(NodeMatcher matcher);
// Matcher for the base path inside an ObjectHierarchy.
::testing::Matcher<const ObjectHierarchy&> PrefixPathMatches(
PrefixPathMatcher matcher);
// Matcher for the children of the object in an ObjectHierarchy.
::testing::Matcher<const ObjectHierarchy&> ChildrenMatch(
ChildrenMatcher matcher);
// Computes the bucket index for a value in a linear histogram.
template <typename T>
size_t ComputeLinearBucketIndex(T floor, T step_size, size_t buckets, T value) {
size_t ret;
for (ret = 0; value >= floor && ret < buckets + 1;
floor += step_size, ret++) {
}
return ret;
}
// Computes the bucket index for a value in an exponential histogram.
template <typename T>
size_t ComputeExponentialBucketIndex(T floor, T initial_step, T step_multiplier,
size_t buckets, T value) {
T current_step = initial_step;
size_t ret;
for (ret = 0; value >= floor && ret < buckets + 1;
floor += current_step, current_step *= step_multiplier, ret++) {
}
return ret;
}
// Creates the expected contents of a linear histogram given parameters and
// values.
template <typename T>
std::vector<T> CreateExpectedLinearHistogramContents(
T floor, T step_size, size_t buckets, const std::vector<T>& values) {
const size_t underflow_bucket_offset = 2;
const size_t array_size = 4 + buckets;
std::vector<T> expected = {floor, step_size};
expected.resize(array_size);
for (T value : values) {
expected[underflow_bucket_offset +
ComputeLinearBucketIndex(floor, step_size, buckets, value)]++;
}
return expected;
}
// Creates the expected contents of an exponential histogram given parameters
// and values.
template <typename T>
std::vector<T> CreateExpectedExponentialHistogramContents(
T floor, T initial_step, T step_multiplier, size_t buckets,
const std::vector<T>& values) {
const size_t underflow_bucket_offset = 3;
const size_t array_size = 5 + buckets;
std::vector<T> expected = {floor, initial_step, step_multiplier};
expected.resize(array_size);
for (T value : values) {
expected[underflow_bucket_offset +
ComputeExponentialBucketIndex(floor, initial_step, step_multiplier,
buckets, value)]++;
}
return expected;
}
} // namespace testing
} // namespace inspect
#endif // LIB_INSPECT_TESTING_INSPECT_H_