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 clear_socket_source 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 clear_socket_source(); 68 set_socket_source($req_fh, $res_fh); 69 70 my @call_args = %options ? ($url, $tempfile, \%options) : ($url, $tempfile); 71 my $response = $http->mirror(@call_args); 72 73 my $got_req = slurp($req_fh); 74 75 my $label = basename($file); 76 77 is( sort_headers($got_req), sort_headers($expect_req), "$label request" ); 78 79 my ($rc) = $give_res =~ m{\S+\s+(\d+)}g; 80 is( $response->{status}, $rc, "$label response code $rc" ) 81 or diag $response->{content}; 82 83 if ( substr($rc,0,1) eq '2' ) { 84 ok( $response->{success}, "$label success flag true" ); 85 ok( -e $tempfile, "$label file created" ); 86 } 87 elsif ( $rc eq '304' ) { 88 ok( $response->{success}, "$label success flag true" ); 89 is( (stat($tempfile))[9], $timestamp{$url_basename}, 90 "$label file not overwritten" ); 91 } 92 else { 93 ok( ! $response->{success}, "$label success flag false" ); 94 ok( ! -e $tempfile, "$label file not created" ); 95 } 96} 97 98done_testing; 99