113fd8722SBrad Bishop #include "propertywatchtest.hpp"
213fd8722SBrad Bishop
33d6d3182SPatrick Venture #include "propertywatchimpl.hpp"
43d6d3182SPatrick Venture
53d6d3182SPatrick Venture #include <array>
639c8215dSMatthew Barth #include <functional>
73d6d3182SPatrick Venture
813fd8722SBrad Bishop using namespace std::string_literals;
913fd8722SBrad Bishop using namespace phosphor::dbus::monitoring;
1013fd8722SBrad Bishop
11d1eac88dSBrad Bishop const std::array<std::string, 4> paths = {
1213fd8722SBrad Bishop "/xyz/openbmc_project/testing/inst1"s,
1313fd8722SBrad Bishop "/xyz/openbmc_project/testing/inst2"s,
1413fd8722SBrad Bishop "/xyz/openbmc_project/testing/inst3"s,
1513fd8722SBrad Bishop "/xyz/openbmc_project/testing/inst4"s,
1613fd8722SBrad Bishop };
1713fd8722SBrad Bishop
18d1eac88dSBrad Bishop const std::array<std::string, 2> interfaces = {
1913fd8722SBrad Bishop "xyz.openbmc_project.Iface1"s,
2013fd8722SBrad Bishop "xyz.openbmc_project.Iface2"s,
2113fd8722SBrad Bishop };
2213fd8722SBrad Bishop
23d1eac88dSBrad Bishop const std::array<std::string, 2> properties = {
2413fd8722SBrad Bishop "Value1"s,
2513fd8722SBrad Bishop "Value2"s,
2613fd8722SBrad Bishop };
2713fd8722SBrad Bishop
2813fd8722SBrad Bishop const std::string meta;
2913fd8722SBrad Bishop
3026dc0bcbSPatrick Williams std::array<std::tuple<std::any, std::any>, 8> storage = {};
3113fd8722SBrad Bishop
32d1eac88dSBrad Bishop const PropertyIndex watchIndex = {
3313fd8722SBrad Bishop {
34d1eac88dSBrad Bishop {PropertyIndex::key_type{paths[0], interfaces[0], properties[0]},
35d1eac88dSBrad Bishop PropertyIndex::mapped_type{meta, meta, storage[0]}},
36d1eac88dSBrad Bishop {PropertyIndex::key_type{paths[0], interfaces[1], properties[1]},
37d1eac88dSBrad Bishop PropertyIndex::mapped_type{meta, meta, storage[1]}},
38d1eac88dSBrad Bishop {PropertyIndex::key_type{paths[1], interfaces[0], properties[0]},
39d1eac88dSBrad Bishop PropertyIndex::mapped_type{meta, meta, storage[2]}},
40d1eac88dSBrad Bishop {PropertyIndex::key_type{paths[1], interfaces[1], properties[1]},
41d1eac88dSBrad Bishop PropertyIndex::mapped_type{meta, meta, storage[3]}},
42d1eac88dSBrad Bishop {PropertyIndex::key_type{paths[2], interfaces[0], properties[0]},
43d1eac88dSBrad Bishop PropertyIndex::mapped_type{meta, meta, storage[4]}},
44d1eac88dSBrad Bishop {PropertyIndex::key_type{paths[2], interfaces[1], properties[1]},
45d1eac88dSBrad Bishop PropertyIndex::mapped_type{meta, meta, storage[5]}},
46d1eac88dSBrad Bishop {PropertyIndex::key_type{paths[3], interfaces[0], properties[0]},
47d1eac88dSBrad Bishop PropertyIndex::mapped_type{meta, meta, storage[6]}},
48d1eac88dSBrad Bishop {PropertyIndex::key_type{paths[3], interfaces[1], properties[1]},
49d1eac88dSBrad Bishop PropertyIndex::mapped_type{meta, meta, storage[7]}},
5013fd8722SBrad Bishop },
5113fd8722SBrad Bishop };
5213fd8722SBrad Bishop
533d6d3182SPatrick Venture template <typename T>
545288136aSMatthew Barth struct Values
553fe976ccSGeorge Liu {};
563d6d3182SPatrick Venture template <>
575288136aSMatthew Barth struct Values<uint8_t>
5813fd8722SBrad Bishop {
getValues5913fd8722SBrad Bishop static auto& get(size_t i)
6013fd8722SBrad Bishop {
61d1eac88dSBrad Bishop static const std::array<uint8_t, 8> values = {
6213fd8722SBrad Bishop {0, 1, 2, 3, 4, 5, 6, 7},
6313fd8722SBrad Bishop };
6413fd8722SBrad Bishop return values[i];
6513fd8722SBrad Bishop }
6613fd8722SBrad Bishop };
6713fd8722SBrad Bishop
683d6d3182SPatrick Venture template <>
695288136aSMatthew Barth struct Values<uint16_t>
7013fd8722SBrad Bishop {
getValues7113fd8722SBrad Bishop static auto& get(size_t i)
7213fd8722SBrad Bishop {
73d1eac88dSBrad Bishop static const std::array<uint16_t, 8> values = {
7413fd8722SBrad Bishop {88, 77, 66, 55, 44, 33, 22, 11},
7513fd8722SBrad Bishop };
7613fd8722SBrad Bishop return values[i];
7713fd8722SBrad Bishop }
7813fd8722SBrad Bishop };
7913fd8722SBrad Bishop
803d6d3182SPatrick Venture template <>
815288136aSMatthew Barth struct Values<uint32_t>
8213fd8722SBrad Bishop {
getValues8313fd8722SBrad Bishop static auto& get(size_t i)
8413fd8722SBrad Bishop {
85d1eac88dSBrad Bishop static const std::array<uint32_t, 8> values = {
8613fd8722SBrad Bishop {0xffffffff, 1, 3, 0, 5, 7, 9, 0xffffffff},
8713fd8722SBrad Bishop };
8813fd8722SBrad Bishop return values[i];
8913fd8722SBrad Bishop }
9013fd8722SBrad Bishop };
9113fd8722SBrad Bishop
923d6d3182SPatrick Venture template <>
935288136aSMatthew Barth struct Values<uint64_t>
9413fd8722SBrad Bishop {
getValues9513fd8722SBrad Bishop static auto& get(size_t i)
9613fd8722SBrad Bishop {
97d1eac88dSBrad Bishop static const std::array<uint64_t, 8> values = {
9813fd8722SBrad Bishop {0xffffffffffffffff, 3, 7, 12234, 0, 3, 9, 0xffffffff},
9913fd8722SBrad Bishop };
10013fd8722SBrad Bishop return values[i];
10113fd8722SBrad Bishop }
10213fd8722SBrad Bishop };
10313fd8722SBrad Bishop
1043d6d3182SPatrick Venture template <>
1055288136aSMatthew Barth struct Values<std::string>
10613fd8722SBrad Bishop {
getValues10713fd8722SBrad Bishop static auto& get(size_t i)
10813fd8722SBrad Bishop {
109d1eac88dSBrad Bishop static const std::array<std::string, 8> values = {
11013fd8722SBrad Bishop {""s, "foo"s, "bar"s, "baz"s, "hello"s, "string", "\x2\x3", "\\"},
11113fd8722SBrad Bishop };
11213fd8722SBrad Bishop return values[i];
11313fd8722SBrad Bishop }
11413fd8722SBrad Bishop };
11513fd8722SBrad Bishop
1163d6d3182SPatrick Venture template <typename T>
nonFilteredCheck(const std::any & value,const size_t ndx)11726dc0bcbSPatrick Williams void nonFilteredCheck(const std::any& value, const size_t ndx)
11839c8215dSMatthew Barth {
11926dc0bcbSPatrick Williams ASSERT_EQ(value.has_value(), true);
12026dc0bcbSPatrick Williams ASSERT_EQ(std::any_cast<T>(value), Values<T>::get(ndx));
12139c8215dSMatthew Barth }
12239c8215dSMatthew Barth
12339c8215dSMatthew Barth template <typename T>
1249b50214bSMatthew Barth struct FilteredValues
1253fe976ccSGeorge Liu {};
1269b50214bSMatthew Barth
1279b50214bSMatthew Barth template <>
1289b50214bSMatthew Barth struct FilteredValues<uint8_t>
1299b50214bSMatthew Barth {
opFiltersFilteredValues1309b50214bSMatthew Barth static auto& opFilters()
1319b50214bSMatthew Barth {
1329b50214bSMatthew Barth static std::unique_ptr<OperandFilters<uint8_t>> filters =
1339b50214bSMatthew Barth std::make_unique<OperandFilters<uint8_t>>(
1349b50214bSMatthew Barth std::vector<std::function<bool(uint8_t)>>{
1359b50214bSMatthew Barth [](const auto& value) { return value < 4; }});
1369b50214bSMatthew Barth return filters;
1379b50214bSMatthew Barth }
expectedFilteredValues1389b50214bSMatthew Barth static auto& expected(size_t i)
1399b50214bSMatthew Barth {
14026dc0bcbSPatrick Williams static const std::array<std::any, 8> values = {
14126dc0bcbSPatrick Williams {std::any(uint8_t(0)), std::any(uint8_t(1)), std::any(uint8_t(2)),
14226dc0bcbSPatrick Williams std::any(uint8_t(3)), std::any(), std::any(), std::any(),
14326dc0bcbSPatrick Williams std::any()}};
1449b50214bSMatthew Barth return values[i];
1459b50214bSMatthew Barth }
1469b50214bSMatthew Barth };
1479b50214bSMatthew Barth
1489b50214bSMatthew Barth template <>
1499b50214bSMatthew Barth struct FilteredValues<uint16_t>
1509b50214bSMatthew Barth {
opFiltersFilteredValues1519b50214bSMatthew Barth static auto& opFilters()
1529b50214bSMatthew Barth {
1539b50214bSMatthew Barth static std::unique_ptr<OperandFilters<uint16_t>> filters =
1549b50214bSMatthew Barth std::make_unique<OperandFilters<uint16_t>>(
1559b50214bSMatthew Barth std::vector<std::function<bool(uint16_t)>>{
1569b50214bSMatthew Barth [](const auto& value) { return value > 44; },
1579b50214bSMatthew Barth [](const auto& value) { return value != 88; }});
1589b50214bSMatthew Barth return filters;
1599b50214bSMatthew Barth }
expectedFilteredValues1609b50214bSMatthew Barth static auto& expected(size_t i)
1619b50214bSMatthew Barth {
16226dc0bcbSPatrick Williams static const std::array<std::any, 8> values = {
16326dc0bcbSPatrick Williams {std::any(), std::any(uint16_t(77)), std::any(uint16_t(66)),
16426dc0bcbSPatrick Williams std::any(uint16_t(55)), std::any(), std::any(), std::any(),
16526dc0bcbSPatrick Williams std::any()}};
1669b50214bSMatthew Barth return values[i];
1679b50214bSMatthew Barth }
1689b50214bSMatthew Barth };
1699b50214bSMatthew Barth
1709b50214bSMatthew Barth template <>
1719b50214bSMatthew Barth struct FilteredValues<uint32_t>
1729b50214bSMatthew Barth {
opFiltersFilteredValues1739b50214bSMatthew Barth static auto& opFilters()
1749b50214bSMatthew Barth {
1759b50214bSMatthew Barth static std::unique_ptr<OperandFilters<uint32_t>> filters =
1769b50214bSMatthew Barth std::make_unique<OperandFilters<uint32_t>>(
1779b50214bSMatthew Barth std::vector<std::function<bool(uint32_t)>>{
1789b50214bSMatthew Barth [](const auto& value) { return value != 0xffffffff; },
1799b50214bSMatthew Barth [](const auto& value) { return value != 0; }});
1809b50214bSMatthew Barth return filters;
1819b50214bSMatthew Barth }
expectedFilteredValues1829b50214bSMatthew Barth static auto& expected(size_t i)
1839b50214bSMatthew Barth {
18426dc0bcbSPatrick Williams static const std::array<std::any, 8> values = {
18526dc0bcbSPatrick Williams {std::any(), std::any(uint32_t(1)), std::any(uint32_t(3)),
18626dc0bcbSPatrick Williams std::any(), std::any(uint32_t(5)), std::any(uint32_t(7)),
18726dc0bcbSPatrick Williams std::any(uint32_t(9)), std::any()}};
1889b50214bSMatthew Barth return values[i];
1899b50214bSMatthew Barth }
1909b50214bSMatthew Barth };
1919b50214bSMatthew Barth
1929b50214bSMatthew Barth template <>
1939b50214bSMatthew Barth struct FilteredValues<uint64_t>
1949b50214bSMatthew Barth {
opFiltersFilteredValues1959b50214bSMatthew Barth static auto& opFilters()
1969b50214bSMatthew Barth {
1979b50214bSMatthew Barth static std::unique_ptr<OperandFilters<uint64_t>> filters =
1989b50214bSMatthew Barth std::make_unique<OperandFilters<uint64_t>>(
1999b50214bSMatthew Barth std::vector<std::function<bool(uint64_t)>>{
2009b50214bSMatthew Barth [](const auto& value) { return (value % 3) != 0; }});
2019b50214bSMatthew Barth return filters;
2029b50214bSMatthew Barth }
expectedFilteredValues2039b50214bSMatthew Barth static auto& expected(size_t i)
2049b50214bSMatthew Barth {
20526dc0bcbSPatrick Williams static const std::array<std::any, 8> values = {
20626dc0bcbSPatrick Williams {std::any(), std::any(), std::any(uint64_t(7)), std::any(),
20726dc0bcbSPatrick Williams std::any(), std::any(), std::any(), std::any()}};
2089b50214bSMatthew Barth return values[i];
2099b50214bSMatthew Barth }
2109b50214bSMatthew Barth };
2119b50214bSMatthew Barth
2129b50214bSMatthew Barth template <>
2139b50214bSMatthew Barth struct FilteredValues<std::string>
2149b50214bSMatthew Barth {
opFiltersFilteredValues2159b50214bSMatthew Barth static auto& opFilters()
2169b50214bSMatthew Barth {
2179b50214bSMatthew Barth static std::unique_ptr<OperandFilters<std::string>> filters =
2189b50214bSMatthew Barth std::make_unique<OperandFilters<std::string>>(
2199b50214bSMatthew Barth std::vector<std::function<bool(std::string)>>{
2209b50214bSMatthew Barth [](const auto& value) { return value != ""s; },
2219b50214bSMatthew Barth [](const auto& value) { return value != "string"s; }});
2229b50214bSMatthew Barth return filters;
2239b50214bSMatthew Barth }
expectedFilteredValues2249b50214bSMatthew Barth static auto& expected(size_t i)
2259b50214bSMatthew Barth {
22626dc0bcbSPatrick Williams static const std::array<std::any, 8> values = {
22726dc0bcbSPatrick Williams {std::any(), std::any("foo"s), std::any("bar"s), std::any("baz"s),
22826dc0bcbSPatrick Williams std::any("hello"s), std::any(), std::any("\x2\x3"s),
22926dc0bcbSPatrick Williams std::any("\\"s)}};
2309b50214bSMatthew Barth return values[i];
2319b50214bSMatthew Barth }
2329b50214bSMatthew Barth };
2339b50214bSMatthew Barth
2349b50214bSMatthew Barth template <typename T>
filteredCheck(const std::any & value,const size_t ndx)23526dc0bcbSPatrick Williams void filteredCheck(const std::any& value, const size_t ndx)
2369b50214bSMatthew Barth {
23726dc0bcbSPatrick Williams ASSERT_EQ(value.has_value(), FilteredValues<T>::expected(ndx).has_value());
23826dc0bcbSPatrick Williams if (value.has_value())
2399b50214bSMatthew Barth {
24026dc0bcbSPatrick Williams ASSERT_EQ(std::any_cast<T>(value),
24126dc0bcbSPatrick Williams std::any_cast<T>(FilteredValues<T>::expected(ndx)));
2429b50214bSMatthew Barth }
2439b50214bSMatthew Barth }
2449b50214bSMatthew Barth
2459b50214bSMatthew Barth template <typename T>
testStart(std::function<void (const std::any &,const size_t)> && checkState,OperandFilters<T> * opFilters=nullptr)24626dc0bcbSPatrick Williams void testStart(std::function<void(const std::any&, const size_t)>&& checkState,
2479b50214bSMatthew Barth OperandFilters<T>* opFilters = nullptr)
24813fd8722SBrad Bishop {
24913fd8722SBrad Bishop using ::testing::_;
250ac803959SPatrick Venture using ::testing::Return;
25113fd8722SBrad Bishop
25213fd8722SBrad Bishop MockDBusInterface dbus;
25313fd8722SBrad Bishop MockDBusInterface::instance(dbus);
25413fd8722SBrad Bishop
25513fd8722SBrad Bishop const std::vector<std::string> expectedMapperInterfaces;
25698d6462aSLei YU PropertyWatchOfType<T, MockDBusInterface> watch(watchIndex, false,
25798d6462aSLei YU opFilters);
25813fd8722SBrad Bishop
25913fd8722SBrad Bishop auto ndx = static_cast<size_t>(0);
26013fd8722SBrad Bishop for (const auto& o : convert(watchIndex))
26113fd8722SBrad Bishop {
26213fd8722SBrad Bishop const auto& path = o.first.get();
263*ecef1191SGeorge Liu const auto& tmpInterfaces = o.second;
26413fd8722SBrad Bishop std::vector<std::string> mapperResponse;
265*ecef1191SGeorge Liu std::transform(tmpInterfaces.begin(), tmpInterfaces.end(),
26613fd8722SBrad Bishop std::back_inserter(mapperResponse),
26713fd8722SBrad Bishop // *INDENT-OFF*
268d1eac88dSBrad Bishop [](const auto& item) { return item.first; });
26913fd8722SBrad Bishop // *INDENT-ON*
270d1eac88dSBrad Bishop EXPECT_CALL(dbus, mapperGetObject(MAPPER_BUSNAME, MAPPER_PATH,
271d1eac88dSBrad Bishop MAPPER_INTERFACE, "GetObject", path,
27213fd8722SBrad Bishop expectedMapperInterfaces))
27313fd8722SBrad Bishop .WillOnce(Return(GetObject({{"", mapperResponse}})));
27413fd8722SBrad Bishop EXPECT_CALL(
275d1eac88dSBrad Bishop dbus, fwdAddMatch(
276f79fc09bSMatthew Barth sdbusplus::bus::match::rules::interfacesAdded(path), _));
277*ecef1191SGeorge Liu for (const auto& i : tmpInterfaces)
27813fd8722SBrad Bishop {
27913fd8722SBrad Bishop const auto& interface = i.first.get();
280*ecef1191SGeorge Liu const auto& tmpProperties = i.second;
28113fd8722SBrad Bishop EXPECT_CALL(
28213fd8722SBrad Bishop dbus,
283f79fc09bSMatthew Barth fwdAddMatch(sdbusplus::bus::match::rules::propertiesChanged(
284f79fc09bSMatthew Barth path, interface),
28513fd8722SBrad Bishop _));
28613fd8722SBrad Bishop
28713fd8722SBrad Bishop PropertiesChanged<T> serviceResponse;
288*ecef1191SGeorge Liu for (const auto& p : tmpProperties)
28913fd8722SBrad Bishop {
2905288136aSMatthew Barth serviceResponse[p] = Values<T>::get(ndx);
29113fd8722SBrad Bishop ++ndx;
29213fd8722SBrad Bishop }
29313fd8722SBrad Bishop Expect<T>::getProperties(dbus, path, interface)
29413fd8722SBrad Bishop .WillOnce(Return(serviceResponse));
29513fd8722SBrad Bishop }
29613fd8722SBrad Bishop }
29713fd8722SBrad Bishop
29813fd8722SBrad Bishop watch.start();
29913fd8722SBrad Bishop
30013fd8722SBrad Bishop ndx = 0;
30113fd8722SBrad Bishop for (auto s : storage)
30213fd8722SBrad Bishop {
30339c8215dSMatthew Barth checkState(std::get<valueIndex>(s), ndx);
30413fd8722SBrad Bishop ++ndx;
30513fd8722SBrad Bishop }
30613fd8722SBrad Bishop
30713fd8722SBrad Bishop // Make sure start logic only runs the first time.
30813fd8722SBrad Bishop watch.start();
30913fd8722SBrad Bishop }
31013fd8722SBrad Bishop
TEST(PropertyWatchTest,TestStart)31113fd8722SBrad Bishop TEST(PropertyWatchTest, TestStart)
31213fd8722SBrad Bishop {
31339c8215dSMatthew Barth testStart<uint8_t>(nonFilteredCheck<uint8_t>);
31439c8215dSMatthew Barth testStart<uint16_t>(nonFilteredCheck<uint16_t>);
31539c8215dSMatthew Barth testStart<uint32_t>(nonFilteredCheck<uint32_t>);
31639c8215dSMatthew Barth testStart<uint64_t>(nonFilteredCheck<uint64_t>);
31739c8215dSMatthew Barth testStart<std::string>(nonFilteredCheck<std::string>);
31813fd8722SBrad Bishop }
31913fd8722SBrad Bishop
TEST(PropertyWatchTest,TestFilters)3209b50214bSMatthew Barth TEST(PropertyWatchTest, TestFilters)
3219b50214bSMatthew Barth {
3229b50214bSMatthew Barth testStart<uint8_t>(filteredCheck<uint8_t>,
3239b50214bSMatthew Barth FilteredValues<uint8_t>::opFilters().get());
3249b50214bSMatthew Barth testStart<uint16_t>(filteredCheck<uint16_t>,
3259b50214bSMatthew Barth FilteredValues<uint16_t>::opFilters().get());
3269b50214bSMatthew Barth testStart<uint32_t>(filteredCheck<uint32_t>,
3279b50214bSMatthew Barth FilteredValues<uint32_t>::opFilters().get());
3289b50214bSMatthew Barth testStart<uint64_t>(filteredCheck<uint64_t>,
3299b50214bSMatthew Barth FilteredValues<uint64_t>::opFilters().get());
3309b50214bSMatthew Barth testStart<std::string>(filteredCheck<std::string>,
3319b50214bSMatthew Barth FilteredValues<std::string>::opFilters().get());
3329b50214bSMatthew Barth }
3339b50214bSMatthew Barth
33413fd8722SBrad Bishop MockDBusInterface* MockDBusInterface::ptr = nullptr;
335