4 Copyright (C) Amitay Isaacs 2015
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 "system/filesys.h"
25 #include "common/pkt_read.c"
26 #include "common/pkt_write.c"
27 #include "common/comm.c"
30 * Test read_handler and dead_handler
33 static void test1_read_handler(uint8_t *buf
, size_t buflen
,
36 int *result
= (int *)private_data
;
41 static void test1_dead_handler(void *private_data
)
43 int *result
= (int *)private_data
;
48 static void test1(void)
51 struct tevent_context
*ev
;
52 struct comm_context
*comm
;
59 mem_ctx
= talloc_new(NULL
);
60 assert(mem_ctx
!= NULL
);
62 ev
= tevent_context_init(mem_ctx
);
68 ret
= comm_setup(ev
, ev
, fd
[0], test1_read_handler
, &result
,
69 test1_dead_handler
, &result
, &comm
);
72 data
[0] = 2 * sizeof(uint32_t);
75 n
= write(fd
[1], (void *)&data
, data
[0]);
97 * Test that the tevent_req returned by comm_write_send() can be free'd.
105 static void test2_read_handler(uint8_t *buf
, size_t buflen
,
108 struct test2_state
*state
= (struct test2_state
*)private_data
;
110 TALLOC_FREE(state
->mem_ctx
);
113 static void test2_dead_handler(void *private_data
)
118 struct test2_write_state
{
122 static void test2_write_done(struct tevent_req
*subreq
);
124 static struct tevent_req
*test2_write_send(TALLOC_CTX
*mem_ctx
,
125 struct tevent_context
*ev
,
126 struct comm_context
*comm
,
127 uint8_t *buf
, size_t buflen
)
129 struct tevent_req
*req
, *subreq
;
130 struct test2_write_state
*state
;
133 req
= tevent_req_create(mem_ctx
, &state
, struct test2_write_state
);
140 for (i
=0; i
<10; i
++) {
141 subreq
= comm_write_send(state
, ev
, comm
, buf
, buflen
);
142 if (tevent_req_nomem(subreq
, req
)) {
143 return tevent_req_post(req
, ev
);
145 tevent_req_set_callback(subreq
, test2_write_done
, req
);
151 static void test2_write_done(struct tevent_req
*subreq
)
153 struct tevent_req
*req
= tevent_req_callback_data(
154 subreq
, struct tevent_req
);
155 struct test2_write_state
*state
= tevent_req_data(
156 req
, struct test2_write_state
);
160 status
= comm_write_recv(subreq
, &ret
);
163 tevent_req_error(req
, ret
);
169 if (state
->count
== 10) {
170 tevent_req_done(req
);
174 static void test2_timer_handler(struct tevent_context
*ev
,
175 struct tevent_timer
*te
,
176 struct timeval cur_time
,
179 struct test2_state
*state
= (struct test2_state
*)private_data
;
184 static void test2(void)
187 struct tevent_context
*ev
;
188 struct comm_context
*comm_reader
, *comm_writer
;
189 struct test2_state test2_state
;
190 struct tevent_req
*req
;
191 struct tevent_timer
*te
;
196 mem_ctx
= talloc_new(NULL
);
197 assert(mem_ctx
!= NULL
);
199 test2_state
.mem_ctx
= talloc_new(mem_ctx
);
200 assert(test2_state
.mem_ctx
!= NULL
);
202 test2_state
.done
= false;
204 ev
= tevent_context_init(mem_ctx
);
210 ret
= comm_setup(ev
, ev
, fd
[0], test2_read_handler
, &test2_state
,
211 test2_dead_handler
, NULL
, &comm_reader
);
214 ret
= comm_setup(ev
, ev
, fd
[1], NULL
, NULL
, test2_dead_handler
, NULL
,
218 data
[0] = 2 * sizeof(uint32_t);
221 req
= test2_write_send(test2_state
.mem_ctx
, ev
, comm_writer
,
222 (uint8_t *)data
, data
[0]);
225 te
= tevent_add_timer(ev
, ev
, tevent_timeval_current_ofs(5,0),
226 test2_timer_handler
, &test2_state
);
229 while (! test2_state
.done
) {
230 tevent_loop_once(ev
);
233 talloc_free(mem_ctx
);
237 * Test that data is written and read correctly.
240 static void test3_dead_handler(void *private_data
)
242 int dead_data
= *(int *)private_data
;
244 assert(dead_data
== 1 || dead_data
== 2);
246 if (dead_data
== 1) {
248 fprintf(stderr
, "writer closed pipe\n");
251 fprintf(stderr
, "reader closed pipe\n");
255 struct test3_writer_state
{
256 struct tevent_context
*ev
;
257 struct comm_context
*comm
;
263 static void test3_writer_next(struct tevent_req
*subreq
);
265 static struct tevent_req
*test3_writer_send(TALLOC_CTX
*mem_ctx
,
266 struct tevent_context
*ev
,
267 struct comm_context
*comm
,
268 size_t *pkt_size
, size_t count
)
270 struct tevent_req
*req
, *subreq
;
271 struct test3_writer_state
*state
;
272 size_t max_size
= 0, buflen
;
275 for (i
=0; i
<count
; i
++) {
276 if (pkt_size
[i
] > max_size
) {
277 max_size
= pkt_size
[i
];
281 req
= tevent_req_create(mem_ctx
, &state
, struct test3_writer_state
);
288 state
->pkt_size
= pkt_size
;
289 state
->count
= count
;
292 state
->buf
= talloc_array(state
, uint8_t, max_size
);
293 if (state
->buf
== NULL
) {
297 for (i
=0; i
<max_size
; i
++) {
298 state
->buf
[i
] = i
%256;
301 buflen
= state
->pkt_size
[state
->id
];
302 *(uint32_t *)state
->buf
= buflen
;
303 subreq
= comm_write_send(state
, state
->ev
, state
->comm
,
305 if (tevent_req_nomem(subreq
, req
)) {
306 return tevent_req_post(req
, ev
);
309 tevent_req_set_callback(subreq
, test3_writer_next
, req
);
313 static void test3_writer_next(struct tevent_req
*subreq
)
315 struct tevent_req
*req
= tevent_req_callback_data(
316 subreq
, struct tevent_req
);
317 struct test3_writer_state
*state
= tevent_req_data(
318 req
, struct test3_writer_state
);
323 ret
= comm_write_recv(subreq
, &err
);
326 tevent_req_error(req
, err
);
331 if (state
->id
>= state
->count
) {
332 tevent_req_done(req
);
336 buflen
= state
->pkt_size
[state
->id
];
337 *(uint32_t *)state
->buf
= buflen
;
338 subreq
= comm_write_send(state
, state
->ev
, state
->comm
,
340 if (tevent_req_nomem(subreq
, req
)) {
344 tevent_req_set_callback(subreq
, test3_writer_next
, req
);
347 static void test3_writer_recv(struct tevent_req
*req
, int *perr
)
349 if (tevent_req_is_unix_error(req
, perr
)) {
355 static void test3_writer(int fd
, size_t *pkt_size
, size_t count
)
358 struct tevent_context
*ev
;
359 struct comm_context
*comm
;
360 struct tevent_req
*req
;
364 mem_ctx
= talloc_new(NULL
);
365 assert(mem_ctx
!= NULL
);
367 ev
= tevent_context_init(mem_ctx
);
370 err
= comm_setup(mem_ctx
, ev
, fd
, NULL
, NULL
,
371 test3_dead_handler
, &dead_data
, &comm
);
373 assert(comm
!= NULL
);
375 req
= test3_writer_send(mem_ctx
, ev
, comm
, pkt_size
, count
);
378 tevent_req_poll(req
, ev
);
380 test3_writer_recv(req
, &err
);
383 talloc_free(mem_ctx
);
386 struct test3_reader_state
{
392 static void test3_reader_handler(uint8_t *buf
, size_t buflen
,
395 struct test3_reader_state
*state
= talloc_get_type_abort(
396 private_data
, struct test3_reader_state
);
398 assert(buflen
== state
->pkt_size
[state
->received
]);
399 printf("%zi ", buflen
);
402 if (state
->received
== state
->count
) {
408 static void test3_reader(int fd
, size_t *pkt_size
, int count
)
411 struct tevent_context
*ev
;
412 struct comm_context
*comm
;
413 struct test3_reader_state
*state
;
417 mem_ctx
= talloc_new(NULL
);
418 assert(mem_ctx
!= NULL
);
420 ev
= tevent_context_init(mem_ctx
);
423 state
= talloc_zero(mem_ctx
, struct test3_reader_state
);
424 assert(state
!= NULL
);
426 state
->pkt_size
= pkt_size
;
427 state
->count
= count
;
431 err
= comm_setup(mem_ctx
, ev
, fd
, test3_reader_handler
, state
,
432 test3_dead_handler
, &dead_data
, &comm
);
434 assert(comm
!= NULL
);
436 while (!state
->done
) {
437 tevent_loop_once(ev
);
440 talloc_free(mem_ctx
);
443 static void test3(void)
448 size_t pkt_size
[13] = { 100, 2048, 500, 4096, 1024, 8192,
449 200, 16384, 300, 32768, 400, 65536,
461 test3_writer(fd
[1], pkt_size
, 13);
467 test3_reader(fd
[0], pkt_size
, 13);
472 int main(int argc
, const char **argv
)
477 fprintf(stderr
, "%s <testnum>\n", argv
[0]);
497 fprintf(stderr
, "Unknown test number %s\n", argv
[1]);