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