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