#
# Copyright (c) 2004-2007 - Consultas, PKG.fr
#
# This file is part of A2P.
#
# A2P is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# A2P is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with A2P; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
#
# $Id: Status.pm 3 2007-10-18 16:20:19Z guillaume $
#

use strict;
use Test;
use GDBM_File;
use Storable qw( thaw );

require 'test/A2P/Defaults.pm' ;

use warnings FATAL => qw(void);

BEGIN {
    plan
        tests  => 215,
        onfail => sub { exit(1) }
}

$| = 1 ;

our $tie_file ;
our $test_string ;
our ( $freezed, $SERVICE_TMP, $SHMDIR, $ADVANCED_DEBUGGING, $LOCKID,
    $LOGFILENAME, $DEBUG_IN_FILE, %STATS );
our $Progname    = 'TEST-Status' ;

unlink $tie_file ;

&info("Loading A2P::Status library");
    ok require A2P::Status ;

&info("Check default A2P::Status table");
    ok join("*",&A2P::Status::INTIAL_STATUS), 'o*_*_*0*0*0*0*0*0*0*0*_*_' ;

my $status ;
my $cache_hashref   = {} ;
my $cache_hashref_2 = {} ;
my %tied__hash      = () ;

my %h = () ;
my %s = () ;
my $do_next_test = 1 ;

sub dump_hash {
    $h{This} = $cache_hashref ;
    map { print STDERR "CACHE: $_ -> ".$h{This}->{$_},($h{This}->{$_}=~/^HASH/?
        " -> (".keys(%{$h{This}->{$_}})." keys)":""),"\n" }
        keys(%{$h{This}}) ;
    map { print STDERR "CACHE: __SID__ -> $_ -> ".$h{This}->{__SID__}->{$_},"\n"
        } keys(%{$h{This}->{__SID__}}) ;
    $h{This} = \%tied__hash ;
    map { print STDERR "TIED : $_ -> ", ( $h{This}->{$_} =~ $freezed ?
        "Freezed storable object" : $h{This}->{$_}),"\n" }
        keys(%{$h{This}}) ;
    delete $h{This} ;
}


&info("Get a status object");
    $status = new A2P::Status( $cache_hashref, \%tied__hash );
    ok defined($status) ;
    ok ref($status) , 'A2P::Status' ;

&info("Check cache");
    ok $cache_hashref->{'noname'} , $status ;
    ok keys(%{$cache_hashref}) , 2 ;

sub check_status_defaults {
    #&dump_hash ;
    my $self = shift ;
    my $job  = shift ;
    &info("Checking Status object defaults of " . $job );
    ok $self->{JOB}, $job ;
    ok $self->is_job, $job ;
    ok $self->{LOCKID}, $LOCKID ;
    ok $self->{DAY}, 19700101 ;
    &info("Checked");
}

&check_status_defaults($status,'noname');
    ok $status->{AFP}, 'noname' ;
    ok $status->get_sid_index, 0 ;

&info("Insert status in cache");
    ok $status->is_job('test'), 'test' ;
    ok $status->cached ;

&info("Check cache");
    ok $cache_hashref->{'test'} , $status ;
    ok keys(%{$cache_hashref}) , 3 ;
    #&dump_hash ;
    delete $cache_hashref->{'noname'} ;
    delete $cache_hashref->{'test'} ;


&info("Try tied cache");
    ok defined(tie( %tied__hash, 'GDBM_File', $tie_file, GDBM_WRCREAT, 0660)) ;
    $cache_hashref->{__GDBM_WRITER__} = 1 ;

&info("Insert status in tied hash");
    $status = new A2P::Status( $cache_hashref, \%tied__hash, 'TEST-UNIT-1' );
    ok $cache_hashref->{'TEST-UNIT-1'} , $status ;
&check_status_defaults($status,'TEST-UNIT-1');
    ok $status->{AFP}, 'TEST-UNIT-1' ;
    ok $status->get_sid_index, 0 ;


