Data-SortedSet-Shared
view release on metacpan or search on metacpan
t/09-frozen.t view on Meta::CPAN
my @seen;
$ro->each(sub { push @seen, $_[0] });
is_deeply \@seen, \@members, 'each() full iteration on PROT_READ handle';
ok $ro->_validate, 'read-only tree validates lock-free';
my $st = $ro->stats;
is $st->{frozen}, 1, 'stats.frozen == 1';
is $st->{readonly}, 1, 'stats.readonly == 1';
is $st->{count}, $N, 'stats.count via read-only view';
# every mutator croaks on the read-only view
like exception(sub { $ro->add(1, 2) }), qr/read-only|frozen/, 'add croaks on read-only view';
like exception(sub { $ro->incr(1, 1) }), qr/read-only|frozen/, 'incr croaks on read-only view';
like exception(sub { $ro->remove(1) }), qr/read-only|frozen/, 'remove croaks on read-only view';
like exception(sub { $ro->clear }), qr/read-only|frozen/, 'clear croaks on read-only view';
like exception(sub { $ro->pop_min }), qr/read-only|frozen/, 'pop_min croaks on read-only view';
like exception(sub { $ro->pop_max }), qr/read-only|frozen/, 'pop_max croaks on read-only view';
like exception(sub { $ro->add_many([[1,2]]) }), qr/read-only|frozen/, 'add_many croaks on read-only view';
like exception(sub { $ro->freeze }), qr/read-only/, 'freeze croaks on read-only view';
is $ro->sync, undef, 'sync is a harmless no-op on a read-only view';
}
# ---- two independent read-only views of the same file, concurrently ----
{
my $a = Data::SortedSet::Shared->new_readonly($path);
my $b = Data::SortedSet::Shared->new_readonly($path);
ok $a->score(1) == 1.5 && $b->score($N) == $N + 0.5,
'two read-only views query the same file';
}
# ---- refuse a read-write reopen of a sealed file ----
like exception(sub { Data::SortedSet::Shared->new($path, 2 * $N) }),
qr/frozen|read-only/, 'read-write reopen of a sealed file is refused';
# ---- refuse a read-write new_from_fd of a sealed file ----
{
open my $fh, '+<', $path or die "open $path: $!";
like exception(sub { Data::SortedSet::Shared->new_from_fd(fileno $fh) }),
qr/frozen|read-only/, 'new_from_fd on a sealed file is refused';
close $fh;
}
# ---- new_readonly rejects a non-frozen file ----
{
my $u = "$dir/unsealed.sset";
{ my $z = Data::SortedSet::Shared->new($u, 100); $z->add(1, 1); }
like exception(sub { Data::SortedSet::Shared->new_readonly($u) }),
qr/not frozen/, 'new_readonly on an unsealed file croaks';
}
# ---- new_readonly error paths ----
like exception(sub { Data::SortedSet::Shared->new_readonly("$dir/does-not-exist.sset") }),
qr/open|No such/, 'new_readonly on a missing path croaks';
like exception(sub { Data::SortedSet::Shared->new_readonly(undef) }),
qr/required/, 'new_readonly requires a path';
done_testing;
# minimal exception helper (avoid a Test::Fatal dependency)
sub exception {
my $code = shift;
my $err;
{ local $@; eval { $code->(); 1 } or $err = $@; }
return $err;
}
( run in 0.820 second using v1.01-cache-2.11-cpan-54e63673c56 )