queryworker: reimplement "clear_caches" command
[MogileFS-Server.git] / t / store.t
blob593f1ca5760d7b6a31a39828a469e4fc170098e1
1 # -*-perl-*-
3 use strict;
4 use warnings;
5 use Test::More;
6 use FindBin qw($Bin);
8 use MogileFS::Server;
9 use MogileFS::Util qw(error_code);
10 use MogileFS::Test;
12 my $sto = eval { temp_store(); };
13 if ($sto) {
14     plan tests => 21;
15 } else {
16     plan skip_all => "Can't create temporary test database: $@";
17     exit 0;
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");
29 my $fid = $df->fid;
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);
38 @on = $fid->devids;
39 is(scalar @on, 2, "FID 101 on 2 devices");
41 # create a tempfile
43     my $fidid = $sto->register_tempfile(
44                                         fid     => undef,
45                                         dmid    => $dmid,
46                                         key     => "my_tempfile",
47                                         classid => $clsid,
48                                         devids  => join(',', 1,2,3),
49                                         );
50     ok($fidid, "got a fidid");
52     my $fidid2 = eval {
53         $sto->register_tempfile(
54                                 fid     => $fidid,
55                                 dmid    => $dmid,
56                                 key     => "my_tempfile",
57                                 classid => $clsid,
58                                 devids  => join(',', 1,2,3),
59                                 );
60     };
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";
80 ok(
81     ref( $match_spec->{pattern} ) eq 'Regexp'?
82         ( $prx =~ $match_spec->{pattern} ) :
83         ( !$prx ),
84     sprintf(
85         "ignore_replace %s return value for storage type '%s'",
86         ref( $match_spec->{pattern} ) eq 'Regexp'?
87             'should' : 'should not',
88         $sto_driver
89     )
90 ) or diag "Got value: $prx";
92 ok(
93     $match_spec->{dies}? $@ : !$@,
94     sprintf(
95         "ignore_replace %s die for storage type '%s'",
96         $match_spec->{dies}? 'should' : 'should not',
97         $sto_driver
98     )
99 ) or diag "Got exception: $@";
101 my $rv;
103 # test retry_on_deadlock using good sql
104 $rv = eval {
105     $sto->retry_on_deadlock( sub { $sto->dbh->do("SELECT 1;"); } );
107 ok (
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
113 $rv = eval {
114     $sto->retry_on_deadlock( sub { $sto->dbh->do("BADSQL;"); } );
116 ok (
117     $@ =~ /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
122 $rv = eval {
123     $sto->retry_on_deadlock( sub { die "preempt"; } );
125 ok (
126     $@ =~ /preempt/,
127     "retry_on_deadlock got a non-sql exception for '$sto_driver'"
128 ) or diag $@;
130 sub _do_induce_deadlock {
131     my @args = @_;
132     return eval {
133         no strict 'refs';
134         no warnings 'redefine';
135         my $c = 0;
136         local *{ "MogileFS\::Store\::$sto_driver\::was_deadlock_error" } = sub {
137             return $c++ < 2; # unlock on third try
138         };
139         $sto->retry_on_deadlock( @args );
140     };
143 # attempt to induce a deadlock and check iterations
144 my $_v = 0;
145 $rv = _do_induce_deadlock( sub { return $_v++; } );
148    !$@,
149    "no exception on retry_on_deadlock while inducing a deadlock"
150 ) or diag $@;
153     $rv == 2,
154     'retry_on_deadlock returned good iteration count while inducing a deadlock'
155 ) or diag $rv;
157 # induce a deadlock using badsql... should return an exemption
158 $rv = _do_induce_deadlock( sub { $sto->dbh->do("BADSQL;"); } );
159 ok (
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
165 $_v = 0;
166 $rv = _do_induce_deadlock(
167     sub {
168         return [ $sto->dbh->do("SELECT 1;"), $_v++ ];
169     }
171 ok (
172     ( !$@ && ref($rv) eq 'ARRAY' ) && (
173         ( $rv->[0] eq '1' || $rv->[0] eq '0E0' ) &&
174         $rv->[1] == 2
175     ),
176     "retry_on_deadlock got proper return value and iteration while inducing a deadlock"