1 /*
2 * SysDB - t/unit/utils/channel_test.c
3 * Copyright (C) 2013 Sebastian 'tokkee' Harl <sh@tokkee.org>
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
17 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
18 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR
19 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
28 #include "utils/channel.h"
29 #include "libsysdb_test.h"
31 #include <check.h>
32 #include <errno.h>
33 #include <limits.h>
35 #include <stdint.h>
37 static struct {
38 int data;
39 int expected_write;
40 int expected_read;
41 } golden_data_int[] = {
42 { 5, 0, 0 },
43 { 15, 0, 0 },
44 { -3, 0, 0 },
45 { INT_MAX, 0, 0 },
46 { 27, 0, 0 },
47 { 42, 0, 0 },
48 { 6, 0, 0 },
49 { 2854, 0, 0 },
50 { 10562, 0, 0 },
51 { 0, 0, 0 },
53 /* exceeding buffer size */
54 { 20, -1, -1 },
55 { 42, -1, -1 },
56 };
58 static struct {
59 char *data;
60 int expected_write;
61 int expected_read;
62 } golden_data_string[] = {
63 { "c", 0, 0 },
64 { "", 0, 0 },
65 { "abc", 0, 0 },
66 { "foobar", 0, 0 },
67 { "qux", 0, 0 },
68 { "a b c", 0, 0 },
69 { "123", 0, 0 },
70 { "xyz", 0, 0 },
71 { "b", 0, 0 },
72 { "a", 0, 0 },
74 /* exceeding buffer size */
75 { "err1", -1, -1 },
76 { "err2", -1, -1 },
77 };
79 static sdb_channel_t *chan;
81 static void
82 setup_int(void)
83 {
84 chan = sdb_channel_create(10, sizeof(int));
85 fail_unless(chan != NULL,
86 "sdb_channel_create(10, sizeof(int)) = NULL; "
87 "expected list object");
88 } /* setup_int */
90 static void
91 setup_string(void)
92 {
93 chan = sdb_channel_create(10, sizeof(char *));
94 fail_unless(chan != NULL,
95 "sdb_chan_create(10, sizeof(char *))) = NULL; "
96 "expected channel object");
97 } /* setup_string */
99 static void
100 teardown(void)
101 {
102 sdb_channel_destroy(chan);
103 chan = NULL;
104 } /* teardown */
106 START_TEST(test_create)
107 {
108 chan = sdb_channel_create(0, 0);
109 fail_unless(chan == NULL,
110 "sdb_channel_create(0, 0) = %p; expected: NULL", chan);
112 chan = sdb_channel_create(0, 1);
113 fail_unless(chan != NULL,
114 "sdb_channel_create(0, 1) = NULL; expected: channel object");
115 sdb_channel_destroy(chan);
117 chan = sdb_channel_create(42, 23);
118 fail_unless(chan != NULL,
119 "sdb_channel_create(32, 23) = NULL; expected: channel object");
120 sdb_channel_destroy(chan);
121 }
122 END_TEST
124 START_TEST(test_write_read)
125 {
126 uint32_t data;
127 int check;
129 chan = sdb_channel_create(0, 1);
130 fail_unless(chan != NULL,
131 "sdb_channel_create(0, 0) = NULL; expected: channel object");
133 data = 0x00ffff00;
134 check = sdb_channel_write(chan, &data);
135 fail_unless(!check, "sdb_channel_write() = %i; expected: 0", check);
136 check = sdb_channel_write(chan, &data);
137 fail_unless(check, "sdb_channel_write() = 0; expected: <0");
139 data = 0xffffffff;
140 check = sdb_channel_read(chan, &data);
141 fail_unless(check == 0,
142 "sdb_channel_read() = %d; expected: 0", check);
143 /* result depends on endianess */
144 fail_unless((data == 0xffffff00) || (data == 0x00ffffff),
145 "sdb_channel_read() returned data %x; "
146 "expected: 0xffffff00 || 0x00ffffff", data);
148 sdb_channel_destroy(chan);
149 }
150 END_TEST
152 START_TEST(test_select)
153 {
154 struct timespec ts = { 0, 10 };
155 int check;
156 int data;
158 chan = sdb_channel_create(0, 1);
160 errno = 0;
161 check = sdb_channel_select(chan, &data, NULL, NULL, NULL, &ts);
162 fail_unless(check < ETIMEDOUT,
163 "sdb_channel_select() = %i; expected: <0", check);
164 fail_unless(errno == ETIMEDOUT,
165 "sdb_channel_select() set errno to %i; expected: %i (ETIMEDOUT)",
166 errno, ETIMEDOUT);
168 check = sdb_channel_select(chan, NULL, NULL, &data, NULL, NULL);
169 fail_unless(! check, "sdb_channel_select() = %i; expected: 0", check);
170 check = sdb_channel_select(chan, NULL, NULL, &data, NULL, &ts);
171 fail_unless(! check, "sdb_channel_select() = %i; expected: 0", check);
173 sdb_channel_destroy(chan);
174 }
175 END_TEST
177 START_TEST(test_write_int)
178 {
179 size_t i;
180 for (i = 0; i < SDB_STATIC_ARRAY_LEN(golden_data_int); ++i) {
181 int data = golden_data_int[i].data;
182 int expected = golden_data_int[i].expected_write;
184 int check = sdb_channel_write(chan, &data);
185 fail_unless(check == expected,
186 "sdb_channel_write(chan, %i) = %i; expected: %i",
187 data, check, expected);
188 }
189 }
190 END_TEST
192 START_TEST(test_read_int)
193 {
194 size_t i;
196 /* populate */
197 for (i = 0; i < SDB_STATIC_ARRAY_LEN(golden_data_int); ++i) {
198 int data = golden_data_int[i].data;
199 int expected = golden_data_int[i].expected_write;
201 int check = sdb_channel_write(chan, &data);
202 fail_unless(check == expected,
203 "sdb_channel_write(chan, %i) = %i; expected: %i",
204 data, check, expected);
205 }
207 for (i = 0; i < SDB_STATIC_ARRAY_LEN(golden_data_int); ++i) {
208 int data = (int)i;
209 int expected = golden_data_int[i].expected_read;
211 int check = sdb_channel_read(chan, &data);
212 fail_unless(check == expected,
213 "sdb_channel_read(chan, %i) = %i; expected: %i",
214 data, check, expected);
215 if (check) {
216 fail_unless(data == (int)i,
217 "sdb_channel_read() modified data to '%i'; "
218 "expected: no modification", data);
219 }
220 else {
221 fail_unless(data == golden_data_int[i].data,
222 "sdb_channel_read() returned data %i; expected: %i",
223 data, golden_data_int[i].data);
224 }
225 }
226 }
227 END_TEST
229 START_TEST(test_write_read_int)
230 {
231 size_t i;
232 for (i = 0; i < SDB_STATIC_ARRAY_LEN(golden_data_int); ++i) {
233 int data = golden_data_int[i].data;
234 int check = sdb_channel_write(chan, &data);
235 fail_unless(check == 0,
236 "sdb_channel_write(chan, %i) = %i; expected: 0",
237 data, check);
239 data = (int)i;
240 check = sdb_channel_read(chan, &data);
241 fail_unless(check == 0,
242 "sdb_channel_read(chan, %i) = %i; expected: 0",
243 data, check);
244 if (check) {
245 fail_unless(data == (int)i,
246 "sdb_channel_read() modified data to '%i'; "
247 "expected: no modification", data);
248 }
249 else {
250 fail_unless(data == golden_data_int[i].data,
251 "sdb_channel_read() returned data %i; expected: %i",
252 data, golden_data_int[i].data);
253 }
254 }
255 }
256 END_TEST
258 START_TEST(test_write_string)
259 {
260 size_t i;
261 for (i = 0; i < SDB_STATIC_ARRAY_LEN(golden_data_string); ++i) {
262 char *data = golden_data_string[i].data;
263 int expected = golden_data_string[i].expected_write;
265 int check = sdb_channel_write(chan, &data);
266 fail_unless(check == expected,
267 "sdb_channel_write(chan, '%s') = %i; expected: %i",
268 data, check, expected);
269 }
270 }
271 END_TEST
273 START_TEST(test_read_string)
274 {
275 size_t i;
277 /* populate */
278 for (i = 0; i < SDB_STATIC_ARRAY_LEN(golden_data_string); ++i) {
279 char *data = golden_data_string[i].data;
280 int expected = golden_data_string[i].expected_write;
282 int check = sdb_channel_write(chan, &data);
283 fail_unless(check == expected,
284 "sdb_channel_write(chan, '%s') = %i; expected: %i",
285 data, check, expected);
286 }
288 for (i = 0; i < SDB_STATIC_ARRAY_LEN(golden_data_string); ++i) {
289 char *data = NULL;
290 int expected = golden_data_string[i].expected_read;
292 int check = sdb_channel_read(chan, &data);
293 fail_unless(check == expected,
294 "sdb_channel_read(chan, '') = %i; expected: %i",
295 check, expected);
296 if (check) {
297 fail_unless(data == NULL,
298 "sdb_channel_read() modified data to '%s'; "
299 "expected: no modification", data);
300 }
301 else {
302 fail_unless(data != NULL,
303 "sdb_channel_read() did not return any data");
304 fail_unless(!strcmp(data, golden_data_string[i].data),
305 "sdb_channel_read() returned data '%s'; expected: '%s'",
306 data, golden_data_string[i].data);
307 }
308 }
309 }
310 END_TEST
312 START_TEST(test_write_read_string)
313 {
314 size_t i;
315 for (i = 0; i < SDB_STATIC_ARRAY_LEN(golden_data_string); ++i) {
316 char *data = golden_data_string[i].data;
317 int check = sdb_channel_write(chan, &data);
318 fail_unless(check == 0,
319 "sdb_channel_write(chan, '%s') = %i; expected: 0",
320 data, check);
322 data = NULL;
323 check = sdb_channel_read(chan, &data);
324 fail_unless(check == 0,
325 "sdb_channel_read(chan, '') = %i; expected: 0", check);
326 if (check) {
327 fail_unless(data == NULL,
328 "sdb_channel_read() modified data to '%s'; "
329 "expected: no modifications", data);
330 }
331 else {
332 fail_unless(data != NULL,
333 "sdb_channel_read() did not return any data");
334 fail_unless(!strcmp(data, golden_data_string[i].data),
335 "sdb_channel_read() returned data '%s'; expected: '%s'",
336 data, golden_data_string[i].data);
337 }
338 }
339 }
340 END_TEST
342 Suite *
343 util_channel_suite(void)
344 {
345 Suite *s = suite_create("utils::channel");
346 TCase *tc;
348 tc = tcase_create("core");
349 tcase_add_test(tc, test_create);
350 tcase_add_test(tc, test_write_read);
351 tcase_add_test(tc, test_select);
352 suite_add_tcase(s, tc);
354 tc = tcase_create("integer");
355 tcase_add_checked_fixture(tc, setup_int, teardown);
356 tcase_add_test(tc, test_write_int);
357 tcase_add_test(tc, test_read_int);
358 tcase_add_test(tc, test_write_read_int);
359 suite_add_tcase(s, tc);
361 tc = tcase_create("string");
362 tcase_add_checked_fixture(tc, setup_string, teardown);
363 tcase_add_test(tc, test_write_string);
364 tcase_add_test(tc, test_read_string);
365 tcase_add_test(tc, test_write_read_string);
366 suite_add_tcase(s, tc);
368 return s;
369 } /* util_llist_suite */
371 /* vim: set tw=78 sw=4 ts=4 noexpandtab : */