&info("Set jobname, a private scalar and save to tied hash");
    ok $status->is_job('TEST-UNIT-2') ;
    ok $status->cached ;
    ok $status->{"TESTUNIT-$$"} = '__PRIVATE__' ;
    ok $status->{"TESTUNIT-$$"} , '__PRIVATE__' ;
&info("Control 'is_tied' returns the same reference avec being tied");
    ok $status->is_tied, 0 ; # Null when not in tied hash
    ok $status->save_tied ;
&info("Status ref is different as re-read from tied hash");
    my $tied = $status->is_tied ;
    ok $tied != $status ;
    ok ref($status) , 'A2P::Status' ;
    ok ref($tied) , 'A2P::Status' ;
    ok $status->get_sid_index, $tied->get_sid_index ;
    ok $cache_hashref->{'TEST-UNIT-2'} , $status ;
    ok $cache_hashref->{'TEST-UNIT-2'} != $tied ;
&info("Close tie");
    untie %tied__hash ;

&info("Reopen as reader and get one in tied hash");
    ok defined(tie( %tied__hash, 'GDBM_File', $tie_file, GDBM_READER, 0660)) ;
    $cache_hashref->{__GDBM_WRITER__} = 0 ;

    ok defined($tied__hash{'TEST-UNIT-2'}) ;
    my $intied = new A2P::Status( $cache_hashref, \%tied__hash, 'TEST-UNIT-2' );
&info("Check status is inserted in cache automatically");
    ok defined($intied) and ref($intied) =~ /^A2P::Status$/ ;
    ok defined($cache_hashref->{'TEST-UNIT-2'}) ;
    #&dump_hash ;

&info("Control the retrieved jobname");
    ok defined($intied->{JOB}) ;
    ok $intied->is_job() ;
    ok $intied->is_job(), 'TEST-UNIT-2' ;
&info("Control private inserted value is there");
    ok $intied->{"TESTUNIT-$$"} , '__PRIVATE__' ;
    #&dump_hash ;

untie %tied__hash ;
&info("Reopen as writer and get new status");
    ok defined(tie( %tied__hash, 'GDBM_File', $tie_file, GDBM_WRCREAT, 0660)) ;
    $cache_hashref->{__GDBM_WRITER__} = 1 ;

    $intied = new A2P::Status( $cache_hashref, \%tied__hash, 'TEST-UNIT-3' );
    ok defined($intied) and ref($intied) =~ /^A2P::Status$/ ;
    ok $intied->get_revision(), 0 ;

&info("Test API used by tied_update_status in A2P::JobStatus");
    &info("Check cache_timer call");
    ok $intied->cache_timer ;
    &info("Check step_status call");
    ok $intied->step_status ;
    ok $intied->step_status(-1), 0 ;
    ok $intied->step_status(0), 'o';
    ok $intied->step_status(12), '_';
    ok $intied->{STATE}->[12], '_' ;
    ok ! $intied->step_status(20);
    ok $intied->step_status(5), '_' ;    # if char '0' return '_'
    ok $intied->step_status(5);          # Still true by default
    ok $intied->step_status(5,'0'), '.'; # Can't set '0' but '.' as default
    ok $intied->step_status(12,'X'), 'X' ;
    ok $intied->step_status(12), 'X';
    ok $intied->{STATE}->[12], 'X' ;
    ok $intied->{STEP}, 12 ;
    #&dump_hash ;

