r23792: convert Samba4 to GPLv3
[jelmer/samba4-debian.git] / source / 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 = 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 = 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 = 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                 if (event_loop_once(ev_ctx) == -1) {
101                         talloc_free(ev_ctx);
102                         torture_fail(test, "Failed event loop\n");
103                 }
104         }
105
106         talloc_free(fde);
107         close(fd[1]);
108
109         while (alarm_count < fde_count+1) {
110                 if (event_loop_once(ev_ctx) == -1) {
111                         break;
112                 }
113         }
114
115         torture_comment(test, "Got %.2f pipe events/sec\n", fde_count/timeval_elapsed(&t));
116
117         talloc_free(se1);
118
119         torture_assert_int_equal(test, alarm_count, 1+fde_count, "alarm count mismatch");
120
121 #ifdef SA_SIGINFO
122         talloc_free(se3);
123         torture_assert_int_equal(test, info_count, fde_count, "info count mismatch");
124 #endif
125
126         talloc_free(ev_ctx);
127
128         return true;
129 }
130
131 struct torture_suite *torture_local_event(TALLOC_CTX *mem_ctx)
132 {
133         struct torture_suite *suite = torture_suite_create(mem_ctx, "EVENT");
134         const char **list = event_backend_list(suite);
135         int i;
136
137         for (i=0;list && list[i];i++) {
138                 torture_suite_add_simple_tcase(suite, list[i],
139                                                test_event_context,
140                                                (const void *)list[i]);
141         }
142
143         return suite;
144 }