def test_ly_data_node_dup_to_ctx(self): sch = "module x {\ namespace urn:x;\ prefix x;\ leaf x { type string; }}" data = "<x xmlns=\"urn:x\">hello</x>" try: ctx1 = ly.Context(None) self.assertIsNotNone(ctx1) ctx1.parse_module_mem(sch, ly.LYS_IN_YANG) data1 = ctx1.parse_data_mem(data, ly.LYD_XML, ly.LYD_OPT_CONFIG | ly.LYD_OPT_STRICT) self.assertIsNotNone(data1) ctx2 = ly.Context(None) self.assertIsNotNone(ctx2) # we expect NULL due to missing schema in the second ctx dup_node = data1.dup_to_ctx(1, ctx2) self.assertIsNone(dup_node) ctx2.parse_module_mem(sch, ly.LYS_IN_YANG) # now we expect success due to schema being added to the second ctx dup_node = data1.dup_to_ctx(1, ctx2) self.assertIsNotNone(dup_node) except Exception as e: self.fail(e)
def test_ly_data_node_insert_after(self): yang_folder = config.TESTS_DIR + "/api/files" config_file = config.TESTS_DIR + "/api/files/a.xml" try: # Setup ctx = ly.Context(yang_folder) self.assertIsNotNone(ctx) ctx.parse_module_mem(lys_module_a, ly.LYS_IN_YIN) root = ctx.parse_data_path(config_file, ly.LYD_XML, ly.LYD_OPT_CONFIG | ly.LYD_OPT_STRICT) self.assertIsNotNone(root) # Tests last = root.next() new_node = ly.Data_Node(None, root.schema().module(), "y", "test") self.assertIsNotNone(new_node) rc = root.insert_after(new_node) self.assertEqual(0, rc) self.assertNotEqual(last.schema().name(), root.next().schema().name()) self.assertEqual("y", root.next().schema().name()) except Exception as e: self.fail(e)
def __init__(self, yang_dir, debug=False): self.yang_dir = yang_dir self.ctx = None self.module = None self.root = None # logging vars self.SYSLOG_IDENTIFIER = "sonic_yang" self.DEBUG = debug # yang model files, need this map it to module self.yangFiles = list() # map from TABLE in config DB to container and module self.confDbYangMap = dict() # JSON format of yang model [similar to pyang conversion] self.yJson = list() # config DB json input, will be cropped as yang models self.jIn = dict() # YANG JSON, this is traslated from config DB json self.xlateJson = dict() # reverse translation from yang JSON, == config db json self.revXlateJson = dict() # below dict store the input config tables which have no YANG models self.tablesWithOutYang = dict() try: self.ctx = ly.Context(yang_dir) except Exception as e: self.fail(e) return
def test_ly_ctx_set_searchdir(self): yang_folder = config.TESTS_DIR + "/data/files" new_yang_folder = config.TESTS_DIR + "/schema/yin" try: # Setup ctx = ly.Context(yang_folder) self.assertIsNotNone(ctx) # Tests list = ctx.get_searchdirs() self.assertEqual(1, len(list)) self.assertEqual(yang_folder, list[0]) ctx.set_searchdir(new_yang_folder) list = ctx.get_searchdirs() self.assertEqual(2, len(list)) self.assertEqual(new_yang_folder, list[1]) ctx.unset_searchdirs(0) list = ctx.get_searchdirs() self.assertEqual(1, len(list)) self.assertEqual(new_yang_folder, list[0]) except Exception as e: self.fail(e)
def test_ly_schema_node_find_path(self): yang_folder = config.TESTS_DIR + "/api/files" try: # Setup ctx = ly.Context(yang_folder) self.assertIsNotNone(ctx) module = ctx.parse_module_mem(lys_module_a, ly.LYS_IN_YIN) self.assertIsNotNone(module) schema_node = module.data() self.assertIsNotNone(schema_node) # Tests set = schema_node.find_path("/a:x/*") self.assertIsNotNone(set) self.assertEqual(5, set.number()) set = schema_node.find_path("/a:x//*") self.assertIsNotNone(set) self.assertEqual(6, set.number()) set = schema_node.find_path("/a:x//.") self.assertIsNotNone(set) self.assertEqual(7, set.number()) except Exception as e: self.fail(e)
def test_ly_ctx_get_module_older(self): yang_folder = config.TESTS_DIR + "/api/files" name = "b" revision = "2016-03-01" revision_older = "2015-01-01" try: # Setup ctx = ly.Context(yang_folder) self.assertIsNotNone(ctx) # Tests module = ctx.load_module("c") self.assertIsNotNone(module) self.assertEqual("c", module.name(), "Module names don't match") module = ctx.load_module(name, revision) self.assertIsNotNone(module) self.assertEqual(name, module.name(), "Module names don't match") self.assertEqual(revision, module.rev().date(), "Module revisions don't match") module_older = ctx.get_module_older(module) self.assertIsNotNone(module_older) self.assertEqual(name, module_older.name(), "Module names don't match") self.assertEqual(revision_older, module_older.rev().date(), "Module revisions don't match") except Exception as e: self.fail(e)
def test_ly_ctx_parse_module_path(self): yang_folder = config.TESTS_DIR + "/api/files" yin_file = config.TESTS_DIR + "/api/files/a.yin" yang_file = config.TESTS_DIR + "/api/files/b.yang" module_name1 = "a" module_name2 = "b" try: # Setup ctx = ly.Context(yang_folder) self.assertIsNotNone(ctx) # Tests module = ctx.parse_module_path(yin_file, ly.LYS_IN_YIN) self.assertIsNotNone(module) self.assertEqual(module_name1, module.name(), "Module names don't match") module = ctx.parse_module_path(yang_file, ly.LYS_IN_YANG) self.assertIsNotNone(module) self.assertEqual(module_name2, module.name(), "Module names don't match") except Exception as e: self.fail(e)
def loadYangModel(self, yangDir): try: # get all files yangFiles = [f for f in listdir(yangDir) if isfile(join(yangDir, f))] # get all yang files yangFiles = [f for f in yangFiles if splitext(f)[-1].lower()==".yang"] yangFiles = [f.split('.')[0] for f in yangFiles] # load yang mdoules self.ctx = ly.Context(yangDir) log.debug(yangFiles) for f in yangFiles: # load a module log.debug(f) m = self.ctx.get_module(f) if m is not None: log.error("Could not get module: {}".format(m.name())) else: m = self.ctx.load_module(f) if m is not None: log.info("module: {} is loaded successfully".format(m.name())) else: return except Exception as e: printExceptionDetails() raise e return
def test_ly_ctx_parse_module_fd_invalid(self): yang_folder = config.TESTS_DIR + "/api/files" yin_file = config.TESTS_DIR + "/api/files/a.yin" try: # Setup ctx = ly.Context(yang_folder) self.assertIsNotNone(ctx) # Tests f = open(yin_file, 'r') fd = f.fileno() # parsing with wrong format should raise runtime exception module = ctx.parse_module_fd(fd, ly.LYS_IN_YANG) raise UnexpectedError("Exception not thrown") except UnexpectedError as e: self.fail(e) except RuntimeError as e: return except Exception as e: self.fail(e) finally: f.close()
def test_ly_ctx_parse_module_fd(self): yang_folder = config.TESTS_DIR + "/api/files" yin_file = config.TESTS_DIR + "/api/files/a.yin" yang_file = config.TESTS_DIR + "/api/files/b.yang" try: # Setup ctx = ly.Context(yang_folder) self.assertIsNotNone(ctx) # Tests f = open(yin_file, 'r') fd = f.fileno() module = ctx.parse_module_fd(fd, ly.LYS_IN_YIN) self.assertIsNotNone(module) self.assertEqual("a", module.name()) f.close() f = open(yang_file, 'r') fd = f.fileno() module = ctx.parse_module_fd(fd, ly.LYS_IN_YANG) self.assertIsNotNone(module) self.assertEqual("b", module.name()) except Exception as e: self.fail(e) finally: f.close()
def test_ly_ctx_clean(self): yang_folder = config.TESTS_DIR + "/api/files" module_name = "a" try: # Setup ctx = ly.Context(yang_folder) self.assertIsNotNone(ctx) module = ctx.load_module(module_name) self.assertIsNotNone(module) self.assertEqual(module_name, module.name(), "Module names don't match") # Tests # confirm module is loaded module = ctx.get_module(module_name) self.assertIsNotNone(module) self.assertEqual(module_name, module.name(), "Module names don't match") ctx.clean() # confirm ctx is cleaned module = ctx.get_module(module_name) self.assertIsNone(module) except Exception as e: self.fail(e)
def test_ly_ctx_new(self): yang_folder1 = config.TESTS_DIR + "/data/files" yang_folder2 = config.TESTS_DIR + "/data:" + config.TESTS_DIR + "/data/files" try: # Tests ctx = ly.Context(yang_folder1) self.assertIsNotNone(ctx) list = ctx.get_searchdirs() self.assertIsNotNone(list) self.assertEqual(1, len(list)) ctx = ly.Context(yang_folder2) self.assertIsNotNone(ctx) list = ctx.get_searchdirs() self.assertIsNotNone(list) self.assertEqual(2, len(list)) except Exception as e: self.fail(e)
def test_ly_data_node_schema_sort(self): yang_folder = config.TESTS_DIR + "/api/files" config_file = config.TESTS_DIR + "/api/files/a.xml" try: # Setup ctx = ly.Context(yang_folder) self.assertIsNotNone(ctx) ctx.parse_module_mem(lys_module_a, ly.LYS_IN_YIN) ctx.parse_data_path(config_file, ly.LYD_XML, ly.LYD_OPT_CONFIG | ly.LYD_OPT_STRICT) mod = ctx.get_module("a", None, 1) self.assertIsNotNone(mod) # Tests root = ly.Data_Node(None, mod, "l") self.assertIsNotNone(root) node = ly.Data_Node(root, mod, "key1", "1") self.assertIsNotNone(node) node = ly.Data_Node(root, mod, "key2", "2") self.assertIsNotNone(node) node = ly.Data_Node(None, mod, "x") self.assertIsNotNone(node) rc = root.insert_after(node) self.assertEqual(0, rc) node = root.next() node2 = ly.Data_Node(node, mod, "bubba", "a") self.assertIsNotNone(node2) node2 = ly.Data_Node(node, mod, "bar-gggg", "b") self.assertIsNotNone(node2) node2 = ly.Data_Node(node, mod, "number64", "64") self.assertIsNotNone(node2) node2 = ly.Data_Node(node, mod, "number32", "32") self.assertIsNotNone(node2) rc = root.schema_sort(1) self.assertEqual(0, rc) root = node self.assertEqual("x", root.schema().name()) self.assertEqual("l", root.next().schema().name()) self.assertEqual("bar-gggg", root.child().schema().name()) self.assertEqual("bubba", root.child().next().schema().name()) self.assertEqual("number32", root.child().next().next().schema().name()) self.assertEqual("number64", root.child().next().next().next().schema().name()) except Exception as e: self.fail(e)
def test_ly_ctx_new_ylmem(self): yang_folder = config.TESTS_DIR + "/api/files" try: ctx = ly.Context(yang_folder) self.assertIsNotNone(ctx) info = ctx.info() self.assertIsNotNone(info) self.assertEqual(ly.LYD_VAL_OK, info.validity()) mem = info.print_mem(ly.LYD_XML, 0) self.assertIsNotNone(mem) new_ctx = ly.Context(yang_folder, ly.LYD_XML, mem, 0) self.assertIsNotNone(new_ctx) list = ctx.get_searchdirs() self.assertIsNotNone(list) self.assertEqual(1, len(list)) except Exception as e: self.fail(e)
def test_ly_ctx_new_ylpath(self): yang_folder = config.TESTS_DIR + "/api/files" path = config.TESTS_DIR + "/api/files/ylpath.xml" try: ctx = ly.Context(yang_folder, path, ly.LYD_XML, 0) self.assertIsNotNone(ctx) list = ctx.get_searchdirs() self.assertIsNotNone(list) self.assertEqual(1, len(list)) except Exception as e: self.fail(e)
def test_ly_data_node_new_path(self): yang_folder = config.TESTS_DIR + "/api/files" config_file = config.TESTS_DIR + "/api/files/a.xml" try: # Setup ctx = ly.Context(yang_folder) self.assertIsNotNone(ctx) ctx.parse_module_mem(lys_module_a, ly.LYS_IN_YIN) ctx.parse_data_path(config_file, ly.LYD_XML, ly.LYD_OPT_CONFIG | ly.LYD_OPT_STRICT) mod = ctx.get_module("a", None, 1) self.assertIsNotNone(mod) # Tests root = ly.Data_Node(ctx, "/a:x/bar-gggg", "a", 0, 0) self.assertIsNotNone(root) self.assertEqual("x", root.schema().name()) self.assertEqual("bar-gggg", root.child().schema().name()) node = root.new_path(ctx, "def-leaf", "def", 0, ly.LYD_PATH_OPT_DFLT) self.assertIsNotNone(node) self.assertEqual("def-leaf", node.schema().name()) self.assertEqual(1, node.dflt()) node = root.new_path(ctx, "def-leaf", "def", 0, 0) self.assertIsNotNone(node) self.assertEqual("def-leaf", node.schema().name()) self.assertEqual(0, node.dflt()) node = root.new_path(ctx, "bubba", "b", 0, 0) self.assertIsNotNone(node) self.assertEqual("bubba", node.schema().name()) node = root.new_path(ctx, "/a:x/number32", "3", 0, 0) self.assertIsNotNone(node) self.assertEqual("number32", node.schema().name()) node = root.new_path(ctx, "/a:l[key1='1'][key2='2']/value", None, 0, 0) self.assertIsNotNone(node) self.assertEqual("l", node.schema().name()) self.assertEqual("key1", node.child().schema().name()) self.assertEqual("key2", node.child().next().schema().name()) self.assertEqual("value", node.child().next().next().schema().name()) except Exception as e: self.fail(e)
def test_ly_ctx_new_invalid(self): yang_folder = "INVALID_PATH" try: ctx = ly.Context(yang_folder) raise UnexpectedError("exception not thrown") except UnexpectedError as e: self.fail(e) except RuntimeError as e: return except Exception as e: self.fail(e)
def test_ly_ctx_info(self): yang_folder = config.TESTS_DIR + "/api/files" try: # Setup ctx = ly.Context(yang_folder) self.assertIsNotNone(ctx) # Tests info = ctx.info() self.assertIsNotNone(info) self.assertEqual(ly.LYD_VAL_OK, info.validity()) except Exception as e: self.fail(e)
def test_ly_ctx_get_searchdirs(self): yang_folder = config.TESTS_DIR + "/data/files" try: # Setup ctx = ly.Context(yang_folder) self.assertIsNotNone(ctx) # Tests list = ctx.get_searchdirs() self.assertEqual(1, len(list)) self.assertEqual(yang_folder, list[0]) except Exception as e: self.fail(e)
def _load_schema_modules_ctx(self, yang_dir=None): if not yang_dir: yang_dir = self.yang_dir ctx = ly.Context(yang_dir) py = glob(yang_dir+"/*.yang") for file in py: try: ctx.parse_module_path(str(file), ly.LYS_IN_YANG) except Exception as e: print("Failed to parse yang module file: " + file) self.fail(e) return ctx
def test_ly_module_print_mem_yin(self): yang_folder = config.TESTS_DIR + "/api/files" try: # Setup ctx = ly.Context(yang_folder) self.assertIsNotNone(ctx) module = ctx.parse_module_mem(lys_module_a, ly.LYS_IN_YIN) self.assertIsNotNone(module) # Tests result = module.print_mem(ly.LYS_OUT_YIN, 0) self.assertEqual(result_yin, result) except Exception as e: self.fail(e)
def test_ly_ctx_load_get_module(self): yang_folder = config.TESTS_DIR + "/api/files" name1 = "a" name2 = "b" revision = "2016-03-01" try: # Setup ctx = ly.Context(yang_folder) self.assertIsNotNone(ctx) # Tests module = ctx.get_module("invalid") self.assertIsNone(module) # module needs to be loaded first module = ctx.get_module(name1) self.assertIsNone(module) module = ctx.load_module(name1) self.assertIsNotNone(module) self.assertEqual(name1, module.name(), "Module names don't match") module = ctx.load_module(name2, revision) self.assertIsNotNone(module) self.assertEqual(name2, module.name(), "Module names don't match") self.assertEqual(revision, module.rev().date(), "Module revisions don't match") module = ctx.get_module(name2, "INVALID_REVISION") self.assertIsNone(module) module = ctx.get_module(name1) self.assertIsNotNone(module) self.assertEqual(name1, module.name(), "Module names don't match") module = ctx.get_module(name2, revision) self.assertIsNotNone(module) self.assertEqual(name2, module.name(), "Module names don't match") self.assertEqual(revision, module.rev().date(), "Module revisions don't match") except Exception as e: self.fail(e)
def _load_schema_modules_ctx(self, yang_dir=None): if not yang_dir: yang_dir = self.yang_dir ctx = ly.Context(yang_dir) py = glob(yang_dir + "/*.yang") for file in py: try: ctx.parse_module_path(str(file), ly.LYS_IN_YANG) except Exception as e: self.sysLog(msg="Failed to parse yang module file: " + file, debug=syslog.LOG_ERR, doPrint=True) self.fail(e) return ctx
def test_ly_ctx_get_module_iter(self): yang_folder = config.TESTS_DIR + "/api/files" module_name = "a" try: ctx = ly.Context(yang_folder) self.assertIsNotNone(ctx) module = ctx.load_module(module_name) self.assertIsNotNone(module) self.assertEqual(module_name, module.name()) itr = ctx.get_module_iter() self.assertIsNotNone(itr) self.assertEqual(7, len(itr)) except Exception as e: self.fail(e)
def __init__(self, yang_dir, debug=False, print_log_enabled=True, sonic_yang_options=0): self.yang_dir = yang_dir self.ctx = None self.module = None self.root = None # logging vars self.SYSLOG_IDENTIFIER = "sonic_yang" self.DEBUG = debug self.print_log_enabled = print_log_enabled if not print_log_enabled: # The default libyang log options are ly.LY_LOLOG|ly.LY_LOSTORE_LAST. # Removing ly.LY_LOLOG will stop libyang from printing the logs. ly.set_log_options(ly.LY_LOSTORE_LAST) # yang model files, need this map it to module self.yangFiles = list() # map from TABLE in config DB to container and module self.confDbYangMap = dict() # JSON format of yang model [similar to pyang conversion] self.yJson = list() # config DB json input, will be cropped as yang models self.jIn = dict() # YANG JSON, this is traslated from config DB json self.xlateJson = dict() # reverse translation from yang JSON, == config db json self.revXlateJson = dict() # below dict store the input config tables which have no YANG models self.tablesWithOutYang = dict() # below dict will store preProcessed yang objects, which may be needed by # all yang modules, such as grouping. self.preProcessedYang = dict() # element path for CONFIG DB. An example for this list could be: # ['PORT', 'Ethernet0', 'speed'] self.elementPath = [] try: self.ctx = ly.Context(yang_dir, sonic_yang_options) except Exception as e: self.fail(e) return
def test_ly_data_node_print_mem_json(self): yang_folder = config.TESTS_DIR + "/api/files" config_file = config.TESTS_DIR + "/api/files/a.xml" try: # Setup ctx = ly.Context(yang_folder) self.assertIsNotNone(ctx) ctx.parse_module_mem(lys_module_a, ly.LYS_IN_YIN) root = ctx.parse_data_path(config_file, ly.LYD_XML, ly.LYD_OPT_CONFIG | ly.LYD_OPT_STRICT) self.assertIsNotNone(root) # Tests result = root.print_mem(ly.LYD_JSON, ly.LYP_FORMAT) self.assertEqual(result_json, result) except Exception as e: self.fail(e)
def test_ly_data_node_leaf(self): yang_folder = config.TESTS_DIR + "/api/files" config_file = config.TESTS_DIR + "/api/files/a.xml" try: ctx = ly.Context(yang_folder) self.assertIsNotNone(ctx) ctx.parse_module_mem(lys_module_a, ly.LYS_IN_YIN) root = ctx.parse_data_path(config_file, ly.LYD_XML, ly.LYD_OPT_CONFIG | ly.LYD_OPT_STRICT) self.assertIsNotNone(root) new_node = ly.Data_Node(root, root.schema().module(), "number32", "100") self.assertIsNotNone(new_node) except Exception as e: self.fail(e)
def test_ly_ctx_data_instantiables(self): yang_folder = config.TESTS_DIR + "/api/files" module_name = "b" try: ctx = ly.Context(yang_folder) self.assertIsNotNone(ctx) module = ctx.load_module(module_name) self.assertIsNotNone(module) self.assertEqual(module_name, module.name()) instantiables = ctx.data_instantiables(0) self.assertIsNotNone(instantiables) self.assertEqual(5, len(instantiables)) except Exception as e: self.fail(e)
def test_ly_ctx_parse_module_mem(self): yang_folder = config.TESTS_DIR + "/api/files" try: # Setup ctx = ly.Context(yang_folder) self.assertIsNotNone(ctx) # Tests module = ctx.parse_module_mem(lys_module_a, ly.LYS_IN_YIN) self.assertIsNotNone(module) self.assertEqual("a", module.name()) module = ctx.parse_module_mem(lys_module_b, ly.LYS_IN_YANG) self.assertIsNotNone(module) self.assertEqual("b", module.name()) except Exception as e: self.fail(e)
def test_ly_ctx_get_disabled_module_iter(self): yang_folder = config.TESTS_DIR + "/api/files" module_name = "x" try: ctx = ly.Context(yang_folder) self.assertIsNotNone(ctx) module = ctx.load_module(module_name) self.assertIsNotNone(module) self.assertEqual(module_name, module.name()) # FIXME no way to disable module from here itr = ctx.get_disabled_module_iter() self.assertIsNotNone(itr) self.assertEqual(0, len(itr)) except Exception as e: self.fail(e)