&info("Check infos API");
    ok $intied->infos(), 1 ;
    ok $intied->infos(1), 0 ;
    ok $intied->infos("AA"), 0 ;
    ok $intied->infos( ( TEST => 111 ) ), 0 ;
    ok $intied->infos( { TEST => 111 } ), 1 ;
    ok $intied->infos( [ TEST => 111 ] ), 0 ;
    ok $intied->{TEST}, 111 ;
        my @test = 'TEST' ;
        &info("Try a call with a bad hash (it generates at least a warning)");
    ok $intied->infos( { @test } ), 1 ;
    ok $intied->{TEST}, "" ;
    ok $intied->infos({ THIS => "TESTUNIT" }) ;
    ok $intied->{THIS}, 'TESTUNIT' ;
    ok $intied->infos( { THIS => "   " }) ;
    ok $intied->{THIS}, '' ;
    ok $intied->infos( { JOBID => 'UNIT-TEST' } ), 1 ;
    ok $intied->{JOBID}, 'UNIT-TEST' ;
    ok $intied->cached ;
    ok defined($cache_hashref->{'TEST-UNIT-3'}) ;
    ok $cache_hashref->{'TEST-UNIT-3'}, $intied ;
    ok defined($cache_hashref->{'UNIT-TEST'}) ;
    ok $cache_hashref->{'UNIT-TEST'}, $intied ;

&info("Check current_in_tie_sid_key API");
    ok $intied->get_sid_index, 0 ;
    ok $intied->current_in_tie_sid_key , 'TEST-UNIT-3' ;

&info("Check status API");
    ok $intied->infos( { STATUS => "done" } ) ;
    ok $intied->{STATUS}, 'done' ;
    ok $intied->status, 'DONE' ;
    ok $intied->{STATUS}, 'DONE' ;

&info("Check save_tied call");
    $intied = new A2P::Status( $cache_hashref, \%tied__hash, 'TEST-UNIT-4' );
    ok $intied->get_revision(), 0 ;
    ok $intied->save_tied(), $intied ;
    ok $intied->get_revision(), 1 ;
    ok defined($tied__hash{'TEST-UNIT-4'}) ;
    $cache_hashref->{__GDBM_WRITER__} = 0 ;
    &info("Must not save_tied and return 0");
    ok $intied->save_tied(), 0 ;
    ok $intied->get_revision(), 2 ;
    $cache_hashref->{__GDBM_WRITER__} = 1 ;

&info("Check about revision API");
    ok $intied->get_revision(), 2 ;
    ok $intied->{REV}, 2 ;
    ok $intied->set_revision(), 3 ;
    ok $intied->get_revision(), 3 ;
    ok $intied->{REV}, 3 ;
    ok $intied->set_revision(), 4 ;
    ok $intied->{REV}, 4 ;

&info("Check current_in_tie_sid_key API");
    ok $intied->current_in_tie_sid_key , 'TEST-UNIT-4' ;

