Data-Fenwick2D-Shared
view release on metacpan or search on metacpan
t/02-frozen.t view on Meta::CPAN
is $ro->prefix(6, 4), $exp_prefix, 'prefix matches producer (lock-free)';
is $ro->rect(2, 1, 8, 5), $exp_rect, 'rect matches producer (lock-free)';
is $ro->point(5, 3), $exp_point, 'point matches producer (lock-free)';
is $ro->rows, $R, 'rows works read-only';
is $ro->cols, $C, 'cols works read-only';
is $ro->path, $path, 'path works read-only';
cmp_ok $ro->memfd, '==', -1, 'memfd works read-only (file-backed -> -1)';
my $st = $ro->stats;
is ref($st), 'HASH', 'stats works read-only';
is $st->{frozen}, 1, 'stats.frozen set';
is $st->{readonly}, 1, 'stats.readonly set';
is $st->{total}, $exp_total, 'stats.total matches producer';
is $st->{rows}, $R, 'stats.rows';
is $st->{cols}, $C, 'stats.cols';
ok eval { $ro->sync; 1 }, 'sync is a silent no-op on a read-only handle'
or diag $@;
like exception(sub { $ro->update(1, 1, 1) }), qr/read-only/, 'update on read-only view croaks';
like exception(sub { $ro->set(1, 1, 1) }), qr/read-only/, 'set on read-only view croaks';
like exception(sub { $ro->clear }), qr/read-only/, 'clear on read-only view croaks';
like exception(sub { $ro->freeze }), qr/read-only/, 'freeze on read-only view croaks';
}
# ---- two independent read-only views of the same file, concurrently ----
{
my $a = Data::Fenwick2D::Shared->new_readonly($path);
my $b = Data::Fenwick2D::Shared->new_readonly($path);
is $a->prefix(6, 4), $exp_prefix, 'view a queries the same file';
is $b->prefix(6, 4), $exp_prefix, 'view b queries the same file';
}
# ---- refuse a read-write reopen of a sealed file ----
like exception(sub { Data::Fenwick2D::Shared->new($path, $R, $C) }),
qr/frozen|read-only/, 'read-write reopen of a sealed file is refused';
# ---- new_from_fd also refuses a sealed file ----
{
open my $fh, '+<', $path or die "open $path: $!";
like exception(sub { Data::Fenwick2D::Shared->new_from_fd(fileno($fh)) }),
qr/frozen|read-only/, 'new_from_fd on a sealed file is refused';
}
# ---- new_readonly rejects a non-frozen file ----
{
my $u = "$dir/unsealed.f2d";
{ my $f = Data::Fenwick2D::Shared->new($u, 4, 4); $f->update(1, 1, 1); }
like exception(sub { Data::Fenwick2D::Shared->new_readonly($u) }),
qr/not frozen/, 'new_readonly on an unsealed file croaks';
}
# ---- new_readonly error paths ----
like exception(sub { Data::Fenwick2D::Shared->new_readonly("$dir/does-not-exist.f2d") }),
qr/open|No such/, 'new_readonly on a missing path croaks';
like exception(sub { Data::Fenwick2D::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.782 second using v1.01-cache-2.11-cpan-54e63673c56 )