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