blob: f1edd2946746c668ddc03f9136ed0a751e132022 [file] [log] [blame]
Michal Vasko193dacd2022-10-13 08:43:05 +02001/**
Radek Krejciad5963b2019-09-06 16:03:05 +02002 * @file test_metadata.c
Michal Vasko193dacd2022-10-13 08:43:05 +02003 * @author Radek Krejci <rkrejci@cesnet.cz>
Radek Krejciad5963b2019-09-06 16:03:05 +02004 * @brief unit tests for Metadata extension (annotation) support
5 *
Michal Vasko193dacd2022-10-13 08:43:05 +02006 * Copyright (c) 2019 - 2022 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;
Michal Vasko193dacd2022-10-13 08:43:05 +020026 const char *units;
Radek Krejciad5963b2019-09-06 16:03:05 +020027
28 const char *data = "module a {yang-version 1.1; namespace urn:tests:extensions:metadata:a; prefix a;"
29 "import ietf-yang-metadata {prefix md;}"
30 "feature f;"
31 "md:annotation x {"
32 " description \"test\";"
33 " if-feature f;"
34 " reference \"test\";"
35 " status \"current\";"
36 " type uint8;"
37 " units meters;"
38 "}}";
Michal Vasko7b1ad1a2020-11-02 15:41:27 +010039 const char *feats[] = {"f", NULL};
Radek Krejcib4ac5a92020-11-23 17:54:33 +010040
Radek Iša56ca9e42020-09-08 18:42:00 +020041 UTEST_ADD_MODULE(data, LYS_IN_YANG, feats, &mod);
Michal Vaskofd69e1d2020-07-03 11:57:17 +020042 assert_int_equal(1, LY_ARRAY_COUNT(mod->compiled->exts));
Radek Krejciad5963b2019-09-06 16:03:05 +020043 e = &mod->compiled->exts[0];
Michal Vasko193dacd2022-10-13 08:43:05 +020044 assert_non_null(e->compiled);
Radek Krejci1b2eef82021-02-17 11:17:27 +010045 assert_non_null(e->substmts);
Michal Vaskofbd037c2022-11-08 10:34:20 +010046 lyplg_ext_get_storage(e, LY_STMT_UNITS, sizeof units, (const void **)&units);
Michal Vasko193dacd2022-10-13 08:43:05 +020047 assert_string_equal("meters", units);
Radek Krejciad5963b2019-09-06 16:03:05 +020048
49 /* invalid */
50 /* missing mandatory type substatement */
51 data = "module aa {yang-version 1.1; namespace urn:tests:extensions:metadata:aa; prefix aa;"
52 "import ietf-yang-metadata {prefix md;}"
53 "md:annotation aa;}";
Radek Iša56ca9e42020-09-08 18:42:00 +020054 assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, data, LYS_IN_YANG, NULL));
Michal Vasko193dacd2022-10-13 08:43:05 +020055 CHECK_LOG_CTX("Ext plugin \"ly2 metadata v1\": Missing mandatory keyword \"type\" as a child of \"md:annotation aa\".",
Michal Vasko6727c682023-02-17 10:40:26 +010056 "Path \"/aa:{extension='md:annotation'}/aa\".");
Radek Krejciad5963b2019-09-06 16:03:05 +020057
58 /* not allowed substatement */
59 data = "module aa {yang-version 1.1; namespace urn:tests:extensions:metadata:aa; prefix aa;"
60 "import ietf-yang-metadata {prefix md;}"
61 "md:annotation aa {default x;}}";
Radek Iša56ca9e42020-09-08 18:42:00 +020062 assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, data, LYS_IN_YANG, NULL));
Michal Vasko193dacd2022-10-13 08:43:05 +020063 CHECK_LOG_CTX("Invalid keyword \"default\" as a child of \"md:annotation aa\" extension instance.",
Michal Vasko6727c682023-02-17 10:40:26 +010064 "Path \"/aa:{extension='md:annotation'}/aa\".");
Radek Krejciad5963b2019-09-06 16:03:05 +020065
66 /* invalid cardinality of units substatement */
67 data = "module aa {yang-version 1.1; namespace urn:tests:extensions:metadata:aa; prefix aa;"
68 "import ietf-yang-metadata {prefix md;}"
69 "md:annotation aa {type string; units x; units y;}}";
Radek Iša56ca9e42020-09-08 18:42:00 +020070 assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, data, LYS_IN_YANG, NULL));
Michal Vasko193dacd2022-10-13 08:43:05 +020071 CHECK_LOG_CTX("Duplicate keyword \"units\".",
Michal Vasko6727c682023-02-17 10:40:26 +010072 "Path \"/aa:{extension='md:annotation'}/aa\".");
Radek Krejciad5963b2019-09-06 16:03:05 +020073
74 /* invalid cardinality of status substatement */
75 data = "module aa {yang-version 1.1; namespace urn:tests:extensions:metadata:aa; prefix aa;"
76 "import ietf-yang-metadata {prefix md;}"
77 "md:annotation aa {type string; status current; status obsolete;}}";
Radek Iša56ca9e42020-09-08 18:42:00 +020078 assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, data, LYS_IN_YANG, NULL));
Michal Vasko193dacd2022-10-13 08:43:05 +020079 CHECK_LOG_CTX("Duplicate keyword \"status\".",
Michal Vasko6727c682023-02-17 10:40:26 +010080 "Path \"/aa:{extension='md:annotation'}/aa\".");
Radek Krejciad5963b2019-09-06 16:03:05 +020081
82 /* invalid cardinality of status substatement */
83 data = "module aa {yang-version 1.1; namespace urn:tests:extensions:metadata:aa; prefix aa;"
84 "import ietf-yang-metadata {prefix md;}"
85 "md:annotation aa {type string; type uint8;}}";
Radek Iša56ca9e42020-09-08 18:42:00 +020086 assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, data, LYS_IN_YANG, NULL));
Michal Vasko193dacd2022-10-13 08:43:05 +020087 CHECK_LOG_CTX("Duplicate keyword \"type\".",
Michal Vasko6727c682023-02-17 10:40:26 +010088 "Path \"/aa:{extension='md:annotation'}/aa\".");
Radek Krejciad5963b2019-09-06 16:03:05 +020089
90 /* duplication of the same annotation */
91 data = "module aa {yang-version 1.1; namespace urn:tests:extensions:metadata:aa; prefix aa;"
92 "import ietf-yang-metadata {prefix md;}"
93 "md:annotation aa {type string;} md:annotation aa {type uint8;}}";
Radek Iša56ca9e42020-09-08 18:42:00 +020094 assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, data, LYS_IN_YANG, NULL));
Michal Vasko193dacd2022-10-13 08:43:05 +020095 CHECK_LOG_CTX("Ext plugin \"ly2 metadata v1\": Extension md:annotation is instantiated multiple times.",
Michal Vasko6727c682023-02-17 10:40:26 +010096 "Path \"/aa:{extension='md:annotation'}/aa\".");
Radek Krejciad5963b2019-09-06 16:03:05 +020097}
98
Radek Krejci7c960162019-09-18 14:16:12 +020099static void
100test_yin(void **state)
101{
Michal Vasko4de7d072021-07-09 09:13:18 +0200102 struct lys_module *mod;
Radek Krejci7c960162019-09-18 14:16:12 +0200103 struct lysc_ext_instance *e;
Michal Vasko193dacd2022-10-13 08:43:05 +0200104 const char *data, *units;
Radek Krejci7c960162019-09-18 14:16:12 +0200105
Michal Vasko7f45cf22020-10-01 12:49:44 +0200106 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 +0200107 "<yang-version value=\"1.1\"/><namespace uri=\"urn:tests:extensions:metadata:a\"/><prefix value=\"a\"/>\n"
108 "<import module=\"ietf-yang-metadata\"><prefix value=\"md\"/></import>\n"
109 "<feature name=\"f\"/>\n"
110 "<md:annotation name=\"x\">\n"
111 " <description><text>test</text></description>\n"
112 " <reference><text>test</text></reference>\n"
113 " <if-feature name=\"f\"/>\n"
114 " <status value=\"current\"/>\n"
115 " <type name=\"uint8\"/>\n"
116 " <units name=\"meters\"/>\n"
117 "</md:annotation></module>";
Michal Vaskofc2cd072021-02-24 13:17:17 +0100118 const char *feats[] = {"f", NULL};
119
120 UTEST_ADD_MODULE(data, LYS_IN_YIN, feats, &mod);
Michal Vaskofd69e1d2020-07-03 11:57:17 +0200121 assert_int_equal(1, LY_ARRAY_COUNT(mod->compiled->exts));
Radek Krejci7c960162019-09-18 14:16:12 +0200122 e = &mod->compiled->exts[0];
Michal Vasko193dacd2022-10-13 08:43:05 +0200123 assert_non_null(e->compiled);
Radek Krejci1b2eef82021-02-17 11:17:27 +0100124 assert_non_null(e->substmts);
Michal Vaskofbd037c2022-11-08 10:34:20 +0100125 lyplg_ext_get_storage(e, LY_STMT_UNITS, sizeof units, (const void **)&units);
Michal Vasko193dacd2022-10-13 08:43:05 +0200126 assert_string_equal("meters", units);
Radek Krejci7c960162019-09-18 14:16:12 +0200127
128 /* invalid */
129 /* missing mandatory type substatement */
130 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"
131 "<yang-version value=\"1.1\"/><namespace uri=\"urn:tests:extensions:metadata:aa\"/><prefix value=\"aa\"/>\n"
132 "<import module=\"ietf-yang-metadata\"><prefix value=\"md\"/></import>\n"
133 "<md:annotation name=\"aa\"/>\n"
134 "</module>";
Radek Iša56ca9e42020-09-08 18:42:00 +0200135 assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, data, LYS_IN_YIN, NULL));
Michal Vasko193dacd2022-10-13 08:43:05 +0200136 CHECK_LOG_CTX("Ext plugin \"ly2 metadata v1\": Missing mandatory keyword \"type\" as a child of \"md:annotation aa\".",
Michal Vasko6727c682023-02-17 10:40:26 +0100137 "Path \"/aa:{extension='md:annotation'}/aa\".");
Radek Krejci7c960162019-09-18 14:16:12 +0200138
139 /* not allowed substatement */
140 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"
141 "<yang-version value=\"1.1\"/><namespace uri=\"urn:tests:extensions:metadata:aa\"/><prefix value=\"aa\"/>\n"
142 "<import module=\"ietf-yang-metadata\"><prefix value=\"md\"/></import>\n"
143 "<md:annotation name=\"aa\">\n"
144 " <default value=\"x\"/>\n"
145 "</md:annotation></module>";
Radek Iša56ca9e42020-09-08 18:42:00 +0200146 assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, data, LYS_IN_YIN, NULL));
Michal Vasko193dacd2022-10-13 08:43:05 +0200147 CHECK_LOG_CTX("Invalid keyword \"default\" as a child of \"md:annotation aa\" extension instance.",
Michal Vasko6727c682023-02-17 10:40:26 +0100148 "Path \"/aa:{extension='md:annotation'}/aa\".");
Radek Krejci7c960162019-09-18 14:16:12 +0200149
150 /* invalid cardinality of units substatement */
151 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"
152 "<yang-version value=\"1.1\"/><namespace uri=\"urn:tests:extensions:metadata:aa\"/><prefix value=\"aa\"/>\n"
153 "<import module=\"ietf-yang-metadata\"><prefix value=\"md\"/></import>\n"
154 "<md:annotation name=\"aa\">\n"
155 " <type name=\"string\"/>\n"
156 " <units name=\"x\"/>\n"
157 " <units name=\"y\"/>\n"
158 "</md:annotation></module>";
Radek Iša56ca9e42020-09-08 18:42:00 +0200159 assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, data, LYS_IN_YIN, NULL));
Michal Vasko193dacd2022-10-13 08:43:05 +0200160 CHECK_LOG_CTX("Duplicate keyword \"units\".",
Michal Vasko6727c682023-02-17 10:40:26 +0100161 "Path \"/aa:{extension='md:annotation'}/aa\".");
Radek Krejci7c960162019-09-18 14:16:12 +0200162
163 /* invalid cardinality of status substatement */
164 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"
165 "<yang-version value=\"1.1\"/><namespace uri=\"urn:tests:extensions:metadata:aa\"/><prefix value=\"aa\"/>\n"
166 "<import module=\"ietf-yang-metadata\"><prefix value=\"md\"/></import>\n"
167 "<md:annotation name=\"aa\">\n"
168 " <type name=\"string\"/>\n"
169 " <status value=\"current\"/>\n"
170 " <status value=\"obsolete\"/>\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));
Michal Vasko193dacd2022-10-13 08:43:05 +0200173 CHECK_LOG_CTX("Duplicate keyword \"status\".",
Michal Vasko6727c682023-02-17 10:40:26 +0100174 "Path \"/aa:{extension='md:annotation'}/aa\".");
Radek Krejci7c960162019-09-18 14:16:12 +0200175
176 /* invalid cardinality of status substatement */
177 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"
178 "<yang-version value=\"1.1\"/><namespace uri=\"urn:tests:extensions:metadata:aa\"/><prefix value=\"aa\"/>\n"
179 "<import module=\"ietf-yang-metadata\"><prefix value=\"md\"/></import>\n"
180 "<md:annotation name=\"aa\">\n"
181 " <type name=\"string\"/>\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));
Michal Vasko193dacd2022-10-13 08:43:05 +0200185 CHECK_LOG_CTX("Duplicate keyword \"type\".",
Michal Vasko6727c682023-02-17 10:40:26 +0100186 "Path \"/aa:{extension='md:annotation'}/aa\".");
Radek Krejci7c960162019-09-18 14:16:12 +0200187
188 /* duplication of the same annotation */
189 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"
190 "<yang-version value=\"1.1\"/><namespace uri=\"urn:tests:extensions:metadata:aa\"/><prefix value=\"aa\"/>\n"
191 "<import module=\"ietf-yang-metadata\"><prefix value=\"md\"/></import>\n"
192 "<md:annotation name=\"aa\">\n"
193 " <type name=\"string\"/>\n"
194 "</md:annotation><md:annotation name=\"aa\">\n"
195 " <type name=\"uint8\"/>\n"
196 "</md:annotation></module>";
Radek Iša56ca9e42020-09-08 18:42:00 +0200197 assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, data, LYS_IN_YIN, NULL));
Michal Vasko193dacd2022-10-13 08:43:05 +0200198 CHECK_LOG_CTX("Ext plugin \"ly2 metadata v1\": Extension md:annotation is instantiated multiple times.",
Michal Vasko6727c682023-02-17 10:40:26 +0100199 "Path \"/aa:{extension='md:annotation'}/aa\".");
Radek Krejci7c960162019-09-18 14:16:12 +0200200}
201
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100202int
203main(void)
Radek Krejciad5963b2019-09-06 16:03:05 +0200204{
205 const struct CMUnitTest tests[] = {
Radek Iša56ca9e42020-09-08 18:42:00 +0200206 UTEST(test_yang),
207 UTEST(test_yin),
Radek Krejciad5963b2019-09-06 16:03:05 +0200208 };
209
210 return cmocka_run_group_tests(tests, NULL, NULL);
211}