libndr: Avoid assigning duplicate versions to symbols
[amitay/samba.git] / librpc / tests / test_ndr_dns_nbt.c
1 /*
2  * Tests for librpc ndr functions
3  *
4  * Copyright (C) Catalyst.NET Ltd 2020
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
18  *
19  */
20
21 #include "replace.h"
22 #include <setjmp.h>
23 #include <cmocka.h>
24
25 #include "includes.h"
26 #include "librpc/ndr/libndr.h"
27 #include "librpc/gen_ndr/ndr_dns.h"
28 #include "librpc/gen_ndr/ndr_nbt.h"
29 #include "lib/util/time.h"
30
31 #define NBT_NAME "EOGFGLGPCACACACACACACACACACACACA" /* "neko" */
32
33
34 static DATA_BLOB generate_obnoxious_dns_name(TALLOC_CTX *mem_ctx,
35                                              size_t n_labels,
36                                              size_t dot_every,
37                                              bool is_nbt)
38 {
39         size_t i, j;
40         char *s;
41         DATA_BLOB name = data_blob_talloc(mem_ctx, NULL, 64 * n_labels + 1);
42         assert_non_null(name.data);
43
44         s = (char*)name.data;
45         if (is_nbt) {
46                 size_t len = strlen(NBT_NAME);
47                 *s = len;
48                 s++;
49                 memcpy(s, NBT_NAME, len);
50                 s += len;
51                 n_labels--;
52         }
53
54         for (i = 0; i < n_labels; i++) {
55                 *s = 63;
56                 s++;
57                 for (j = 0; j < 63; j++) {
58                         if (j % dot_every == (dot_every - 1)) {
59                                 *s = '.';
60                         } else {
61                                 *s = 'x';
62                         }
63                         s++;
64                 }
65         }
66         *s = 0;
67         s++;
68         name.length = s - (char*)name.data;
69         return name;
70 }
71
72
73 static char *_test_ndr_pull_dns_string_list(TALLOC_CTX *mem_ctx,
74                                             size_t n_labels,
75                                             size_t dot_every,
76                                             bool is_nbt)
77 {
78         enum ndr_err_code ndr_err;
79         DATA_BLOB blob = generate_obnoxious_dns_name(mem_ctx,
80                                                      n_labels,
81                                                      dot_every,
82                                                      is_nbt);
83
84         char *name;
85         ndr_pull_flags_fn_t fn;
86
87         if (is_nbt) {
88                 fn = (ndr_pull_flags_fn_t)ndr_pull_nbt_string;
89         } else {
90                 fn = (ndr_pull_flags_fn_t)ndr_pull_dns_string;
91         }
92
93         ndr_err = ndr_pull_struct_blob(&blob,
94                                        mem_ctx,
95                                        &name,
96                                        fn);
97         /* Success here is not expected, but we let it go to measure timing. */
98         if (ndr_err == NDR_ERR_SUCCESS) {
99                 printf("pull succeed\n");
100         } else {
101                 assert_int_equal(ndr_err, NDR_ERR_STRING);
102         }
103
104         TALLOC_FREE(blob.data);
105         return name;
106 }
107
108
109 static void _test_ndr_push_dns_string_list(TALLOC_CTX *mem_ctx,
110                                            char *name,
111                                            bool is_nbt)
112 {
113         DATA_BLOB blob;
114         enum ndr_err_code ndr_err;
115         ndr_push_flags_fn_t fn;
116
117         if (is_nbt) {
118                 fn = (ndr_push_flags_fn_t)ndr_push_nbt_string;
119         } else {
120                 fn = (ndr_push_flags_fn_t)ndr_push_dns_string;
121         }
122
123         ndr_err = ndr_push_struct_blob(&blob,
124                                        mem_ctx,
125                                        name,
126                                        fn);
127
128         /* Success here is not expected, but we let it go to measure timing. */
129         if (ndr_err == NDR_ERR_SUCCESS) {
130                 printf("push succeed\n");
131         } else {
132                 assert_int_equal(ndr_err, NDR_ERR_STRING);
133         }
134 }
135
136
137 static uint64_t elapsed_time(struct timespec start, const char *print)
138 {
139         struct timespec end;
140         unsigned long long microsecs;
141         clock_gettime_mono(&end);
142         end.tv_sec -= start.tv_sec;
143         if (end.tv_nsec < start.tv_nsec) {
144                 /* we need to borrow */
145                 end.tv_nsec += 1000 * 1000 * 1000;
146                 end.tv_sec -= 1;
147         }
148         end.tv_nsec -= start.tv_nsec;
149         microsecs = end.tv_sec * 1000000;
150         microsecs += end.tv_nsec / 1000;
151
152         if (print != NULL) {
153                 printf(" %s: %llu microseconds\n", print, microsecs);
154         }
155         return microsecs;
156 }
157
158
159 static void test_ndr_dns_string_half_dots(void **state)
160 {
161         TALLOC_CTX *mem_ctx = talloc_new(NULL);
162         char *name;
163         struct timespec start;
164         uint64_t elapsed;
165
166         clock_gettime_mono(&start);
167         name =_test_ndr_pull_dns_string_list(mem_ctx, 127, 2, false);
168         elapsed_time(start, "pull");
169         _test_ndr_push_dns_string_list(mem_ctx, name, false);
170         elapsed = elapsed_time(start, "total");
171         assert_in_range(elapsed, 0, 200000);
172         talloc_free(mem_ctx);
173 }
174
175 static void test_ndr_nbt_string_half_dots(void **state)
176 {
177         TALLOC_CTX *mem_ctx = talloc_new(NULL);
178         char *name;
179         struct timespec start;
180         uint64_t elapsed;
181
182         clock_gettime_mono(&start);
183         name =_test_ndr_pull_dns_string_list(mem_ctx, 127, 2, true);
184         elapsed_time(start, "pull");
185         _test_ndr_push_dns_string_list(mem_ctx, name, true);
186         elapsed = elapsed_time(start, "total");
187         assert_in_range(elapsed, 0, 200000);
188         talloc_free(mem_ctx);
189 }
190
191 static void test_ndr_dns_string_all_dots(void **state)
192 {
193         TALLOC_CTX *mem_ctx = talloc_new(NULL);
194         char *name;
195         struct timespec start;
196         uint64_t elapsed;
197
198         clock_gettime_mono(&start);
199         name =_test_ndr_pull_dns_string_list(mem_ctx, 127, 1, false);
200         elapsed_time(start, "pull");
201         _test_ndr_push_dns_string_list(mem_ctx, name, false);
202         elapsed = elapsed_time(start, "total");
203         assert_in_range(elapsed, 0, 200000);
204         talloc_free(mem_ctx);
205 }
206
207 static void test_ndr_nbt_string_all_dots(void **state)
208 {
209         TALLOC_CTX *mem_ctx = talloc_new(NULL);
210         char *name;
211         struct timespec start;
212         uint64_t elapsed;
213
214         clock_gettime_mono(&start);
215         name =_test_ndr_pull_dns_string_list(mem_ctx, 127, 1, true);
216         elapsed_time(start, "pull");
217         _test_ndr_push_dns_string_list(mem_ctx, name, true);
218         elapsed = elapsed_time(start, "total");
219         assert_in_range(elapsed, 0, 200000);
220         talloc_free(mem_ctx);
221 }
222
223
224
225 int main(int argc, const char **argv)
226 {
227         const struct CMUnitTest tests[] = {
228                 cmocka_unit_test(test_ndr_nbt_string_half_dots),
229                 cmocka_unit_test(test_ndr_dns_string_half_dots),
230                 cmocka_unit_test(test_ndr_nbt_string_all_dots),
231                 cmocka_unit_test(test_ndr_dns_string_all_dots),
232         };
233
234         cmocka_set_message_output(CM_OUTPUT_SUBUNIT);
235         return cmocka_run_group_tests(tests, NULL, NULL);
236 }