Remove useless comment.
[privoxy.git] / tools / privoxy-regression-test.pl
index ae5fa9a..955fc87 100755 (executable)
@@ -7,7 +7,7 @@
 # A regression test "framework" for Privoxy. For documentation see:
 # perldoc privoxy-regression-test.pl
 #
-# $Id: privoxy-regression-test.pl,v 1.170 2009/05/15 20:25:51 fk Exp $
+# $Id: privoxy-regression-test.pl,v 1.185 2009/06/10 16:36:42 fk Exp $
 #
 # Wish list:
 #
@@ -69,13 +69,12 @@ use constant {
 
     # Internal use, don't modify
     # Available debug bits:
-    LL_ERROR            =>  1,
+    LL_SOFT_ERROR       =>  1,
     LL_VERBOSE_FAILURE  =>  2,
     LL_PAGE_FETCHING    =>  4,
     LL_FILE_LOADING     =>  8,
     LL_VERBOSE_SUCCESS  => 16,
     LL_STATUS           => 32,
-    LL_SOFT_ERROR       => 64,
 
     CLIENT_HEADER_TEST  =>  1,
     SERVER_HEADER_TEST  =>  2,
@@ -109,9 +108,8 @@ sub get_default_log_level () {
     $log_level |= LL_VERBOSE_SUCCESS if DEBUG_LEVEL_VERBOSE_SUCCESS;
     $log_level |= LL_STATUS          if DEBUG_LEVEL_STATUS;
 
-    # These are intended to be always on.
+    # This one is supposed to be always on.
     $log_level |= LL_SOFT_ERROR;
-    $log_level |= LL_ERROR;
 
     return $log_level;
 }
@@ -140,14 +138,14 @@ sub parse_tag ($) {
 
 sub check_for_forbidden_characters ($) {
 
-    my $tag = shift; # XXX: also used to check values though.
-    my $allowed = '[-=\dA-Za-z~{}:.\/();\s,+@"_%\?&*^]';
+    my $string = shift;
+    my $allowed = '[-=\dA-Za-z~{}:./();\t ,+@"_%?&*^]';
 
-    unless ($tag =~ m/^$allowed*$/) {
-        my $forbidden = $tag;
+    unless ($string =~ m/^$allowed*$/o) {
+        my $forbidden = $string;
         $forbidden =~ s@^$allowed*(.).*@$1@;
 
-        l(LL_ERROR, "'" . $tag . "' contains character '" . $forbidden. "' which is unacceptable.");
+        log_and_die("'" . $string . "' contains character '" . $forbidden. "' which is unacceptable.");
     }
 }
 
@@ -166,6 +164,10 @@ sub load_regressions_tests () {
 
     l(LL_STATUS, "Asking Privoxy for the number of action files available ...");
 
+    # Dear Privoxy, please reload the config file if necessary ...
+    get_cgi_page_or_else($curl_url);
+
+    # ... so we get the latest one here.
     foreach (@{get_cgi_page_or_else($curl_url)}) {
 
         chomp;
@@ -366,9 +368,8 @@ sub load_action_files ($) {
                 # Will be used by each following Sticky URL.
                 $sticky_actions = $value;
                 if ($sticky_actions =~ /{[^}]*\s/) {
-                    l(LL_ERROR,
-                      "'Sticky Actions' with whitespace inside the " .
-                      "action parameters are currently unsupported.");
+                    log_and_die("'Sticky Actions' with whitespace inside the " .
+                                "action parameters are currently unsupported.");
                 }
             }
             
@@ -434,7 +435,7 @@ sub load_action_files ($) {
                     l(LL_FILE_LOADING, "Sticky actions: " . $sticky_actions);
                     $regression_tests[$si][$ri]{'sticky-actions'} = $sticky_actions;
                 } else {
-                    l(LL_ERROR, "Sticky URL without Sticky Actions: $value");
+                    log_and_die("Sticky URL without Sticky Actions: $value");
                 }
 
             } else {
@@ -491,21 +492,7 @@ sub execute_regression_tests () {
                 die "Regression test id mismatch" if ($r != $regression_tests[$s][$r]{'regression-test-id'});
 
                 my $number = $regression_tests[$s][$r]{'number'};
-                my $skip_reason = undef;
-
-                if ($regression_tests[$s][$r]{'ignore'}) {
-
-                    $skip_reason = "Ignore flag is set";
-
-                } elsif (cli_option_is_set('test-number')
-                         and get_cli_option('test-number') != $number) {
-
-                    $skip_reason = "Only executing test " . get_cli_option('test-number');
-
-                } else {
-
-                    $skip_reason = level_is_unacceptable($regression_tests[$s][$r]{'level'});
-                }
+                my $skip_reason = get_skip_reason($regression_tests[$s][$r]);
 
                 if (defined $skip_reason) {
 
@@ -542,6 +529,27 @@ sub execute_regression_tests () {
     }
 }
 
+sub get_skip_reason ($) {
+    my $test = shift;
+    my $skip_reason = undef;
+
+    if ($test->{'ignore'}) {
+
+        $skip_reason = "Ignore flag is set";
+
+    } elsif (cli_option_is_set('test-number') and
+             get_cli_option('test-number') != $test->{'number'}) {
+
+        $skip_reason = "Only executing test " . get_cli_option('test-number');
+
+    } else {
+
+        $skip_reason = level_is_unacceptable($test->{'level'});
+    }
+
+    return $skip_reason;
+}
+
 sub level_is_unacceptable ($) {
     my $level = shift;
     my $min_level = get_cli_option('min-level');
@@ -587,8 +595,10 @@ sub dependency_unsatisfied ($) {
 
         foreach (@privoxy_config) {
 
-             $dependency_problem = undef if (/$dependency/);
-             last; # XXX: this looks ... interesting.
+            if (/$dependency/) {
+                $dependency_problem = undef;
+                last;
+            }
         }
 
     } elsif (defined ($dependencies{$level}{'feature status'})) {
@@ -620,44 +630,47 @@ sub register_dependency ($$) {
     } elsif ($dependency =~ /feature status\s+(.*)/) {
 
         $dependencies{$level}{'feature status'} = $1;
+
+    } else {
+
+        log_and_die("Didn't recognize dependency: $dependency.");
     }
 }
 
 # XXX: somewhat misleading name
 sub execute_regression_test ($) {
 
-    my $test_ref = shift;
-    my %test = %{$test_ref};
+    my $test = shift;
     my $result = 0;
 
-    if ($test{'type'} == CLIENT_HEADER_TEST) {
+    if ($test->{'type'} == CLIENT_HEADER_TEST) {
 
-        $result = execute_client_header_regression_test($test_ref);
+        $result = execute_client_header_regression_test($test);
 
-    } elsif ($test{'type'} == SERVER_HEADER_TEST) {
+    } elsif ($test->{'type'} == SERVER_HEADER_TEST) {
 
-        $result = execute_server_header_regression_test($test_ref);
+        $result = execute_server_header_regression_test($test);
 
-    } elsif ($test{'type'} == DUMB_FETCH_TEST
-          or $test{'type'} == TRUSTED_CGI_REQUEST) {
+    } elsif ($test->{'type'} == DUMB_FETCH_TEST
+          or $test->{'type'} == TRUSTED_CGI_REQUEST) {
 
-        $result = execute_dumb_fetch_test($test_ref);
+        $result = execute_dumb_fetch_test($test);
 
-    } elsif ($test{'type'} == METHOD_TEST) {
+    } elsif ($test->{'type'} == METHOD_TEST) {
 
-        $result = execute_method_test($test_ref);
+        $result = execute_method_test($test);
 
-    } elsif ($test{'type'} == BLOCK_TEST) {
+    } elsif ($test->{'type'} == BLOCK_TEST) {
 
-        $result = execute_block_test($test_ref);
+        $result = execute_block_test($test);
 
-    } elsif ($test{'type'} == STICKY_ACTIONS_TEST) {
+    } elsif ($test->{'type'} == STICKY_ACTIONS_TEST) {
 
-        $result = execute_sticky_actions_test($test_ref);
+        $result = execute_sticky_actions_test($test);
 
     } else {
 
-        die "Unsupported test type detected: " . $test{'type'};
+        die "Unsupported test type detected: " . $test->{'type'};
     }
 
     return $result;
@@ -665,14 +678,13 @@ sub execute_regression_test ($) {
 
 sub execute_method_test ($) {
 
-    my $test_ref = shift;
-    my %test = %{$test_ref};
+    my $test = shift;
     my $buffer_ref;
     my $status_code;
-    my $method = $test{'data'};
+    my $method = $test->{'data'};
 
     my $curl_parameters = '';
-    my $expected_status_code = $test{'expected-status-code'};
+    my $expected_status_code = $test->{'expected-status-code'};
 
     $curl_parameters .= '--request ' . $method . ' ';
     # Don't complain about the 'missing' body
@@ -688,22 +700,21 @@ sub execute_method_test ($) {
 
 sub execute_dumb_fetch_test ($) {
 
-    my $test_ref = shift;
-    my %test = %{$test_ref};
+    my $test = shift;
     my $buffer_ref;
     my $status_code;
 
     my $curl_parameters = '';
-    my $expected_status_code = $test{'expected-status-code'};
+    my $expected_status_code = $test->{'expected-status-code'};
 
-    if (defined $test{method}) {
-        $curl_parameters .= '--request ' . $test{method} . ' ';
+    if (defined $test->{method}) {
+        $curl_parameters .= '--request ' . $test->{method} . ' ';
     }
-    if ($test{type} == TRUSTED_CGI_REQUEST) {
+    if ($test->{type} == TRUSTED_CGI_REQUEST) {
         $curl_parameters .= '--referer ' . PRIVOXY_CGI_URL . ' ';
     }
 
-    $curl_parameters .= $test{'data'};
+    $curl_parameters .= $test->{'data'};
 
     $buffer_ref = get_page_with_curl($curl_parameters);
     $status_code = get_status_code($buffer_ref);
@@ -730,15 +741,18 @@ sub execute_sticky_actions_test ($) {
     my $final_results = get_final_results($url);
 
     foreach my $sticky_action (@sticky_actions) {
+
         if (defined $final_results->{$sticky_action}) {
             # Exact match
             $verified_actions++;
-        }elsif ($sticky_action =~ /-.*\{/ and
-                not defined $final_results->{$sticky_action}) {
+
+        } elsif ($sticky_action =~ /-.*\{/) {
+
             # Disabled multi actions aren't explicitly listed as
             # disabled and thus have to be checked by verifying
             # that they aren't enabled.
             $verified_actions++;
+
         } else {
             l(LL_VERBOSE_FAILURE,
               "Ooops. '$sticky_action' is not among the final results.");
@@ -824,28 +838,28 @@ sub check_status_code_result ($$) {
 
 sub execute_client_header_regression_test ($) {
 
-    my $test_ref = shift;
+    my $test = shift;
     my $buffer_ref;
     my $header;
 
-    $buffer_ref = get_show_request_with_curl($test_ref);
+    $buffer_ref = get_show_request_with_curl($test);
 
-    $header = get_header($buffer_ref, $test_ref);
+    $header = get_header($buffer_ref, $test);
 
-    return check_header_result($test_ref, $header);
+    return check_header_result($test, $header);
 }
 
 sub execute_server_header_regression_test ($) {
 
-    my $test_ref = shift;
+    my $test = shift;
     my $buffer_ref;
     my $header;
 
-    $buffer_ref = get_head_with_curl($test_ref);
+    $buffer_ref = get_head_with_curl($test);
 
-    $header = get_server_header($buffer_ref, $test_ref);
+    $header = get_server_header($buffer_ref, $test);
 
-    return check_header_result($test_ref, $header);
+    return check_header_result($test, $header);
 }
 
 sub interpret_result ($) {
@@ -855,16 +869,15 @@ sub interpret_result ($) {
 
 sub check_header_result ($$) {
 
-    my $test_ref = shift;
+    my $test = shift;
     my $header = shift;
 
-    my %test = %{$test_ref};
-    my $expect_header = $test{'expect-header'};
+    my $expect_header = $test->{'expect-header'};
     my $success = 0;
 
     if ($expect_header eq 'NO CHANGE') {
 
-        if (defined($header) and $header eq $test{'data'}) {
+        if (defined($header) and $header eq $test->{'data'}) {
 
             $success = 1;
 
@@ -877,7 +890,7 @@ sub check_header_result ($$) {
 
     } elsif ($expect_header eq 'REMOVAL') {
 
-        if (defined($header) and $header eq $test{'data'}) {
+        if (defined($header) and $header eq $test->{'data'}) {
 
             l(LL_VERBOSE_FAILURE,
               "Ooops. Expected removal but: '" . $header . "' is still there.");
@@ -891,7 +904,7 @@ sub check_header_result ($$) {
 
     } elsif ($expect_header eq 'SOME CHANGE') {
 
-        if (defined($header) and not $header eq $test{'data'}) {
+        if (defined($header) and not $header eq $test->{'data'}) {
 
             $success = 1;
 
@@ -932,12 +945,11 @@ sub get_header ($$) {
     our $filtered_request = '';
 
     my $buffer_ref = shift;
-    my $test_ref = shift;
+    my $test = shift;
 
-    my %test = %{$test_ref};
     my @buffer = @{$buffer_ref};
 
-    my $expect_header = $test{'expect-header'};
+    my $expect_header = $test->{'expect-header'};
 
     die "get_header called with no expect header" unless defined $expect_header;
 
@@ -952,7 +964,7 @@ sub get_header ($$) {
      or $expect_header eq 'NO CHANGE'
      or  $expect_header eq 'SOME CHANGE') {
 
-        $expect_header = $test{'data'};
+        $expect_header = $test->{'data'};
     }
 
     $header_to_get = get_header_name($expect_header);
@@ -991,24 +1003,23 @@ sub get_header ($$) {
 sub get_server_header ($$) {
 
     my $buffer_ref = shift;
-    my $test_ref = shift;
+    my $test = shift;
 
-    my %test = %{$test_ref};
     my @buffer = @{$buffer_ref};
 
-    my $expect_header = $test{'expect-header'};
+    my $expect_header = $test->{'expect-header'};
     my $header;
     my $header_to_get;
 
     # XXX: Should be caught before starting to test.
-    l(LL_ERROR, "No expect header for test " . $test{'number'})
+    log_and_die("No expect header for test " . $test->{'number'})
         unless defined $expect_header;
 
     if ($expect_header eq 'REMOVAL'
      or $expect_header eq 'NO CHANGE'
      or $expect_header eq 'SOME CHANGE') {
 
-        $expect_header = $test{'data'};
+        $expect_header = $test->{'data'};
     }
 
     $header_to_get = get_header_name($expect_header);
@@ -1042,7 +1053,7 @@ sub get_status_code ($) {
 
             return '123' if cli_option_is_set('fuzzer-feeding');
             chomp;
-            l(LL_ERROR, 'Unexpected buffer line: "' . $_ . '"');
+            log_and_die('Unexpected buffer line: "' . $_ . '"');
         }
     }
 }
@@ -1054,22 +1065,21 @@ sub get_test_keys () {
 # XXX: incomplete
 sub test_content_as_string ($) {
 
-    my $test_ref = shift;
-    my %test = %{$test_ref};
+    my $test = shift;
 
     my $s = "\n\t";
 
     foreach my $key (get_test_keys()) {
-        $test{$key} = 'Not set' unless (defined $test{$key});
+        $test->{$key} = 'Not set' unless (defined $test->{$key});
     }
 
-    $s .= 'Tag: ' . $test{'tag'};
+    $s .= 'Tag: ' . $test->{'tag'};
     $s .= "\n\t";
-    $s .= 'Set header: ' . $test{'data'}; # XXX: adjust for other test types
+    $s .= 'Set header: ' . $test->{'data'}; # XXX: adjust for other test types
     $s .= "\n\t";
-    $s .= 'Expected header: ' . $test{'expect-header'};
+    $s .= 'Expected header: ' . $test->{'expect-header'};
     $s .= "\n\t";
-    $s .= 'Ignore: ' . $test{'ignore'};
+    $s .= 'Ignore: ' . $test->{'ignore'};
 
     return $s;
 }
@@ -1094,11 +1104,6 @@ sub fuzz_header($) {
 #
 ############################################################################
 
-sub check_for_curl () {
-    my $curl = CURL;
-    l(LL_ERROR, "No curl found.") unless (`which $curl`);
-}
-
 sub get_cgi_page_or_else ($) {
 
     my $cgi_url = shift;
@@ -1118,7 +1123,7 @@ sub get_cgi_page_or_else ($) {
 
         } else {
 
-            l(LL_ERROR, $log_message);
+            log_and_die($log_message);
         }
     }
     
@@ -1129,18 +1134,17 @@ sub get_cgi_page_or_else ($) {
 sub get_show_request_with_curl ($) {
 
     our $privoxy_cgi_url;
-    my $test_ref = shift;
-    my %test = %{$test_ref};
+    my $test = shift;
 
     my $curl_parameters = ' ';
-    my $header = $test{'data'};
+    my $header = $test->{'data'};
 
     if (cli_option_is_set('header-fuzzing')) {
         $header = fuzz_header($header);
     }
 
     # Enable the action to test
-    $curl_parameters .= '-H \'X-Privoxy-Control: ' . $test{'tag'} . '\' ';
+    $curl_parameters .= '-H \'X-Privoxy-Control: ' . $test->{'tag'} . '\' ';
     # The header to filter
     $curl_parameters .= '-H \'' . $header . '\' ';
 
@@ -1154,15 +1158,14 @@ sub get_show_request_with_curl ($) {
 sub get_head_with_curl ($) {
 
     our $fellatio_url = FELLATIO_URL;
-    my $test_ref = shift;
-    my %test = %{$test_ref};
+    my $test = shift;
 
     my $curl_parameters = ' ';
 
     # Enable the action to test
-    $curl_parameters .= '-H \'X-Privoxy-Control: ' . $test{'tag'} . '\' ';
+    $curl_parameters .= '-H \'X-Privoxy-Control: ' . $test->{'tag'} . '\' ';
     # The header to filter
-    $curl_parameters .= '-H \'X-Gimme-Head-With: ' . $test{'data'} . '\' ';
+    $curl_parameters .= '-H \'X-Gimme-Head-With: ' . $test->{'data'} . '\' ';
     $curl_parameters .= '--head ';
 
     $curl_parameters .= ' ';
@@ -1207,6 +1210,7 @@ sub get_page_with_curl ($) {
         @buffer = `$curl_line`;
 
         if ($?) {
+            log_and_die("Executing '$curl_line' failed.") unless @buffer;
             $failure_reason = array_as_string(\@buffer);
             chomp $failure_reason;
             l(LL_SOFT_ERROR, "Fetch failure: '" . $failure_reason . $! ."'");
@@ -1214,9 +1218,8 @@ sub get_page_with_curl ($) {
     } while ($? && --$retries_left);
 
     unless ($retries_left) {
-        l(LL_ERROR,
-          "Running curl failed " . get_cli_option('retries') .
-          " times in a row. Last error: '" . $failure_reason . "'.");
+        log_and_die("Running curl failed " . get_cli_option('retries') .
+                    " times in a row. Last error: '" . $failure_reason . "'.");
     }
 
     return \@buffer;
@@ -1241,8 +1244,8 @@ sub array_as_string ($) {
 }
 
 sub show_test ($) {
-    my $test_ref = shift;
-    log_message('Test is:' . test_content_as_string($test_ref));
+    my $test = shift;
+    log_message('Test is:' . test_content_as_string($test));
 }
 
 # Conditional log
@@ -1251,17 +1254,14 @@ sub l ($$) {
     my $this_level = shift;
     my $message = shift;
 
-    return unless ($log_level & $this_level);
-
-    if (LL_ERROR & $this_level) {
-        $message = 'Oh noes. ' . $message . ' Fatal error. Exiting.';
-    }
+    log_message($message) if ($log_level & $this_level);
+}
 
-    log_message($message);
+sub log_and_die ($) {
+    my $message = shift;
 
-    if (LL_ERROR & $this_level) {
-        exit;
-    }
+    log_message('Oh noes. ' . $message . ' Fatal error. Exiting.');
+    exit;
 }
 
 sub log_message ($) {
@@ -1300,76 +1300,75 @@ sub log_result ($$) {
     our $verbose_test_description;
     our $filtered_request;
 
-    my $test_ref = shift;
+    my $test = shift;
     my $result = shift;
     my $number = shift;
 
-    my %test = %{$test_ref};
     my $message = '';
 
     $message .= interpret_result($result);
     $message .= " for test ";
     $message .= $number;
     $message .= '/';
-    $message .= $test{'number'};
+    $message .= $test->{'number'};
     $message .= '/';
-    $message .= $test{'section-id'};
+    $message .= $test->{'section-id'};
     $message .= '/';
-    $message .= $test{'regression-test-id'};
+    $message .= $test->{'regression-test-id'};
     $message .= '.';
 
     if ($verbose_test_description) {
 
-        if ($test{'type'} == CLIENT_HEADER_TEST) {
+        if ($test->{'type'} == CLIENT_HEADER_TEST) {
 
             $message .= ' Header ';
-            $message .= quote($test{'data'});
+            $message .= quote($test->{'data'});
             $message .= ' and tag ';
-            $message .= quote($test{'tag'});
+            $message .= quote($test->{'tag'});
 
-        } elsif ($test{'type'} == SERVER_HEADER_TEST) {
+        } elsif ($test->{'type'} == SERVER_HEADER_TEST) {
 
             $message .= ' Request Header ';
-            $message .= quote($test{'data'});
+            $message .= quote($test->{'data'});
             $message .= ' and tag ';
-            $message .= quote($test{'tag'});
+            $message .= quote($test->{'tag'});
 
-        } elsif ($test{'type'} == DUMB_FETCH_TEST) {
+        } elsif ($test->{'type'} == DUMB_FETCH_TEST) {
 
             $message .= ' URL ';
-            $message .= quote($test{'data'});
+            $message .= quote($test->{'data'});
             $message .= ' and expected status code ';
-            $message .= quote($test{'expected-status-code'});
+            $message .= quote($test->{'expected-status-code'});
 
-        } elsif ($test{'type'} == TRUSTED_CGI_REQUEST) {
+        } elsif ($test->{'type'} == TRUSTED_CGI_REQUEST) {
 
             $message .= ' CGI URL ';
-            $message .= quote($test{'data'});
+            $message .= quote($test->{'data'});
             $message .= ' and expected status code ';
-            $message .= quote($test{'expected-status-code'});
+            $message .= quote($test->{'expected-status-code'});
 
-        } elsif ($test{'type'} == METHOD_TEST) {
+        } elsif ($test->{'type'} == METHOD_TEST) {
 
             $message .= ' HTTP method ';
-            $message .= quote($test{'data'});
+            $message .= quote($test->{'data'});
             $message .= ' and expected status code ';
-            $message .= quote($test{'expected-status-code'});
+            $message .= quote($test->{'expected-status-code'});
 
-        } elsif ($test{'type'} == BLOCK_TEST) {
+        } elsif ($test->{'type'} == BLOCK_TEST) {
 
             $message .= ' Supposedly-blocked URL: ';
-            $message .= quote($test{'data'});
+            $message .= quote($test->{'data'});
 
-        } elsif ($test{'type'} == STICKY_ACTIONS_TEST) {
+        } elsif ($test->{'type'} == STICKY_ACTIONS_TEST) {
 
             $message .= ' Sticky Actions: ';
-            $message .= quote($test{'sticky-actions'});
+            $message .= quote($test->{'sticky-actions'});
             $message .= ' and URL: ';
-            $message .= quote($test{'data'});
+            $message .= quote($test->{'data'});
 
         } else {
 
-            die "Incomplete support for test type " . $test{'type'} .  " detected.";
+            die "Incomplete support for test type " . $test->{'type'} .  " detected.";
         }
     }
 
@@ -1498,7 +1497,7 @@ sub init_proxy_settings($) {
 sub start_forks($) {
     my $forks = shift;
 
-    l(LL_ERROR, "Invalid --fork value: " . $forks . ".") if ($forks < 0); 
+    log_and_die("Invalid --fork value: " . $forks . ".") if ($forks < 0);
 
     foreach my $fork (1 .. $forks) {
         log_message("Starting fork $fork");
@@ -1513,7 +1512,6 @@ sub main () {
 
     init_our_variables();
     parse_cli_options();
-    check_for_curl();
     init_proxy_settings('vanilla-proxy');
     load_regressions_tests();
     init_proxy_settings('fuzz-proxy');