&info("Simulating SID updates from another thread:");
    $LOCKID = "SIMUL-1" ;
    $0 = "TEST-Status-SM" , A2P::Syslog::SetLogger(0);
    &info("1. First call initialize the status object");
    $status = new A2P::Status( $cache_hashref, \%tied__hash, 'TEST-UNIT-5' );
    ok $status->step_status ;
    ok $status->infos ;
    ok $status->cached ;
    ok $s{timer1} = $status->cache_timer ;
        $s{timer2} = $status->timer ;
    ok $s{timer1} , $s{timer2} ;
    ok $status->save_tied , $status ;
    ok $cache_hashref->{'TEST-UNIT-5'} , $status ;
    ok ! exists($cache_hashref->{'SIMULATION-1'}) ;
    ok $status->get_revision , 1 ;
    ok $status->get_sid_index , 0 ;
    ok $status->get_sid_key , 'TEST-UNIT-5' ;
    ok $status->get_sid_version_key , 'TEST-UNIT-5_rev' ;
        $s{version} = &thaw($tied__hash{'TEST-UNIT-5_rev'}) ;
    ok @{$s{version}} , 3 ;
    ok $s{version}->[0] , 1 ;
    ok $s{version}->[1] , "SIMUL-1" ;
    ok $s{version}->[2] , $s{timer2} ;
    undef $status ;
    ok defined($tied__hash{'TEST-UNIT-5'}) ;
    ok defined($tied__hash{'TEST-UNIT-5_rev'}) ;
    ok $tied__hash{'SIMULATION-1'} , undef ;
    #&dump_hash ;

    &info("2. Second call initialize the status itself and a private value");
    $status = new A2P::Status( $cache_hashref, \%tied__hash, 'TEST-UNIT-5' );
    ok $status->step_status(1,'.') , '.';
    ok $status->infos({ STATUS => 'WAITING', FILE => 'TEST.test-unit-5' });
    ok $status->cached ;
    ok $status->cache_timer ;
    ok $status->save_tied , $status ;
    ok $cache_hashref->{'TEST-UNIT-5'} , $status ;
    ok ! exists($cache_hashref->{'SIMULATION-1'}) ;
    undef $status ;
    ok defined($tied__hash{'TEST-UNIT-5'}) ;
    ok defined($tied__hash{'TEST-UNIT-5_rev'}) ;
        $s{version} = &thaw($tied__hash{'TEST-UNIT-5_rev'}) ;
    ok @{$s{version}} , 3 ;
    ok $s{version}->[0] , 2 ;
    ok $tied__hash{'SIMULATION-1'} , undef ;

    &info("3. Third call initialize the JID");
    $status = new A2P::Status( $cache_hashref, \%tied__hash, 'TEST-UNIT-5' );
    ok $status->step_status(1,'o') , 'o';
    ok $status->step_status(1,'o') , 'o';
    ok $status->step_status(1,'-') , 'o';
    ok $status->infos({ JID => 'SIMULATION-1', STATUS => 'STARTING',
        FILE => 'TEST/test-unit-5' });
    ok $status->cached ;
    ok $status->cache_timer ;
    ok $status->save_tied , $status ;
    ok $cache_hashref->{'TEST-UNIT-5'} , $status ;
    ok $cache_hashref->{'SIMULATION-1'}, $status ;
    undef $status ;
    ok defined($tied__hash{'TEST-UNIT-5'}) ;
    ok defined($tied__hash{'TEST-UNIT-5_rev'}) ;
        $s{version} = &thaw($tied__hash{'TEST-UNIT-5_rev'}) ;
    ok @{$s{version}} , 3 ;
    ok $s{version}->[0] , 3 ;
    ok $tied__hash{'SIMULATION-1'} , 'TEST-UNIT-5' ;

    $cache_hashref = { __GDBM_WRITER__ => 1 } ;
    #&dump_hash ;

    &info("4. Next update from converter using another cache");
    $0 = "TEST-Status-CO" , A2P::Syslog::SetLogger(0);
    $cache_hashref_2->{__GDBM_WRITER__} = 1 ;
    $status = new A2P::Status( $cache_hashref_2, \%tied__hash, 'TEST-UNIT-5' );
    ok $status->step_status(2,'.') , '.';
    ok $status->infos({ JID => 'SIMULATION-1' });
    ok $status->cached ;
    ok $status->cache_timer ;
    ok $status->save_tied , $status ;
    ok $cache_hashref_2->{'TEST-UNIT-5'} , $status ;
    ok $cache_hashref_2->{'SIMULATION-1'}, $status ;
    ok $cache_hashref_2->{'__SID__'}->{3}, undef ;
    undef $status ;
    ok defined($tied__hash{'TEST-UNIT-5'}) ;
    ok defined($tied__hash{'TEST-UNIT-5_rev'}) ;
        $s{version} = &thaw($tied__hash{'TEST-UNIT-5_rev'}) ;
    ok @{$s{version}} , 3 ;
    ok $s{version}->[0] , 4 ;
    ok $tied__hash{'SIMULATION-1'} , 'TEST-UNIT-5' ;

    &info("5. Clear the cache to simulate check from a2p-status as reader");
    $cache_hashref = { __GDBM_WRITER__ => 0 } ;
    #&dump_hash ;

    &info("6. In the same time a2p-status get the status and update it in DB");
    $0 = "TEST-Status-DB" , A2P::Syslog::SetLogger(0);
    $status = new A2P::Status( $cache_hashref, \%tied__hash, 'TEST-UNIT-5' );

    &info("Check current_in_tie_sid_key API");
    ok $status->current_in_tie_sid_key , 'TEST-UNIT-5' ;

    ok $cache_hashref->{'TEST-UNIT-5'} , $status ;
    ok $cache_hashref->{'SIMULATION-1'}, $status ;
    ok $status->get_sid_index , 0 ;
    &info("7. Here a sync with DB result in a change of SID");
    ok A2P::Status::_found_sid() , 0 ;
    ok $status->{DB}->{SID} , undef ;
    $status->{PREVIOUS_SID} = 'TEST-UNIT-5' ;
    $status->{SID} = $status->{DB}->{SID} = 3 ;
    ok $status->get_revision, 4 ;
    $status->{DB}->{REV} = $status->get_revision ;
    ok $status->get_sid_index , 3 ;
    $cache_hashref->{'__SID__'}->{$status->get_sid_index} = $status ;
    ok A2P::Status::_found_sid(3), 3 ;
    ok A2P::Status::_found_sid() , 4 ;
    ok $status->cache_timer ;
    #&dump_hash ;

    &info("Check current_in_tie_sid_key API");
    ok $status->current_in_tie_sid_key , 'TEST-UNIT-5' ;

    &info("8. Check we can't update status tied hash");
    ok $status->get_revision, 4 ;
    ok $status->save_tied , 0 ;
    ok $status->get_revision, 5 ;
    ok $cache_hashref->{'TEST-UNIT-5'} , $status ;
    ok $cache_hashref->{'SIMULATION-1'}, $status ;
    ok $cache_hashref->{'__SID__'}->{3}, $status ;
    ok defined($tied__hash{'TEST-UNIT-5'}) ;
    ok defined($tied__hash{'TEST-UNIT-5_rev'}) ;
        $s{version} = &thaw($tied__hash{'TEST-UNIT-5_rev'}) ;
    ok @{$s{version}} , 3 ;
    ok $s{version}->[0] , 4 ;
    ok ! exists($tied__hash{'_SID_3'}) ;
    ok ! exists($tied__hash{'_SID_3_rev'}) ;
    ok $tied__hash{'SIMULATION-1'} , 'TEST-UNIT-5' ;
    #&dump_hash ;

    &info("9. Retry to update tied hash");
    $cache_hashref->{__GDBM_WRITER__} = 1 ;
    undef $status ;
    $status = new A2P::Status( $cache_hashref, \%tied__hash, 'TEST-UNIT-5' );
    ok $cache_hashref->{'TEST-UNIT-5'} , $status ;
    ok $cache_hashref->{'SIMULATION-1'}, $status ;
    ok $status->get_sid_index , 3 ;
    ok $cache_hashref->{'__SID__'}->{3}, $status ;
    &info("Here sync_with_db simulates a change of SID with PREVIOUS_SID");
    ok $status->{SID} , 3 ;
    ok $status->get_sid_index , 3 ;
    ok $status->{PREVIOUS_SID} , 'TEST-UNIT-5' ;
    ok $status->{DB}->{SID} , 3 ;
    ok $status->cache_timer ;

    &info("10. Check we have updated status tied hash");
    ok $status->save_tied , $status ;
    # Only deleted after save_tied in sync_with_db
    delete $tied__hash{'TEST-UNIT-5_rev'} ;
    ok $status->get_revision, 6 ;
    ok $cache_hashref->{'TEST-UNIT-5'} , $status ;
    ok $cache_hashref->{'SIMULATION-1'}, $status ;
    ok $cache_hashref->{'__SID__'}->{3}, $status ;
    ok $tied__hash{'TEST-UNIT-5'} , '3' ;
    ok ! exists($tied__hash{'TEST-UNIT-5_rev'}) ;
    ok defined($tied__hash{'_SID_3'}) ;
    ok defined($tied__hash{'_SID_3_rev'}) ;
        $s{version} = &thaw($tied__hash{'_SID_3_rev'}) ;
    ok @{$s{version}} , 3 ;
    ok $s{version}->[0] , 6 ;
    ok $tied__hash{'SIMULATION-1'} , 'TEST-UNIT-5' ;

    &info("Check current_in_tie_sid_key API");
    ok $status->current_in_tie_sid_key , '_SID_3' ;
    undef $status ;

    &info("11. Following check as reader are done with new SID key");
    $cache_hashref->{__GDBM_WRITER__} = 0 ;
    undef $status ;
    $status = new A2P::Status( $cache_hashref, \%tied__hash, '_SID_3' );
    ok $status->get_revision, 6 ;
    ok $status->get_sid_index , 3 ;
    $cache_hashref->{'__SID__'}->{$status->get_sid_index} = $status ;
    #&dump_hash ;

    &info("Check current_in_tie_sid_key API");
    ok $status->current_in_tie_sid_key , '_SID_3' ;

    &info("12. Use the other cache and control SID is not troubled");
    $0 = "TEST-Status-CO" , A2P::Syslog::SetLogger(0);
    $status = new A2P::Status( $cache_hashref_2, \%tied__hash, 'TEST-UNIT-5' );

    &info("Check current_in_tie_sid_key API");
    ok $status->current_in_tie_sid_key , '_SID_3' ;

    ok $status->step_status(2,'o') , 'o';
    ok $status->infos ;
    ok $status->cached ;
    ok $status->cache_timer ;
    #&dump_hash ;
    ok $status->save_tied , $status ;
    ok $status->get_revision, 7 ;
    ok $cache_hashref_2->{'TEST-UNIT-5'} , $status ;
    ok $cache_hashref_2->{'SIMULATION-1'}, $status ;
    ok $cache_hashref_2->{'__SID__'}->{3}, $status ;
    ok ! exists($tied__hash{'TEST-UNIT-5_rev'}) ;
    ok defined($tied__hash{'_SID_3'}) ;
    ok defined($tied__hash{'_SID_3_rev'}) ;
    ok defined($tied__hash{'_SID_3_rev'}) ;
        $s{version} = &thaw($tied__hash{'_SID_3_rev'}) ;
    ok @{$s{version}} , 3 ;
    ok $s{version}->[0] , 7 ;
    ok $tied__hash{'SIMULATION-1'} , 'TEST-UNIT-5' ;
    ok $tied__hash{'TEST-UNIT-5'}  , '3' ;
    undef $status ;

