kong/spec/01-unit/11-reports_spec.lua (328 lines of code) (raw):
local meta = require "kong.meta"
local helpers = require "spec.helpers"
local reports = require "kong.reports"
local cjson = require "cjson"
describe("reports", function()
describe("send()", function()
lazy_setup(function()
reports.toggle(true)
end)
lazy_teardown(function()
package.loaded["kong.reports"] = nil
end)
it("sends report over TCP[TLS]", function()
local thread = helpers.tcp_server(8189, {tls=true})
reports.send("stub", {
hello = "world",
foo = "bar",
baz = function() return "bat" end,
foobar = function() return { foo = "bar" } end,
bazbat = { baz = "bat" },
nilval = function() return nil end,
}, "127.0.0.1", 8189)
local ok, res = thread:join()
assert.True(ok)
assert.matches("^<14>", res)
res = res:sub(5)
assert.matches("cores=%d+", res)
assert.matches("uname=[%w]+", res)
assert.matches("version=" .. meta._VERSION, res, nil, true)
assert.matches("hostname=[%w]+", res)
assert.matches("foo=bar", res, nil, true)
assert.matches("hello=world", res, nil, true)
assert.matches("signal=stub", res, nil, true)
assert.matches("baz=bat", res, nil, true)
assert.not_matches("nilval", res, nil, true)
assert.matches("foobar=" .. cjson.encode({ foo = "bar" }), res, nil, true)
assert.matches("bazbat=" .. cjson.encode({ baz = "bat" }), res, nil, true)
end)
it("doesn't send if not enabled", function()
reports.toggle(false)
local thread = helpers.tcp_server(8189, { requests = 1, timeout = 0.1 })
reports.send({
foo = "bar"
}, "127.0.0.1", 8189)
local ok, res = thread:join()
assert.True(ok)
assert.equal("timeout", res)
end)
it("accepts custom immutable items", function()
reports.toggle(true)
local thread = helpers.tcp_server(8189, {tls=true})
reports.add_immutable_value("imm1", "fooval")
reports.add_immutable_value("imm2", "barval")
reports.send("stub", {k1 = "bazval"}, "127.0.0.1", 8189)
local ok, res = thread:join()
assert.True(ok)
assert.matches("imm1=fooval", res)
assert.matches("imm2=barval", res)
assert.matches("k1=bazval", res)
end)
end)
describe("configure_ping()", function()
local conf_loader = require "kong.conf_loader"
before_each(function()
package.loaded["kong.reports"] = nil
reports = require "kong.reports"
reports.toggle(true)
reports._create_counter()
end)
describe("sends 'cluster_id'", function()
it("uses mock value 123e4567-e89b-12d3-a456-426655440000", function()
local conf = assert(conf_loader(nil, {
database = "postgres",
}))
reports.configure_ping(conf)
local thread = helpers.tcp_server(8189, {tls=true})
reports.send_ping("127.0.0.1", 8189)
local _, res = assert(thread:join())
assert._matches("cluster_id=123e4567-e89b-12d3-a456-426655440000", res, nil, true)
end)
end)
describe("sends 'database'", function()
it("postgres", function()
local conf = assert(conf_loader(nil, {
database = "postgres",
}))
reports.configure_ping(conf)
local thread = helpers.tcp_server(8189, {tls=true})
reports.send_ping("127.0.0.1", 8189)
local _, res = assert(thread:join())
assert._matches("database=postgres", res, nil, true)
end)
it("cassandra", function()
local conf = assert(conf_loader(nil, {
database = "cassandra",
}))
reports.configure_ping(conf)
local thread = helpers.tcp_server(8189, {tls=true})
reports.send_ping("127.0.0.1", 8189)
local _, res = assert(thread:join())
assert.matches("database=cassandra", res, nil, true)
end)
it("off", function()
local conf = assert(conf_loader(nil, {
database = "off",
}))
reports.configure_ping(conf)
local thread = helpers.tcp_server(8189, {tls=true})
reports.send_ping("127.0.0.1", 8189)
local _, res = assert(thread:join())
assert.matches("database=off", res, nil, true)
end)
end)
describe("sends 'role'", function()
it("traditional", function()
local conf = assert(conf_loader(nil))
reports.configure_ping(conf)
local thread = helpers.tcp_server(8189, {tls=true})
reports.send_ping("127.0.0.1", 8189)
local _, res = assert(thread:join())
assert._matches("role=traditional", res, nil, true)
end)
it("control_plane", function()
local conf = assert(conf_loader(nil, {
role = "control_plane",
cluster_cert = "spec/fixtures/kong_spec.crt",
cluster_cert_key = "spec/fixtures/kong_spec.key",
}))
reports.configure_ping(conf)
local thread = helpers.tcp_server(8189, {tls=true})
reports.send_ping("127.0.0.1", 8189)
local _, res = assert(thread:join())
assert.matches("role=control_plane", res, nil, true)
end)
it("data_plane", function()
local conf = assert(conf_loader(nil, {
role = "data_plane",
database = "off",
cluster_cert = "spec/fixtures/kong_spec.crt",
cluster_cert_key = "spec/fixtures/kong_spec.key",
}))
reports.configure_ping(conf)
local thread = helpers.tcp_server(8189, {tls=true})
reports.send_ping("127.0.0.1", 8189)
local _, res = assert(thread:join())
assert.matches("role=data_plane", res, nil, true)
end)
end)
describe("sends 'kic'", function()
it("default (off)", function()
local conf = assert(conf_loader(nil))
reports.configure_ping(conf)
local thread = helpers.tcp_server(8189, {tls=true})
reports.send_ping("127.0.0.1", 8189)
local _, res = assert(thread:join())
assert._matches("kic=false", res, nil, true)
end)
it("enabled", function()
local conf = assert(conf_loader(nil, {
kic = "on",
}))
reports.configure_ping(conf)
local thread = helpers.tcp_server(8189, {tls=true})
reports.send_ping("127.0.0.1", 8189)
local _, res = assert(thread:join())
assert.matches("kic=true", res, nil, true)
end)
end)
describe("sends '_admin' for 'admin_listen'", function()
it("off", function()
local conf = assert(conf_loader(nil, {
admin_listen = "off",
}))
reports.configure_ping(conf)
local thread = helpers.tcp_server(8189, {tls=true})
reports.send_ping("127.0.0.1", 8189)
local _, res = assert(thread:join())
assert.matches("_admin=0", res, nil, true)
end)
it("on", function()
local conf = assert(conf_loader(nil, {
admin_listen = "127.0.0.1:8001",
}))
reports.configure_ping(conf)
local thread = helpers.tcp_server(8189, {tls=true})
reports.send_ping("127.0.0.1", 8189)
local _, res = assert(thread:join())
assert.matches("_admin=1", res, nil, true)
end)
end)
describe("sends '_proxy' for 'proxy_listen'", function()
it("off", function()
local conf = assert(conf_loader(nil, {
proxy_listen = "off",
}))
reports.configure_ping(conf)
local thread = helpers.tcp_server(8189, {tls=true})
reports.send_ping("127.0.0.1", 8189)
local _, res = assert(thread:join())
assert.matches("_proxy=0", res, nil, true)
end)
it("on", function()
local conf = assert(conf_loader(nil, {
proxy_listen = "127.0.0.1:8000",
}))
reports.configure_ping(conf)
local thread = helpers.tcp_server(8189, {tls=true})
reports.send_ping("127.0.0.1", 8189)
local _, res = assert(thread:join())
assert.matches("_proxy=1", res, nil, true)
end)
end)
describe("sends '_stream' for 'stream_listen'", function()
it("off", function()
local conf = assert(conf_loader(nil, {
stream_listen = "off",
}))
reports.configure_ping(conf)
local thread = helpers.tcp_server(8189, {tls=true})
reports.send_ping("127.0.0.1", 8189)
local _, res = assert(thread:join())
assert.matches("_stream=0", res, nil, true)
end)
it("on", function()
local conf = assert(conf_loader(nil, {
stream_listen = "127.0.0.1:8000",
}))
reports.configure_ping(conf)
local thread = helpers.tcp_server(8189, {tls=true})
reports.send_ping("127.0.0.1", 8189)
local _, res = assert(thread:join())
assert.matches("_stream=1", res, nil, true)
end)
end)
it("default configuration ping contents", function()
local conf = assert(conf_loader())
reports.configure_ping(conf)
local thread = helpers.tcp_server(8189, {tls=true})
reports.send_ping("127.0.0.1", 8189)
local _, res = assert(thread:join())
assert.matches("database=" .. helpers.test_conf.database, res, nil, true)
assert.matches("_admin=1", res, nil, true)
assert.matches("_proxy=1", res, nil, true)
assert.matches("_stream=0", res, nil, true)
end)
end)
describe("retrieve_redis_version()", function()
lazy_setup(function()
stub(ngx, "log")
end)
lazy_teardown(function()
ngx.log:revert() -- luacheck: ignore
end)
before_each(function()
package.loaded["kong.reports"] = nil
reports = require "kong.reports"
reports.toggle(true)
reports._create_counter()
end)
it("does not query Redis if not enabled", function()
reports.toggle(false)
local red_mock = {
info = function() end,
}
local s = spy.on(red_mock, "info")
reports.retrieve_redis_version(red_mock)
assert.spy(s).was_not_called()
end)
it("queries Redis if enabled", function()
local red_mock = {
info = function()
return "redis_version:2.4.5\r\nredis_git_sha1:e09e31b1"
end,
}
local s = spy.on(red_mock, "info")
reports.retrieve_redis_version(red_mock)
assert.spy(s).was_called_with(red_mock, "server")
end)
it("queries Redis only once", function()
local red_mock = {
info = function()
return "redis_version:2.4.5\r\nredis_git_sha1:e09e31b1"
end,
}
local s = spy.on(red_mock, "info")
reports.retrieve_redis_version(red_mock)
reports.retrieve_redis_version(red_mock)
reports.retrieve_redis_version(red_mock)
assert.spy(s).was_called(1)
end)
it("retrieves major.minor version", function()
local red_mock = {
info = function()
return "redis_version:2.4.5\r\nredis_git_sha1:e09e31b1"
end,
}
reports.retrieve_redis_version(red_mock)
assert.equal("2.4", reports.get_ping_value("redis_version"))
end)
it("retrieves 'unknown' when the version could not be retrieved (1/3)", function()
local red_mock = {
info = function()
return nil
end,
}
reports.retrieve_redis_version(red_mock)
assert.equal("unknown", reports.get_ping_value("redis_version"))
end)
it("retrieves 'unknown' when the version could not be retrieved (2/3)", function()
local red_mock = {
info = function()
return ngx.null
end,
}
reports.retrieve_redis_version(red_mock)
assert.equal("unknown", reports.get_ping_value("redis_version"))
end)
it("retrieves 'unknown' when the version could not be retrieved (3/3)", function()
local red_mock = {
info = function()
return "hello world"
end,
}
reports.retrieve_redis_version(red_mock)
assert.equal("unknown", reports.get_ping_value("redis_version"))
end)
end)
end)