]> git.ipfire.org Git - thirdparty/kea.git/commitdiff
[#1077] migrate src/lib/yang to sysrepo 1.4
authorAndrei Pavel <andrei@isc.org>
Thu, 15 Jul 2021 12:21:27 +0000 (15:21 +0300)
committerTomek Mrugalski <tomek@isc.org>
Fri, 23 Jul 2021 10:45:36 +0000 (10:45 +0000)
48 files changed:
src/lib/testutils/log_utils.cc
src/lib/yang/pretests/sysrepo_setup_tests.cc
src/lib/yang/tests/adaptor_host_unittests.cc
src/lib/yang/tests/config_unittests.cc
src/lib/yang/tests/json_configs.h
src/lib/yang/tests/sysrepo_setup.h
src/lib/yang/tests/translator_class_unittests.cc
src/lib/yang/tests/translator_control_socket_unittests.cc
src/lib/yang/tests/translator_database_unittests.cc
src/lib/yang/tests/translator_host_unittests.cc
src/lib/yang/tests/translator_logger_unittests.cc
src/lib/yang/tests/translator_option_data_unittests.cc
src/lib/yang/tests/translator_option_def_unittests.cc
src/lib/yang/tests/translator_pd_pool_unittests.cc
src/lib/yang/tests/translator_pool_unittests.cc
src/lib/yang/tests/translator_shared_network_unittests.cc
src/lib/yang/tests/translator_subnet_unittests.cc
src/lib/yang/tests/translator_unittests.cc
src/lib/yang/tests/translator_utils_unittests.cc
src/lib/yang/tests/yang_configs.h
src/lib/yang/testutils/translator_test.cc
src/lib/yang/testutils/translator_test.h
src/lib/yang/translator.cc
src/lib/yang/translator.h
src/lib/yang/translator_class.cc
src/lib/yang/translator_class.h
src/lib/yang/translator_config.cc
src/lib/yang/translator_config.h
src/lib/yang/translator_control_socket.cc
src/lib/yang/translator_control_socket.h
src/lib/yang/translator_database.cc
src/lib/yang/translator_database.h
src/lib/yang/translator_host.cc
src/lib/yang/translator_host.h
src/lib/yang/translator_logger.cc
src/lib/yang/translator_logger.h
src/lib/yang/translator_option_data.cc
src/lib/yang/translator_option_data.h
src/lib/yang/translator_option_def.cc
src/lib/yang/translator_option_def.h
src/lib/yang/translator_pd_pool.cc
src/lib/yang/translator_pd_pool.h
src/lib/yang/translator_pool.cc
src/lib/yang/translator_pool.h
src/lib/yang/translator_shared_network.cc
src/lib/yang/translator_shared_network.h
src/lib/yang/translator_subnet.cc
src/lib/yang/translator_subnet.h

index 50523190384ef76aecbff0bb6a08654b1774b9d3..56b6d333d5b0367f5b0f53d556a3e8e9d6658c22 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2016-2020 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2016-2021 Internet Systems Consortium, Inc. ("ISC")
 //
 // This Source Code Form is subject to the terms of the Mozilla Public
 // License, v. 2.0. If a copy of the MPL was not distributed with this
@@ -57,8 +57,8 @@ bool LogContentTest::checkFile() {
     while (getline(file, line) && (i != exp_strings_.size())) {
         exp_line = exp_strings_[i];
         if (verbose_) {
-            cout << "Read line  :" << line << endl;
-            cout << "Looking for:" << exp_line << endl;
+            cout << "Read line  : " << line << endl;
+            cout << "Looking for: " << exp_line << endl;
         }
         i++;
         if (string::npos == line.find(exp_line)) {
index 3bd71595d4821742e83a2df8035f06aa3040ecd2..b1c514ad42a3ff1bcb7ddf4f451c9f30ce594b3d 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2018-2019 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2018-2021 Internet Systems Consortium, Inc. ("ISC")
 //
 // This Source Code Form is subject to the terms of the Mozilla Public
 // License, v. 2.0. If a copy of the MPL was not distributed with this
@@ -9,37 +9,34 @@
 #define KEATEST_MODULE
 #include <yang/yang_revisions.h>
 
-#ifndef HAVE_PRE_0_7_6_SYSREPO
 #include <sysrepo-cpp/Session.hpp>
-#else
-#include <sysrepo-cpp/Session.h>
-#endif
 
 #include <sstream>
 
 using namespace std;
-#ifndef HAVE_PRE_0_7_6_SYSREPO
 using namespace sysrepo;
-#endif
 using namespace isc::yang;
 
+using libyang::S_Context;
+using libyang::S_Module;
+
 const string REPOSITORY = SYSREPO_REPO;
 
 /// @brief Returns nicely formed error message if module is missing
 ///
 /// @param name name of the YANG module to complain about
-/// #param revision revision of the YANG module
+/// @param revision revision of the YANG module
 /// @return a text explaining what the problem is and how to fix it
 string missingModuleText(const string& name, const string& revision) {
     stringstream tmp;
     tmp << "ERROR: YANG module " << name << " is not installed." << endl
-        << "The environment is not suitable for running unit-tests." << endl
+        << "The environment is not suitable for running unit tests." << endl
         << "Please locate " << name << "@" << revision << ".yang, "
-        << "change to its directory and issue the following command:"
-        << endl << endl
-        << "# sysrepoctl -i -s " << REPOSITORY << "/yang "
-        << "-s . -g " << name << "@" << revision << ".yang" << endl
-        << endl << endl;
+        << "change to its directory and issue the following command:" << endl
+        << endl
+        << "sysrepoctl -i " << name << "@" << revision << ".yang" << endl
+        << endl
+        << endl;
     return (tmp.str());
 }
 
@@ -76,11 +73,11 @@ string badRevisionModuleText(const string& name, const string& expected,
 int main() {
     S_Connection conn;
     try {
-        conn.reset(new Connection("sysrepo setup check"));
+        conn = std::make_shared<Connection>();
     } catch (const sysrepo_exception& ex) {
-        cerr << "ERROR: Can't connect to sysrepo: " << ex.what() << endl;
-        cerr << "ERROR: Make sure the sysrepod daemon is running." << endl;
-        exit(-1);
+        cerr << "ERROR: Can't initialize sysrepo: " << ex.what() << endl;
+        cerr << "ERROR: Make sure you have the right permissions to the sysrepo repository." << endl;
+        return 1;
     }
 
     S_Session sess;
@@ -89,74 +86,46 @@ int main() {
     } catch (const sysrepo_exception& ex) {
         cerr << "ERROR: Can't establish a sysrepo session: "
              << ex.what() << endl;
-        exit(-2);
+        return 2;
     }
 
-    S_Yang_Schemas schemas;
+    vector<S_Module> modules;
     try {
-        schemas = sess->list_schemas();
+        S_Context context(sess->get_context());
+        modules = context->get_module_iter();
     } catch (const sysrepo_exception& ex) {
-        cerr << "ERROR: Can't list available schemas: " <<  ex.what() << endl;
-        exit(-3);
+        cerr << "ERROR: Can't retrieve available modules: " << ex.what() << endl;
+        return 3;
     }
 
-    map<string, bool> found;
-    map<string, string> got;
-    for (auto modrev : YANG_REVISIONS) {
-        found[modrev.first] = false;
-    }
-
-    for (size_t i = 0; i < schemas->schema_cnt(); ++i) {
-        string module = schemas->schema(i)->module_name();
-        if (YANG_REVISIONS.count(module)) {
-            found[module] = true;
-            if (!schemas->schema(i)->revision() ||
-                !schemas->schema(i)->revision()->revision()) {
-                got[module] = "none";
-            } else {
-                string rev = schemas->schema(i)->revision()->revision();
-                got[module] = rev;
-            }
+    std::unordered_map<std::string, std::string> installed_modules;
+    for (S_Module const& module : modules) {
+        if (!module->name()) {
+            cerr << "ERROR: module name is mangled" << endl;
+            return 4;
         }
-    }
-
-    int exit_code = 0;
-
-    for (auto modfnd : found) {
-        string rev = YANG_REVISIONS.at(modfnd.first);
-        if (!modfnd.second) {
-            if (exit_code > -4) {
-                exit_code = -4;
-            }
-            --exit_code;
-            cerr << missingModuleText(modfnd.first, rev);
-        } else if (rev != got[modfnd.first]) {
-            if (exit_code > -40) {
-                exit_code += -40;
-            } else {
-                exit_code += -10;
-            }
-            cerr << badRevisionModuleText(modfnd.first, rev, got[modfnd.first]);
+        string const name(module->name());
+        if (!module->rev() || !module->rev()->date()) {
+            cerr << "ERROR: module revision is mangled" << endl;
+            return 5;
         }
+        string const revision(module->rev()->date());
+        installed_modules.emplace(name, revision);
     }
 
-    try {
-        sess.reset();
-        conn.reset(new Connection("sysrepo setup check",
-                                  SR_CONN_DAEMON_REQUIRED));
-    } catch (const sysrepo_exception& ex) {
-        cerr <<"ERROR: Can't connect to sysrepo daemon: " <<ex.what() << endl
-             << endl
-             << "Sysrepo daemon is required or actions will be local to "
-             << "the local library instance." << endl;
-        cerr << "Please make sure the sysrepod daemon is running." << endl;
-        cerr << "The following command should do the trick:" << endl;
-        cerr << endl;
-        cerr << "$ sudo sysrepod" << endl;
-        cerr << endl;
-
-        exit_code -= 100;
+    for (auto const& kv : YANG_REVISIONS) {
+        std::string const& name(kv.first);
+        std::string const& revision(kv.second);
+        if (!installed_modules.count(name)) {
+            cerr << missingModuleText(name, revision);
+            return 6;
+        }
+        string const& expected_revision(installed_modules.at(name));
+        if (expected_revision != revision) {
+            cerr << badRevisionModuleText(name, expected_revision, revision);
+            return 7;
+        }
     }
 
-    exit(exit_code);
+    return 0;
 }
index 0e7f91c3b3d4d27c42a486d3b1910dde9952252c..dbed7cb472ff4818770478164e9afa7ab1a57020 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2018 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2018-2021 Internet Systems Consortium, Inc. ("ISC")
 //
 // This Source Code Form is subject to the terms of the Mozilla Public
 // License, v. 2.0. If a copy of the MPL was not distributed with this
@@ -6,6 +6,7 @@
 
 #include <config.h>
 
+#include <testutils/gtest_utils.h>
 #include <yang/adaptor_host.h>
 
 #include <gtest/gtest.h>
@@ -115,4 +116,4 @@ TEST(AdaptorHostTest, notQuoted) {
     EXPECT_EQ("73:6f:6d:65:22:76:61:6c:75:65", id->stringValue());
 }
 
-}; // end of anonymous namespace
+}  // namespace
index f749a3060a4b59ba62809df15fd7e9394f087a86..11b1c34c9189cef41c6edf1807602ae7731ffab5 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2018-2020 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2018-2021 Internet Systems Consortium, Inc. ("ISC")
 //
 // This Source Code Form is subject to the terms of the Mozilla Public
 // License, v. 2.0. If a copy of the MPL was not distributed with this
 #include <testutils/user_context_utils.h>
 #include <yang/translator_config.h>
 #include <yang/yang_models.h>
-#include <yang/tests/yang_configs.h>
 #include <yang/tests/json_configs.h>
+#include <yang/tests/yang_configs.h>
+#include <yang/tests/sysrepo_setup.h>
+
 #include <boost/algorithm/string.hpp>
+
 #include <gtest/gtest.h>
+
 #include <iostream>
 
 using namespace std;
@@ -21,9 +25,7 @@ using namespace isc;
 using namespace isc::data;
 using namespace isc::yang;
 using namespace isc::yang::test;
-#ifndef HAVE_PRE_0_7_6_SYSREPO
 using namespace sysrepo;
-#endif
 
 namespace {
 
@@ -50,39 +52,38 @@ std::string generateDiff(std::string, std::string) {
 }
 #endif
 
-
 /// @brief Test Fixture class for Yang <-> JSON configs.
 class ConfigTest : public ::testing::Test {
 public:
+    virtual ~ConfigTest() = default;
 
-    /// @brief Constructor.
-    ConfigTest() {
-        createSession();
+    void SetUp() override {
+        SysrepoSetup::cleanSharedMemory();
+        connection_ = std::make_shared<Connection>();
+        session_.reset(new Session(connection_, SR_DS_CANDIDATE));
+        translator_.reset(new TranslatorBasic(session_, model_));
+        cleanModelData();
     }
 
-    /// @brief Virtual destructor.
-    virtual ~ConfigTest() {
+    void TearDown() override {
+        cleanModelData();
+        translator_.reset();
         session_.reset();
         connection_.reset();
-        model_.clear();
+        SysrepoSetup::cleanSharedMemory();
     }
 
-    /// @brief Set model.
-    ///
-    /// @param model The model name.
-    void setModel(const string model) {
-        model_ = model;
-    }
-
-    /// @brief Create session.
-    void createSession() {
-        connection_.reset(new Connection("configs unittests"));
-        session_.reset(new Session(connection_, SR_DS_CANDIDATE));
+    void cleanModelData() {
+        std::string toplevel_node("config");
+        if (model_ == IETF_DHCPV6_SERVER) {
+            toplevel_node = "server";
+        }
+        translator_->delItem("/" + model_ + ":" + toplevel_node);
     }
 
     /// @brief Reset session.
     void resetSession() {
-        session_.reset(new Session(connection_, SR_DS_CANDIDATE));
+        SetUp();
     }
 
     /// @brief Loads YANG configuration from specified tree.
@@ -105,7 +106,7 @@ public:
     ///
     /// @param config The JSON tree to load in textual format.
     void load(const string& config) {
-        ConstElementPtr json;
+        ElementPtr json;
         ASSERT_NO_THROW(json = Element::fromJSON(config));
         load(json);
     }
@@ -192,13 +193,28 @@ public:
 
     /// @brief The sysrepo session.
     S_Session session_;
+
+    std::unique_ptr<TranslatorBasic> translator_;
 };
 
-// Check empty config with ietf-dhcpv6-server model.
-TEST_F(ConfigTest, emptyIetf6) {
-    // First set the model.
-    setModel(IETF_DHCPV6_SERVER);
+struct ConfigTestKeaV4 : ConfigTest {
+    ConfigTestKeaV4() {
+        model_ = KEA_DHCP4_SERVER;
+    }
+};
+struct ConfigTestKeaV6 : ConfigTest {
+    ConfigTestKeaV6() {
+        model_ = KEA_DHCP6_SERVER;
+    }
+};
+struct ConfigTestIetfV6 : ConfigTest {
+    ConfigTestIetfV6() {
+        model_ = IETF_DHCPV6_SERVER;
+    }
+};
 
+// Check empty config with ietf-dhcpv6-server model.
+TEST_F(ConfigTestIetfV6, emptyIetf6) {
     YRTree tree;
     ASSERT_NO_THROW(load(tree));
     EXPECT_TRUE(verify(tree));
@@ -211,45 +227,36 @@ TEST_F(ConfigTest, emptyIetf6) {
 }
 
 // Check empty config with kea-dhcp4-server:config model.
-TEST_F(ConfigTest, emptyKeaDhcp4) {
-    // First set the model.
-    setModel(KEA_DHCP4_SERVER);
-
+TEST_F(ConfigTestKeaV4, emptyKeaDhcp4) {
     YRTree tree;
     ASSERT_NO_THROW(load(tree));
-    EXPECT_TRUE(verify(tree));
+    EXPECT_TRUE(verify(emptyTreeKeaDhcp4));
 
     ConstElementPtr json = Element::fromJSON(emptyJson4);
     EXPECT_TRUE(verify(json));
     ASSERT_NO_THROW(load(json));
     EXPECT_TRUE(verify(emptyJson4));
-    EXPECT_TRUE(verify(tree));
+    EXPECT_TRUE(verify(emptyTreeKeaDhcp4));
 }
 
 // Check empty config with kea-dhcp6-server:config model.
-TEST_F(ConfigTest, emptyKeaDhcp6) {
-    // First set the model.
-    setModel(KEA_DHCP6_SERVER);
-
+TEST_F(ConfigTestKeaV6, emptyKeaDhcp6) {
     YRTree tree;
     ASSERT_NO_THROW(load(tree));
-    EXPECT_TRUE(verify(tree));
+    EXPECT_TRUE(verify(emptyTreeKeaDhcp6));
 
     ConstElementPtr json = Element::fromJSON(emptyJson6);
     EXPECT_TRUE(verify(json));
     ASSERT_NO_THROW(load(json));
     EXPECT_TRUE(verify(emptyJson6));
-    EXPECT_TRUE(verify(tree));
+    EXPECT_TRUE(verify(emptyTreeKeaDhcp6));
 }
 
 // Check subnet with two pools with ietf-dhcpv6-server model.
 // Validation will fail because the current model has a vendor-info
 // container with a mandatory ent-num leaf and no presence flag,
 // and of course the candidate YANG tree has nothing for this.
-TEST_F(ConfigTest, subnetTwoPoolsIetf6) {
-    // First set the model.
-    setModel(subnetTwoPoolsModelIetf6);
-
+TEST_F(ConfigTestIetfV6, subnetTwoPoolsIetf6) {
     ASSERT_NO_THROW(load(subnetTwoPoolsTreeIetf6));
     EXPECT_TRUE(verify(subnetTwoPoolsJson6));
 
@@ -258,16 +265,12 @@ TEST_F(ConfigTest, subnetTwoPoolsIetf6) {
     ASSERT_NO_THROW(load(subnetTwoPoolsJson6));
     EXPECT_TRUE(verify(subnetTwoPoolsTreeIetf6));
 
-    cout << "validation is expected to fail: please ignore messages" << endl;
     EXPECT_FALSE(validate());
 }
 
 // Check subnet with a pool and option data lists with
 // kea-dhcp4-server:config model.
-TEST_F(ConfigTest, subnetOptionsKeaDhcp4) {
-    // First set the model.
-    setModel(subnetOptionsModelKeaDhcp4);
-
+TEST_F(ConfigTestKeaV4, subnetOptionsKeaDhcp4) {
     ASSERT_NO_THROW(load(subnetOptionsTreeKeaDhcp4));
     EXPECT_TRUE(verify(subnetOptionsJson4));
 
@@ -281,10 +284,7 @@ TEST_F(ConfigTest, subnetOptionsKeaDhcp4) {
 
 // Check subnet with a pool and option data lists with
 // kea-dhcp6-server:config model.
-TEST_F(ConfigTest, subnetOptionsKeaDhcp6) {
-    // First set the model.
-    setModel(subnetOptionsModelKeaDhcp6);
-
+TEST_F(ConfigTestKeaV6, subnetOptionsKeaDhcp6) {
     ASSERT_NO_THROW(load(subnetOptionsTreeKeaDhcp6));
     EXPECT_TRUE(verify(subnetOptionsJson6));
 
@@ -297,10 +297,7 @@ TEST_F(ConfigTest, subnetOptionsKeaDhcp6) {
 }
 
 // Check with timers.
-TEST_F(ConfigTest, subnetTimersIetf6) {
-    // First set the model.
-    setModel(subnetTimersModel);
-
+TEST_F(ConfigTestIetfV6, subnetTimersIetf6) {
     ASSERT_NO_THROW(load(subnetTimersIetf6));
     EXPECT_TRUE(verify(subnetTimersJson6));
 
@@ -311,10 +308,7 @@ TEST_F(ConfigTest, subnetTimersIetf6) {
 }
 
 // Check a ietf-dhcpv6-server configuration which validates.
-TEST_F(ConfigTest, validateIetf6) {
-    // First set the model.
-    setModel(validModelIetf6);
-
+TEST_F(ConfigTestIetfV6, validateIetf6) {
     ASSERT_NO_THROW(load(validTreeIetf6));
     EXPECT_TRUE(verify(validTreeIetf6));
 
@@ -328,10 +322,7 @@ TEST_F(ConfigTest, validateIetf6) {
 }
 
 // Check Kea4 example files.
-TEST_F(ConfigTest, examples4) {
-    // First set the model.
-    setModel(KEA_DHCP4_SERVER);
-
+TEST_F(ConfigTestKeaV4, examples4) {
     vector<string> examples = {
         "advanced.json",
         "all-keys-netconf.json",
@@ -369,10 +360,7 @@ TEST_F(ConfigTest, examples4) {
 }
 
 // Check Kea6 example files.
-TEST_F(ConfigTest, examples6) {
-    // First set the model.
-    setModel(KEA_DHCP6_SERVER);
-
+TEST_F(ConfigTestKeaV6, examples6) {
     vector<string> examples = {
         "advanced.json",
         "all-keys-netconf.json",
@@ -414,10 +402,7 @@ TEST_F(ConfigTest, examples6) {
 }
 
 // Check the example in the design document.
-TEST_F(ConfigTest, designExample) {
-    // First set the model.
-    setModel(designExampleModel);
-
+TEST_F(ConfigTestIetfV6, designExample) {
     ASSERT_NO_THROW(load(designExampleTree));
     EXPECT_TRUE(verify(designExampleJson));
 
@@ -427,4 +412,4 @@ TEST_F(ConfigTest, designExample) {
     EXPECT_TRUE(verify(designExampleTree));
 }
 
-}; // end of anonymous namespace
+}  // namespace
index 032aef1cb7f259f742bc82b51bc3ed1390bfacba..1f7e4a40e7732157895f3e7a117a88b1922d9035 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2018 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2018-2021 Internet Systems Consortium, Inc. ("ISC")
 //
 // This Source Code Form is subject to the terms of the Mozilla Public
 // License, v. 2.0. If a copy of the MPL was not distributed with this
@@ -155,7 +155,6 @@ const std::string designExampleJson =
     "        \"id\": 1,\n"
     "        \"subnet\": \"2001:db8:20:b00::/56\",\n"
     "        \"user-context\": { \"description\": \"example\" },\n"
-    "        \"pools\": [ ],\n"
     "        \"pd-pools\": [\n"
     "          {\n"
     "            \"prefix\": \"2001:db8:20:b00::\",\n"
@@ -168,8 +167,8 @@ const std::string designExampleJson =
     "  }\n"
     "}";
 
-}; // end of namespace isc::yang::test
-}; // end of namespace isc::yang
-}; // end of namespace isc
+}  // namespace test
+}  // namespace yang
+}  // namespace isc
 
 #endif // ISC_JSON_CONFIGS_H
index 855431f4118a024aa1ab38135240f7496b6d4f8d..8b62084d015ba9c0641aaaf4a47ce6f1bbf81044 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2018 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2018-2021 Internet Systems Consortium, Inc. ("ISC")
 //
 // This Source Code Form is subject to the terms of the Mozilla Public
 // License, v. 2.0. If a copy of the MPL was not distributed with this
@@ -9,68 +9,65 @@
 
 #include <config.h>
 
+#include <testutils/gtest_utils.h>
 #include <yang/translator.h>
+#include <yang/yang_models.h>
+
 #include <gtest/gtest.h>
 
 namespace isc {
 namespace yang {
 namespace test {
 
+struct SysrepoSetup {
+    static void cleanSharedMemory() {
+        system("rm -rf /dev/shm/sr_*");
+        system("rm -rf /dev/shm/srsub_*");
+    }
+};
+
 /// @brief Test Fixture template for translator tests.
 ///
 /// @tparam Name The name of the translator to test.
 /// @tparam Type The type of the translator to test.
-template<char const* Name, typename Type>
+template<char const* Name, typename translator_t>
 class GenericTranslatorTest : public ::testing::Test {
 public:
+    virtual ~GenericTranslatorTest() = default;
 
-    /// @brief Constructor.
-    GenericTranslatorTest() : conn_(), sess_(), t_obj_() { }
-
-    /// @brief useModel
-    ///
-    /// Open a sysrepo session and create a translator object using
-    /// the given model.
-    ///
-    /// @param model The model to use.
-    void useModel(std::string model) {
-        std::string full_name =
-            "translator " + std::string(Name) + " unittests";
-#ifndef HAVE_PRE_0_7_6_SYSREPO
-        conn_.reset(new sysrepo::Connection(full_name.c_str()));
+    void SetUp() override {
+        SysrepoSetup::cleanSharedMemory();
+        conn_.reset(new sysrepo::Connection());
         sess_.reset(new sysrepo::Session(conn_, SR_DS_CANDIDATE));
-#else
-        conn_.reset(new Connection(full_name.c_str()));
-        sess_.reset(new Session(conn_, SR_DS_CANDIDATE));
-#endif
-        EXPECT_NO_THROW(t_obj_.reset(new Type(sess_, model)));
+        t_obj_.reset(new translator_t(sess_, model_));
+        cleanModelData();
     }
 
-    /// @brief Destructor.
-    ///
-    /// Destroy all objects.
-    virtual ~GenericTranslatorTest() {
+    void TearDown() override {
+        cleanModelData();
         t_obj_.reset();
         sess_.reset();
         conn_.reset();
+        SysrepoSetup::cleanSharedMemory();
+    }
+
+    void cleanModelData() {
+        std::string toplevel_node("config");
+        if (model_ == IETF_DHCPV6_SERVER) {
+            toplevel_node = "server";
+        }
+        t_obj_->delItem("/" + model_ + ":" + toplevel_node);
     }
 
     /// @brief Sysrepo connection.
-#ifndef HAVE_PRE_0_7_6_SYSREPO
     sysrepo::S_Connection conn_;
-#else
-    S_Connection conn_;
-#endif
 
     /// @brief Sysrepo session.
-#ifndef HAVE_PRE_0_7_6_SYSREPO
     sysrepo::S_Session sess_;
-#else
-    S_Session sess_;
-#endif
 
     /// @brief Shared pointer to the transaction object.
-    boost::shared_ptr<Type> t_obj_;
+    boost::shared_ptr<translator_t> t_obj_;
+    std::string model_;
 };
 
 } // namespace test
index 30191b259c0c54366b17d6f791a2d78ef389684d..3dcb518541e9ac0824bf641640134213ecc798dd 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2018 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2018-2021 Internet Systems Consortium, Inc. ("ISC")
 //
 // This Source Code Form is subject to the terms of the Mozilla Public
 // License, v. 2.0. If a copy of the MPL was not distributed with this
@@ -18,9 +18,7 @@ using namespace isc;
 using namespace isc::data;
 using namespace isc::yang;
 using namespace isc::yang::test;
-#ifndef HAVE_PRE_0_7_6_SYSREPO
 using namespace sysrepo;
-#endif
 
 namespace {
 
@@ -28,22 +26,28 @@ namespace {
 extern char const client_classes[] = "client classes";
 
 /// @brief Test fixture class for @ref TranslatorClasses.
-class TranslatorClassesTest :
+class TranslatorClassesTestv4 :
     public GenericTranslatorTest<client_classes, TranslatorClasses> {
 public:
 
     /// Constructor.
-    TranslatorClassesTest() { }
+    TranslatorClassesTestv4() {
+        model_ = KEA_DHCP4_SERVER;
+    }
+};
+class TranslatorClassesTestv6 :
+    public GenericTranslatorTest<client_classes, TranslatorClasses> {
+public:
 
-    /// Destructor (does nothing).
-    virtual ~TranslatorClassesTest() { }
+    /// Constructor.
+    TranslatorClassesTestv6() {
+        model_ = KEA_DHCP6_SERVER;
+    }
 };
 
 // This test verifies that an empty client class list can be properly
 // translated from YANG to JSON.
-TEST_F(TranslatorClassesTest, getEmpty) {
-    useModel(KEA_DHCP4_SERVER);
-
+TEST_F(TranslatorClassesTestv4, getEmpty) {
     // Get the client class list and check if it is empty.
     const string& xpath = "/kea-dhcp4-server:config";
     ConstElementPtr classes;
@@ -53,9 +57,7 @@ TEST_F(TranslatorClassesTest, getEmpty) {
 
 // This test verifies that one client class can be properly translated
 // from YANG to JSON.
-TEST_F(TranslatorClassesTest, get) {
-    useModel(KEA_DHCP6_SERVER);
-
+TEST_F(TranslatorClassesTestv6, get) {
     // Create the client class.
     const string& xpath = "/kea-dhcp6-server:config";
     const string& xclass = xpath + "/client-class[name='foo']";
@@ -83,9 +85,7 @@ TEST_F(TranslatorClassesTest, get) {
 
 // This test verifies that an empty client class list can be properly
 // translated from JSON to YANG.
-TEST_F(TranslatorClassesTest, setEmpty) {
-    useModel(KEA_DHCP4_SERVER);
-
+TEST_F(TranslatorClassesTestv4, setEmpty) {
     // Set empty list.
     const string& xpath = "/kea-dhcp4-server:config";
     ConstElementPtr classes = Element::createList();
@@ -95,18 +95,11 @@ TEST_F(TranslatorClassesTest, setEmpty) {
     classes.reset();
     EXPECT_NO_THROW(classes = t_obj_->getClasses(xpath));
     EXPECT_FALSE(classes);
-
-    // Check that the tree representation is empty.
-    S_Tree tree;
-    EXPECT_NO_THROW(tree = sess_->get_subtree("/kea-dhcp4-server:config"));
-    EXPECT_FALSE(tree);
 }
 
 // This test verifies that one client class can be properly translated
 // from JSON to YANG.
-TEST_F(TranslatorClassesTest, set) {
-    useModel(KEA_DHCP6_SERVER);
-
+TEST_F(TranslatorClassesTestv6, set) {
     // Set one client class.
     const string& xpath = "/kea-dhcp6-server:config";
     ElementPtr classes = Element::createList();
@@ -125,24 +118,8 @@ TEST_F(TranslatorClassesTest, set) {
     ASSERT_EQ(1, got->size());
     EXPECT_TRUE(cclass->equals(*got->get(0)));
 
-    // Check the tree representation.
-    S_Tree tree;
-    EXPECT_NO_THROW(tree = sess_->get_subtree("/kea-dhcp6-server:config"));
-    ASSERT_TRUE(tree);
-    string expected =
-        "kea-dhcp6-server:config (container)\n"
-        " |\n"
-        " -- client-class (list instance)\n"
-        "     |\n"
-        "     -- name = foo\n"
-        "     |\n"
-        "     -- test = ''==''\n"
-        "     |\n"
-        "     -- only-if-required = false\n";
-    EXPECT_EQ(expected, tree->to_string(100));
-
     // Check it validates.
     EXPECT_NO_THROW(sess_->validate());
 }
 
-}; // end of anonymous namespace
+}  // namespace
index 5ceef861b4dcb6a93765cd29d890b6b85e26e545..8c7d4602a892158ca3e0073618c95033486db65d 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2018 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2018-2021 Internet Systems Consortium, Inc. ("ISC")
 //
 // This Source Code Form is subject to the terms of the Mozilla Public
 // License, v. 2.0. If a copy of the MPL was not distributed with this
@@ -17,9 +17,7 @@ using namespace isc;
 using namespace isc::data;
 using namespace isc::yang;
 using namespace isc::yang::test;
-#ifndef HAVE_PRE_0_7_6_SYSREPO
 using namespace sysrepo;
-#endif
 
 namespace {
 
@@ -27,22 +25,43 @@ namespace {
 extern char const control_socket[] = "control socket";
 
 /// @brief Test fixture class for @ref TranslatorControlSocket.
-class TranslatorControlSocketTest :
+class TranslatorControlSocketTestv4 :
     public GenericTranslatorTest<control_socket, TranslatorControlSocket> {
 public:
 
     /// Constructor.
-    TranslatorControlSocketTest() { }
+    TranslatorControlSocketTestv4() {
+        model_ = KEA_DHCP4_SERVER;
+    }
 
-    /// Destructor (does nothing).
-    virtual ~TranslatorControlSocketTest() { }
+    virtual ~TranslatorControlSocketTestv4() = default;
+};
+class TranslatorControlSocketTestv6 :
+    public GenericTranslatorTest<control_socket, TranslatorControlSocket> {
+public:
+
+    /// Constructor.
+    TranslatorControlSocketTestv6() {
+        model_ = KEA_DHCP6_SERVER;
+    }
+
+    virtual ~TranslatorControlSocketTestv6() = default;
+};
+class TranslatorControlSocketTestCtrlAgent :
+    public GenericTranslatorTest<control_socket, TranslatorControlSocket> {
+public:
+
+    /// Constructor.
+    TranslatorControlSocketTestCtrlAgent() {
+        model_ = KEA_CTRL_AGENT;
+    }
+
+    virtual ~TranslatorControlSocketTestCtrlAgent() = default;
 };
 
 // This test verifies that an empty control socket can be properly
 // translated from YANG to JSON.
-TEST_F(TranslatorControlSocketTest, getEmpty) {
-    useModel(KEA_DHCP4_SERVER);
-
+TEST_F(TranslatorControlSocketTestv4, getEmpty) {
     // Get empty.
     const string& xpath = "/kea-dhcp4-server:config/control-socket";
     ConstElementPtr sock;
@@ -52,9 +71,7 @@ TEST_F(TranslatorControlSocketTest, getEmpty) {
 
 // This test verifies that a not empty control socket can be properly
 // translated from YANG to JSON.
-TEST_F(TranslatorControlSocketTest, get) {
-    useModel(KEA_DHCP6_SERVER);
-
+TEST_F(TranslatorControlSocketTestv6, get) {
     // Set a value.
     const string& xpath = "/kea-dhcp6-server:config/control-socket";
     const string& xname = xpath + "/socket-name";
@@ -88,9 +105,7 @@ TEST_F(TranslatorControlSocketTest, get) {
 
 // This test verifies that a not empty control socket can be properly
 // translated from JSON to YANG.
-TEST_F(TranslatorControlSocketTest, set) {
-    useModel(KEA_CTRL_AGENT);
-
+TEST_F(TranslatorControlSocketTestCtrlAgent, set) {
     // Set a value.
     const string& xpath =
         "/kea-ctrl-agent:config/control-sockets/socket[server-type='dhcp4']/control-socket";
@@ -129,9 +144,7 @@ TEST_F(TranslatorControlSocketTest, set) {
 
 // This test verifies that an empty control socket can be properly
 // translated from JSON to YANG.
-TEST_F(TranslatorControlSocketTest, setEmpty) {
-    useModel(KEA_DHCP4_SERVER);
-
+TEST_F(TranslatorControlSocketTestv4, setEmpty) {
     // Set a value.
     const string& xpath = "/kea-dhcp4-server:config/control-socket";
     const string& xname = xpath + "/socket-name";
@@ -143,14 +156,21 @@ TEST_F(TranslatorControlSocketTest, setEmpty) {
     EXPECT_NO_THROW(sess_->set_item(xtype.c_str(), s_type));
     S_Val s_context(new Val("{ \"foo\": 1 }"));
     EXPECT_NO_THROW(sess_->set_item(xcontext.c_str(), s_context));
+    sess_->apply_changes();
+
+    // Get it back.
+    ConstElementPtr sock;
+    EXPECT_NO_THROW(sock = t_obj_->getControlSocket(xpath));
+    ASSERT_TRUE(sock);
+    EXPECT_EQ(sock->str(),
+        R"({ "socket-name": "/tmp/kea.sock", "socket-type": "unix", "user-context": { "foo": 1 } })");
 
     // Reset to empty.
-    ASSERT_NO_THROW(t_obj_->setControlSocket(xpath, ConstElementPtr()));
+    EXPECT_NO_THROW(t_obj_->setControlSocket(xpath, ConstElementPtr()));
 
     // Get it back.
-    ConstElementPtr sock;
     EXPECT_NO_THROW(sock = t_obj_->getControlSocket(xpath));
     EXPECT_FALSE(sock);
 }
 
-}; // end of anonymous namespace
+}  // namespace
index bf71051a038057e38a7c6fe3fe7f87a3fc75fbfb..a279ea1d18c7a62581b62ca41296f1f54a1a2126 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2018-2019 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2018-2021 Internet Systems Consortium, Inc. ("ISC")
 //
 // This Source Code Form is subject to the terms of the Mozilla Public
 // License, v. 2.0. If a copy of the MPL was not distributed with this
@@ -17,9 +17,7 @@ using namespace isc;
 using namespace isc::data;
 using namespace isc::yang;
 using namespace isc::yang::test;
-#ifndef HAVE_PRE_0_7_6_SYSREPO
 using namespace sysrepo;
-#endif
 
 namespace {
 
@@ -27,22 +25,29 @@ namespace {
 extern char const database_access[] = "database access";
 
 /// @brief Test fixture class for @ref TranslatorDatabase.
-class TranslatorDatabaseTest :
+class TranslatorDatabaseTestv4 :
     public GenericTranslatorTest<database_access, TranslatorDatabase> {
 public:
+    TranslatorDatabaseTestv4() {
+        model_ = KEA_DHCP4_SERVER;
+    }
 
-    /// Constructor.
-    TranslatorDatabaseTest() { }
+    virtual ~TranslatorDatabaseTestv4() = default;
+};
+
+class TranslatorDatabaseTestv6 :
+    public GenericTranslatorTest<database_access, TranslatorDatabase> {
+public:
+    TranslatorDatabaseTestv6() {
+        model_ = KEA_DHCP6_SERVER;
+    }
 
-    /// Destructor (does nothing).
-    virtual ~TranslatorDatabaseTest() { }
+    virtual ~TranslatorDatabaseTestv6() = default;
 };
 
 // This test verifies that an empty database can be properly
 // translated from YANG to JSON.
-TEST_F(TranslatorDatabaseTest, getEmpty) {
-    useModel(KEA_DHCP4_SERVER);
-
+TEST_F(TranslatorDatabaseTestv4, getEmpty) {
     // Get empty.
     const string& xpath = "/kea-dhcp4-server:config/lease-database";
     ConstElementPtr database;
@@ -52,9 +57,7 @@ TEST_F(TranslatorDatabaseTest, getEmpty) {
 
 // This test verifies that a database can be properly
 // translated from YANG to JSON.
-TEST_F(TranslatorDatabaseTest, get) {
-    useModel(KEA_DHCP4_SERVER);
-
+TEST_F(TranslatorDatabaseTestv4, get) {
     // Set a value.
     const string& xpath = "/kea-dhcp4-server:config/lease-database";
     const string& xtype = xpath + "/database-type";
@@ -62,11 +65,7 @@ TEST_F(TranslatorDatabaseTest, get) {
     S_Val s_type(new Val("memfile"));
     EXPECT_NO_THROW(sess_->set_item(xtype.c_str(), s_type));
     uint32_t li = 3600;
-#ifdef HAVE_POST_0_7_7_SYSREPO
     S_Val s_interval(new Val(li));
-#else
-    S_Val s_interval(new Val(li, SR_UINT32_T));
-#endif
     EXPECT_NO_THROW(sess_->set_item(xinterval.c_str(), s_interval));
 
     // Get empty.
@@ -86,9 +85,7 @@ TEST_F(TranslatorDatabaseTest, get) {
 
 // This test verifies that a database can be properly
 // translated from JSON to YANG.
-TEST_F(TranslatorDatabaseTest, set) {
-    useModel(KEA_DHCP4_SERVER);
-
+TEST_F(TranslatorDatabaseTestv4, set) {
     // Set a value.
     const string& xpath = "/kea-dhcp4-server:config/lease-database";
     ElementPtr database = Element::createMap();
@@ -114,9 +111,7 @@ TEST_F(TranslatorDatabaseTest, set) {
 
 // This test verifies that an empty database can be properly
 // translated from JSON to YANG.
-TEST_F(TranslatorDatabaseTest, setEmpty) {
-    useModel(KEA_DHCP4_SERVER);
-
+TEST_F(TranslatorDatabaseTestv4, setEmpty) {
     // Set a value.
     const string& xpath = "/kea-dhcp4-server:config/lease-database";
     const string& xtype = xpath + "/database-type";
@@ -124,12 +119,9 @@ TEST_F(TranslatorDatabaseTest, setEmpty) {
     S_Val s_type(new Val("memfile"));
     EXPECT_NO_THROW(sess_->set_item(xtype.c_str(), s_type));
     uint32_t li = 3600;
-#ifdef HAVE_POST_0_7_7_SYSREPO
     S_Val s_interval(new Val(li));
-#else
-    S_Val s_interval(new Val(li, SR_UINT32_T));
-#endif
     EXPECT_NO_THROW(sess_->set_item(xinterval.c_str(), s_interval));
+    sess_->apply_changes();
 
     // Reset to empty.
     ASSERT_NO_THROW(t_obj_->setDatabase(xpath, ConstElementPtr()));
@@ -144,22 +136,29 @@ TEST_F(TranslatorDatabaseTest, setEmpty) {
 extern char const database_accesses[] = "database accesses";
 
 /// @brief Test fixture class for @ref TranslatorDatabases.
-class TranslatorDatabasesTest :
+class TranslatorDatabasesTestv4 :
     public GenericTranslatorTest<database_accesses, TranslatorDatabases> {
 public:
 
     /// Constructor.
-    TranslatorDatabasesTest() { }
+    TranslatorDatabasesTestv4() {
+        model_ = KEA_DHCP4_SERVER;
+    }
+};
 
-    /// Destructor (does nothing).
-    virtual ~TranslatorDatabasesTest() { }
+class TranslatorDatabasesTestv6 :
+    public GenericTranslatorTest<database_accesses, TranslatorDatabases> {
+public:
+
+    /// Constructor.
+    TranslatorDatabasesTestv6() {
+        model_ = KEA_DHCP6_SERVER;
+    }
 };
 
 // This test verifies that an empty database list can be properly
 // translated from YANG to JSON.
-TEST_F(TranslatorDatabasesTest, getEmpty) {
-    useModel(KEA_DHCP6_SERVER);
-
+TEST_F(TranslatorDatabasesTestv6, getEmpty) {
     // Get empty.
     const string& xpath = "/kea-dhcp6-server:config/hosts-database";
     ConstElementPtr databases;
@@ -169,9 +168,7 @@ TEST_F(TranslatorDatabasesTest, getEmpty) {
 
 // This test verifies that a database list can be properly
 // translated from YANG to JSON.
-TEST_F(TranslatorDatabasesTest, get) {
-    useModel(KEA_DHCP4_SERVER);
-
+TEST_F(TranslatorDatabasesTestv4, get) {
     // Set a value.
     const string& xpath = "/kea-dhcp4-server:config/hosts-database";
     const string& xdatabase = xpath + "[database-type='mysql']";
@@ -189,11 +186,7 @@ TEST_F(TranslatorDatabasesTest, get) {
     S_Val s_host(new Val("localhost"));
     EXPECT_NO_THROW(sess_->set_item(xhost.c_str(), s_host));
     uint16_t mport = 3306;
-#ifdef HAVE_POST_0_7_7_SYSREPO
     S_Val s_port(new Val(mport));
-#else
-    S_Val s_port(new Val(mport, SR_UINT16_T));
-#endif
     EXPECT_NO_THROW(sess_->set_item(xport.c_str(), s_port));
 
     // Get empty.
@@ -232,9 +225,7 @@ TEST_F(TranslatorDatabasesTest, get) {
 
 // This test verifies that a database list can be properly
 // translated from JSON to YANG.
-TEST_F(TranslatorDatabasesTest, set) {
-    useModel(KEA_DHCP6_SERVER);
-
+TEST_F(TranslatorDatabasesTestv6, set) {
     // Set a value.
     const string& xpath = "/kea-dhcp6-server:config/hosts-database";
     ElementPtr database = Element::createMap();
@@ -269,9 +260,7 @@ TEST_F(TranslatorDatabasesTest, set) {
 
 // This test verifies that an emptied database list can be properly
 // translated from JSON to YANG.
-TEST_F(TranslatorDatabasesTest, setEmpty) {
-    useModel(KEA_DHCP4_SERVER);
-
+TEST_F(TranslatorDatabasesTestv4, setEmpty) {
     // Set a value.
     const string& xpath = "/kea-dhcp4-server:config/hosts-database";
     const string& xdatabase = xpath + "[database-type='mysql']";
@@ -289,15 +278,12 @@ TEST_F(TranslatorDatabasesTest, setEmpty) {
     S_Val s_host(new Val("localhost"));
     EXPECT_NO_THROW(sess_->set_item(xhost.c_str(), s_host));
     uint16_t mport = 3306;
-#ifdef HAVE_POST_0_7_7_SYSREPO
     S_Val s_port(new Val(mport));
-#else
-    S_Val s_port(new Val(mport, SR_UINT16_T));
-#endif
     EXPECT_NO_THROW(sess_->set_item(xport.c_str(), s_port));
+    sess_->apply_changes();
 
     // Reset to empty.
-    ASSERT_NO_THROW(t_obj_->setDatabase(xdatabase, ConstElementPtr()));
+    EXPECT_NO_THROW(t_obj_->setDatabase(xdatabase, ConstElementPtr()));
 
     // Get empty.
     ConstElementPtr databases;
@@ -307,9 +293,7 @@ TEST_F(TranslatorDatabasesTest, setEmpty) {
 
 // This test verifies that an empty database list can be properly
 // translated from JSON to YANG.
-TEST_F(TranslatorDatabasesTest, setEmpties) {
-    useModel(KEA_DHCP4_SERVER);
-
+TEST_F(TranslatorDatabasesTestv4, setEmpties) {
     // Set a value.
     const string& xpath = "/kea-dhcp4-server:config/hosts-database";
     const string& xdatabase = xpath + "[database-type='mysql']";
@@ -327,15 +311,12 @@ TEST_F(TranslatorDatabasesTest, setEmpties) {
     S_Val s_host(new Val("localhost"));
     EXPECT_NO_THROW(sess_->set_item(xhost.c_str(), s_host));
     uint16_t mport = 3306;
-#ifdef HAVE_POST_0_7_7_SYSREPO
     S_Val s_port(new Val(mport));
-#else
-    S_Val s_port(new Val(mport, SR_UINT16_T));
-#endif
     EXPECT_NO_THROW(sess_->set_item(xport.c_str(), s_port));
+    sess_->apply_changes();
 
     // Reset to empty.
-    ASSERT_NO_THROW(t_obj_->setDatabases(xdatabase, ConstElementPtr()));
+    EXPECT_NO_THROW(t_obj_->setDatabases(xdatabase, ConstElementPtr()));
 
     // Get empty.
     ConstElementPtr databases;
@@ -343,4 +324,4 @@ TEST_F(TranslatorDatabasesTest, setEmpties) {
     EXPECT_FALSE(databases);
 }
 
-}; // end of anonymous namespace
+}  // namespace
index 375d775832ab9a9bf9f07b4f4bff97de5198e69f..26fd2026dd0eb0d8316be5c71fd02349bcb04e91 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2018 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2018-2021 Internet Systems Consortium, Inc. ("ISC")
 //
 // This Source Code Form is subject to the terms of the Mozilla Public
 // License, v. 2.0. If a copy of the MPL was not distributed with this
@@ -18,9 +18,7 @@ using namespace isc;
 using namespace isc::data;
 using namespace isc::yang;
 using namespace isc::yang::test;
-#ifndef HAVE_PRE_0_7_6_SYSREPO
 using namespace sysrepo;
-#endif
 
 namespace {
 
@@ -28,37 +26,40 @@ namespace {
 extern char const host_reservations[] = "host reservations";
 
 /// @brief Test fixture class for @ref TranslatorHosts.
-class TranslatorHostsTest :
+class TranslatorHostsTestv4 :
     public GenericTranslatorTest<host_reservations, TranslatorHosts> {
 public:
 
     /// Constructor.
-    TranslatorHostsTest() { }
+    TranslatorHostsTestv4() {
+        model_ = KEA_DHCP4_SERVER;
+    }
+};
+
+class TranslatorHostsTestv6 :
+    public GenericTranslatorTest<host_reservations, TranslatorHosts> {
+public:
 
-    /// Destructor (does nothing).
-    virtual ~TranslatorHostsTest() { }
+    /// Constructor.
+    TranslatorHostsTestv6() {
+        model_ = KEA_DHCP6_SERVER;
+    }
 };
 
 // This test verifies that an empty host reservation list can be properly
 // translated from YANG to JSON.
-TEST_F(TranslatorHostsTest, getEmpty) {
-    useModel(KEA_DHCP6_SERVER);
-
+TEST_F(TranslatorHostsTestv6, getEmpty) {
     // Get the host reservation list and check if it is empty.
     const string& xpath =
         "/kea-dhcp6-server:config/subnet6[id='111']";
     ConstElementPtr hosts;
     EXPECT_NO_THROW(hosts = t_obj_->getHosts(xpath));
-    ASSERT_TRUE(hosts);
-    ASSERT_EQ(Element::list, hosts->getType());
-    EXPECT_EQ(0, hosts->size());
+    ASSERT_FALSE(hosts);
 }
 
 // This test verifies that one host reservation can be properly
 // translated from YANG to JSON.
-TEST_F(TranslatorHostsTest, get) {
-    useModel(KEA_DHCP6_SERVER);
-
+TEST_F(TranslatorHostsTestv6, get) {
     // Create the subnet 2001:db8::/48 #111.
     const string& xpath =
         "/kea-dhcp6-server:config/subnet6[id='111']";
@@ -97,9 +98,7 @@ TEST_F(TranslatorHostsTest, get) {
 
 // This test verifies that an empty host reservation list can be properly
 // translated from JSON to YANG.
-TEST_F(TranslatorHostsTest, setEmpty) {
-    useModel(KEA_DHCP6_SERVER);
-
+TEST_F(TranslatorHostsTestv6, setEmpty) {
     // Create the subnet 2001:db8::/48 #111.
     const string& xpath =
         "/kea-dhcp6-server:config/subnet6[id='111']";
@@ -114,16 +113,12 @@ TEST_F(TranslatorHostsTest, setEmpty) {
     // Get it back.
     hosts.reset();
     EXPECT_NO_THROW(hosts = t_obj_->getHosts(xpath));
-    ASSERT_TRUE(hosts);
-    ASSERT_EQ(Element::list, hosts->getType());
-    EXPECT_EQ(0, hosts->size());
+    ASSERT_FALSE(hosts);
 }
 
 // This test verifies that one host reservation can be properly
 // translated from JSON to YANG.
-TEST_F(TranslatorHostsTest, set) {
-    useModel(KEA_DHCP4_SERVER);
-
+TEST_F(TranslatorHostsTestv4, set) {
     // Create the subnet 10.0.0.0/14 #111.
     const string& xpath =
         "/kea-dhcp4-server:config/subnet4[id='111']";
@@ -148,39 +143,13 @@ TEST_F(TranslatorHostsTest, set) {
     ASSERT_EQ(1, hosts->size());
     EXPECT_TRUE(host->equals(*hosts->get(0)));
 
-    // Check the tree representation.
-    S_Tree tree;
-    EXPECT_NO_THROW(tree = sess_->get_subtree("/kea-dhcp4-server:config"));
-    ASSERT_TRUE(tree);
-    string expected =
-        "kea-dhcp4-server:config (container)\n"
-        " |\n"
-        " -- subnet4 (list instance)\n"
-        "     |\n"
-        "     -- id = 111\n"
-        "     |\n"
-        "     -- subnet = 10.0.0.0/24\n"
-        "     |\n"
-        "     -- host (list instance)\n"
-        "         |\n"
-        "         -- identifier-type = flex-id\n"
-        "         |\n"
-        "         -- identifier = 00:ff\n"
-        "         |\n"
-        "         -- hostname = foo\n"
-        "         |\n"
-        "         -- ip-address = 10.0.0.1\n";
-    EXPECT_EQ(expected, tree->to_string(100));
-
     // Check it validates.
     EXPECT_NO_THROW(sess_->validate());
 }
 
 // This test verifies that several host reservations can be properly
 // translated from YANG to JSON.
-TEST_F(TranslatorHostsTest, getMany) {
-    useModel(KEA_DHCP6_SERVER);
-
+TEST_F(TranslatorHostsTestv6, getMany) {
     // Create the subnet 2001:db8::/48 #111.
     const string& xpath =
         "/kea-dhcp6-server:config/subnet6[id='111']";
index cc8100a8e0c7e34725e35223196515a84d622637..92e87b447eb3c982f60e8eebd8639838bc50216c 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2018-2019 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2018-2021 Internet Systems Consortium, Inc. ("ISC")
 //
 // This Source Code Form is subject to the terms of the Mozilla Public
 // License, v. 2.0. If a copy of the MPL was not distributed with this
@@ -17,9 +17,7 @@ using namespace isc;
 using namespace isc::data;
 using namespace isc::yang;
 using namespace isc::yang::test;
-#ifndef HAVE_PRE_0_7_6_SYSREPO
 using namespace sysrepo;
-#endif
 
 namespace {
 
@@ -27,49 +25,48 @@ namespace {
 extern char const logger_list[] = "logger list";
 
 /// @brief Test fixture class for @ref TranslatorLoggers.
-class TranslatorLoggersTest :
+class TranslatorLoggersTestv4 :
     public GenericTranslatorTest<logger_list, TranslatorLoggers> {
 public:
 
     /// Constructor.
-    TranslatorLoggersTest() { }
+    TranslatorLoggersTestv4() {
+        model_ = KEA_DHCP4_SERVER;
+    }
+};
+class TranslatorLoggersTestv6 :
+    public GenericTranslatorTest<logger_list, TranslatorLoggers> {
+public:
 
-    /// Destructor (does nothing).
-    virtual ~TranslatorLoggersTest() { }
+    /// Constructor.
+    TranslatorLoggersTestv6() {
+        model_ = KEA_DHCP6_SERVER;
+    }
 };
 
 // This test verifies that an empty logger list can be properly
 // translated from YANG to JSON.
-TEST_F(TranslatorLoggersTest, getEmpty) {
-    useModel(KEA_DHCP4_SERVER);
-
+TEST_F(TranslatorLoggersTestv4, getEmpty) {
     // Get empty.
     const string& xpath = "/kea-dhcp4-server:config";
     ConstElementPtr loggers;
     EXPECT_NO_THROW(loggers = t_obj_->getLoggers(xpath));
-    ASSERT_TRUE(loggers);
-    EXPECT_EQ(0, loggers->size());
+    ASSERT_FALSE(loggers);
 }
 
 // This test verifies that one logger can be properly
 // translated from YANG to JSON.
-TEST_F(TranslatorLoggersTest, get) {
-    useModel(KEA_DHCP6_SERVER);
-
+TEST_F(TranslatorLoggersTestv6, get) {
     // Set a value.
     const string& xpath = "/kea-dhcp6-server:config";
     const string& xlogger = xpath + "/logger[name='foo']";
     const string& xseverity = xlogger + "/severity";
-   const string& xoption = xlogger + "/output-option[output='/bar']";
+    const string& xoption = xlogger + "/output-option[output='/bar']";
     const string& xmaxver = xoption + "/maxver";
     S_Val s_severity(new Val("WARN", SR_ENUM_T));
     EXPECT_NO_THROW(sess_->set_item(xseverity.c_str(), s_severity));
     uint32_t max_ver = 10;
-#ifdef HAVE_POST_0_7_7_SYSREPO
     S_Val s_maxver(new Val(max_ver));
-#else
-    S_Val s_maxver(new Val(max_ver, SR_UINT32_T));
-#endif
     EXPECT_NO_THROW(sess_->set_item(xmaxver.c_str(), s_maxver));
 
     // Get empty.
@@ -106,9 +103,7 @@ TEST_F(TranslatorLoggersTest, get) {
 
 // This test verifies that one logger can be properly
 // translated from JSON to YANG.
-TEST_F(TranslatorLoggersTest, set) {
-    useModel(KEA_DHCP4_SERVER);
-
+TEST_F(TranslatorLoggersTestv4, set) {
     // Set a value.
     const string& xpath = "/kea-dhcp4-server:config";
     ElementPtr option = Element::createMap();
@@ -155,30 +150,10 @@ TEST_F(TranslatorLoggersTest, set) {
     ASSERT_EQ(Element::integer, maxver->getType());
     EXPECT_EQ(10, maxver->intValue());
 
-    // Check the tree representation.
-    S_Tree tree;
-    EXPECT_NO_THROW(tree = sess_->get_subtree("/kea-dhcp4-server:config"));
-    ASSERT_TRUE(tree);
-    string expected =
-        "kea-dhcp4-server:config (container)\n"
-        " |\n"
-        " -- logger (list instance)\n"
-        "     |\n"
-        "     -- name = foo\n"
-        "     |\n"
-        "     -- output-option (list instance)\n"
-        "     |   |\n"
-        "     |   -- output = /bar\n"
-        "     |   |\n"
-        "     |   -- maxver = 10\n"
-        "     |\n"
-        "     -- severity = WARN\n";
-    EXPECT_EQ(expected, tree->to_string(100));
-
     // Check it validates.
     EXPECT_NO_THROW(sess_->validate());
 }
 
 /// @todo: Implement a test that will cover multiple loggers.
 
-}; // end of anonymous namespace
+}  // namespace
index e95030a7634d02563691f17f96122d49116b25e7..8270c0599e16aed5048e26c40b8046ba93b808e9 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2018 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2018-2021 Internet Systems Consortium, Inc. ("ISC")
 //
 // This Source Code Form is subject to the terms of the Mozilla Public
 // License, v. 2.0. If a copy of the MPL was not distributed with this
@@ -18,9 +18,7 @@ using namespace isc;
 using namespace isc::data;
 using namespace isc::yang;
 using namespace isc::yang::test;
-#ifndef HAVE_PRE_0_7_6_SYSREPO
 using namespace sysrepo;
-#endif
 
 namespace {
 
@@ -28,36 +26,39 @@ namespace {
 extern char const option_data_list[] = "option data list";
 
 /// @brief Test fixture class for @ref TranslatorOptionDataList.
-class TranslatorOptionDataListTest :
+class TranslatorOptionDataListTestv4 :
     public GenericTranslatorTest<option_data_list, TranslatorOptionDataList> {
 public:
 
     /// Constructor.
-    TranslatorOptionDataListTest() { }
+    TranslatorOptionDataListTestv4() {
+        model_ = KEA_DHCP4_SERVER;
+     }
+};
+
+class TranslatorOptionDataListTestv6 :
+    public GenericTranslatorTest<option_data_list, TranslatorOptionDataList> {
+public:
 
-    /// Destructor (does nothing).
-    virtual ~TranslatorOptionDataListTest() { }
+    /// Constructor.
+    TranslatorOptionDataListTestv6() {
+        model_ = KEA_DHCP6_SERVER;
+     }
 };
 
 // This test verifies that an empty option data list can be properly
 // translated from YANG to JSON.
-TEST_F(TranslatorOptionDataListTest, getEmpty) {
-    useModel(KEA_DHCP4_SERVER);
-
+TEST_F(TranslatorOptionDataListTestv4, getEmpty) {
     // Get the option data list and check if it is empty.
     const string& xpath = "/kea-dhcp4-server:config";
     ConstElementPtr options;
     EXPECT_NO_THROW(options = t_obj_->getOptionDataList(xpath));
-    ASSERT_TRUE(options);
-    ASSERT_EQ(Element::list, options->getType());
-    EXPECT_EQ(0, options->size());
+    ASSERT_FALSE(options);
 }
 
 // This test verifies that one option data can be properly translated
 // from YANG to JSON.
-TEST_F(TranslatorOptionDataListTest, get) {
-    useModel(KEA_DHCP6_SERVER);
-
+TEST_F(TranslatorOptionDataListTestv6, get) {
     // Create the option code 100.
     const string& xpath = "/kea-dhcp6-server:config";
     const string& xoption = xpath + "/option-data[code='100'][space='dns']";
@@ -94,9 +95,7 @@ TEST_F(TranslatorOptionDataListTest, get) {
 
 // This test verifies that an empty option data list can be properly
 // translated from JSON to YANG.
-TEST_F(TranslatorOptionDataListTest, setEmpty) {
-    useModel(KEA_DHCP4_SERVER);
-
+TEST_F(TranslatorOptionDataListTestv4, setEmpty) {
     // Set empty list.
     const string& xpath = "/kea-dhcp4-server:config";
     ConstElementPtr options = Element::createList();
@@ -105,20 +104,12 @@ TEST_F(TranslatorOptionDataListTest, setEmpty) {
     // Get it back.
     options.reset();
     EXPECT_NO_THROW(options = t_obj_->getOptionDataList(xpath));
-    ASSERT_TRUE(options);
-    EXPECT_EQ(0, options->size());
-
-    // Check that the tree representation is empty.
-    S_Tree tree;
-    EXPECT_NO_THROW(tree = sess_->get_subtree("/kea-dhcp4-server:config"));
-    EXPECT_FALSE(tree);
+    ASSERT_FALSE(options);
 }
 
 // This test verifies that one option data can be properly translated
 // from JSON to YANG.
-TEST_F(TranslatorOptionDataListTest, set) {
-    useModel(KEA_DHCP6_SERVER);
-
+TEST_F(TranslatorOptionDataListTestv6, set) {
     // Set one option data.
     const string& xpath = "/kea-dhcp6-server:config";
     ElementPtr options = Element::createList();
@@ -138,28 +129,8 @@ TEST_F(TranslatorOptionDataListTest, set) {
     ASSERT_EQ(1, got->size());
     EXPECT_TRUE(option->equals(*got->get(0)));
 
-    // Check the tree representation.
-    S_Tree tree;
-    EXPECT_NO_THROW(tree = sess_->get_subtree("/kea-dhcp6-server:config"));
-    ASSERT_TRUE(tree);
-    string expected =
-        "kea-dhcp6-server:config (container)\n"
-        " |\n"
-        " -- option-data (list instance)\n"
-        "     |\n"
-        "     -- code = 100\n"
-        "     |\n"
-        "     -- space = dns\n"
-        "     |\n"
-        "     -- data = 12121212\n"
-        "     |\n"
-        "     -- csv-format = false\n"
-        "     |\n"
-        "     -- always-send = false\n";
-    EXPECT_EQ(expected, tree->to_string(100));
-
     // Check it validates.
     EXPECT_NO_THROW(sess_->validate());
 }
 
-}; // end of anonymous namespace
+}  // namespace
index 515d9ec303f3c35606a515ded62d1f7fef7c2f3d..b056076713aee2eefe7b56ca7fb36e70c6cab78d 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2018 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2018-2021 Internet Systems Consortium, Inc. ("ISC")
 //
 // This Source Code Form is subject to the terms of the Mozilla Public
 // License, v. 2.0. If a copy of the MPL was not distributed with this
@@ -18,9 +18,7 @@ using namespace isc;
 using namespace isc::data;
 using namespace isc::yang;
 using namespace isc::yang::test;
-#ifndef HAVE_PRE_0_7_6_SYSREPO
 using namespace sysrepo;
-#endif
 
 namespace {
 
@@ -28,36 +26,47 @@ namespace {
 extern char const option_definition_list[] = "option definition list";
 
 /// @brief Test fixture class for @ref TranslatorOptionDefList.
-class TranslatorOptionDefListTest :
+class TranslatorOptionDefListTestKeaV4 :
     public GenericTranslatorTest<option_definition_list, TranslatorOptionDefList> {
 public:
 
     /// Constructor.
-    TranslatorOptionDefListTest() { }
+    TranslatorOptionDefListTestKeaV4() {
+        model_ = KEA_DHCP4_SERVER;
+    }
+};
+class TranslatorOptionDefListTestKeaV6 :
+    public GenericTranslatorTest<option_definition_list, TranslatorOptionDefList> {
+public:
+
+    /// Constructor.
+    TranslatorOptionDefListTestKeaV6() {
+        model_ = KEA_DHCP6_SERVER;
+    }
+};
+class TranslatorOptionDefListTestIetfV6 :
+    public GenericTranslatorTest<option_definition_list, TranslatorOptionDefList> {
+public:
 
-    /// Destructor (does nothing).
-    virtual ~TranslatorOptionDefListTest() { }
+    /// Constructor.
+    TranslatorOptionDefListTestIetfV6() {
+        model_ = IETF_DHCPV6_SERVER;
+    }
 };
 
 // This test verifies that an empty option definition list can be properly
 // translated from YANG to JSON.
-TEST_F(TranslatorOptionDefListTest, getEmpty) {
-    useModel(KEA_DHCP4_SERVER);
-
+TEST_F(TranslatorOptionDefListTestKeaV4, getEmpty) {
     // Get the option definition list and check if it is empty.
     const string& xpath = "/kea-dhcp4-server:config";
     ConstElementPtr options;
     EXPECT_NO_THROW(options = t_obj_->getOptionDefList(xpath));
-    ASSERT_TRUE(options);
-    ASSERT_EQ(Element::list, options->getType());
-    EXPECT_EQ(0, options->size());
+    ASSERT_FALSE(options);
 }
 
 // This test verifies that one option definition can be properly
 // translated from YANG to JSON.
-TEST_F(TranslatorOptionDefListTest, get) {
-    useModel(KEA_DHCP6_SERVER);
-
+TEST_F(TranslatorOptionDefListTestKeaV6, get) {
     // Create the option code 100.
     const string& xpath = "/kea-dhcp6-server:config";
     const string& xdef = xpath + "/option-def[code='100'][space='isc']";
@@ -94,9 +103,7 @@ TEST_F(TranslatorOptionDefListTest, get) {
 
 // This test verifies that an empty option definition list can be properly
 // translated from JSON to YANG.
-TEST_F(TranslatorOptionDefListTest, setEmpty) {
-    useModel(KEA_DHCP4_SERVER);
-
+TEST_F(TranslatorOptionDefListTestKeaV4, setEmpty) {
     // Set empty list.
     const string& xpath = "/kea-dhcp4-server:config";
     ConstElementPtr defs = Element::createList();
@@ -105,20 +112,12 @@ TEST_F(TranslatorOptionDefListTest, setEmpty) {
     // Get it back.
     defs.reset();
     EXPECT_NO_THROW(defs = t_obj_->getOptionDefList(xpath));
-    ASSERT_TRUE(defs);
-    EXPECT_EQ(0, defs->size());
-
-    // Check that the tree representation is empty.
-    S_Tree tree;
-    EXPECT_NO_THROW(tree = sess_->get_subtree("/kea-dhcp4-server:config"));
-    EXPECT_FALSE(tree);
+    ASSERT_FALSE(defs);
 }
 
 // This test verifies that one option definition can be properly
 // translated from JSON to YANG.
-TEST_F(TranslatorOptionDefListTest, set) {
-    useModel(KEA_DHCP6_SERVER);
-
+TEST_F(TranslatorOptionDefListTestKeaV6, set) {
     // Set one option def.
     const string& xpath = "/kea-dhcp6-server:config";
     ElementPtr defs = Element::createList();
@@ -138,26 +137,6 @@ TEST_F(TranslatorOptionDefListTest, set) {
     ASSERT_EQ(1, got->size());
     EXPECT_TRUE(def->equals(*got->get(0)));
 
-    // Check the tree representation.
-    S_Tree tree;
-    EXPECT_NO_THROW(tree = sess_->get_subtree("/kea-dhcp6-server:config"));
-    ASSERT_TRUE(tree);
-    string expected =
-        "kea-dhcp6-server:config (container)\n"
-        " |\n"
-        " -- option-def (list instance)\n"
-        "     |\n"
-        "     -- code = 100\n"
-        "     |\n"
-        "     -- space = isc\n"
-        "     |\n"
-        "     -- name = foo\n"
-        "     |\n"
-        "     -- type = string\n"
-        "     |\n"
-        "     -- array = false\n";
-    EXPECT_EQ(expected, tree->to_string(100));
-
     // Check it validates.
     EXPECT_NO_THROW(sess_->validate());
 }
index 1be28b16c8e18986f4b899fc33d6d05b49476056..8d5b3fe02087c9955b113d53a383333848ad0d54 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2018-2019 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2018-2021 Internet Systems Consortium, Inc. ("ISC")
 //
 // This Source Code Form is subject to the terms of the Mozilla Public
 // License, v. 2.0. If a copy of the MPL was not distributed with this
@@ -18,9 +18,7 @@ using namespace isc;
 using namespace isc::data;
 using namespace isc::yang;
 using namespace isc::yang::test;
-#ifndef HAVE_PRE_0_7_6_SYSREPO
 using namespace sysrepo;
-#endif
 
 namespace {
 
@@ -28,52 +26,50 @@ namespace {
 extern char const pd_pool_list[] = "pd pool list";
 
 /// @brief Test fixture class for @ref TranslatorPdPools.
-class TranslatorPdPoolsTest :
+class TranslatorPdPoolsTestKeaV6 :
     public GenericTranslatorTest<pd_pool_list, TranslatorPdPools> {
 public:
 
     /// Constructor.
-    TranslatorPdPoolsTest() { }
+    TranslatorPdPoolsTestKeaV6() {
+        model_ = KEA_DHCP6_SERVER;
+    }
+};
+class TranslatorPdPoolsTestIetfV6 :
+    public GenericTranslatorTest<pd_pool_list, TranslatorPdPools> {
+public:
 
-    /// Destructor (does nothing).
-    virtual ~TranslatorPdPoolsTest() { }
+    /// Constructor.
+    TranslatorPdPoolsTestIetfV6() {
+        model_ = IETF_DHCPV6_SERVER;
+    }
 };
 
 // This test verifies that an empty pd pool list can be properly
 // translated from YANG to JSON using the IETF model.
-TEST_F(TranslatorPdPoolsTest, getEmptyIetf) {
-    useModel(IETF_DHCPV6_SERVER);
-
+TEST_F(TranslatorPdPoolsTestIetfV6, getEmptyIetf) {
     // Get the pd-pool list and check if it is empty.
     const string& xpath =
         "/ietf-dhcpv6-server:server/server-config/network-ranges"
         "/network-range[network-range-id='111']/pd-pools";
     ConstElementPtr pools;
     EXPECT_NO_THROW(pools = t_obj_->getPdPools(xpath));
-    ASSERT_TRUE(pools);
-    ASSERT_EQ(Element::list, pools->getType());
-    EXPECT_EQ(0, pools->size());
+    ASSERT_FALSE(pools);
 }
 
 // This test verifies that an empty pd pool list can be properly
 // translated from YANG to JSON using the Kea ad hoc model.
-TEST_F(TranslatorPdPoolsTest, getEmptyKea) {
-    useModel(KEA_DHCP6_SERVER);
-
+TEST_F(TranslatorPdPoolsTestKeaV6, getEmptyKea) {
     // Get the pd-pool list and check if it is empty.
     const string& xpath = "/kea-dhcp6-server:config/subnet6[id='111']";
     ConstElementPtr pools;
     EXPECT_NO_THROW(pools = t_obj_->getPdPools(xpath));
-    ASSERT_TRUE(pools);
-    ASSERT_EQ(Element::list, pools->getType());
-    EXPECT_EQ(0, pools->size());
+    ASSERT_FALSE(pools);
 }
 
 // This test verifies that one pd pool can be properly
 // translated from YANG to JSON using the IETF model.
-TEST_F(TranslatorPdPoolsTest, getIetf) {
-    useModel(IETF_DHCPV6_SERVER);
-
+TEST_F(TranslatorPdPoolsTestIetfV6, getIetf) {
     // Create the subnet 2001:db8::/48 #111.
     const string& subnet =
         "/ietf-dhcpv6-server:server/server-config/network-ranges"
@@ -89,11 +85,7 @@ TEST_F(TranslatorPdPoolsTest, getIetf) {
     EXPECT_NO_THROW(sess_->set_item(prefix.c_str(), s_prefix));
     const string& length = xpath + "/prefix-length";
     uint8_t len = 56;
-#ifdef HAVE_POST_0_7_7_SYSREPO
     S_Val s_length(new Val(len));
-#else
-    S_Val s_length(new Val(len, SR_UINT8_T));
-#endif
     EXPECT_NO_THROW(sess_->set_item(length.c_str(), s_length));
 
     // Get the pool.
@@ -116,9 +108,7 @@ TEST_F(TranslatorPdPoolsTest, getIetf) {
 
 // This test verifies that one pd pool can be properly
 // translated from YANG to JSON using the Kea ad hoc model.
-TEST_F(TranslatorPdPoolsTest, getKea) {
-    useModel(KEA_DHCP6_SERVER);
-
+TEST_F(TranslatorPdPoolsTestKeaV6, getKea) {
     // Create the subnet 2001:db8::/48 #111.
     const string& xpath =
         "/kea-dhcp6-server:config/subnet6[id='111']";
@@ -132,11 +122,7 @@ TEST_F(TranslatorPdPoolsTest, getKea) {
     spool << xpath + "/pd-pool[prefix='" << prefix << "']";
     const string& x_delegated = spool.str() + "/delegated-len";
     uint8_t dl = 64;
-#ifdef HAVE_POST_0_7_7_SYSREPO
     S_Val s_delegated(new Val(dl));
-#else
-    S_Val s_delegated(new Val(dl, SR_UINT8_T));
-#endif
     EXPECT_NO_THROW(sess_->set_item(x_delegated.c_str(), s_delegated));
 
     // Get the pool.
@@ -160,9 +146,7 @@ TEST_F(TranslatorPdPoolsTest, getKea) {
 
 // This test verifies that an empty pd pool list can be properly
 // translated from JSON to YANG using the IETF model.
-TEST_F(TranslatorPdPoolsTest, setEmptyIetf) {
-    useModel(IETF_DHCPV6_SERVER);
-
+TEST_F(TranslatorPdPoolsTestIetfV6, setEmptyIetf) {
     // Create the subnet 2001:db8::/48 #111.
     const string& subnet =
         "/ietf-dhcpv6-server:server/server-config/network-ranges"
@@ -179,16 +163,12 @@ TEST_F(TranslatorPdPoolsTest, setEmptyIetf) {
     // Get it back.
     pools.reset();
     EXPECT_NO_THROW(pools = t_obj_->getPdPools(xpath));
-    ASSERT_TRUE(pools);
-    ASSERT_EQ(Element::list, pools->getType());
-    EXPECT_EQ(0, pools->size());
+    ASSERT_FALSE(pools);
 }
 
 // This test verifies that an empty pd pool list can be properly
 // translated from JSON to YANG using the Kea ad hoc model.
-TEST_F(TranslatorPdPoolsTest, setEmptyKea) {
-    useModel(KEA_DHCP6_SERVER);
-
+TEST_F(TranslatorPdPoolsTestKeaV6, setEmptyKea) {
     // Create the subnet 2001:db8::/48 #111.
     const string& xpath =
         "/kea-dhcp6-server:config/subnet6[id='111']";
@@ -203,16 +183,12 @@ TEST_F(TranslatorPdPoolsTest, setEmptyKea) {
     // Get it back.
     pools.reset();
     EXPECT_NO_THROW(pools = t_obj_->getPdPools(xpath));
-    ASSERT_TRUE(pools);
-    ASSERT_EQ(Element::list, pools->getType());
-    EXPECT_EQ(0, pools->size());
+    ASSERT_FALSE(pools);
 }
 
 // This test verifies that one pd pool can be properly
 // translated from JSON to YANG using the IETF model.
-TEST_F(TranslatorPdPoolsTest, setIetf) {
-    useModel(IETF_DHCPV6_SERVER);
-
+TEST_F(TranslatorPdPoolsTestIetfV6, setIetf) {
     // Create the subnet 2001:db8::/48 #111.
     const string& subnet =
         "/ietf-dhcpv6-server:server/server-config/network-ranges"
@@ -237,43 +213,11 @@ TEST_F(TranslatorPdPoolsTest, setIetf) {
     ASSERT_EQ(Element::list, pools->getType());
     ASSERT_EQ(1, pools->size());
     EXPECT_TRUE(pool->equals(*pools->get(0)));
-
-    // Check the tree representation.
-    S_Tree tree;
-    EXPECT_NO_THROW(tree = sess_->get_subtree("/ietf-dhcpv6-server:server"));
-    ASSERT_TRUE(tree);
-    string expected =
-        "ietf-dhcpv6-server:server (container)\n"
-        " |\n"
-        " -- server-config (container)\n"
-        "     |\n"
-        "     -- network-ranges (container)\n"
-        "         |\n"
-        "         -- network-range (list instance)\n"
-        "             |\n"
-        "             -- network-range-id = 111\n"
-        "             |\n"
-        "             -- network-prefix = 2001:db8::/48\n"
-        "             |\n"
-        "             -- pd-pools (container)\n"
-        "                 |\n"
-        "                 -- pd-pool (list instance)\n"
-        "                     |\n"
-        "                     -- pool-id = 0\n"
-        "                     |\n"
-        "                     -- prefix = 2001:db8:0:1000::/56\n"
-        "                     |\n"
-        "                     -- prefix-length = 56\n"
-        "                     |\n"
-        "                     -- max-pd-space-utilization = disabled\n";
-    EXPECT_EQ(expected, tree->to_string(100));
 }
 
 // This test verifies that one pd pool can be properly
 // translated from JSON to YANG using the kea ad hoc model.
-TEST_F(TranslatorPdPoolsTest, setKea) {
-    useModel(KEA_DHCP6_SERVER);
-
+TEST_F(TranslatorPdPoolsTestKeaV6, setKea) {
     // Create the subnet 2001:db8::/48 #111.
     const string& xpath =
         "/kea-dhcp6-server:config/subnet6[id='111']";
@@ -298,35 +242,13 @@ TEST_F(TranslatorPdPoolsTest, setKea) {
     ASSERT_EQ(1, pools->size());
     EXPECT_TRUE(pool->equals(*pools->get(0)));
 
-    // Check the tree representation.
-    S_Tree tree;
-    EXPECT_NO_THROW(tree = sess_->get_subtree("/kea-dhcp6-server:config"));
-    ASSERT_TRUE(tree);
-    string expected =
-        "kea-dhcp6-server:config (container)\n"
-        " |\n"
-        " -- subnet6 (list instance)\n"
-        "     |\n"
-        "     -- id = 111\n"
-        "     |\n"
-        "     -- subnet = 2001:db8::/48\n"
-        "     |\n"
-        "     -- pd-pool (list instance)\n"
-        "         |\n"
-        "         -- prefix = 2001:db8:0:1000::/56\n"
-        "         |\n"
-        "         -- delegated-len = 64\n";
-    EXPECT_EQ(expected, tree->to_string(100));
-
     // Check it validates.
     EXPECT_NO_THROW(sess_->validate());
 }
 
 // This test verifies that a non-empty list of pd pools can be properly
 // translated from YANG to JSON using the Kea ad hoc model.
-TEST_F(TranslatorPdPoolsTest, getListKea) {
-    useModel(KEA_DHCP6_SERVER);
-
+TEST_F(TranslatorPdPoolsTestKeaV6, getListKea) {
     // Create the subnet 2001:db8::/48 #111.
     const string& xpath =
         "/kea-dhcp6-server:config/subnet6[id='111']";
@@ -340,11 +262,7 @@ TEST_F(TranslatorPdPoolsTest, getListKea) {
     spool << xpath + "/pd-pool[prefix='" << prefix << "']";
     const string& x_delegated = spool.str() + "/delegated-len";
     uint8_t dl = 64;
-#ifdef HAVE_POST_0_7_7_SYSREPO
     S_Val s_delegated(new Val(dl));
-#else
-    S_Val s_delegated(new Val(dl, SR_UINT8_T));
-#endif
     EXPECT_NO_THROW(sess_->set_item(x_delegated.c_str(), s_delegated));
 
     // Create the second pd-pool 2001:db8:0:2000::/56
@@ -353,11 +271,7 @@ TEST_F(TranslatorPdPoolsTest, getListKea) {
     spool2 << xpath + "/pd-pool[prefix='" << prefix2 << "']";
     const string& x_delegated2 = spool2.str() + "/delegated-len";
     uint8_t dl2 = 60;
-#ifdef HAVE_POST_0_7_7_SYSREPO
     S_Val s_delegated2(new Val(dl2));
-#else
-    S_Val s_delegated2(new Val(dl2, SR_UINT8_T));
-#endif
     EXPECT_NO_THROW(sess_->set_item(x_delegated2.c_str(), s_delegated2));
 
 
@@ -373,4 +287,4 @@ TEST_F(TranslatorPdPoolsTest, getListKea) {
               "\"2001:db8:0:2000::\", \"prefix-len\": 56 } ]");
 }
 
-}; // end of anonymous namespace
+}  // namespace
index e18f2e11743439ac88911fc4baedd15f6885f5d6..54d005a22c9df2f09936abca034fdcd79583bc7a 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2018 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2018-2021 Internet Systems Consortium, Inc. ("ISC")
 //
 // This Source Code Form is subject to the terms of the Mozilla Public
 // License, v. 2.0. If a copy of the MPL was not distributed with this
@@ -18,9 +18,7 @@ using namespace isc;
 using namespace isc::data;
 using namespace isc::yang;
 using namespace isc::yang::test;
-#ifndef HAVE_PRE_0_7_6_SYSREPO
 using namespace sysrepo;
-#endif
 
 namespace {
 
@@ -28,51 +26,59 @@ namespace {
 extern char const pool_list[] = "pool list";
 
 /// @brief Test fixture class for @ref TranslatorPools.
-class TranslatorPoolsTest :
+class TranslatorPoolsTestKeaV4 :
     public GenericTranslatorTest<pool_list, TranslatorPools> {
 public:
 
     /// Constructor.
-    TranslatorPoolsTest() { }
+    TranslatorPoolsTestKeaV4() {
+        model_ = KEA_DHCP4_SERVER;
+    }
+};
+
+class TranslatorPoolsTestKeaV6 :
+    public GenericTranslatorTest<pool_list, TranslatorPools> {
+public:
+
+    /// Constructor.
+    TranslatorPoolsTestKeaV6() {
+        model_ = KEA_DHCP6_SERVER;
+    }
+};
+class TranslatorPoolsTestIetfV6 :
+    public GenericTranslatorTest<pool_list, TranslatorPools> {
+public:
 
-    /// Destructor (does nothing).
-    virtual ~TranslatorPoolsTest() { }
+    /// Constructor.
+    TranslatorPoolsTestIetfV6() {
+        model_ = IETF_DHCPV6_SERVER;
+    }
 };
 
 // This test verifies that an empty pool list can be properly
 // translated from YANG to JSON using IETF model.
-TEST_F(TranslatorPoolsTest, getEmptyIetf) {
-    useModel(IETF_DHCPV6_SERVER);
-
+TEST_F(TranslatorPoolsTestIetfV6, getEmptyIetf) {
     // Get the pool list and check if it is empty.
     const string& xpath = "/ietf-dhcpv6-server:server/server-config/"
         "network-ranges/network-range[network-range-id='111']/address-pools";
     ConstElementPtr pools;
     EXPECT_NO_THROW(pools = t_obj_->getPools(xpath));
-    ASSERT_TRUE(pools);
-    ASSERT_EQ(Element::list, pools->getType());
-    EXPECT_EQ(0, pools->size());
+    ASSERT_FALSE(pools);
 }
 
 // This test verifies that an empty pool list can be properly
 // translated from YANG to JSON using Kea ad hoc model.
-TEST_F(TranslatorPoolsTest, getEmptyKea) {
-    useModel(KEA_DHCP6_SERVER);
-
+TEST_F(TranslatorPoolsTestKeaV6, getEmptyKea) {
     // Get the pool list and check if it is empty.
     const string& xpath = "/kea-dhcp6-server:config/subnet6[id='111']";
     ConstElementPtr pools;
     EXPECT_NO_THROW(pools = t_obj_->getPools(xpath));
-    ASSERT_TRUE(pools);
-    ASSERT_EQ(Element::list, pools->getType());
-    EXPECT_EQ(0, pools->size());
+    ASSERT_FALSE(pools);
 }
 
 // This test verifies that one pool can be properly
 // translated from YANG to JSON using IETF model.
-TEST_F(TranslatorPoolsTest, getIetf) {
-    useModel(IETF_DHCPV6_SERVER);
-
+TEST_F(TranslatorPoolsTestIetfV6, getIetf) {
     // Create the subnet 2001:db8::/48 #111.
     const string& subnet = "/ietf-dhcpv6-server:server/server-config/"
         "network-ranges/network-range[network-range-id='111']";
@@ -103,9 +109,7 @@ TEST_F(TranslatorPoolsTest, getIetf) {
 
 // This test verifies that one pool can be properly
 // translated from YANG to JSON using Kea ad hoc model.
-TEST_F(TranslatorPoolsTest, getKea) {
-    useModel(KEA_DHCP6_SERVER);
-
+TEST_F(TranslatorPoolsTestKeaV6, getKea) {
     // Create the subnet 2001:db8::/48 #111.
     const string& xpath =
         "/kea-dhcp6-server:config/subnet6[id='111']";
@@ -147,9 +151,7 @@ TEST_F(TranslatorPoolsTest, getKea) {
 
 // This test verifies that an empty pool list can be properly
 // translated from JSON to YANG using IETF model.
-TEST_F(TranslatorPoolsTest, setEmptyIetf) {
-    useModel(IETF_DHCPV6_SERVER);
-
+TEST_F(TranslatorPoolsTestIetfV6, setEmptyIetf) {
     // Create the subnet 2001:db8::/48 #111.
     const string& subnet = "/ietf-dhcpv6-server:server/server-config/"
         "network-ranges/network-range[network-range-id='111']";
@@ -165,16 +167,12 @@ TEST_F(TranslatorPoolsTest, setEmptyIetf) {
     // Get it back.
     pools.reset();
     EXPECT_NO_THROW(pools = t_obj_->getPools(xpath));
-    ASSERT_TRUE(pools);
-    ASSERT_EQ(Element::list, pools->getType());
-    EXPECT_EQ(0, pools->size());
+    ASSERT_FALSE(pools);
 }
 
 // This test verifies that an empty pool list can be properly
 // translated from JSON to YANG using Kea ad hoc model.
-TEST_F(TranslatorPoolsTest, setEmptyKea) {
-    useModel(KEA_DHCP6_SERVER);
-
+TEST_F(TranslatorPoolsTestKeaV6, setEmptyKea) {
     // Create the subnet 2001:db8::/48 #111.
     const string& xpath =
         "/kea-dhcp6-server:config/subnet6[id='111']";
@@ -189,16 +187,12 @@ TEST_F(TranslatorPoolsTest, setEmptyKea) {
     // Get it back.
     pools.reset();
     EXPECT_NO_THROW(pools = t_obj_->getPools(xpath));
-    ASSERT_TRUE(pools);
-    ASSERT_EQ(Element::list, pools->getType());
-    EXPECT_EQ(0, pools->size());
+    ASSERT_FALSE(pools);
 }
 
 // This test verifies that one pool can be properly
 // translated from JSON to YANG using IETF model.
-TEST_F(TranslatorPoolsTest, setIetf) {
-    useModel(IETF_DHCPV6_SERVER);
-
+TEST_F(TranslatorPoolsTestIetfV6, setIetf) {
     // Create the subnet 2001:db8::/48 #111.
     const string& subnet = "/ietf-dhcpv6-server:server/server-config/"
         "network-ranges/network-range[network-range-id='111']";
@@ -221,45 +215,11 @@ TEST_F(TranslatorPoolsTest, setIetf) {
     ASSERT_EQ(Element::list, pools->getType());
     ASSERT_EQ(1, pools->size());
     EXPECT_TRUE(pool->equals(*pools->get(0)));
-
-    // Check the tree representation.
-    S_Tree tree;
-    EXPECT_NO_THROW(tree = sess_->get_subtree("/ietf-dhcpv6-server:server"));
-    ASSERT_TRUE(tree);
-    string expected =
-        "ietf-dhcpv6-server:server (container)\n"
-        " |\n"
-        " -- server-config (container)\n"
-        "     |\n"
-        "     -- network-ranges (container)\n"
-        "         |\n"
-        "         -- network-range (list instance)\n"
-        "             |\n"
-        "             -- network-range-id = 111\n"
-        "             |\n"
-        "             -- network-prefix = 2001:db8::/48\n"
-        "             |\n"
-        "             -- address-pools (container)\n"
-        "                 |\n"
-        "                 -- address-pool (list instance)\n"
-        "                     |\n"
-        "                     -- pool-id = 0\n"
-        "                     |\n"
-        "                     -- pool-prefix = 2001:db8::1:0/112\n"
-        "                     |\n"
-        "                     -- start-address = 2001:db8::1:0\n"
-        "                     |\n"
-        "                     -- end-address = 2001:db8::1:ffff\n"
-        "                     |\n"
-        "                     -- max-address-count = disabled\n";
-    EXPECT_EQ(expected, tree->to_string(100));
 }
 
 // This test verifies that one pool can be properly
 // translated from JSON to YANG using Kea ad hoc model.
-TEST_F(TranslatorPoolsTest, setKea) {
-    useModel(KEA_DHCP6_SERVER);
-
+TEST_F(TranslatorPoolsTestKeaV6, setKea) {
     // Create the subnet 2001:db8::/48 #111.
     const string& xpath =
         "/kea-dhcp6-server:config/subnet6[id='111']";
@@ -283,28 +243,8 @@ TEST_F(TranslatorPoolsTest, setKea) {
     ASSERT_EQ(1, pools->size());
     EXPECT_TRUE(pool->equals(*pools->get(0)));
 
-    // Check the tree representation.
-    S_Tree tree;
-    EXPECT_NO_THROW(tree = sess_->get_subtree("/kea-dhcp6-server:config"));
-    ASSERT_TRUE(tree);
-    string expected =
-        "kea-dhcp6-server:config (container)\n"
-        " |\n"
-        " -- subnet6 (list instance)\n"
-        "     |\n"
-        "     -- id = 111\n"
-        "     |\n"
-        "     -- subnet = 2001:db8::/48\n"
-        "     |\n"
-        "     -- pool (list instance)\n"
-        "         |\n"
-        "         -- start-address = 2001:db8::1\n"
-        "         |\n"
-        "         -- end-address = 2001:db8::100\n";
-    EXPECT_EQ(expected, tree->to_string(100));
-
     // Check it validates.
     EXPECT_NO_THROW(sess_->validate());
 }
 
-}; // end of anonymous namespace
+}  // namespace
index ad255e75ba80855ba5c445479d88856541cc9a45..253470049e00d003a53d64e50e4952573b2dac01 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2018 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2018-2021 Internet Systems Consortium, Inc. ("ISC")
 //
 // This Source Code Form is subject to the terms of the Mozilla Public
 // License, v. 2.0. If a copy of the MPL was not distributed with this
@@ -17,9 +17,7 @@ using namespace isc;
 using namespace isc::data;
 using namespace isc::yang;
 using namespace isc::yang::test;
-#ifndef HAVE_PRE_0_7_6_SYSREPO
 using namespace sysrepo;
-#endif
 
 namespace {
 
@@ -27,36 +25,38 @@ namespace {
 extern char const shared_networks[] = "shared networks";
 
 /// @brief Test fixture class for @ref TranslatorSharedNetworks.
-class TranslatorSharedNetworksTest :
+class TranslatorSharedNetworksTestKeaV4 :
     public GenericTranslatorTest<shared_networks, TranslatorSharedNetworks> {
 public:
 
     /// Constructor.
-    TranslatorSharedNetworksTest() { }
+    TranslatorSharedNetworksTestKeaV4() {
+        model_ = KEA_DHCP4_SERVER;
+    }
+};
+class TranslatorSharedNetworksTestKeaV6 :
+    public GenericTranslatorTest<shared_networks, TranslatorSharedNetworks> {
+public:
 
-    /// Destructor (does nothing).
-    virtual ~TranslatorSharedNetworksTest() { }
+    /// Constructor.
+    TranslatorSharedNetworksTestKeaV6() {
+        model_ = KEA_DHCP6_SERVER;
+    }
 };
 
 // This test verifies that an empty shared network list can be properly
 // translated from YANG to JSON.
-TEST_F(TranslatorSharedNetworksTest, getEmpty) {
-    useModel(KEA_DHCP4_SERVER);
-
+TEST_F(TranslatorSharedNetworksTestKeaV4, getEmpty) {
     // Get the shared network list and check if it is empty.
     const string& xpath = "/kea-dhcp4-server:config";
     ConstElementPtr networks;
     EXPECT_NO_THROW(networks = t_obj_->getSharedNetworks(xpath));
-    ASSERT_TRUE(networks);
-    ASSERT_EQ(Element::list, networks->getType());
-    EXPECT_EQ(0, networks->size());
+    ASSERT_FALSE(networks);
 }
 
 // This test verifies that one shared network can be properly
 // translated from YANG to JSON.
-TEST_F(TranslatorSharedNetworksTest, get) {
-    useModel(KEA_DHCP6_SERVER);
-
+TEST_F(TranslatorSharedNetworksTestKeaV6, get) {
     // Create the subnet 2001:db8::/48 #111 in shared network foo.
     const string& xpath = "/kea-dhcp6-server:config";
     const string& xnetwork = xpath + "/shared-network[name='foo']";
@@ -89,9 +89,7 @@ TEST_F(TranslatorSharedNetworksTest, get) {
 
 // This test verifies that an empty shared network list can be properly
 // translated from JSON to YANG.
-TEST_F(TranslatorSharedNetworksTest, setEmpty) {
-    useModel(KEA_DHCP4_SERVER);
-
+TEST_F(TranslatorSharedNetworksTestKeaV4, setEmpty) {
     // Set empty list.
     const string& xpath = "/kea-dhcp4-server:config";
     ConstElementPtr networks = Element::createList();
@@ -100,21 +98,12 @@ TEST_F(TranslatorSharedNetworksTest, setEmpty) {
     // Get it back.
     networks.reset();
     EXPECT_NO_THROW(networks = t_obj_->getSharedNetworks(xpath));
-    ASSERT_TRUE(networks);
-    ASSERT_EQ(Element::list, networks->getType());
-    EXPECT_EQ(0, networks->size());
-
-    // Check that the tree representation is empty.
-    S_Tree tree;
-    EXPECT_NO_THROW(tree = sess_->get_subtree("/kea-dhcp4-server:config"));
-    EXPECT_FALSE(tree);
+    ASSERT_FALSE(networks);
 }
 
 // This test verifies that one shared network can be properly
 // translated from JSON to YANG.
-TEST_F(TranslatorSharedNetworksTest, set) {
-    useModel(KEA_DHCP6_SERVER);
-
+TEST_F(TranslatorSharedNetworksTestKeaV6, set) {
     // Set one shared network.
     const string& xpath = "/kea-dhcp6-server:config";
     ElementPtr networks = Element::createList();
@@ -137,24 +126,6 @@ TEST_F(TranslatorSharedNetworksTest, set) {
     ASSERT_EQ(1, networks->size());
     EXPECT_TRUE(share->equals(*networks->get(0)));
 
-    // Check the tree representation.
-    S_Tree tree;
-    EXPECT_NO_THROW(tree = sess_->get_subtree("/kea-dhcp6-server:config"));
-    ASSERT_TRUE(tree);
-    string expected =
-        "kea-dhcp6-server:config (container)\n"
-        " |\n"
-        " -- shared-network (list instance)\n"
-        "     |\n"
-        "     -- name = foo\n"
-        "     |\n"
-        "     -- subnet6 (list instance)\n"
-        "         |\n"
-        "         -- id = 123\n"
-        "         |\n"
-        "         -- subnet = 2001:db8::/48\n";
-    EXPECT_EQ(expected, tree->to_string(100));
-
     // Check it validates.
     EXPECT_NO_THROW(sess_->validate());
 }
@@ -168,9 +139,7 @@ TEST_F(TranslatorSharedNetworksTest, set) {
 // shared-network "bar":
 //   - subnet1: 2001:db8:101::/48 (subnet-id 101)
 //   - subnet1: 2001:db8:102::/48 (subnet-id 102)
-TEST_F(TranslatorSharedNetworksTest, getList) {
-    useModel(KEA_DHCP6_SERVER);
-
+TEST_F(TranslatorSharedNetworksTestKeaV6, getList) {
     const string& xpath = "/kea-dhcp6-server:config";
 
     // Those two networks will be added.
@@ -237,4 +206,4 @@ TEST_F(TranslatorSharedNetworksTest, getList) {
     EXPECT_EQ(exp_both, networks->str());
 }
 
-}; // end of anonymous namespace
+}  // namespace
index f2d31fd1b4803a93819d290255454189cade0635..cc3459686f55f36281896388d85030d71363605d 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2018 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2018-2021 Internet Systems Consortium, Inc. ("ISC")
 //
 // This Source Code Form is subject to the terms of the Mozilla Public
 // License, v. 2.0. If a copy of the MPL was not distributed with this
@@ -17,9 +17,7 @@ using namespace isc;
 using namespace isc::data;
 using namespace isc::yang;
 using namespace isc::yang::test;
-#ifndef HAVE_PRE_0_7_6_SYSREPO
 using namespace sysrepo;
-#endif
 
 namespace {
 
@@ -27,51 +25,58 @@ namespace {
 extern char const subnet_list[] = "subnet list";
 
 /// @brief Test fixture class for @ref TranslatorSubnets.
-class TranslatorSubnetsTest :
+class TranslatorSubnetsTestKeaV4 :
     public GenericTranslatorTest<subnet_list, TranslatorSubnets> {
 public:
 
     /// Constructor.
-    TranslatorSubnetsTest() { }
+    TranslatorSubnetsTestKeaV4() {
+        model_ = KEA_DHCP4_SERVER;
+    }
+};
+class TranslatorSubnetsTestKeaV6 :
+    public GenericTranslatorTest<subnet_list, TranslatorSubnets> {
+public:
+
+    /// Constructor.
+    TranslatorSubnetsTestKeaV6() {
+        model_ = KEA_DHCP6_SERVER;
+    }
+};
+class TranslatorSubnetsTestIetfV6 :
+    public GenericTranslatorTest<subnet_list, TranslatorSubnets> {
+public:
 
-    /// Destructor (does nothing).
-    virtual ~TranslatorSubnetsTest() { }
+    /// Constructor.
+    TranslatorSubnetsTestIetfV6() {
+        model_ = IETF_DHCPV6_SERVER;
+    }
 };
 
 // This test verifies that an empty subnet list can be properly
 // translated from YANG to JSON using IETF model.
-TEST_F(TranslatorSubnetsTest, getEmptyIetf) {
-    useModel(IETF_DHCPV6_SERVER);
-
+TEST_F(TranslatorSubnetsTestIetfV6, getEmptyIetf) {
     // Get the subnet list and check if it is empty.
     const string& xpath =
         "/ietf-dhcpv6-server:server/server-config/network-ranges";
     ConstElementPtr subnets;
     EXPECT_NO_THROW(subnets = t_obj_->getSubnets(xpath));
-    ASSERT_TRUE(subnets);
-    ASSERT_EQ(Element::list, subnets->getType());
-    EXPECT_EQ(0, subnets->size());
+    ASSERT_FALSE(subnets);
 }
 
 // This test verifies that an empty subnet list can be properly
 // translated from YANG to JSON using Kea ad hoc model.
-TEST_F(TranslatorSubnetsTest, getEmptyKea) {
-    useModel(KEA_DHCP6_SERVER);
-
+TEST_F(TranslatorSubnetsTestKeaV6, getEmptyKea) {
     // Get the subnet list and check if it is empty.
     const string& xpath = "/kea-dhcp6-server:config";
     ConstElementPtr subnets;
     EXPECT_NO_THROW(subnets = t_obj_->getSubnets(xpath));
-    ASSERT_TRUE(subnets);
-    ASSERT_EQ(Element::list, subnets->getType());
-    EXPECT_EQ(0, subnets->size());
+    ASSERT_FALSE(subnets);
 }
 
 // This test verifies that one subnet can be properly
 // translated from YANG to JSON using IETF model.
-TEST_F(TranslatorSubnetsTest, getIetf) {
-    useModel(IETF_DHCPV6_SERVER);
-
+TEST_F(TranslatorSubnetsTestIetfV6, getIetf) {
     // Create the subnet 2001:db8::/48 #111.
     const string& xpath =
         "/ietf-dhcpv6-server:server/server-config/network-ranges";
@@ -84,7 +89,7 @@ TEST_F(TranslatorSubnetsTest, getIetf) {
     ConstElementPtr subnet;
     EXPECT_NO_THROW(subnet = t_obj_->getSubnet(xsub));
     ASSERT_TRUE(subnet);
-    EXPECT_EQ("{ \"id\": 111, \"pools\": [  ], "
+    EXPECT_EQ("{ \"id\": 111, "
               "\"subnet\": \"2001:db8::/48\" }",
               subnet->str());
 
@@ -94,14 +99,13 @@ TEST_F(TranslatorSubnetsTest, getIetf) {
     ASSERT_TRUE(subnets);
     ASSERT_EQ(Element::list, subnets->getType());
     ASSERT_EQ(1, subnets->size());
+    ASSERT_TRUE(subnets->get(0));
     EXPECT_TRUE(subnet->equals(*subnets->get(0)));
 }
 
 // This test verifies that one subnet can be properly
 // translated from YANG to JSON using Kea ad hoc model.
-TEST_F(TranslatorSubnetsTest, getKea) {
-    useModel(KEA_DHCP6_SERVER);
-
+TEST_F(TranslatorSubnetsTestKeaV6, getKea) {
     // Create the subnet 2001:db8::/48 #111.
     const string& xpath = "/kea-dhcp6-server:config";
     const string& xsub = xpath + "/subnet6[id='111']";
@@ -129,9 +133,7 @@ TEST_F(TranslatorSubnetsTest, getKea) {
 
 // This test verifies that one subnet with two pools can be properly
 // translated from YANG to JSON using IETF model.
-TEST_F(TranslatorSubnetsTest, getPoolsIetf) {
-    useModel(IETF_DHCPV6_SERVER);
-
+TEST_F(TranslatorSubnetsTestIetfV6, getPoolsIetf) {
     // Create the subnet 2001:db8::/48 #111.
     const string& xpath =
         "/ietf-dhcpv6-server:server/server-config/network-ranges";
@@ -151,10 +153,6 @@ TEST_F(TranslatorSubnetsTest, getPoolsIetf) {
     S_Val s_pool2(new Val("2001:db8::2:0/112"));
     EXPECT_NO_THROW(sess_->set_item(prefix2.c_str(), s_pool2));
 
-    // Uncomment this for debugging.
-    // S_Tree tree = sess_->get_subtree("/ietf-dhcpv6-server:server");
-    // cerr << "tree:\n" << tree->to_string(100) << "\n";
-
     // Get the subnet.
     ConstElementPtr subnet;
     EXPECT_NO_THROW(subnet = t_obj_->getSubnet(xsub));
@@ -185,9 +183,7 @@ TEST_F(TranslatorSubnetsTest, getPoolsIetf) {
 
 // This test verifies that one subnet with two pools can be properly
 // translated from YANG to JSON using Kea ad hoc model.
-TEST_F(TranslatorSubnetsTest, getPoolsKea) {
-    useModel(KEA_DHCP6_SERVER);
-
+TEST_F(TranslatorSubnetsTestKeaV6, getPoolsKea) {
     // Create the subnet 2001:db8::/48 #111.
     const string& xpath = "/kea-dhcp6-server:config";
     const string& xsub = xpath + "/subnet6[id='111']";
@@ -207,10 +203,6 @@ TEST_F(TranslatorSubnetsTest, getPoolsKea) {
     S_Val s_pool2;
     EXPECT_NO_THROW(sess_->set_item(prefix2.c_str(), s_pool2));
 
-    // Uncomment this for debugging.
-    // S_Tree tree = sess_->get_subtree("/kea-dhcp6-server:config");
-    // cerr << "tree:\n" << tree->to_string(100) << "\n";
-
     // Get the subnet.
     ConstElementPtr subnet;
     EXPECT_NO_THROW(subnet = t_obj_->getSubnet(xsub));
@@ -241,9 +233,7 @@ TEST_F(TranslatorSubnetsTest, getPoolsKea) {
 
 // This test verifies that an empty subnet list can be properly
 // translated from JSON to YANG using IETF model.
-TEST_F(TranslatorSubnetsTest, setEmptyIetf) {
-    useModel(IETF_DHCPV6_SERVER);
-
+TEST_F(TranslatorSubnetsTestIetfV6, setEmptyIetf) {
     // Set empty list.
     const string& xpath =
         "/ietf-dhcpv6-server:server/server-config/network-ranges";
@@ -253,21 +243,12 @@ TEST_F(TranslatorSubnetsTest, setEmptyIetf) {
     // Get it back.
     subnets.reset();
     EXPECT_NO_THROW(subnets = t_obj_->getSubnets(xpath));
-    ASSERT_TRUE(subnets);
-    ASSERT_EQ(Element::list, subnets->getType());
-    EXPECT_EQ(0, subnets->size());
-
-    // Check that the tree representation is empty.
-    S_Tree tree;
-    EXPECT_NO_THROW(tree = sess_->get_subtree("/ietf-dhcpv6-server:server"));
-    EXPECT_FALSE(tree);
+    ASSERT_FALSE(subnets);
 }
 
 // This test verifies that an empty subnet list can be properly
 // translated from JSON to YANG using Kea ad hoc model.
-TEST_F(TranslatorSubnetsTest, setEmptyKea) {
-    useModel(KEA_DHCP4_SERVER);
-
+TEST_F(TranslatorSubnetsTestKeaV4, setEmptyKea) {
     // Set empty list.
     const string& xpath = "/kea-dhcp4-server:config";
     ElementPtr subnets = Element::createList();
@@ -276,21 +257,12 @@ TEST_F(TranslatorSubnetsTest, setEmptyKea) {
     // Get it back.
     subnets.reset();
     EXPECT_NO_THROW(subnets = t_obj_->getSubnets(xpath));
-    ASSERT_TRUE(subnets);
-    ASSERT_EQ(Element::list, subnets->getType());
-    EXPECT_EQ(0, subnets->size());
-
-    // Check that the tree representation is empty.
-    S_Tree tree;
-    EXPECT_NO_THROW(tree = sess_->get_subtree("/kea-dhcp4-server:config"));
-    EXPECT_FALSE(tree);
+    ASSERT_FALSE(subnets);
 }
 
 // This test verifies that one subnet can be properly
 // translated from JSON to YANG using IETF model.
-TEST_F(TranslatorSubnetsTest, setIetf) {
-    useModel(IETF_DHCPV6_SERVER);
-
+TEST_F(TranslatorSubnetsTestIetfV6, setIetf) {
     // Set one subnet.
     const string& xpath =
         "/ietf-dhcpv6-server:server/server-config/network-ranges";
@@ -298,7 +270,6 @@ TEST_F(TranslatorSubnetsTest, setIetf) {
     ElementPtr subnet = Element::createMap();
     subnet->set("subnet", Element::create(string("2001:db8::/48")));
     subnet->set("id", Element::create(123));
-    subnet->set("pools", Element::createList());
     subnets->add(subnet);
     EXPECT_NO_THROW(t_obj_->setSubnets(xpath, subnets));
 
@@ -313,9 +284,7 @@ TEST_F(TranslatorSubnetsTest, setIetf) {
 
 // This test verifies that one subnet can be properly
 // translated from JSON to YANG using Kea ad hoc model.
-TEST_F(TranslatorSubnetsTest, setKea) {
-    useModel(KEA_DHCP4_SERVER);
-
+TEST_F(TranslatorSubnetsTestKeaV4, setKea) {
     // Set one subnet.
     const string& xpath = "/kea-dhcp4-server:config";
     ElementPtr subnets = Element::createList();
@@ -339,9 +308,7 @@ TEST_F(TranslatorSubnetsTest, setKea) {
 
 // This test verifies that one subnet with two pools can be properly
 // translated from JSON to YANG using IETF model.
-TEST_F(TranslatorSubnetsTest, setTwoIetf) {
-    useModel(IETF_DHCPV6_SERVER);
-
+TEST_F(TranslatorSubnetsTestIetfV6, setTwoIetf) {
     // Set one subnet.
     const string& xpath =
         "/ietf-dhcpv6-server:server/server-config/network-ranges";
@@ -371,57 +338,11 @@ TEST_F(TranslatorSubnetsTest, setTwoIetf) {
     ASSERT_EQ(Element::list, subnets->getType());
     ASSERT_EQ(1, subnets->size());
     EXPECT_TRUE(subnet->equals(*subnets->get(0)));
-
-    // Check the tree representation.
-    S_Tree tree;
-    EXPECT_NO_THROW(tree = sess_->get_subtree("/ietf-dhcpv6-server:server"));
-    ASSERT_TRUE(tree);
-    string expected =
-        "ietf-dhcpv6-server:server (container)\n"
-        " |\n"
-        " -- server-config (container)\n"
-        "     |\n"
-        "     -- network-ranges (container)\n"
-        "         |\n"
-        "         -- network-range (list instance)\n"
-        "             |\n"
-        "             -- network-range-id = 123\n"
-        "             |\n"
-        "             -- network-prefix = 2001:db8::/48\n"
-        "             |\n"
-        "             -- address-pools (container)\n"
-        "                 |\n"
-        "                 -- address-pool (list instance)\n"
-        "                 |   |\n"
-        "                 |   -- pool-id = 0\n"
-        "                 |   |\n"
-        "                 |   -- pool-prefix = 2001:db8::1:0/112\n"
-        "                 |   |\n"
-        "                 |   -- start-address = 2001:db8::1:0\n"
-        "                 |   |\n"
-        "                 |   -- end-address = 2001:db8::1:ffff\n"
-        "                 |   |\n"
-        "                 |   -- max-address-count = disabled\n"
-        "                 |\n"
-        "                 -- address-pool (list instance)\n"
-        "                     |\n"
-        "                     -- pool-id = 1\n"
-        "                     |\n"
-        "                     -- pool-prefix = 2001:db8::2:0/112\n"
-        "                     |\n"
-        "                     -- start-address = 2001:db8::2:0\n"
-        "                     |\n"
-        "                     -- end-address = 2001:db8::2:ffff\n"
-        "                     |\n"
-        "                     -- max-address-count = disabled\n";
-    EXPECT_EQ(expected, tree->to_string(100));
 }
 
 // This test verifies that one subnet with two pools can be properly
 // translated from JSON to YANG using Kea ad hoc model.
-TEST_F(TranslatorSubnetsTest, setTwoKea) {
-    useModel(KEA_DHCP4_SERVER);
-
+TEST_F(TranslatorSubnetsTestKeaV4, setTwoKea) {
     // Set one subnet.
     const string& xpath = "/kea-dhcp4-server:config";
     ElementPtr subnets = Element::createList();
@@ -451,36 +372,8 @@ TEST_F(TranslatorSubnetsTest, setTwoKea) {
     ASSERT_EQ(1, subnets->size());
     EXPECT_TRUE(subnet->equals(*subnets->get(0)));
 
-    // Check the tree representation.
-    S_Tree tree;
-    EXPECT_NO_THROW(tree = sess_->get_subtree("/kea-dhcp4-server:config"));
-    ASSERT_TRUE(tree);
-    string expected =
-        "kea-dhcp4-server:config (container)\n"
-        " |\n"
-        " -- subnet4 (list instance)\n"
-        "     |\n"
-        "     -- id = 123\n"
-        "     |\n"
-        "     -- pool (list instance)\n"
-        "     |   |\n"
-        "     |   -- start-address = 10.0.1.0\n"
-        "     |   |\n"
-        "     |   -- end-address = 10.0.1.15\n"
-        "     |   |\n"
-        "     |   -- prefix = 10.0.1.0/28\n"
-        "     |\n"
-        "     -- pool (list instance)\n"
-        "     |   |\n"
-        "     |   -- start-address = 10.0.1.200\n"
-        "     |   |\n"
-        "     |   -- end-address = 10.0.1.222\n"
-        "     |\n"
-        "     -- subnet = 10.0.1.0/24\n";
-    EXPECT_EQ(expected, tree->to_string(100));
-
     // Check it validates.
     EXPECT_NO_THROW(sess_->validate());
 }
 
-}; // end of anonymous namespace
+}  // namespace
index f47368ca1761abe61e6093f5d210d03a80e1ea19..3deed28eff0959142b3b94f6147a0d5742c08ee5 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2018-2019 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2018-2021 Internet Systems Consortium, Inc. ("ISC")
 //
 // This Source Code Form is subject to the terms of the Mozilla Public
 // License, v. 2.0. If a copy of the MPL was not distributed with this
@@ -6,25 +6,27 @@
 
 #include <config.h>
 
+#include <testutils/gtest_utils.h>
 #include <yang/translator.h>
 
 #include <boost/scoped_ptr.hpp>
+
 #include <gtest/gtest.h>
 
 using namespace std;
 using namespace isc;
 using namespace isc::data;
 using namespace isc::yang;
-#ifndef HAVE_PRE_0_7_6_SYSREPO
 using namespace sysrepo;
-#endif
+
+using libyang::S_Data_Node;
 
 namespace {
 
 // Test constructor.
 TEST(TranslatorBasicTest, constructor) {
     // Get a connection.
-    S_Connection conn(new Connection("translator unittests"));
+    S_Connection conn(std::make_shared<Connection>());
     // Get a session.
     S_Session sess(new Session(conn, SR_DS_CANDIDATE));
     // Get a translator object.
@@ -61,11 +63,7 @@ TEST(TranslatorBasicTest, valueFrom) {
 
     // Unsigned 8 bit integer.
     uint8_t u8(123);
-#ifdef HAVE_POST_0_7_7_SYSREPO
     s_val.reset(new Val(u8));
-#else
-    s_val.reset(new Val(u8, SR_UINT8_T));
-#endif
     EXPECT_NO_THROW(elem = TranslatorBasic::value(s_val));
     ASSERT_TRUE(elem);
     ASSERT_EQ(Element::integer, elem->getType());
@@ -74,11 +72,7 @@ TEST(TranslatorBasicTest, valueFrom) {
 
     // Unsigned 16 bit integer.
     uint16_t u16(12345);
-#ifdef HAVE_POST_0_7_7_SYSREPO
     s_val.reset(new Val(u16));
-#else
-    s_val.reset(new Val(u16, SR_UINT16_T));
-#endif
     EXPECT_NO_THROW(elem = TranslatorBasic::value(s_val));
     ASSERT_TRUE(elem);
     ASSERT_EQ(Element::integer, elem->getType());
@@ -87,11 +81,7 @@ TEST(TranslatorBasicTest, valueFrom) {
 
     // Unsigned 32 bit integer.
     uint32_t u32(123456789);
-#ifdef HAVE_POST_0_7_7_SYSREPO
     s_val.reset(new Val(u32));
-#else
-    s_val.reset(new Val(u32, SR_UINT32_T));
-#endif
     EXPECT_NO_THROW(elem = TranslatorBasic::value(s_val));
     ASSERT_TRUE(elem);
     ASSERT_EQ(Element::integer, elem->getType());
@@ -100,11 +90,7 @@ TEST(TranslatorBasicTest, valueFrom) {
 
     // Signed 8 bit integer.
     int8_t s8(-123);
-#ifdef HAVE_POST_0_7_7_SYSREPO
     s_val.reset(new Val(s8));
-#else
-    s_val.reset(new Val(s8, SR_INT8_T));
-#endif
     EXPECT_NO_THROW(elem = TranslatorBasic::value(s_val));
     ASSERT_TRUE(elem);
     ASSERT_EQ(Element::integer, elem->getType());
@@ -113,11 +99,7 @@ TEST(TranslatorBasicTest, valueFrom) {
 
     // Signed 16 bit integer.
     int16_t s16(-12345);
-#ifdef HAVE_POST_0_7_7_SYSREPO
     s_val.reset(new Val(s16));
-#else
-    s_val.reset(new Val(s16, SR_INT16_T));
-#endif
     EXPECT_NO_THROW(elem = TranslatorBasic::value(s_val));
     ASSERT_TRUE(elem);
     ASSERT_EQ(Element::integer, elem->getType());
@@ -126,11 +108,7 @@ TEST(TranslatorBasicTest, valueFrom) {
 
     // Signed 32 bit integer.
     int32_t s32(-123456789);
-#ifdef HAVE_POST_0_7_7_SYSREPO
     s_val.reset(new Val(s32));
-#else
-    s_val.reset(new Val(s32, SR_INT32_T));
-#endif
     EXPECT_NO_THROW(elem = TranslatorBasic::value(s_val));
     ASSERT_TRUE(elem);
     ASSERT_EQ(Element::integer, elem->getType());
@@ -174,26 +152,13 @@ TEST(TranslatorBasicTest, valueFrom) {
 // Test basic yang value to JSON using sysrepo test models.
 TEST(TranslatorBasicTest, getItem) {
     // Get a translator object to play with.
-    S_Connection conn(new Connection("translator unittests"));
+    S_Connection conn(std::make_shared<Connection>());
     S_Session sess(new Session(conn, SR_DS_CANDIDATE));
     boost::scoped_ptr<TranslatorBasic> t_obj;
     ASSERT_NO_THROW(t_obj.reset(new TranslatorBasic(sess, "")));
-
-    // Container.
-    string xpath = "/keatest-module:container/list";
     S_Val s_val;
-    EXPECT_NO_THROW(sess->set_item(xpath.c_str(), s_val));
     ConstElementPtr elem;
-    EXPECT_NO_THROW(elem = t_obj->getItem("/keatest-module:container"));
-    EXPECT_FALSE(elem);
-    elem.reset();
-
-    // List.
-    EXPECT_NO_THROW(elem = t_obj->getItem(xpath));
-    ASSERT_TRUE(elem);
-    ASSERT_EQ(Element::list, elem->getType());
-    EXPECT_EQ(0, elem->size());
-    elem.reset();
+    string xpath;
 
     // String.
     xpath = "/keatest-module:main/string";
@@ -218,11 +183,7 @@ TEST(TranslatorBasicTest, getItem) {
     // Unsigned 8 bit integer.
     xpath = "/keatest-module:main/ui8";
     uint8_t u8(8);
-#ifdef HAVE_POST_0_7_7_SYSREPO
     s_val.reset(new Val(u8));
-#else
-    s_val.reset(new Val(u8, SR_UINT8_T));
-#endif
     EXPECT_NO_THROW(sess->set_item(xpath.c_str(), s_val));
     EXPECT_NO_THROW(elem = t_obj->getItem(xpath));
     ASSERT_TRUE(elem);
@@ -233,11 +194,7 @@ TEST(TranslatorBasicTest, getItem) {
     // Unsigned 16 bit integer.
     xpath = "/keatest-module:main/ui16";
     uint16_t u16(16);
-#ifdef HAVE_POST_0_7_7_SYSREPO
     s_val.reset(new Val(u16));
-#else
-    s_val.reset(new Val(u16, SR_UINT16_T));
-#endif
     EXPECT_NO_THROW(sess->set_item(xpath.c_str(), s_val));
     EXPECT_NO_THROW(elem = t_obj->getItem(xpath));
     ASSERT_TRUE(elem);
@@ -248,11 +205,7 @@ TEST(TranslatorBasicTest, getItem) {
     // Unsigned 32 bit integer.
     xpath = "/keatest-module:main/ui32";
     uint32_t u32(32);
-#ifdef HAVE_POST_0_7_7_SYSREPO
     s_val.reset(new Val(u32));
-#else
-    s_val.reset(new Val(u32, SR_UINT32_T));
-#endif
     EXPECT_NO_THROW(sess->set_item(xpath.c_str(), s_val));
     EXPECT_NO_THROW(elem = t_obj->getItem(xpath));
     ASSERT_TRUE(elem);
@@ -263,11 +216,7 @@ TEST(TranslatorBasicTest, getItem) {
     // Signed 8 bit integer.
     xpath = "/keatest-module:main/i8";
     int8_t s8(8);
-#ifdef HAVE_POST_0_7_7_SYSREPO
     s_val.reset(new Val(s8));
-#else
-    s_val.reset(new Val(s8, SR_INT8_T));
-#endif
     EXPECT_NO_THROW(sess->set_item(xpath.c_str(), s_val));
     EXPECT_NO_THROW(elem = t_obj->getItem(xpath));
     ASSERT_TRUE(elem);
@@ -278,11 +227,7 @@ TEST(TranslatorBasicTest, getItem) {
     // Signed 16 bit integer.
     xpath = "/keatest-module:main/i16";
     int16_t s16(16);
-#ifdef HAVE_POST_0_7_7_SYSREPO
     s_val.reset(new Val(s16));
-#else
-    s_val.reset(new Val(s16, SR_INT16_T));
-#endif
     EXPECT_NO_THROW(sess->set_item(xpath.c_str(), s_val));
     EXPECT_NO_THROW(elem = t_obj->getItem(xpath));
     ASSERT_TRUE(elem);
@@ -293,11 +238,7 @@ TEST(TranslatorBasicTest, getItem) {
     // Signed 32 bit integer.
     xpath = "/keatest-module:main/i32";
     int32_t s32(32);
-#ifdef HAVE_POST_0_7_7_SYSREPO
     s_val.reset(new Val(s32));
-#else
-    s_val.reset(new Val(s32, SR_INT32_T));
-#endif
     EXPECT_NO_THROW(sess->set_item(xpath.c_str(), s_val));
     EXPECT_NO_THROW(elem = t_obj->getItem(xpath));
     ASSERT_TRUE(elem);
@@ -345,25 +286,13 @@ TEST(TranslatorBasicTest, getItem) {
 
     // Leaf-list: 1, 2 and 3.
     u8 = 1;
-#ifdef HAVE_POST_0_7_7_SYSREPO
     s_val.reset(new Val(u8));
-#else
-    s_val.reset(new Val(u8, SR_UINT8_T));
-#endif
     EXPECT_NO_THROW(sess->set_item(xpath.c_str(), s_val));
     u8 = 2;
-#ifdef HAVE_POST_0_7_7_SYSREPO
     s_val.reset(new Val(u8));
-#else
-    s_val.reset(new Val(u8, SR_UINT8_T));
-#endif
     EXPECT_NO_THROW(sess->set_item(xpath.c_str(), s_val));
     u8 = 3;
-#ifdef HAVE_POST_0_7_7_SYSREPO
     s_val.reset(new Val(u8));
-#else
-    s_val.reset(new Val(u8, SR_UINT8_T));
-#endif
     EXPECT_NO_THROW(sess->set_item(xpath.c_str(), s_val));
     EXPECT_NO_THROW(elem = t_obj->getItems(xpath));
     ASSERT_TRUE(elem);
@@ -384,8 +313,9 @@ TEST(TranslatorBasicTest, getItem) {
 
     // Not found.
     xpath = "/keatest-module:main/no_such_string";
-    EXPECT_NO_THROW(sess->delete_item(xpath.c_str()));
-    EXPECT_NO_THROW(elem = t_obj->getItem(xpath));
+    // sysrepo_exception: "Invalid argument" Â¯\_(ツ)_/¯
+    EXPECT_THROW(sess->delete_item(xpath.c_str()), sysrepo_exception);
+    EXPECT_THROW(elem = t_obj->getItem(xpath), SysrepoError);
     EXPECT_FALSE(elem);
     elem.reset();
 
@@ -395,7 +325,7 @@ TEST(TranslatorBasicTest, getItem) {
         elem = t_obj->getItem(xpath);
         ADD_FAILURE() << "expected exception";
     } catch (const SysrepoError& ex) {
-        EXPECT_EQ("sysrepo error getting item at 'null': Invalid argument",
+        EXPECT_EQ("sysrepo error getting item at 'null': libyang error",
                   string(ex.what()));
     } catch (const std::exception& ex) {
         ADD_FAILURE() << "unexpected exception with: " << ex.what();
@@ -519,7 +449,7 @@ TEST(TranslatorBasicTest, valueTo) {
 // Test JSON to  basic yang value using sysrepo test models.
 TEST(TranslatorBasicTest, setItem) {
     // Get a translator object to play with.
-    S_Connection conn(new Connection("translator unittests"));
+    S_Connection conn(std::make_shared<Connection>());
     S_Session sess(new Session(conn, SR_DS_CANDIDATE));
     boost::scoped_ptr<TranslatorBasic> t_obj;
     ASSERT_NO_THROW(t_obj.reset(new TranslatorBasic(sess, "")));
@@ -531,17 +461,8 @@ TEST(TranslatorBasicTest, setItem) {
     EXPECT_THROW(t_obj->setItem(xpath, elem, SR_CONTAINER_PRESENCE_T),
                  NotImplemented);
 
-    // List.
-    xpath = "/keatest-module:container/list";
-    elem = Element::createList();
-    EXPECT_NO_THROW(t_obj->setItem(xpath, elem, SR_LIST_T));
-    S_Val s_val;
-    EXPECT_NO_THROW(s_val = sess->get_item(xpath.c_str()));
-    ASSERT_TRUE(s_val);
-    ASSERT_EQ(SR_LIST_T, s_val->type());
-    s_val.reset();
-
     // String.
+    S_Val s_val;
     xpath = "/keatest-module:main/string";
     elem = Element::create(string("str"));
     EXPECT_NO_THROW(t_obj->setItem(xpath, elem, SR_STRING_T));
@@ -664,28 +585,27 @@ TEST(TranslatorBasicTest, setItem) {
 
     // Leaf-list.
     xpath = "/keatest-module:main/numbers";
-    S_Vals s_vals;
-    EXPECT_NO_THROW(s_vals = sess->get_items(xpath.c_str()));
-    EXPECT_FALSE(s_vals);
-    s_vals.reset();
+    S_Data_Node data_node;
+    EXPECT_NO_THROW(data_node = sess->get_subtree(xpath.c_str()));
+    EXPECT_FALSE(data_node);
+    data_node.reset();
 
     // Fill it.
-    elem = Element::create(1);
-    EXPECT_NO_THROW(t_obj->setItem(xpath, elem, SR_UINT8_T));
-    elem = Element::create(2);
-    EXPECT_NO_THROW(t_obj->setItem(xpath, elem, SR_UINT8_T));
-    elem = Element::create(3);
-    EXPECT_NO_THROW(t_obj->setItem(xpath, elem, SR_UINT8_T));
-    EXPECT_NO_THROW(s_vals = sess->get_items(xpath.c_str()));
-    ASSERT_TRUE(s_vals);
-    EXPECT_EQ(3, s_vals->val_cnt());
-    s_vals.reset();
+    sess->set_item_str(xpath.c_str(), "1");
+    sess->set_item_str(xpath.c_str(), "2");
+    sess->set_item_str(xpath.c_str(), "3");
+    sess->apply_changes();
+    // sysrepo_exception: "Invalid argument" Â¯\_(ツ)_/¯
+    EXPECT_THROW(data_node = sess->get_subtree(xpath.c_str()),
+        sysrepo_exception);
+    EXPECT_FALSE(data_node);
+    data_node.reset();
 
     // Clean it.
     EXPECT_NO_THROW(t_obj->delItem(xpath));
-    EXPECT_NO_THROW(s_vals = sess->get_items(xpath.c_str()));
-    EXPECT_FALSE(s_vals);
-    s_vals.reset();
+    EXPECT_NO_THROW(data_node = sess->get_subtree(xpath.c_str()));
+    EXPECT_FALSE(data_node);
+    data_node.reset();
 
     // Bad xpath.
     xpath = "/keatest-module:main/no_such_string";
@@ -695,7 +615,7 @@ TEST(TranslatorBasicTest, setItem) {
         ADD_FAILURE() << "expected exception";
     } catch (const SysrepoError& ex) {
         string expected = "sysrepo error setting item '\"str\"' at '" +
-            xpath + "': Request contains unknown element";
+            xpath + "': Invalid argument";
         EXPECT_EQ(expected, string(ex.what()));
     } catch (const std::exception& ex) {
         ADD_FAILURE() << "unexpected exception with: " << ex.what();
@@ -706,56 +626,55 @@ TEST(TranslatorBasicTest, setItem) {
     elem = Element::create(true);
     try {
         t_obj->setItem(xpath, elem, SR_BOOL_T);
-        ADD_FAILURE() << "expected exception";
     } catch (const SysrepoError& ex) {
-        string expected = "sysrepo error setting item 'true' at '" +
-            xpath + "': Invalid argument";
-        EXPECT_EQ(expected, string(ex.what()));
+        ADD_FAILURE() << "unexpected exception with: " << ex.what();
     } catch (const std::exception& ex) {
         ADD_FAILURE() << "unexpected exception with: " << ex.what();
     }
 
+    // In sysrepo 1.x, set_item() is based on set_item_str() which sets the
+    // value in textual format. After setting a value with SR_BOOL_T, it's value
+    // is now "true". :)
+    elem = t_obj->getItem(xpath);
+    ASSERT_TRUE(elem);
+    EXPECT_EQ(elem->getType(), Element::string);
+    EXPECT_EQ(elem->str(), "\"true\"");
+
     // Delete (twice).
     xpath = "/keatest-module:main/string";
     EXPECT_NO_THROW(s_val = sess->get_item(xpath.c_str()));
     EXPECT_TRUE(s_val);
     s_val.reset();
     EXPECT_NO_THROW(t_obj->delItem(xpath));
-    EXPECT_NO_THROW(s_val = sess->get_item(xpath.c_str()));
+    // sysrepo_exception: "Item not found" Â¯\_(ツ)_/¯
+    EXPECT_THROW(s_val = sess->get_item(xpath.c_str()), sysrepo_exception);
     EXPECT_FALSE(s_val);
     EXPECT_NO_THROW(t_obj->delItem(xpath));
 }
 
-// Test yang list iteration.
+// Test yang list item retrieval.
 TEST(TranslatorBasicTest, list) {
     // Get a translator object to play with.
-    S_Connection conn(new Connection("translator unittests"));
+    S_Connection conn(std::make_shared<Connection>());
     S_Session sess(new Session(conn, SR_DS_CANDIDATE));
     boost::scoped_ptr<TranslatorBasic> t_obj;
     ASSERT_NO_THROW(t_obj.reset(new TranslatorBasic(sess, "")));
+    string xpath;
 
     // Empty list.
-    S_Iter_Value iter;
-    EXPECT_NO_THROW(iter = t_obj->getIter("/keatest-module:container/list"));
-    ASSERT_TRUE(iter);
-    string xpath;
-    EXPECT_NO_THROW(xpath = t_obj->getNext(iter));
-    EXPECT_TRUE(xpath.empty());
+    ElementPtr element;
+    EXPECT_NO_THROW(element = t_obj->getItem("/keatest-module:container/list"));
+    EXPECT_FALSE(element);
+    element.reset();
 
     // Retried with a filled list.
     xpath = "/keatest-module:container/list[key1='key1'][key2='key2']/leaf";
     S_Val s_val(new Val("Leaf value"));
     EXPECT_NO_THROW(sess->set_item(xpath.c_str(), s_val));
-    EXPECT_NO_THROW(iter = t_obj->getIter("/keatest-module:container/list"));
-    ASSERT_TRUE(iter);
-    EXPECT_NO_THROW(xpath = t_obj->getNext(iter));
-    EXPECT_EQ("/keatest-module:container/list[key1='key1'][key2='key2']",
-              xpath);
-    EXPECT_NO_THROW(xpath = t_obj->getNext(iter));
-    EXPECT_TRUE(xpath.empty());
-
-    // Not found: same as empty because sr_get_items_iter() translates
-    // SR_ERR_NOT_FOUND by SR_ERR_OK...
+    EXPECT_NO_THROW(element = t_obj->getItem("/keatest-module:container/list"));
+    ASSERT_TRUE(element);
+    EXPECT_NO_THROW(element = t_obj->getItem("/keatest-module:container/list[key1='key1'][key2='key2']"));
+    ASSERT_TRUE(element);
 }
 
-}; // end of anonymous namespace
+} // anonymous namespace
index 2bd374009d113f7859e6dd0a80af364a8f5d73d9..fa6d0a13d27119e775f81334f9413c8ebc55ad17 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2018-2019 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2018-2021 Internet Systems Consortium, Inc. ("ISC")
 //
 // This Source Code Form is subject to the terms of the Mozilla Public
 // License, v. 2.0. If a copy of the MPL was not distributed with this
@@ -6,18 +6,19 @@
 
 #include <config.h>
 
+#include <testutils/gtest_utils.h>
 #include <yang/tests/yang_configs.h>
+#include <yang/tests/sysrepo_setup.h>
 
 #include <gtest/gtest.h>
+
 #include <sstream>
 
 using namespace std;
 using namespace isc;
 using namespace isc::yang;
 using namespace isc::yang::test;
-#ifndef HAVE_PRE_0_7_6_SYSREPO
 using namespace sysrepo;
-#endif
 
 namespace {
 
@@ -61,93 +62,83 @@ TEST(YangReprTest, item) {
 
 // Test get with test module.
 TEST(YangReprTest, getTest) {
+    SysrepoSetup::cleanSharedMemory();
 
     // Get a translator object to play with.
-    S_Connection conn(new Connection("utils unittests"));
+    S_Connection conn(std::make_shared<Connection>());
     S_Session sess(new Session(conn, SR_DS_CANDIDATE));
 
+    // Cleanup.
+    EXPECT_NO_THROW(sess->delete_item("/keatest-module:container"));
+    EXPECT_NO_THROW(sess->apply_changes());
+    EXPECT_NO_THROW(sess->delete_item("/keatest-module:main"));
+    EXPECT_NO_THROW(sess->apply_changes());
+
     // Fill the test module.
     string xpath;
     S_Val s_val;
 
-    // Create a list.
-    xpath = "/keatest-module:container/list";
-    EXPECT_NO_THROW(sess->set_item(xpath.c_str(), s_val));
-
     xpath = "/keatest-module:main/string";
     s_val.reset(new Val("str", SR_STRING_T));
     EXPECT_NO_THROW(sess->set_item(xpath.c_str(), s_val));
+    EXPECT_NO_THROW(sess->apply_changes());
 
     xpath = "/keatest-module:main/boolean";
     s_val.reset(new Val(true, SR_BOOL_T));
     EXPECT_NO_THROW(sess->set_item(xpath.c_str(), s_val));
+    EXPECT_NO_THROW(sess->apply_changes());
 
     xpath = "/keatest-module:main/ui8";
     uint8_t u8(8);
-#ifdef HAVE_POST_0_7_7_SYSREPO
     s_val.reset(new Val(u8));
-#else
-    s_val.reset(new Val(u8, SR_UINT8_T));
-#endif
     EXPECT_NO_THROW(sess->set_item(xpath.c_str(), s_val));
+    EXPECT_NO_THROW(sess->apply_changes());
 
     xpath = "/keatest-module:main/ui16";
     uint16_t u16(16);
-#ifdef HAVE_POST_0_7_7_SYSREPO
     s_val.reset(new Val(u16));
-#else
-    s_val.reset(new Val(u16, SR_UINT16_T));
-#endif
     EXPECT_NO_THROW(sess->set_item(xpath.c_str(), s_val));
+    EXPECT_NO_THROW(sess->apply_changes());
 
     xpath = "/keatest-module:main/ui32";
     uint32_t u32(32);
-#ifdef HAVE_POST_0_7_7_SYSREPO
     s_val.reset(new Val(u32));
-#else
-    s_val.reset(new Val(u32, SR_UINT32_T));
-#endif
     EXPECT_NO_THROW(sess->set_item(xpath.c_str(), s_val));
+    EXPECT_NO_THROW(sess->apply_changes());
 
     xpath = "/keatest-module:main/i8";
     int8_t s8(8);
-#ifdef HAVE_POST_0_7_7_SYSREPO
     s_val.reset(new Val(s8));
-#else
-    s_val.reset(new Val(s8, SR_INT8_T));
-#endif
     EXPECT_NO_THROW(sess->set_item(xpath.c_str(), s_val));
+    EXPECT_NO_THROW(sess->apply_changes());
 
     xpath = "/keatest-module:main/i16";
     int16_t s16(16);
-#ifdef HAVE_POST_0_7_7_SYSREPO
     s_val.reset(new Val(s16));
-#else
-    s_val.reset(new Val(s16, SR_INT16_T));
-#endif
     EXPECT_NO_THROW(sess->set_item(xpath.c_str(), s_val));
+    EXPECT_NO_THROW(sess->apply_changes());
 
     xpath = "/keatest-module:main/i32";
     int32_t s32(32);
-#ifdef HAVE_POST_0_7_7_SYSREPO
     s_val.reset(new Val(s32));
-#else
-    s_val.reset(new Val(s32, SR_INT32_T));
-#endif
     EXPECT_NO_THROW(sess->set_item(xpath.c_str(), s_val));
+    EXPECT_NO_THROW(sess->apply_changes());
 
     xpath = "/keatest-module:main/id_ref";
     s_val.reset(new Val("keatest-module:id_1", SR_IDENTITYREF_T));
     EXPECT_NO_THROW(sess->set_item(xpath.c_str(), s_val));
+    EXPECT_NO_THROW(sess->apply_changes());
 
     xpath = "/keatest-module:main/enum";
     s_val.reset(new Val("maybe", SR_ENUM_T));
     EXPECT_NO_THROW(sess->set_item(xpath.c_str(), s_val));
+    EXPECT_NO_THROW(sess->apply_changes());
 
     // Binary.
     xpath = "/keatest-module:main/raw";
     s_val.reset(new Val("Zm9vYmFy", SR_BINARY_T));
     EXPECT_NO_THROW(sess->set_item(xpath.c_str(), s_val));
+    EXPECT_NO_THROW(sess->apply_changes());
 
     // Get it.
     YangRepr repr(testModel);
@@ -160,10 +151,18 @@ TEST(YangReprTest, getTest) {
 
 // This test verifies that errors are handled properly.
 TEST(YangReprTrest, getTestErrors) {
+    SysrepoSetup::cleanSharedMemory();
+
     // Get a translator object to play with.
-    S_Connection conn(new Connection("utils unittests"));
+    S_Connection conn(std::make_shared<Connection>());
     S_Session sess(new Session(conn, SR_DS_CANDIDATE));
 
+    // Cleanup.
+    EXPECT_NO_THROW(sess->delete_item("/keatest-module:container"));
+    EXPECT_NO_THROW(sess->apply_changes());
+    EXPECT_NO_THROW(sess->delete_item("/keatest-module:main"));
+    EXPECT_NO_THROW(sess->apply_changes());
+
     // Get it.
     YangRepr repr(testModel);
     YRTree tree;
@@ -172,42 +171,53 @@ TEST(YangReprTrest, getTestErrors) {
     // Verify.
     EXPECT_TRUE(repr.verify(testTree, sess, cerr));
 
-    // Some error messages will be displayed.
-    cout << "Some error messages will be displayed. Please ignore." << endl;
-
-    // Change a path.
+    // Change a path. Remove final 'm'.
     YRTree badpath = testTree;
-    badpath[14].xpath_ = "/keatest-module:kernel-module"; // removed final 's'
+    string xpath("/keatest-module:main/enum");
+    YRItem node(badpath.at(xpath));
+    node.xpath_ = "/keatest-module:main/enu";
+    badpath.erase(xpath);
+    badpath.emplace(xpath, node);
     EXPECT_FALSE(repr.verify(badpath, sess, cerr));
 
-    // Change a value.
+    // Change a value from "str" to "Str".
     YRTree badvalue = testTree;
-    badvalue[3].value_ = "Str"; // was "str"
+    xpath = "/keatest-module:main/string";
+    badvalue.at(xpath).value_ = "Str";
     EXPECT_FALSE(repr.verify(badvalue, sess, cerr));
 
-    // Change a type.
+    // Change a type from SR_INT32_T to SR_UINT32_T.
     YRTree badtype = testTree;
-    badtype[10].type_ = SR_UINT32_T; // was SR_INT32_T
+    xpath = "/keatest-module:main/i32";
+    badtype.at(xpath).type_ = SR_UINT32_T;
     EXPECT_FALSE(repr.verify(badtype, sess, cerr));
 
     // Add a record at the end.
     YRTree badmissing = testTree;
-    const string& xpathpc = "/keatest-module:presence-container";
-    badmissing.push_back(YRItem(xpathpc, "", SR_CONTAINER_PRESENCE_T, false));
+    xpath = "/keatest-module:presence-container";
+    badmissing.emplace(xpath, YRItem(xpath, "", SR_CONTAINER_PRESENCE_T, false));
     EXPECT_FALSE(repr.verify(badmissing, sess, cerr));
 
     // Delete last record.
     YRTree badextra = testTree;
-    badextra.pop_back();
+    badextra.erase("/keatest-module:kernel-modules");
     EXPECT_FALSE(repr.verify(badextra, sess, cerr));
 }
 
 // Test set with test module.
 TEST(YangReprTest, setTest) {
+    SysrepoSetup::cleanSharedMemory();
+
     // Get a translator object to play with.
-    S_Connection conn(new Connection("utils unittests"));
+    S_Connection conn(std::make_shared<Connection>());
     S_Session sess(new Session(conn, SR_DS_CANDIDATE));
 
+    // Cleanup.
+    EXPECT_NO_THROW(sess->delete_item("/keatest-module:container"));
+    EXPECT_NO_THROW(sess->apply_changes());
+    EXPECT_NO_THROW(sess->delete_item("/keatest-module:main"));
+    EXPECT_NO_THROW(sess->apply_changes());
+
     // Set the module content.
     YangRepr repr(testModel);
     EXPECT_NO_THROW(repr.set(testTree, sess));
@@ -223,10 +233,20 @@ TEST(YangReprTest, setTest) {
 /// @param model name of the model to be verified against.
 /// @param tree tree to be verified.
 void sanityCheckConfig(const std::string& model, const YRTree& tree) {
+    SysrepoSetup::cleanSharedMemory();
+
     // Get a translator object to play with.
-    S_Connection conn(new Connection("utils unittests"));
+    S_Connection conn(std::make_shared<Connection>());
     S_Session sess(new Session(conn, SR_DS_CANDIDATE));
 
+    // Cleanup.
+    TranslatorBasic translator(sess, model);
+    std::string toplevel_node("config");
+    if (model == IETF_DHCPV6_SERVER) {
+        toplevel_node = "server";
+    }
+    translator.delItem("/" + model + ":" + toplevel_node);
+
     // Get it.
     YangRepr repr(model);
 
@@ -235,7 +255,8 @@ void sanityCheckConfig(const std::string& model, const YRTree& tree) {
     bool result = false;
     EXPECT_NO_THROW(result = repr.verify(tree, sess, cerr))
         << " for model " << model;
-    EXPECT_TRUE(result);
+    EXPECT_TRUE(result)
+        << " for model " << model;
 }
 
 // This is test environment sanity check. It verifies that all configuration
@@ -246,4 +267,4 @@ TEST(YangReprTest, verifyConfigs) {
     }
 }
 
-}; // end of anonymous namespace
+}  // namespace
index c0b2f845d982bc0f3870ced35880a5b69db76e0b..e3254b93c66de1f36beed3edece0e0e96274cbcb 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2018 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2018-2021 Internet Systems Consortium, Inc. ("ISC")
 //
 // This Source Code Form is subject to the terms of the Mozilla Public
 // License, v. 2.0. If a copy of the MPL was not distributed with this
@@ -16,9 +16,8 @@ namespace test {
 
 /// @brief The test module from sysrepo tests.
 const std::string testModel = "keatest-module";
-const YRTree testTree = {
-    { "/keatest-module:container",      "", SR_CONTAINER_T, false },
-    { "/keatest-module:container/list", "", SR_LIST_T,      true },
+const YRTree testTree = YangRepr::buildTreeFromVector({
+    { "/keatest-module:container", "", SR_CONTAINER_T, false },
     { "/keatest-module:main", "", SR_CONTAINER_T, false },
     { "/keatest-module:main/string", "str", SR_STRING_T, true },
     { "/keatest-module:main/boolean", "true", SR_BOOL_T, true },
@@ -33,29 +32,26 @@ const YRTree testTree = {
     { "/keatest-module:main/enum", "maybe", SR_ENUM_T, true },
     { "/keatest-module:main/raw", "Zm9vYmFy", SR_BINARY_T, true },
     { "/keatest-module:kernel-modules", "", SR_CONTAINER_T, false }
-};
+});
 
 /// @brief A subnet with two pools with ietf-dhcpv6-server model.
 const std::string subnetTwoPoolsModelIetf6 = IETF_DHCPV6_SERVER;
-const YRTree subnetTwoPoolsTreeIetf6 = {
+const YRTree subnetTwoPoolsTreeIetf6 = YangRepr::buildTreeFromVector({
     { "/ietf-dhcpv6-server:server", "", SR_CONTAINER_PRESENCE_T, false },
     { "/ietf-dhcpv6-server:server/server-config", "", SR_CONTAINER_T, false },
     { "/ietf-dhcpv6-server:server/server-config/network-ranges",
       "", SR_CONTAINER_T, false },
     { "/ietf-dhcpv6-server:server/server-config/network-ranges/"
-      "network-range[network-range-id='111']", "", SR_LIST_T, true },
+      "network-range[network-range-id='111']", "", SR_LIST_T, false },
     { "/ietf-dhcpv6-server:server/server-config/network-ranges/"
       "network-range[network-range-id='111']/network-range-id",
       "111", SR_UINT32_T, false },
     { "/ietf-dhcpv6-server:server/server-config/network-ranges/"
       "network-range[network-range-id='111']/network-prefix",
       "2001:db8::/48", SR_STRING_T, true },
-    { "/ietf-dhcpv6-server:server/server-config/network-ranges/"
-      "network-range[network-range-id='111']/address-pools",
-      "", SR_CONTAINER_T, false },
     { "/ietf-dhcpv6-server:server/server-config/network-ranges/"
       "network-range[network-range-id='111']/address-pools/"
-      "address-pool[pool-id='0']", "", SR_LIST_T, true },
+      "address-pool[pool-id='0']", "", SR_LIST_T, false },
     { "/ietf-dhcpv6-server:server/server-config/network-ranges/"
       "network-range[network-range-id='111']/address-pools/"
       "address-pool[pool-id='0']/pool-id", "0", SR_UINT32_T, false },
@@ -77,7 +73,7 @@ const YRTree subnetTwoPoolsTreeIetf6 = {
       "disabled", SR_ENUM_T, true },
     { "/ietf-dhcpv6-server:server/server-config/network-ranges/"
       "network-range[network-range-id='111']/address-pools/"
-      "address-pool[pool-id='1']", "", SR_LIST_T, true },
+      "address-pool[pool-id='1']", "", SR_LIST_T, false },
     { "/ietf-dhcpv6-server:server/server-config/network-ranges/"
       "network-range[network-range-id='111']/address-pools/"
       "address-pool[pool-id='1']/pool-id", "1", SR_UINT32_T, false },
@@ -96,30 +92,52 @@ const YRTree subnetTwoPoolsTreeIetf6 = {
     { "/ietf-dhcpv6-server:server/server-config/network-ranges/"
       "network-range[network-range-id='111']/address-pools/"
       "address-pool[pool-id='1']/max-address-count",
-      "disabled", SR_ENUM_T, true }
-};
+      "disabled", SR_ENUM_T, true },
+    { "/ietf-dhcpv6-server:server/server-config/serv-attributes/duid/type-code",
+      "65535", SR_UINT16_T, false },
+    { "/ietf-dhcpv6-server:server/server-config/network-ranges/"
+      "network-range[network-range-id='111']/address-pools",
+      "", SR_CONTAINER_T, false },
+    { "/ietf-dhcpv6-server:server/server-config/network-ranges/"
+      "network-range[network-range-id='111']/pd-pools",
+      "", SR_CONTAINER_T, false },
+    { "/ietf-dhcpv6-server:server/server-config/network-ranges/"
+      "network-range[network-range-id='111']/host-reservations",
+      "", SR_CONTAINER_T, false },
+    { "/ietf-dhcpv6-server:server/server-config/serv-attributes",
+      "", SR_CONTAINER_T, false },
+    { "/ietf-dhcpv6-server:server/server-config/serv-attributes/duid",
+      "", SR_CONTAINER_T, false },
+    { "/ietf-dhcpv6-server:server/server-config/serv-attributes/lease-storage",
+      "", SR_CONTAINER_T, false },
+    { "/ietf-dhcpv6-server:server/server-config/serv-attributes/vendor-info",
+      "", SR_CONTAINER_T, false },
+    { "/ietf-dhcpv6-server:server/server-config/option-sets",
+      "", SR_CONTAINER_T, false },
+    { "/ietf-dhcpv6-server:server/server-config/relay-opaque-paras",
+      "", SR_CONTAINER_T, false },
+    { "/ietf-dhcpv6-server:server/server-config/rsoo-enabled-options",
+      "", SR_CONTAINER_T, false },
+});
 
 /// @brief A subnet with timers with ietf-dhcpv6-server model.
 const std::string subnetTimersModel = IETF_DHCPV6_SERVER;
-const YRTree subnetTimersIetf6 = {
+const YRTree subnetTimersIetf6 = YangRepr::buildTreeFromVector({
     { "/ietf-dhcpv6-server:server", "", SR_CONTAINER_PRESENCE_T, false },
     { "/ietf-dhcpv6-server:server/server-config", "", SR_CONTAINER_T, false },
     { "/ietf-dhcpv6-server:server/server-config/network-ranges",
       "", SR_CONTAINER_T, false },
     { "/ietf-dhcpv6-server:server/server-config/network-ranges/"
-      "network-range[network-range-id='111']", "", SR_LIST_T, true },
+      "network-range[network-range-id='111']", "", SR_LIST_T, false },
     { "/ietf-dhcpv6-server:server/server-config/network-ranges/"
       "network-range[network-range-id='111']/network-range-id",
       "111", SR_UINT32_T, false },
     { "/ietf-dhcpv6-server:server/server-config/network-ranges/"
       "network-range[network-range-id='111']/network-prefix",
       "2001:db8::/48", SR_STRING_T, true },
-    { "/ietf-dhcpv6-server:server/server-config/network-ranges/"
-      "network-range[network-range-id='111']/address-pools",
-      "", SR_CONTAINER_T, false },
     { "/ietf-dhcpv6-server:server/server-config/network-ranges/"
       "network-range[network-range-id='111']/address-pools/"
-      "address-pool[pool-id='0']", "", SR_LIST_T, true },
+      "address-pool[pool-id='0']", "", SR_LIST_T, false },
     { "/ietf-dhcpv6-server:server/server-config/network-ranges/"
       "network-range[network-range-id='111']/address-pools/"
       "address-pool[pool-id='0']/pool-id", "0", SR_UINT32_T, false },
@@ -147,7 +165,7 @@ const YRTree subnetTimersIetf6 = {
       "disabled", SR_ENUM_T, true },
     { "/ietf-dhcpv6-server:server/server-config/network-ranges/"
       "network-range[network-range-id='111']/address-pools/"
-      "address-pool[pool-id='1']", "", SR_LIST_T, true },
+      "address-pool[pool-id='1']", "", SR_LIST_T, false },
     { "/ietf-dhcpv6-server:server/server-config/network-ranges/"
       "network-range[network-range-id='111']/address-pools/"
       "address-pool[pool-id='1']/pool-id", "1", SR_UINT32_T, false },
@@ -172,13 +190,38 @@ const YRTree subnetTimersIetf6 = {
     { "/ietf-dhcpv6-server:server/server-config/network-ranges/"
       "network-range[network-range-id='111']/address-pools/"
       "address-pool[pool-id='1']/max-address-count",
-      "disabled", SR_ENUM_T, true }
-};
+      "disabled", SR_ENUM_T, true },
+    { "/ietf-dhcpv6-server:server/server-config/serv-attributes/duid/type-code",
+      "65535", SR_UINT16_T, false },
+    { "/ietf-dhcpv6-server:server/server-config/network-ranges/"
+      "network-range[network-range-id='111']/address-pools",
+      "", SR_CONTAINER_T, false },
+    { "/ietf-dhcpv6-server:server/server-config/network-ranges/"
+      "network-range[network-range-id='111']/pd-pools",
+      "", SR_CONTAINER_T, false },
+    { "/ietf-dhcpv6-server:server/server-config/network-ranges/"
+      "network-range[network-range-id='111']/host-reservations",
+      "", SR_CONTAINER_T, false },
+    { "/ietf-dhcpv6-server:server/server-config/serv-attributes",
+      "", SR_CONTAINER_T, false },
+    { "/ietf-dhcpv6-server:server/server-config/serv-attributes/duid",
+      "", SR_CONTAINER_T, false },
+    { "/ietf-dhcpv6-server:server/server-config/serv-attributes/lease-storage",
+      "", SR_CONTAINER_T, false },
+    { "/ietf-dhcpv6-server:server/server-config/serv-attributes/vendor-info",
+      "", SR_CONTAINER_T, false },
+    { "/ietf-dhcpv6-server:server/server-config/option-sets",
+      "", SR_CONTAINER_T, false },
+    { "/ietf-dhcpv6-server:server/server-config/relay-opaque-paras",
+      "", SR_CONTAINER_T, false },
+    { "/ietf-dhcpv6-server:server/server-config/rsoo-enabled-options",
+      "", SR_CONTAINER_T, false },
+});
 
 /// @brief A subnet with two pools with ietf-dhcpv6-server model
 /// which validates.
 const std::string validModelIetf6 = IETF_DHCPV6_SERVER;
-const YRTree validTreeIetf6 = {
+const YRTree validTreeIetf6 = YangRepr::buildTreeFromVector({
     { "/ietf-dhcpv6-server:server", "", SR_CONTAINER_PRESENCE_T, false },
     { "/ietf-dhcpv6-server:server/server-config", "", SR_CONTAINER_T, false },
     { "/ietf-dhcpv6-server:server/server-config/serv-attributes",
@@ -190,14 +233,14 @@ const YRTree validTreeIetf6 = {
     { "/ietf-dhcpv6-server:server/server-config/option-sets",
       "", SR_CONTAINER_T, false },
     { "/ietf-dhcpv6-server:server/server-config/option-sets"
-      "/option-set[option-set-id='0']", "", SR_LIST_T, true },
+      "/option-set[option-set-id='0']", "", SR_LIST_T, false },
     { "/ietf-dhcpv6-server:server/server-config/option-sets"
       "/option-set[option-set-id='0']/option-set-id",
-      "0", SR_UINT32_T, false },
+      "0", SR_UINT32_T, true },
     { "/ietf-dhcpv6-server:server/server-config/network-ranges",
       "", SR_CONTAINER_T, false },
     { "/ietf-dhcpv6-server:server/server-config/network-ranges/"
-      "network-range[network-range-id='111']", "", SR_LIST_T, true },
+      "network-range[network-range-id='111']", "", SR_LIST_T, false },
     { "/ietf-dhcpv6-server:server/server-config/network-ranges/"
       "network-range[network-range-id='111']/network-range-id",
       "111", SR_UINT32_T, false },
@@ -207,12 +250,9 @@ const YRTree validTreeIetf6 = {
     { "/ietf-dhcpv6-server:server/server-config/network-ranges/"
       "network-range[network-range-id='111']/network-prefix",
       "2001:db8::/48", SR_STRING_T, true },
-    { "/ietf-dhcpv6-server:server/server-config/network-ranges/"
-      "network-range[network-range-id='111']/pd-pools",
-      "", SR_CONTAINER_T, false },
     { "/ietf-dhcpv6-server:server/server-config/network-ranges/"
       "network-range[network-range-id='111']/pd-pools/"
-      "pd-pool[pool-id='0']", "", SR_LIST_T, true },
+      "pd-pool[pool-id='0']", "", SR_LIST_T, false },
     { "/ietf-dhcpv6-server:server/server-config/network-ranges/"
       "network-range[network-range-id='111']/pd-pools/"
       "pd-pool[pool-id='0']/pool-id", "0", SR_UINT32_T, false },
@@ -248,7 +288,7 @@ const YRTree validTreeIetf6 = {
       "disabled", SR_ENUM_T, true },
     { "/ietf-dhcpv6-server:server/server-config/network-ranges/"
       "network-range[network-range-id='111']/pd-pools/"
-      "pd-pool[pool-id='1']", "", SR_LIST_T, true },
+      "pd-pool[pool-id='1']", "", SR_LIST_T, false },
     { "/ietf-dhcpv6-server:server/server-config/network-ranges/"
       "network-range[network-range-id='111']/pd-pools/"
       "pd-pool[pool-id='1']/pool-id", "1", SR_UINT32_T, false },
@@ -281,20 +321,45 @@ const YRTree validTreeIetf6 = {
     { "/ietf-dhcpv6-server:server/server-config/network-ranges/"
       "network-range[network-range-id='111']/pd-pools/"
       "pd-pool[pool-id='1']/max-pd-space-utilization",
-      "disabled", SR_ENUM_T, true }
-};
+      "disabled", SR_ENUM_T, true },
+    { "/ietf-dhcpv6-server:server/server-config/serv-attributes/duid/type-code",
+      "65535", SR_UINT16_T, false },
+    { "/ietf-dhcpv6-server:server/server-config/network-ranges/"
+      "network-range[network-range-id='111']/address-pools",
+      "", SR_CONTAINER_T, false },
+    { "/ietf-dhcpv6-server:server/server-config/network-ranges/"
+      "network-range[network-range-id='111']/pd-pools",
+      "", SR_CONTAINER_T, false },
+    { "/ietf-dhcpv6-server:server/server-config/network-ranges/"
+      "network-range[network-range-id='111']/host-reservations",
+      "", SR_CONTAINER_T, false },
+    { "/ietf-dhcpv6-server:server/server-config/serv-attributes",
+      "", SR_CONTAINER_T, false },
+    { "/ietf-dhcpv6-server:server/server-config/serv-attributes/duid",
+      "", SR_CONTAINER_T, false },
+    { "/ietf-dhcpv6-server:server/server-config/serv-attributes/lease-storage",
+      "", SR_CONTAINER_T, false },
+    { "/ietf-dhcpv6-server:server/server-config/serv-attributes/vendor-info",
+      "", SR_CONTAINER_T, false },
+    { "/ietf-dhcpv6-server:server/server-config/option-sets",
+      "", SR_CONTAINER_T, false },
+    { "/ietf-dhcpv6-server:server/server-config/relay-opaque-paras",
+      "", SR_CONTAINER_T, false },
+    { "/ietf-dhcpv6-server:server/server-config/rsoo-enabled-options",
+      "", SR_CONTAINER_T, false },
+});
 
 /// @brief A subnet with a pool and option data lists with
 /// kea-dhcp4-server:config model.
 const std::string subnetOptionsModelKeaDhcp4 = KEA_DHCP4_SERVER;
-const YRTree subnetOptionsTreeKeaDhcp4 = {
+const YRTree subnetOptionsTreeKeaDhcp4 = YangRepr::buildTreeFromVector({
     { "/kea-dhcp4-server:config", "", SR_CONTAINER_T, false },
     { "/kea-dhcp4-server:config/subnet4[id='111']", "",
-      SR_LIST_T, true },
+      SR_LIST_T, false },
     { "/kea-dhcp4-server:config/subnet4[id='111']/id",
       "111", SR_UINT32_T, false },
     { "/kea-dhcp4-server:config/subnet4[id='111']/"
-      "option-data[code='100'][space='dns']", "", SR_LIST_T, true },
+      "option-data[code='100'][space='dns']", "", SR_LIST_T, false },
     { "/kea-dhcp4-server:config/subnet4[id='111']/"
       "option-data[code='100'][space='dns']/code",
       "100", SR_UINT8_T, false },
@@ -312,7 +377,7 @@ const YRTree subnetOptionsTreeKeaDhcp4 = {
       "false", SR_BOOL_T, true },
     { "/kea-dhcp4-server:config/subnet4[id='111']/"
       "pool[start-address='10.0.1.0'][end-address='10.0.1.255']",
-      "", SR_LIST_T, true },
+      "", SR_LIST_T, false },
     { "/kea-dhcp4-server:config/subnet4[id='111']/"
       "pool[start-address='10.0.1.0'][end-address='10.0.1.255']/start-address",
       "10.0.1.0", SR_STRING_T, false },
@@ -323,21 +388,33 @@ const YRTree subnetOptionsTreeKeaDhcp4 = {
       "pool[start-address='10.0.1.0'][end-address='10.0.1.255']/prefix",
       "10.0.1.0/24", SR_STRING_T, true },
     { "/kea-dhcp4-server:config/subnet4[id='111']/subnet",
-      "10.0.0.0/8", SR_STRING_T, true }
-};
+      "10.0.0.0/8", SR_STRING_T, true },
+    { "/kea-dhcp4-server:config/expired-leases-processing",
+      "", SR_CONTAINER_T, false },
+    { "/kea-dhcp4-server:config/dhcp-ddns",
+      "", SR_CONTAINER_T, false },
+    { "/kea-dhcp4-server:config/config-control",
+      "", SR_CONTAINER_T, false },
+    { "/kea-dhcp4-server:config/sanity-checks",
+      "", SR_CONTAINER_T, false },
+    { "/kea-dhcp4-server:config/interfaces-config",
+      "", SR_CONTAINER_T, false },
+    { "/kea-dhcp4-server:config/subnet4[id='111']/relay",
+      "", SR_CONTAINER_T, false },
+});
 
 /// @brief A subnet with a pool and option data lists with
 /// kea-dhcp6-server:config model.
 const std::string subnetOptionsModelKeaDhcp6 = KEA_DHCP6_SERVER;
-const YRTree subnetOptionsTreeKeaDhcp6 = {
+const YRTree subnetOptionsTreeKeaDhcp6 = YangRepr::buildTreeFromVector({
     { "/kea-dhcp6-server:config", "", SR_CONTAINER_T, false },
     { "/kea-dhcp6-server:config/subnet6[id='111']", "",
-      SR_LIST_T, true },
+      SR_LIST_T, false },
     { "/kea-dhcp6-server:config/subnet6[id='111']/id",
       "111", SR_UINT32_T, false },
     { "/kea-dhcp6-server:config/subnet6[id='111']/"
       "pool[start-address='2001:db8::1:0'][end-address='2001:db8::1:ffff']",
-      "", SR_LIST_T, true },
+      "", SR_LIST_T, false },
     { "/kea-dhcp6-server:config/subnet6[id='111']/"
       "pool[start-address='2001:db8::1:0'][end-address='2001:db8::1:ffff']/"
       "start-address", "2001:db8::1:0", SR_STRING_T, false },
@@ -350,7 +427,7 @@ const YRTree subnetOptionsTreeKeaDhcp6 = {
     { "/kea-dhcp6-server:config/subnet6[id='111']/"
       "pool[start-address='2001:db8::1:0'][end-address='2001:db8::1:ffff']/"
       "option-data[code='100'][space='dns']",
-      "", SR_LIST_T, true },
+      "", SR_LIST_T, false },
     { "/kea-dhcp6-server:config/subnet6[id='111']/"
       "pool[start-address='2001:db8::1:0'][end-address='2001:db8::1:ffff']/"
       "option-data[code='100'][space='dns']/code",
@@ -372,48 +449,112 @@ const YRTree subnetOptionsTreeKeaDhcp6 = {
       "option-data[code='100'][space='dns']/always-send",
       "false", SR_BOOL_T, true },
     { "/kea-dhcp6-server:config/subnet6[id='111']/subnet",
-      "2001:db8::/48", SR_STRING_T, true }
-};
+      "2001:db8::/48", SR_STRING_T, true },
+    { "/kea-dhcp6-server:config/expired-leases-processing",
+      "", SR_CONTAINER_T, false },
+    { "/kea-dhcp6-server:config/dhcp-ddns",
+      "", SR_CONTAINER_T, false },
+    { "/kea-dhcp6-server:config/config-control",
+      "", SR_CONTAINER_T, false },
+    { "/kea-dhcp6-server:config/sanity-checks",
+      "", SR_CONTAINER_T, false },
+    { "/kea-dhcp6-server:config/interfaces-config",
+      "", SR_CONTAINER_T, false },
+    { "/kea-dhcp6-server:config/subnet6[id='111']/relay",
+      "", SR_CONTAINER_T, false },
+});
 
 /// @brief Example from the design document.
 const std::string designExampleModel = IETF_DHCPV6_SERVER;
-const YRTree designExampleTree = {
+const YRTree designExampleTree = YangRepr::buildTreeFromVector({
     { "/ietf-dhcpv6-server:server", "", SR_CONTAINER_PRESENCE_T, false },
     { "/ietf-dhcpv6-server:server/server-config", "", SR_CONTAINER_T, false },
     { "/ietf-dhcpv6-server:server/server-config/network-ranges",
       "", SR_CONTAINER_T, false },
     { "/ietf-dhcpv6-server:server/server-config/network-ranges/"
-      "network-range[network-range-id='1']", "", SR_LIST_T, true },
+      "network-range[network-range-id='1']", "", SR_LIST_T, false },
     { "/ietf-dhcpv6-server:server/server-config/network-ranges/"
       "network-range[network-range-id='1']/network-range-id",
       "1", SR_UINT32_T, false },
     { "/ietf-dhcpv6-server:server/server-config/network-ranges/"
       "network-range[network-range-id='1']/network-description",
       "example", SR_STRING_T, true },
-    { "/ietf-dhcpv6-server:server/server-config/network-ranges/"
-      "network-range[network-range-id='1']/network-prefix",
-      "2001:db8:20:b00::/56", SR_STRING_T, true },
     { "/ietf-dhcpv6-server:server/server-config/network-ranges/"
       "network-range[network-range-id='1']/pd-pools",
       "", SR_CONTAINER_T, false },
     { "/ietf-dhcpv6-server:server/server-config/network-ranges/"
-      "network-range[network-range-id='1']/pd-pools/"
-      "pd-pool[pool-id='0']", "", SR_LIST_T, true },
+      "network-range[network-range-id='1']/pd-pools/pd-pool[pool-id='0']",
+      "", SR_LIST_T, false },
     { "/ietf-dhcpv6-server:server/server-config/network-ranges/"
-      "network-range[network-range-id='1']/pd-pools/"
-      "pd-pool[pool-id='0']/pool-id", "0", SR_UINT32_T, false },
+      "network-range[network-range-id='1']/pd-pools/pd-pool[pool-id='0']"
+      "/pool-id",
+      "0", SR_UINT32_T, true },
     { "/ietf-dhcpv6-server:server/server-config/network-ranges/"
-      "network-range[network-range-id='1']/pd-pools/"
-      "pd-pool[pool-id='0']/prefix",
+      "network-range[network-range-id='1']/pd-pools/pd-pool[pool-id='0']"
+      "/prefix",
       "2001:db8:20:b00::/57", SR_STRING_T, true },
     { "/ietf-dhcpv6-server:server/server-config/network-ranges/"
-      "network-range[network-range-id='1']/pd-pools/"
-      "pd-pool[pool-id='0']/prefix-length", "57", SR_UINT8_T, true },
+      "network-range[network-range-id='1']/pd-pools/pd-pool[pool-id='0']"
+      "/prefix-length",
+      "57", SR_UINT8_T, true },
     { "/ietf-dhcpv6-server:server/server-config/network-ranges/"
       "network-range[network-range-id='1']/pd-pools/"
       "pd-pool[pool-id='0']/max-pd-space-utilization",
-      "disabled", SR_ENUM_T, true }
-};
+      "disabled", SR_ENUM_T, true },
+    { "/ietf-dhcpv6-server:server/server-config/network-ranges/"
+      "network-range[network-range-id='1']/network-prefix",
+      "2001:db8:20:b00::/56", SR_STRING_T, true },
+    { "/ietf-dhcpv6-server:server/server-config/serv-attributes/duid/type-code",
+      "65535", SR_UINT16_T, false },
+    { "/ietf-dhcpv6-server:server/server-config/network-ranges/"
+      "network-range[network-range-id='1']/host-reservations",
+      "", SR_CONTAINER_T, false },
+    { "/ietf-dhcpv6-server:server/server-config/serv-attributes",
+      "", SR_CONTAINER_T, false },
+    { "/ietf-dhcpv6-server:server/server-config/serv-attributes/duid",
+      "", SR_CONTAINER_T, false },
+    { "/ietf-dhcpv6-server:server/server-config/serv-attributes/lease-storage",
+      "", SR_CONTAINER_T, false },
+    { "/ietf-dhcpv6-server:server/server-config/serv-attributes/vendor-info",
+      "", SR_CONTAINER_T, false },
+    { "/ietf-dhcpv6-server:server/server-config/option-sets",
+      "", SR_CONTAINER_T, false },
+    { "/ietf-dhcpv6-server:server/server-config/relay-opaque-paras",
+      "", SR_CONTAINER_T, false },
+    { "/ietf-dhcpv6-server:server/server-config/rsoo-enabled-options",
+      "", SR_CONTAINER_T, false },
+    { "/ietf-dhcpv6-server:server/server-config/network-ranges/"
+      "network-range[network-range-id='1']/address-pools",
+      "", SR_CONTAINER_T, false },
+});
+
+const YRTree emptyTreeKeaDhcp4 = YangRepr::buildTreeFromVector({
+    { "/kea-dhcp4-server:config", "", SR_CONTAINER_T, false },
+    { "/kea-dhcp4-server:config/expired-leases-processing",
+      "", SR_CONTAINER_T, false },
+    { "/kea-dhcp4-server:config/dhcp-ddns",
+      "", SR_CONTAINER_T, false },
+    { "/kea-dhcp4-server:config/config-control",
+      "", SR_CONTAINER_T, false },
+    { "/kea-dhcp4-server:config/sanity-checks",
+      "", SR_CONTAINER_T, false },
+    { "/kea-dhcp4-server:config/interfaces-config",
+      "", SR_CONTAINER_T, false },
+});
+
+const YRTree emptyTreeKeaDhcp6 = YangRepr::buildTreeFromVector({
+    { "/kea-dhcp6-server:config", "", SR_CONTAINER_T, false },
+    { "/kea-dhcp6-server:config/expired-leases-processing",
+      "", SR_CONTAINER_T, false },
+    { "/kea-dhcp6-server:config/dhcp-ddns",
+      "", SR_CONTAINER_T, false },
+    { "/kea-dhcp6-server:config/config-control",
+      "", SR_CONTAINER_T, false },
+    { "/kea-dhcp6-server:config/sanity-checks",
+      "", SR_CONTAINER_T, false },
+    { "/kea-dhcp6-server:config/interfaces-config",
+      "", SR_CONTAINER_T, false },
+});
 
 /// @brief Set of example configurations.
 const std::vector<std::pair<std::string, YRTree> > test_configs =
@@ -427,8 +568,8 @@ const std::vector<std::pair<std::string, YRTree> > test_configs =
     { designExampleModel,          designExampleTree }
 };
 
-}; // end of namespace isc::yang::test
-}; // end of namespace isc::yang
-}; // end of namespace isc
+}  // namespace test
+}  // namespace yang
+}  // namespace isc
 
 #endif // ISC_YANG_CONFIGS_H
index 16f322b1373b7109a87dc63241a2b953fbce1d68..16fa33b82af9fe48d4dd61b7c4aa725e1d3f5333 100644 (file)
@@ -7,15 +7,14 @@
 #include <config.h>
 
 #include <yang/testutils/translator_test.h>
+
 #include <boost/lexical_cast.hpp>
+
 #include <sstream>
 
 using namespace std;
 using namespace isc::data;
-#ifndef HAVE_PRE_0_7_6_SYSREPO
 using namespace sysrepo;
-#endif
-
 namespace isc {
 namespace yang {
 namespace test {
@@ -113,16 +112,12 @@ YangRepr::Tree
 YangRepr::get(S_Session session) const {
     Tree result;
     try {
-        const string& xpath0 = "/" + model_ + ":*//.";
         TranslatorBasic tb(session, model_);
-        S_Iter_Value iter = tb.getIter(xpath0);
-        for (;;) {
-            const string& xpath = tb.getNext(iter);
-            if (xpath.empty()) {
-                break;
-            }
-            result.push_back(YangReprItem::get(xpath, session));
-        }
+        string const xpath0("/" + model_ + ":*//.");
+        tb.forAll(xpath0, [&](libyang::S_Data_Node const& node) {
+            string const& xpath(node->path());
+            result.emplace(xpath, YangReprItem::get(xpath, session));
+        });
     } catch (const sysrepo_exception& ex) {
         isc_throw(SysrepoError,
                   "sysrepo error in  YangRepr::getTree: " << ex.what());
@@ -133,31 +128,47 @@ YangRepr::get(S_Session session) const {
 bool
 YangRepr::verify(const Tree& expected, S_Session session,
                  ostream& errs) const {
-    const Tree& got = get(session);
-    for (size_t i = 0; (i < expected.size()) && (i < got.size()); ++i) {
-        if (expected[i] == got[i]) {
+    bool result(true);
+    const Tree& received = get(session);
+    for (auto const& kv : received) {
+        string const& xpath(kv.first);
+        YangReprItem const& received_node(kv.second);
+
+        auto iterator(expected.find(xpath));
+        if (iterator == expected.end()) {
+            errs << "received " << received_node << ", but was not expected"
+                 << endl;
+            result = false;
             continue;
         }
-        errs << "expected[" << i << "]: " << expected[i] << endl;
-        errs << "got[" << i << "]: " << got[i] << endl;
-        return (false);
-    }
-    if (expected.size() == got.size()) {
-        return (true);
+
+        YangReprItem const expected_node(iterator->second);
+        if (expected_node != received_node) {
+            errs << "expected " << expected_node << ", but received "
+                 << received_node << endl;
+            result = false;
+        }
     }
-    if (expected.size() > got.size()) {
-        errs << "missings " << (expected.size() - got.size());
-        errs << " beginning by:" << endl << expected[got.size()] << endl;
-    } else {
-        errs << "extras " << (got.size() - expected.size());
-        errs << " beginning by:" << endl << got[expected.size()] << endl;
+
+    for (auto const& kv : expected) {
+        string const& xpath(kv.first);
+        YangReprItem const& expected_node(kv.second);
+
+        auto iterator(received.find(xpath));
+        if (iterator == received.end()) {
+            errs << "expected " << expected_node << ", but was not received"
+                 << endl;
+            result = false;
+        }
     }
-    return (false);
+
+    return result;
 }
 
 void
 YangRepr::set(const Tree& tree, S_Session session) const {
-    for (auto item : tree) {
+    for (auto const& kv : tree) {
+        YangReprItem const& item(kv.second);
         if (!item.settable_) {
             continue;
         }
@@ -170,6 +181,8 @@ YangRepr::set(const Tree& tree, S_Session session) const {
                           "YangRepr::set called for a container");
 
             case SR_LIST_T:
+                isc_throw(NotImplemented,
+                          "YangRepr::set called for a list");
                 break;
 
             case SR_STRING_T:
@@ -192,11 +205,7 @@ YangRepr::set(const Tree& tree, S_Session session) const {
             case SR_UINT8_T:
                 try {
                     uint8_t u8 = boost::lexical_cast<unsigned>(item.value_);
-#ifdef HAVE_POST_0_7_7_SYSREPO
                     s_val.reset(new Val(u8));
-#else
-                    s_val.reset(new Val(u8, SR_UINT8_T));
-#endif
                 } catch (const boost::bad_lexical_cast&) {
                     isc_throw(BadValue,
                               "'" << item.value_ << "' not an uint8");
@@ -206,11 +215,7 @@ YangRepr::set(const Tree& tree, S_Session session) const {
             case SR_UINT16_T:
                 try {
                     uint16_t u16 = boost::lexical_cast<uint16_t>(item.value_);
-#ifdef HAVE_POST_0_7_7_SYSREPO
                     s_val.reset(new Val(u16));
-#else
-                    s_val.reset(new Val(u16, SR_UINT16_T));
-#endif
                 } catch (const boost::bad_lexical_cast&) {
                     isc_throw(BadValue,
                               "'" << item.value_ << "' not an uint16");
@@ -220,11 +225,7 @@ YangRepr::set(const Tree& tree, S_Session session) const {
             case SR_UINT32_T:
                 try {
                     uint32_t u32 = boost::lexical_cast<uint32_t>(item.value_);
-#ifdef HAVE_POST_0_7_7_SYSREPO
                     s_val.reset(new Val(u32));
-#else
-                    s_val.reset(new Val(u32, SR_UINT32_T));
-#endif
                 } catch (const boost::bad_lexical_cast&) {
                     isc_throw(BadValue,
                               "'" << item.value_ << "' not an uint32");
@@ -234,11 +235,7 @@ YangRepr::set(const Tree& tree, S_Session session) const {
             case SR_INT8_T:
                 try {
                     int8_t i8 = boost::lexical_cast<int>(item.value_);
-#ifdef HAVE_POST_0_7_7_SYSREPO
                     s_val.reset(new Val(i8));
-#else
-                    s_val.reset(new Val(i8, SR_INT8_T));
-#endif
                 } catch (const boost::bad_lexical_cast&) {
                     isc_throw(BadValue,
                               "'" << item.value_ << "' not an int8");
@@ -248,11 +245,7 @@ YangRepr::set(const Tree& tree, S_Session session) const {
             case SR_INT16_T:
                 try {
                     int16_t i16 = boost::lexical_cast<int16_t>(item.value_);
-#ifdef HAVE_POST_0_7_7_SYSREPO
                     s_val.reset(new Val(i16));
-#else
-                    s_val.reset(new Val(i16, SR_INT16_T));
-#endif
                 } catch (const boost::bad_lexical_cast&) {
                     isc_throw(BadValue,
                               "'" << item.value_ << "' not an int16");
@@ -262,11 +255,7 @@ YangRepr::set(const Tree& tree, S_Session session) const {
             case SR_INT32_T:
                 try {
                     int32_t i32 = boost::lexical_cast<int32_t>(item.value_);
-#ifdef HAVE_POST_0_7_7_SYSREPO
                     s_val.reset(new Val(i32));
-#else
-                    s_val.reset(new Val(i32, SR_INT32_T));
-#endif
                 } catch (const boost::bad_lexical_cast&) {
                     isc_throw(BadValue,
                               "'" << item.value_ << "' not an int32");
@@ -295,10 +284,11 @@ YangRepr::set(const Tree& tree, S_Session session) const {
                       << ", error: " << ex.what());
         }
     }
+    session->apply_changes();
 }
 
 bool
-YangRepr::validate(S_Session session, std::ostream& errs) const {
+YangRepr::validate(S_Session session, ostream& errs) const {
     try {
         // Try to validate. If it succeeds, then we're done here.
         session->validate();
@@ -308,37 +298,25 @@ YangRepr::validate(S_Session session, std::ostream& errs) const {
     }
     try {
         // If we get here, it means the validate() threw exceptions.
-        S_Errors s_errors = session->get_last_errors();
-        if (!s_errors) {
-
+        S_Errors errors(session->get_error());
+        if (!errors) {
             // This is really weird. An exception was thrown, but
             // get_last_errors() didn't return anything. Maybe we're out of
             // memory or something?
             errs << "no errors" << endl;
             return (false);
         }
-        size_t cnt = s_errors->error_cnt();
-        errs << "got " << cnt << " errors" << endl;
-        for (size_t i = 0; i < cnt; ++i) {
-            S_Error s_error = s_errors->error(i);
-            if (!s_error) {
+        size_t const count(errors->error_cnt());
+        errs << "got " << count << " errors" << endl;
+        for (size_t i = 0; i < count ; ++i) {
+            const char* message(errors->message(i));
+            const char* xpath(errors->xpath(i));
+            if (!message || !xpath) {
                 continue;
             }
-            const char* xpath = s_error->xpath();
-            const char* message = s_error->message();
-            if (!xpath || !message) {
-                continue;
-            }
-            // Bug in sysrepo returning message for xpath().
-            if (xpath == message) {
-                errs << message << endl;
-            } else {
-                errs << message << endl
-                     << "At " << xpath << endl;
-            }
+            errs << message << " at " << xpath << endl;
         }
     } catch (const std::exception& ex) {
-        // Bug in sysrepo rethrowing the last error when trying to get it.
         errs << "double error " << ex.what();
     }
     return (false);
@@ -431,12 +409,13 @@ ostream& operator<<(ostream& os, const YangRepr::YangReprItem& item) {
 }
 
 ostream& operator<<(ostream& os, const YangRepr::Tree& tree) {
-    for (auto item : tree) {
+    for (auto const& kv : tree) {
+        YangRepr::YangReprItem const& item(kv.second);
         os << item << endl;
     }
     return (os);
 }
 
-}; // end of namespace isc::yang::test
-}; // end of namespace isc::yang
-}; // end of namespace isc
+}  // namespace test
+}  // namespace yang
+}  // namespace isc
index 4fc829962090922271f6bd1d80e63fe468b60986..4ee50964bfd4b3a39b8b1f3485d7a63bac591dc3 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2018 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2018-2021 Internet Systems Consortium, Inc. ("ISC")
 //
 // This Source Code Form is subject to the terms of the Mozilla Public
 // License, v. 2.0. If a copy of the MPL was not distributed with this
@@ -46,12 +46,8 @@ public:
         /// @param xpath The xpath of an element to be retrieved.
         /// @param session Sysrepo session.
         /// @return YangReprItem instance representing configuration parameter.
-#ifndef HAVE_PRE_0_7_6_SYSREPO
         static YangReprItem get(const std::string& xpath,
                                 sysrepo::S_Session session);
-#else
-        static YangReprItem get(const std::string& xpath, S_Session session);
-#endif
 
         /// @brief The xpath.
         std::string xpath_;
@@ -85,16 +81,17 @@ public:
     };
 
     /// @brief Tree type.
-    typedef std::vector<YangReprItem> Tree;
+    ///
+    /// Indexed by xpath so that we can check against an entry received from
+    /// sysrepo which has empirically proven to not come in a certain order
+    /// starting with sysrepo 1.x. Relying on the order would have made a linear
+    /// data structure more fitting.
+    using Tree = std::unordered_map<std::string, YangReprItem>;
 
     /// @brief Get tree from session.
     ///
     /// @param session Sysrepo session.
-#ifndef HAVE_PRE_0_7_6_SYSREPO
     Tree get(sysrepo::S_Session session) const;
-#else
-    Tree get(S_Session session) const;
-#endif
 
     /// @brief Verifies a tree.
     ///
@@ -103,13 +100,8 @@ public:
     /// @param errs Error stream.
     /// @return true if verification succeeds, false with errors displayed.
     /// on errs if it fails.
-#ifndef HAVE_PRE_0_7_6_SYSREPO
     bool verify(const Tree& expected, sysrepo::S_Session session,
                 std::ostream& errs) const;
-#else
-    bool verify(const Tree& expected, S_Session session,
-                std::ostream& errs) const;
-#endif
 
     /// @brief Sets specified tree in a sysrepo.
     ///
@@ -117,11 +109,7 @@ public:
     ///
     /// @param tree The tree to install.
     /// @param session Sysrepo session.
-#ifndef HAVE_PRE_0_7_6_SYSREPO
     void set(const Tree& tree, sysrepo::S_Session session) const;
-#else
-    void set(const Tree& tree, S_Session session) const;
-#endif
 
     /// @brief Validate.
     ///
@@ -129,11 +117,20 @@ public:
     /// @param errs Error stream.
     /// @return True if validation succeeds, false with errors displayed
     /// on errs if it fails.
-#ifndef HAVE_PRE_0_7_6_SYSREPO
     bool validate(sysrepo::S_Session session, std::ostream& errs) const;
-#else
-    bool validate(S_Session session, std::ostream& errs) const;
-#endif
+
+    /// @brief Convenience function that indexes a collection of items by xpath.
+    ///
+    /// @param v the input vector
+    ///
+    /// @return the output map
+    static Tree buildTreeFromVector(std::vector<YangReprItem> const& v) {
+        Tree tree;
+        for (YangReprItem const& item : v) {
+            tree.emplace(item.xpath_, item);
+        }
+        return tree;
+    }
 
     /// @brief The model name.
     std::string model_;
@@ -154,8 +151,8 @@ std::ostream& operator<<(std::ostream& os, const YRItem& item);
 /// @brief Overrides standard output operator for @c Tree object.
 std::ostream& operator<<(std::ostream& os, const YRTree& tree);
 
-}; // end of namespace isc::yang::test
-}; // end of namespace isc::yang
-}; // end of namespace isc
+}  // namespace test
+}  // namespace yang
+}  // namespace isc
 
 #endif // ISC_TRANSLATOR_TEST_H
index 531be3569eb7e89b5becac195ce2999c7e588b55..9a2d48a2da48d5f4ad67307cbc46d8004c5ef9ff 100644 (file)
@@ -13,9 +13,7 @@
 using namespace std;
 using namespace isc::data;
 using namespace isc::util::encode;
-#ifndef HAVE_PRE_0_7_6_SYSREPO
 using namespace sysrepo;
-#endif
 
 namespace {
 
@@ -48,11 +46,7 @@ TranslatorBasic::~TranslatorBasic() {
 }
 
 ElementPtr
-#ifndef HAVE_PRE_0_7_6_SYSREPO
 TranslatorBasic::value(sysrepo::S_Val s_val) {
-#else
-TranslatorBasic::value(S_Val s_val) {
-#endif
     if (!s_val) {
         isc_throw(BadValue, "value called with null");
     }
@@ -113,6 +107,10 @@ TranslatorBasic::getItem(const string& xpath) {
     try {
         s_val = session_->get_item(xpath.c_str());
     } catch (const sysrepo_exception& ex) {
+        if (std::string(ex.what()).find("Item not found") != string::npos) {
+            // The YANG configuration node was not there.
+            return nullptr;
+        }
         isc_throw(SysrepoError, "sysrepo error getting item at '" << xpath
                   << "': " << ex.what());
     }
@@ -124,23 +122,21 @@ TranslatorBasic::getItem(const string& xpath) {
 
 ElementPtr
 TranslatorBasic::getItems(const string& xpath) {
-    S_Vals s_vals;
+    S_Vals s_vals(getValuesFromItems(xpath));
+    if (!s_vals) {
+        return (ElementPtr());
+    }
+    ElementPtr result(Element::createList());
     try {
-        s_vals = session_->get_items(xpath.c_str());
-        if (!s_vals) {
-            return (ElementPtr());
-        }
-        ElementPtr result = Element::createList();
         for (size_t i = 0; i < s_vals->val_cnt(); ++i) {
             S_Val s_val = s_vals->val(i);
             result->add(value(s_val));
         }
-        return (result);
     } catch (const sysrepo_exception& ex) {
-        isc_throw(SysrepoError,
-                  "sysrepo error getting item at '" << xpath
-                  << "': " << ex.what());
+        isc_throw(SysrepoError, "sysrepo error getting item at '"
+                                    << xpath << "': " << ex.what());
     }
+    return (result);
 }
 
 S_Val
@@ -188,11 +184,7 @@ TranslatorBasic::value(ConstElementPtr elem, sr_type_t type) {
                       "value for an integer called with not an integer: "
                       << elem->str());
         }
-#ifdef HAVE_POST_0_7_7_SYSREPO
-        s_val.reset(new Val(static_cast<uint8_t>(elem->intValue())));
-#else
-        s_val.reset(new Val(static_cast<uint8_t>(elem->intValue()), type));
-#endif
+        s_val.reset(new Val(elem->intValue(), type));
         break;
 
     case SR_UINT16_T:
@@ -201,11 +193,7 @@ TranslatorBasic::value(ConstElementPtr elem, sr_type_t type) {
                       "value for an integer called with not an integer: "
                       << elem->str());
         }
-#ifdef HAVE_POST_0_7_7_SYSREPO
-        s_val.reset(new Val(static_cast<uint16_t>(elem->intValue())));
-#else
-        s_val.reset(new Val(static_cast<uint16_t>(elem->intValue()), type));
-#endif
+        s_val.reset(new Val(elem->intValue(), type));
         break;
 
     case SR_UINT32_T:
@@ -214,11 +202,7 @@ TranslatorBasic::value(ConstElementPtr elem, sr_type_t type) {
                       "value for an integer called with not an integer: "
                       << elem->str());
         }
-#ifdef HAVE_POST_0_7_7_SYSREPO
-        s_val.reset(new Val(static_cast<uint32_t>(elem->intValue())));
-#else
-        s_val.reset(new Val(static_cast<uint32_t>(elem->intValue()), type));
-#endif
+        s_val.reset(new Val(elem->intValue(), type));
         break;
 
     case SR_INT8_T:
@@ -227,11 +211,7 @@ TranslatorBasic::value(ConstElementPtr elem, sr_type_t type) {
                       "value for an integer called with not an integer: "
                       << elem->str());
         }
-#ifdef HAVE_POST_0_7_7_SYSREPO
-        s_val.reset(new Val(static_cast<int8_t>(elem->intValue())));
-#else
-        s_val.reset(new Val(static_cast<int8_t>(elem->intValue()), type));
-#endif
+        s_val.reset(new Val(elem->intValue(), type));
         break;
 
     case SR_INT16_T:
@@ -240,11 +220,7 @@ TranslatorBasic::value(ConstElementPtr elem, sr_type_t type) {
                       "value for an integer called with not an integer: "
                       << elem->str());
         }
-#ifdef HAVE_POST_0_7_7_SYSREPO
-        s_val.reset(new Val(static_cast<int16_t>(elem->intValue())));
-#else
-        s_val.reset(new Val(static_cast<int16_t>(elem->intValue()), type));
-#endif
+        s_val.reset(new Val(elem->intValue(), type));
         break;
 
     case SR_INT32_T:
@@ -253,11 +229,7 @@ TranslatorBasic::value(ConstElementPtr elem, sr_type_t type) {
                       "value for an integer called with not an integer: "
                       << elem->str());
         }
-#ifdef HAVE_POST_0_7_7_SYSREPO
-        s_val.reset(new Val(static_cast<int32_t>(elem->intValue())));
-#else
-        s_val.reset(new Val(static_cast<int32_t>(elem->intValue()), type));
-#endif
+        s_val.reset(new Val(elem->intValue(), type));
         break;
 
     case SR_DECIMAL64_T:
@@ -288,9 +260,6 @@ void
 TranslatorBasic::setItem(const string& xpath, ConstElementPtr elem,
                          sr_type_t type) {
     S_Val s_val = value(elem, type);
-    if (!s_val && (type != SR_LIST_T)) {
-        return;
-    }
     try {
         session_->set_item(xpath.c_str(), s_val);
     } catch (const sysrepo_exception& ex) {
@@ -298,6 +267,7 @@ TranslatorBasic::setItem(const string& xpath, ConstElementPtr elem,
                   "sysrepo error setting item '" << elem->str()
                   << "' at '" << xpath << "': " << ex.what());
     }
+    session_->apply_changes();
 }
 
 void
@@ -305,35 +275,24 @@ TranslatorBasic::delItem(const std::string& xpath) {
     try {
         session_->delete_item(xpath.c_str());
     } catch (const sysrepo_exception& ex) {
+        if (std::string(ex.what()).find("Invalid argument") != string::npos) {
+            // The YANG configuration node was not there.
+            return;
+        }
         isc_throw(SysrepoError,
                   "sysrepo error deleting item at '"
                   << xpath << "': " << ex.what());
     }
+    session_->apply_changes();
 }
 
-
-S_Iter_Value
-TranslatorBasic::getIter(const std::string& xpath) {
-    return (session_->get_items_iter(xpath.c_str()));
-}
-
-string
-TranslatorBasic::getNext(S_Iter_Value iter) {
-    if (!iter) {
-        isc_throw(BadValue, "getNext called with null");
-    }
-    S_Val s_val;
+S_Vals TranslatorBasic::getValuesFromItems(std::string const& xpath) {
     try {
-        s_val = session_->get_item_next(iter);
-    } catch (const sysrepo_exception&) {
-        // Should not happen according to the doc but still happen?
-        return ("");
-    }
-    if (!s_val) {
-        return ("");
+        return session_->get_items(xpath.c_str());
+    } catch (sysrepo::sysrepo_exception const& exception) {
+        isc_throw(SysrepoError, "sysrepo error getting items: " << exception.what());
     }
-    return (s_val->xpath());
 }
 
-}; // end of namespace isc::yang
-}; // end of namespace isc
+}  // namespace yang
+}  // namespace isc
index 5c3313e42453efad37547139623e5cc0df99a194..bdc0b1097dd09cc3d11f404cd8966d7dadc7461c 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2018 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2018-2021 Internet Systems Consortium, Inc. ("ISC")
 //
 // This Source Code Form is subject to the terms of the Mozilla Public
 // License, v. 2.0. If a copy of the MPL was not distributed with this
 #include <cc/data.h>
 #include <yang/sysrepo_error.h>
 
-#ifndef HAVE_SYSREPO
-#error "config.h must be included before translator.h"
-#endif
-
-#ifndef HAVE_PRE_0_7_6_SYSREPO
 #include <sysrepo-cpp/Session.hpp>
-#else
-#include <sysrepo-cpp/Session.h>
-#endif
 
 namespace isc {
 namespace yang {
@@ -26,16 +18,11 @@ namespace yang {
 /// @brief Between YANG and JSON translator class for basic values.
 class TranslatorBasic {
 public:
-
     /// @brief Constructor.
     ///
     /// @param session Sysrepo session.
     /// @param model Model name (used and shared by derived classes).
-#ifndef HAVE_PRE_0_7_6_SYSREPO
     TranslatorBasic(sysrepo::S_Session session, const std::string& model);
-#else
-    TranslatorBasic(S_Session session, const std::string& model);
-#endif
 
     /// @brief Destructor.
     virtual ~TranslatorBasic();
@@ -47,11 +34,7 @@ public:
     /// @param s_val The value.
     /// @return The Element representing the sysrepo value.
     /// @throw NotImplemented when the value type is not supported.
-#ifndef HAVE_PRE_0_7_6_SYSREPO
     static isc::data::ElementPtr value(sysrepo::S_Val s_val);
-#else
-    static isc::data::ElementPtr value(S_Val s_val);
-#endif
 
     /// @brief Get and translate basic value from YANG to JSON.
     ///
@@ -71,18 +54,22 @@ public:
     /// null when not found.
     isc::data::ElementPtr getItems(const std::string& xpath);
 
+    /// @brief Get the values of all siblings at a certain xpath.
+    ///
+    /// @param xpath the xpath to the element to be retrieved from, usually a
+    /// list
+    ///
+    /// @return all the entries populated with values
+    sysrepo::S_Vals getValuesFromItems(std::string const& xpath);
+
     /// @brief Translate basic value from JSON to YANG.
     ///
     /// @note Please don't use this outside tests.
     ///
     /// @param elem The JSON element.
     /// @param type The sysrepo type.
-#ifndef HAVE_PRE_0_7_6_SYSREPO
     static sysrepo::S_Val value(isc::data::ConstElementPtr elem,
                                 sr_type_t type);
-#else
-    static S_Val value(isc::data::ConstElementPtr elem, sr_type_t type);
-#endif
 
     /// @brief Translate and set basic value from JSON to YANG.
     ///
@@ -97,42 +84,67 @@ public:
     /// @param xpath The xpath of the basic value.
     void delItem(const std::string& xpath);
 
-    /// List iterator methods keeping the session private.
-
-    /// @brief Get iterator over a YANG list.
+    /// @brief Run a function for a node and all its children.
     ///
-    /// @param xpath The xpath of the list.
-    /// @return An S_Iter_Value pointer. Null is the list does not exist.
-#ifndef HAVE_PRE_0_7_6_SYSREPO
-    sysrepo::S_Iter_Value getIter(const std::string& xpath);
-#else
-    S_Iter_Value getIter(const std::string& xpath);
-#endif
-
-    /// @brief Get xpath of the next YANG list item.
+    /// @tparam functor_t typename of the function to be called
+    ///
+    /// @param xpath the xpath to be travelled
+    /// @param f the function to be called on the node itself and each
+    /// descendant
+    template <typename functor_t>
+    void forAll(std::string const& xpath, functor_t f) {
+        libyang::S_Data_Node data_node(session_->get_data(xpath.c_str()));
+        if (!data_node) {
+            return;
+        }
+
+        for (libyang::S_Data_Node& root : data_node->tree_for()) {
+            for (libyang::S_Data_Node const& n : root->tree_dfs()) {
+                f(n);
+            }
+        }
+    }
+
+    /// @brief Retrieve a list as ElementPtr from sysrepo from a certain xpath.
+    ///
+    /// @tparam T typename of the translator that holds the function that will
+    /// be called on the xpath of each child from the list
     ///
-    /// @param iter The iterator pointing to the previous element
-    /// @return The xpath of the next element. Empty string when at
-    /// the end of the list.
-#ifndef HAVE_PRE_0_7_6_SYSREPO
-    std::string getNext(sysrepo::S_Iter_Value iter);
-#else
-    std::string getNext(S_Iter_Value iter);
-#endif
+    /// @param xpath the xpath to the element to be retrieved from, usually a
+    /// list
+    /// @param t address of a translator instance that holds the function that
+    /// will be called on the xpath of each child from the list
+    /// @param f the function that will be called on the xpath of each child
+    /// from the list
+    template <typename T>
+    isc::data::ElementPtr getList(std::string const& xpath,
+                                  T& t,
+                                  isc::data::ElementPtr (T::*f)(std::string const& xpath)) {
+        isc::data::ElementPtr result;
+        sysrepo::S_Vals values(getValuesFromItems(xpath));
+        if (values) {
+            for (size_t i(0); i < values->val_cnt(); ++i) {
+                isc::data::ElementPtr x((t.*f)(values->val(i)->xpath()));
+                if (x) {
+                    if (!result) {
+                        result = isc::data::Element::createList();
+                    }
+                    result->add(x);
+                }
+            }
+        }
+        return result;
+    }
 
 protected:
     /// @brief The sysrepo session.
-#ifndef HAVE_PRE_0_7_6_SYSREPO
     sysrepo::S_Session session_;
-#else
-    S_Session session_;
-#endif
 
     /// @brief The model.
     std::string model_;
 };
 
-}; // end of namespace isc::yang
-}; // end of namespace isc
+}  // namespace yang
+}  // namespace isc
 
 #endif // ISC_TRANSLATOR_H
index 88f97cd46103698e47fe2a9fcf6eb95855f09291..457d9afedcb011b61bbc1530c59a99d655887178 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2018 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2018-2021 Internet Systems Consortium, Inc. ("ISC")
 //
 // This Source Code Form is subject to the terms of the Mozilla Public
 // License, v. 2.0. If a copy of the MPL was not distributed with this
@@ -13,9 +13,7 @@
 
 using namespace std;
 using namespace isc::data;
-#ifndef HAVE_PRE_0_7_6_SYSREPO
 using namespace sysrepo;
-#endif
 
 namespace isc {
 namespace yang {
@@ -194,24 +192,8 @@ TranslatorClasses::getClasses(const string& xpath) {
 
 ElementPtr
 TranslatorClasses::getClassesKea(const string& xpath) {
-    S_Iter_Value iter = getIter(xpath + "/client-class");
-    if (!iter) {
-        // Can't happen.
-        isc_throw(Unexpected, "getClassesKea: can't get iterator: " << xpath);
-    }
-    ElementPtr result = Element::createList();
-    for (;;) {
-        const string& cclass = getNext(iter);
-        if (cclass.empty()) {
-            break;
-        }
-        result->add(getClass(cclass));
-    }
-    if (result->size() > 0) {
-        return (result);
-    } else {
-        return (ElementPtr());
-    }
+    return getList<TranslatorClass>(xpath + "/client-class", *this,
+                                    &TranslatorClass::getClass);
 }
 
 void
@@ -245,5 +227,5 @@ TranslatorClasses::setClassesKea(const string& xpath, ConstElementPtr elem) {
     }
 }
 
-}; // end of namespace isc::yang
-}; // end of namespace isc
+}  // namespace yang
+}  // namespace isc
index 3e641c4100059c77642bf41935816264651442c6..dca4de9b1504cd38364a7b6d5072aabfeccb9d5a 100644 (file)
@@ -77,11 +77,7 @@ public:
     ///
     /// @param session Sysrepo session.
     /// @param model Model name.
-#ifndef HAVE_PRE_0_7_6_SYSREPO
     TranslatorClass(sysrepo::S_Session session, const std::string& model);
-#else
-    TranslatorClass(S_Session session, const std::string& model);
-#endif
 
     /// @brief Destructor.
     virtual ~TranslatorClass();
@@ -127,11 +123,7 @@ public:
     ///
     /// @param session Sysrepo session.
     /// @param model Model name.
-#ifndef HAVE_PRE_0_7_6_SYSREPO
     TranslatorClasses(sysrepo::S_Session session, const std::string& model);
-#else
-    TranslatorClasses(S_Session session, const std::string& model);
-#endif
 
     /// @brief Destructor.
     virtual ~TranslatorClasses();
@@ -167,7 +159,7 @@ protected:
                        isc::data::ConstElementPtr elem);
 };
 
-}; // end of namespace isc::yang
-}; // end of namespace isc
+}  // namespace yang
+}  // namespace isc
 
 #endif // ISC_TRANSLATOR_CLASS_H
index 898d662e814c00c181bdbff7bbd67ea607140603..cff95eaae8d68067f3e0c5b6b49fc8b19405f758 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2018-2019 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2018-2021 Internet Systems Consortium, Inc. ("ISC")
 //
 // This Source Code Form is subject to the terms of the Mozilla Public
 // License, v. 2.0. If a copy of the MPL was not distributed with this
@@ -13,9 +13,7 @@
 
 using namespace std;
 using namespace isc::data;
-#ifndef HAVE_PRE_0_7_6_SYSREPO
 using namespace sysrepo;
-#endif
 
 namespace isc {
 namespace yang {
@@ -105,36 +103,23 @@ TranslatorConfig::getParam(ElementPtr& storage, const std::string& xpath,
     }
 }
 
-ElementPtr
-TranslatorConfig::getHooksKea(const std::string& xpath) {
-    S_Iter_Value iter = getIter(xpath + "/hook-library");
-    if (iter) {
-        ElementPtr hook_libs = Element::createList();
-        for (;;) {
-            const string& lib = getNext(iter);
-            if (lib.empty()) {
-                break;
-            }
-            ElementPtr hook_lib = Element::createMap();
-            ConstElementPtr name = getItem(lib + "/library");
-            if (name) {
-                hook_lib->set("library", name);
-                ConstElementPtr params = getItem(lib + "/parameters");
-                if (params) {
-                    string parameters = params->stringValue();
-                    if (!parameters.empty()) {
-                        hook_lib->set("parameters",
-                                      Element::fromJSON(parameters));
-                    }
-                }
-                hook_libs->add(hook_lib);
-            }
-        }
-        if (!hook_libs->empty()) {
-            return (hook_libs);
+ElementPtr TranslatorConfig::getHook(string const& xpath) {
+    ElementPtr const& hook_library(Element::createMap());
+    ElementPtr const& name(getItem(xpath + "/library"));
+    if (name) {
+        hook_library->set("library", name);
+        ElementPtr const& parameters(getItem(xpath + "/parameters"));
+        if (parameters) {
+            hook_library->set("parameters",
+                              Element::fromJSON(parameters->stringValue()));
         }
     }
-    return (ElementPtr());
+    return hook_library;
+}
+
+ElementPtr
+TranslatorConfig::getHooksKea(const std::string& xpath) {
+    return getList(xpath + "/hook-library", *this, &TranslatorConfig::getHook);
 }
 
 isc::data::ElementPtr
@@ -898,5 +883,5 @@ TranslatorConfig::setServerKeaDhcp6(ConstElementPtr elem) {
     }
 }
 
-}; // end of namespace isc::yang
-}; // end of namespace isc
+}  // namespace yang
+}  // namespace isc
index bb3290649f097017fe0c3db0a578977d970acb11..f34b93cc05ff9586ee9f7d5792961ed0e1505f32 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2018-2019 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2018-2021 Internet Systems Consortium, Inc. ("ISC")
 //
 // This Source Code Form is subject to the terms of the Mozilla Public
 // License, v. 2.0. If a copy of the MPL was not distributed with this
@@ -388,11 +388,7 @@ public:
     ///
     /// @param session Sysrepo session.
     /// @param model Model name.
-#ifndef HAVE_PRE_0_7_6_SYSREPO
     TranslatorConfig(sysrepo::S_Session session, const std::string& model);
-#else
-    TranslatorConfig(S_Session session, const std::string& model);
-#endif
 
     /// @brief Destructor.
     virtual ~TranslatorConfig();
@@ -484,6 +480,8 @@ protected:
     void setServerKeaDhcpCommon(const std::string& xpath,
                                 isc::data::ConstElementPtr elem);
 
+    isc::data::ElementPtr getHook(const std::string& xpath);
+
     /// @brief Retrieves hooks configuration from sysrepo.
     ///
     /// @param xpath path to hooks configuration.
index 65757e583e6d09d8df7dacf550e3d1f79bccda46..4a685ce8781e2d4738d6c334b9bf79390bce7de3 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2018 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2018-2021 Internet Systems Consortium, Inc. ("ISC")
 //
 // This Source Code Form is subject to the terms of the Mozilla Public
 // License, v. 2.0. If a copy of the MPL was not distributed with this
@@ -13,9 +13,7 @@
 
 using namespace std;
 using namespace isc::data;
-#ifndef HAVE_PRE_0_7_6_SYSREPO
 using namespace sysrepo;
-#endif
 
 namespace isc {
 namespace yang {
@@ -89,9 +87,6 @@ void
 TranslatorControlSocket::setControlSocketKea(const string& xpath,
                                              ConstElementPtr elem) {
     if (!elem) {
-        delItem(xpath + "/socket-name");
-        delItem(xpath + "/socket-type");
-        delItem(xpath + "/user-context");
         delItem(xpath);
         return;
     }
@@ -112,5 +107,5 @@ TranslatorControlSocket::setControlSocketKea(const string& xpath,
     }
 }
 
-}; // end of namespace isc::yang
-}; // end of namespace isc
+}  // namespace yang
+}  // namespace isc
index 236d17bdd6f5b86844b0334a165b15a61d10e255..326e6eb73db7533d18b77f87740d3ea5e7eab203 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2018-2019 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2018-2021 Internet Systems Consortium, Inc. ("ISC")
 //
 // This Source Code Form is subject to the terms of the Mozilla Public
 // License, v. 2.0. If a copy of the MPL was not distributed with this
@@ -74,12 +74,8 @@ public:
     ///
     /// @param session Sysrepo session.
     /// @param model Model name.
-#ifndef HAVE_PRE_0_7_6_SYSREPO
     TranslatorControlSocket(sysrepo::S_Session session,
                             const std::string& model);
-#else
-    TranslatorControlSocket(S_Session session, const std::string& model);
-#endif
 
     /// @brief Destructor.
     virtual ~TranslatorControlSocket();
@@ -119,7 +115,7 @@ protected:
                              isc::data::ConstElementPtr elem);
 };
 
-}; // end of namespace isc::yang
-}; // end of namespace isc
+}  // namespace yang
+}  // namespace isc
 
 #endif // ISC_TRANSLATOR_CONTROL_SOCKET_H
index 3527a79fbac805de2b35089a278fbe6379d6fc89..0738b0d0fba6493f8025a8da9ef01db5d815a7fc 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2018-2019 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2018-2021 Internet Systems Consortium, Inc. ("ISC")
 //
 // This Source Code Form is subject to the terms of the Mozilla Public
 // License, v. 2.0. If a copy of the MPL was not distributed with this
@@ -13,9 +13,7 @@
 
 using namespace std;
 using namespace isc::data;
-#ifndef HAVE_PRE_0_7_6_SYSREPO
 using namespace sysrepo;
-#endif
 
 namespace isc {
 namespace yang {
@@ -279,24 +277,8 @@ TranslatorDatabases::getDatabases(const string& xpath) {
 
 ElementPtr
 TranslatorDatabases::getDatabasesKea(const string& xpath) {
-    S_Iter_Value iter = getIter(xpath);
-    if (!iter) {
-        // Can't happen.
-        isc_throw(Unexpected, "getDatabasesKea can't get iterator: " << xpath);
-    }
-    ElementPtr result = Element::createList();
-    for (;;) {
-        const string& database = getNext(iter);
-        if (database.empty()) {
-            break;
-        }
-        result->add(getDatabase(database));
-    }
-    if (result->size() > 0) {
-        return (result);
-    } else {
-        return (ElementPtr());
-    }
+    return getList<TranslatorDatabase>(xpath, *this,
+                                       &TranslatorDatabase::getDatabase);
 }
 
 void
@@ -336,5 +318,5 @@ TranslatorDatabases::setDatabasesKea(const string& xpath,
     }
 }
 
-}; // end of namespace isc::yang
-}; // end of namespace isc
+}  // namespace yang
+}  // namespace isc
index 0f86bd91e0ed8d52c34aed1d6b7ff6685b89d466..b4e1107e5bbc6708f25de108aec9d0a7bb4f0623 100644 (file)
@@ -114,11 +114,7 @@ public:
     ///
     /// @param session Sysrepo session.
     /// @param model Model name.
-#ifndef HAVE_PRE_0_7_6_SYSREPO
     TranslatorDatabase(sysrepo::S_Session session, const std::string& model);
-#else
-    TranslatorDatabase(S_Session session, const std::string& model);
-#endif
 
     /// @brief Destructor.
     virtual ~TranslatorDatabase();
@@ -171,11 +167,7 @@ public:
     ///
     /// @param session Sysrepo session.
     /// @param model Model name.
-#ifndef HAVE_PRE_0_7_6_SYSREPO
     TranslatorDatabases(sysrepo::S_Session session, const std::string& model);
-#else
-    TranslatorDatabases(S_Session session, const std::string& model);
-#endif
 
     /// @brief Destructor.
     virtual ~TranslatorDatabases();
@@ -213,7 +205,7 @@ protected:
                          isc::data::ConstElementPtr elem);
 };
 
-}; // end of namespace isc::yang
-}; // end of namespace isc
+}  // namespace yang
+}  // namespace isc
 
 #endif // ISC_TRANSLATOR_DATABASE_H
index 9b164c8ecbf071d02eac76ba9fe073f1299da4b8..fd4dc40668f5ce07f9a543d3ce77dc00878fc31c 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2018 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2018-2021 Internet Systems Consortium, Inc. ("ISC")
 //
 // This Source Code Form is subject to the terms of the Mozilla Public
 // License, v. 2.0. If a copy of the MPL was not distributed with this
@@ -13,9 +13,7 @@
 
 using namespace std;
 using namespace isc::data;
-#ifndef HAVE_PRE_0_7_6_SYSREPO
 using namespace sysrepo;
-#endif
 
 namespace isc {
 namespace yang {
@@ -193,26 +191,8 @@ TranslatorHosts::~TranslatorHosts() {
 
 ElementPtr
 TranslatorHosts::getHosts(const string& xpath) {
-    try {
-        ElementPtr result = Element::createList();
-        S_Iter_Value iter = getIter(xpath + "/host");
-        if (!iter) {
-            // Can't happen.
-            isc_throw(Unexpected, "getHosts can't get iterator: " << xpath);
-        }
-        for (;;) {
-            const string& host = getNext(iter);
-            if (host.empty()) {
-                break;
-            }
-            result->add(getHost(host));
-        }
-        return (result);
-    } catch (const sysrepo_exception& ex) {
-        isc_throw(SysrepoError,
-                  "sysrepo error getting host reservations at '" << xpath
-                  << "': " << ex.what());
-    }
+    return getList<TranslatorHost>(xpath + "/host", *this,
+                                   &TranslatorHost::getHost);
 }
 
 void
@@ -277,5 +257,5 @@ TranslatorHosts::setHostsKea(const string& xpath, ConstElementPtr elem) {
     }
 }
 
-}; // end of namespace isc::yang
-}; // end of namespace isc
+}  // namespace yang
+}  // namespace isc
index 3677f7094b1f073e9b133710ab357c39c78c0612..33712488e8e2b4bef9fd05e8d2c3d06eac96fb96 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2018 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2018-2021 Internet Systems Consortium, Inc. ("ISC")
 //
 // This Source Code Form is subject to the terms of the Mozilla Public
 // License, v. 2.0. If a copy of the MPL was not distributed with this
@@ -116,11 +116,7 @@ public:
     ///
     /// @param session Sysrepo session.
     /// @param model Model name.
-#ifndef HAVE_PRE_0_7_6_SYSREPO
     TranslatorHost(sysrepo::S_Session session, const std::string& model);
-#else
-    TranslatorHost(S_Session session, const std::string& model);
-#endif
 
     /// @brief Destructor.
     virtual ~TranslatorHost();
@@ -167,11 +163,7 @@ public:
     ///
     /// @param session Sysrepo session.
     /// @param model Model name.
-#ifndef HAVE_PRE_0_7_6_SYSREPO
     TranslatorHosts(sysrepo::S_Session session, const std::string& model);
-#else
-    TranslatorHosts(S_Session session, const std::string& model);
-#endif
 
     /// @brief Destructor.
     virtual ~TranslatorHosts();
@@ -198,7 +190,7 @@ protected:
                      isc::data::ConstElementPtr elem);
 };
 
-}; // end of namespace isc::yang
-}; // end of namespace isc
+}  // namespace yang
+}  // namespace isc
 
 #endif // ISC_TRANSLATOR_HOST_H
index e4a21d244e6ae70f64246d6cd1df3628c2a20e63..de0442840a3cd177df370330a5ac5a1e4e3fc32a 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2018-2019 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2018-2021 Internet Systems Consortium, Inc. ("ISC")
 //
 // This Source Code Form is subject to the terms of the Mozilla Public
 // License, v. 2.0. If a copy of the MPL was not distributed with this
@@ -13,9 +13,7 @@
 
 using namespace std;
 using namespace isc::data;
-#ifndef HAVE_PRE_0_7_6_SYSREPO
 using namespace sysrepo;
-#endif
 
 namespace isc {
 namespace yang {
@@ -103,21 +101,8 @@ TranslatorLogger::getOutputOption(const string& xpath) {
 
 ElementPtr
 TranslatorLogger::getOutputOptions(const string& xpath) {
-    S_Iter_Value iter = getIter(xpath + "/output-option");
-    if (!iter) {
-        // Can't happen.
-        isc_throw(Unexpected, "getOutputOptions: can't get iterator: "
-                  << xpath);
-    }
-    ElementPtr result = Element::createList();
-    for (;;) {
-        const string& option = getNext(iter);
-        if (option.empty()) {
-            break;
-        }
-        result->add(getOutputOption(option));
-    }
-    return (result);
+    return getList(xpath + "/output-option", *this,
+                   &TranslatorLogger::getOutputOption);
 }
 
 void
@@ -197,7 +182,7 @@ TranslatorLogger::setOutputOptions(const string& xpath, ConstElementPtr elem) {
     for (size_t i = 0; i < elem->size(); ++i) {
         ConstElementPtr option = elem->get(i);
         if (!option->contains("output")) {
-            isc_throw(BadValue, "output-options without output: "
+            isc_throw(BadValue, "output-option without output: "
                       << option->str());
         }
         string output = option->get("output")->stringValue();
@@ -235,20 +220,8 @@ TranslatorLoggers::getLoggers(const string& xpath) {
 
 ElementPtr
 TranslatorLoggers::getLoggersKea(const string& xpath) {
-    S_Iter_Value iter = getIter(xpath + "/logger");
-    if (!iter) {
-        // Can't happen.
-        isc_throw(Unexpected, "getLoggersKea: can't get iterator: " << xpath);
-    }
-    ElementPtr result = Element::createList();
-    for (;;) {
-        const string& logger = getNext(iter);
-        if (logger.empty()) {
-            break;
-        }
-        result->add(getLogger(logger));
-    }
-    return (result);
+    return getList<TranslatorLogger>(xpath + "/logger", *this,
+                                     &TranslatorLogger::getLogger);
 }
 
 void
@@ -284,5 +257,5 @@ TranslatorLoggers::setLoggersKea(const string& xpath, ConstElementPtr elem) {
     }
 }
 
-}; // end of namespace isc::yang
-}; // end of namespace isc
+}  // namespace yang
+}  // namespace isc
index 5aca5315ef60ee3f9b4aee1521cdb5e24abb397e..346a386b4e05eb2d8fa15183249b224cc84fb618 100644 (file)
@@ -99,11 +99,7 @@ public:
     ///
     /// @param session Sysrepo session.
     /// @param model Model name.
-#ifndef HAVE_PRE_0_7_6_SYSREPO
     TranslatorLogger(sysrepo::S_Session session, const std::string& model);
-#else
-    TranslatorLogger(S_Session session, const std::string& model);
-#endif
 
     /// @brief Destructor.
     virtual ~TranslatorLogger();
@@ -177,11 +173,7 @@ public:
     ///
     /// @param session Sysrepo session.
     /// @param model Model name.
-#ifndef HAVE_PRE_0_7_6_SYSREPO
     TranslatorLoggers(sysrepo::S_Session session, const std::string& model);
-#else
-    TranslatorLoggers(S_Session session, const std::string& model);
-#endif
 
     /// @brief Destructor.
     virtual ~TranslatorLoggers();
@@ -217,7 +209,7 @@ protected:
                        isc::data::ConstElementPtr elem);
 };
 
-}; // end of namespace isc::yang
-}; // end of namespace isc
+}  // namespace yang
+}  // namespace isc
 
 #endif // ISC_TRANSLATOR_LOGGER_H
index 644cf794693096090c0147fdc651d6275bb9036b..9947fdc55ba30bda2b8ece9450e2edf3544f539f 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2018 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2018-2021 Internet Systems Consortium, Inc. ("ISC")
 //
 // This Source Code Form is subject to the terms of the Mozilla Public
 // License, v. 2.0. If a copy of the MPL was not distributed with this
@@ -13,9 +13,7 @@
 
 using namespace std;
 using namespace isc::data;
-#ifndef HAVE_PRE_0_7_6_SYSREPO
 using namespace sysrepo;
-#endif
 
 namespace isc {
 namespace yang {
@@ -152,21 +150,8 @@ TranslatorOptionDataList::getOptionDataList(const string& xpath) {
 
 ConstElementPtr
 TranslatorOptionDataList::getOptionDataListKea(const string& xpath) {
-    ElementPtr result = Element::createList();
-    S_Iter_Value iter = getIter(xpath + "/option-data");
-    if (!iter) {
-        // Can't happen.
-        isc_throw(Unexpected, "getOptionDataListKea: can't get iterator: "
-                  << xpath);
-    }
-    for (;;) {
-        const string& option = getNext(iter);
-        if (option.empty()) {
-            break;
-        }
-        result->add(getOptionData(option));
-    }
-    return (result);
+    return getList<TranslatorOptionData>(xpath + "/option-data", *this,
+                                         &TranslatorOptionData::getOptionData);
 }
 
 void
@@ -208,5 +193,5 @@ TranslatorOptionDataList::setOptionDataListKea(const string& xpath,
     }
 }
 
-}; // end of namespace isc::yang
-}; // end of namespace isc
+}  // namespace yang
+}  // namespace isc
index 69c444e6ac76735647a46a54a3211911b0cc14f8..7d4572446c8b70402b1b38eaeaac55eb3e953740 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2018 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2018-2021 Internet Systems Consortium, Inc. ("ISC")
 //
 // This Source Code Form is subject to the terms of the Mozilla Public
 // License, v. 2.0. If a copy of the MPL was not distributed with this
@@ -79,11 +79,7 @@ public:
     ///
     /// @param session Sysrepo session.
     /// @param model Model name.
-#ifndef HAVE_PRE_0_7_6_SYSREPO
     TranslatorOptionData(sysrepo::S_Session session, const std::string& model);
-#else
-    TranslatorOptionData(S_Session session, const std::string& model);
-#endif
 
     /// @brief Destructor.
     virtual ~TranslatorOptionData();
@@ -130,12 +126,8 @@ public:
     ///
     /// @param session Sysrepo session.
     /// @param model Model name.
-#ifndef HAVE_PRE_0_7_6_SYSREPO
     TranslatorOptionDataList(sysrepo::S_Session session,
                              const std::string& model);
-#else
-    TranslatorOptionDataList(S_Session session, const std::string& model);
-#endif
 
     /// @brief Destructor.
     virtual ~TranslatorOptionDataList();
@@ -169,7 +161,7 @@ protected:
                               isc::data::ConstElementPtr elem);
 };
 
-}; // end of namespace isc::yang
-}; // end of namespace isc
+}  // namespace yang
+}  // namespace isc
 
 #endif // ISC_TRANSLATOR_OPTION_DATA_H
index 8153859c26b36b0cfa1685729292723ea9d152af..a552191aa835069c14c0d3f6b84a8274747f197a 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2018 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2018-2021 Internet Systems Consortium, Inc. ("ISC")
 //
 // This Source Code Form is subject to the terms of the Mozilla Public
 // License, v. 2.0. If a copy of the MPL was not distributed with this
@@ -13,9 +13,7 @@
 
 using namespace std;
 using namespace isc::data;
-#ifndef HAVE_PRE_0_7_6_SYSREPO
 using namespace sysrepo;
-#endif
 
 namespace isc {
 namespace yang {
@@ -161,21 +159,8 @@ TranslatorOptionDefList::getOptionDefList(const string& xpath) {
 
 ConstElementPtr
 TranslatorOptionDefList::getOptionDefListKea(const string& xpath) {
-    ElementPtr result = Element::createList();
-    S_Iter_Value iter = getIter(xpath + "/option-def");
-    if (!iter) {
-        // Can't happen.
-        isc_throw(Unexpected, "getOptionDefListKea: can't get iterator: "
-                  << xpath);
-    }
-    for (;;) {
-        const string& def = getNext(iter);
-        if (def.empty()) {
-            break;
-        }
-        result->add(getOptionDef(def));
-    }
-    return (result);
+    return getList<TranslatorOptionDef>(xpath + "/option-def", *this,
+                                        &TranslatorOptionDefList::getOptionDef);
 }
 
 void
@@ -219,5 +204,5 @@ TranslatorOptionDefList::setOptionDefListKea(const string& xpath,
     }
 }
 
-}; // end of namespace isc::yang
-}; // end of namespace isc
+}  // namespace yang
+}  // namespace isc
index b3332edd25d6a82560a65cf229665f0d6a93b3ff..7003e498b1bbb1ee8f34400c348ad8e8e733a814 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2018 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2018-2021 Internet Systems Consortium, Inc. ("ISC")
 //
 // This Source Code Form is subject to the terms of the Mozilla Public
 // License, v. 2.0. If a copy of the MPL was not distributed with this
@@ -82,11 +82,7 @@ public:
     ///
     /// @param session Sysrepo session.
     /// @param model Model name.
-#ifndef HAVE_PRE_0_7_6_SYSREPO
     TranslatorOptionDef(sysrepo::S_Session session, const std::string& model);
-#else
-    TranslatorOptionDef(S_Session session, const std::string& model);
-#endif
 
     /// @brief Destructor.
     virtual ~TranslatorOptionDef();
@@ -135,12 +131,8 @@ public:
     ///
     /// @param session Sysrepo session.
     /// @param model Model name.
-#ifndef HAVE_PRE_0_7_6_SYSREPO
     TranslatorOptionDefList(sysrepo::S_Session session,
                             const std::string& model);
-#else
-    TranslatorOptionDefList(S_Session session, const std::string& model);
-#endif
 
     /// @brief Destructor.
     virtual ~TranslatorOptionDefList();
@@ -176,7 +168,7 @@ protected:
                              isc::data::ConstElementPtr elem);
 };
 
-}; // end of namespace isc::yang
-}; // end of namespace isc
+}  // namespace yang
+}  // namespace isc
 
 #endif // ISC_TRANSLATOR_OPTION_DEF_H
index 081558be1f4b305462ef6d41abaa238a648e2bc6..f6ffe7170761cfb1cdc4065bf603a4ebd6cb4eda 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2018 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2018-2021 Internet Systems Consortium, Inc. ("ISC")
 //
 // This Source Code Form is subject to the terms of the Mozilla Public
 // License, v. 2.0. If a copy of the MPL was not distributed with this
@@ -14,9 +14,7 @@
 
 using namespace std;
 using namespace isc::data;
-#ifndef HAVE_PRE_0_7_6_SYSREPO
 using namespace sysrepo;
-#endif
 
 namespace isc {
 namespace yang {
@@ -314,20 +312,8 @@ TranslatorPdPools::getPdPools(const string& xpath) {
 
 ElementPtr
 TranslatorPdPools::getPdPoolsCommon(const string& xpath) {
-    ElementPtr result = Element::createList();
-    S_Iter_Value iter = getIter(xpath + "/pd-pool");
-    if (!iter) {
-        // Can't happen.
-        isc_throw(Unexpected, "getPdPools: can't get iterator: " << xpath);
-    }
-    for (;;) {
-        const string& pool = getNext(iter);
-        if (pool.empty()) {
-            break;
-        }
-        result->add(getPdPool(pool));
-    }
-    return (result);
+    return getList<TranslatorPdPool>(xpath + "/pd-pool", *this,
+                                     &TranslatorPdPool::getPdPool);
 }
 
 void
@@ -375,5 +361,5 @@ TranslatorPdPools::setPdPoolsPrefix(const string& xpath,
     }
 }
 
-}; // end of namespace isc::yang
-}; // end of namespace isc
+}  // namespace yang
+}  // namespace isc
index fae6bbeda673b0e1eaf900ad42e7e5cac518a9be..ced16b49948cbe7066d34d551df3f6c2036eeab9 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2018 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2018-2021 Internet Systems Consortium, Inc. ("ISC")
 //
 // This Source Code Form is subject to the terms of the Mozilla Public
 // License, v. 2.0. If a copy of the MPL was not distributed with this
@@ -120,11 +120,7 @@ public:
     ///
     /// @param session Sysrepo session.
     /// @param model Model name.
-#ifndef HAVE_PRE_0_7_6_SYSREPO
     TranslatorPdPool(sysrepo::S_Session session, const std::string& model);
-#else
-    TranslatorPdPool(S_Session session, const std::string& model);
-#endif
 
     /// @brief Destructor.
     virtual ~TranslatorPdPool();
@@ -187,11 +183,7 @@ public:
     ///
     /// @param session Sysrepo session.
     /// @param model Model name.
-#ifndef HAVE_PRE_0_7_6_SYSREPO
     TranslatorPdPools(sysrepo::S_Session session, const std::string& model);
-#else
-    TranslatorPdPools(S_Session session, const std::string& model);
-#endif
 
     /// @brief Destructor.
     virtual ~TranslatorPdPools();
@@ -231,7 +223,7 @@ protected:
                           isc::data::ConstElementPtr elem);
 };
 
-}; // end of namespace isc::yang
-}; // end of namespace isc
+}  // namespace yang
+}  // namespace isc
 
 #endif // ISC_TRANSLATOR_PD_POOL_H
index 905e2b6b1817c4d94403c0f419eab1a5dc625e19..d4593855cfb3d4962b20526ae407e185994e2839 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2018-2019 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2018-2021 Internet Systems Consortium, Inc. ("ISC")
 //
 // This Source Code Form is subject to the terms of the Mozilla Public
 // License, v. 2.0. If a copy of the MPL was not distributed with this
@@ -17,9 +17,7 @@
 using namespace std;
 using namespace isc::data;
 using namespace isc::asiolink;
-#ifndef HAVE_PRE_0_7_6_SYSREPO
 using namespace sysrepo;
-#endif
 
 namespace isc {
 namespace yang {
@@ -86,6 +84,9 @@ TranslatorPool::getPoolIetf6(const string& xpath) {
     // @todo: option-data
     /// no require-client-classes nor user-context.
     // Skip rapid-commit.
+    if (result->empty()) {
+        return ElementPtr();
+    }
     return (result);
 }
 
@@ -295,38 +296,14 @@ TranslatorPools::getPools(const string& xpath) {
 
 ElementPtr
 TranslatorPools::getPoolsIetf(const string& xpath) {
-    ElementPtr result = Element::createList();
-    S_Iter_Value iter = getIter(xpath + "/address-pool");
-    if (!iter) {
-        // Can't happen.
-        isc_throw(Unexpected, "getPoolsIetf can't get iterator: " << xpath);
-    }
-    for (;;) {
-        const string& pool = getNext(iter);
-        if (pool.empty()) {
-            break;
-        }
-        result->add(getPool(pool));
-    }
-    return (result);
+    return getList<TranslatorPool>(xpath + "/address-pool", *this,
+                                   &TranslatorPool::getPool);
 }
 
 ElementPtr
 TranslatorPools::getPoolsKea(const string& xpath) {
-    ElementPtr result = Element::createList();
-    S_Iter_Value iter = getIter(xpath + "/pool");
-    if (!iter) {
-        // Can't happen.
-        isc_throw(Unexpected, "getPoolsKea can't get iterator: " << xpath);
-    }
-    for (;;) {
-        const string& pool = getNext(iter);
-        if (pool.empty()) {
-            break;
-        }
-        result->add(getPool(pool));
-    }
-    return (result);
+    return getList<TranslatorPool>(xpath + "/pool", *this,
+                                   &TranslatorPool::getPool);
 }
 
 void
@@ -378,5 +355,5 @@ TranslatorPools::setPoolsByAddresses(const string& xpath,
     }
 }
 
-}; // end of namespace isc::yang
-}; // end of namespace isc
+}  // namespace yang
+}  // namespace isc
index 0f2fa7530eb36510b9a2a4fe24703119e2b2cf2d..a3ff7db7f4a9dfe971e55a24f1356f7471898e3a 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2018-2019 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2018-2021 Internet Systems Consortium, Inc. ("ISC")
 //
 // This Source Code Form is subject to the terms of the Mozilla Public
 // License, v. 2.0. If a copy of the MPL was not distributed with this
@@ -128,11 +128,7 @@ public:
     ///
     /// @param session Sysrepo session.
     /// @param model Model name.
-#ifndef HAVE_PRE_0_7_6_SYSREPO
     TranslatorPool(sysrepo::S_Session session, const std::string& model);
-#else
-    TranslatorPool(S_Session session, const std::string& model);
-#endif
 
     /// @brief Destructor.
     virtual ~TranslatorPool();
@@ -202,11 +198,7 @@ public:
     ///
     /// @param session Sysrepo session.
     /// @param model Model name.
-#ifndef HAVE_PRE_0_7_6_SYSREPO
     TranslatorPools(sysrepo::S_Session session, const std::string& model);
-#else
-    TranslatorPools(S_Session session, const std::string& model);
-#endif
 
     /// @brief Destructor.
     virtual ~TranslatorPools();
@@ -250,7 +242,7 @@ protected:
                              isc::data::ConstElementPtr elem);
 };
 
-}; // end of namespace isc::yang
-}; // end of namespace isc
+}  // namespace yang
+}  // namespace isc
 
 #endif // ISC_TRANSLATOR_POOL_H
index 9ba195f7619ffdc2e2bb75da831ea03e29ba195a..6d385e1a8c9aed5efbe2b102e9bcbca45d1af10b 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2018-2019 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2018-2021 Internet Systems Consortium, Inc. ("ISC")
 //
 // This Source Code Form is subject to the terms of the Mozilla Public
 // License, v. 2.0. If a copy of the MPL was not distributed with this
@@ -13,9 +13,7 @@
 
 using namespace std;
 using namespace isc::data;
-#ifndef HAVE_PRE_0_7_6_SYSREPO
 using namespace sysrepo;
-#endif
 
 namespace isc {
 namespace yang {
@@ -349,27 +347,8 @@ TranslatorSharedNetworks::~TranslatorSharedNetworks() {
 
 ElementPtr
 TranslatorSharedNetworks::getSharedNetworks(const string& xpath) {
-    try {
-        ElementPtr result = Element::createList();
-        S_Iter_Value iter = getIter(xpath + "/shared-network");
-        if (!iter) {
-            // Can't happen.
-            isc_throw(Unexpected, "getSharedNetworks: can't get iterator: "
-                      << xpath);
-        }
-        for (;;) {
-            const string& network = getNext(iter);
-            if (network.empty()) {
-                break;
-            }
-            result->add(getSharedNetwork(network));
-        }
-        return (result);
-    } catch (const sysrepo_exception& ex) {
-        isc_throw(SysrepoError,
-                  "sysrepo error getting shared networks at '" << xpath
-                  << "': " << ex.what());
-    }
+    return getList<TranslatorSharedNetwork>(xpath + "/shared-network", *this,
+                                            &TranslatorSharedNetwork::getSharedNetwork);
 }
 
 void
@@ -407,5 +386,5 @@ TranslatorSharedNetworks::setSharedNetworksKea(const string& xpath,
     }
 }
 
-}; // end of namespace isc::yang
-}; // end of namespace isc
+}  // namespace yang
+}  // namespace isc
index 316e9b8bb118b56146f247f2185b6c7db114d1ad..43c534d12c069161356a4018264e133e3930c231 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2018-2019 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2018-2021 Internet Systems Consortium, Inc. ("ISC")
 //
 // This Source Code Form is subject to the terms of the Mozilla Public
 // License, v. 2.0. If a copy of the MPL was not distributed with this
@@ -148,12 +148,8 @@ public:
     ///
     /// @param session Sysrepo session.
     /// @param model Model name.
-#ifndef HAVE_PRE_0_7_6_SYSREPO
     TranslatorSharedNetwork(sysrepo::S_Session session,
                             const std::string& model);
-#else
-    TranslatorSharedNetwork(S_Session session, const std::string& model);
-#endif
 
     /// @brief Destructor.
     virtual ~TranslatorSharedNetwork();
@@ -206,12 +202,8 @@ public:
     ///
     /// @param session Sysrepo session.
     /// @param model Model name.
-#ifndef HAVE_PRE_0_7_6_SYSREPO
     TranslatorSharedNetworks(sysrepo::S_Session session,
                              const std::string& model);
-#else
-    TranslatorSharedNetworks(S_Session session, const std::string& model);
-#endif
 
     /// @brief Destructor.
     virtual ~TranslatorSharedNetworks();
@@ -240,7 +232,7 @@ protected:
                               isc::data::ConstElementPtr elem);
 };
 
-}; // end of namespace isc::yang
-}; // end of namespace isc
+}  // namespace yang
+}  // namespace isc
 
 #endif // ISC_TRANSLATOR_SHARED_NETWORK_H
index 1d8ac030b745726afd9f7d1be8c01e9a3bf4cb36..40798973c88018564f4e846d31253eede8da8c57 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2018-2019 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2018-2021 Internet Systems Consortium, Inc. ("ISC")
 //
 // This Source Code Form is subject to the terms of the Mozilla Public
 // License, v. 2.0. If a copy of the MPL was not distributed with this
@@ -6,16 +6,15 @@
 
 #include <config.h>
 
-#include <yang/translator_subnet.h>
 #include <yang/adaptor_pool.h>
+#include <yang/translator_subnet.h>
 #include <yang/yang_models.h>
+
 #include <sstream>
 
 using namespace std;
 using namespace isc::data;
-#ifndef HAVE_PRE_0_7_6_SYSREPO
 using namespace sysrepo;
-#endif
 
 namespace isc {
 namespace yang {
@@ -87,7 +86,9 @@ TranslatorSubnet::getSubnetIetf6(const string& xpath) {
         result->set("user-context", context);
     }
     /// missing a lot of things
-    AdaptorPool::toSubnet(model_, result, result->get("pools"));
+    if (result->get("pools")) {
+        AdaptorPool::toSubnet(model_, result, result->get("pools"));
+    }
     return (result);
 }
 
@@ -484,20 +485,8 @@ TranslatorSubnets::getSubnets(const string& xpath) {
 ElementPtr
 TranslatorSubnets::getSubnetsCommon(const string& xpath,
                                     const std::string& subsel) {
-    ElementPtr result = Element::createList();
-    S_Iter_Value iter = getIter(xpath + "/" + subsel);
-    if (!iter) {
-        /// Can't happen.
-        isc_throw(Unexpected, "getSubnets: can't get iterator: " << xpath);
-    }
-    for (;;) {
-        const string& subnet = getNext(iter);
-        if (subnet.empty()) {
-            break;
-        }
-        result->add(getSubnet(subnet));
-    }
-    return (result);
+    return getList<TranslatorSubnet>(xpath + "/" + subsel, *this,
+                                     &TranslatorSubnet::getSubnet);
 }
 
 void
@@ -550,5 +539,5 @@ TranslatorSubnets::setSubnetsKea(const string& xpath, ConstElementPtr elem,
     }
 }
 
-}; // end of namespace isc::yang
-}; // end of namespace isc
+}  // namespace yang
+}  // namespace isc
index 1d493d6f8004a8623987cbdaefb7192edafab883..92d517000bae28cbc3b3e76f7fac7163b57c5df5 100644 (file)
@@ -259,11 +259,7 @@ public:
     ///
     /// @param session Sysrepo session.
     /// @param model Model name.
-#ifndef HAVE_PRE_0_7_6_SYSREPO
     TranslatorSubnet(sysrepo::S_Session session, const std::string& model);
-#else
-    TranslatorSubnet(S_Session session, const std::string& model);
-#endif
 
     /// @brief Destructor.
     virtual ~TranslatorSubnet();
@@ -322,11 +318,7 @@ public:
     ///
     /// @param session Sysrepo session.
     /// @param model Model name.
-#ifndef HAVE_PRE_0_7_6_SYSREPO
     TranslatorSubnets(sysrepo::S_Session session, const std::string& model);
-#else
-    TranslatorSubnets(S_Session session, const std::string& model);
-#endif
 
     /// @brief Destructor.
     virtual ~TranslatorSubnets();
@@ -369,7 +361,7 @@ protected:
                        const std::string& subsel);
 };
 
-}; // end of namespace isc::yang
-}; // end of namespace isc
+}  // namespace yang
+}  // namespace isc
 
 #endif // ISC_TRANSLATOR_SUBNET_H