Added better tests of existence around failure to write to readonly handle
[dbsrgits/DBM-Deep.git] / t / 11_optimize.t
CommitLineData
ffed8b01 1##
2# DBM::Deep Test
3##
4use strict;
a59a8dca 5use Test::More tests => 9;
ffed8b01 6
7use_ok( 'DBM::Deep' );
8
9unlink "t/test.db";
10my $db = DBM::Deep->new(
11 file => "t/test.db",
12 autoflush => 1,
13);
ffed8b01 14
15##
16# create some unused space
17##
18$db->{key1} = "value1";
19$db->{key2} = "value2";
20
21$db->{a} = {};
22$db->{a}{b} = [];
23$db->{a}{c} = 'value2';
24
25my $b = $db->{a}->{b};
26$b->[0] = 1;
27$b->[1] = 2;
28$b->[2] = {};
29$b->[2]->{c} = [];
30
31my $c = $b->[2]->{c};
32$c->[0] = 'd';
33$c->[1] = {};
34$c->[1]->{e} = 'f';
35
36undef $c;
37undef $b;
38
39delete $db->{key2};
40delete $db->{a}{b};
41
42##
43# take byte count readings before, and after optimize
44##
4d35d856 45my $before = (stat($db->_fh()))[7];
ffed8b01 46my $result = $db->optimize();
4d35d856 47my $after = (stat($db->_fh()))[7];
ffed8b01 48
a59a8dca 49ok( $result, "optimize succeeded" );
50ok( $after < $before, "file size has shrunk" ); # make sure file shrunk
ffed8b01 51
52is( $db->{key1}, 'value1', "key1's value is still there after optimize" );
53is( $db->{a}{c}, 'value2', "key2's value is still there after optimize" );
a59a8dca 54
55##
56# now for the tricky one -- try to store a new key while file is being
57# optimized and locked by another process. filehandle should be invalidated,
58# and automatically re-opened transparently. Cannot test on Win32, due to
59# problems with fork()ing, flock()ing, etc. Win32 very bad.
60##
61
656abae9 62SKIP: {
63 skip "Fork tests skipped on Win32", 4 if $^O eq 'MSWin32';
64
65 ##
66 # first things first, get us about 1000 keys so the optimize() will take
67 # at least a few seconds on any machine, and re-open db with locking
68 ##
69 for (1..1000) { $db->STORE( $_, $_ ); }
70 undef $db;
71
72 ##
73 # now, fork a process for the optimize()
74 ##
75 my $pid = fork();
76
77 unless ( $pid ) {
78 # child fork
79
80 # re-open db
81 $db = DBM::Deep->new(
82 file => "t/test.db",
83 autoflush => 1,
84 locking => 1
85 );
656abae9 86
87 # optimize and exit
88 $db->optimize();
89
90 exit( 0 );
91 }
92
93 # parent fork
94 ok( defined($pid), "fork was successful" ); # make sure fork was successful
95
96 # re-open db
97 $db = DBM::Deep->new(
98 file => "t/test.db",
99 autoflush => 1,
100 locking => 1
101 );
656abae9 102
103 # sleep for 1 second to make sure optimize() is running in the other fork
104 sleep(1);
105
106 # now, try to get a lock and store a key
107 $db->{parentfork} = "hello";
108
109 # see if it was stored successfully
110 is( $db->{parentfork}, "hello", "stored key while optimize took place" );
111 # ok(1);
112
113 # now check some existing values from before
114 is( $db->{key1}, 'value1', "key1's value is still there after optimize" );
115 is( $db->{a}{c}, 'value2', "key2's value is still there after optimize" );
a59a8dca 116}