[cpp-sp] 02/02: Test of XML-based, nested property tree usage.

Scott Cantor cantor.2 at osu.edu
Tue Nov 19 20:35:37 UTC 2024


This is an automated email from the git hooks/post-receive script.

scantor pushed a commit to branch main
in repository cpp-sp.

View the commit online:
http://git.shibboleth.net/view/?p=cpp-sp.git;a=commit;h=3f7dc8feb820303e948cb8a1a3dc9ccaf5fbfaa1

commit 3f7dc8feb820303e948cb8a1a3dc9ccaf5fbfaa1
Author: Scott Cantor <cantor.2 at osu.edu>
AuthorDate: Tue Nov 19 15:35:18 2024 -0500

    Test of XML-based, nested property tree usage.
---
 shibsp/util/BoostPropertySet.cpp            |   4 +-
 shibsp/util/BoostPropertySet.h              |  26 ++++--
 shibsp/util/PropertySet.h                   |  20 ++---
 tests/Makefile.am                           |   3 +-
 tests/data/util/boostpropset/attributes.ini |   7 ++
 tests/data/util/boostpropset/tree.xml       |   6 ++
 tests/util/BoostPropertySetTests.cpp        | 130 ++++++++++++++++++++++++++++
 tests/util/PropertyTreeTests.cpp            |   4 +-
 8 files changed, 174 insertions(+), 26 deletions(-)

diff --git a/shibsp/util/BoostPropertySet.cpp b/shibsp/util/BoostPropertySet.cpp
index bab326f8..b0de0aa8 100644
--- a/shibsp/util/BoostPropertySet.cpp
+++ b/shibsp/util/BoostPropertySet.cpp
@@ -15,7 +15,7 @@
 /**
  * BoostPropertySet.cpp
  * 
- * DOM-based property set implementation.
+ * Boost propertytree-based property set implementation.
  */
 
 #include "internal.h"
@@ -45,7 +45,7 @@ PropertySet2::~PropertySet2()
 {
 }
 
-BoostPropertySet::BoostPropertySet() : m_parent(nullptr)
+BoostPropertySet::BoostPropertySet() : m_parent(nullptr), m_pt(nullptr)
 {
 }
 
diff --git a/shibsp/util/BoostPropertySet.h b/shibsp/util/BoostPropertySet.h
index ed1bb5fa..7188c8af 100644
--- a/shibsp/util/BoostPropertySet.h
+++ b/shibsp/util/BoostPropertySet.h
@@ -13,9 +13,9 @@
  */
 
 /**
- * @file shibsp/util/DOMPropertySet.h
+ * @file shibsp/util/BoostPropertySet.h
  * 
- * DOM-based property set implementation.
+ * Boost propertytree-based property set implementation.
  */
 
 #ifndef __shibsp_boostpropset_h__
