예제 #1
0
class ContainerTest(unittest.TestCase):
    def setUp(self):
        self.ctx = Context(YANG_DIR)
        mod = self.ctx.load_module('yolo-system')
        mod.feature_enable_all()
        self.container = next(self.ctx.find_path('/yolo-system:conf'))

    def tearDown(self):
        self.container = None
        self.ctx = None

    def test_cont_attrs(self):
        self.assertIsInstance(self.container, Container)
        self.assertEqual(self.container.nodetype(), Node.CONTAINER)
        self.assertEqual(self.container.keyword(), 'container')
        self.assertEqual(self.container.name(), 'conf')
        self.assertEqual(self.container.fullname(), 'yolo-system:conf')
        self.assertEqual(self.container.description(), 'Configuration.')
        self.assertEqual(self.container.config_set(), False)
        self.assertEqual(self.container.config_false(), False)
        self.assertEqual(self.container.mandatory(), False)
        self.assertIsInstance(self.container.module(), Module)
        self.assertEqual(self.container.schema_path(), '/yolo-system:conf')
        self.assertEqual(self.container.data_path(), '/yolo-system:conf')
        self.assertIs(self.container.presence(), None)

    def test_cont_iter(self):
        children = list(iter(self.container))
        self.assertEqual(len(children), 6)

    def test_cont_children_leafs(self):
        leafs = list(self.container.children(types=(Node.LEAF, )))
        self.assertEqual(len(leafs), 4)
예제 #2
0
class RevisionTest(unittest.TestCase):
    def setUp(self):
        self.ctx = Context(YANG_DIR)
        mod = self.ctx.load_module('yolo-system')
        revisions = list(mod.revisions())
        self.revision = revisions[0]

    def tearDown(self):
        self.revision = None
        self.ctx.destroy()
        self.ctx = None

    def test_rev_date(self):
        self.assertEqual(self.revision.date(), '1999-04-01')

    def test_rev_reference(self):
        self.assertEqual(
            self.revision.reference(),
            'RFC 2549 - IP over Avian Carriers with Quality of Service.')

    def test_rev_description(self):
        self.assertEqual(self.revision.description(), 'Version update.')

    def test_rev_extensions(self):
        exts = list(self.revision.extensions())
        self.assertEqual(len(exts), 1)
        ext = self.revision.get_extension('human-name',
                                          prefix='omg-extensions')
        self.assertIsInstance(ext, Extension)
예제 #3
0
class RpcTest(unittest.TestCase):
    def setUp(self):
        self.ctx = Context(YANG_DIR)
        self.ctx.load_module("yolo-system")
        self.rpc = next(self.ctx.find_path("/yolo-system:format-disk"))

    def tearDown(self):
        self.rpc = None
        self.ctx.destroy()
        self.ctx = None

    def test_rpc_attrs(self):
        self.assertIsInstance(self.rpc, SRpc)
        self.assertEqual(self.rpc.nodetype(), SNode.RPC)
        self.assertEqual(self.rpc.keyword(), "rpc")
        self.assertEqual(self.rpc.schema_path(), "/yolo-system:format-disk")

    def test_rpc_extensions(self):
        ext = list(self.rpc.extensions())
        self.assertEqual(len(ext), 1)
        ext = self.rpc.get_extension("require-admin", prefix="omg-extensions")
        self.assertIsInstance(ext, Extension)

    def test_rpc_params(self):
        leaf = next(self.rpc.children())
        self.assertIsInstance(leaf, SLeaf)
        self.assertEqual(leaf.data_path(), "/yolo-system:format-disk/disk")
        leaf = next(self.rpc.input().children())
        self.assertIsInstance(leaf, SLeaf)

    def test_rpc_no_parent(self):
        self.assertIsNone(self.rpc.parent())
예제 #4
0
class ListTest(unittest.TestCase):

    SCHEMA_PATH = '/yolo-system:conf/yolo-system:url'
    DATA_PATH = "/yolo-system:conf/url[proto='%s'][host='%s']"

    def setUp(self):
        self.ctx = Context(YANG_DIR)
        self.ctx.load_module('yolo-system')
        self.list = next(self.ctx.find_path(self.SCHEMA_PATH))

    def tearDown(self):
        self.list = None
        self.ctx = None

    def test_list_attrs(self):
        self.assertIsInstance(self.list, List)
        self.assertEqual(self.list.nodetype(), Node.LIST)
        self.assertEqual(self.list.keyword(), 'list')
        self.assertEqual(self.list.schema_path(), self.SCHEMA_PATH)
        self.assertEqual(self.list.data_path(), self.DATA_PATH)
        self.assertFalse(self.list.ordered())

    def test_list_keys(self):
        keys = list(self.list.keys())
        self.assertEqual(len(keys), 2)

    def test_list_iter(self):
        children = list(iter(self.list))
        self.assertEqual(len(children), 4)

    def test_list_children_skip_keys(self):
        children = list(self.list.children(skip_keys=True))
        self.assertEqual(len(children), 2)
