File: 11_optimize.t

package info (click to toggle)
libdbm-deep-perl 2.0008-1
  • links: PTS, VCS
  • area: main
  • in suites: wheezy
  • size: 884 kB
  • sloc: perl: 7,383; sql: 36
file content (131 lines) | stat: -rw-r--r-- 3,080 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
use strict;
use warnings FATAL => 'all';

use Test::More;

plan skip_all => "Skipping the optimize tests on Win32/cygwin for now."
    if ( $^O eq 'MSWin32' || $^O eq 'cygwin' );

use t::common qw( new_fh );

use_ok( 'DBM::Deep' );

my ($fh, $filename) = new_fh();
my $db = DBM::Deep->new(
    file => $filename,
    autoflush => 1,
);

##
# create some unused space
##
$db->{key1} = "value1";
$db->{key2} = "value2";

$db->{a} = {};
$db->{a}{b} = [];
$db->{a}{c} = 'value2';

my $b = $db->{a}->{b};
$b->[0] = 1;
$b->[1] = 2;
$b->[2] = {};
$b->[2]->{c} = [];

my $c = $b->[2]->{c};
$c->[0] = 'd';
$c->[1] = {};
$c->[1]->{e} = 'f';

undef $c;
undef $b;

delete $db->{key2};
delete $db->{a}{b};

##
# take byte count readings before, and after optimize
##
my $before = (stat($filename))[7];
my $result = $db->optimize();
my $after = (stat($filename))[7];

ok( $result, "optimize succeeded" );
cmp_ok( $after, '<', $before, "file size has shrunk" ); # make sure file shrunk

is( $db->{key1}, 'value1', "key1's value is still there after optimize" );
is( $db->{a}{c}, 'value2', "key2's value is still there after optimize" );

$db->_get_self->_engine->storage->close( $db->_get_self );

##
# now for the tricky one -- try to store a new key while file is being
# optimized and locked by another process.  filehandle should be invalidated,
# and automatically re-opened transparently.  Cannot test on Win32, due to
# problems with fork()ing, flock()ing, etc.  Win32 very bad.
##

SKIP: {
    skip "Fork tests skipped until fh/filename question solved.", 4;
    skip "Fork tests skipped on Win32", 4
        if $^O eq 'MSWin32' || $^O eq 'cygwin';

    ##
    # first things first, get us about 1000 keys so the optimize() will take
    # at least a few seconds on any machine, and re-open db with locking
    ##
    for (1..1000) { $db->STORE( $_, $_ +1 ); }
    undef $db;

    ##
    # now, fork a process for the optimize()
    ##
    my $pid = fork();

    unless ( $pid ) {
        # child fork

        # re-open db
        $db = DBM::Deep->new(
            file => $filename,
            autoflush => 1,
            locking => 1
        );

        # optimize and exit
        $db->optimize();

        exit( 0 );
    }
    # parent fork
    ok( defined($pid), "fork was successful" ); # make sure fork was successful

    # re-open db
    $db = DBM::Deep->new(
        file => $filename,
        autoflush => 1,
        locking => 1
    );

    # sleep for 1 second to make sure optimize() is running in the other fork
    sleep(1);

    # now, try to get a lock and store a key
    $db->{parentfork} = "hello";

    # see if it was stored successfully
    is( $db->{parentfork}, "hello", "stored key while optimize took place" );

    undef $db;
    $db = DBM::Deep->new(
        file => $filename,
        autoflush => 1,
        locking => 1
    );

    # now check some existing values from before
    is( $db->{key1}, 'value1', "key1's value is still there after optimize" );
    is( $db->{a}{c}, 'value2', "key2's value is still there after optimize" );
}

done_testing;