API-Docker
view release on metacpan or search on metacpan
t/mock_harness.t view on Meta::CPAN
use strict;
use warnings;
use Test::More;
use lib 't/lib';
use Test::API::Docker::Mock;
# Regression coverage for the test harness itself (karr k109), not for
# lib/: Test::API::Docker::Mock's fallback route matching used to
# interpolate a route key straight into a regex (`m{^$route_path$}` in
# _mock_docker), so a key containing a regex metacharacter was read as a
# pattern rather than as the literal path it looks like. `.` is the case
# that bites here: it matches any single character, so a route meant for one
# exact path silently also matched a different path that happened to differ
# only at the position the dot sat. Fixed with \Q...\E so the fallback tier
# is literal matching, tolerant only of whitespace between method and path
# -- which is what every route key in this suite, bar the one dynamic
# pattern in t/streaming_methods.t, was written as though it already were.
#
# The fallback tier only runs once the request path fails an EXACT string
# match against a route key (the `exists $routes{$key}` fast path in
# _mock_docker), so a route with a metacharacter has to be probed with a
# path that is close but not identical to reach it -- an exact hit never
# touches the regex at all.
check_live_access();
subtest 'a route key with a regex metacharacter is matched literally, not as a pattern' => sub {
plan skip_all => 'the mock route table is bypassed in live mode' if is_live();
# sha256:deadbeef.dead and sha256:deadbeefXdead differ only at the dot's
# position and are otherwise the same length. Unescaped,
# m{^sha256:deadbeef.dead$} reads the dot as "any character" and matches
# the second string too, even though only the first was ever registered.
my $docker = test_docker(
'GET /images/sha256:deadbeef.dead/json' => { Id => 'the-dotted-one' },
);
my $exact = $docker->images->inspect('sha256:deadbeef.dead');
is $exact->id, 'the-dotted-one',
'the literal path the route key names still matches -- this one is an '
. 'exact hash hit and never reaches the regex fallback at all';
my $err = do {
local $@;
eval { $docker->images->inspect('sha256:deadbeefXdead') };
$@;
};
like $err, qr/No mock route for/,
'a path that only accidentally resembles the route key -- same length, '
. 'differing at exactly the position the "." sat -- is refused rather '
. 'than matched. On the old, unescaped fallback this returned '
. 'the-dotted-one instead of croaking: a route for one image answering '
. 'for a different one';
};
done_testing;
( run in 0.720 second using v1.01-cache-2.11-cpan-54e63673c56 )