schema compilation CHANGE partial support for types
- resolving types
- support for binary type
- support for range/length restriction of the type, but missing checking
that the derived type strictly narrows the defined range/length
diff --git a/tests/src/test_parser_yang.c b/tests/src/test_parser_yang.c
index f50e565..674ba2f 100644
--- a/tests/src/test_parser_yang.c
+++ b/tests/src/test_parser_yang.c
@@ -909,7 +909,6 @@
test_identity(void **state)
{
(void) state; /* unused */
- int dict = 1; /* magic variable for FREE macros */
struct ly_parser_ctx ctx;
struct lysp_module *mod = NULL;
@@ -960,7 +959,6 @@
test_feature(void **state)
{
(void) state; /* unused */
- int dict = 1; /* magic variable for FREE macros */
struct ly_parser_ctx ctx;
struct lysp_module *mod = NULL;
@@ -1011,7 +1009,6 @@
test_deviation(void **state)
{
(void) state; /* unused */
- int dict = 1; /* magic variable for FREE macros */
struct ly_parser_ctx ctx;
struct lysp_deviation *d = NULL;
@@ -1074,7 +1071,7 @@
/* invalid cardinality */
#define TEST_DUP(TYPE, MEMBER, VALUE1, VALUE2) \
TEST_DUP_GENERIC(TYPE" {", MEMBER, VALUE1, VALUE2, parse_deviate, \
- &d, "1", lysp_deviate_free(ctx.ctx, d, 1); free(d); d = NULL)
+ &d, "1", lysp_deviate_free(ctx.ctx, d); free(d); d = NULL)
TEST_DUP("add", "config", "true", "false");
TEST_DUP("replace", "default", "int8", "uint8");
@@ -1089,29 +1086,29 @@
assert_int_equal(LY_SUCCESS, parse_deviate(&ctx, &str, &d));
assert_non_null(d);
assert_string_equal(" ...", str);
- lysp_deviate_free(ctx.ctx, d, 1); free(d); d = NULL;
+ lysp_deviate_free(ctx.ctx, d); free(d); d = NULL;
str = " add {units meters; must 1; must 2; unique x; unique y; default a; default b; config true; mandatory true; min-elements 1; max-elements 2; prefix:ext;} ...";
assert_int_equal(LY_SUCCESS, parse_deviate(&ctx, &str, &d));
assert_non_null(d);
assert_string_equal(" ...", str);
- lysp_deviate_free(ctx.ctx, d, 1); free(d); d = NULL;
+ lysp_deviate_free(ctx.ctx, d); free(d); d = NULL;
str = " delete {units meters; must 1; must 2; unique x; unique y; default a; default b; prefix:ext;} ...";
assert_int_equal(LY_SUCCESS, parse_deviate(&ctx, &str, &d));
assert_non_null(d);
assert_string_equal(" ...", str);
- lysp_deviate_free(ctx.ctx, d, 1); free(d); d = NULL;
+ lysp_deviate_free(ctx.ctx, d); free(d); d = NULL;
str = " replace {type string; units meters; default a; config true; mandatory true; min-elements 1; max-elements 2; prefix:ext;} ...";
assert_int_equal(LY_SUCCESS, parse_deviate(&ctx, &str, &d));
assert_non_null(d);
assert_string_equal(" ...", str);
- lysp_deviate_free(ctx.ctx, d, 1); free(d); d = NULL;
+ lysp_deviate_free(ctx.ctx, d); free(d); d = NULL;
/* invalid substatements */
#define TEST_NOT_SUP(DEV, STMT, VALUE) \
str = " "DEV" {"STMT" "VALUE";}..."; \
assert_int_equal(LY_EVALID, parse_deviate(&ctx, &str, &d)); \
logbuf_assert("Deviate \""DEV"\" does not support keyword \""STMT"\". Line number 1."); \
- lysp_deviate_free(ctx.ctx, d, 1); free(d); d = NULL
+ lysp_deviate_free(ctx.ctx, d); free(d); d = NULL
TEST_NOT_SUP("not-supported", "units", "meters");
TEST_NOT_SUP("not-supported", "must", "1");
@@ -1162,7 +1159,7 @@
str = "cont {" MEMBER" "VALUE1";"MEMBER" "VALUE2";} ..."; \
assert_int_equal(LY_EVALID, parse_container(&ctx, &str, NULL, (struct lysp_node**)&c)); \
logbuf_assert("Duplicate keyword \""MEMBER"\". Line number 1."); \
- lysp_node_free(ctx.ctx, (struct lysp_node*)c, 1); c = NULL;
+ lysp_node_free(ctx.ctx, (struct lysp_node*)c); c = NULL;
TEST_DUP("config", "true", "false");
TEST_DUP("description", "text1", "text2");
@@ -1193,17 +1190,17 @@
assert_null(c->next);
assert_int_equal(LYS_CONFIG_R | LYS_STATUS_CURR, c->flags);
ly_set_erase(&ctx.tpdfs_nodes, NULL);
- lysp_node_free(ctx.ctx, (struct lysp_node*)c, 1); c = NULL;
+ lysp_node_free(ctx.ctx, (struct lysp_node*)c); c = NULL;
/* invalid */
str = " cont {augment /root;} ...";
assert_int_equal(LY_EVALID, parse_container(&ctx, &str, NULL, (struct lysp_node**)&c));
logbuf_assert("Invalid keyword \"augment\" as a child of \"container\". Line number 1.");
- lysp_node_free(ctx.ctx, (struct lysp_node*)c, 1); c = NULL;
+ lysp_node_free(ctx.ctx, (struct lysp_node*)c); c = NULL;
str = " cont {nonsence true;} ...";
assert_int_equal(LY_EVALID, parse_container(&ctx, &str, NULL, (struct lysp_node**)&c));
logbuf_assert("Invalid character sequence \"nonsence\", expected a keyword. Line number 1.");
- lysp_node_free(ctx.ctx, (struct lysp_node*)c, 1); c = NULL;
+ lysp_node_free(ctx.ctx, (struct lysp_node*)c); c = NULL;
ly_ctx_destroy(ctx.ctx, NULL);
}
diff --git a/tests/src/test_tree_schema_compile.c b/tests/src/test_tree_schema_compile.c
index 29ba61d..b900800 100644
--- a/tests/src/test_tree_schema_compile.c
+++ b/tests/src/test_tree_schema_compile.c
@@ -55,6 +55,18 @@
return 0;
}
+static int
+logger_teardown(void **state)
+{
+ (void) state; /* unused */
+#if ENABLE_LOGGER_CHECKING
+ if (*state) {
+ fprintf(stderr, "%s\n", logbuf);
+ }
+#endif
+ return 0;
+}
+
void
logbuf_clean(void)
{
@@ -349,13 +361,123 @@
ly_ctx_destroy(ctx, NULL);
}
+static void
+test_node_type_length_range(void **state)
+{
+ *state = test_node_type_length_range;
+
+ struct ly_ctx *ctx;
+ struct lys_module *mod;
+ struct lysc_type *type;
+
+ assert_int_equal(LY_SUCCESS, ly_ctx_new(NULL, LY_CTX_DISABLE_SEARCHDIRS, &ctx));
+
+ assert_non_null(mod = lys_parse_mem(ctx, "module a {namespace urn:a;prefix a;leaf l {type binary {length min;}}}", LYS_IN_YANG));
+ assert_int_equal(LY_SUCCESS, lys_compile(mod, 0));
+ type = ((struct lysc_node_leaf*)mod->compiled->data)->type;
+ assert_non_null(type);
+ assert_non_null(((struct lysc_type_bin*)type)->length);
+ assert_non_null(((struct lysc_type_bin*)type)->length->parts);
+ assert_int_equal(1, LY_ARRAY_SIZE(((struct lysc_type_bin*)type)->length->parts));
+ assert_int_equal(0, ((struct lysc_type_bin*)type)->length->parts[0].min_u64);
+ assert_int_equal(0, ((struct lysc_type_bin*)type)->length->parts[0].max_u64);
+
+ assert_non_null(mod = lys_parse_mem(ctx, "module b {namespace urn:b;prefix b;leaf l {type binary {length max;}}}", LYS_IN_YANG));
+ assert_int_equal(LY_SUCCESS, lys_compile(mod, 0));
+ type = ((struct lysc_node_leaf*)mod->compiled->data)->type;
+ assert_non_null(type);
+ assert_non_null(((struct lysc_type_bin*)type)->length);
+ assert_non_null(((struct lysc_type_bin*)type)->length->parts);
+ assert_int_equal(1, LY_ARRAY_SIZE(((struct lysc_type_bin*)type)->length->parts));
+ assert_int_equal(__UINT64_C(18446744073709551615), ((struct lysc_type_bin*)type)->length->parts[0].min_u64);
+ assert_int_equal(__UINT64_C(18446744073709551615), ((struct lysc_type_bin*)type)->length->parts[0].max_u64);
+
+ assert_non_null(mod = lys_parse_mem(ctx, "module c {namespace urn:c;prefix c;leaf l {type binary {length min..max;}}}", LYS_IN_YANG));
+ assert_int_equal(LY_SUCCESS, lys_compile(mod, 0));
+ type = ((struct lysc_node_leaf*)mod->compiled->data)->type;
+ assert_non_null(type);
+ assert_non_null(((struct lysc_type_bin*)type)->length);
+ assert_non_null(((struct lysc_type_bin*)type)->length->parts);
+ assert_int_equal(1, LY_ARRAY_SIZE(((struct lysc_type_bin*)type)->length->parts));
+ assert_int_equal(0, ((struct lysc_type_bin*)type)->length->parts[0].min_u64);
+ assert_int_equal(__UINT64_C(18446744073709551615), ((struct lysc_type_bin*)type)->length->parts[0].max_u64);
+
+ assert_non_null(mod = lys_parse_mem(ctx, "module d {namespace urn:d;prefix d;leaf l {type binary {length 5;}}}", LYS_IN_YANG));
+ assert_int_equal(LY_SUCCESS, lys_compile(mod, 0));
+ type = ((struct lysc_node_leaf*)mod->compiled->data)->type;
+ assert_non_null(type);
+ assert_non_null(((struct lysc_type_bin*)type)->length);
+ assert_non_null(((struct lysc_type_bin*)type)->length->parts);
+ assert_int_equal(1, LY_ARRAY_SIZE(((struct lysc_type_bin*)type)->length->parts));
+ assert_int_equal(5, ((struct lysc_type_bin*)type)->length->parts[0].min_u64);
+ assert_int_equal(5, ((struct lysc_type_bin*)type)->length->parts[0].max_u64);
+
+ assert_non_null(mod = lys_parse_mem(ctx, "module e {namespace urn:e;prefix e;leaf l {type binary {length 1..10;}}}", LYS_IN_YANG));
+ assert_int_equal(LY_SUCCESS, lys_compile(mod, 0));
+ type = ((struct lysc_node_leaf*)mod->compiled->data)->type;
+ assert_non_null(type);
+ assert_non_null(((struct lysc_type_bin*)type)->length);
+ assert_non_null(((struct lysc_type_bin*)type)->length->parts);
+ assert_int_equal(1, LY_ARRAY_SIZE(((struct lysc_type_bin*)type)->length->parts));
+ assert_int_equal(1, ((struct lysc_type_bin*)type)->length->parts[0].min_u64);
+ assert_int_equal(10, ((struct lysc_type_bin*)type)->length->parts[0].max_u64);
+
+ assert_non_null(mod = lys_parse_mem(ctx, "module f {namespace urn:f;prefix f;leaf l {type binary {length 1..10|20..30;}}}", LYS_IN_YANG));
+ assert_int_equal(LY_SUCCESS, lys_compile(mod, 0));
+ type = ((struct lysc_node_leaf*)mod->compiled->data)->type;
+ assert_non_null(type);
+ assert_non_null(((struct lysc_type_bin*)type)->length);
+ assert_non_null(((struct lysc_type_bin*)type)->length->parts);
+ assert_int_equal(2, LY_ARRAY_SIZE(((struct lysc_type_bin*)type)->length->parts));
+ assert_int_equal(1, ((struct lysc_type_bin*)type)->length->parts[0].min_u64);
+ assert_int_equal(10, ((struct lysc_type_bin*)type)->length->parts[0].max_u64);
+ assert_int_equal(20, ((struct lysc_type_bin*)type)->length->parts[1].min_u64);
+ assert_int_equal(30, ((struct lysc_type_bin*)type)->length->parts[1].max_u64);
+
+ assert_non_null(mod = lys_parse_mem(ctx, "module g {namespace urn:g;prefix g;leaf l {type binary {length \"16 | 32\";}}}", LYS_IN_YANG));
+ assert_int_equal(LY_SUCCESS, lys_compile(mod, 0));
+ type = ((struct lysc_node_leaf*)mod->compiled->data)->type;
+ assert_non_null(type);
+ assert_non_null(((struct lysc_type_bin*)type)->length);
+ assert_non_null(((struct lysc_type_bin*)type)->length->parts);
+ assert_int_equal(2, LY_ARRAY_SIZE(((struct lysc_type_bin*)type)->length->parts));
+ assert_int_equal(16, ((struct lysc_type_bin*)type)->length->parts[0].min_u64);
+ assert_int_equal(16, ((struct lysc_type_bin*)type)->length->parts[0].max_u64);
+ assert_int_equal(32, ((struct lysc_type_bin*)type)->length->parts[1].min_u64);
+ assert_int_equal(32, ((struct lysc_type_bin*)type)->length->parts[1].max_u64);
+
+ /* invalid values */
+ assert_non_null(mod = lys_parse_mem(ctx, "module aa {namespace urn:aa;prefix aa;leaf l {type binary {length -10;}}}", LYS_IN_YANG));
+ assert_int_equal(LY_EVALID, lys_compile(mod, 0));
+ logbuf_assert("Invalid length restriction - value \"-10\" does not fit the type limitations.");
+ assert_non_null(mod = lys_parse_mem(ctx, "module bb {namespace urn:bb;prefix bb;leaf l {type binary {length 18446744073709551616;}}}", LYS_IN_YANG));
+ assert_int_equal(LY_EVALID, lys_compile(mod, 0));
+ logbuf_assert("Invalid length restriction - invalid value \"18446744073709551616\".");
+ assert_non_null(mod = lys_parse_mem(ctx, "module cc {namespace urn:cc;prefix cc;leaf l {type binary {length \"max .. 10\";}}}", LYS_IN_YANG));
+ assert_int_equal(LY_EVALID, lys_compile(mod, 0));
+ logbuf_assert("Invalid length restriction - unexpected data after max keyword (.. 10).");
+ assert_non_null(mod = lys_parse_mem(ctx, "module dd {namespace urn:dd;prefix dd;leaf l {type binary {length 50..10;}}}", LYS_IN_YANG));
+ assert_int_equal(LY_EVALID, lys_compile(mod, 0));
+ logbuf_assert("Invalid length restriction - values are not in ascending order (10).");
+ assert_non_null(mod = lys_parse_mem(ctx, "module ee {namespace urn:ee;prefix ee;leaf l {type binary {length \"50 | 10\";}}}", LYS_IN_YANG));
+ assert_int_equal(LY_EVALID, lys_compile(mod, 0));
+ logbuf_assert("Invalid length restriction - values are not in ascending order (10).");
+ assert_non_null(mod = lys_parse_mem(ctx, "module ff {namespace urn:ff;prefix ff;leaf l {type binary {length \"x\";}}}", LYS_IN_YANG));
+ assert_int_equal(LY_EVALID, lys_compile(mod, 0));
+ logbuf_assert("Invalid length restriction - unexpected data (x).");
+
+ *state = NULL;
+ ly_ctx_destroy(ctx, NULL);
+}
+
int main(void)
{
const struct CMUnitTest tests[] = {
- cmocka_unit_test_setup(test_module, logger_setup),
- cmocka_unit_test_setup(test_feature, logger_setup),
- cmocka_unit_test_setup(test_identity, logger_setup),
- cmocka_unit_test_setup(test_node_container, logger_setup),
+ cmocka_unit_test_setup_teardown(test_module, logger_setup, logger_teardown),
+ cmocka_unit_test_setup_teardown(test_feature, logger_setup, logger_teardown),
+ cmocka_unit_test_setup_teardown(test_identity, logger_setup, logger_teardown),
+ cmocka_unit_test_setup_teardown(test_node_type_length_range, logger_setup, logger_teardown),
+ cmocka_unit_test_setup_teardown(test_node_container, logger_setup, logger_teardown),
};
return cmocka_run_group_tests(tests, NULL, NULL);