예제 #5
0
class RpcTest(unittest.TestCase):
    def setUp(self):
        self.ctx = Context(YANG_DIR)
        self.ctx.load_module('yolo-system')
        self.rpc = next(self.ctx.find_path('/yolo-system:format-disk'))

    def tearDown(self):
        self.rpc = None
        self.ctx = None

    def test_rpc_attrs(self):
        self.assertIsInstance(self.rpc, Rpc)
        self.assertEqual(self.rpc.nodetype(), Node.RPC)
        self.assertEqual(self.rpc.keyword(), 'rpc')
        self.assertEqual(self.rpc.schema_path(), '/yolo-system:format-disk')

    def test_rpc_extensions(self):
        ext = list(self.rpc.extensions())
        self.assertEqual(len(ext), 1)
        ext = self.rpc.get_extension('require-admin', prefix='omg-extensions')
        self.assertIsInstance(ext, Extension)

    def test_rpc_params(self):
        leaf = next(self.rpc.children())
        self.assertIsInstance(leaf, Leaf)
        self.assertEqual(leaf.data_path(), '/yolo-system:format-disk/disk')
        leaf = next(self.rpc.input().children())
        self.assertIsInstance(leaf, Leaf)
예제 #6
0
 def setUp(self):
     self.ctx = Context(YANG_DIR)
     mod = self.ctx.load_module('yolo-system')
     mod.feature_enable_all()
     self.leaf = next(
         self.ctx.find_path(
             '/yolo-system:conf/yolo-system:isolation-level'))
예제 #7
0
 def test_ctx_env_search_dir(self):
     try:
         os.environ['YANGPATH'] = ':'.join([
             os.path.join(YANG_DIR, 'omg'),
             os.path.join(YANG_DIR, 'wtf'),
         ])
         ctx = Context(os.path.join(YANG_DIR, 'yolo'))
         mod = ctx.load_module('yolo-system')
         self.assertIsInstance(mod, Module)
     finally:
         del os.environ['YANGPATH']
예제 #8
0
 def test_diff(self):
     with Context(OLD_YANG_DIR) as ctx_old, Context(NEW_YANG_DIR) as ctx_new:
         mod = ctx_old.load_module("yolo-system")
         mod.feature_enable_all()
         mod = ctx_new.load_module("yolo-system")
         mod.feature_enable_all()
         diffs = []
         for d in schema_diff(ctx_old, ctx_new):
             if isinstance(d, (SNodeAdded, SNodeRemoved)):
                 diffs.append((d.__class__, d.node.schema_path()))
             else:
                 diffs.append((d.__class__, d.new.schema_path()))
         self.assertEqual(frozenset(diffs), self.expected_diffs)
예제 #9
0
 def test_ctx_env_search_dir(self):
     try:
         os.environ["YANGPATH"] = ":".join(
             [os.path.join(YANG_DIR, "omg"), os.path.join(YANG_DIR, "wtf")]
         )
         with Context(os.path.join(YANG_DIR, "yolo")) as ctx:
             mod = ctx.load_module("yolo-system")
             self.assertIsInstance(mod, Module)
     finally:
         del os.environ["YANGPATH"]
예제 #10
0
class ListTest(unittest.TestCase):

    SCHEMA_PATH = "/yolo-system:conf/yolo-system:url"
    DATA_PATH = "/yolo-system:conf/url[proto='%s'][host='%s']"

    def setUp(self):
        self.ctx = Context(YANG_DIR)
        self.ctx.load_module("yolo-system")
        self.list = next(self.ctx.find_path(self.SCHEMA_PATH))

    def tearDown(self):
        self.list = None
        self.ctx.destroy()
        self.ctx = None

    def test_list_attrs(self):
        self.assertIsInstance(self.list, SList)
        self.assertEqual(self.list.nodetype(), SNode.LIST)
        self.assertEqual(self.list.keyword(), "list")
        self.assertEqual(self.list.schema_path(), self.SCHEMA_PATH)
        self.assertEqual(self.list.data_path(), self.DATA_PATH)
        self.assertFalse(self.list.ordered())

    def test_list_keys(self):
        keys = list(self.list.keys())
        self.assertEqual(len(keys), 2)

    def test_list_iter(self):
        children = list(iter(self.list))
        self.assertEqual(len(children), 6)

    def test_list_children_skip_keys(self):
        children = list(self.list.children(skip_keys=True))
        self.assertEqual(len(children), 4)

    def test_list_parent(self):
        parent = self.list.parent()
        self.assertIsNotNone(parent)
        self.assertIsInstance(parent, SContainer)
        self.assertEqual(parent.name(), "conf")
예제 #11
0
class IfFeatureTest(unittest.TestCase):
    def setUp(self):
        self.ctx = Context(YANG_DIR)
        mod = self.ctx.load_module("yolo-system")
        mod.feature_enable_all()
        self.leaf = next(
            self.ctx.find_path("/yolo-system:conf/yolo-system:isolation-level")
        )

    def tearDown(self):
        self.ctx.destroy()
        self.ctx = None

    def test_iffeatures(self):
        iffeatures = list(self.leaf.if_features())
        self.assertEqual(len(iffeatures), 1)

    def test_iffeature_tree(self):
        iff = next(self.leaf.if_features())
        tree = iff.tree()
        self.assertIsInstance(tree, IfOrFeatures)
        self.assertIsInstance(tree.a, IfFeature)
        self.assertIsInstance(tree.b, IfFeature)
        self.assertEqual(tree.a.feature().name(), "turbo-boost")
        self.assertEqual(tree.b.feature().name(), "networking")

    def test_iffeature_str(self):
        iff = next(self.leaf.if_features())
        self.assertEqual(str(iff), "turbo-boost OR networking")

    def test_iffeature_dump(self):
        iff = next(self.leaf.if_features())
        self.assertEqual(
            iff.dump(),
            """OR
 turbo-boost [Goes faster.]
 networking [Supports networking.]
""",
        )
