| # Licensed to the Apache Software Foundation (ASF) under one |
| # or more contributor license agreements. See the NOTICE file |
| # distributed with this work for additional information |
| # regarding copyright ownership. The ASF licenses this file |
| # to you under the Apache License, Version 2.0 (the |
| # "License"); you may not use this file except in compliance |
| # with the License. You may obtain a copy of the License at |
| # |
| # http://www.apache.org/licenses/LICENSE-2.0 |
| # |
| # Unless required by applicable law or agreed to in writing, |
| # software distributed under the License is distributed on an |
| # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| # KIND, either express or implied. See the License for the |
| # specific language governing permissions and limitations |
| # under the License. |
| BEGIN { |
| if ($ENV{TEST_EVENTS_MODULE} ne "lua-resty-events") { |
| $SkipReason = "Only for lua-resty-events events module"; |
| } |
| } |
| use Test::Nginx::Socket::Lua $SkipReason ? (skip_all => $SkipReason) : (); |
| use t::APISIX 'no_plan'; |
| |
| log_level('info'); |
| no_root_location(); |
| |
| run_tests(); |
| |
| __DATA__ |
| |
| === TEST 1: create stream route with a upstream that enable active healthcheck only, \ |
| two upstream nodes: one healthy + one unhealthy, unhealthy node with high priority |
| --- config |
| location /t { |
| content_by_lua_block { |
| local t = require("lib.test_admin").test |
| local code, body = t('/apisix/admin/stream_routes/1', |
| ngx.HTTP_PUT, |
| [[{ |
| "remote_addr": "127.0.0.1", |
| "upstream": { |
| "nodes": [ |
| { "host": "127.0.0.1", "port": 1995, "weight": 100, "priority": 0 }, |
| { "host": "127.0.0.1", "port": 9995, "weight": 100, "priority": 1 } |
| ], |
| "type": "roundrobin", |
| "retries": 0, |
| "checks": { |
| "active": { |
| "type": "tcp", |
| "timeout": 1, |
| "healthy": { |
| "interval": 1, |
| "successes": 2 |
| }, |
| "unhealthy": { |
| "interval": 1, |
| "tcp_failures": 1, |
| "timeouts": 1 |
| } |
| } |
| } |
| } |
| }]] |
| ) |
| if code >= 300 then |
| ngx.status = code |
| end |
| ngx.say(body) |
| } |
| } |
| --- request |
| GET /t |
| --- response_body |
| passed |
| |
| |
| |
| === TEST 2: hit stream routes |
| --- stream_conf_enable |
| --- config |
| location /t { |
| content_by_lua_block { |
| -- send first request to create health checker |
| local sock = ngx.socket.tcp() |
| local ok, err = sock:connect("127.0.0.1", 1985) |
| if not ok then |
| ngx.say("failed to connect: ", err) |
| return |
| end |
| local data, _ = sock:receive() |
| assert(data == nil, "first request should fail") |
| sock:close() |
| |
| -- wait for health check to take effect |
| ngx.sleep(10) |
| |
| for i = 1, 3 do |
| local sock = ngx.socket.tcp() |
| local ok, err = sock:connect("127.0.0.1", 1985) |
| if not ok then |
| ngx.say("failed to connect: ", err) |
| return |
| end |
| |
| local _, err = sock:send("mmm") |
| if err then |
| ngx.say("failed to send: ", err) |
| return |
| end |
| |
| local data, err = sock:receive() |
| if err then |
| ngx.say("failed to receive: ", err) |
| return |
| end |
| |
| assert(data == "hello world", "response should be 'hello world'") |
| |
| sock:close() |
| end |
| |
| local t = require("lib.test_admin").test |
| local code, body = t('/apisix/admin/stream_routes/1', |
| ngx.HTTP_DELETE |
| ) |
| |
| if code >= 300 then |
| ngx.status = code |
| ngs.say("failed to delete stream route") |
| return |
| end |
| |
| -- wait for checker to release |
| ngx.sleep(3) |
| |
| ngx.say("passed") |
| } |
| } |
| --- timeout: 15 |
| --- request |
| GET /t |
| --- response_body |
| passed |
| --- error_log |
| create new checker |
| proxy request to 127.0.0.1:9995 while connecting to upstream |
| connect() failed (111: Connection refused) while connecting to upstream, client: 127.0.0.1, server: 0.0.0.0:1985, upstream: "127.0.0.1:9995" |
| unhealthy TCP increment (1/1) for '127.0.0.1(127.0.0.1:9995)' |
| proxy request to 127.0.0.1:1995 while connecting to upstream |
| proxy request to 127.0.0.1:1995 while connecting to upstream |
| proxy request to 127.0.0.1:1995 while connecting to upstream |
| try to release checker |
| |
| |
| |
| === TEST 3: create stream route with a upstream that enable active and passive healthcheck, \ |
| configure active healthcheck with a high unhealthy threshold, \ |
| two upstream nodes: one healthy + one unhealthy, unhealthy node with high priority |
| --- config |
| location /t { |
| content_by_lua_block { |
| local t = require("lib.test_admin").test |
| local code, body = t('/apisix/admin/stream_routes/1', |
| ngx.HTTP_PUT, |
| [[{ |
| "remote_addr": "127.0.0.1", |
| "upstream": { |
| "nodes": [ |
| { "host": "127.0.0.1", "port": 1995, "weight": 100, "priority": 0 }, |
| { "host": "127.0.0.1", "port": 9995, "weight": 100, "priority": 1 } |
| ], |
| "type": "roundrobin", |
| "retries": 0, |
| "checks": { |
| "active": { |
| "type": "tcp", |
| "timeout": 1, |
| "healthy": { |
| "interval": 60, |
| "successes": 2 |
| }, |
| "unhealthy": { |
| "interval": 1, |
| "tcp_failures": 254, |
| "timeouts": 1 |
| } |
| }, |
| "passive": { |
| "type": "tcp", |
| "healthy": { |
| "successes": 1 |
| }, |
| "unhealthy": { |
| "tcp_failures": 1 |
| } |
| } |
| } |
| } |
| }]] |
| ) |
| if code >= 300 then |
| ngx.status = code |
| end |
| ngx.say(body) |
| } |
| } |
| --- request |
| GET /t |
| --- response_body |
| passed |
| |
| |
| |
| === TEST 4: hit stream routes |
| --- stream_conf_enable |
| --- config |
| location /t { |
| content_by_lua_block { |
| local sock = ngx.socket.tcp() |
| local ok, err = sock:connect("127.0.0.1", 1985) |
| if not ok then |
| ngx.say("failed to connect: ", err) |
| return |
| end |
| local data, _ = sock:receive() |
| assert(data == nil, "first request should fail") |
| sock:close() |
| ngx.sleep(8) |
| -- Due to the implementation of lua-resty-events, it relies on the kernel and |
| -- the Nginx event loop to process socket connections. |
| -- When lua-resty-healthcheck handles passive healthchecks and uses lua-resty-events |
| -- as the events module, the synchronization of the first event usually occurs |
| -- before the start of the passive healthcheck. So when the execution finishes and |
| -- healthchecker tries to record the healthcheck status, it will not be able to find |
| -- an existing target (because the synchronization event has not finished yet), which |
| -- will lead to some anomalies that deviate from the original test case, so compatibility |
| -- operations are performed here. |
| local sock = ngx.socket.tcp() |
| local ok, err = sock:connect("127.0.0.1", 1985) |
| if not ok then |
| ngx.say("failed to connect: ", err) |
| return |
| end |
| local data, _ = sock:receive() |
| assert(data == nil, "first request should fail") |
| sock:close() |
| |
| for i = 1, 3 do |
| local sock = ngx.socket.tcp() |
| local ok, err = sock:connect("127.0.0.1", 1985) |
| if not ok then |
| ngx.say("failed to connect: ", err) |
| return |
| end |
| |
| local _, err = sock:send("mmm") |
| if err then |
| ngx.say("failed to send: ", err) |
| return |
| end |
| |
| local data, err = sock:receive() |
| if err then |
| ngx.say("failed to receive: ", err) |
| return |
| end |
| |
| assert(data == "hello world", "response should be 'hello world'") |
| |
| sock:close() |
| end |
| |
| ngx.say("passed") |
| } |
| } |
| --- request |
| GET /t |
| --- response_body |
| passed |
| --- error_log |
| proxy request to 127.0.0.1:9995 while connecting to upstream |
| connect() failed (111: Connection refused) while connecting to upstream, client: 127.0.0.1, server: 0.0.0.0:1985, upstream: "127.0.0.1:9995" |
| enabled healthcheck passive while connecting to upstream, client: 127.0.0.1, server: 0.0.0.0:1985, upstream: "127.0.0.1:9995", |
| unhealthy TCP increment (1/1) for '(127.0.0.1:9995)' while connecting to upstream, client: 127.0.0.1, server: 0.0.0.0:1985, upstream: "127.0.0.1:9995", |
| proxy request to 127.0.0.1:1995 while connecting to upstream |
| proxy request to 127.0.0.1:1995 while connecting to upstream |
| proxy request to 127.0.0.1:1995 while connecting to upstream |
| --- timeout: 10 |