9 use MogileFS::Util qw(error_code);
12 my $sto = eval { temp_store(); };
16 plan skip_all => "Can't create temporary test database: $@";
20 my $dmid = $sto->create_domain("foo");
21 ok($dmid, "created a domain");
22 my $clsid = $sto->create_class($dmid, "classA");
23 ok($clsid, "created a class");
25 my $df = MogileFS::DevFID->new(100, 200);
26 ok($df, "made devfid");
27 ok($df->add_to_db, "added to db");
30 ok($fid, "got fid from df");
31 my @on = $fid->devids;
32 is(scalar @on, 1, "FID 200 on one device");
33 is($on[0], 100, "is correct number");
35 ok($sto->mass_insert_file_on(MogileFS::DevFID->new(1, 101),
36 MogileFS::DevFID->new(2, 101)), "did mass insert");
37 $fid = MogileFS::FID->new(101);
39 is(scalar @on, 2, "FID 101 on 2 devices");
43 my $fidid = $sto->register_tempfile(
48 devids => join(',', 1,2,3),
50 ok($fidid, "got a fidid");
53 $sto->register_tempfile(
58 devids => join(',', 1,2,3),
61 my $errc = error_code($@);
62 ok(!$fidid2, "didn't get fidid");
63 is($errc, "dup", "got a dup into tempfile")
64 or die "Got error: $@\n";
67 my $ignore_replace_match = {
68 base => { pattern => undef, dies => 1 },
69 MySQL => { pattern => qr/INSERT IGNORE/, dies => 0 },
70 SQLite => { pattern => qr/REPLACE/, dies => 0 },
71 Postgres => { pattern => undef, dies => 1 },
74 my $prx = eval { $sto->ignore_replace } || '';
75 my $sto_driver = ( split( /::/, ref($sto) ) )[2] || 'base';
76 my $match_spec = $ignore_replace_match->{ $sto_driver }
77 or die "Test not configured for '$sto_driver' storage driver";
81 ref( $match_spec->{pattern} ) eq 'Regexp'?
82 ( $prx =~ $match_spec->{pattern} ) :
85 "ignore_replace %s return value for storage type '%s'",
86 ref( $match_spec->{pattern} ) eq 'Regexp'?
87 'should' : 'should not',
90 ) or diag "Got value: $prx";
93 $match_spec->{dies}? $@ : !$@,
95 "ignore_replace %s die for storage type '%s'",
96 $match_spec->{dies}? 'should' : 'should not',
99 ) or diag "Got exception: $@";
103 # test retry_on_deadlock using good sql
105 $sto->retry_on_deadlock( sub { $sto->dbh->do("SELECT 1;"); } );
108 $rv eq '1' || $rv eq '0E0',
109 "retry_on_deadlock return value for '$sto_driver': $rv"
110 ) or diag "Got return value: $rv";
112 # test retry_on_deadlock using bad sql
114 $sto->retry_on_deadlock( sub { $sto->dbh->do("BADSQL;"); } );
118 "retry_on_deadlock got an exception on bad sql '$sto_driver'"
119 ) or diag "Got exception value: $@";
121 # test retry_on_deadlock using a custom exception
123 $sto->retry_on_deadlock( sub { die "preempt"; } );
127 "retry_on_deadlock got a non-sql exception for '$sto_driver'"
130 sub _do_induce_deadlock {
134 no warnings 'redefine';
136 local *{ "MogileFS\::Store\::$sto_driver\::was_deadlock_error" } = sub {
137 return $c++ < 2; # unlock on third try
139 $sto->retry_on_deadlock( @args );
143 # attempt to induce a deadlock and check iterations
145 $rv = _do_induce_deadlock( sub { return $_v++; } );
149 "no exception on retry_on_deadlock while inducing a deadlock"
154 'retry_on_deadlock returned good iteration count while inducing a deadlock'
157 # induce a deadlock using badsql... should return an exemption
158 $rv = _do_induce_deadlock( sub { $sto->dbh->do("BADSQL;"); } );
160 !$rv && $@ =~ /BADSQL/,
161 "retry_on_deadlock got expected exemption inducing a deadlock with bad sql"
162 ) or diag "Got value '$rv' with exemption: $@";
164 # induce a deadlock with good sql check sql return and iterations
166 $rv = _do_induce_deadlock(
168 return [ $sto->dbh->do("SELECT 1;"), $_v++ ];
172 ( !$@ && ref($rv) eq 'ARRAY' ) && (
173 ( $rv->[0] eq '1' || $rv->[0] eq '0E0' ) &&
176 "retry_on_deadlock got proper return value and iteration while inducing a deadlock"