From 70fbe88a291428280d1b2d76466a82f084c31d4d Mon Sep 17 00:00:00 2001 From: peusterm Date: Tue, 5 Mar 2019 14:50:08 +0100 Subject: [PATCH] Polished toolchain for YANG validation #73 Signed-off-by: peusterm --- models/Makefile | 11 +- models/doc/ietf-ped.html | 28 +++ models/doc/ietf-ped.tree | 2 + models/doc/ietf-ped.uml | 6 +- models/example-instance.yml | 6 - models/examples/basic-ped.yml | 10 + models/ietf-ped.yang | 18 +- models/ietf_ped_model.py | 399 ++++++++++++++++++++++++++++++++++ models/test.py | 28 --- models/test_model.py | 64 ++++++ 10 files changed, 524 insertions(+), 48 deletions(-) delete mode 100644 models/example-instance.yml create mode 100644 models/examples/basic-ped.yml create mode 100644 models/ietf_ped_model.py delete mode 100644 models/test.py create mode 100644 models/test_model.py diff --git a/models/Makefile b/models/Makefile index a0f244f..022b4b6 100644 --- a/models/Makefile +++ b/models/Makefile @@ -26,7 +26,8 @@ # partner consortium (www.5gtango.eu). .DEFAULT_GOAL := all -DOC_DIR="doc" +DOC_DIR := "doc" +PYBINDPLUGIN := $(shell python -c 'import pyangbind; import os; print("{}/plugin".format(os.path.dirname(pyangbind.__file__)))') validate: # generate doc @@ -38,13 +39,13 @@ validate: bind: # generate / compile python model - PYBINDPLUGIN=$(shell python -c 'import pyangbind; import os; print("{}/plugin".format(os.path.dirname(pyangbind.__file__)))') - pyang --plugindir $(PYBINDPLUGIN) -f pybind -o model.py ietf-ped.yang + pyang --plugindir $(PYBINDPLUGIN) -f pybind -o ietf_ped_model.py ietf-ped.yang test: - python test.py + # test the example ped files against the model + pytest -v -all: validate bind +all: validate bind test clean: rm doc/* \ No newline at end of file diff --git a/models/doc/ietf-ped.html b/models/doc/ietf-ped.html index 7ab1bec..e3d2aa0 100644 --- a/models/doc/ietf-ped.html +++ b/models/doc/ietf-ped.html @@ -259,6 +259,34 @@

