From cd07912073c951b4bbb871ed2653af1be2cfc714 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 28 Apr 2024 11:55:11 +0200 Subject: Adding upstream version 2.1.30. Signed-off-by: Daniel Baumann --- tests/utests/node/list.c | 1632 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1632 insertions(+) create mode 100644 tests/utests/node/list.c (limited to 'tests/utests/node/list.c') diff --git a/tests/utests/node/list.c b/tests/utests/node/list.c new file mode 100644 index 0000000..8b14ece --- /dev/null +++ b/tests/utests/node/list.c @@ -0,0 +1,1632 @@ +/** + * @file list.c + * @author Radek Iša + * @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 + +/* 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) \ + "\n" \ + "\n" \ + " \n" \ + " \n" \ + " \n" \ + NODES \ + "\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", "" + " " + " " + " " + " " + " " + ""); + 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", "" + " " + " " + " " + " " + ""); + UTEST_INVALID_MODULE(schema, LYS_IN_YIN, NULL, LY_EVALID); + CHECK_LOG_CTX("The list's key \"u " + " " + " " + " " + " " + " " + " " + " " + " " + ""); + 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", "" + "" + " " + "" + " " + " " + "" + ""); + 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", + "" + " " + " " + " " + " " + " " + " " + " " + ""); + 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", + "" + " " + " " + " " + " " + " " + ""); + 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", + "" + " " + " " + " " + " " + " " + " " + " " + ""); + 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", + "" + " " + " " + " " + " " + ""); + 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 8."); + + schema = MODULE_CREATE_YIN("TERR_0", + "" + " " + " " + " " + " " + " " + " " + ""); + 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 8."); + + schema = MODULE_CREATE_YIN("TERR_0", + "" + " " + " " + " " + " " + " " + " " + ""); + 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 8."); + + schema = MODULE_CREATE_YIN("TERR_0", + "" + " " + " " + " " + " " + " " + " " + ""); + 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 8."); + + schema = MODULE_CREATE_YIN("TERR_0", + "" + " " + " " + " " + " " + " " + ""); + 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 8."); + + schema = MODULE_CREATE_YIN("T6", + "" + " " + " " + " " + " " + ""); + 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", + "" + " " + " " + " " + " " + " " + " " + ""); + 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", + "" + " " + " " + " " + " " + " " + " " + ""); + 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", + "" + " " + " " + " " + " " + " " + " " + ""); + 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 8."); + + schema = MODULE_CREATE_YIN("T_DEFS1", + "" + " " + " " + " " + " " + " " + " " + ""); + 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", + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \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", + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \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 = + "" + " 0" + " Tomáš Novák" + " User" + "" + "" + " 1" + " Martin Novák" + " 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 = + "" + " 0" + " Tomáš Novák" + " User" + "" + "" + " 1" + " Tomáš Novák" + " Admin" + ""; + /* 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 = + "" + " 0" + " Tomáš Novák" + " User" + "" + "" + " 0" + " Tomáš Novák" + " Admin" + ""; + /* 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\".", + "Data location \"/T0:user[uid='0']\"."); + + data = + "" + " 0" + " Tomáš Novák" + " User" + "" + "" + " 1" + " Tomáš Novák" + " 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']\".", + "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 = + "" + " 0" + " Tomáš Novák" + " User" + "" + "" + " 0" + " Tomáš Novák" + " Admin" + ""; + /* 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 = + "" + " 0" + " Tomáš Novák" + " User" + "" + "" + " 0" + " Tomáš Novák" + " 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\".", + "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 = + "" + " 0" + " Tomáš Novák" + " User" + "" + "" + " 1" + " Tomáš Novák" + " Admin" + "" + "" + " 2" + " Tomáš Jak" + " Admin" + ""; + 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 = + "" + " 0" + " Tomáš Novák" + " User" + "" + "" + " 1" + " Tomáš Novák" + " Admin" + "" + "" + " 2" + " Tomáš Novák" + " Admin" + "" + "" + " 3" + " Tomáš Novák" + " Admin" + "" + "" + " 4" + " Tomáš Novák" + " Admin" + ""; + 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 = + "" + " 0" + " Tomáš Novák" + " User" + "" + "" + " 1" + " Tomáš Novák" + " Admin" + ""; + 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 = + "" + " 0" + " Tomáš Novák" + " User" + "" + "" + " 1" + " Tomáš Novák" + " Admin" + "" + "" + " 2" + " Tomáš Novák" + " Admin" + "" + "" + " 3" + " Tomáš Novák" + " Admin" + "" + "" + " 4" + " Tomáš Novák" + " Admin" + "" + "" + " 5" + " Tomáš Novák" + " Admin" + ""; + CHECK_PARSE_LYD_PARAM(data, LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_EVALID, tree); + assert_null(tree); + CHECK_LOG_CTX("Too many \"user\" instances.", + "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 = ""; + /* 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\".", + "Data location \"/T0:user[uid='0']\"."); + + 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']\".", + "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 = + "{\"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\".", + "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 = + "{\"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\"."); + + 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.", + "Data location \"/T2:user[uid='5']\"."); + + 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 = + "" + " 0" + " Tomáš Novák" + " User" + "" + "" + " 1" + " Martin Novák" + " User" + ""; + + data_2 = + "" + " 0" + " Tomáš Novák" + " User" + ""; + + diff_expected = + "" + "1" + "Martin Novák" + "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 = + "" + " 0" + " Tomáš Novák" + " User" + ""; + + data_2 = + "" + " 0" + " Tomáš Novák" + " User" + "" + "" + " 1" + " Martin Novák" + " User" + ""; + + diff_expected = + "" + "1Martin NovákUser" + ""; + 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 = + "" + " 0" + " Tomáš Novák" + " User" + "" + "" + " 1" + " Martin Novák" + " User" + ""; + + data_2 = + "" + " 0" + " Tomáš Novák" + " Admin" + "" + "" + " 1" + " Martin Novák" + " User" + ""; + + diff_expected = + "" + "0" + "Admin"; + 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 = + "" + " 0" + " Tomáš Novák" + " User" + "" + "" + " 1" + " Martin Novák" + " User" + ""; + + data_2 = + "" + " 0" + " Tomáš Novák" + " User" + "" + "" + " 1" + " Martin Novák" + " 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 = + "" + " 0" + " Tomáš Novák" + "" + "" + " 1" + " Martin Novák" + " Admin" + ""; + + LYD_TREE_CREATE(data_1, model_1); + + /* XML */ + expected_string = + "" + "0Tomáš Novák" + "" + "" + "1Martin NovákAdmin" + ""; + 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); +} -- cgit v1.2.3