comparison upstream_hash.t @ 411:17c5a1cc8757

Tests: upstream hash tests.
author Sergey Kandaurov <pluknet@nginx.com>
date Tue, 03 Jun 2014 12:09:09 +0400
parents
children 4ceb2d12b7d2
comparison
equal deleted inserted replaced
410:9fe6fc05c1d1 411:17c5a1cc8757
1 #!/usr/bin/perl
2
3 # (C) Sergey Kandaurov
4 # (C) Nginx, Inc.
5
6 # Tests for upstream hash balancer module.
7
8 ###############################################################################
9
10 use warnings;
11 use strict;
12
13 use Test::More;
14
15 BEGIN { use FindBin; chdir($FindBin::Bin); }
16
17 use lib 'lib';
18 use Test::Nginx;
19
20 ###############################################################################
21
22 select STDERR; $| = 1;
23 select STDOUT; $| = 1;
24
25 my $t = Test::Nginx->new()->has(qw/http proxy rewrite upstream_hash/);
26
27 $t->write_file_expand('nginx.conf', <<'EOF');
28
29 %%TEST_GLOBALS%%
30
31 daemon off;
32
33 events {
34 }
35
36 http {
37 %%TEST_GLOBALS_HTTP%%
38
39 upstream u {
40 hash $arg_a;
41 server 127.0.0.1:8081;
42 server 127.0.0.1:8082;
43 server 127.0.0.1:8083;
44 }
45
46 upstream u2 {
47 hash $arg_a;
48 server 127.0.0.1:8081;
49 server 127.0.0.1:8083;
50 }
51
52 upstream cw {
53 hash $arg_a consistent;
54 server 127.0.0.1:8081;
55 server 127.0.0.1:8082;
56 server 127.0.0.1:8083 weight=10;
57 }
58
59 upstream cw2 {
60 hash $arg_a consistent;
61 server 127.0.0.1:8081;
62 server 127.0.0.1:8083 weight=10;
63 }
64
65 upstream c {
66 hash $arg_a consistent;
67 server 127.0.0.1:8081;
68 server 127.0.0.1:8082;
69 server 127.0.0.1:8083;
70 }
71
72 upstream c2 {
73 hash $arg_a consistent;
74 server 127.0.0.1:8081;
75 server 127.0.0.1:8083;
76 }
77
78 upstream bad {
79 hash $arg_a;
80 server 127.0.0.1:8081;
81 server 127.0.0.1:8084;
82 }
83
84 upstream cbad {
85 hash $arg_a consistent;
86 server 127.0.0.1:8081;
87 server 127.0.0.1:8084;
88 }
89
90 server {
91 listen 127.0.0.1:8080;
92 server_name localhost;
93
94 location / {
95 proxy_pass http://u;
96 }
97 location /2 {
98 proxy_pass http://u2;
99 }
100 location /cw {
101 proxy_pass http://cw;
102 }
103 location /cw2 {
104 proxy_pass http://cw2;
105 }
106 location /c {
107 proxy_pass http://c;
108 }
109 location /c2 {
110 proxy_pass http://c2;
111 }
112 location /bad {
113 proxy_pass http://bad;
114 }
115 location /cbad {
116 proxy_pass http://cbad;
117 }
118 location /pnu {
119 proxy_pass http://u/;
120 proxy_next_upstream http_502;
121 }
122 }
123
124 server {
125 listen 127.0.0.1:8081;
126 listen 127.0.0.1:8082;
127 listen 127.0.0.1:8083;
128 server_name localhost;
129
130 add_header X-Port $server_port;
131
132 location / {
133 return 204;
134 }
135
136 location /502 {
137 if ($server_port = 8083) {
138 return 502;
139 }
140 return 204;
141 }
142 }
143 }
144
145 EOF
146
147 $t->try_run('no upstream hash')->plan(11);
148
149 ###############################################################################
150
151 # Ony requests for absent peer are moved to other peers if hash is consistent.
152 # Check this by comparing two upstreams with different number of peers.
153
154 ok(!cmp_peers([iter('/', 20)], [iter('/2', 20)], 8082), 'inconsistent');
155 ok(cmp_peers([iter('/c', 20)], [iter('/c2', 20)], 8082), 'consistent');
156 ok(cmp_peers([iter('/cw', 20)], [iter('/cw2', 20)], 8082), 'consistent weight');
157
158 like(many('/?a=1', 10), qr/808\d: 10/, 'stable hash');
159 like(many('/c?a=1', 10), qr/808\d: 10/, 'stable hash - consistent');
160
161 my @res = iter('/', 10);
162
163 is(@res, 10, 'all hashed peers');
164
165 @res = grep { $_ != 8083 } @res;
166 my @res2 = iter('/502', 10);
167
168 is_deeply(\@res, \@res2, 'no proxy_next_upstream');
169 isnt(@res2, 10, 'no proxy_next_upstream peers');
170
171 is(iter('/pnu/502', 10), 10, 'proxy_next_upstream peers');
172
173 @res = grep { $_ == 8081 } iter('/bad', 20);
174 is(@res, 20, 'all hashed peers - bad');
175
176 @res = grep { $_ == 8081 } iter('/cbad', 20);
177 is(@res, 20, 'all hashed peers - bad consistent');
178
179 ###############################################################################
180
181 # Returns true if two arrays follow consistency, i.e., they may only differ
182 # by @args present in $p, but absent in $p2, for the same indices.
183
184 sub cmp_peers {
185 my ($p, $p2, @args) = @_;
186
187 for my $i (0 .. $#$p) {
188 next if @{$p}[$i] == @{$p2}[$i];
189 next if (grep $_ == @{$p}[$i], @args);
190 return 0;
191 }
192
193 return 1;
194 }
195
196 # series of requests, each with unique hash key
197
198 sub iter {
199 my ($uri, $count) = @_;
200 my @res;
201
202 for my $i (1 .. $count) {
203 if (http_get("$uri/?a=$i") =~ /X-Port: (\d+)/) {
204 push @res, $1 if defined $1;
205 }
206 }
207
208 return @res;
209 }
210
211 sub many {
212 my ($uri, $count) = @_;
213 my %ports;
214
215 for my $i (1 .. $count) {
216 if (http_get($uri) =~ /X-Port: (\d+)/) {
217 $ports{$1} = 0 unless defined $ports{$1};
218 $ports{$1}++;
219 }
220 }
221
222 return join ', ', map { $_ . ": " . $ports{$_} } sort keys %ports;
223 }
224
225 ###############################################################################