File Coverage

lib/Test/APIcast.pm
Criterion Covered Total %
statement 38 84 45.2
branch 0 16 0.0
condition 1 2 50.0
subroutine 14 20 70.0
pod 0 6 0.0
total 53 128 41.4


line stmt bran cond sub pod time code
1             package Test::APIcast;
2 1     1   508 use v5.10.1;
  1         2  
3 1     1   4 use strict;
  1         1  
  1         20  
4 1     1   12 use warnings FATAL => 'all';
  1         1  
  1         48  
5              
6             our $VERSION = "0.21";
7              
8             BEGIN {
9 1   50 1   43 $ENV{TEST_NGINX_BINARY} ||= 'openresty';
10             }
11              
12 1     1   384 use Test::Nginx::Socket::Lua -Base;
  1         152549  
  1         7  
13 1     1   2350  
  1     1   2  
  1     1   69  
  1     1   6  
  1         2  
  1         28  
  1         4  
  1         2  
  1         14  
  1         3  
  1         1  
  1         24  
14 1     1   4 use Cwd qw(cwd abs_path);
  1         1  
  1         60  
15 1     1   500 use File::Spec::Functions qw(catfile);
  1         645  
  1         55  
16 1     1   425 use File::Slurp qw(read_file);
  1         3159  
  1         1017  
