Add a testcase for destroyObject
Validate that:
-Dbus signal callbacks are established.
-The propertyChangedTo filter works correctly.
-The destroyObject action works correctly.
Change-Id: I0981fed76aa26ff275a401ae81fd230833dfc4cc
Signed-off-by: Brad Bishop <bradleyb@fuzziesquirrel.com>
diff --git a/example/events.d/match2.yaml b/example/events.d/match2.yaml
index d31a694..84b28f1 100644
--- a/example/events.d/match2.yaml
+++ b/example/events.d/match2.yaml
@@ -4,25 +4,30 @@
events:
- name: Example Match(2)
description: >
- Matches any PropertiesChanged signal emitted
- by /xyz/openbmc_project/testing.
+ Destroys the /deleteme1 and /deleteme2 objects
+ When the value of ExampleProperty2 on
+ /testing/inventory/trigger changes to xxxyyy.
type: match
signatures:
- type: signal
- path: /xyz/openbmc_project/Inventory/example
+ path: /testing/inventory/trigger1
interface: org.freedesktop.DBus.Properties
member: PropertiesChanged
filters:
- name: propertyChangedTo
args:
- interface: xyz.openbmc_project.Example.Iface1
- property: ExampleProperty1
+ interface: xyz.openbmc_project.Example.Iface2
+ property: ExampleProperty2
value:
type: string
- value: testString
+ value: xxxyyy
actions:
- name: destroyObject
args:
- path: Example
+ path: /deleteme1
+ - name: destroyObject
+ args:
+ path: /deleteme2
+
# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4
diff --git a/test/test.cpp b/test/test.cpp
index 669879d..0a1fbd9 100644
--- a/test/test.cpp
+++ b/test/test.cpp
@@ -100,6 +100,25 @@
return result.empty();
}
+/**@brief Check an object for one or more interfaces. */
+template <typename ...T>
+auto hasInterfaces(const std::vector<std::string> &l, const Object<T...> &r)
+{
+ std::vector<std::string> stripped, interfaces;
+ std::transform(
+ r.cbegin(),
+ r.cend(),
+ std::back_inserter(stripped),
+ [](auto &p){ return p.first; });
+ std::set_difference(
+ stripped.cbegin(),
+ stripped.cend(),
+ l.cbegin(),
+ l.cend(),
+ std::back_inserter(interfaces));
+ return interfaces.empty();
+}
+
void runTests(phosphor::inventory::manager::Manager &mgr)
{
const std::string root{ROOT};
@@ -112,6 +131,14 @@
INTERFACE,
"Notify");
};
+ auto set = [&](const std::string &path)
+ {
+ return b.new_method_call(
+ SERVICE,
+ path.c_str(),
+ "org.freedesktop.DBus.Properties",
+ "Set");
+ };
Object<std::string> obj{
{
@@ -149,6 +176,91 @@
assert(!moreSignals);
}
+ // Make sure DBus signals are handled.
+ {
+ ObjectPath relDeleteMeOne{"/deleteme1"};
+ ObjectPath relDeleteMeTwo{"/deleteme2"};
+ ObjectPath relTriggerOne{"/trigger1"};
+ ObjectPath deleteMeOne{root + relDeleteMeOne};
+ ObjectPath deleteMeTwo{root + relDeleteMeTwo};
+ ObjectPath triggerOne{root + relTriggerOne};
+
+ // Create some objects to be deleted by an action.
+ {
+ auto m = notify();
+ m.append(relDeleteMeOne);
+ m.append(obj);
+ b.call(m);
+ }
+ {
+ auto m = notify();
+ m.append(relDeleteMeTwo);
+ m.append(obj);
+ b.call(m);
+ }
+
+ // Create the triggering object.
+ {
+ auto m = notify();
+ m.append(relTriggerOne);
+ m.append(obj);
+ b.call(m);
+ }
+
+ // Set a property that should not trigger due to a filter.
+ {
+ SignalQueue queue(
+ "path='" + root + "',member='InterfacesRemoved'");
+ auto m = set(triggerOne);
+ m.append("xyz.openbmc_project.Example.Iface2");
+ m.append("ExampleProperty2");
+ m.append(sdbusplus::message::variant<std::string>("abc123"));
+ b.call(m);
+ auto sig{queue.pop()};
+ assert(!sig);
+ }
+
+ // Set a property that should trigger.
+ {
+ SignalQueue queue(
+ "path='" + root + "',member='InterfacesRemoved'");
+
+ auto m = set(triggerOne);
+ m.append("xyz.openbmc_project.Example.Iface2");
+ m.append("ExampleProperty2");
+ m.append(sdbusplus::message::variant<std::string>("xxxyyy"));
+ b.call(m);
+
+ ObjectPath sigpath;
+ std::vector<std::string> interfaces;
+ {
+ std::vector<std::string> interfaces;
+ auto sig{queue.pop()};
+ assert(sig);
+ sig.read(sigpath);
+ assert(sigpath == deleteMeOne);
+ sig.read(interfaces);
+ std::sort(interfaces.begin(), interfaces.end());
+ assert(hasInterfaces(interfaces, obj));
+ }
+ {
+ std::vector<std::string> interfaces;
+ auto sig{queue.pop()};
+ assert(sig);
+ sig.read(sigpath);
+ assert(sigpath == deleteMeTwo);
+ sig.read(interfaces);
+ std::sort(interfaces.begin(), interfaces.end());
+ assert(hasInterfaces(interfaces, obj));
+ }
+ {
+ // Make sure there were only two signals.
+ auto sig{queue.pop()};
+ assert(!sig);
+ }
+ }
+ }
+
mgr.shutdown();
std::cout << "Success!" << std::endl;
}