예제 #12
0
class ModuleTest(unittest.TestCase):
    def setUp(self):
        self.ctx = Context(YANG_DIR)
        self.module = self.ctx.load_module('yolo-system')

    def tearDown(self):
        self.module = None
        self.ctx = None

    def test_mod_dump_str(self):
        s = str(self.module)
        self.assertGreater(len(s), 0)

    def test_mod_attrs(self):
        self.assertEqual(self.module.name(), 'yolo-system')
        self.assertEqual(self.module.description(), 'YOLO.')
        self.assertEqual(self.module.prefix(), 'sys')

    def test_mod_iter(self):
        children = list(iter(self.module))
        self.assertEqual(len(children), 4)

    def test_mod_children_rpcs(self):
        rpcs = list(self.module.children(types=(Node.RPC, )))
        self.assertEqual(len(rpcs), 2)

    def test_mod_features(self):
        self.assertFalse(self.module.feature_state('turbo-boost'))
        self.module.feature_enable('turbo-boost')
        self.assertTrue(self.module.feature_state('turbo-boost'))
        self.module.feature_disable('turbo-boost')
        self.assertFalse(self.module.feature_state('turbo-boost'))
        self.module.feature_enable_all()
        self.assertTrue(self.module.feature_state('turbo-boost'))
        self.module.feature_disable_all()

    def test_mod_revisions(self):
        revisions = list(self.module.revisions())
        self.assertEqual(len(revisions), 2)
        self.assertIsInstance(revisions[0], Revision)
        self.assertEqual(revisions[0].date(), '1999-04-01')
        self.assertEqual(revisions[1].date(), '1990-04-01')
예제 #13
0
 def test_ctx_invalid_dir(self):
     with Context('/does/not/exist') as ctx:
         self.assertIsNot(ctx, None)
예제 #14
0
 def setUp(self):
     self.ctx = Context(YANG_DIR)
     self.ctx.load_module('yolo-system')
     self.rpc = next(self.ctx.find_path('/yolo-system:format-disk'))
예제 #15
0
class LeafTypeTest(unittest.TestCase):
    def setUp(self):
        self.ctx = Context(YANG_DIR)
        self.ctx.load_module('yolo-system')

    def tearDown(self):
        self.ctx = None

    def test_leaf_type_derived(self):
        leaf = next(
            self.ctx.find_path('/yolo-system:conf/yolo-system:hostname'))
        self.assertIsInstance(leaf, Leaf)
        t = leaf.type()
        self.assertIsInstance(t, Type)
        self.assertEqual(t.name(), 'host')
        self.assertEqual(t.base(), Type.STRING)
        d = t.derived_type()
        self.assertEqual(d.name(), 'str')
        dd = d.derived_type()
        self.assertEqual(dd.name(), 'string')

    def test_leaf_type_status(self):
        leaf = next(
            self.ctx.find_path('/yolo-system:conf/yolo-system:hostname'))
        self.assertIsInstance(leaf, Leaf)
        self.assertEqual(leaf.deprecated(), False)
        self.assertEqual(leaf.obsolete(), False)
        leaf = next(
            self.ctx.find_path(
                '/yolo-system:conf/yolo-system:deprecated-leaf'))
        self.assertIsInstance(leaf, Leaf)
        self.assertEqual(leaf.deprecated(), True)
        self.assertEqual(leaf.obsolete(), False)
        leaf = next(
            self.ctx.find_path('/yolo-system:conf/yolo-system:obsolete-leaf'))
        self.assertIsInstance(leaf, Leaf)
        self.assertEqual(leaf.deprecated(), False)
        self.assertEqual(leaf.obsolete(), True)

    def test_leaf_type_union(self):
        leaf = next(self.ctx.find_path('/yolo-system:conf/yolo-system:number'))
        self.assertIsInstance(leaf, LeafList)
        t = leaf.type()
        self.assertIsInstance(t, Type)
        self.assertEqual(t.name(), 'number')
        self.assertEqual(t.base(), Type.UNION)
        types = set(u.name() for u in t.union_types())
        self.assertEqual(types, set(['signed', 'unsigned']))
        bases = set(t.basenames())
        self.assertEqual(bases, set(['int16', 'int32', 'uint16', 'uint32']))

    def test_leaf_type_enum(self):
        leaf = next(
            self.ctx.find_path(
                '/yolo-system:conf/yolo-system:url/yolo-system:proto'))
        self.assertIsInstance(leaf, Leaf)
        t = leaf.type()
        self.assertIsInstance(t, Type)
        self.assertEqual(t.name(), 'protocol')
        self.assertEqual(t.base(), Type.ENUM)
        enums = [e for e, _ in t.enums()]
        self.assertEqual(enums, ['http', 'https', 'ftp', 'sftp', 'tftp'])

    def test_leaf_type_bits(self):
        leaf = next(
            self.ctx.find_path(
                '/yolo-system:chmod/yolo-system:input/yolo-system:perms'))
        self.assertIsInstance(leaf, Leaf)
        t = leaf.type()
        self.assertIsInstance(t, Type)
        self.assertEqual(t.name(), 'permissions')
        self.assertEqual(t.base(), Type.BITS)
        bits = [b for b, _ in t.bits()]
        self.assertEqual(bits, ['read', 'write', 'execute'])
예제 #16
0
 def setUp(self):
     self.ctx = Context(YANG_DIR)
     self.ctx.load_module('yolo-system')
     self.list = next(self.ctx.find_path(self.SCHEMA_PATH))
