1N/A#!/usr/bin/perl
1N/A#
1N/A# Tests for various caching errors
1N/A#
1N/A
1N/Amy $file = "tf$$.txt";
1N/A$: = Tie::File::_default_recsep();
1N/Amy $data = join $:, "record0" .. "record9", "";
1N/Amy $V = $ENV{INTEGRITY}; # Verbose integrity checking?
1N/A
1N/Aprint "1..111\n";
1N/A
1N/Amy $N = 1;
1N/Ause Tie::File;
1N/Aprint "ok $N\n"; $N++;
1N/A
1N/Aopen F, "> $file" or die $!;
1N/Abinmode F;
1N/Aprint F $data;
1N/Aclose F;
1N/A
1N/A# Limit cache size to 30 bytes
1N/Amy $MAX = 30;
1N/A# -- that's enough space for 3 records, but not 4, on both \n and \r\n systems
1N/Amy $o = tie @a, 'Tie::File', $file, memory => $MAX, autodefer => 0;
1N/Aprint $o ? "ok $N\n" : "not ok $N\n";
1N/A$N++;
1N/A
1N/A# (3-5) Let's see if data was properly expired from the cache
1N/Amy @z = @a; # force cache to contain all ten records
1N/A# It should now contain only the *last* three records, 7, 8, and 9
1N/A{
1N/A my $x = "7 8 9";
1N/A my $a = join " ", sort $o->{cache}->ckeys;
1N/A if ($a eq $x) { print "ok $N\n" }
1N/A else { print "not ok $N # cache keys were <$a>; expected <$x>\n" }
1N/A $N++;
1N/A}
1N/Acheck();
1N/A
1N/A# Here we redo *all* the splice tests, with populate()
1N/A# calls before each one, to make sure that splice() does not botch the cache.
1N/A
1N/A# (6-25) splicing at the beginning
1N/Asplice(@a, 0, 0, "rec4");
1N/Acheck();
1N/Asplice(@a, 0, 1, "rec5"); # same length
1N/Acheck();
1N/Asplice(@a, 0, 1, "record5"); # longer
1N/Acheck();
1N/Asplice(@a, 0, 1, "r5"); # shorter
1N/Acheck();
1N/Asplice(@a, 0, 1); # removal
1N/Acheck();
1N/Asplice(@a, 0, 0); # no-op
1N/Acheck();
1N/A
1N/Asplice(@a, 0, 0, 'r7', 'rec8'); # insert more than one
1N/Acheck();
1N/Asplice(@a, 0, 2, 'rec7', 'record8', 'rec9'); # insert more than delete
1N/Acheck();
1N/Asplice(@a, 0, 3, 'record9', 'rec10'); # delete more than insert
1N/Acheck();
1N/Asplice(@a, 0, 2); # delete more than one
1N/Acheck();
1N/A
1N/A
1N/A# (26-45) splicing in the middle
1N/Asplice(@a, 1, 0, "rec4");
1N/Acheck();
1N/Asplice(@a, 1, 1, "rec5"); # same length
1N/Acheck();
1N/Asplice(@a, 1, 1, "record5"); # longer
1N/Acheck();
1N/Asplice(@a, 1, 1, "r5"); # shorter
1N/Acheck();
1N/Asplice(@a, 1, 1); # removal
1N/Acheck();
1N/Asplice(@a, 1, 0); # no-op
1N/Acheck();
1N/A
1N/Asplice(@a, 1, 0, 'r7', 'rec8'); # insert more than one
1N/Acheck();
1N/Asplice(@a, 1, 2, 'rec7', 'record8', 'rec9'); # insert more than delete
1N/Acheck();
1N/Asplice(@a, 1, 3, 'record9', 'rec10'); # delete more than insert
1N/Acheck();
1N/Asplice(@a, 1, 2); # delete more than one
1N/Acheck();
1N/A
1N/A# (46-65) splicing at the end
1N/Asplice(@a, 3, 0, "rec4");
1N/Acheck();
1N/Asplice(@a, 3, 1, "rec5"); # same length
1N/Acheck();
1N/Asplice(@a, 3, 1, "record5"); # longer
1N/Acheck();
1N/Asplice(@a, 3, 1, "r5"); # shorter
1N/Acheck();
1N/Asplice(@a, 3, 1); # removal
1N/Acheck();
1N/Asplice(@a, 3, 0); # no-op
1N/Acheck();
1N/A
1N/Asplice(@a, 3, 0, 'r7', 'rec8'); # insert more than one
1N/Acheck();
1N/Asplice(@a, 3, 2, 'rec7', 'record8', 'rec9'); # insert more than delete
1N/Acheck();
1N/Asplice(@a, 3, 3, 'record9', 'rec10'); # delete more than insert
1N/Acheck();
1N/Asplice(@a, 3, 2); # delete more than one
1N/Acheck();
1N/A
1N/A# (66-85) splicing with negative subscript
1N/Asplice(@a, -1, 0, "rec4");
1N/Acheck();
1N/Asplice(@a, -1, 1, "rec5"); # same length
1N/Acheck();
1N/Asplice(@a, -1, 1, "record5"); # longer
1N/Acheck();
1N/Asplice(@a, -1, 1, "r5"); # shorter
1N/Acheck();
1N/Asplice(@a, -1, 1); # removal
1N/Acheck();
1N/Asplice(@a, -1, 0); # no-op
1N/Acheck();
1N/A
1N/Asplice(@a, -1, 0, 'r7', 'rec8'); # insert more than one
1N/Acheck();
1N/Asplice(@a, -1, 2, 'rec7', 'record8', 'rec9'); # insert more than delete
1N/Acheck();
1N/Asplice(@a, -3, 3, 'record9', 'rec10'); # delete more than insert
1N/Acheck();
1N/Asplice(@a, -4, 3); # delete more than one
1N/Acheck();
1N/A
1N/A# (86-87) scrub it all out
1N/Asplice(@a, 0, 3);
1N/Acheck();
1N/A
1N/A# (88-89) put some back in
1N/Asplice(@a, 0, 0, "rec0", "rec1");
1N/Acheck();
1N/A
1N/A# (90-91) what if we remove too many records?
1N/Asplice(@a, 0, 17);
1N/Acheck();
1N/A
1N/A# (92-95) In the past, splicing past the end was not correctly detected
1N/A# (1.14)
1N/Asplice(@a, 89, 3);
1N/Acheck();
1N/Asplice(@a, @a, 3);
1N/Acheck();
1N/A
1N/A# (96-99) Also we did not emulate splice's freaky behavior when inserting
1N/A# past the end of the array (1.14)
1N/Asplice(@a, 89, 0, "I", "like", "pie");
1N/Acheck();
1N/Asplice(@a, 89, 0, "pie pie pie");
1N/Acheck();
1N/A
1N/A# (100-105) Test default arguments
1N/Asplice @a, 0, 0, (0..11);
1N/Acheck();
1N/Asplice @a, 4;
1N/Acheck();
1N/Asplice @a;
1N/Acheck();
1N/A
1N/A# (106-111) One last set of tests. I don't know what state the cache
1N/A# is in now. But if I read any three records, those three records are
1N/A# what should be in the cache, and nothing else.
1N/A@a = "record0" .. "record9";
1N/Acheck(); # In 0.18 #107 fails here--STORE was not flushing the cache when
1N/A # replacing an old cached record with a longer one
1N/Afor (5, 6, 1) { my $z = $a[$_] }
1N/A{
1N/A my $x = "5 6 1";
1N/A my $a = join " ", $o->{cache}->_produce_lru;
1N/A if ($a eq $x) { print "ok $N\n" }
1N/A else { print "not ok $N # LRU was <$a>; expected <$x>\n" }
1N/A $N++;
1N/A $x = "1 5 6";
1N/A $a = join " ", sort $o->{cache}->ckeys;
1N/A if ($a eq $x) { print "ok $N\n" }
1N/A else { print "not ok $N # cache keys were <$a>; expected <$x>\n" }
1N/A $N++;
1N/A}
1N/Acheck();
1N/A
1N/A
1N/Asub init_file {
1N/A my $data = shift;
1N/A open F, "> $file" or die $!;
1N/A binmode F;
1N/A print F $data;
1N/A close F;
1N/A}
1N/A
1N/Asub check {
1N/A my $integrity = $o->_check_integrity($file, $ENV{INTEGRITY});
1N/A print $integrity ? "ok $N\n" : "not ok $N\n";
1N/A $N++;
1N/A
1N/A my $b = $o->{cache}->bytes;
1N/A print $b <= $MAX
1N/A ? "ok $N\n"
1N/A : "not ok $N # $b bytes cached, should be <= $MAX\n";
1N/A $N++;
1N/A}
1N/A
1N/A
1N/Asub ctrlfix {
1N/A for (@_) {
1N/A s/\n/\\n/g;
1N/A s/\r/\\r/g;
1N/A }
1N/A}
1N/A
1N/AEND {
1N/A undef $o;
1N/A untie @a;
1N/A 1 while unlink $file;
1N/A}
1N/A
1N/A
1N/A