From 596e02ef677c0d018fb7bc28a70bdba53b25567d Mon Sep 17 00:00:00 2001 From: Oleg Jukovec Date: Tue, 9 Jul 2024 15:52:59 +0300 Subject: [PATCH] final --- test/entrypoint/config.yaml | 32 +++ test/helper.lua | 215 ------------------ test/helpers/init.lua | 26 +++ .../{helper_server.lua => helpers/server.lua} | 0 test/integration/metrics-export_test.lua | 67 ------ test/integration/role_test.lua | 69 ++++++ test/integration/simple_app/config.yaml | 17 -- test/integration/simple_app/instances.yml | 1 - test/unit/http_test.lua | 65 ++++-- 9 files changed, 172 insertions(+), 320 deletions(-) create mode 100644 test/entrypoint/config.yaml delete mode 100644 test/helper.lua create mode 100644 test/helpers/init.lua rename test/{helper_server.lua => helpers/server.lua} (100%) delete mode 100644 test/integration/metrics-export_test.lua create mode 100644 test/integration/role_test.lua delete mode 100644 test/integration/simple_app/config.yaml delete mode 100644 test/integration/simple_app/instances.yml diff --git a/test/entrypoint/config.yaml b/test/entrypoint/config.yaml new file mode 100644 index 0000000..135bb20 --- /dev/null +++ b/test/entrypoint/config.yaml @@ -0,0 +1,32 @@ +credentials: + users: + guest: + roles: [super] + +groups: + group-001: + replicasets: + replicaset-001: + roles: [roles.metrics-export] + roles_cfg: + roles.metrics-export: + http: + - listen: 8081 + endpoints: + - path: /metrics + format: json + - path: /metrics/2/ + format: prometheus + - listen: '127.0.0.1:8082' + endpoints: + - path: /metrics + format: prometheus + - path: /metrics/2 + format: json + instances: + master: + iproto: + listen: + - uri: '127.0.0.1:3313' + database: + mode: rw diff --git a/test/helper.lua b/test/helper.lua deleted file mode 100644 index d0c3486..0000000 --- a/test/helper.lua +++ /dev/null @@ -1,215 +0,0 @@ -local t = require("luatest") -local fio = require("fio") - -local helpers = require("luatest.helpers") - -helpers.project_root = fio.dirname(debug.sourcedir()) - -function helpers.create_space(space_name, engine) - local space_format = { - { - name = "id", - type = "number" - }, - { - name = "first_name", - type = "string" - }, - { - name = "value", - type = "number", - is_nullable = true - }, - { - name = "count", - type = "number", - is_nullable = true - }, - { - name = "non_unique_id", - type = "number", - is_nullable = true, - }, - { - name = "json_path_field", - is_nullable = true, - }, - { - name = "multikey_field", - is_nullable = true - }, - { - name = "functional_field", - is_nullable = true - }, - } - - local space = box.schema.create_space(space_name, { - engine = engine - }) - space:format(space_format) - - return space -end - -function helpers.create_space_with_tree_index(engine) - local space = helpers.create_space("tree", engine) - - space:create_index("primary", { - type = "TREE", - parts = { - { - field = 1 - } - } - }) - space:create_index("index_for_first_name", { - type = "TREE", - parts = { - { - field = 2 - } - } - }) - space:create_index("multipart_index", { - type = "TREE", - parts = { - { - field = 3, - is_nullable = true - }, - { - field = 4, - is_nullable = true - } - } - }) - space:create_index("non_unique_index", { - type = "TREE", - parts = { - { - field = 5, - is_nullable = true - } - }, - unique = false - }) - - if _TARANTOOL >= "2" then - space:create_index("json_path_index", { - type = "TREE", - parts = { - { - field = 6, - type = "scalar", - path = "age", - is_nullable = true - } - } - }) - space:create_index("multikey_index", { - type = "TREE", - parts = { - { - field = 7, - type = "str", - path = "data[*].name" - } - } - }) - if engine ~= "vinyl" then - space:create_index("functional_index", { - type = "TREE", - parts = { - { - field = 1, - type = "string" - } - }, - func = "tree_func" - }) - end - end - - return space -end - -function helpers.create_space_with_hash_index(engine) - local space = helpers.create_space("hash", engine) - space:create_index("primary", { - type = "HASH", - parts = { - { - field = 1 - } - } - }) - space:create_index("index_for_first_name", { - type = "HASH", - parts = { - { - field = 2 - } - } - }) - space:create_index("multipart_index", { - type = "HASH", - parts = { - { - field = 1 - }, - { - field = 2 - } - } - }) - - return space -end - -function helpers.create_space_with_bitset_index(engine) - local space = helpers.create_space("bitset", engine) - space:create_index("primary", { - type = "TREE", - parts = { - { - field = 1 - } - } - }) - space:create_index("index_for_first_name", { - type = "BITSET", - parts = { - { - field = 2, - type = "string" - } - }, - unique = false - }) - - return space -end - -local function tarantool_version() - local major_minor_patch = _G._TARANTOOL:split('-', 1)[1] - local major_minor_patch_parts = major_minor_patch:split('.', 2) - - local major = tonumber(major_minor_patch_parts[1]) - local minor = tonumber(major_minor_patch_parts[2]) - local patch = tonumber(major_minor_patch_parts[3]) - - return major, minor, patch -end - -local function tarantool_role_is_supported() - local major, _, _ = tarantool_version() - return major >= 3 -end - -function helpers.skip_if_unsupported() - t.skip_if(not tarantool_role_is_supported(), - 'Tarantool role is supported only for Tarantool starting from v3.0.0') -end - -return helpers diff --git a/test/helpers/init.lua b/test/helpers/init.lua new file mode 100644 index 0000000..0fb8d20 --- /dev/null +++ b/test/helpers/init.lua @@ -0,0 +1,26 @@ +local t = require("luatest") + +local helpers = {} + +local function tarantool_version() + local major_minor_patch = _G._TARANTOOL:split('-', 1)[1] + local major_minor_patch_parts = major_minor_patch:split('.', 2) + + local major = tonumber(major_minor_patch_parts[1]) + local minor = tonumber(major_minor_patch_parts[2]) + local patch = tonumber(major_minor_patch_parts[3]) + + return major, minor, patch +end + +local function tarantool_role_is_supported() + local major, _, _ = tarantool_version() + return major >= 3 +end + +function helpers.skip_if_unsupported() + t.skip_if(not tarantool_role_is_supported(), + 'Tarantool role is supported only for Tarantool starting from v3.0.0') +end + +return helpers diff --git a/test/helper_server.lua b/test/helpers/server.lua similarity index 100% rename from test/helper_server.lua rename to test/helpers/server.lua diff --git a/test/integration/metrics-export_test.lua b/test/integration/metrics-export_test.lua deleted file mode 100644 index f0cac88..0000000 --- a/test/integration/metrics-export_test.lua +++ /dev/null @@ -1,67 +0,0 @@ -local t = require('luatest') -local fio = require('fio') - -local helpers = require('test.helper') -local Server = require('test.helper_server') - -local g = t.group() - -g.before_all(function (cg) - helpers.skip_if_unsupported() -end) - -g.before_each(function(cg) - cg.workdir = fio.tempdir() - fio.mktree(cg.workdir) - - fio.copytree(".rocks", fio.pathjoin(cg.workdir, ".rocks")) - fio.copytree("roles", fio.pathjoin(cg.workdir, "roles")) - - cg.router = Server:new({ - config_file = fio.abspath(fio.pathjoin('test', 'integration', 'simple_app', 'config.yaml')), - chdir = cg.workdir, - alias = 'master', - workdir = cg.workdir, - }) - - -- We start instance before each test because - -- we need to force reload of metrics-export role and also instance environment - -- from previous tests can influence test result. - -- (e.g function creation, when testing that role doesn't start w/o it) - -- Restarting instance is the easiest way to achieve it. - -- It takes around 1s to start an instance, which considering small amount - -- of integration tests is not a problem. - cg.router:start{wait_until_ready = true} -end) - -g.after_each(function(cg) - cg.router:stop() - fio.rmtree(cg.workdir) -end) - -g.test_dummy = function(cg) - cg.router:exec(function() - box.schema.create_space('users', {if_not_exists = true}) - - box.space.users:format({ - {name = 'id', type = 'unsigned'}, - {name = 'first name', type = 'string'}, - {name = 'second name', type = 'string', is_nullable = true}, - {name = 'age', type = 'number', is_nullable = false}, - }) - - box.space.users:create_index('primary', { - parts = { - {field = 1, type = 'unsigned'}, - }, - }) - - box.space.users:insert{1, 'Samantha', 'Carter', 30} - box.space.users:insert{2, 'Fay', 'Rivers', 41} - box.space.users:insert{3, 'Zachariah', 'Peters', 13} - box.space.users:insert{4, 'Milo', 'Walters', 74} - end) - t.assert_equals(cg.router:exec(function() - return #box.space.users:select({}, {limit = 10}) - end), 4) -end diff --git a/test/integration/role_test.lua b/test/integration/role_test.lua new file mode 100644 index 0000000..515963a --- /dev/null +++ b/test/integration/role_test.lua @@ -0,0 +1,69 @@ +local fio = require('fio') +local json = require('json') +local helpers = require('test.helpers') +local http_client = require('http.client') +local server = require('test.helpers.server') + +local t = require('luatest') +local g = t.group() + +g.before_all(function() + helpers.skip_if_unsupported() +end) + +g.before_each(function(cg) + cg.workdir = fio.tempdir() + fio.mktree(cg.workdir) + + fio.copytree(".rocks", fio.pathjoin(cg.workdir, ".rocks")) + fio.copytree("roles", fio.pathjoin(cg.workdir, "roles")) + + cg.router = server:new({ + config_file = fio.abspath(fio.pathjoin('test', 'entrypoint', 'config.yaml')), + chdir = cg.workdir, + alias = 'master', + workdir = cg.workdir, + }) + + -- It takes around 1s to start an instance, which considering small amount + -- of integration tests is not a problem. But at the same time, we have a + -- clean work environment. + cg.router:start{wait_until_ready = true} +end) + +g.after_each(function(cg) + cg.router:stop() + fio.rmtree(cg.workdir) +end) + +local function assert_json(uri) + local response = http_client.get(uri) + t.assert_equals(response.status, 200) + t.assert(response.body) + + local decoded = json.decode(response.body) + t.assert(#decoded > 0) +end + +local function assert_prometheus(uri) + local response = http_client.get(uri) + t.assert_equals(response.status, 200) + t.assert(response.body) + + -- It’s not very clear how to keep the check simple and clear here. So I + -- just took a line from `prometheus` format which should be in the future + -- releases and don't clash with JSON to avoid false-positive. + t.assert_str_contains(response.body, "# TYPE tnt_memtx_tnx_user gauge") +end + +g.test_endpoints = function() + assert_json("http://127.0.0.1:8081/metrics") + assert_json("http://127.0.0.1:8081/metrics/") + assert_prometheus("http://127.0.0.1:8081/metrics/2") + assert_prometheus("http://127.0.0.1:8081/metrics/2/") + + assert_prometheus("http://127.0.0.1:8082/metrics") + assert_prometheus("http://127.0.0.1:8082/metrics/") + assert_json("http://127.0.0.1:8082/metrics/2") + assert_json("http://127.0.0.1:8082/metrics/2/") +end diff --git a/test/integration/simple_app/config.yaml b/test/integration/simple_app/config.yaml deleted file mode 100644 index 69fe25f..0000000 --- a/test/integration/simple_app/config.yaml +++ /dev/null @@ -1,17 +0,0 @@ -credentials: - users: - guest: - roles: [super] - -groups: - group-001: - replicasets: - replicaset-001: - roles: [roles.metrics-export] - instances: - master: - iproto: - listen: - - uri: '127.0.0.1:3313' - database: - mode: rw diff --git a/test/integration/simple_app/instances.yml b/test/integration/simple_app/instances.yml deleted file mode 100644 index b79b9b8..0000000 --- a/test/integration/simple_app/instances.yml +++ /dev/null @@ -1 +0,0 @@ -master: diff --git a/test/unit/http_test.lua b/test/unit/http_test.lua index 58ca110..8552407 100644 --- a/test/unit/http_test.lua +++ b/test/unit/http_test.lua @@ -5,18 +5,18 @@ local metrics = require('metrics') local t = require('luatest') local g = t.group() -g.before_all(function(gc) - gc.role = require('roles.metrics-export') +g.before_all(function(cg) + cg.role = require('roles.metrics-export') end) -g.before_each(function(gc) - gc.counter = metrics.counter('some_counter') - gc.counter:inc(1, {label = 'ANY'}) +g.before_each(function(cg) + cg.counter = metrics.counter('some_counter') + cg.counter:inc(1, {label = 'ANY'}) end) -g.after_each(function(gc) - gc.role.stop() - metrics.registry:unregister(gc.counter) +g.after_each(function(cg) + cg.role.stop() + metrics.registry:unregister(cg.counter) end) local function assert_none(uri) @@ -48,6 +48,7 @@ local function assert_prometheus(uri) t.assert(response.body) local data = response.body + -- luacheck: ignore local expected_prometheus = [[# HELP some_counter # TYPE some_counter counter some_counter{label="ANY"} 1 @@ -55,8 +56,8 @@ some_counter{label="ANY"} 1 t.assert_equals(data, expected_prometheus) end -g.test_json_endpoint = function(gc) - g.role.apply({ +g.test_json_endpoint = function(cg) + cg.role.apply({ http = { { listen = 8081, @@ -72,8 +73,8 @@ g.test_json_endpoint = function(gc) assert_json("http://127.0.0.1:8081/json_metrics") end -g.test_prometheus_endpoint = function(gc) - g.role.apply({ +g.test_prometheus_endpoint = function(cg) + cg.role.apply({ http = { { listen = 8081, @@ -89,8 +90,8 @@ g.test_prometheus_endpoint = function(gc) assert_prometheus("http://127.0.0.1:8081/prometheus_metrics") end -g.test_mixed = function(gc) - g.role.apply({ +g.test_mixed = function(cg) + cg.role.apply({ http = { { listen = 8081, @@ -131,8 +132,8 @@ g.test_mixed = function(gc) assert_prometheus("http://127.0.0.1:8082/metrics4") end -g.test_reapply = function(gc) - g.role.apply({ +g.test_reapply = function(cg) + cg.role.apply({ http = { { listen = 8081, @@ -162,7 +163,7 @@ g.test_reapply = function(gc) assert_prometheus("http://127.0.0.1:8081/metrics2") assert_json("http://127.0.0.1:8082/metrics/1") - g.role.apply({ + cg.role.apply({ http = { { listen = 8081, @@ -180,8 +181,8 @@ g.test_reapply = function(gc) assert_none("http://127.0.0.1:8082/metrics/1") end -g.test_stop = function(gc) - g.role.apply({ +g.test_stop = function(cg) + cg.role.apply({ http = { { listen = 8081, @@ -196,6 +197,30 @@ g.test_stop = function(gc) }) assert_json("http://127.0.0.1:8081/metrics1") - g.role.stop() + cg.role.stop() assert_none("http://127.0.0.1:8082/metrics/1") end + +g.test_endpoint_and_slashes = function(cg) + cg.role.apply({ + http = { + { + listen = 8081, + endpoints = { + { + path = "/endpoint", + format = "json", + }, + { + path = "/endpoint/2/", + format = "json", + }, + }, + }, + }, + }) + assert_json("http://127.0.0.1:8081/endpoint") + assert_json("http://127.0.0.1:8081/endpoint/") + assert_json("http://127.0.0.1:8081/endpoint/2") + assert_json("http://127.0.0.1:8081/endpoint/2/") +end