&info("Check remove_from_cache call");
    $cache_hashref->{__GDBM_WRITER__} = 1 ;
    $intied = new A2P::Status( $cache_hashref, \%tied__hash, 'TEST_UNIT_6' );
    ok $intied->save_tied(), $intied ;
    ok defined($tied__hash{'TEST_UNIT_6'}) ;
    ok $cache_hashref->{'TEST_UNIT_6'}, $intied ;
    $intied->remove_from_cache ;
    ok defined($tied__hash{'TEST_UNIT_6'}) ;
    ok $cache_hashref->{'TEST_UNIT_6'}, undef ;

&info("Check cache/timer info APIs");
    ok $cache_hashref->{__GDBM_WRITER__} ;
    $status = new A2P::Status( $cache_hashref, \%tied__hash, 'TEST_UNIT_7' );
    ok $status->cached ;
    ok exists($cache_hashref->{'TEST_UNIT_7'}) ;
    ok $cache_hashref->{'TEST_UNIT_7'}, $status ;
    ok exists($cache_hashref->{'TEST_UNIT_7'}->{TIMER}) ;
    ok $cache_hashref->{'TEST_UNIT_7'}->{TIMER} ;
    ok $cache_hashref->{'TEST_UNIT_7'}->timer ;
        my $timer = $cache_hashref->{'TEST_UNIT_7'}->{TIMER} ;
    ok $cache_hashref->{'TEST_UNIT_7'}->timer, $timer ;

