You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@httpd.apache.org by ji...@apache.org on 2017/06/27 22:19:28 UTC

svn commit: r1800096 - in /httpd/test/framework/trunk: Misc.pm t/modules/proxy_fcgi.t

Author: jim
Date: Tue Jun 27 22:19:28 2017
New Revision: 1800096

URL: http://svn.apache.org/viewvc?rev=1800096&view=rev
Log:
rework some items... Simplyfy runner and avoid potential
race condition.

Modified:
    httpd/test/framework/trunk/Misc.pm
    httpd/test/framework/trunk/t/modules/proxy_fcgi.t

Modified: httpd/test/framework/trunk/Misc.pm
URL: http://svn.apache.org/viewvc/httpd/test/framework/trunk/Misc.pm?rev=1800096&r1=1800095&r2=1800096&view=diff
==============================================================================
--- httpd/test/framework/trunk/Misc.pm (original)
+++ httpd/test/framework/trunk/Misc.pm Tue Jun 27 22:19:28 2017
@@ -22,36 +22,24 @@ use Apache::TestConfig ();
 
 use strict;
 use warnings FATAL => 'all';
-require IO::Select;
 
 BEGIN {
     # Just a bunch of useful subs
 }
 
-sub do_do_run_run
+sub forker
 {
     my $msg = shift;
     my $func = shift;
 
-    pipe(READ_END, WRITE_END);
     my $pid = fork();
     unless (defined $pid) {
-        t_debug "couldn't fork $msg";
+        t_debug "couldn't fork/run $msg";
         ok 0;
-        exit;
+        $pid = -1;
     }
     if ($pid == 0) {
-        print WRITE_END 'x';
-        close WRITE_END;
         $func->(@_);
-        exit;
-    }
-    # give time for the system call to take effect
-    unless (IO::Select->new((\*READ_END,))->can_read(2)) {
-        t_debug "timed out waiting for $msg";
-        ok 0;
-        kill 'TERM', $pid;
-        exit;
     }
     return $pid;
 }

Modified: httpd/test/framework/trunk/t/modules/proxy_fcgi.t
URL: http://svn.apache.org/viewvc/httpd/test/framework/trunk/t/modules/proxy_fcgi.t?rev=1800096&r1=1800095&r2=1800096&view=diff
==============================================================================
--- httpd/test/framework/trunk/t/modules/proxy_fcgi.t (original)
+++ httpd/test/framework/trunk/t/modules/proxy_fcgi.t Tue Jun 27 22:19:28 2017
@@ -29,31 +29,60 @@ Apache::TestRequest::module("proxy_fcgi"
 # Launches a short-lived FCGI daemon that will handle exactly one request with
 # the given handler function. Returns the child PID; exits on failure.
 
-sub fcgi_request
+sub run_fcgi_handler($$)
 {
     my $fcgi_port    = shift;
     my $handler_func = shift;
 
-    # Child process. Open up a listening socket.
-    my $sock = FCGI::OpenSocket(":$fcgi_port", 10);
+    # Use a pipe for ready-signalling between the child and parent. Much faster
+    # (and more reliable) than just sleeping for a few seconds.
+    pipe(READ_END, WRITE_END);
+    my $pid = fork();
+
+    unless (defined $pid) {
+        t_debug "couldn't fork FCGI process";
+        ok 0;
+        exit;
+    }
+
+    if ($pid == 0) {
+        # Child process. Open up a listening socket.
+        my $sock = FCGI::OpenSocket(":$fcgi_port", 10);
+
+        # Signal the parent process that we're ready.
+        print WRITE_END 'x';
+        close WRITE_END;
+
+        # Listen for and respond to exactly one request from the client.
+        my $request = FCGI::Request(\*STDIN, \*STDOUT, \*STDERR, \%ENV,
+                                    $sock, &FCGI::FAIL_ACCEPT_ON_INTR);
+
+        if ($request->Accept() == 0) {
+            # Run the handler.
+            $handler_func->();
+            $request->Finish();
+        }
 
-    # Listen for and respond to exactly one request from the client.
-    my $request = FCGI::Request(\*STDIN, \*STDOUT, \*STDERR, \%ENV,
-                                $sock, &FCGI::FAIL_ACCEPT_ON_INTR);
-
-    if ($request->Accept() == 0) {
-        # Run the handler.
-        $handler_func->(@_);
-        $request->Finish();
+        # Clean up and exit.
+        FCGI::CloseSocket($sock);
+        exit;
     }
 
-    # Clean up and exit.
-    FCGI::CloseSocket($sock);
-}
+    # Parent process. Wait for the daemon to launch.
+    unless (IO::Select->new((\*READ_END,))->can_read(2)) {
+        t_debug "timed out waiting for FCGI process to start";
+        ok 0;
+
+        kill 'TERM', $pid;
+        # Note that we don't waitpid() here because Perl's fork() implementation
+        # on some platforms (Windows) doesn't guarantee that the pseudo-TERM
+        # signal will be delivered. Just wait for the child to be cleaned up
+        # when we exit.
 
-sub run_fcgi_handler
-{
-    return Misc::do_do_run_run("FCGI process", \&fcgi_request, @_);
+        exit;
+    }
+
+    return $pid;
 }
 
 # Convenience wrapper for run_fcgi_handler() that will echo back the envvars in
@@ -77,17 +106,18 @@ sub launch_envvar_echo_daemon($)
 #
 # Calling this function will run one test that must be accounted for in the test
 # plan.
-sub run_fcgi_envvar_request($$)
+sub run_fcgi_envvar_request
 {
     my $fcgi_port = shift;
     my $uri       = shift;
+    my $backend   = shift || "FCGI";
 
     # Launch the FCGI process.
     my $child = launch_envvar_echo_daemon($fcgi_port) unless ($fcgi_port == -1) ;
 
     # Hit the backend.
     my $r = GET($uri);
-    ok t_cmp($r->code, 200, "proxy to FCGI backend works (" . $uri . ")");
+    ok t_cmp($r->code, 200, "proxy to $backend backend works (" . $uri . ")");
 
     # Split the returned envvars into a dictionary.
     my %envs = ();
@@ -205,9 +235,15 @@ ok t_cmp($envs->{'SCRIPT_NAME'}, '/modul
 # Testing using php-fpm directly
 if ($have_php_fpm) {
     my $pid_file = "/tmp/php-fpm-" . $$ . "-" . time . ".pid";
-    Misc::do_do_run_run("php-fpm", sub { system "php-fpm -F -g $pid_file -p $servroot/php-fpm"; });
-    sleep 1; # Yes, we really need this here since php-fpm takes a while
-    $envs = run_fcgi_envvar_request(-1, "/fpm/sub1/sub2/test.php?query");
-    kill 'TERM', `cat $pid_file`;
-    ok t_cmp($envs->{'SCRIPT_NAME'}, '/fpm/sub1/sub2/test.php', "Server sets correct SCRIPT_NAME by default");
+    my $pid = Misc::forker("php-fpm", sub { system "php-fpm -F -g $pid_file -p $servroot/php-fpm"; });
+    if ($pid > 0) {
+        while (! -e $pid_file) {}
+        $envs = run_fcgi_envvar_request(- 1, "/fpm/sub1/sub2/test.php?query", "PHP-FPM");
+        ok t_cmp($envs->{'SCRIPT_NAME'}, '/fpm/sub1/sub2/test.php', "Server sets correct SCRIPT_NAME by default");
+
+        # TODO: Add more here
+        kill 'TERM', $pid;
+        kill 'TERM', `cat $pid_file`;
+        waitpid($pid, 0);
+    }
 }