Skip to content

Commit

Permalink
feature: added test cases about round-robin load balance algorithms. (#…
Browse files Browse the repository at this point in the history
…123)

* feature: added test cases about round-robin load balance algorithms.

* feature: added test cases about consistent hash algorithms.
  • Loading branch information
membphis authored Jun 17, 2019
1 parent 7b54aaa commit c02d44f
Show file tree
Hide file tree
Showing 9 changed files with 570 additions and 2 deletions.
4 changes: 4 additions & 0 deletions lua/apisix/admin/upstreams.lua
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@ function _M.put(uri_segs, conf)
return 400, {error_msg = "invalid configuration: " .. err}
end

if conf.type == "chash" and not conf.key then
return 400, {error_msg = "missing key"}
end

local key = "/upstreams/" .. id
core.log.info("key: ", key)
local res, err = core.etcd.set(key, conf)
Expand Down
64 changes: 64 additions & 0 deletions lua/apisix/core/schema.lua
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,66 @@ local id_schema = {
}
}

-- todo: chash and roundrobin have different properties, we may support
-- this limitation later.

-- {
-- "definitions": {
-- "nodes": {
-- "patternProperties": {
-- ".*": {
-- "minimum": 1,
-- "type": "integer"
-- }
-- },
-- "minProperties": 1,
-- "type": "object"
-- }
-- },
-- "type": "object",
-- "anyOf": [
-- {
-- "properties": {
-- "type": {
-- "type": "string",
-- "enum": [
-- "roundrobin"
-- ]
-- },
-- "nodes": {
-- "$ref": "#/definitions/nodes"
-- }
-- },
-- "required": [
-- "type",
-- "nodes"
-- ],
-- "additionalProperties": false
-- },
-- {
-- "properties": {
-- "type": {
-- "type": "string",
-- "enum": [
-- "chash"
-- ]
-- },
-- "nodes": {
-- "$ref": "#/definitions/nodes"
-- },
-- "key": {
-- "type": "string"
-- }
-- },
-- "required": [
-- "key",
-- "type",
-- "nodes"
-- ],
-- "additionalProperties": false
-- }
-- ]
-- }

local upstream_schema = {
type = "object",
Expand All @@ -52,6 +112,10 @@ local upstream_schema = {
type = "string",
enum = {"chash", "roundrobin"}
},
key = {
type = "string",
enum = {"remote_addr"},
},
id = id_schema
},
required = {"nodes", "type"},
Expand Down
13 changes: 11 additions & 2 deletions t/APISix.pm
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ use lib 'lib';
use Cwd qw(cwd);
use Test::Nginx::Socket::Lua::Stream -Base;

log_level('info');
no_long_string();
no_shuffle();

my $pwd = cwd();

