Skip to content

Commit

Permalink
test: allow to count select requests on storages
Browse files Browse the repository at this point in the history
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
  • Loading branch information
Totktonada committed Oct 14, 2021
1 parent d13fe63 commit 68d574e
Show file tree
Hide file tree
Showing 2 changed files with 112 additions and 3 deletions.
29 changes: 29 additions & 0 deletions test/entrypoint/srv_select.lua
Original file line number Diff line number Diff line change
Expand Up @@ -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,
}
Expand All @@ -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
)
Expand Down
86 changes: 83 additions & 3 deletions test/helper.lua
Original file line number Diff line number Diff line change
Expand Up @@ -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'),
Expand All @@ -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' },
Expand All @@ -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' },
Expand Down Expand Up @@ -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

0 comments on commit 68d574e

Please sign in to comment.