RIFT OSM R1 Initial Submission
[osm/SO.git] / rwlaunchpad / test / utest_rwnsm.py
diff --git a/rwlaunchpad/test/utest_rwnsm.py b/rwlaunchpad/test/utest_rwnsm.py
new file mode 100755 (executable)
index 0000000..e125739
--- /dev/null
@@ -0,0 +1,215 @@
+#!/usr/bin/env python3
+
+# 
+#   Copyright 2016 RIFT.IO Inc
+#
+#   Licensed under the Apache License, Version 2.0 (the "License");
+#   you may not use this file except in compliance with the License.
+#   You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+#   Unless required by applicable law or agreed to in writing, software
+#   distributed under the License is distributed on an "AS IS" BASIS,
+#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#   See the License for the specific language governing permissions and
+#   limitations under the License.
+#
+
+
+import argparse
+import logging
+import os
+import sys
+import unittest
+import uuid
+import xmlrunner
+
+from gi.repository import (
+        NsdYang,
+        NsrYang,
+        )
+
+logger = logging.getLogger('test-rwnsmtasklet')
+
+import rift.tasklets.rwnsmtasklet.rwnsmtasklet as rwnsmtasklet
+import rift.tasklets.rwnsmtasklet.xpath as rwxpath
+
+class TestGiXpath(unittest.TestCase):
+    def setUp(self):
+        rwxpath.reset_cache()
+
+    def test_nsd_elements(self):
+        """
+        Test that a particular element in a list is corerctly retrieved. In
+        this case, we are trying to retrieve an NSD from the NSD catalog.
+
+        """
+        # Create the initial NSD catalog
+        nsd_catalog = NsdYang.YangData_Nsd_NsdCatalog()
+
+        # Create an NSD, set its 'id', and add it to the catalog
+        nsd_id = str(uuid.uuid4())
+        nsd_catalog.nsd.append(
+                NsdYang.YangData_Nsd_NsdCatalog_Nsd(
+                    id=nsd_id,
+                    )
+                )
+
+        # Retrieve the NSD using and xpath expression
+        xpath = '/nsd:nsd-catalog/nsd:nsd[nsd:id={}]'.format(nsd_id)
+        nsd = rwxpath.getxattr(nsd_catalog, xpath)
+
+        self.assertEqual(nsd_id, nsd.id)
+
+        # Modified the name of the NSD using an xpath expression
+        rwxpath.setxattr(nsd_catalog, xpath + "/nsd:name", "test-name")
+
+        name = rwxpath.getxattr(nsd_catalog, xpath + "/nsd:name")
+        self.assertEqual("test-name", name)
+
+    def test_nsd_scalar_fields(self):
+        """
+        Test that setxattr correctly sets the value specified by an xpath.
+
+        """
+        # Define a simple NSD
+        nsd = NsdYang.YangData_Nsd_NsdCatalog_Nsd()
+
+        # Check that the unset fields are in fact set to None
+        self.assertEqual(None, rwxpath.getxattr(nsd, "/nsd:nsd-catalog/nsd:nsd/nsd:name"))
+        self.assertEqual(None, rwxpath.getxattr(nsd, "/nsd:nsd-catalog/nsd:nsd/nsd:short-name"))
+
+        # Set the values of the 'name' and 'short-name' fields
+        rwxpath.setxattr(nsd, "/nsd:nsd-catalog/nsd:nsd/nsd:name", "test-name")
+        rwxpath.setxattr(nsd, "/nsd:nsd-catalog/nsd:nsd/nsd:short-name", "test-short-name")
+
+        # Check that the 'name' and 'short-name' fields are correctly set
+        self.assertEqual(nsd.name, rwxpath.getxattr(nsd, "/nsd:nsd-catalog/nsd:nsd/nsd:name"))
+        self.assertEqual(nsd.short_name, rwxpath.getxattr(nsd, "/nsd:nsd-catalog/nsd:nsd/nsd:short-name"))
+
+
+class TestInputParameterSubstitution(unittest.TestCase):
+    def setUp(self):
+        self.substitute_input_parameters = rwnsmtasklet.InputParameterSubstitution(logger)
+
+    def test_null_arguments(self):
+        """
+        If None is passed to the substitutor for either the NSD or the NSR
+        config, no exception should be raised.
+
+        """
+        nsd = NsdYang.YangData_Nsd_NsdCatalog_Nsd()
+        nsr_config = NsrYang.YangData_Nsr_NsInstanceConfig_Nsr()
+
+        self.substitute_input_parameters(None, None)
+        self.substitute_input_parameters(nsd, None)
+        self.substitute_input_parameters(None, nsr_config)
+
+    def test_illegal_input_parameter(self):
+        """
+        In the NSD there is a list of the parameters that are allowed to be
+        sbustituted by input parameters. This test checks that when an input
+        parameter is provided in the NSR config that is not in the NSD, it is
+        not applied.
+
+        """
+        # Define the original NSD
+        nsd = NsdYang.YangData_Nsd_NsdCatalog_Nsd()
+        nsd.name = "robert"
+        nsd.short_name = "bob"
+
+        # Define which parameters may be modified
+        nsd.input_parameter_xpath.append(
+                NsdYang.YangData_Nsd_NsdCatalog_Nsd_InputParameterXpath(
+                    xpath="/nsd:nsd-catalog/nsd:nsd/nsd:name",
+                    label="NSD Name",
+                    )
+                )
+
+        # Define the input parameters that are intended to be modified
+        nsr_config = NsrYang.YangData_Nsr_NsInstanceConfig_Nsr()
+        nsr_config.input_parameter.extend([
+            NsrYang.YangData_Nsr_NsInstanceConfig_Nsr_InputParameter(
+                xpath="/nsd:nsd-catalog/nsd:nsd/nsd:name",
+                value="alice",
+                ),
+            NsrYang.YangData_Nsr_NsInstanceConfig_Nsr_InputParameter(
+                xpath="/nsd:nsd-catalog/nsd:nsd/nsd:short-name",
+                value="alice",
+                ),
+            ])
+
+        self.substitute_input_parameters(nsd, nsr_config)
+
+        # Verify that only the parameter in the input_parameter_xpath list is
+        # modified after the input parameters have been applied.
+        self.assertEqual("alice", nsd.name)
+        self.assertEqual("bob", nsd.short_name)
+
+    def test_substitution(self):
+        """
+        Test that substitution of input parameters occurs as expected.
+
+        """
+        # Define the original NSD
+        nsd = NsdYang.YangData_Nsd_NsdCatalog_Nsd()
+        nsd.name = "robert"
+        nsd.short_name = "bob"
+
+        # Define which parameters may be modified
+        nsd.input_parameter_xpath.extend([
+                NsdYang.YangData_Nsd_NsdCatalog_Nsd_InputParameterXpath(
+                    xpath="/nsd:nsd-catalog/nsd:nsd/nsd:name",
+                    label="NSD Name",
+                    ),
+                NsdYang.YangData_Nsd_NsdCatalog_Nsd_InputParameterXpath(
+                    xpath="/nsd:nsd-catalog/nsd:nsd/nsd:short-name",
+                    label="NSD Short Name",
+                    ),
+                ])
+
+        # Define the input parameters that are intended to be modified
+        nsr_config = NsrYang.YangData_Nsr_NsInstanceConfig_Nsr()
+        nsr_config.input_parameter.extend([
+            NsrYang.YangData_Nsr_NsInstanceConfig_Nsr_InputParameter(
+                xpath="/nsd:nsd-catalog/nsd:nsd/nsd:name",
+                value="robert",
+                ),
+            NsrYang.YangData_Nsr_NsInstanceConfig_Nsr_InputParameter(
+                xpath="/nsd:nsd-catalog/nsd:nsd/nsd:short-name",
+                value="bob",
+                ),
+            ])
+
+        self.substitute_input_parameters(nsd, nsr_config)
+
+        # Verify that both the 'name' and 'short-name' fields are correctly
+        # replaced.
+        self.assertEqual("robert", nsd.name)
+        self.assertEqual("bob", nsd.short_name)
+
+
+def main(argv=sys.argv[1:]):
+    logging.basicConfig(format='TEST %(message)s')
+
+    parser = argparse.ArgumentParser()
+    parser.add_argument('-v', '--verbose', action='store_true')
+
+    args = parser.parse_args(argv)
+
+    # Set the global logging level
+    logging.getLogger().setLevel(logging.DEBUG if args.verbose else logging.FATAL)
+
+    # Make the test logger very quiet
+    logger.addHandler(logging.NullHandler())
+
+    # The unittest framework requires a program name, so use the name of this
+    # file instead (we do not want to have to pass a fake program name to main
+    # when this is called from the interpreter).
+    unittest.main(argv=[__file__] + argv,
+            testRunner=xmlrunner.XMLTestRunner(
+                output=os.environ["RIFT_MODULE_TEST"]))
+
+if __name__ == '__main__':
+    main()