Kubernetes-REST
view release on metacpan or search on metacpan
t/13_io_backends.t view on Meta::CPAN
subtest 'HTTPTinyIO - call() with empty content' => sub {
my $io = Kubernetes::REST::HTTPTinyIO->new;
my $mock_ua = Test::MockHTTPTiny->new(
status => 200,
content => undef,
);
$io->{ua} = $mock_ua;
my $req = Kubernetes::REST::HTTPRequest->new(
method => 'GET',
url => 'http://mock.local/api/v1/pods',
headers => {},
);
my $res = $io->call($req);
is $res->status, 200, 'status ok with no content';
};
subtest 'HTTPTinyIO - call_streaming() with data callback' => sub {
my $io = Kubernetes::REST::HTTPTinyIO->new;
my @delivered_chunks;
my $mock_ua = Test::MockHTTPTiny->new(
status => 200,
content => undef,
on_data_callback => sub {
my ($cb) = @_;
$cb->(qq|{"type":"ADDED","object":{"kind":"Pod"}}\n|);
$cb->(qq|{"type":"DELETED","object":{"kind":"Pod"}}\n|);
},
);
$io->{ua} = $mock_ua;
my $req = Kubernetes::REST::HTTPRequest->new(
method => 'GET',
url => 'http://mock.local/api/v1/pods?watch=true',
headers => {},
);
my @chunks;
my $res = $io->call_streaming($req, sub { push @chunks, $_[0] });
is $res->status, 200, 'streaming returns 200';
is scalar @chunks, 2, 'received 2 chunks';
like $chunks[0], qr/ADDED/, 'first chunk is ADDED';
like $chunks[1], qr/DELETED/, 'second chunk is DELETED';
};
# ============================================================================
# Test that REST.pm uses LWPIO by default
# ============================================================================
subtest 'REST default IO is LWPIO' => sub {
use Test::Kubernetes::Mock qw(mock_api);
# The mock API uses Mock::IO, so test by creating a non-mock one
require Kubernetes::REST;
require Kubernetes::REST::Server;
require Kubernetes::REST::AuthToken;
my $api = Kubernetes::REST->new(
server => Kubernetes::REST::Server->new(endpoint => 'http://test.local'),
credentials => Kubernetes::REST::AuthToken->new(token => 'test'),
resource_map_from_cluster => 0,
);
isa_ok $api->io, 'Kubernetes::REST::LWPIO', 'default IO is LWPIO';
};
subtest 'REST allows HTTPTinyIO override' => sub {
require Kubernetes::REST;
require Kubernetes::REST::Server;
require Kubernetes::REST::AuthToken;
require Kubernetes::REST::HTTPTinyIO;
my $api = Kubernetes::REST->new(
server => Kubernetes::REST::Server->new(endpoint => 'http://test.local'),
credentials => Kubernetes::REST::AuthToken->new(token => 'test'),
resource_map_from_cluster => 0,
io => Kubernetes::REST::HTTPTinyIO->new,
);
isa_ok $api->io, 'Kubernetes::REST::HTTPTinyIO', 'can override with HTTPTinyIO';
};
done_testing;
# ============================================================================
# Minimal mock LWP::UserAgent for testing LWPIO without network
# ============================================================================
package Test::MockLWP;
use strict;
use warnings;
sub new {
my ($class, %args) = @_;
bless {
code => $args{code} // 200,
content => $args{content} // '',
streaming_chunks => $args{streaming_chunks} // [],
last_request => undef,
}, $class;
}
sub request {
my ($self, $req, $content_cb) = @_;
$self->{last_request} = $req;
if ($content_cb && ref $content_cb eq 'CODE') {
# Streaming mode: deliver chunks via callback
for my $chunk (@{$self->{streaming_chunks}}) {
$content_cb->($chunk);
}
}
return Test::MockLWP::Response->new(
code => $self->{code},
content => $self->{content},
);
}
sub last_request { $_[0]->{last_request} }
package Test::MockLWP::Response;
use strict;
use warnings;
sub new {
my ($class, %args) = @_;
bless \%args, $class;
}
sub code { $_[0]->{code} }
sub decoded_content { $_[0]->{content} }
# ============================================================================
# Minimal mock HTTP::Tiny for testing HTTPTinyIO without network
( run in 1.491 second using v1.01-cache-2.11-cpan-524268b4103 )