1*256a93a4Safresh1#!./perl -w 2*256a93a4Safresh1use strict; 3*256a93a4Safresh1 4*256a93a4Safresh1use Test::More; 5*256a93a4Safresh1use Config; 6*256a93a4Safresh1use File::Temp 'tempdir'; 7*256a93a4Safresh1use File::Spec; 8*256a93a4Safresh1use Fcntl qw( :mode ); 9*256a93a4Safresh1 10*256a93a4Safresh1BEGIN { 11*256a93a4Safresh1 plan(skip_all => "GDBM_File was not built") 12*256a93a4Safresh1 unless $Config{extensions} =~ /\bGDBM_File\b/; 13*256a93a4Safresh1 14*256a93a4Safresh1 plan(tests => 7); 15*256a93a4Safresh1 use_ok('GDBM_File'); 16*256a93a4Safresh1} 17*256a93a4Safresh1 18*256a93a4Safresh1SKIP: { 19*256a93a4Safresh1 skip "GDBM_File crash tolerance not available", 6, 20*256a93a4Safresh1 unless GDBM_File->crash_tolerance_status; 21*256a93a4Safresh1 22*256a93a4Safresh1 my $wd = tempdir(CLEANUP => 1); 23*256a93a4Safresh1 chdir $wd; 24*256a93a4Safresh1 25*256a93a4Safresh1 sub createdb { 26*256a93a4Safresh1 my ($name, $type, $code) = @_; 27*256a93a4Safresh1 my %h; 28*256a93a4Safresh1 $type //= 0; 29*256a93a4Safresh1 my $dbh = tie(%h, 'GDBM_File', $name, GDBM_NEWDB|$type, 0640); 30*256a93a4Safresh1 if ($code) { 31*256a93a4Safresh1 &{$code}($dbh, \%h); 32*256a93a4Safresh1 } 33*256a93a4Safresh1 untie %h 34*256a93a4Safresh1 } 35*256a93a4Safresh1 my $even = 'a.db'; 36*256a93a4Safresh1 my $odd = 'b.db'; 37*256a93a4Safresh1 my $time = time; 38*256a93a4Safresh1 39*256a93a4Safresh1 # 40*256a93a4Safresh1 # Valid cases 41*256a93a4Safresh1 # 42*256a93a4Safresh1 43*256a93a4Safresh1 # access modes 44*256a93a4Safresh1 createdb($even); 45*256a93a4Safresh1 createdb($odd); 46*256a93a4Safresh1 chmod S_IRUSR, $even; 47*256a93a4Safresh1 chmod S_IWUSR, $odd; 48*256a93a4Safresh1 is_deeply([GDBM_File->latest_snapshot($even, $odd)], 49*256a93a4Safresh1 [ 'a.db', GDBM_SNAPSHOT_OK ], "different acess modes"); 50*256a93a4Safresh1 51*256a93a4Safresh1 # mtimes 52*256a93a4Safresh1 chmod S_IRUSR, $odd; 53*256a93a4Safresh1 utime($time, $time, $even); 54*256a93a4Safresh1 utime($time, $time-5, $odd); 55*256a93a4Safresh1 is_deeply([GDBM_File->latest_snapshot($even, $odd)], 56*256a93a4Safresh1 [ 'a.db', GDBM_SNAPSHOT_OK ], "different mtimes"); 57*256a93a4Safresh1 unlink $even, $odd; 58*256a93a4Safresh1 59*256a93a4Safresh1 # numsync 60*256a93a4Safresh1 createdb($even, GDBM_NUMSYNC); 61*256a93a4Safresh1 createdb($odd, GDBM_NUMSYNC, sub { shift->sync }); 62*256a93a4Safresh1 chmod S_IRUSR, $even, $odd; 63*256a93a4Safresh1 utime($time, $time, $even, $odd); 64*256a93a4Safresh1 is_deeply([GDBM_File->latest_snapshot($even, $odd)], 65*256a93a4Safresh1 [ 'b.db', GDBM_SNAPSHOT_OK ], "different numsync value"); 66*256a93a4Safresh1 67*256a93a4Safresh1 # 68*256a93a4Safresh1 # Erroneous cases 69*256a93a4Safresh1 # 70*256a93a4Safresh1 71*256a93a4Safresh1 unlink $even, $odd; 72*256a93a4Safresh1 73*256a93a4Safresh1 # Same snapshots 74*256a93a4Safresh1 createdb($even); 75*256a93a4Safresh1 createdb($odd); 76*256a93a4Safresh1 chmod S_IRUSR, $even, $odd; 77*256a93a4Safresh1 utime($time, $time, $even, $odd); 78*256a93a4Safresh1 is_deeply([GDBM_File->latest_snapshot($even, $odd)], 79*256a93a4Safresh1 [ undef, GDBM_SNAPSHOT_SAME ], "GDBM_SNAPSHOT_SAME"); 80*256a93a4Safresh1 81*256a93a4Safresh1 # Both writable 82*256a93a4Safresh1 chmod S_IWUSR, $even, $odd; 83*256a93a4Safresh1 is_deeply([GDBM_File->latest_snapshot($even, $odd)], 84*256a93a4Safresh1 [ undef, GDBM_SNAPSHOT_BAD ], "GDBM_SNAPSHOT_BAD"); 85*256a93a4Safresh1 86*256a93a4Safresh1 # numsync difference > 1 87*256a93a4Safresh1 unlink $even, $odd; 88*256a93a4Safresh1 89*256a93a4Safresh1 createdb($even, GDBM_NUMSYNC); 90*256a93a4Safresh1 createdb($odd, GDBM_NUMSYNC, 91*256a93a4Safresh1 sub { 92*256a93a4Safresh1 my $dbh = shift; 93*256a93a4Safresh1 $dbh->sync; 94*256a93a4Safresh1 $dbh->sync; 95*256a93a4Safresh1 }); 96*256a93a4Safresh1 chmod S_IRUSR, $even, $odd; 97*256a93a4Safresh1 utime($time, $time, $even, $odd); 98*256a93a4Safresh1 is_deeply([GDBM_File->latest_snapshot($even, $odd)], 99*256a93a4Safresh1 [ undef, GDBM_SNAPSHOT_SUSPICIOUS ], "GDBM_SNAPSHOT_SUSPICIOUS"); 100*256a93a4Safresh1} 101