blob: 8ffc822a2b86b911c36618a04409b7b910cd51f3 [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 <fuchsia/inspect/cpp/fidl.h>
#include <lib/component/cpp/expose.h>
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "matchers.h"
namespace {
using component::Metric;
using component::Object;
using component::Property;
using testing::UnorderedElementsAre;
TEST(Property, StringValue) {
Property a("test");
EXPECT_THAT(a.ToFidl("key"), StringProperty("key", "test"));
a.Set("test2");
EXPECT_THAT(a.ToFidl("key"), StringProperty("key", "test2"));
}
TEST(Property, VectorValue) {
Property::ByteVector test_vector;
test_vector.push_back('\0');
test_vector.push_back('\10');
Property a(test_vector);
EXPECT_THAT(a.ToFidl("key"), ByteVectorProperty("key", test_vector));
test_vector.push_back('a');
a.Set(test_vector);
EXPECT_THAT(a.ToFidl("key"), ByteVectorProperty("key", test_vector));
}
TEST(Property, StringCallback) {
Property a([] { return std::string("test"); });
// Check callback is called.
EXPECT_THAT(a.ToFidl("key"), StringProperty("key", "test"));
// Set to new callback, cancelling token. New value should be present.
a.Set([] { return std::string("test2"); });
EXPECT_THAT(a.ToFidl("key"), StringProperty("key", "test2"));
}
TEST(Property, VectorCallback) {
Property a([] { return Property::ByteVector(2, 'a'); });
// Check callback is called.
EXPECT_THAT(a.ToFidl("key"),
ByteVectorProperty("key", Property::ByteVector(2, 'a')));
// Set to new callback, cancelling token. New value should be present.
a.Set([] { return Property::ByteVector(2, 'b'); });
EXPECT_THAT(a.ToFidl("key"),
ByteVectorProperty("key", Property::ByteVector(2, 'b')));
}
TEST(Metric, SetValue) {
Metric a;
EXPECT_THAT(a.ToFidl("key"), IntMetric("key", 0));
a.SetInt(-10);
EXPECT_THAT(a.ToFidl("key"), IntMetric("key", -10));
a.SetUInt(1000);
EXPECT_THAT(a.ToFidl("key"), UIntMetric("key", 1000));
a.SetDouble(1.25);
EXPECT_THAT(a.ToFidl("key"), DoubleMetric("key", 1.25));
}
TEST(Metric, Arithmetic) {
Metric a;
EXPECT_THAT(a.ToFidl("key"), IntMetric("key", 0));
a.Sub(10);
EXPECT_THAT(a.ToFidl("key"), IntMetric("key", -10));
a.Sub(1.5);
EXPECT_THAT(a.ToFidl("key"), IntMetric("key", -11));
a.SetUInt(0);
a.Add(1);
EXPECT_THAT(a.ToFidl("key"), UIntMetric("key", 1));
// Check that overflowing works properly.
// Subtracting below 0 should wrap around.
// Adding and subtracting by a double should also wrap.
a.Sub(2);
EXPECT_THAT(a.ToFidl("key"), UIntMetric("key", 0xFFFFFFFFFFFFFFFF));
a.Add(2.12);
EXPECT_THAT(a.ToFidl("key"), UIntMetric("key", 1));
a.Sub(2.12);
EXPECT_THAT(a.ToFidl("key"), UIntMetric("key", 0xFFFFFFFFFFFFFFFF));
a.Add(-1);
EXPECT_THAT(a.ToFidl("key"), UIntMetric("key", 0xFFFFFFFFFFFFFFFE));
a.SetDouble(1.25);
a.Add(0.5);
EXPECT_THAT(a.ToFidl("key"), DoubleMetric("key", 1.75));
a.Sub(1);
EXPECT_THAT(a.ToFidl("key"), DoubleMetric("key", 0.75));
}
TEST(Metric, ValueCallback) {
Metric a = component::CallbackMetric(
[](Metric* out_metric) { out_metric->SetInt(10); });
// Check callback is called.
EXPECT_THAT(a.ToFidl("key"), IntMetric("key", 10));
// Set to new callback, cancelling token. New value should be present.
a.SetCallback([](Metric* out_metric) { out_metric->SetInt(11); });
EXPECT_THAT(a.ToFidl("key"), IntMetric("key", 11));
}
TEST(Object, Name) {
fbl::RefPtr<Object> object = fbl::MakeRefCounted<Object>("test");
EXPECT_STREQ("test", object->name().c_str());
}
TEST(Object, ReadData) {
fbl::RefPtr<Object> object = fbl::MakeRefCounted<Object>("test");
object->SetProperty("property", component::Property("value"));
object->SetMetric("int metric", component::IntMetric(-10));
object->SetMetric("uint metric", component::UIntMetric(0xFF));
object->SetMetric("double metric", component::DoubleMetric(0.25));
fuchsia::inspect::Object obj;
object->ReadData(
[&obj](fuchsia::inspect::Object val) { obj = std::move(val); });
EXPECT_STREQ("test", obj.name.c_str());
EXPECT_THAT(*obj.properties,
UnorderedElementsAre(StringProperty("property", "value")));
EXPECT_THAT(*obj.metrics,
UnorderedElementsAre(IntMetric("int metric", -10),
UIntMetric("uint metric", 0xFF),
DoubleMetric("double metric", 0.25)));
}
component::Object::StringOutputVector ListChildren(fbl::RefPtr<Object> object) {
component::Object::StringOutputVector ret;
object->ListChildren([&ret](component::Object::StringOutputVector val) {
ret = std::move(val);
});
return ret;
}
TEST(Object, SetTakeChild) {
fbl::RefPtr<Object> object = fbl::MakeRefCounted<Object>("test");
component::Object::StringOutputVector children_list;
object->SetChild(fbl::MakeRefCounted<Object>("child1"));
children_list = ListChildren(object);
EXPECT_THAT(*children_list, UnorderedElementsAre(fidl::StringPtr("child1")));
auto child = object->TakeChild("child1");
children_list = ListChildren(object);
EXPECT_STREQ("child1", child->name().c_str());
EXPECT_THAT(*children_list, UnorderedElementsAre());
}
TEST(Object, ChildrenCallback) {
fbl::RefPtr<Object> object = fbl::MakeRefCounted<Object>("test");
component::Object::StringOutputVector children_list;
object->SetChild(fbl::MakeRefCounted<Object>("concrete1"));
object->SetChild(fbl::MakeRefCounted<Object>("concrete2"));
children_list = ListChildren(object);
EXPECT_THAT(*children_list,
UnorderedElementsAre(fidl::StringPtr("concrete1"),
fidl::StringPtr("concrete2")));
// Set the callback and ensure it is merged with the concrete objects.
object->SetChildrenCallback([](component::Object::ObjectVector* out) {
out->emplace_back(fbl::MakeRefCounted<Object>("dynamic1"));
out->emplace_back(fbl::MakeRefCounted<Object>("dynamic2"));
out->emplace_back(fbl::MakeRefCounted<Object>("dynamic3"));
});
children_list = ListChildren(object);
EXPECT_THAT(*children_list,
UnorderedElementsAre(
fidl::StringPtr("concrete1"), fidl::StringPtr("concrete2"),
fidl::StringPtr("dynamic1"), fidl::StringPtr("dynamic2"),
fidl::StringPtr("dynamic3")));
}
} // namespace