예제 #17
0
 def test_ctx_get_invalid_module(self):
     with Context(YANG_DIR) as ctx:
         ctx.load_module('wtf-types')
         with self.assertRaises(LibyangError):
             ctx.get_module('yolo-system')
예제 #18
0
 def test_ctx_get_module(self):
     with Context(YANG_DIR) as ctx:
         ctx.load_module('yolo-system')
         mod = ctx.get_module('wtf-types')
         self.assertIsInstance(mod, Module)
예제 #19
0
 def test_ctx_load_invalid_module(self):
     with Context(YANG_DIR) as ctx:
         with self.assertRaises(LibyangError):
             ctx.load_module('invalid-module')
예제 #20
0
 def setUp(self):
     self.ctx = Context(YANG_DIR)
     self.module = self.ctx.load_module('yolo-system')
예제 #21
0
class DataTest(unittest.TestCase):
    def setUp(self):
        self.ctx = Context(YANG_DIR)
        mod = self.ctx.load_module('yolo-system')
        mod.feature_enable_all()

    def tearDown(self):
        self.ctx.destroy()
        self.ctx = None

    JSON_CONFIG = '''{
  "yolo-system:conf": {
    "hostname": "foo",
    "speed": 1234,
    "number": [
      1000,
      2000,
      3000
    ],
    "url": [
      {
        "proto": "https",
        "host": "github.com",
        "path": "/rjarry/libyang-cffi",
        "enabled": false
      },
      {
        "proto": "http",
        "host": "foobar.com",
        "port": 8080,
        "path": "/index.html",
        "enabled": true
      }
    ]
  }
}
'''

    def test_data_parse_config_json(self):
        dnode = self.ctx.parse_data_mem(self.JSON_CONFIG, 'json', config=True)
        self.assertIsInstance(dnode, DContainer)
        try:
            j = dnode.print_mem('json', pretty=True)
            self.assertEqual(j, self.JSON_CONFIG)
        finally:
            dnode.free()

    JSON_STATE = '''{
  "yolo-system:state": {
    "hostname": "foo",
    "speed": 1234,
    "number": [
      1000,
      2000,
      3000
    ],
    "url": [
      {
        "proto": "https",
        "host": "github.com",
        "path": "/rjarry/libyang-cffi",
        "enabled": false
      },
      {
        "proto": "http",
        "host": "foobar.com",
        "port": 8080,
        "path": "/index.html",
        "enabled": true
      }
    ]
  }
}
'''

    def test_data_parse_state_json(self):
        dnode = self.ctx.parse_data_mem(self.JSON_STATE,
                                        'json',
                                        data=True,
                                        no_yanglib=True)
        self.assertIsInstance(dnode, DContainer)
        try:
            j = dnode.print_mem('json', pretty=True)
            self.assertEqual(j, self.JSON_STATE)
        finally:
            dnode.free()

    XML_CONFIG = '''<conf xmlns="urn:yang:yolo:system">
  <hostname>foo</hostname>
  <speed>1234</speed>
  <number>1000</number>
  <number>2000</number>
  <number>3000</number>
  <url>
    <proto>https</proto>
    <host>github.com</host>
    <path>/rjarry/libyang-cffi</path>
    <enabled>false</enabled>
  </url>
  <url>
    <proto>http</proto>
    <host>foobar.com</host>
    <port>8080</port>
    <path>/index.html</path>
    <enabled>true</enabled>
  </url>
</conf>
'''

    def test_data_parse_config_xml(self):
        dnode = self.ctx.parse_data_mem(self.XML_CONFIG, 'xml', config=True)
        self.assertIsInstance(dnode, DContainer)
        try:
            xml = dnode.print_mem('xml', pretty=True)
            self.assertEqual(xml, self.XML_CONFIG)
        finally:
            dnode.free()

    XML_STATE = '''<state xmlns="urn:yang:yolo:system">
  <hostname>foo</hostname>
  <speed>1234</speed>
  <number>1000</number>
  <number>2000</number>
  <number>3000</number>
  <url>
    <proto>https</proto>
    <host>github.com</host>
    <path>/rjarry/libyang-cffi</path>
    <enabled>false</enabled>
  </url>
  <url>
    <proto>http</proto>
    <host>foobar.com</host>
    <port>8080</port>
    <path>/index.html</path>
    <enabled>true</enabled>
  </url>
</state>
'''

    def test_data_parse_data_xml(self):
        dnode = self.ctx.parse_data_mem(self.XML_STATE,
                                        'xml',
                                        data=True,
                                        no_yanglib=True)
        self.assertIsInstance(dnode, DContainer)
        try:
            xml = dnode.print_mem('xml', pretty=True)
            self.assertEqual(xml, self.XML_STATE)
        finally:
            dnode.free()

    def test_data_create_paths(self):
        state = self.ctx.create_data_path('/yolo-system:state')
        try:
            state.create_path('hostname', 'foo')
            state.create_path('speed', 1234)
            state.create_path('number', 1000)
            state.create_path('number', 2000)
            state.create_path('number', 3000)
            u = state.create_path('url[proto="https"][host="github.com"]')
            u.create_path('path', '/rjarry/libyang-cffi')
            u.create_path('enabled', False)
            u = state.create_path('url[proto="http"][host="foobar.com"]')
            u.create_path('port', 8080)
            u.create_path('path', '/index.html')
            u.create_path('enabled', True)
            state.validate(strict=True)
            self.assertEqual(state.print_mem('json', pretty=True),
                             self.JSON_STATE)
        finally:
            state.free()

    def test_data_create_invalid_type(self):
        s = self.ctx.create_data_path('/yolo-system:state')
        try:
            with self.assertRaises(LibyangError):
                s.create_path('speed', 1234000000000000000000000000)
        finally:
            s.free()

    def test_data_create_invalid_regexp(self):
        s = self.ctx.create_data_path('/yolo-system:state')
        try:
            with self.assertRaises(LibyangError):
                s.create_path('hostname', 'INVALID.HOST')
        finally:
            s.free()

    DICT_CONFIG = {
        'conf': {
            'hostname':
            'foo',
            'speed':
            1234,
            'number': [1000, 2000, 3000],
            'url': [
                {
                    'proto': 'https',
                    'host': 'github.com',
                    'path': '/rjarry/libyang-cffi',
                    'enabled': False,
                },
                {
                    'proto': 'http',
                    'host': 'foobar.com',
                    'port': 8080,
                    'path': '/index.html',
                    'enabled': True,
                },
            ],
        },
    }

    def test_data_to_dict_config(self):
        dnode = self.ctx.parse_data_mem(self.JSON_CONFIG, 'json', config=True)
        self.assertIsInstance(dnode, DContainer)
        try:
            dic = dnode.print_dict()
        finally:
            dnode.free()
        self.assertEqual(dic, self.DICT_CONFIG)

    def test_data_to_dict_rpc_input(self):
        dnode = self.ctx.parse_data_mem(
            '{"yolo-system:format-disk": {"disk": "/dev/sda"}}',
            'json',
            rpc=True)
        self.assertIsInstance(dnode, DRpc)
        try:
            dic = dnode.print_dict()
        finally:
            dnode.free()
        self.assertEqual(dic, {'format-disk': {'disk': '/dev/sda'}})

    def test_data_from_dict_module(self):
        module = self.ctx.get_module('yolo-system')
        dnode = module.parse_data_dict(self.DICT_CONFIG)
        self.assertIsInstance(dnode, DContainer)
        try:
            j = dnode.print_mem('json', pretty=True)
        finally:
            dnode.free()
        self.assertEqual(json.loads(j), json.loads(self.JSON_CONFIG))

    def test_data_from_dict_invalid(self):
        try:
            from unittest.mock import patch
        except ImportError:
            self.skipTest('unittest.mock not available')
        module = self.ctx.get_module('yolo-system')
        orig_create = Context.create_data_path
        orig_free = DNode.free
        created = []
        freed = []

        def wrapped_create(self, *args, **kwargs):
            c = orig_create(self, *args, **kwargs)
            if c is not None:
                created.append(c)
            return c

        def wrapped_free(self, *args, **kwargs):
            freed.append(self)
            orig_free(self, *args, **kwargs)

        root = module.parse_data_dict({
            'conf': {
                'hostname': 'foo',
                'speed': 1234,
                'number': [1000, 2000, 3000],
            }
        })

        invalid_dict = {
            'conf': {
                'url': [
                    {
                        'proto': 'https',
                        'host': 'github.com',
                        'path': '/rjarry/libyang-cffi',
                        'enabled': False,
                    },
                    {
                        'proto': 'http',
                        'host': 'foobar.com',
                        'port': 'INVALID.PORT',
                        'path': '/index.html',
                        'enabled': True,
                    },
                ],
            },
        }

        try:
            with patch.object(Context, 'create_data_path', wrapped_create), \
                    patch.object(DNode, 'free', wrapped_free):
                with self.assertRaises(LibyangError):
                    module.parse_data_dict(invalid_dict, parent=root)
            self.assertGreater(len(created), 0)
            self.assertGreater(len(freed), 0)
            self.assertEqual(freed, list(reversed(created)))
        finally:
            root.free()

    def test_data_from_dict_container(self):
        snode = next(self.ctx.find_path('/yolo-system:conf'))
        self.assertIsInstance(snode, SContainer)
        dnode = snode.parse_data_dict(self.DICT_CONFIG)
        self.assertIsInstance(dnode, DContainer)
        try:
            j = dnode.print_mem('json', pretty=True)
        finally:
            dnode.free()
        self.assertEqual(json.loads(j), json.loads(self.JSON_CONFIG))

    def test_data_from_dict_leaf(self):
        snode = next(
            self.ctx.find_path('/yolo-system:state/yolo-system:hostname'))
        self.assertIsInstance(snode, SLeaf)
        dnode = snode.parse_data_dict({'hostname': 'foo'})
        try:
            j = dnode.print_mem('json')
        finally:
            dnode.free()
        self.assertEqual(j, '{"yolo-system:state":{"hostname":"foo"}}')

    def test_data_from_dict_rpc(self):
        snode = next(self.ctx.find_path('/yolo-system:format-disk'))
        self.assertIsInstance(snode, SRpc)
        dnode = snode.parse_data_dict({'format-disk': {
            'duration': 42
        }},
                                      rpc_output=True)
        self.assertIsInstance(dnode, DRpc)
        try:
            j = dnode.print_mem('json')
        finally:
            dnode.free()
        self.assertEqual(j, '{"yolo-system:format-disk":{"duration":42}}')
