1NAME 2 Test::Nginx - Testing modules for Nginx C module development 3 4DESCRIPTION 5 This distribution provides two testing modules for Nginx C module 6 development: 7 8 * Test::Nginx::LWP 9 10 * Test::Nginx::Socket 11 12 All of them are based on Test::Base. 13 14 Usually, Test::Nginx::Socket is preferred because it works on a much 15 lower level and not that fault tolerant like Test::Nginx::LWP. 16 17 Also, a lot of connection hang issues (like wrong "r->main->count" value 18 in nginx 0.8.x) can only be captured by Test::Nginx::Socket because 19 Perl's LWP::UserAgent client will close the connection itself which will 20 conceal such issues from the testers. 21 22 Test::Nginx automatically starts an nginx instance (from the "PATH" env) 23 rooted at t/servroot/ and the default config template makes this nginx 24 instance listen on the port 1984 by default. One can specify a different 25 port number by setting his port number to the "TEST_NGINX_PORT" 26 environment, as in 27 28 export TEST_NGINX_PORT=1989 29 30 etcproxy integration 31 The default settings in etcproxy 32 (https://github.com/chaoslawful/etcproxy) makes this small TCP proxy 33 split the TCP packets into bytes and introduce 1 ms latency among them. 34 35 There's usually various TCP chains that we can put etcproxy into, for 36 example 37 38 Test::Nginx <=> nginx 39 $ ./etcproxy 1234 1984 40 41 Here we tell etcproxy to listen on port 1234 and to delegate all the TCP 42 traffic to the port 1984, the default port that Test::Nginx makes nginx 43 listen to. 44 45 And then we tell Test::Nginx to test against the port 1234, where 46 etcproxy listens on, rather than the port 1984 that nginx directly 47 listens on: 48 49 $ TEST_NGINX_CLIENT_PORT=1234 prove -r t/ 50 51 Then the TCP chain now looks like this: 52 53 Test::Nginx <=> etcproxy (1234) <=> nginx (1984) 54 55 So etcproxy can effectively emulate extreme network conditions and 56 exercise "unusual" code paths in your nginx server by your tests. 57 58 In practice, *tons* of weird bugs can be captured by this setting. Even 59 ourselves didn't expect that this simple approach is so effective. 60 61 nginx <=> memcached 62 We first start the memcached server daemon on port 11211: 63 64 memcached -p 11211 -vv 65 66 and then we another etcproxy instance to listen on port 11984 like this 67 68 $ ./etcproxy 11984 11211 69 70 Then we tell our t/foo.t test script to connect to 11984 rather than 71 11211: 72 73 # foo.t 74 use Test::Nginx::Socket; 75 repeat_each(1); 76 plan tests => 2 * repeat_each() * blocks(); 77 $ENV{TEST_NGINX_MEMCACHED_PORT} ||= 11211; # make this env take a default value 78 run_tests(); 79 80 __DATA__ 81 82 === TEST 1: sanity 83 --- config 84 location /foo { 85 set $memc_cmd set; 86 set $memc_key foo; 87 set $memc_value bar; 88 memc_pass 127.0.0.1:$TEST_NGINX_MEMCACHED_PORT; 89 } 90 --- request 91 GET /foo 92 --- response_body_like: STORED 93 94 The Test::Nginx library will automatically expand the special macro 95 $TEST_NGINX_MEMCACHED_PORT to the environment with the same name. You 96 can define your own $TEST_NGINX_BLAH_BLAH_PORT macros as long as its 97 prefix is "TEST_NGINX_" and all in upper case letters. 98 99 And now we can run your test script against the etcproxy port 11984: 100 101 TEST_NGINX_MEMCACHED_PORT=11984 prove t/foo.t 102 103 Then the TCP chains look like this: 104 105 Test::Nginx <=> nginx (1984) <=> etcproxy (11984) <=> memcached (11211) 106 107 If "TEST_NGINX_MEMCACHED_PORT" is not set, then it will take the default 108 value 11211, which is what we want when there's no etcproxy configured: 109 110 Test::Nginx <=> nginx (1984) <=> memcached (11211) 111 112 This approach also works for proxied mysql and postgres traffic. Please 113 see the live test suite of ngx_drizzle and ngx_postgres for more 114 details. 115 116 Usually we set both "TEST_NGINX_CLIENT_PORT" and 117 "TEST_NGINX_MEMCACHED_PORT" (and etc) at the same time, effectively 118 yielding the following chain: 119 120 Test::Nginx <=> etcproxy (1234) <=> nginx (1984) <=> etcproxy (11984) <=> memcached (11211) 121 122 as long as you run two separate etcproxy instances in two separate 123 terminals. 124 125 It's easy to verify if the traffic actually goes through your etcproxy 126 server. Just check if the terminal running etcproxy emits outputs. By 127 default, etcproxy always dump out the incoming and outgoing data to 128 stdout/stderr. 129 130 valgrind integration 131 Test::Nginx has integrated support for valgrind (<http://valgrind.org>) 132 even though by default it does not bother running it with the tests 133 because valgrind will significantly slow down the test sutie. 134 135 First ensure that your valgrind executable visible in your PATH env. And 136 then run your test suite with the "TEST_NGINX_USE_VALGRIND" env set to 137 true: 138 139 TEST_NGINX_USE_VALGRIND=1 prove -r t 140 141 If you see false alarms, you do have a chance to skip them by defining a 142 ./valgrind.suppress file at the root of your module source tree, as in 143 144 <https://github.com/chaoslawful/drizzle-nginx-module/blob/master/valgrin 145 d.suppress> 146 147 This is the suppression file for ngx_drizzle. Test::Nginx will 148 automatically use it to start nginx with valgrind memcheck if this file 149 does exist at the expected location. 150 151 If you do see a lot of "Connection refused" errors while running the 152 tests this way, then you probably have a slow machine (or a very busy 153 one) that the default waiting time is not sufficient for valgrind to 154 start. You can define the sleep time to a larger value by setting the 155 "TEST_NGINX_SLEEP" env: 156 157 TEST_NGINX_SLEEP=1 prove -r t 158 159 The time unit used here is "second". The default sleep setting just fits 160 my ThinkPad ("Core2Duo T9600"). 161 162 Applying the no-pool patch to your nginx core is recommended while 163 running nginx with valgrind: 164 165 <https://github.com/shrimp/no-pool-nginx> 166 167 The nginx memory pool can prevent valgrind from spotting lots of invalid 168 memory reads/writes as well as certain double-free errors. We did find a 169 lot more memory issues in many of our modules when we first introduced 170 the no-pool patch in practice ;) 171 172 There's also more advanced features in Test::Nginx that have never 173 documented. I'd like to write more about them in the near future ;) 174 175Nginx C modules that use Test::Nginx to drive their test suites 176 ngx_echo 177 <http://github.com/agentzh/echo-nginx-module> 178 179 ngx_headers_more 180 <http://github.com/agentzh/headers-more-nginx-module> 181 182 ngx_chunkin 183 <http://wiki.nginx.org/NginxHttpChunkinModule> 184 185 ngx_memc 186 <http://wiki.nginx.org/NginxHttpMemcModule> 187 188 ngx_drizzle 189 <http://github.com/chaoslawful/drizzle-nginx-module> 190 191 ngx_rds_json 192 <http://github.com/agentzh/rds-json-nginx-module> 193 194 ngx_xss 195 <http://github.com/agentzh/xss-nginx-module> 196 197 ngx_srcache 198 <http://github.com/agentzh/srcache-nginx-module> 199 200 ngx_lua 201 <http://github.com/chaoslawful/lua-nginx-module> 202 203 ngx_set_misc 204 <http://github.com/agentzh/set-misc-nginx-module> 205 206 ngx_array_var 207 <http://github.com/agentzh/array-var-nginx-module> 208 209 ngx_form_input 210 <http://github.com/calio/form-input-nginx-module> 211 212 ngx_iconv 213 <http://github.com/calio/iconv-nginx-module> 214 215 ngx_set_cconv 216 <http://github.com/liseen/set-cconv-nginx-module> 217 218 ngx_postgres 219 <http://github.com/FRiCKLE/ngx_postgres> 220 221 ngx_coolkit 222 <http://github.com/FRiCKLE/ngx_coolkit> 223 224SOURCE REPOSITORY 225 This module has a Git repository on Github, which has access for all. 226 227 http://github.com/agentzh/test-nginx 228 229 If you want a commit bit, feel free to drop me a line. 230 231AUTHORS 232 agentzh (章亦春) "<agentzh@gmail.com>" 233 234 Antoine BONAVITA "<antoine.bonavita@gmail.com>" 235 236COPYRIGHT & LICENSE 237 Copyright (c) 2009-2011, Taobao Inc., Alibaba Group 238 (<http://www.taobao.com>). 239 240 Copyright (c) 2009-2011, agentzh "<agentzh@gmail.com>". 241 242 Copyright (c) 2011, Antoine Bonavita "<antoine.bonavita@gmail.com>". 243 244 This module is licensed under the terms of the BSD license. 245 246 Redistribution and use in source and binary forms, with or without 247 modification, are permitted provided that the following conditions are 248 met: 249 250 * Redistributions of source code must retain the above copyright 251 notice, this list of conditions and the following disclaimer. 252 253 * Redistributions in binary form must reproduce the above copyright 254 notice, this list of conditions and the following disclaimer in the 255 documentation and/or other materials provided with the distribution. 256 257 * Neither the name of the Taobao Inc. nor the names of its 258 contributors may be used to endorse or promote products derived from 259 this software without specific prior written permission. 260 261 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 262 IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 263 TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 264 PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 265 HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 266 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 267 TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 268 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 269 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 270 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 271 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 272 273SEE ALSO 274 Test::Nginx::LWP, Test::Nginx::Socket, Test::Base. 275 276