sub read_file($) {
Expand Down Expand Up @@ -60,11 +64,16 @@ _EOC_
server {
listen 1980;
listen 1981;
listen 1982;
location /hello {
echo "hello world";
location / {
content_by_lua_block {
require("lib.server").go()
}
}
}
_EOC_

$block->set_value("http_config", $http_config);
Expand Down
File renamed without changes.
31 changes: 31 additions & 0 deletions t/admin/upstream.t
Original file line number Diff line number Diff line change
Expand Up @@ -416,6 +416,7 @@ GET /t
local code, body = t('/apisix/admin/upstreams/1',
ngx.HTTP_PUT,
[[{
"key": "remote_addr",
"nodes": {
"127.0.0.1:8080": 1
},
Expand All @@ -424,6 +425,7 @@ GET /t
[[{
"node": {
"value": {
"key": "remote_addr",
"nodes": {
"127.0.0.1:8080": 1
},
Expand Down Expand Up @@ -535,3 +537,32 @@ GET /t
{"error_msg":"invalid configuration: invalid \"patternProperties\" in docuement at pointer \"#\/nodes\/127.0.0.1%3A8080\""}
--- no_error_log
[error]



=== TEST 17: set upstream (missing key)
--- config
location /t {
content_by_lua_block {
local t = require("lib.test_admin").test
local code, body = t('/apisix/admin/upstreams/1',
ngx.HTTP_PUT,
[[{
"nodes": {
"127.0.0.1:8080": 1
},
"type": "chash"
}]]
)

ngx.status = code
ngx.print(body)
}
}
--- request
GET /t
--- error_code: 400
--- response_body
{"error_msg":"missing key"}
--- no_error_log
[error]
24 changes: 24 additions & 0 deletions t/lib/server.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
local _M = {}


function _M.hello()
ngx.say("hello world")
end


function _M.server_port()
ngx.print(ngx.var.server_port)
end


function _M.go()
local action = string.sub(ngx.var.uri, 2)
if not _M[action] then
return ngx.exit(404)
end

return _M[action]()
end


return _M
175 changes: 175 additions & 0 deletions t/node/chash-balance.t
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
BEGIN {
if ($ENV{TEST_NGINX_CHECK_LEAK}) {
$SkipReason = "unavailable for the hup tests";

} else {
$ENV{TEST_NGINX_USE_HUP} = 1;
undef $ENV{TEST_NGINX_USE_STAP};
}
}

use t::APISix 'no_plan';

repeat_each(1);
log_level('info');
no_root_location();
no_shuffle();

run_tests();

__DATA__

=== TEST 1: set route(two upstream node)
--- config
location /t {
content_by_lua_block {
local t = require("lib.test_admin").test
local code, body = t('/apisix/admin/routes/1',
ngx.HTTP_PUT,
[[{
"plugins": {},
"uri": "/server_port",
"upstream": {
"key": "remote_addr",
"type": "chash",
"nodes": {
"127.0.0.1:1980": 1,
"127.0.0.1:1981": 1
}
}
}]]
)

if code >= 300 then
ngx.status = code
end
ngx.say(body)
}
}
--- request
GET /t
--- response_body
passed
--- no_error_log
[error]



=== TEST 2: hit routes
--- config
location /t {
content_by_lua_block {
local http = require "resty.http"
local uri = "http://127.0.0.1:" .. ngx.var.server_port
.. "/server_port"

local ports_count = {}
for i = 1, 12 do
local httpc = http.new()
local res, err = httpc:request_uri(uri, {method = "GET"})
if not res then
ngx.say(err)
return
end
ports_count[res.body] = (ports_count[res.body] or 0) + 1
end

local ports_arr = {}
for port, count in pairs(ports_count) do
table.insert(ports_arr, {port = port, count = count})
end

local function cmd(a, b)
return a.port > b.port
end
table.sort(ports_arr, cmd)

ngx.say(require("cjson").encode(ports_arr))
ngx.exit(200)
}
}
--- request
GET /t
--- response_body
[{"count":12,"port":"1980"}]
--- no_error_log
[error]



=== TEST 3: set route(three upstream node)
--- config
location /t {
content_by_lua_block {
local t = require("lib.test_admin").test
local code, body = t('/apisix/admin/routes/1',
ngx.HTTP_PUT,
[[{
"plugins": {},
"uri": "/server_port",
"upstream": {
"key": "remote_addr",
"type": "chash",
"nodes": {
"127.0.0.1:1980": 1,
"127.0.0.1:1981": 1,
"127.0.0.1:1982": 1
}
}
}]]
)

if code >= 300 then
ngx.status = code
end
ngx.say(body)
}
}
--- request
GET /t
--- response_body
passed
--- no_error_log
[error]



=== TEST 4: hit routes
--- config
location /t {
content_by_lua_block {
local http = require "resty.http"
local uri = "http://127.0.0.1:" .. ngx.var.server_port
.. "/server_port"

local ports_count = {}
for i = 1, 12 do
local httpc = http.new()
local res, err = httpc:request_uri(uri, {method = "GET"})
if not res then
ngx.say(err)
return
end
ports_count[res.body] = (ports_count[res.body] or 0) + 1
end

local ports_arr = {}
for port, count in pairs(ports_count) do
table.insert(ports_arr, {port = port, count = count})
end

local function cmd(a, b)
return a.port > b.port
end
table.sort(ports_arr, cmd)

ngx.say(require("cjson").encode(ports_arr))
ngx.exit(200)
}
}
--- request
GET /t
--- response_body
[{"count":12,"port":"1982"}]
--- no_error_log
[error]
10 changes: 10 additions & 0 deletions t/node/no-upstream.t → t/node/not-exist-upstream.t
Original file line number Diff line number Diff line change
@@ -1,3 +1,13 @@
BEGIN {
if ($ENV{TEST_NGINX_CHECK_LEAK}) {
$SkipReason = "unavailable for the hup tests";

} else {
$ENV{TEST_NGINX_USE_HUP} = 1;
undef $ENV{TEST_NGINX_USE_STAP};
}
}

use t::APISix 'no_plan';

repeat_each(1);
Expand Down
Loading

0 comments on commit c02d44f

Please sign in to comment.