fixed perl event loop
[urisagit/Stem.git] / t / event / event_test.pl
CommitLineData
4536f655 1#!/usr/local/bin/perl -w
2
3BEGIN {
4 $Stem::Vars::Env{ 'event_loop' } = shift ;
5
6 unless ( eval { require Time::HiRes } ) {
7
8 Time::HiRes->import( qw( time ) ) ;
9 }
10}
11
12use strict ;
13
4932dd97 14use Test::More tests => 27 ;
4536f655 15
16use Symbol ;
17
18use Stem::Event ;
19use Stem::Class ;
20
21my $self = bless {} ;
22
23test_events() ;
24
25exit ;
26
27sub test_events {
28
4932dd97 29 test_null_events() ;
30 test_plain_events () ;
31 test_signal_events () ;
4536f655 32 test_hard_timer_events () ;
33 test_soft_timer_events () ;
34 test_io_events () ;
35}
36
37sub 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
47sub 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
62sub triggered {
63
64 my( $self ) = @_ ;
65
66 ok( 1, 'plain event triggered' ) ;
67}
68
69sub 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
99sub 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
110use constant INTERVAL => 4 ;
111use constant SLEEP => 2 ;
112use 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
117sub 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
140sub 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 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 delta 2' ) ;
166 ok( $delta <= INTERVAL + SLEEP, 'hard 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
177sub 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
201sub 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 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 delta 2' ) ;
230 ok( $delta >= INTERVAL + SLEEP, 'soft delta 3' ) ;
231
232 $self->{'soft_timer_event'}->cancel() ;
233
234 Stem::Event::stop_loop() ;
235}
236
237sub 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
277sub read_timeout {
278
279 my( $self ) = @_ ;
280
281 ok( 1, 'read event timed out' ) ;
282
283 $self->{'write_event'}->start() ;
284}
285
286
287sub 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
298sub 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
320sub 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
3361 ;