made event ok lines more consistant
[urisagit/Stem.git] / t / event / event_test.pl
1 #!/usr/local/bin/perl -w
2
3 BEGIN {
4         $Stem::Vars::Env{ 'event_loop' } = shift ;
5
6         unless ( eval { require Time::HiRes } ) {
7
8                 Time::HiRes->import( qw( time ) ) ;
9         }
10 }
11
12 use strict ;
13
14 use Test::More tests => 27 ;
15
16 use Symbol ;
17
18 use Stem::Event ;
19 use Stem::Class ;
20
21 my $self = bless {} ;
22
23 test_events() ;
24
25 exit ;
26
27 sub test_events {
28
29         test_null_events() ;
30         test_plain_events () ;
31         test_signal_events () ;
32         test_hard_timer_events () ;
33         test_soft_timer_events () ;
34         test_io_events () ;
35 }
36
37 sub test_null_events {
38
39         local $SIG{__WARN__} = sub{} if
40                         $Stem::Vars::Env{ 'event_loop' } eq 'event' ;
41
42         Stem::Event::start_loop() ;
43
44         ok( 1, 'null - event loop exit' ) ;
45 }
46
47 sub test_plain_events {
48
49         my $event = Stem::Event::Plain->new(
50                 'object' => $self
51         ) ;
52
53         ok( ref $event, 'plain - event created' ) ;
54
55         Stem::Event::start_loop() ;
56
57         ok( 1, 'plain - event loop exit' ) ;
58 }
59
60 # callback method for plain
61
62 sub triggered {
63
64         my( $self ) = @_ ;
65
66         ok( 1, 'plain - event triggered' ) ;
67 }
68
69 sub test_signal_events {
70
71         SKIP: {
72                 if ( $^O =~ /win32/i ) {
73
74                         skip( "signals not supported on windows", 3 ) ;
75                         return ;
76                 }
77
78                 my $event = Stem::Event::Signal->new(
79                         'object'        => $self,
80                         'signal'        => 'INT',
81                 ) ;
82
83                 ok( ref $event, 'signal - event created' ) ;
84
85                 $self->{'sig_event'} = $event ;
86
87                 kill 'INT', $$ ;
88
89 #print "kill INT\n" ;
90
91                 Stem::Event::start_loop() ;
92
93                 ok( 1, 'signal - event loop exit' ) ;
94         }
95 }
96
97 # callback method for signal
98
99 sub sig_int_handler {
100
101         my( $self ) = @_ ;
102
103         ok( 1, 'signal - event triggered' ) ;
104
105         $self->{'sig_event'}->cancel() ;
106         Stem::Event::stop_loop() ;
107 }
108
109
110 use constant INTERVAL   => 4 ;
111 use constant SLEEP      => 2 ;
112 use constant TIMER_CNT  => 2 ;
113
114 # hard timeouts are timed from the beginning of the callback. so accumulated
115 # time in the callback doesn't affect the next callback.
116
117 sub test_hard_timer_events {
118
119         my $event = Stem::Event::Timer->new(
120                 'object'        => $self,
121                 'method'        => 'hard_timeout',
122                 'interval'      => INTERVAL,
123                 'delay'         => INTERVAL,    # REMOVE - only for .10
124                 'repeat'        => 1,
125                 'hard'          => 1,
126         ) ;
127
128         ok( ref $event, 'hard timer - event created' ) ;
129         print "$event\n" unless ref $event ;
130
131         $self->{'hard_timer_event'} = $event ;
132         $self->{'hard_timer_count'} = TIMER_CNT ;
133         $self->{'hard_timer_start_time'} = time ;
134
135         Stem::Event::start_loop() ;
136
137         ok( 1, 'hard timer - event loop exit' ) ;
138 }
139
140 sub hard_timeout {
141
142         my( $self ) = @_ ;
143
144         ok( 1, 'hard timer - event triggered' ) ;
145
146         if ( --$self->{'hard_timer_count'} > 0 ) {
147
148                 my $time = time ;
149                 my $delta = $time - $self->{'hard_timer_start_time'} ;
150                 $self->{'hard_timer_start_time'} = $time ;
151
152                 ok( $delta >= INTERVAL, 'hard timer - delta' ) ;
153
154                 hard_sleep( SLEEP ) ;
155
156                 return ;
157         }
158
159         
160         my $time = time ;
161         my $delta = $time - $self->{'hard_timer_start_time'} ;
162
163 #print "O $self->{'hard_timer_start_time'} T $time D $delta I ", INTERVAL, "\n" ;
164
165         ok( $delta >= INTERVAL, 'hard timer - delta 2' ) ;
166         ok( $delta <= INTERVAL + SLEEP, 'hard timer - delta sleep' ) ;
167
168         $self->{'hard_timer_event'}->cancel() ;
169
170         Stem::Event::stop_loop() ;
171 }
172
173
174 # Soft timeouts are timed from the end of the callback. so accumulated
175 # time in the callback delays the next callback.
176
177 sub test_soft_timer_events {
178
179         my $event = Stem::Event::Timer->new(
180                 'object'        => $self,
181                 'method'        => 'soft_timeout',
182                 'interval'      => INTERVAL,
183                 'delay'         => INTERVAL,    # REMOVE  - only for .10
184                 'repeat'        => 1,
185         ) ;
186
187         ok( ref $event, 'soft timer - event created' ) ;
188 #       print "$event\n" unless ref $event ;
189
190         $self->{'soft_timer_event'} = $event ;
191         $self->{'soft_timer_count'} = TIMER_CNT ;
192         $self->{'soft_timer_start_time'} = time ;
193
194 #print "OTIME $self->{'soft_timer_start_time'}\n" ;
195
196         Stem::Event::start_loop() ;
197
198         ok( 1, 'soft timer - event loop exit' ) ;
199 }
200
201 sub soft_timeout {
202
203         my( $self ) = @_ ;
204
205         ok( 1, 'soft timer - event triggered' ) ;
206
207         if ( --$self->{'soft_timer_count'} > 0 ) {
208
209                 my $time = time ;
210                 my $delta = $time - $self->{'soft_timer_start_time'} ;
211
212 #print "T $time D $delta I ", INTERVAL, "\n" ;
213
214                 ok( $delta >= INTERVAL, 'soft timer - delta' ) ;
215
216                 hard_sleep( SLEEP ) ;
217
218 #my $curr_time = time() ;
219 #print "DONE $curr_time\n" ;
220
221                 return ;
222         }
223
224         my $time = time ;
225         my $delta = $time - $self->{'soft_timer_start_time'} ;
226
227 #print "TIME2 $time OTIME $self->{'soft_timer_start_time'} DEL $delta INTERVAL ", INTERVAL, "\n" ;
228
229 #       ok( $delta >= INTERVAL, 'soft timer - delta 2' ) ;
230         ok( $delta >= INTERVAL + SLEEP, 'soft timer - delta 3' ) ;
231
232         $self->{'soft_timer_event'}->cancel() ;
233
234         Stem::Event::stop_loop() ;
235 }
236
237 sub test_io_events {
238
239         Stem::Event::init_loop() ;
240
241         my $read_fh = gensym ;
242         my $write_fh = gensym ;
243
244 # get a pipe to read/write through.
245
246         use Socket;
247         socketpair( $read_fh, $write_fh, AF_UNIX, SOCK_STREAM, PF_UNSPEC ) ;
248
249         $self->{read_fh} = $read_fh ;
250         $self->{write_fh} = $write_fh ;
251         $self->{message} = 'Stem Read/Write Event' ;
252
253         # create the read and write events
254
255         my $read_event = Stem::Event::Read->new(
256                                 'object'        =>      $self,
257                                 'fh'            =>      $read_fh,
258                                 'timeout'       =>      3,
259         ) ;
260
261         ok( ref $read_event, 'read - event created' ) ;
262         $self->{'read_event'} = $read_event ;
263
264         my $write_event = Stem::Event::Write->new(
265                                 'object'        =>      $self,
266                                 'fh'            =>      $write_fh,
267         ) ;
268
269         ok( ref $write_event, 'write - event created' ) ;
270         $self->{'write_event'} = $write_event ;
271
272         Stem::Event::start_loop() ;
273
274         ok( 1, 'io event - loop exit' ) ;
275 }
276
277 sub read_timeout {
278
279         my( $self ) = @_ ;
280
281         ok( 1, 'read - event timed out' ) ;
282
283         $self->{'write_event'}->start() ;
284 }
285
286
287 sub writeable {
288
289         my( $self ) = @_ ;
290
291         ok( 1, 'write - event triggered' ) ;
292
293         syswrite( $self->{'write_fh'}, $self->{'message'} ) ;
294
295         $self->{'write_event'}->cancel() ;
296 }
297
298 sub readable {
299
300         my( $self ) = @_ ;
301
302         ok(1, 'read - event triggered' ) ;
303
304         my( $read_buf ) ;
305
306         my $bytes_read = sysread( $self->{'read_fh'}, $read_buf, 1000 ) ;
307
308         ok( $bytes_read, 'read - byte count' ) ;
309
310         is( $read_buf, $self->{'message'}, 'read event compare' ) ;
311
312         $self->{'read_event'}->cancel() ;
313
314         Stem::Event::stop_loop() ;
315 }
316
317 # do a real hard sleep without alarm signal as that can screw up the tests
318 # sleep time is in (float) seconds
319
320 sub hard_sleep {
321
322         my( $sleep_time ) = @_ ;
323
324 #print "BEFORE TIME $sleep_time\n" ;
325         while( $sleep_time > 0 ) {
326
327                 my $curr_time = time() ;
328                 select( undef, undef, undef, $sleep_time ) ;
329
330                 $sleep_time -= time() - $curr_time ;
331
332 #print "AFTER TIME $sleep_time\n" ;
333         }
334 }
335
336 1 ;