Add testcases for property and property groups

Change-Id: I4b30d0729a704d6833c840ea08daeee961a5730b
Signed-off-by: Brad Bishop <bradleyb@fuzziesquirrel.com>
diff --git a/src/test/.gitignore b/src/test/.gitignore
index c1bc7de..e1da423 100644
--- a/src/test/.gitignore
+++ b/src/test/.gitignore
@@ -2,3 +2,5 @@
 *.trs
 /pathgentest
 /pathgentest.hpp
+/propertygentest
+/propertygentest.hpp
diff --git a/src/test/Makefile.am b/src/test/Makefile.am
index 02772e7..330bf3e 100644
--- a/src/test/Makefile.am
+++ b/src/test/Makefile.am
@@ -36,3 +36,28 @@
 		-d yaml/pathgentest \
 		-o $(builddir)/$@ \
 		generate-cpp
+
+check_PROGRAMS += propertygentest
+propertygentest_SOURCES = \
+	propertygentest.cpp
+propertygentest_CXXFLAGS = \
+	$(gtest_cflags)
+propertygentest_LDFLAGS = \
+	$(OESDK_TESTCASE_FLAGS)
+propertygentest_LDADD = \
+	${gtest_ldadd}
+
+BUILT_SOURCES += propertygentest.hpp
+CLEANFILES += propertygentest.hpp
+
+PROPERTY_TEST_GEN_DEPS = \
+	templates/propertygentest.mako.hpp \
+	yaml/propertygentest
+
+propertygentest.hpp: $(PROPERTY_TEST_GEN_DEPS)
+	$(AM_V_GEN) $(PYTHON) $(PDMGEN) \
+		-t propertygentest.mako.hpp \
+		-p "${TEMPLATESEARCH}" \
+		-d yaml/propertygentest \
+		-o $(builddir)/$@ \
+		generate-cpp
diff --git a/src/test/propertygentest.cpp b/src/test/propertygentest.cpp
new file mode 100644
index 0000000..cf32191
--- /dev/null
+++ b/src/test/propertygentest.cpp
@@ -0,0 +1,156 @@
+#include <array>
+#include <string>
+#include <gtest/gtest.h>
+#include "data_types.hpp"
+
+using namespace std::string_literals;
+using namespace phosphor::dbus::monitoring;
+
+using Property =
+    TupleOfRefs <
+    const std::string,
+    const std::string,
+    const std::string >;
+
+using GroupOfProperties = std::vector<Property>;
+
+#include "propertygentest.hpp"
+const std::array<std::string, 3> expectedMeta =
+{
+    "property1"s,
+    "property2"s,
+    "property3"s,
+};
+
+const std::array<std::string, 4> expectedInterfaces =
+{
+    "xyz.openbmc_project.Test.Iface3"s,
+    "xyz.openbmc_project.Test.Iface2"s,
+    "xyz.openbmc_project.Test.Iface6"s,
+    "xyz.openbmc_project.Test.Iface1"s,
+};
+
+const std::array<std::string, 4> expectedProperties =
+{
+    "Foo"s,
+    "Value"s,
+    "Bar"s,
+    "Baz"s,
+};
+
+const std::array<GroupOfProperties, 4> expectedGroups =
+{
+    {
+        {
+            Property{ interfaces[0], properties[0], meta[0] },
+            Property{ interfaces[1], properties[1], meta[1] },
+        },
+        {
+            Property{ interfaces[0], properties[2], meta[0] },
+            Property{ interfaces[1], properties[0], meta[1] },
+        },
+        {
+            Property{ interfaces[2], properties[0], meta[0] },
+            Property{ interfaces[3], properties[1], meta[1] },
+        },
+        {
+            Property{ interfaces[0], properties[2], meta[0] },
+            Property{ interfaces[1], properties[1], meta[1] },
+            Property{ interfaces[2], properties[3], meta[2] },
+        },
+    }
+};
+
+const std::array<std::string, 4> expectedTypes =
+{
+    "uint32_t"s,
+    "int32_t"s,
+    "std::string"s,
+    "int32_t"s,
+};
+
+TEST(PropertyGenTest, MetaSameSize)
+{
+    ASSERT_EQ(sizeof(expectedMeta), sizeof(meta));
+}
+
+TEST(PropertyGenTest, IfacesSameSize)
+{
+    ASSERT_EQ(sizeof(expectedInterfaces), sizeof(interfaces));
+}
+
+TEST(PropertyGenTest, PropertiesSameSize)
+{
+    ASSERT_EQ(sizeof(expectedProperties), sizeof(properties));
+}
+
+TEST(PropertyGenTest, GroupsSameSize)
+{
+    ASSERT_EQ(sizeof(expectedGroups), sizeof(groups));
+}
+
+TEST(PropertyGenTest, TypesSameSize)
+{
+    ASSERT_EQ(sizeof(expectedTypes), sizeof(types));
+}
+
+TEST(PropertyGenTest, MetaSameContent)
+{
+    size_t i;
+    for (i = 0; i < expectedMeta.size(); ++i)
+    {
+        ASSERT_EQ(meta[i],
+                  expectedMeta[i]);
+    }
+}
+
+TEST(PropertyGenTest, IfacesSameContent)
+{
+    size_t i;
+    for (i = 0; i < expectedInterfaces.size(); ++i)
+    {
+        ASSERT_EQ(interfaces[i],
+                  expectedInterfaces[i]);
+    }
+}
+
+TEST(PropertyGenTest, PropertiesSameContent)
+{
+    size_t i;
+    for (i = 0; i < expectedProperties.size(); ++i)
+    {
+        ASSERT_EQ(expectedProperties[i], properties[i]);
+    }
+}
+
+TEST(PropertyGenTest, GroupsSameContent)
+{
+    size_t i;
+    for (i = 0; i < expectedGroups.size(); ++i)
+    {
+        size_t j;
+        for (j = 0; j < expectedGroups[i].size(); ++j)
+        {
+            const auto& expectedIface = std::get<0>(expectedGroups[i][j]).get();
+            const auto& actualIface = std::get<0>(groups[i][j]).get();
+            ASSERT_EQ(expectedIface, actualIface);
+
+            const auto& expectedProperty = std::get<1>(expectedGroups[i][j]).get();
+            const auto& actualProperty = std::get<1>(groups[i][j]).get();
+            ASSERT_EQ(expectedProperty, actualProperty);
+
+            const auto& expectedMeta = std::get<1>(expectedGroups[i][j]).get();
+            const auto& actualMeta = std::get<1>(groups[i][j]).get();
+            ASSERT_EQ(expectedMeta, actualMeta);
+        }
+    }
+}
+
+TEST(PropertyGenTest, TypesSameContent)
+{
+    size_t i;
+    for (i = 0; i < expectedTypes.size(); ++i)
+    {
+        ASSERT_EQ(expectedTypes[i], types[i]);
+    }
+}
diff --git a/src/test/templates/propertygentest.mako.hpp b/src/test/templates/propertygentest.mako.hpp
new file mode 100644
index 0000000..16febd7
--- /dev/null
+++ b/src/test/templates/propertygentest.mako.hpp
@@ -0,0 +1,34 @@
+const std::array<std::string, ${len(meta)}> meta = {
+% for m in meta:
+    "${m.name}"s,
+% endfor
+};
+
+const std::array<std::string, ${len(interfaces)}> interfaces = {
+% for i in interfaces:
+    "${i.name}"s,
+% endfor
+};
+
+const std::array<std::string, ${len(propertynames)}> properties = {
+% for p in propertynames:
+    "${p.name}"s,
+% endfor
+};
+
+const std::array<GroupOfProperties, ${len(propertygroups)}> groups = {{
+% for g in propertygroups:
+    // ${g.name}
+    {
+        % for p in g.members:
+        Property{ interfaces[${p[0]}], properties[${p[1]}], meta[${p[2]}] },
+        % endfor
+    },
+% endfor
+}};
+
+const std::array<std::string, ${len(propertygroups)}> types = {
+% for g in propertygroups:
+    "${g.datatype}"s,
+% endfor
+};
diff --git a/src/test/yaml/propertygentest/groupone.yaml b/src/test/yaml/propertygentest/groupone.yaml
new file mode 100644
index 0000000..9ab9ace
--- /dev/null
+++ b/src/test/yaml/propertygentest/groupone.yaml
@@ -0,0 +1,23 @@
+- name: test property group
+  class: group
+  group: property
+  type: uint32
+  members:
+    - interface: xyz.openbmc_project.Test.Iface3
+      property: Foo
+      meta: property1
+    - interface: xyz.openbmc_project.Test.Iface2
+      property: Value
+      meta: property2
+
+- name: test property group 2
+  class: group
+  group: property
+  type: int32
+  members:
+    - interface: xyz.openbmc_project.Test.Iface3
+      property: Bar
+      meta: property1
+    - interface: xyz.openbmc_project.Test.Iface2
+      property: Foo
+      meta: property2
diff --git a/src/test/yaml/propertygentest/grouptwo.yaml b/src/test/yaml/propertygentest/grouptwo.yaml
new file mode 100644
index 0000000..4f2db02
--- /dev/null
+++ b/src/test/yaml/propertygentest/grouptwo.yaml
@@ -0,0 +1,26 @@
+- name: test property group
+  class: group
+  group: property
+  type: string
+  members:
+    - interface: xyz.openbmc_project.Test.Iface6
+      property: Foo
+      meta: property1
+    - interface: xyz.openbmc_project.Test.Iface1
+      property: Value
+      meta: property2
+
+- name: test property group 3
+  class: group
+  group: property
+  type: int32
+  members:
+    - interface: xyz.openbmc_project.Test.Iface3
+      property: Bar
+      meta: property1
+    - interface: xyz.openbmc_project.Test.Iface2
+      property: Value
+      meta: property2
+    - interface: xyz.openbmc_project.Test.Iface6
+      property: Baz
+      meta: property3