comparison stream_upstream_hash.t @ 571:5c3946ebd867

Tests: basic stream tests for upstream hash.
author Sergey Kandaurov <pluknet@nginx.com>
date Tue, 12 May 2015 18:07:28 +0300
parents
children 824754da4afc
comparison
equal deleted inserted replaced
570:f7bc1f74970a 571:5c3946ebd867
1 #!/usr/bin/perl
2
3 # (C) Sergey Kandaurov
4 # (C) Nginx, Inc.
5
6 # Stream tests for upstream hash balancer module.
7
8 ###############################################################################
9
10 use warnings;
11 use strict;
12
13 use Test::More;
14
15 use IO::Select;
16
17 BEGIN { use FindBin; chdir($FindBin::Bin); }
18
19 use lib 'lib';
20 use Test::Nginx;
21
22 ###############################################################################
23
24 select STDERR; $| = 1;
25 select STDOUT; $| = 1;
26
27 my $t = Test::Nginx->new()->has(qw/stream stream_upstream_hash/)->plan(2);
28
29 $t->write_file_expand('nginx.conf', <<'EOF');
30
31 %%TEST_GLOBALS%%
32
33 daemon off;
34
35 events {
36 }
37
38 stream {
39 upstream hash {
40 hash $remote_addr;
41 server 127.0.0.1:8087;
42 server 127.0.0.1:8088;
43 }
44
45 upstream cons {
46 hash $remote_addr consistent;
47 server 127.0.0.1:8087;
48 server 127.0.0.1:8088;
49 }
50
51 server {
52 listen 127.0.0.1:8081;
53 proxy_pass hash;
54 }
55
56 server {
57 listen 127.0.0.1:8082;
58 proxy_pass cons;
59 }
60 }
61
62 EOF
63
64 $t->run_daemon(\&stream_daemon, 8087);
65 $t->run_daemon(\&stream_daemon, 8088);
66 $t->run();
67
68 $t->waitforsocket('127.0.0.1:8087');
69 $t->waitforsocket('127.0.0.1:8088');
70
71 ###############################################################################
72
73 is(many('.', 10, peer => '127.0.0.1:8081'), '8088: 10', 'hash');
74 is(many('.', 10, peer => '127.0.0.1:8082'), '8088: 10', 'hash consistent');
75
76 ###############################################################################
77
78 sub many {
79 my ($data, $count, %opts) = @_;
80 my (%ports, $peer);
81
82 $peer = $opts{peer};
83
84 for (1 .. $count) {
85 if (stream_get($data, $peer) =~ /(\d+)/) {
86 $ports{$1} = 0 unless defined $ports{$1};
87 $ports{$1}++;
88 }
89 }
90
91 return join ', ', map { $_ . ": " . $ports{$_} } sort keys %ports;
92 }
93
94 sub stream_get {
95 my ($data, $peer) = @_;
96
97 my $s = stream_connect($peer);
98 stream_write($s, $data);
99
100 $data = '';
101 while (my $buf = stream_read($s)) {
102 $data .= $buf;
103 }
104 return $data;
105 }
106
107 sub stream_connect {
108 my $peer = shift;
109 my $s = IO::Socket::INET->new(
110 Proto => 'tcp',
111 PeerAddr => $peer || '127.0.0.1:8080'
112 )
113 or die "Can't connect to nginx: $!\n";
114
115 return $s;
116 }
117
118 sub stream_write {
119 my ($s, $message) = @_;
120
121 local $SIG{PIPE} = 'IGNORE';
122
123 $s->blocking(0);
124 while (IO::Select->new($s)->can_write(1.5)) {
125 my $n = $s->syswrite($message);
126 last unless $n;
127 $message = substr($message, $n);
128 last unless length $message;
129 }
130
131 if (length $message) {
132 $s->close();
133 }
134 }
135
136 sub stream_read {
137 my ($s) = @_;
138 my ($buf);
139
140 $s->blocking(0);
141 if (IO::Select->new($s)->can_read(3)) {
142 $s->sysread($buf, 1024);
143 };
144
145 log_in($buf);
146 return $buf;
147 }
148
149 ###############################################################################
150
151 sub stream_daemon {
152 my ($port) = @_;
153
154 my $server = IO::Socket::INET->new(
155 Proto => 'tcp',
156 LocalAddr => '127.0.0.1',
157 LocalPort => $port,
158 Listen => 5,
159 Reuse => 1
160 )
161 or die "Can't create listening socket: $!\n";
162
163 my $sel = IO::Select->new($server);
164
165 local $SIG{PIPE} = 'IGNORE';
166
167 while (my @ready = $sel->can_read) {
168 foreach my $fh (@ready) {
169 if ($server == $fh) {
170 my $new = $fh->accept;
171 $new->autoflush(1);
172 $sel->add($new);
173
174 } elsif (stream_handle_client($fh)) {
175 $sel->remove($fh);
176 $fh->close;
177 }
178 }
179 }
180 }
181
182 sub stream_handle_client {
183 my ($client) = @_;
184
185 log2c("(new connection $client)");
186
187 $client->sysread(my $buffer, 65536) or return 1;
188
189 log2i("$client $buffer");
190
191 $buffer = $client->sockport();
192
193 log2o("$client $buffer");
194
195 $client->syswrite($buffer);
196
197 return 1;
198 }
199
200 sub log2i { Test::Nginx::log_core('|| <<', @_); }
201 sub log2o { Test::Nginx::log_core('|| >>', @_); }
202 sub log2c { Test::Nginx::log_core('||', @_); }
203
204 ###############################################################################