| /** |
| * @file list.c |
| * @author Radek Iša <isa@cesnet.cz> |
| * @brief test for list node |
| * |
| * Copyright (c) 2021 CESNET, z.s.p.o. |
| * |
| * 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 UTEST HEADER */ |
| #define _UTEST_MAIN_ |
| #include "../utests.h" |
| |
| /* GLOBAL INCLUDE HEADERS */ |
| #include <ctype.h> |
| |
| /* LOCAL INCLUDE HEADERS */ |
| #include "libyang.h" |
| #include "path.h" |
| |
| #define LYD_TREE_CREATE(INPUT, MODEL) \ |
| CHECK_PARSE_LYD_PARAM(INPUT, LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_SUCCESS, MODEL) |
| |
| #define MODULE_CREATE_YIN(MOD_NAME, NODES) \ |
| "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" \ |
| "<module name=\"" MOD_NAME "\"\n" \ |
| " xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\"\n" \ |
| " xmlns:pref=\"urn:tests:" MOD_NAME "\">\n" \ |
| " <yang-version value=\"1.1\"/>\n" \ |
| " <namespace uri=\"urn:tests:" MOD_NAME "\"/>\n" \ |
| " <prefix value=\"pref\"/>\n" \ |
| NODES \ |
| "</module>\n" |
| |
| #define MODULE_CREATE_YANG(MOD_NAME, NODES) \ |
| "module " MOD_NAME " {\n" \ |
| " yang-version 1.1;\n" \ |
| " namespace \"urn:tests:" MOD_NAME "\";\n" \ |
| " prefix pref;\n" \ |
| NODES \ |
| "}\n" |
| |
| static void |
| test_schema_yang(void **state) |
| { |
| const char *schema; |
| struct lys_module *mod; |
| struct lysc_node_list *lysc_leaf; |
| struct lysc_node *lysc_node; |
| |
| schema = MODULE_CREATE_YANG("T0", "list user {" |
| "key uid;" |
| "unique name;" |
| "leaf uid{type int32;}" |
| "leaf name{type string;}" |
| "leaf group{type string;}" |
| "}"); |
| UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, &mod); |
| lysc_leaf = (void *)mod->compiled->data; |
| CHECK_LYSC_NODE_LIST(lysc_leaf, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_ORDBY_SYSTEM, 1, "user", 0, \ |
| 0, 0, 0, 0, 1, 0xffffffff, 0, 0, 0, 1, 0); |
| lysc_node = lysc_leaf->child; |
| CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_KEY, 1, "uid", 1, LYS_LEAF, 1, 0, 0, 0); |
| lysc_node = lysc_node->next; |
| CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_UNIQUE, 1, "name", 1, LYS_LEAF, 1, 0, 0, 0); |
| lysc_node = lysc_node->next; |
| CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR, 1, "group", 0, LYS_LEAF, 1, 0, 0, 0); |
| |
| schema = MODULE_CREATE_YANG("T1", "list user {" |
| "key uid;" |
| "container name{" |
| " leaf fist {type string;}" |
| " container second{leaf sub { type int32;}}" |
| "}" |
| "leaf uid{type int32;}" |
| "}"); |
| UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, &mod); |
| lysc_leaf = (void *)mod->compiled->data; |
| CHECK_LYSC_NODE_LIST(lysc_leaf, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_ORDBY_SYSTEM, 1, "user", 0, \ |
| 0, 0, 0, 0, 1, 0xffffffff, 0, 0, 0, 0, 0); |
| lysc_node = lysc_leaf->child; |
| CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_KEY, 1, "uid", 1, LYS_LEAF, 1, 0, 0, 0); |
| lysc_node = lysc_node->next; |
| CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR, 1, "name", 0, LYS_CONTAINER, 1, 0, 0, 0); |
| |
| schema = MODULE_CREATE_YANG("T2", "list grup {" |
| "key \"guid\";" |
| "leaf guid{type int32;}" |
| "list users{ key name; leaf name {type string;}}" |
| "}"); |
| UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, &mod); |
| lysc_leaf = (void *)mod->compiled->data; |
| CHECK_LYSC_NODE_LIST(lysc_leaf, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_ORDBY_SYSTEM, 1, "grup", 0, \ |
| 0, 0, 0, 0, 1, 0xffffffff, 0, 0, 0, 0, 0); |
| lysc_node = lysc_leaf->child; |
| CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_KEY, 1, "guid", 1, LYS_LEAF, 1, 0, 0, 0); |
| lysc_node = lysc_node->next; |
| CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_ORDBY_SYSTEM, 1, "users", 0, LYS_LIST, 1, 0, 0, 0); |
| |
| /* restriction */ |
| schema = MODULE_CREATE_YANG("T3", "list grup {" |
| "key guid;" |
| "min-elements 10;" |
| "max-elements 20;" |
| "leaf guid{type int32;}" |
| "list users{ key name; leaf name {type string;}}" |
| "}"); |
| UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, &mod); |
| lysc_leaf = (void *)mod->compiled->data; |
| CHECK_LYSC_NODE_LIST(lysc_leaf, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_MAND_TRUE | LYS_ORDBY_SYSTEM, 1, \ |
| "grup", 0, 0, 0, 0, 0, 1, 20, 10, 0, 0, 0, 0); |
| lysc_node = lysc_leaf->child; |
| CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_KEY, 1, "guid", 1, LYS_LEAF, 1, 0, 0, 0); |
| lysc_node = lysc_node->next; |
| CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_ORDBY_SYSTEM, 1, "users", 0, LYS_LIST, 1, 0, 0, 0); |
| |
| schema = MODULE_CREATE_YANG("T4", "list user {" |
| "key \"uid name\";" |
| "unique name;" |
| "leaf uid{type int32;}" |
| "leaf name{type string;}" |
| "leaf group{type string;}" |
| "}"); |
| UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, &mod); |
| lysc_leaf = (void *)mod->compiled->data; |
| CHECK_LYSC_NODE_LIST(lysc_leaf, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_ORDBY_SYSTEM, 1, "user", 0, \ |
| 0, 0, 0, 0, 1, 0xffffffff, 0, 0, 0, 1, 0); |
| lysc_node = lysc_leaf->child; |
| CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_KEY, 1, "uid", 1, LYS_LEAF, 1, 0, 0, 0); |
| lysc_node = lysc_node->next; |
| CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_UNIQUE | LYS_KEY, 1, "name", 1, LYS_LEAF, 1, 0, 0, 0); |
| lysc_node = lysc_node->next; |
| CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR, 1, "group", 0, LYS_LEAF, 1, 0, 0, 0); |
| |
| schema = MODULE_CREATE_YANG("T5", "list rule {" |
| "key \"id\";" |
| "unique \"name\";" |
| "unique \"ip port\";" |
| "leaf id{type int32;}" |
| "leaf name{type string;}" |
| "leaf ip{type string;}" |
| "leaf port{type int16;}" |
| "}"); |
| UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, &mod); |
| lysc_leaf = (void *)mod->compiled->data; |
| CHECK_LYSC_NODE_LIST(lysc_leaf, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_ORDBY_SYSTEM, 1, "rule", 0, \ |
| 0, 0, 0, 0, 1, 0xffffffff, 0, 0, 0, 2, 0); |
| lysc_node = lysc_leaf->child; |
| CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_KEY, 1, "id", 1, LYS_LEAF, 1, 0, 0, 0); |
| lysc_node = lysc_node->next; |
| CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_UNIQUE, 1, "name", 1, LYS_LEAF, 1, 0, 0, 0); |
| lysc_node = lysc_node->next; |
| CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_UNIQUE, 1, "ip", 1, LYS_LEAF, 1, 0, 0, 0); |
| lysc_node = lysc_node->next; |
| CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_UNIQUE, 1, "port", 0, LYS_LEAF, 1, 0, 0, 0); |
| |
| /* test error */ |
| schema = MODULE_CREATE_YANG("TERR_0", "list user {" |
| "key uid;" |
| "min-elements 10;" |
| "max-elements -1;" |
| "leaf uid{type int32;}" |
| "leaf name{type string;}" |
| "leaf group{type string;}" |
| "}"); |
| UTEST_INVALID_MODULE(schema, LYS_IN_YANG, NULL, LY_EVALID); |
| CHECK_LOG_CTX("Parsing module \"TERR_0\" failed.", NULL, |
| "Invalid value \"-1\" of \"max-elements\".", "Line number 5."); |
| |
| schema = MODULE_CREATE_YANG("TERR_0", "list user {" |
| "key uid;" |
| "min-elements 10;" |
| "max-elements 4294967298;" |
| "leaf uid{type int32;}" |
| "leaf name{type string;}" |
| "leaf group{type string;}" |
| "}"); |
| UTEST_INVALID_MODULE(schema, LYS_IN_YANG, NULL, LY_EVALID); |
| CHECK_LOG_CTX("Parsing module \"TERR_0\" failed.", NULL, |
| "Value \"4294967298\" is out of \"max-elements\" bounds.", "Line number 5."); |
| |
| schema = MODULE_CREATE_YANG("TERR_0", "list user {" |
| "key uid;" |
| "min-elements 20;" |
| "max-elements 10;" |
| "leaf uid{type int32;}" |
| "leaf name{type string;}" |
| "leaf group{type string;}" |
| "}"); |
| UTEST_INVALID_MODULE(schema, LYS_IN_YANG, NULL, LY_EVALID); |
| CHECK_LOG_CTX("List min-elements 20 is bigger than max-elements 10.", "/TERR_0:user"); |
| |
| schema = MODULE_CREATE_YANG("TERR_0", "list user {" |
| "key uid;" |
| "min-elements -1;" |
| "max-elements 20;" |
| "leaf uid{type int32;}" |
| "leaf name{type string;}" |
| "leaf group{type string;}" |
| "}"); |
| UTEST_INVALID_MODULE(schema, LYS_IN_YANG, NULL, LY_EVALID); |
| CHECK_LOG_CTX("Parsing module \"TERR_0\" failed.", NULL, |
| "Invalid value \"-1\" of \"min-elements\".", "Line number 5."); |
| |
| schema = MODULE_CREATE_YANG("TERR_0", "list user {" |
| "key uid;" |
| "key name;" |
| "leaf uid{type int32;}" |
| "leaf name{type string;}" |
| "leaf group{type string;}" |
| "}"); |
| UTEST_INVALID_MODULE(schema, LYS_IN_YANG, NULL, LY_EVALID); |
| CHECK_LOG_CTX("Parsing module \"TERR_0\" failed.", NULL, |
| "Duplicate keyword \"key\".", "Line number 5."); |
| |
| schema = MODULE_CREATE_YANG("T6", "list user {" |
| "config false;" |
| "leaf uid{type int32;}" |
| "leaf name{type string;}" |
| "leaf group{type string;}" |
| "}"); |
| UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, &mod); |
| lysc_leaf = (void *)mod->compiled->data; |
| CHECK_LYSC_NODE_LIST(lysc_leaf, 0, 0, LYS_CONFIG_R | LYS_STATUS_CURR | LYS_ORDBY_USER | LYS_KEYLESS | LYS_SET_CONFIG, \ |
| 1, "user", 0, 0, 0, 0, 0, 1, 0xffffffff, 0, 0, 0, 0, 0); |
| lysc_node = lysc_leaf->child; |
| CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_R | LYS_STATUS_CURR, 1, "uid", 1, LYS_LEAF, 1, 0, 0, 0); |
| lysc_node = lysc_node->next; |
| CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_R | LYS_STATUS_CURR, 1, "name", 1, LYS_LEAF, 1, 0, 0, 0); |
| lysc_node = lysc_node->next; |
| CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_R | LYS_STATUS_CURR, 1, "group", 0, LYS_LEAF, 1, 0, 0, 0); |
| |
| schema = MODULE_CREATE_YANG("T7", "list user {" |
| "key uid;" |
| "unique name;" |
| "ordered-by user;" |
| "leaf uid{type int32;}" |
| "leaf name{type string;}" |
| "leaf group{type string;}" |
| "}"); |
| UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, &mod); |
| lysc_leaf = (void *)mod->compiled->data; |
| CHECK_LYSC_NODE_LIST(lysc_leaf, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_ORDBY_USER, 1, "user", 0, \ |
| 0, 0, 0, 0, 1, 0xffffffff, 0, 0, 0, 1, 0); |
| lysc_node = lysc_leaf->child; |
| CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_KEY, 1, "uid", 1, LYS_LEAF, 1, 0, 0, 0); |
| lysc_node = lysc_node->next; |
| CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_UNIQUE, 1, "name", 1, LYS_LEAF, 1, 0, 0, 0); |
| lysc_node = lysc_node->next; |
| CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR, 1, "group", 0, LYS_LEAF, 1, 0, 0, 0); |
| |
| schema = MODULE_CREATE_YANG("T8", "list user {" |
| "key uid;" |
| "unique name;" |
| "ordered-by system;" |
| "leaf uid{type int32;}" |
| "leaf name{type string;}" |
| "leaf group{type string;}" |
| "}"); |
| UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, &mod); |
| lysc_leaf = (void *)mod->compiled->data; |
| CHECK_LYSC_NODE_LIST(lysc_leaf, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_ORDBY_SYSTEM, 1, "user", 0, \ |
| 0, 0, 0, 0, 1, 0xffffffff, 0, 0, 0, 1, 0); |
| lysc_node = lysc_leaf->child; |
| CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_KEY, 1, "uid", 1, LYS_LEAF, 1, 0, 0, 0); |
| lysc_node = lysc_node->next; |
| CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_UNIQUE, 1, "name", 1, LYS_LEAF, 1, 0, 0, 0); |
| lysc_node = lysc_node->next; |
| CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR, 1, "group", 0, LYS_LEAF, 1, 0, 0, 0); |
| |
| schema = MODULE_CREATE_YANG("TERROR0", "list user {" |
| "key uid;" |
| "unique name;" |
| "ordered-by systeme;" |
| "leaf uid{type int32;}" |
| "leaf name{type string;}" |
| "leaf group{type string;}" |
| "}"); |
| UTEST_INVALID_MODULE(schema, LYS_IN_YANG, NULL, LY_EVALID); |
| CHECK_LOG_CTX("Parsing module \"TERROR0\" failed.", NULL, |
| "Invalid value \"systeme\" of \"ordered-by\".", "Line number 5."); |
| |
| schema = MODULE_CREATE_YANG("TERROR0", "list \"\" {" |
| "key uid;" |
| "unique name;" |
| "ordered-by system;" |
| "leaf uid{type int32;}" |
| "leaf name{type string;}" |
| "leaf group{type string;}" |
| "}"); |
| UTEST_INVALID_MODULE(schema, LYS_IN_YANG, NULL, LY_EVALID); |
| CHECK_LOG_CTX("Parsing module \"TERROR0\" failed.", NULL, |
| "Statement argument is required.", "Line number 5."); |
| |
| schema = MODULE_CREATE_YANG("T9", "list user {" |
| "key uid;" |
| "unique name;" |
| "ordered-by system;" |
| "leaf uid{type int32;}" |
| "leaf name{type string;}" |
| "leaf group{type string; default \"abcd\";}" |
| "}"); |
| UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, &mod); |
| lysc_leaf = (void *)mod->compiled->data; |
| CHECK_LYSC_NODE_LIST(lysc_leaf, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_ORDBY_SYSTEM, 1, "user", 0, \ |
| 0, 0, 0, 0, 1, 0xffffffff, 0, 0, 0, 1, 0); |
| lysc_node = lysc_leaf->child; |
| CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_KEY, 1, "uid", 1, LYS_LEAF, 1, 0, 0, 0); |
| lysc_node = lysc_node->next; |
| CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_UNIQUE, 1, "name", 1, LYS_LEAF, 1, 0, 0, 0); |
| lysc_node = lysc_node->next; |
| CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_SET_DFLT, 1, "group", 0, LYS_LEAF, 1, 0, 0, 0); |
| |
| schema = MODULE_CREATE_YANG("T10", "list user {" |
| "key uid;" |
| "leaf uid{type int32; default \"25\";}" |
| "leaf name{type string;}" |
| "leaf group{type string;}" |
| "}"); |
| UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, &mod); |
| lysc_leaf = (void *)mod->compiled->data; |
| CHECK_LYSC_NODE_LIST(lysc_leaf, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_ORDBY_SYSTEM, 1, "user", 0, \ |
| 0, 0, 0, 0, 1, 0xffffffff, 0, 0, 0, 0, 0); |
| lysc_node = lysc_leaf->child; |
| CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_KEY | LYS_SET_DFLT, 1, "uid", 1, LYS_LEAF, 1, 0, 0, 0); |
| lysc_node = lysc_node->next; |
| CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR, 1, "name", 1, LYS_LEAF, 1, 0, 0, 0); |
| lysc_node = lysc_node->next; |
| CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR, 1, "group", 0, LYS_LEAF, 1, 0, 0, 0); |
| |
| schema = MODULE_CREATE_YANG("T11", |
| "typedef my_type {" |
| " type int8; default \"25\";" |
| "}" |
| "list user {" |
| " key uid;" |
| " leaf uid{type my_type;}" |
| " leaf name{type string;}" |
| " leaf group{type string;}" |
| "}"); |
| UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, &mod); |
| lysc_leaf = (void *)mod->compiled->data; |
| CHECK_LYSC_NODE_LIST(lysc_leaf, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_ORDBY_SYSTEM, 1, "user", 0, \ |
| 0, 0, 0, 0, 1, 0xffffffff, 0, 0, 0, 0, 0); |
| lysc_node = lysc_leaf->child; |
| CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_KEY, 1, "uid", 1, LYS_LEAF, 1, 0, 0, 0); |
| lysc_node = lysc_node->next; |
| CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR, 1, "name", 1, LYS_LEAF, 1, 0, 0, 0); |
| lysc_node = lysc_node->next; |
| CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR, 1, "group", 0, LYS_LEAF, 1, 0, 0, 0); |
| |
| } |
| |
| static void |
| test_schema_yin(void **state) |
| { |
| const char *schema; |
| struct lys_module *mod; |
| struct lysc_node_list *lysc_leaf; |
| struct lysc_node *lysc_node; |
| |
| schema = MODULE_CREATE_YIN("T0", "<list name=\"user\">" |
| " <key value=\"uid\"/>" |
| " <unique tag=\"name\"/>" |
| " <leaf name=\"uid\"><type name=\"int32\"/></leaf>" |
| " <leaf name=\"name\"><type name=\"string\"/></leaf>" |
| " <leaf name=\"group\"><type name=\"string\"/></leaf>" |
| "</list>"); |
| UTEST_ADD_MODULE(schema, LYS_IN_YIN, NULL, &mod); |
| lysc_leaf = (void *)mod->compiled->data; |
| CHECK_LYSC_NODE_LIST(lysc_leaf, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_ORDBY_SYSTEM, 1, "user", 0, \ |
| 0, 0, 0, 0, 1, 0xffffffff, 0, 0, 0, 1, 0); |
| lysc_node = lysc_leaf->child; |
| CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_KEY, 1, "uid", 1, LYS_LEAF, 1, 0, 0, 0); |
| lysc_node = lysc_node->next; |
| CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_UNIQUE, 1, "name", 1, LYS_LEAF, 1, 0, 0, 0); |
| lysc_node = lysc_node->next; |
| CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR, 1, "group", 0, LYS_LEAF, 1, 0, 0, 0); |
| |
| schema = MODULE_CREATE_YIN("T00", "<list name=\"user\">" |
| " <key value=\"u<id\"/>" |
| " <leaf name=\"uid\"><type name=\"int32\"/></leaf>" |
| " <leaf name=\"name\"><type name=\"string\"/></leaf>" |
| " <leaf name=\"group\"><type name=\"string\"/></leaf>" |
| "</list>"); |
| UTEST_INVALID_MODULE(schema, LYS_IN_YIN, NULL, LY_EVALID); |
| CHECK_LOG_CTX("The list's key \"u<id\" not found.", "/T00:user"); |
| |
| schema = MODULE_CREATE_YIN("T1", "<list name=\"user\"> " |
| " <key value=\"uid\"/>" |
| " <container name=\"name\">" |
| " <leaf name=\"fist\"> <type name=\"string\"/> </leaf>" |
| " <container name=\"second\">" |
| " <leaf name=\"sub\"> <type name=\"int32\"/></leaf>" |
| " </container>" |
| " </container>" |
| " <leaf name=\"uid\"> <type name=\"int32\"/></leaf>" |
| "</list>"); |
| UTEST_ADD_MODULE(schema, LYS_IN_YIN, NULL, &mod); |
| lysc_leaf = (void *)mod->compiled->data; |
| CHECK_LYSC_NODE_LIST(lysc_leaf, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_ORDBY_SYSTEM, 1, "user", 0, \ |
| 0, 0, 0, 0, 1, 0xffffffff, 0, 0, 0, 0, 0); |
| lysc_node = lysc_leaf->child; |
| CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_KEY, 1, "uid", 1, LYS_LEAF, 1, 0, 0, 0); |
| lysc_node = lysc_node->next; |
| CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR, 1, "name", 0, LYS_CONTAINER, 1, 0, 0, 0); |
| |
| schema = MODULE_CREATE_YIN("T2", "<list name=\"grup\">" |
| "<key value=\"guid\"/>" |
| "<leaf name=\"guid\"> <type name=\"int32\"/> </leaf>" |
| "<list name=\"users\">" |
| " <key value=\"name\"/>" |
| " <leaf name=\"name\"> <type name=\"string\"/> </leaf>" |
| "</list>" |
| "</list>"); |
| UTEST_ADD_MODULE(schema, LYS_IN_YIN, NULL, &mod); |
| lysc_leaf = (void *)mod->compiled->data; |
| CHECK_LYSC_NODE_LIST(lysc_leaf, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_ORDBY_SYSTEM, 1, "grup", 0, \ |
| 0, 0, 0, 0, 1, 0xffffffff, 0, 0, 0, 0, 0); |
| lysc_node = lysc_leaf->child; |
| CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_KEY, 1, "guid", 1, LYS_LEAF, 1, 0, 0, 0); |
| lysc_node = lysc_node->next; |
| CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_ORDBY_SYSTEM, 1, "users", 0, LYS_LIST, 1, 0, 0, 0); |
| |
| /* restriction */ |
| schema = MODULE_CREATE_YIN("T3", |
| "<list name = \"grup\">" |
| " <key value=\"guid\"/>" |
| " <min-elements value=\"10\"/>" |
| " <max-elements value=\"20\"/>" |
| " <leaf name=\"guid\"> <type name=\"int32\"/> </leaf>" |
| " <list name=\"users\"> <key value=\"name\"/>" |
| " <leaf name=\"name\"> <type name=\"string\"/> </leaf>" |
| " </list>" |
| "</list>"); |
| UTEST_ADD_MODULE(schema, LYS_IN_YIN, NULL, &mod); |
| lysc_leaf = (void *)mod->compiled->data; |
| CHECK_LYSC_NODE_LIST(lysc_leaf, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_MAND_TRUE | LYS_ORDBY_SYSTEM, 1, "grup", \ |
| 0, 0, 0, 0, 0, 1, 20, 10, 0, 0, 0, 0); |
| lysc_node = lysc_leaf->child; |
| CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_KEY, 1, "guid", 1, LYS_LEAF, 1, 0, 0, 0); |
| lysc_node = lysc_node->next; |
| CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_ORDBY_SYSTEM, 1, "users", 0, LYS_LIST, 1, 0, 0, 0); |
| |
| schema = MODULE_CREATE_YIN("T4", |
| "<list name=\"user\">" |
| " <key value=\"uid name\"/>" |
| " <unique tag=\"name\"/>" |
| " <leaf name=\"uid\"> <type name=\"int32\"/> </leaf>" |
| " <leaf name=\"name\"> <type name=\"string\"/> </leaf>" |
| " <leaf name=\"group\"> <type name=\"string\"/> </leaf>" |
| "</list>"); |
| UTEST_ADD_MODULE(schema, LYS_IN_YIN, NULL, &mod); |
| lysc_leaf = (void *)mod->compiled->data; |
| CHECK_LYSC_NODE_LIST(lysc_leaf, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_ORDBY_SYSTEM, 1, "user", 0, \ |
| 0, 0, 0, 0, 1, 0xffffffff, 0, 0, 0, 1, 0); |
| lysc_node = lysc_leaf->child; |
| CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_KEY, 1, "uid", 1, LYS_LEAF, 1, 0, 0, 0); |
| lysc_node = lysc_node->next; |
| CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_UNIQUE | LYS_KEY, 1, "name", 1, LYS_LEAF, 1, 0, 0, 0); |
| lysc_node = lysc_node->next; |
| CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR, 1, "group", 0, LYS_LEAF, 1, 0, 0, 0); |
| |
| schema = MODULE_CREATE_YIN("T5", |
| "<list name=\"rule\">" |
| " <key value=\"id\"/>" |
| " <unique tag=\"name\"/>" |
| " <unique tag=\"ip port\"/>" |
| " <leaf name=\"id\"> <type name=\"int32\"/></leaf>" |
| " <leaf name=\"name\"> <type name=\"string\"/> </leaf>" |
| " <leaf name=\"ip\"> <type name=\"string\"/> </leaf>" |
| " <leaf name=\"port\"> <type name=\"int16\"/> </leaf>" |
| "</list>"); |
| UTEST_ADD_MODULE(schema, LYS_IN_YIN, NULL, &mod); |
| lysc_leaf = (void *)mod->compiled->data; |
| CHECK_LYSC_NODE_LIST(lysc_leaf, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_ORDBY_SYSTEM, 1, "rule", 0, \ |
| 0, 0, 0, 0, 1, 0xffffffff, 0, 0, 0, 2, 0); |
| lysc_node = lysc_leaf->child; |
| CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_KEY, 1, "id", 1, LYS_LEAF, 1, 0, 0, 0); |
| lysc_node = lysc_node->next; |
| CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_UNIQUE, 1, "name", 1, LYS_LEAF, 1, 0, 0, 0); |
| lysc_node = lysc_node->next; |
| CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_UNIQUE, 1, "ip", 1, LYS_LEAF, 1, 0, 0, 0); |
| lysc_node = lysc_node->next; |
| CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_UNIQUE, 1, "port", 0, LYS_LEAF, 1, 0, 0, 0); |
| |
| /* test error */ |
| schema = MODULE_CREATE_YIN("TERR_0", |
| "<list name=\"user\">" |
| " <key value=\"uid\"/>" |
| " <min-elements value=\"10\"/>" |
| " <max-elements value=\"-1\"/>" |
| " <leaf name=\"uid\"> <type name=\"int32\"> </leaf>" |
| "</list>"); |
| UTEST_INVALID_MODULE(schema, LYS_IN_YIN, NULL, LY_EVALID); |
| CHECK_LOG_CTX("Parsing module \"TERR_0\" failed.", NULL, |
| "Invalid value \"-1\" of \"value\" attribute in \"max-elements\" element.", "Line number 10."); |
| |
| schema = MODULE_CREATE_YIN("TERR_0", |
| "<list name=\"user\">" |
| " <key value=\"uid\"/>" |
| " <min-elements value=\"10\"/>" |
| " <max-elements value=\"4294967298\"/>" |
| " <leaf name=\"uid\"> <type name=\"int32\"/> </leaf>" |
| " <leaf name=\"name\"> <type name=\"string\"/> </leaf>" |
| " <leaf name=\"group\"> <type name=\"string\"/> </leaf>" |
| "</list>"); |
| UTEST_INVALID_MODULE(schema, LYS_IN_YIN, NULL, LY_EVALID); |
| CHECK_LOG_CTX("Parsing module \"TERR_0\" failed.", NULL, |
| "Value \"4294967298\" of \"value\" attribute in \"max-elements\" element is out of bounds.", "Line number 10."); |
| |
| schema = MODULE_CREATE_YIN("TERR_0", |
| "<list name=\"user\">" |
| " <key value=\"uid\"/>" |
| " <min-elements value=\"20\"/>" |
| " <max-elements value=\"10\"/>" |
| " <leaf name=\"uid\"> <type name=\"int32\"/> </leaf>" |
| " <leaf name=\"name\"> <type name=\"string\"/> </leaf>" |
| " <leaf name=\"group\"> <type name=\"string\"/> </leaf>" |
| "</list>"); |
| UTEST_INVALID_MODULE(schema, LYS_IN_YIN, NULL, LY_EVALID); |
| CHECK_LOG_CTX("Parsing module \"TERR_0\" failed.", NULL, |
| "Invalid combination of min-elements and max-elements: min value 20 is bigger than the max value 10.", "Line number 10."); |
| |
| schema = MODULE_CREATE_YIN("TERR_0", |
| "<list name=\"user\">" |
| " <key value=\"uid\"/>" |
| " <min-elements value=\"-1\"/>" |
| " <max-elements value=\"20\"/>" |
| " <leaf name=\"uid\"> <type name=\"int32\"/> </leaf>" |
| " <leaf name=\"name\"> <type name=\"string\"/> </leaf>" |
| " <leaf name=\"group\"> <type name=\"string\"/> </leaf>" |
| "</list>"); |
| UTEST_INVALID_MODULE(schema, LYS_IN_YIN, NULL, LY_EVALID); |
| CHECK_LOG_CTX("Parsing module \"TERR_0\" failed.", NULL, |
| "Value \"-1\" of \"value\" attribute in \"min-elements\" element is out of bounds.", "Line number 10."); |
| |
| schema = MODULE_CREATE_YIN("TERR_0", |
| "<list name=\"user\">" |
| " <key value=\"uid\"/>" |
| " <key value=\"name\"/>" |
| " <leaf name=\"uid\"> <type name=\"int32\"/> </leaf>" |
| " <leaf name=\"name\"> <type name=\"string\"/> </leaf>" |
| " <leaf name=\"group\"> <type name=\"string\"/> </leaf>" |
| "</list>"); |
| UTEST_INVALID_MODULE(schema, LYS_IN_YIN, NULL, LY_EVALID); |
| CHECK_LOG_CTX("Parsing module \"TERR_0\" failed.", NULL, |
| "Redefinition of \"key\" sub-element in \"list\" element.", "Line number 10."); |
| |
| schema = MODULE_CREATE_YIN("T6", |
| "<list name=\"user\">" |
| " <config value=\"false\"/>" |
| " <leaf name=\"uid\"> <type name=\"int32\"/> </leaf>" |
| " <leaf name=\"name\"> <type name=\"string\"/> </leaf>" |
| " <leaf name=\"group\"><type name=\"string\"/> </leaf>" |
| "</list>"); |
| UTEST_ADD_MODULE(schema, LYS_IN_YIN, NULL, &mod); |
| lysc_leaf = (void *)mod->compiled->data; |
| CHECK_LYSC_NODE_LIST(lysc_leaf, 0, 0, LYS_CONFIG_R | LYS_STATUS_CURR | LYS_ORDBY_USER | LYS_KEYLESS | LYS_SET_CONFIG, \ |
| 1, "user", 0, 0, 0, 0, 0, 1, 0xffffffff, 0, 0, 0, 0, 0); |
| lysc_node = lysc_leaf->child; |
| CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_R | LYS_STATUS_CURR, 1, "uid", 1, LYS_LEAF, 1, 0, 0, 0); |
| lysc_node = lysc_node->next; |
| CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_R | LYS_STATUS_CURR, 1, "name", 1, LYS_LEAF, 1, 0, 0, 0); |
| lysc_node = lysc_node->next; |
| CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_R | LYS_STATUS_CURR, 1, "group", 0, LYS_LEAF, 1, 0, 0, 0); |
| |
| schema = MODULE_CREATE_YIN("T7", |
| "<list name=\"user\">" |
| " <key value=\"uid\"/>" |
| " <unique tag=\"name\"/>" |
| " <ordered-by value=\"user\"/>" |
| " <leaf name=\"uid\"> <type name=\"int32\"/> </leaf>" |
| " <leaf name=\"name\"> <type name=\"string\"/> </leaf>" |
| " <leaf name=\"group\"><type name=\"string\"/> </leaf>" |
| "</list>"); |
| UTEST_ADD_MODULE(schema, LYS_IN_YIN, NULL, &mod); |
| lysc_leaf = (void *)mod->compiled->data; |
| CHECK_LYSC_NODE_LIST(lysc_leaf, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_ORDBY_USER, 1, "user", 0, \ |
| 0, 0, 0, 0, 1, 0xffffffff, 0, 0, 0, 1, 0); |
| lysc_node = lysc_leaf->child; |
| CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_KEY, 1, "uid", 1, LYS_LEAF, 1, 0, 0, 0); |
| lysc_node = lysc_node->next; |
| CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_UNIQUE, 1, "name", 1, LYS_LEAF, 1, 0, 0, 0); |
| lysc_node = lysc_node->next; |
| CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR, 1, "group", 0, LYS_LEAF, 1, 0, 0, 0); |
| |
| schema = MODULE_CREATE_YIN("T8", |
| "<list name=\"user\">" |
| " <key value=\"uid\"/>" |
| " <unique tag=\"name\"/>" |
| " <ordered-by value=\"system\"/>" |
| " <leaf name=\"uid\"> <type name=\"int32\"/> </leaf>" |
| " <leaf name=\"name\"> <type name=\"string\"/> </leaf>" |
| " <leaf name=\"group\"><type name=\"string\"/> </leaf>" |
| "</list>"); |
| UTEST_ADD_MODULE(schema, LYS_IN_YIN, NULL, &mod); |
| lysc_leaf = (void *)mod->compiled->data; |
| CHECK_LYSC_NODE_LIST(lysc_leaf, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_ORDBY_SYSTEM, 1, "user", 0, \ |
| 0, 0, 0, 0, 1, 0xffffffff, 0, 0, 0, 1, 0); |
| lysc_node = lysc_leaf->child; |
| CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_KEY, 1, "uid", 1, LYS_LEAF, 1, 0, 0, 0); |
| lysc_node = lysc_node->next; |
| CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_UNIQUE, 1, "name", 1, LYS_LEAF, 1, 0, 0, 0); |
| lysc_node = lysc_node->next; |
| CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR, 1, "group", 0, LYS_LEAF, 1, 0, 0, 0); |
| |
| schema = MODULE_CREATE_YIN("TERROR0", |
| "<list name=\"user\">" |
| " <key value=\"uid\"/>" |
| " <unique tag=\"name\"/>" |
| " <ordered-by value=\"systeme\"/>" |
| " <leaf name=\"uid\"> <type name=\"int32\"/> </leaf>" |
| " <leaf name=\"name\"> <type name=\"string\"/> </leaf>" |
| " <leaf name=\"group\"><type name=\"string\"/> </leaf>" |
| "</list>"); |
| UTEST_INVALID_MODULE(schema, LYS_IN_YIN, NULL, LY_EVALID); |
| CHECK_LOG_CTX("Parsing module \"TERROR0\" failed.", NULL, |
| "Invalid value \"systeme\" of \"value\" attribute in \"ordered-by\" element. Valid values are \"system\" and \"user\".", |
| "Line number 10."); |
| |
| schema = MODULE_CREATE_YIN("T_DEFS1", |
| "<list name=\"user\">" |
| " <key value=\"uid\"/>" |
| " <unique tag=\"name\"/>" |
| " <ordered-by value=\"system\"/>" |
| " <leaf name=\"uid\"> <type name=\"int32\"/> </leaf>" |
| " <leaf name=\"name\"> <type name=\"string\"/> </leaf>" |
| " <leaf name=\"group\"><type name=\"string\"/> <default value=\"ath\"/> </leaf>" |
| "</list>"); |
| UTEST_ADD_MODULE(schema, LYS_IN_YIN, NULL, &mod); |
| lysc_leaf = (void *)mod->compiled->data; |
| CHECK_LYSC_NODE_LIST(lysc_leaf, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_ORDBY_SYSTEM, 1, "user", 0, \ |
| 0, 0, 0, 0, 1, 0xffffffff, 0, 0, 0, 1, 0); |
| lysc_node = lysc_leaf->child; |
| CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_KEY, 1, "uid", 1, LYS_LEAF, 1, 0, 0, 0); |
| lysc_node = lysc_node->next; |
| CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_UNIQUE, 1, "name", 1, LYS_LEAF, 1, 0, 0, 0); |
| lysc_node = lysc_node->next; |
| CHECK_LYSC_NODE(lysc_node, 0, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_SET_DFLT, 1, "group", 0, LYS_LEAF, 1, 0, 0, 0); |
| |
| } |
| |
| static void |
| test_schema_print(void **state) |
| { |
| const char *schema_yang, *schema_yin; |
| char *printed; |
| struct lys_module *mod; |
| |
| /* test print yang to yin */ |
| schema_yang = MODULE_CREATE_YANG("PRINT0", |
| "list user {" |
| " min-elements 10;" |
| " max-elements 20;" |
| " key \"uid name\";" |
| " unique name;" |
| " leaf uid{type int32;}" |
| " leaf name{type string;}" |
| " leaf group{type string;}" |
| "}"); |
| schema_yin = MODULE_CREATE_YIN("PRINT0", |
| " <list name=\"user\">\n" |
| " <key value=\"uid name\"/>\n" |
| " <unique tag=\"name\"/>\n" |
| " <min-elements value=\"10\"/>\n" |
| " <max-elements value=\"20\"/>\n" |
| " <leaf name=\"uid\">\n" |
| " <type name=\"int32\"/>\n" |
| " </leaf>\n" |
| " <leaf name=\"name\">\n" |
| " <type name=\"string\"/>\n" |
| " </leaf>\n" |
| " <leaf name=\"group\">\n" |
| " <type name=\"string\"/>\n" |
| " </leaf>\n" |
| " </list>\n"); |
| |
| UTEST_ADD_MODULE(schema_yang, LYS_IN_YANG, NULL, &mod); |
| assert_non_null(mod); |
| assert_int_equal(LY_SUCCESS, lys_print_mem(&printed, mod, LYS_OUT_YIN, 0)); |
| assert_string_equal(printed, schema_yin); |
| free(printed); |
| |
| /* test print yin to yang */ |
| schema_yang = MODULE_CREATE_YANG("PRINT1", |
| "\n" |
| " list user {\n" |
| " key \"uid name\";\n" |
| " unique \"name\";\n" |
| " min-elements 10;\n" |
| " max-elements 20;\n" |
| " leaf uid {\n" |
| " type int32;\n" |
| " }\n" |
| " leaf name {\n" |
| " type string;\n" |
| " }\n" |
| " leaf group {\n" |
| " type string;\n" |
| " }\n" |
| " }\n"); |
| schema_yin = MODULE_CREATE_YIN("PRINT1", |
| " <list name=\"user\">\n" |
| " <key value=\"uid name\"/>\n" |
| " <unique tag=\"name\"/>\n" |
| " <min-elements value=\"10\"/>\n" |
| " <max-elements value=\"20\"/>\n" |
| " <leaf name=\"uid\">\n" |
| " <type name=\"int32\"/>\n" |
| " </leaf>\n" |
| " <leaf name=\"name\">\n" |
| " <type name=\"string\"/>\n" |
| " </leaf>\n" |
| " <leaf name=\"group\">\n" |
| " <type name=\"string\"/>\n" |
| " </leaf>\n" |
| " </list>\n"); |
| |
| UTEST_ADD_MODULE(schema_yin, LYS_IN_YIN, NULL, &mod); |
| assert_non_null(mod); |
| assert_int_equal(LY_SUCCESS, lys_print_mem(&printed, mod, LYS_OUT_YANG, 0)); |
| assert_string_equal(printed, schema_yang); |
| free(printed); |
| |
| /* test no segmentation fold due ignoring default value */ |
| schema_yang = MODULE_CREATE_YANG("PRINT2", "list user {" |
| "key uid;" |
| "leaf uid{type int32; default \"25\";}" |
| "leaf name{type string;}" |
| "leaf group{type string;}" |
| "}"); |
| |
| UTEST_ADD_MODULE(schema_yang, LYS_IN_YANG, NULL, &mod); |
| assert_non_null(mod); |
| assert_int_equal(LY_SUCCESS, lys_print_mem(&printed, mod, LYS_OUT_YIN, 0)); |
| free(printed); |
| } |
| |
| static void |
| test_xml(void **state) |
| { |
| struct lyd_node *tree; |
| const char *data, *schema; |
| struct lyd_node_inner *list_tree; |
| struct lyd_node_term *list_leaf; |
| |
| schema = MODULE_CREATE_YANG("T0", "list user {" |
| "key uid;" |
| "unique \"name group\";" |
| "leaf uid{type uint32;}" |
| "leaf name{type string;}" |
| "leaf group{type string;}" |
| "}"); |
| UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, NULL); |
| |
| /* add data */ |
| data = |
| "<user xmlns=\"urn:tests:T0\">" |
| " <uid>0</uid>" |
| " <name>Tomáš Novák</name>" |
| " <group>User</group>" |
| "</user>" |
| "<user xmlns=\"urn:tests:T0\">" |
| " <uid>1</uid>" |
| " <name>Martin Novák</name>" |
| " <group>User</group>" |
| "</user>"; |
| /* check first item */ |
| CHECK_PARSE_LYD_PARAM(data, LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_SUCCESS, tree); |
| list_tree = (void *)tree; |
| CHECK_LYD_NODE_INNER(list_tree, 1, 0, 0, 0, 1, 0, 0, 1); |
| list_leaf = (void *) list_tree->child; |
| assert_string_equal(list_leaf->schema->name, "uid"); |
| CHECK_LYD_NODE_TERM(list_leaf, 0, 0, 1, 1, 1, UINT32, "0", 0); |
| list_leaf = (void *) list_leaf->next; |
| assert_string_equal(list_leaf->schema->name, "name"); |
| CHECK_LYD_NODE_TERM(list_leaf, 0, 0, 1, 1, 1, STRING, "Tomáš Novák"); |
| list_leaf = (void *) list_leaf->next; |
| assert_string_equal(list_leaf->schema->name, "group"); |
| CHECK_LYD_NODE_TERM(list_leaf, 0, 0, 0, 1, 1, STRING, "User"); |
| /* check second item */ |
| list_tree = (void *) list_tree->next; |
| CHECK_LYD_NODE_INNER(list_tree, 1, 0, 0, 0, 0, 0, 0, 1); |
| list_leaf = (void *) list_tree->child; |
| assert_string_equal(list_leaf->schema->name, "uid"); |
| CHECK_LYD_NODE_TERM(list_leaf, 0, 0, 1, 1, 1, UINT32, "1", 1); |
| list_leaf = (void *) list_leaf->next; |
| assert_string_equal(list_leaf->schema->name, "name"); |
| CHECK_LYD_NODE_TERM(list_leaf, 0, 0, 1, 1, 1, STRING, "Martin Novák"); |
| list_leaf = (void *) list_leaf->next; |
| assert_string_equal(list_leaf->schema->name, "group"); |
| CHECK_LYD_NODE_TERM(list_leaf, 0, 0, 0, 1, 1, STRING, "User"); |
| lyd_free_all(tree); |
| |
| /* add data */ |
| data = |
| "<user xmlns=\"urn:tests:T0\">" |
| " <uid>0</uid>" |
| " <name>Tomáš Novák</name>" |
| " <group>User</group>" |
| "</user>" |
| "<user xmlns=\"urn:tests:T0\">" |
| " <uid>1</uid>" |
| " <name>Tomáš Novák</name>" |
| " <group>Admin</group>" |
| "</user>"; |
| /* check first item */ |
| CHECK_PARSE_LYD_PARAM(data, LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_SUCCESS, tree); |
| list_tree = (void *)tree; |
| CHECK_LYD_NODE_INNER(list_tree, 1, 0, 0, 0, 1, 0, 0, 1); |
| list_leaf = (void *) list_tree->child; |
| assert_string_equal(list_leaf->schema->name, "uid"); |
| CHECK_LYD_NODE_TERM(list_leaf, 0, 0, 1, 1, 1, UINT32, "0", 0); |
| list_leaf = (void *) list_leaf->next; |
| assert_string_equal(list_leaf->schema->name, "name"); |
| CHECK_LYD_NODE_TERM(list_leaf, 0, 0, 1, 1, 1, STRING, "Tomáš Novák"); |
| list_leaf = (void *) list_leaf->next; |
| assert_string_equal(list_leaf->schema->name, "group"); |
| CHECK_LYD_NODE_TERM(list_leaf, 0, 0, 0, 1, 1, STRING, "User"); |
| /* check second item */ |
| list_tree = (void *) list_tree->next; |
| CHECK_LYD_NODE_INNER(list_tree, 1, 0, 0, 0, 0, 0, 0, 1); |
| list_leaf = (void *) list_tree->child; |
| assert_string_equal(list_leaf->schema->name, "uid"); |
| CHECK_LYD_NODE_TERM(list_leaf, 0, 0, 1, 1, 1, UINT32, "1", 1); |
| list_leaf = (void *) list_leaf->next; |
| assert_string_equal(list_leaf->schema->name, "name"); |
| CHECK_LYD_NODE_TERM(list_leaf, 0, 0, 1, 1, 1, STRING, "Tomáš Novák"); |
| list_leaf = (void *) list_leaf->next; |
| assert_string_equal(list_leaf->schema->name, "group"); |
| CHECK_LYD_NODE_TERM(list_leaf, 0, 0, 0, 1, 1, STRING, "Admin"); |
| lyd_free_all(tree); |
| |
| data = |
| "<user xmlns=\"urn:tests:T0\">" |
| " <uid>0</uid>" |
| " <name>Tomáš Novák</name>" |
| " <group>User</group>" |
| "</user>" |
| "<user xmlns=\"urn:tests:T0\">" |
| " <uid>0</uid>" |
| " <name>Tomáš Novák</name>" |
| " <group>Admin</group>" |
| "</user>"; |
| /* check first item */ |
| CHECK_PARSE_LYD_PARAM(data, LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_EVALID, tree); |
| assert_null(tree); |
| CHECK_LOG_CTX("Duplicate instance of \"user\".", |
| "Schema location /T0:user, data location /T0:user[uid='0']."); |
| |
| data = |
| "<user xmlns=\"urn:tests:T0\">" |
| " <uid>0</uid>" |
| " <name>Tomáš Novák</name>" |
| " <group>User</group>" |
| "</user>" |
| "<user xmlns=\"urn:tests:T0\">" |
| " <uid>1</uid>" |
| " <name>Tomáš Novák</name>" |
| " <group>User</group>" |
| "</user>"; |
| /* check first item */ |
| CHECK_PARSE_LYD_PARAM(data, LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_EVALID, tree); |
| assert_null(tree); |
| CHECK_LOG_CTX("Unique data leaf(s) \"name group\" not satisfied in \"/T0:user[uid='0']\" and \"/T0:user[uid='1']\".", |
| "Schema location /T0:user, data location /T0:user[uid='1']."); |
| |
| /* double key */ |
| schema = MODULE_CREATE_YANG("T1", "list user {" |
| "key \"uid group\";" |
| "leaf uid{type uint32;}" |
| "leaf name{type string;}" |
| "leaf group{type string;}" |
| "}"); |
| UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, NULL); |
| data = |
| "<user xmlns=\"urn:tests:T1\">" |
| " <uid>0</uid>" |
| " <name>Tomáš Novák</name>" |
| " <group>User</group>" |
| "</user>" |
| "<user xmlns=\"urn:tests:T1\">" |
| " <uid>0</uid>" |
| " <name>Tomáš Novák</name>" |
| " <group>Admin</group>" |
| "</user>"; |
| /* check first item */ |
| CHECK_PARSE_LYD_PARAM(data, LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_SUCCESS, tree); |
| list_tree = (void *)tree; |
| CHECK_LYD_NODE_INNER(list_tree, 1, 0, 0, 0, 1, 0, 0, 1); |
| list_leaf = (void *) list_tree->child; |
| assert_string_equal(list_leaf->schema->name, "uid"); |
| CHECK_LYD_NODE_TERM(list_leaf, 0, 0, 1, 1, 1, UINT32, "0", 0); |
| list_leaf = (void *) list_leaf->next; |
| assert_string_equal(list_leaf->schema->name, "group"); |
| CHECK_LYD_NODE_TERM(list_leaf, 0, 0, 1, 1, 1, STRING, "User"); |
| list_leaf = (void *) list_leaf->next; |
| assert_string_equal(list_leaf->schema->name, "name"); |
| CHECK_LYD_NODE_TERM(list_leaf, 0, 0, 0, 1, 1, STRING, "Tomáš Novák"); |
| /* check second item */ |
| list_tree = (void *) list_tree->next; |
| CHECK_LYD_NODE_INNER(list_tree, 1, 0, 0, 0, 0, 0, 0, 1); |
| list_leaf = (void *) list_tree->child; |
| assert_string_equal(list_leaf->schema->name, "uid"); |
| CHECK_LYD_NODE_TERM(list_leaf, 0, 0, 1, 1, 1, UINT32, "0", 0); |
| list_leaf = (void *) list_leaf->next; |
| assert_string_equal(list_leaf->schema->name, "group"); |
| CHECK_LYD_NODE_TERM(list_leaf, 0, 0, 1, 1, 1, STRING, "Admin"); |
| list_leaf = (void *) list_leaf->next; |
| assert_string_equal(list_leaf->schema->name, "name"); |
| CHECK_LYD_NODE_TERM(list_leaf, 0, 0, 0, 1, 1, STRING, "Tomáš Novák"); |
| lyd_free_all(tree); |
| |
| data = |
| "<user xmlns=\"urn:tests:T1\">" |
| " <uid>0</uid>" |
| " <name>Tomáš Novák</name>" |
| " <group>User</group>" |
| "</user>" |
| "<user xmlns=\"urn:tests:T1\">" |
| " <uid>0</uid>" |
| " <name>Tomáš Novák</name>" |
| " <group>User</group>" |
| "</user>"; |
| /* check first item */ |
| CHECK_PARSE_LYD_PARAM(data, LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_EVALID, tree); |
| assert_null(tree); |
| CHECK_LOG_CTX("Duplicate instance of \"user\".", |
| "Schema location /T1:user, data location /T1:user[uid='0'][group='User']."); |
| |
| /* min elements max elements */ |
| schema = MODULE_CREATE_YANG("T2", |
| "list user {" |
| " key uid;" |
| " min-elements 3;" |
| " max-elements 5;" |
| " leaf uid{type uint32;}" |
| " leaf name{type string;}" |
| " leaf group{type string;}" |
| "}"); |
| UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, NULL); |
| data = |
| "<user xmlns=\"urn:tests:T2\">" |
| " <uid>0</uid>" |
| " <name>Tomáš Novák</name>" |
| " <group>User</group>" |
| "</user>" |
| "<user xmlns=\"urn:tests:T2\">" |
| " <uid>1</uid>" |
| " <name>Tomáš Novák</name>" |
| " <group>Admin</group>" |
| "</user>" |
| "<user xmlns=\"urn:tests:T2\">" |
| " <uid>2</uid>" |
| " <name>Tomáš Jak</name>" |
| " <group>Admin</group>" |
| "</user>"; |
| CHECK_PARSE_LYD_PARAM(data, LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_SUCCESS, tree); |
| list_tree = (void *)tree; |
| CHECK_LYD_NODE_INNER(list_tree, 1, 0, 0, 0, 1, 0, 0, 1); |
| list_leaf = (void *) list_tree->child; |
| assert_string_equal(list_leaf->schema->name, "uid"); |
| CHECK_LYD_NODE_TERM(list_leaf, 0, 0, 1, 1, 1, UINT32, "0", 0); |
| list_leaf = (void *) list_leaf->next; |
| assert_string_equal(list_leaf->schema->name, "name"); |
| CHECK_LYD_NODE_TERM(list_leaf, 0, 0, 1, 1, 1, STRING, "Tomáš Novák"); |
| list_leaf = (void *) list_leaf->next; |
| assert_string_equal(list_leaf->schema->name, "group"); |
| CHECK_LYD_NODE_TERM(list_leaf, 0, 0, 0, 1, 1, STRING, "User"); |
| /* check second item */ |
| list_tree = (void *) list_tree->next; |
| CHECK_LYD_NODE_INNER(list_tree, 1, 0, 0, 0, 1, 0, 0, 1); |
| list_leaf = (void *) list_tree->child; |
| assert_string_equal(list_leaf->schema->name, "uid"); |
| CHECK_LYD_NODE_TERM(list_leaf, 0, 0, 1, 1, 1, UINT32, "1", 1); |
| list_leaf = (void *) list_leaf->next; |
| assert_string_equal(list_leaf->schema->name, "name"); |
| CHECK_LYD_NODE_TERM(list_leaf, 0, 0, 1, 1, 1, STRING, "Tomáš Novák"); |
| list_leaf = (void *) list_leaf->next; |
| assert_string_equal(list_leaf->schema->name, "group"); |
| CHECK_LYD_NODE_TERM(list_leaf, 0, 0, 0, 1, 1, STRING, "Admin"); |
| /* check third item */ |
| list_tree = (void *) list_tree->next; |
| CHECK_LYD_NODE_INNER(list_tree, 1, 0, 0, 0, 0, 0, 0, 1); |
| list_leaf = (void *) list_tree->child; |
| assert_string_equal(list_leaf->schema->name, "uid"); |
| CHECK_LYD_NODE_TERM(list_leaf, 0, 0, 1, 1, 1, UINT32, "2", 2); |
| list_leaf = (void *) list_leaf->next; |
| assert_string_equal(list_leaf->schema->name, "name"); |
| CHECK_LYD_NODE_TERM(list_leaf, 0, 0, 1, 1, 1, STRING, "Tomáš Jak"); |
| list_leaf = (void *) list_leaf->next; |
| assert_string_equal(list_leaf->schema->name, "group"); |
| CHECK_LYD_NODE_TERM(list_leaf, 0, 0, 0, 1, 1, STRING, "Admin"); |
| lyd_free_all(tree); |
| |
| data = |
| "<user xmlns=\"urn:tests:T2\">" |
| " <uid>0</uid>" |
| " <name>Tomáš Novák</name>" |
| " <group>User</group>" |
| "</user>" |
| "<user xmlns=\"urn:tests:T2\">" |
| " <uid>1</uid>" |
| " <name>Tomáš Novák</name>" |
| " <group>Admin</group>" |
| "</user>" |
| "<user xmlns=\"urn:tests:T2\">" |
| " <uid>2</uid>" |
| " <name>Tomáš Novák</name>" |
| " <group>Admin</group>" |
| "</user>" |
| "<user xmlns=\"urn:tests:T2\">" |
| " <uid>3</uid>" |
| " <name>Tomáš Novák</name>" |
| " <group>Admin</group>" |
| "</user>" |
| "<user xmlns=\"urn:tests:T2\">" |
| " <uid>4</uid>" |
| " <name>Tomáš Novák</name>" |
| " <group>Admin</group>" |
| "</user>"; |
| CHECK_PARSE_LYD_PARAM(data, LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_SUCCESS, tree); |
| list_tree = (void *)tree; |
| CHECK_LYD_NODE_INNER(list_tree, 1, 0, 0, 0, 1, 0, 0, 1); |
| list_tree = (void *) list_tree->next; |
| CHECK_LYD_NODE_INNER(list_tree, 1, 0, 0, 0, 1, 0, 0, 1); |
| list_tree = (void *) list_tree->next; |
| CHECK_LYD_NODE_INNER(list_tree, 1, 0, 0, 0, 1, 0, 0, 1); |
| list_tree = (void *) list_tree->next; |
| CHECK_LYD_NODE_INNER(list_tree, 1, 0, 0, 0, 1, 0, 0, 1); |
| list_tree = (void *) list_tree->next; |
| CHECK_LYD_NODE_INNER(list_tree, 1, 0, 0, 0, 0, 0, 0, 1); |
| lyd_free_all(tree); |
| |
| /* check wrong number of items */ |
| data = |
| "<user xmlns=\"urn:tests:T2\">" |
| " <uid>0</uid>" |
| " <name>Tomáš Novák</name>" |
| " <group>User</group>" |
| "</user>" |
| "<user xmlns=\"urn:tests:T2\">" |
| " <uid>1</uid>" |
| " <name>Tomáš Novák</name>" |
| " <group>Admin</group>" |
| "</user>"; |
| CHECK_PARSE_LYD_PARAM(data, LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_EVALID, tree); |
| assert_null(tree); |
| CHECK_LOG_CTX("Too few \"user\" instances.", |
| "Schema location /T2:user."); |
| |
| data = |
| "<user xmlns=\"urn:tests:T2\">" |
| " <uid>0</uid>" |
| " <name>Tomáš Novák</name>" |
| " <group>User</group>" |
| "</user>" |
| "<user xmlns=\"urn:tests:T2\">" |
| " <uid>1</uid>" |
| " <name>Tomáš Novák</name>" |
| " <group>Admin</group>" |
| "</user>" |
| "<user xmlns=\"urn:tests:T2\">" |
| " <uid>2</uid>" |
| " <name>Tomáš Novák</name>" |
| " <group>Admin</group>" |
| "</user>" |
| "<user xmlns=\"urn:tests:T2\">" |
| " <uid>3</uid>" |
| " <name>Tomáš Novák</name>" |
| " <group>Admin</group>" |
| "</user>" |
| "<user xmlns=\"urn:tests:T2\">" |
| " <uid>4</uid>" |
| " <name>Tomáš Novák</name>" |
| " <group>Admin</group>" |
| "</user>" |
| "<user xmlns=\"urn:tests:T2\">" |
| " <uid>5</uid>" |
| " <name>Tomáš Novák</name>" |
| " <group>Admin</group>" |
| "</user>"; |
| CHECK_PARSE_LYD_PARAM(data, LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_EVALID, tree); |
| assert_null(tree); |
| CHECK_LOG_CTX("Too many \"user\" instances.", |
| "Schema location /T2:user, data location /T2:user[uid='5']."); |
| |
| /* empty list */ |
| schema = MODULE_CREATE_YANG("T_EMPTY_LIST", |
| "container user_list {" |
| " list user {" |
| " key uid;" |
| " unique \"name group\";" |
| " leaf uid{type uint32;}" |
| " leaf name{type string;}" |
| " leaf group{type string;}" |
| "}" |
| "}"); |
| UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, NULL); |
| |
| /* empty list */ |
| data = "<user_list xmlns=\"urn:tests:T_EMPTY_LIST\"/>"; |
| /* check first item */ |
| CHECK_PARSE_LYD_PARAM(data, LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_SUCCESS, tree); |
| list_tree = (void *)tree; |
| CHECK_LYD_NODE_INNER(list_tree, 0, 0, 0, 1, 0, 0, 0, 1); |
| lyd_free_all(tree); |
| } |
| |
| static void |
| test_json(void **state) |
| { |
| struct lyd_node *tree; |
| const char *data, *schema; |
| struct lyd_node_inner *list_tree; |
| struct lyd_node_term *list_leaf; |
| |
| schema = MODULE_CREATE_YANG("T0", "list user {" |
| "key uid;" |
| "unique \"name group\";" |
| "leaf uid{type uint32;}" |
| "leaf name{type string;}" |
| "leaf group{type string;}" |
| "}"); |
| UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, NULL); |
| |
| /* add data */ |
| data = |
| "{\"T0:user\": [" |
| " {\"uid\":0, \"name\":\"Jan Kuba\", \"group\":\"User\"}," |
| " {\"uid\":1, \"name\":\"Martin Novák\", \"group\":\"User\"}" |
| "]}"; |
| |
| CHECK_PARSE_LYD_PARAM(data, LYD_JSON, 0, LYD_VALIDATE_PRESENT, LY_SUCCESS, tree); |
| list_tree = (void *)tree; |
| CHECK_LYD_NODE_INNER(list_tree, 1, 0, 0, 0, 1, 0, 0, 1); |
| list_leaf = (void *) list_tree->child; |
| assert_string_equal(list_leaf->schema->name, "uid"); |
| CHECK_LYD_NODE_TERM(list_leaf, 0, 0, 1, 1, 1, UINT32, "0", 0); |
| list_leaf = (void *) list_leaf->next; |
| assert_string_equal(list_leaf->schema->name, "name"); |
| CHECK_LYD_NODE_TERM(list_leaf, 0, 0, 1, 1, 1, STRING, "Jan Kuba"); |
| list_leaf = (void *) list_leaf->next; |
| assert_string_equal(list_leaf->schema->name, "group"); |
| CHECK_LYD_NODE_TERM(list_leaf, 0, 0, 0, 1, 1, STRING, "User"); |
| /* check second item */ |
| list_tree = (void *) list_tree->next; |
| CHECK_LYD_NODE_INNER(list_tree, 1, 0, 0, 0, 0, 0, 0, 1); |
| list_leaf = (void *) list_tree->child; |
| assert_string_equal(list_leaf->schema->name, "uid"); |
| CHECK_LYD_NODE_TERM(list_leaf, 0, 0, 1, 1, 1, UINT32, "1", 1); |
| list_leaf = (void *) list_leaf->next; |
| assert_string_equal(list_leaf->schema->name, "name"); |
| CHECK_LYD_NODE_TERM(list_leaf, 0, 0, 1, 1, 1, STRING, "Martin Novák"); |
| list_leaf = (void *) list_leaf->next; |
| assert_string_equal(list_leaf->schema->name, "group"); |
| CHECK_LYD_NODE_TERM(list_leaf, 0, 0, 0, 1, 1, STRING, "User"); |
| lyd_free_all(tree); |
| |
| /* Unique */ |
| data = |
| "{\"T0:user\": [" |
| " {\"uid\":0, \"name\":\"Jan Kuba\", \"group\":\"User\"}," |
| " {\"uid\":1, \"name\":\"Jan Kuba\", \"group\":\"Admin\"}" |
| "]}"; |
| |
| /* check first item */ |
| CHECK_PARSE_LYD_PARAM(data, LYD_JSON, 0, LYD_VALIDATE_PRESENT, LY_SUCCESS, tree); |
| list_tree = (void *)tree; |
| CHECK_LYD_NODE_INNER(list_tree, 1, 0, 0, 0, 1, 0, 0, 1); |
| list_leaf = (void *) list_tree->child; |
| assert_string_equal(list_leaf->schema->name, "uid"); |
| CHECK_LYD_NODE_TERM(list_leaf, 0, 0, 1, 1, 1, UINT32, "0", 0); |
| list_leaf = (void *) list_leaf->next; |
| assert_string_equal(list_leaf->schema->name, "name"); |
| CHECK_LYD_NODE_TERM(list_leaf, 0, 0, 1, 1, 1, STRING, "Jan Kuba"); |
| list_leaf = (void *) list_leaf->next; |
| assert_string_equal(list_leaf->schema->name, "group"); |
| CHECK_LYD_NODE_TERM(list_leaf, 0, 0, 0, 1, 1, STRING, "User"); |
| /* check second item */ |
| list_tree = (void *) list_tree->next; |
| CHECK_LYD_NODE_INNER(list_tree, 1, 0, 0, 0, 0, 0, 0, 1); |
| list_leaf = (void *) list_tree->child; |
| assert_string_equal(list_leaf->schema->name, "uid"); |
| CHECK_LYD_NODE_TERM(list_leaf, 0, 0, 1, 1, 1, UINT32, "1", 1); |
| list_leaf = (void *) list_leaf->next; |
| assert_string_equal(list_leaf->schema->name, "name"); |
| CHECK_LYD_NODE_TERM(list_leaf, 0, 0, 1, 1, 1, STRING, "Jan Kuba"); |
| list_leaf = (void *) list_leaf->next; |
| assert_string_equal(list_leaf->schema->name, "group"); |
| CHECK_LYD_NODE_TERM(list_leaf, 0, 0, 0, 1, 1, STRING, "Admin"); |
| lyd_free_all(tree); |
| |
| data = |
| "{\"T0:user\": [" |
| " {\"uid\":0, \"name\":\"Jan Kuba\", \"group\":\"User\"}," |
| " {\"uid\":0, \"name\":\"Jan Kuba\", \"group\":\"Admin\"}" |
| "]}"; |
| CHECK_PARSE_LYD_PARAM(data, LYD_JSON, 0, LYD_VALIDATE_PRESENT, LY_EVALID, tree); |
| assert_null(tree); |
| CHECK_LOG_CTX("Duplicate instance of \"user\".", |
| "Schema location /T0:user, data location /T0:user[uid='0'], line number 1."); |
| |
| data = |
| "{\"T0:user\": [" |
| " {\"uid\":0, \"name\":\"Jan Kuba\", \"group\":\"User\"}," |
| " {\"uid\":1, \"name\":\"Jan Kuba\", \"group\":\"User\"}" |
| "]}"; |
| CHECK_PARSE_LYD_PARAM(data, LYD_JSON, 0, LYD_VALIDATE_PRESENT, LY_EVALID, tree); |
| assert_null(tree); |
| CHECK_LOG_CTX("Unique data leaf(s) \"name group\" not satisfied in \"/T0:user[uid='0']\" and \"/T0:user[uid='1']\".", |
| "Schema location /T0:user, data location /T0:user[uid='1'], line number 1."); |
| |
| /* double key */ |
| schema = MODULE_CREATE_YANG("T1", "list user {" |
| "key \"uid group\";" |
| "leaf uid{type uint32;}" |
| "leaf name{type string;}" |
| "leaf group{type string;}" |
| "}"); |
| UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, NULL); |
| data = |
| "{\"T1:user\": [" |
| " {\"uid\":0, \"name\":\"Jan Kuba\", \"group\":\"User\"}," |
| " {\"uid\":0, \"name\":\"Jan Kuba\", \"group\":\"Admin\"}" |
| "]}"; |
| CHECK_PARSE_LYD_PARAM(data, LYD_JSON, 0, LYD_VALIDATE_PRESENT, LY_SUCCESS, tree); |
| list_tree = (void *)tree; |
| CHECK_LYD_NODE_INNER(list_tree, 1, 0, 0, 0, 1, 0, 0, 1); |
| list_leaf = (void *) list_tree->child; |
| assert_string_equal(list_leaf->schema->name, "uid"); |
| CHECK_LYD_NODE_TERM(list_leaf, 0, 0, 1, 1, 1, UINT32, "0", 0); |
| list_leaf = (void *) list_leaf->next; |
| assert_string_equal(list_leaf->schema->name, "group"); |
| CHECK_LYD_NODE_TERM(list_leaf, 0, 0, 1, 1, 1, STRING, "User"); |
| list_leaf = (void *) list_leaf->next; |
| assert_string_equal(list_leaf->schema->name, "name"); |
| CHECK_LYD_NODE_TERM(list_leaf, 0, 0, 0, 1, 1, STRING, "Jan Kuba"); |
| /* check second item */ |
| list_tree = (void *) list_tree->next; |
| CHECK_LYD_NODE_INNER(list_tree, 1, 0, 0, 0, 0, 0, 0, 1); |
| list_leaf = (void *) list_tree->child; |
| assert_string_equal(list_leaf->schema->name, "uid"); |
| CHECK_LYD_NODE_TERM(list_leaf, 0, 0, 1, 1, 1, UINT32, "0", 0); |
| list_leaf = (void *) list_leaf->next; |
| assert_string_equal(list_leaf->schema->name, "group"); |
| CHECK_LYD_NODE_TERM(list_leaf, 0, 0, 1, 1, 1, STRING, "Admin"); |
| list_leaf = (void *) list_leaf->next; |
| assert_string_equal(list_leaf->schema->name, "name"); |
| CHECK_LYD_NODE_TERM(list_leaf, 0, 0, 0, 1, 1, STRING, "Jan Kuba"); |
| lyd_free_all(tree); |
| |
| data = |
| "{\"T1:user\": [" |
| " {\"uid\":0, \"name\":\"Jan Kuba\", \"group\":\"User\"}," |
| " {\"uid\":0, \"name\":\"Jan Kuba\", \"group\":\"User\"}" |
| "]}"; |
| /* check first item */ |
| CHECK_PARSE_LYD_PARAM(data, LYD_JSON, 0, LYD_VALIDATE_PRESENT, LY_EVALID, tree); |
| assert_null(tree); |
| CHECK_LOG_CTX("Duplicate instance of \"user\".", |
| "Schema location /T1:user, data location /T1:user[uid='0'][group='User'], line number 1."); |
| |
| /* min elements max elements */ |
| schema = MODULE_CREATE_YANG("T2", |
| "list user {" |
| " key uid;" |
| " min-elements 3;" |
| " max-elements 5;" |
| " leaf uid{type uint32;}" |
| " leaf name{type string;}" |
| " leaf group{type string;}" |
| "}"); |
| UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, NULL); |
| data = |
| "{\"T2:user\": [" |
| " {\"uid\":0, \"name\":\"Jan Kuba\", \"group\":\"User\"}," |
| " {\"uid\":1, \"name\":\"Antonín Kuba\", \"group\":\"User\"}," |
| " {\"uid\":2, \"name\":\"Tomáš Novák\", \"group\":\"Admin\"}" |
| "]}"; |
| |
| CHECK_PARSE_LYD_PARAM(data, LYD_JSON, 0, LYD_VALIDATE_PRESENT, LY_SUCCESS, tree); |
| list_tree = (void *)tree; |
| CHECK_LYD_NODE_INNER(list_tree, 1, 0, 0, 0, 1, 0, 0, 1); |
| list_leaf = (void *) list_tree->child; |
| assert_string_equal(list_leaf->schema->name, "uid"); |
| CHECK_LYD_NODE_TERM(list_leaf, 0, 0, 1, 1, 1, UINT32, "0", 0); |
| list_leaf = (void *) list_leaf->next; |
| assert_string_equal(list_leaf->schema->name, "name"); |
| CHECK_LYD_NODE_TERM(list_leaf, 0, 0, 1, 1, 1, STRING, "Jan Kuba"); |
| list_leaf = (void *) list_leaf->next; |
| assert_string_equal(list_leaf->schema->name, "group"); |
| CHECK_LYD_NODE_TERM(list_leaf, 0, 0, 0, 1, 1, STRING, "User"); |
| /* check second item */ |
| list_tree = (void *) list_tree->next; |
| CHECK_LYD_NODE_INNER(list_tree, 1, 0, 0, 0, 1, 0, 0, 1); |
| list_leaf = (void *) list_tree->child; |
| assert_string_equal(list_leaf->schema->name, "uid"); |
| CHECK_LYD_NODE_TERM(list_leaf, 0, 0, 1, 1, 1, UINT32, "1", 1); |
| list_leaf = (void *) list_leaf->next; |
| assert_string_equal(list_leaf->schema->name, "name"); |
| CHECK_LYD_NODE_TERM(list_leaf, 0, 0, 1, 1, 1, STRING, "Antonín Kuba"); |
| list_leaf = (void *) list_leaf->next; |
| assert_string_equal(list_leaf->schema->name, "group"); |
| CHECK_LYD_NODE_TERM(list_leaf, 0, 0, 0, 1, 1, STRING, "User"); |
| /* check third item */ |
| list_tree = (void *) list_tree->next; |
| CHECK_LYD_NODE_INNER(list_tree, 1, 0, 0, 0, 0, 0, 0, 1); |
| list_leaf = (void *) list_tree->child; |
| assert_string_equal(list_leaf->schema->name, "uid"); |
| CHECK_LYD_NODE_TERM(list_leaf, 0, 0, 1, 1, 1, UINT32, "2", 2); |
| list_leaf = (void *) list_leaf->next; |
| assert_string_equal(list_leaf->schema->name, "name"); |
| CHECK_LYD_NODE_TERM(list_leaf, 0, 0, 1, 1, 1, STRING, "Tomáš Novák"); |
| list_leaf = (void *) list_leaf->next; |
| assert_string_equal(list_leaf->schema->name, "group"); |
| CHECK_LYD_NODE_TERM(list_leaf, 0, 0, 0, 1, 1, STRING, "Admin"); |
| lyd_free_all(tree); |
| |
| data = |
| "{\"T2:user\": [" |
| " {\"uid\":0, \"name\":\"Jan Kuba\", \"group\":\"User\"}," |
| " {\"uid\":1, \"name\":\"Antonín Kuba\", \"group\":\"User\"}," |
| " {\"uid\":2, \"name\":\"Antonín Kuba\", \"group\":\"User\"}," |
| " {\"uid\":3, \"name\":\"Antonín Kuba\", \"group\":\"User\"}," |
| " {\"uid\":4, \"name\":\"Tomáš Novák\", \"group\":\"Admin\"}" |
| "]}"; |
| CHECK_PARSE_LYD_PARAM(data, LYD_JSON, 0, LYD_VALIDATE_PRESENT, LY_SUCCESS, tree); |
| list_tree = (void *)tree; |
| CHECK_LYD_NODE_INNER(list_tree, 1, 0, 0, 0, 1, 0, 0, 1); |
| list_tree = (void *) list_tree->next; |
| CHECK_LYD_NODE_INNER(list_tree, 1, 0, 0, 0, 1, 0, 0, 1); |
| list_tree = (void *) list_tree->next; |
| CHECK_LYD_NODE_INNER(list_tree, 1, 0, 0, 0, 1, 0, 0, 1); |
| list_tree = (void *) list_tree->next; |
| CHECK_LYD_NODE_INNER(list_tree, 1, 0, 0, 0, 1, 0, 0, 1); |
| list_tree = (void *) list_tree->next; |
| CHECK_LYD_NODE_INNER(list_tree, 1, 0, 0, 0, 0, 0, 0, 1); |
| lyd_free_all(tree); |
| |
| /* check wrong number of items */ |
| data = |
| "{\"T2:user\": [" |
| " {\"uid\":0, \"name\":\"Jan Kuba\", \"group\":\"User\"}," |
| " {\"uid\":4, \"name\":\"Tomáš Novák\", \"group\":\"Admin\"}" |
| "]}"; |
| CHECK_PARSE_LYD_PARAM(data, LYD_JSON, 0, LYD_VALIDATE_PRESENT, LY_EVALID, tree); |
| assert_null(tree); |
| CHECK_LOG_CTX("Too few \"user\" instances.", |
| "Schema location /T2:user, line number 1."); |
| |
| data = |
| "{\"T2:user\": [" |
| " {\"uid\":0, \"name\":\"Jan Kuba\", \"group\":\"User\"}," |
| " {\"uid\":1, \"name\":\"Antonín Kuba\", \"group\":\"User\"}," |
| " {\"uid\":2, \"name\":\"Antonín Kuba\", \"group\":\"User\"}," |
| " {\"uid\":3, \"name\":\"Antonín Kuba\", \"group\":\"User\"}," |
| " {\"uid\":4, \"name\":\"Tomáš Novák\", \"group\":\"Admin\"}," |
| " {\"uid\":5, \"name\":\"Tomáš Novák\", \"group\":\"Admin\"}" |
| "]}"; |
| CHECK_PARSE_LYD_PARAM(data, LYD_JSON, 0, LYD_VALIDATE_PRESENT, LY_EVALID, tree); |
| assert_null(tree); |
| CHECK_LOG_CTX("Too many \"user\" instances.", |
| "Schema location /T2:user, data location /T2:user[uid='5'], line number 1."); |
| |
| schema = MODULE_CREATE_YANG("T_EMPTY_LIST", |
| "container user_list {" |
| " list user {" |
| " key uid;" |
| " unique \"name group\";" |
| " leaf uid{type uint32;}" |
| " leaf name{type string;}" |
| " leaf group{type string;}" |
| "}" |
| "}"); |
| UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, NULL); |
| |
| /* empty list */ |
| data = |
| "{\"T_EMPTY_LIST:user_list\": {}" |
| "}"; |
| |
| /* check first item */ |
| CHECK_PARSE_LYD_PARAM(data, LYD_JSON, 0, LYD_VALIDATE_PRESENT, LY_SUCCESS, tree); |
| list_tree = (void *)tree; |
| CHECK_LYD_NODE_INNER(list_tree, 0, 0, 0, 1, 0, 0, 0, 1); |
| lyd_free_all(tree); |
| } |
| |
| static void |
| test_diff(void **state) |
| { |
| const char *schema; |
| struct lyd_node *model_1, *model_2; |
| struct lyd_node *diff; |
| const char *data_1; |
| const char *data_2; |
| const char *diff_expected; |
| |
| schema = MODULE_CREATE_YANG("T0", "list user {" |
| "key uid;" |
| "unique \"name group\";" |
| "leaf uid{type uint32;}" |
| "leaf name{type string;}" |
| "leaf group{type string;}" |
| "}"); |
| UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, NULL); |
| |
| /* delete item */ |
| data_1 = |
| "<user xmlns=\"urn:tests:T0\">" |
| " <uid>0</uid>" |
| " <name>Tomáš Novák</name>" |
| " <group>User</group>" |
| "</user>" |
| "<user xmlns=\"urn:tests:T0\">" |
| " <uid>1</uid>" |
| " <name>Martin Novák</name>" |
| " <group>User</group>" |
| "</user>"; |
| |
| data_2 = |
| "<user xmlns=\"urn:tests:T0\">" |
| " <uid>0</uid>" |
| " <name>Tomáš Novák</name>" |
| " <group>User</group>" |
| "</user>"; |
| |
| diff_expected = |
| "<user xmlns=\"urn:tests:T0\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\"" |
| " yang:operation=\"delete\">" |
| "<uid>1</uid>" |
| "<name>Martin Novák</name>" |
| "<group>User</group>" |
| "</user>"; |
| CHECK_PARSE_LYD_PARAM(data_1, LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_SUCCESS, model_1); |
| CHECK_PARSE_LYD_PARAM(data_2, LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_SUCCESS, model_2); |
| assert_int_equal(LY_SUCCESS, lyd_diff_siblings(model_1, model_2, 0, &diff)); |
| assert_non_null(diff); |
| CHECK_LYD_STRING_PARAM(diff, diff_expected, LYD_XML, LYD_PRINT_WITHSIBLINGS | LYD_PRINT_SHRINK); |
| assert_int_equal(LY_SUCCESS, lyd_diff_apply_all(&model_1, diff)); |
| CHECK_LYD(model_1, model_2); |
| lyd_free_all(model_1); |
| lyd_free_all(model_2); |
| lyd_free_all(diff); |
| |
| /* add item */ |
| data_1 = |
| "<user xmlns=\"urn:tests:T0\">" |
| " <uid>0</uid>" |
| " <name>Tomáš Novák</name>" |
| " <group>User</group>" |
| "</user>"; |
| |
| data_2 = |
| "<user xmlns=\"urn:tests:T0\">" |
| " <uid>0</uid>" |
| " <name>Tomáš Novák</name>" |
| " <group>User</group>" |
| "</user>" |
| "<user xmlns=\"urn:tests:T0\">" |
| " <uid>1</uid>" |
| " <name>Martin Novák</name>" |
| " <group>User</group>" |
| "</user>"; |
| |
| diff_expected = |
| "<user xmlns=\"urn:tests:T0\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\"" |
| " yang:operation=\"create\">" |
| "<uid>1</uid><name>Martin Novák</name><group>User</group>" |
| "</user>"; |
| CHECK_PARSE_LYD_PARAM(data_1, LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_SUCCESS, model_1); |
| CHECK_PARSE_LYD_PARAM(data_2, LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_SUCCESS, model_2); |
| assert_int_equal(LY_SUCCESS, lyd_diff_siblings(model_1, model_2, 0, &diff)); |
| assert_non_null(diff); |
| CHECK_LYD_STRING_PARAM(diff, diff_expected, LYD_XML, LYD_PRINT_WITHSIBLINGS | LYD_PRINT_SHRINK); |
| assert_int_equal(LY_SUCCESS, lyd_diff_apply_all(&model_1, diff)); |
| CHECK_LYD(model_1, model_2); |
| lyd_free_all(model_1); |
| lyd_free_all(model_2); |
| lyd_free_all(diff); |
| |
| /* diff one */ |
| data_1 = |
| "<user xmlns=\"urn:tests:T0\">" |
| " <uid>0</uid>" |
| " <name>Tomáš Novák</name>" |
| " <group>User</group>" |
| "</user>" |
| "<user xmlns=\"urn:tests:T0\">" |
| " <uid>1</uid>" |
| " <name>Martin Novák</name>" |
| " <group>User</group>" |
| "</user>"; |
| |
| data_2 = |
| "<user xmlns=\"urn:tests:T0\">" |
| " <uid>0</uid>" |
| " <name>Tomáš Novák</name>" |
| " <group>Admin</group>" |
| "</user>" |
| "<user xmlns=\"urn:tests:T0\">" |
| " <uid>1</uid>" |
| " <name>Martin Novák</name>" |
| " <group>User</group>" |
| "</user>"; |
| |
| diff_expected = |
| "<user xmlns=\"urn:tests:T0\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\"" |
| " yang:operation=\"none\">" |
| "<uid>0</uid>" |
| "<group yang:operation=\"replace\" yang:orig-default=\"false\"" |
| " yang:orig-value=\"User\">Admin</group></user>"; |
| CHECK_PARSE_LYD_PARAM(data_1, LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_SUCCESS, model_1); |
| CHECK_PARSE_LYD_PARAM(data_2, LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_SUCCESS, model_2); |
| assert_int_equal(LY_SUCCESS, lyd_diff_siblings(model_1, model_2, 0, &diff)); |
| assert_non_null(diff); |
| CHECK_LYD_STRING_PARAM(diff, diff_expected, LYD_XML, LYD_PRINT_WITHSIBLINGS | LYD_PRINT_SHRINK); |
| assert_int_equal(LY_SUCCESS, lyd_diff_apply_all(&model_1, diff)); |
| CHECK_LYD(model_1, model_2); |
| lyd_free_all(model_1); |
| lyd_free_all(model_2); |
| lyd_free_all(diff); |
| |
| /* diff same */ |
| data_1 = |
| "<user xmlns=\"urn:tests:T0\">" |
| " <uid>0</uid>" |
| " <name>Tomáš Novák</name>" |
| " <group>User</group>" |
| "</user>" |
| "<user xmlns=\"urn:tests:T0\">" |
| " <uid>1</uid>" |
| " <name>Martin Novák</name>" |
| " <group>User</group>" |
| "</user>"; |
| |
| data_2 = |
| "<user xmlns=\"urn:tests:T0\">" |
| " <uid>0</uid>" |
| " <name>Tomáš Novák</name>" |
| " <group>User</group>" |
| "</user>" |
| "<user xmlns=\"urn:tests:T0\">" |
| " <uid>1</uid>" |
| " <name>Martin Novák</name>" |
| " <group>User</group>" |
| "</user>"; |
| |
| CHECK_PARSE_LYD_PARAM(data_1, LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_SUCCESS, model_1); |
| CHECK_PARSE_LYD_PARAM(data_2, LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_SUCCESS, model_2); |
| assert_int_equal(LY_SUCCESS, lyd_diff_siblings(model_1, model_2, 0, &diff)); |
| assert_null(diff); |
| assert_int_equal(LY_SUCCESS, lyd_diff_apply_all(&model_1, diff)); |
| CHECK_LYD(model_1, model_2); |
| lyd_free_all(model_1); |
| lyd_free_all(model_2); |
| lyd_free_all(diff); |
| } |
| |
| static void |
| test_print(void **state) |
| { |
| |
| const char *schema; |
| const char *expected_string; |
| |
| schema = MODULE_CREATE_YANG("T0", |
| "list user {" |
| "key uid;" |
| "leaf uid{type uint32;}" |
| "leaf name{type string;}" |
| "leaf group{type string; default \"User\";}" |
| "}"); |
| UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, NULL); |
| |
| struct lyd_node *model_1; |
| const char *data_1 = |
| "<user xmlns=\"urn:tests:T0\">" |
| " <uid>0</uid>" |
| " <name>Tomáš Novák</name>" |
| "</user>" |
| "<user xmlns=\"urn:tests:T0\">" |
| " <uid>1</uid>" |
| " <name>Martin Novák</name>" |
| " <group>Admin</group>" |
| "</user>"; |
| |
| LYD_TREE_CREATE(data_1, model_1); |
| |
| /* XML */ |
| expected_string = |
| "<user xmlns=\"urn:tests:T0\">" |
| "<uid>0</uid><name>Tomáš Novák</name>" |
| "</user>" |
| "<user xmlns=\"urn:tests:T0\">" |
| "<uid>1</uid><name>Martin Novák</name><group>Admin</group>" |
| "</user>"; |
| CHECK_LYD_STRING_PARAM(model_1, expected_string, LYD_XML, LYD_PRINT_SHRINK | LYD_PRINT_WITHSIBLINGS | LYD_PRINT_SHRINK); |
| |
| /* JSON */ |
| expected_string = "{\"T0:user\":[" |
| "{\"uid\":0,\"name\":\"Tomáš Novák\"}," |
| "{\"uid\":1,\"name\":\"Martin Novák\",\"group\":\"Admin\"}" |
| "]}"; |
| CHECK_LYD_STRING_PARAM(model_1, expected_string, LYD_JSON, LYD_PRINT_SHRINK | LYD_PRINT_WITHSIBLINGS | LYD_PRINT_SHRINK); |
| |
| lyd_free_all(model_1); |
| } |
| |
| int |
| main(void) |
| { |
| const struct CMUnitTest tests[] = { |
| UTEST(test_schema_yang), |
| UTEST(test_schema_yin), |
| UTEST(test_schema_print), |
| |
| UTEST(test_xml), |
| UTEST(test_json), |
| UTEST(test_diff), |
| UTEST(test_print), |
| }; |
| |
| return cmocka_run_group_tests(tests, NULL, NULL); |
| } |