blob: b92dbec355b275f5bd086c18f2a9e7873bdac411 [file] [log] [blame]
#include <array>
#include "propertywatchimpl.hpp"
#include "propertywatchtest.hpp"
using namespace std::string_literals;
using namespace phosphor::dbus::monitoring;
const std::array<std::string, 4> paths =
{
"/xyz/openbmc_project/testing/inst1"s,
"/xyz/openbmc_project/testing/inst2"s,
"/xyz/openbmc_project/testing/inst3"s,
"/xyz/openbmc_project/testing/inst4"s,
};
const std::array<std::string, 2> interfaces =
{
"xyz.openbmc_project.Iface1"s,
"xyz.openbmc_project.Iface2"s,
};
const std::array<std::string, 2> properties =
{
"Value1"s,
"Value2"s,
};
const std::string meta;
std::array<any_ns::any, 8> storage = { };
const PropertyIndex watchIndex =
{
{
{
PropertyIndex::key_type{paths[0], interfaces[0], properties[0]},
PropertyIndex::mapped_type{meta, meta, storage[0]}
},
{
PropertyIndex::key_type{paths[0], interfaces[1], properties[1]},
PropertyIndex::mapped_type{meta, meta, storage[1]}
},
{
PropertyIndex::key_type{paths[1], interfaces[0], properties[0]},
PropertyIndex::mapped_type{meta, meta, storage[2]}
},
{
PropertyIndex::key_type{paths[1], interfaces[1], properties[1]},
PropertyIndex::mapped_type{meta, meta, storage[3]}
},
{
PropertyIndex::key_type{paths[2], interfaces[0], properties[0]},
PropertyIndex::mapped_type{meta, meta, storage[4]}
},
{
PropertyIndex::key_type{paths[2], interfaces[1], properties[1]},
PropertyIndex::mapped_type{meta, meta, storage[5]}
},
{
PropertyIndex::key_type{paths[3], interfaces[0], properties[0]},
PropertyIndex::mapped_type{meta, meta, storage[6]}
},
{
PropertyIndex::key_type{paths[3], interfaces[1], properties[1]},
PropertyIndex::mapped_type{meta, meta, storage[7]}
},
},
};
template <typename T> struct ExpectedValues {};
template <> struct ExpectedValues<uint8_t>
{
static auto& get(size_t i)
{
static const std::array<uint8_t, 8> values =
{
{0, 1, 2, 3, 4, 5, 6, 7},
};
return values[i];
}
};
template <> struct ExpectedValues<uint16_t>
{
static auto& get(size_t i)
{
static const std::array<uint16_t, 8> values =
{
{88, 77, 66, 55, 44, 33, 22, 11},
};
return values[i];
}
};
template <> struct ExpectedValues<uint32_t>
{
static auto& get(size_t i)
{
static const std::array<uint32_t, 8> values =
{
{0xffffffff, 1, 3, 0, 5, 7, 9, 0xffffffff},
};
return values[i];
}
};
template <> struct ExpectedValues<uint64_t>
{
static auto& get(size_t i)
{
static const std::array<uint64_t, 8> values =
{
{0xffffffffffffffff, 3, 7, 12234, 0, 3, 9, 0xffffffff},
};
return values[i];
}
};
template <> struct ExpectedValues<std::string>
{
static auto& get(size_t i)
{
static const std::array<std::string, 8> values =
{
{""s, "foo"s, "bar"s, "baz"s, "hello"s, "string", "\x2\x3", "\\"},
};
return values[i];
}
};
template <typename T>
void testStart()
{
using ::testing::Return;
using ::testing::_;
MockDBusInterface dbus;
MockDBusInterface::instance(dbus);
const std::vector<std::string> expectedMapperInterfaces;
PropertyWatchOfType<T, MockDBusInterface> watch(watchIndex);
auto ndx = static_cast<size_t>(0);
for (const auto& o : convert(watchIndex))
{
const auto& path = o.first.get();
const auto& interfaces = o.second;
std::vector<std::string> mapperResponse;
std::transform(
interfaces.begin(),
interfaces.end(),
std::back_inserter(mapperResponse),
// *INDENT-OFF*
[](const auto & item)
{
return item.first;
});
// *INDENT-ON*
EXPECT_CALL(
dbus,
mapperGetObject(
MAPPER_BUSNAME,
MAPPER_PATH,
MAPPER_INTERFACE,
"GetObject",
path,
expectedMapperInterfaces))
.WillOnce(Return(GetObject({{"", mapperResponse}})));
EXPECT_CALL(
dbus,
fwdAddMatch(
sdbusplus::bus::match::rules::member("InterfacesAdded") +
sdbusplus::bus::match::rules::path(path) +
sdbusplus::bus::match::rules::interface(
"org.freedesktop.DBus.ObjectManager"),
_));
for (const auto& i : interfaces)
{
const auto& interface = i.first.get();
const auto& properties = i.second;
EXPECT_CALL(
dbus,
fwdAddMatch(
sdbusplus::bus::match::rules::member("PropertiesChanged") +
sdbusplus::bus::match::rules::path(path) +
sdbusplus::bus::match::rules::argN(0, interface) +
sdbusplus::bus::match::rules::interface(
"org.freedesktop.DBus.Properties"),
_));
PropertiesChanged<T> serviceResponse;
for (const auto& p : properties)
{
serviceResponse[p] = ExpectedValues<T>::get(ndx);
++ndx;
}
Expect<T>::getProperties(dbus, path, interface)
.WillOnce(Return(serviceResponse));
}
}
watch.start();
ndx = 0;
for (auto s : storage)
{
ASSERT_EQ(s.empty(), false);
ASSERT_EQ(any_ns::any_cast<T>(s), ExpectedValues<T>::get(ndx));
++ndx;
}
// Make sure start logic only runs the first time.
watch.start();
}
TEST(PropertyWatchTest, TestStart)
{
testStart<uint8_t>();
testStart<uint16_t>();
testStart<uint32_t>();
testStart<uint64_t>();
testStart<std::string>();
}
MockDBusInterface* MockDBusInterface::ptr = nullptr;