예제 #22
0
class ModuleTest(unittest.TestCase):
    def setUp(self):
        self.ctx = Context(YANG_DIR)
        self.module = self.ctx.load_module('yolo-system')

    def tearDown(self):
        self.module = None
        self.ctx.destroy()
        self.ctx = None

    def test_mod_print_mem(self):
        s = self.module.print_mem('tree')
        self.assertGreater(len(s), 0)

    def test_mod_attrs(self):
        self.assertEqual(self.module.name(), 'yolo-system')
        self.assertEqual(self.module.description(), 'YOLO.')
        self.assertEqual(self.module.prefix(), 'sys')

    def test_mod_filepath(self):
        self.assertEqual(self.module.filepath(),
                         os.path.join(YANG_DIR, 'yolo/yolo-system.yang'))

    def test_mod_iter(self):
        children = list(iter(self.module))
        self.assertEqual(len(children), 4)

    def test_mod_children_rpcs(self):
        rpcs = list(self.module.children(types=(SNode.RPC, )))
        self.assertEqual(len(rpcs), 2)

    def test_mod_enable_features(self):
        self.assertFalse(self.module.feature_state('turbo-boost'))
        self.module.feature_enable('turbo-boost')
        self.assertTrue(self.module.feature_state('turbo-boost'))
        self.module.feature_disable('turbo-boost')
        self.assertFalse(self.module.feature_state('turbo-boost'))
        self.module.feature_enable_all()
        self.assertTrue(self.module.feature_state('turbo-boost'))
        self.module.feature_disable_all()

    def test_mod_features(self):
        features = list(self.module.features())
        self.assertEqual(len(features), 2)

    def test_mod_get_feature(self):
        self.module.feature_enable('turbo-boost')
        feature = self.module.get_feature('turbo-boost')
        self.assertEqual(feature.name(), 'turbo-boost')
        self.assertEqual(feature.description(), 'Goes faster.')
        self.assertIsNone(feature.reference())
        self.assertTrue(feature.state())
        self.assertFalse(feature.deprecated())
        self.assertFalse(feature.obsolete())

    def test_mod_get_feature_not_found(self):
        with self.assertRaises(LibyangError):
            self.module.get_feature('does-not-exist')

    def test_mod_revisions(self):
        revisions = list(self.module.revisions())
        self.assertEqual(len(revisions), 2)
        self.assertIsInstance(revisions[0], Revision)
        self.assertEqual(revisions[0].date(), '1999-04-01')
        self.assertEqual(revisions[1].date(), '1990-04-01')
