1function mcp_config_pools(oldss) 2 local srv = mcp.backend 3 mcp.backend_read_timeout(0.5) 4 mcp.backend_connect_timeout(5) 5 mcp.backend_retry_timeout(5) 6 7 -- Single backend for zones to ease testing. 8 -- For purposes of this config the proxy is always "zone 1" (z1) 9 local b1 = srv('b1', '127.0.0.1', 11411) 10 local b2 = srv('b2', '127.0.0.1', 11412) 11 local b3 = srv('b3', '127.0.0.1', 11413) 12 13 local b1z = {b1} 14 local b2z = {b2} 15 local b3z = {b3} 16 17 local dead = srv('dead', '127.9.9.9', 11011); 18 19 local no_label = srv('', '127.0.0.1', 11414) 20 21 -- convert the backends to pools. 22 -- as per a normal full config see simple.lua or t/startfile.lua 23 local zones = { 24 z1 = mcp.pool(b1z), 25 z2 = mcp.pool(b2z), 26 z3 = mcp.pool(b3z), 27 dead = mcp.pool({dead}), 28 no_label = mcp.pool({no_label}) 29 } 30 31 return zones 32end 33 34-- WORKER CODE: 35function new_basic(zones, func) 36 local fgen = mcp.funcgen_new() 37 local o = { t = {}, c = 0 } 38 39 o.t.z1 = fgen:new_handle(zones.z1) 40 o.t.z2 = fgen:new_handle(zones.z2) 41 o.t.z3 = fgen:new_handle(zones.z3) 42 o.t.dead = fgen:new_handle(zones.dead) 43 o.t.no_label = fgen:new_handle(zones.no_label) 44 45 fgen:ready({ f = func, a = o}) 46 return fgen 47end 48 49-- Do specialized testing based on the key prefix. 50function mcp_config_routes(zones) 51 local map = {} 52 53 map.b = new_basic(zones, function(rctx, a) 54 return function(r) 55 return rctx:enqueue_and_wait(r, a.t.z1) 56 end 57 end) 58 59 map.errcheck = new_basic(zones, function(rctx, a) 60 return function(r) 61 local res = rctx:enqueue_and_wait(r, a.t.z1) 62 -- expect an error 63 if res:ok() then 64 return "FAIL\r\n" 65 end 66 if res:code() == mcp.MCMC_CODE_ERROR then 67 return "ERROR\r\n" 68 elseif res:code() == mcp.MCMC_CODE_CLIENT_ERROR then 69 return "CLIENT_ERROR\r\n" 70 elseif res:code() == mcp.MCMC_CODE_SERVER_ERROR then 71 return "SERVER_ERROR\r\n" 72 end 73 return "FAIL" 74 end 75 end) 76 77 -- show that we fetched the key by generating our own response string. 78 map.getkey = new_basic(zones, function(rctx, a) 79 return function(r) 80 return "VALUE |" .. r:key() .. " 0 2\r\nts\r\nEND\r\n" 81 end 82 end) 83 84 map.rtrimkey = new_basic(zones, function(rctx, a) 85 return function(r) 86 r:rtrimkey(4) 87 return rctx:enqueue_and_wait(r, a.t.z1) 88 end 89 end) 90 91 map.ltrimkey = new_basic(zones, function(rctx, a) 92 return function(r) 93 r:ltrimkey(10) 94 return rctx:enqueue_and_wait(r, a.t.z1) 95 end 96 end) 97 98 map.nolabel = new_basic(zones, function(rctx, a) 99 return function(r) 100 return rctx:enqueue_and_wait(r, a.t.no_label) 101 end 102 end) 103 104 map.ntokens = new_basic(zones, function(rctx, a) 105 return function(r) 106 return "VA 1 C123 v\r\n" .. r:ntokens() .. "\r\n" 107 end 108 end) 109 110 map.hasflag = { 111 [mcp.CMD_MG] = new_basic(zones, function(rctx, a) 112 return function(r) 113 if r:has_flag("c") then 114 return "HD C123\r\n" 115 elseif r:has_flag("O") then 116 return "HD Oabc\r\n" 117 end 118 return "NF\r\n" 119 end 120 end), 121 [mcp.CMD_GET] = new_basic(zones, function(rctx, a) 122 return function(r) 123 if r:has_flag("F") then 124 return "ERROR flag found\r\n" 125 end 126 return "END\r\n" 127 end 128 end) 129 } 130 131 -- Input flags: N10 k c R10 132 -- Output flags: N100 k R100 133 map.flagtoken = new_basic(zones, function(rctx, a) 134 return function(r) 135 -- flag_token on non-existing flags: no effect 136 local Ttoken = r:flag_token("T", "T100") 137 local Otoken = r:flag_token("O", nil) 138 local vtoken = r:flag_token("v", "") 139 if vtoken or Otoken or Ttoken then 140 return "ERROR found non-existing flag.\r\n" 141 end 142 143 -- flag_token to replace: N10 -> N100 144 local found, Ntoken = r:flag_token("N", "N100") 145 if not found or Ntoken ~= "10" then 146 return "ERROR unexpected N token.\r\n" 147 end 148 149 -- flag_token with nil 2nd arg: equvalent to fetch 150 r:flag_token("k", nil) 151 if not r:has_flag("k") then 152 return "ERROR unexpected k token.\r\n" 153 end 154 155 -- flag_token with self 2nd arg: no effect 156 r:flag_token("c", "c") 157 if not r:has_flag("c") then 158 return "ERROR unexpected c token 1.\r\n" 159 end 160 161 -- flag_token with "" 2nd arg: remove 162 r:flag_token("c", "") 163 if r:has_flag("c") then 164 return "ERROR unexpected c token 2.\r\n" 165 end 166 167 -- repeated flag_token calls: new value is returned. 168 local _, Rtoken = r:flag_token("R", "R100") 169 if Rtoken ~= '10' then 170 return "ERROR unexpected R token 1.\r\n" 171 end 172 _, Rtoken = r:flag_token("R", "R100") 173 if Rtoken ~= '100' then 174 return "ERROR unexpected R token 2.\r\n" 175 end 176 177 return "HD\r\n" 178 end 179 end) 180 181 map.request = { 182 [mcp.CMD_MS] = new_basic(zones, function(rctx, a) 183 return function(r) 184 local key = r:key() 185 local newReq = mcp.request("ms /request/edit 2\r\n", "ab\r\n") 186 return rctx:enqueue_and_wait(newReq, a.t.z1) 187 end 188 end), 189 [mcp.CMD_MG] = new_basic(zones, function(rctx, a) 190 return function(r) 191 local key = r:key() 192 if key == "/request/old" then 193 local newReq = mcp.request("mg /request/new c\r\n") 194 return rctx:enqueue_and_wait(newReq, a.t.z1) 195 else 196 local res = rctx:enqueue_and_wait(r, a.t.z1) 197 local newReq = mcp.request("ms /request/a " .. res:vlen() .. "\r\n", res) 198 return rctx:enqueue_and_wait(newReq, a.t.z2) 199 end 200 end 201 end) 202 } 203 204 map.response = { 205 [mcp.CMD_GET] = new_basic(zones, function(rctx, a) 206 return function(r) 207 local res = rctx:enqueue_and_wait(r, a.t.z1) 208 local key = r:key() 209 if key == "/response/hit" then 210 local hit = res:hit() 211 if hit then 212 return res 213 end 214 return "ERROR hit is false\r\n" 215 elseif key == "/response/not_hit" then 216 local hit = res:hit() 217 if not hit then 218 return "SERVER_ERROR\r\n" 219 end 220 return res 221 end 222 return "ERROR unhandled key\r\n" 223 224 end 225 end), 226 [mcp.CMD_MG] = new_basic(zones, function(rctx, a) 227 return function(r) 228 local res = rctx:enqueue_and_wait(r, a.t.z1) 229 local key = r:key() 230 if key == "/response/elapsed" then 231 local elapsed = res:elapsed() 232 if elapsed > 100000 then 233 return res 234 end 235 return "ERROR elapsed is invalid.\r\n" 236 elseif key == "/response/ok" then 237 local ok = res:ok() 238 if ok then 239 return res 240 end 241 return "ERROR ok is false\r\n" 242 elseif key == "/response/not_ok" then 243 local ok = res:ok() 244 if not ok then 245 return "SERVER_ERROR\r\n" 246 end 247 return "HD\r\n" 248 elseif key == "/response/hit" then 249 local hit = res:hit() 250 if hit then 251 return res 252 end 253 return "ERROR hit is false\r\n" 254 elseif key == "/response/not_hit" then 255 local hit = res:hit() 256 if not hit then 257 return "SERVER_ERROR\r\n" 258 end 259 return "HD\r\n" 260 elseif key == "/response/vlen" then 261 local vlen = res:vlen() 262 if vlen == 1 then 263 return res 264 end 265 return "ERROR vlen is not 1\r\n" 266 elseif key == "/response/code_ok" then 267 local code = res:code() 268 if code == mcp.MCMC_CODE_OK then 269 return res 270 end 271 return "ERROR expect MCMC_CODE_OK, but got " .. code .. "\r\n" 272 elseif key == "/response/code_miss" then 273 local code = res:code() 274 if code == mcp.MCMC_CODE_END then 275 return res 276 end 277 return "ERROR expect MCMC_CODE_END, but got " .. code .. "\r\n" 278 elseif key == "/response/line" then 279 local line = res:line() 280 if line == "v c123" then 281 return res 282 end 283 return "ERROR unexpected line, got [" .. line .. "]\r\n" 284 elseif key == "/response/blank" then 285 res:flag_blank("O") 286 return res 287 end 288 return "ERROR unhandled key\r\n" 289 290 end 291 end), 292 [mcp.CMD_MS] = new_basic(zones, function(rctx, a) 293 return function(r) 294 local key = r:key() 295 local res = rctx:enqueue_and_wait(r, a.t.z1) 296 local code = res:code() 297 298 if key == "/response/code_ok" then 299 if code == mcp.MCMC_CODE_OK then 300 return res 301 end 302 return "ERROR expect MCMC_CODE_OK, but got " .. code .. "\r\n" 303 elseif key == "/response/line" then 304 local line = res:line() 305 if line == "O123 C123" then 306 return res 307 end 308 return "ERROR unexpected line, got [" .. line .. "]\r\n" 309 end 310 return "ERROR unhandled key\r\n" 311 end 312 end), 313 [mcp.CMD_SET] = new_basic(zones, function(rctx, a) 314 return function(r) 315 local res = rctx:enqueue_and_wait(r, a.t.z1) 316 local key = r:key() 317 if key == "/response/code_stored" then 318 local code = res:code() 319 if code == mcp.MCMC_CODE_STORED then 320 return res 321 end 322 return "ERROR expect MCMC_CODE_STORED, but got " .. code .. "\r\n" 323 elseif key == "/response/code_exists" then 324 local code = res:code() 325 if code == mcp.MCMC_CODE_EXISTS then 326 return res 327 end 328 return "ERROR expect MCMC_CODE_EXISTS, but got " .. code .. "\r\n" 329 elseif key == "/response/code_not_stored" then 330 local code = res:code() 331 if code == mcp.MCMC_CODE_NOT_STORED then 332 return res 333 end 334 return "ERROR expect MCMC_CODE_NOT_STORED, but got " .. code .. "\r\n" 335 elseif key == "/response/code_not_found" then 336 local code = res:code() 337 if code == mcp.MCMC_CODE_NOT_FOUND then 338 return res 339 end 340 return "ERROR expect MCMC_CODE_NOT_FOUND, but got " .. code .. "\r\n" 341 end 342 return "ERROR unhandled key\r\n" 343 end 344 end), 345 [mcp.CMD_TOUCH] = new_basic(zones, function(rctx, a) 346 return function(r) 347 local res = rctx:enqueue_and_wait(r, a.t.z1) 348 local key = r:key() 349 local code = res:code() 350 if code == mcp.MCMC_CODE_TOUCHED then 351 return res 352 end 353 return "ERROR expect MCMC_CODE_TOUCHED, but got " .. code .. "\r\n" 354 end 355 end), 356 [mcp.CMD_DELETE] = new_basic(zones, function(rctx, a) 357 return function(r) 358 local res = rctx:enqueue_and_wait(r, a.t.z1) 359 local key = r:key() 360 local code = res:code() 361 if code == mcp.MCMC_CODE_DELETED then 362 return res 363 end 364 return "ERROR expect MCMC_CODE_DELETED, but got " .. code .. "\r\n" 365 end 366 end), 367 } 368 369 map.token = new_basic(zones, function(rctx, a) 370 return function(r) 371 local key = r:key() 372 if key == "/token/replacement" then 373 r:token(4, "C456") 374 elseif key == "/token/removal" then 375 r:token(4, "") 376 else 377 local token = r:token(2) 378 r:flag_token("P", "P" .. token) 379 end 380 return rctx:enqueue_and_wait(r, a.t.z1) 381 end 382 end) 383 384 map.zonetest = new_basic(zones, function(rctx, a) 385 return function(r) 386 local key = r:key() 387 if key == "/zonetest/a" then 388 return rctx:enqueue_and_wait(r, a.t.z1) 389 elseif key == "/zonetest/b" then 390 return rctx:enqueue_and_wait(r, a.t.z2) 391 elseif key == "/zonetest/c" then 392 return rctx:enqueue_and_wait(r, a.t.z3) 393 else 394 return "END\r\n" 395 end 396 end 397 end) 398 399 map.logtest = new_basic(zones, function(rctx, a) 400 return function(r) 401 mcp.log("testing manual log messages") 402 return "END\r\n" 403 end 404 end) 405 406 map.logreqtest = new_basic(zones, function(rctx, a) 407 return function(r) 408 local res = rctx:enqueue_and_wait(r, a.t.z1) 409 mcp.log_req(r, res, "logreqtest") 410 return res 411 end 412 end) 413 414 map.logreqstest = new_basic(zones, function(rctx, a) 415 return function(r) 416 local res = rctx:enqueue_and_wait(r, a.t.z1) 417 mcp.log_reqsample(150, 0, true, r, res, "logsampletest") 418 return res 419 end 420 end) 421 422 map.sanity = new_basic(zones, function(rctx, a) 423 local z = {a.t.z1, a.t.z2, a.t.z3} 424 return function(r) 425 rctx:enqueue(r, z) 426 rctx:wait_cond(3) 427 return rctx:result(a.t.z3) 428 end 429 end) 430 431 map.dead = new_basic(zones, function(rctx, a) 432 return function(r) 433 return rctx:enqueue_and_wait(r, a.t.dead) 434 end 435 end) 436 437 map.deadrespcode = new_basic(zones, function(rctx, a) 438 return function(r) 439 local res = rctx:enqueue_and_wait(r, a.t.dead) 440 if res:code() == mcp.MCMC_CODE_SERVER_ERROR then 441 return "ERROR code_correct\r\n" 442 end 443 return "ERROR code_incorrect: " .. res:code() .. "\r\n" 444 end 445 end) 446 447 map.millis = new_basic(zones, function(rctx, a) 448 return function(r) 449 local time = mcp.time_real_millis() 450 return "HD t" .. time .. "\r\n" 451 end 452 end) 453 454 local def_fg = mcp.funcgen_new() 455 def_fg:ready({ 456 f = function(rctx) 457 return function(r) 458 return "SERVER_ERROR no set route\r\n" 459 end 460 end 461 }) 462 463 mcp.attach(mcp.CMD_ANY_STORAGE, mcp.router_new({ 464 map = map, mode = "anchor", start = "/", stop = "/", default = def_fg 465 })) 466end 467