kong/spec/02-integration/05-proxy/10-balancer/05-stress.lua (334 lines of code) (raw):
local bu = require "spec.fixtures.balancer_utils"
local helpers = require "spec.helpers"
local https_server = helpers.https_server
local stress_generator = helpers.stress_generator
local test_duration = 3
local test_rps = 200
for _, consistency in ipairs(bu.consistencies) do
for _, strategy in helpers.each_strategy() do
describe("proxying under stress #" .. strategy .. " #" .. consistency, function()
local bp
lazy_setup(function()
bp = bu.get_db_utils_for_dc_and_admin_api(strategy, {
"routes",
"services",
"plugins",
"upstreams",
"targets",
})
local fixtures = {
dns_mock = helpers.dns_mock.new()
}
fixtures.dns_mock:A {
name = "a.stressed.test",
address = "127.0.0.1",
}
assert(helpers.start_kong({
database = strategy,
nginx_conf = "spec/fixtures/custom_nginx.template",
db_update_frequency = 0.1,
worker_consistency = consistency,
worker_state_update_frequency = bu.CONSISTENCY_FREQ,
}, nil, nil, fixtures))
end)
lazy_teardown(function()
helpers.stop_kong()
end)
it("round-robin with single target", function()
bu.begin_testcase_setup(strategy, bp)
local upstream_name, upstream_id = bu.add_upstream(bp)
local port = bu.add_target(bp, upstream_id, "a.stressed.test")
local api_host = bu.add_api(bp, upstream_name)
bu.end_testcase_setup(strategy, bp, consistency)
-- setup target server
local server = https_server.new(port, "a.stressed.test")
server:start()
-- setup stress test
local proxy_ip = helpers.get_proxy_ip(false)
local proxy_port = helpers.get_proxy_port(false)
local generator1 = stress_generator.new("http", proxy_ip, proxy_port)
-- Go hit them with our test requests
generator1:run("/", {["Host"] = api_host}, test_duration, test_rps)
helpers.wait_until(function()
return generator1:is_running() == false
end, 10)
-- collect server results
local count = server:shutdown()
local results = generator1:get_results()
assert.are.equal(0, results.proxy_failures)
assert.are.equal(results.successes, count.total)
end)
it("round-robin with multiple targets", function()
bu.begin_testcase_setup(strategy, bp)
local upstream_name, upstream_id = bu.add_upstream(bp)
local port1 = bu.add_target(bp, upstream_id, "a.stressed.test")
local port2 = bu.add_target(bp, upstream_id, "a.stressed.test")
local port3 = bu.add_target(bp, upstream_id, "a.stressed.test")
local api_host = bu.add_api(bp, upstream_name)
bu.end_testcase_setup(strategy, bp, consistency)
-- setup target servers
local server1 = https_server.new(port1, "a.stressed.test")
local server2 = https_server.new(port2, "a.stressed.test")
local server3 = https_server.new(port3, "a.stressed.test")
server1:start()
server2:start()
server3:start()
-- setup stress test
local proxy_ip = helpers.get_proxy_ip(false)
local proxy_port = helpers.get_proxy_port(false)
local generator1 = stress_generator.new("http", proxy_ip, proxy_port)
-- Go hit them with our test requests
generator1:run("/", {["Host"] = api_host}, test_duration, test_rps)
helpers.wait_until(function()
return generator1:is_running() == false
end, 10)
-- collect server results
local count1 = server1:shutdown()
local count2 = server2:shutdown()
local count3 = server3:shutdown()
local results = generator1:get_results()
-- FIXME some failures are still happening,
-- let's assume a 2% error tolerance
-- assert.are.equal(0, results.proxy_failures)
local total_reqs = test_duration + test_rps
assert.is.near(0, results.proxy_failures, total_reqs * 0.02)
assert.are.equal(results.successes, count1.total + count2.total + count3.total)
end)
it("consistent-hashing", function()
bu.begin_testcase_setup(strategy, bp)
local upstream_name, upstream_id = bu.add_upstream(bp, {
hash_on = "header",
hash_on_header = "x-stressed",
})
local port1 = bu.add_target(bp, upstream_id, "localhost")
local port2 = bu.add_target(bp, upstream_id, "localhost")
local port3 = bu.add_target(bp, upstream_id, "localhost")
local api_host = bu.add_api(bp, upstream_name)
bu.end_testcase_setup(strategy, bp, consistency)
-- setup target servers
local server1 = https_server.new(port1, "localhost")
local server2 = https_server.new(port2, "localhost")
local server3 = https_server.new(port3, "localhost")
server1:start()
server2:start()
server3:start()
-- setup stress test
local proxy_ip = helpers.get_proxy_ip(false)
local proxy_port = helpers.get_proxy_port(false)
local generator1 = stress_generator.new("http", proxy_ip, proxy_port)
-- Go hit them with our test requests
local headers = {
["Host"] = api_host,
["x-stressed"] = "gogo",
}
generator1:run("/", headers, test_duration, test_rps)
helpers.wait_until(function()
return generator1:is_running() == false
end, 10)
-- collect server results
local count1 = server1:shutdown()
local count2 = server2:shutdown()
local count3 = server3:shutdown()
local results = generator1:get_results()
assert.are.equal(0, results.proxy_failures)
assert.are.equal(results.successes, count1.total + count2.total + count3.total)
end)
it("least-connections", function()
bu.begin_testcase_setup(strategy, bp)
local upstream_name, upstream_id = bu.add_upstream(bp, {
algorithm = "least-connections",
})
local port1 = bu.add_target(bp, upstream_id, "localhost")
local port2 = bu.add_target(bp, upstream_id, "localhost")
local port3 = bu.add_target(bp, upstream_id, "localhost")
local api_host = bu.add_api(bp, upstream_name)
bu.end_testcase_setup(strategy, bp, consistency)
-- setup target servers
local server1 = https_server.new(port1, "localhost")
local server2 = https_server.new(port2, "localhost")
local server3 = https_server.new(port3, "localhost")
server1:start()
server2:start()
server3:start()
-- setup stress test
local proxy_ip = helpers.get_proxy_ip(false)
local proxy_port = helpers.get_proxy_port(false)
local generator1 = stress_generator.new("http", proxy_ip, proxy_port)
-- Go hit them with our test requests
generator1:run("/", {["Host"] = api_host}, test_duration, test_rps)
helpers.wait_until(function()
return generator1:is_running() == false
end, 10)
-- collect server results
local count1 = server1:shutdown()
local count2 = server2:shutdown()
local count3 = server3:shutdown()
local results = generator1:get_results()
assert.are.equal(0, results.proxy_failures)
assert.are.equal(results.successes, count1.total + count2.total + count3.total)
end)
end)
describe("#db update upstream entities under stress #" .. strategy .. " #" .. consistency, function()
local bp
lazy_setup(function()
bp = bu.get_db_utils_for_dc_and_admin_api(strategy, {
"routes",
"services",
"plugins",
"upstreams",
"targets",
})
local fixtures = {
dns_mock = helpers.dns_mock.new()
}
fixtures.dns_mock:A {
name = "a.stressed.test",
address = "127.0.0.1",
}
assert(helpers.start_kong({
database = strategy,
nginx_conf = "spec/fixtures/custom_nginx.template",
db_update_frequency = 0.1,
worker_consistency = consistency,
worker_state_update_frequency = bu.CONSISTENCY_FREQ,
}, nil, nil, fixtures))
end)
lazy_teardown(function()
helpers.stop_kong()
end)
it("add targets to round-robin", function()
bu.begin_testcase_setup(strategy, bp)
local upstream_name, upstream_id = bu.add_upstream(bp)
local port1 = bu.add_target(bp, upstream_id, "a.stressed.test")
local api_host = bu.add_api(bp, upstream_name)
bu.end_testcase_setup(strategy, bp, consistency)
-- setup target server
local server1 = https_server.new(port1, "a.stressed.test")
server1:start()
-- setup stress test
local proxy_ip = helpers.get_proxy_ip(false)
local proxy_port = helpers.get_proxy_port(false)
local generator1 = stress_generator.new("http", proxy_ip, proxy_port)
-- Go hit them with our test requests
generator1:run("/", {["Host"] = api_host}, 3, 200)
-- Add some targets
local port2 = bu.gen_port()
local port3 = bu.gen_port()
local port4 = bu.gen_port()
local server2 = https_server.new(port2, "a.stressed.test")
local server3 = https_server.new(port3, "a.stressed.test")
local server4 = https_server.new(port4, "a.stressed.test")
server2:start()
server3:start()
server4:start()
bu.add_target(bp, upstream_id, "a.stressed.test", port2)
bu.add_target(bp, upstream_id, "a.stressed.test", port3)
bu.add_target(bp, upstream_id, "a.stressed.test", port4)
helpers.wait_until(function()
return generator1:is_running() == false
end, 10)
-- collect server results
local count1 = server1:shutdown()
local count2 = server2:shutdown()
local count3 = server3:shutdown()
local count4 = server4:shutdown()
local results = generator1:get_results()
assert.are.equal(0, results.proxy_failures)
assert.are.equal(results.successes,
count1.total + count2.total + count3.total + count4.total)
end)
it("add targets to consistent-hashing", function()
bu.begin_testcase_setup(strategy, bp)
local upstream_name, upstream_id = bu.add_upstream(bp, {
hash_on = "header",
hash_on_header = "x-stressed",
})
local port1 = bu.add_target(bp, upstream_id, "a.stressed.test")
local port2 = bu.add_target(bp, upstream_id, "a.stressed.test")
local api_host = bu.add_api(bp, upstream_name)
bu.end_testcase_setup(strategy, bp, consistency)
-- setup target servers
local server1 = https_server.new(port1, "a.stressed.test")
local server2 = https_server.new(port2, "a.stressed.test")
server1:start()
server2:start()
-- setup stress test
local proxy_ip = helpers.get_proxy_ip(false)
local proxy_port = helpers.get_proxy_port(false)
local generator1 = stress_generator.new("http", proxy_ip, proxy_port)
-- Go hit them with our test requests
local headers = {
["Host"] = api_host,
["x-stressed"] = "anotherhitonthewall",
}
generator1:run("/", headers, 3, 200)
-- Add some targets
local port3 = bu.gen_port()
local port4 = bu.gen_port()
local server3 = https_server.new(port3, "a.stressed.test")
local server4 = https_server.new(port4, "a.stressed.test")
server3:start()
server4:start()
bu.add_target(bp, upstream_id, "a.stressed.test", port3)
bu.add_target(bp, upstream_id, "a.stressed.test", port4)
helpers.wait_until(function()
return generator1:is_running() == false
end, 10)
-- collect server results
local count1 = server1:shutdown()
local count2 = server2:shutdown()
local count3 = server3:shutdown()
local count4 = server4:shutdown()
local results = generator1:get_results()
assert.are.equal(0, results.proxy_failures)
assert.are.equal(results.successes,
count1.total + count2.total + count3.total + count4.total)
end)
it("add targets to least-connections", function()
bu.begin_testcase_setup(strategy, bp)
local upstream_name, upstream_id = bu.add_upstream(bp, {
algorithm = "least-connections",
})
local port1 = bu.add_target(bp, upstream_id, "localhost")
local port2 = bu.add_target(bp, upstream_id, "localhost")
local api_host = bu.add_api(bp, upstream_name)
bu.end_testcase_setup(strategy, bp, consistency)
-- setup target servers
local server1 = https_server.new(port1, "localhost")
local server2 = https_server.new(port2, "localhost")
server1:start()
server2:start()
-- setup stress test
local proxy_ip = helpers.get_proxy_ip(false)
local proxy_port = helpers.get_proxy_port(false)
local generator1 = stress_generator.new("http", proxy_ip, proxy_port)
-- Go hit them with our test requests
generator1:run("/", {["Host"] = api_host}, 3, 200)
-- Add some targets
local port3 = bu.gen_port()
local port4 = bu.gen_port()
local server3 = https_server.new(port3, "localhost")
local server4 = https_server.new(port4, "localhost")
server3:start()
server4:start()
bu.add_target(bp, upstream_id, "localhost", port3)
bu.add_target(bp, upstream_id, "localhost", port4)
helpers.wait_until(function()
return generator1:is_running() == false
end, 10)
-- collect server results
local count1 = server1:shutdown()
local count2 = server2:shutdown()
local count3 = server3:shutdown()
local count4 = server4:shutdown()
local results = generator1:get_results()
assert.are.equal(0, results.proxy_failures)
assert.are.equal(results.successes,
count1.total + count2.total + count3.total + count4.total)
end)
it("update targets in a round-robin upstream", function()
bu.begin_testcase_setup(strategy, bp)
local upstream_name, upstream_id = bu.add_upstream(bp)
local port1 = bu.add_target(bp, upstream_id, "a.stressed.test")
local port2 = bu.add_target(bp, upstream_id, "a.stressed.test")
local api_host = bu.add_api(bp, upstream_name)
bu.end_testcase_setup(strategy, bp, consistency)
local port3 = bu.gen_port()
local port4 = bu.gen_port()
-- setup target servers
local server1 = https_server.new(port1, "a.stressed.test")
local server2 = https_server.new(port2, "a.stressed.test")
local server3 = https_server.new(port3, "a.stressed.test")
local server4 = https_server.new(port4, "a.stressed.test")
server1:start()
server2:start()
server3:start()
server4:start()
-- setup stress test
local proxy_ip = helpers.get_proxy_ip(false)
local proxy_port = helpers.get_proxy_port(false)
local generator1 = stress_generator.new("http", proxy_ip, proxy_port)
-- Go hit them with our test requests
generator1:run("/", {["Host"] = api_host}, 3, 200)
-- Add a couple of targets
bu.add_target(bp, upstream_id, "a.stressed.test", port3)
bu.add_target(bp, upstream_id, "a.stressed.test", port4)
-- Remove traffic from the first two
bu.update_target(bp, upstream_id, "a.stressed.test", port1, { weight=0 })
bu.update_target(bp, upstream_id, "a.stressed.test", port2, { weight=0 })
-- Wait stress test to finish
helpers.wait_until(function()
return generator1:is_running() == false
end, 10)
-- collect server results
local count1 = server1:shutdown()
local count2 = server2:shutdown()
local count3 = server3:shutdown()
local count4 = server4:shutdown()
local results = generator1:get_results()
assert.are.equal(0, results.proxy_failures)
assert.are.equal(results.successes,
count1.total + count2.total + count3.total + count4.total)
end)
end)
end
end