From 1652cc1d030da8b1890d9b81e7fd20055762a222 Mon Sep 17 00:00:00 2001 From: knutroy Date: Thu, 14 Jun 2007 12:08:15 +0000 Subject: [PATCH] Miscellaneous improvements to regression test framework, most notably changes regarding how events are processed. We now state what events we are waiting for when calling run_loop. The central event dispatcher monitors this list and decides when to pause the loop. Return value from run_loop is the event name and whatever arguments were sent by the event creator, if the event triggered no explicit handler, or otherwise, the return value(s) from the event handler. If subsequent events occur between a loop-pausing event and the time the loop actually pauses, such events are queued and eligible candidates for return value of the next call to run_loop. This way, events will not be lost accidentally, which might happen in previous revisions. git-svn-id: svn+ssh://projects.linpro.no/svn/varnish/trunk@1513 d4fa192b-c00b-0410-8231-f00ffab90ce4 --- varnish-tools/regress/lib/Varnish/Test.pm | 2 +- .../regress/lib/Varnish/Test/Case.pm | 35 ++++------- .../lib/Varnish/Test/Case/Ticket056.pm | 5 +- .../lib/Varnish/Test/Case/Ticket102.pm | 9 ++- .../regress/lib/Varnish/Test/Client.pm | 3 + .../regress/lib/Varnish/Test/Engine.pm | 62 +++++++++---------- .../regress/lib/Varnish/Test/Varnish.pm | 7 ++- 7 files changed, 61 insertions(+), 62 deletions(-) diff --git a/varnish-tools/regress/lib/Varnish/Test.pm b/varnish-tools/regress/lib/Varnish/Test.pm index a631c13f..2bf963c4 100644 --- a/varnish-tools/regress/lib/Varnish/Test.pm +++ b/varnish-tools/regress/lib/Varnish/Test.pm @@ -83,7 +83,7 @@ sub start_engine($;@) { return if defined $self->{'engine'}; $self->{'engine'} = Varnish::Test::Engine->new(@args); - $self->{'engine'}->run_loop; + $self->{'engine'}->run_loop('ev_varnish_started'); } sub stop_engine($;$) { diff --git a/varnish-tools/regress/lib/Varnish/Test/Case.pm b/varnish-tools/regress/lib/Varnish/Test/Case.pm index 93332b29..7a860605 100644 --- a/varnish-tools/regress/lib/Varnish/Test/Case.pm +++ b/varnish-tools/regress/lib/Varnish/Test/Case.pm @@ -67,14 +67,14 @@ sub init($) { my $vcl = $varnish->backend_block('main') . ${ref($self)."::VCL"}; $varnish->send_vcl(ref($self), $vcl); - $self->run_loop(); + $self->run_loop('ev_varnish_command_ok'); $varnish->use_vcl(ref($self)); - $self->run_loop(); + $self->run_loop('ev_varnish_command_ok'); } # Start the child $varnish->start_child(); - $self->run_loop(); + $self->run_loop('ev_varnish_child_started'); } sub fini($) { @@ -84,13 +84,16 @@ sub fini($) { # Stop the worker process $varnish->stop_child(); - $self->run_loop(); + # Wait for both events, the order is unpredictable, so wait for + # any of them both times. + $self->run_loop('ev_varnish_child_stopped', 'ev_varnish_command_ok'); + $self->run_loop('ev_varnish_child_stopped', 'ev_varnish_command_ok'); # Revert to initial VCL script no strict 'refs'; if (${ref($self)."::VCL"}) { $varnish->use_vcl('boot'); - $self->run_loop(); + $self->run_loop('ev_varnish_command_ok', 'ev_varnish_command_unknown'); } delete $self->{'engine'}->{'case'}; @@ -122,16 +125,10 @@ sub run($;@) { } } -sub run_loop($) { - my ($self) = @_; - - $self->{'engine'}->run_loop; -} - -sub pause_loop($;@) { - my ($self, @args) = @_; +sub run_loop($@) { + my ($self, @wait_for) = @_; - $self->{'engine'}->pause_loop(@args); + return $self->{'engine'}->run_loop(@wait_for); } sub new_client($) { @@ -140,23 +137,17 @@ sub new_client($) { return Varnish::Test::Client->new($self->{'engine'}); } -sub ev_varnish_command_ok($) { - my ($self) = @_; - - $self->pause_loop; -} - sub ev_client_response($$$) { my ($self, $client, $response) = @_; - $self->{'engine'}->pause_loop($response); + return $response; } sub ev_client_timeout($$) { my ($self, $client) = @_; $client->shutdown(2); - $self->{'engine'}->pause_loop; + return $client; } 1; diff --git a/varnish-tools/regress/lib/Varnish/Test/Case/Ticket056.pm b/varnish-tools/regress/lib/Varnish/Test/Case/Ticket056.pm index c68632ef..1c9baee7 100644 --- a/varnish-tools/regress/lib/Varnish/Test/Case/Ticket056.pm +++ b/varnish-tools/regress/lib/Varnish/Test/Case/Ticket056.pm @@ -55,9 +55,10 @@ sub testVersionMatch($) { $request->protocol($cv); $client->send_request($request, 2); - my $response = $self->run_loop; + my ($event, $response) = $self->run_loop('ev_client_response', 'ev_client_timeout'); - croak 'No (complete) response received' unless defined($response); + croak 'Client time-out before receiving a (complete) response' + if $event eq 'ev_client_timeout'; croak 'Server was not contacted by Varnish' if $self->{'engine'}->{'server'}->{'requests'} != $requests + 1; croak sprintf('Protocol version mismatch: got: %s expected: %s', diff --git a/varnish-tools/regress/lib/Varnish/Test/Case/Ticket102.pm b/varnish-tools/regress/lib/Varnish/Test/Case/Ticket102.pm index bb9921f2..bd069efe 100644 --- a/varnish-tools/regress/lib/Varnish/Test/Case/Ticket102.pm +++ b/varnish-tools/regress/lib/Varnish/Test/Case/Ticket102.pm @@ -54,11 +54,16 @@ sub testBodyInCachedPOST($) { my $request = HTTP::Request->new('POST', '/'); $request->protocol('HTTP/1.1'); $client->send_request($request, 2); - my $response = $self->run_loop; - croak 'No (complete) response received' unless defined($response); + + my ($event, $response) = $self->run_loop('ev_client_response', 'ev_client_timeout'); + + croak 'Client time-out before receiving a (complete) response' + if $event eq 'ev_client_timeout'; croak 'Empty body' if $response->content eq ''; croak 'Incorrect body' if $response->content ne $body; } + + return 'OK'; } sub ev_server_request($$$$) { diff --git a/varnish-tools/regress/lib/Varnish/Test/Client.pm b/varnish-tools/regress/lib/Varnish/Test/Client.pm index a549a10e..15866e04 100644 --- a/varnish-tools/regress/lib/Varnish/Test/Client.pm +++ b/varnish-tools/regress/lib/Varnish/Test/Client.pm @@ -99,6 +99,8 @@ sub mux_input($$$$) { $self->got_response($response); } elsif ($data_length < $content_length) { + $self->log(sprintf('Partial response. Bytes in body: %d received, %d expected, %d remaining', + $data_length, $content_length, $content_length - $data_length)); last; } else { @@ -108,6 +110,7 @@ sub mux_input($$$$) { } } else { + $self->log('Partial response. Content-Length unknown. Expecting CLOSE as end-of-response.'); last; } } diff --git a/varnish-tools/regress/lib/Varnish/Test/Engine.pm b/varnish-tools/regress/lib/Varnish/Test/Engine.pm index 0d6952ac..e95b3ac1 100644 --- a/varnish-tools/regress/lib/Varnish/Test/Engine.pm +++ b/varnish-tools/regress/lib/Varnish/Test/Engine.pm @@ -48,7 +48,8 @@ sub new($$;%) { my $self = bless({ 'mux' => IO::Multiplex->new, 'controller' => $controller, - 'config' => \%config }, $class); + 'config' => \%config, + 'pending' => [] }, $class); $self->{'server'} = Varnish::Test::Server->new($self); $self->{'varnish'} = Varnish::Test::Varnish->new($self); @@ -65,30 +66,30 @@ sub log($$$) { print STDERR $str; } -sub run_loop($) { - my ($self) = @_; +sub run_loop($@) { + my ($self, @wait_for) = @_; - croak 'Engine::run: Already inside select-loop. Your code is buggy.' + croak 'Engine::run_loop: Already inside select-loop. Your code is buggy.' if exists($self->{'in_loop'}); + croak 'Engine::run_loop: No events to wait for.' + if @wait_for == 0; + + while (@{$self->{'pending'}} > 0) { + my ($event, @args) = @{shift @{$self->{'pending'}}}; + return ($event, @args) if grep({ $_ eq $event } @wait_for); + } + + $self->{'wait_for'} = \@wait_for; $self->{'in_loop'} = 1; $self->{'mux'}->loop; delete $self->{'in_loop'}; + delete $self->{'wait_for'}; - return delete $self->{'return'} if exists $self->{'return'}; + return @{shift @{$self->{'pending'}}} if @{$self->{'pending'}} > 0; return undef; } -sub pause_loop($;$) { - my ($self, $return) = @_; - - croak 'Engine::pause: Not inside select-loop. Your code is buggy.' - unless exists($self->{'in_loop'}); - - $self->{'return'} = $return if defined($return); - $self->{'mux'}->endloop; -} - sub shutdown($) { my ($self) = @_; @@ -99,32 +100,27 @@ sub shutdown($) { } } -sub ev_varnish_started($) { - my ($self) = @_; - - $self->pause_loop; -} - sub AUTOLOAD ($;@) { my ($self, @args) = @_; - (my $event_handler = our $AUTOLOAD) =~ s/.*://; + (my $event = our $AUTOLOAD) =~ s/.*://; + + return if $event eq 'DESTROY'; - return if $event_handler eq 'DESTROY'; + croak sprintf('Unknown method "%s"', $event) + unless $event =~ /^ev_(.*)$/; - croak sprintf('received event (%s) while not running a case', $event_handler) - unless defined $self->{'case'}; + $self->log($self, 'ENG: ', sprintf('EVENT "%s"', $1)); - croak sprintf('Unknown method "%s"', $event_handler) - unless $event_handler =~ /^ev_(.*)$/; + @args = $self->{'case'}->$event(@args) + if (defined($self->{'case'}) and $self->{'case'}->can($event)); - if ($self->{'case'}->can($event_handler)) { - $self->log($self, 'ENG: ', sprintf('EVENT "%s"', $1)); - return $self->{'case'}->$event_handler(@args); + if (@{$self->{'pending'}} > 0) { + push(@{$self->{'pending'}}, [ $event, @args ]); } - else { - $self->log($self, 'ENG: ', sprintf('EVENT "%s" IGNORED', $1)); - return undef; + elsif (grep({ $_ eq $event} @{$self->{'wait_for'}}) > 0) { + push(@{$self->{'pending'}}, [ $event, @args ]); + $self->{'mux'}->endloop; } } diff --git a/varnish-tools/regress/lib/Varnish/Test/Varnish.pm b/varnish-tools/regress/lib/Varnish/Test/Varnish.pm index d2fb5674..f3c5fb89 100644 --- a/varnish-tools/regress/lib/Varnish/Test/Varnish.pm +++ b/varnish-tools/regress/lib/Varnish/Test/Varnish.pm @@ -190,7 +190,7 @@ sub mux_input($$$$) { $self->log($$data); - if ($$data =~ /rolling\(2\)\.\.\./) { + if ($$data =~ /^rolling\(2\)\.\.\./m) { $self->{'state'} = 'stopped'; $self->{'engine'}->ev_varnish_started; } @@ -204,7 +204,10 @@ sub mux_input($$$$) { } $self->{'engine'}->ev_varnish_command_ok(delete $self->{'pending'}) - if ($$data =~ /^200 0/ and $self->{'pending'}); + if ($$data =~ /^200 \d+/m and $self->{'pending'}); + + $self->{'engine'}->ev_varnish_command_unknown(delete $self->{'pending'}) + if ($$data =~ /^300 \d+/m and $self->{'pending'}); $$data = ''; } -- 2.39.5