1 /**
2  * @file test_sec5_1.c
3  * @author Pavol Vican
4  * @brief Cmocka test for RFC 6020 section 5.1. conformance.
5  *
6  * Copyright (c) 2016 CESNET, z.s.p.o.
7  *
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  */
14 
15 #include <stdio.h>
16 #include <stdlib.h>
17 #include <setjmp.h>
18 #include <errno.h>
19 #include <unistd.h>
20 #include <stdarg.h>
21 #include <cmocka.h>
22 #include <string.h>
23 #include <sys/wait.h>
24 
25 #include "tests/config.h"
26 #include "libyang.h"
27 
28 #define TEST_DIR "sec5_1"
29 #define TEST_NAME test_sec5_1
30 #define TEST_SCHEMA_COUNT 6
31 #define TEST_SCHEMA_LOAD_FAIL 1,1,1,1,1,0
32 #define TEST_DATA_FILE_COUNT 0
33 #define TEST_DATA_FILE_LOAD_FAIL 0
34 
35 struct state {
36     struct ly_ctx *ctx;
37     struct lyd_node *node;
38 };
39 
40 static int
setup_f(void ** state)41 setup_f(void **state)
42 {
43     struct state *st;
44 
45     (*state) = st = calloc(1, sizeof *st);
46     if (!st) {
47         fprintf(stderr, "Memory allocation error");
48         return -1;
49     }
50 
51     /* libyang context */
52     st->ctx = ly_ctx_new(TESTS_DIR "/conformance/" TEST_DIR, 0);
53     if (!st->ctx) {
54         fprintf(stderr, "Failed to create context.\n");
55         return -1;
56     }
57 
58     return 0;
59 }
60 
61 static int
teardown_f(void ** state)62 teardown_f(void **state)
63 {
64     struct state *st = (*state);
65 
66     lyd_free(st->node);
67     ly_ctx_destroy(st->ctx, NULL);
68     free(st);
69     (*state) = NULL;
70 
71     return 0;
72 }
73 
74 static void
TEST_IMPORT_INCLUDE(void ** state)75 TEST_IMPORT_INCLUDE(void **state)
76 {
77     struct state *st = (*state);
78     const int schemas_fail[] = {TEST_SCHEMA_LOAD_FAIL};
79     const int data_files_fail[] = {TEST_DATA_FILE_LOAD_FAIL};
80     char buf[1024];
81     LYS_INFORMAT schema_format = LYS_IN_YANG;
82     const struct lys_module *mod;
83     int i, j, ret;
84 
85     for (i = 0; i < 2; ++i) {
86         for (j = 0; j < TEST_SCHEMA_COUNT; ++j) {
87             sprintf(buf, TESTS_DIR "/conformance/" TEST_DIR "/mod%d.%s", j + 1, (schema_format == LYS_IN_YANG ? "yang" : "yin"));
88             mod = lys_parse_path(st->ctx, buf, schema_format);
89             if (schemas_fail[j]) {
90                 assert_ptr_equal(mod, NULL);
91             } else {
92                 assert_ptr_not_equal(mod, NULL);
93             }
94         }
95 
96         for (j = 0; j < TEST_DATA_FILE_COUNT; ++j) {
97             sprintf(buf, TESTS_DIR "/conformance/data%d.xml", j + 1);
98             st->node = lyd_parse_path(st->ctx, buf, LYD_XML, LYD_OPT_CONFIG);
99             if (data_files_fail[j]) {
100                 assert_ptr_not_equal(st->node, NULL);
101             } else {
102                 assert_ptr_equal(st->node, NULL);
103             }
104         }
105 
106         if (schema_format == LYS_IN_YANG) {
107             /* convert the modules */
108             for (j = 0; j < TEST_SCHEMA_COUNT; ++j) {
109                 sprintf(buf, BUILD_DIR "/yang2yin "
110                              TESTS_DIR "/conformance/" TEST_DIR "/mod%d.yang "
111                              TESTS_DIR "/conformance/" TEST_DIR "/mod%d.yin", j + 1, j + 1);
112                 ret = system(buf);
113                 if (ret == -1) {
114                     fprintf(stderr, "system() failed (%s).\n", strerror(errno));
115                     fail();
116                 } else if (WEXITSTATUS(ret) != 0) {
117                     fprintf(stderr, "Executing command \"%s\" finished with %d.\n", buf, WEXITSTATUS(ret));
118                     fail();
119                 }
120             }
121 
122             schema_format = LYS_IN_YIN;
123             ly_ctx_destroy(st->ctx, NULL);
124             st->ctx = ly_ctx_new(TESTS_DIR "/conformance/" TEST_DIR, 0);
125             if (!st->ctx) {
126                 fprintf(stderr, "Failed to create context.\n");
127                 fail();
128             }
129         } else {
130             /* remove the modules */
131             for (j = 0; j < TEST_SCHEMA_COUNT; ++j) {
132                 sprintf(buf, TESTS_DIR "/conformance/" TEST_DIR "/mod%d.yin", j + 1);
133                 if (unlink(buf)) {
134                     fprintf(stderr, "unlink() on \"%s\" failed (%s).\n", buf, strerror(errno));
135                 }
136             }
137         }
138     }
139 }
140 
141 int
main(void)142 main(void)
143 {
144     const struct CMUnitTest tests[] = {
145         cmocka_unit_test_setup_teardown(TEST_IMPORT_INCLUDE, setup_f, teardown_f),
146     };
147 
148     return cmocka_run_group_tests(tests, NULL, NULL);
149 }
150 
151