1 /*
2    Unix SMB/CIFS implementation.
3 
4    testing of the events subsystem
5 
6    Copyright (C) Stefan Metzmacher
7 
8    This program is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 2 of the License, or
11    (at your option) any later version.
12 
13    This program is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17 
18    You should have received a copy of the GNU General Public License
19    along with this program; if not, write to the Free Software
20    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22 
23 #include "includes.h"
24 #include "lib/events/events.h"
25 #include "system/filesys.h"
26 #include "torture/torture.h"
27 
28 const struct event_ops *event_standard_get_ops(void);
29 const struct event_ops *event_liboop_get_ops(void);
30 const struct event_ops *gtk_event_get_ops(void);
31 
32 static int write_fd, read_fd;
33 static struct fd_event *fde;
34 static int te_count;
35 static int fde_count;
36 static struct torture_context *test;
37 
fde_handler(struct event_context * ev_ctx,struct fd_event * f,uint16_t flags,void * private)38 static void fde_handler(struct event_context *ev_ctx, struct fd_event *f,
39 			uint16_t flags, void *private)
40 {
41 	int *fd = private;
42 
43 	torture_comment(test, "event[%d] fd[%d] events[0x%08X]%s%s\n",
44 						fde_count, *fd, flags,
45 					(flags & EVENT_FD_READ)?" EVENT_FD_READ":"",
46 					(flags & EVENT_FD_WRITE)?" EVENT_FD_WRITE":"");
47 
48 	if (fde_count > 5) {
49 		torture_result(test, TORTURE_FAIL,
50 					   __location__": got more than fde 5 events - bug!");
51 		talloc_free(fde);
52 		fde = NULL;
53 		return;
54 	}
55 
56 	event_set_fd_flags(fde, 0);
57 	fde_count++;
58 }
59 
timed_handler(struct event_context * ev_ctx,struct timed_event * te,struct timeval tval,void * private)60 static void timed_handler(struct event_context *ev_ctx, struct timed_event *te,
61 			  struct timeval tval, void *private)
62 {
63 	torture_comment(test, "timed_handler called[%d]\n", te_count);
64 	if (te_count > 2) {
65 		close(write_fd);
66 		write_fd = -1;
67 	}
68 	if (te_count > 5) {
69 		torture_comment(test, "remove fd event!\n");
70 		talloc_free(fde);
71 		fde = NULL;
72 		return;
73 	}
74 	te_count++;
75 	event_add_timed(ev_ctx, ev_ctx, timeval_current_ofs(0,500), timed_handler, private);
76 }
77 
test_event_context(struct torture_context * torture_ctx,const void * test_data)78 static bool test_event_context(struct torture_context *torture_ctx,
79 							   const void *test_data)
80 {
81 	struct event_context *ev_ctx;
82 	int fd[2] = { -1, -1 };
83 	BOOL try_epoll = (BOOL)test_data;
84 	TALLOC_CTX *mem_ctx = torture_ctx;
85 
86 	ev_ctx = event_context_init_ops(mem_ctx,
87 									event_standard_get_ops(),
88 									&try_epoll);
89 
90 	test = torture_ctx;
91 
92 	/* reset globals */
93 	write_fd = -1;
94 	read_fd = -1;
95 	fde = NULL;
96 	te_count = 0;
97 	fde_count = 0;
98 
99 	/* create a pipe */
100 	pipe(fd);
101 	read_fd = fd[0];
102 	write_fd = fd[1];
103 
104 	fde = event_add_fd(ev_ctx, ev_ctx, read_fd, EVENT_FD_READ, fde_handler, &read_fd);
105 
106 	event_add_timed(ev_ctx, ev_ctx, timeval_current_ofs(0,500), timed_handler, fde);
107 
108 	event_loop_wait(ev_ctx);
109 
110 	close(read_fd);
111 	close(write_fd);
112 
113 	talloc_free(ev_ctx);
114 	return true;
115 }
116 
torture_local_event(TALLOC_CTX * mem_ctx)117 struct torture_suite *torture_local_event(TALLOC_CTX *mem_ctx)
118 {
119 	struct torture_suite *suite = torture_suite_create(mem_ctx, "EVENT");
120 
121 	torture_suite_add_simple_tcase(suite, "standard with select",
122 								   test_event_context,
123 								   (void *)False);
124 
125 	torture_suite_add_simple_tcase(suite, "standard try epoll (or select)",
126 								   test_event_context,
127 								   (void *)True);
128 
129 	return suite;
130 }
131