blob: 8ebe67bb0276088f22bef190889438550316b23e [file] [log] [blame]
Radek Krejciad5963b2019-09-06 16:03:05 +02001/*
2 * @file test_metadata.c
3 * @author: Radek Krejci <rkrejci@cesnet.cz>
4 * @brief unit tests for Metadata extension (annotation) support
5 *
Radek Iša56ca9e42020-09-08 18:42:00 +02006 * Copyright (c) 2019-2020 CESNET, z.s.p.o.
Radek Krejciad5963b2019-09-06 16:03:05 +02007 *
8 * This source code is licensed under BSD 3-Clause License (the "License").
9 * You may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
11 *
12 * https://opensource.org/licenses/BSD-3-Clause
13 */
Radek Iša56ca9e42020-09-08 18:42:00 +020014#define _UTEST_MAIN_
Radek Krejcib4ac5a92020-11-23 17:54:33 +010015#include "utests.h"
Radek Krejciad5963b2019-09-06 16:03:05 +020016
Radek Krejci70593c12020-06-13 20:48:09 +020017#include "libyang.h"
Radek Krejci1b2eef82021-02-17 11:17:27 +010018#include "plugins_exts.h"
Radek Krejcif1ca0ac2021-04-12 16:00:06 +020019#include "plugins_exts/metadata.h"
Radek Krejciad5963b2019-09-06 16:03:05 +020020
Radek Krejciad5963b2019-09-06 16:03:05 +020021static void
22test_yang(void **state)
23{
Michal Vasko4de7d072021-07-09 09:13:18 +020024 struct lys_module *mod;
Radek Krejciad5963b2019-09-06 16:03:05 +020025 struct lysc_ext_instance *e;
Radek Krejciad5963b2019-09-06 16:03:05 +020026
27 const char *data = "module a {yang-version 1.1; namespace urn:tests:extensions:metadata:a; prefix a;"
28 "import ietf-yang-metadata {prefix md;}"
29 "feature f;"
30 "md:annotation x {"
31 " description \"test\";"
32 " if-feature f;"
33 " reference \"test\";"
34 " status \"current\";"
35 " type uint8;"
36 " units meters;"
37 "}}";
Michal Vasko7b1ad1a2020-11-02 15:41:27 +010038 const char *feats[] = {"f", NULL};
Radek Krejcib4ac5a92020-11-23 17:54:33 +010039
Radek Iša56ca9e42020-09-08 18:42:00 +020040 UTEST_ADD_MODULE(data, LYS_IN_YANG, feats, &mod);
Michal Vaskofd69e1d2020-07-03 11:57:17 +020041 assert_int_equal(1, LY_ARRAY_COUNT(mod->compiled->exts));
Radek Krejciad5963b2019-09-06 16:03:05 +020042 e = &mod->compiled->exts[0];
Radek Krejci1b2eef82021-02-17 11:17:27 +010043 assert_non_null(e->data);
44 assert_non_null(e->substmts);
45 assert_string_equal("meters", *(const char **)e->substmts[ANNOTATION_SUBSTMT_UNITS].storage);
Radek Krejciad5963b2019-09-06 16:03:05 +020046
47 /* invalid */
48 /* missing mandatory type substatement */
49 data = "module aa {yang-version 1.1; namespace urn:tests:extensions:metadata:aa; prefix aa;"
50 "import ietf-yang-metadata {prefix md;}"
51 "md:annotation aa;}";
Radek Iša56ca9e42020-09-08 18:42:00 +020052 assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, data, LYS_IN_YANG, NULL));
53 CHECK_LOG_CTX("Missing mandatory keyword \"type\" as a child of \"md:annotation aa\".", "/aa:{extension='md:annotation'}/aa");
Radek Krejciad5963b2019-09-06 16:03:05 +020054
55 /* not allowed substatement */
56 data = "module aa {yang-version 1.1; namespace urn:tests:extensions:metadata:aa; prefix aa;"
57 "import ietf-yang-metadata {prefix md;}"
58 "md:annotation aa {default x;}}";
Radek Iša56ca9e42020-09-08 18:42:00 +020059 assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, data, LYS_IN_YANG, NULL));
60 CHECK_LOG_CTX("Invalid keyword \"default\" as a child of \"md:annotation aa\" extension instance.", "/aa:{extension='md:annotation'}/aa");
Radek Krejciad5963b2019-09-06 16:03:05 +020061
62 /* invalid cardinality of units substatement */
63 data = "module aa {yang-version 1.1; namespace urn:tests:extensions:metadata:aa; prefix aa;"
64 "import ietf-yang-metadata {prefix md;}"
65 "md:annotation aa {type string; units x; units y;}}";
Radek Iša56ca9e42020-09-08 18:42:00 +020066 assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, data, LYS_IN_YANG, NULL));
67 CHECK_LOG_CTX("Duplicate keyword \"units\".", "/aa:{extension='md:annotation'}/aa");
Radek Krejciad5963b2019-09-06 16:03:05 +020068
69 /* invalid cardinality of status substatement */
70 data = "module aa {yang-version 1.1; namespace urn:tests:extensions:metadata:aa; prefix aa;"
71 "import ietf-yang-metadata {prefix md;}"
72 "md:annotation aa {type string; status current; status obsolete;}}";
Radek Iša56ca9e42020-09-08 18:42:00 +020073 assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, data, LYS_IN_YANG, NULL));
74 CHECK_LOG_CTX("Duplicate keyword \"status\".", "/aa:{extension='md:annotation'}/aa");
Radek Krejciad5963b2019-09-06 16:03:05 +020075
76 /* invalid cardinality of status substatement */
77 data = "module aa {yang-version 1.1; namespace urn:tests:extensions:metadata:aa; prefix aa;"
78 "import ietf-yang-metadata {prefix md;}"
79 "md:annotation aa {type string; type uint8;}}";
Radek Iša56ca9e42020-09-08 18:42:00 +020080 assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, data, LYS_IN_YANG, NULL));
81 CHECK_LOG_CTX("Duplicate keyword \"type\".", "/aa:{extension='md:annotation'}/aa");
Radek Krejciad5963b2019-09-06 16:03:05 +020082
83 /* duplication of the same annotation */
84 data = "module aa {yang-version 1.1; namespace urn:tests:extensions:metadata:aa; prefix aa;"
85 "import ietf-yang-metadata {prefix md;}"
86 "md:annotation aa {type string;} md:annotation aa {type uint8;}}";
Radek Iša56ca9e42020-09-08 18:42:00 +020087 assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, data, LYS_IN_YANG, NULL));
88 CHECK_LOG_CTX("Extension plugin \"libyang 2 - metadata, version 1\": "
Radek Krejci932d3bb2021-02-09 16:29:38 +010089 "Extension md:annotation is instantiated multiple times.", "/aa:{extension='md:annotation'}/aa");
Radek Krejciad5963b2019-09-06 16:03:05 +020090}
91
Radek Krejci7c960162019-09-18 14:16:12 +020092static void
93test_yin(void **state)
94{
Michal Vasko4de7d072021-07-09 09:13:18 +020095 struct lys_module *mod;
Radek Krejci7c960162019-09-18 14:16:12 +020096 struct lysc_ext_instance *e;
Michal Vasko7f45cf22020-10-01 12:49:44 +020097 const char *data;
Radek Krejci7c960162019-09-18 14:16:12 +020098
Michal Vasko7f45cf22020-10-01 12:49:44 +020099 data = "<module xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\" xmlns:md=\"urn:ietf:params:xml:ns:yang:ietf-yang-metadata\" name=\"a\">\n"
Radek Krejci7c960162019-09-18 14:16:12 +0200100 "<yang-version value=\"1.1\"/><namespace uri=\"urn:tests:extensions:metadata:a\"/><prefix value=\"a\"/>\n"
101 "<import module=\"ietf-yang-metadata\"><prefix value=\"md\"/></import>\n"
102 "<feature name=\"f\"/>\n"
103 "<md:annotation name=\"x\">\n"
104 " <description><text>test</text></description>\n"
105 " <reference><text>test</text></reference>\n"
106 " <if-feature name=\"f\"/>\n"
107 " <status value=\"current\"/>\n"
108 " <type name=\"uint8\"/>\n"
109 " <units name=\"meters\"/>\n"
110 "</md:annotation></module>";
Michal Vaskofc2cd072021-02-24 13:17:17 +0100111 const char *feats[] = {"f", NULL};
112
113 UTEST_ADD_MODULE(data, LYS_IN_YIN, feats, &mod);
Michal Vaskofd69e1d2020-07-03 11:57:17 +0200114 assert_int_equal(1, LY_ARRAY_COUNT(mod->compiled->exts));
Radek Krejci7c960162019-09-18 14:16:12 +0200115 e = &mod->compiled->exts[0];
Radek Krejci1b2eef82021-02-17 11:17:27 +0100116 assert_non_null(e->data);
117 assert_non_null(e->substmts);
118 assert_string_equal("meters", *(const char **)e->substmts[ANNOTATION_SUBSTMT_UNITS].storage);
Radek Krejci7c960162019-09-18 14:16:12 +0200119
120 /* invalid */
121 /* missing mandatory type substatement */
122 data = "<module xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\" xmlns:md=\"urn:ietf:params:xml:ns:yang:ietf-yang-metadata\" name=\"aa\">\n"
123 "<yang-version value=\"1.1\"/><namespace uri=\"urn:tests:extensions:metadata:aa\"/><prefix value=\"aa\"/>\n"
124 "<import module=\"ietf-yang-metadata\"><prefix value=\"md\"/></import>\n"
125 "<md:annotation name=\"aa\"/>\n"
126 "</module>";
Radek Iša56ca9e42020-09-08 18:42:00 +0200127 assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, data, LYS_IN_YIN, NULL));
Radek Krejci85ac8312021-03-03 20:21:33 +0100128 CHECK_LOG_CTX("Missing mandatory keyword \"type\" as a child of \"md:annotation aa\".", "/aa:{extension='md:annotation'}/aa");
Radek Krejci7c960162019-09-18 14:16:12 +0200129
130 /* not allowed substatement */
131 data = "<module xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\" xmlns:md=\"urn:ietf:params:xml:ns:yang:ietf-yang-metadata\" name=\"aa\">\n"
132 "<yang-version value=\"1.1\"/><namespace uri=\"urn:tests:extensions:metadata:aa\"/><prefix value=\"aa\"/>\n"
133 "<import module=\"ietf-yang-metadata\"><prefix value=\"md\"/></import>\n"
134 "<md:annotation name=\"aa\">\n"
135 " <default value=\"x\"/>\n"
136 "</md:annotation></module>";
Radek Iša56ca9e42020-09-08 18:42:00 +0200137 assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, data, LYS_IN_YIN, NULL));
Radek Krejci85ac8312021-03-03 20:21:33 +0100138 CHECK_LOG_CTX("Invalid keyword \"default\" as a child of \"md:annotation aa\" extension instance.", "/aa:{extension='md:annotation'}/aa");
Radek Krejci7c960162019-09-18 14:16:12 +0200139
140 /* invalid cardinality of units substatement */
141 data = "<module xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\" xmlns:md=\"urn:ietf:params:xml:ns:yang:ietf-yang-metadata\" name=\"aa\">\n"
142 "<yang-version value=\"1.1\"/><namespace uri=\"urn:tests:extensions:metadata:aa\"/><prefix value=\"aa\"/>\n"
143 "<import module=\"ietf-yang-metadata\"><prefix value=\"md\"/></import>\n"
144 "<md:annotation name=\"aa\">\n"
145 " <type name=\"string\"/>\n"
146 " <units name=\"x\"/>\n"
147 " <units name=\"y\"/>\n"
148 "</md:annotation></module>";
Radek Iša56ca9e42020-09-08 18:42:00 +0200149 assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, data, LYS_IN_YIN, NULL));
150 CHECK_LOG_CTX("Duplicate keyword \"units\".", "/aa:{extension='md:annotation'}/aa");
Radek Krejci7c960162019-09-18 14:16:12 +0200151
152 /* invalid cardinality of status substatement */
153 data = "<module xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\" xmlns:md=\"urn:ietf:params:xml:ns:yang:ietf-yang-metadata\" name=\"aa\">\n"
154 "<yang-version value=\"1.1\"/><namespace uri=\"urn:tests:extensions:metadata:aa\"/><prefix value=\"aa\"/>\n"
155 "<import module=\"ietf-yang-metadata\"><prefix value=\"md\"/></import>\n"
156 "<md:annotation name=\"aa\">\n"
157 " <type name=\"string\"/>\n"
158 " <status value=\"current\"/>\n"
159 " <status value=\"obsolete\"/>\n"
160 "</md:annotation></module>";
Radek Iša56ca9e42020-09-08 18:42:00 +0200161 assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, data, LYS_IN_YIN, NULL));
162 CHECK_LOG_CTX("Duplicate keyword \"status\".", "/aa:{extension='md:annotation'}/aa");
Radek Krejci7c960162019-09-18 14:16:12 +0200163
164 /* invalid cardinality of status substatement */
165 data = "<module xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\" xmlns:md=\"urn:ietf:params:xml:ns:yang:ietf-yang-metadata\" name=\"aa\">\n"
166 "<yang-version value=\"1.1\"/><namespace uri=\"urn:tests:extensions:metadata:aa\"/><prefix value=\"aa\"/>\n"
167 "<import module=\"ietf-yang-metadata\"><prefix value=\"md\"/></import>\n"
168 "<md:annotation name=\"aa\">\n"
169 " <type name=\"string\"/>\n"
170 " <type name=\"uint8\"/>\n"
171 "</md:annotation></module>";
Radek Iša56ca9e42020-09-08 18:42:00 +0200172 assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, data, LYS_IN_YIN, NULL));
173 CHECK_LOG_CTX("Duplicate keyword \"type\".", "/aa:{extension='md:annotation'}/aa");
Radek Krejci7c960162019-09-18 14:16:12 +0200174
175 /* duplication of the same annotation */
176 data = "<module xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\" xmlns:md=\"urn:ietf:params:xml:ns:yang:ietf-yang-metadata\" name=\"aa\">\n"
177 "<yang-version value=\"1.1\"/><namespace uri=\"urn:tests:extensions:metadata:aa\"/><prefix value=\"aa\"/>\n"
178 "<import module=\"ietf-yang-metadata\"><prefix value=\"md\"/></import>\n"
179 "<md:annotation name=\"aa\">\n"
180 " <type name=\"string\"/>\n"
181 "</md:annotation><md:annotation name=\"aa\">\n"
182 " <type name=\"uint8\"/>\n"
183 "</md:annotation></module>";
Radek Iša56ca9e42020-09-08 18:42:00 +0200184 assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, data, LYS_IN_YIN, NULL));
185 CHECK_LOG_CTX("Extension plugin \"libyang 2 - metadata, version 1\": "
Radek Krejci932d3bb2021-02-09 16:29:38 +0100186 "Extension md:annotation is instantiated multiple times.", "/aa:{extension='md:annotation'}/aa");
Radek Krejci7c960162019-09-18 14:16:12 +0200187}
188
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100189int
190main(void)
Radek Krejciad5963b2019-09-06 16:03:05 +0200191{
192 const struct CMUnitTest tests[] = {
Radek Iša56ca9e42020-09-08 18:42:00 +0200193 UTEST(test_yang),
194 UTEST(test_yin),
Radek Krejciad5963b2019-09-06 16:03:05 +0200195 };
196
197 return cmocka_run_group_tests(tests, NULL, NULL);
198}