예제 #23
0
 def test_ctx_missing_dir(self):
     with Context(os.path.join(YANG_DIR, 'yolo')) as ctx:
         self.assertIsNot(ctx, None)
         with self.assertRaises(LibyangError):
             ctx.load_module('yolo-system')
예제 #24
0
class DataTest(unittest.TestCase):
    def setUp(self):
        self.ctx = Context(YANG_DIR)
        mod = self.ctx.load_module("yolo-system")
        mod.feature_enable_all()

    def tearDown(self):
        self.ctx.destroy()
        self.ctx = None

    JSON_CONFIG = """{
  "yolo-system:conf": {
    "hostname": "foo",
    "speed": 1234,
    "number": [
      1000,
      2000,
      3000
    ],
    "url": [
      {
        "proto": "https",
        "host": "github.com",
        "path": "/CESNET/libyang-python",
        "enabled": false
      },
      {
        "proto": "http",
        "host": "foobar.com",
        "port": 8080,
        "path": "/index.html",
        "enabled": true
      }
    ]
  }
}
"""

    def test_data_parse_config_json(self):
        dnode = self.ctx.parse_data_mem(self.JSON_CONFIG, "json", config=True)
        self.assertIsInstance(dnode, DContainer)
        try:
            j = dnode.print_mem("json", pretty=True)
            self.assertEqual(j, self.JSON_CONFIG)
        finally:
            dnode.free()

    JSON_STATE = """{
  "yolo-system:state": {
    "hostname": "foo",
    "speed": 1234,
    "number": [
      1000,
      2000,
      3000
    ],
    "url": [
      {
        "proto": "https",
        "host": "github.com",
        "path": "/CESNET/libyang-python",
        "enabled": false
      },
      {
        "proto": "http",
        "host": "foobar.com",
        "port": 8080,
        "path": "/index.html",
        "enabled": true
      }
    ]
  }
}
"""

    def test_data_parse_state_json(self):
        dnode = self.ctx.parse_data_mem(self.JSON_STATE,
                                        "json",
                                        data=True,
                                        no_yanglib=True)
        self.assertIsInstance(dnode, DContainer)
        try:
            j = dnode.print_mem("json", pretty=True)
            self.assertEqual(j, self.JSON_STATE)
        finally:
            dnode.free()

    XML_CONFIG = """<conf xmlns="urn:yang:yolo:system">
  <hostname>foo</hostname>
  <speed>1234</speed>
  <number>1000</number>
  <number>2000</number>
  <number>3000</number>
  <url>
    <proto>https</proto>
    <host>github.com</host>
    <path>/CESNET/libyang-python</path>
    <enabled>false</enabled>
  </url>
  <url>
    <proto>http</proto>
    <host>foobar.com</host>
    <port>8080</port>
    <path>/index.html</path>
    <enabled>true</enabled>
  </url>
</conf>
"""

    def test_data_parse_config_xml(self):
        dnode = self.ctx.parse_data_mem(self.XML_CONFIG, "xml", config=True)
        self.assertIsInstance(dnode, DContainer)
        try:
            xml = dnode.print_mem("xml", pretty=True)
            self.assertEqual(xml, self.XML_CONFIG)
        finally:
            dnode.free()

    XML_STATE = """<state xmlns="urn:yang:yolo:system">
  <hostname>foo</hostname>
  <speed>1234</speed>
  <number>1000</number>
  <number>2000</number>
  <number>3000</number>
  <url>
    <proto>https</proto>
    <host>github.com</host>
    <path>/CESNET/libyang-python</path>
    <enabled>false</enabled>
  </url>
  <url>
    <proto>http</proto>
    <host>foobar.com</host>
    <port>8080</port>
    <path>/index.html</path>
    <enabled>true</enabled>
  </url>
</state>
"""

    def test_data_parse_data_xml(self):
        dnode = self.ctx.parse_data_mem(self.XML_STATE,
                                        "xml",
                                        data=True,
                                        no_yanglib=True)
        self.assertIsInstance(dnode, DContainer)
        try:
            xml = dnode.print_mem("xml", pretty=True)
            self.assertEqual(xml, self.XML_STATE)
        finally:
            dnode.free()

    def test_data_parse_duplicate_data_type(self):
        with self.assertRaises(ValueError):
            self.ctx.parse_data_mem("", "xml", edit=True, rpc=True)

    XML_EDIT = """<conf xmlns="urn:yang:yolo:system">
  <hostname-ref>notdefined</hostname-ref>
</conf>
"""

    def test_data_parse_edit(self):
        dnode = self.ctx.parse_data_mem(self.XML_EDIT, "xml", edit=True)
        self.assertIsInstance(dnode, DContainer)
        try:
            xml = dnode.print_mem("xml", pretty=True)
            self.assertEqual(xml, self.XML_EDIT)
        finally:
            dnode.free()

    def test_data_create_paths(self):
        state = self.ctx.create_data_path("/yolo-system:state")
        try:
            state.create_path("hostname", "foo")
            state.create_path("speed", 1234)
            state.create_path("number", 1000)
            state.create_path("number", 2000)
            state.create_path("number", 3000)
            u = state.create_path('url[proto="https"][host="github.com"]')
            u.create_path("path", "/CESNET/libyang-python")
            u.create_path("enabled", False)
            u = state.create_path('url[proto="http"][host="foobar.com"]')
            u.create_path("port", 8080)
            u.create_path("path", "/index.html")
            u.create_path("enabled", True)
            self.assertEqual(state.print_mem("json", pretty=True),
                             self.JSON_STATE)
        finally:
            state.free()

    def test_data_create_invalid_type(self):
        s = self.ctx.create_data_path("/yolo-system:state")
        try:
            with self.assertRaises(LibyangError):
                s.create_path("speed", 1234000000000000000000000000)
        finally:
            s.free()

    def test_data_create_invalid_regexp(self):
        s = self.ctx.create_data_path("/yolo-system:state")
        try:
            with self.assertRaises(LibyangError):
                s.create_path("hostname", "INVALID.HOST")
        finally:
            s.free()

    DICT_CONFIG = {
        "conf": {
            "hostname":
            "foo",
            "speed":
            1234,
            "number": [1000, 2000, 3000],
            "url": [
                {
                    "enabled": False,
                    "path": "/CESNET/libyang-python",
                    "host": "github.com",
                    "proto": "https",
                },
                {
                    "port": 8080,
                    "proto": "http",
                    "path": "/index.html",
                    "enabled": True,
                    "host": "foobar.com",
                },
            ],
        }
    }

    def test_data_to_dict_config(self):
        dnode = self.ctx.parse_data_mem(self.JSON_CONFIG, "json", config=True)
        self.assertIsInstance(dnode, DContainer)
        try:
            dic = dnode.print_dict()
        finally:
            dnode.free()
        self.assertEqual(dic, self.DICT_CONFIG)

    def test_data_to_dict_rpc_input(self):
        dnode = self.ctx.parse_data_mem(
            '{"yolo-system:format-disk": {"disk": "/dev/sda"}}',
            "json",
            rpc=True)
        self.assertIsInstance(dnode, DRpc)
        try:
            dic = dnode.print_dict()
        finally:
            dnode.free()
        self.assertEqual(dic, {"format-disk": {"disk": "/dev/sda"}})

    def test_data_from_dict_module(self):
        module = self.ctx.get_module("yolo-system")
        dnode = module.parse_data_dict(self.DICT_CONFIG,
                                       strict=True,
                                       config=True)
        self.assertIsInstance(dnode, DContainer)
        try:
            j = dnode.print_mem("json", pretty=True)
        finally:
            dnode.free()
        self.assertEqual(json.loads(j), json.loads(self.JSON_CONFIG))

    DICT_EDIT = {"conf": {"hostname-ref": "notdefined"}}

    def test_data_from_dict_edit(self):
        module = self.ctx.get_module("yolo-system")
        dnode = module.parse_data_dict(self.DICT_EDIT, strict=True, edit=True)
        self.assertIsInstance(dnode, DContainer)
        try:
            xml = dnode.print_mem("xml", pretty=True)
        finally:
            dnode.free()
        self.assertEqual(xml, self.XML_EDIT)

    def test_data_from_dict_invalid(self):
        module = self.ctx.get_module("yolo-system")

        created = []
        freed = []

        class FakeLib:
            def __init__(self, orig):
                self.orig = orig

            def lyd_new(self, *args):
                c = self.orig.lyd_new(*args)
                if c:
                    created.append(c)
                return c

            def lyd_new_leaf(self, *args):
                c = self.orig.lyd_new_leaf(*args)
                if c:
                    created.append(c)
                return c

            def lyd_free(self, dnode):
                freed.append(dnode)
                self.orig.lyd_free(dnode)

            def __getattr__(self, name):
                return getattr(self.orig, name)

        fake_lib = FakeLib(lib)

        root = module.parse_data_dict(
            {
                "conf": {
                    "hostname": "foo",
                    "speed": 1234,
                    "number": [1000, 2000, 3000]
                }
            },
            strict=True,
            config=True,
        )

        invalid_dict = {
            "url": [
                {
                    "host": "github.com",
                    "proto": "https",
                    "enabled": False,
                    "path": "/CESNET/libyang-python",
                },
                {
                    "proto": "http",
                    "path": "/index.html",
                    "enabled": True,
                    "host": "foobar.com",
                    "port": "INVALID.PORT",
                },
            ]
        }

        try:
            with patch("libyang.data.lib", fake_lib):
                with self.assertRaises(LibyangError):
                    root.merge_data_dict(invalid_dict,
                                         strict=True,
                                         config=True)
            self.assertGreater(len(created), 0)
            self.assertGreater(len(freed), 0)
            self.assertEqual(freed, list(reversed(created)))
        finally:
            root.free()

    def test_data_from_dict_container(self):
        dnode = self.ctx.create_data_path("/yolo-system:conf")
        self.assertIsInstance(dnode, DContainer)
        subtree = dnode.merge_data_dict(self.DICT_CONFIG["conf"],
                                        strict=True,
                                        config=True,
                                        validate=False)
        # make sure subtree validation is forbidden
        with self.assertRaises(LibyangError):
            subtree.validate(config=True)
        try:
            dnode.validate(config=True)
            j = dnode.print_mem("json", pretty=True)
        finally:
            dnode.free()
        self.assertEqual(json.loads(j), json.loads(self.JSON_CONFIG))

    def test_data_from_dict_leaf(self):
        dnode = self.ctx.create_data_path("/yolo-system:state")
        self.assertIsInstance(dnode, DContainer)
        dnode.merge_data_dict({"hostname": "foo"},
                              strict=True,
                              data=True,
                              no_yanglib=True)
        try:
            j = dnode.print_mem("json")
        finally:
            dnode.free()
        self.assertEqual(j, '{"yolo-system:state":{"hostname":"foo"}}')

    def test_data_from_dict_rpc(self):
        dnode = self.ctx.create_data_path("/yolo-system:format-disk")
        self.assertIsInstance(dnode, DRpc)
        dnode.merge_data_dict({"duration": 42}, rpcreply=True, strict=True)
        try:
            j = dnode.print_mem("json")
        finally:
            dnode.free()
        self.assertEqual(j, '{"yolo-system:format-disk":{"duration":42}}')

    def test_data_from_dict_action(self):
        module = self.ctx.get_module("yolo-system")
        dnode = module.parse_data_dict(
            {
                "conf": {
                    "url": [
                        {
                            "proto": "https",
                            "host": "github.com",
                            "fetch": {
                                "timeout": 42
                            },
                        },
                    ],
                },
            },
            rpc=True,
            strict=True,
        )
        self.assertIsInstance(dnode, DContainer)
        try:
            j = dnode.print_mem("json")
        finally:
            dnode.free()
        self.assertEqual(
            j,
            '{"yolo-system:conf":{"url":[{"proto":"https","host":"github.com","fetch":{"timeout":42}}]}}',
        )

    def test_data_to_dict_action(self):
        module = self.ctx.get_module("yolo-system")
        request = module.parse_data_dict(
            {
                "conf": {
                    "url": [
                        {
                            "proto": "https",
                            "host": "github.com",
                            "fetch": {
                                "timeout": 42
                            },
                        },
                    ],
                },
            },
            rpc=True,
            strict=True,
        )
        dnode = self.ctx.parse_data_mem(
            '{"yolo-system:result":"not found"}',
            "json",
            rpcreply=True,
            rpc_request=request,
        )
        try:
            dic = dnode.print_dict()
        finally:
            dnode.free()
            request.free()
        self.assertEqual(
            dic,
            {
                "conf": {
                    "url": [
                        {
                            "proto": "https",
                            "host": "github.com",
                            "fetch": {
                                "result": "not found"
                            },
                        },
                    ],
                },
            },
        )
