schemas FEATURE add schema getters from the context
Also check for the duplicities in the context when parsing a new schema.
diff --git a/src/common.c b/src/common.c
index ab3b71f..dab8288 100644
--- a/src/common.c
+++ b/src/common.c
@@ -11,8 +11,8 @@
*
* https://opensource.org/licenses/BSD-3-Clause
*/
-#define _XOPEN_SOURCE
-#define _DEFAULT_SOURCE
+
+#include "common.h"
#include <assert.h>
#include <errno.h>
@@ -25,7 +25,6 @@
#include <sys/types.h>
#include <unistd.h>
-#include "common.h"
#include "tree_schema.h"
const char *const ly_stmt_list[] = {
diff --git a/src/common.h b/src/common.h
index d7d17de..afd4d0b 100644
--- a/src/common.h
+++ b/src/common.h
@@ -15,6 +15,10 @@
#ifndef LY_COMMON_H_
#define LY_COMMON_H_
+#define _DEFAULT_SOURCE
+#define _GNU_SOURCE
+#define _XOPEN_SOURCE
+
#include <assert.h>
#include <pthread.h>
#include <stdint.h>
diff --git a/src/context.c b/src/context.c
index 1216704..ff6dc84 100644
--- a/src/context.c
+++ b/src/context.c
@@ -12,7 +12,8 @@
* https://opensource.org/licenses/BSD-3-Clause
*/
-#define _DEFAULT_SOURCE
+#include "common.h"
+
#define _BSD_SOURCE
#include <errno.h>
#include <limits.h>
@@ -23,7 +24,6 @@
#include <unistd.h>
#include "context.h"
-#include "common.h"
#include "tree_schema_internal.h"
#include "libyang.h"
@@ -261,6 +261,187 @@
return ctx->module_set_id;
}
+/**
+ * @brief Iterate over the modules in the given context. Returned modules must match the given key at the offset of
+ * lysp_module and lysc_module structures (they are supposed to be placed at the same offset in both structures).
+ *
+ * @param[in] ctx Context where to iterate.
+ * @param[in] key Key value to search for.
+ * @param[in] key_offset Key's offset in struct lysp_module and struct lysc_module to get value from the context's
+ * modules to match with the key.
+ * @param[in,out] Iterator to pass between the function calls. On the first call, the variable is supposed to be
+ * initiated to 0. After each call returning a module, the value is greater by 1 than the index of the returned
+ * module in the context.
+ * @return Module matching the given key, NULL if no such module found.
+ */
+static const struct lys_module *
+ly_ctx_get_module_by_iter(const struct ly_ctx *ctx, const char *key, size_t key_offset, unsigned int *index)
+{
+ const struct lys_module *mod;
+ const char *value;
+
+ for (; *index < ctx->list.count; ++(*index)) {
+ mod = ctx->list.objs[*index];
+ if (mod->compiled) {
+ value = *(const char**)(((int8_t*)(mod->compiled)) + key_offset);
+ } else {
+ value = *(const char**)(((int8_t*)(mod->parsed)) + key_offset);
+ }
+ if (!strcmp(key, value)) {
+ /* increment index for the next run */
+ ++(*index);
+ return mod;
+ }
+ }
+ /* done */
+ return NULL;
+}
+
+/**
+ * @brief Unifying function for ly_ctx_get_module() and ly_ctx_get_module_ns()
+ * @param[in] ctx Context where to search.
+ * @param[in] key Name or Namespace as a search key.
+ * @param[in] key_offset Key's offset in struct lysp_module to get value from the context's modules to match with the key.
+ * @param[in] revision Revision date to match. If NULL, the matching module must have no revision. To search for the latest
+ * revision module, use ly_ctx_get_module_latest_by().
+ * @return Matching module if any.
+ */
+static const struct lys_module *
+ly_ctx_get_module_by(const struct ly_ctx *ctx, const char *key, size_t key_offset, const char *revision)
+{
+ const struct lys_module *mod;
+ unsigned int index = 0;
+
+ while ((mod = ly_ctx_get_module_by_iter(ctx, key, key_offset, &index))) {
+ if (!revision) {
+ if ((mod->compiled && !mod->compiled->revs) || (!mod->compiled && !mod->parsed->revs)) {
+ /* found requested module without revision */
+ return mod;
+ }
+ } else {
+ if ((mod->compiled && mod->compiled->revs && !strcmp(mod->compiled->revs[0].date, revision)) ||
+ (!mod->compiled && mod->parsed->revs && !strcmp(mod->parsed->revs[0].date, revision))) {
+ /* found requested module of the specific revision */
+ return mod;
+ }
+ }
+ }
+
+ return NULL;
+}
+
+API const struct lys_module *
+ly_ctx_get_module_ns(const struct ly_ctx *ctx, const char *ns, const char *revision)
+{
+ LY_CHECK_ARG_RET(ctx, ctx, ns, NULL);
+ return ly_ctx_get_module_by(ctx, ns, offsetof(struct lysp_module, ns), revision);
+}
+
+API const struct lys_module *
+ly_ctx_get_module(const struct ly_ctx *ctx, const char *name, const char *revision)
+{
+ LY_CHECK_ARG_RET(ctx, ctx, name, NULL);
+ return ly_ctx_get_module_by(ctx, name, offsetof(struct lysp_module, name), revision);
+}
+
+/**
+ * @brief Unifying function for ly_ctx_get_module_latest() and ly_ctx_get_module_latest_ns()
+ * @param[in] ctx Context where to search.
+ * @param[in] key Name or Namespace as a search key.
+ * @param[in] key_offset Key's offset in struct lysp_module to get value from the context's modules to match with the key.
+ * @return Matching module if any.
+ */
+static const struct lys_module *
+ly_ctx_get_module_latest_by(const struct ly_ctx *ctx, const char *key, size_t key_offset)
+{
+ const struct lys_module *mod, *newest = NULL;
+ unsigned int index = 0;
+ const char *date, *date_newest = NULL;
+
+ while ((mod = ly_ctx_get_module_by_iter(ctx, key, key_offset, &index))) {
+ if (!newest) {
+ newest = mod;
+ } else {
+ if ((newest->compiled && !newest->compiled->revs) || (!newest->compiled && !newest->parsed->revs)) {
+ /* prefer modules with revisions, module with no revision
+ * is supposed to be the oldest one */
+ newest = mod;
+ date_newest = NULL;
+ } else {
+ if (!date_newest) {
+ if (newest->compiled) {
+ date_newest = newest->compiled->revs[0].date;
+ } else {
+ date_newest = newest->parsed->revs[0].date;
+ }
+ }
+ if (mod->compiled) {
+ date = mod->compiled->revs[0].date;
+ } else {
+ date = mod->parsed->revs[0].date;
+ }
+ if (strcmp(date, date_newest) > 0) {
+ /* the current module is newer than so far newest, so remember it */
+ newest = mod;
+ date_newest = NULL;
+ }
+ }
+ }
+ }
+
+ return newest;
+}
+
+API const struct lys_module *
+ly_ctx_get_module_latest(const struct ly_ctx *ctx, const char *name)
+{
+ LY_CHECK_ARG_RET(ctx, ctx, name, NULL);
+ return ly_ctx_get_module_latest_by(ctx, name, offsetof(struct lysp_module, name));
+}
+
+const struct lys_module *
+ly_ctx_get_module_latest_ns(const struct ly_ctx *ctx, const char *ns)
+{
+ LY_CHECK_ARG_RET(ctx, ctx, ns, NULL);
+ return ly_ctx_get_module_latest_by(ctx, ns, offsetof(struct lysp_module, ns));
+}
+
+/**
+ * @brief Unifying function for ly_ctx_get_module_implemented() and ly_ctx_get_module_implemented_ns()
+ * @param[in] ctx Context where to search.
+ * @param[in] key Name or Namespace as a search key.
+ * @param[in] key_offset Key's offset in struct lysp_module to get value from the context's modules to match with the key.
+ * @return Matching module if any.
+ */
+static const struct lys_module *
+ly_ctx_get_module_implemented_by(const struct ly_ctx *ctx, const char *key, size_t key_offset)
+{
+ const struct lys_module *mod;
+ unsigned int index = 0;
+
+ while ((mod = ly_ctx_get_module_by_iter(ctx, key, key_offset, &index))) {
+ if ((mod->compiled && mod->compiled->implemented) || (!mod->compiled && mod->parsed->implemented)) {
+ return mod;
+ }
+ }
+
+ return NULL;
+}
+
+API const struct lys_module *
+ly_ctx_get_module_implemented(const struct ly_ctx *ctx, const char *name)
+{
+ LY_CHECK_ARG_RET(ctx, ctx, name, NULL);
+ return ly_ctx_get_module_implemented_by(ctx, name, offsetof(struct lysp_module, name));
+}
+
+API const struct lys_module *
+ly_ctx_get_module_implemented_ns(const struct ly_ctx *ctx, const char *ns)
+{
+ LY_CHECK_ARG_RET(ctx, ctx, ns, NULL);
+ return ly_ctx_get_module_implemented_by(ctx, ns, offsetof(struct lysp_module, ns));
+}
+
API void
ly_ctx_destroy(struct ly_ctx *ctx, void (*private_destructor)(const struct lysc_node *node, void *priv))
{
diff --git a/src/context.h b/src/context.h
index a172417..2333bb3 100644
--- a/src/context.h
+++ b/src/context.h
@@ -152,6 +152,72 @@
uint16_t ly_ctx_get_module_set_id(const struct ly_ctx *ctx);
/**
+ * @brief Get YANG module of the given name and revision.
+ *
+ * @param[in] ctx Context to work in.
+ * @param[in] name Name of the YANG module to get.
+ * @param[in] revision Requested revision date of the YANG module to get. If not specified,
+ * the schema with no revision is returned, if it is present in the context.
+ * @return Pointer to the YANG module, NULL if no schema in the context follows the name and revision requirements.
+ */
+const struct lys_module *ly_ctx_get_module(const struct ly_ctx *ctx, const char *name, const char *revision);
+
+/**
+ * @brief Get the latest revision of the YANG module specified by its name.
+ *
+ * YANG modules with no revision are supposed to be the oldest one.
+ *
+ * @param[in] ctx Context where to search.
+ * @param[in] name Name of the YANG module to get.
+ * @return The latest revision of the specified YANG module in the given context, NULL if no YANG module of the
+ * given name is present in the context.
+ */
+const struct lys_module *ly_ctx_get_module_latest(const struct ly_ctx *ctx, const char *name);
+
+/**
+ * @brief Get the (only) implemented YANG module specified by its name.
+ *
+ * @param[in] ctx Context where to search.
+ * @param[in] name Name of the YANG module to get.
+ * @return The only implemented YANG module revision of the given name in the given context. NULL if there is no
+ * implemented module of the given name.
+ */
+const struct lys_module *ly_ctx_get_module_implemented(const struct ly_ctx *ctx, const char *name);
+
+/**
+ * @brief Get YANG module of the given namespace and revision.
+ *
+ * @param[in] ctx Context to work in.
+ * @param[in] ns Namespace of the YANG module to get.
+ * @param[in] revision Requested revision date of the YANG module to get. If not specified,
+ * the schema with no revision is returned, if it is present in the context.
+ * @return Pointer to the YANG module, NULL if no schema in the context follows the namespace and revision requirements.
+ */
+const struct lys_module *ly_ctx_get_module_ns(const struct ly_ctx *ctx, const char *ns, const char *revision);
+
+/**
+ * @brief Get the latest revision of the YANG module specified by its namespace.
+ *
+ * YANG modules with no revision are supposed to be the oldest one.
+ *
+ * @param[in] ctx Context where to search.
+ * @param[in] ns Namespace of the YANG module to get.
+ * @return The latest revision of the specified YANG module in the given context, NULL if no YANG module of the
+ * given namespace is present in the context.
+ */
+const struct lys_module *ly_ctx_get_module_latest_ns(const struct ly_ctx *ctx, const char *ns);
+
+/**
+ * @brief Get the (only) implemented YANG module specified by its namespace.
+ *
+ * @param[in] ctx Context where to search.
+ * @param[in] ns Namespace of the YANG module to get.
+ * @return The only implemented YANG module revision of the given namespace in the given context. NULL if there is no
+ * implemented module of the given namespace.
+ */
+const struct lys_module *ly_ctx_get_module_implemented_ns(const struct ly_ctx *ctx, const char *ns);
+
+/**
* @brief Free all internal structures of the specified context.
*
* The function should be used before terminating the application to destroy
diff --git a/src/log.c b/src/log.c
index 18d0b38..57da747 100644
--- a/src/log.c
+++ b/src/log.c
@@ -12,14 +12,14 @@
* https://opensource.org/licenses/BSD-3-Clause
*/
-#define _GNU_SOURCE
+#include "common.h"
+
#include <assert.h>
#include <inttypes.h>
#include <stdarg.h>
#include <stdio.h>
#include "libyang.h"
-#include "common.h"
#include "context.h"
THREAD_LOCAL enum int_log_opts log_opt;
diff --git a/src/parser_yang.c b/src/parser_yang.c
index 434073d..7ea75c6 100644
--- a/src/parser_yang.c
+++ b/src/parser_yang.c
@@ -1424,7 +1424,7 @@
return LY_EVALID;
}
- strncpy(rev->rev, word, word_len);
+ strncpy(rev->date, word, word_len);
free(buf);
YANG_READ_SUBSTMT_FOR(ctx, data, kw, word, word_len, ret) {
diff --git a/src/tree_schema.c b/src/tree_schema.c
index 3960bb3..60bd9b9 100644
--- a/src/tree_schema.c
+++ b/src/tree_schema.c
@@ -11,7 +11,8 @@
*
* https://opensource.org/licenses/BSD-3-Clause
*/
-#define _DEFAULT_SOURCE
+
+#include "common.h"
#include <ctype.h>
#include <errno.h>
@@ -24,7 +25,6 @@
#include <unistd.h>
#include "libyang.h"
-#include "common.h"
#include "context.h"
#include "tree_schema_internal.h"
@@ -1076,7 +1076,7 @@
return ret;
}
-const struct lys_module *
+static const struct lys_module *
lys_parse_mem_(struct ly_ctx *ctx, const char *data, LYS_INFORMAT format, const char *revision, int implement)
{
struct lys_module *mod = NULL;
@@ -1103,21 +1103,36 @@
}
if (implement) {
+ if (ly_ctx_get_module_implemented(ctx, mod->parsed->name)) {
+ LOGERR(ctx, LY_EDENIED, "Module \"%s\" is already implemented in the context.", mod->parsed->name);
+ lys_module_free(mod, NULL);
+ return NULL;
+ }
mod->parsed->implemented = 1;
}
if (revision) {
/* check revision of the parsed model */
- if (!mod->parsed->revs || strcmp(revision, mod->parsed->revs[0].rev)) {
+ if (!mod->parsed->revs || strcmp(revision, mod->parsed->revs[0].date)) {
LOGERR(ctx, LY_EINVAL, "Module \"%s\" parsed with the wrong revision (\"%s\" instead \"%s\").",
- mod->parsed->name, mod->parsed->revs[0].rev, revision);
- lysp_module_free(mod->parsed);
- free(mod);
+ mod->parsed->name, mod->parsed->revs[0].date, revision);
+ lys_module_free(mod, NULL);
return NULL;
}
}
/* check for duplicity in the context */
+ if (ly_ctx_get_module(ctx, mod->parsed->name, mod->parsed->revs ? mod->parsed->revs[0].date : NULL)) {
+ if (mod->parsed->revs) {
+ LOGERR(ctx, LY_EEXIST, "Module \"%s\" of revision \"%s\" is already present in the context.",
+ mod->parsed->name, mod->parsed->revs[0].date);
+ } else {
+ LOGERR(ctx, LY_EEXIST, "Module \"%s\" with no revision is already present in the context.",
+ mod->parsed->name);
+ }
+ lys_module_free(mod, NULL);
+ return NULL;
+ }
/* add into context */
ly_set_add(&ctx->list, mod, LY_SET_OPT_USEASLIST);
@@ -1238,9 +1253,9 @@
}
if (rev) {
len = dot - ++rev;
- if (!mod->parsed->revs || len != 10 || strncmp(mod->parsed->revs[0].rev, rev, len)) {
+ if (!mod->parsed->revs || len != 10 || strncmp(mod->parsed->revs[0].date, rev, len)) {
LOGWRN(ctx, "File name \"%s\" does not match module revision \"%s\".", filename,
- mod->parsed->revs ? mod->parsed->revs[0].rev : "none");
+ mod->parsed->revs ? mod->parsed->revs[0].date : "none");
}
}
diff --git a/src/tree_schema.h b/src/tree_schema.h
index 12394eb..3b939ea 100644
--- a/src/tree_schema.h
+++ b/src/tree_schema.h
@@ -308,7 +308,7 @@
* @brief YANG revision-stmt
*/
struct lysp_revision {
- char rev[LY_REV_SIZE]; /**< revision date (madatory) */
+ char date[LY_REV_SIZE]; /**< revision date (madatory) */
const char *dsc; /**< description statement */
const char *ref; /**< reference statement */
struct lysp_ext_instance *exts; /**< list of the extension instances ([sized array](@ref sizedarrays)) */
@@ -739,7 +739,6 @@
struct lysp_module {
struct ly_ctx *ctx; /**< libyang context of the module (mandatory) */
const char *name; /**< name of the module (mandatory) */
- const char *filepath; /**< path, if the schema was read from a file, NULL in case of reading from memory */
union {
/* module */
const char *ns; /**< namespace of the module (module - mandatory) */
@@ -747,14 +746,15 @@
const char *belongsto; /**< belongs to parent module (submodule - mandatory) */
};
const char *prefix; /**< module prefix or submodule belongsto prefix of main module (mandatory) */
+ struct lysp_revision *revs; /**< list of the module revisions ([sized array](@ref sizedarrays)), the first revision
+ in the list is always the last (newest) revision of the module */
struct lysp_import *imports; /**< list of imported modules ([sized array](@ref sizedarrays)) */
struct lysp_include *includes; /**< list of included submodules ([sized array](@ref sizedarrays)) */
+ const char *filepath; /**< path, if the schema was read from a file, NULL in case of reading from memory */
const char *org; /**< party/company responsible for the module */
const char *contact; /**< contact information for the module */
const char *dsc; /**< description of the module */
const char *ref; /**< cross-reference for the module */
- struct lysp_revision *revs; /**< list of the module revisions ([sized array](@ref sizedarrays)), the first revision
- in the list is always the last (newest) revision of the module */
struct lysp_ext *extensions; /**< list of extension statements ([sized array](@ref sizedarrays)) */
struct lysp_feature *features; /**< list of feature definitions ([sized array](@ref sizedarrays)) */
struct lysp_ident *identities; /**< list of identities ([sized array](@ref sizedarrays)) */
@@ -825,6 +825,14 @@
*/
/**
+ * @brief Compiled YANG revision statement
+ */
+struct lysc_revision {
+ char date[LY_REV_SIZE]; /**< revision-date (mandatory) */
+ struct lysc_ext_instance *exts; /**< list of the extension instances ([sized array](@ref sizedarrays)) */
+};
+
+/**
* @brief Compiled YANG if-feature-stmt
*/
struct lysc_iffeature {
@@ -857,6 +865,8 @@
const char *name; /**< name of the module (mandatory) */
const char *ns; /**< namespace of the module (mandatory) */
const char *prefix; /**< module prefix (mandatory) */
+ struct lysc_revision *revs; /**< list of the module revisions ([sized array](@ref sizedarrays)), the first revision
+ in the list is always the last (newest) revision of the module */
struct lysc_import *imports; /**< list of imported modules ([sized array](@ref sizedarrays)) */
diff --git a/src/tree_schema_helpers.c b/src/tree_schema_helpers.c
index 0d0620c..b95505a 100644
--- a/src/tree_schema_helpers.c
+++ b/src/tree_schema_helpers.c
@@ -92,7 +92,7 @@
struct lysp_revision rev;
for (i = 1, r = 0; revs && i < LY_ARRAY_SIZE(revs); i++) {
- if (strcmp(revs[i].rev, revs[r].rev) > 0) {
+ if (strcmp(revs[i].date, revs[r].date) > 0) {
r = i;
}
}
diff --git a/tests/src/test_context.c b/tests/src/test_context.c
index d0fc202..992fdfa 100644
--- a/tests/src/test_context.c
+++ b/tests/src/test_context.c
@@ -14,6 +14,7 @@
#include "tests/config.h"
#include "../../src/context.c"
+#include "../../src/tree_schema.c"
#include <stdarg.h>
#include <stddef.h>
@@ -77,6 +78,7 @@
struct ly_ctx *ctx;
const char * const *list;
+ will_return_count(__wrap_ly_set_add, 0, 6);
assert_int_equal(LY_SUCCESS, ly_ctx_new(NULL, 0, &ctx));
/* invalid arguments */
@@ -177,6 +179,8 @@
(void) state; /* unused */
struct ly_ctx *ctx;
+
+ will_return_always(__wrap_ly_set_add, 0);
assert_int_equal(LY_SUCCESS, ly_ctx_new(NULL, 0xffffffff, &ctx));
/* invalid arguments */
@@ -255,11 +259,13 @@
{
(void) state; /* unused */
+ struct ly_ctx *ctx;
+
/* invalid arguments */
assert_int_equal(0, ly_ctx_get_module_set_id(NULL));
logbuf_assert("Invalid argument ctx (ly_ctx_get_module_set_id()).");
- struct ly_ctx *ctx;
+ will_return_always(__wrap_ly_set_add, 0);
assert_int_equal(LY_SUCCESS, ly_ctx_new(NULL, 0, &ctx));
assert_int_equal(ctx->module_set_id, ly_ctx_get_module_set_id(ctx));
@@ -267,12 +273,71 @@
ly_ctx_destroy(ctx, NULL);
}
+static void
+test_get_models(void **state)
+{
+ (void) state; /* unused */
+
+ struct ly_ctx *ctx;
+ const struct lys_module *mod, *mod2;
+ const char *str1 = "module a {namespace urn:a;prefix a;revision 2018-10-23;}";
+ const char *str2 = "module a {namespace urn:a;prefix a;revision 2018-10-23;revision 2018-10-24;}";
+
+ will_return_always(__wrap_ly_set_add, 0);
+ assert_int_equal(LY_SUCCESS, ly_ctx_new(NULL, 0, &ctx));
+
+ /* invalid arguments */
+ assert_ptr_equal(NULL, ly_ctx_get_module(NULL, NULL, NULL));
+ logbuf_assert("Invalid argument ctx (ly_ctx_get_module()).");
+ assert_ptr_equal(NULL, ly_ctx_get_module(ctx, NULL, NULL));
+ logbuf_assert("Invalid argument name (ly_ctx_get_module()).");
+ assert_ptr_equal(NULL, ly_ctx_get_module_ns(NULL, NULL, NULL));
+ logbuf_assert("Invalid argument ctx (ly_ctx_get_module_ns()).");
+ assert_ptr_equal(NULL, ly_ctx_get_module_ns(ctx, NULL, NULL));
+ logbuf_assert("Invalid argument ns (ly_ctx_get_module_ns()).");
+ assert_null(ly_ctx_get_module(ctx, "nonsence", NULL));
+
+ /* internal modules */
+ assert_null(ly_ctx_get_module_implemented(ctx, "ietf-yang-types"));
+ mod = ly_ctx_get_module_implemented(ctx, "yang");
+ assert_non_null(mod);
+ assert_non_null(mod->parsed);
+ assert_string_equal("yang", mod->parsed->name);
+ mod2 = ly_ctx_get_module_implemented_ns(ctx, mod->parsed->ns);
+ assert_ptr_equal(mod, mod2);
+ assert_non_null(ly_ctx_get_module(ctx, "ietf-yang-metadata", "2016-08-05"));
+ assert_non_null(ly_ctx_get_module(ctx, "ietf-yang-types", "2013-07-15"));
+ assert_non_null(ly_ctx_get_module(ctx, "ietf-inet-types", "2013-07-15"));
+ assert_non_null(ly_ctx_get_module(ctx, "ietf-datastores", "2017-08-17"));
+
+ /* select module by revision */
+ mod = lys_parse_mem(ctx, str1, LYS_IN_YANG);
+ /* invalid attempts - implementing module of the same name and inserting the same module */
+ assert_null(lys_parse_mem(ctx, str2, LYS_IN_YANG));
+ logbuf_assert("Module \"a\" is already implemented in the context.");
+ assert_null(lys_parse_mem_(ctx, str1, LYS_IN_YANG, NULL, 0));
+ logbuf_assert("Module \"a\" of revision \"2018-10-23\" is already present in the context.");
+ /* insert the second module only as imported, not implemented */
+ mod2 = lys_parse_mem_(ctx, str2, LYS_IN_YANG, NULL, 0);
+ assert_non_null(mod);
+ assert_non_null(mod2);
+ assert_ptr_not_equal(mod, mod2);
+ mod = ly_ctx_get_module_latest(ctx, "a");
+ assert_ptr_equal(mod, mod2);
+ mod2 = ly_ctx_get_module_latest_ns(ctx, mod->parsed->ns);
+ assert_ptr_equal(mod, mod2);
+
+ /* cleanup */
+ ly_ctx_destroy(ctx, NULL);
+}
+
int main(void)
{
const struct CMUnitTest tests[] = {
cmocka_unit_test_setup(test_searchdirs, logger_setup),
cmocka_unit_test_setup(test_options, logger_setup),
cmocka_unit_test_setup(test_models, logger_setup),
+ cmocka_unit_test_setup(test_get_models, logger_setup),
};
return cmocka_run_group_tests(tests, NULL, NULL);
diff --git a/tests/src/test_hash_table.c b/tests/src/test_hash_table.c
index 1afeb83..05cd1f9 100644
--- a/tests/src/test_hash_table.c
+++ b/tests/src/test_hash_table.c
@@ -12,8 +12,7 @@
* https://opensource.org/licenses/BSD-3-Clause
*/
-#define _BSD_SOURCE
-#define _DEFAULT_SOURCE
+#include "common.h"
#include "tests/config.h"
#include "../../src/hash_table.c"
diff --git a/tests/src/test_parser_yang.c b/tests/src/test_parser_yang.c
index db73f63..8f5085c 100644
--- a/tests/src/test_parser_yang.c
+++ b/tests/src/test_parser_yang.c
@@ -785,7 +785,7 @@
assert_string_equal("RFC7950", mod->ref));
/* revision */
TEST_GENERIC("revision 2018-10-12;}", mod->revs,
- assert_string_equal("2018-10-12", mod->revs[0].rev));
+ assert_string_equal("2018-10-12", mod->revs[0].date));
/* rpc */
TEST_GENERIC("rpc test;}", mod->rpcs,
assert_string_equal("test", mod->rpcs[0].name));
diff --git a/tests/src/test_set.c b/tests/src/test_set.c
index a6c53c4..982163f 100644
--- a/tests/src/test_set.c
+++ b/tests/src/test_set.c
@@ -11,9 +11,8 @@
*
* https://opensource.org/licenses/BSD-3-Clause
*/
+#include "common.h"
-#define _BSD_SOURCE
-#define _DEFAULT_SOURCE
#include <stdarg.h>
#include <stddef.h>
#include <setjmp.h>
diff --git a/tests/src/test_tree_schema_helpers.c b/tests/src/test_tree_schema_helpers.c
index 3dc7d7c..ac4e7bf 100644
--- a/tests/src/test_tree_schema_helpers.c
+++ b/tests/src/test_tree_schema_helpers.c
@@ -91,9 +91,9 @@
/* revisions are stored in wrong order - the newest is the last */
LY_ARRAY_NEW_RET(NULL, revs, rev,);
- strcpy(rev->rev, "2018-01-01");
+ strcpy(rev->date, "2018-01-01");
LY_ARRAY_NEW_RET(NULL, revs, rev,);
- strcpy(rev->rev, "2018-12-31");
+ strcpy(rev->date, "2018-12-31");
assert_int_equal(2, LY_ARRAY_SIZE(revs));
assert_string_equal("2018-01-01", &revs[0]);
diff --git a/tests/src/test_xml.c b/tests/src/test_xml.c
index 568e55e..95d1302 100644
--- a/tests/src/test_xml.c
+++ b/tests/src/test_xml.c
@@ -12,8 +12,8 @@
* https://opensource.org/licenses/BSD-3-Clause
*/
-#define _BSD_SOURCE
-#define _DEFAULT_SOURCE
+#include "common.h"
+
#include <stdarg.h>
#include <stddef.h>
#include <setjmp.h>