summaryrefslogtreecommitdiffstats
path: root/tests/utests/types
diff options
context:
space:
mode:
Diffstat (limited to 'tests/utests/types')
-rw-r--r--tests/utests/types/binary.c269
-rw-r--r--tests/utests/types/bits.c1117
-rw-r--r--tests/utests/types/boolean.c111
-rw-r--r--tests/utests/types/decimal64.c125
-rw-r--r--tests/utests/types/empty.c108
-rw-r--r--tests/utests/types/enumeration.c114
-rw-r--r--tests/utests/types/identityref.c123
-rw-r--r--tests/utests/types/inet_types.c149
-rw-r--r--tests/utests/types/instanceid.c292
-rw-r--r--tests/utests/types/instanceid_keys.c77
-rw-r--r--tests/utests/types/int16.c75
-rw-r--r--tests/utests/types/int32.c75
-rw-r--r--tests/utests/types/int64.c83
-rw-r--r--tests/utests/types/int8.c1765
-rw-r--r--tests/utests/types/leafref.c222
-rw-r--r--tests/utests/types/string.c1410
-rw-r--r--tests/utests/types/uint16.c75
-rw-r--r--tests/utests/types/uint32.c75
-rw-r--r--tests/utests/types/uint64.c83
-rw-r--r--tests/utests/types/uint8.c77
-rw-r--r--tests/utests/types/union.c136
-rw-r--r--tests/utests/types/yang_types.c223
22 files changed, 6784 insertions, 0 deletions
diff --git a/tests/utests/types/binary.c b/tests/utests/types/binary.c
new file mode 100644
index 0000000..05b6b97
--- /dev/null
+++ b/tests/utests/types/binary.c
@@ -0,0 +1,269 @@
+/**
+ * @file binary.c
+ * @author Michal Vaško <mvasko@cesnet.cz>
+ * @brief test for built-in binary type
+ *
+ * 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"
+
+/* LOCAL INCLUDE HEADERS */
+#include "libyang.h"
+
+#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"
+
+#define TEST_SUCCESS_LYB(MOD_NAME, NODE_NAME, DATA) \
+ { \
+ struct lyd_node *tree_1; \
+ struct lyd_node *tree_2; \
+ char *xml_out, *data; \
+ data = "<" NODE_NAME " xmlns=\"urn:tests:" MOD_NAME "\">" DATA "</" NODE_NAME ">"; \
+ CHECK_PARSE_LYD_PARAM(data, LYD_XML, LYD_PARSE_ONLY | LYD_PARSE_STRICT, 0, LY_SUCCESS, tree_1); \
+ assert_int_equal(lyd_print_mem(&xml_out, tree_1, LYD_LYB, LYD_PRINT_WITHSIBLINGS), 0); \
+ assert_int_equal(LY_SUCCESS, lyd_parse_data_mem(UTEST_LYCTX, xml_out, LYD_LYB, LYD_PARSE_ONLY | LYD_PARSE_STRICT, 0, &tree_2)); \
+ assert_non_null(tree_2); \
+ CHECK_LYD(tree_1, tree_2); \
+ free(xml_out); \
+ lyd_free_all(tree_1); \
+ lyd_free_all(tree_2); \
+ }
+
+static void
+test_plugin_store(void **state)
+{
+ const char *val, *dec_val;
+ unsigned char bin_val[2];
+ struct ly_err_item *err = NULL;
+ struct lys_module *mod;
+ struct lyd_value value = {0};
+ struct lyplg_type *type = lyplg_type_plugin_find("", NULL, ly_data_type2str[LY_TYPE_BINARY]);
+ struct lysc_type *lysc_type;
+ LY_ERR ly_ret;
+ const char *schema;
+
+ /* create schema. Prepare common used variables */
+ schema = MODULE_CREATE_YANG("a", "leaf l {type binary;}");
+ UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, &mod);
+ lysc_type = ((struct lysc_node_leaf *)mod->compiled->data)->type;
+
+ /* check proper type */
+ assert_string_equal("libyang 2 - binary, version 1", type->id);
+
+ /* check store XML double pad */
+ val = "YWhveQ==";
+ dec_val = "ahoy";
+ assert_int_equal(LY_SUCCESS, type->store(UTEST_LYCTX, lysc_type, val, strlen(val),
+ 0, LY_VALUE_XML, NULL, LYD_VALHINT_STRING, NULL, &value, NULL, &err));
+ CHECK_LYD_VALUE(value, BINARY, val, dec_val, strlen(dec_val));
+ assert_ptr_equal(value.realtype, lysc_type);
+ type->free(UTEST_LYCTX, &value);
+
+ assert_int_equal(LY_SUCCESS, type->store(UTEST_LYCTX, lysc_type, dec_val, strlen(dec_val),
+ 0, LY_VALUE_LYB, NULL, 0, NULL, &value, NULL, &err));
+ CHECK_LYD_VALUE(value, BINARY, val, dec_val, strlen(dec_val));
+ assert_ptr_equal(value.realtype, lysc_type);
+ type->free(UTEST_LYCTX, &value);
+
+ /* single pad */
+ val = "YWhveWo=";
+ dec_val = "ahoyj";
+ assert_int_equal(LY_SUCCESS, type->store(UTEST_LYCTX, lysc_type, val, strlen(val),
+ 0, LY_VALUE_XML, NULL, LYD_VALHINT_STRING, NULL, &value, NULL, &err));
+ CHECK_LYD_VALUE(value, BINARY, val, dec_val, strlen(dec_val));
+ assert_ptr_equal(value.realtype, lysc_type);
+ type->free(UTEST_LYCTX, &value);
+
+ assert_int_equal(LY_SUCCESS, type->store(UTEST_LYCTX, lysc_type, dec_val, strlen(dec_val),
+ 0, LY_VALUE_LYB, NULL, 0, NULL, &value, NULL, &err));
+ CHECK_LYD_VALUE(value, BINARY, val, dec_val, strlen(dec_val));
+ assert_ptr_equal(value.realtype, lysc_type);
+ type->free(UTEST_LYCTX, &value);
+
+ /* no pad */
+ val = "YWhveWoy";
+ dec_val = "ahoyj2";
+ assert_int_equal(LY_SUCCESS, type->store(UTEST_LYCTX, lysc_type, val, strlen(val),
+ 0, LY_VALUE_XML, NULL, LYD_VALHINT_STRING, NULL, &value, NULL, &err));
+ CHECK_LYD_VALUE(value, BINARY, val, dec_val, strlen(dec_val));
+ assert_ptr_equal(value.realtype, lysc_type);
+ type->free(UTEST_LYCTX, &value);
+
+ assert_int_equal(LY_SUCCESS, type->store(UTEST_LYCTX, lysc_type, dec_val, strlen(dec_val),
+ 0, LY_VALUE_LYB, NULL, 0, NULL, &value, NULL, &err));
+ CHECK_LYD_VALUE(value, BINARY, val, dec_val, strlen(dec_val));
+ assert_ptr_equal(value.realtype, lysc_type);
+ type->free(UTEST_LYCTX, &value);
+
+ /* binary data */
+ val = "q80=";
+ bin_val[0] = 0xab;
+ bin_val[1] = 0xcd;
+ assert_int_equal(LY_SUCCESS, type->store(UTEST_LYCTX, lysc_type, val, strlen(val),
+ 0, LY_VALUE_XML, NULL, LYD_VALHINT_STRING, NULL, &value, NULL, &err));
+ CHECK_LYD_VALUE(value, BINARY, val, bin_val, 2);
+ assert_ptr_equal(value.realtype, lysc_type);
+ type->free(UTEST_LYCTX, &value);
+
+ assert_int_equal(LY_SUCCESS, type->store(UTEST_LYCTX, lysc_type, bin_val, 2,
+ 0, LY_VALUE_LYB, NULL, 0, NULL, &value, NULL, &err));
+ CHECK_LYD_VALUE(value, BINARY, val, bin_val, 2);
+ assert_ptr_equal(value.realtype, lysc_type);
+ type->free(UTEST_LYCTX, &value);
+
+ /* newlines after every 64 chars */
+ val = "MIIEAzCCAuugAwIBAgIURc4sipHvJSlNrQIhRhZilBvV4RowDQYJKoZIhvcNAQEL\n"
+ "BQAwgZAxCzAJBgNVBAYTAkNaMRYwFAYDVQQIDA1Tb3V0aCBNb3JhdmlhMQ0wCwYD\n"
+ "VQQHDARCcm5vMRgwFgYDVQQKDA9DRVNORVQgei5zLnAuby4xDDAKBgNVBAsMA1RN\n"
+ "QzETMBEGA1UEAwwKZXhhbXBsZSBDQTEdMBsGCSqGSIb3DQEJARYOY2FAZXhhbXBs\n"
+ "ZS5vcmcwHhcNMjEwOTAzMTAyMTAxWhcNMzEwOTAxMTAyMTAxWjCBkDELMAkGA1UE\n"
+ "BhMCQ1oxFjAUBgNVBAgMDVNvdXRoIE1vcmF2aWExDTALBgNVBAcMBEJybm8xGDAW\n"
+ "BgNVBAoMD0NFU05FVCB6LnMucC5vLjEMMAoGA1UECwwDVE1DMRMwEQYDVQQDDApl\n"
+ "eGFtcGxlIENBMR0wGwYJKoZIhvcNAQkBFg5jYUBleGFtcGxlLm9yZzCCASIwDQYJ\n"
+ "KoZIhvcNAQEBBQADggEPADCCAQoCggEBAN4Ld3JDDocyy9KXNJhEUPeZpQW3UdUN\n"
+ "Xloeh5n/bxasgThkBuQ7oF/nKyVUe517U1CJA993ZIc0jhIWThAnqXkz70DX5EZ7\n"
+ "ancPd01MidA6T8k1RYYJWr+vyIRYYBYzK7LSnU6wMWqPTgzZB+KMWwb065ooLEB5\n"
+ "XwqAeTIMPLRqM1Galewl4ZSuRJnrXxRjfF3AWNyC9dZw6wIg8cppvoLdBGQiFJQf\n"
+ "9SgiVy+HyedAytFEixqKAAIgQUJwhCgbEd6jGFbeaL8HT4MFp1VmaaUBQMkZj/Gn\n"
+ "KBwCk5BEMu76EN1pzHc4Dd6DabQNGCnsqOPe31yhQGmNFy9R6zNnWZMCAwEAAaNT\n"
+ "MFEwHQYDVR0OBBYEFM7w/pO8vk5oowvWPoCKo0RW/JcnMB8GA1UdIwQYMBaAFM7w\n"
+ "/pO8vk5oowvWPoCKo0RW/JcnMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEL\n"
+ "BQADggEBAG/xfYuRKnCyiwYC/K7kAjHmCNnLCr1mx8P1ECsSJPme3OThDTNeGf8i\n"
+ "N2952tGmMFDa+DaAwPc6Gt3cWTb/NYMTLWlt2yj5rJAcLXxIU0SMafBf+F7E/R8A\n"
+ "b/HDDjs0pQaJ0EJhQJVkMdfj3Wq9l0dJT5iEBUrUQflDufiMdEJEIGKZh86MgzEL\n"
+ "bcn1QX8dlLc91M2OifWStqLzXPicG+jjuoPUceC0flMQDb2qx03sxvJKfYfS5ArA\n"
+ "CqvdWyXLoP7DI9THJrMI/vBHJKpl4Wtmsh2OLn9VHauFMzPSGke5GwjXCpbXGepj\n"
+ "9qWN8Gd/FWgSDH2OBvZ6aHdB1pPjN9k=";
+ assert_int_equal(LY_SUCCESS, type->store(UTEST_LYCTX, lysc_type, val, strlen(val),
+ 0, LY_VALUE_XML, NULL, LYD_VALHINT_STRING, NULL, &value, NULL, &err));
+ assert_ptr_equal(value.realtype, lysc_type);
+ type->free(UTEST_LYCTX, &value);
+
+ /* empty value */
+ val = "";
+ assert_int_equal(LY_SUCCESS, type->store(UTEST_LYCTX, lysc_type, val, strlen(val),
+ 0, LY_VALUE_XML, NULL, LYD_VALHINT_STRING, NULL, &value, NULL, &err));
+ CHECK_LYD_VALUE(value, BINARY, "", "", 0);
+ assert_ptr_equal(value.realtype, lysc_type);
+ type->free(UTEST_LYCTX, &value);
+
+ /* short value */
+ val = "YQ==";
+ dec_val = "a";
+ assert_int_equal(LY_SUCCESS, type->store(UTEST_LYCTX, lysc_type, val, strlen(val),
+ 0, LY_VALUE_XML, NULL, LYD_VALHINT_STRING, NULL, &value, NULL, &err));
+ CHECK_LYD_VALUE(value, BINARY, val, dec_val, strlen(dec_val));
+ assert_ptr_equal(value.realtype, lysc_type);
+ type->free(UTEST_LYCTX, &value);
+
+ assert_int_equal(LY_SUCCESS, type->store(UTEST_LYCTX, lysc_type, dec_val, strlen(dec_val),
+ 0, LY_VALUE_LYB, NULL, 0, NULL, &value, NULL, &err));
+ CHECK_LYD_VALUE(value, BINARY, val, dec_val, strlen(dec_val));
+ assert_ptr_equal(value.realtype, lysc_type);
+ type->free(UTEST_LYCTX, &value);
+
+ /*
+ * ERROR TESTS
+ */
+ val = "q80.";
+ err = NULL;
+ ly_ret = type->store(UTEST_LYCTX, lysc_type, val, strlen(val),
+ 0, LY_VALUE_XML, NULL, LYD_VALHINT_STRING, NULL, &value, NULL, &err);
+ assert_int_equal(LY_EVALID, ly_ret);
+ assert_string_equal(err->msg, "Invalid Base64 character '.'.");
+ ly_err_free(err);
+
+ val = "q80";
+ err = NULL;
+ ly_ret = type->store(UTEST_LYCTX, lysc_type, val, strlen(val),
+ 0, LY_VALUE_XML, NULL, LYD_VALHINT_STRING, NULL, &value, NULL, &err);
+ assert_int_equal(LY_EVALID, ly_ret);
+ assert_string_equal(err->msg, "Base64 encoded value length must be divisible by 4.");
+ ly_err_free(err);
+}
+
+static void
+test_plugin_print(void **state)
+{
+ const char *schema, *val;
+ struct lyd_value value = {0};
+ struct lys_module *mod;
+ struct lysc_type *lysc_type;
+ struct lyplg_type *type = lyplg_type_plugin_find("", NULL, ly_data_type2str[LY_TYPE_BINARY]);
+ struct ly_err_item *err = NULL;
+
+ /* create schema. Prepare common used variables */
+ schema = MODULE_CREATE_YANG("a", "leaf l {type binary;}");
+ UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, &mod);
+ lysc_type = ((struct lysc_node_leaf *)mod->compiled->data)->type;
+
+ /* Testing empty value. */
+ val = "";
+ assert_int_equal(LY_SUCCESS, type->store(UTEST_LYCTX, lysc_type, val, strlen(val),
+ 0, LY_VALUE_XML, NULL, LYD_VALHINT_STRING, NULL, &value, NULL, &err));
+ assert_string_equal("", value.realtype->plugin->print(UTEST_LYCTX, &(value), LY_VALUE_CANON, NULL, NULL, NULL));
+ type->free(UTEST_LYCTX, &value);
+}
+
+static void
+test_plugin_duplicate(void **state)
+{
+ const char *schema, *val;
+ struct lyd_value value = {0}, dup;
+ struct lys_module *mod;
+ struct lysc_type *lysc_type;
+ struct lyplg_type *type = lyplg_type_plugin_find("", NULL, ly_data_type2str[LY_TYPE_BINARY]);
+ struct ly_err_item *err = NULL;
+
+ /* create schema. Prepare common used variables */
+ schema = MODULE_CREATE_YANG("a", "leaf l {type binary;}");
+ UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, &mod);
+ lysc_type = ((struct lysc_node_leaf *)mod->compiled->data)->type;
+
+ /* Testing empty value. */
+ val = "";
+ assert_int_equal(LY_SUCCESS, type->store(UTEST_LYCTX, lysc_type, val, strlen(val),
+ 0, LY_VALUE_XML, NULL, LYD_VALHINT_STRING, NULL, &value, NULL, &err));
+ assert_int_equal(LY_SUCCESS, type->duplicate(UTEST_LYCTX, &value, &dup));
+ CHECK_LYD_VALUE(dup, BINARY, "", "", 0);
+ type->free(UTEST_LYCTX, &value);
+ type->free(UTEST_LYCTX, &dup);
+}
+
+static void
+test_data_lyb(void **state)
+{
+ const char *schema;
+
+ schema = MODULE_CREATE_YANG("lyb", "leaf port {type binary;}");
+ UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, NULL);
+ TEST_SUCCESS_LYB("lyb", "port", "");
+ TEST_SUCCESS_LYB("lyb", "port", "YWhveQ==");
+}
+
+int
+main(void)
+{
+ const struct CMUnitTest tests[] = {
+ UTEST(test_plugin_store),
+ UTEST(test_plugin_print),
+ UTEST(test_plugin_duplicate),
+ UTEST(test_data_lyb),
+ };
+
+ return cmocka_run_group_tests(tests, NULL, NULL);
+}
diff --git a/tests/utests/types/bits.c b/tests/utests/types/bits.c
new file mode 100644
index 0000000..3d42ebc
--- /dev/null
+++ b/tests/utests/types/bits.c
@@ -0,0 +1,1117 @@
+/**
+ * @file bits.c
+ * @author Radek Iša <isa@cesnet.cz>
+ * @brief test for int8 values
+ *
+ * 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 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"
+
+#define TEST_SUCCESS_XML(MOD_NAME, DATA, TYPE, ...) \
+ { \
+ struct lyd_node *tree; \
+ const char *data = "<port xmlns=\"urn:tests:" MOD_NAME "\">" DATA "</port>"; \
+ CHECK_PARSE_LYD_PARAM(data, LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_SUCCESS, tree); \
+ CHECK_LYSC_NODE(tree->schema, NULL, 0, 0x5, 1, "port", 0, LYS_LEAF, 0, 0, 0, 0); \
+ CHECK_LYD_NODE_TERM((struct lyd_node_term *)tree, 0, 0, 0, 0, 1, TYPE, __VA_ARGS__); \
+ lyd_free_all(tree); \
+ }
+
+#define TEST_SUCCESS_JSON(MOD_NAME, DATA, TYPE, ...) \
+ { \
+ struct lyd_node *tree; \
+ const char *data = "{\"" MOD_NAME ":port\":\"" DATA "\"}"; \
+ CHECK_PARSE_LYD_PARAM(data, LYD_JSON, 0, LYD_VALIDATE_PRESENT, LY_SUCCESS, tree); \
+ CHECK_LYSC_NODE(tree->schema, NULL, 0, 0x5, 1, "port", 0, LYS_LEAF, 0, 0, 0, 0); \
+ CHECK_LYD_NODE_TERM((struct lyd_node_term *)tree, 0, 0, 0, 0, 1, TYPE, __VA_ARGS__); \
+ lyd_free_all(tree); \
+ }
+
+#define TEST_SUCCESS_LYB(MOD_NAME, NODE_NAME, DATA) \
+ { \
+ struct lyd_node *tree_1; \
+ struct lyd_node *tree_2; \
+ char *xml_out, *data; \
+ data = "<" NODE_NAME " xmlns=\"urn:tests:" MOD_NAME "\">" DATA "</" NODE_NAME ">"; \
+ CHECK_PARSE_LYD_PARAM(data, LYD_XML, LYD_PARSE_ONLY | LYD_PARSE_STRICT, 0, LY_SUCCESS, tree_1); \
+ assert_int_equal(lyd_print_mem(&xml_out, tree_1, LYD_LYB, LYD_PRINT_WITHSIBLINGS), 0); \
+ assert_int_equal(LY_SUCCESS, lyd_parse_data_mem(UTEST_LYCTX, xml_out, LYD_LYB, LYD_PARSE_ONLY | LYD_PARSE_STRICT, 0, &tree_2)); \
+ assert_non_null(tree_2); \
+ CHECK_LYD(tree_1, tree_2); \
+ free(xml_out); \
+ lyd_free_all(tree_1); \
+ lyd_free_all(tree_2); \
+ }
+
+#define TEST_ERROR_XML(MOD_NAME, DATA) \
+ {\
+ struct lyd_node *tree; \
+ const char *data = "<port xmlns=\"urn:tests:" MOD_NAME "\">" DATA "</port>"; \
+ CHECK_PARSE_LYD_PARAM(data, LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_EVALID, tree); \
+ assert_null(tree); \
+ }
+
+#define TEST_ERROR_JSON(MOD_NAME, DATA) \
+ { \
+ struct lyd_node *tree; \
+ const char *data = "{\"" MOD_NAME ":port\":" DATA "}"; \
+ CHECK_PARSE_LYD_PARAM(data, LYD_JSON, 0, LYD_VALIDATE_PRESENT, LY_EVALID, tree); \
+ assert_null(tree); \
+ }
+
+static void
+test_schema_yang(void **state)
+{
+ const char *schema;
+ struct lys_module *mod;
+ struct lysc_node_leaf *lysc_leaf;
+ struct lysp_node_leaf *lysp_leaf;
+ struct lysc_type_bits *lysc_type;
+
+ schema = MODULE_CREATE_YANG("T0", "leaf port {type bits { bit zero;\nbit one;"
+ " bit ten{position 10;}\tbit \"eleven\"; bit last{position 4294967295; }}}");
+ UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, &mod);
+ assert_non_null(mod);
+ lysc_leaf = (void *)mod->compiled->data;
+ CHECK_LYSC_NODE_LEAF(lysc_leaf, NULL, 0, 0x5, 1, "port", 0, 0, 0, NULL, 0, 0, NULL, NULL);
+ lysc_type = (struct lysc_type_bits *) lysc_leaf->type;
+ CHECK_LYSC_TYPE_BITS(lysc_type, 0, 5);
+ CHECK_LYSC_TYPE_BITENUM_ITEM(&(lysc_type->bits[0]), 0, NULL, 0, 0, "zero", NULL);
+ CHECK_LYSC_TYPE_BITENUM_ITEM(&(lysc_type->bits[1]), 1, NULL, 0, 0, "one", NULL);
+ CHECK_LYSC_TYPE_BITENUM_ITEM(&(lysc_type->bits[2]), 10, NULL, 0, 0, "ten", NULL);
+ CHECK_LYSC_TYPE_BITENUM_ITEM(&(lysc_type->bits[3]), 11, NULL, 0, 0, "eleven", NULL);
+ CHECK_LYSC_TYPE_BITENUM_ITEM(&(lysc_type->bits[4]), 4294967295, NULL, 0, 0, "last", NULL);
+ lysp_leaf = (void *)mod->parsed->data;
+ CHECK_LYSP_NODE_LEAF(lysp_leaf, NULL, 0, 0x0, 0, "port", 0, 0, NULL, 0, 0, NULL, NULL);
+ CHECK_LYSP_TYPE(&(lysp_leaf->type), 0, 5, 0, 0, 0, 0x02, 0, 0, "bits", 0, 0, 1, 0, 0, 0);
+
+ schema = MODULE_CREATE_YANG("T1", "leaf port {type bits { bit _ten {position 10;} bit _ten-one;"
+ " bit _two {position 2;} bit ten_end...;}}");
+ UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, &mod);
+ assert_non_null(mod);
+ lysc_leaf = (void *)mod->compiled->data;
+ CHECK_LYSC_NODE_LEAF(lysc_leaf, NULL, 0, 0x5, 1, "port", 0, 0, 0, NULL, 0, 0, NULL, NULL);
+ lysc_type = (struct lysc_type_bits *) lysc_leaf->type;
+ CHECK_LYSC_TYPE_BITS(lysc_type, 0, 4);
+ CHECK_LYSC_TYPE_BITENUM_ITEM(&(lysc_type->bits[0]), 2, NULL, 0, 0, "_two", NULL);
+ CHECK_LYSC_TYPE_BITENUM_ITEM(&(lysc_type->bits[1]), 10, NULL, 0, 0, "_ten", NULL);
+ CHECK_LYSC_TYPE_BITENUM_ITEM(&(lysc_type->bits[2]), 11, NULL, 0, 0, "_ten-one", NULL);
+ CHECK_LYSC_TYPE_BITENUM_ITEM(&(lysc_type->bits[3]), 12, NULL, 0, 0, "ten_end...", NULL);
+ lysp_leaf = (void *)mod->parsed->data;
+ CHECK_LYSP_NODE_LEAF(lysp_leaf, NULL, 0, 0x0, 0, "port", 0, 0, NULL, 0, 0, NULL, NULL);
+ CHECK_LYSP_TYPE(&(lysp_leaf->type), 0, 4, 0, 0, 0, 0x02, 0, 0, "bits", 0, 0, 1, 0, 0, 0);
+
+ /* TEST MODULE SUBTYPE */
+ schema = MODULE_CREATE_YANG("T2", "typedef my_type{type bits {"
+ " bit ten {position 10;} bit eleven; bit two {position 2;} bit twelve;}}"
+ "leaf port {type my_type;}");
+ UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, &mod);
+ assert_non_null(mod);
+ lysc_leaf = (void *)mod->compiled->data;
+ CHECK_LYSC_NODE_LEAF(lysc_leaf, NULL, 0, 0x5, 1, "port", 0, 0, 0, NULL, 0, 0, NULL, NULL);
+ lysc_type = (struct lysc_type_bits *) lysc_leaf->type;
+ CHECK_LYSC_TYPE_BITS(lysc_type, 0, 4);
+ CHECK_LYSC_TYPE_BITENUM_ITEM(&(lysc_type->bits[0]), 2, NULL, 0, 0, "two", NULL);
+ CHECK_LYSC_TYPE_BITENUM_ITEM(&(lysc_type->bits[1]), 10, NULL, 0, 0, "ten", NULL);
+ CHECK_LYSC_TYPE_BITENUM_ITEM(&(lysc_type->bits[2]), 11, NULL, 0, 0, "eleven", NULL);
+ CHECK_LYSC_TYPE_BITENUM_ITEM(&(lysc_type->bits[3]), 12, NULL, 0, 0, "twelve", NULL);
+ lysp_leaf = (void *)mod->parsed->data;
+ CHECK_LYSP_NODE_LEAF(lysp_leaf, NULL, 0, 0x0, 0, "port", 0, 0, NULL, 0, 0, NULL, NULL);
+ CHECK_LYSP_TYPE(&(lysp_leaf->type), 0, 0, 0, 0, 0, 0, 0, 0, "my_type", 0, 0, 1, 0, 0, 0);
+
+ schema = MODULE_CREATE_YANG("T3", "typedef my_type{type bits {"
+ " bit ten {position 10;} bit eleven; bit two {position 2;} bit twelve;}}"
+ "leaf port {type my_type {"
+ " bit ten {position 10;} bit two;}}");
+ UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, &mod);
+ assert_non_null(mod);
+ lysc_leaf = (void *)mod->compiled->data;
+ CHECK_LYSC_NODE_LEAF(lysc_leaf, NULL, 0, 0x5, 1, "port", 0, 0, 0, NULL, 0, 0, NULL, NULL);
+ lysc_type = (struct lysc_type_bits *) lysc_leaf->type;
+ CHECK_LYSC_TYPE_BITS(lysc_type, 0, 2);
+ CHECK_LYSC_TYPE_BITENUM_ITEM(&(lysc_type->bits[0]), 2, NULL, 0, 0, "two", NULL);
+ CHECK_LYSC_TYPE_BITENUM_ITEM(&(lysc_type->bits[1]), 10, NULL, 0, 0, "ten", NULL);
+ lysp_leaf = (void *)mod->parsed->data;
+ CHECK_LYSP_NODE_LEAF(lysp_leaf, NULL, 0, 0x0, 0, "port", 0, 0, NULL, 0, 0, NULL, NULL);
+ CHECK_LYSP_TYPE(&(lysp_leaf->type), 0, 2, 0, 0, 0, 0x02, 0, 0, "my_type", 0, 0, 1, 0, 0, 0);
+
+ /*
+ * TEST ERROR
+ */
+ /* test change bit possition */
+ schema = MODULE_CREATE_YANG("TERR_0", "typedef my_type{type bits {"
+ " bit ten {position 10;} bit eleven; bit two {position 2;} bit \"twelve\";}}"
+ "leaf port {type my_type {"
+ " bit ten {position 11;} bit two;}}");
+ UTEST_INVALID_MODULE(schema, LYS_IN_YANG, NULL, LY_EVALID);
+ CHECK_LOG_CTX("Invalid bits - position of the item \"ten\" has changed from 10 to 11 in the derived type.", "/TERR_0:port");
+
+ /* add new bit */
+ schema = MODULE_CREATE_YANG("TERR_1", "typedef my_type{type bits {"
+ " bit ten {position 10;} bit eleven; bit two {position 2;} bit twelve;}}"
+ "leaf port {type my_type {"
+ " bit ten {position 10;} bit two; bit test;}}");
+ UTEST_INVALID_MODULE(schema, LYS_IN_YANG, NULL, LY_EVALID);
+ CHECK_LOG_CTX("Invalid bits - derived type adds new item \"test\".", "/TERR_1:port");
+
+ /* different max value => autoadd index */
+ schema = MODULE_CREATE_YANG("TERR_2", "leaf port {type bits {"
+ " bit first {position -1;} bit second;"
+ "}}");
+ UTEST_INVALID_MODULE(schema, LYS_IN_YANG, NULL, LY_EVALID);
+ CHECK_LOG_CTX("Parsing module \"TERR_2\" failed.", NULL,
+ "Invalid value \"-1\" of \"position\".", "Line number 5.");
+
+ /* different max value => autoadd index */
+ schema = MODULE_CREATE_YANG("TERR_3", "leaf port {type bits {"
+ " bit first {position 4294967295;} bit second;"
+ "}}");
+ UTEST_INVALID_MODULE(schema, LYS_IN_YANG, NULL, LY_EVALID);
+ CHECK_LOG_CTX("Invalid bits - it is not possible to auto-assign bit position for \"second\" since the highest value is already 4294967295.",
+ "/TERR_3:port");
+
+ schema = MODULE_CREATE_YANG("TERR_4", "leaf port {type bits {"
+ " bit first {position 10;} bit \"\";"
+ "}}");
+ UTEST_INVALID_MODULE(schema, LYS_IN_YANG, NULL, LY_EVALID);
+ CHECK_LOG_CTX("Parsing module \"TERR_4\" failed.", NULL,
+ "Statement argument is required.", "Line number 5.");
+
+ /* wrong character */
+ schema = MODULE_CREATE_YANG("TERR_5", "leaf port {type bits {"
+ " bit first {position 10;} bit abcd^;"
+ "}}");
+ UTEST_INVALID_MODULE(schema, LYS_IN_YANG, NULL, LY_EVALID);
+ CHECK_LOG_CTX("Parsing module \"TERR_5\" failed.", NULL,
+ "Invalid identifier character '^' (0x005e).", "Line number 5.");
+
+ schema = MODULE_CREATE_YANG("TERR_6", "leaf port {type bits {"
+ " bit hi; bit hi;"
+ "}}");
+ UTEST_INVALID_MODULE(schema, LYS_IN_YANG, NULL, LY_EVALID);
+ CHECK_LOG_CTX("Parsing module \"TERR_6\" failed.", NULL,
+ "Duplicate identifier \"hi\" of bit statement.", "Line number 5.");
+
+ /* wrong character */
+ schema = MODULE_CREATE_YANG("TERR_7", "leaf port {type bits {"
+ " bit first {position 10;} bit \"ab&cd\";"
+ "}}");
+ UTEST_INVALID_MODULE(schema, LYS_IN_YANG, NULL, LY_EVALID);
+ CHECK_LOG_CTX("Parsing module \"TERR_7\" failed.", NULL,
+ "Invalid identifier character '&' (0x0026).", "Line number 5.");
+
+ schema = MODULE_CREATE_YANG("TERR_8", "leaf port {type bits {"
+ " bit first {position 10;} bit \"4abcd\";"
+ "}}");
+ UTEST_INVALID_MODULE(schema, LYS_IN_YANG, NULL, LY_EVALID);
+ CHECK_LOG_CTX("Parsing module \"TERR_8\" failed.", NULL,
+ "Invalid identifier first character '4' (0x0034).", "Line number 5.");
+
+ schema = MODULE_CREATE_YANG("TERR_9", "leaf port {type bits;}");
+ UTEST_INVALID_MODULE(schema, LYS_IN_YANG, NULL, LY_EVALID);
+ CHECK_LOG_CTX("Missing bit substatement for bits type.", "/TERR_9:port");
+
+ /* new features of YANG 1.1 in YANG 1.0 */
+ schema = "module TERR_10 {"
+ " namespace \"urn:tests:TERR_10\";"
+ " prefix pref;"
+ " feature f;"
+ " leaf l {type bits {"
+ " bit one {if-feature f;}"
+ " }}"
+ "}";
+ UTEST_INVALID_MODULE(schema, LYS_IN_YANG, NULL, LY_EVALID);
+ CHECK_LOG_CTX("Parsing module \"TERR_10\" failed.", NULL,
+ "Invalid keyword \"if-feature\" as a child of \"bit\" - the statement is allowed only in YANG 1.1 modules.",
+ "Line number 1.");
+
+ schema = "module TERR_11 {"
+ " namespace \"urn:tests:TERR_10\";"
+ " prefix pref;"
+ " typedef mytype {type bits {bit one;}}"
+ " leaf l {type mytype {bit one;}}"
+ "}";
+ UTEST_INVALID_MODULE(schema, LYS_IN_YANG, NULL, LY_EVALID);
+ CHECK_LOG_CTX("Bits type can be subtyped only in YANG 1.1 modules.", "/TERR_11:l");
+
+ /* feature is not present */
+ schema = MODULE_CREATE_YANG("IF_0", "feature f;"
+ "leaf port {type bits { bit zero;\nbit one;"
+ " bit ten{if-feature f; position 10;}\tbit eleven;}}");
+ UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, &mod);
+ assert_int_equal(LY_ENOT, lys_feature_value (mod, "f"));
+ assert_non_null(mod);
+ lysc_leaf = (void *)mod->compiled->data;
+ CHECK_LYSC_NODE_LEAF(lysc_leaf, NULL, 0, 0x5, 1, "port", 0, 0, 0, NULL, 0, 0, NULL, NULL);
+ lysc_type = (struct lysc_type_bits *) lysc_leaf->type;
+ CHECK_LYSC_TYPE_BITS(lysc_type, 0, 3);
+ CHECK_LYSC_TYPE_BITENUM_ITEM(&(lysc_type->bits[0]), 0, NULL, 0, 0, "zero", NULL);
+ CHECK_LYSC_TYPE_BITENUM_ITEM(&(lysc_type->bits[1]), 1, NULL, 0, 0, "one", NULL);
+ CHECK_LYSC_TYPE_BITENUM_ITEM(&(lysc_type->bits[2]), 11, NULL, 0, 0, "eleven", NULL);
+ lysp_leaf = (void *)mod->parsed->data;
+ CHECK_LYSP_NODE_LEAF(lysp_leaf, NULL, 0, 0x0, 0, "port", 0, 0, NULL, 0, 0, NULL, NULL);
+ CHECK_LYSP_TYPE(&(lysp_leaf->type), 0, 4, 0, 0, 0, 0x02, 0, 0, "bits", 0, 0, 1, 0, 0, 0);
+
+ /* feature is present */
+ schema = MODULE_CREATE_YANG("IF_1", "feature f;"
+ "leaf port {type bits { bit zero;\nbit one;"
+ " bit ten{position 10; if-feature f;}\tbit eleven;}}");
+ const char *IF_1_FEATURES[] = {"f", NULL};
+
+ UTEST_ADD_MODULE(schema, LYS_IN_YANG, IF_1_FEATURES, &mod);
+ assert_non_null(mod);
+ lysc_leaf = (void *)mod->compiled->data;
+ CHECK_LYSC_NODE_LEAF(lysc_leaf, NULL, 0, 0x5, 1, "port", 0, 0, 0, NULL, 0, 0, NULL, NULL);
+ lysc_type = (struct lysc_type_bits *) lysc_leaf->type;
+ CHECK_LYSC_TYPE_BITS(lysc_type, 0, 4);
+ CHECK_LYSC_TYPE_BITENUM_ITEM(&(lysc_type->bits[0]), 0, NULL, 0, 0, "zero", NULL);
+ CHECK_LYSC_TYPE_BITENUM_ITEM(&(lysc_type->bits[1]), 1, NULL, 0, 0, "one", NULL);
+ CHECK_LYSC_TYPE_BITENUM_ITEM(&(lysc_type->bits[2]), 10, NULL, 0, 0, "ten", NULL);
+ CHECK_LYSC_TYPE_BITENUM_ITEM(&(lysc_type->bits[3]), 11, NULL, 0, 0, "eleven", NULL);
+ lysp_leaf = (void *)mod->parsed->data;
+ CHECK_LYSP_NODE_LEAF(lysp_leaf, NULL, 0, 0x0, 0, "port", 0, 0, NULL, 0, 0, NULL, NULL);
+ CHECK_LYSP_TYPE(&(lysp_leaf->type), 0, 4, 0, 0, 0, 0x02, 0, 0, "bits", 0, 0, 1, 0, 0, 0);
+}
+
+static void
+test_schema_yin(void **state)
+{
+ const char *schema;
+ struct lys_module *mod;
+ struct lysc_node_leaf *lysc_leaf;
+ struct lysp_node_leaf *lysp_leaf;
+ struct lysc_type_bits *lysc_type;
+
+ schema = MODULE_CREATE_YIN("T0",
+ "<leaf name=\"port\"> <type name=\"bits\">"
+ " <bit name=\"zero\"/> <bit name=\"one\"/>"
+ " <bit name=\"ten\"> <position value=\"10\"/> </bit>"
+ " <bit name=\"eleven\"/>"
+ " <bit name=\"last\"> <position value=\"4294967295\"/> </bit>"
+ "</type></leaf>");
+ UTEST_ADD_MODULE(schema, LYS_IN_YIN, NULL, &mod);
+ assert_non_null(mod);
+ lysc_leaf = (void *)mod->compiled->data;
+ CHECK_LYSC_NODE_LEAF(lysc_leaf, NULL, 0, 0x5, 1, "port", 0, 0, 0, NULL, 0, 0, NULL, NULL);
+ lysc_type = (struct lysc_type_bits *) lysc_leaf->type;
+ CHECK_LYSC_TYPE_BITS(lysc_type, 0, 5);
+ CHECK_LYSC_TYPE_BITENUM_ITEM(&(lysc_type->bits[0]), 0, NULL, 0, 0, "zero", NULL);
+ CHECK_LYSC_TYPE_BITENUM_ITEM(&(lysc_type->bits[1]), 1, NULL, 0, 0, "one", NULL);
+ CHECK_LYSC_TYPE_BITENUM_ITEM(&(lysc_type->bits[2]), 10, NULL, 0, 0, "ten", NULL);
+ CHECK_LYSC_TYPE_BITENUM_ITEM(&(lysc_type->bits[3]), 11, NULL, 0, 0, "eleven", NULL);
+ CHECK_LYSC_TYPE_BITENUM_ITEM(&(lysc_type->bits[4]), 4294967295, NULL, 0, 0, "last", NULL);
+ lysp_leaf = (void *)mod->parsed->data;
+ CHECK_LYSP_NODE_LEAF(lysp_leaf, NULL, 0, 0x0, 0, "port", 0, 0, NULL, 0, 0, NULL, NULL);
+ CHECK_LYSP_TYPE(&(lysp_leaf->type), 0, 5, 0, 0, 0, 0x02, 0, 0, "bits", 0, 0, 1, 0, 0, 0);
+
+ schema = MODULE_CREATE_YIN("T1",
+ "<leaf name=\"port\"> <type name=\"bits\">"
+ " <bit name=\"_ten\"> <position value=\"10\"/> </bit> <bit name=\"_ten-one\"/>"
+ " <bit name=\"_two\"> <position value=\"2\"/> </bit> <bit name=\"ten_end...\"/>"
+ "</type></leaf>");
+ UTEST_ADD_MODULE(schema, LYS_IN_YIN, NULL, &mod);
+ assert_non_null(mod);
+ lysc_leaf = (void *)mod->compiled->data;
+ CHECK_LYSC_NODE_LEAF(lysc_leaf, NULL, 0, 0x5, 1, "port", 0, 0, 0, NULL, 0, 0, NULL, NULL);
+ lysc_type = (struct lysc_type_bits *) lysc_leaf->type;
+ CHECK_LYSC_TYPE_BITS(lysc_type, 0, 4);
+ CHECK_LYSC_TYPE_BITENUM_ITEM(&(lysc_type->bits[0]), 2, NULL, 0, 0, "_two", NULL);
+ CHECK_LYSC_TYPE_BITENUM_ITEM(&(lysc_type->bits[1]), 10, NULL, 0, 0, "_ten", NULL);
+ CHECK_LYSC_TYPE_BITENUM_ITEM(&(lysc_type->bits[2]), 11, NULL, 0, 0, "_ten-one", NULL);
+ CHECK_LYSC_TYPE_BITENUM_ITEM(&(lysc_type->bits[3]), 12, NULL, 0, 0, "ten_end...", NULL);
+ lysp_leaf = (void *)mod->parsed->data;
+ CHECK_LYSP_NODE_LEAF(lysp_leaf, NULL, 0, 0x0, 0, "port", 0, 0, NULL, 0, 0, NULL, NULL);
+ CHECK_LYSP_TYPE(&(lysp_leaf->type), 0, 4, 0, 0, 0, 0x02, 0, 0, "bits", 0, 0, 1, 0, 0, 0);
+
+ /* TEST MODULE SUBTYPE */
+ schema = MODULE_CREATE_YIN("T2",
+ "<typedef name=\"my_type\"> <type name=\"bits\">"
+ " <bit name=\"ten\"> <position value=\"10\"/> </bit>"
+ " <bit name=\"eleven\"/> <bit name=\"two\"> <position value=\"2\"/> </bit>"
+ " <bit name=\"twelve\"/>"
+ "</type> </typedef>"
+ "<leaf name=\"port\"> <type name=\"my_type\"/></leaf>");
+ UTEST_ADD_MODULE(schema, LYS_IN_YIN, NULL, &mod);
+ assert_non_null(mod);
+ lysc_leaf = (void *)mod->compiled->data;
+ CHECK_LYSC_NODE_LEAF(lysc_leaf, NULL, 0, 0x5, 1, "port", 0, 0, 0, NULL, 0, 0, NULL, NULL);
+ lysc_type = (struct lysc_type_bits *) lysc_leaf->type;
+ CHECK_LYSC_TYPE_BITS(lysc_type, 0, 4);
+ CHECK_LYSC_TYPE_BITENUM_ITEM(&(lysc_type->bits[0]), 2, NULL, 0, 0, "two", NULL);
+ CHECK_LYSC_TYPE_BITENUM_ITEM(&(lysc_type->bits[1]), 10, NULL, 0, 0, "ten", NULL);
+ CHECK_LYSC_TYPE_BITENUM_ITEM(&(lysc_type->bits[2]), 11, NULL, 0, 0, "eleven", NULL);
+ CHECK_LYSC_TYPE_BITENUM_ITEM(&(lysc_type->bits[3]), 12, NULL, 0, 0, "twelve", NULL);
+ lysp_leaf = (void *)mod->parsed->data;
+ CHECK_LYSP_NODE_LEAF(lysp_leaf, NULL, 0, 0x0, 0, "port", 0, 0, NULL, 0, 0, NULL, NULL);
+ CHECK_LYSP_TYPE(&(lysp_leaf->type), 0, 0, 0, 0, 0, 0, 0, 0, "my_type", 0, 0, 1, 0, 0, 0);
+
+ schema = MODULE_CREATE_YIN("T3", "<typedef name=\"my_type\"> <type name=\"bits\">"
+ " <bit name=\"ten\"> <position value=\"10\"/></bit>"
+ " <bit name=\"eleven\"/> <bit name=\"two\"> <position value=\"2\"/> </bit>"
+ " <bit name=\"twelve\"/>"
+ "</type></typedef>"
+ "<leaf name=\"port\"> <type name=\"my_type\">"
+ " <bit name=\"ten\"> <position value=\"10\"/> </bit>"
+ " <bit name=\"two\"/>"
+ "</type></leaf>");
+ UTEST_ADD_MODULE(schema, LYS_IN_YIN, NULL, &mod);
+ assert_non_null(mod);
+ lysc_leaf = (void *)mod->compiled->data;
+ CHECK_LYSC_NODE_LEAF(lysc_leaf, NULL, 0, 0x5, 1, "port", 0, 0, 0, NULL, 0, 0, NULL, NULL);
+ lysc_type = (struct lysc_type_bits *) lysc_leaf->type;
+ CHECK_LYSC_TYPE_BITS(lysc_type, 0, 2);
+ CHECK_LYSC_TYPE_BITENUM_ITEM(&(lysc_type->bits[0]), 2, NULL, 0, 0, "two", NULL);
+ CHECK_LYSC_TYPE_BITENUM_ITEM(&(lysc_type->bits[1]), 10, NULL, 0, 0, "ten", NULL);
+ lysp_leaf = (void *)mod->parsed->data;
+ CHECK_LYSP_NODE_LEAF(lysp_leaf, NULL, 0, 0x0, 0, "port", 0, 0, NULL, 0, 0, NULL, NULL);
+ CHECK_LYSP_TYPE(&(lysp_leaf->type), 0, 2, 0, 0, 0, 0x02, 0, 0, "my_type", 0, 0, 1, 0, 0, 0);
+
+ /*
+ * TEST ERROR
+ */
+ /* test change bit possition */
+ schema = MODULE_CREATE_YIN("TERR_0", "<typedef name=\"my_type\"> <type name=\"bits\">"
+ " <bit name=\"ten\"> <position value=\"10\"/> </bit>"
+ " <bit name=\"eleven\"/>"
+ " <bit name=\"two\"> <position value=\"2\"/> </bit>"
+ " <bit name=\"twelve\"/>"
+ "</type></typedef>"
+ "<leaf name=\"port\"> <type name=\"my_type\">"
+ " <bit name=\"ten\"> <position value=\"11\"/> </bit> <bit name=\"two\"/>"
+ "</type></leaf>");
+ UTEST_INVALID_MODULE(schema, LYS_IN_YIN, NULL, LY_EVALID);
+ CHECK_LOG_CTX("Invalid bits - position of the item \"ten\" has changed from 10 to 11 in the derived type.", "/TERR_0:port");
+
+ /* add new bit */
+ schema = MODULE_CREATE_YIN("TERR_1",
+ "<typedef name=\"my_type\"> <type name=\"bits\">"
+ " <bit name=\"ten\"> <position value=\"10\"/> </bit>"
+ " <bit name=\"eleven\"/>"
+ " <bit name=\"two\"> <position value=\"2\"/> </bit>"
+ " <bit name=\"twelve\"/>"
+ "</type></typedef>"
+ "<leaf name=\"port\"> <type name=\"my_type\">"
+ " <bit name=\"ten\"> <position value=\"10\"/> </bit>"
+ " <bit name=\"two\"/>"
+ " <bit name=\"test\"/>"
+ "</type></leaf>");
+ UTEST_INVALID_MODULE(schema, LYS_IN_YIN, NULL, LY_EVALID);
+ CHECK_LOG_CTX("Invalid bits - derived type adds new item \"test\".", "/TERR_1:port");
+
+ /* different max value => autoadd index */
+ schema = MODULE_CREATE_YIN("TERR_2",
+ "<leaf name=\"port\"> <type name=\"bits\">"
+ " <bit name=\"first\"> <position value=\"-1\"> </bit>"
+ " <bit name=\"second\">"
+ "</type></leaf>");
+ UTEST_INVALID_MODULE(schema, LYS_IN_YIN, NULL, LY_EVALID);
+ CHECK_LOG_CTX("Parsing module \"TERR_2\" failed.", NULL,
+ "Invalid value \"-1\" of \"value\" attribute in \"position\" element.", "Line number 8.");
+
+ /* different max value => autoadd index */
+ schema = MODULE_CREATE_YIN("TERR_3",
+ "<leaf name=\"port\"> <type name=\"bits\">"
+ " <bit name=\"first\"> <position value=\"4294967295\"/> </bit>"
+ " <bit name=\"second\"/>"
+ "</type></leaf>");
+ UTEST_INVALID_MODULE(schema, LYS_IN_YIN, NULL, LY_EVALID);
+ CHECK_LOG_CTX("Invalid bits - it is not possible to auto-assign bit position for \"second\" since the highest value is already 4294967295.",
+ "/TERR_3:port");
+
+ schema = MODULE_CREATE_YIN("TERR_4",
+ "<leaf name=\"port\"> <type name=\"bits\">"
+ " <bit name=\" ahoj \"> <position value=\"20\"/> </bit>"
+ " <bit name=\"second\"/>"
+ "</type></leaf>");
+ UTEST_INVALID_MODULE(schema, LYS_IN_YIN, NULL, LY_EVALID);
+ CHECK_LOG_CTX("Parsing module \"TERR_4\" failed.", NULL,
+ "Invalid identifier first character ' ' (0x0020).",
+ "Line number 8.");
+
+ schema = MODULE_CREATE_YIN("TERR_5",
+ "<leaf name=\"port\"> <type name=\"bits\">"
+ " <bit name=\"ah oj\"> <position value=\"20\"/> </bit>"
+ " <bit name=\"second\"/>"
+ "</type></leaf>");
+ UTEST_INVALID_MODULE(schema, LYS_IN_YIN, NULL, LY_EVALID);
+ CHECK_LOG_CTX("Parsing module \"TERR_5\" failed.", NULL,
+ "Invalid identifier character ' ' (0x0020).",
+ "Line number 8.");
+
+ schema = MODULE_CREATE_YIN("TERR_6",
+ "<leaf name=\"port\"> <type name=\"bits\">"
+ " <bit name=\"hi\"/> "
+ " <bit name=\"hi\"/>"
+ "</type></leaf>");
+ UTEST_INVALID_MODULE(schema, LYS_IN_YIN, NULL, LY_EVALID);
+ CHECK_LOG_CTX("Parsing module \"TERR_6\" failed.", NULL,
+ "Duplicate identifier \"hi\" of bit statement.",
+ "Line number 8.");
+
+ schema = MODULE_CREATE_YIN("TERR_7",
+ "<leaf name=\"port\"> <type name=\"bits\">"
+ " <bit name=\"4ahoj\"> <position value=\"20\"/> </bit>"
+ " <bit name=\"second\"/>"
+ "</type></leaf>");
+ UTEST_INVALID_MODULE(schema, LYS_IN_YIN, NULL, LY_EVALID);
+ CHECK_LOG_CTX("Parsing module \"TERR_7\" failed.", NULL,
+ "Invalid identifier first character '4' (0x0034).",
+ "Line number 8.");
+
+ /* TEST EMPTY NAME*/
+ schema = MODULE_CREATE_YIN("TERR_8",
+ "<leaf name=\"port\"> <type name=\"bits\">"
+ " <bit name=\"\"> <position value=\"20\"/> </bit>"
+ " <bit name=\"second\"/>"
+ "</type></leaf>");
+ UTEST_INVALID_MODULE(schema, LYS_IN_YIN, NULL, LY_EVALID);
+ CHECK_LOG_CTX("Parsing module \"TERR_8\" failed.", NULL,
+ "Empty identifier is not allowed.",
+ "Line number 8.");
+}
+
+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",
+ "typedef my_type{type bits {"
+ " bit ten {position 10;} bit eleven; bit two {position 2;} bit twelve;}}"
+ "leaf port {type my_type {"
+ " bit ten {position 10;} bit two;}}");
+
+ schema_yin = MODULE_CREATE_YIN("PRINT0",
+ " <typedef name=\"my_type\">\n"
+ " <type name=\"bits\">\n"
+ " <bit name=\"ten\">\n"
+ " <position value=\"10\"/>\n"
+ " </bit>\n"
+ " <bit name=\"eleven\"/>\n"
+ " <bit name=\"two\">\n"
+ " <position value=\"2\"/>\n"
+ " </bit>\n"
+ " <bit name=\"twelve\"/>\n"
+ " </type>\n"
+ " </typedef>\n"
+ " <leaf name=\"port\">\n"
+ " <type name=\"my_type\">\n"
+ " <bit name=\"ten\">\n"
+ " <position value=\"10\"/>\n"
+ " </bit>\n"
+ " <bit name=\"two\"/>\n"
+ " </type>\n"
+ " </leaf>\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"
+ " typedef my_type {\n"
+ " type bits {\n"
+ " bit ten {\n"
+ " position 10;\n"
+ " }\n"
+ " bit eleven;\n"
+ " bit two {\n"
+ " position 2;\n"
+ " }\n"
+ " bit twelve;\n"
+ " }\n"
+ " }\n\n"
+ " leaf port {\n"
+ " type my_type {\n"
+ " bit ten {\n"
+ " position 10;\n"
+ " }\n"
+ " bit two;\n"
+ " }\n"
+ " }\n");
+
+ schema_yin = MODULE_CREATE_YIN("PRINT1",
+ " <typedef name=\"my_type\">\n"
+ " <type name=\"bits\">\n"
+ " <bit name=\"ten\">\n"
+ " <position value=\"10\"/>\n"
+ " </bit>\n"
+ " <bit name=\"eleven\"/>\n"
+ " <bit name=\"two\">\n"
+ " <position value=\"2\"/>\n"
+ " </bit>\n"
+ " <bit name=\"twelve\"/>\n"
+ " </type>\n"
+ " </typedef>\n"
+ " <leaf name=\"port\">\n"
+ " <type name=\"my_type\">\n"
+ " <bit name=\"ten\">\n"
+ " <position value=\"10\"/>\n"
+ " </bit>\n"
+ " <bit name=\"two\"/>\n"
+ " </type>\n"
+ " </leaf>\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);
+}
+
+static void
+test_data_xml(void **state)
+{
+
+ const char *schema;
+ struct lyd_node *tree;
+ const char *data;
+
+ /* xml test */
+ schema = MODULE_CREATE_YANG("T0", "typedef my_type{type bits {"
+ " bit ten {position 10;} bit eleven; bit two {position 2;} bit twelve;"
+ " bit _test-end...;}}"
+ "leaf port {type my_type;}");
+ UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, NULL);
+
+ TEST_SUCCESS_XML("T0", "ten two twelve", BITS, "two ten twelve", "two", "ten", "twelve");
+ TEST_SUCCESS_XML("T0", "ten\ntwo\ttwelve", BITS, "two ten twelve", "two", "ten", "twelve");
+ TEST_SUCCESS_XML("T0", "ten two", BITS, "two ten", "two", "ten");
+ TEST_SUCCESS_XML("T0", "_test-end...", BITS, "_test-end...", "_test-end...");
+ TEST_SUCCESS_XML("T0", "twelve\nten\ttwo \n eleven", BITS, "two ten eleven twelve",
+ "two", "ten", "eleven", "twelve");
+ TEST_SUCCESS_XML("T0", "", BITS, "");
+ TEST_SUCCESS_XML("T0", "\n\t", BITS, "");
+
+ TEST_ERROR_XML("T0", "twelvea");
+ CHECK_LOG_CTX("Invalid bit \"twelvea\".",
+ "Schema location \"/T0:port\", line number 1.");
+ TEST_ERROR_XML("T0", "twelve t");
+ CHECK_LOG_CTX("Invalid bit \"t\".",
+ "Schema location \"/T0:port\", line number 1.");
+ TEST_ERROR_XML("T0", "ELEVEN");
+ CHECK_LOG_CTX("Invalid bit \"ELEVEN\".",
+ "Schema location \"/T0:port\", line number 1.");
+
+ /* empty value */
+ data = "<port xmlns=\"urn:tests:T0\"/>"; \
+ CHECK_PARSE_LYD_PARAM(data, LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_SUCCESS, tree);
+ CHECK_LYSC_NODE(tree->schema, NULL, 0, 0x5, 1, "port", 0, LYS_LEAF, 0, 0, 0, 0);
+ CHECK_LYD_NODE_TERM((struct lyd_node_term *)tree, 0, 0, 0, 0, 1, BITS, "");
+ lyd_free_all(tree);
+
+}
+
+static void
+test_data_json(void **state)
+{
+ const char *schema;
+
+ /* variable for default value test */
+
+ /* xml test */
+ schema = MODULE_CREATE_YANG("T0", "typedef my_type{type bits {"
+ " bit ten {position 10;} bit eleven; bit two {position 2;} bit twelve;"
+ " bit _test-end...;}}"
+ "leaf port {type my_type;}");
+ UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, NULL);
+
+ TEST_SUCCESS_JSON("T0", "ten two twelve", BITS, "two ten twelve", "two", "ten", "twelve");
+ TEST_SUCCESS_JSON("T0", "ten\\ntwo\\ttwelve", BITS, "two ten twelve", "two", "ten", "twelve");
+ TEST_SUCCESS_JSON("T0", "ten two", BITS, "two ten", "two", "ten");
+ TEST_SUCCESS_JSON("T0", "_test-end...", BITS, "_test-end...", "_test-end...");
+ TEST_SUCCESS_JSON("T0", "twelve\\nten\\ttwo \\n eleven", BITS, "two ten eleven twelve",
+ "two", "ten", "eleven", "twelve");
+ TEST_SUCCESS_JSON("T0", "", BITS, "");
+ TEST_SUCCESS_JSON("T0", "\\n\\t", BITS, "");
+
+ TEST_ERROR_JSON("T0", "twelvea");
+ CHECK_LOG_CTX("Invalid character sequence \"twelvea}\", expected a JSON value.",
+ "Line number 1.");
+ TEST_ERROR_JSON("T0", "twelve t");
+ CHECK_LOG_CTX("Invalid character sequence \"twelve t}\", expected a JSON value.",
+ "Line number 1.");
+ TEST_ERROR_JSON("T0", "ELEVEN");
+ CHECK_LOG_CTX("Invalid character sequence \"ELEVEN}\", expected a JSON value.",
+ "Line number 1.");
+}
+
+static void
+test_data_lyb(void **state)
+{
+ const char *schema;
+
+ schema = MODULE_CREATE_YANG("lyb", "typedef my_type{type bits {"
+ " bit ten {position 10;} bit eleven; bit two {position 2;} bit twelve;"
+ " bit _test-end...;}}"
+ "leaf port {type my_type;}");
+ UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, NULL);
+ TEST_SUCCESS_LYB("lyb", "port", "ten twelve");
+ TEST_SUCCESS_LYB("lyb", "port", "two");
+ TEST_SUCCESS_LYB("lyb", "port", "");
+}
+
+static void
+test_diff(void **state)
+{
+ const char *schema;
+ struct lyd_node *model_1, *model_2;
+ struct lyd_node *diff;
+ const char *expected_string;
+ const char *data_1;
+ const char *data_2;
+ const char *diff_expected;
+
+ schema = MODULE_CREATE_YANG("T0", "leaf port {type bits { bit zero; bit one;"
+ " bit two; bit three;}}");
+ UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, NULL);
+
+ data_1 = "<port xmlns=\"urn:tests:T0\"> two three </port>";
+ data_2 = "<port xmlns=\"urn:tests:T0\"> one</port>";
+ diff_expected = "<port xmlns=\"urn:tests:T0\""
+ " xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"replace\""
+ " yang:orig-default=\"false\" yang:orig-value=\"two three\">one</port>";
+ 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);
+
+ /* create data from diff */
+ diff_expected = "<port xmlns=\"urn:tests:T0\""
+ " xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"replace\""
+ " yang:orig-default=\"false\" yang:orig-value=\"two three \"></port>";
+ CHECK_PARSE_LYD_PARAM(diff_expected, LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_SUCCESS, diff)
+ data_1 = "<port xmlns=\"urn:tests:T0\"> two three </port>";
+ CHECK_PARSE_LYD_PARAM(data_1, LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_SUCCESS, model_1)
+ assert_int_equal(LY_SUCCESS, lyd_diff_apply_all(&model_1, diff));
+ expected_string = "<port xmlns=\"urn:tests:T0\"/>";
+
+ CHECK_LYD_STRING_PARAM(model_1, expected_string, LYD_XML, LYD_PRINT_WITHSIBLINGS | LYD_PRINT_SHRINK);
+ lyd_free_all(model_1);
+ lyd_free_all(diff);
+
+ /* create data from diff */
+ diff_expected = "<port xmlns=\"urn:tests:T0\""
+ " xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"replace\""
+ " yang:orig-default=\"false\" yang:orig-value=\"two three\"> one </port>";
+ CHECK_PARSE_LYD_PARAM(diff_expected, LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_SUCCESS, diff)
+ data_1 = "<port xmlns=\"urn:tests:T0\"> two three </port>";
+ CHECK_PARSE_LYD_PARAM(data_1, LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_SUCCESS, model_1)
+ assert_int_equal(LY_SUCCESS, lyd_diff_apply_all(&model_1, diff));
+ expected_string = "<port xmlns=\"urn:tests:T0\">one</port>";
+
+ CHECK_LYD_STRING_PARAM(model_1, expected_string, LYD_XML, LYD_PRINT_WITHSIBLINGS | LYD_PRINT_SHRINK);
+ lyd_free_all(model_1);
+ lyd_free_all(diff);
+
+}
+
+static void
+test_print(void **state)
+{
+ const char *schema;
+ const char *expected_string;
+ struct lyd_node *model_1;
+ const char *data;
+
+ schema = MODULE_CREATE_YANG("T0", "leaf port {type bits { bit zero; bit one;"
+ " bit two; bit three;}}");
+ UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, NULL);
+
+ /* print zero bits */
+ data = "<port xmlns=\"urn:tests:T0\"></port>";
+ CHECK_PARSE_LYD_PARAM(data, LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_SUCCESS, model_1)
+ /* XML */
+ expected_string = "<port xmlns=\"urn:tests:T0\"/>";
+ CHECK_LYD_STRING_PARAM(model_1, expected_string, LYD_XML, LYD_PRINT_SHRINK | LYD_PRINT_WITHSIBLINGS | LYD_PRINT_SHRINK);
+ /* JSON */
+ expected_string = "{\"T0:port\":\"\"}";
+ CHECK_LYD_STRING_PARAM(model_1, expected_string, LYD_JSON, LYD_PRINT_SHRINK | LYD_PRINT_WITHSIBLINGS | LYD_PRINT_SHRINK);
+ /* free */
+ lyd_free_all(model_1);
+
+ /* print one bit */
+ data = "<port xmlns=\"urn:tests:T0\"> two </port>";
+ CHECK_PARSE_LYD_PARAM(data, LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_SUCCESS, model_1)
+ /* XML */
+ expected_string = "<port xmlns=\"urn:tests:T0\">two</port>";
+ CHECK_LYD_STRING_PARAM(model_1, expected_string, LYD_XML, LYD_PRINT_SHRINK | LYD_PRINT_WITHSIBLINGS | LYD_PRINT_SHRINK);
+ /* JSON */
+ expected_string = "{\"T0:port\":\"two\"}";
+ CHECK_LYD_STRING_PARAM(model_1, expected_string, LYD_JSON, LYD_PRINT_SHRINK | LYD_PRINT_WITHSIBLINGS | LYD_PRINT_SHRINK);
+ /* free */
+ lyd_free_all(model_1);
+
+ /* print two bits */
+ data = "<port xmlns=\"urn:tests:T0\">three two </port>";
+ CHECK_PARSE_LYD_PARAM(data, LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_SUCCESS, model_1)
+ /* XML */
+ expected_string = "<port xmlns=\"urn:tests:T0\">two three</port>";
+ CHECK_LYD_STRING_PARAM(model_1, expected_string, LYD_XML, LYD_PRINT_SHRINK | LYD_PRINT_WITHSIBLINGS | LYD_PRINT_SHRINK);
+ /* JSON */
+ expected_string = "{\"T0:port\":\"two three\"}";
+ CHECK_LYD_STRING_PARAM(model_1, expected_string, LYD_JSON, LYD_PRINT_SHRINK | LYD_PRINT_WITHSIBLINGS | LYD_PRINT_SHRINK);
+ /* free */
+ lyd_free_all(model_1);
+}
+
+static void
+test_plugin_store(void **state)
+{
+ const char *val_text = NULL;
+ struct ly_err_item *err = NULL;
+ struct lys_module *mod;
+ struct lyd_value value = {0};
+ struct lyplg_type *type = lyplg_type_plugin_find("", NULL, ly_data_type2str[LY_TYPE_BITS]);
+ struct lysc_type *lysc_type;
+ struct lysc_type lysc_type_test;
+ LY_ERR ly_ret;
+ char *alloc;
+ const char *schema;
+
+ /* create schema. Prepare common used variables */
+ schema = MODULE_CREATE_YANG("T0", "leaf port {type bits { bit zero; bit one;"
+ " bit two; bit three;}}");
+ UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, &mod);
+ lysc_type = ((struct lysc_node_leaf *)mod->compiled->data)->type;
+
+ /* check proper type */
+ assert_string_equal("libyang 2 - bits, version 1", type->id);
+
+ /* check store
+ */
+ val_text = "";
+ assert_int_equal(LY_SUCCESS, type->store(UTEST_LYCTX, lysc_type, val_text, strlen(val_text),
+ 0, LY_VALUE_XML, NULL, LYD_VALHINT_STRING, NULL, &value, NULL, &err));
+ CHECK_LYD_VALUE(value, BITS, "");
+ assert_ptr_equal(value.realtype, lysc_type);
+ type->free(UTEST_LYCTX, &value);
+
+ val_text = "zero one two";
+ assert_int_equal(LY_SUCCESS, type->store(UTEST_LYCTX, lysc_type, val_text, strlen(val_text),
+ 0, LY_VALUE_XML, NULL, LYD_VALHINT_STRING, NULL, &value, NULL, &err));
+ CHECK_LYD_VALUE(value, BITS, "zero one two", "zero", "one", "two");
+ assert_ptr_equal(value.realtype, lysc_type);
+ type->free(UTEST_LYCTX, &value);
+
+ val_text = "zero two";
+ assert_int_equal(LY_SUCCESS, type->store(UTEST_LYCTX, lysc_type, val_text, strlen(val_text),
+ 0, LY_VALUE_XML, NULL, LYD_VALHINT_STRING, NULL, &value, NULL, &err));
+ CHECK_LYD_VALUE(value, BITS, "zero two", "zero", "two");
+ assert_ptr_equal(value.realtype, lysc_type);
+ type->free(UTEST_LYCTX, &value);
+
+ val_text = "\n ";
+ ly_ret = type->store(UTEST_LYCTX, lysc_type, val_text, strlen(val_text),
+ 0, LY_VALUE_XML, NULL, LYD_VALHINT_STRING, NULL, &value, NULL, &err);
+ assert_int_equal(LY_SUCCESS, ly_ret);
+ CHECK_LYD_VALUE(value, BITS, "");
+ assert_ptr_equal(value.realtype, lysc_type);
+ type->free(UTEST_LYCTX, &value);
+
+ /*
+ * minor tests
+ * dynamic alocated input text
+ */
+ val_text = "two";
+ alloc = (char *)malloc(strlen(val_text) + 1);
+ memcpy(alloc, val_text, strlen(val_text) + 1);
+ ly_ret = type->store(UTEST_LYCTX, lysc_type, alloc, strlen(val_text),
+ LYPLG_TYPE_STORE_DYNAMIC, LY_VALUE_XML, NULL, LYD_VALHINT_STRING, NULL, &value, NULL, &err);
+ alloc = NULL;
+ assert_int_equal(LY_SUCCESS, ly_ret);
+ CHECK_LYD_VALUE(value, BITS, "two", "two");
+ type->free(UTEST_LYCTX, &value);
+
+ /* wrong lysc_type of value */
+ lysc_type_test = *lysc_type;
+ lysc_type_test.basetype = LY_TYPE_INT8;
+ val_text = "two";
+ ly_ret = type->store(UTEST_LYCTX, &lysc_type_test, val_text, strlen(val_text),
+ 0, LY_VALUE_XML, NULL, LYD_VALHINT_STRING, NULL, &value, NULL, &err);
+ assert_int_equal(LY_EINVAL, ly_ret);
+ ly_err_free(err);
+
+ /*
+ * ERROR TESTS
+ */
+ val_text = "two";
+ err = NULL;
+ ly_ret = type->store(UTEST_LYCTX, lysc_type, val_text, strlen(val_text),
+ 0, LY_VALUE_XML, NULL, LYD_VALHINT_HEXNUM, NULL, &value, NULL, &err);
+ assert_int_equal(LY_EVALID, ly_ret);
+ ly_err_free(err);
+
+ val_text = "two two";
+ err = NULL;
+ ly_ret = type->store(UTEST_LYCTX, lysc_type, val_text, strlen(val_text),
+ 0, LY_VALUE_XML, NULL, LYD_VALHINT_STRING, NULL, &value, NULL, &err);
+ assert_int_equal(LY_EVALID, ly_ret);
+ ly_err_free(err);
+}
+
+static void
+test_plugin_compare(void **state)
+{
+ struct ly_err_item *err = NULL;
+ struct lys_module *mod;
+ struct lyd_value values[10];
+ struct lyplg_type *type = lyplg_type_plugin_find("", NULL, ly_data_type2str[LY_TYPE_BITS]);
+ struct lysc_type *lysc_type;
+ LY_ERR ly_ret;
+ const char *schema;
+ /* different type */
+ const char *diff_type_text = "20";
+ struct lyd_value diff_type_val;
+ struct lysc_type *diff_type;
+ /* Value which are going to be created to tested */
+ const char *val_init[] = {"", "two zero", "three", "zero two", "zero", "three"};
+
+ /* create schema. Prepare common used variables */
+ schema = MODULE_CREATE_YANG("T0", "typedef my_int_type { type bits { bit zero; bit one;"
+ " bit two; bit three;}}"
+ "leaf p1 {type my_int_type;}"
+ "leaf p2 {type my_int_type;}"
+ "leaf p3 {type my_int_type{bit three; bit zero;}}"
+ "leaf p4 {type string;}");
+ UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, &mod);
+ lysc_type = ((struct lysc_node_leaf *)mod->compiled->data)->type;
+
+ /* CREATE VALUES */
+ for (unsigned int it = 0; it < sizeof(val_init) / sizeof(val_init[0]); it++) {
+ ly_ret = type->store(UTEST_LYCTX, lysc_type, val_init[it], strlen(val_init[it]),
+ 0, LY_VALUE_XML, NULL, LYD_VALHINT_STRING, NULL, &(values[it]), NULL, &err);
+ assert_int_equal(LY_SUCCESS, ly_ret);
+ }
+
+ /*
+ * BASIC TEST;
+ */
+ assert_int_equal(LY_SUCCESS, type->compare(&(values[0]), &(values[0])));
+ assert_int_equal(LY_SUCCESS, type->compare(&(values[1]), &(values[3])));
+ assert_int_equal(LY_ENOT, type->compare(&(values[0]), &(values[1])));
+ assert_int_equal(LY_ENOT, type->compare(&(values[3]), &(values[4])));
+ assert_int_equal(LY_ENOT, type->compare(&(values[1]), &(values[0])));
+ assert_int_equal(LY_ENOT, type->compare(&(values[1]), &(values[2])));
+ assert_int_equal(LY_SUCCESS, type->compare(&(values[2]), &(values[5])));
+
+ /*
+ * SAME TYPE but different node
+ */
+ diff_type_text = val_init[2];
+ diff_type = ((struct lysc_node_leaf *)mod->compiled->data->next)->type;
+ ly_ret = diff_type->plugin->store(UTEST_LYCTX, diff_type, diff_type_text, strlen(diff_type_text),
+ 0, LY_VALUE_XML, NULL, LYD_VALHINT_STRING, NULL, &diff_type_val, NULL, &err);
+ assert_int_equal(LY_SUCCESS, ly_ret);
+ assert_int_equal(LY_SUCCESS, type->compare(&diff_type_val, &(values[2])));
+ assert_int_equal(LY_ENOT, type->compare(&diff_type_val, &(values[1])));
+ type->free(UTEST_LYCTX, &(diff_type_val));
+
+ /*
+ * derivated type add some limitations
+ */
+ diff_type_text = val_init[2];
+ diff_type = ((struct lysc_node_leaf *)mod->compiled->data->next->next)->type;
+ ly_ret = diff_type->plugin->store(UTEST_LYCTX, diff_type, diff_type_text, strlen(diff_type_text),
+ 0, LY_VALUE_XML, NULL, LYD_VALHINT_STRING, NULL, &diff_type_val, NULL, &err);
+ assert_int_equal(LY_SUCCESS, ly_ret);
+ assert_int_equal(LY_ENOT, type->compare(&diff_type_val, &(values[2])));
+ assert_int_equal(LY_ENOT, type->compare(&diff_type_val, &(values[1])));
+ type->free(UTEST_LYCTX, &(diff_type_val));
+
+ /*
+ * different type (STRING)
+ */
+ diff_type_text = val_init[2];
+ diff_type = ((struct lysc_node_leaf *)mod->compiled->data->next->next->next)->type;
+ ly_ret = diff_type->plugin->store(UTEST_LYCTX, diff_type, diff_type_text, strlen(diff_type_text),
+ 0, LY_VALUE_XML, NULL, LYD_VALHINT_STRING, NULL, &diff_type_val, NULL, &err);
+ assert_int_equal(LY_SUCCESS, ly_ret);
+ assert_int_equal(LY_ENOT, type->compare(&diff_type_val, &(values[2])));
+ assert_int_equal(LY_ENOT, type->compare(&diff_type_val, &(values[0])));
+ type->free(UTEST_LYCTX, &(diff_type_val));
+
+ /* delete values */
+ for (unsigned int it = 0; it < sizeof(val_init) / sizeof(val_init[0]); it++) {
+ type->free(UTEST_LYCTX, &(values[it]));
+ }
+}
+
+static void
+test_plugin_print(void **state)
+{
+ struct ly_err_item *err = NULL;
+ struct lys_module *mod;
+ struct lyd_value values[10];
+ struct lyplg_type *type = lyplg_type_plugin_find("", NULL, ly_data_type2str[LY_TYPE_BITS]);
+ struct lysc_type *lysc_type;
+ LY_ERR ly_ret;
+ const char *schema;
+ /* Value which are going to be created to tested */
+ const char *val_init[] = {"", "two zero", "three", "zero two", "zero", "three"};
+
+ /* create schema. Prepare common used variables */
+ schema = MODULE_CREATE_YANG("T0",
+ "leaf p1 { type bits { bit zero; bit one;"
+ " bit two; bit three;}}");
+ UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, &mod);
+ lysc_type = ((struct lysc_node_leaf *)mod->compiled->data)->type;
+
+ /* CREATE VALUES */
+ for (unsigned int it = 0; it < sizeof(val_init) / sizeof(val_init[0]); it++) {
+ ly_ret = type->store(UTEST_LYCTX, lysc_type, val_init[it], strlen(val_init[it]),
+ 0, LY_VALUE_XML, NULL, LYD_VALHINT_STRING, NULL, &(values[it]), NULL, &err);
+ assert_int_equal(LY_SUCCESS, ly_ret);
+ }
+
+ /* print value */
+ ly_bool dynamic = 0;
+
+ assert_string_equal("", type->print(UTEST_LYCTX, &(values[0]), LY_VALUE_XML, NULL, &dynamic, NULL));
+ assert_string_equal("zero two", type->print(UTEST_LYCTX, &(values[1]), LY_VALUE_XML, NULL, &dynamic, NULL));
+ assert_string_equal("three", type->print(UTEST_LYCTX, &(values[2]), LY_VALUE_XML, NULL, &dynamic, NULL));
+ assert_string_equal("zero two", type->print(UTEST_LYCTX, &(values[3]), LY_VALUE_XML, NULL, &dynamic, NULL));
+ assert_string_equal("zero", type->print(UTEST_LYCTX, &(values[4]), LY_VALUE_XML, NULL, &dynamic, NULL));
+ assert_string_equal("three", type->print(UTEST_LYCTX, &(values[5]), LY_VALUE_XML, NULL, &dynamic, NULL));
+
+ for (unsigned int it = 0; it < sizeof(val_init) / sizeof(val_init[0]); it++) {
+ type->free(UTEST_LYCTX, &(values[it]));
+ }
+}
+
+static void
+test_plugin_dup(void **state)
+{
+ struct ly_err_item *err = NULL;
+ struct lys_module *mod;
+ struct lyd_value values[10];
+ struct lyplg_type *type = lyplg_type_plugin_find("", NULL, ly_data_type2str[LY_TYPE_BITS]);
+ struct lysc_type *lysc_type;
+ const char *schema;
+ LY_ERR ly_ret;
+ /* Value which are going to be tested */
+ const char *val_init[] = {"", "two zero", "three", "zero two", "zero", "three one two zero"};
+
+ /* create schema. Prepare common used variables */
+ schema = MODULE_CREATE_YANG("T0",
+ "leaf p1 { type bits { bit zero; bit one;"
+ " bit two; bit three;}}");
+ UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, &mod);
+ lysc_type = ((struct lysc_node_leaf *)mod->compiled->data)->type;
+
+ /* CREATE VALUES */
+ for (unsigned int it = 0; it < sizeof(val_init) / sizeof(val_init[0]); it++) {
+ ly_ret = type->store(UTEST_LYCTX, lysc_type, val_init[it], strlen(val_init[it]),
+ 0, LY_VALUE_XML, NULL, LYD_VALHINT_STRING, NULL, &(values[it]), NULL, &err);
+ assert_int_equal(LY_SUCCESS, ly_ret);
+ }
+
+ /* print duplicate value */
+ struct lyd_value dup_value;
+
+ assert_int_equal(LY_SUCCESS, type->duplicate(UTEST_LYCTX, &(values[0]), &dup_value));
+ CHECK_LYD_VALUE(dup_value, BITS, "");
+ assert_ptr_equal(dup_value.realtype, values[0].realtype);
+ type->free(UTEST_LYCTX, &dup_value);
+
+ assert_int_equal(LY_SUCCESS, type->duplicate(UTEST_LYCTX, &(values[1]), &dup_value));
+ CHECK_LYD_VALUE(dup_value, BITS, "zero two", "zero", "two");
+ assert_ptr_equal(dup_value.realtype, values[1].realtype);
+ type->free(UTEST_LYCTX, &dup_value);
+
+ assert_int_equal(LY_SUCCESS, type->duplicate(UTEST_LYCTX, &(values[2]), &dup_value));
+ CHECK_LYD_VALUE(dup_value, BITS, "three", "three");
+ assert_ptr_equal(dup_value.realtype, values[2].realtype);
+ type->free(UTEST_LYCTX, &dup_value);
+
+ assert_int_equal(LY_SUCCESS, type->duplicate(UTEST_LYCTX, &(values[3]), &dup_value));
+ CHECK_LYD_VALUE(dup_value, BITS, "zero two", "zero", "two");
+ assert_ptr_equal(dup_value.realtype, values[3].realtype);
+ type->free(UTEST_LYCTX, &dup_value);
+
+ assert_int_equal(LY_SUCCESS, type->duplicate(UTEST_LYCTX, &(values[4]), &dup_value));
+ CHECK_LYD_VALUE(dup_value, BITS, "zero", "zero");
+ assert_ptr_equal(dup_value.realtype, values[4].realtype);
+ type->free(UTEST_LYCTX, &dup_value);
+
+ assert_int_equal(LY_SUCCESS, type->duplicate(UTEST_LYCTX, &(values[5]), &dup_value));
+ CHECK_LYD_VALUE(dup_value, BITS, "zero one two three", "zero", "one", "two", "three");
+ assert_ptr_equal(dup_value.realtype, values[5].realtype);
+ type->free(UTEST_LYCTX, &dup_value);
+
+ /* error tests */
+ assert_int_equal(LY_EINVAL, type->duplicate(NULL, &(values[0]), &dup_value));
+
+ for (unsigned int it = 0; it < sizeof(val_init) / sizeof(val_init[0]); it++) {
+ type->free(UTEST_LYCTX, &(values[it]));
+ }
+}
+
+int
+main(void)
+{
+ const struct CMUnitTest tests[] = {
+ UTEST(test_schema_yang),
+ UTEST(test_schema_yin),
+ UTEST(test_schema_print),
+ UTEST(test_data_xml),
+ UTEST(test_data_json),
+ UTEST(test_data_lyb),
+ UTEST(test_diff),
+ UTEST(test_print),
+
+ UTEST(test_plugin_store),
+ UTEST(test_plugin_compare),
+ UTEST(test_plugin_print),
+ UTEST(test_plugin_dup),
+ };
+
+ return cmocka_run_group_tests(tests, NULL, NULL);
+}
diff --git a/tests/utests/types/boolean.c b/tests/utests/types/boolean.c
new file mode 100644
index 0000000..841db2a
--- /dev/null
+++ b/tests/utests/types/boolean.c
@@ -0,0 +1,111 @@
+/**
+ * @file boolean.c
+ * @author Adam Piecek <piecek@cesnet.cz>
+ * @brief test for built-in enumeration type
+ *
+ * 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"
+
+/* LOCAL INCLUDE HEADERS */
+#include "libyang.h"
+
+#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"
+
+#define TEST_SUCCESS_XML(MOD_NAME, NODE_NAME, DATA, TYPE, ...) \
+ { \
+ struct lyd_node *tree; \
+ const char *data = "<" NODE_NAME " xmlns=\"urn:tests:" MOD_NAME "\">" DATA "</" NODE_NAME ">"; \
+ CHECK_PARSE_LYD_PARAM(data, LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_SUCCESS, tree); \
+ CHECK_LYD_NODE_TERM((struct lyd_node_term *)tree, 0, 0, 0, 0, 1, TYPE, __VA_ARGS__); \
+ lyd_free_all(tree); \
+ }
+
+#define TEST_ERROR_XML(MOD_NAME, NODE_NAME, DATA) \
+ {\
+ struct lyd_node *tree; \
+ const char *data = "<" NODE_NAME " xmlns=\"urn:tests:" MOD_NAME "\">" DATA "</" NODE_NAME ">"; \
+ CHECK_PARSE_LYD_PARAM(data, LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_EVALID, tree); \
+ assert_null(tree); \
+ }
+
+#define TEST_SUCCESS_LYB(MOD_NAME, NODE_NAME, DATA) \
+ { \
+ struct lyd_node *tree_1; \
+ struct lyd_node *tree_2; \
+ char *xml_out, *data; \
+ data = "<" NODE_NAME " xmlns=\"urn:tests:" MOD_NAME "\">" DATA "</" NODE_NAME ">"; \
+ CHECK_PARSE_LYD_PARAM(data, LYD_XML, LYD_PARSE_ONLY | LYD_PARSE_STRICT, 0, LY_SUCCESS, tree_1); \
+ assert_int_equal(lyd_print_mem(&xml_out, tree_1, LYD_LYB, LYD_PRINT_WITHSIBLINGS), 0); \
+ assert_int_equal(LY_SUCCESS, lyd_parse_data_mem(UTEST_LYCTX, xml_out, LYD_LYB, LYD_PARSE_ONLY | LYD_PARSE_STRICT, 0, &tree_2)); \
+ assert_non_null(tree_2); \
+ CHECK_LYD(tree_1, tree_2); \
+ free(xml_out); \
+ lyd_free_all(tree_1); \
+ lyd_free_all(tree_2); \
+ }
+
+static void
+test_data_xml(void **state)
+{
+ const char *schema;
+
+ /* xml test */
+ schema = MODULE_CREATE_YANG("defs", "typedef tboolean {type boolean;}"
+ "leaf l1 {type boolean;}"
+ "leaf l2 {type tboolean;}");
+ UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, NULL);
+
+ TEST_SUCCESS_XML("defs", "l1", "true", BOOL, "true", 1);
+
+ TEST_SUCCESS_XML("defs", "l1", "false", BOOL, "false", 0);
+
+ TEST_SUCCESS_XML("defs", "l2", "false", BOOL, "false", 0);
+
+ /* invalid value */
+ TEST_ERROR_XML("defs", "l1", "unsure");
+ CHECK_LOG_CTX("Invalid boolean value \"unsure\".",
+ "Schema location \"/defs:l1\", line number 1.");
+
+ TEST_ERROR_XML("defs", "l1", " true");
+ CHECK_LOG_CTX("Invalid boolean value \" true\".",
+ "Schema location \"/defs:l1\", line number 1.");
+}
+
+static void
+test_plugin_lyb(void **state)
+{
+ const char *schema;
+
+ schema = MODULE_CREATE_YANG("lyb",
+ "leaf bool {type boolean;}");
+ UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, NULL);
+ TEST_SUCCESS_LYB("lyb", "bool", "true");
+ TEST_SUCCESS_LYB("lyb", "bool", "false");
+}
+
+int
+main(void)
+{
+ const struct CMUnitTest tests[] = {
+ UTEST(test_data_xml),
+ UTEST(test_plugin_lyb),
+ };
+
+ return cmocka_run_group_tests(tests, NULL, NULL);
+}
diff --git a/tests/utests/types/decimal64.c b/tests/utests/types/decimal64.c
new file mode 100644
index 0000000..e0a7cab
--- /dev/null
+++ b/tests/utests/types/decimal64.c
@@ -0,0 +1,125 @@
+/**
+ * @file decimal64.c
+ * @author Adam Piecek <piecek@cesnet.cz>
+ * @brief test for built-in enumeration type
+ *
+ * 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"
+
+/* LOCAL INCLUDE HEADERS */
+#include "libyang.h"
+
+#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"
+
+#define TEST_SUCCESS_XML(MOD_NAME, NODE_NAME, DATA, TYPE, ...) \
+ { \
+ struct lyd_node *tree; \
+ const char *data = "<" NODE_NAME " xmlns=\"urn:tests:" MOD_NAME "\">" DATA "</" NODE_NAME ">"; \
+ CHECK_PARSE_LYD_PARAM(data, LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_SUCCESS, tree); \
+ CHECK_LYD_NODE_TERM((struct lyd_node_term *)tree, 0, 0, 0, 0, 1, TYPE, __VA_ARGS__); \
+ lyd_free_all(tree); \
+ }
+
+#define TEST_ERROR_XML(MOD_NAME, NODE_NAME, DATA) \
+ {\
+ struct lyd_node *tree; \
+ const char *data = "<" NODE_NAME " xmlns=\"urn:tests:" MOD_NAME "\">" DATA "</" NODE_NAME ">"; \
+ CHECK_PARSE_LYD_PARAM(data, LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_EVALID, tree); \
+ assert_null(tree); \
+ }
+
+#define TEST_SUCCESS_LYB(MOD_NAME, NODE_NAME, DATA) \
+ { \
+ struct lyd_node *tree_1; \
+ struct lyd_node *tree_2; \
+ char *xml_out, *data; \
+ data = "<" NODE_NAME " xmlns=\"urn:tests:" MOD_NAME "\">" DATA "</" NODE_NAME ">"; \
+ CHECK_PARSE_LYD_PARAM(data, LYD_XML, LYD_PARSE_ONLY | LYD_PARSE_STRICT, 0, LY_SUCCESS, tree_1); \
+ assert_int_equal(lyd_print_mem(&xml_out, tree_1, LYD_LYB, LYD_PRINT_WITHSIBLINGS), 0); \
+ assert_int_equal(LY_SUCCESS, lyd_parse_data_mem(UTEST_LYCTX, xml_out, LYD_LYB, LYD_PARSE_ONLY | LYD_PARSE_STRICT, 0, &tree_2)); \
+ assert_non_null(tree_2); \
+ CHECK_LYD(tree_1, tree_2); \
+ free(xml_out); \
+ lyd_free_all(tree_1); \
+ lyd_free_all(tree_2); \
+ }
+
+static void
+test_data_xml(void **state)
+{
+ const char *schema;
+
+ /* xml test */
+ schema = MODULE_CREATE_YANG("defs", "leaf l1 {type decimal64 {fraction-digits 1; range 1.5..10;}}"
+ "leaf l2 {type decimal64 {fraction-digits 18;}}");
+ UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, NULL);
+
+ TEST_SUCCESS_XML("defs", "l1", "\n +8 \t\n ", DEC64, "8.0", 80);
+ TEST_SUCCESS_XML("defs", "l1", "8.00", DEC64, "8.0", 80);
+
+ TEST_SUCCESS_XML("defs", "l2", "-9.223372036854775808", DEC64, "-9.223372036854775808",
+ INT64_C(-9223372036854775807) - INT64_C(1));
+ TEST_SUCCESS_XML("defs", "l2", "9.223372036854775807", DEC64, "9.223372036854775807", INT64_C(9223372036854775807));
+
+ TEST_ERROR_XML("defs", "l1", "\n 15 \t\n ");
+ CHECK_LOG_CTX("Unsatisfied range - value \"15.0\" is out of the allowed range.",
+ "Schema location \"/defs:l1\", line number 3.");
+
+ TEST_ERROR_XML("defs", "l1", "\n 0 \t\n ");
+ CHECK_LOG_CTX("Unsatisfied range - value \"0.0\" is out of the allowed range.",
+ "Schema location \"/defs:l1\", line number 3.");
+
+ TEST_ERROR_XML("defs", "l1", "xxx");
+ CHECK_LOG_CTX("Invalid 1. character of decimal64 value \"xxx\".",
+ "Schema location \"/defs:l1\", line number 1.");
+
+ TEST_ERROR_XML("defs", "l1", "");
+ CHECK_LOG_CTX("Invalid empty decimal64 value.",
+ "Schema location \"/defs:l1\", line number 1.");
+
+ TEST_ERROR_XML("defs", "l1", "8.5 xxx");
+ CHECK_LOG_CTX("Invalid 6. character of decimal64 value \"8.5 xxx\".",
+ "Schema location \"/defs:l1\", line number 1.");
+
+ TEST_ERROR_XML("defs", "l1", "8.55 xxx");
+ CHECK_LOG_CTX("Value \"8.55\" of decimal64 type exceeds defined number (1) of fraction digits.",
+ "Schema location \"/defs:l1\", line number 1.");
+}
+
+static void
+test_plugin_lyb(void **state)
+{
+ const char *schema;
+
+ schema = MODULE_CREATE_YANG("lyb",
+ "leaf dec64 {type decimal64 {fraction-digits 1; range 1.5..10;}}");
+ UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, NULL);
+ TEST_SUCCESS_LYB("lyb", "dec64", "8.00");
+}
+
+int
+main(void)
+{
+ const struct CMUnitTest tests[] = {
+ UTEST(test_data_xml),
+ UTEST(test_plugin_lyb),
+ };
+
+ return cmocka_run_group_tests(tests, NULL, NULL);
+}
diff --git a/tests/utests/types/empty.c b/tests/utests/types/empty.c
new file mode 100644
index 0000000..0ab9710
--- /dev/null
+++ b/tests/utests/types/empty.c
@@ -0,0 +1,108 @@
+/**
+ * @file empty.c
+ * @author Adam Piecek <piecek@cesnet.cz>
+ * @brief test for built-in enumeration type
+ *
+ * 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"
+
+/* LOCAL INCLUDE HEADERS */
+#include "libyang.h"
+
+#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"
+
+#define TEST_SUCCESS_XML(MOD_NAME, NODE_NAME, DATA, TYPE, ...) \
+ { \
+ struct lyd_node *tree; \
+ const char *data = "<" NODE_NAME " xmlns=\"urn:tests:" MOD_NAME "\">" DATA "</" NODE_NAME ">"; \
+ CHECK_PARSE_LYD_PARAM(data, LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_SUCCESS, tree); \
+ CHECK_LYD_NODE_TERM((struct lyd_node_term *)tree, 0, 0, 0, 0, 1, TYPE, __VA_ARGS__); \
+ lyd_free_all(tree); \
+ }
+
+#define TEST_ERROR_XML(MOD_NAME, NODE_NAME, DATA) \
+ {\
+ struct lyd_node *tree; \
+ const char *data = "<" NODE_NAME " xmlns=\"urn:tests:" MOD_NAME "\">" DATA "</" NODE_NAME ">"; \
+ CHECK_PARSE_LYD_PARAM(data, LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_EVALID, tree); \
+ assert_null(tree); \
+ }
+
+#define TEST_SUCCESS_LYB(MOD_NAME, NODE_NAME, DATA) \
+ { \
+ struct lyd_node *tree_1; \
+ struct lyd_node *tree_2; \
+ char *xml_out, *data; \
+ data = "<" NODE_NAME " xmlns=\"urn:tests:" MOD_NAME "\">" DATA "</" NODE_NAME ">"; \
+ CHECK_PARSE_LYD_PARAM(data, LYD_XML, LYD_PARSE_ONLY | LYD_PARSE_STRICT, 0, LY_SUCCESS, tree_1); \
+ assert_int_equal(lyd_print_mem(&xml_out, tree_1, LYD_LYB, LYD_PRINT_WITHSIBLINGS), 0); \
+ assert_int_equal(LY_SUCCESS, lyd_parse_data_mem(UTEST_LYCTX, xml_out, LYD_LYB, LYD_PARSE_ONLY | LYD_PARSE_STRICT, 0, &tree_2)); \
+ assert_non_null(tree_2); \
+ CHECK_LYD(tree_1, tree_2); \
+ free(xml_out); \
+ lyd_free_all(tree_1); \
+ lyd_free_all(tree_2); \
+ }
+
+static void
+test_data_xml(void **state)
+{
+ const char *schema;
+
+ /* xml test */
+ schema = MODULE_CREATE_YANG("defs", "typedef tempty {type empty;}"
+ "leaf l1 {type empty;}"
+ "leaf l2 {type tempty;}");
+ UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, NULL);
+
+ TEST_SUCCESS_XML("defs", "l1", "", EMPTY, "");
+
+ TEST_SUCCESS_XML("defs", "l2", "", EMPTY, "");
+
+ /* invalid value */
+ TEST_ERROR_XML("defs", "l1", "x");
+ CHECK_LOG_CTX("Invalid empty value length 1.",
+ "Schema location \"/defs:l1\", line number 1.");
+
+ TEST_ERROR_XML("defs", "l1", " ");
+ CHECK_LOG_CTX("Invalid empty value length 1.",
+ "Schema location \"/defs:l1\", line number 1.");
+}
+
+static void
+test_plugin_lyb(void **state)
+{
+ const char *schema;
+
+ schema = MODULE_CREATE_YANG("lyb",
+ "leaf empty {type empty;}");
+ UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, NULL);
+ TEST_SUCCESS_LYB("lyb", "empty", "");
+}
+
+int
+main(void)
+{
+ const struct CMUnitTest tests[] = {
+ UTEST(test_data_xml),
+ UTEST(test_plugin_lyb),
+ };
+
+ return cmocka_run_group_tests(tests, NULL, NULL);
+}
diff --git a/tests/utests/types/enumeration.c b/tests/utests/types/enumeration.c
new file mode 100644
index 0000000..660479f
--- /dev/null
+++ b/tests/utests/types/enumeration.c
@@ -0,0 +1,114 @@
+/**
+ * @file enumeration.c
+ * @author Adam Piecek <piecek@cesnet.cz>
+ * @brief test for built-in enumeration type
+ *
+ * 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"
+
+/* LOCAL INCLUDE HEADERS */
+#include "libyang.h"
+
+#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"
+
+#define TEST_SUCCESS_XML(MOD_NAME, NODE_NAME, DATA, TYPE, ...) \
+ { \
+ struct lyd_node *tree; \
+ const char *data = "<" NODE_NAME " xmlns=\"urn:tests:" MOD_NAME "\">" DATA "</" NODE_NAME ">"; \
+ CHECK_PARSE_LYD_PARAM(data, LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_SUCCESS, tree); \
+ CHECK_LYD_NODE_TERM((struct lyd_node_term *)tree, 0, 0, 0, 0, 1, TYPE, __VA_ARGS__); \
+ lyd_free_all(tree); \
+ }
+
+#define TEST_ERROR_XML(MOD_NAME, NODE_NAME, DATA) \
+ {\
+ struct lyd_node *tree; \
+ const char *data = "<" NODE_NAME " xmlns=\"urn:tests:" MOD_NAME "\">" DATA "</" NODE_NAME ">"; \
+ CHECK_PARSE_LYD_PARAM(data, LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_EVALID, tree); \
+ assert_null(tree); \
+ }
+
+#define TEST_SUCCESS_LYB(MOD_NAME, NODE_NAME, DATA) \
+ { \
+ struct lyd_node *tree_1; \
+ struct lyd_node *tree_2; \
+ char *xml_out, *data; \
+ data = "<" NODE_NAME " xmlns=\"urn:tests:" MOD_NAME "\">" DATA "</" NODE_NAME ">"; \
+ CHECK_PARSE_LYD_PARAM(data, LYD_XML, LYD_PARSE_ONLY | LYD_PARSE_STRICT, 0, LY_SUCCESS, tree_1); \
+ assert_int_equal(lyd_print_mem(&xml_out, tree_1, LYD_LYB, LYD_PRINT_WITHSIBLINGS), 0); \
+ assert_int_equal(LY_SUCCESS, lyd_parse_data_mem(UTEST_LYCTX, xml_out, LYD_LYB, LYD_PARSE_ONLY | LYD_PARSE_STRICT, 0, &tree_2)); \
+ assert_non_null(tree_2); \
+ CHECK_LYD(tree_1, tree_2); \
+ free(xml_out); \
+ lyd_free_all(tree_1); \
+ lyd_free_all(tree_2); \
+ }
+
+static void
+test_data_xml(void **state)
+{
+ const char *schema;
+
+ /* xml test */
+ schema = MODULE_CREATE_YANG("defs", "feature f; leaf l1 {type enumeration {enum white; enum yellow {if-feature f;}}}");
+ UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, NULL);
+
+ TEST_SUCCESS_XML("defs", "l1", "white", ENUM, "white", "white");
+
+ /* disabled feature */
+ TEST_ERROR_XML("defs", "l1", "yellow");
+ CHECK_LOG_CTX("Invalid enumeration value \"yellow\".",
+ "Schema location \"/defs:l1\", line number 1.");
+
+ /* leading/trailing whitespaces */
+ TEST_ERROR_XML("defs", "l1", " white");
+ CHECK_LOG_CTX("Invalid enumeration value \" white\".",
+ "Schema location \"/defs:l1\", line number 1.");
+
+ TEST_ERROR_XML("defs", "l1", "white\n");
+ CHECK_LOG_CTX("Invalid enumeration value \"white\n\".",
+ "Schema location \"/defs:l1\", line number 2.");
+
+ /* invalid value */
+ TEST_ERROR_XML("defs", "l1", "black");
+ CHECK_LOG_CTX("Invalid enumeration value \"black\".",
+ "Schema location \"/defs:l1\", line number 1.");
+}
+
+static void
+test_plugin_lyb(void **state)
+{
+ const char *schema;
+
+ schema = MODULE_CREATE_YANG("lyb", "leaf l1 {type enumeration {enum white; enum yellow; enum black;}}");
+ UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, NULL);
+ TEST_SUCCESS_LYB("lyb", "l1", "white");
+ TEST_SUCCESS_LYB("lyb", "l1", "black");
+}
+
+int
+main(void)
+{
+ const struct CMUnitTest tests[] = {
+ UTEST(test_data_xml),
+ UTEST(test_plugin_lyb),
+ };
+
+ return cmocka_run_group_tests(tests, NULL, NULL);
+}
diff --git a/tests/utests/types/identityref.c b/tests/utests/types/identityref.c
new file mode 100644
index 0000000..cdfe057
--- /dev/null
+++ b/tests/utests/types/identityref.c
@@ -0,0 +1,123 @@
+/**
+ * @file identityref.c
+ * @author Adam Piecek <piecek@cesnet.cz>
+ * @brief test for built-in enumeration type
+ *
+ * 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"
+
+/* LOCAL INCLUDE HEADERS */
+#include "libyang.h"
+
+#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"
+
+#define TEST_SUCCESS_XML(MOD_NAME, NAMESPACES, NODE_NAME, DATA, TYPE, ...) \
+ { \
+ struct lyd_node *tree; \
+ const char *data = "<" NODE_NAME " xmlns=\"urn:tests:" MOD_NAME "\" " NAMESPACES ">" DATA "</" NODE_NAME ">"; \
+ CHECK_PARSE_LYD_PARAM(data, LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_SUCCESS, tree); \
+ CHECK_LYD_NODE_TERM((struct lyd_node_term *)tree, 0, 0, 0, 0, 1, TYPE, __VA_ARGS__); \
+ lyd_free_all(tree); \
+ }
+
+#define TEST_ERROR_XML(MOD_NAME, NAMESPACES, NODE_NAME, DATA) \
+ {\
+ struct lyd_node *tree; \
+ const char *data = "<" NODE_NAME " xmlns=\"urn:tests:" MOD_NAME "\" " NAMESPACES ">" DATA "</" NODE_NAME ">"; \
+ CHECK_PARSE_LYD_PARAM(data, LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_EVALID, tree); \
+ assert_null(tree); \
+ }
+
+#define TEST_SUCCESS_LYB(MOD_NAME, NODE_NAME, DATA) \
+ { \
+ struct lyd_node *tree_1; \
+ struct lyd_node *tree_2; \
+ char *xml_out, *data; \
+ data = "<" NODE_NAME " xmlns=\"urn:tests:" MOD_NAME "\">" DATA "</" NODE_NAME ">"; \
+ CHECK_PARSE_LYD_PARAM(data, LYD_XML, LYD_PARSE_ONLY | LYD_PARSE_STRICT, 0, LY_SUCCESS, tree_1); \
+ assert_int_equal(lyd_print_mem(&xml_out, tree_1, LYD_LYB, LYD_PRINT_WITHSIBLINGS), 0); \
+ assert_int_equal(LY_SUCCESS, lyd_parse_data_mem(UTEST_LYCTX, xml_out, LYD_LYB, LYD_PARSE_ONLY | LYD_PARSE_STRICT, 0, &tree_2)); \
+ assert_non_null(tree_2); \
+ CHECK_LYD(tree_1, tree_2); \
+ free(xml_out); \
+ lyd_free_all(tree_1); \
+ lyd_free_all(tree_2); \
+ }
+
+static void
+test_data_xml(void **state)
+{
+ const char *schema, *schema2;
+
+ /* xml test */
+ schema = MODULE_CREATE_YANG("ident-base", "identity ident-base;"
+ "identity ident-imp {base ident-base;}");
+ UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, NULL);
+
+ schema2 = MODULE_CREATE_YANG("defs", "import ident-base {prefix ib;}"
+ "identity ident1 {base ib:ident-base;}"
+ "leaf l1 {type identityref {base ib:ident-base;}}");
+ UTEST_ADD_MODULE(schema2, LYS_IN_YANG, NULL, NULL);
+
+ TEST_SUCCESS_XML("defs", "", "l1", "ident1", IDENT, "defs:ident1", "ident1");
+
+ TEST_SUCCESS_XML("defs", "xmlns:i=\"urn:tests:ident-base\"", "l1", "i:ident-imp", IDENT, "ident-base:ident-imp",
+ "ident-imp");
+
+ /* invalid value */
+ TEST_ERROR_XML("defs", "", "l1", "fast-ethernet");
+ CHECK_LOG_CTX("Invalid identityref \"fast-ethernet\" value - identity not found in module \"defs\".",
+ "Schema location \"/defs:l1\", line number 1.");
+
+ TEST_ERROR_XML("defs", "xmlns:x=\"urn:tests:defs\"", "l1", "x:slow-ethernet");
+ CHECK_LOG_CTX("Invalid identityref \"x:slow-ethernet\" value - identity not found in module \"defs\".",
+ "Schema location \"/defs:l1\", line number 1.");
+
+ TEST_ERROR_XML("defs", "xmlns:x=\"urn:tests:ident-base\"", "l1", "x:ident-base");
+ CHECK_LOG_CTX("Invalid identityref \"x:ident-base\" value - identity not derived from the base \"ident-base:ident-base\".",
+ "Schema location \"/defs:l1\", line number 1.");
+
+ TEST_ERROR_XML("defs", "xmlns:x=\"urn:tests:unknown\"", "l1", "x:ident-base");
+ CHECK_LOG_CTX("Invalid identityref \"x:ident-base\" value - unable to map prefix to YANG schema.",
+ "Schema location \"/defs:l1\", line number 1.");
+}
+
+static void
+test_plugin_lyb(void **state)
+{
+ const char *schema;
+
+ schema = MODULE_CREATE_YANG("lyb",
+ "identity idbase;"
+ "identity ident {base idbase;}"
+ "leaf lf {type identityref {base idbase;}}");
+ UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, NULL);
+ TEST_SUCCESS_LYB("lyb", "lf", "ident");
+}
+
+int
+main(void)
+{
+ const struct CMUnitTest tests[] = {
+ UTEST(test_data_xml),
+ UTEST(test_plugin_lyb),
+ };
+
+ return cmocka_run_group_tests(tests, NULL, NULL);
+}
diff --git a/tests/utests/types/inet_types.c b/tests/utests/types/inet_types.c
new file mode 100644
index 0000000..eb4e480
--- /dev/null
+++ b/tests/utests/types/inet_types.c
@@ -0,0 +1,149 @@
+/**
+ * @file inet_types.c
+ * @author Michal Vaško <mvasko@cesnet.cz>
+ * @brief test for ietf-inet-types values
+ *
+ * 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"
+
+/* LOCAL INCLUDE HEADERS */
+#include "libyang.h"
+
+#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" \
+ " import ietf-inet-types {\n" \
+ " prefix inet;\n" \
+ " }\n" \
+ NODES \
+ "}\n"
+
+#define TEST_SUCCESS_XML(MOD_NAME, NODE_NAME, DATA, TYPE, ...) \
+ { \
+ struct lyd_node *tree; \
+ const char *data = "<" NODE_NAME " xmlns=\"urn:tests:" MOD_NAME "\">" DATA "</" NODE_NAME ">"; \
+ CHECK_PARSE_LYD_PARAM(data, LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_SUCCESS, tree); \
+ CHECK_LYD_NODE_TERM((struct lyd_node_term *)tree, 0, 0, 0, 0, 1, TYPE, __VA_ARGS__); \
+ lyd_free_all(tree); \
+ }
+
+#define TEST_SUCCESS_LYB(MOD_NAME, NODE_NAME, DATA) \
+ { \
+ struct lyd_node *tree_1; \
+ struct lyd_node *tree_2; \
+ char *xml_out, *data; \
+ data = "<" NODE_NAME " xmlns=\"urn:tests:" MOD_NAME "\">" DATA "</" NODE_NAME ">"; \
+ CHECK_PARSE_LYD_PARAM(data, LYD_XML, LYD_PARSE_ONLY | LYD_PARSE_STRICT, 0, LY_SUCCESS, tree_1); \
+ assert_int_equal(lyd_print_mem(&xml_out, tree_1, LYD_LYB, LYD_PRINT_WITHSIBLINGS), 0); \
+ assert_int_equal(LY_SUCCESS, lyd_parse_data_mem(UTEST_LYCTX, xml_out, LYD_LYB, LYD_PARSE_ONLY | LYD_PARSE_STRICT, 0, &tree_2)); \
+ assert_non_null(tree_2); \
+ CHECK_LYD(tree_1, tree_2); \
+ free(xml_out); \
+ lyd_free_all(tree_1); \
+ lyd_free_all(tree_2); \
+ }
+
+static void
+test_data_xml(void **state)
+{
+ const char *schema;
+
+ /* xml test */
+ schema = MODULE_CREATE_YANG("a",
+ "leaf l {type inet:ip-address;}"
+ "leaf l2 {type inet:ipv6-address;}"
+ "leaf l3 {type inet:ip-address-no-zone;}"
+ "leaf l4 {type inet:ipv6-address-no-zone;}"
+ "leaf l5 {type inet:ip-prefix;}"
+ "leaf l6 {type inet:ipv4-prefix;}"
+ "leaf l7 {type inet:ipv6-prefix;}");
+ UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, NULL);
+
+ /* ip-address */
+ TEST_SUCCESS_XML("a", "l", "192.168.0.1", UNION, "192.168.0.1", STRING, "192.168.0.1");
+ TEST_SUCCESS_XML("a", "l", "192.168.0.1%12", UNION, "192.168.0.1%12", STRING, "192.168.0.1%12");
+ TEST_SUCCESS_XML("a", "l", "2008:15:0:0:0:0:feAC:1", UNION, "2008:15::feac:1", STRING, "2008:15::feac:1");
+
+ /* ipv6-address */
+ TEST_SUCCESS_XML("a", "l2", "FAAC:21:011:Da85::87:daaF%1", STRING, "faac:21:11:da85::87:daaf%1");
+
+ /* ip-address-no-zone */
+ TEST_SUCCESS_XML("a", "l3", "127.0.0.1", UNION, "127.0.0.1", STRING, "127.0.0.1");
+ TEST_SUCCESS_XML("a", "l3", "0:00:000:0000:000:00:0:1", UNION, "::1", STRING, "::1");
+
+ /* ipv6-address-no-zone */
+ TEST_SUCCESS_XML("a", "l4", "A:B:c:D:e:f:1:0", STRING, "a:b:c:d:e:f:1:0");
+
+ /* ip-prefix */
+ TEST_SUCCESS_XML("a", "l5", "158.1.58.4/1", UNION, "128.0.0.0/1", STRING, "128.0.0.0/1");
+ TEST_SUCCESS_XML("a", "l5", "158.1.58.4/24", UNION, "158.1.58.0/24", STRING, "158.1.58.0/24");
+ TEST_SUCCESS_XML("a", "l5", "2000:A:B:C:D:E:f:a/16", UNION, "2000::/16", STRING, "2000::/16");
+
+ /* ipv4-prefix */
+ TEST_SUCCESS_XML("a", "l6", "0.1.58.4/32", STRING, "0.1.58.4/32");
+ TEST_SUCCESS_XML("a", "l6", "12.1.58.4/8", STRING, "12.0.0.0/8");
+
+ /* ipv6-prefix */
+ TEST_SUCCESS_XML("a", "l7", "::C:D:E:f:a/112", STRING, "::c:d:e:f:0/112");
+ TEST_SUCCESS_XML("a", "l7", "::C:D:E:f:a/110", STRING, "::c:d:e:c:0/110");
+ TEST_SUCCESS_XML("a", "l7", "::C:D:E:f:a/96", STRING, "::c:d:e:0:0/96");
+ TEST_SUCCESS_XML("a", "l7", "::C:D:E:f:a/55", STRING, "::/55");
+}
+
+static void
+test_data_lyb(void **state)
+{
+ const char *schema;
+
+ schema = MODULE_CREATE_YANG("lyb",
+ "leaf l {type inet:ip-address;}"
+ "leaf l2 {type inet:ipv6-address;}"
+ "leaf l3 {type inet:ip-address-no-zone;}"
+ "leaf l4 {type inet:ipv6-address-no-zone;}"
+ "leaf l5 {type inet:ip-prefix;}"
+ "leaf l6 {type inet:ipv4-prefix;}"
+ "leaf l7 {type inet:ipv6-prefix;}");
+ UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, NULL);
+
+ TEST_SUCCESS_LYB("lyb", "l", "192.168.0.1");
+ TEST_SUCCESS_LYB("lyb", "l2", "FAAC:21:011:Da85::87:daaF%1");
+ TEST_SUCCESS_LYB("lyb", "l3", "127.0.0.1");
+ TEST_SUCCESS_LYB("lyb", "l4", "A:B:c:D:e:f:1:0");
+ TEST_SUCCESS_LYB("lyb", "l5", "158.1.58.4/1");
+ TEST_SUCCESS_LYB("lyb", "l6", "12.1.58.4/8");
+ TEST_SUCCESS_LYB("lyb", "l7", "::C:D:E:f:a/112");
+}
+
+int
+main(void)
+{
+ const struct CMUnitTest tests[] = {
+ UTEST(test_data_xml),
+ UTEST(test_data_lyb),
+ };
+
+ return cmocka_run_group_tests(tests, NULL, NULL);
+}
diff --git a/tests/utests/types/instanceid.c b/tests/utests/types/instanceid.c
new file mode 100644
index 0000000..06c8622
--- /dev/null
+++ b/tests/utests/types/instanceid.c
@@ -0,0 +1,292 @@
+/**
+ * @file instanceid.c
+ * @author Adam Piecek <piecek@cesnet.cz>
+ * @brief test for built-in enumeration type
+ *
+ * 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"
+
+/* LOCAL INCLUDE HEADERS */
+#include "libyang.h"
+#include "path.h"
+
+#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"
+
+#define TEST_SUCCESS_XML2(XML1, MOD_NAME, NAMESPACES, NODE_NAME, DATA, TYPE, ...) \
+ { \
+ struct lyd_node *tree; \
+ const char *data = XML1 "<" NODE_NAME " xmlns=\"urn:tests:" MOD_NAME "\" " NAMESPACES ">" DATA "</" NODE_NAME ">"; \
+ CHECK_PARSE_LYD_PARAM(data, LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_SUCCESS, tree); \
+ CHECK_LYD_NODE_TERM((struct lyd_node_term *)tree, 0, 0, 1, 0, 1, TYPE, __VA_ARGS__); \
+ lyd_free_all(tree); \
+ }
+
+#define TEST_ERROR_XML2(XML1, MOD_NAME, NAMESPACES, NODE_NAME, DATA, RET) \
+ {\
+ struct lyd_node *tree; \
+ const char *data = "<" NODE_NAME " xmlns=\"urn:tests:" MOD_NAME "\" " NAMESPACES ">" DATA "</" NODE_NAME ">"; \
+ CHECK_PARSE_LYD_PARAM(data, LYD_XML, 0, LYD_VALIDATE_PRESENT, RET, tree); \
+ assert_null(tree); \
+ }
+
+#define LYB_CHECK_START \
+ struct lyd_node *tree_1; \
+ struct lyd_node *tree_2; \
+ char *xml_out, *data;
+
+#define LYB_CHECK_END \
+ { \
+ CHECK_PARSE_LYD_PARAM(data, LYD_XML, LYD_PARSE_ONLY | LYD_PARSE_STRICT, 0, LY_SUCCESS, tree_1); \
+ assert_int_equal(lyd_print_mem(&xml_out, tree_1, LYD_LYB, LYD_PRINT_WITHSIBLINGS), 0); \
+ assert_int_equal(LY_SUCCESS, lyd_parse_data_mem(UTEST_LYCTX, xml_out, LYD_LYB, LYD_PARSE_ONLY | LYD_PARSE_STRICT, 0, &tree_2)); \
+ assert_non_null(tree_2); \
+ CHECK_LYD(tree_1, tree_2); \
+ free(xml_out); \
+ lyd_free_all(tree_1); \
+ lyd_free_all(tree_2); \
+ }
+
+#define TEST_SUCCESS_LYB(MOD_NAME, NODE_NAME1, DATA1, NODE_NAME2, DATA2) \
+ LYB_CHECK_START \
+ data = "<" NODE_NAME1 " xmlns=\"urn:tests:" MOD_NAME "\">" DATA1 "</" NODE_NAME1 ">" \
+ "<xdf:" NODE_NAME2 " xmlns:xdf=\"urn:tests:" MOD_NAME "\">/xdf:" DATA2 "</xdf:" NODE_NAME2 ">"; \
+ LYB_CHECK_END \
+
+#define TEST_SUCCESS_LYB2(MOD_NAME, NODE_NAME, DATA) \
+ { \
+ LYB_CHECK_START \
+ data = "<" NODE_NAME " xmlns:aa=\"urn:tests:lyb2\" xmlns=\"urn:tests:" MOD_NAME "\">/aa:" DATA "</" NODE_NAME ">"; \
+ LYB_CHECK_END \
+ }
+
+static void
+test_data_xml(void **state)
+{
+ const char *schema, *schema2;
+ const enum ly_path_pred_type val1[] = {LY_PATH_PREDTYPE_NONE, LY_PATH_PREDTYPE_NONE};
+ const enum ly_path_pred_type val2[] = {LY_PATH_PREDTYPE_LIST, LY_PATH_PREDTYPE_NONE};
+ const enum ly_path_pred_type val3[] = {LY_PATH_PREDTYPE_LEAFLIST};
+ const enum ly_path_pred_type val4[] = {LY_PATH_PREDTYPE_LIST, LY_PATH_PREDTYPE_NONE};
+ const enum ly_path_pred_type val5[] = {LY_PATH_PREDTYPE_LIST, LY_PATH_PREDTYPE_NONE};
+ const enum ly_path_pred_type val6[] = {LY_PATH_PREDTYPE_LIST, LY_PATH_PREDTYPE_NONE};
+
+ /* xml test */
+ schema = MODULE_CREATE_YANG("mod", "container cont {leaf l2 {type empty;}}");
+ UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, NULL);
+
+ schema2 = MODULE_CREATE_YANG("defs", "identity ident; identity ident-der1 {base ident;} identity ident-der2 {base ident;}"
+ "leaf l1 {type instance-identifier {require-instance true;}}"
+ "leaf l2 {type instance-identifier {require-instance false;}}"
+ "container cont {leaf l {type empty;}}"
+ "list list {key \"id\"; leaf id {type string;} leaf value {type string;}}"
+ "leaf-list llist {type uint32;}"
+ "list list-inst {key \"id\"; leaf id {type instance-identifier;} leaf value {type string;}}"
+ "list list-ident {key \"id\"; leaf id {type identityref {base ident;}} leaf value {type string;}}"
+ "list list2 {key \"id id2\"; leaf id {type string;} leaf id2 {type string;}}"
+ "list list-keyless {config false; leaf value {type string;}}");
+ UTEST_ADD_MODULE(schema2, LYS_IN_YANG, NULL, NULL);
+
+ TEST_SUCCESS_XML2("<cont xmlns=\"urn:tests:defs\"><l/></cont>", "defs", "xmlns:xdf=\"urn:tests:defs\"", "l1",
+ "/xdf:cont/xdf:l", INST, "/defs:cont/l", val1);
+
+ TEST_SUCCESS_XML2("<list xmlns=\"urn:tests:defs\"><id>a</id></list><list xmlns=\"urn:tests:defs\"><id>b</id></list>",
+ "defs", "xmlns:xdf=\"urn:tests:defs\"", "xdf:l1", "/xdf:list[xdf:id='b']/xdf:id", INST,
+ "/defs:list[id='b']/id", val2);
+
+ TEST_SUCCESS_XML2("<llist xmlns=\"urn:tests:defs\">1</llist><llist xmlns=\"urn:tests:defs\">2</llist>",
+ "defs", "xmlns:xdf=\"urn:tests:defs\"", "xdf:l1", "/xdf:llist[.='1']", INST, "/defs:llist[.='1']", val3);
+
+ TEST_SUCCESS_XML2("<list-inst xmlns=\"urn:tests:defs\"><id xmlns:b=\"urn:tests:defs\">/b:llist[.='1']</id>"
+ "<value>x</value></list-inst>"
+ "<list-inst xmlns=\"urn:tests:defs\"><id xmlns:b=\"urn:tests:defs\">/b:llist[.='2']</id>"
+ "<value>y</value></list-inst>"
+ "<llist xmlns=\"urn:tests:defs\">1</llist><llist xmlns=\"urn:tests:defs\">2</llist>",
+ "defs", "xmlns:a=\"urn:tests:defs\"", "a:l1", "/a:list-inst[a:id=\"/a:llist[.='1']\"]/a:value",
+ INST, "/defs:list-inst[id=\"/defs:llist[.='1']\"]/value", val4);
+
+ TEST_SUCCESS_XML2("<list-ident xmlns=\"urn:tests:defs\"><id xmlns:b=\"urn:tests:defs\">b:ident-der1</id>"
+ "<value>x</value></list-ident>"
+ "<list-ident xmlns=\"urn:tests:defs\"><id xmlns:b=\"urn:tests:defs\">b:ident-der2</id>"
+ "<value>y</value></list-ident>",
+ "defs", "xmlns:a=\"urn:tests:defs\"", "a:l1", "/a:list-ident[a:id='a:ident-der1']/a:value",
+ INST, "/defs:list-ident[id='defs:ident-der1']/value", val5);
+
+ TEST_SUCCESS_XML2("<list2 xmlns=\"urn:tests:defs\"><id>defs:xxx</id><id2>x</id2></list2>"
+ "<list2 xmlns=\"urn:tests:defs\"><id>a:xxx</id><id2>y</id2></list2>",
+ "defs", "xmlns:a=\"urn:tests:defs\"", "a:l1", "/a:list2[a:id='a:xxx'][a:id2='y']/a:id2",
+ INST, "/defs:list2[id='a:xxx'][id2='y']/id2", val6);
+
+ /* syntax/semantic errors */
+ TEST_ERROR_XML2("<list xmlns=\"urn:tests:defs\"><id>a</id></list>"
+ "<list xmlns=\"urn:tests:defs\"><id>b</id><value>x</value></list>",
+ "defs", "xmlns:xdf=\"urn:tests:defs\"", "xdf:l1", "/xdf:list[2]/xdf:value", LY_EVALID);
+ CHECK_LOG_CTX("Invalid instance-identifier \"/xdf:list[2]/xdf:value\" value - semantic error.",
+ "Schema location \"/defs:l1\", line number 1.");
+
+ TEST_ERROR_XML2("",
+ "defs", "xmlns:xdf=\"urn:tests:defs\"", "xdf:l1", "/t:cont/t:1l", LY_EVALID);
+ CHECK_LOG_CTX("Invalid instance-identifier \"/t:cont/t:1l\" value - syntax error.",
+ "Schema location \"/defs:l1\", line number 1.");
+
+ TEST_ERROR_XML2("",
+ "defs", "xmlns:xdf=\"urn:tests:defs\"", "xdf:l1", "/t:cont:t:1l", LY_EVALID);
+ CHECK_LOG_CTX("Invalid instance-identifier \"/t:cont:t:1l\" value - syntax error.",
+ "Schema location \"/defs:l1\", line number 1.");
+
+ TEST_ERROR_XML2("",
+ "defs", "xmlns:xdf=\"urn:tests:defs\"", "xdf:l1", "/xdf:cont/xdf:invalid/xdf:path", LY_EVALID);
+ CHECK_LOG_CTX("Invalid instance-identifier \"/xdf:cont/xdf:invalid/xdf:path\" value - semantic error.",
+ "Schema location \"/defs:l1\", line number 1.");
+
+ /* non-existing instances, instance-identifier is here in JSON format because it is already in internal
+ * representation without canonical prefixes */
+ TEST_ERROR_XML2("<cont xmlns=\"urn:tests:mod\"/>",
+ "defs", "xmlns:m=\"urn:tests:mod\"", "l1", "/m:cont/m:l2", LY_ENOTFOUND);
+ CHECK_LOG_CTX_APPTAG("Invalid instance-identifier \"/mod:cont/l2\" value - required instance not found.",
+ "Data location \"/defs:l1\".", "instance-required");
+
+ TEST_ERROR_XML2("<llist xmlns=\"urn:tests:defs\">1</llist>",
+ "defs", "xmlns:a=\"urn:tests:defs\"", "l1", "/a:llist[.='2']", LY_ENOTFOUND);
+ CHECK_LOG_CTX_APPTAG("Invalid instance-identifier \"/defs:llist[.='2']\" value - required instance not found.",
+ "Data location \"/defs:l1\".", "instance-required");
+
+ TEST_ERROR_XML2("<list2 xmlns=\"urn:tests:defs\"><id>a</id><id2>a</id2></list2>"
+ "<list2 xmlns=\"urn:tests:defs\"><id>c</id><id2>b</id2></list2>"
+ "<llist xmlns=\"urn:tests:defs\">a</llist>"
+ "<llist xmlns=\"urn:tests:defs\">b</llist>",
+ "defs", "xmlns:a=\"urn:tests:defs\"", "l1", "/a:list2[a:id='a'][a:id2='a']/a:id", LY_ENOTFOUND);
+ CHECK_LOG_CTX_APPTAG("Invalid instance-identifier \"/defs:list2[id='a'][id2='a']/id\" value - required instance not found.",
+ "Data location \"/defs:l1\".", "instance-required");
+
+ TEST_ERROR_XML2("<list2 xmlns=\"urn:tests:defs\"><id>a</id><id2>a</id2></list2>"
+ "<list2 xmlns=\"urn:tests:defs\"><id>c</id><id2>b</id2></list2>"
+ "<llist xmlns=\"urn:tests:defs\">1</llist>"
+ "<llist xmlns=\"urn:tests:defs\">2</llist>",
+ "defs", "xmlns:a=\"urn:tests:defs\"", "l1", "/a:llist[.='3']", LY_ENOTFOUND);
+ CHECK_LOG_CTX_APPTAG("Invalid instance-identifier \"/defs:llist[.='3']\" value - required instance not found.",
+ "Data location \"/defs:l1\".", "instance-required");
+
+ TEST_ERROR_XML2("",
+ "defs", "xmlns:a=\"urn:tests:defs\"", "l1", "/a:list-keyless[3]", LY_ENOTFOUND);
+ CHECK_LOG_CTX_APPTAG("Invalid instance-identifier \"/defs:list-keyless[3]\" value - required instance not found.",
+ "Data location \"/defs:l1\".", "instance-required");
+
+ /* more errors */
+ TEST_ERROR_XML2("<llist xmlns=\"urn:tests:defs\">x</llist>",
+ "defs", "xmlns:t=\"urn:tests:defs\"", "t:l1", "/t:llist[1", LY_EVALID);
+ CHECK_LOG_CTX("Invalid instance-identifier \"/t:llist[1\" value - syntax error.",
+ "Schema location \"/defs:l1\", line number 1.");
+
+ TEST_ERROR_XML2("<cont xmlns=\"urn:tests:mod\"/>",
+ "defs", "xmlns:m=\"urn:tests:mod\"", "l1", "/m:cont[1]", LY_EVALID);
+ CHECK_LOG_CTX("Invalid instance-identifier \"/m:cont[1]\" value - semantic error.",
+ "Schema location \"/defs:l1\", line number 1.");
+
+ TEST_ERROR_XML2("<cont xmlns=\"urn:tests:mod\"/>",
+ "defs", "xmlns:m=\"urn:tests:mod\"", "l1", "[1]", LY_EVALID);
+ CHECK_LOG_CTX("Invalid instance-identifier \"[1]\" value - syntax error.",
+ "Schema location \"/defs:l1\", line number 1.");
+
+ TEST_ERROR_XML2("<cont xmlns=\"urn:tests:mod\"><l2/></cont>",
+ "defs", "xmlns:m=\"urn:tests:mod\"", "l1", "/m:cont/m:l2[l2='1']", LY_EVALID);
+ CHECK_LOG_CTX("Invalid instance-identifier \"/m:cont/m:l2[l2='1']\" value - syntax error.",
+ "Schema location \"/defs:l1\", line number 1.");
+
+ TEST_ERROR_XML2("<cont xmlns=\"urn:tests:mod\"><l2/></cont>",
+ "defs", "xmlns:m=\"urn:tests:mod\"", "l1", "/m:cont/m:l2[m:l2='1']", LY_EVALID);
+ CHECK_LOG_CTX("Invalid instance-identifier \"/m:cont/m:l2[m:l2='1']\" value - semantic error.",
+ "Schema location \"/defs:l1\", line number 1.");
+
+ TEST_ERROR_XML2("<llist xmlns=\"urn:tests:defs\">1</llist><llist xmlns=\"urn:tests:defs\">2</llist>",
+ "defs", "xmlns:t=\"urn:tests:defs\"", "t:l1", "/t:llist[4]", LY_EVALID);
+ CHECK_LOG_CTX("Invalid instance-identifier \"/t:llist[4]\" value - semantic error.",
+ "Schema location \"/defs:l1\", line number 1.");
+
+ TEST_ERROR_XML2("",
+ "defs", "xmlns:xdf=\"urn:tests:defs\"", "xdf:l2", "/t:llist[6]", LY_EVALID);
+ CHECK_LOG_CTX("Invalid instance-identifier \"/t:llist[6]\" value - semantic error.",
+ "Schema location \"/defs:l2\", line number 1.");
+
+ TEST_ERROR_XML2("<list xmlns=\"urn:tests:defs\"><id>1</id><value>x</value></list>",
+ "defs", "xmlns:xdf=\"urn:tests:defs\"", "xdf:l2", "/xdf:list[xdf:value='x']", LY_EVALID);
+ CHECK_LOG_CTX("Invalid instance-identifier \"/xdf:list[xdf:value='x']\" value - semantic error.",
+ "Schema location \"/defs:l2\", line number 1.");
+
+ TEST_ERROR_XML2("",
+ "defs", "xmlns:xdf=\"urn:tests:defs\"", "xdf:l2", "/xdf:list[.='x']", LY_EVALID);
+ CHECK_LOG_CTX("Invalid instance-identifier \"/xdf:list[.='x']\" value - semantic error.",
+ "Schema location \"/defs:l2\", line number 1.");
+
+ TEST_ERROR_XML2("<llist xmlns=\"urn:tests:defs\">1</llist>",
+ "defs", "xmlns:t=\"urn:tests:defs\"", "t:l1", "/t:llist[.='x']", LY_EVALID);
+ CHECK_LOG_CTX("Invalid instance-identifier \"/t:llist[.='x']\" value - semantic error.",
+ "Schema location \"/defs:l1\", line number 1.");
+
+ TEST_ERROR_XML2("",
+ "defs", "xmlns:xdf=\"urn:tests:defs\"", "xdf:l2", "/t:llist[1][2]", LY_EVALID);
+ CHECK_LOG_CTX("Invalid instance-identifier \"/t:llist[1][2]\" value - syntax error.",
+ "Schema location \"/defs:l2\", line number 1.");
+
+ TEST_ERROR_XML2("",
+ "defs", "xmlns:xdf=\"urn:tests:defs\"", "xdf:l2", "/t:llist[.='a'][.='b']", LY_EVALID);
+ CHECK_LOG_CTX("Invalid instance-identifier \"/t:llist[.='a'][.='b']\" value - syntax error.",
+ "Schema location \"/defs:l2\", line number 1.");
+
+ TEST_ERROR_XML2("<list xmlns=\"urn:tests:defs\"><id>1</id><value>x</value></list>",
+ "defs", "xmlns:xdf=\"urn:tests:defs\"", "xdf:l2", "/xdf:list[xdf:id='1'][xdf:id='2']/xdf:value", LY_EVALID);
+ CHECK_LOG_CTX("Invalid instance-identifier \"/xdf:list[xdf:id='1'][xdf:id='2']/xdf:value\" value - syntax error.",
+ "Schema location \"/defs:l2\", line number 1.");
+
+ TEST_ERROR_XML2("",
+ "defs", "xmlns:xdf=\"urn:tests:defs\"", "xdf:l2", "/xdf:list2[xdf:id='1']/xdf:value", LY_EVALID);
+ CHECK_LOG_CTX("Invalid instance-identifier \"/xdf:list2[xdf:id='1']/xdf:value\" value - semantic error.",
+ "Schema location \"/defs:l2\", line number 1.");
+}
+
+static void
+test_plugin_lyb(void **state)
+{
+ const char *schema;
+
+ schema = MODULE_CREATE_YANG("lyb",
+ "leaf-list leaflisttarget {type string;}"
+ "leaf inst {type instance-identifier {require-instance true;}}");
+ UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, NULL);
+ TEST_SUCCESS_LYB("lyb", "leaflisttarget", "1", "inst", "leaflisttarget[.='1']");
+
+ /* ietf-netconf-acm node-instance-identifier type */
+ assert_int_equal(LY_SUCCESS, ly_ctx_set_searchdir(UTEST_LYCTX, TESTS_DIR_MODULES_YANG));
+ schema = MODULE_CREATE_YANG("lyb2",
+ "import ietf-netconf-acm {prefix acm;}"
+ "leaf-list ll {type string;}"
+ "leaf nii {type acm:node-instance-identifier;}");
+ UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, NULL);
+ TEST_SUCCESS_LYB2("lyb2", "nii", "ll[. = 'some_string']");
+}
+
+int
+main(void)
+{
+ const struct CMUnitTest tests[] = {
+ UTEST(test_data_xml),
+ UTEST(test_plugin_lyb),
+ };
+
+ return cmocka_run_group_tests(tests, NULL, NULL);
+}
diff --git a/tests/utests/types/instanceid_keys.c b/tests/utests/types/instanceid_keys.c
new file mode 100644
index 0000000..6d527cb
--- /dev/null
+++ b/tests/utests/types/instanceid_keys.c
@@ -0,0 +1,77 @@
+/**
+ * @file instanceid_keys.c
+ * @author Michal Vasko <mvasko@cesnet.cz>
+ * @brief test for yang instance-identifier-keys type
+ *
+ * Copyright (c) 2022 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"
+
+/* LOCAL INCLUDE HEADERS */
+#include "libyang.h"
+
+#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"
+
+#define TEST_SUCCESS_XML_NS1(MOD_NAME, NODE_NAME, PREFIX, NS, DATA, TYPE, ...) \
+ { \
+ struct lyd_node *tree; \
+ const char *data = "<" NODE_NAME " xmlns=\"urn:tests:" MOD_NAME "\" xmlns:" PREFIX "=\"" NS "\">" DATA "</" NODE_NAME ">"; \
+ CHECK_PARSE_LYD_PARAM(data, LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_SUCCESS, tree); \
+ CHECK_LYD_NODE_TERM((struct lyd_node_term *)tree, 0, 0, 0, 0, 1, TYPE, __VA_ARGS__); \
+ lyd_free_all(tree); \
+ }
+
+#define TEST_ERROR_XML(MOD_NAME, NODE_NAME, DATA) \
+ {\
+ struct lyd_node *tree; \
+ const char *data = "<" NODE_NAME " xmlns=\"urn:tests:" MOD_NAME "\">" DATA "</" NODE_NAME ">"; \
+ CHECK_PARSE_LYD_PARAM(data, LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_EVALID, tree); \
+ assert_null(tree); \
+ }
+
+static void
+test_data_xml(void **state)
+{
+ const char *schema;
+
+ /* xml test */
+ schema = MODULE_CREATE_YANG("defs", "import yang {prefix y;} leaf l1 {type y:instance-identifier-keys;}");
+ UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, NULL);
+
+ TEST_SUCCESS_XML_NS1("defs", "l1", "px", "urn:tests:defs", "[px:key='val']", STRING, "[defs:key='val']");
+
+ TEST_ERROR_XML("defs", "l1", "black");
+ CHECK_LOG_CTX("Invalid first character 'b', list key predicates expected.", "Schema location \"/defs:l1\", line number 1.");
+
+ TEST_ERROR_XML("defs", "l1", "[this is not a valid xpath]");
+ CHECK_LOG_CTX("Invalid character 0x69 ('i'), perhaps \"this\" is supposed to be a function call.",
+ "Schema location \"/defs:l1\", line number 1.");
+
+ TEST_ERROR_XML("defs", "l1", "[px:key='val']");
+ CHECK_LOG_CTX("Failed to resolve prefix \"px\".", "Schema location \"/defs:l1\", line number 1.");
+}
+
+int
+main(void)
+{
+ const struct CMUnitTest tests[] = {
+ UTEST(test_data_xml),
+ };
+
+ return cmocka_run_group_tests(tests, NULL, NULL);
+}
diff --git a/tests/utests/types/int16.c b/tests/utests/types/int16.c
new file mode 100644
index 0000000..f6796a1
--- /dev/null
+++ b/tests/utests/types/int16.c
@@ -0,0 +1,75 @@
+/**
+ * @file int16.c
+ * @author Michal Vasko <mvasko@cesnet.cz>
+ * @brief test for int16 values
+ *
+ * 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"
+#include "plugins_internal.h"
+
+#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"
+
+#define TEST_SUCCESS_XML(MOD_NAME, DATA, TYPE, ...) \
+ { \
+ struct lyd_node *tree; \
+ const char *data = "<port xmlns=\"urn:tests:" MOD_NAME "\">" DATA "</port>"; \
+ CHECK_PARSE_LYD_PARAM(data, LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_SUCCESS, tree); \
+ CHECK_LYSC_NODE(tree->schema, NULL, 0, 0x5, 1, "port", 0, LYS_LEAF, 0, 0, 0, 0); \
+ CHECK_LYD_NODE_TERM((struct lyd_node_term *)tree, 0, 0, 0, 0, 1, TYPE, ## __VA_ARGS__); \
+ lyd_free_all(tree); \
+ }
+
+#define TEST_ERROR_XML(MOD_NAME, DATA) \
+ {\
+ struct lyd_node *tree; \
+ const char *data = "<port xmlns=\"urn:tests:" MOD_NAME "\">" DATA "</port>"; \
+ CHECK_PARSE_LYD_PARAM(data, LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_EVALID, tree); \
+ assert_null(tree); \
+ }
+
+static void
+test_data_xml(void **state)
+{
+ const char *schema;
+
+ /* xml test */
+ schema = MODULE_CREATE_YANG("defs", "leaf port {type int16 {range -20..-10;}}");
+ UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, NULL);
+
+ TEST_ERROR_XML("defs", "100");
+ CHECK_LOG_CTX("Unsatisfied range - value \"100\" is out of the allowed range.",
+ "Schema location \"/defs:port\", line number 1.");
+}
+
+int
+main(void)
+{
+ const struct CMUnitTest tests[] = {
+ UTEST(test_data_xml),
+ };
+
+ return cmocka_run_group_tests(tests, NULL, NULL);
+}
diff --git a/tests/utests/types/int32.c b/tests/utests/types/int32.c
new file mode 100644
index 0000000..9989a67
--- /dev/null
+++ b/tests/utests/types/int32.c
@@ -0,0 +1,75 @@
+/**
+ * @file int32.c
+ * @author Michal Vasko <mvasko@cesnet.cz>
+ * @brief test for int32 values
+ *
+ * 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"
+#include "plugins_internal.h"
+
+#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"
+
+#define TEST_SUCCESS_XML(MOD_NAME, DATA, TYPE, ...) \
+ { \
+ struct lyd_node *tree; \
+ const char *data = "<port xmlns=\"urn:tests:" MOD_NAME "\">" DATA "</port>"; \
+ CHECK_PARSE_LYD_PARAM(data, LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_SUCCESS, tree); \
+ CHECK_LYSC_NODE(tree->schema, NULL, 0, 0x5, 1, "port", 0, LYS_LEAF, 0, 0, 0, 0); \
+ CHECK_LYD_NODE_TERM((struct lyd_node_term *)tree, 0, 0, 0, 0, 1, TYPE, ## __VA_ARGS__); \
+ lyd_free_all(tree); \
+ }
+
+#define TEST_ERROR_XML(MOD_NAME, DATA) \
+ {\
+ struct lyd_node *tree; \
+ const char *data = "<port xmlns=\"urn:tests:" MOD_NAME "\">" DATA "</port>"; \
+ CHECK_PARSE_LYD_PARAM(data, LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_EVALID, tree); \
+ assert_null(tree); \
+ }
+
+static void
+test_data_xml(void **state)
+{
+ const char *schema;
+
+ /* xml test */
+ schema = MODULE_CREATE_YANG("defs", "leaf port {type int32;}");
+ UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, NULL);
+
+ TEST_ERROR_XML("defs", "0x01");
+ CHECK_LOG_CTX("Invalid type int32 value \"0x01\".",
+ "Schema location \"/defs:port\", line number 1.");
+}
+
+int
+main(void)
+{
+ const struct CMUnitTest tests[] = {
+ UTEST(test_data_xml),
+ };
+
+ return cmocka_run_group_tests(tests, NULL, NULL);
+}
diff --git a/tests/utests/types/int64.c b/tests/utests/types/int64.c
new file mode 100644
index 0000000..6b5e47e
--- /dev/null
+++ b/tests/utests/types/int64.c
@@ -0,0 +1,83 @@
+/**
+ * @file int64.c
+ * @author Michal Vasko <mvasko@cesnet.cz>
+ * @brief test for int32 values
+ *
+ * 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"
+#include "plugins_internal.h"
+
+#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"
+
+#define TEST_SUCCESS_XML(MOD_NAME, DATA, TYPE, ...) \
+ { \
+ struct lyd_node *tree; \
+ const char *data = "<port xmlns=\"urn:tests:" MOD_NAME "\">" DATA "</port>"; \
+ CHECK_PARSE_LYD_PARAM(data, LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_SUCCESS, tree); \
+ CHECK_LYSC_NODE(tree->schema, NULL, 0, 0x5, 1, "port", 0, LYS_LEAF, 0, 0, 0, 0); \
+ CHECK_LYD_NODE_TERM((struct lyd_node_term *)tree, 0, 0, 0, 0, 1, TYPE, ## __VA_ARGS__); \
+ lyd_free_all(tree); \
+ }
+
+#define TEST_ERROR_XML(MOD_NAME, DATA) \
+ {\
+ struct lyd_node *tree; \
+ const char *data = "<port xmlns=\"urn:tests:" MOD_NAME "\">" DATA "</port>"; \
+ CHECK_PARSE_LYD_PARAM(data, LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_EVALID, tree); \
+ assert_null(tree); \
+ }
+
+static void
+test_data_xml(void **state)
+{
+ const char *schema;
+
+ /* xml test */
+ schema = MODULE_CREATE_YANG("defs", "leaf port {type int64;}");
+ UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, NULL);
+
+ TEST_ERROR_XML("defs", "");
+ CHECK_LOG_CTX("Invalid type int64 empty value.",
+ "Schema location \"/defs:port\", line number 1.");
+
+ TEST_ERROR_XML("defs", " ");
+ CHECK_LOG_CTX("Invalid type int64 empty value.",
+ "Schema location \"/defs:port\", line number 1.");
+
+ TEST_ERROR_XML("defs", "-10 xxx");
+ CHECK_LOG_CTX("Invalid type int64 value \"-10 xxx\".",
+ "Schema location \"/defs:port\", line number 1.");
+}
+
+int
+main(void)
+{
+ const struct CMUnitTest tests[] = {
+ UTEST(test_data_xml),
+ };
+
+ return cmocka_run_group_tests(tests, NULL, NULL);
+}
diff --git a/tests/utests/types/int8.c b/tests/utests/types/int8.c
new file mode 100644
index 0000000..7d0b9ad
--- /dev/null
+++ b/tests/utests/types/int8.c
@@ -0,0 +1,1765 @@
+/**
+ * @file int8.c
+ * @author Radek Iša <isa@cesnet.cz>
+ * @brief test for int8 values
+ *
+ * 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"
+#include "plugins_internal.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"
+
+#define TEST_SUCCESS_XML(MOD_NAME, DATA, TYPE, ...) \
+ { \
+ struct lyd_node *tree; \
+ const char *data = "<port xmlns=\"urn:tests:" MOD_NAME "\">" DATA "</port>"; \
+ CHECK_PARSE_LYD_PARAM(data, LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_SUCCESS, tree); \
+ CHECK_LYSC_NODE(tree->schema, NULL, 0, 0x5, 1, "port", 0, LYS_LEAF, 0, 0, 0, 0); \
+ CHECK_LYD_NODE_TERM((struct lyd_node_term *)tree, 0, 0, 0, 0, 1, TYPE, __VA_ARGS__); \
+ lyd_free_all(tree); \
+ }
+
+#define TEST_SUCCESS_JSON(MOD_NAME, DATA, TYPE, ...) \
+ { \
+ struct lyd_node *tree; \
+ const char *data = "{\"" MOD_NAME ":port\":" DATA "}"; \
+ CHECK_PARSE_LYD_PARAM(data, LYD_JSON, 0, LYD_VALIDATE_PRESENT, LY_SUCCESS, tree); \
+ CHECK_LYSC_NODE(tree->schema, NULL, 0, 0x5, 1, "port", 0, LYS_LEAF, 0, 0, 0, 0); \
+ CHECK_LYD_NODE_TERM((struct lyd_node_term *)tree, 0, 0, 0, 0, 1, TYPE, __VA_ARGS__); \
+ lyd_free_all(tree); \
+ }
+
+#define TEST_SUCCESS_LYB(MOD_NAME, NODE_NAME, DATA) \
+ { \
+ struct lyd_node *tree_1; \
+ struct lyd_node *tree_2; \
+ char *xml_out, *data; \
+ data = "<" NODE_NAME " xmlns=\"urn:tests:" MOD_NAME "\">" DATA "</" NODE_NAME ">"; \
+ CHECK_PARSE_LYD_PARAM(data, LYD_XML, LYD_PARSE_ONLY | LYD_PARSE_STRICT, 0, LY_SUCCESS, tree_1); \
+ assert_int_equal(lyd_print_mem(&xml_out, tree_1, LYD_LYB, LYD_PRINT_WITHSIBLINGS), 0); \
+ assert_int_equal(LY_SUCCESS, lyd_parse_data_mem(UTEST_LYCTX, xml_out, LYD_LYB, LYD_PARSE_ONLY | LYD_PARSE_STRICT, 0, &tree_2)); \
+ assert_non_null(tree_2); \
+ CHECK_LYD(tree_1, tree_2); \
+ free(xml_out); \
+ lyd_free_all(tree_1); \
+ lyd_free_all(tree_2); \
+ }
+
+#define TEST_ERROR_XML(MOD_NAME, DATA) \
+ {\
+ struct lyd_node *tree; \
+ const char *data = "<port xmlns=\"urn:tests:" MOD_NAME "\">" DATA "</port>"; \
+ CHECK_PARSE_LYD_PARAM(data, LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_EVALID, tree); \
+ assert_null(tree); \
+ }
+
+#define TEST_ERROR_JSON(MOD_NAME, DATA) \
+ { \
+ struct lyd_node *tree; \
+ const char *data = "{\"" MOD_NAME ":port\":" DATA "}"; \
+ CHECK_PARSE_LYD_PARAM(data, LYD_JSON, 0, LYD_VALIDATE_PRESENT, LY_EVALID, tree); \
+ assert_null(tree); \
+ }
+
+static void
+test_schema_yang(void **state)
+{
+ const char *schema;
+ struct lys_module *mod;
+ struct lysc_node_leaf *lysc_leaf;
+ struct lysp_node_leaf *lysp_leaf;
+ struct lysc_range *range;
+
+ schema = MODULE_CREATE_YANG("defs", "leaf port {type int8 {range \"0 .. 50 | 127\";}}");
+ UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, &mod);
+ assert_non_null(mod);
+ lysc_leaf = (void *)mod->compiled->data;
+ CHECK_LYSC_NODE_LEAF(lysc_leaf, NULL, 0, 0x5, 1, "port", 0, 0, 0, NULL, 0, 0, NULL, NULL);
+ CHECK_LYSC_TYPE_NUM((struct lysc_type_num *)lysc_leaf->type, LY_TYPE_INT8, 0, 1);
+ range = ((struct lysc_type_num *)lysc_leaf->type)->range;
+ CHECK_LYSC_RANGE(range, NULL, NULL, NULL, 0, 2, NULL);
+ assert_int_equal(range->parts[0].min_64, 0);
+ assert_int_equal(range->parts[0].max_64, 50);
+ assert_int_equal(range->parts[1].min_64, 127);
+ assert_int_equal(range->parts[1].max_64, 127);
+ lysp_leaf = (void *)mod->parsed->data;
+ CHECK_LYSP_NODE_LEAF(lysp_leaf, NULL, 0, 0x0, 0, "port", 0, 0, NULL, 0, 0, NULL, NULL);
+ CHECK_LYSP_TYPE(&(lysp_leaf->type), 0, 0, 0, 0, 0, 0x80, 0, 0, "int8", 0, 0, 1, 1, 0, 0);
+ CHECK_LYSP_RESTR(lysp_leaf->type.range, "0 .. 50 | 127", NULL, NULL, NULL, 0, NULL);
+
+ /* TEST MODULE T0 */
+ schema = MODULE_CREATE_YANG("T0", "leaf port {type int8;}");
+ UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, &mod);
+ assert_non_null(mod);
+ lysc_leaf = (void *)mod->compiled->data;
+ CHECK_LYSC_NODE_LEAF(lysc_leaf, NULL, 0, 0x5, 1, "port", 0, 0, 0, NULL, 0, 0, NULL, NULL);
+ CHECK_LYSC_TYPE_NUM((struct lysc_type_num *)lysc_leaf->type, LY_TYPE_INT8, 0, 0);
+ lysp_leaf = (void *)mod->parsed->data;
+ CHECK_LYSP_NODE_LEAF(lysp_leaf, NULL, 0, 0x0, 0, "port", 0, 0, NULL, 0, 0, NULL, NULL);
+ CHECK_LYSP_TYPE(&(lysp_leaf->type), 0, 0, 0, 0, 0, 0x0, 0, 0, "int8", 0, 0, 1, 0, 0, 0);
+
+ /* TEST MODULE T1 */
+ schema = MODULE_CREATE_YANG("T1", "leaf port {type int8 {range \"0 .. 50 |51 .. 60\";}}");
+ UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, &mod);
+ assert_non_null(mod);
+ lysc_leaf = (void *)mod->compiled->data;
+ CHECK_LYSC_NODE_LEAF(lysc_leaf, NULL, 0, 0x5, 1, "port", 0, 0, 0, NULL, 0, 0, NULL, NULL);
+ CHECK_LYSC_TYPE_NUM((struct lysc_type_num *)lysc_leaf->type, LY_TYPE_INT8, 0, 1);
+ range = ((struct lysc_type_num *)lysc_leaf->type)->range;
+ CHECK_LYSC_RANGE(range, NULL, NULL, NULL, 0, 2, NULL);
+ assert_int_equal(range->parts[0].min_64, 0);
+ assert_int_equal(range->parts[0].max_64, 50);
+ assert_int_equal(range->parts[1].min_64, 51);
+ assert_int_equal(range->parts[1].max_64, 60);
+ lysp_leaf = (void *)mod->parsed->data;
+ CHECK_LYSP_NODE_LEAF(lysp_leaf, NULL, 0, 0x0, 0, "port", 0, 0, NULL, 0, 0, NULL, NULL);
+ CHECK_LYSP_TYPE(&(lysp_leaf->type), 0, 0, 0, 0, 0, 0x80, 0, 0, "int8", 0, 0, 1, 1, 0, 0);
+ CHECK_LYSP_RESTR(lysp_leaf->type.range, "0 .. 50 |51 .. 60", NULL, NULL, NULL, 0, NULL);
+
+ /* TEST MODULE T1 */
+ schema = MODULE_CREATE_YANG("T2", "leaf port {type int8 {range \"20\";}}");
+ UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, &mod);
+ assert_non_null(mod);
+ lysc_leaf = (void *)mod->compiled->data;
+ CHECK_LYSC_NODE_LEAF(lysc_leaf, NULL, 0, 0x5, 1, "port", 0, 0, 0, NULL, 0, 0, NULL, NULL);
+ CHECK_LYSC_TYPE_NUM((struct lysc_type_num *)lysc_leaf->type, LY_TYPE_INT8, 0, 1);
+ range = ((struct lysc_type_num *)lysc_leaf->type)->range;
+ CHECK_LYSC_RANGE(range, NULL, NULL, NULL, 0, 1, NULL);
+ assert_int_equal(range->parts[0].min_64, 20);
+ assert_int_equal(range->parts[0].max_64, 20);
+ lysp_leaf = (void *)mod->parsed->data;
+ CHECK_LYSP_NODE_LEAF(lysp_leaf, NULL, 0, 0x0, 0, "port", 0, 0, NULL, 0, 0, NULL, NULL);
+ CHECK_LYSP_TYPE(&(lysp_leaf->type), 0, 0, 0, 0, 0, 0x80, 0, 0, "int8", 0, 0, 1, 1, 0, 0);
+ CHECK_LYSP_RESTR(lysp_leaf->type.range, "20", NULL, NULL, NULL, 0, NULL);
+
+ /* TEST MODULE T3 */
+ schema = MODULE_CREATE_YANG("T3", "leaf port {type int8 {range \"-128 .. -60 | -1 .. 1 | 60 .. 127\";}}");
+ UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, &mod);
+ assert_non_null(mod);
+ lysc_leaf = (void *)mod->compiled->data;
+ CHECK_LYSC_NODE_LEAF(lysc_leaf, NULL, 0, 0x5, 1, "port", 0, 0, 0, NULL, 0, 0, NULL, NULL);
+ CHECK_LYSC_TYPE_NUM((struct lysc_type_num *)lysc_leaf->type, LY_TYPE_INT8, 0, 1);
+ range = ((struct lysc_type_num *)lysc_leaf->type)->range;
+ CHECK_LYSC_RANGE(range, NULL, NULL, NULL, 0, 3, NULL);
+ assert_int_equal(range->parts[0].min_64, -128);
+ assert_int_equal(range->parts[0].max_64, -60);
+ assert_int_equal(range->parts[1].min_64, -1);
+ assert_int_equal(range->parts[1].max_64, 1);
+ assert_int_equal(range->parts[2].min_64, 60);
+ assert_int_equal(range->parts[2].max_64, 127);
+ lysp_leaf = (void *)mod->parsed->data;
+ CHECK_LYSP_NODE_LEAF(lysp_leaf, NULL, 0, 0x0, 0, "port", 0, 0, NULL, 0, 0, NULL, NULL);
+ CHECK_LYSP_TYPE(&(lysp_leaf->type), 0, 0, 0, 0, 0, 0x80, 0, 0, "int8", 0, 0, 1, 1, 0, 0);
+ CHECK_LYSP_RESTR(lysp_leaf->type.range, "-128 .. -60 | -1 .. 1 | 60 .. 127", NULL, NULL, NULL, 0, NULL);
+
+ /* TEST MODULE T4 */
+ schema = MODULE_CREATE_YANG("T4", "leaf port {type int8 {range \"1 .. 1\";}}");
+ UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, &mod);
+ assert_non_null(mod);
+ lysc_leaf = (void *)mod->compiled->data;
+ CHECK_LYSC_NODE_LEAF(lysc_leaf, NULL, 0, 0x5, 1, "port", 0, 0, 0, NULL, 0, 0, NULL, NULL);
+ CHECK_LYSC_TYPE_NUM((struct lysc_type_num *)lysc_leaf->type, LY_TYPE_INT8, 0, 1);
+ range = ((struct lysc_type_num *)lysc_leaf->type)->range;
+ CHECK_LYSC_RANGE(range, NULL, NULL, NULL, 0, 1, NULL);
+ assert_int_equal(range->parts[0].min_64, 1);
+ assert_int_equal(range->parts[0].max_64, 1);
+ lysp_leaf = (void *)mod->parsed->data;
+ CHECK_LYSP_NODE_LEAF(lysp_leaf, NULL, 0, 0x0, 0, "port", 0, 0, NULL, 0, 0, NULL, NULL);
+ CHECK_LYSP_TYPE(&(lysp_leaf->type), 0, 0, 0, 0, 0, 0x80, 0, 0, "int8", 0, 0, 1, 1, 0, 0);
+ CHECK_LYSP_RESTR(lysp_leaf->type.range, "1 .. 1", NULL, NULL, NULL, 0, NULL);
+
+ /* TEST MODULE T4 */
+ schema = MODULE_CREATE_YANG("T5", "leaf port {type int8 {range \"7\";}}");
+ UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, &mod);
+ assert_non_null(mod);
+ lysc_leaf = (void *)mod->compiled->data;
+ CHECK_LYSC_NODE_LEAF(lysc_leaf, NULL, 0, 0x5, 1, "port", 0, 0, 0, NULL, 0, 0, NULL, NULL);
+ CHECK_LYSC_TYPE_NUM((struct lysc_type_num *)lysc_leaf->type, LY_TYPE_INT8, 0, 1);
+ range = ((struct lysc_type_num *)lysc_leaf->type)->range;
+ CHECK_LYSC_RANGE(range, NULL, NULL, NULL, 0, 1, NULL);
+ assert_int_equal(range->parts[0].min_64, 7);
+ assert_int_equal(range->parts[0].max_64, 7);
+ lysp_leaf = (void *)mod->parsed->data;
+ CHECK_LYSP_NODE_LEAF(lysp_leaf, NULL, 0, 0x0, 0, "port", 0, 0, NULL, 0, 0, NULL, NULL);
+ CHECK_LYSP_TYPE(&(lysp_leaf->type), 0, 0, 0, 0, 0, 0x80, 0, 0, "int8", 0, 0, 1, 1, 0, 0);
+ CHECK_LYSP_RESTR(lysp_leaf->type.range, "7", NULL, NULL, NULL, 0, NULL);
+
+ /* TEST MODULE T4 */
+ schema = MODULE_CREATE_YANG("T6", "leaf port {type int8 {range \"min .. max\";}}");
+ UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, &mod);
+ assert_non_null(mod);
+ lysc_leaf = (void *)mod->compiled->data;
+ CHECK_LYSC_NODE_LEAF(lysc_leaf, NULL, 0, 0x5, 1, "port", 0, 0, 0, NULL, 0, 0, NULL, NULL);
+ CHECK_LYSC_TYPE_NUM((struct lysc_type_num *)lysc_leaf->type, LY_TYPE_INT8, 0, 1);
+ range = ((struct lysc_type_num *)lysc_leaf->type)->range;
+ CHECK_LYSC_RANGE(range, NULL, NULL, NULL, 0, 1, NULL);
+ assert_int_equal(range->parts[0].min_64, -128);
+ assert_int_equal(range->parts[0].max_64, 127);
+ lysp_leaf = (void *)mod->parsed->data;
+ CHECK_LYSP_NODE_LEAF(lysp_leaf, NULL, 0, 0x0, 0, "port", 0, 0, NULL, 0, 0, NULL, NULL);
+ CHECK_LYSP_TYPE(&(lysp_leaf->type), 0, 0, 0, 0, 0, 0x80, 0, 0, "int8", 0, 0, 1, 1, 0, 0);
+ CHECK_LYSP_RESTR(lysp_leaf->type.range, "min .. max", NULL, NULL, NULL, 0, NULL);
+
+ /* TEST ERROR -60 .. 0 | 0 .. 127 */
+ schema = MODULE_CREATE_YANG("ERR0", "leaf port {type int8 {range \"-60 .. 0 | 0 .. 127\";}}");
+ UTEST_INVALID_MODULE(schema, LYS_IN_YANG, NULL, LY_EEXIST);
+ CHECK_LOG_CTX("Invalid range restriction - values are not in ascending order (0).", "/ERR0:port");
+
+ /* TEST ERROR 0 .. 128 */
+ schema = MODULE_CREATE_YANG("ERR1", "leaf port {type int8 {range \"0 .. 128\";}}");
+ UTEST_INVALID_MODULE(schema, LYS_IN_YANG, NULL, LY_EDENIED);
+ CHECK_LOG_CTX("Invalid range restriction - value \"128\" does not fit the type limitations.", "/ERR1:port");
+
+ /* TEST ERROR -129 .. 126 */
+ schema = MODULE_CREATE_YANG("ERR2", "leaf port {type int8 {range \"-129 .. 0\";}}");
+ UTEST_INVALID_MODULE(schema, LYS_IN_YANG, NULL, LY_EDENIED);
+ CHECK_LOG_CTX("Invalid range restriction - value \"-129\" does not fit the type limitations.", "/ERR2:port");
+
+ /* TEST ERROR 0 */
+ schema = MODULE_CREATE_YANG("ERR3", "leaf port {type int8 {range \"-129\";}}");
+ UTEST_INVALID_MODULE(schema, LYS_IN_YANG, NULL, LY_EDENIED);
+ CHECK_LOG_CTX("Invalid range restriction - value \"-129\" does not fit the type limitations.", "/ERR3:port");
+
+ /*
+ * TEST MODULE SUBTYPE
+ */
+ schema = MODULE_CREATE_YANG("TS0",
+ "typedef my_int_type {"
+ " type int8 {range \"-128 .. -60 | -1 .. 1 | 60 .. 127\";}"
+ "}"
+ "leaf my_leaf {type my_int_type; }");
+ UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, &mod);
+ assert_non_null(mod);
+ lysc_leaf = (void *)mod->compiled->data;
+ CHECK_LYSC_NODE_LEAF(lysc_leaf, NULL, 0, 0x5, 1, "my_leaf", 0, 0, 0, NULL, 0, 0, NULL, NULL);
+ CHECK_LYSC_TYPE_NUM((struct lysc_type_num *)lysc_leaf->type, LY_TYPE_INT8, 0, 1);
+ range = ((struct lysc_type_num *)lysc_leaf->type)->range;
+ CHECK_LYSC_RANGE(range, NULL, NULL, NULL, 0, 3, NULL);
+ assert_int_equal(range->parts[0].min_64, -128);
+ assert_int_equal(range->parts[0].max_64, -60);
+ assert_int_equal(range->parts[1].min_64, -1);
+ assert_int_equal(range->parts[1].max_64, 1);
+ assert_int_equal(range->parts[2].min_64, 60);
+ assert_int_equal(range->parts[2].max_64, 127);
+ lysp_leaf = (void *)mod->parsed->data;
+ CHECK_LYSP_NODE_LEAF(lysp_leaf, NULL, 0, 0x0, 0, "my_leaf", 0, 0, NULL, 0, 0, NULL, NULL);
+ CHECK_LYSP_TYPE(&(lysp_leaf->type), 0, 0, 0, 0, 0, 0x0, 0, 0, "my_int_type", 0, 0, 1, 0, 0, 0);
+
+ /* TEST SUBTYPE RANGE */
+ schema = MODULE_CREATE_YANG("TS1",
+ "typedef my_int_type {"
+ " type int8 {range \"-100 .. -60 | -1 .. 1 | 60 .. 127\";}"
+ "}"
+ "leaf my_leaf {type my_int_type {range \"min .. -60\";}}");
+ UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, &mod);
+ assert_non_null(mod);
+ lysc_leaf = (void *)mod->compiled->data;
+ CHECK_LYSC_NODE_LEAF(lysc_leaf, NULL, 0, 0x5, 1, "my_leaf", 0, 0, 0, NULL, 0, 0, NULL, NULL);
+ CHECK_LYSC_TYPE_NUM((struct lysc_type_num *)lysc_leaf->type, LY_TYPE_INT8, 0, 1);
+ range = ((struct lysc_type_num *)lysc_leaf->type)->range;
+ CHECK_LYSC_RANGE(range, NULL, NULL, NULL, 0, 1, NULL);
+ assert_int_equal(range->parts[0].min_64, -100);
+ assert_int_equal(range->parts[0].max_64, -60);
+ lysp_leaf = (void *)mod->parsed->data;
+ CHECK_LYSP_NODE_LEAF(lysp_leaf, NULL, 0, 0x0, 0, "my_leaf", 0, 0, NULL, 0, 0, NULL, NULL);
+ CHECK_LYSP_TYPE(&(lysp_leaf->type), 0, 0, 0, 0, 0, 0x80, 0, 0, "my_int_type", 0, 0, 1, 1, 0, 0);
+ CHECK_LYSP_RESTR(lysp_leaf->type.range, "min .. -60", NULL, NULL, NULL, 0, NULL);
+
+ /* TEST SUBTYPE RANGE */
+ schema = MODULE_CREATE_YANG("TS2",
+ "typedef my_int_type {"
+ " type int8 {range \"-100 .. -60 | -1 .. 1 | 60 .. 120\";}"
+ "}"
+ "leaf my_leaf {type my_int_type {range \"70 .. max\";}}");
+ UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, &mod);
+ assert_non_null(mod);
+ lysc_leaf = (void *)mod->compiled->data;
+ CHECK_LYSC_NODE_LEAF(lysc_leaf, NULL, 0, 0x5, 1, "my_leaf", 0, 0, 0, NULL, 0, 0, NULL, NULL);
+ CHECK_LYSC_TYPE_NUM((struct lysc_type_num *)lysc_leaf->type, LY_TYPE_INT8, 0, 1);
+ range = ((struct lysc_type_num *)lysc_leaf->type)->range;
+ CHECK_LYSC_RANGE(range, NULL, NULL, NULL, 0, 1, NULL);
+ assert_int_equal(range->parts[0].min_64, 70);
+ assert_int_equal(range->parts[0].max_64, 120);
+ lysp_leaf = (void *)mod->parsed->data;
+ CHECK_LYSP_NODE_LEAF(lysp_leaf, NULL, 0, 0x0, 0, "my_leaf", 0, 0, NULL, 0, 0, NULL, NULL);
+ CHECK_LYSP_TYPE(&(lysp_leaf->type), 0, 0, 0, 0, 0, 0x80, 0, 0, "my_int_type", 0, 0, 1, 1, 0, 0);
+ CHECK_LYSP_RESTR(lysp_leaf->type.range, "70 .. max", NULL, NULL, NULL, 0, NULL);
+
+ /* TEST SUBTYPE RANGE */
+ schema = MODULE_CREATE_YANG("TS3",
+ "typedef my_int_type {"
+ " type int8 {range \"-100 .. -60 | -1 .. 1 | 60 .. 127\";}"
+ "}"
+ "leaf my_leaf {type my_int_type {range \"-1 .. 1\";}}");
+ UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, &mod);
+ assert_non_null(mod);
+ lysc_leaf = (void *)mod->compiled->data;
+ CHECK_LYSC_NODE_LEAF(lysc_leaf, NULL, 0, 0x5, 1, "my_leaf", 0, 0, 0, NULL, 0, 0, NULL, NULL);
+ CHECK_LYSC_TYPE_NUM((struct lysc_type_num *)lysc_leaf->type, LY_TYPE_INT8, 0, 1);
+ range = ((struct lysc_type_num *)lysc_leaf->type)->range;
+ CHECK_LYSC_RANGE(range, NULL, NULL, NULL, 0, 1, NULL);
+ assert_int_equal(range->parts[0].min_64, -1);
+ assert_int_equal(range->parts[0].max_64, 1);
+ lysp_leaf = (void *)mod->parsed->data;
+ CHECK_LYSP_NODE_LEAF(lysp_leaf, NULL, 0, 0x0, 0, "my_leaf", 0, 0, NULL, 0, 0, NULL, NULL);
+ CHECK_LYSP_TYPE(&(lysp_leaf->type), 0, 0, 0, 0, 0, 0x80, 0, 0, "my_int_type", 0, 0, 1, 1, 0, 0);
+ CHECK_LYSP_RESTR(lysp_leaf->type.range, "-1 .. 1", NULL, NULL, NULL, 0, NULL);
+
+ /* TEST SUBTYPE RANGE */
+ schema = MODULE_CREATE_YANG("TS4",
+ "typedef my_int_type {"
+ " type int8 {range \"-128 .. -60 | -1 .. 1 | 60 .. 127\";}"
+ "}"
+ "leaf my_leaf {type my_int_type { "
+ " range \"min .. -60 | -1 .. 1 | 60 .. max\";}"
+ "}");
+ UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, &mod);
+ assert_non_null(mod);
+ lysc_leaf = (void *)mod->compiled->data;
+ CHECK_LYSC_NODE_LEAF(lysc_leaf, NULL, 0, 0x5, 1, "my_leaf", 0, 0, 0, NULL, 0, 0, NULL, NULL);
+ CHECK_LYSC_TYPE_NUM((struct lysc_type_num *)lysc_leaf->type, LY_TYPE_INT8, 0, 1);
+ range = ((struct lysc_type_num *)lysc_leaf->type)->range;
+ CHECK_LYSC_RANGE(range, NULL, NULL, NULL, 0, 3, NULL);
+ assert_int_equal(range->parts[0].min_64, -128);
+ assert_int_equal(range->parts[0].max_64, -60);
+ assert_int_equal(range->parts[1].min_64, -1);
+ assert_int_equal(range->parts[1].max_64, 1);
+ assert_int_equal(range->parts[2].min_64, 60);
+ assert_int_equal(range->parts[2].max_64, 127);
+ lysp_leaf = (void *)mod->parsed->data;
+ CHECK_LYSP_NODE_LEAF(lysp_leaf, NULL, 0, 0x0, 0, "my_leaf", 0, 0, NULL, 0, 0, NULL, NULL);
+ CHECK_LYSP_TYPE(&(lysp_leaf->type), 0, 0, 0, 0, 0, 0x80, 0, 0, "my_int_type", 0, 0, 1, 1, 0, 0);
+ CHECK_LYSP_RESTR(lysp_leaf->type.range, "min .. -60 | -1 .. 1 | 60 .. max", NULL, NULL, NULL, 0, NULL);
+
+ /* TEST SUBTYPE ERROR min .. max */
+ schema = MODULE_CREATE_YANG("TS_ERR0",
+ "typedef my_int_type { type int8 {range \"-128 .. -60 | -1 .. 1 | 60 .. 127\";}}"
+ "leaf my_leaf {type my_int_type {range \"min .. max\";}}");
+ UTEST_INVALID_MODULE(schema, LYS_IN_YANG, NULL, LY_EVALID);
+ CHECK_LOG_CTX("Invalid range restriction - the derived restriction (min .. max) is not equally or more limiting.",
+ "/TS_ERR0:my_leaf");
+
+ /* TEST SUBTYPE ERROR -80 .. 80 */
+ schema = MODULE_CREATE_YANG("TS_ERR1",
+ "typedef my_int_type { type int8 {range \"-128 .. -60 | -1 .. 1 | 60 .. 127\";}}"
+ " leaf my_leaf {type my_int_type {range \"-80 .. 80\";}}");
+ UTEST_INVALID_MODULE(schema, LYS_IN_YANG, NULL, LY_EVALID);
+ CHECK_LOG_CTX("Invalid range restriction - the derived restriction (-80 .. 80) is not equally or more limiting.",
+ "/TS_ERR1:my_leaf");
+
+ /* TEST SUBTYPE ERROR 0 .. max */
+ schema = MODULE_CREATE_YANG("TS_ERR2",
+ "typedef my_int_type { type int8 {range \"-128 .. -60 | -1 .. 1 | 60 .. 127\";}}"
+ "leaf my_leaf {type my_int_type {range \"0 .. max\";}}");
+ UTEST_INVALID_MODULE(schema, LYS_IN_YANG, NULL, LY_EVALID);
+ CHECK_LOG_CTX("Invalid range restriction - the derived restriction (0 .. max) is not equally or more limiting.",
+ "/TS_ERR2:my_leaf");
+
+ /* TEST SUBTYPE ERROR -2 .. 2 */
+ schema = MODULE_CREATE_YANG("TS_ERR3",
+ "typedef my_int_type { type int8 {range \"-128 .. -60 | -1 .. 1 | 60 .. 127\";}}"
+ "leaf my_leaf {type my_int_type {range \"-2 .. 2\";}}");
+ UTEST_INVALID_MODULE(schema, LYS_IN_YANG, NULL, LY_EVALID);
+ CHECK_LOG_CTX("Invalid range restriction - the derived restriction (-2 .. 2) is not equally or more limiting.",
+ "/TS_ERR3:my_leaf");
+
+ /* TEST SUBTYPE ERROR -2 .. 2 */
+ schema = MODULE_CREATE_YANG("TS_ERR4",
+ "typedef my_int_type { type int8 {range \"-128 .. -60 | -1 .. 1 | 60 .. 127\";}}"
+ "leaf my_leaf {type my_int_type {range \"-100 .. -90 | 100 .. 128\";}}");
+ UTEST_INVALID_MODULE(schema, LYS_IN_YANG, NULL, LY_EDENIED);
+ CHECK_LOG_CTX("Invalid range restriction - value \"128\" does not fit the type limitations.",
+ "/TS_ERR4:my_leaf");
+
+ /*
+ * TEST DEFAULT VALUE
+ */
+ schema = MODULE_CREATE_YANG("DF0",
+ "leaf port {"
+ " type int8 {range \"0 .. 50 | 127\";}"
+ " default \"20\";"
+ "}");
+ UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, &mod);
+ assert_non_null(mod);
+ lysc_leaf = (void *)mod->compiled->data;
+ CHECK_LYSC_NODE_LEAF(lysc_leaf, NULL, 0, 0x205, 1, "port", 0, 0, 0, NULL, 0, 0, NULL, 1);
+ CHECK_LYSC_TYPE_NUM((struct lysc_type_num *)lysc_leaf->type, LY_TYPE_INT8, 0, 1);
+ CHECK_LYD_VALUE(*(lysc_leaf->dflt), INT8, "20", 20);
+ range = ((struct lysc_type_num *)lysc_leaf->type)->range;
+ CHECK_LYSC_RANGE(range, NULL, NULL, NULL, 0, 2, NULL);
+ assert_int_equal(range->parts[0].min_64, 0);
+ assert_int_equal(range->parts[0].max_64, 50);
+ assert_int_equal(range->parts[1].min_64, 127);
+ assert_int_equal(range->parts[1].max_64, 127);
+ lysp_leaf = (void *)mod->parsed->data;
+ CHECK_LYSP_NODE_LEAF(lysp_leaf, NULL, 0, 0x0, 0, "port", 0, 0, NULL, 0, 0, NULL, "20");
+ CHECK_LYSP_TYPE(&(lysp_leaf->type), 0, 0, 0, 0, 0, 0x80, 0, 0, "int8", 0, 0, 1, 1, 0, 0);
+ CHECK_LYSP_RESTR(lysp_leaf->type.range, "0 .. 50 | 127", NULL, NULL, NULL, 0, NULL);
+
+ /* TEST DEFAULT VALUE */
+ schema = MODULE_CREATE_YANG("DF1", "leaf port {type int8 {range \"0 .. 50 | 127\";}"
+ "default \"127\"; }");
+ UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, &mod);
+ assert_non_null(mod);
+ lysc_leaf = (void *)mod->compiled->data;
+ CHECK_LYSC_NODE_LEAF(lysc_leaf, NULL, 0, 0x205, 1, "port", 0, 0, 0, NULL, 0, 0, NULL, 1);
+ CHECK_LYSC_TYPE_NUM((struct lysc_type_num *)lysc_leaf->type, LY_TYPE_INT8, 0, 1);
+ CHECK_LYD_VALUE(*(lysc_leaf->dflt), INT8, "127", 127);
+ range = ((struct lysc_type_num *)lysc_leaf->type)->range;
+ CHECK_LYSC_RANGE(range, NULL, NULL, NULL, 0, 2, NULL);
+ assert_int_equal(range->parts[0].min_64, 0);
+ assert_int_equal(range->parts[0].max_64, 50);
+ assert_int_equal(range->parts[1].min_64, 127);
+ assert_int_equal(range->parts[1].max_64, 127);
+ lysp_leaf = (void *)mod->parsed->data;
+ CHECK_LYSP_NODE_LEAF(lysp_leaf, NULL, 0, 0x0, 0, "port", 0, 0, NULL, 0, 0, NULL, "127");
+ CHECK_LYSP_TYPE(&(lysp_leaf->type), 0, 0, 0, 0, 0, 0x80, 0, 0, "int8", 0, 0, 1, 1, 0, 0);
+ CHECK_LYSP_RESTR(lysp_leaf->type.range, "0 .. 50 | 127", NULL, NULL, NULL, 0, NULL);
+
+ /* TEST DEFAULT VALUE ERROR */
+ schema = MODULE_CREATE_YANG("TD_ERR0",
+ "leaf port {"
+ " type int8 {range \"0 .. 50 | 127\";}"
+ " default \"128\";"
+ "}");
+ UTEST_INVALID_MODULE(schema, LYS_IN_YANG, NULL, LY_EVALID);
+ CHECK_LOG_CTX("Invalid default - value does not fit the type (Value \"128\" is out of type int8 min/max bounds.).",
+ "Schema location \"/TD_ERR0:port\".");
+
+ /* TEST DEFAULT VALUE ERROR */
+ schema = MODULE_CREATE_YANG("TD_ERR1",
+ "leaf port {"
+ " type int8 {range \"0 .. 50 | 127\";}"
+ " default \"-1\";"
+ "}");
+ UTEST_INVALID_MODULE(schema, LYS_IN_YANG, NULL, LY_EVALID);
+ CHECK_LOG_CTX("Invalid default - value does not fit the type (Unsatisfied range - value \"-1\" is out of the allowed range.).",
+ "Schema location \"/TD_ERR1:port\".");
+
+ /* TEST DEFAULT VALUE ERROR */
+ schema = MODULE_CREATE_YANG("TD_ERR2",
+ "leaf port {"
+ " type int8 {range \"0 .. 50 | 127\";}"
+ " default \"60\";"
+ "}");
+ UTEST_INVALID_MODULE(schema, LYS_IN_YANG, NULL, LY_EVALID);
+ CHECK_LOG_CTX("Invalid default - value does not fit the type (Unsatisfied range - value \"60\" is out of the allowed range.).",
+ "Schema location \"/TD_ERR2:port\".");
+
+ /* TEST DEFAULT VALUE ERROR */
+ schema = MODULE_CREATE_YANG("TD_ERR3",
+ "typedef my_int_type { type int8 {range \"60 .. 127\";} default \"127\";}"
+ "leaf my_leaf {type my_int_type {range \"70 .. 80\";}}");
+ UTEST_INVALID_MODULE(schema, LYS_IN_YANG, NULL, LY_EVALID);
+ CHECK_LOG_CTX("Invalid default - value does not fit the type (Unsatisfied range - value \"127\" is out of the allowed range.).",
+ "Schema location \"/TD_ERR3:my_leaf\".");
+
+ /* TEST DEFAULT HEXADECIMAL */
+ schema = MODULE_CREATE_YANG("DF_HEX0",
+ "leaf port {"
+ " type int8;"
+ " default \"0xf\";"
+ "}");
+ UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, &mod);
+ assert_non_null(mod);
+ lysc_leaf = (void *)mod->compiled->data;
+ CHECK_LYSC_NODE_LEAF(lysc_leaf, NULL, 0, 0x205, 1, "port", 0, 0, 0, NULL, 0, 0, NULL, 1);
+ CHECK_LYSC_TYPE_NUM((struct lysc_type_num *)lysc_leaf->type, LY_TYPE_INT8, 0, 0);
+ CHECK_LYD_VALUE(*(lysc_leaf->dflt), INT8, "15", 15);
+ lysp_leaf = (void *)mod->parsed->data;
+ CHECK_LYSP_NODE_LEAF(lysp_leaf, NULL, 0, 0x0, 0, "port", 0, 0, NULL, 0, 0, NULL, "0xf");
+ CHECK_LYSP_TYPE(&(lysp_leaf->type), 0, 0, 0, 0, 0, 0x0, 0, 0, "int8", 0, 0, 1, 0, 0, 0);
+
+ /* TEST DEFAULT HEXADECIMAL */
+ schema = MODULE_CREATE_YANG("DF_HEX1",
+ "leaf port {"
+ " type int8;"
+ " default \"-0xf\";"
+ "}");
+ UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, &mod);
+ assert_non_null(mod);
+ lysc_leaf = (void *)mod->compiled->data;
+ CHECK_LYSC_NODE_LEAF(lysc_leaf, NULL, 0, 0x205, 1, "port", 0, 0, 0, NULL, 0, 0, NULL, 1);
+ CHECK_LYSC_TYPE_NUM((struct lysc_type_num *)lysc_leaf->type, LY_TYPE_INT8, 0, 0);
+ CHECK_LYD_VALUE(*(lysc_leaf->dflt), INT8, "-15", -15);
+ lysp_leaf = (void *)mod->parsed->data;
+ CHECK_LYSP_NODE_LEAF(lysp_leaf, NULL, 0, 0x0, 0, "port", 0, 0, NULL, 0, 0, NULL, "-0xf");
+ CHECK_LYSP_TYPE(&(lysp_leaf->type), 0, 0, 0, 0, 0, 0x0, 0, 0, "int8", 0, 0, 1, 0, 0, 0);
+
+ /* TEST DEFAULT HEXADECIMAL */
+ schema = MODULE_CREATE_YANG("DF_HEXI0",
+ "leaf port {"
+ " type int8 {range \"0 .. 50 | 127\";}"
+ " default \"+0x7F\";"
+ "}");
+ UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, &mod);
+ assert_non_null(mod);
+ lysc_leaf = (void *)mod->compiled->data;
+ CHECK_LYSC_NODE_LEAF(lysc_leaf, NULL, 0, 0x205, 1, "port", 0, 0, 0, NULL, 0, 0, NULL, 1);
+ CHECK_LYSC_TYPE_NUM((struct lysc_type_num *)lysc_leaf->type, LY_TYPE_INT8, 0, 1);
+ CHECK_LYD_VALUE(*(lysc_leaf->dflt), INT8, "127", 127);
+ range = ((struct lysc_type_num *)lysc_leaf->type)->range;
+ CHECK_LYSC_RANGE(range, NULL, NULL, NULL, 0, 2, NULL);
+ assert_int_equal(range->parts[0].min_64, 0);
+ assert_int_equal(range->parts[0].max_64, 50);
+ assert_int_equal(range->parts[1].min_64, 127);
+ assert_int_equal(range->parts[1].max_64, 127);
+ lysp_leaf = (void *)mod->parsed->data;
+ CHECK_LYSP_NODE_LEAF(lysp_leaf, NULL, 0, 0x0, 0, "port", 0, 0, NULL, 0, 0, NULL, "+0x7F");
+ CHECK_LYSP_TYPE(&(lysp_leaf->type), 0, 0, 0, 0, 0, 0x80, 0, 0, "int8", 0, 0, 1, 1, 0, 0);
+ CHECK_LYSP_RESTR(lysp_leaf->type.range, "0 .. 50 | 127", NULL, NULL, NULL, 0, NULL);
+
+ /* TEST DEFAULT HEXADECIMAL ERROR */
+ schema = MODULE_CREATE_YANG("DF_HEX2",
+ "leaf port {"
+ " type int8;"
+ " default \"0xff\";"
+ "}");
+ UTEST_INVALID_MODULE(schema, LYS_IN_YANG, NULL, LY_EVALID);
+ CHECK_LOG_CTX("Invalid default - value does not fit the type (Value \"0xff\" is out of type int8 min/max bounds.).",
+ "Schema location \"/DF_HEX2:port\".");
+
+ /* TEST DEFAULT HEXADECIMAL ERROR */
+ schema = MODULE_CREATE_YANG("DF_HEX3",
+ "leaf port {"
+ " type int8;"
+ " default \"-0x81\";"
+ "}");
+ UTEST_INVALID_MODULE(schema, LYS_IN_YANG, NULL, LY_EVALID);
+ CHECK_LOG_CTX("Invalid default - value does not fit the type (Value \"-0x81\" is out of type int8 min/max bounds.).",
+ "Schema location \"/DF_HEX3:port\".");
+
+ /* TEST DEFAULT HEXADECIMAL ERROR */
+ schema = MODULE_CREATE_YANG("DF_HEX4",
+ "leaf port {"
+ " type int8;"
+ " default \"0x80\";"
+ "}");
+ UTEST_INVALID_MODULE(schema, LYS_IN_YANG, NULL, LY_EVALID);
+ CHECK_LOG_CTX("Invalid default - value does not fit the type (Value \"0x80\" is out of type int8 min/max bounds.).",
+ "Schema location \"/DF_HEX4:port\".");
+
+ /* TEST DEFAULT VALUE OCTAL */
+ schema = MODULE_CREATE_YANG("DF_OCT0",
+ "leaf port {"
+ " type int8;"
+ " default \"017\";"
+ "}");
+ UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, &mod);
+ assert_non_null(mod);
+ lysc_leaf = (void *)mod->compiled->data;
+ CHECK_LYSC_NODE_LEAF(lysc_leaf, NULL, 0, 0x205, 1, "port", 0, 0, 0, NULL, 0, 0, NULL, 1);
+ CHECK_LYSC_TYPE_NUM((struct lysc_type_num *)lysc_leaf->type, LY_TYPE_INT8, 0, 0);
+ CHECK_LYD_VALUE(*(lysc_leaf->dflt), INT8, "15", 15);
+ lysp_leaf = (void *)mod->parsed->data;
+ CHECK_LYSP_NODE_LEAF(lysp_leaf, NULL, 0, 0x0, 0, "port", 0, 0, NULL, 0, 0, NULL, "017");
+ CHECK_LYSP_TYPE(&(lysp_leaf->type), 0, 0, 0, 0, 0, 0x0, 0, 0, "int8", 0, 0, 1, 0, 0, 0);
+
+ /* TEST DEFAULT VALUE OCTAL */
+ schema = MODULE_CREATE_YANG("DF_OCT1",
+ "leaf port {"
+ " type int8;"
+ " default \"-017\";"
+ "}");
+ UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, &mod);
+ assert_non_null(mod);
+ lysc_leaf = (void *)mod->compiled->data;
+ CHECK_LYSC_NODE_LEAF(lysc_leaf, NULL, 0, 0x205, 1, "port", 0, 0, 0, NULL, 0, 0, NULL, 1);
+ CHECK_LYSC_TYPE_NUM((struct lysc_type_num *)lysc_leaf->type, LY_TYPE_INT8, 0, 0);
+ CHECK_LYD_VALUE(*(lysc_leaf->dflt), INT8, "-15", -15);
+ lysp_leaf = (void *)mod->parsed->data;
+ CHECK_LYSP_NODE_LEAF(lysp_leaf, NULL, 0, 0x0, 0, "port", 0, 0, NULL, 0, 0, NULL, "-017");
+ CHECK_LYSP_TYPE(&(lysp_leaf->type), 0, 0, 0, 0, 0, 0x0, 0, 0, "int8", 0, 0, 1, 0, 0, 0);
+
+ /* TEST DEFAULT VALUE OCTAL */
+ schema = MODULE_CREATE_YANG("DF_OCTI0",
+ "leaf port {"
+ " type int8;"
+ " default \"+017\";"
+ "}");
+ UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, &mod);
+ assert_non_null(mod);
+ lysc_leaf = (void *)mod->compiled->data;
+ CHECK_LYSC_NODE_LEAF(lysc_leaf, NULL, 0, 0x205, 1, "port", 0, 0, 0, NULL, 0, 0, NULL, 1);
+ CHECK_LYSC_TYPE_NUM((struct lysc_type_num *)lysc_leaf->type, LY_TYPE_INT8, 0, 0);
+ CHECK_LYD_VALUE(*(lysc_leaf->dflt), INT8, "15", 15);
+ lysp_leaf = (void *)mod->parsed->data;
+ CHECK_LYSP_NODE_LEAF(lysp_leaf, NULL, 0, 0x0, 0, "port", 0, 0, NULL, 0, 0, NULL, "+017");
+ CHECK_LYSP_TYPE(&(lysp_leaf->type), 0, 0, 0, 0, 0, 0x0, 0, 0, "int8", 0, 0, 1, 0, 0, 0);
+
+ /* TEST DEFAULT VALUE OCTAL ERROR*/
+ schema = MODULE_CREATE_YANG("DF_OCT2",
+ "leaf port {"
+ " type int8;"
+ " default \"0377\";"
+ "}");
+ UTEST_INVALID_MODULE(schema, LYS_IN_YANG, NULL, LY_EVALID);
+ CHECK_LOG_CTX("Invalid default - value does not fit the type (Value \"0377\" is out of type int8 min/max bounds.).",
+ "Schema location \"/DF_OCT2:port\".");
+
+ /* TEST DEFAULT VALUE OCTAL ERROR*/
+ schema = MODULE_CREATE_YANG("DF_OCT3",
+ "leaf port {"
+ " type int8;"
+ " default \"-0201\";"
+ "}");
+ UTEST_INVALID_MODULE(schema, LYS_IN_YANG, NULL, LY_EVALID);
+ CHECK_LOG_CTX("Invalid default - value does not fit the type (Value \"-0201\" is out of type int8 min/max bounds.).",
+ "Schema location \"/DF_OCT3:port\".");
+
+ /* TEST DEFAULT VALUE OCTAL ERROR*/
+ schema = MODULE_CREATE_YANG("DF_OCT4",
+ "leaf port {"
+ " type int8;"
+ " default \"0200\";"
+ "}");
+ UTEST_INVALID_MODULE(schema, LYS_IN_YANG, NULL, LY_EVALID);
+ CHECK_LOG_CTX("Invalid default - value does not fit the type (Value \"0200\" is out of type int8 min/max bounds.).",
+ "Schema location \"/DF_OCT4:port\".");
+}
+
+static void
+test_schema_yin(void **state)
+{
+ const char *schema;
+ struct lys_module *mod;
+ struct lysc_node_leaf *lysc_leaf;
+ struct lysp_node_leaf *lysp_leaf;
+ struct lysc_range *range;
+
+ /* TEST T0 */
+ schema = MODULE_CREATE_YIN("T0", "<leaf name=\"port\"> <type name=\"int8\"/> </leaf>");
+ UTEST_ADD_MODULE(schema, LYS_IN_YIN, NULL, &mod);
+ assert_non_null(mod);
+ lysc_leaf = (void *)mod->compiled->data;
+ CHECK_LYSC_NODE_LEAF(lysc_leaf, NULL, 0, 0x5, 1, "port", 0, 0, 0, NULL, 0, 0, NULL, NULL);
+ CHECK_LYSC_TYPE_NUM((struct lysc_type_num *)lysc_leaf->type, LY_TYPE_INT8, 0, 0);
+ range = ((struct lysc_type_num *)lysc_leaf->type)->range;
+ lysp_leaf = (void *)mod->parsed->data;
+ CHECK_LYSP_NODE_LEAF(lysp_leaf, NULL, 0, 0x0, 0, "port", 0, 0, NULL, 0, 0, NULL, NULL);
+ CHECK_LYSP_TYPE(&(lysp_leaf->type), 0, 0, 0, 0, 0, 0x0, 0, 0, "int8", 0, 0, 1, 0, 0, 0);
+
+ /* TEST T1 */
+ schema = MODULE_CREATE_YIN("T1",
+ "<leaf name=\"port\"> "
+ " <type name=\"int8\"> <range value = \"0 .. 10\"/> </type>"
+ "</leaf>");
+ UTEST_ADD_MODULE(schema, LYS_IN_YIN, NULL, &mod);
+ assert_non_null(mod);
+ lysc_leaf = (void *)mod->compiled->data;
+ CHECK_LYSC_NODE_LEAF(lysc_leaf, NULL, 0, 0x5, 1, "port", 0, 0, 0, NULL, 0, 0, NULL, NULL);
+ CHECK_LYSC_TYPE_NUM((struct lysc_type_num *)lysc_leaf->type, LY_TYPE_INT8, 0, 1);
+ range = ((struct lysc_type_num *)lysc_leaf->type)->range;
+ CHECK_LYSC_RANGE(range, NULL, NULL, NULL, 0, 1, NULL);
+ assert_int_equal(range->parts[0].min_64, 0);
+ assert_int_equal(range->parts[0].max_64, 10);
+ lysp_leaf = (void *)mod->parsed->data;
+ CHECK_LYSP_NODE_LEAF(lysp_leaf, NULL, 0, 0x0, 0, "port", 0, 0, NULL, 0, 0, NULL, NULL);
+ CHECK_LYSP_TYPE(&(lysp_leaf->type), 0, 0, 0, 0, 0, 0x80, 0, 0, "int8", 0, 0, 1, 1, 0, 0);
+ CHECK_LYSP_RESTR(lysp_leaf->type.range, "0 .. 10", NULL, NULL, NULL, 0, NULL);
+
+ /* TEST T1 */
+ schema = MODULE_CREATE_YIN("T2",
+ "<leaf name=\"port\"> "
+ " <type name=\"int8\"> <range value = \"-127 .. 10 | max\"/> </type>"
+ "</leaf>");
+ UTEST_ADD_MODULE(schema, LYS_IN_YIN, NULL, &mod);
+ assert_non_null(mod);
+ lysc_leaf = (void *)mod->compiled->data;
+ CHECK_LYSC_NODE_LEAF(lysc_leaf, NULL, 0, 0x5, 1, "port", 0, 0, 0, NULL, 0, 0, NULL, NULL);
+ CHECK_LYSC_TYPE_NUM((struct lysc_type_num *)lysc_leaf->type, LY_TYPE_INT8, 0, 1);
+ range = ((struct lysc_type_num *)lysc_leaf->type)->range;
+ CHECK_LYSC_RANGE(range, NULL, NULL, NULL, 0, 2, NULL);
+ assert_int_equal(range->parts[0].min_64, -127);
+ assert_int_equal(range->parts[0].max_64, 10);
+ assert_int_equal(range->parts[1].min_64, 127);
+ assert_int_equal(range->parts[1].max_64, 127);
+ lysp_leaf = (void *)mod->parsed->data;
+ CHECK_LYSP_NODE_LEAF(lysp_leaf, NULL, 0, 0x0, 0, "port", 0, 0, NULL, 0, 0, NULL, NULL);
+ CHECK_LYSP_TYPE(&(lysp_leaf->type), 0, 0, 0, 0, 0, 0x80, 0, 0, "int8", 0, 0, 1, 1, 0, 0);
+ CHECK_LYSP_RESTR(lysp_leaf->type.range, "-127 .. 10 | max", NULL, NULL, NULL, 0, NULL);
+
+ /* TEST T2 */
+ schema = MODULE_CREATE_YIN("T3",
+ "<leaf name=\"port\"> "
+ " <type name=\"int8\"> <range value =\"min .. 10 | 11 .. 12 | 30\"/> </type>"
+ "</leaf>");
+ UTEST_ADD_MODULE(schema, LYS_IN_YIN, NULL, &mod);
+ assert_non_null(mod);
+ lysc_leaf = (void *)mod->compiled->data;
+ CHECK_LYSC_NODE_LEAF(lysc_leaf, NULL, 0, 0x5, 1, "port", 0, 0, 0, NULL, 0, 0, NULL, NULL);
+ CHECK_LYSC_TYPE_NUM((struct lysc_type_num *)lysc_leaf->type, LY_TYPE_INT8, 0, 1);
+ range = ((struct lysc_type_num *)lysc_leaf->type)->range;
+ CHECK_LYSC_RANGE(range, NULL, NULL, NULL, 0, 3, NULL);
+ assert_int_equal(range->parts[0].min_64, -128);
+ assert_int_equal(range->parts[0].max_64, 10);
+ assert_int_equal(range->parts[1].min_64, 11);
+ assert_int_equal(range->parts[1].max_64, 12);
+ assert_int_equal(range->parts[2].min_64, 30);
+ assert_int_equal(range->parts[2].max_64, 30);
+ lysp_leaf = (void *)mod->parsed->data;
+ CHECK_LYSP_NODE_LEAF(lysp_leaf, NULL, 0, 0x0, 0, "port", 0, 0, NULL, 0, 0, NULL, NULL);
+ CHECK_LYSP_TYPE(&(lysp_leaf->type), 0, 0, 0, 0, 0, 0x80, 0, 0, "int8", 0, 0, 1, 1, 0, 0);
+ CHECK_LYSP_RESTR(lysp_leaf->type.range, "min .. 10 | 11 .. 12 | 30", NULL, NULL, NULL, 0, NULL);
+
+ /* TEST ERROR -60 .. 0 | 0 .. 127 */
+ schema = MODULE_CREATE_YIN("TE0",
+ "<leaf name=\"port\"> "
+ " <type name=\"int8\"> <range value = \"min .. 0 | 0 .. 12\"/> </type>"
+ "</leaf>");
+ UTEST_INVALID_MODULE(schema, LYS_IN_YIN, NULL, LY_EEXIST);
+ CHECK_LOG_CTX("Invalid range restriction - values are not in ascending order (0).", "/TE0:port");
+
+ /* TEST ERROR 0 .. 128 */
+ schema = MODULE_CREATE_YIN("TE1",
+ "<leaf name=\"port\">"
+ " <type name=\"int8\"> <range value = \"0 .. 128\"/> </type>"
+ "</leaf>");
+ UTEST_INVALID_MODULE(schema, LYS_IN_YIN, NULL, LY_EDENIED);
+ CHECK_LOG_CTX("Invalid range restriction - value \"128\" does not fit the type limitations.", "/TE1:port");
+
+ /* TEST ERROR -129 .. 126 */
+ schema = MODULE_CREATE_YIN("TE2",
+ "<leaf name=\"port\"> "
+ " <type name=\"int8\"> <range value =\"-129 .. 126\"/> </type>"
+ "</leaf>");
+ UTEST_INVALID_MODULE(schema, LYS_IN_YIN, NULL, LY_EDENIED);
+ CHECK_LOG_CTX("Invalid range restriction - value \"-129\" does not fit the type limitations.", "/TE2:port");
+
+ /* TEST YIN */
+ schema = MODULE_CREATE_YIN("TS0",
+ "<typedef name= \"my_int_type\">"
+ " <type name=\"int8\"> <range value = \"-127 .. 10 | max\"/> </type>"
+ "</typedef>"
+ "<leaf name=\"my_leaf\"> <type name=\"my_int_type\"/> </leaf>");
+ UTEST_ADD_MODULE(schema, LYS_IN_YIN, NULL, &mod);
+ assert_non_null(mod);
+ lysc_leaf = (void *)mod->compiled->data;
+ CHECK_LYSC_NODE_LEAF(lysc_leaf, NULL, 0, 0x5, 1, "my_leaf", 0, 0, 0, NULL, 0, 0, NULL, NULL);
+ CHECK_LYSC_TYPE_NUM((struct lysc_type_num *)lysc_leaf->type, LY_TYPE_INT8, 0, 1);
+ range = ((struct lysc_type_num *)lysc_leaf->type)->range;
+ CHECK_LYSC_RANGE(range, NULL, NULL, NULL, 0, 2, NULL);
+ assert_int_equal(range->parts[0].min_64, -127);
+ assert_int_equal(range->parts[0].max_64, 10);
+ assert_int_equal(range->parts[1].min_64, 127);
+ assert_int_equal(range->parts[1].max_64, 127);
+ lysp_leaf = (void *)mod->parsed->data;
+ CHECK_LYSP_NODE_LEAF(lysp_leaf, NULL, 0, 0x0, 0, "my_leaf", 0, 0, NULL, 0, 0, NULL, NULL);
+ CHECK_LYSP_TYPE(&(lysp_leaf->type), 0, 0, 0, 0, 0, 0x0, 0, 0, "my_int_type", 0, 0, 1, 0, 0, 0);
+
+ /* TEST YIN */
+ schema = MODULE_CREATE_YIN("TS1",
+ "<typedef name= \"my_int_type\">"
+ " <type name=\"int8\"> <range value = \"-127 .. 10 | 90 .. 100\"/> </type>"
+ "</typedef>"
+ "<leaf name=\"port\"> <type name=\"my_int_type\"> <range value ="
+ " \"min .. -30 | 100 .. max\"/> </type> </leaf>");
+ UTEST_ADD_MODULE(schema, LYS_IN_YIN, NULL, &mod);
+ assert_non_null(mod);
+ lysc_leaf = (void *)mod->compiled->data;
+ CHECK_LYSC_NODE_LEAF(lysc_leaf, NULL, 0, 0x5, 1, "port", 0, 0, 0, NULL, 0, 0, NULL, NULL);
+ CHECK_LYSC_TYPE_NUM((struct lysc_type_num *)lysc_leaf->type, LY_TYPE_INT8, 0, 1);
+ range = ((struct lysc_type_num *)lysc_leaf->type)->range;
+ CHECK_LYSC_RANGE(range, NULL, NULL, NULL, 0, 2, NULL);
+ assert_int_equal(range->parts[0].min_64, -127);
+ assert_int_equal(range->parts[0].max_64, -30);
+ assert_int_equal(range->parts[1].min_64, 100);
+ assert_int_equal(range->parts[1].max_64, 100);
+ lysp_leaf = (void *)mod->parsed->data;
+ CHECK_LYSP_NODE_LEAF(lysp_leaf, NULL, 0, 0x0, 0, "port", 0, 0, NULL, 0, 0, NULL, NULL);
+ CHECK_LYSP_TYPE(&(lysp_leaf->type), 0, 0, 0, 0, 0, 0x80, 0, 0, "my_int_type", 0, 0, 1, 1, 0, 0);
+ CHECK_LYSP_RESTR(lysp_leaf->type.range, "min .. -30 | 100 .. max", NULL, NULL, NULL, 0, NULL);
+
+ /* TEST ERROR */
+ schema = MODULE_CREATE_YIN("TS_ERR1",
+ "<typedef name= \"my_int_type\">"
+ " <type name=\"int8\"> <range value = \"-127 .. 10 | 90 .. 100\"/> </type>"
+ "</typedef>"
+ "<leaf name=\"port\">"
+ " <type name=\"my_int_type\"> <range value = \"min .. max\"/> </type>"
+ "</leaf>");
+ UTEST_INVALID_MODULE(schema, LYS_IN_YIN, NULL, LY_EVALID);
+ CHECK_LOG_CTX("Invalid range restriction - the derived restriction (min .. max) is not equally or more limiting.",
+ "/TS_ERR1:port");
+
+ /* TEST ERROR */
+ schema = MODULE_CREATE_YIN("TS_ERR2",
+ "<typedef name= \"my_int_type\">"
+ " <type name=\"int8\"> <range value = \"-127 .. 10 | 90 .. 100\"/> </type>"
+ "</typedef>"
+ "<leaf name=\"port\">"
+ " <type name=\"my_int_type\"> <range value = \"5 .. 11\"/> </type>"
+ "</leaf>");
+ UTEST_INVALID_MODULE(schema, LYS_IN_YIN, NULL, LY_EVALID);
+ CHECK_LOG_CTX("Invalid range restriction - the derived restriction (5 .. 11) is not equally or more limiting.",
+ "/TS_ERR2:port");
+
+ /* TEST DEFAULT VALUE */
+ schema = MODULE_CREATE_YIN("DF0",
+ "<leaf name=\"port\">"
+ " <default value=\"12\" />"
+ " <type name=\"int8\"> <range value = \"min .. 0 | 1 .. 12\"/> </type>"
+ "</leaf>");
+ UTEST_ADD_MODULE(schema, LYS_IN_YIN, NULL, &mod);
+ assert_non_null(mod);
+ lysc_leaf = (void *)mod->compiled->data;
+ CHECK_LYSC_NODE_LEAF(lysc_leaf, NULL, 0, 0x205, 1, "port", 0, 0, 0, NULL, 0, 0, NULL, 1);
+ CHECK_LYSC_TYPE_NUM((struct lysc_type_num *)lysc_leaf->type, LY_TYPE_INT8, 0, 1);
+ CHECK_LYD_VALUE(*(lysc_leaf->dflt), INT8, "12", 12);
+ range = ((struct lysc_type_num *)lysc_leaf->type)->range;
+ CHECK_LYSC_RANGE(range, NULL, NULL, NULL, 0, 2, NULL);
+ assert_int_equal(range->parts[0].min_64, -128);
+ assert_int_equal(range->parts[0].max_64, 0);
+ assert_int_equal(range->parts[1].min_64, 1);
+ assert_int_equal(range->parts[1].max_64, 12);
+ lysp_leaf = (void *)mod->parsed->data;
+ CHECK_LYSP_NODE_LEAF(lysp_leaf, NULL, 0, 0x0, 0, "port", 0, 0, NULL, 0, 0, NULL, "12");
+ CHECK_LYSP_TYPE(&(lysp_leaf->type), 0, 0, 0, 0, 0, 0x80, 0, 0, "int8", 0, 0, 1, 1, 0, 0);
+ CHECK_LYSP_RESTR(lysp_leaf->type.range, "min .. 0 | 1 .. 12", NULL, NULL, NULL, 0, NULL);
+
+ /* TEST ERROR TD0 */
+ schema = MODULE_CREATE_YIN("TD_ERR0",
+ "<leaf name=\"port\">"
+ " <default value=\"128\" />"
+ " <type name=\"int8\"> <range value = \"min .. 0 | 1 .. 12\"/> </type>"
+ "</leaf>");
+ UTEST_INVALID_MODULE(schema, LYS_IN_YIN, NULL, LY_EVALID);
+ CHECK_LOG_CTX("Invalid default - value does not fit the type (Value \"128\" is out of type int8 min/max bounds.).",
+ "Schema location \"/TD_ERR0:port\".");
+
+ /* TEST ERROR TD1 */
+ schema = MODULE_CREATE_YIN("TD_ERR1",
+ "<leaf name=\"port\">"
+ " <default value=\"13\" />"
+ " <type name=\"int8\"> <range value = \"min .. 0 | 1 .. 12\"/> </type>"
+ "</leaf>");
+ UTEST_INVALID_MODULE(schema, LYS_IN_YIN, NULL, LY_EVALID);
+ CHECK_LOG_CTX("Invalid default - value does not fit the type (Unsatisfied range - value \"13\" is out of the allowed range.).",
+ "Schema location \"/TD_ERR1:port\".");
+
+ /* TEST ERROR TD1 */
+ schema = MODULE_CREATE_YIN("TD_ERR3",
+ "<typedef name= \"my_int_type\">"
+ " <default value=\"10\" />"
+ " <type name=\"int8\"> <range value = \"-127 .. 10 | max\"/> </type>"
+ "</typedef>"
+ "<leaf name=\"my_leaf\">"
+ " <type name=\"my_int_type\">"
+ " <range value = \"-127 .. -80\"/> </type>"
+ "</leaf>");
+ UTEST_INVALID_MODULE(schema, LYS_IN_YIN, NULL, LY_EVALID);
+ CHECK_LOG_CTX("Invalid default - value does not fit the type (Unsatisfied range - value \"10\" is out of the allowed range.).",
+ "Schema location \"/TD_ERR3:my_leaf\".");
+
+ /* TEST DEFAULT VALUE HEXADECIMAL */
+ schema = MODULE_CREATE_YIN("DF_HEX0",
+ "<leaf name=\"port\">"
+ " <default value=\"+0xf\" />"
+ " <type name=\"int8\" />"
+ "</leaf>");
+ UTEST_ADD_MODULE(schema, LYS_IN_YIN, NULL, &mod);
+ assert_non_null(mod);
+ lysc_leaf = (void *)mod->compiled->data;
+ CHECK_LYSC_NODE_LEAF(lysc_leaf, NULL, 0, 0x205, 1, "port", 0, 0, 0, NULL, 0, 0, NULL, 1);
+ CHECK_LYSC_TYPE_NUM((struct lysc_type_num *)lysc_leaf->type, LY_TYPE_INT8, 0, 0);
+ CHECK_LYD_VALUE(*(lysc_leaf->dflt), INT8, "15", 15);
+ lysp_leaf = (void *)mod->parsed->data;
+ CHECK_LYSP_NODE_LEAF(lysp_leaf, NULL, 0, 0x0, 0, "port", 0, 0, NULL, 0, 0, NULL, "+0xf");
+ CHECK_LYSP_TYPE(&(lysp_leaf->type), 0, 0, 0, 0, 0, 0x0, 0, 0, "int8", 0, 0, 1, 0, 0, 0);
+
+ /* TEST DEFAULT VALUE HEXADECIMAL */
+ schema = MODULE_CREATE_YIN("DF_HEX1",
+ "<leaf name=\"port\">"
+ " <default value=\"-0xf\" />"
+ " <type name=\"int8\" />"
+ "</leaf>");
+ UTEST_ADD_MODULE(schema, LYS_IN_YIN, NULL, &mod);
+ assert_non_null(mod);
+ lysc_leaf = (void *)mod->compiled->data;
+ CHECK_LYSC_NODE_LEAF(lysc_leaf, NULL, 0, 0x205, 1, "port", 0, 0, 0, NULL, 0, 0, NULL, 1);
+ CHECK_LYSC_TYPE_NUM((struct lysc_type_num *)lysc_leaf->type, LY_TYPE_INT8, 0, 0);
+ CHECK_LYD_VALUE(*(lysc_leaf->dflt), INT8, "-15", -15);
+ lysp_leaf = (void *)mod->parsed->data;
+ CHECK_LYSP_NODE_LEAF(lysp_leaf, NULL, 0, 0x0, 0, "port", 0, 0, NULL, 0, 0, NULL, "-0xf");
+ CHECK_LYSP_TYPE(&(lysp_leaf->type), 0, 0, 0, 0, 0, 0x0, 0, 0, "int8", 0, 0, 1, 0, 0, 0);
+
+ /* TEST DEFAULT VALUE HEXADECIMAL ERROR */
+ schema = MODULE_CREATE_YIN("DF_HEX2",
+ "<leaf name=\"port\">"
+ " <default value=\"0xff\" />"
+ " <type name=\"int8\" />"
+ "</leaf>");
+ UTEST_INVALID_MODULE(schema, LYS_IN_YIN, NULL, LY_EVALID);
+ CHECK_LOG_CTX("Invalid default - value does not fit the type (Value \"0xff\" is out of type int8 min/max bounds.).",
+ "Schema location \"/DF_HEX2:port\".");
+
+ /* TEST DEFAULT VALUE HEXADECIMAL ERROR */
+ schema = MODULE_CREATE_YIN("DF_HEX2",
+ "<leaf name=\"port\">"
+ " <default value=\"-0x81\" />"
+ " <type name=\"int8\" />"
+ "</leaf>");
+ UTEST_INVALID_MODULE(schema, LYS_IN_YIN, NULL, LY_EVALID);
+ CHECK_LOG_CTX("Invalid default - value does not fit the type (Value \"-0x81\" is out of type int8 min/max bounds.).",
+ "Schema location \"/DF_HEX2:port\".");
+
+ /* TEST DEFAULT VALUE HEXADECIMAL ERROR */
+ schema = MODULE_CREATE_YIN("DF_HEX4",
+ "<leaf name=\"port\">"
+ " <default value=\"0x80\" />"
+ " <type name=\"int8\" />"
+ "</leaf>");
+ UTEST_INVALID_MODULE(schema, LYS_IN_YIN, NULL, LY_EVALID);
+ CHECK_LOG_CTX("Invalid default - value does not fit the type (Value \"0x80\" is out of type int8 min/max bounds.).",
+ "Schema location \"/DF_HEX4:port\".");
+
+ /* TEST DEFAULT VALUE OCTAL */
+ schema = MODULE_CREATE_YIN("DF_OCT0",
+ "<leaf name=\"port\">"
+ " <default value=\"+017\" />"
+ " <type name=\"int8\" />"
+ "</leaf>");
+ UTEST_ADD_MODULE(schema, LYS_IN_YIN, NULL, &mod);
+ assert_non_null(mod);
+ lysc_leaf = (void *)mod->compiled->data;
+ CHECK_LYSC_NODE_LEAF(lysc_leaf, NULL, 0, 0x205, 1, "port", 0, 0, 0, NULL, 0, 0, NULL, 1);
+ CHECK_LYSC_TYPE_NUM((struct lysc_type_num *)lysc_leaf->type, LY_TYPE_INT8, 0, 0);
+ CHECK_LYD_VALUE(*(lysc_leaf->dflt), INT8, "15", 15);
+ lysp_leaf = (void *)mod->parsed->data;
+ CHECK_LYSP_NODE_LEAF(lysp_leaf, NULL, 0, 0x0, 0, "port", 0, 0, NULL, 0, 0, NULL, "+017");
+ CHECK_LYSP_TYPE(&(lysp_leaf->type), 0, 0, 0, 0, 0, 0x0, 0, 0, "int8", 0, 0, 1, 0, 0, 0);
+
+ /* TEST DEFAULT VALUE OCTAL */
+ schema = MODULE_CREATE_YIN("DF_OCT1",
+ "<leaf name=\"port\">"
+ " <default value=\"-017\" />"
+ " <type name=\"int8\" />"
+ "</leaf>");
+ UTEST_ADD_MODULE(schema, LYS_IN_YIN, NULL, &mod);
+ assert_non_null(mod);
+ lysc_leaf = (void *)mod->compiled->data;
+ CHECK_LYSC_NODE_LEAF(lysc_leaf, NULL, 0, 0x205, 1, "port", 0, 0, 0, NULL, 0, 0, NULL, 1);
+ CHECK_LYSC_TYPE_NUM((struct lysc_type_num *)lysc_leaf->type, LY_TYPE_INT8, 0, 0);
+ CHECK_LYD_VALUE(*(lysc_leaf->dflt), INT8, "-15", -15);
+ lysp_leaf = (void *)mod->parsed->data;
+ CHECK_LYSP_NODE_LEAF(lysp_leaf, NULL, 0, 0x0, 0, "port", 0, 0, NULL, 0, 0, NULL, "-017");
+ CHECK_LYSP_TYPE(&(lysp_leaf->type), 0, 0, 0, 0, 0, 0x0, 0, 0, "int8", 0, 0, 1, 0, 0, 0);
+
+ /* TEST DEFAULT VALUE OCTAL ERROR */
+ schema = MODULE_CREATE_YIN("DF_OCT2",
+ "<leaf name=\"port\">"
+ " <default value=\"-0201\" />"
+ " <type name=\"int8\" />"
+ "</leaf>");
+ UTEST_INVALID_MODULE(schema, LYS_IN_YIN, NULL, LY_EVALID);
+ CHECK_LOG_CTX("Invalid default - value does not fit the type (Value \"-0201\" is out of type int8 min/max bounds.).",
+ "Schema location \"/DF_OCT2:port\".");
+
+ /* TEST DEFAULT VALUE OCTAL ERROR */
+ schema = MODULE_CREATE_YIN("DF_OCT3",
+ "<leaf name=\"port\">"
+ " <default value=\"0200\" />"
+ " <type name=\"int8\" />"
+ "</leaf>");
+ UTEST_INVALID_MODULE(schema, LYS_IN_YIN, NULL, LY_EVALID);
+ CHECK_LOG_CTX("Invalid default - value does not fit the type (Value \"0200\" is out of type int8 min/max bounds.).",
+ "Schema location \"/DF_OCT3:port\".");
+}
+
+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",
+ " description \"desc\";\n"
+ "leaf port {type int8 {range \"0 .. 50 | 127\";} default \"20\";}");
+ schema_yin = MODULE_CREATE_YIN("PRINT0",
+ "\n"
+ " <description>\n"
+ " <text>desc</text>\n"
+ " </description>\n"
+ " <leaf name=\"port\">\n"
+ " <type name=\"int8\">\n"
+ " <range value=\"0 .. 50 | 127\"/>\n"
+ " </type>\n"
+ " <default value=\"20\"/>\n"
+ " </leaf>\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"
+ " description\n"
+ " \"desc\";\n\n"
+ " leaf port {\n"
+ " type int8 {\n"
+ " range \"0 .. 50 | 127\";\n"
+ " }\n"
+ " default \"20\";\n"
+ " }\n");
+ schema_yin = MODULE_CREATE_YIN("PRINT1",
+ "<description>"
+ " <text>desc</text>"
+ "</description>"
+ "<leaf name=\"port\">"
+ " <type name=\"int8\">"
+ " <range value=\"0 .. 50 | 127\"/>"
+ " </type>"
+ "<default value=\"20\"/>"
+ "</leaf>");
+
+ 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 print yang to yin */
+ schema_yang = MODULE_CREATE_YANG("PRINT2",
+ " description \"desc\";\n"
+ "leaf port {type int8;}");
+ schema_yin = MODULE_CREATE_YIN("PRINT2",
+ "\n"
+ " <description>\n"
+ " <text>desc</text>\n"
+ " </description>\n"
+ " <leaf name=\"port\">\n"
+ " <type name=\"int8\"/>\n"
+ " </leaf>\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("PRINT3",
+ "\n"
+ " leaf port {\n"
+ " type int8;\n"
+ " }\n");
+ schema_yin = MODULE_CREATE_YIN("PRINT3",
+ "<leaf name=\"port\">"
+ " <type name=\"int8\"/>"
+ "</leaf>");
+
+ 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);
+}
+
+static void
+test_data_xml(void **state)
+{
+ const char *schema;
+ struct lyd_node *tree;
+ const char *data;
+ /* variable for default value test */
+ struct lysc_node_container *lysc_root;
+ struct lyd_node_inner *lyd_root;
+
+ /* xml test */
+ schema = MODULE_CREATE_YANG("defs", "leaf port {type int8 {range \"0 .. 50 | 105\";}}");
+ UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, NULL);
+
+ TEST_SUCCESS_XML("defs", "+50", INT8, "50", 50);
+ TEST_SUCCESS_XML("defs", "50", INT8, "50", 50);
+ TEST_SUCCESS_XML("defs", "105", INT8, "105", 105);
+ TEST_SUCCESS_XML("defs", "0", INT8, "0", 0);
+ TEST_SUCCESS_XML("defs", "-0", INT8, "0", 0);
+ TEST_ERROR_XML("defs", "-1");
+ CHECK_LOG_CTX("Unsatisfied range - value \"-1\" is out of the allowed range.",
+ "Schema location \"/defs:port\", line number 1.");
+ TEST_ERROR_XML("defs", "51");
+ CHECK_LOG_CTX("Unsatisfied range - value \"51\" is out of the allowed range.",
+ "Schema location \"/defs:port\", line number 1.");
+ TEST_ERROR_XML("defs", "106");
+ CHECK_LOG_CTX("Unsatisfied range - value \"106\" is out of the allowed range.",
+ "Schema location \"/defs:port\", line number 1.");
+ TEST_ERROR_XML("defs", "104");
+ CHECK_LOG_CTX("Unsatisfied range - value \"104\" is out of the allowed range.",
+ "Schema location \"/defs:port\", line number 1.");
+ TEST_ERROR_XML("defs", "60");
+ CHECK_LOG_CTX("Unsatisfied range - value \"60\" is out of the allowed range.",
+ "Schema location \"/defs:port\", line number 1.");
+
+ schema = MODULE_CREATE_YANG("T0", "leaf port {type int8; }");
+ UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, NULL);
+ TEST_SUCCESS_XML("T0", "-128", INT8, "-128", -128);
+ TEST_SUCCESS_XML("T0", "-100", INT8, "-100", -100);
+ TEST_SUCCESS_XML("T0", "0", INT8, "0", 0);
+ TEST_SUCCESS_XML("T0", "10", INT8, "10", 10);
+ TEST_SUCCESS_XML("T0", "50", INT8, "50", 50);
+ TEST_SUCCESS_XML("T0", "127", INT8, "127", 127);
+ /* leading zeros */
+ TEST_SUCCESS_XML("T0", "-015", INT8, "-15", -15);
+ TEST_SUCCESS_XML("T0", "015", INT8, "15", 15);
+ TEST_ERROR_XML("T0", "-129");
+ CHECK_LOG_CTX("Value \"-129\" is out of type int8 min/max bounds.",
+ "Schema location \"/T0:port\", line number 1.");
+ TEST_ERROR_XML("T0", "128");
+ CHECK_LOG_CTX("Value \"128\" is out of type int8 min/max bounds.",
+ "Schema location \"/T0:port\", line number 1.");
+ TEST_ERROR_XML("T0", "256");
+ CHECK_LOG_CTX("Value \"256\" is out of type int8 min/max bounds.",
+ "Schema location \"/T0:port\", line number 1.");
+ TEST_ERROR_XML("T0", "1024");
+ CHECK_LOG_CTX("Value \"1024\" is out of type int8 min/max bounds.",
+ "Schema location \"/T0:port\", line number 1.");
+
+ /*
+ * default value
+ */
+ schema = MODULE_CREATE_YANG("T1",
+ "container cont {\n"
+ " leaf port {type int8 {range \"0 .. 50 | 105\";} default \"20\";}"
+ "}");
+ /* check using default value */
+ UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, NULL);
+ data = "<cont xmlns=\"urn:tests:" "T1" "\">" "</cont>";
+ CHECK_PARSE_LYD_PARAM(data, LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_SUCCESS, tree);
+ lysc_root = (void *)tree->schema;
+ CHECK_LYSC_NODE(lysc_root->child, NULL, 0, 0x205, 1, "port", 0, LYS_LEAF, 1, 0, 0, 0);
+ lyd_root = ((struct lyd_node_inner *)tree);
+ CHECK_LYD_NODE_TERM((struct lyd_node_term *)lyd_root->child, 1, 0, 0, 1, 1,
+ INT8, "20", 20);\
+ lyd_free_all(tree);
+
+ /* check rewriting default value */
+ UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, NULL);
+ data = "<cont xmlns=\"urn:tests:T1\">" "<port> 30 </port>" "</cont>";
+ CHECK_PARSE_LYD_PARAM(data, LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_SUCCESS, tree);
+ lysc_root = (void *)tree->schema;
+ CHECK_LYSC_NODE(lysc_root->child, NULL, 0, 0x205, 1, "port", 0, LYS_LEAF, 1, 0, 0, 0);
+ lyd_root = ((struct lyd_node_inner *)tree);
+ CHECK_LYD_NODE_TERM((struct lyd_node_term *)lyd_root->child, 0, 0, 0, 1, 1,
+ INT8, "30", 30);
+ lyd_free_all(tree);
+
+ /*
+ * specific error
+ */
+ schema = MODULE_CREATE_YANG("T2", "leaf port {type int8 {range \"0 .. 50 | 105\" {"
+ " error-app-tag \"range-violation\";"
+ " error-message \"invalid range of value\";"
+ "}}}");
+ UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, NULL);
+
+ TEST_ERROR_XML("T2", "120");
+ CHECK_LOG_CTX_APPTAG("invalid range of value", "Schema location \"/T2:port\", line number 1.", "range-violation");
+}
+
+static void
+test_data_json(void **state)
+{
+ const char *schema;
+ /* value for default test */
+ struct lysc_node_container *lysc_root;
+ struct lyd_node_inner *lyd_root;
+ const char *data;
+ struct lyd_node *tree;
+
+ /* parsing json data */
+ schema = MODULE_CREATE_YANG("defs", "leaf port {type int8 {range \"0 .. 50 | 105\";}}");
+ UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, NULL);
+
+ TEST_SUCCESS_JSON("defs", "50", INT8, "50", 50);
+ TEST_SUCCESS_JSON("defs", "50", INT8, "50", 50);
+ TEST_SUCCESS_JSON("defs", "105", INT8, "105", 105);
+ TEST_SUCCESS_JSON("defs", "0", INT8, "0", 0);
+ TEST_SUCCESS_JSON("defs", "-0", INT8, "0", 0);
+ TEST_ERROR_JSON("defs", "-1");
+ CHECK_LOG_CTX("Unsatisfied range - value \"-1\" is out of the allowed range.",
+ "Schema location \"/defs:port\", line number 1.");
+ TEST_ERROR_JSON("defs", "51");
+ CHECK_LOG_CTX("Unsatisfied range - value \"51\" is out of the allowed range.",
+ "Schema location \"/defs:port\", line number 1.");
+ TEST_ERROR_JSON("defs", "106");
+ CHECK_LOG_CTX("Unsatisfied range - value \"106\" is out of the allowed range.",
+ "Schema location \"/defs:port\", line number 1.");
+ TEST_ERROR_JSON("defs", "104");
+ CHECK_LOG_CTX("Unsatisfied range - value \"104\" is out of the allowed range.",
+ "Schema location \"/defs:port\", line number 1.");
+ TEST_ERROR_JSON("defs", "60");
+ CHECK_LOG_CTX("Unsatisfied range - value \"60\" is out of the allowed range.",
+ "Schema location \"/defs:port\", line number 1.");
+
+ schema = MODULE_CREATE_YANG("T0", "leaf port {type int8; }");
+ UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, NULL);
+ TEST_SUCCESS_JSON("T0", "-128", INT8, "-128", -128);
+ TEST_SUCCESS_JSON("T0", "-100", INT8, "-100", -100);
+ TEST_SUCCESS_JSON("T0", "0", INT8, "0", 0);
+ TEST_SUCCESS_JSON("T0", "10", INT8, "10", 10);
+ TEST_SUCCESS_JSON("T0", "50", INT8, "50", 50);
+ TEST_SUCCESS_JSON("T0", "127", INT8, "127", 127);
+ /* leading zeros */
+ TEST_ERROR_JSON("T0", "015");
+ TEST_ERROR_JSON("T0", "-015");
+ TEST_ERROR_JSON("defs", "+50");
+ TEST_ERROR_JSON("T0", "-129");
+ CHECK_LOG_CTX("Value \"-129\" is out of type int8 min/max bounds.",
+ "Schema location \"/T0:port\", line number 1.");
+ TEST_ERROR_JSON("T0", "128");
+ CHECK_LOG_CTX("Value \"128\" is out of type int8 min/max bounds.",
+ "Schema location \"/T0:port\", line number 1.");
+ TEST_ERROR_JSON("T0", "256");
+ CHECK_LOG_CTX("Value \"256\" is out of type int8 min/max bounds.",
+ "Schema location \"/T0:port\", line number 1.");
+ TEST_ERROR_JSON("T0", "1024");
+ CHECK_LOG_CTX("Value \"1024\" is out of type int8 min/max bounds.",
+ "Schema location \"/T0:port\", line number 1.");
+
+ /*
+ * default value
+ */
+ schema = MODULE_CREATE_YANG("T1",
+ "container cont {\n"
+ " leaf port {type int8 {range \"0 .. 50 | 105\";} default \"20\";}"
+ "}");
+ /* check using default value */
+ UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, NULL);
+ data = "{\"T1:cont\":{}}";
+ CHECK_PARSE_LYD_PARAM(data, LYD_JSON, 0, LYD_VALIDATE_PRESENT, LY_SUCCESS, tree);
+ lysc_root = (void *)tree->schema;
+ CHECK_LYSC_NODE(lysc_root->child, NULL, 0, 0x205, 1, "port", 0, LYS_LEAF, 1, 0, 0, 0);
+ lyd_root = ((struct lyd_node_inner *)tree);
+ CHECK_LYD_NODE_TERM((struct lyd_node_term *)lyd_root->child, 1, 0, 0, 1, 1,
+ INT8, "20", 20);\
+ lyd_free_all(tree);
+
+ /* check rewriting default value */
+ UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, NULL);
+ data = "{\"T1:cont\":{\":port\":30}}";
+ CHECK_PARSE_LYD_PARAM(data, LYD_JSON, 0, LYD_VALIDATE_PRESENT, LY_SUCCESS, tree);
+ lysc_root = (void *)tree->schema;
+ CHECK_LYSC_NODE(lysc_root->child, NULL, 0, 0x205, 1, "port", 0, LYS_LEAF, 1, 0, 0, 0);
+ lyd_root = ((struct lyd_node_inner *)tree);
+ CHECK_LYD_NODE_TERM((struct lyd_node_term *)lyd_root->child, 0, 0, 0, 1, 1,
+ INT8, "30", 30);
+ lyd_free_all(tree);
+
+}
+
+static void
+test_data_lyb(void **state)
+{
+ const char *schema;
+
+ schema = MODULE_CREATE_YANG("lyb", "leaf port {type int8;}");
+ UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, NULL);
+ TEST_SUCCESS_LYB("lyb", "port", "-128");
+ TEST_SUCCESS_LYB("lyb", "port", "0");
+ TEST_SUCCESS_LYB("lyb", "port", "1");
+ TEST_SUCCESS_LYB("lyb", "port", "127");
+}
+
+static void
+test_diff(void **state)
+{
+ const char *schema;
+
+ schema = MODULE_CREATE_YANG("defs", "leaf port {type int8 {range \"0 .. 50 | 120\";}}");
+ UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, NULL);
+
+ struct lyd_node *model_1, *model_2;
+ struct lyd_node *diff;
+ const char *expected_string;
+ const char *data_1 = "<port xmlns=\"urn:tests:defs\"> 5 </port>";
+ const char *data_2 = "<port xmlns=\"urn:tests:defs\"> 6 </port>";
+ const char *diff_expected = "<port xmlns=\"urn:tests:defs\" "
+ "xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" "
+ "yang:operation=\"replace\" yang:orig-default=\"false\" yang:orig-value=\"5\">"
+ "6</port>";
+
+ LYD_TREE_CREATE(data_1, model_1);
+ LYD_TREE_CREATE(data_2, 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);
+
+ /* create data from diff */
+ diff_expected = "<port xmlns=\"urn:tests:defs\" "
+ "xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" "
+ "yang:operation=\"replace\" yang:orig-default=\"false\" yang:orig-value=\"5\">"
+ "120</port>";
+ LYD_TREE_CREATE(diff_expected, diff);
+ data_1 = "<port xmlns=\"urn:tests:defs\"> 5 </port>";
+ LYD_TREE_CREATE(data_1, model_1);
+ assert_int_equal(LY_SUCCESS, lyd_diff_apply_all(&model_1, diff));
+ expected_string = "<port xmlns=\"urn:tests:defs\">120</port>";
+
+ CHECK_LYD_STRING_PARAM(model_1, expected_string, LYD_XML, LYD_PRINT_WITHSIBLINGS | LYD_PRINT_SHRINK);
+ lyd_free_all(model_1);
+ lyd_free_all(diff);
+
+ /*
+ * check creating data out of range
+ */
+ diff_expected = "<port xmlns=\"urn:tests:defs\" "
+ "xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" "
+ "yang:operation=\"replace\" yang:orig-default=\"false\" yang:orig-value=\"5\">"
+ "121</port>";
+ CHECK_PARSE_LYD_PARAM(diff_expected, LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_EVALID, model_1);
+ CHECK_LOG_CTX("Unsatisfied range - value \"121\" is out of the allowed range.",
+ "Schema location \"/defs:port\", line number 1.");
+
+ /*
+ * diff from default value
+ */
+ data_1 = "<cont xmlns=\"urn:tests:T0\"></cont>";
+ data_2 = "<cont xmlns=\"urn:tests:T0\"> <port> 6 </port> </cont>";
+ diff_expected = "<cont xmlns=\"urn:tests:T0\""
+ " xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\""
+ " yang:operation=\"create\"><port>6</port></cont>";
+
+ schema = MODULE_CREATE_YANG("T0",
+ "container cont {\n"
+ " leaf port {type int8; default \"20\";}"
+ "}");
+ UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, NULL);
+ LYD_TREE_CREATE(data_1, model_1);
+ LYD_TREE_CREATE(data_2, 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(diff);
+
+ lyd_free_all(model_1);
+ lyd_free_all(model_2);
+}
+
+static void
+test_print(void **state)
+{
+ const char *schema = MODULE_CREATE_YANG("defs", "leaf port {type int8 {range \"0 .. 50\";}}");
+ const char *expected_string;
+
+ UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, NULL);
+
+ struct lyd_node *model_1;
+ const char *data_1 = "<port xmlns=\"urn:tests:defs\"> 50 </port>";
+
+ LYD_TREE_CREATE(data_1, model_1);
+
+ /* XML */
+ expected_string = "<port xmlns=\"urn:tests:defs\">50</port>";
+ CHECK_LYD_STRING_PARAM(model_1, expected_string, LYD_XML, LYD_PRINT_SHRINK | LYD_PRINT_WITHSIBLINGS | LYD_PRINT_SHRINK);
+
+ /* JSON */
+ expected_string = "{\"defs:port\":50}";
+ CHECK_LYD_STRING_PARAM(model_1, expected_string, LYD_JSON, LYD_PRINT_SHRINK | LYD_PRINT_WITHSIBLINGS | LYD_PRINT_SHRINK);
+
+ lyd_free_all(model_1);
+}
+
+static void
+test_plugin_store(void **state)
+{
+ const char *val_text = NULL;
+ struct ly_err_item *err = NULL;
+ struct lys_module *mod;
+ struct lyd_value value = {0};
+ struct lyplg_type *type = lyplg_type_plugin_find("", NULL, ly_data_type2str[LY_TYPE_INT8]);
+ struct lysc_type *lysc_type;
+ LY_ERR ly_ret;
+ char *alloc;
+ const char *schema;
+ struct lysc_type lysc_type_test;
+
+ /* create schema. Prepare common used variables */
+ schema = MODULE_CREATE_YANG("defs", "leaf port {type int8 {range \"-50 .. 50\";}}");
+ UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, &mod);
+ lysc_type = ((struct lysc_node_leaf *)mod->compiled->data)->type;
+
+ /* check proper type */
+ assert_string_equal("libyang 2 - integers, version 1", type->id);
+
+ /* check store
+ * options = LY_TYPE_STORE_IMPLEMENT | LY_TYPE_STORE_DYNAMIC
+ * hint = LYD_VALHINT_DECNUM, LYD_VALHINT_HEXNUM, LYD_VALHINT_OCTNUM
+ */
+ val_text = "20";
+ assert_int_equal(LY_SUCCESS, type->store(UTEST_LYCTX, lysc_type, val_text, strlen(val_text),
+ 0, LY_VALUE_XML, NULL, LYD_VALHINT_DECNUM, NULL, &value, NULL, &err));
+ CHECK_LYD_VALUE(value, INT8, "20", 20);
+ assert_ptr_equal(value.realtype, lysc_type);
+ type->free(UTEST_LYCTX, &value);
+
+ val_text = "-20";
+ assert_int_equal(LY_SUCCESS, type->store(UTEST_LYCTX, lysc_type, val_text, strlen(val_text),
+ 0, LY_VALUE_XML, NULL, LYD_VALHINT_DECNUM, NULL, &value, NULL, &err));
+ CHECK_LYD_VALUE(value, INT8, "-20", -20);
+ assert_ptr_equal(value.realtype, lysc_type);
+ type->free(UTEST_LYCTX, &value);
+
+ val_text = "0xf";
+ ly_ret = type->store(UTEST_LYCTX, lysc_type, val_text, strlen(val_text),
+ 0, LY_VALUE_XML, NULL, LYD_VALHINT_HEXNUM, NULL, &value, NULL, &err);
+ assert_int_equal(LY_SUCCESS, ly_ret);
+ CHECK_LYD_VALUE(value, INT8, "15", 15);
+ assert_ptr_equal(value.realtype, lysc_type);
+ type->free(UTEST_LYCTX, &value);
+
+ val_text = "1B";
+ ly_ret = type->store(UTEST_LYCTX, lysc_type, val_text, strlen(val_text),
+ 0, LY_VALUE_XML, NULL, LYD_VALHINT_HEXNUM, NULL, &value, NULL, &err);
+ assert_int_equal(LY_SUCCESS, ly_ret);
+ CHECK_LYD_VALUE(value, INT8, "27", 27);
+ assert_ptr_equal(value.realtype, lysc_type);
+ type->free(UTEST_LYCTX, &value);
+
+ val_text = "-0xf";
+ ly_ret = type->store(UTEST_LYCTX, lysc_type, val_text, strlen(val_text),
+ 0, LY_VALUE_XML, NULL, LYD_VALHINT_HEXNUM, NULL, &value, NULL, &err);
+ assert_int_equal(LY_SUCCESS, ly_ret);
+ CHECK_LYD_VALUE(value, INT8, "-15", -15);
+ assert_ptr_equal(value.realtype, lysc_type);
+ type->free(UTEST_LYCTX, &value);
+
+ val_text = "027";
+ ly_ret = type->store(UTEST_LYCTX, lysc_type, val_text, strlen(val_text),
+ 0, LY_VALUE_XML, NULL, LYD_VALHINT_OCTNUM, NULL, &value, NULL, &err);
+ assert_int_equal(LY_SUCCESS, ly_ret);
+ CHECK_LYD_VALUE(value, INT8, "23", 23);
+ assert_ptr_equal(value.realtype, lysc_type);
+ type->free(UTEST_LYCTX, &value);
+
+ val_text = "-027";
+ ly_ret = type->store(UTEST_LYCTX, lysc_type, val_text, strlen(val_text),
+ 0, LY_VALUE_XML, NULL, LYD_VALHINT_OCTNUM, NULL, &value, NULL, &err);
+ assert_int_equal(LY_SUCCESS, ly_ret);
+ CHECK_LYD_VALUE(value, INT8, "-23", -23);
+ assert_ptr_equal(value.realtype, lysc_type);
+ type->free(UTEST_LYCTX, &value);
+
+ /*
+ * minor tests
+ * dynamic alocated input text
+ */
+ val_text = "0xa";
+ alloc = (char *)malloc(strlen(val_text) + 1);
+
+ memcpy(alloc, val_text, strlen(val_text) + 1);
+ ly_ret = type->store(UTEST_LYCTX, lysc_type, alloc, strlen(val_text),
+ LYPLG_TYPE_STORE_DYNAMIC, LY_VALUE_XML, NULL, LYD_VALHINT_HEXNUM, NULL, &value, NULL, &err);
+ alloc = NULL;
+ assert_int_equal(LY_SUCCESS, ly_ret);
+ CHECK_LYD_VALUE(value, INT8, "10", 10);
+ type->free(UTEST_LYCTX, &value);
+
+ /* wrong lysc_type of value */
+ lysc_type_test = *lysc_type;
+ lysc_type_test.basetype = LY_TYPE_UINT8;
+ val_text = "20";
+ ly_ret = type->store(UTEST_LYCTX, &lysc_type_test, val_text, strlen(val_text),
+ 0, LY_VALUE_XML, NULL, LYD_VALHINT_HEXNUM, NULL, &value, NULL, &err);
+ assert_int_equal(LY_EINT, ly_ret);
+
+ /*
+ * ERROR TESTS
+ */
+ val_text = "";
+ err = NULL;
+ ly_ret = type->store(UTEST_LYCTX, lysc_type, val_text, strlen(val_text),
+ 0, LY_VALUE_XML, NULL, LYD_VALHINT_HEXNUM, NULL, &value, NULL, &err);
+ assert_int_equal(LY_EVALID, ly_ret);
+ ly_err_free(err);
+
+ val_text = "";
+ err = NULL;
+ ly_ret = type->store(UTEST_LYCTX, lysc_type, val_text, 1,
+ 0, LY_VALUE_XML, NULL, LYD_VALHINT_HEXNUM, NULL, &value, NULL, &err);
+ assert_int_equal(LY_EVALID, ly_ret);
+ ly_err_free(err);
+
+ val_text = "10 b";
+ err = NULL;
+ ly_ret = type->store(UTEST_LYCTX, lysc_type, val_text, strlen(val_text),
+ 0, LY_VALUE_XML, NULL, LYD_VALHINT_HEXNUM, NULL, &value, NULL, &err);
+ assert_int_equal(LY_EVALID, ly_ret);
+ ly_err_free(err);
+
+ val_text = "a";
+ err = NULL;
+ ly_ret = type->store(UTEST_LYCTX, lysc_type, val_text, strlen(val_text),
+ 0, LY_VALUE_XML, NULL, LYD_VALHINT_DECNUM, NULL, &value, NULL, &err);
+ assert_int_equal(LY_EVALID, ly_ret);
+ ly_err_free(err);
+}
+
+static void
+test_plugin_compare(void **state)
+{
+ struct ly_err_item *err = NULL;
+ struct lys_module *mod;
+ struct lyd_value values[10];
+ struct lyplg_type *type = lyplg_type_plugin_find("", NULL, ly_data_type2str[LY_TYPE_INT8]);
+ struct lysc_type *lysc_type;
+ LY_ERR ly_ret;
+ const char *schema;
+ /* different type */
+ const char *diff_type_text = "20";
+ struct lyd_value diff_type_val;
+ struct lysc_type *diff_type;
+ /* Value which are going to be created to tested */
+ const char *val_init[] = {"20", "30", "-30", "0", "-0", "20"};
+
+ /* create schema. Prepare common used variables */
+ schema = MODULE_CREATE_YANG("T0", "typedef my_int_type {type int8; }"
+ "leaf p1 {type my_int_type;}"
+ "leaf p2 {type my_int_type;}"
+ "leaf p3 {type my_int_type{range \"0 .. 50\";}}"
+ "leaf p4 {type uint8;}");
+ UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, &mod);
+ lysc_type = ((struct lysc_node_leaf *)mod->compiled->data)->type;
+
+ /* CREATE VALUES */
+ for (unsigned int it = 0; it < sizeof(val_init) / sizeof(val_init[0]); it++) {
+ ly_ret = type->store(UTEST_LYCTX, lysc_type, val_init[it], strlen(val_init[it]),
+ 0, LY_VALUE_XML, NULL, LYD_VALHINT_DECNUM, NULL, &(values[it]), NULL, &err);
+ assert_int_equal(LY_SUCCESS, ly_ret);
+ }
+
+ /*
+ * BASIC TEST;
+ */
+ assert_int_equal(LY_SUCCESS, type->compare(&(values[0]), &(values[0])));
+ assert_int_equal(LY_SUCCESS, type->compare(&(values[0]), &(values[5])));
+ assert_int_equal(LY_ENOT, type->compare(&(values[0]), &(values[1])));
+ assert_int_equal(LY_ENOT, type->compare(&(values[1]), &(values[0])));
+ assert_int_equal(LY_ENOT, type->compare(&(values[1]), &(values[2])));
+ assert_int_equal(LY_SUCCESS, type->compare(&(values[3]), &(values[4])));
+
+ /*
+ * SAME TYPE but different node
+ */
+ diff_type_text = "20";
+ diff_type = ((struct lysc_node_leaf *)mod->compiled->data->next)->type;
+ ly_ret = diff_type->plugin->store(UTEST_LYCTX, diff_type, diff_type_text, strlen(diff_type_text),
+ 0, LY_VALUE_XML, NULL, LYD_VALHINT_DECNUM, NULL, &diff_type_val, NULL, &err);
+ assert_int_equal(LY_SUCCESS, ly_ret);
+ assert_int_equal(LY_SUCCESS, type->compare(&diff_type_val, &(values[0])));
+ assert_int_equal(LY_ENOT, type->compare(&diff_type_val, &(values[1])));
+ type->free(UTEST_LYCTX, &(diff_type_val));
+
+ /*
+ * derivated type add some limitations
+ */
+ diff_type_text = "20";
+ diff_type = ((struct lysc_node_leaf *)mod->compiled->data->next->next)->type;
+ ly_ret = diff_type->plugin->store(UTEST_LYCTX, diff_type, diff_type_text, strlen(diff_type_text),
+ 0, LY_VALUE_XML, NULL, LYD_VALHINT_DECNUM, NULL, &diff_type_val, NULL, &err);
+ assert_int_equal(LY_SUCCESS, ly_ret);
+ assert_int_equal(LY_ENOT, type->compare(&diff_type_val, &(values[0])));
+ assert_int_equal(LY_ENOT, type->compare(&diff_type_val, &(values[1])));
+ type->free(UTEST_LYCTX, &(diff_type_val));
+
+ /*
+ * different type (UINT8)
+ */
+ diff_type_text = "20";
+ diff_type = ((struct lysc_node_leaf *)mod->compiled->data->next->next->next)->type;
+ ly_ret = diff_type->plugin->store(UTEST_LYCTX, diff_type, diff_type_text, strlen(diff_type_text),
+ 0, LY_VALUE_XML, NULL, LYD_VALHINT_DECNUM, NULL, &diff_type_val, NULL, &err);
+ assert_int_equal(LY_SUCCESS, ly_ret);
+ assert_int_equal(LY_ENOT, type->compare(&diff_type_val, &(values[0])));
+ assert_int_equal(LY_ENOT, type->compare(&diff_type_val, &(values[1])));
+ type->free(UTEST_LYCTX, &(diff_type_val));
+
+ /* delete values */
+ for (unsigned int it = 0; it < sizeof(val_init) / sizeof(val_init[0]); it++) {
+ type->free(UTEST_LYCTX, &(values[it]));
+ }
+}
+
+static void
+test_plugin_print(void **state)
+{
+ struct ly_err_item *err = NULL;
+ struct lys_module *mod;
+ struct lyd_value values[10];
+ struct lyplg_type *type = lyplg_type_plugin_find("", NULL, ly_data_type2str[LY_TYPE_INT8]);
+ struct lysc_type *lysc_type;
+ LY_ERR ly_ret;
+ const char *schema;
+ /* Value which are going to be created to tested */
+ const char *val_init[] = {"20", "0x4A", "-f", "0", "-0", "-20"};
+
+ /* create schema. Prepare common used variables */
+ schema = MODULE_CREATE_YANG("defs", "leaf port {type int8;}");
+ UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, &mod);
+ lysc_type = ((struct lysc_node_leaf *)mod->compiled->data)->type;
+
+ /* CREATE VALUES */
+ for (unsigned int it = 0; it < sizeof(val_init) / sizeof(val_init[0]); it++) {
+ ly_ret = type->store(UTEST_LYCTX, lysc_type, val_init[it], strlen(val_init[it]),
+ 0, LY_VALUE_XML, NULL, LYD_VALHINT_HEXNUM, NULL, &(values[it]), NULL, &err);
+ assert_int_equal(LY_SUCCESS, ly_ret);
+ }
+
+ /* print value */
+ ly_bool dynamic = 0;
+
+ assert_string_equal("32", type->print(UTEST_LYCTX, &(values[0]), LY_VALUE_XML, NULL, &dynamic, NULL));
+ assert_string_equal("74", type->print(UTEST_LYCTX, &(values[1]), LY_VALUE_XML, NULL, &dynamic, NULL));
+ assert_string_equal("-15", type->print(UTEST_LYCTX, &(values[2]), LY_VALUE_XML, NULL, &dynamic, NULL));
+ assert_string_equal("0", type->print(UTEST_LYCTX, &(values[3]), LY_VALUE_XML, NULL, &dynamic, NULL));
+ assert_string_equal("0", type->print(UTEST_LYCTX, &(values[4]), LY_VALUE_XML, NULL, &dynamic, NULL));
+ assert_string_equal("-32", type->print(UTEST_LYCTX, &(values[5]), LY_VALUE_XML, NULL, &dynamic, NULL));
+
+ for (unsigned int it = 0; it < sizeof(val_init) / sizeof(val_init[0]); it++) {
+ type->free(UTEST_LYCTX, &(values[it]));
+ }
+}
+
+static void
+test_plugin_dup(void **state)
+{
+ struct ly_err_item *err = NULL;
+ struct lys_module *mod;
+ struct lyd_value values[10];
+ struct lyplg_type *type = lyplg_type_plugin_find("", NULL, ly_data_type2str[LY_TYPE_INT8]);
+ struct lysc_type *lysc_type[2];
+ const char *schema;
+ LY_ERR ly_ret;
+ /* Value which are going to be tested */
+ const char *val_init[] = {"20", "0x4A", "-f", "0", "-0x80", "-20"};
+
+ /* create schema. Prepare common used variables */
+ schema = MODULE_CREATE_YANG("T0", "leaf port {type int8;}");
+ UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, &mod);
+ lysc_type[0] = ((struct lysc_node_leaf *)mod->compiled->data)->type;
+
+ schema = MODULE_CREATE_YANG("T1",
+ "typedef my_int_type {"
+ " type int8 {range \"-100 .. 100\";} default 20;"
+ "}"
+ "leaf port {type my_int_type; }");
+ UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, &mod);
+ lysc_type[1] = ((struct lysc_node_leaf *)mod->compiled->data)->type;
+
+ /* CREATE VALUES */
+ for (unsigned int it = 0; it < sizeof(val_init) / sizeof(val_init[0]); it++) {
+ ly_ret = type->store(UTEST_LYCTX, lysc_type[it % 2], val_init[it], strlen(val_init[it]),
+ 0, LY_VALUE_XML, NULL, LYD_VALHINT_HEXNUM, NULL, &(values[it]), NULL, &err);
+ assert_int_equal(LY_SUCCESS, ly_ret);
+ }
+
+ /* print duplicate value */
+ struct lyd_value dup_value;
+
+ assert_int_equal(LY_SUCCESS, type->duplicate(UTEST_LYCTX, &(values[0]), &dup_value));
+ CHECK_LYD_VALUE(dup_value, INT8, "32", 0x20);
+ assert_ptr_equal(dup_value.realtype, values[0].realtype);
+ type->free(UTEST_LYCTX, &dup_value);
+
+ assert_int_equal(LY_SUCCESS, type->duplicate(UTEST_LYCTX, &(values[1]), &dup_value));
+ CHECK_LYD_VALUE(dup_value, INT8, "74", 0x4a);
+ assert_ptr_equal(dup_value.realtype, values[1].realtype);
+ type->free(UTEST_LYCTX, &dup_value);
+
+ assert_int_equal(LY_SUCCESS, type->duplicate(UTEST_LYCTX, &(values[2]), &dup_value));
+ CHECK_LYD_VALUE(dup_value, INT8, "-15", -0xf);
+ assert_ptr_equal(dup_value.realtype, values[2].realtype);
+ type->free(UTEST_LYCTX, &dup_value);
+
+ assert_int_equal(LY_SUCCESS, type->duplicate(UTEST_LYCTX, &(values[3]), &dup_value));
+ CHECK_LYD_VALUE(dup_value, INT8, "0", 0x0);
+ assert_ptr_equal(dup_value.realtype, values[3].realtype);
+ type->free(UTEST_LYCTX, &dup_value);
+
+ assert_int_equal(LY_SUCCESS, type->duplicate(UTEST_LYCTX, &(values[4]), &dup_value));
+ CHECK_LYD_VALUE(dup_value, INT8, "-128", -0x80);
+ assert_ptr_equal(dup_value.realtype, values[4].realtype);
+ type->free(UTEST_LYCTX, &dup_value);
+
+ assert_int_equal(LY_SUCCESS, type->duplicate(UTEST_LYCTX, &(values[5]), &dup_value));
+ CHECK_LYD_VALUE(dup_value, INT8, "-32", -0x20);
+ assert_ptr_equal(dup_value.realtype, values[5].realtype);
+ type->free(UTEST_LYCTX, &dup_value);
+
+ /* error tests */
+ assert_int_equal(LY_EINVAL, type->duplicate(NULL, &(values[0]), &dup_value));
+
+ for (unsigned int it = 0; it < sizeof(val_init) / sizeof(val_init[0]); it++) {
+ type->free(UTEST_LYCTX, &(values[it]));
+ }
+}
+
+int
+main(void)
+{
+ const struct CMUnitTest tests[] = {
+ UTEST(test_schema_yang),
+ UTEST(test_schema_yin),
+ UTEST(test_schema_print),
+ UTEST(test_data_xml),
+ UTEST(test_data_json),
+ UTEST(test_data_lyb),
+ UTEST(test_diff),
+ UTEST(test_print),
+
+ UTEST(test_plugin_store),
+ UTEST(test_plugin_compare),
+ UTEST(test_plugin_print),
+ UTEST(test_plugin_dup),
+ };
+
+ return cmocka_run_group_tests(tests, NULL, NULL);
+}
diff --git a/tests/utests/types/leafref.c b/tests/utests/types/leafref.c
new file mode 100644
index 0000000..c8d0cb6
--- /dev/null
+++ b/tests/utests/types/leafref.c
@@ -0,0 +1,222 @@
+/**
+ * @file leafref.c
+ * @author Adam Piecek <piecek@cesnet.cz>
+ * @brief test for built-in enumeration type
+ *
+ * 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"
+
+/* LOCAL INCLUDE HEADERS */
+#include "libyang.h"
+
+#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"
+
+#define TEST_SUCCESS_XML2(XML1, MOD_NAME, NAMESPACES, NODE_NAME, DATA, TYPE, ...) \
+ { \
+ struct lyd_node *tree; \
+ const char *data = XML1 "<" NODE_NAME " xmlns=\"urn:tests:" MOD_NAME "\" " NAMESPACES ">" DATA "</" NODE_NAME ">"; \
+ CHECK_PARSE_LYD_PARAM(data, LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_SUCCESS, tree); \
+ CHECK_LYD_NODE_TERM((struct lyd_node_term *)tree, 0, 0, 1, 0, 1, TYPE, __VA_ARGS__); \
+ lyd_free_all(tree); \
+ }
+
+#define TEST_ERROR_XML2(XML1, MOD_NAME, NAMESPACES, NODE_NAME, DATA, RET) \
+ {\
+ struct lyd_node *tree; \
+ const char *data = XML1 "<" NODE_NAME " xmlns=\"urn:tests:" MOD_NAME "\" " NAMESPACES ">" DATA "</" NODE_NAME ">"; \
+ CHECK_PARSE_LYD_PARAM(data, LYD_XML, 0, LYD_VALIDATE_PRESENT, RET, tree); \
+ assert_null(tree); \
+ }
+
+#define TEST_SUCCESS_LYB(MOD_NAME, NODE_NAME1, DATA1, NODE_NAME2, DATA2) \
+ { \
+ struct lyd_node *tree_1; \
+ struct lyd_node *tree_2; \
+ char *xml_out, *data; \
+ data = "<" NODE_NAME1 " xmlns=\"urn:tests:" MOD_NAME "\"><name>" DATA1 "</name></" NODE_NAME1 ">" \
+ "<" NODE_NAME2 " xmlns=\"urn:tests:" MOD_NAME "\">" DATA2 "</" NODE_NAME2 ">"; \
+ CHECK_PARSE_LYD_PARAM(data, LYD_XML, LYD_PARSE_ONLY | LYD_PARSE_STRICT, 0, LY_SUCCESS, tree_1); \
+ assert_int_equal(lyd_print_mem(&xml_out, tree_1, LYD_LYB, LYD_PRINT_WITHSIBLINGS), 0); \
+ assert_int_equal(LY_SUCCESS, lyd_parse_data_mem(UTEST_LYCTX, xml_out, LYD_LYB, LYD_PARSE_ONLY | LYD_PARSE_STRICT, 0, &tree_2)); \
+ assert_non_null(tree_2); \
+ CHECK_LYD(tree_1, tree_2); \
+ free(xml_out); \
+ lyd_free_all(tree_1); \
+ lyd_free_all(tree_2); \
+ }
+
+static void
+test_data_xml(void **state)
+{
+ const char *schema, *schema2, *schema3, *data;
+ struct lyd_node *tree;
+
+ /* xml test */
+ schema = MODULE_CREATE_YANG("defs", "leaf lref {type leafref {path /leaflisttarget; require-instance true;}}"
+ "leaf lref2 {type leafref {path \"../list[id = current()/../str-norestr]/targets\"; require-instance true;}}"
+ "leaf str-norestr {type string;}"
+ "list list {key id; leaf id {type string;} leaf value {type string;} leaf-list targets {type string;}}"
+ "container cont {leaf leaftarget {type empty;}"
+ " list listtarget {key id; max-elements 5;leaf id {type uint8;} leaf value {type string;}}"
+ " leaf-list leaflisttarget {type uint8; max-elements 5;}}"
+ "leaf-list leaflisttarget {type string;}");
+ UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, NULL);
+
+ schema2 = MODULE_CREATE_YANG("leafrefs", "import defs {prefix t;}"
+ "container c { container x {leaf x {type string;}} list l {"
+ " key \"id value\"; leaf id {type string;} leaf value {type string;}"
+ " leaf lr1 {type leafref {path \"../../../t:str-norestr\"; require-instance true;}}"
+ " leaf lr2 {type leafref {path \"../../l[id=current()/../../../t:str-norestr]\" +"
+ " \"[value=current()/../../../t:str-norestr]/value\"; require-instance true;}}"
+ " leaf lr3 {type leafref {path \"/t:list[t:id=current ( )/../../x/x]/t:targets\";}}"
+ "}}");
+ UTEST_ADD_MODULE(schema2, LYS_IN_YANG, NULL, NULL);
+
+ TEST_SUCCESS_XML2("<leaflisttarget xmlns=\"urn:tests:defs\">x</leaflisttarget>"
+ "<leaflisttarget xmlns=\"urn:tests:defs\">y</leaflisttarget>",
+ "defs", "xmlns:a=\"urn:tests:defs\"", "a:lref", "y", STRING, "y");
+
+ TEST_SUCCESS_XML2("<list xmlns=\"urn:tests:defs\"><id>x</id><targets>a</targets><targets>b</targets></list>"
+ "<list xmlns=\"urn:tests:defs\"><id>y</id><targets>x</targets><targets>y</targets></list>"
+ "<str-norestr xmlns=\"urn:tests:defs\">y</str-norestr>",
+ "defs", "xmlns:a=\"urn:tests:defs\"", "a:lref2", "y", STRING, "y");
+
+ data = "<str-norestr xmlns=\"urn:tests:defs\">y</str-norestr>"
+ "<c xmlns=\"urn:tests:leafrefs\"><l><id>x</id><value>x</value><lr1>y</lr1></l></c>";
+ CHECK_PARSE_LYD_PARAM(data, LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_SUCCESS, tree);
+ CHECK_LYD_NODE_TERM((struct lyd_node_term *)lyd_child(lyd_child(tree->next->next)->next)->next->next,
+ 0, 0, 0, 1, 1, STRING, "y");
+ lyd_free_all(tree);
+
+ data = "<list xmlns=\"urn:tests:defs\"><id>x</id><targets>a</targets><targets>b</targets></list>"
+ "<list xmlns=\"urn:tests:defs\"><id>y</id><targets>c</targets><targets>d</targets></list>"
+ "<c xmlns=\"urn:tests:leafrefs\"><x><x>y</x></x>"
+ "<l><id>x</id><value>x</value><lr3>c</lr3></l></c>";
+ CHECK_PARSE_LYD_PARAM(data, LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_SUCCESS, tree);
+ CHECK_LYD_NODE_TERM((struct lyd_node_term *)lyd_child(lyd_child(tree->next->next->next)->next)->next->next,
+ 0, 0, 0, 1, 1, STRING, "c");
+ lyd_free_all(tree);
+
+ schema3 = MODULE_CREATE_YANG("simple", "leaf l1 {type leafref {path \"../target\";}}"
+ "leaf target {type string;}");
+ UTEST_ADD_MODULE(schema3, LYS_IN_YANG, NULL, NULL);
+
+ data = "<l1 xmlns=\"urn:tests:simple\">&quot;*&quot;&#39;</l1>"
+ "<target xmlns=\"urn:tests:simple\">&quot;*&quot;&#39;</target>";
+ CHECK_PARSE_LYD_PARAM(data, LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_SUCCESS, tree);
+ lyd_free_all(tree);
+
+ data = "<l1 xmlns=\"urn:tests:simple\">&quot;*&#39;&quot;</l1>"
+ "<target xmlns=\"urn:tests:simple\">&quot;*&#39;&quot;</target>";
+ CHECK_PARSE_LYD_PARAM(data, LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_SUCCESS, tree);
+ lyd_free_all(tree);
+
+ /* invalid value */
+ TEST_ERROR_XML2("<leaflisttarget xmlns=\"urn:tests:defs\">x</leaflisttarget>",
+ "defs", "", "lref", "y", LY_EVALID);
+ CHECK_LOG_CTX_APPTAG("Invalid leafref value \"y\" - no target instance \"/leaflisttarget\" with the same value.",
+ "Data location \"/defs:lref\".", "instance-required");
+
+ TEST_ERROR_XML2("<list xmlns=\"urn:tests:defs\"><id>x</id><targets>a</targets><targets>b</targets></list>"
+ "<list xmlns=\"urn:tests:defs\"><id>y</id><targets>x</targets><targets>y</targets></list>"
+ "<str-norestr xmlns=\"urn:tests:defs\">y</str-norestr>",
+ "defs", "", "lref2", "b", LY_EVALID);
+ CHECK_LOG_CTX_APPTAG("Invalid leafref value \"b\" - "
+ "no target instance \"../list[id = current()/../str-norestr]/targets\" with the same value.",
+ "Data location \"/defs:lref2\".", "instance-required");
+
+ TEST_ERROR_XML2("<list xmlns=\"urn:tests:defs\"><id>x</id><targets>a</targets><targets>b</targets></list>"
+ "<list xmlns=\"urn:tests:defs\"><id>y</id><targets>x</targets><targets>y</targets></list>",
+ "defs", "", "lref2", "b", LY_EVALID);
+ CHECK_LOG_CTX_APPTAG("Invalid leafref value \"b\" - "
+ "no target instance \"../list[id = current()/../str-norestr]/targets\" with the same value.",
+ "Data location \"/defs:lref2\".", "instance-required");
+
+ TEST_ERROR_XML2("<str-norestr xmlns=\"urn:tests:defs\">y</str-norestr>",
+ "defs", "", "lref2", "b", LY_EVALID);
+ CHECK_LOG_CTX_APPTAG("Invalid leafref value \"b\" - "
+ "no target instance \"../list[id = current()/../str-norestr]/targets\" with the same value.",
+ "Data location \"/defs:lref2\".", "instance-required");
+
+ TEST_ERROR_XML2("<str-norestr xmlns=\"urn:tests:defs\">y</str-norestr>",
+ "leafrefs", "", "c", "<l><id>x</id><value>x</value><lr1>a</lr1></l>", LY_EVALID);
+ CHECK_LOG_CTX_APPTAG("Invalid leafref value \"a\" - no target instance \"../../../t:str-norestr\" with the same value.",
+ "Data location \"/leafrefs:c/l[id='x'][value='x']/lr1\".", "instance-required");
+
+ TEST_ERROR_XML2("<str-norestr xmlns=\"urn:tests:defs\">z</str-norestr>",
+ "leafrefs", "", "c", "<l><id>y</id><value>y</value></l><l><id>x</id><value>x</value><lr2>z</lr2></l>", LY_EVALID);
+ CHECK_LOG_CTX_APPTAG("Invalid leafref value \"z\" - no target instance \"../../l[id=current()/../../../t:str-norestr]"
+ "[value=current()/../../../t:str-norestr]/value\" with the same value.",
+ "Data location \"/leafrefs:c/l[id='x'][value='x']/lr2\".", "instance-required");
+
+ TEST_ERROR_XML2("",
+ "defs", "", "lref", "%n", LY_EVALID);
+ CHECK_LOG_CTX_APPTAG("Invalid leafref value \"%n\" - no target instance \"/leaflisttarget\" with the same value.",
+ "Data location \"/defs:lref\".", "instance-required");
+}
+
+static void
+test_data_json(void **state)
+{
+ const char *schema, *data;
+ struct lyd_node *tree;
+
+ /* json test */
+ schema = MODULE_CREATE_YANG("simple", "leaf l1 {type leafref {path \"../target\";}}"
+ "leaf target {type string;}");
+ UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, NULL);
+
+ data = "{"
+ " \"simple:l1\":\"\\\"*\\\"'\","
+ " \"simple:target\":\"\\\"*\\\"'\""
+ "}";
+ CHECK_PARSE_LYD_PARAM(data, LYD_JSON, 0, LYD_VALIDATE_PRESENT, LY_SUCCESS, tree);
+ lyd_free_all(tree);
+
+ data = "{"
+ " \"simple:l1\":\"\\\"*'\\\"\","
+ " \"simple:target\":\"\\\"*'\\\"\""
+ "}";
+ CHECK_PARSE_LYD_PARAM(data, LYD_JSON, 0, LYD_VALIDATE_PRESENT, LY_SUCCESS, tree);
+ lyd_free_all(tree);
+}
+
+static void
+test_plugin_lyb(void **state)
+{
+ const char *schema;
+
+ schema = MODULE_CREATE_YANG("lyb",
+ "list lst {key \"name\"; leaf name {type string;}}"
+ "leaf lref {type leafref {path \"../lst/name\";}}");
+ UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, NULL);
+ TEST_SUCCESS_LYB("lyb", "lst", "key_str", "lref", "key_str");
+}
+
+int
+main(void)
+{
+ const struct CMUnitTest tests[] = {
+ UTEST(test_data_xml),
+ UTEST(test_data_json),
+ UTEST(test_plugin_lyb),
+ };
+
+ return cmocka_run_group_tests(tests, NULL, NULL);
+}
diff --git a/tests/utests/types/string.c b/tests/utests/types/string.c
new file mode 100644
index 0000000..d232e9d
--- /dev/null
+++ b/tests/utests/types/string.c
@@ -0,0 +1,1410 @@
+/**
+ * @file string.c
+ * @author Radek Iša <isa@cesnet.cz>
+ * @brief test for string values
+ *
+ * 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
+ */
+
+#define _UTEST_MAIN_
+#include "../utests.h"
+
+/* GLOBAL INCLUDE HEADERS */
+#include <ctype.h>
+
+/* LOCAL INCLUDE HEADERS */
+#include "libyang.h"
+#include "path.h"
+#include "plugins_internal.h"
+
+#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"
+
+#define TEST_SUCCESS_XML(MOD_NAME, DATA, TYPE, ...)\
+ {\
+ struct lyd_node *tree;\
+ const char *data = "<port xmlns=\"urn:tests:" MOD_NAME "\">" DATA "</port>";\
+ CHECK_PARSE_LYD_PARAM(data, LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_SUCCESS, tree);\
+ CHECK_LYSC_NODE(tree->schema, NULL, 0, 0x5, 1, "port", 0, LYS_LEAF, 0, 0, 0, 0);\
+ CHECK_LYD_NODE_TERM((struct lyd_node_term *) tree, 0, 0, 0, 0, 1, TYPE, __VA_ARGS__);\
+ lyd_free_all(tree);\
+ }
+
+#define TEST_SUCCESS_JSON(MOD_NAME, DATA, TYPE, ...)\
+ {\
+ struct lyd_node *tree;\
+ const char *data = "{\"" MOD_NAME ":port\":\"" DATA "\"}";\
+ CHECK_PARSE_LYD_PARAM(data, LYD_JSON, 0, LYD_VALIDATE_PRESENT, LY_SUCCESS, tree);\
+ CHECK_LYSC_NODE(tree->schema, NULL, 0, 0x5, 1, "port", 0, LYS_LEAF, 0, 0, 0, 0);\
+ CHECK_LYD_NODE_TERM((struct lyd_node_term *) tree, 0, 0, 0, 0, 1, TYPE, __VA_ARGS__);\
+ lyd_free_all(tree);\
+ }
+
+#define TEST_SUCCESS_LYB(MOD_NAME, NODE_NAME, DATA) \
+ { \
+ struct lyd_node *tree_1; \
+ struct lyd_node *tree_2; \
+ char *xml_out, *data; \
+ data = "<" NODE_NAME " xmlns=\"urn:tests:" MOD_NAME "\">" DATA "</" NODE_NAME ">"; \
+ CHECK_PARSE_LYD_PARAM(data, LYD_XML, LYD_PARSE_ONLY | LYD_PARSE_STRICT, 0, LY_SUCCESS, tree_1); \
+ assert_int_equal(lyd_print_mem(&xml_out, tree_1, LYD_LYB, LYD_PRINT_WITHSIBLINGS), 0); \
+ assert_int_equal(LY_SUCCESS, lyd_parse_data_mem(UTEST_LYCTX, xml_out, LYD_LYB, LYD_PARSE_ONLY | LYD_PARSE_STRICT, 0, &tree_2)); \
+ assert_non_null(tree_2); \
+ CHECK_LYD(tree_1, tree_2); \
+ free(xml_out); \
+ lyd_free_all(tree_1); \
+ lyd_free_all(tree_2); \
+ }
+
+#define TEST_ERROR_XML(MOD_NAME, DATA)\
+ {\
+ struct lyd_node *tree;\
+ const char *data = "<port xmlns=\"urn:tests:" MOD_NAME "\">" DATA "</port>";\
+ CHECK_PARSE_LYD_PARAM(data, LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_EVALID, tree);\
+ assert_null(tree);\
+ }
+
+#define TEST_ERROR_JSON(MOD_NAME, DATA)\
+ {\
+ struct lyd_node *tree;\
+ const char *data = "{\"" MOD_NAME ":port\":\"" DATA "\"}";\
+ CHECK_PARSE_LYD_PARAM(data, LYD_JSON, 0, LYD_VALIDATE_PRESENT, LY_EVALID, tree);\
+ assert_null(tree);\
+ }
+
+static void
+test_schema_yang(void **state)
+{
+ const char *schema;
+ struct lys_module *mod;
+ struct lysc_node_leaf *lysc_leaf;
+ struct lysp_node_leaf *lysp_leaf;
+ struct lysc_pattern *pattern;
+ struct lysc_range *range;
+
+ /* TEST BASE STRING */
+ schema = MODULE_CREATE_YANG("base", "leaf port {type string;}");
+ UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, &mod);
+ assert_non_null(mod);
+ lysc_leaf = (void *) mod->compiled->data;
+ CHECK_LYSC_NODE_LEAF(lysc_leaf, NULL, 0, 0x5, 1, "port", 0, 0, 0, NULL, 0, 0, NULL, NULL);
+ CHECK_LYSC_TYPE_NUM((struct lysc_type_num *)lysc_leaf->type, LY_TYPE_STRING, 0, 0);
+ lysp_leaf = (void *) mod->parsed->data;
+ CHECK_LYSP_NODE_LEAF(lysp_leaf, NULL, 0, 0x0, 0, "port", 0, 0, NULL, 0, 0, NULL, NULL);
+ CHECK_LYSP_TYPE(&(lysp_leaf->type), 0, 0, 0, 0, 0, 0x0, 0, 0, "string", 0, 0, 1, 0, 0, 0);
+
+ /* TEST MODULE T0 */
+ schema = MODULE_CREATE_YANG("T0", "leaf port {type string"
+ "{length \"10 .. max\";}"
+ "}");
+ UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, &mod);
+ assert_non_null(mod);
+ lysc_leaf = (void *) mod->compiled->data;
+ CHECK_LYSC_NODE_LEAF(lysc_leaf, NULL, 0, 0x5, 1, "port", 0, 0, 0, NULL, 0, 0, NULL, NULL);
+ CHECK_LYSC_TYPE_STR((struct lysc_type_str *)lysc_leaf->type, 0, 1, 0);
+ range = ((struct lysc_type_str *)lysc_leaf->type)->length;
+ CHECK_LYSC_RANGE(range, NULL, NULL, NULL, 0, 1, NULL);
+ assert_int_equal(range->parts[0].min_u64, 10);
+ assert_true(range->parts[0].max_u64 == 18446744073709551615ull);
+ lysp_leaf = (void *) mod->parsed->data;
+ CHECK_LYSP_NODE_LEAF(lysp_leaf, NULL, 0, 0x0, 0, "port", 0, 0, NULL, 0, 0, NULL, NULL);
+ CHECK_LYSP_TYPE(&(lysp_leaf->type), 0, 0, 0, 0, 0, 0x10, 0, 1, "string", 0, 0, 1, 0, 0, 0);
+ CHECK_LYSP_RESTR(lysp_leaf->type.length, "10 .. max", NULL, NULL, NULL, 0, NULL);
+
+ /* TEST MODULE T1 */
+ schema = MODULE_CREATE_YANG("T1", "leaf port {type string"
+ "{length \"min .. 20 | 50\";}"
+ "}");
+ UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, &mod);
+ assert_non_null(mod);
+ lysc_leaf = (void *) mod->compiled->data;
+ CHECK_LYSC_NODE_LEAF(lysc_leaf, NULL, 0, 0x5, 1, "port", 0, 0, 0, NULL, 0, 0, NULL, NULL);
+ CHECK_LYSC_TYPE_STR((struct lysc_type_str *)lysc_leaf->type, 0, 1, 0);
+ range = ((struct lysc_type_str *)lysc_leaf->type)->length;
+ CHECK_LYSC_RANGE(range, NULL, NULL, NULL, 0, 2, NULL);
+ assert_int_equal(range->parts[0].min_u64, 0);
+ assert_int_equal(range->parts[0].max_u64, 20);
+ assert_int_equal(range->parts[1].min_u64, 50);
+ assert_int_equal(range->parts[1].max_u64, 50);
+ lysp_leaf = (void *) mod->parsed->data;
+ CHECK_LYSP_NODE_LEAF(lysp_leaf, NULL, 0, 0x0, 0, "port", 0, 0, NULL, 0, 0, NULL, NULL);
+ CHECK_LYSP_TYPE(&(lysp_leaf->type), 0, 0, 0, 0, 0, 0x10, 0, 1, "string", 0, 0, 1, 0, 0, 0);
+ CHECK_LYSP_RESTR(lysp_leaf->type.length, "min .. 20 | 50", NULL, NULL, NULL, 0, NULL);
+
+ /* TEST MODULE T2 */
+ schema = MODULE_CREATE_YANG("T2", "leaf port {type string"
+ "{length \"10 .. 20 | 50 .. 100 | 255\";}"
+ "}");
+ UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, &mod);
+ assert_non_null(mod);
+ lysc_leaf = (void *) mod->compiled->data;
+ CHECK_LYSC_NODE_LEAF(lysc_leaf, NULL, 0, 0x5, 1, "port", 0, 0, 0, NULL, 0, 0, NULL, NULL);
+ CHECK_LYSC_TYPE_STR((struct lysc_type_str *)lysc_leaf->type, 0, 1, 0);
+ range = ((struct lysc_type_str *)lysc_leaf->type)->length;
+ CHECK_LYSC_RANGE(range, NULL, NULL, NULL, 0, 3, NULL);
+ assert_int_equal(range->parts[0].min_u64, 10);
+ assert_int_equal(range->parts[0].max_u64, 20);
+ assert_int_equal(range->parts[1].min_u64, 50);
+ assert_int_equal(range->parts[1].max_u64, 100);
+ assert_int_equal(range->parts[2].min_u64, 255);
+ assert_int_equal(range->parts[2].max_u64, 255);
+ lysp_leaf = (void *) mod->parsed->data;
+ CHECK_LYSP_NODE_LEAF(lysp_leaf, NULL, 0, 0x0, 0, "port", 0, 0, NULL, 0, 0, NULL, NULL);
+ CHECK_LYSP_TYPE(&(lysp_leaf->type), 0, 0, 0, 0, 0, 0x10, 0, 1, "string", 0, 0, 1, 0, 0, 0);
+ CHECK_LYSP_RESTR(lysp_leaf->type.length, "10 .. 20 | 50 .. 100 | 255", NULL, NULL, NULL, 0, NULL);
+
+ /* SUBTYPE MODULE T2 */
+ schema = MODULE_CREATE_YANG("TS0",
+ "typedef my_type {"
+ " type string {length \"10 .. 20 | 50 .. 100 | 255\";}"
+ "}"
+ "leaf port {type my_type {length \"min .. 15 | max\";}}");
+ UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, &mod);
+ assert_non_null(mod);
+ lysc_leaf = (void *) mod->compiled->data;
+ CHECK_LYSC_NODE_LEAF(lysc_leaf, NULL, 0, 0x5, 1, "port", 0, 0, 0, NULL, 0, 0, NULL, NULL);
+ CHECK_LYSC_TYPE_STR((struct lysc_type_str *)lysc_leaf->type, 0, 1, 0);
+ range = ((struct lysc_type_str *)lysc_leaf->type)->length;
+ CHECK_LYSC_RANGE(range, NULL, NULL, NULL, 0, 2, NULL);
+ assert_int_equal(range->parts[0].min_u64, 10);
+ assert_int_equal(range->parts[0].max_u64, 15);
+ assert_int_equal(range->parts[1].min_u64, 255);
+ assert_int_equal(range->parts[1].max_u64, 255);
+ lysp_leaf = (void *) mod->parsed->data;
+ CHECK_LYSP_NODE_LEAF(lysp_leaf, NULL, 0, 0x0, 0, "port", 0, 0, NULL, 0, 0, NULL, NULL);
+ CHECK_LYSP_TYPE(&(lysp_leaf->type), 0, 0, 0, 0, 0, 0x10, 0, 1, "my_type", 0, 0, 1, 0, 0, 0);
+ CHECK_LYSP_RESTR(lysp_leaf->type.length, "min .. 15 | max", NULL, NULL, NULL, 0, NULL);
+
+ /* ERROR TESTS NEGATIVE VALUE */
+ schema = MODULE_CREATE_YANG("ERR0", "leaf port {type string {length \"-1 .. 20\";}}");
+ UTEST_INVALID_MODULE(schema, LYS_IN_YANG, NULL, LY_EDENIED);
+ CHECK_LOG_CTX("Invalid length restriction - value \"-1\" does not fit the type limitations.", "/ERR0:port");
+
+ schema = MODULE_CREATE_YANG("ERR1", "leaf port {type string {length \"100 .. 18446744073709551616\";}}");
+ UTEST_INVALID_MODULE(schema, LYS_IN_YANG, NULL, LY_EVALID);
+ CHECK_LOG_CTX("Invalid length restriction - invalid value \"18446744073709551616\".", "/ERR1:port");
+
+ schema = MODULE_CREATE_YANG("ERR2", "leaf port {type string {length \"10 .. 20 | 20 .. 30\";}}");
+ UTEST_INVALID_MODULE(schema, LYS_IN_YANG, NULL, LY_EEXIST);
+ CHECK_LOG_CTX("Invalid length restriction - values are not in ascending order (20).", "/ERR2:port");
+
+ schema = MODULE_CREATE_YANG("ERR3",
+ "typedef my_type {"
+ " type string;"
+ "}"
+ "leaf port {type my_type {length \"-1 .. 15\";}}");
+ UTEST_INVALID_MODULE(schema, LYS_IN_YANG, NULL, LY_EDENIED);
+ CHECK_LOG_CTX("Invalid length restriction - value \"-1\" does not fit the type limitations.", "/ERR3:port");
+
+ /*
+ * PATTERN
+ */
+ schema = MODULE_CREATE_YANG("TPATTERN_0", "leaf port {type string"
+ "{pattern '[a-zA-Z_][a-zA-Z0-9\\-_.]*';}"
+ "}");
+ UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, &mod);
+ assert_non_null(mod);
+ lysc_leaf = (void *) mod->compiled->data;
+ CHECK_LYSC_NODE_LEAF(lysc_leaf, NULL, 0, 0x5, 1, "port", 0, 0, 0, NULL, 0, 0, NULL, NULL);
+ CHECK_LYSC_TYPE_STR((struct lysc_type_str *)lysc_leaf->type, 0, 0, 1);
+ pattern = ((struct lysc_type_str *)lysc_leaf->type)->patterns[0];
+ CHECK_LYSC_PATTERN(pattern, NULL, NULL, NULL, "[a-zA-Z_][a-zA-Z0-9\\-_.]*", 0, 0, NULL);
+ lysp_leaf = (void *) mod->parsed->data;
+ CHECK_LYSP_NODE_LEAF(lysp_leaf, NULL, 0, 0x0, 0, "port", 0, 0, NULL, 0, 0, NULL, NULL);
+ CHECK_LYSP_TYPE(&(lysp_leaf->type), 0, 0, 0, 0, 0, 0x40, 0, 0, "string", 0, 1, 1, 0, 0, 0);
+ CHECK_LYSP_RESTR(&(lysp_leaf->type.patterns[0]), "\x6" "[a-zA-Z_][a-zA-Z0-9\\-_.]*", NULL, NULL, NULL, 0, NULL);
+
+ schema = MODULE_CREATE_YANG("TPATTERN_1", "leaf port {type string{"
+ " pattern '[a-zA-Z_][a-zA-Z0-9\\-_.]*' ;"
+ " pattern 'abc.*' {modifier invert-match;}"
+ "}}");
+ UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, &mod);
+ assert_non_null(mod);
+ lysc_leaf = (void *) mod->compiled->data;
+ CHECK_LYSC_NODE_LEAF(lysc_leaf, NULL, 0, 0x5, 1, "port", 0, 0, 0, NULL, 0, 0, NULL, NULL);
+ CHECK_LYSC_TYPE_STR((struct lysc_type_str *)lysc_leaf->type, 0, 0, 2);
+ pattern = ((struct lysc_type_str *)lysc_leaf->type)->patterns[0];
+ CHECK_LYSC_PATTERN(pattern, NULL, NULL, NULL, "[a-zA-Z_][a-zA-Z0-9\\-_.]*", 0, 0, NULL);
+ pattern = ((struct lysc_type_str *)lysc_leaf->type)->patterns[1];
+ CHECK_LYSC_PATTERN(pattern, NULL, NULL, NULL, "abc.*", 0, 0x1, NULL);
+ lysp_leaf = (void *) mod->parsed->data;
+ CHECK_LYSP_NODE_LEAF(lysp_leaf, NULL, 0, 0x0, 0, "port", 0, 0, NULL, 0, 0, NULL, NULL);
+ CHECK_LYSP_TYPE(&(lysp_leaf->type), 0, 0, 0, 0, 0, 0x40, 0, 0, "string", 0, 2, 1, 0, 0, 0);
+ CHECK_LYSP_RESTR(&(lysp_leaf->type.patterns[0]), "\x6" "[a-zA-Z_][a-zA-Z0-9\\-_.]*", NULL, NULL, NULL, 0, NULL);
+ CHECK_LYSP_RESTR(&(lysp_leaf->type.patterns[1]), "\x15" "abc.*", NULL, NULL, NULL, 0, NULL);
+
+ schema = MODULE_CREATE_YANG("TPATTERN_2",
+ "typedef my_type {"
+ " type string{"
+ " pattern '[a-zA-Z_][a-zA-Z0-9\\-_.]*' ;"
+ " pattern 'abc.*' {modifier invert-match;}"
+ "}}"
+ "leaf port {type my_type {pattern 'bcd.*';}}");
+ UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, &mod);
+ assert_non_null(mod);
+ lysc_leaf = (void *) mod->compiled->data;
+ CHECK_LYSC_NODE_LEAF(lysc_leaf, NULL, 0, 0x5, 1, "port", 0, 0, 0, NULL, 0, 0, NULL, NULL);
+ CHECK_LYSC_TYPE_STR((struct lysc_type_str *)lysc_leaf->type, 0, 0, 3);
+ pattern = ((struct lysc_type_str *)lysc_leaf->type)->patterns[0];
+ CHECK_LYSC_PATTERN(pattern, NULL, NULL, NULL, "[a-zA-Z_][a-zA-Z0-9\\-_.]*", 0, 0, NULL);
+ pattern = ((struct lysc_type_str *)lysc_leaf->type)->patterns[1];
+ CHECK_LYSC_PATTERN(pattern, NULL, NULL, NULL, "abc.*", 0, 0x1, NULL);
+ pattern = ((struct lysc_type_str *)lysc_leaf->type)->patterns[2];
+ CHECK_LYSC_PATTERN(pattern, NULL, NULL, NULL, "bcd.*", 0, 0x0, NULL);
+ lysp_leaf = (void *) mod->parsed->data;
+ CHECK_LYSP_NODE_LEAF(lysp_leaf, NULL, 0, 0x0, 0, "port", 0, 0, NULL, 0, 0, NULL, NULL);
+ CHECK_LYSP_TYPE(&(lysp_leaf->type), 0, 0, 0, 0, 0, 0x40, 0, 0, "my_type", 0, 1, 1, 0, 0, 0);
+ CHECK_LYSP_RESTR(&(lysp_leaf->type.patterns[0]), "\x6" "bcd.*", NULL, NULL, NULL, 0, NULL);
+
+ /*
+ * TEST pattern error
+ */
+ schema = MODULE_CREATE_YANG("TPATTERN_ERR_0", "leaf port {type string {"
+ "pattern '[a-zA-Z_[a-zA-Z0-9\\-_.*';"
+ "}}");
+ UTEST_INVALID_MODULE(schema, LYS_IN_YANG, NULL, LY_EVALID);
+ CHECK_LOG_CTX("Regular expression \"[a-zA-Z_[a-zA-Z0-9\\-_.*\" is not valid (\"\": missing terminating ] for character class).",
+ "/TPATTERN_ERR_0:port");
+
+ schema = MODULE_CREATE_YANG("TDEFAULT_0",
+ "typedef my_type {"
+ " type string{"
+ " pattern \"[a-zA-Z_][a-zA-Z0-9\\\\-_.]*\";"
+ " length \"2 .. 5 | 10\";"
+ " }"
+ " default \"a1i-j\";"
+ "}"
+ "leaf port {type my_type;}");
+ UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, &mod);
+ assert_non_null(mod);
+ lysc_leaf = (void *) mod->compiled->data;
+ CHECK_LYSC_NODE_LEAF(lysc_leaf, NULL, 0, 0x5, 1, "port", 0, 0, 0, NULL, 0, 0, NULL, "a1i-j");
+ CHECK_LYSC_TYPE_STR((struct lysc_type_str *)lysc_leaf->type, 0, 1, 1);
+ pattern = ((struct lysc_type_str *)lysc_leaf->type)->patterns[0];
+ CHECK_LYSC_PATTERN(pattern, NULL, NULL, NULL, "[a-zA-Z_][a-zA-Z0-9\\-_.]*", 0, 0, NULL);
+ range = ((struct lysc_type_str *)lysc_leaf->type)->length;
+ CHECK_LYSC_RANGE(range, NULL, NULL, NULL, 0, 2, NULL);
+ assert_int_equal(range->parts[0].min_u64, 2);
+ assert_int_equal(range->parts[0].max_u64, 5);
+ assert_int_equal(range->parts[1].min_u64, 10);
+ assert_int_equal(range->parts[1].max_u64, 10);
+ lysp_leaf = (void *) mod->parsed->data;
+ CHECK_LYSP_NODE_LEAF(lysp_leaf, NULL, 0, 0x0, 0, "port", 0, 0, NULL, 0, 0, NULL, NULL);
+ CHECK_LYSP_TYPE(&(lysp_leaf->type), 0, 0, 0, 0, 0, 0x0, 0, 0, "my_type", 0, 0, 1, 0, 0, 0);
+
+ /* TEST pattern backslash
+ * The '[' character is escaped, thus character group is broken.
+ */
+
+ schema = MODULE_CREATE_YANG("TPATTERN_BC_ERR_1", "leaf port {type string {"
+ "pattern '\\[a]b';" /* pattern '\[a]b'; */
+ "}}");
+ UTEST_INVALID_MODULE(schema, LYS_IN_YANG, NULL, LY_EVALID);
+ CHECK_LOG_CTX("Regular expression \"\\[a]b\" is not valid (\"]b\": character group doesn't begin with '[').",
+ "/TPATTERN_BC_ERR_1:port");
+
+ schema = MODULE_CREATE_YANG("TPATTERN_BC_ERR_2", "leaf port {type string {"
+ "pattern \"\\\\[a]b\";" /* pattern "\\[a]b"; */
+ "}}");
+ UTEST_INVALID_MODULE(schema, LYS_IN_YANG, NULL, LY_EVALID);
+ CHECK_LOG_CTX("Regular expression \"\\[a]b\" is not valid (\"]b\": character group doesn't begin with '[').",
+ "/TPATTERN_BC_ERR_2:port");
+
+ /* PATTERN AND LENGTH */
+ schema = MODULE_CREATE_YANG("TPL_0",
+ "typedef my_type {"
+ " type string{"
+ " length \"2 .. 10\";"
+ " }"
+ "}"
+ "leaf port {type my_type{ pattern \"[a-zA-Z_][a-zA-Z0-9\\\\-_.]*\";}}");
+ UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, &mod);
+ assert_non_null(mod);
+ lysc_leaf = (void *) mod->compiled->data;
+ CHECK_LYSC_NODE_LEAF(lysc_leaf, NULL, 0, 0x5, 1, "port", 0, 0, 0, NULL, 0, 0, NULL, NULL);
+ CHECK_LYSC_TYPE_STR((struct lysc_type_str *)lysc_leaf->type, 0, 1, 1);
+ pattern = ((struct lysc_type_str *)lysc_leaf->type)->patterns[0];
+ CHECK_LYSC_PATTERN(pattern, NULL, NULL, NULL, "[a-zA-Z_][a-zA-Z0-9\\-_.]*", 0, 0, NULL);
+ range = ((struct lysc_type_str *)lysc_leaf->type)->length;
+ CHECK_LYSC_RANGE(range, NULL, NULL, NULL, 0, 1, NULL);
+ assert_int_equal(range->parts[0].min_u64, 2);
+ assert_int_equal(range->parts[0].max_u64, 10);
+ lysp_leaf = (void *) mod->parsed->data;
+ CHECK_LYSP_NODE_LEAF(lysp_leaf, NULL, 0, 0x0, 0, "port", 0, 0, NULL, 0, 0, NULL, NULL);
+ CHECK_LYSP_TYPE(&(lysp_leaf->type), 0, 0, 0, 0, 0, 0x40, 0, 0, "my_type", 0, 1, 1, 0, 0, 0);
+ CHECK_LYSP_RESTR(&(lysp_leaf->type.patterns[0]), "\x6" "[a-zA-Z_][a-zA-Z0-9\\-_.]*",
+ NULL, NULL, NULL, 0, NULL);
+}
+
+static void
+test_schema_yin(void **state)
+{
+ const char *schema;
+ struct lys_module *mod;
+ struct lysc_node_leaf *lysc_leaf;
+ struct lysp_node_leaf *lysp_leaf;
+ struct lysc_pattern *pattern;
+ struct lysc_range *range;
+
+ /* TEST BASE STRING */
+ schema = MODULE_CREATE_YIN("base", "<leaf name=\"port\"> <type name=\"string\"/> </leaf>");
+ UTEST_ADD_MODULE(schema, LYS_IN_YIN, NULL, &mod);
+ assert_non_null(mod);
+ lysc_leaf = (void *) mod->compiled->data;
+ CHECK_LYSC_NODE_LEAF(lysc_leaf, NULL, 0, 0x5, 1, "port", 0, 0, 0, NULL, 0, 0, NULL, NULL);
+ CHECK_LYSC_TYPE_NUM((struct lysc_type_num *)lysc_leaf->type, LY_TYPE_STRING, 0, 0);
+ lysp_leaf = (void *) mod->parsed->data;
+ CHECK_LYSP_NODE_LEAF(lysp_leaf, NULL, 0, 0x0, 0, "port", 0, 0, NULL, 0, 0, NULL, NULL);
+ CHECK_LYSP_TYPE(&(lysp_leaf->type), 0, 0, 0, 0, 0, 0x0, 0, 0, "string", 0, 0, 1, 0, 0, 0);
+
+ /* TEST MODULE T0 */
+ schema = MODULE_CREATE_YIN("T0", "<leaf name=\"port\"> <type name=\"string\">"
+ "<length value=\"10 .. max\"/>"
+ "</type> </leaf>");
+ UTEST_ADD_MODULE(schema, LYS_IN_YIN, NULL, &mod);
+ assert_non_null(mod);
+ lysc_leaf = (void *) mod->compiled->data;
+ CHECK_LYSC_NODE_LEAF(lysc_leaf, NULL, 0, 0x5, 1, "port", 0, 0, 0, NULL, 0, 0, NULL, NULL);
+ CHECK_LYSC_TYPE_STR((struct lysc_type_str *)lysc_leaf->type, 0, 1, 0);
+ range = ((struct lysc_type_str *)lysc_leaf->type)->length;
+ CHECK_LYSC_RANGE(range, NULL, NULL, NULL, 0, 1, NULL);
+ assert_int_equal(range->parts[0].min_u64, 10);
+ assert_true(range->parts[0].max_u64 == 18446744073709551615ull);
+ lysp_leaf = (void *) mod->parsed->data;
+ CHECK_LYSP_NODE_LEAF(lysp_leaf, NULL, 0, 0x0, 0, "port", 0, 0, NULL, 0, 0, NULL, NULL);
+ CHECK_LYSP_TYPE(&(lysp_leaf->type), 0, 0, 0, 0, 0, 0x10, 0, 1, "string", 0, 0, 1, 0, 0, 0);
+ CHECK_LYSP_RESTR(lysp_leaf->type.length, "10 .. max", NULL, NULL, NULL, 0, NULL);
+
+ /* TEST MODULE T1 */
+ schema = MODULE_CREATE_YIN("T1", "<leaf name=\"port\"> <type name=\"string\">"
+ " <length value=\"min .. 20 | 50\"/>"
+ "</type></leaf>");
+ UTEST_ADD_MODULE(schema, LYS_IN_YIN, NULL, &mod);
+ assert_non_null(mod);
+ lysc_leaf = (void *) mod->compiled->data;
+ CHECK_LYSC_NODE_LEAF(lysc_leaf, NULL, 0, 0x5, 1, "port", 0, 0, 0, NULL, 0, 0, NULL, NULL);
+ CHECK_LYSC_TYPE_STR((struct lysc_type_str *)lysc_leaf->type, 0, 1, 0);
+ range = ((struct lysc_type_str *)lysc_leaf->type)->length;
+ CHECK_LYSC_RANGE(range, NULL, NULL, NULL, 0, 2, NULL);
+ assert_int_equal(range->parts[0].min_u64, 0);
+ assert_int_equal(range->parts[0].max_u64, 20);
+ assert_int_equal(range->parts[1].min_u64, 50);
+ assert_int_equal(range->parts[1].max_u64, 50);
+ lysp_leaf = (void *) mod->parsed->data;
+ CHECK_LYSP_NODE_LEAF(lysp_leaf, NULL, 0, 0x0, 0, "port", 0, 0, NULL, 0, 0, NULL, NULL);
+ CHECK_LYSP_TYPE(&(lysp_leaf->type), 0, 0, 0, 0, 0, 0x10, 0, 1, "string", 0, 0, 1, 0, 0, 0);
+ CHECK_LYSP_RESTR(lysp_leaf->type.length, "min .. 20 | 50", NULL, NULL, NULL, 0, NULL);
+
+ /* TEST MODULE T2 */
+ schema = MODULE_CREATE_YIN("T2", "<leaf name=\"port\"> <type name=\"string\">"
+ "<length value=\"10 .. 20 | 50 .. 100 | 255\"/>"
+ "</type></leaf>");
+ UTEST_ADD_MODULE(schema, LYS_IN_YIN, NULL, &mod);
+ assert_non_null(mod);
+ lysc_leaf = (void *) mod->compiled->data;
+ CHECK_LYSC_NODE_LEAF(lysc_leaf, NULL, 0, 0x5, 1, "port", 0, 0, 0, NULL, 0, 0, NULL, NULL);
+ CHECK_LYSC_TYPE_STR((struct lysc_type_str *)lysc_leaf->type, 0, 1, 0);
+ range = ((struct lysc_type_str *)lysc_leaf->type)->length;
+ CHECK_LYSC_RANGE(range, NULL, NULL, NULL, 0, 3, NULL);
+ assert_int_equal(range->parts[0].min_u64, 10);
+ assert_int_equal(range->parts[0].max_u64, 20);
+ assert_int_equal(range->parts[1].min_u64, 50);
+ assert_int_equal(range->parts[1].max_u64, 100);
+ assert_int_equal(range->parts[2].min_u64, 255);
+ assert_int_equal(range->parts[2].max_u64, 255);
+ lysp_leaf = (void *) mod->parsed->data;
+ CHECK_LYSP_NODE_LEAF(lysp_leaf, NULL, 0, 0x0, 0, "port", 0, 0, NULL, 0, 0, NULL, NULL);
+ CHECK_LYSP_TYPE(&(lysp_leaf->type), 0, 0, 0, 0, 0, 0x10, 0, 1, "string", 0, 0, 1, 0, 0, 0);
+ CHECK_LYSP_RESTR(lysp_leaf->type.length, "10 .. 20 | 50 .. 100 | 255", NULL, NULL, NULL, 0, NULL);
+
+ /* SUBTYPE MODULE T2 */
+ schema = MODULE_CREATE_YIN("TS0",
+ "<typedef name=\"my_type\">"
+ " <type name=\"string\"> <length value=\"10 .. 20 | 50 .. 100 | 255\"/> </type>"
+ "</typedef>"
+ "<leaf name=\"port\"> <type name=\"my_type\">"
+ " <length value=\"min .. 15 | max\"/>"
+ "</type> </leaf>");
+ UTEST_ADD_MODULE(schema, LYS_IN_YIN, NULL, &mod);
+ assert_non_null(mod);
+ lysc_leaf = (void *) mod->compiled->data;
+ CHECK_LYSC_NODE_LEAF(lysc_leaf, NULL, 0, 0x5, 1, "port", 0, 0, 0, NULL, 0, 0, NULL, NULL);
+ CHECK_LYSC_TYPE_STR((struct lysc_type_str *)lysc_leaf->type, 0, 1, 0);
+ range = ((struct lysc_type_str *)lysc_leaf->type)->length;
+ CHECK_LYSC_RANGE(range, NULL, NULL, NULL, 0, 2, NULL);
+ assert_int_equal(range->parts[0].min_u64, 10);
+ assert_int_equal(range->parts[0].max_u64, 15);
+ assert_int_equal(range->parts[1].min_u64, 255);
+ assert_int_equal(range->parts[1].max_u64, 255);
+ lysp_leaf = (void *) mod->parsed->data;
+ CHECK_LYSP_NODE_LEAF(lysp_leaf, NULL, 0, 0x0, 0, "port", 0, 0, NULL, 0, 0, NULL, NULL);
+ CHECK_LYSP_TYPE(&(lysp_leaf->type), 0, 0, 0, 0, 0, 0x10, 0, 1, "my_type", 0, 0, 1, 0, 0, 0);
+ CHECK_LYSP_RESTR(lysp_leaf->type.length, "min .. 15 | max", NULL, NULL, NULL, 0, NULL);
+
+ /* ERROR TESTS NEGATIVE VALUE */
+ schema = MODULE_CREATE_YIN("ERR0", "<leaf name=\"port\"> <type name=\"string\">"
+ "<length value =\"-1 .. 20\"/> </type></leaf>");
+ UTEST_INVALID_MODULE(schema, LYS_IN_YIN, NULL, LY_EDENIED);
+ CHECK_LOG_CTX("Invalid length restriction - value \"-1\" does not fit the type limitations.", "/ERR0:port");
+
+ schema = MODULE_CREATE_YIN("ERR1", "<leaf name=\"port\"> <type name=\"string\">"
+ "<length value=\"100 .. 18446744073709551616\"/>"
+ "</type> </leaf>");
+ UTEST_INVALID_MODULE(schema, LYS_IN_YIN, NULL, LY_EVALID);
+ CHECK_LOG_CTX("Invalid length restriction - invalid value \"18446744073709551616\".", "/ERR1:port");
+
+ schema = MODULE_CREATE_YIN("ERR2", "<leaf name=\"port\">"
+ "<type name=\"string\"> <length value=\"10 .. 20 | 20 .. 30\"/>"
+ "</type> </leaf>");
+ UTEST_INVALID_MODULE(schema, LYS_IN_YIN, NULL, LY_EEXIST);
+ CHECK_LOG_CTX("Invalid length restriction - values are not in ascending order (20).", "/ERR2:port");
+
+ schema = MODULE_CREATE_YIN("ERR3",
+ "<typedef name=\"my_type\"> <type name=\"string\"/> </typedef>"
+ "<leaf name=\"port\"> <type name=\"my_type\"> <length value=\"-1 .. 15\"/>"
+ "</type> </leaf>");
+ UTEST_INVALID_MODULE(schema, LYS_IN_YIN, NULL, LY_EDENIED);
+ CHECK_LOG_CTX("Invalid length restriction - value \"-1\" does not fit the type limitations.", "/ERR3:port");
+
+ /*
+ * PATTERN
+ */
+ schema = MODULE_CREATE_YIN("TPATTERN_0", "<leaf name=\"port\"> <type name=\"string\">"
+ "<pattern value=\"[a-zA-Z_][a-zA-Z0-9\\-_.]*\"/>"
+ "</type> </leaf>");
+ UTEST_ADD_MODULE(schema, LYS_IN_YIN, NULL, &mod);
+ assert_non_null(mod);
+ lysc_leaf = (void *) mod->compiled->data;
+ CHECK_LYSC_NODE_LEAF(lysc_leaf, NULL, 0, 0x5, 1, "port", 0, 0, 0, NULL, 0, 0, NULL, NULL);
+ CHECK_LYSC_TYPE_STR((struct lysc_type_str *)lysc_leaf->type, 0, 0, 1);
+ pattern = ((struct lysc_type_str *)lysc_leaf->type)->patterns[0];
+ CHECK_LYSC_PATTERN(pattern, NULL, NULL, NULL, "[a-zA-Z_][a-zA-Z0-9\\-_.]*", 0, 0, NULL);
+ lysp_leaf = (void *) mod->parsed->data;
+ CHECK_LYSP_NODE_LEAF(lysp_leaf, NULL, 0, 0x0, 0, "port", 0, 0, NULL, 0, 0, NULL, NULL);
+ CHECK_LYSP_TYPE(&(lysp_leaf->type), 0, 0, 0, 0, 0, 0x40, 0, 0, "string", 0, 1, 1, 0, 0, 0);
+ CHECK_LYSP_RESTR(&(lysp_leaf->type.patterns[0]), "\x6" "[a-zA-Z_][a-zA-Z0-9\\-_.]*", NULL, NULL, NULL, 0, NULL);
+
+ schema = MODULE_CREATE_YIN("TPATTERN_1", "<leaf name=\"port\"> <type name=\"string\">"
+ " <pattern value=\"[a-zA-Z_][a-zA-Z0-9\\-_.]*\"/>"
+ " <pattern value=\"abc.*\"> <modifier value=\"invert-match\"/> </pattern>"
+ "</type> </leaf>");
+ UTEST_ADD_MODULE(schema, LYS_IN_YIN, NULL, &mod);
+ assert_non_null(mod);
+ lysc_leaf = (void *) mod->compiled->data;
+ CHECK_LYSC_NODE_LEAF(lysc_leaf, NULL, 0, 0x5, 1, "port", 0, 0, 0, NULL, 0, 0, NULL, NULL);
+ CHECK_LYSC_TYPE_STR((struct lysc_type_str *)lysc_leaf->type, 0, 0, 2);
+ pattern = ((struct lysc_type_str *)lysc_leaf->type)->patterns[0];
+ CHECK_LYSC_PATTERN(pattern, NULL, NULL, NULL, "[a-zA-Z_][a-zA-Z0-9\\-_.]*", 0, 0, NULL);
+ pattern = ((struct lysc_type_str *)lysc_leaf->type)->patterns[1];
+ CHECK_LYSC_PATTERN(pattern, NULL, NULL, NULL, "abc.*", 0, 0x1, NULL);
+ lysp_leaf = (void *) mod->parsed->data;
+ CHECK_LYSP_NODE_LEAF(lysp_leaf, NULL, 0, 0x0, 0, "port", 0, 0, NULL, 0, 0, NULL, NULL);
+ CHECK_LYSP_TYPE(&(lysp_leaf->type), 0, 0, 0, 0, 0, 0x40, 0, 0, "string", 0, 2, 1, 0, 0, 0);
+ CHECK_LYSP_RESTR(&(lysp_leaf->type.patterns[0]), "\x6" "[a-zA-Z_][a-zA-Z0-9\\-_.]*", NULL, NULL, NULL, 0, NULL);
+ CHECK_LYSP_RESTR(&(lysp_leaf->type.patterns[1]), "\x15" "abc.*", NULL, NULL, NULL, 0, NULL);
+
+ schema = MODULE_CREATE_YIN("TPATTERN_2",
+ "<typedef name=\"my_type\">"
+ " <type name=\"string\">"
+ " <pattern value=\"[a-zA-Z_][a-zA-Z0-9\\-_.]*\"/>"
+ " <pattern value=\"abc.*\"> <modifier value=\"invert-match\"/> </pattern>"
+ "</type> </typedef>"
+ "<leaf name=\"port\"><type name=\"my_type\"> <pattern value=\"bcd.*\"/> </type></leaf>");
+ UTEST_ADD_MODULE(schema, LYS_IN_YIN, NULL, &mod);
+ assert_non_null(mod);
+ lysc_leaf = (void *) mod->compiled->data;
+ CHECK_LYSC_NODE_LEAF(lysc_leaf, NULL, 0, 0x5, 1, "port", 0, 0, 0, NULL, 0, 0, NULL, NULL);
+ CHECK_LYSC_TYPE_STR((struct lysc_type_str *)lysc_leaf->type, 0, 0, 3);
+ pattern = ((struct lysc_type_str *)lysc_leaf->type)->patterns[0];
+ CHECK_LYSC_PATTERN(pattern, NULL, NULL, NULL, "[a-zA-Z_][a-zA-Z0-9\\-_.]*", 0, 0, NULL);
+ pattern = ((struct lysc_type_str *)lysc_leaf->type)->patterns[1];
+ CHECK_LYSC_PATTERN(pattern, NULL, NULL, NULL, "abc.*", 0, 0x1, NULL);
+ pattern = ((struct lysc_type_str *)lysc_leaf->type)->patterns[2];
+ CHECK_LYSC_PATTERN(pattern, NULL, NULL, NULL, "bcd.*", 0, 0x0, NULL);
+ lysp_leaf = (void *) mod->parsed->data;
+ CHECK_LYSP_NODE_LEAF(lysp_leaf, NULL, 0, 0x0, 0, "port", 0, 0, NULL, 0, 0, NULL, NULL);
+ CHECK_LYSP_TYPE(&(lysp_leaf->type), 0, 0, 0, 0, 0, 0x40, 0, 0, "my_type", 0, 1, 1, 0, 0, 0);
+ CHECK_LYSP_RESTR(&(lysp_leaf->type.patterns[0]), "\x6" "bcd.*", NULL, NULL, NULL, 0, NULL);
+
+ /*
+ * TEST pattern error
+ * */
+ schema = MODULE_CREATE_YIN("TPATTERN_ERR_0",
+ "<leaf name=\"port\"> <type name=\"string\">"
+ " <pattern value=\"[a-zA-Z_][a-zA-Z0-9\\-_.*\"/>"
+ "</type> </leaf>");
+ UTEST_INVALID_MODULE(schema, LYS_IN_YIN, NULL, LY_EVALID);
+ CHECK_LOG_CTX("Regular expression \"[a-zA-Z_][a-zA-Z0-9\\-_.*\" is not valid (\"\": missing terminating ] for character class).",
+ "/TPATTERN_ERR_0:port");
+
+ /*
+ * DEFAUT VALUE
+ */
+ schema = MODULE_CREATE_YIN("TDEFAULT_0",
+ "<typedef name=\"my_type\">"
+ " <type name=\"string\">"
+ " <pattern value=\"[a-zA-Z_][a-zA-Z0-9\\-_.]*\"/>"
+ " <length value=\"2 .. 5 | 10\"/>"
+ " </type>"
+ " <default value=\"a1i-j\"/>"
+ "</typedef>"
+ "<leaf name=\"port\"> <type name=\"my_type\"/> </leaf>");
+ UTEST_ADD_MODULE(schema, LYS_IN_YIN, NULL, &mod);
+ assert_non_null(mod);
+ lysc_leaf = (void *) mod->compiled->data;
+ CHECK_LYSC_NODE_LEAF(lysc_leaf, NULL, 0, 0x5, 1, "port", 0, 0, 0, NULL, 0, 0, NULL, "a1i-j");
+ CHECK_LYSC_TYPE_STR((struct lysc_type_str *)lysc_leaf->type, 0, 1, 1);
+ pattern = ((struct lysc_type_str *)lysc_leaf->type)->patterns[0];
+ CHECK_LYSC_PATTERN(pattern, NULL, NULL, NULL, "[a-zA-Z_][a-zA-Z0-9\\-_.]*", 0, 0, NULL);
+ range = ((struct lysc_type_str *)lysc_leaf->type)->length;
+ CHECK_LYSC_RANGE(range, NULL, NULL, NULL, 0, 2, NULL);
+ assert_int_equal(range->parts[0].min_u64, 2);
+ assert_int_equal(range->parts[0].max_u64, 5);
+ assert_int_equal(range->parts[1].min_u64, 10);
+ assert_int_equal(range->parts[1].max_u64, 10);
+ lysp_leaf = (void *) mod->parsed->data;
+ CHECK_LYSP_NODE_LEAF(lysp_leaf, NULL, 0, 0x0, 0, "port", 0, 0, NULL, 0, 0, NULL, NULL);
+ CHECK_LYSP_TYPE(&(lysp_leaf->type), 0, 0, 0, 0, 0, 0x0, 0, 0, "my_type", 0, 0, 1, 0, 0, 0);
+
+ schema = MODULE_CREATE_YIN("TDEFAULT_1",
+ "<typedef name=\"my_type\">"
+ " <type name=\"string\">"
+ " </type>"
+ " <default value=\"a1i-j&lt;\"/>"
+ "</typedef>"
+ "<leaf name=\"port\"> <type name=\"my_type\"/> </leaf>");
+ UTEST_ADD_MODULE(schema, LYS_IN_YIN, NULL, &mod);
+ assert_non_null(mod);
+ lysc_leaf = (void *) mod->compiled->data;
+ CHECK_LYSC_NODE_LEAF(lysc_leaf, NULL, 0, 0x5, 1, "port", 0, 0, 0, NULL, 0, 0, NULL, "a1i-j<");
+ CHECK_LYSC_TYPE_STR((struct lysc_type_str *)lysc_leaf->type, 0, 0, 0);
+ CHECK_LYSC_RANGE(range, NULL, NULL, NULL, 0, 2, NULL);
+ assert_int_equal(range->parts[0].min_u64, 2);
+ assert_int_equal(range->parts[0].max_u64, 5);
+ assert_int_equal(range->parts[1].min_u64, 10);
+ assert_int_equal(range->parts[1].max_u64, 10);
+ lysp_leaf = (void *) mod->parsed->data;
+ CHECK_LYSP_NODE_LEAF(lysp_leaf, NULL, 0, 0x0, 0, "port", 0, 0, NULL, 0, 0, NULL, NULL);
+ CHECK_LYSP_TYPE(&(lysp_leaf->type), 0, 0, 0, 0, 0, 0x0, 0, 0, "my_type", 0, 0, 1, 0, 0, 0);
+
+ schema = MODULE_CREATE_YIN("TDEFAULT_2",
+ "<typedef name=\"my_type\">"
+ " <type name=\"string\">"
+ " <length value=\"2\"/>"
+ " </type>"
+ " <default value=\"a1i-j&lt;\"/>"
+ "</typedef>"
+ "<leaf name=\"port\"> <type name=\"my_type\"/> </leaf>");
+ UTEST_INVALID_MODULE(schema, LYS_IN_YIN, NULL, LY_EVALID);
+
+ schema = MODULE_CREATE_YIN("TDEFAULT_2",
+ "<typedef name=\"my_type\">"
+ " <type name=\"string\">"
+ " <length value=\"2\"/>"
+ " </type>"
+ " <default value=\"a1i-j&lt;\"/>"
+ "</typedef>"
+ "<leaf name=\"port\"> <type name=\"my_type\"/> </leaf>");
+ UTEST_INVALID_MODULE(schema, LYS_IN_YIN, NULL, LY_EVALID);
+
+ schema = MODULE_CREATE_YIN("TDEFAULT_3",
+ "<typedef name=\"my_type\">"
+ " <default value=\"a1i-j&lt;\"/>"
+ " <type name=\"string\">"
+ "</type> </typedef>"
+ "<leaf name=\"port\"><type name=\"my_type\"> <pattern value=\"bcd.*\"/> </type></leaf>");
+ UTEST_INVALID_MODULE(schema, LYS_IN_YIN, NULL, LY_EVALID);
+
+}
+
+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",
+ "leaf port {type string {"
+ "length \"min .. 20 | 50\";"
+ "pattern \"p.*\\\\\\\\\";"
+ "pattern 'p4.*' {modifier invert-match;}"
+ "}default \"p\\\"<\\\\\";}");
+ schema_yin = MODULE_CREATE_YIN("PRINT0",
+ " <leaf name=\"port\">\n"
+ " <type name=\"string\">\n"
+ " <length value=\"min .. 20 | 50\"/>\n"
+ " <pattern value=\"p.*\\\\\"/>\n"
+ " <pattern value=\"p4.*\">\n"
+ " <modifier value=\"invert-match\"/>\n"
+ " </pattern>\n"
+ " </type>\n"
+ " <default value=\"p&quot;&lt;\\\"/>\n"
+ " </leaf>\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"
+ " leaf port {\n"
+ " type string {\n"
+ " length \"min .. 20 | 50\";\n"
+ " pattern \"p.*\\\\\\\\\";\n"
+ " pattern \"p4.*\" {\n"
+ " modifier invert-match;\n"
+ " }\n"
+ " }\n"
+ " default \"p\\\"<\\\\\";\n"
+ " }\n");
+ schema_yin = MODULE_CREATE_YIN("PRINT1",
+ " <leaf name=\"port\">\n"
+ " <type name=\"string\">\n"
+ " <length value=\"min .. 20 | 50\"/>\n"
+ " <pattern value=\"p.*\\\\\"/>\n"
+ " <pattern value=\"p4.*\">\n"
+ " <modifier value=\"invert-match\"/>\n"
+ " </pattern>\n"
+ " </type>\n"
+ " <default value=\"p&quot;&lt;\\\"/>\n"
+ " </leaf>\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);
+}
+
+static void
+test_data_xml(void **state)
+{
+ const char *schema;
+ struct lyd_node *tree;
+ const char *data;
+ struct lysc_node_container *lysc_root;
+ struct lyd_node_inner *lyd_root;
+
+ /* NO RESTRICTION TESTS */
+ schema = MODULE_CREATE_YANG("T0", "leaf port {type string;}");
+ UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, NULL);
+ /* space on start and new line */
+ TEST_SUCCESS_XML("T0", " 50 \n\t 64", STRING, " 50 \n\t 64");
+ /* nuber as string */
+ TEST_SUCCESS_XML("T0", "50", STRING, "50");
+ TEST_SUCCESS_XML("T0", "+250", STRING, "+250");
+ /* references */
+ TEST_SUCCESS_XML("T0", "&quot;", STRING, "\"");
+ TEST_SUCCESS_XML("T0", "|&amp;|", STRING, "|&|");
+ TEST_SUCCESS_XML("T0", "&apos;", STRING, "'");
+ TEST_SUCCESS_XML("T0", "&lt;", STRING, "<");
+ TEST_SUCCESS_XML("T0", "&gt;", STRING, ">");
+ TEST_SUCCESS_XML("T0", "&#x42f;&#1071;", STRING, "ЯЯ");
+ /* special characters */
+ TEST_SUCCESS_XML("T0", "\"", STRING, "\"");
+ TEST_SUCCESS_XML("T0", "'", STRING, "'");
+ TEST_SUCCESS_XML("T0", ">", STRING, ">");
+ TEST_SUCCESS_XML("T0", "", STRING, "");
+ TEST_SUCCESS_XML("T0", "&amp;&lt;lt;", STRING, "&<lt;");
+ /* CDATA IS NOT SUPPORTED
+ * TEST_SUCCESS_XML("T2", "<![CDATA[<greeting>Hello, world! & Wecome</greeting>]]>", STRING,
+ * "<greeting>Hello, world! & Wecome</greeting>");
+ * COMMENT IN MIDDLE OF TEXT IS NOT SUPPORTED
+ * TEST_SUCCESS_XML("T2", "this isn't <!--' this is comment '-->comment",
+ * STRING, "this isn't comment");
+ */
+
+ /* error */
+ TEST_ERROR_XML("T0", "< df");
+ CHECK_LOG_CTX("Child element \"df\" inside a terminal node \"port\" found.",
+ "Data location \"/T0:port\", line number 1.");
+ TEST_ERROR_XML("T0", "&text;");
+ CHECK_LOG_CTX("Entity reference \"&text;</po\" not supported, only predefined references allowed.", "Line number 1.");
+ TEST_ERROR_XML("T0", "\"&#x8;\"");
+ CHECK_LOG_CTX("Invalid character reference \"&#x8;\"</port\" (0x00000008).", "Line number 1.");
+
+ /* TEST INVERTED PATTERN ADN LENGTH */
+ schema = MODULE_CREATE_YANG("T1", "leaf port {type string {"
+ " length \"5 .. 10 | 20\";"
+ " pattern '[a-zA-Z_][a-zA-Z0-9\\-_.<]*' ;"
+ " pattern 'p4.*' {modifier invert-match;"
+ " error-app-tag \"pattern-violation\"; error-message \"invalid pattern of value\";}"
+ "}}");
+ UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, NULL);
+ /* inverted value */
+ TEST_SUCCESS_XML("T1", "abcde", STRING, "abcde");
+ TEST_SUCCESS_XML("T1", "abcde&lt;", STRING, "abcde<");
+ TEST_ERROR_XML("T1", "p4abc");
+ CHECK_LOG_CTX_APPTAG("invalid pattern of value", "Schema location \"/T1:port\", line number 1.", "pattern-violation");
+ /* size 20 */
+ TEST_SUCCESS_XML("T1", "ahojahojahojahojahoj", STRING, "ahojahojahojahojahoj");
+ TEST_SUCCESS_XML("T1", "abc-de", STRING, "abc-de");
+ /* ERROR LENGTH */
+ TEST_ERROR_XML("T1", "p4a&lt;");
+ CHECK_LOG_CTX("Unsatisfied length - string \"p4a<\" length is not allowed.",
+ "Schema location \"/T1:port\", line number 1.");
+
+ /* TEST DEFAULT VALUE */
+ schema = MODULE_CREATE_YANG("T2",
+ "container cont {\n"
+ " leaf port {type string {length \"0 .. 50 | 105\";} default \"test\";}"
+ "}");
+ /* using default value */
+ UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, NULL);
+ data = "<cont xmlns=\"urn:tests:" "T2" "\">" "</cont>";
+ CHECK_PARSE_LYD_PARAM(data, LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_SUCCESS, tree);
+ lysc_root = (void *)tree->schema;
+ CHECK_LYSC_NODE(lysc_root->child, NULL, 0, 0x205, 1, "port", 0, LYS_LEAF, 1, 0, 0, 0);
+ lyd_root = ((struct lyd_node_inner *) tree);
+ CHECK_LYD_NODE_TERM((struct lyd_node_term *) lyd_root->child, 1, 0, 0, 1, 1,
+ STRING, "test");\
+ lyd_free_all(tree);
+
+ /* rewriting default value */
+ UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, NULL);
+ data = "<cont xmlns=\"urn:tests:T2\">" "<port> 52 </port>" "</cont>";
+ CHECK_PARSE_LYD_PARAM(data, LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_SUCCESS, tree);
+ lysc_root = (void *)tree->schema;
+ CHECK_LYSC_NODE(lysc_root->child, NULL, 0, 0x205, 1, "port", 0, LYS_LEAF, 1, 0, 0, 0);
+ lyd_root = ((struct lyd_node_inner *) tree);
+ CHECK_LYD_NODE_TERM((struct lyd_node_term *) lyd_root->child, 0, 0, 0, 1, 1,
+ STRING, " 52 ");
+ lyd_free_all(tree);
+
+ /* WHIT STRING TEST */
+ schema = MODULE_CREATE_YANG("T_WHITE", "leaf port {type string;}");
+ UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, NULL);
+ TEST_SUCCESS_XML("T_WHITE", " \n\t", STRING, " \n\t");
+ TEST_SUCCESS_XML("T_WHITE", " \n&lt;\t", STRING, " \n<\t");
+
+ /* UTF-8 length and pattern*/
+ schema = MODULE_CREATE_YANG("T_UTF8", "leaf port {type string {"
+ " length \"5 .. 10\";"
+ " pattern '[€]{5,7}' ;"
+ "}}");
+ UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, NULL);
+ TEST_SUCCESS_XML("T_UTF8", "€€€€€", STRING, "€€€€€");
+ TEST_ERROR_XML("T_UTF8", "€€€");
+ CHECK_LOG_CTX("Unsatisfied length - string \"€€€\" length is not allowed.",
+ "Schema location \"/T_UTF8:port\", line number 1.");
+ TEST_ERROR_XML("T_UTF8", "€€€€€€€€");
+ CHECK_LOG_CTX("Unsatisfied pattern - \"€€€€€€€€\" does not conform to \"[€]{5,7}\".",
+ "Schema location \"/T_UTF8:port\", line number 1.");
+
+ /* ANCHOR TEST ^$ is implicit */
+ schema = MODULE_CREATE_YANG("T_ANCHOR", "leaf port {type string {"
+ " pattern 'a.*b' ;"
+ "}}");
+ UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, NULL);
+ TEST_ERROR_XML("T_ANCHOR", "abc");
+ CHECK_LOG_CTX("Unsatisfied pattern - \"abc\" does not conform to \"a.*b\".",
+ "Schema location \"/T_ANCHOR:port\", line number 1.");
+ TEST_ERROR_XML("T_ANCHOR", "cab");
+ CHECK_LOG_CTX("Unsatisfied pattern - \"cab\" does not conform to \"a.*b\".",
+ "Schema location \"/T_ANCHOR:port\", line number 1.");
+}
+
+static void
+test_data_json(void **state)
+{
+ const char *schema;
+ struct lyd_node *tree;
+ const char *data;
+ struct lysc_node_container *lysc_root;
+ struct lyd_node_inner *lyd_root;
+
+ /* NO RESTRICTION TESTS */
+ schema = MODULE_CREATE_YANG("T0", "leaf port {type string;}");
+ UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, NULL);
+ TEST_SUCCESS_JSON("T0", "this is text", STRING, "this is text");
+ /* space on start and new line */
+ TEST_SUCCESS_JSON("T0", " 50 \\n\\t 64", STRING, " 50 \n\t 64");
+ /* nuber as string */
+ TEST_SUCCESS_JSON("T0", "50", STRING, "50");
+ TEST_SUCCESS_JSON("T0", "+250", STRING, "+250");
+ /* references */
+ TEST_SUCCESS_JSON("T0", "\\\"", STRING, "\"");
+ TEST_SUCCESS_JSON("T0", "|&|", STRING, "|&|");
+ TEST_SUCCESS_JSON("T0", "<", STRING, "<");
+ TEST_SUCCESS_JSON("T0", ">", STRING, ">");
+ TEST_SUCCESS_JSON("T0", "\\u042F", STRING, "Я");
+ TEST_SUCCESS_JSON("T0", "\\u042FFF", STRING, "ЯFF");
+ /* special characters */
+ TEST_SUCCESS_JSON("T0", "'", STRING, "'");
+ TEST_SUCCESS_JSON("T0", ">", STRING, ">");
+ TEST_SUCCESS_JSON("T0", "", STRING, "");
+ TEST_SUCCESS_JSON("T0", "\\\" \\\\ \\r \\/ \\n \\t \\u20ac", STRING, "\" \\ \r / \n \t €");
+
+ /* ERROR invalid json string */
+ TEST_ERROR_JSON("T0", "\n");
+ CHECK_LOG_CTX("Invalid character in JSON string \"\n\" (0x0000000a).",
+ "Line number 1.");
+ /* backspace and form feed are valid JSON escape sequences, but the control characters they represents are not allowed values for YANG string type */
+ TEST_ERROR_JSON("T0", "\\b");
+ CHECK_LOG_CTX("Invalid character reference \"\\b\" (0x00000008).", "Line number 1.");
+
+ TEST_ERROR_JSON("T0", "\\f");
+ CHECK_LOG_CTX("Invalid character reference \"\\f\" (0x0000000c).", "Line number 1.");
+
+ TEST_ERROR_JSON("T0", "\"");
+ CHECK_LOG_CTX("Unexpected character \"\"\" after JSON string.", "Line number 1.");
+
+ TEST_ERROR_JSON("T0", "aabb \\x");
+ CHECK_LOG_CTX("Invalid character escape sequence \\x.", "Line number 1.");
+
+ /* TEST INVERTED PATTERN ADN LENGTH */
+ schema = MODULE_CREATE_YANG("T1", "leaf port {type string {"
+ " length \"5 .. 10 | 20\";"
+ " pattern '[a-zA-Z_][a-zA-Z0-9\\-_.<]*\\n[a-zA-Z0-9\\-_.<]*' ;"
+ " pattern 'p4.*\\n' {modifier invert-match;}"
+ "}}");
+ UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, NULL);
+ /* inverted value */
+ TEST_SUCCESS_JSON("T1", "a\\nbcde", STRING, "a\nbcde");
+ TEST_ERROR_JSON("T1", "p4abc\\n");
+ CHECK_LOG_CTX("Unsatisfied pattern - \"p4abc\n\" does not conform to inverted \"p4.*\\n\".",
+ "Schema location \"/T1:port\", line number 1.");
+ /* size 20 */
+ TEST_SUCCESS_JSON("T1", "ahojahojaho\\njahojaho", STRING, "ahojahojaho\njahojaho");
+ TEST_SUCCESS_JSON("T1", "abc\\n-de", STRING, "abc\n-de");
+ /* ERROR LENGTH */
+ TEST_ERROR_JSON("T1", "p4a\u042F");
+ CHECK_LOG_CTX("Unsatisfied length - string \"p4aЯ\" length is not allowed.",
+ "Schema location \"/T1:port\", line number 1.");
+
+ /* TEST DEFAULT VALUE */
+ schema = MODULE_CREATE_YANG("T_DEFAULT2",
+ "container cont {\n"
+ " leaf port {type string {length \"0 .. 50 | 105\";} default \"test\";}"
+ "}");
+ /* using default value */
+ UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, NULL);
+ data = "{\"T_DEFAULT2:cont\":{}}";
+ CHECK_PARSE_LYD_PARAM(data, LYD_JSON, 0, LYD_VALIDATE_PRESENT, LY_SUCCESS, tree);
+ lysc_root = (void *)tree->schema;
+ CHECK_LYSC_NODE(lysc_root->child, NULL, 0, 0x205, 1, "port", 0, LYS_LEAF, 1, 0, 0, 0);
+ lyd_root = ((struct lyd_node_inner *) tree);
+ CHECK_LYD_NODE_TERM((struct lyd_node_term *) lyd_root->child, 1, 0, 0, 1, 1,
+ STRING, "test");\
+ lyd_free_all(tree);
+
+ /* rewriting default value */
+ UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, NULL);
+ data = "{\"T_DEFAULT2:cont\":{\":port\": \" 52 \"}}";\
+ CHECK_PARSE_LYD_PARAM(data, LYD_JSON, 0, LYD_VALIDATE_PRESENT, LY_SUCCESS, tree);
+ lysc_root = (void *)tree->schema;
+ CHECK_LYSC_NODE(lysc_root->child, NULL, 0, 0x205, 1, "port", 0, LYS_LEAF, 1, 0, 0, 0);
+ lyd_root = ((struct lyd_node_inner *) tree);
+ CHECK_LYD_NODE_TERM((struct lyd_node_term *) lyd_root->child, 0, 0, 0, 1, 1,
+ STRING, " 52 ");
+ lyd_free_all(tree);
+
+ /* UTF-8 length and pattern*/
+ schema = MODULE_CREATE_YANG("T_UTF8", "leaf port {type string {"
+ " length \"5 .. 10\";"
+ " pattern '[€]{5,7}' ;"
+ "}}");
+ UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, NULL);
+ TEST_SUCCESS_JSON("T_UTF8", "€€€€€", STRING, "€€€€€");
+ TEST_ERROR_JSON("T_UTF8", "€€€");
+ CHECK_LOG_CTX("Unsatisfied length - string \"€€€\" length is not allowed.",
+ "Schema location \"/T_UTF8:port\", line number 1.");
+ TEST_ERROR_JSON("T_UTF8", "€€€€€€€€");
+ CHECK_LOG_CTX("Unsatisfied pattern - \"€€€€€€€€\" does not conform to \"[€]{5,7}\".",
+ "Schema location \"/T_UTF8:port\", line number 1.");
+
+ /* ANCHOR TEST ^$ is implicit */
+ schema = MODULE_CREATE_YANG("T_ANCHOR", "leaf port {type string {"
+ " pattern 'a.*b' ;"
+ "}}");
+ UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, NULL);
+ TEST_ERROR_JSON("T_ANCHOR", "abc");
+ CHECK_LOG_CTX("Unsatisfied pattern - \"abc\" does not conform to \"a.*b\".",
+ "Schema location \"/T_ANCHOR:port\", line number 1.");
+ TEST_ERROR_JSON("T_ANCHOR", "cb");
+ CHECK_LOG_CTX("Unsatisfied pattern - \"cb\" does not conform to \"a.*b\".",
+ "Schema location \"/T_ANCHOR:port\", line number 1.");
+}
+
+static void
+test_data_lyb(void **state)
+{
+ const char *schema;
+
+ schema = MODULE_CREATE_YANG("lyb", "leaf port {type string;}");
+ UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, NULL);
+ TEST_SUCCESS_LYB("lyb", "port", "");
+ TEST_SUCCESS_LYB("lyb", "port", "a");
+ TEST_SUCCESS_LYB("lyb", "port", "abcdefghijklmnopqrstuvwxyz");
+}
+
+static void
+test_diff(void **state)
+{
+ (void) state;
+ const char *schema;
+
+ schema = MODULE_CREATE_YANG("T_DIFF", "leaf port {type string {length \"6 .. 50 | 120\";}}");
+ UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, NULL);
+
+ struct lyd_node *model_1, *model_2;
+ struct lyd_node *diff;
+ const char *data_1 = "<port xmlns=\"urn:tests:T_DIFF\"> text abc &lt; </port>";
+ const char *data_2 = "<port xmlns=\"urn:tests:T_DIFF\"> text abc &gt; </port>";
+ const char *diff_expected = "<port xmlns=\"urn:tests:T_DIFF\""
+ " xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\""
+ " yang:operation=\"replace\" yang:orig-default=\"false\""
+ " yang:orig-value=\" text abc &lt; \"> text abc &gt; </port>";
+
+ 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);
+
+ /* create data from diff */
+ diff_expected = "<port xmlns=\"urn:tests:T_DIFF\""
+ " xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\""
+ " yang:operation=\"replace\" yang:orig-default=\"false\""
+ " yang:orig-value=\" 10^20 \">jjjjjjj</port>";
+
+ CHECK_PARSE_LYD_PARAM(diff_expected, LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_SUCCESS, diff);
+ data_1 = "<port xmlns=\"urn:tests:T_DIFF\"> 10^20 </port>";
+ CHECK_PARSE_LYD_PARAM(data_1, LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_SUCCESS, model_1);
+ assert_int_equal(LY_SUCCESS, lyd_diff_apply_all(&model_1, diff));
+ const char *expected = "<port xmlns=\"urn:tests:T_DIFF\">jjjjjjj</port>";
+
+ CHECK_LYD_STRING_PARAM(model_1, expected, LYD_XML, LYD_PRINT_WITHSIBLINGS | LYD_PRINT_SHRINK);
+ lyd_free_all(model_1);
+ lyd_free_all(diff);
+
+ /* check creating data breaking restrictions */
+ diff_expected = "<port xmlns=\"urn:tests:T_DIFF\" "
+ "xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" "
+ "yang:operation=\"replace\" yang:orig-default=\"false\" yang:orig-value=\" 555 555\">"
+ "121</port>";
+ CHECK_PARSE_LYD_PARAM(diff_expected, LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_EVALID, model_1);
+ CHECK_LOG_CTX("Unsatisfied length - string \"121\" length is not allowed.",
+ "Schema location \"/T_DIFF:port\", line number 1.");
+
+ /* diff from default value */
+ data_1 = "<cont xmlns=\"urn:tests:T_DIFF1\"></cont>";
+ data_2 = "<cont xmlns=\"urn:tests:T_DIFF1\"> <port> 6 </port> </cont>";
+ diff_expected = "<cont xmlns=\"urn:tests:T_DIFF1\""
+ " xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\""
+ " yang:operation=\"create\"><port> 6 </port></cont>";
+
+ schema = MODULE_CREATE_YANG("T_DIFF1",
+ "container cont {\n"
+ " leaf port {type string; default \" 20\n30 \";}"
+ "}");
+ UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, NULL);
+ 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(diff);
+
+ lyd_free_all(model_1);
+ lyd_free_all(model_2);
+}
+
+static void
+test_print(void **state)
+{
+ (void) state;
+ const char *schema;
+
+ schema = MODULE_CREATE_YANG("T_PRINT", "leaf port {type string;}");
+ UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, NULL);
+
+ struct lyd_node *model_1;
+ const char *data_1 = "<port xmlns=\"urn:tests:T_PRINT\"> &lt; hello &gt; </port>";
+
+ CHECK_PARSE_LYD_PARAM(data_1, LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_SUCCESS, model_1);
+
+ /* XML */
+ const char *expected_xml = "<port xmlns=\"urn:tests:T_PRINT\"> &lt; hello &gt; </port>";
+
+ CHECK_LYD_STRING_PARAM(model_1, expected_xml, LYD_XML, LYD_PRINT_SHRINK | LYD_PRINT_WITHSIBLINGS | LYD_PRINT_SHRINK);
+
+ /* JSON */
+ const char *expected_json = "{\"T_PRINT:port\":\" < hello > \"}";
+
+ CHECK_LYD_STRING_PARAM(model_1, expected_json, LYD_JSON, LYD_PRINT_SHRINK | LYD_PRINT_WITHSIBLINGS | LYD_PRINT_SHRINK);
+
+ lyd_free_all(model_1);
+}
+
+static void
+test_plugin_store(void **state)
+{
+ (void) state;
+
+ const char *val_text = NULL;
+ struct ly_err_item *err = NULL;
+ struct lys_module *mod;
+ struct lyd_value value = {0};
+ struct lyplg_type *type = lyplg_type_plugin_find("", NULL, ly_data_type2str[LY_TYPE_STRING]);
+ struct lysc_type *lysc_type;
+ char *alloc_text;
+ unsigned int alloc_text_size;
+ LY_ERR ly_ret;
+ const char *schema;
+
+ schema = MODULE_CREATE_YANG("T0", "leaf port {type string {length \"0 .. 10\";"
+ "pattern '[0-9\\n<>\\\"\\|]*' ;}}");
+ UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, &mod);
+ lysc_type = ((struct lysc_node_leaf *) mod->compiled->data)->type;
+
+ /* check proper type */
+ assert_string_equal("libyang 2 - string, version 1", type->id);
+
+ /* check store */
+ val_text = "20";
+ assert_int_equal(LY_SUCCESS, type->store(UTEST_LYCTX, lysc_type, val_text, strlen(val_text),
+ 0, LY_VALUE_XML, NULL, LYD_VALHINT_STRING, NULL, &value, NULL, &err));
+ CHECK_LYD_VALUE(value, STRING, "20");
+ assert_ptr_equal(value.realtype, lysc_type);
+ type->free(UTEST_LYCTX, &value);
+
+ val_text = "150\n";
+ assert_int_equal(LY_SUCCESS, type->store(UTEST_LYCTX, lysc_type, val_text, strlen(val_text),
+ 0, LY_VALUE_XML, NULL, LYD_VALHINT_STRING, NULL, &value, NULL, &err));
+ CHECK_LYD_VALUE(value, STRING, "150\n");
+ assert_ptr_equal(value.realtype, lysc_type);
+ type->free(UTEST_LYCTX, &value);
+
+ val_text = "<\"150>\n";
+ assert_int_equal(LY_SUCCESS, type->store(UTEST_LYCTX, lysc_type, val_text, strlen(val_text),
+ 0, LY_VALUE_XML, NULL, LYD_VALHINT_STRING, NULL, &value, NULL, &err));
+ CHECK_LYD_VALUE(value, STRING, "<\"150>\n");
+ assert_ptr_equal(value.realtype, lysc_type);
+ type->free(UTEST_LYCTX, &value);
+
+ val_text = "<\"150>\n|hi how are you";
+ assert_int_equal(LY_SUCCESS, type->store(UTEST_LYCTX, lysc_type, val_text, 8,
+ 0, LY_VALUE_XML, NULL, LYD_VALHINT_STRING, NULL, &value, NULL, &err));
+ CHECK_LYD_VALUE(value, STRING, "<\"150>\n|");
+ assert_ptr_equal(value.realtype, lysc_type);
+ type->free(UTEST_LYCTX, &value);
+
+ val_text = "";
+ assert_int_equal(LY_SUCCESS, type->store(UTEST_LYCTX, lysc_type, val_text, strlen(val_text),
+ 0, LY_VALUE_XML, NULL, LYD_VALHINT_STRING, NULL, &value, NULL, &err));
+ CHECK_LYD_VALUE(value, STRING, "");
+ assert_ptr_equal(value.realtype, lysc_type);
+ type->free(UTEST_LYCTX, &value);
+
+ /*
+ * minor tests
+ * dynamic alocated input text
+ */
+ val_text = "<250>";
+ alloc_text_size = strlen(val_text);
+ alloc_text = (char *) malloc(alloc_text_size + 1);
+ memcpy(alloc_text, val_text, alloc_text_size + 1);
+
+ ly_ret = type->store(UTEST_LYCTX, lysc_type, alloc_text, alloc_text_size,
+ LYPLG_TYPE_STORE_DYNAMIC, LY_VALUE_XML, NULL, LYD_VALHINT_STRING, NULL, &value, NULL, &err);
+ alloc_text = NULL;
+ assert_int_equal(LY_SUCCESS, ly_ret);
+ CHECK_LYD_VALUE(value, STRING, "<250>");
+ type->free(UTEST_LYCTX, &value);
+
+ /* wrong lysc_type of value */
+ struct lysc_type lysc_type_test = *lysc_type;
+
+ lysc_type_test.basetype = LY_TYPE_UINT8;
+ val_text = "20";
+ ly_ret = type->store(UTEST_LYCTX, &lysc_type_test, val_text, strlen(val_text),
+ 0, LY_VALUE_XML, NULL, LYD_VALHINT_STRING, NULL, &value, NULL, &err);
+ assert_int_equal(LY_EINVAL, ly_ret);
+ ly_err_free(err);
+
+ /* TEST pattern backslash */
+
+ schema = MODULE_CREATE_YANG("TPATTERN_BC_1", "leaf port {type string {"
+ "pattern '\\\\[a]b';" /* pattern '\\[a]b'; */
+ "}}");
+ UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, &mod);
+ lysc_type = ((struct lysc_node_leaf *)mod->compiled->data)->type;
+ val_text = "\\ab";
+ assert_int_equal(LY_SUCCESS, type->store(UTEST_LYCTX, lysc_type, val_text, strlen(val_text),
+ 0, LY_VALUE_XML, NULL, LYD_VALHINT_STRING, NULL, &value, NULL, &err));
+ CHECK_LYD_VALUE(value, STRING, "\\ab");
+ type->free(UTEST_LYCTX, &value);
+
+ schema = MODULE_CREATE_YANG("TPATTERN_BC_2", "leaf port {type string {"
+ "pattern \"\\\\\\\\[a]b\";" /* pattern "\\\\[a]b"; */
+ "}}");
+ UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, &mod);
+ lysc_type = ((struct lysc_node_leaf *)mod->compiled->data)->type;
+ val_text = "\\ab";
+ assert_int_equal(LY_SUCCESS, type->store(UTEST_LYCTX, lysc_type, val_text, strlen(val_text),
+ 0, LY_VALUE_XML, NULL, LYD_VALHINT_STRING, NULL, &value, NULL, &err));
+ CHECK_LYD_VALUE(value, STRING, "\\ab");
+ type->free(UTEST_LYCTX, &value);
+
+ /* ERROR TESTS */
+
+ val_text = "10 \"| bcdei";
+ err = NULL;
+ ly_ret = type->store(UTEST_LYCTX, lysc_type, val_text, strlen(val_text),
+ 0, LY_VALUE_XML, NULL, LYD_VALHINT_STRING, NULL, &value, NULL, &err);
+ assert_int_equal(LY_EVALID, ly_ret);
+ ly_err_free(err);
+
+ val_text = "012345678901";
+ err = NULL;
+ ly_ret = type->store(UTEST_LYCTX, lysc_type, val_text, strlen(val_text),
+ 0, LY_VALUE_XML, NULL, LYD_VALHINT_STRING, NULL, &value, NULL, &err);
+ assert_int_equal(LY_EVALID, ly_ret);
+ ly_err_free(err);
+
+ val_text = "10";
+ err = NULL;
+ ly_ret = type->store(UTEST_LYCTX, lysc_type, val_text, strlen(val_text),
+ 0, LY_VALUE_XML, NULL, LYD_VALHINT_DECNUM, NULL, &value, NULL, &err);
+ assert_int_equal(LY_EVALID, ly_ret);
+ ly_err_free(err);
+
+}
+
+static void
+test_plugin_compare(void **state)
+{
+ struct ly_err_item *err = NULL;
+ struct lys_module *mod;
+ struct lyd_value values[10];
+ struct lyplg_type *type = lyplg_type_plugin_find("", NULL, ly_data_type2str[LY_TYPE_STRING]);
+ struct lysc_type *lysc_type;
+ LY_ERR ly_ret;
+ const char *schema;
+
+ /* different type */
+ const char *diff_type_text = "20";
+ struct lyd_value diff_type_val;
+ struct lysc_type *diff_type;
+
+ /* create schema. Prepare common used variables */
+ schema = MODULE_CREATE_YANG("T0", "typedef my_int_type {type string; }"
+ "leaf p1 {type my_int_type;}"
+ "leaf p2 {type my_int_type;}"
+ "leaf p3 {type string;}"
+ "leaf p4 {type uint8;}");
+ UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, &mod);
+ lysc_type = ((struct lysc_node_leaf *) mod->compiled->data)->type;
+
+ /* CREATE VALUES */
+ const char *val_init[] = {"hi", "hello", "hi", "hello", "hell", "hh"};
+
+ for (int unsigned it = 0; it < sizeof(val_init) / sizeof(val_init[0]); it++) {
+ ly_ret = type->store(UTEST_LYCTX, lysc_type, val_init[it], strlen(val_init[it]),
+ 0, LY_VALUE_XML, NULL, LYD_VALHINT_STRING, NULL, &(values[it]), NULL, &err);
+ assert_int_equal(LY_SUCCESS, ly_ret);
+ }
+
+ /* BASIC TEST; */
+ assert_int_equal(LY_SUCCESS, type->compare(&(values[0]), &(values[0])));
+ assert_int_equal(LY_SUCCESS, type->compare(&(values[0]), &(values[2])));
+ assert_int_equal(LY_ENOT, type->compare(&(values[0]), &(values[1])));
+ assert_int_equal(LY_ENOT, type->compare(&(values[1]), &(values[0])));
+ assert_int_equal(LY_ENOT, type->compare(&(values[1]), &(values[2])));
+ assert_int_equal(LY_SUCCESS, type->compare(&(values[1]), &(values[3])));
+
+ /* SAME TYPE but different node */
+ diff_type_text = "hi";
+ diff_type = ((struct lysc_node_leaf *) mod->compiled->data->next)->type;
+ ly_ret = diff_type->plugin->store(UTEST_LYCTX, diff_type, diff_type_text, strlen(diff_type_text),
+ 0, LY_VALUE_XML, NULL, LYD_VALHINT_STRING, NULL, &diff_type_val, NULL, &err);
+ assert_int_equal(LY_SUCCESS, ly_ret);
+ assert_int_equal(LY_SUCCESS, type->compare(&diff_type_val, &(values[0])));
+ assert_int_equal(LY_ENOT, type->compare(&diff_type_val, &(values[1])));
+ type->free(UTEST_LYCTX, &(diff_type_val));
+
+ /* original type */
+ diff_type_text = "hi";
+ diff_type = ((struct lysc_node_leaf *) mod->compiled->data->next->next)->type;
+ ly_ret = diff_type->plugin->store(UTEST_LYCTX, diff_type, diff_type_text, strlen(diff_type_text),
+ 0, LY_VALUE_XML, NULL, LYD_VALHINT_STRING, NULL, &diff_type_val, NULL, &err);
+ assert_int_equal(LY_SUCCESS, ly_ret);
+ assert_int_equal(LY_ENOT, type->compare(&diff_type_val, &(values[0])));
+ assert_int_equal(LY_ENOT, type->compare(&diff_type_val, &(values[1])));
+ type->free(UTEST_LYCTX, &(diff_type_val));
+
+ /* different type (UINT8) */
+ diff_type_text = "20";
+ diff_type = ((struct lysc_node_leaf *) mod->compiled->data->next->next->next)->type;
+ ly_ret = diff_type->plugin->store(UTEST_LYCTX, diff_type, diff_type_text, strlen(diff_type_text),
+ 0, LY_VALUE_XML, NULL, LYD_VALHINT_DECNUM, NULL, &diff_type_val, NULL, &err);
+ assert_int_equal(LY_SUCCESS, ly_ret);
+ assert_int_equal(LY_ENOT, type->compare(&diff_type_val, &(values[0])));
+ assert_int_equal(LY_ENOT, type->compare(&diff_type_val, &(values[1])));
+ type->free(UTEST_LYCTX, &(diff_type_val));
+
+ /* delete values */
+ for (int unsigned it = 0; it < sizeof(val_init) / sizeof(val_init[0]); it++) {
+ type->free(UTEST_LYCTX, &(values[it]));
+ }
+}
+
+static void
+test_plugin_print(void **state)
+{
+ struct ly_err_item *err = NULL;
+ struct lys_module *mod;
+ struct lyd_value values[10];
+ struct lyplg_type *type = lyplg_type_plugin_find("", NULL, ly_data_type2str[LY_TYPE_STRING]);
+ struct lysc_type *lysc_type;
+ LY_ERR ly_ret;
+
+ /* create schema. Prepare common used variables */
+ const char *schema = MODULE_CREATE_YANG("defs", "leaf port {type string;}");
+
+ UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, &mod);
+ lysc_type = ((struct lysc_node_leaf *) mod->compiled->data)->type;
+
+ /* CREATE VALUES */
+ const char *val_init[] = {"20", "0x4A", "<|>", "\""};
+
+ for (int unsigned it = 0; it < sizeof(val_init) / sizeof(val_init[0]); it++) {
+ ly_ret = type->store(UTEST_LYCTX, lysc_type, val_init[it], strlen(val_init[it]),
+ 0, LY_VALUE_XML, NULL, LYD_VALHINT_STRING, NULL, &(values[it]), NULL, &err);
+ assert_int_equal(LY_SUCCESS, ly_ret);
+ }
+
+ /* print value */
+ ly_bool dynamic = 0;
+
+ assert_string_equal("20", type->print(UTEST_LYCTX, &(values[0]), LY_VALUE_XML, NULL, &dynamic, NULL));
+ assert_string_equal("0x4A", type->print(UTEST_LYCTX, &(values[1]), LY_VALUE_XML, NULL, &dynamic, NULL));
+ assert_string_equal("<|>", type->print(UTEST_LYCTX, &(values[2]), LY_VALUE_XML, NULL, &dynamic, NULL));
+ assert_string_equal("\"", type->print(UTEST_LYCTX, &(values[3]), LY_VALUE_XML, NULL, &dynamic, NULL));
+
+ for (int unsigned it = 0; it < sizeof(val_init) / sizeof(val_init[0]); it++) {
+ type->free(UTEST_LYCTX, &(values[it]));
+ }
+}
+
+static void
+test_plugin_dup(void **state)
+{
+
+ struct ly_err_item *err = NULL;
+ struct lys_module *mod;
+ struct lyd_value values[10];
+ struct lyplg_type *type = lyplg_type_plugin_find("", NULL, ly_data_type2str[LY_TYPE_STRING]);
+ struct lysc_type *lysc_type[2];
+ const char *schema;
+ LY_ERR ly_ret;
+
+ /* create schema. Prepare common used variables */
+ schema = MODULE_CREATE_YANG("T0", "leaf port {type string;}");
+ UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, &mod);
+ lysc_type[0] = ((struct lysc_node_leaf *) mod->compiled->data)->type;
+
+ schema = MODULE_CREATE_YANG("T1",
+ "typedef my_int_type {"
+ " type string {length \"1 .. 100\";} default 20;"
+ "}"
+ "leaf port {type my_int_type; }");
+ UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, &mod);
+ lysc_type[1] = ((struct lysc_node_leaf *) mod->compiled->data)->type;
+
+ /* CREATE VALUES */
+ const char *val_init[] = {"20", "0x4A", "<\">", "0x4A"};
+
+ for (int unsigned it = 0; it < sizeof(val_init) / sizeof(val_init[0]); it++) {
+ ly_ret = type->store(UTEST_LYCTX, lysc_type[it % 2], val_init[it], strlen(val_init[it]),
+ 0, LY_VALUE_XML, NULL, LYD_VALHINT_STRING, NULL, &(values[it]), NULL, &err);
+ assert_int_equal(LY_SUCCESS, ly_ret);
+ }
+
+ /* print duplicate value */
+ struct lyd_value dup_value;
+
+ assert_int_equal(LY_SUCCESS, type->duplicate(UTEST_LYCTX, &(values[0]), &dup_value));
+ CHECK_LYD_VALUE(dup_value, STRING, "20");
+ assert_ptr_equal(dup_value.realtype, values[0].realtype);
+ type->free(UTEST_LYCTX, &dup_value);
+
+ assert_int_equal(LY_SUCCESS, type->duplicate(UTEST_LYCTX, &(values[1]), &dup_value));
+ CHECK_LYD_VALUE(dup_value, STRING, "0x4A");
+ assert_ptr_equal(dup_value.realtype, values[1].realtype);
+ type->free(UTEST_LYCTX, &dup_value);
+
+ assert_int_equal(LY_SUCCESS, type->duplicate(UTEST_LYCTX, &(values[2]), &dup_value));
+ CHECK_LYD_VALUE(dup_value, STRING, "<\">");
+ assert_ptr_equal(dup_value.realtype, values[2].realtype);
+ type->free(UTEST_LYCTX, &dup_value);
+
+ assert_int_equal(LY_SUCCESS, type->duplicate(UTEST_LYCTX, &(values[3]), &dup_value));
+ CHECK_LYD_VALUE(dup_value, STRING, "0x4A");
+ assert_ptr_equal(dup_value.realtype, values[3].realtype);
+ type->free(UTEST_LYCTX, &dup_value);
+
+ /* error tests */
+ assert_int_equal(LY_EINVAL, type->duplicate(NULL, &(values[0]), &dup_value));
+
+ for (int unsigned it = 0; it < sizeof(val_init) / sizeof(val_init[0]); it++) {
+ type->free(UTEST_LYCTX, &(values[it]));
+ }
+}
+
+int
+main(void)
+{
+ const struct CMUnitTest tests[] = {
+ UTEST(test_schema_yang),
+ UTEST(test_schema_yin),
+ UTEST(test_schema_print),
+ UTEST(test_data_xml),
+ UTEST(test_data_json),
+ UTEST(test_data_lyb),
+ UTEST(test_diff),
+ UTEST(test_print),
+
+ UTEST(test_plugin_store),
+ UTEST(test_plugin_compare),
+ UTEST(test_plugin_print),
+ UTEST(test_plugin_dup),
+ };
+
+ return cmocka_run_group_tests(tests, NULL, NULL);
+}
diff --git a/tests/utests/types/uint16.c b/tests/utests/types/uint16.c
new file mode 100644
index 0000000..7cbb014
--- /dev/null
+++ b/tests/utests/types/uint16.c
@@ -0,0 +1,75 @@
+/**
+ * @file uint16.c
+ * @author Michal Vasko <mvasko@cesnet.cz>
+ * @brief test for uint16 values
+ *
+ * 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"
+#include "plugins_internal.h"
+
+#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"
+
+#define TEST_SUCCESS_XML(MOD_NAME, DATA, TYPE, ...) \
+ { \
+ struct lyd_node *tree; \
+ const char *data = "<port xmlns=\"urn:tests:" MOD_NAME "\">" DATA "</port>"; \
+ CHECK_PARSE_LYD_PARAM(data, LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_SUCCESS, tree); \
+ CHECK_LYSC_NODE(tree->schema, NULL, 0, 0x5, 1, "port", 0, LYS_LEAF, 0, 0, 0, 0); \
+ CHECK_LYD_NODE_TERM((struct lyd_node_term *)tree, 0, 0, 0, 0, 1, TYPE, ## __VA_ARGS__); \
+ lyd_free_all(tree); \
+ }
+
+#define TEST_ERROR_XML(MOD_NAME, DATA) \
+ {\
+ struct lyd_node *tree; \
+ const char *data = "<port xmlns=\"urn:tests:" MOD_NAME "\">" DATA "</port>"; \
+ CHECK_PARSE_LYD_PARAM(data, LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_EVALID, tree); \
+ assert_null(tree); \
+ }
+
+static void
+test_data_xml(void **state)
+{
+ const char *schema;
+
+ /* xml test */
+ schema = MODULE_CREATE_YANG("defs", "leaf port {type uint16 {range 150..200;}}");
+ UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, NULL);
+
+ TEST_ERROR_XML("defs", "\n 1500 \t\n ");
+ CHECK_LOG_CTX("Unsatisfied range - value \"1500\" is out of the allowed range.",
+ "Schema location \"/defs:port\", line number 3.");
+}
+
+int
+main(void)
+{
+ const struct CMUnitTest tests[] = {
+ UTEST(test_data_xml),
+ };
+
+ return cmocka_run_group_tests(tests, NULL, NULL);
+}
diff --git a/tests/utests/types/uint32.c b/tests/utests/types/uint32.c
new file mode 100644
index 0000000..e3e6377
--- /dev/null
+++ b/tests/utests/types/uint32.c
@@ -0,0 +1,75 @@
+/**
+ * @file uint32.c
+ * @author Michal Vasko <mvasko@cesnet.cz>
+ * @brief test for uint32 values
+ *
+ * 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"
+#include "plugins_internal.h"
+
+#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"
+
+#define TEST_SUCCESS_XML(MOD_NAME, DATA, TYPE, ...) \
+ { \
+ struct lyd_node *tree; \
+ const char *data = "<port xmlns=\"urn:tests:" MOD_NAME "\">" DATA "</port>"; \
+ CHECK_PARSE_LYD_PARAM(data, LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_SUCCESS, tree); \
+ CHECK_LYSC_NODE(tree->schema, NULL, 0, 0x5, 1, "port", 0, LYS_LEAF, 0, 0, 0, 0); \
+ CHECK_LYD_NODE_TERM((struct lyd_node_term *)tree, 0, 0, 0, 0, 1, TYPE, ## __VA_ARGS__); \
+ lyd_free_all(tree); \
+ }
+
+#define TEST_ERROR_XML(MOD_NAME, DATA) \
+ {\
+ struct lyd_node *tree; \
+ const char *data = "<port xmlns=\"urn:tests:" MOD_NAME "\">" DATA "</port>"; \
+ CHECK_PARSE_LYD_PARAM(data, LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_EVALID, tree); \
+ assert_null(tree); \
+ }
+
+static void
+test_data_xml(void **state)
+{
+ const char *schema;
+
+ /* xml test */
+ schema = MODULE_CREATE_YANG("defs", "leaf port {type uint32;}");
+ UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, NULL);
+
+ TEST_ERROR_XML("defs", "-10");
+ CHECK_LOG_CTX("Value \"-10\" is out of type uint32 min/max bounds.",
+ "Schema location \"/defs:port\", line number 1.");
+}
+
+int
+main(void)
+{
+ const struct CMUnitTest tests[] = {
+ UTEST(test_data_xml),
+ };
+
+ return cmocka_run_group_tests(tests, NULL, NULL);
+}
diff --git a/tests/utests/types/uint64.c b/tests/utests/types/uint64.c
new file mode 100644
index 0000000..401c37c
--- /dev/null
+++ b/tests/utests/types/uint64.c
@@ -0,0 +1,83 @@
+/**
+ * @file uint64.c
+ * @author Michal Vasko <mvasko@cesnet.cz>
+ * @brief test for uint64 values
+ *
+ * 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"
+#include "plugins_internal.h"
+
+#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"
+
+#define TEST_SUCCESS_XML(MOD_NAME, DATA, TYPE, ...) \
+ { \
+ struct lyd_node *tree; \
+ const char *data = "<port xmlns=\"urn:tests:" MOD_NAME "\">" DATA "</port>"; \
+ CHECK_PARSE_LYD_PARAM(data, LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_SUCCESS, tree); \
+ CHECK_LYSC_NODE(tree->schema, NULL, 0, 0x5, 1, "port", 0, LYS_LEAF, 0, 0, 0, 0); \
+ CHECK_LYD_NODE_TERM((struct lyd_node_term *)tree, 0, 0, 0, 0, 1, TYPE, ## __VA_ARGS__); \
+ lyd_free_all(tree); \
+ }
+
+#define TEST_ERROR_XML(MOD_NAME, DATA) \
+ {\
+ struct lyd_node *tree; \
+ const char *data = "<port xmlns=\"urn:tests:" MOD_NAME "\">" DATA "</port>"; \
+ CHECK_PARSE_LYD_PARAM(data, LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_EVALID, tree); \
+ assert_null(tree); \
+ }
+
+static void
+test_data_xml(void **state)
+{
+ const char *schema;
+
+ /* xml test */
+ schema = MODULE_CREATE_YANG("defs", "leaf port {type uint64;}");
+ UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, NULL);
+
+ TEST_ERROR_XML("defs", "");
+ CHECK_LOG_CTX("Invalid type uint64 empty value.",
+ "Schema location \"/defs:port\", line number 1.");
+
+ TEST_ERROR_XML("defs", " ");
+ CHECK_LOG_CTX("Invalid type uint64 empty value.",
+ "Schema location \"/defs:port\", line number 1.");
+
+ TEST_ERROR_XML("defs", "10 xxx");
+ CHECK_LOG_CTX("Invalid type uint64 value \"10 xxx\".",
+ "Schema location \"/defs:port\", line number 1.");
+}
+
+int
+main(void)
+{
+ const struct CMUnitTest tests[] = {
+ UTEST(test_data_xml),
+ };
+
+ return cmocka_run_group_tests(tests, NULL, NULL);
+}
diff --git a/tests/utests/types/uint8.c b/tests/utests/types/uint8.c
new file mode 100644
index 0000000..dad4039
--- /dev/null
+++ b/tests/utests/types/uint8.c
@@ -0,0 +1,77 @@
+/**
+ * @file uint8.c
+ * @author Michal Vasko <mvasko@cesnet.cz>
+ * @brief test for uint8 values
+ *
+ * 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"
+#include "plugins_internal.h"
+
+#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"
+
+#define TEST_SUCCESS_XML(MOD_NAME, DATA, TYPE, ...) \
+ { \
+ struct lyd_node *tree; \
+ const char *data = "<port xmlns=\"urn:tests:" MOD_NAME "\">" DATA "</port>"; \
+ CHECK_PARSE_LYD_PARAM(data, LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_SUCCESS, tree); \
+ CHECK_LYSC_NODE(tree->schema, NULL, 0, 0x5, 1, "port", 0, LYS_LEAF, 0, 0, 0, 0); \
+ CHECK_LYD_NODE_TERM((struct lyd_node_term *)tree, 0, 0, 0, 0, 1, TYPE, __VA_ARGS__); \
+ lyd_free_all(tree); \
+ }
+
+#define TEST_ERROR_XML(MOD_NAME, DATA) \
+ {\
+ struct lyd_node *tree; \
+ const char *data = "<port xmlns=\"urn:tests:" MOD_NAME "\">" DATA "</port>"; \
+ CHECK_PARSE_LYD_PARAM(data, LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_EVALID, tree); \
+ assert_null(tree); \
+ }
+
+static void
+test_data_xml(void **state)
+{
+ const char *schema;
+
+ /* xml test */
+ schema = MODULE_CREATE_YANG("defs", "leaf port {type uint8 {range 150..200;}}");
+ UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, NULL);
+
+ TEST_SUCCESS_XML("defs", "\n 150 \t\n ", UINT8, "150", 150);
+
+ TEST_ERROR_XML("defs", "\n 15 \t\n ");
+ CHECK_LOG_CTX("Unsatisfied range - value \"15\" is out of the allowed range.",
+ "Schema location \"/defs:port\", line number 3.");
+}
+
+int
+main(void)
+{
+ const struct CMUnitTest tests[] = {
+ UTEST(test_data_xml),
+ };
+
+ return cmocka_run_group_tests(tests, NULL, NULL);
+}
diff --git a/tests/utests/types/union.c b/tests/utests/types/union.c
new file mode 100644
index 0000000..9a0705a
--- /dev/null
+++ b/tests/utests/types/union.c
@@ -0,0 +1,136 @@
+/**
+ * @file union.c
+ * @author Adam Piecek <piecek@cesnet.cz>
+ * @brief test for built-in enumeration type
+ *
+ * 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"
+
+/* LOCAL INCLUDE HEADERS */
+#include "libyang.h"
+#include "path.h"
+
+#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"
+
+#define TEST_SUCCESS_XML2(XML1, MOD_NAME, NAMESPACES, NODE_NAME, DATA, TYPE, ...) \
+ { \
+ struct lyd_node *tree; \
+ const char *data = XML1 "<" NODE_NAME " xmlns=\"urn:tests:" MOD_NAME "\" " NAMESPACES ">" DATA "</" NODE_NAME ">"; \
+ CHECK_PARSE_LYD_PARAM(data, LYD_XML, LYD_PARSE_STRICT, LYD_VALIDATE_PRESENT, LY_SUCCESS, tree); \
+ CHECK_LYD_NODE_TERM((struct lyd_node_term *)tree, 0, 0, 1, 0, 1, TYPE, __VA_ARGS__); \
+ lyd_free_all(tree); \
+ }
+
+#define TEST_ERROR_XML2(XML1, MOD_NAME, NAMESPACES, NODE_NAME, DATA, RET) \
+ {\
+ struct lyd_node *tree; \
+ const char *data = XML1 "<" NODE_NAME " xmlns=\"urn:tests:" MOD_NAME "\" " NAMESPACES ">" DATA "</" NODE_NAME ">"; \
+ CHECK_PARSE_LYD_PARAM(data, LYD_XML, LYD_PARSE_STRICT, LYD_VALIDATE_PRESENT, RET, tree); \
+ assert_null(tree); \
+ }
+
+#define TEST_SUCCESS_LYB(MOD_NAME, NODE_NAME, DATA) \
+ { \
+ struct lyd_node *tree_1; \
+ struct lyd_node *tree_2; \
+ char *xml_out, *data; \
+ data = "<" NODE_NAME " xmlns=\"urn:tests:" MOD_NAME "\">" DATA "</" NODE_NAME ">"; \
+ CHECK_PARSE_LYD_PARAM(data, LYD_XML, LYD_PARSE_ONLY | LYD_PARSE_STRICT, 0, LY_SUCCESS, tree_1); \
+ assert_int_equal(lyd_print_mem(&xml_out, tree_1, LYD_LYB, LYD_PRINT_WITHSIBLINGS), 0); \
+ assert_int_equal(LY_SUCCESS, lyd_parse_data_mem(UTEST_LYCTX, xml_out, LYD_LYB, LYD_PARSE_ONLY | LYD_PARSE_STRICT, 0, &tree_2)); \
+ assert_non_null(tree_2); \
+ CHECK_LYD(tree_1, tree_2); \
+ free(xml_out); \
+ lyd_free_all(tree_1); \
+ lyd_free_all(tree_2); \
+ }
+
+static void
+test_data_xml(void **state)
+{
+ const char *schema;
+ const enum ly_path_pred_type val1[] = {LY_PATH_PREDTYPE_LEAFLIST};
+
+ /* xml test */
+ schema = MODULE_CREATE_YANG("defs", "identity ident1; identity ident2 {base ident1;}"
+ "leaf un1 {type union {"
+ " type leafref {path /int8; require-instance true;}"
+ " type leafref {path /int64; require-instance true;}"
+ " type union { type identityref {base ident1;} type instance-identifier {require-instance true;} }"
+ " type string {length 1..20;}}}"
+ "leaf int8 {type int8 {range 10..20;}}"
+ "leaf int64 {type int64;}"
+ "leaf-list llist {type string;}");
+ UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, NULL);
+
+ TEST_SUCCESS_XML2("<int8 xmlns=\"urn:tests:defs\">12</int8>",
+ "defs", "", "un1", "12", UNION, "12", INT8, "12", 12);
+
+ TEST_SUCCESS_XML2("<int8 xmlns=\"urn:tests:defs\">12</int8>",
+ "defs", "", "un1", "2", UNION, "2", STRING, "2");
+
+ TEST_SUCCESS_XML2("<int8 xmlns=\"urn:tests:defs\">10</int8>",
+ "defs", "xmlns:x=\"urn:tests:defs\"", "un1", "x:ident2", UNION, "defs:ident2", IDENT, "defs:ident2", "ident2");
+
+ TEST_SUCCESS_XML2("<int8 xmlns=\"urn:tests:defs\">10</int8>",
+ "defs", "xmlns:x=\"urn:tests:defs\"", "un1", "x:ident55", UNION, "x:ident55", STRING, "x:ident55");
+
+ TEST_SUCCESS_XML2("<llist xmlns=\"urn:tests:defs\">x</llist>"
+ "<llist xmlns=\"urn:tests:defs\">y</llist>",
+ "defs", "xmlns:x=\"urn:tests:defs\"", "un1", "/x:llist[.='y']", UNION, "/defs:llist[.='y']",
+ INST, "/defs:llist[.='y']", val1);
+
+ TEST_SUCCESS_XML2("<llist xmlns=\"urn:tests:defs\">x</llist>"
+ "<llist xmlns=\"urn:tests:defs\">y</llist>",
+ "defs", "xmlns:x=\"urn:tests:defs\"", "un1", "/x:llist[3]", UNION, "/x:llist[3]",
+ STRING, "/x:llist[3]");
+
+ /* invalid value */
+ TEST_ERROR_XML2("",
+ "defs", "", "un1", "123456789012345678901", LY_EVALID);
+ CHECK_LOG_CTX("Invalid union value \"123456789012345678901\" - no matching subtype found.",
+ "Schema location \"/defs:un1\", line number 1.");
+}
+
+static void
+test_plugin_lyb(void **state)
+{
+ const char *schema;
+
+ schema = MODULE_CREATE_YANG("lyb",
+ "leaf int8 {type int8 {range 10..20;}}"
+ "leaf un1 {type union {"
+ " type leafref {path /int8; require-instance true;}"
+ " type string;}}");
+ UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, NULL);
+ TEST_SUCCESS_LYB("lyb", "un1", "12");
+ TEST_SUCCESS_LYB("lyb", "un1", "some_string");
+ TEST_SUCCESS_LYB("lyb", "un1", "");
+}
+
+int
+main(void)
+{
+ const struct CMUnitTest tests[] = {
+ UTEST(test_data_xml),
+ UTEST(test_plugin_lyb),
+ };
+
+ return cmocka_run_group_tests(tests, NULL, NULL);
+}
diff --git a/tests/utests/types/yang_types.c b/tests/utests/types/yang_types.c
new file mode 100644
index 0000000..6ce7671
--- /dev/null
+++ b/tests/utests/types/yang_types.c
@@ -0,0 +1,223 @@
+/**
+ * @file yang_types.c
+ * @author Michal Vaško <mvasko@cesnet.cz>
+ * @brief test for ietf-yang-types values
+ *
+ * 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"
+
+#include <stdlib.h>
+
+#include "compat.h"
+#include "libyang.h"
+
+#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" \
+ " import ietf-yang-types {\n" \
+ " prefix yang;\n" \
+ " }\n" \
+ NODES \
+ "}\n"
+
+#define TEST_SUCCESS_XML(MOD_NAME, NODE_NAME, DATA, TYPE, ...) \
+ { \
+ struct lyd_node *tree; \
+ const char *data = "<" NODE_NAME " xmlns=\"urn:tests:" MOD_NAME "\">" DATA "</" NODE_NAME ">"; \
+ CHECK_PARSE_LYD_PARAM(data, LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_SUCCESS, tree); \
+ CHECK_LYD_NODE_TERM((struct lyd_node_term *)tree, 0, 0, 0, 0, 1, TYPE, __VA_ARGS__); \
+ lyd_free_all(tree); \
+ }
+
+#define TEST_ERROR_XML(MOD_NAME, NODE_NAME, DATA) \
+ {\
+ struct lyd_node *tree; \
+ const char *data = "<" NODE_NAME " xmlns=\"urn:tests:" MOD_NAME "\">" DATA "</" NODE_NAME ">"; \
+ CHECK_PARSE_LYD_PARAM(data, LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_EVALID, tree); \
+ assert_null(tree); \
+ }
+
+#define TEST_SUCCESS_LYB(MOD_NAME, NODE_NAME, DATA) \
+ { \
+ struct lyd_node *tree_1; \
+ struct lyd_node *tree_2; \
+ char *xml_out, *data; \
+ data = "<" NODE_NAME " xmlns=\"urn:tests:" MOD_NAME "\">" DATA "</" NODE_NAME ">"; \
+ CHECK_PARSE_LYD_PARAM(data, LYD_XML, LYD_PARSE_ONLY | LYD_PARSE_STRICT, 0, LY_SUCCESS, tree_1); \
+ assert_int_equal(lyd_print_mem(&xml_out, tree_1, LYD_LYB, LYD_PRINT_WITHSIBLINGS), 0); \
+ assert_int_equal(LY_SUCCESS, lyd_parse_data_mem(UTEST_LYCTX, xml_out, LYD_LYB, LYD_PARSE_ONLY | LYD_PARSE_STRICT, 0, &tree_2)); \
+ assert_non_null(tree_2); \
+ CHECK_LYD(tree_1, tree_2); \
+ free(xml_out); \
+ lyd_free_all(tree_1); \
+ lyd_free_all(tree_2); \
+ }
+
+static void
+test_data_xml(void **state)
+{
+ const char *schema;
+
+ /* xml test */
+ schema = MODULE_CREATE_YANG("a",
+ "leaf l {type yang:date-and-time;}"
+ "leaf l2 {type yang:xpath1.0;}");
+ UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, NULL);
+ schema = MODULE_CREATE_YANG("b",
+ "");
+ UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, NULL);
+
+ /* date-and-time */
+#if defined (HAVE_TM_GMTOFF) && defined (HAVE_TIME_H_TIMEZONE)
+ TEST_SUCCESS_XML("a", "l", "2005-05-25T23:15:15.88888Z", STRING, "2005-05-25T21:15:15.88888-02:00");
+ TEST_SUCCESS_XML("a", "l", "2005-05-31T23:15:15-08:59", STRING, "2005-06-01T06:14:15-02:00");
+ TEST_SUCCESS_XML("a", "l", "2005-05-31T23:15:15-23:00", STRING, "2005-06-01T20:15:15-02:00");
+
+ /* test 1 second before epoch (mktime returns -1, but it is a correct value), with and without DST */
+ TEST_SUCCESS_XML("a", "l", "1970-01-01T00:59:59-02:00", STRING, "1970-01-01T00:59:59-02:00");
+ TEST_SUCCESS_XML("a", "l", "1969-12-31T23:59:59-02:00", STRING, "1969-12-31T23:59:59-02:00");
+
+ /* canonize */
+ TEST_SUCCESS_XML("a", "l", "2005-02-29T23:15:15-02:00", STRING, "2005-03-01T23:15:15-02:00");
+
+ /* fractional hours */
+ TEST_SUCCESS_XML("a", "l", "2005-05-25T23:15:15.88888+04:30", STRING, "2005-05-25T16:45:15.88888-02:00");
+#else
+ /* Tests run with a TZ offset of +02:00, but this platform cannot represent that in time_t,
+ * so libyang always returns unspecified TZ. */
+ TEST_SUCCESS_XML("a", "l", "2005-05-25T23:15:15.88888Z", STRING, "2005-05-25T23:15:15.88888-00:00");
+ TEST_SUCCESS_XML("a", "l", "2005-05-31T23:15:15-08:59", STRING, "2005-06-01T08:14:15-00:00");
+ TEST_SUCCESS_XML("a", "l", "2005-05-31T23:15:15-23:00", STRING, "2005-06-01T22:15:15-00:00");
+
+ /* test 1 second before epoch (mktime returns -1, but it is a correct value), with and without DST */
+ TEST_SUCCESS_XML("a", "l", "1970-01-01T00:59:59-02:00", STRING, "1970-01-01T02:59:59-00:00");
+ TEST_SUCCESS_XML("a", "l", "1969-12-31T23:59:59-02:00", STRING, "1970-01-01T01:59:59-00:00");
+
+ /* canonize */
+ TEST_SUCCESS_XML("a", "l", "2005-02-29T23:15:15-02:00", STRING, "2005-03-02T01:15:15-00:00");
+
+ /* fractional hours */
+ TEST_SUCCESS_XML("a", "l", "2005-05-25T23:15:15.88888+04:30", STRING, "2005-05-25T18:45:15.88888-00:00");
+#endif
+
+ /* unknown timezone -- timezone conversion MUST NOT happen */
+ TEST_SUCCESS_XML("a", "l", "2017-02-01T00:00:00-00:00", STRING, "2017-02-01T00:00:00-00:00");
+ TEST_SUCCESS_XML("a", "l", "2021-02-29T00:00:00-00:00", STRING, "2021-03-01T00:00:00-00:00");
+
+ TEST_ERROR_XML("a", "l", "2005-05-31T23:15:15.-08:00");
+ CHECK_LOG_CTX("Unsatisfied pattern - \"2005-05-31T23:15:15.-08:00\" does not conform to "
+ "\"\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(\\.\\d+)?(Z|[\\+\\-]\\d{2}:\\d{2})\".",
+ "Schema location \"/a:l\", line number 1.");
+
+ /* xpath1.0 */
+ TEST_SUCCESS_XML("a\" xmlns:aa=\"urn:tests:a", "l2", "/aa:l2[. = '4']", STRING, "/a:l2[.='4']");
+ TEST_SUCCESS_XML("a\" xmlns:yl=\"urn:ietf:params:xml:ns:yang:ietf-yang-library\" "
+ "xmlns:ds=\"urn:ietf:params:xml:ns:yang:ietf-datastores", "l2",
+ "/yl:yang-library/yl:datastore/yl:name = 'ds:running'", STRING,
+ "/ietf-yang-library:yang-library/datastore/name='ietf-datastores:running'");
+ TEST_SUCCESS_XML("a\" xmlns:a1=\"urn:tests:a\" xmlns:a2=\"urn:tests:a\" xmlns:bb=\"urn:tests:b", "l2",
+ "/a1:node1/a2:node2[a1:node3/bb:node4]/bb:node5 | bb:node6 and (bb:node7)", STRING,
+ "/a:node1/node2[node3/b:node4]/b:node5 | b:node6 and (b:node7)");
+ TEST_SUCCESS_XML("a", "l2", "/l2[. = '4']", STRING, "/l2[.='4']");
+
+ TEST_ERROR_XML("a", "l2", "/a:l2[. = '4']");
+ CHECK_LOG_CTX("Failed to resolve prefix \"a\".", "Schema location \"/a:l2\", line number 1.");
+ TEST_ERROR_XML("a\" xmlns:yl=\"urn:ietf:params:xml:ns:yang:ietf-yang-library", "l2",
+ "/yl:yang-library/yl:datastore/yl::name");
+ CHECK_LOG_CTX("Storing value failed.", "Schema location \"/a:l2\", line number 1.",
+ "Invalid character 'y'[31] of expression '/yl:yang-library/yl:datastore/yl::name'.",
+ "Schema location \"/a:l2\", line number 1.");
+}
+
+static void
+test_print(void **state)
+{
+ const char *schema = MODULE_CREATE_YANG("a", "leaf l {type yang:xpath1.0;}");
+ const char *data, *expected;
+ struct lyd_node *tree;
+
+ UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, NULL);
+
+ /* XML data */
+ data = "<l xmlns=\"urn:tests:a\" xmlns:aa=\"urn:tests:a\">/aa:l[. = '/aa:l']</l>";
+ CHECK_PARSE_LYD_PARAM(data, LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_SUCCESS, tree);
+
+ /* XML print */
+ expected = "<l xmlns=\"urn:tests:a\" xmlns:pref=\"urn:tests:a\">/pref:l[.='/pref:l']</l>";
+ CHECK_LYD_STRING_PARAM(tree, expected, LYD_XML, LYD_PRINT_SHRINK | LYD_PRINT_WITHSIBLINGS);
+
+ /* JSON print */
+ expected = "{\"a:l\":\"/a:l[.='/a:l']\"}";
+ CHECK_LYD_STRING_PARAM(tree, expected, LYD_JSON, LYD_PRINT_SHRINK | LYD_PRINT_WITHSIBLINGS);
+
+ lyd_free_tree(tree);
+
+ /* JSON data */
+ data = "{\"a:l\":\"/a:l/k/m[. = '/a:l']\"}";
+ CHECK_PARSE_LYD_PARAM(data, LYD_JSON, 0, LYD_VALIDATE_PRESENT, LY_SUCCESS, tree);
+
+ /* XML print */
+ expected = "<l xmlns=\"urn:tests:a\" xmlns:pref=\"urn:tests:a\">/pref:l/pref:k/pref:m[.='/pref:l']</l>";
+ CHECK_LYD_STRING_PARAM(tree, expected, LYD_XML, LYD_PRINT_SHRINK | LYD_PRINT_WITHSIBLINGS);
+
+ /* JSON print */
+ expected = "{\"a:l\":\"/a:l/k/m[. = '/a:l']\"}";
+ CHECK_LYD_STRING_PARAM(tree, expected, LYD_JSON, LYD_PRINT_SHRINK | LYD_PRINT_WITHSIBLINGS);
+
+ lyd_free_tree(tree);
+}
+
+static void
+test_lyb(void **state)
+{
+ const char *schema;
+
+ /* xml test */
+ schema = MODULE_CREATE_YANG("a",
+ "leaf l {type yang:date-and-time;}"
+ "leaf l2 {type yang:xpath1.0;}");
+ UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, NULL);
+
+ /* date-and-time */
+ TEST_SUCCESS_LYB("a", "l", "2005-05-25T23:15:15.88888Z");
+ TEST_SUCCESS_LYB("a", "l", "2005-05-31T23:15:15-08:59");
+ TEST_SUCCESS_LYB("a", "l", "2005-05-01T20:15:15-00:00");
+
+ /* xpath1.0 */
+ TEST_SUCCESS_LYB("a\" xmlns:aa=\"urn:tests:a", "l2", "/aa:l2[. = '4']");
+}
+
+int
+main(void)
+{
+ const struct CMUnitTest tests[] = {
+ UTEST(test_data_xml),
+ UTEST(test_print),
+ UTEST(test_lyb),
+ };
+
+ return cmocka_run_group_tests(tests, NULL, NULL);
+}