예제 #25
0
 def test_ctx_iter_modules(self):
     with Context(YANG_DIR) as ctx:
         ctx.load_module('yolo-system')
         modules = list(iter(ctx))
         self.assertGreater(len(modules), 0)
예제 #26
0
 def test_ctx_find_path(self):
     with Context(YANG_DIR) as ctx:
         ctx.load_module('yolo-system')
         node = next(ctx.find_path('/yolo-system:format-disk'))
         self.assertIsInstance(node, SRpc)
예제 #27
0
 def setUp(self):
     self.ctx = Context(YANG_DIR)
     mod = self.ctx.load_module('yolo-system')
     revisions = list(mod.revisions())
     self.revision = revisions[0]
예제 #28
0
 def setUp(self):
     self.ctx = Context(YANG_DIR)
     mod = self.ctx.load_module('yolo-system')
     mod.feature_enable_all()
     self.container = next(self.ctx.find_path('/yolo-system:conf'))
예제 #29
0
 def setUp(self):
     self.ctx = Context(YANG_DIR)
     mod = self.ctx.load_module('yolo-system')
     mod.feature_enable_all()
예제 #30
0
 def test_ctx_load_module(self):
     with Context(YANG_DIR) as ctx:
         mod = ctx.load_module('yolo-system')
         self.assertIsInstance(mod, Module)