1#!perl 2 3use strict; 4use warnings; 5 6use File::Basename; 7use Test::More 0.88; 8use lib 't'; 9use Util qw[tmpfile rewind slurp monkey_patch dir_list parse_case 10 set_socket_source sort_headers $CRLF $LF]; 11use HTTP::Tiny; 12use File::Temp qw/tempdir/; 13use File::Spec; 14 15BEGIN { monkey_patch() } 16 17my $tempdir = tempdir( TMPDIR => 1, CLEANUP => 1 ); 18my $tempfile = File::Spec->catfile( $tempdir, "tempfile.txt" ); 19 20my $known_epoch = 760233600; 21my $day = 24*3600; 22 23my %timestamp = ( 24 'modified.txt' => $known_epoch - 2 * $day, 25 'not-modified.txt' => $known_epoch - 2 * $day, 26); 27 28for my $file ( dir_list("corpus", qr/^mirror/ ) ) { 29 1 while unlink $tempfile; 30 my $data = do { local (@ARGV,$/) = $file; <> }; 31 my ($params, $expect_req, $give_res) = split /--+\n/, $data; 32 # cleanup source data 33 my $version = HTTP::Tiny->VERSION || 0; 34 $expect_req =~ s{VERSION}{$version}; 35 s{\n}{$CRLF}g for ($expect_req, $give_res); 36 37 # figure out what request to make 38 my $case = parse_case($params); 39 my $url = $case->{url}->[0]; 40 my %options; 41 42 my %headers; 43 for my $line ( @{ $case->{headers} } ) { 44 my ($k,$v) = ($line =~ m{^([^:]+): (.*)$}g); 45 $headers{$k} = $v; 46 } 47 $options{headers} = \%headers if %headers; 48 49 # maybe create a file 50 (my $url_basename = $url) =~ s{.*/}{}; 51 if ( my $mtime = $timestamp{$url_basename} ) { 52 open my $fh, ">", $tempfile; 53 close $fh; 54 utime $mtime, $mtime, $tempfile; 55 if ($^O eq 'MSWin32') { 56 # Deal with stat and daylight savings issues on Windows 57 # by reading back mtime 58 $timestamp{$url_basename} = (stat $tempfile)[9]; 59 } 60 } 61 62 # setup mocking and test 63 my $res_fh = tmpfile($give_res); 64 my $req_fh = tmpfile(); 65 66 my $http = HTTP::Tiny->new( keep_alive => 0 ); 67 set_socket_source($req_fh, $res_fh); 68 69 my @call_args = %options ? ($url, $tempfile, \%options) : ($url, $tempfile); 70 my $response = $http->mirror(@call_args); 71 72 my $got_req = slurp($req_fh); 73 74 my $label = basename($file); 75 76 is( sort_headers($got_req), sort_headers($expect_req), "$label request" ); 77 78 my ($rc) = $give_res =~ m{\S+\s+(\d+)}g; 79 is( $response->{status}, $rc, "$label response code $rc" ) 80 or diag $response->{content}; 81 82 if ( substr($rc,0,1) eq '2' ) { 83 ok( $response->{success}, "$label success flag true" ); 84 ok( -e $tempfile, "$label file created" ); 85 } 86 elsif ( $rc eq '304' ) { 87 ok( $response->{success}, "$label success flag true" ); 88 is( (stat($tempfile))[9], $timestamp{$url_basename}, 89 "$label file not overwritten" ); 90 } 91 else { 92 ok( ! $response->{success}, "$label success flag false" ); 93 ok( ! -e $tempfile, "$label file not created" ); 94 } 95} 96 97done_testing; 98