Checking in changes prior to tagging of version 2.63.
[MogileFS-Server.git] / t / store-sqlite.t
blob8468d6acac0adc1165e02a902ca8f6471f63488f
1 # -*-perl-*-
2 # tests for SQlite-specific features
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;
11 use File::Temp ();
12 use POSIX qw(:sys_wait_h);
14 my ($fh, $filename) = File::Temp::tempfile();
15 close($fh);
16 MogileFS::Config->set_config('db_dsn', "DBI:SQLite:$filename");
17 MogileFS::Config->set_config('db_user', '');
18 MogileFS::Config->set_config('db_pass', '');
19 MogileFS::Config->set_config('max_handles', 0xffffffff);
21 my ($r, $w, $pid, $buf);
22 my $sto = eval { MogileFS::Store->new };
23 if ($sto) {
24     plan tests => 28;
25 } else {
26     plan skip_all => "Can't create temporary test database: $@";
27     exit 0;
30 Mgd::set_store($sto);
31 is(ref($sto), "MogileFS::Store::SQLite", "store is sane");
32 is($sto->setup_database, 1, "setup database");
34 is(1, pipe($r, $w), "IPC pipe is ready");
36 # normal lock contention
37 $pid = fork;
38 fail("fork failed: $!") unless defined $pid;
39 if ($pid == 0) {
40     $sto = Mgd::get_store(); # fork-safe
41     $SIG{TERM} = sub {
42         $sto->release_lock("test-lock") == 1 or die "released bad lock";
43         exit 0;
44     };
45     $sto->get_lock("test-lock", 1) == 1 or die "child failed to get_lock";
46     close($r);
47     syswrite($w, ".") == 1 or die "child failed to wake parent";
48     sleep 60;
49     exit 0;
51 if ($pid > 0) {
52     is(sysread($r, $buf, 1), 1, "child wakes us up");
53     is($buf, ".", "child wakes parent up properly");
54     ok(! $sto->get_lock("test-lock", 1), "fails to lock while child has lock");
55     is(kill(TERM => $pid), 1, "kill successful");
56     is(waitpid($pid, 0), $pid, "waitpid successful");
57     is($?, 0, "child dies correctly");
58     is($sto->get_lock("test-lock", 1), 1, "acquire lock when child dies");
61 # detects recursive lock
62 ok(! eval { $sto->get_lock("test-lock", 1); }, "recursion fails");
63 like($@, qr/Lock recursion detected/i, "proper error on failed lock");
64 is($sto->release_lock("test-lock"), 1, "lock release");
66 is($sto->get_lock("test-lock", 0), 1, "acquire lock with 0 timeout");
67 is($sto->release_lock("test-lock"), 1, "lock release");
68 is($sto->release_lock("test-lock") + 0, 0, "redundant lock release");
70 # waits for lock
71 $pid = fork;
72 fail("fork failed: $!") unless defined $pid;
73 if ($pid == 0) {
74     $sto = Mgd::get_store(); # fork-safe
75     $sto->get_lock("test-lock", 1) or die "child failed to get_lock";
76     close($r);
77     syswrite($w, ".") == 1 or die "child failed to wake parent";
78     sleep 2;
79     $sto->release_lock("test-lock") == 1 or die "child failed to release";
80     exit 0;
82 if ($pid > 0) {
83     is(sysread($r, $buf, 1), 1, "parent woken up");
84     is($buf, ".", "child wakes parent up properly");
85     ok($sto->get_lock("test-lock", 6), "acquire lock eventually");
86     is(waitpid($pid, 0), $pid, "waitpid successful");
87     is($?, 0, "child dies correctly");
88     is($sto->release_lock("test-lock"), 1, "lock release");
92 # kill -9 a lock holder
93 $pid = fork;
94 fail("fork failed: $!") unless defined $pid;
95 if ($pid == 0) {
96     $sto = Mgd::get_store(); # fork-safe
97     $sto->get_lock("test-lock", 1) or die "child failed to get_lock";
98     close($r);
99     syswrite($w, ".") == 1 or die "child failed to wake parent";
100     sleep 60;
101     exit 0;
103 if ($pid > 0) {
104     is(sysread($r, $buf, 1), 1, "parent woken up");
105     is($buf, ".", "child wakes parent up properly");
106     is(kill(KILL => $pid), 1, "kill -9 successful");
107     is(waitpid($pid, 0), $pid, "waitpid successful");
108     ok(WIFSIGNALED($?) && WTERMSIG($?) == 9, "child was SIGKILL-ed");
109     ok($sto->get_lock("test-lock", 1), "acquire lock in parent");