r25035: Fix some more warnings, use service pointer rather than service number in...
[bbaumbach/samba-autobuild/.git] / source4 / torture / local / event.c
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 3 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, see <http://www.gnu.org/licenses/>.
20 */
21
22 #include "includes.h"
23 #include "lib/events/events.h"
24 #include "system/filesys.h"
25 #include "torture/torture.h"
26
27 static int fde_count;
28
29 static void fde_handler(struct event_context *ev_ctx, struct fd_event *f, 
30                         uint16_t flags, void *private)
31 {
32         int *fd = (int *)private;
33         char c;
34 #ifdef SA_SIGINFO
35         kill(getpid(), SIGUSR1);
36 #endif
37         kill(getpid(), SIGALRM);
38         read(fd[0], &c, 1);
39         write(fd[1], &c, 1);
40         fde_count++;
41 }
42
43 static void finished_handler(struct event_context *ev_ctx, struct timed_event *te,
44                              struct timeval tval, void *private)
45 {
46         int *finished = (int *)private;
47         (*finished) = 1;
48 }
49
50 static void count_handler(struct event_context *ev_ctx, struct signal_event *te,
51                           int signum, int count, void *info, void *private)
52 {
53         int *countp = (int *)private;
54         (*countp) += count;
55 }
56
57 static bool test_event_context(struct torture_context *test,
58                                const void *test_data)
59 {
60         struct event_context *ev_ctx;
61         int fd[2] = { -1, -1 };
62         const char *backend = (const char *)test_data;
63         int alarm_count=0, info_count=0;
64         struct fd_event *fde;
65         struct signal_event *se1, *se2, *se3;
66         int finished=0;
67         struct timeval t;
68         char c = 0;
69
70         ev_ctx = event_context_init_byname(test, backend);
71         if (ev_ctx == NULL) {
72                 torture_comment(test, "event backend '%s' not supported\n", backend);
73                 return true;
74         }
75
76         torture_comment(test, "Testing event backend '%s'\n", backend);
77
78         /* reset globals */
79         fde_count = 0;
80
81         /* create a pipe */
82         pipe(fd);
83
84         fde = event_add_fd(ev_ctx, ev_ctx, fd[0], EVENT_FD_READ|EVENT_FD_AUTOCLOSE, 
85                            fde_handler, fd);
86
87         event_add_timed(ev_ctx, ev_ctx, timeval_current_ofs(2,0), 
88                         finished_handler, &finished);
89
90         se1 = event_add_signal(ev_ctx, ev_ctx, SIGALRM, SA_RESTART, count_handler, &alarm_count);
91         se2 = event_add_signal(ev_ctx, ev_ctx, SIGALRM, SA_RESETHAND, count_handler, &alarm_count);
92 #ifdef SA_SIGINFO
93         se3 = event_add_signal(ev_ctx, ev_ctx, SIGUSR1, SA_SIGINFO, count_handler, &info_count);
94 #endif
95
96         write(fd[1], &c, 1);
97
98         t = timeval_current();
99         while (!finished) {
100                 errno = 0;
101                 if (event_loop_once(ev_ctx) == -1) {
102                         talloc_free(ev_ctx);
103                         torture_fail(test, talloc_asprintf(test, "Failed event loop %s\n", strerror(errno)));
104                 }
105         }
106
107         talloc_free(fde);
108         close(fd[1]);
109
110         while (alarm_count < fde_count+1) {
111                 if (event_loop_once(ev_ctx) == -1) {
112                         break;
113                 }
114         }
115
116         torture_comment(test, "Got %.2f pipe events/sec\n", fde_count/timeval_elapsed(&t));
117
118         talloc_free(se1);
119
120         torture_assert_int_equal(test, alarm_count, 1+fde_count, "alarm count mismatch");
121
122 #ifdef SA_SIGINFO
123         talloc_free(se3);
124         torture_assert_int_equal(test, info_count, fde_count, "info count mismatch");
125 #endif
126
127         talloc_free(ev_ctx);
128
129         return true;
130 }
131
132 struct torture_suite *torture_local_event(TALLOC_CTX *mem_ctx)
133 {
134         struct torture_suite *suite = torture_suite_create(mem_ctx, "EVENT");
135         const char **list = event_backend_list(suite);
136         int i;
137
138         for (i=0;list && list[i];i++) {
139                 torture_suite_add_simple_tcase(suite, list[i],
140                                                test_event_context,
141                                                (const void *)list[i]);
142         }
143
144         return suite;
145 }