1#!/usr/bin/perl 2 3use strict; 4use warnings; 5 6use IO::Async::Test; 7 8use Test::More; 9use Test::Refcount; 10 11use lib "."; 12use t::TimeAbout; 13 14use Time::HiRes qw( time ); 15 16use IO::Async::Timer::Absolute; 17 18use IO::Async::Loop; 19 20use constant AUT => $ENV{TEST_QUICK_TIMERS} ? 0.1 : 1; 21 22my $loop = IO::Async::Loop->new_builtin; 23 24testing_loop( $loop ); 25 26{ 27 my $expired; 28 my @eargs; 29 30 my $timer = IO::Async::Timer::Absolute->new( 31 time => time + 2 * AUT, 32 33 on_expire => sub { @eargs = @_; $expired = 1 }, 34 ); 35 36 ok( defined $timer, '$timer defined' ); 37 isa_ok( $timer, "IO::Async::Timer", '$timer isa IO::Async::Timer' ); 38 39 is_oneref( $timer, '$timer has refcount 1 initially' ); 40 41 $loop->add( $timer ); 42 43 is_refcount( $timer, 2, '$timer has refcount 2 after adding to Loop' ); 44 45 ok( $timer->is_running, 'Started Timer is running' ); 46 47 time_about( sub { wait_for { $expired } }, 2, 'Timer works' ); 48 is_deeply( \@eargs, [ $timer ], 'on_expire args' ); 49 50 ok( !$timer->is_running, 'Expired Timer is no longer running' ); 51 52 undef @eargs; 53 54 is_refcount( $timer, 2, '$timer has refcount 2 before removing from Loop' ); 55 56 $loop->remove( $timer ); 57 58 is_oneref( $timer, '$timer has refcount 1 after removing from Loop' ); 59} 60 61{ 62 my $expired; 63 64 my $timer = IO::Async::Timer::Absolute->new( 65 time => time + 2 * AUT, 66 on_expire => sub { $expired++ }, 67 ); 68 69 $loop->add( $timer ); 70 $loop->remove( $timer ); 71 72 $loop->loop_once( 3 * AUT ); 73 74 ok( !$expired, "Removed Timer does not expire" ); 75} 76 77{ 78 my $expired; 79 80 my $timer = IO::Async::Timer::Absolute->new( 81 time => time + 5 * AUT, 82 on_expire => sub { $expired++ }, 83 ); 84 85 $loop->add( $timer ); 86 87 $timer->configure( time => time + 1 * AUT ); 88 89 time_about( sub { wait_for { $expired } }, 1, 'Reconfigured timer works' ); 90 91 $loop->remove( $timer ); 92} 93 94{ 95 my $timer = IO::Async::Timer::Absolute->new( 96 time => time + 1 * AUT, 97 on_expire => sub { die "Test failed to replace expiry handler" }, 98 ); 99 100 $loop->add( $timer ); 101 102 my $new_expired; 103 $timer->configure( on_expire => sub { $new_expired = 1 } ); 104 105 time_about( sub { wait_for { $new_expired } }, 1, 'Reconfigured timer on_expire works' ); 106 107 $loop->remove( $timer ); 108} 109 110## Subclass 111 112my $sub_expired; 113{ 114 my $timer = TestTimer->new( 115 time => time + 2 * AUT, 116 ); 117 118 ok( defined $timer, 'subclass $timer defined' ); 119 isa_ok( $timer, "IO::Async::Timer", 'subclass $timer isa IO::Async::Timer' ); 120 121 is_oneref( $timer, 'subclass $timer has refcount 1 initially' ); 122 123 $loop->add( $timer ); 124 125 is_refcount( $timer, 2, 'subclass $timer has refcount 2 after adding to Loop' ); 126 127 ok( $timer->is_running, 'Started subclass Timer is running' ); 128 129 time_about( sub { wait_for { $sub_expired } }, 2, 'subclass Timer works' ); 130 131 ok( !$timer->is_running, 'Expired subclass Timer is no longer running' ); 132 133 is_refcount( $timer, 2, 'subclass $timer has refcount 2 before removing from Loop' ); 134 135 $loop->remove( $timer ); 136 137 is_oneref( $timer, 'subclass $timer has refcount 1 after removing from Loop' ); 138} 139 140done_testing; 141 142package TestTimer; 143use base qw( IO::Async::Timer::Absolute ); 144 145sub on_expire { $sub_expired = 1 } 146