]> err.no Git - varnish/commitdiff
Miscellaneous improvements to regression test framework, most notably
authorknutroy <knutroy@d4fa192b-c00b-0410-8231-f00ffab90ce4>
Thu, 14 Jun 2007 12:08:15 +0000 (12:08 +0000)
committerknutroy <knutroy@d4fa192b-c00b-0410-8231-f00ffab90ce4>
Thu, 14 Jun 2007 12:08:15 +0000 (12:08 +0000)
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
varnish-tools/regress/lib/Varnish/Test/Case.pm
varnish-tools/regress/lib/Varnish/Test/Case/Ticket056.pm
varnish-tools/regress/lib/Varnish/Test/Case/Ticket102.pm
varnish-tools/regress/lib/Varnish/Test/Client.pm
varnish-tools/regress/lib/Varnish/Test/Engine.pm
varnish-tools/regress/lib/Varnish/Test/Varnish.pm

index a631c13f20c883d161ac86820854adc6df3b5e32..2bf963c4a916619da80ff4c77b121bc86b2cf752 100644 (file)
@@ -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($;$) {
index 93332b298c067adeb2754188cdff9a7f87140b1e..7a8606059170a51f25ec64af7c6af1e3c3521d64 100644 (file)
@@ -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;
index c68632efc9ae4cccce2f688166c3a7de9dbc6f3c..1c9baee794b88e1761a12c39768de916b3ac3cdc 100644 (file)
@@ -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',
index bb9921f218bc1b390550c12fefcf7eae9bdaf67a..bd069efea3ce636984025f497ced5070d338f066 100644 (file)
@@ -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($$$$) {
index a549a10e11802047eddbb3bcda439d0b82a34152..15866e048864e5254ab032f2db1efaa160b4d855 100644 (file)
@@ -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;
        }
     }
index 0d6952acc30264bb3024be729da5d436f5ab6b98..e95b3ac17d472d365f75d2d14378be58f70a468c 100644 (file)
@@ -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;
     }
 }
 
index d2fb567419ef954733523428be0bc9cd66a6213b..f3c5fb89ec2992fa96a80acc96597fe1391f28b4 100644 (file)
@@ -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 = '';
 }