mirror of
https://github.com/owasp-modsecurity/ModSecurity.git
synced 2025-09-29 19:24:29 +03:00
Some more updates for regression testing.
This commit is contained in:
@@ -1,4 +1,6 @@
|
|||||||
### Pass
|
### Tests all of the actions in each phase
|
||||||
|
|
||||||
|
# Pass
|
||||||
{
|
{
|
||||||
type => "action",
|
type => "action",
|
||||||
comment => "pass action in phase:1",
|
comment => "pass action in phase:1",
|
||||||
@@ -72,7 +74,7 @@
|
|||||||
),
|
),
|
||||||
},
|
},
|
||||||
|
|
||||||
### Allow
|
# Allow
|
||||||
{
|
{
|
||||||
type => "action",
|
type => "action",
|
||||||
comment => "allow action in phase:1",
|
comment => "allow action in phase:1",
|
||||||
@@ -146,7 +148,7 @@
|
|||||||
),
|
),
|
||||||
},
|
},
|
||||||
|
|
||||||
### Deny
|
# Deny
|
||||||
{
|
{
|
||||||
type => "action",
|
type => "action",
|
||||||
comment => "deny action in phase:1",
|
comment => "deny action in phase:1",
|
||||||
@@ -216,7 +218,7 @@
|
|||||||
),
|
),
|
||||||
},
|
},
|
||||||
|
|
||||||
### Drop
|
# Drop
|
||||||
{
|
{
|
||||||
type => "action",
|
type => "action",
|
||||||
comment => "drop action in phase:1",
|
comment => "drop action in phase:1",
|
||||||
@@ -286,7 +288,7 @@
|
|||||||
),
|
),
|
||||||
},
|
},
|
||||||
|
|
||||||
### Redirect
|
# Redirect
|
||||||
{
|
{
|
||||||
type => "action",
|
type => "action",
|
||||||
comment => "redirect action in phase:1 (get)",
|
comment => "redirect action in phase:1 (get)",
|
||||||
@@ -360,7 +362,7 @@
|
|||||||
),
|
),
|
||||||
},
|
},
|
||||||
|
|
||||||
### Proxy
|
# Proxy
|
||||||
{
|
{
|
||||||
type => "action",
|
type => "action",
|
||||||
comment => "proxy action in phase:1 (get)",
|
comment => "proxy action in phase:1 (get)",
|
||||||
|
@@ -1,4 +1,6 @@
|
|||||||
### SecAudit* directive tests
|
### SecAudit* directive tests
|
||||||
|
|
||||||
|
# SecAuditEngine
|
||||||
{
|
{
|
||||||
type => "config",
|
type => "config",
|
||||||
comment => "SecAuditEngine On",
|
comment => "SecAuditEngine On",
|
||||||
@@ -75,6 +77,84 @@
|
|||||||
GET => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt",
|
GET => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt",
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
|
|
||||||
|
# SecAuditLogType & SecAuditLogStorageDir
|
||||||
|
{
|
||||||
|
type => "config",
|
||||||
|
comment => "SecAuditLogType Serial",
|
||||||
|
conf => qq(
|
||||||
|
SecAuditEngine On
|
||||||
|
SecAuditLog $ENV{AUDIT_LOG}
|
||||||
|
SecAuditLogType Serial
|
||||||
|
),
|
||||||
|
match_log => {
|
||||||
|
audit => [ qr/./, 1 ],
|
||||||
|
},
|
||||||
|
match_response => {
|
||||||
|
status => qr/^404$/,
|
||||||
|
},
|
||||||
|
request => new HTTP::Request(
|
||||||
|
GET => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/bogus",
|
||||||
|
),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type => "config",
|
||||||
|
comment => "SecAuditLogType Concurrent",
|
||||||
|
conf => qq(
|
||||||
|
SecAuditEngine On
|
||||||
|
SecAuditLog $ENV{AUDIT_LOG}
|
||||||
|
SecAuditLogType Concurrent
|
||||||
|
SecAuditLogStorageDir "$ENV{LOGS_DIR}/audit"
|
||||||
|
),
|
||||||
|
test => sub {
|
||||||
|
### Perl code to parse the audit log entry and verify
|
||||||
|
### that the concurrent audit log exists and contains
|
||||||
|
### the correct data.
|
||||||
|
###
|
||||||
|
### TODO: Need some API for this :)
|
||||||
|
###
|
||||||
|
|
||||||
|
# Parse log
|
||||||
|
my $alogre = qr/^(?:\S+)\ (?:\S+)\ (?:\S+)\ (?:\S+)\ \[(?:[^:]+):(?:\d+:\d+:\d+)\ (?:[^\]]+)\]\ \"(?:.*)\"\ (?:\d+)\ (?:\S+)\ \"(?:.*)\"\ \"(?:.*)\"\ (\S+)\ \"(?:.*)\"\ (\S+)\ (?:\d+)\ (?:\d+)\ (?:\S+)(?:.*)$/m;
|
||||||
|
my $alog = match_log("audit", $alogre, 1);
|
||||||
|
chomp $alog;
|
||||||
|
my @log = ($alog =~ m/$alogre/);
|
||||||
|
my($id, $fn) = ($log[0], $log[1]);
|
||||||
|
if (!$id or !$fn) {
|
||||||
|
dbg("LOG ENTRY: $alog");
|
||||||
|
die "Failed to parse audit log: $ENV{AUDIT_LOG}\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
# Verify concurrent log exists
|
||||||
|
my $alogdatafn = "$ENV{LOGS_DIR}/audit$fn";
|
||||||
|
if (! -e "$alogdatafn") {
|
||||||
|
die "Audit log does not exist: $alogdatafn\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
# Verify concurrent log contents
|
||||||
|
$LOG{$id}{fd} = new FileHandle($alogdatafn, O_RDONLY);
|
||||||
|
$LOG{$id}{fd}->blocking(0);
|
||||||
|
$LOG{$id}{buf} = "";
|
||||||
|
my $alogdata = match_log($id, qr/^--[^-]+-A--.*$id.*-Z--$/s, 1);
|
||||||
|
if (defined $alogdata) {
|
||||||
|
$LOG{$id}{fd}->close();
|
||||||
|
delete $LOG{$id};
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Error
|
||||||
|
dbg("LOGDATA: \"$alogdata\"");
|
||||||
|
die "Audit log data did not match.\n";
|
||||||
|
},
|
||||||
|
match_response => {
|
||||||
|
status => qr/^200$/,
|
||||||
|
},
|
||||||
|
request => new HTTP::Request(
|
||||||
|
GET => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt",
|
||||||
|
),
|
||||||
|
},
|
||||||
|
|
||||||
|
# SecAuditLogRelevantStatus
|
||||||
{
|
{
|
||||||
type => "config",
|
type => "config",
|
||||||
comment => "SecAuditLogRelevantStatus (pos)",
|
comment => "SecAuditLogRelevantStatus (pos)",
|
||||||
@@ -111,6 +191,8 @@
|
|||||||
GET => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt",
|
GET => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt",
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
|
|
||||||
|
# SecAuditLogParts
|
||||||
{
|
{
|
||||||
type => "config",
|
type => "config",
|
||||||
comment => "SecAuditLogParts (minimal)",
|
comment => "SecAuditLogParts (minimal)",
|
||||||
|
@@ -1 +1,49 @@
|
|||||||
### Misc directive tests
|
### Misc directive tests
|
||||||
|
|
||||||
|
### TODO:
|
||||||
|
# SecTmpDir
|
||||||
|
# SecUploadDir
|
||||||
|
# SecUploadKeepFiles
|
||||||
|
# SecWebAppId
|
||||||
|
# SecDataDir
|
||||||
|
# SecChrootDir
|
||||||
|
# SecGuardianLog
|
||||||
|
|
||||||
|
# SecServerSignature
|
||||||
|
{
|
||||||
|
type => "config",
|
||||||
|
comment => "SecServerSignature On",
|
||||||
|
conf => qq(
|
||||||
|
SecServerSignature "NewServerSignature"
|
||||||
|
),
|
||||||
|
match_log => {
|
||||||
|
error => [ qr/NewServerSignature/, 1 ],
|
||||||
|
},
|
||||||
|
match_response => {
|
||||||
|
status => qr/^200$/,
|
||||||
|
raw => qr/^Server: +NewServerSignature$/m,
|
||||||
|
},
|
||||||
|
request => new HTTP::Request(
|
||||||
|
GET => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt",
|
||||||
|
),
|
||||||
|
},
|
||||||
|
|
||||||
|
# SecDefaultAction
|
||||||
|
{
|
||||||
|
type => "config",
|
||||||
|
comment => "SecServerSignature On",
|
||||||
|
conf => qq(
|
||||||
|
SecRuleEngine on
|
||||||
|
SecDefaultAction "phase:1,deny,status:500"
|
||||||
|
SecRule REQUEST_URI "test.txt"
|
||||||
|
),
|
||||||
|
match_log => {
|
||||||
|
error => [ qr/ModSecurity: Access denied with code 500 \(phase 1\)/, 1 ],
|
||||||
|
},
|
||||||
|
match_response => {
|
||||||
|
status => qr/^500$/,
|
||||||
|
},
|
||||||
|
request => new HTTP::Request(
|
||||||
|
GET => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt",
|
||||||
|
),
|
||||||
|
},
|
||||||
|
@@ -1,5 +1,6 @@
|
|||||||
|
### Tests for directives altering how a request is handled
|
||||||
|
|
||||||
### SecArgumentSeparator
|
# SecArgumentSeparator
|
||||||
{
|
{
|
||||||
type => "config",
|
type => "config",
|
||||||
comment => "SecArgumentSeparator (get-pos)",
|
comment => "SecArgumentSeparator (get-pos)",
|
||||||
@@ -85,7 +86,7 @@
|
|||||||
),
|
),
|
||||||
},
|
},
|
||||||
|
|
||||||
### SecRequestBodyAccess
|
# SecRequestBodyAccess
|
||||||
{
|
{
|
||||||
type => "config",
|
type => "config",
|
||||||
comment => "SecRequestBodyAccess (pos)",
|
comment => "SecRequestBodyAccess (pos)",
|
||||||
@@ -133,7 +134,7 @@
|
|||||||
),
|
),
|
||||||
},
|
},
|
||||||
|
|
||||||
### SecRequestBodyLimit
|
# SecRequestBodyLimit
|
||||||
{
|
{
|
||||||
type => "config",
|
type => "config",
|
||||||
comment => "SecRequestBodyLimit (equal)",
|
comment => "SecRequestBodyLimit (equal)",
|
||||||
@@ -179,7 +180,7 @@
|
|||||||
),
|
),
|
||||||
},
|
},
|
||||||
|
|
||||||
### SecRequestBodyInMemoryLimit
|
# SecRequestBodyInMemoryLimit
|
||||||
{
|
{
|
||||||
type => "config",
|
type => "config",
|
||||||
comment => "SecRequestBodyInMemoryLimit (equal)",
|
comment => "SecRequestBodyInMemoryLimit (equal)",
|
||||||
@@ -249,7 +250,7 @@ Content-Disposition: form-data; name="b"
|
|||||||
-----------------------------69343412719991675451336310646--), 1024),
|
-----------------------------69343412719991675451336310646--), 1024),
|
||||||
},
|
},
|
||||||
|
|
||||||
### SecCookieFormat
|
# SecCookieFormat
|
||||||
{
|
{
|
||||||
type => "config",
|
type => "config",
|
||||||
comment => "SecCookieFormat (pos)",
|
comment => "SecCookieFormat (pos)",
|
||||||
|
145
apache2/t/regression/config/10-response-directives.t
Normal file
145
apache2/t/regression/config/10-response-directives.t
Normal file
@@ -0,0 +1,145 @@
|
|||||||
|
### Tests for directives altering how a response is handled
|
||||||
|
|
||||||
|
# SecResponseBodyAccess
|
||||||
|
{
|
||||||
|
type => "config",
|
||||||
|
comment => "SecResponseBodyAccess (pos)",
|
||||||
|
conf => qq(
|
||||||
|
SecRuleEngine On
|
||||||
|
SecResponseBodyAccess On
|
||||||
|
SecResponseBodyMimeType null
|
||||||
|
SecRule RESPONSE_BODY "TEST" "phase:4,deny"
|
||||||
|
),
|
||||||
|
match_log => {
|
||||||
|
error => [ qr/Access denied with code 403 \(phase 4\)\. Pattern match "TEST" at RESPONSE_BODY\./, 1 ],
|
||||||
|
},
|
||||||
|
match_response => {
|
||||||
|
status => qr/^403$/,
|
||||||
|
},
|
||||||
|
request => new HTTP::Request(
|
||||||
|
GET => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt",
|
||||||
|
),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type => "config",
|
||||||
|
comment => "SecResponseBodyAccess (neg)",
|
||||||
|
conf => qq(
|
||||||
|
SecRuleEngine On
|
||||||
|
SecResponseBodyAccess Off
|
||||||
|
SecResponseBodyMimeType null
|
||||||
|
SecRule RESPONSE_BODY "TEST" "phase:4,deny"
|
||||||
|
),
|
||||||
|
match_log => {
|
||||||
|
-error => [ qr/Access denied/, 1 ],
|
||||||
|
},
|
||||||
|
match_response => {
|
||||||
|
status => qr/^200$/,
|
||||||
|
},
|
||||||
|
request => new HTTP::Request(
|
||||||
|
GET => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt",
|
||||||
|
),
|
||||||
|
},
|
||||||
|
|
||||||
|
# SecResponseBodyLimit
|
||||||
|
{
|
||||||
|
type => "config",
|
||||||
|
comment => "SecResponseBodyLimit (equal)",
|
||||||
|
conf => qq(
|
||||||
|
SecRuleEngine On
|
||||||
|
SecResponseBodyAccess On
|
||||||
|
SecResponseBodyMimeType null
|
||||||
|
SecResponseBodyLimit 8192
|
||||||
|
),
|
||||||
|
match_log => {
|
||||||
|
-error => [ qr/Content-Length \(\d+\) over the limit/, 1 ],
|
||||||
|
},
|
||||||
|
match_response => {
|
||||||
|
status => qr/^200$/,
|
||||||
|
},
|
||||||
|
request => new HTTP::Request(
|
||||||
|
GET => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/8k.txt",
|
||||||
|
),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type => "config",
|
||||||
|
comment => "SecResponseBodyLimit (less)",
|
||||||
|
conf => qq(
|
||||||
|
SecRuleEngine On
|
||||||
|
SecResponseBodyAccess On
|
||||||
|
SecResponseBodyMimeType null
|
||||||
|
SecResponseBodyLimit 9000
|
||||||
|
),
|
||||||
|
match_log => {
|
||||||
|
-error => [ qr/Content-Length \(\d+\) over the limit/, 1 ],
|
||||||
|
},
|
||||||
|
match_response => {
|
||||||
|
status => qr/^200$/,
|
||||||
|
},
|
||||||
|
request => new HTTP::Request(
|
||||||
|
GET => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/8k.txt",
|
||||||
|
),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type => "config",
|
||||||
|
comment => "SecResponseBodyLimit (greater)",
|
||||||
|
conf => qq(
|
||||||
|
SecRuleEngine On
|
||||||
|
SecResponseBodyAccess On
|
||||||
|
SecResponseBodyMimeType null
|
||||||
|
SecResponseBodyLimit 8000
|
||||||
|
),
|
||||||
|
match_log => {
|
||||||
|
error => [ qr/Content-Length \(\d+\) over the limit \(8000\)\./, 1 ],
|
||||||
|
},
|
||||||
|
match_response => {
|
||||||
|
status => qr/^500$/,
|
||||||
|
},
|
||||||
|
request => new HTTP::Request(
|
||||||
|
GET => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/8k.txt",
|
||||||
|
),
|
||||||
|
},
|
||||||
|
|
||||||
|
# ResponseBodyLimitAction
|
||||||
|
{
|
||||||
|
type => "config",
|
||||||
|
comment => "SecResponseBodyLimitAction Reject",
|
||||||
|
conf => qq(
|
||||||
|
SecRuleEngine On
|
||||||
|
SecResponseBodyAccess On
|
||||||
|
SecResponseBodyMimeType null
|
||||||
|
SecResponseBodyLimit 5
|
||||||
|
SecResponseBodyLimitAction Reject
|
||||||
|
),
|
||||||
|
match_log => {
|
||||||
|
error => [ qr/Content-Length \(\d+\) over the limit \(5\)\./, 1 ],
|
||||||
|
},
|
||||||
|
match_response => {
|
||||||
|
status => qr/^500$/,
|
||||||
|
},
|
||||||
|
request => new HTTP::Request(
|
||||||
|
GET => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/8k.txt",
|
||||||
|
),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type => "config",
|
||||||
|
comment => "SecResponseBodyLimitAction ProcessPartial",
|
||||||
|
conf => qq(
|
||||||
|
SecRuleEngine On
|
||||||
|
SecResponseBodyAccess On
|
||||||
|
SecResponseBodyMimeType null
|
||||||
|
SecResponseBodyLimit 5
|
||||||
|
SecDebugLog $ENV{DEBUG_LOG}
|
||||||
|
SecDebugLogLevel 4
|
||||||
|
SecResponseBodyLimitAction ProcessPartial
|
||||||
|
),
|
||||||
|
match_log => {
|
||||||
|
-error => [ qr/Content-Length \(\d+\) over the limit/, 1 ],
|
||||||
|
debug => [ qr/Processing partial response body \(limit 5\)/, 1 ],
|
||||||
|
},
|
||||||
|
match_response => {
|
||||||
|
status => qr/^200$/,
|
||||||
|
},
|
||||||
|
request => new HTTP::Request(
|
||||||
|
GET => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/8k.txt",
|
||||||
|
),
|
||||||
|
},
|
BIN
apache2/t/regression/server_root/htdocs/8k.txt
Normal file
BIN
apache2/t/regression/server_root/htdocs/8k.txt
Normal file
Binary file not shown.
@@ -1,3 +1,4 @@
|
|||||||
|
#!/usr/bin/perl
|
||||||
#!@PERL@
|
#!@PERL@
|
||||||
#
|
#
|
||||||
# Run regression tests.
|
# Run regression tests.
|
||||||
@@ -29,6 +30,7 @@ my $SROOT_DIR = "$REG_DIR/server_root";
|
|||||||
my $CONF_DIR = "$SROOT_DIR/conf";
|
my $CONF_DIR = "$SROOT_DIR/conf";
|
||||||
my $LOGS_DIR = "$SROOT_DIR/logs";
|
my $LOGS_DIR = "$SROOT_DIR/logs";
|
||||||
my $PID_FILE = "$LOGS_DIR/httpd.pid";
|
my $PID_FILE = "$LOGS_DIR/httpd.pid";
|
||||||
|
my $HTTPD = q(@APXS_HTTPD@);
|
||||||
my $PASSED = 0;
|
my $PASSED = 0;
|
||||||
my $TOTAL = 0;
|
my $TOTAL = 0;
|
||||||
my %C = ();
|
my %C = ();
|
||||||
@@ -37,6 +39,11 @@ my $UA_NAME = "ModSecurity Regression Tests/1.2.3";
|
|||||||
my $UA = LWP::UserAgent->new;
|
my $UA = LWP::UserAgent->new;
|
||||||
$UA->agent($UA_NAME);
|
$UA->agent($UA_NAME);
|
||||||
|
|
||||||
|
# Hack for testing the script w/o configure
|
||||||
|
if ($HTTPD eq "\@APXS_HTTPD\@") {
|
||||||
|
$HTTPD = "/usr/local/apache2/bin/httpd";
|
||||||
|
}
|
||||||
|
|
||||||
$SIG{TERM} = $SIG{INT} = \&handle_interrupt;
|
$SIG{TERM} = $SIG{INT} = \&handle_interrupt;
|
||||||
|
|
||||||
my %opt;
|
my %opt;
|
||||||
@@ -74,8 +81,13 @@ EOT
|
|||||||
usage() if ($opt{h});
|
usage() if ($opt{h});
|
||||||
|
|
||||||
### Check httpd binary
|
### Check httpd binary
|
||||||
$opt{a} = "@APXS_HTTPD@" unless (defined $opt{a});
|
if (defined $opt{a}) {
|
||||||
usage("Invalid Apache startup script: $opt{a}\n") unless (-e $opt{a});
|
$HTTPD = $opt{a};
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$opt{a} = $HTTPD;
|
||||||
|
}
|
||||||
|
usage("Invalid Apache startup script: $HTTPD\n") unless (-e $HTTPD);
|
||||||
|
|
||||||
### Defaults
|
### Defaults
|
||||||
$opt{A} = "$LOGS_DIR/modsec_audit.log" unless (defined $opt{A});
|
$opt{A} = "$LOGS_DIR/modsec_audit.log" unless (defined $opt{A});
|
||||||
@@ -86,7 +98,7 @@ $opt{H} = "$SROOT_DIR/htdocs" unless (defined $opt{H});
|
|||||||
$opt{p} = 8088 unless (defined $opt{p});
|
$opt{p} = 8088 unless (defined $opt{p});
|
||||||
|
|
||||||
unless (defined $opt{S}) {
|
unless (defined $opt{S}) {
|
||||||
my $httpd_root = `$opt{a} -V`;
|
my $httpd_root = `$HTTPD -V`;
|
||||||
($opt{S} = $httpd_root) =~ s/.*-D HTTPD_ROOT="([^"]*)".*/$1/sm;
|
($opt{S} = $httpd_root) =~ s/.*-D HTTPD_ROOT="([^"]*)".*/$1/sm;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -178,7 +190,8 @@ sub runfile {
|
|||||||
$CONF_DIR, $t{type}, $cfg, $n;
|
$CONF_DIR, $t{type}, $cfg, $n;
|
||||||
# dbg("Writing test config to: $conf_fn");
|
# dbg("Writing test config to: $conf_fn");
|
||||||
open(CONF, ">$conf_fn") or die "Failed to open conf \"$conf_fn\": $!\n";
|
open(CONF, ">$conf_fn") or die "Failed to open conf \"$conf_fn\": $!\n";
|
||||||
print CONF (ref $t{conf} eq "CODE" ? &{$t{conf}} : $t{conf});
|
print CONF (ref $t{conf} eq "CODE" ? eval { &{$t{conf}} } : $t{conf});
|
||||||
|
msg("$@") if ($@);
|
||||||
close CONF;
|
close CONF;
|
||||||
$httpd_up = httpd_start("Include $conf_fn") ? 0 : 1;
|
$httpd_up = httpd_start("Include $conf_fn") ? 0 : 1;
|
||||||
}
|
}
|
||||||
@@ -223,15 +236,15 @@ sub runfile {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
msg("Failed to start httpd.");
|
|
||||||
$rc = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
# Run any arbitrary perl tests
|
# Run any arbitrary perl tests
|
||||||
if ($rc == 0 and exists $t{test} and defined $t{test}) {
|
if ($rc == 0 and exists $t{test} and defined $t{test}) {
|
||||||
dbg("Executing perl test(s)...");
|
dbg("Executing perl test(s)...");
|
||||||
$rc = &{$t{test}};
|
$rc = eval { &{$t{test}} };
|
||||||
|
if (! defined $rc) {
|
||||||
|
msg("Error running test: $@");
|
||||||
|
$rc = -1;
|
||||||
|
}
|
||||||
dbg("Perl tests returned: $rc");
|
dbg("Perl tests returned: $rc");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -257,6 +270,10 @@ sub runfile {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
msg("Failed to start httpd.");
|
||||||
|
$rc = 1;
|
||||||
|
}
|
||||||
|
|
||||||
if ($rc == 0) {
|
if ($rc == 0) {
|
||||||
$pass++;
|
$pass++;
|
||||||
@@ -307,7 +324,8 @@ sub do_request {
|
|||||||
|
|
||||||
# Allow test to execute code
|
# Allow test to execute code
|
||||||
if (ref $r eq "CODE") {
|
if (ref $r eq "CODE") {
|
||||||
$r = &$r;
|
$r = eval { &$r };
|
||||||
|
msg("$@") unless (defined $r);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ref $r eq "HTTP::Request") {
|
if (ref $r eq "HTTP::Request") {
|
||||||
@@ -334,13 +352,16 @@ sub match_response {
|
|||||||
elsif ($name eq "content") {
|
elsif ($name eq "content") {
|
||||||
return $& if ($resp->content =~ m/$re/m);
|
return $& if ($resp->content =~ m/$re/m);
|
||||||
}
|
}
|
||||||
|
elsif ($name eq "raw") {
|
||||||
|
return $& if ($resp->as_string =~ m/$re/m);
|
||||||
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
sub match_log {
|
sub match_log {
|
||||||
my($name, $re, $timeout) = @_;
|
my($name, $re, $timeout) = @_;
|
||||||
my $t0 = gettimeofday();
|
my $t0 = gettimeofday;
|
||||||
my($fh,$rbuf) = ($LOG{$name}{fd}, \$LOG{$name}{buf});
|
my($fh,$rbuf) = ($LOG{$name}{fd}, \$LOG{$name}{buf});
|
||||||
my $n = length($$rbuf);
|
my $n = length($$rbuf);
|
||||||
|
|
||||||
@@ -350,7 +371,7 @@ sub match_log {
|
|||||||
|
|
||||||
do {
|
do {
|
||||||
$n += $fh->sysread($$rbuf, 1024, $n);
|
$n += $fh->sysread($$rbuf, 1024, $n);
|
||||||
# dbg("Match \"$re\" in \"$$rbuf\" ($n)");
|
# dbg("Match \"$re\" in $name \"$$rbuf\" ($n)");
|
||||||
return $& if ($$rbuf =~ m/$re/m);
|
return $& if ($$rbuf =~ m/$re/m);
|
||||||
# TODO: Use select()/poll()
|
# TODO: Use select()/poll()
|
||||||
sleep 0.1;
|
sleep 0.1;
|
||||||
@@ -413,7 +434,7 @@ sub done {
|
|||||||
sub httpd_start {
|
sub httpd_start {
|
||||||
httpd_reset_logs();
|
httpd_reset_logs();
|
||||||
my @p = (
|
my @p = (
|
||||||
$opt{a},
|
$HTTPD,
|
||||||
-d => $opt{S},
|
-d => $opt{S},
|
||||||
-f => $opt{C},
|
-f => $opt{C},
|
||||||
(map { (-c => $_) } ("Listen localhost:$opt{p}", @_)),
|
(map { (-c => $_) } ("Listen localhost:$opt{p}", @_)),
|
||||||
@@ -459,7 +480,7 @@ sub httpd_start {
|
|||||||
sub httpd_stop {
|
sub httpd_stop {
|
||||||
httpd_reset_logs();
|
httpd_reset_logs();
|
||||||
my @p = (
|
my @p = (
|
||||||
$opt{a},
|
$HTTPD,
|
||||||
-d => $opt{S},
|
-d => $opt{S},
|
||||||
-f => $opt{C},
|
-f => $opt{C},
|
||||||
(map { (-c => $_) } ("Listen localhost:$opt{p}", @_)),
|
(map { (-c => $_) } ("Listen localhost:$opt{p}", @_)),
|
||||||
@@ -505,7 +526,7 @@ sub httpd_stop {
|
|||||||
sub httpd_reload {
|
sub httpd_reload {
|
||||||
httpd_reset_logs();
|
httpd_reset_logs();
|
||||||
my @p = (
|
my @p = (
|
||||||
$opt{a},
|
$HTTPD,
|
||||||
-d => $opt{S},
|
-d => $opt{S},
|
||||||
-f => $opt{C},
|
-f => $opt{C},
|
||||||
(map { (-c => $_) } ("Listen localhost:$opt{p}", @_)),
|
(map { (-c => $_) } ("Listen localhost:$opt{p}", @_)),
|
||||||
|
Reference in New Issue
Block a user