From 68d574ecb5ee280003f91696dcdf9acce91545b0 Mon Sep 17 00:00:00 2001 From: Alexander Turenko Date: Thu, 14 Oct 2021 03:05:28 +0300 Subject: [PATCH] test: allow to count select requests on storages I don't want to lean on box.stat() information here, because I don't control all iproto calls to storages: say, vshard rebalancer may perform them in background. Instead, I wrapped particular storage function I'm interested in. The goal is to be able to determine how much storages is involved into a select/pairs request. Part of #220 --- test/entrypoint/srv_select.lua | 29 ++++++++++++ test/helper.lua | 86 ++++++++++++++++++++++++++++++++-- 2 files changed, 112 insertions(+), 3 deletions(-) diff --git a/test/entrypoint/srv_select.lua b/test/entrypoint/srv_select.lua index 0a1fce689..1555ba8e2 100755 --- a/test/entrypoint/srv_select.lua +++ b/test/entrypoint/srv_select.lua @@ -192,6 +192,34 @@ package.preload['customers-storage'] = function() } end +package.preload['statistics-storage'] = function() + return { + role_name = 'statistics-storage', + dependencies = {'cartridge.roles.crud-storage'}, + init = function() + assert(_G._crud.select_on_storage ~= nil) + + -- Here we count requests. + local storage_stat_table = { + select_requests = 0, + } + + -- Wrap select_on_storage() function. + local select_on_storage_saved = _G._crud.select_on_storage + _G._crud.select_on_storage = function(...) + local requests = storage_stat_table.select_requests + storage_stat_table.select_requests = requests + 1 + return select_on_storage_saved(...) + end + + -- Accessor for the statistics. + rawset(_G, 'storage_stat', function() + return storage_stat_table + end) + end, + } +end + local box_opts = { readahead = 10 * 1024 * 1024, } @@ -203,6 +231,7 @@ local ok, err = errors.pcall('CartridgeCfgError', cartridge.cfg, { 'cartridge.roles.crud-router', 'cartridge.roles.crud-storage', 'customers-storage', + 'statistics-storage', }}, box_opts ) diff --git a/test/helper.lua b/test/helper.lua index 4c56385bb..03401b3cb 100644 --- a/test/helper.lua +++ b/test/helper.lua @@ -141,7 +141,14 @@ function helpers.truncate_space_on_cluster(cluster, space_name) end end -function helpers.get_test_replicasets() +function helpers.get_test_replicasets(opts) + local opts = opts or {} + + local storage_roles = {'customers-storage', 'crud-storage'} + for _, role in ipairs(opts.extra_storage_roles or {}) do + table.insert(storage_roles, role) + end + return { { uuid = helpers.uuid('a'), @@ -154,7 +161,7 @@ function helpers.get_test_replicasets() { uuid = helpers.uuid('b'), alias = 's-1', - roles = { 'customers-storage', 'crud-storage' }, + roles = storage_roles, servers = { { instance_uuid = helpers.uuid('b', 1), alias = 's1-master' }, { instance_uuid = helpers.uuid('b', 2), alias = 's1-replica' }, @@ -163,7 +170,7 @@ function helpers.get_test_replicasets() { uuid = helpers.uuid('c'), alias = 's-2', - roles = { 'customers-storage', 'crud-storage' }, + roles = storage_roles, servers = { { instance_uuid = helpers.uuid('c', 1), alias = 's2-master' }, { instance_uuid = helpers.uuid('c', 2), alias = 's2-replica' }, @@ -230,4 +237,77 @@ function helpers.get_other_storage_bucket_id(cluster, bucket_id) ]], {bucket_id}) end +-- Determine a replicaset alias by a server object. +function helpers.get_replicaset_alias(cluster, needle_server) + for _, replicaset in ipairs(cluster.replicasets) do + for _, server in ipairs(replicaset.servers) do + if server.alias == needle_server.alias then + return replicaset.alias + end + end + end + error(('Unable to find replicaset alias for server %s'):format( + needle_server.alias)) +end + +-- Accumulate statistics from given storages. +-- +-- The statistics is grouped by replicasets. +-- +-- Example of a return value: +-- +-- { +-- ['s-1'] = { +-- select_requests = 1, +-- }, +-- ['s-2'] = { +-- select_requests = 0, +-- }, +-- } +function helpers.collect_storage_stat(cluster, aliases) + local res = {} + + helpers.call_on_servers(cluster, aliases, function(server) + -- Collect the statistics. + local storage_stat = server.net_box:call('storage_stat') + + -- Initialize if needed. + local replicaset_alias = helpers.get_replicaset_alias(cluster, server) + if res[replicaset_alias] == nil then + res[replicaset_alias] = {} + end + + -- Accumulate the collected statistics. + for key, val in pairs(storage_stat) do + local old = res[replicaset_alias][key] or 0 + res[replicaset_alias][key] = old + val + end + end) + + return res +end + +-- Difference between 'a' and 'b' storage statistics. +-- +-- The return value structure is the same as for +-- helpers.collect_storage_stat(). +function helpers.diff_storage_stat(a, b) + local diff = table.deepcopy(a) + + for replicaset_alias, stat_b in pairs(b) do + -- Initialize if needed. + if diff[replicaset_alias] == nil then + diff[replicaset_alias] = {} + end + + -- Substract 'b' statistics from 'a'. + for key, val in pairs(stat_b) do + local old = diff[replicaset_alias][key] or 0 + diff[replicaset_alias][key] = old - val + end + end + + return diff +end + return helpers