blob: d7c2ace0b109776e85ec3babf9c9e7cdb525c82b [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 SRC_LIB_INSPECT_DEPRECATED_TESTING_INSPECT_H_
#define SRC_LIB_INSPECT_DEPRECATED_TESTING_INSPECT_H_
#include "fuchsia/inspect/deprecated/cpp/fidl.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "src/lib/inspect_deprecated/inspect.h"
#include "src/lib/inspect_deprecated/reader.h"
namespace inspect_deprecated {
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 StringProperty with the given name, irrespective of value.
::testing::Matcher<const hierarchy::Property&> StringPropertyExists(const std::string& name);
// 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.
// |total_buckets| is the number of buckets initially defined when the histogram
// property was created plus 2 (overflow and underflow).
template <typename T>
size_t ComputeLinearBucketIndex(T floor, T step_size, size_t total_buckets, T value) {
size_t ret = 0;
while (value >= floor && ret < total_buckets - 1) {
floor += step_size;
ret++;
}
return ret;
}
// Computes the bucket index for a value in an exponential histogram.
// |total_buckets| is the number of buckets initially defined when the histogram
// property was created plus 2 (overflow and underflow).
template <typename T>
size_t ComputeExponentialBucketIndex(T floor, T initial_step, T step_multiplier,
size_t total_buckets, T value) {
T current_floor = floor;
T current_step = initial_step;
size_t ret = 0;
while (value >= current_floor && ret < total_buckets - 1) {
current_floor = 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) {
// Linear Histogram arrays contain 2 fields with metadata.
const size_t underflow_bucket_offset = 2;
// |buckets| + 1 underflow bucket + 1 overflow bucket
const size_t total_buckets = 2 + buckets;
const size_t array_size = underflow_bucket_offset + total_buckets;
std::vector<T> expected = {floor, step_size};
expected.resize(array_size);
for (T value : values) {
expected[underflow_bucket_offset +
ComputeLinearBucketIndex(floor, step_size, total_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) {
// Exp. Histogram arrays contain 3 fields with metadata.
const size_t underflow_bucket_offset = 3;
// |buckets| + 1 underflow bucket + 1 overflow bucket
const size_t total_buckets = 2 + buckets;
const size_t array_size = underflow_bucket_offset + total_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, total_buckets,
value)]++;
}
return expected;
}
} // namespace testing
} // namespace inspect_deprecated
#endif // SRC_LIB_INSPECT_DEPRECATED_TESTING_INSPECT_H_