9 use Getopt
::Long
qw(:config permute); # allow mixed args.
16 my $webhost = 'mycaldav';
17 my $althost = 'myempty';
24 $dbadir =~ s{/[^/]*$}{};
25 my $patchdir = $dbadir . "/patches";
28 GetOptions
('debug!' => \
$debug,
30 'dbuser=s' => \
$dbuser,
31 'dbpass=s' => \
$dbpass,
32 'webhost=s' => \
$webhost,
33 'althost=s' => \
$althost,
34 'test=s' => \
$testdef,
37 'help' => \
$helpmeplease );
39 usage
() if ( $helpmeplease || ((!defined($suite) || !defined($case)) && !defined($testdef)));
44 my @arguments = ( "--basic", "--proxy", "" );
45 push @arguments, "--silent" unless ( $debug );
46 push @arguments, "--verbose" if ( $debug );
51 my $is_head_request = 0;
52 my @auth = ( "--user", "user1:user1" );
54 if ( !defined($testdef) ) {
55 $testdef = "tests/$suite/$case.test";
58 my $datafile = $testdef;
59 $datafile =~ s{\.test$}{};
60 push @arguments, "--header", 'X-DAViCal-Testcase: '.$datafile;
66 my $sql_variable = "";
67 my $sql_statement = "";
70 my $replacements = ();
73 open( TEST
, '<', $testdef ) or die "Can't open '$testdef'";
77 # Do any variable replcements we have so far
78 foreach my $variable ( keys %{$sql_values} ) {
79 my $value = $sql_values->{$variable};
80 $line =~ s/##$variable##/$value/g;
84 if ( /^END$state$/ ) {
85 if ( $state eq "SQL" ) {
86 get_sql_value
( $sql_variable, $sql_values, $sql_statement );
88 elsif ( $state eq "DOSQL" ) {
89 do_sql
( $sql_statement );
91 elsif ( $state eq "QUERY" ) {
92 push @
$queries, $sql_statement;
96 elsif ( $state eq "DATA" ) {
97 $data_binary .= $line;
99 elsif ( $state eq "SQL" || $state eq "QUERY" || $state eq "DOSQL" ) {
100 $sql_statement .= $line;
107 $line =~ /^\s*HEAD\s*(#|$|=)/ && do {
108 push @arguments, "--include";
111 $line =~ /^\s*VERBOSE\s*(#|$|=)/ && do {
112 push @arguments, "--verbose";
115 $line =~ /^\s*NOAUTH\s*(#|$|=)/ && do {
119 $line =~ /^\s*AUTH\s*=\s*(\S.*)$/ && do {
120 @auth = ( "--user", $1 );
123 $line =~ /^\s*DATA\s*=\s*(\S.*)$/ && do {
125 if ( defined($suite) ) {
126 if ( -e
"tests/$suite/$basename.data" ) {
127 $datafile="tests/$suite/$basename.data";
129 elsif ( -e
"tests/$suite/$basename" ) {
130 $datafile="tests/$suite/$basename";
134 elsif ( -e
"$basename.data" ) {
135 $datafile="$basename.data";
137 elsif ( -e
$basename ) {
141 die "Can't find DATA file $basename or $basename.data";
145 $line =~ /^BEGINDATA\s*$/ && do {
150 $line =~ /^GETSQL\s*=\s*(\S.*)$/ && do {
156 $line =~ /^DOSQL\s*$/ && do {
161 $line =~ /^REPLACE\s*=\s*(\S)(.*)$/ && do {
163 $2 =~ /^([^$separator]*)$separator([^$separator]*)$separator$/ && do {
164 push @
$replacements, { 'pattern' => $1, 'replacement' => $2 };
168 $line =~ /^QUERY\s*$/ && do {
173 $line =~ /^\s*TYPE\s*=\s*(\S.*)$/ && do {
174 if ( $1 eq "HEAD" ) {
175 $is_head_request = 1;
178 push @arguments, "--request", $1;
182 $line =~ /^\s*HEADER\s*=\s*(\S.*)$/ && do {
184 $arg =~ s{regression.host}{$webhost};
185 $arg =~ s{alternate.host}{$althost};
186 push @arguments, "--header", $arg;
189 $line =~ /^\s*URL\s*=\s*(\S.*)$/ && do {
191 $url =~ s{regression.host}{$webhost};
192 $url =~ s{alternate.host}{$althost};
195 $line =~ /^\s*SCRIPT\s*=\s*(\S.*)$/ && do {
197 $script =~ s{regression.host}{$webhost};
198 $script =~ s{alternate.host}{$althost};
199 push @scripts, $script;
204 if ( !defined($url) && !defined($script) ) {
206 The .test file must contain either a URL or a SCRIPT.
211 push @arguments, "--head" if ( $is_head_request );
213 push @arguments, @auth;
215 if ( -f
$datafile ) {
216 push @arguments, "--data-binary", "\@$datafile";
218 elsif ( defined($data_binary) ) {
219 push @arguments, "--data-binary", $data_binary;
226 if ( defined($url) ) {
227 push @arguments, $url;
229 print STDERR
join " ", "curl", @arguments, "\n" if ( $debug );
231 open RESULTS
, "-|", "curl", @arguments;
234 foreach my $replacement ( @
$replacements ) {
235 $line =~ s/$replacement->{'pattern'}/$replacement->{'replacement'}/;
241 if ( defined($script) ) {
242 foreach $script ( @scripts ) {
243 open RESULTS
, "-|", $script;
246 foreach my $replacement ( @
$replacements ) {
247 $line =~ s/$replacement->{'pattern'}/$replacement->{'replacement'}/;
254 if ( defined(@
{$queries}) && @
{$queries} ) {
255 opendb
() unless defined($dbh);
257 print STDERR
"Processing special queries\n" if ( $debug );
258 foreach $sql_statement ( @
$queries ) {
259 # run SQL statement and dump results, into array of hashes
260 my $results = $dbh->selectall_arrayref($sql_statement, { Slice
=> {} } );
262 print $dbh->errstr, "\n";
265 foreach my $row ( @
$results ) {
266 print "Query result ================================================\n" if ( $debug );
268 foreach my $name ( sort keys %$row ) {
269 my $value = $row->{$name};
270 $value = 'NULL' unless ( defined($value) );
271 printf("%17.17s: >%s<\n", $name, $value );
281 =item do_sql( $sql_statement )
282 Queries the database using the specified statement and
288 opendb
() unless defined($dbh);
291 print $dbh->errstr, "\n";
294 print "SQL executed successfully.\n";
299 =item get_sql_value( $sql_variable, $sql_values, $sql_statement )
300 Queries the database using the specified statement and puts
301 the first column of the first row returned into the
302 hash referenced $sql_values->{$sql_variable} for replacement
303 later in the parsing process.
310 opendb
() unless defined($dbh);
311 my $results = $dbh->selectall_arrayref($sql);
313 print $dbh->errstr, "\n";
316 print STDERR
"RESULT for $varname is ", $results->[0][0], "\n" if ( $debug );
317 $values->{$varname} = (defined($results->[0][0]) ?
$results->[0][0] : "");
321 Opens the database connection to the global $dbh handle.
322 Note that the standard PostgreSQL environment variables will also work
326 $dsn = "dbi:Pg:dbname=$dsn";
327 $dbh = DBI
->connect($dsn, $dbuser, $dbpass, { AutoCommit
=> 1 } ) or die "Can't connect to database $dsn";
335 dav_test [DB opts] [--suite <testsuite> --case <testname>] | [--test <filename>]
337 This program will read the file 'tests/<testsuite>/<testname>.test
338 and follow the instructions there.
340 The following options are available for controlling the database, for
341 those test cases which might require it:
342 --dsn <database>[;port=NNNN][;host=example.com]
347 The test instructions will include lines defining the test like:
348 =================================================
350 URL=http://mycaldav/caldav.php/andrew/
352 HEADER=Content-type: text/xml
356 # This will let you use ##somename## for this value after this
358 SELECT column FROM table WHERE criteria
360 # The data can be included in line
364 # The result could be some SQL output
366 SELECT something, or, other FROM table ...
369 REPLACE=/pattern/replacement/options
370 =================================================
372 URL The URL to request from.
373 HEADER An additional header for the request
374 TYPE The type of request (e.g. GET/PUT/POST/REPORT/...)
375 HEAD Whether to include the headers in the recorded response
376 VERBOSE Whether to provide the full request / response headers.
377 DATA The name of a different test in this suite to use data from.
378 REPLACE A perl regex replacement to post-process the result through.
380 Additionally, if a file 'tests/<testsuite>/<testname>.data' exists
381 the contents of that file will be sent in the body of the request.