blob: fcaa9dac6ddbd51663bd0f72d373a86f51f3180d [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 Vasko7a266772024-01-23 11:02:38 +010056 "/aa:{extension='md:annotation'}/aa", 0);
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 Vasko7a266772024-01-23 11:02:38 +010064 "/aa:{extension='md:annotation'}/aa", 0);
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 Vasko7a266772024-01-23 11:02:38 +010071 CHECK_LOG_CTX("Duplicate keyword \"units\".", "/aa:{extension='md:annotation'}/aa", 0);
Radek Krejciad5963b2019-09-06 16:03:05 +020072
73 /* invalid cardinality of status substatement */
74 data = "module aa {yang-version 1.1; namespace urn:tests:extensions:metadata:aa; prefix aa;"
75 "import ietf-yang-metadata {prefix md;}"
76 "md:annotation aa {type string; status current; status obsolete;}}";
Radek Iša56ca9e42020-09-08 18:42:00 +020077 assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, data, LYS_IN_YANG, NULL));
Michal Vasko7a266772024-01-23 11:02:38 +010078 CHECK_LOG_CTX("Duplicate keyword \"status\".", "/aa:{extension='md:annotation'}/aa", 0);
Radek Krejciad5963b2019-09-06 16:03:05 +020079
80 /* invalid cardinality of status substatement */
81 data = "module aa {yang-version 1.1; namespace urn:tests:extensions:metadata:aa; prefix aa;"
82 "import ietf-yang-metadata {prefix md;}"
83 "md:annotation aa {type string; type uint8;}}";
Radek Iša56ca9e42020-09-08 18:42:00 +020084 assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, data, LYS_IN_YANG, NULL));
Michal Vasko7a266772024-01-23 11:02:38 +010085 CHECK_LOG_CTX("Duplicate keyword \"type\".", "/aa:{extension='md:annotation'}/aa", 0);
Radek Krejciad5963b2019-09-06 16:03:05 +020086
87 /* duplication of the same annotation */
88 data = "module aa {yang-version 1.1; namespace urn:tests:extensions:metadata:aa; prefix aa;"
89 "import ietf-yang-metadata {prefix md;}"
90 "md:annotation aa {type string;} md:annotation aa {type uint8;}}";
Radek Iša56ca9e42020-09-08 18:42:00 +020091 assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, data, LYS_IN_YANG, NULL));
Michal Vasko193dacd2022-10-13 08:43:05 +020092 CHECK_LOG_CTX("Ext plugin \"ly2 metadata v1\": Extension md:annotation is instantiated multiple times.",
Michal Vasko7a266772024-01-23 11:02:38 +010093 "/aa:{extension='md:annotation'}/aa", 0);
Radek Krejciad5963b2019-09-06 16:03:05 +020094}
95
Radek Krejci7c960162019-09-18 14:16:12 +020096static void
97test_yin(void **state)
98{
Michal Vasko4de7d072021-07-09 09:13:18 +020099 struct lys_module *mod;
Radek Krejci7c960162019-09-18 14:16:12 +0200100 struct lysc_ext_instance *e;
Michal Vasko193dacd2022-10-13 08:43:05 +0200101 const char *data, *units;
Radek Krejci7c960162019-09-18 14:16:12 +0200102
Michal Vasko7f45cf22020-10-01 12:49:44 +0200103 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 +0200104 "<yang-version value=\"1.1\"/><namespace uri=\"urn:tests:extensions:metadata:a\"/><prefix value=\"a\"/>\n"
105 "<import module=\"ietf-yang-metadata\"><prefix value=\"md\"/></import>\n"
106 "<feature name=\"f\"/>\n"
107 "<md:annotation name=\"x\">\n"
108 " <description><text>test</text></description>\n"
109 " <reference><text>test</text></reference>\n"
110 " <if-feature name=\"f\"/>\n"
111 " <status value=\"current\"/>\n"
112 " <type name=\"uint8\"/>\n"
113 " <units name=\"meters\"/>\n"
114 "</md:annotation></module>";
Michal Vaskofc2cd072021-02-24 13:17:17 +0100115 const char *feats[] = {"f", NULL};
116
117 UTEST_ADD_MODULE(data, LYS_IN_YIN, feats, &mod);
Michal Vaskofd69e1d2020-07-03 11:57:17 +0200118 assert_int_equal(1, LY_ARRAY_COUNT(mod->compiled->exts));
Radek Krejci7c960162019-09-18 14:16:12 +0200119 e = &mod->compiled->exts[0];
Michal Vasko193dacd2022-10-13 08:43:05 +0200120 assert_non_null(e->compiled);
Radek Krejci1b2eef82021-02-17 11:17:27 +0100121 assert_non_null(e->substmts);
Michal Vaskofbd037c2022-11-08 10:34:20 +0100122 lyplg_ext_get_storage(e, LY_STMT_UNITS, sizeof units, (const void **)&units);
Michal Vasko193dacd2022-10-13 08:43:05 +0200123 assert_string_equal("meters", units);
Radek Krejci7c960162019-09-18 14:16:12 +0200124
125 /* invalid */
126 /* missing mandatory type substatement */
127 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"
128 "<yang-version value=\"1.1\"/><namespace uri=\"urn:tests:extensions:metadata:aa\"/><prefix value=\"aa\"/>\n"
129 "<import module=\"ietf-yang-metadata\"><prefix value=\"md\"/></import>\n"
130 "<md:annotation name=\"aa\"/>\n"
131 "</module>";
Radek Iša56ca9e42020-09-08 18:42:00 +0200132 assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, data, LYS_IN_YIN, NULL));
Michal Vasko193dacd2022-10-13 08:43:05 +0200133 CHECK_LOG_CTX("Ext plugin \"ly2 metadata v1\": Missing mandatory keyword \"type\" as a child of \"md:annotation aa\".",
Michal Vasko7a266772024-01-23 11:02:38 +0100134 "/aa:{extension='md:annotation'}/aa", 0);
Radek Krejci7c960162019-09-18 14:16:12 +0200135
136 /* not allowed substatement */
137 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"
138 "<yang-version value=\"1.1\"/><namespace uri=\"urn:tests:extensions:metadata:aa\"/><prefix value=\"aa\"/>\n"
139 "<import module=\"ietf-yang-metadata\"><prefix value=\"md\"/></import>\n"
140 "<md:annotation name=\"aa\">\n"
141 " <default value=\"x\"/>\n"
142 "</md:annotation></module>";
Radek Iša56ca9e42020-09-08 18:42:00 +0200143 assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, data, LYS_IN_YIN, NULL));
Michal Vasko193dacd2022-10-13 08:43:05 +0200144 CHECK_LOG_CTX("Invalid keyword \"default\" as a child of \"md:annotation aa\" extension instance.",
Michal Vasko7a266772024-01-23 11:02:38 +0100145 "/aa:{extension='md:annotation'}/aa", 0);
Radek Krejci7c960162019-09-18 14:16:12 +0200146
147 /* invalid cardinality of units substatement */
148 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"
149 "<yang-version value=\"1.1\"/><namespace uri=\"urn:tests:extensions:metadata:aa\"/><prefix value=\"aa\"/>\n"
150 "<import module=\"ietf-yang-metadata\"><prefix value=\"md\"/></import>\n"
151 "<md:annotation name=\"aa\">\n"
152 " <type name=\"string\"/>\n"
153 " <units name=\"x\"/>\n"
154 " <units name=\"y\"/>\n"
155 "</md:annotation></module>";
Radek Iša56ca9e42020-09-08 18:42:00 +0200156 assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, data, LYS_IN_YIN, NULL));
Michal Vasko7a266772024-01-23 11:02:38 +0100157 CHECK_LOG_CTX("Duplicate keyword \"units\".", "/aa:{extension='md:annotation'}/aa", 0);
Radek Krejci7c960162019-09-18 14:16:12 +0200158
159 /* invalid cardinality of status substatement */
160 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"
161 "<yang-version value=\"1.1\"/><namespace uri=\"urn:tests:extensions:metadata:aa\"/><prefix value=\"aa\"/>\n"
162 "<import module=\"ietf-yang-metadata\"><prefix value=\"md\"/></import>\n"
163 "<md:annotation name=\"aa\">\n"
164 " <type name=\"string\"/>\n"
165 " <status value=\"current\"/>\n"
166 " <status value=\"obsolete\"/>\n"
167 "</md:annotation></module>";
Radek Iša56ca9e42020-09-08 18:42:00 +0200168 assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, data, LYS_IN_YIN, NULL));
Michal Vasko7a266772024-01-23 11:02:38 +0100169 CHECK_LOG_CTX("Duplicate keyword \"status\".", "/aa:{extension='md:annotation'}/aa", 0);
Radek Krejci7c960162019-09-18 14:16:12 +0200170
171 /* invalid cardinality of status substatement */
172 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"
173 "<yang-version value=\"1.1\"/><namespace uri=\"urn:tests:extensions:metadata:aa\"/><prefix value=\"aa\"/>\n"
174 "<import module=\"ietf-yang-metadata\"><prefix value=\"md\"/></import>\n"
175 "<md:annotation name=\"aa\">\n"
176 " <type name=\"string\"/>\n"
177 " <type name=\"uint8\"/>\n"
178 "</md:annotation></module>";
Radek Iša56ca9e42020-09-08 18:42:00 +0200179 assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, data, LYS_IN_YIN, NULL));
Michal Vasko7a266772024-01-23 11:02:38 +0100180 CHECK_LOG_CTX("Duplicate keyword \"type\".", "/aa:{extension='md:annotation'}/aa", 0);
Radek Krejci7c960162019-09-18 14:16:12 +0200181
182 /* duplication of the same annotation */
183 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"
184 "<yang-version value=\"1.1\"/><namespace uri=\"urn:tests:extensions:metadata:aa\"/><prefix value=\"aa\"/>\n"
185 "<import module=\"ietf-yang-metadata\"><prefix value=\"md\"/></import>\n"
186 "<md:annotation name=\"aa\">\n"
187 " <type name=\"string\"/>\n"
188 "</md:annotation><md:annotation name=\"aa\">\n"
189 " <type name=\"uint8\"/>\n"
190 "</md:annotation></module>";
Radek Iša56ca9e42020-09-08 18:42:00 +0200191 assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, data, LYS_IN_YIN, NULL));
Michal Vasko193dacd2022-10-13 08:43:05 +0200192 CHECK_LOG_CTX("Ext plugin \"ly2 metadata v1\": Extension md:annotation is instantiated multiple times.",
Michal Vasko7a266772024-01-23 11:02:38 +0100193 "/aa:{extension='md:annotation'}/aa", 0);
Radek Krejci7c960162019-09-18 14:16:12 +0200194}
195
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100196int
197main(void)
Radek Krejciad5963b2019-09-06 16:03:05 +0200198{
199 const struct CMUnitTest tests[] = {
Radek Iša56ca9e42020-09-08 18:42:00 +0200200 UTEST(test_yang),
201 UTEST(test_yin),
Radek Krejciad5963b2019-09-06 16:03:05 +0200202 };
203
204 return cmocka_run_group_tests(tests, NULL, NULL);
205}