/* * @file test_tree_schema.cpp * @author: Hrvoje Varga * @brief unit tests for functions from tree_schema.h header * * Copyright (C) 2018 Deutsche Telekom AG. * * Author: Hrvoje Varga * * This source code is licensed under BSD 3-Clause License (the "License"). * You may not use this file except in compliance with the License. * You may obtain a copy of the License at * * https://opensource.org/licenses/BSD-3-Clause */ #include "Libyang.hpp" #include "Tree_Schema.hpp" #include "microtest.h" #include "../tests/config.h" const char *lys_module_a = \ " \ \ \ \ \ \ \ \ version 1 \ \ \ RFC XXXX \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ "; const char *lys_module_b = \ "module b {\ namespace \"urn:b\";\ prefix b_mod;\ include bsub;\ include btop;\ feature foo;\ grouping gg {\ leaf bar-gggg {\ type string;\ }\ }\ container x {\ leaf bar-leaf {\ if-feature \"bar\";\ type string;\ }\ uses gg {\ if-feature \"bar\";\ }\ leaf baz {\ if-feature \"foo\";\ type string;\ }\ leaf bubba {\ type string;\ }\ }\ augment \"/x\" {\ if-feature \"bar\";\ container bar-y;\ }\ rpc bar-rpc {\ if-feature \"bar\";\ }\ rpc foo-rpc {\ if-feature \"foo\";\ }\ }"; const char *lys_module_a_with_typo = \ " \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ "; const char *result_tree = "\ module: a\n\ +--rw top\n\ | +--rw bar-sub2\n\ +--rw x\n\ +--rw bubba? string\n"; const char *result_yang = "\ module a {\n\ namespace \"urn:a\";\n\ prefix a_mod;\n\ \n\ include \"asub\";\n\ \n\ include \"atop\";\n\ \n\ revision 2015-01-01 {\n\ description\n\ \"version 1\";\n\ reference\n\ \"RFC XXXX\";\n\ }\n\ \n\ feature foo;\n\ \n\ grouping gg {\n\ leaf bar-gggg {\n\ type string;\n\ }\n\ }\n\ \n\ container x {\n\ leaf bar-leaf {\n\ if-feature \"bar\";\n\ type string;\n\ }\n\n\ uses gg {\n\ if-feature \"bar\";\n\ }\n\n\ leaf baz {\n\ if-feature \"foo\";\n\ type string;\n\ }\n\n\ leaf bubba {\n\ type string;\n\ }\n\ }\n\ \n\ augment \"/x\" {\n\ if-feature \"bar\";\n\ container bar-y {\n\ leaf ll {\n\ type string;\n\ }\n\ }\n\ }\n\ \n\ rpc bar-rpc {\n\ if-feature \"bar\";\n\ }\n\ \n\ rpc foo-rpc {\n\ if-feature \"foo\";\n\ }\n\ }\n"; const char *result_yin = "\ \n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\ version 1\n\ \n\ \n\ RFC XXXX\n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\ \n"; TEST(test_ly_ctx_parse_module_mem) { const char *yang_folder = TESTS_DIR "/api/files"; try { auto ctx = std::make_shared(yang_folder); ASSERT_NOTNULL(ctx); auto module = ctx->parse_module_mem(lys_module_a, LYS_IN_YIN); ASSERT_NOTNULL(module); ASSERT_STREQ("a", module->name()); module = ctx->parse_module_mem(lys_module_b, LYS_IN_YANG); ASSERT_NOTNULL(module); ASSERT_STREQ("b", module->name()); } catch (const std::exception& e) { mt::printFailed(e.what(), stdout); throw; } } TEST(test_ly_ctx_parse_module_mem_invalid) { const char *yang_folder = TESTS_DIR "/api/files"; try { auto ctx = std::make_shared(yang_folder); ASSERT_NOTNULL(ctx); ctx->parse_module_mem(lys_module_a_with_typo, LYS_IN_YIN); throw std::runtime_error("exception not thrown"); } catch (const std::exception& e) { ASSERT_STREQ("Module parsing failed.", e.what()); return; } } TEST(test_ly_ctx_parse_module_fd) { const char *yang_folder = TESTS_DIR "/api/files"; const char *yin_file = TESTS_DIR "/api/files/a.yin"; const char *yang_file = TESTS_DIR "/api/files/b.yang"; try { auto ctx = std::make_shared(yang_folder); ASSERT_NOTNULL(ctx); FILE *f = fopen(yin_file, "r"); auto fd = fileno(f); auto module = ctx->parse_module_fd(fd, LYS_IN_YIN); ASSERT_NOTNULL(module); ASSERT_STREQ("a", module->name()); fclose(f); f = fopen(yang_file, "r"); fd = fileno(f); module = ctx->parse_module_fd(fd, LYS_IN_YANG); ASSERT_NOTNULL(module); ASSERT_STREQ("b", module->name()); fclose(f); } catch (const std::exception& e) { mt::printFailed(e.what(), stdout); throw; } } TEST(test_ly_ctx_parse_module_fd_invalid) { const char *yang_folder = TESTS_DIR "/api/files"; const char *yin_file = TESTS_DIR "/api/files/a.yin"; try { auto ctx = std::make_shared(yang_folder); ASSERT_NOTNULL(ctx); FILE *f = fopen(yin_file, "r"); auto fd = fileno(f); auto module = ctx->parse_module_fd(fd, LYS_IN_YANG); throw std::runtime_error("exception not thrown"); } catch( const std::exception& e ) { ASSERT_STREQ("Module parsing failed.", e.what()); return; } } TEST(test_ly_ctx_parse_module_path) { const char *yang_folder = TESTS_DIR "/api/files"; const char *yin_file = TESTS_DIR "/api/files/a.yin"; const char *yang_file = TESTS_DIR "/api/files/b.yang"; try { auto ctx = std::make_shared(yang_folder); ASSERT_NOTNULL(ctx); auto module = ctx->parse_module_path(yin_file, LYS_IN_YIN); ASSERT_NOTNULL(module); ASSERT_STREQ("a", module->name()); module = ctx->parse_module_path(yang_file, LYS_IN_YANG); ASSERT_NOTNULL(module); ASSERT_STREQ("b", module->name()); } catch (const std::exception& e) { mt::printFailed(e.what(), stdout); throw; } } TEST(test_ly_ctx_parse_module_path_invalid) { const char *yang_folder = TESTS_DIR "/api/files"; const char *yin_file = TESTS_DIR "/api/files/a.yin"; try { auto ctx = std::make_shared(yang_folder); ASSERT_NOTNULL(ctx); auto module = ctx->parse_module_path(yin_file, LYS_IN_YANG); throw std::runtime_error("exception not thrown"); } catch( const std::exception& e ) { ASSERT_STREQ("Module parsing failed.", e.what()); return; } } TEST(test_ly_module_print_mem_tree) { const char *yang_folder = TESTS_DIR "/api/files"; try { auto ctx = std::make_shared(yang_folder); ASSERT_NOTNULL(ctx); auto module = ctx->parse_module_mem(lys_module_a, LYS_IN_YIN); ASSERT_NOTNULL(module); auto result = module->print_mem(LYS_OUT_TREE, 0); ASSERT_STREQ(result_tree, result); } catch (const std::exception& e) { mt::printFailed(e.what(), stdout); throw; } } TEST(test_ly_module_print_mem_yang) { const char *yang_folder = TESTS_DIR "/api/files"; try { auto ctx = std::make_shared(yang_folder); ASSERT_NOTNULL(ctx); auto module = ctx->parse_module_mem(lys_module_a, LYS_IN_YIN); ASSERT_NOTNULL(module); auto result = module->print_mem(LYS_OUT_YANG, 0); ASSERT_STREQ(result_yang, result); } catch (const std::exception& e) { mt::printFailed(e.what(), stdout); throw; } } TEST(test_ly_module_print_mem_yin) { const char *yang_folder = TESTS_DIR "/api/files"; try { auto ctx = std::make_shared(yang_folder); ASSERT_NOTNULL(ctx); auto module = ctx->parse_module_mem(lys_module_a, LYS_IN_YIN); ASSERT_NOTNULL(module); auto result = module->print_mem(LYS_OUT_YIN, 0); ASSERT_STREQ(result_yin, result); } catch (const std::exception& e) { mt::printFailed(e.what(), stdout); throw; } } TEST(test_ly_schema_node_find_path) { const char *yang_folder = TESTS_DIR "/api/files"; try { auto ctx = std::make_shared(yang_folder); ASSERT_NOTNULL(ctx); auto module = ctx->parse_module_mem(lys_module_a, LYS_IN_YIN); ASSERT_NOTNULL(module); auto schema_node = module->data(); ASSERT_NOTNULL(schema_node); auto set = schema_node->find_path("/a:x/*"); ASSERT_NOTNULL(set); ASSERT_EQ(5, set->number()); set = schema_node->find_path("/a:x//*"); ASSERT_NOTNULL(set); ASSERT_EQ(6, set->number()); set = schema_node->find_path("/a:x//."); ASSERT_NOTNULL(set); ASSERT_EQ(7, set->number()); } catch (const std::exception& e) { mt::printFailed(e.what(), stdout); throw; } } TEST(test_ly_schema_node_path) { const char *yang_folder = TESTS_DIR "/api/files"; try { auto ctx = std::make_shared(yang_folder); ASSERT_NOTNULL(ctx); auto module = ctx->parse_module_mem(lys_module_a, LYS_IN_YIN); ASSERT_NOTNULL(module); auto schema_node = module->data(); ASSERT_NOTNULL(schema_node); const char *path_template = "/a:x/a:bar-gggg"; auto set = schema_node->find_path(path_template); ASSERT_NOTNULL(set); auto schemas = set->schema(); auto schema = schemas.at(0); auto path = schema->path(0); ASSERT_STREQ(path_template, path); } catch (const std::exception& e) { mt::printFailed(e.what(), stdout); throw; } } TEST(test_ly_module_data_instatiables) { const char *yang_folder = TESTS_DIR "/api/files"; const char *module_name1 = "b"; try { auto ctx = std::make_shared(yang_folder); ASSERT_NOTNULL(ctx); auto module = ctx->load_module(module_name1); ASSERT_NOTNULL(module); ASSERT_STREQ(module_name1, module->name()); auto list = std::make_shared>(module->data_instantiables(0)); ASSERT_NOTNULL(list); ASSERT_EQ(1, list->size()); } catch( const std::exception& e ) { mt::printFailed(e.what(), stdout); throw; } } TEST(test_ly_schema_child_instatiables) { const char *yang_folder = TESTS_DIR "/api/files"; const char *module_name = "b"; try { auto ctx = std::make_shared(yang_folder); ASSERT_NOTNULL(ctx); auto module = ctx->load_module(module_name); ASSERT_NOTNULL(module); ASSERT_STREQ(module_name, module->name()); auto list = std::make_shared>(module->data_instantiables(0)); ASSERT_NOTNULL(list); ASSERT_EQ(1, list->size()); auto child_list = std::make_shared>(list->front()->child_instantiables(0)); ASSERT_NOTNULL(child_list); ASSERT_EQ(3, child_list->size()); } catch( const std::exception& e ) { mt::printFailed(e.what(), stdout); throw; } } TEST_MAIN();