Tagged 0.981_01 (experimental auditlog)
[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);
14if ($db->error()) {
15 die "ERROR: " . $db->error();
16}
17
18##
19# create some unused space
20##
21$db->{key1} = "value1";
22$db->{key2} = "value2";
23
24$db->{a} = {};
25$db->{a}{b} = [];
26$db->{a}{c} = 'value2';
27
28my $b = $db->{a}->{b};
29$b->[0] = 1;
30$b->[1] = 2;
31$b->[2] = {};
32$b->[2]->{c} = [];
33
34my $c = $b->[2]->{c};
35$c->[0] = 'd';
36$c->[1] = {};
37$c->[1]->{e} = 'f';
38
39undef $c;
40undef $b;
41
42delete $db->{key2};
43delete $db->{a}{b};
44
45##
46# take byte count readings before, and after optimize
47##
4d35d856 48my $before = (stat($db->_fh()))[7];
ffed8b01 49my $result = $db->optimize();
4d35d856 50my $after = (stat($db->_fh()))[7];
ffed8b01 51
52if ($db->error()) {
53 die "ERROR: " . $db->error();
54}
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
62##
63# now for the tricky one -- try to store a new key while file is being
64# optimized and locked by another process. filehandle should be invalidated,
65# and automatically re-opened transparently. Cannot test on Win32, due to
66# problems with fork()ing, flock()ing, etc. Win32 very bad.
67##
68
656abae9 69SKIP: {
70 skip "Fork tests skipped on Win32", 4 if $^O eq 'MSWin32';
71
72 ##
73 # first things first, get us about 1000 keys so the optimize() will take
74 # at least a few seconds on any machine, and re-open db with locking
75 ##
76 for (1..1000) { $db->STORE( $_, $_ ); }
77 undef $db;
78
79 ##
80 # now, fork a process for the optimize()
81 ##
82 my $pid = fork();
83
84 unless ( $pid ) {
85 # child fork
86
87 # re-open db
88 $db = DBM::Deep->new(
89 file => "t/test.db",
90 autoflush => 1,
91 locking => 1
92 );
93 if ($db->error()) {
94 die "ERROR: " . $db->error();
95 }
96
97 # optimize and exit
98 $db->optimize();
99
100 exit( 0 );
101 }
102
103 # parent fork
104 ok( defined($pid), "fork was successful" ); # make sure fork was successful
105
106 # re-open db
107 $db = DBM::Deep->new(
108 file => "t/test.db",
109 autoflush => 1,
110 locking => 1
111 );
112 if ($db->error()) {
113 die "ERROR: " . $db->error();
114 }
115
116 # sleep for 1 second to make sure optimize() is running in the other fork
117 sleep(1);
118
119 # now, try to get a lock and store a key
120 $db->{parentfork} = "hello";
121
122 # see if it was stored successfully
123 is( $db->{parentfork}, "hello", "stored key while optimize took place" );
124 # ok(1);
125
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}