@@ -30,18 +30,22 @@ namespace shibsp {
 
     /**
      * Boost property tree-based property set implementation.
+     * 
+     * <p>This implementation is generally suitable only for trees created
+     * by hand or that are parsed via one of the non-XML parsing methods.</p>
+     * 
+     * <p>The XML-based representation uses special "reserved" property node
+     * names for attributes and element content and can therefore not be used
+     * directly as a means of exposing the properties via this interface.</p>
      */
     class SHIBSP_API BoostPropertySet : public virtual PropertySet2
     {
     public:
         BoostPropertySet();
-        
         virtual ~BoostPropertySet();
 
-        const PropertySet2* getParent() const;
-        void setParent(const PropertySet2* parent);
         bool getBool(const char* name, bool defaultValue) const;
-        const char* getString(const char* name, const char* defaultValue) const;
+        const char* getString(const char* name, const char* defaultValue=nullptr) const;
         unsigned int getUnsignedInt(const char* name, unsigned int defaultValue) const;
         int getInt(const char* name, int defaultValue) const;
 
@@ -53,7 +57,17 @@ namespace shibsp {
          */
         void load(const boost::property_tree::ptree& pt, const char* unsetter=nullptr);
 
+    protected:
+        /**
+         * Installs a parent PropertySet to allow an inheritance relationship to a different instance.
+         * 
+         * @param parent the parent PropertySet to install
+         */
+        void setParent(const PropertySet2* parent);
+
     private:
+        const PropertySet2* getParent() const;
+
         const PropertySet2* m_parent;
         const boost::property_tree::ptree* m_pt;
 		std::set<std::string> m_unset;
diff --git a/shibsp/util/PropertySet.h b/shibsp/util/PropertySet.h
index e321cff2..fd74c2ce 100644
--- a/shibsp/util/PropertySet.h
+++ b/shibsp/util/PropertySet.h
@@ -15,7 +15,7 @@
 /**
  * @file shibsp/util/PropertySet.h
  * 
- * Interface to a generic set of typed properties or a DOM container of additional data.
+ * Interface to a generic set of typed properties.
  */
 
 #ifndef __shibsp_propset_h__
@@ -101,6 +101,10 @@ namespace shibsp {
     /**
      * Interface to a generic set of typed properties.
      * 
+     * <p>This new variant will be based on supporting a dotted path syntax to access
+     * "nested" sets of named properties, which used to be navigated explicitly with
+     * a hierarchy of child objects. That is now only one-way, down the tree.</p>
+     * 
      * TODO: This will replace the original interface and be renamed back to PropertySet
      * once code migration is completed.
      */
@@ -112,20 +116,6 @@ namespace shibsp {
     public:
         virtual ~PropertySet2();
 
-        /**
-         * Returns parent of this PropertySet, if any.
-         *
-         * @return the parent object, or nullptr
-         */
-        virtual const PropertySet2* getParent() const=0;
-
-        /**
-         * Establishes a "parent" PropertySet to supply inherited settings.
-         *
-         * @param parent    the parent PropertySet to use
-         */
-        virtual void setParent(const PropertySet2* parent)=0;
-
         /**
          * Returns a boolean-valued property.
          * 
diff --git a/tests/Makefile.am b/tests/Makefile.am
index b55b7b94..edf67c90 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -11,7 +11,8 @@ shibsptest_CXXFLAGS = \
 
 shibsptest_SOURCES = \
 	AgentTestSuite.cpp \
-	util/PropertyTreeTests.cpp
+	util/PropertyTreeTests.cpp \
+	util/BoostPropertySetTests.cpp
 
 shibsptest_LDADD = \
     $(top_builddir)/shibsp/libshibsp.la
diff --git a/tests/data/util/boostpropset/attributes.ini b/tests/data/util/boostpropset/attributes.ini
new file mode 100644
index 00000000..396d7cd5
--- /dev/null
+++ b/tests/data/util/boostpropset/attributes.ini
@@ -0,0 +1,7 @@
+[config]
+UseEnvironment = true
+#UseHeaders = true
+
+[mappings]
+foo =  bar
+bar =   baz
diff --git a/tests/data/util/boostpropset/tree.xml b/tests/data/util/boostpropset/tree.xml
new file mode 100644
index 00000000..6bfae97e
--- /dev/null
+++ b/tests/data/util/boostpropset/tree.xml
@@ -0,0 +1,6 @@
+<root foo="bar">
+    <one foo="baz" />
+    <one unset="foo">
+        <two />
+    </one>
+</root>
diff --git a/tests/util/BoostPropertySetTests.cpp b/tests/util/BoostPropertySetTests.cpp
new file mode 100644
index 00000000..e8e9e376
--- /dev/null
+++ b/tests/util/BoostPropertySetTests.cpp
@@ -0,0 +1,130 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * BoostPropertySetTests.cpp
+ *
+ * Unit tests for BoostPropertySet usage.
+ */
+
+#include "util/BoostPropertySet.h"
+
+#include <memory>
+#include <vector>
+#include <boost/test/unit_test.hpp>
+#include <boost/property_tree/ini_parser.hpp>
+#include <boost/property_tree/xml_parser.hpp>
+
+using namespace shibsp;
+using namespace std;
+namespace pt = boost::property_tree;
+
+#define DATA_PATH "data/util/boostpropset/"
+
+struct BPS_Fixture {
+    BPS_Fixture() : data_path(DATA_PATH) {}
+    string data_path;
+};
+
+BOOST_FIXTURE_TEST_CASE(BoostPropertySet_ini, BPS_Fixture)
+{
+    pt::ptree tree;
+    pt::read_ini(data_path + "attributes.ini", tree);
+
+    BoostPropertySet props;
+    props.load(tree);
+
+    BOOST_CHECK_EQUAL(props.getBool("config.UseEnvironment", false), true);
+    BOOST_CHECK_EQUAL(props.getBool("config.UseHeaders", false), false);
+
+    BOOST_CHECK_EQUAL(props.getString("mappings.foo"), "bar");
+    BOOST_CHECK_EQUAL(props.getString("mappings.bar"), "baz");
+
+    // Test invalid conversions.
+    BOOST_CHECK_EQUAL(props.getInt("mappings.foo", 42), 42);
+    BOOST_CHECK_EQUAL(props.getUnsignedInt("mappings.bar", 42), 42);
+}
+
+// Exposes setParent as public method for test.
+class TestBoostPropertySet : public virtual BoostPropertySet {
+public:
+    TestBoostPropertySet() {} 
+    virtual ~TestBoostPropertySet() {}
+
+    void setParent(const PropertySet2* parent) {
+        BoostPropertySet::setParent(parent);
+    }
+};
+
+BOOST_FIXTURE_TEST_CASE(BoostPropertySet_tree, BPS_Fixture)
+{
+    pt::ptree tree;
+    pt::read_xml(data_path + "tree.xml", tree);
+
+    // Holds the heap objects, and provides simple access to them.
+    // In a real scenario, there would be a mesh of "real" objects connected
+    // while exposing a PropertySet interface.
+    vector<unique_ptr<TestBoostPropertySet>> ones;
+    vector<unique_ptr<TestBoostPropertySet>> twos;
+
+    // Set up nested tree of PropertySets wrapped around each layer's <xmlattr> node.
+
+    const pt::ptree& root = tree.get_child("root");
+    TestBoostPropertySet rootset;
+    const boost::optional<const pt::ptree&> xmlattr = root.get_child_optional("<xmlattr>");
+    if (xmlattr) {
+        rootset.load(xmlattr.get(), "unset");
+    }
+
+    for (const pair<const string,pt::ptree>& child : root) {
+        if (child.first == "one") {
+            ones.push_back(make_unique<TestBoostPropertySet>());
+            const auto& one = ones.back();
+            const boost::optional<const pt::ptree&> xmlattr = child.second.get_child_optional("<xmlattr>");
+            if (xmlattr) {
+                one->load(xmlattr.get(), "unset");
+            }
+            one->setParent(&rootset);
+
+            for (const pair<const string,pt::ptree>& child2 : child.second) {
+                if (child2.first == "two") {
+                    twos.push_back(make_unique<TestBoostPropertySet>());
+                    const auto& two = twos.back();
+                    const boost::optional<const pt::ptree&> xmlattr = child2.second.get_child_optional("<xmlattr>");
+                    if (xmlattr) {
+                        two->load(xmlattr.get(), "unset");
+                    }
+                    two->setParent(one.get());
+                }
+            }
+        }
+    }
+
+    BOOST_CHECK_EQUAL(ones.size(), 2);
+    BOOST_CHECK_EQUAL(twos.size(), 1);
+    BOOST_CHECK_EQUAL(rootset.getString("foo"), "bar");
+    BOOST_CHECK_EQUAL(rootset.getString("<xmlattr>"), nullptr);
+    BOOST_CHECK_EQUAL(rootset.getString("one"), nullptr);
+
+    BOOST_CHECK_EQUAL(ones[0]->getString("foo"), "baz");
+    BOOST_CHECK_EQUAL(ones[0]->getString("<xmlattr>"), nullptr);
+
+    BOOST_CHECK_EQUAL(ones[1]->getString("foo", "zork"), "zork");
+    BOOST_CHECK_EQUAL(ones[1]->getString("<xmlattr>"), nullptr);
+    BOOST_CHECK_EQUAL(ones[1]->getString("two"), nullptr);
+
+    BOOST_CHECK_EQUAL(twos[0]->getString("unset"), "foo");
+    BOOST_CHECK_EQUAL(twos[0]->getString("foo"), nullptr);
+    BOOST_CHECK_EQUAL(twos[0]->getString("<xmlattr>"), nullptr);
+}
diff --git a/tests/util/PropertyTreeTests.cpp b/tests/util/PropertyTreeTests.cpp
index f42f8be5..9a5951e3 100644
--- a/tests/util/PropertyTreeTests.cpp
+++ b/tests/util/PropertyTreeTests.cpp
@@ -24,7 +24,7 @@
 using namespace std;
 namespace pt = boost::property_tree;
 
-#define DATA_PATH "data/propertytree/"
+#define DATA_PATH "data/util/propertytree/"
 
 struct PT_Fixture {
     PT_Fixture() : data_path(DATA_PATH) {}
@@ -41,7 +41,7 @@ BOOST_FIXTURE_TEST_CASE(PropertyTree_RequestMap_simple, PT_Fixture)
     const pt::ptree& requestMap = tree.get_child("RequestMap");
     BOOST_CHECK_EQUAL(requestMap.size(), 2);
 
-    for (const pair<string,pt::ptree>& child : requestMap) {
+    for (const pair<const string,pt::ptree>& child : requestMap) {
         BOOST_CHECK_EQUAL(child.first, "Host");
 
         BOOST_CHECK_GE(child.second.size(), 1);

-- 
To stop receiving notification emails like this one, please contact
the administrator of this repository.


More information about the commits mailing list