Module: ietf-ped, Namespace: ? current /pe:ped/pe:version + + +
+   + author +
+ + leaf + string + config + ? + current + /pe:ped/pe:author + + +
+   + description +
+ + leaf + string + config + ? + current + /pe:ped/pe:description diff --git a/models/doc/ietf-ped.tree b/models/doc/ietf-ped.tree index b9c95cb..4be90b7 100644 --- a/models/doc/ietf-ped.tree +++ b/models/doc/ietf-ped.tree @@ -4,3 +4,5 @@ module: ietf-ped +--rw vendor? string +--rw name? string +--rw version? string + +--rw author? string + +--rw description? string diff --git a/models/doc/ietf-ped.uml b/models/doc/ietf-ped.uml index 9b5f289..8e70c3a 100644 --- a/models/doc/ietf-ped.uml +++ b/models/doc/ietf-ped.uml @@ -12,7 +12,7 @@ hide <> stereotype hide <> circle page 1x1 Title ietf-ped -note top of pe_ietf_ped : Namespace: urn:ietf:params:xml:ns:yang:ietf-ped \nPrefix: pe \nOrganization : \n \nContact : \n \nRevision : 2019-02-21 \n +note top of pe_ietf_ped : Namespace: urn:ietf:params:xml:ns:yang:ietf-ped \nPrefix: pe \nOrganization : \nPaderborn University \nContact : \nManuel Peuster \nRevision : 2019-02-21 \n package "pe:ietf-ped" as pe_ietf_ped { class "ietf-ped" as ietf_ped << (M, #33CCFF) module>> class "ped" as ietf_ped_I_ped <> @@ -21,9 +21,11 @@ ietf_ped_I_ped : descriptor-schema : string = https://github.com/mpeuster/tng- ietf_ped_I_ped : vendor : string ietf_ped_I_ped : name : string ietf_ped_I_ped : version : string +ietf_ped_I_ped : author : string +ietf_ped_I_ped : description : string } center footer - UML Generated : 2019-02-28 22:37 + UML Generated : 2019-03-05 14:49 endfooter @enduml diff --git a/models/example-instance.yml b/models/example-instance.yml deleted file mode 100644 index 3bee0b5..0000000 --- a/models/example-instance.yml +++ /dev/null @@ -1,6 +0,0 @@ ---- -ped: - descriptor-schema: "blaa" - vendor: "com.vendor" - name: "my_example" - version: "0.1" \ No newline at end of file diff --git a/models/examples/basic-ped.yml b/models/examples/basic-ped.yml new file mode 100644 index 0000000..98f39c5 --- /dev/null +++ b/models/examples/basic-ped.yml @@ -0,0 +1,10 @@ +--- +ped: + descriptor-schema: "https://github.com/sonata-nfv/tng-sdk-benchmark/blob/master/models/" + vendor: "com.vendor" + name: "my_example_ped" + version: "0.1" + author: "Manuel Peuster " + description: "Example PED." + + \ No newline at end of file diff --git a/models/ietf-ped.yang b/models/ietf-ped.yang index 939ac65..0972413 100644 --- a/models/ietf-ped.yang +++ b/models/ietf-ped.yang @@ -30,9 +30,9 @@ module ietf-ped { namespace "urn:ietf:params:xml:ns:yang:ietf-ped"; prefix "pe"; - organization ""; - contact ""; - description ""; + organization "Paderborn University"; + contact "Manuel Peuster "; + description "Performance Experiment Descriptor (PED) model."; revision 2019-02-21 { description @@ -43,26 +43,30 @@ module ietf-ped container ped { description "Performance Experiment Descriptor (PED)"; - leaf descriptor-schema { type string; default "https://github.com/mpeuster/tng-sdk-benchmark/raw/feature-73/models/ped.yang"; // update this description "Pointer to this data model."; } - leaf vendor { type string; description "Vendor of the described experiments."; } - leaf name { type string; description "Name of the described experiments."; } - leaf version { type string; description "Version of the described experiments."; } + leaf author { + type string; + description "Author of the described experiments."; + } + leaf description { + type string; + description "Generic description text."; + } } } \ No newline at end of file diff --git a/models/ietf_ped_model.py b/models/ietf_ped_model.py new file mode 100644 index 0000000..08f7953 --- /dev/null +++ b/models/ietf_ped_model.py @@ -0,0 +1,399 @@ +# -*- coding: utf-8 -*- +from operator import attrgetter +from pyangbind.lib.yangtypes import RestrictedPrecisionDecimalType +from pyangbind.lib.yangtypes import RestrictedClassType +from pyangbind.lib.yangtypes import TypedListType +from pyangbind.lib.yangtypes import YANGBool +from pyangbind.lib.yangtypes import YANGListType +from pyangbind.lib.yangtypes import YANGDynClass +from pyangbind.lib.yangtypes import ReferenceType +from pyangbind.lib.base import PybindBase +from collections import OrderedDict +from decimal import Decimal +from bitarray import bitarray +import six + +# PY3 support of some PY2 keywords (needs improved) +if six.PY3: + import builtins as __builtin__ + long = int +elif six.PY2: + import __builtin__ + +class yc_ped_ietf_ped__ped(PybindBase): + """ + This class was auto-generated by the PythonClass plugin for PYANG + from YANG module ietf-ped - based on the path /ped. Each member element of + the container is represented as a class variable - with a specific + YANG type. + + YANG Description: Performance Experiment Descriptor (PED) + """ + __slots__ = ('_path_helper', '_extmethods', '__descriptor_schema','__vendor','__name','__version','__author','__description',) + + _yang_name = 'ped' + + _pybind_generated_by = 'container' + + def __init__(self, *args, **kwargs): + + self._path_helper = False + + self._extmethods = False + self.__descriptor_schema = YANGDynClass(base=six.text_type, default=six.text_type("https://github.com/mpeuster/tng-sdk-benchmark/raw/feature-73/models/ped.yang"), is_leaf=True, yang_name="descriptor-schema", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='urn:ietf:params:xml:ns:yang:ietf-ped', defining_module='ietf-ped', yang_type='string', is_config=True) + self.__vendor = YANGDynClass(base=six.text_type, is_leaf=True, yang_name="vendor", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='urn:ietf:params:xml:ns:yang:ietf-ped', defining_module='ietf-ped', yang_type='string', is_config=True) + self.__name = YANGDynClass(base=six.text_type, is_leaf=True, yang_name="name", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='urn:ietf:params:xml:ns:yang:ietf-ped', defining_module='ietf-ped', yang_type='string', is_config=True) + self.__version = YANGDynClass(base=six.text_type, is_leaf=True, yang_name="version", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='urn:ietf:params:xml:ns:yang:ietf-ped', defining_module='ietf-ped', yang_type='string', is_config=True) + self.__author = YANGDynClass(base=six.text_type, is_leaf=True, yang_name="author", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='urn:ietf:params:xml:ns:yang:ietf-ped', defining_module='ietf-ped', yang_type='string', is_config=True) + self.__description = YANGDynClass(base=six.text_type, is_leaf=True, yang_name="description", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='urn:ietf:params:xml:ns:yang:ietf-ped', defining_module='ietf-ped', yang_type='string', is_config=True) + + load = kwargs.pop("load", None) + if args: + if len(args) > 1: + raise TypeError("cannot create a YANG container with >1 argument") + all_attr = True + for e in self._pyangbind_elements: + if not hasattr(args[0], e): + all_attr = False + break + if not all_attr: + raise ValueError("Supplied object did not have the correct attributes") + for e in self._pyangbind_elements: + nobj = getattr(args[0], e) + if nobj._changed() is False: + continue + setmethod = getattr(self, "_set_%s" % e) + if load is None: + setmethod(getattr(args[0], e)) + else: + setmethod(getattr(args[0], e), load=load) + + def _path(self): + if hasattr(self, "_parent"): + return self._parent._path()+[self._yang_name] + else: + return ['ped'] + + def _get_descriptor_schema(self): + """ + Getter method for descriptor_schema, mapped from YANG variable /ped/descriptor_schema (string) + + YANG Description: Pointer to this data model. + """ + return self.__descriptor_schema + + def _set_descriptor_schema(self, v, load=False): + """ + Setter method for descriptor_schema, mapped from YANG variable /ped/descriptor_schema (string) + If this variable is read-only (config: false) in the + source YANG file, then _set_descriptor_schema is considered as a private + method. Backends looking to populate this variable should + do so via calling thisObj._set_descriptor_schema() directly. + + YANG Description: Pointer to this data model. + """ + if hasattr(v, "_utype"): + v = v._utype(v) + try: + t = YANGDynClass(v,base=six.text_type, default=six.text_type("https://github.com/mpeuster/tng-sdk-benchmark/raw/feature-73/models/ped.yang"), is_leaf=True, yang_name="descriptor-schema", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='urn:ietf:params:xml:ns:yang:ietf-ped', defining_module='ietf-ped', yang_type='string', is_config=True) + except (TypeError, ValueError): + raise ValueError({ + 'error-string': """descriptor_schema must be of a type compatible with string""", + 'defined-type': "string", + 'generated-type': """YANGDynClass(base=six.text_type, default=six.text_type("https://github.com/mpeuster/tng-sdk-benchmark/raw/feature-73/models/ped.yang"), is_leaf=True, yang_name="descriptor-schema", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='urn:ietf:params:xml:ns:yang:ietf-ped', defining_module='ietf-ped', yang_type='string', is_config=True)""", + }) + + self.__descriptor_schema = t + if hasattr(self, '_set'): + self._set() + + def _unset_descriptor_schema(self): + self.__descriptor_schema = YANGDynClass(base=six.text_type, default=six.text_type("https://github.com/mpeuster/tng-sdk-benchmark/raw/feature-73/models/ped.yang"), is_leaf=True, yang_name="descriptor-schema", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='urn:ietf:params:xml:ns:yang:ietf-ped', defining_module='ietf-ped', yang_type='string', is_config=True) + + + def _get_vendor(self): + """ + Getter method for vendor, mapped from YANG variable /ped/vendor (string) + + YANG Description: Vendor of the described experiments. + """ + return self.__vendor + + def _set_vendor(self, v, load=False): + """ + Setter method for vendor, mapped from YANG variable /ped/vendor (string) + If this variable is read-only (config: false) in the + source YANG file, then _set_vendor is considered as a private + method. Backends looking to populate this variable should + do so via calling thisObj._set_vendor() directly. + + YANG Description: Vendor of the described experiments. + """ + if hasattr(v, "_utype"): + v = v._utype(v) + try: + t = YANGDynClass(v,base=six.text_type, is_leaf=True, yang_name="vendor", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='urn:ietf:params:xml:ns:yang:ietf-ped', defining_module='ietf-ped', yang_type='string', is_config=True) + except (TypeError, ValueError): + raise ValueError({ + 'error-string': """vendor must be of a type compatible with string""", + 'defined-type': "string", + 'generated-type': """YANGDynClass(base=six.text_type, is_leaf=True, yang_name="vendor", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='urn:ietf:params:xml:ns:yang:ietf-ped', defining_module='ietf-ped', yang_type='string', is_config=True)""", + }) + + self.__vendor = t + if hasattr(self, '_set'): + self._set() + + def _unset_vendor(self): + self.__vendor = YANGDynClass(base=six.text_type, is_leaf=True, yang_name="vendor", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='urn:ietf:params:xml:ns:yang:ietf-ped', defining_module='ietf-ped', yang_type='string', is_config=True) + + + def _get_name(self): + """ + Getter method for name, mapped from YANG variable /ped/name (string) + + YANG Description: Name of the described experiments. + """ + return self.__name + + def _set_name(self, v, load=False): + """ + Setter method for name, mapped from YANG variable /ped/name (string) + If this variable is read-only (config: false) in the + source YANG file, then _set_name is considered as a private + method. Backends looking to populate this variable should + do so via calling thisObj._set_name() directly. + + YANG Description: Name of the described experiments. + """ + if hasattr(v, "_utype"): + v = v._utype(v) + try: + t = YANGDynClass(v,base=six.text_type, is_leaf=True, yang_name="name", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='urn:ietf:params:xml:ns:yang:ietf-ped', defining_module='ietf-ped', yang_type='string', is_config=True) + except (TypeError, ValueError): + raise ValueError({ + 'error-string': """name must be of a type compatible with string""", + 'defined-type': "string", + 'generated-type': """YANGDynClass(base=six.text_type, is_leaf=True, yang_name="name", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='urn:ietf:params:xml:ns:yang:ietf-ped', defining_module='ietf-ped', yang_type='string', is_config=True)""", + }) + + self.__name = t + if hasattr(self, '_set'): + self._set() + + def _unset_name(self): + self.__name = YANGDynClass(base=six.text_type, is_leaf=True, yang_name="name", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='urn:ietf:params:xml:ns:yang:ietf-ped', defining_module='ietf-ped', yang_type='string', is_config=True) + + + def _get_version(self): + """ + Getter method for version, mapped from YANG variable /ped/version (string) + + YANG Description: Version of the described experiments. + """ + return self.__version + + def _set_version(self, v, load=False): + """ + Setter method for version, mapped from YANG variable /ped/version (string) + If this variable is read-only (config: false) in the + source YANG file, then _set_version is considered as a private + method. Backends looking to populate this variable should + do so via calling thisObj._set_version() directly. + + YANG Description: Version of the described experiments. + """ + if hasattr(v, "_utype"): + v = v._utype(v) + try: + t = YANGDynClass(v,base=six.text_type, is_leaf=True, yang_name="version", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='urn:ietf:params:xml:ns:yang:ietf-ped', defining_module='ietf-ped', yang_type='string', is_config=True) + except (TypeError, ValueError): + raise ValueError({ + 'error-string': """version must be of a type compatible with string""", + 'defined-type': "string", + 'generated-type': """YANGDynClass(base=six.text_type, is_leaf=True, yang_name="version", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='urn:ietf:params:xml:ns:yang:ietf-ped', defining_module='ietf-ped', yang_type='string', is_config=True)""", + }) + + self.__version = t + if hasattr(self, '_set'): + self._set() + + def _unset_version(self): + self.__version = YANGDynClass(base=six.text_type, is_leaf=True, yang_name="version", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='urn:ietf:params:xml:ns:yang:ietf-ped', defining_module='ietf-ped', yang_type='string', is_config=True) + + + def _get_author(self): + """ + Getter method for author, mapped from YANG variable /ped/author (string) + + YANG Description: Author of the described experiments. + """ + return self.__author + + def _set_author(self, v, load=False): + """ + Setter method for author, mapped from YANG variable /ped/author (string) + If this variable is read-only (config: false) in the + source YANG file, then _set_author is considered as a private + method. Backends looking to populate this variable should + do so via calling thisObj._set_author() directly. + + YANG Description: Author of the described experiments. + """ + if hasattr(v, "_utype"): + v = v._utype(v) + try: + t = YANGDynClass(v,base=six.text_type, is_leaf=True, yang_name="author", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='urn:ietf:params:xml:ns:yang:ietf-ped', defining_module='ietf-ped', yang_type='string', is_config=True) + except (TypeError, ValueError): + raise ValueError({ + 'error-string': """author must be of a type compatible with string""", + 'defined-type': "string", + 'generated-type': """YANGDynClass(base=six.text_type, is_leaf=True, yang_name="author", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='urn:ietf:params:xml:ns:yang:ietf-ped', defining_module='ietf-ped', yang_type='string', is_config=True)""", + }) + + self.__author = t + if hasattr(self, '_set'): + self._set() + + def _unset_author(self): + self.__author = YANGDynClass(base=six.text_type, is_leaf=True, yang_name="author", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='urn:ietf:params:xml:ns:yang:ietf-ped', defining_module='ietf-ped', yang_type='string', is_config=True) + + + def _get_description(self): + """ + Getter method for description, mapped from YANG variable /ped/description (string) + + YANG Description: Generic description text. + """ + return self.__description + + def _set_description(self, v, load=False): + """ + Setter method for description, mapped from YANG variable /ped/description (string) + If this variable is read-only (config: false) in the + source YANG file, then _set_description is considered as a private + method. Backends looking to populate this variable should + do so via calling thisObj._set_description() directly. + + YANG Description: Generic description text. + """ + if hasattr(v, "_utype"): + v = v._utype(v) + try: + t = YANGDynClass(v,base=six.text_type, is_leaf=True, yang_name="description", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='urn:ietf:params:xml:ns:yang:ietf-ped', defining_module='ietf-ped', yang_type='string', is_config=True) + except (TypeError, ValueError): + raise ValueError({ + 'error-string': """description must be of a type compatible with string""", + 'defined-type': "string", + 'generated-type': """YANGDynClass(base=six.text_type, is_leaf=True, yang_name="description", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='urn:ietf:params:xml:ns:yang:ietf-ped', defining_module='ietf-ped', yang_type='string', is_config=True)""", + }) + + self.__description = t + if hasattr(self, '_set'): + self._set() + + def _unset_description(self): + self.__description = YANGDynClass(base=six.text_type, is_leaf=True, yang_name="description", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='urn:ietf:params:xml:ns:yang:ietf-ped', defining_module='ietf-ped', yang_type='string', is_config=True) + + descriptor_schema = __builtin__.property(_get_descriptor_schema, _set_descriptor_schema) + vendor = __builtin__.property(_get_vendor, _set_vendor) + name = __builtin__.property(_get_name, _set_name) + version = __builtin__.property(_get_version, _set_version) + author = __builtin__.property(_get_author, _set_author) + description = __builtin__.property(_get_description, _set_description) + + + _pyangbind_elements = OrderedDict([('descriptor_schema', descriptor_schema), ('vendor', vendor), ('name', name), ('version', version), ('author', author), ('description', description), ]) + + +class ietf_ped(PybindBase): + """ + This class was auto-generated by the PythonClass plugin for PYANG + from YANG module ietf-ped - based on the path /ietf-ped. Each member element of + the container is represented as a class variable - with a specific + YANG type. + + YANG Description: Performance Experiment Descriptor (PED) model. + """ + __slots__ = ('_path_helper', '_extmethods', '__ped',) + + _yang_name = 'ietf-ped' + + _pybind_generated_by = 'container' + + def __init__(self, *args, **kwargs): + + self._path_helper = False + + self._extmethods = False + self.__ped = YANGDynClass(base=yc_ped_ietf_ped__ped, is_container='container', yang_name="ped", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, extensions=None, namespace='urn:ietf:params:xml:ns:yang:ietf-ped', defining_module='ietf-ped', yang_type='container', is_config=True) + + load = kwargs.pop("load", None) + if args: + if len(args) > 1: + raise TypeError("cannot create a YANG container with >1 argument") + all_attr = True + for e in self._pyangbind_elements: + if not hasattr(args[0], e): + all_attr = False + break + if not all_attr: + raise ValueError("Supplied object did not have the correct attributes") + for e in self._pyangbind_elements: + nobj = getattr(args[0], e) + if nobj._changed() is False: + continue + setmethod = getattr(self, "_set_%s" % e) + if load is None: + setmethod(getattr(args[0], e)) + else: + setmethod(getattr(args[0], e), load=load) + + def _path(self): + if hasattr(self, "_parent"): + return self._parent._path()+[self._yang_name] + else: + return [] + + def _get_ped(self): + """ + Getter method for ped, mapped from YANG variable /ped (container) + + YANG Description: Performance Experiment Descriptor (PED) + """ + return self.__ped + + def _set_ped(self, v, load=False): + """ + Setter method for ped, mapped from YANG variable /ped (container) + If this variable is read-only (config: false) in the + source YANG file, then _set_ped is considered as a private + method. Backends looking to populate this variable should + do so via calling thisObj._set_ped() directly. + + YANG Description: Performance Experiment Descriptor (PED) + """ + if hasattr(v, "_utype"): + v = v._utype(v) + try: + t = YANGDynClass(v,base=yc_ped_ietf_ped__ped, is_container='container', yang_name="ped", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, extensions=None, namespace='urn:ietf:params:xml:ns:yang:ietf-ped', defining_module='ietf-ped', yang_type='container', is_config=True) + except (TypeError, ValueError): + raise ValueError({ + 'error-string': """ped must be of a type compatible with container""", + 'defined-type': "container", + 'generated-type': """YANGDynClass(base=yc_ped_ietf_ped__ped, is_container='container', yang_name="ped", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, extensions=None, namespace='urn:ietf:params:xml:ns:yang:ietf-ped', defining_module='ietf-ped', yang_type='container', is_config=True)""", + }) + + self.__ped = t + if hasattr(self, '_set'): + self._set() + + def _unset_ped(self): + self.__ped = YANGDynClass(base=yc_ped_ietf_ped__ped, is_container='container', yang_name="ped", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, extensions=None, namespace='urn:ietf:params:xml:ns:yang:ietf-ped', defining_module='ietf-ped', yang_type='container', is_config=True) + + ped = __builtin__.property(_get_ped, _set_ped) + + + _pyangbind_elements = OrderedDict([('ped', ped), ]) + + diff --git a/models/test.py b/models/test.py deleted file mode 100644 index beaee79..0000000 --- a/models/test.py +++ /dev/null @@ -1,28 +0,0 @@ -import model -from model import ietf_ped -from pyangbind.lib.serialise import pybindJSONDecoder -import pyangbind.lib.pybindJSON as pybindJSON -import yaml -import json - -# -# re-generate the model -# pyang --plugindir $PYBINDPLUGIN -f pybind -o model.py ietf-ped.yang -# - -#m = ietf_ped() -#print(ietf_ped) -#print(pybindJSON.dumps(m)) - -# -#pybindJSONDecoder.load_ietf_json(data, None, None, obj=m.ped()) - -# json version -#m2 = pybindJSON.load("example-instance.json", model, "ietf_ped") -#print(m2.ped.vendor) - -# yaml version -data = yaml.load(open("example-instance.yml", "r")) -print(data) -m3 = pybindJSON.loads(data, model, "ietf_ped") -print(m3.ped.vendor) \ No newline at end of file diff --git a/models/test_model.py b/models/test_model.py new file mode 100644 index 0000000..a250b4b --- /dev/null +++ b/models/test_model.py @@ -0,0 +1,64 @@ +# Copyright (c) 2019 Manuel Peuster, 5GTANGO, Paderborn University +# ALL RIGHTS RESERVED. +# +# 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. +# +# Neither the name of the 5GTANGO, Paderborn University +# nor the names of its contributors may be used to endorse or promote +# products derived from this software without specific prior written +# permission. +# +# This work has also been performed in the framework of the 5GTANGO project, +# funded by the European Commission under Grant number 761493 through +# the Horizon 2020 and 5G-PPP programmes. The authors would like to +# acknowledge the contributions of their colleagues of the SONATA +# partner consortium (www.5gtango.eu). + +import unittest +import ietf_ped_model as generated_model +import yaml +import glob +import os +import pyangbind.lib.pybindJSON as pybindJSON + + +MODEL_NAME = "ietf_ped" +EXAMPLE_DIR = "examples/" + + +def check_against_model(yaml_path): + """ + Open a given YAML file and tries to load it into + model that was generated by pyangbind. + Fails if the YAML file is not compatible to the + model. + """ + with open(yaml_path, "r") as f: + ped_data = yaml.load(f) + ped_model = pybindJSON.loads(ped_data, generated_model, MODEL_NAME) + # print(ped_model.ped.name) # example how to use model + return ped_model + + +class TestStringMethods(unittest.TestCase): + + def test_example_peds_against_model(self): + # collect all example PED files which should be checked against model + example_peds = list() + example_peds.extend(glob.glob(os.path.join(EXAMPLE_DIR, "*.yml"))) + example_peds.extend(glob.glob(os.path.join(EXAMPLE_DIR, "*.yaml"))) + # check each PED file against the model + for ep in example_peds: + self.assertIsNotNone(check_against_model(ep)) + print("File: '{}' is valid against model '{}'." + .format(ep, MODEL_NAME))