&info("Check compared_with_one_from_tiehash API");
    ok $status->get_revision, 0 ;
    ok $status->save_tied(), $status ;
    ok $status->get_revision, 1 ;
    ok defined($tied__hash{'TEST_UNIT_7'}) ;
        my $dirty = $status->clone ;
    ok $status->save_tied(), $status ;
    ok $status->get_revision, 2 ;
    ok $dirty->get_revision, 1 ;
        # Dirty cache entry
    ok $status->compared_with_one_from_tiehash, $status ;
        my $updated = $dirty->compared_with_one_from_tiehash ;
    ok $updated != $dirty ;
    ok $updated->get_revision, 2 ;
        $updated->cached ;
    ok $cache_hashref->{'TEST_UNIT_7'}, $updated ;
    ok $dirty->get_revision, 1 ;
    ok $dirty->set_revision, 2 ;
    ok $dirty->compared_with_one_from_tiehash, $dirty ;
    ok $dirty->set_revision, 3 ;
    ok $dirty->compared_with_one_from_tiehash, $dirty ;
    ok $cache_hashref->{'TEST_UNIT_7'} != $dirty ;

$do_next_test = 0 ;
if ($do_next_test) { # This long test should normally be disabled
&info("Check remove_from_tied_hash API timing");
    $status = new A2P::Status( $cache_hashref, \%tied__hash, 'TEST_UNIT_8' );
    my $ostatus = new A2P::Status( $cache_hashref, \%tied__hash, 'TEST_UNIT_9' );
    ok $status->save_tied(), $status ;
    ok $ostatus->save_tied(), $ostatus ;
    ok defined($tied__hash{'TEST_UNIT_8'}) ;
        my $i = 0 ;
        while ( $i++ < 10000 ) {
            #&dump_hash if ( $i == 10 );
            $status->is_job('TEST_UNIT_8_ref_'.$i);
            $status->save_tied();
            $ostatus->is_job('TEST_UNIT_9_ref_'.$i);
            $ostatus->save_tied();
        }
        $status->set_sid_index(500);
        $status->save_tied ;
        $ostatus->set_sid_index(5000);
        $ostatus->save_tied ;
    my ( $size, $maxsize ) = ( -s $tie_file, 3000000 );
    &info("Memory file size = $size bytes");
    $size > $maxsize ? ok $size, $maxsize : ok 1 ;
    my ( $timing, $maxtiming ) = ( $STATS{'TIMING-SAVE-TIED-MAX'}, 20000 );
    &info("Max save to tied timing = $timing");
    $timing > $maxtiming ? ok $timing, $maxtiming : ok 1 ;
        $status->remove_from_cache ;
        $status->remove_from_tied_hash();
    ( $timing, $maxtiming ) = ( $STATS{'TIMING-REMOVE-FROM-TIED-MAX'}, 700000 );
    &info("Max remove timing = $timing");
    $timing > $maxtiming ? ok $timing, $maxtiming : ok 1 ;
        my $tiedhash = tied( %tied__hash ) ;
    ok ref($tiedhash) , 'GDBM_File' ;
    &info("Shrinking memory file...");
        my $shrinked = -s $tie_file ? $tiedhash->reorganize() : 0 ;
        undef $tiedhash ;
    (defined($shrinked) and $shrinked >= 0) ? ok $shrinked, 0 : ok 0 ;
    ( $size, $maxsize ) = ( -s $tie_file, 1200000 );
    &info("Shrinked memory file size = $size bytes");
    $size > $maxsize ? ok $size, $maxsize : ok 1 ;
}

# Clean
#&dump_hash ;
untie %tied__hash ;
unlink $tie_file ;

exit(0) ;
