torture: smbtorture test case to verify Compound related handling
[Samba.git] / librpc / tests / test_ndr_dns_nbt.c
blob1e2ef45c10dd1aeb124e00b80fed0e2562b57e19
1 /*
2 * Tests for librpc ndr functions
4 * Copyright (C) Catalyst.NET Ltd 2020
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.
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.
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/>.
21 #include "replace.h"
22 #include <setjmp.h>
23 #include <cmocka.h>
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"
31 #define NBT_NAME "EOGFGLGPCACACACACACACACACACACACA" /* "neko" */
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)
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);
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--;
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';
63 s++;
66 *s = 0;
67 s++;
68 name.length = s - (char*)name.data;
69 return name;
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)
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);
84 char *name;
85 ndr_pull_flags_fn_t fn;
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;
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);
104 TALLOC_FREE(blob.data);
105 return name;
109 static void _test_ndr_push_dns_string_list(TALLOC_CTX *mem_ctx,
110 char *name,
111 bool is_nbt)
113 DATA_BLOB blob;
114 enum ndr_err_code ndr_err;
115 ndr_push_flags_fn_t fn;
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;
123 ndr_err = ndr_push_struct_blob(&blob,
124 mem_ctx,
125 name,
126 fn);
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);
137 static uint64_t elapsed_time(struct timespec start, const char *print)
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;
148 end.tv_nsec -= start.tv_nsec;
149 microsecs = end.tv_sec * 1000000;
150 microsecs += end.tv_nsec / 1000;
152 if (print != NULL) {
153 printf(" %s: %llu microseconds\n", print, microsecs);
155 return microsecs;
159 static void test_ndr_dns_string_half_dots(void **state)
161 TALLOC_CTX *mem_ctx = talloc_new(NULL);
162 char *name;
163 struct timespec start;
164 uint64_t elapsed;
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);
175 static void test_ndr_nbt_string_half_dots(void **state)
177 TALLOC_CTX *mem_ctx = talloc_new(NULL);
178 char *name;
179 struct timespec start;
180 uint64_t elapsed;
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);
191 static void test_ndr_dns_string_all_dots(void **state)
193 TALLOC_CTX *mem_ctx = talloc_new(NULL);
194 char *name;
195 struct timespec start;
196 uint64_t elapsed;
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);
207 static void test_ndr_nbt_string_all_dots(void **state)
209 TALLOC_CTX *mem_ctx = talloc_new(NULL);
210 char *name;
211 struct timespec start;
212 uint64_t elapsed;
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);
225 int main(int argc, const char **argv)
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),
234 cmocka_set_message_output(CM_OUTPUT_SUBUNIT);
235 return cmocka_run_group_tests(tests, NULL, NULL);