Mercurial > hg > nginx-tests
comparison upstream_least_conn.t @ 294:71e275487aeb
Tests: upstream least_conn and ip_hash tests.
author | Maxim Dounin <mdounin@mdounin.ru> |
---|---|
date | Sat, 08 Jun 2013 04:10:53 +0400 |
parents | |
children | 86fa2a5a37ea |
comparison
equal
deleted
inserted
replaced
293:719285b89d7e | 294:71e275487aeb |
---|---|
1 #!/usr/bin/perl | |
2 | |
3 # (C) Maxim Dounin | |
4 | |
5 # Tests for upstream least_conn balancer module. | |
6 | |
7 ############################################################################### | |
8 | |
9 use warnings; | |
10 use strict; | |
11 | |
12 use Test::More; | |
13 | |
14 use Socket qw/ CRLF /; | |
15 | |
16 BEGIN { use FindBin; chdir($FindBin::Bin); } | |
17 | |
18 use lib 'lib'; | |
19 use Test::Nginx; | |
20 | |
21 ############################################################################### | |
22 | |
23 select STDERR; $| = 1; | |
24 select STDOUT; $| = 1; | |
25 | |
26 my $t = Test::Nginx->new()->has(qw/http proxy upstream_least_conn/)->plan(2); | |
27 | |
28 $t->write_file_expand('nginx.conf', <<'EOF'); | |
29 | |
30 %%TEST_GLOBALS%% | |
31 | |
32 daemon off; | |
33 | |
34 events { | |
35 } | |
36 | |
37 http { | |
38 %%TEST_GLOBALS_HTTP%% | |
39 | |
40 upstream u { | |
41 least_conn; | |
42 server 127.0.0.1:8081; | |
43 server 127.0.0.1:8082; | |
44 } | |
45 | |
46 server { | |
47 listen 127.0.0.1:8080; | |
48 server_name localhost; | |
49 | |
50 location / { | |
51 proxy_pass http://u; | |
52 } | |
53 } | |
54 } | |
55 | |
56 EOF | |
57 | |
58 $t->run_daemon(\&http_daemon, 8081); | |
59 $t->run_daemon(\&http_daemon, 8082); | |
60 $t->run(); | |
61 | |
62 $t->waitforsocket('127.0.0.1:8081'); | |
63 $t->waitforsocket('127.0.0.1:8082'); | |
64 | |
65 ############################################################################### | |
66 | |
67 is(many('/', 10), '8081: 5, 8082: 5', 'balanced'); | |
68 is(parallel('/w', 10), '8081: 1, 8082: 9', 'least conn'); | |
69 | |
70 ############################################################################### | |
71 | |
72 sub many { | |
73 my ($uri, $count) = @_; | |
74 my %ports; | |
75 | |
76 for (1 .. $count) { | |
77 if (http_get($uri) =~ /X-Port: (\d+)/) { | |
78 $ports{$1} = 0 unless defined $ports{$1}; | |
79 $ports{$1}++; | |
80 } | |
81 } | |
82 | |
83 return join ', ', map { $_ . ": " . $ports{$_} } sort keys %ports; | |
84 } | |
85 | |
86 sub parallel { | |
87 my ($uri, $count, %opts) = @_; | |
88 my (@sockets, %ports); | |
89 | |
90 for (1 .. $count) { | |
91 push(@sockets, http_start($uri)); | |
92 select undef, undef, undef, 0.1; | |
93 } | |
94 | |
95 for (1 .. $count) { | |
96 if (http_end(pop(@sockets)) =~ /X-Port: (\d+)/) { | |
97 $ports{$1} = 0 unless defined $ports{$1}; | |
98 $ports{$1}++; | |
99 } | |
100 } | |
101 | |
102 return join ', ', map { $_ . ": " . $ports{$_} } sort keys %ports; | |
103 } | |
104 | |
105 sub http_start { | |
106 my ($uri) = @_; | |
107 | |
108 my $s; | |
109 my $request = "GET $uri HTTP/1.0" . CRLF . CRLF; | |
110 | |
111 eval { | |
112 local $SIG{ALRM} = sub { die "timeout\n" }; | |
113 local $SIG{PIPE} = sub { die "sigpipe\n" }; | |
114 alarm(3); | |
115 $s = IO::Socket::INET->new( | |
116 Proto => 'tcp', | |
117 PeerAddr => '127.0.0.1:8080' | |
118 ); | |
119 log_out($request); | |
120 $s->print($request); | |
121 alarm(0); | |
122 }; | |
123 alarm(0); | |
124 if ($@) { | |
125 log_in("died: $@"); | |
126 return undef; | |
127 } | |
128 return $s; | |
129 } | |
130 | |
131 sub http_end { | |
132 my ($s) = @_; | |
133 my $reply; | |
134 | |
135 eval { | |
136 local $SIG{ALRM} = sub { die "timeout\n" }; | |
137 local $SIG{PIPE} = sub { die "sigpipe\n" }; | |
138 alarm(3); | |
139 local $/; | |
140 $reply = $s->getline(); | |
141 log_in($reply); | |
142 alarm(0); | |
143 }; | |
144 alarm(0); | |
145 if ($@) { | |
146 log_in("died: $@"); | |
147 return undef; | |
148 } | |
149 return $reply; | |
150 } | |
151 | |
152 ############################################################################### | |
153 | |
154 sub http_daemon { | |
155 my ($port) = @_; | |
156 | |
157 my $server = IO::Socket::INET->new( | |
158 Proto => 'tcp', | |
159 LocalHost => '127.0.0.1', | |
160 LocalPort => $port, | |
161 Listen => 5, | |
162 Reuse => 1 | |
163 ) | |
164 or die "Can't create listening socket: $!\n"; | |
165 | |
166 local $SIG{PIPE} = 'IGNORE'; | |
167 | |
168 while (my $client = $server->accept()) { | |
169 $client->autoflush(1); | |
170 | |
171 my $headers = ''; | |
172 my $uri = ''; | |
173 | |
174 while (<$client>) { | |
175 $headers .= $_; | |
176 last if (/^\x0d?\x0a?$/); | |
177 } | |
178 | |
179 $uri = $1 if $headers =~ /^\S+\s+([^ ]+)\s+HTTP/i; | |
180 | |
181 if ($uri eq '/w' && $port == 8081) { | |
182 Test::Nginx::log_core('||', "$port: sleep(1.5)"); | |
183 select undef, undef, undef, 1.5; | |
184 } | |
185 | |
186 Test::Nginx::log_core('||', "$port: response, 200"); | |
187 print $client <<EOF; | |
188 HTTP/1.1 200 OK | |
189 Connection: close | |
190 X-Port: $port | |
191 | |
192 OK | |
193 EOF | |
194 | |
195 close $client; | |
196 } | |
197 } | |
198 | |
199 ############################################################################### |