17              
18             my $pwd = cwd();
19             our $path = $ENV{TEST_NGINX_APICAST_PATH} ||= "$pwd/gateway";
20             our $spec = "$pwd/spec";
21             our $servroot = $Test::Nginx::Util::ServRoot;
22              
23             our $Fixtures = abs_path($ENV{TEST_NGINX_FIXTURES} || catfile('t', 'fixtures'));
24              
25             # src/?/policy.lua allows us to require apicast.policy.apolicy
26             $ENV{TEST_NGINX_LUA_PATH} = "$path/src/?.lua;$path/src/?/policy.lua;;";
27             $ENV{TEST_NGINX_MANAGEMENT_CONFIG} = "$path/conf.d/management.conf";
28             $ENV{TEST_NGINX_UPSTREAM_CONFIG} = "$path/http.d/upstream.conf";
29             $ENV{TEST_NGINX_BACKEND_CONFIG} = "$path/conf.d/backend.conf";
30             $ENV{TEST_NGINX_APICAST_CONFIG} = "$path/conf.d/apicast.conf";
31             $ENV{APICAST_DIR} = $path;
32              
33             if ($ENV{DEBUG}) {
34             $ENV{TEST_NGINX_ERROR_LOG} ||= '/dev/stderr';
35             }
36              
37             our @EXPORT = qw( get_random_port );
38              
39             our @PORTS = ();
40              
41 0     0 0   sub get_random_port {
42 0           my $tries = 1000;
43 0           my $ServerPort;
44              
45 0           for (my $i = 0; $i < $tries; $i++) {
46 0           my $port = int(rand 60000) + 1025;
47              
48 0           my $sock = IO::Socket::INET->new(
49             LocalAddr => $Test::Nginx::Util::ServerAddr,
50             LocalPort => $port,
51             Proto => 'tcp',
52             Timeout => 0.1,
53             );
54              
55 0 0         if (defined $sock) {
56 0           push @PORTS, $sock;
57 0           $ServerPort = $port;
58 0           last;
59             }
60              
61 0 0         if ($Test::Nginx::Util::Verbose) {
62 0           warn "Try again, port $port is already in use: $@\n";
63             }
64             }
65              
66 0 0         if (!defined $ServerPort) {
67 0           bail_out "Cannot find an available listening port number after $tries attempts.\n";
68             }
69              
70 0           return $ServerPort;
71             }
72              
73             env_to_nginx('APICAST_DIR');
74             env_to_nginx("TEST_NGINX_SERVER_PORT=$Test::Nginx::Util::ServerPortForClient");
75              
76             log_level('debug');
77             repeat_each($ENV{TEST_NGINX_REPEAT_EACH} || 2);
78             no_root_location();
79              
80             add_block_preprocessor(sub {
81             my $block = shift;
82              
83             $ENV{TEST_NGINX_RANDOM_PORT} = $block->random_port;
84             });
85              
86              
87 0     0 0   sub close_random_ports {
88 0           my $sock;
89 0           while (defined($sock = shift @PORTS)){
90 0           $sock->close();
91             }
92             };
93              
94             our $dns = sub ($$$) {
95             my ($host, $ip, $ttl) = @_;
96              
97             return sub {
98             # Get DNS request ID from passed UDP datagram
99             my $dns_id = unpack("n", shift);
100             # Set name and encode it
101             my $name = $host;
102             $name =~ s/([^.]+)\.?/chr(length($1)) . $1/ge;
103             $name .= "\0";
104             my $s = '';
105             $s .= pack("n", $dns_id);
106             # DNS response flags, hardcoded
107             # response, opcode, authoritative, truncated, recursion desired, recursion available, reserved
108             my $flags = (1 << 15) + (0 << 11) + (1 << 10) + (0 << 9) + (1 << 8) + (1 << 7) + 0;
109             $flags = pack("n", $flags);
110             $s .= $flags;
111             $s .= pack("nnnn", 1, 1, 0, 0);
112             $s .= $name;
113             $s .= pack("nn", 1, 1); # query class A
114              
115             # Set response address and pack it
116             my @addr = split /\./, $ip;
117             my $data = pack("CCCC", @addr);
118              
119             # pointer reference to the first name
120             # $name = pack("n", 0b1100000000001100);
121              
122             # name + type A + class IN + TTL + length + data(ip)
123             $s .= $name. pack("nnNn", 1, 1, $ttl || 0, 4) . $data;
124             return $s;
125             }
126             };
127              
128             sub Test::Base::Filter::random_port {
129 0     0 0   my ($self, $code) = @_;
130              
131 0           my $block = $self->current_block;
132 0           my $random_port = $block->random_port;
133              
134 0 0         if ( !defined $random_port ) {
135 0 0         if ($Test::Nginx::Util::Randomize) {
136 0           $random_port = get_random_port();
137             } else {
138 0           $random_port = 1953;
139             }
140             }
141              
142 0           $block->set_value('random_port', $random_port);
143              
144 0           $ENV{TEST_NGINX_RANDOM_PORT} = $random_port;
145              
146 0           return $code;
147             }
148              
149              
150             sub Test::Base::Filter::dns {
151 0     0 0   my ($self, $code) = @_;
152              
153 0           my $input = eval $code;
154              
155 0 0         if ($@) {
156 0           die "failed to evaluate code $code: $@\n";
157             }
158              
159 0           return $dns->(@$input)
160             }
161              
162              
163             sub Test::Base::Filter::env {
164 0     0 0   my ($self, $input) = @_;
165              
166 0           return Test::Nginx::Util::expand_env_in_config($input);
167             }
168              
169             sub Test::Base::Filter::fixture {
170 0     0 0   my $name = filter_arguments;
171              
172 0 0         if (! $name) {
173 0           bail_out("fixture filter needs argument - file to be loaded");
174             };
175              
176 0           my $file = catfile($Fixtures, $name);
177              
178 0 0         if (! -f $file) {
179 0           bail_out("$file is not a file - fixture cannot be loaded");
180             }
181 0           my $contents = read_file($file);
182              
183 0           return $contents;
184             }
185              
186              
187             BEGIN {
188 1     1   10 no warnings 'redefine';
  1         2  
  1         94  
189              
190 1     1   4 *write_config_file= \&Test::Nginx::Util::write_config_file;
191              
192             *Test::Nginx::Util::write_config_file = sub ($$) {
193 0           write_config_file(@_);
194 0           close_random_ports();
195 1         56 };
196             }
197              
198             1;
199             __END__