From 52da7cd17308850a02b7d9d953f5d9177c319175 Mon Sep 17 00:00:00 2001 From: Cedric Koch-Hofer Date: Fri, 24 May 2024 06:40:59 +0000 Subject: [PATCH] DAOS-10250 control: Get enabled and disabled ranks with dmg pool query Makes enabled and disabled ranks option of dmg compatible. Update and add cmocka unit tests of engine management related functions. Fix memory leaks of ranks string in function ds_mgmt_drpc_pool_query(). Features: control dmg Required-githooks: true Signed-off-by: Cedric Koch-Hofer --- src/control/cmd/dmg/pool.go | 4 - src/control/cmd/dmg/pool_test.go | 32 +++- src/gurt/misc.c | 83 +++++----- src/gurt/tests/test_gurt.c | 123 +++++++++++++- src/include/daos_srv/pool.h | 8 +- src/include/gurt/common.h | 3 +- src/mgmt/srv_drpc.c | 155 +++++++++++------- src/mgmt/srv_internal.h | 9 +- src/mgmt/srv_pool.c | 19 +-- src/mgmt/tests/mocks.c | 42 +++-- src/mgmt/tests/mocks.h | 16 +- src/mgmt/tests/srv_drpc_tests.c | 24 +-- src/pool/srv_cli.c | 114 ++++++++----- .../ftest/control/dmg_pool_query_ranks.py | 44 ++--- 14 files changed, 424 insertions(+), 252 deletions(-) diff --git a/src/control/cmd/dmg/pool.go b/src/control/cmd/dmg/pool.go index e678b0932ab..e75043873a2 100644 --- a/src/control/cmd/dmg/pool.go +++ b/src/control/cmd/dmg/pool.go @@ -646,10 +646,6 @@ func (cmd *PoolQueryCmd) Execute(args []string) error { if cmd.HealthOnly { req.QueryMask = daos.HealthOnlyPoolQueryMask } - // TODO (DAOS-10250) The two options should not be incompatible (i.e. engine limitation) - if cmd.ShowEnabledRanks && cmd.ShowDisabledRanks { - return errIncompatFlags("show-enabled-ranks", "show-disabled-ranks") - } if cmd.ShowEnabledRanks { req.QueryMask.SetOptions(daos.PoolQueryOptionEnabledEngines) } diff --git a/src/control/cmd/dmg/pool_test.go b/src/control/cmd/dmg/pool_test.go index 263243f034f..d02579b3a7f 100644 --- a/src/control/cmd/dmg/pool_test.go +++ b/src/control/cmd/dmg/pool_test.go @@ -1012,6 +1012,32 @@ func TestPoolCommands(t *testing.T) { }, " "), nil, }, + { + "Query pool with UUID, enabled ranks and disabled ranks", + "pool query --show-disabled --show-enabled 12345678-1234-1234-1234-1234567890ab", + strings.Join([]string{ + printRequest(t, &control.PoolQueryReq{ + ID: "12345678-1234-1234-1234-1234567890ab", + QueryMask: setQueryMask(func(qm *daos.PoolQueryMask) { + qm.SetOptions(daos.PoolQueryOptionEnabledEngines, daos.PoolQueryOptionDisabledEngines) + }), + }), + }, " "), + nil, + }, + { + "Query pool with UUID, enabled ranks and disabled ranks", + "pool query -b -e 12345678-1234-1234-1234-1234567890ab", + strings.Join([]string{ + printRequest(t, &control.PoolQueryReq{ + ID: "12345678-1234-1234-1234-1234567890ab", + QueryMask: setQueryMask(func(qm *daos.PoolQueryMask) { + qm.SetOptions(daos.PoolQueryOptionEnabledEngines, daos.PoolQueryOptionDisabledEngines) + }), + }), + }, " "), + nil, + }, { "Query pool for health only", "pool query --health-only 12345678-1234-1234-1234-1234567890ab", @@ -1056,12 +1082,6 @@ func TestPoolCommands(t *testing.T) { "", fmt.Errorf("Unknown command"), }, - { - "Query pool with incompatible arguments", - "pool query --show-disabled --show-enabled 12345678-1234-1234-1234-1234567890ab", - "", - errors.New("may not be mixed"), - }, }) } diff --git a/src/gurt/misc.c b/src/gurt/misc.c index 29cc6d3bc24..85b060627d4 100644 --- a/src/gurt/misc.c +++ b/src/gurt/misc.c @@ -750,14 +750,19 @@ d_rank_list_dump(d_rank_list_t *rank_list, d_string_t name, int name_len) char * d_rank_list_to_str(d_rank_list_t *rank_list) { - char *str; - bool truncated = false; - d_rank_range_list_t *range_list; + char *str = NULL; + d_rank_range_list_t *range_list = NULL; + int rc; range_list = d_rank_range_list_create_from_ranks(rank_list); - if (range_list == NULL) + if (range_list == NULL) { + DL_WARN(-DER_NOMEM, "rank list could not be serialized"); return NULL; - str = d_rank_range_list_str(range_list, &truncated); + } + + rc = d_rank_range_list_str(range_list, &str); + if (rc != -DER_SUCCESS) + DL_WARN(rc, "rank list could not be serialized"); d_rank_range_list_free(range_list); @@ -844,7 +849,6 @@ d_rank_range_list_realloc(d_rank_range_list_t *range_list, uint32_t size) return range_list; } -/* TODO (DAOS-10253) Add unit tests for this function */ d_rank_range_list_t * d_rank_range_list_create_from_ranks(d_rank_list_t *rank_list) { @@ -854,6 +858,8 @@ d_rank_range_list_create_from_ranks(d_rank_list_t *rank_list) unsigned int i; /* rank index */ unsigned int j; /* rank range index */ + D_ASSERT(rank_list != NULL); + d_rank_list_sort(rank_list); if ((rank_list == NULL) || (rank_list->rl_ranks == NULL) || (rank_list->rl_nr == 0)) return d_rank_range_list_alloc(0); @@ -890,56 +896,51 @@ d_rank_range_list_create_from_ranks(d_rank_list_t *rank_list) return range_list; } -/* TODO (DAOS-10253) Add unit tests for this function */ -char * -d_rank_range_list_str(d_rank_range_list_t *list, bool *truncated) +int +d_rank_range_list_str(d_rank_range_list_t *list, char **ranks_str) { - const size_t MAXBYTES = 512; - char *line; - char *linepos; - int ret = 0; - size_t remaining = MAXBYTES - 2u; - int i; - int err = 0; + const size_t MAXBYTES = 512u; + size_t remaining = MAXBYTES - 2u; + char *line; + char *linepos; + int i; + int len; + int rc; + + D_ASSERT(list != NULL); - *truncated = false; D_ALLOC(line, MAXBYTES); if (line == NULL) - return NULL; + D_GOTO(error, rc = -DER_NOMEM); *line = '['; linepos = line + 1; for (i = 0; i < list->rrl_nr; i++) { - uint32_t lo = list->rrl_ranges[i].lo; - uint32_t hi = list->rrl_ranges[i].hi; - bool lastrange = (i == (list->rrl_nr - 1)); + uint32_t lo = list->rrl_ranges[i].lo; + uint32_t hi = list->rrl_ranges[i].hi; + bool lastrange = (i == (list->rrl_nr - 1)); if (lo == hi) - ret = snprintf(linepos, remaining, "%u%s", lo, lastrange ? "" : ","); + len = snprintf(linepos, remaining, "%u%s", lo, lastrange ? "" : ","); else - ret = snprintf(linepos, remaining, "%u-%u%s", lo, hi, lastrange ? "" : ","); - - if (ret < 0) { - err = errno; - D_ERROR("rank set could not be serialized: %s (%d)\n", strerror(err), err); - break; - } - - if (ret >= remaining) { - err = EOVERFLOW; - D_WARN("rank set has been partially serialized\n"); - break; - } - - remaining -= ret; - linepos += ret; + len = snprintf(linepos, remaining, "%u-%u%s", lo, hi, lastrange ? "" : ","); + if (len < 0) + D_GOTO(error, rc = -DER_INVAL); + if (len >= remaining) + D_GOTO(error, rc = -DER_TRUNC); + + remaining -= len; + linepos += len; } memcpy(linepos, "]", 2u); - if (err != 0) - *truncated = true; + *ranks_str = line; + D_GOTO(out, rc = -DER_SUCCESS); - return line; +error: + D_FREE(line); +out: + return rc; } void diff --git a/src/gurt/tests/test_gurt.c b/src/gurt/tests/test_gurt.c index 40f9256e724..9db9785981a 100644 --- a/src/gurt/tests/test_gurt.c +++ b/src/gurt/tests/test_gurt.c @@ -2510,6 +2510,125 @@ test_d_setenv(void **state) assert_false(d_isenv_def("foo")); } +static void +test_d_rank_range_list_create_from_ranks(void **state) +{ + d_rank_list_t *ranks; + d_rank_range_list_t *range_list; + + (void)state; /* unused */ + + // Test with empty list + ranks = d_rank_list_alloc(0); + assert_non_null(ranks); + + range_list = d_rank_range_list_create_from_ranks(ranks); + assert_non_null(range_list); + assert_int_equal(range_list->rrl_nr, 0); + + d_rank_range_list_free(range_list); + d_rank_list_free(ranks); + + // Test with one rank + ranks = d_rank_list_alloc(1); + assert_non_null(ranks); + ranks->rl_ranks[0] = 2; + + range_list = d_rank_range_list_create_from_ranks(ranks); + assert_non_null(range_list); + assert_int_equal(range_list->rrl_nr, 1); + assert_int_equal(range_list->rrl_ranges[0].lo, 2); + assert_int_equal(range_list->rrl_ranges[0].hi, 2); + + d_rank_range_list_free(range_list); + d_rank_list_free(ranks); + + // Test with 4 ranks and two ranges + ranks = d_rank_list_alloc(4); + assert_non_null(ranks); + ranks->rl_ranks[0] = 2; + ranks->rl_ranks[1] = 1; + ranks->rl_ranks[2] = 5; + ranks->rl_ranks[3] = 3; + + range_list = d_rank_range_list_create_from_ranks(ranks); + assert_non_null(range_list); + assert_int_equal(range_list->rrl_nr, 2); + assert_int_equal(range_list->rrl_ranges[0].lo, 1); + assert_int_equal(range_list->rrl_ranges[0].hi, 3); + assert_int_equal(range_list->rrl_ranges[1].lo, 5); + assert_int_equal(range_list->rrl_ranges[1].hi, 5); + + d_rank_range_list_free(range_list); + d_rank_list_free(ranks); +} + +static void +test_d_rank_range_list_str(void **state) +{ + d_rank_range_list_t *range_list; + char *ranks_str = NULL; + int i; + int rc; + + (void)state; /* unused */ + + // Test with empty list + range_list = d_rank_range_list_alloc(0); + assert_non_null(range_list); + + rc = d_rank_range_list_str(range_list, &ranks_str); + assert_int_equal(rc, 0); + assert_string_equal(ranks_str, "[]"); + + D_FREE(ranks_str); + d_rank_range_list_free(range_list); + + // Test with one rank + range_list = d_rank_range_list_alloc(1); + assert_non_null(range_list); + range_list->rrl_ranges[0].lo = 2; + range_list->rrl_ranges[0].hi = 2; + + rc = d_rank_range_list_str(range_list, &ranks_str); + assert_int_equal(rc, 0); + assert_string_equal(ranks_str, "[2]"); + + D_FREE(ranks_str); + ranks_str = NULL; + d_rank_range_list_free(range_list); + + // Test with 4 ranks and two ranges + range_list = d_rank_range_list_alloc(2); + assert_non_null(range_list); + range_list->rrl_ranges[0].lo = 1; + range_list->rrl_ranges[0].hi = 3; + range_list->rrl_ranges[1].lo = 5; + range_list->rrl_ranges[1].hi = 5; + + rc = d_rank_range_list_str(range_list, &ranks_str); + assert_int_equal(rc, 0); + assert_string_equal(ranks_str, "[1-3,5]"); + + D_FREE(ranks_str); + ranks_str = NULL; + d_rank_range_list_free(range_list); + + // Test truncate error + range_list = d_rank_range_list_alloc(1024); + assert_non_null(range_list); + for (i = 0; i < 1024; ++i) { + range_list->rrl_ranges[i].lo = i; + range_list->rrl_ranges[i].hi = i; + } + + rc = d_rank_range_list_str(range_list, &ranks_str); + assert_int_equal(rc, -DER_TRUNC); + assert_null(ranks_str); + + d_rank_range_list_free(range_list); +} + int main(int argc, char **argv) { @@ -2546,7 +2665,9 @@ main(int argc, char **argv) teardown_getenv_mocks), cmocka_unit_test_setup_teardown(test_d_getenv_uint64_t, setup_getenv_mocks, teardown_getenv_mocks), - cmocka_unit_test(test_d_setenv)}; + cmocka_unit_test(test_d_setenv), + cmocka_unit_test(test_d_rank_range_list_create_from_ranks), + cmocka_unit_test(test_d_rank_range_list_str)}; d_register_alt_assert(mock_assert); diff --git a/src/include/daos_srv/pool.h b/src/include/daos_srv/pool.h index 8c63e469beb..08a166464c9 100644 --- a/src/include/daos_srv/pool.h +++ b/src/include/daos_srv/pool.h @@ -303,9 +303,11 @@ int dsc_pool_svc_delete_acl(uuid_t pool_uuid, d_rank_list_t *ranks, uint64_t dea enum daos_acl_principal_type principal_type, const char *principal_name); -int dsc_pool_svc_query(uuid_t pool_uuid, d_rank_list_t *ps_ranks, uint64_t deadline, - d_rank_list_t **ranks, daos_pool_info_t *pool_info, - uint32_t *pool_layout_ver, uint32_t *upgrade_layout_ver); +int + dsc_pool_svc_query(uuid_t pool_uuid, d_rank_list_t *ps_ranks, uint64_t deadline, + d_rank_list_t **enabled_ranks, d_rank_list_t **disabled_ranks, + daos_pool_info_t *pool_info, uint32_t *pool_layout_ver, + uint32_t *upgrade_layout_ver); int dsc_pool_svc_query_target(uuid_t pool_uuid, d_rank_list_t *ps_ranks, uint64_t deadline, d_rank_t rank, uint32_t tgt_idx, daos_target_info_t *ti); diff --git a/src/include/gurt/common.h b/src/include/gurt/common.h index 8dec9ea9871..329495af0d9 100644 --- a/src/include/gurt/common.h +++ b/src/include/gurt/common.h @@ -486,7 +486,8 @@ char *d_rank_list_to_str(d_rank_list_t *rank_list); d_rank_range_list_t *d_rank_range_list_alloc(uint32_t size); d_rank_range_list_t *d_rank_range_list_realloc(d_rank_range_list_t *range_list, uint32_t size); d_rank_range_list_t *d_rank_range_list_create_from_ranks(d_rank_list_t *rank_list); -char *d_rank_range_list_str(d_rank_range_list_t *list, bool *truncated); +int + d_rank_range_list_str(d_rank_range_list_t *list, char **ranks_str); void d_rank_range_list_free(d_rank_range_list_t *range_list); #ifdef FAULT_INJECTION diff --git a/src/mgmt/srv_drpc.c b/src/mgmt/srv_drpc.c index 5d41d42afcc..2b806796e36 100644 --- a/src/mgmt/srv_drpc.c +++ b/src/mgmt/srv_drpc.c @@ -394,7 +394,7 @@ static int pool_create_fill_resp(Mgmt__PoolCreateResp *resp, uuid_t uuid, d_rank D_DEBUG(DB_MGMT, "%d service replicas\n", svc_ranks->rl_nr); - rc = ds_mgmt_pool_query(uuid, svc_ranks, &enabled_ranks, &pool_info, NULL, NULL); + rc = ds_mgmt_pool_query(uuid, svc_ranks, &enabled_ranks, NULL, &pool_info, NULL, NULL); if (rc != 0) { D_ERROR("Failed to query created pool: rc=%d\n", rc); D_GOTO(out, rc); @@ -1731,30 +1731,61 @@ pool_query_free_tier_stats(Mgmt__PoolQueryResp *resp) resp->n_tier_stats = 0; } +static int +rank_list_to_str(d_rank_list_t *ranks, char **ranks_str) +{ + d_rank_range_list_t *range_list = NULL; + char *range_list_str; + int rc; + + D_ASSERT(ranks_str != NULL); + + if (ranks == NULL) { + range_list_str = NULL; + D_GOTO(out, rc = -DER_SUCCESS); + } + + range_list = d_rank_range_list_create_from_ranks(ranks); + if (range_list == NULL) + D_GOTO(error, rc = -DER_NOMEM); + + rc = d_rank_range_list_str(range_list, &range_list_str); + if (rc != -DER_SUCCESS) + D_GOTO(error, rc = rc); + +out: + *ranks_str = range_list_str; + +error: + d_rank_range_list_free(range_list); + + return rc; +} + void ds_mgmt_drpc_pool_query(Drpc__Call *drpc_req, Drpc__Response *drpc_resp) { - struct drpc_alloc alloc = PROTO_ALLOCATOR_INIT(alloc); - int rc = 0; - Mgmt__PoolQueryReq *req; - Mgmt__PoolQueryResp resp = MGMT__POOL_QUERY_RESP__INIT; - Mgmt__StorageUsageStats scm = MGMT__STORAGE_USAGE_STATS__INIT; - Mgmt__StorageUsageStats nvme = MGMT__STORAGE_USAGE_STATS__INIT; - Mgmt__PoolRebuildStatus rebuild = MGMT__POOL_REBUILD_STATUS__INIT; - uuid_t uuid; - daos_pool_info_t pool_info = {0}; - d_rank_list_t *svc_ranks; - d_rank_list_t *ranks; - d_rank_range_list_t *range_list; - char *range_list_str = NULL; - bool truncated; - size_t len; - uint8_t *body; + struct drpc_alloc alloc = PROTO_ALLOCATOR_INIT(alloc); + int rc = 0; + Mgmt__PoolQueryReq *req; + Mgmt__PoolQueryResp resp = MGMT__POOL_QUERY_RESP__INIT; + Mgmt__StorageUsageStats scm = MGMT__STORAGE_USAGE_STATS__INIT; + Mgmt__StorageUsageStats nvme = MGMT__STORAGE_USAGE_STATS__INIT; + Mgmt__PoolRebuildStatus rebuild = MGMT__POOL_REBUILD_STATUS__INIT; + uuid_t uuid; + daos_pool_info_t pool_info = {0}; + d_rank_list_t *svc_ranks = NULL; + d_rank_list_t *enabled_ranks = NULL; + d_rank_list_t *disabled_ranks = NULL; + char *enabled_ranks_str = NULL; + char *disabled_ranks_str = NULL; + size_t len; + uint8_t *body; req = mgmt__pool_query_req__unpack(&alloc.alloc, drpc_req->body.len, drpc_req->body.data); if (alloc.oom || req == NULL) { - D_ERROR("Failed to unpack pool query req\n"); + D_ERROR("Failed to unpack pool query req"); drpc_resp->status = DRPC__STATUS__FAILED_UNMARSHAL_PAYLOAD; return; } @@ -1762,58 +1793,61 @@ ds_mgmt_drpc_pool_query(Drpc__Call *drpc_req, Drpc__Response *drpc_resp) D_INFO("Received request to query DAOS pool %s\n", req->id); if (uuid_parse(req->id, uuid) != 0) { - rc = -DER_INVAL; - DL_ERROR(rc, "Pool UUID is invalid"); - goto out; - } - - /* TODO (DAOS-10250) Enabled and disabled engines should be retrieve both if needed */ - if (req->query_mask & DPI_ENGINES_ENABLED && req->query_mask & DPI_ENGINES_DISABLED) { - D_ERROR("cannot query enabled and disabled engines in the same request\n"); - D_GOTO(out, rc = -DER_NOTSUPPORTED); + DL_ERROR(-DER_INVAL, "Pool UUID is invalid"); + D_GOTO(error, rc = -DER_INVAL); } svc_ranks = uint32_array_to_rank_list(req->svc_ranks, req->n_svc_ranks); if (svc_ranks == NULL) - D_GOTO(out, rc = -DER_NOMEM); + D_GOTO(error, rc = -DER_NOMEM); pool_info.pi_bits = req->query_mask; - rc = ds_mgmt_pool_query(uuid, svc_ranks, &ranks, &pool_info, &resp.pool_layout_ver, - &resp.upgrade_layout_ver); + rc = ds_mgmt_pool_query(uuid, svc_ranks, &enabled_ranks, &disabled_ranks, &pool_info, + &resp.pool_layout_ver, &resp.upgrade_layout_ver); if (rc != 0) { - D_ERROR("Failed to query the pool, rc=%d\n", rc); - goto out_svc_ranks; + DL_ERROR(rc, DF_UUID ": Failed to query the pool", DP_UUID(uuid)); + D_GOTO(error, rc = rc); } - /* Calculate and stringify rank ranges to return to control plane for display */ - range_list = d_rank_range_list_create_from_ranks(ranks); - if (range_list == NULL) - D_GOTO(out_ranks, rc = -DER_NOMEM); - range_list_str = d_rank_range_list_str(range_list, &truncated); - if (range_list_str == NULL) - D_GOTO(out_ranges, rc = -DER_NOMEM); - D_DEBUG(DB_MGMT, DF_UUID": %s ranks: %s%s\n", DP_UUID(uuid), - pool_info.pi_bits & DPI_ENGINES_ENABLED ? "ENABLED" : "DISABLED", range_list_str, - truncated ? " ...(TRUNCATED)" : ""); + rc = rank_list_to_str(enabled_ranks, &enabled_ranks_str); + if (rc != -DER_SUCCESS) { + DL_ERROR(rc, DF_UUID ": Failed to serialize the list of enabled ranks", + DP_UUID(uuid)); + D_GOTO(error, rc = rc); + } + if (enabled_ranks_str != NULL) + D_DEBUG(DB_MGMT, DF_UUID ": list of enabled ranks: %s", DP_UUID(uuid), + enabled_ranks_str); + + rc = rank_list_to_str(disabled_ranks, &disabled_ranks_str); + if (rc != -DER_SUCCESS) { + DL_ERROR(rc, DF_UUID ": Failed to serialize the list of disabled ranks", + DP_UUID(uuid)); + D_GOTO(error, rc = rc); + } + if (disabled_ranks_str != NULL) + D_DEBUG(DB_MGMT, DF_UUID ": list of disabled ranks: %s", DP_UUID(uuid), + disabled_ranks_str); /* Populate the response */ resp.query_mask = pool_info.pi_bits; - resp.uuid = req->id; - resp.total_targets = pool_info.pi_ntargets; + resp.uuid = req->id; + resp.total_targets = pool_info.pi_ntargets; resp.disabled_targets = pool_info.pi_ndisabled; - resp.active_targets = pool_info.pi_space.ps_ntargets; - resp.total_engines = pool_info.pi_nnodes; - resp.svc_ldr = pool_info.pi_leader; + resp.active_targets = pool_info.pi_space.ps_ntargets; + resp.total_engines = pool_info.pi_nnodes; + resp.svc_ldr = pool_info.pi_leader; resp.svc_reps = req->svc_ranks; resp.n_svc_reps = req->n_svc_ranks; - resp.version = pool_info.pi_map_ver; - resp.enabled_ranks = (req->query_mask & DPI_ENGINES_ENABLED) ? range_list_str : ""; - resp.disabled_ranks = (req->query_mask & DPI_ENGINES_DISABLED) ? range_list_str : ""; + resp.version = pool_info.pi_map_ver; + if (enabled_ranks_str != NULL) + resp.enabled_ranks = enabled_ranks_str; + if (disabled_ranks_str != NULL) + resp.disabled_ranks = disabled_ranks_str; D_ALLOC_ARRAY(resp.tier_stats, DAOS_MEDIA_MAX); - if (resp.tier_stats == NULL) { - D_GOTO(out_ranges, rc = -DER_NOMEM); - } + if (resp.tier_stats == NULL) + D_GOTO(error, rc = -DER_NOMEM); storage_usage_stats_from_pool_space(&scm, &pool_info.pi_space, DAOS_MEDIA_SCM); @@ -1828,13 +1862,7 @@ ds_mgmt_drpc_pool_query(Drpc__Call *drpc_req, Drpc__Response *drpc_resp) pool_rebuild_status_from_info(&rebuild, &pool_info.pi_rebuild_st); resp.rebuild = &rebuild; -out_ranges: - d_rank_range_list_free(range_list); -out_ranks: - d_rank_list_free(ranks); -out_svc_ranks: - d_rank_list_free(svc_ranks); -out: +error: resp.status = rc; len = mgmt__pool_query_resp__get_packed_size(&resp); @@ -1847,10 +1875,13 @@ ds_mgmt_drpc_pool_query(Drpc__Call *drpc_req, Drpc__Response *drpc_resp) drpc_resp->body.data = body; } - D_FREE(range_list_str); - mgmt__pool_query_req__free_unpacked(req, &alloc.alloc); + d_rank_list_free(enabled_ranks); + D_FREE(enabled_ranks_str); + d_rank_list_free(disabled_ranks); + D_FREE(disabled_ranks_str); + d_rank_list_free(svc_ranks); pool_query_free_tier_stats(&resp); } diff --git a/src/mgmt/srv_internal.h b/src/mgmt/srv_internal.h index 1667765ff02..df31a993403 100644 --- a/src/mgmt/srv_internal.h +++ b/src/mgmt/srv_internal.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 2016-2023 Intel Corporation. + * (C) Copyright 2016-2024 Intel Corporation. * * SPDX-License-Identifier: BSD-2-Clause-Patent */ @@ -111,9 +111,10 @@ int ds_mgmt_pool_delete_acl(uuid_t pool_uuid, d_rank_list_t *svc_ranks, int ds_mgmt_pool_list_cont(uuid_t uuid, d_rank_list_t *svc_ranks, struct daos_pool_cont_info **containers, uint64_t *ncontainers); -int ds_mgmt_pool_query(uuid_t pool_uuid, d_rank_list_t *svc_ranks, d_rank_list_t **ranks, - daos_pool_info_t *pool_info, uint32_t *pool_layout_ver, - uint32_t *upgrade_layout_ver); +int + ds_mgmt_pool_query(uuid_t pool_uuid, d_rank_list_t *svc_ranks, d_rank_list_t **enabled_ranks, + d_rank_list_t **disabled_ranks, daos_pool_info_t *pool_info, + uint32_t *pool_layout_ver, uint32_t *upgrade_layout_ver); int ds_mgmt_pool_query_targets(uuid_t pool_uuid, d_rank_list_t *svc_ranks, d_rank_t rank, d_rank_list_t *tgts, daos_target_info_t **infos); diff --git a/src/mgmt/srv_pool.c b/src/mgmt/srv_pool.c index c1eb018cdb1..bde2a6e37ee 100644 --- a/src/mgmt/srv_pool.c +++ b/src/mgmt/srv_pool.c @@ -389,13 +389,8 @@ ds_mgmt_pool_list_cont(uuid_t uuid, d_rank_list_t *svc_ranks, * * \param[in] pool_uuid UUID of the pool. * \param[in] svc_ranks Ranks of pool svc replicas. - * \param[out] ranks Optional, returned storage ranks in this pool. - * If #pool_info is NULL, engines with disabled targets. - * If #pool_info is passed, engines with enabled or - * disabled targets according to - * #pi_bits (DPI_ENGINES_ENABLED bit). - * Note: ranks may be empty (i.e., *ranks->rl_nr may be 0). - * The caller must free the list with d_rank_list_free(). + * \param[out] enabled_ranks Optional, returned storage ranks with enabled targets. + * \param[out] disabled_ranks Optional, returned storage ranks with disabled targets. * \param[in][out] pool_info Query results * \param[in][out] pool_layout_ver Pool global version * \param[in][out] upgrade_layout_ver Latest pool global version this pool might be upgraded @@ -405,9 +400,9 @@ ds_mgmt_pool_list_cont(uuid_t uuid, d_rank_list_t *svc_ranks, * Negative value Other error */ int -ds_mgmt_pool_query(uuid_t pool_uuid, d_rank_list_t *svc_ranks, d_rank_list_t **ranks, - daos_pool_info_t *pool_info, uint32_t *pool_layout_ver, - uint32_t *upgrade_layout_ver) +ds_mgmt_pool_query(uuid_t pool_uuid, d_rank_list_t *svc_ranks, d_rank_list_t **enabled_ranks, + d_rank_list_t **disabled_ranks, daos_pool_info_t *pool_info, + uint32_t *pool_layout_ver, uint32_t *upgrade_layout_ver) { if (pool_info == NULL) { D_ERROR("pool_info was NULL\n"); @@ -416,8 +411,8 @@ ds_mgmt_pool_query(uuid_t pool_uuid, d_rank_list_t *svc_ranks, d_rank_list_t **r D_DEBUG(DB_MGMT, "Querying pool "DF_UUID"\n", DP_UUID(pool_uuid)); - return dsc_pool_svc_query(pool_uuid, svc_ranks, mgmt_ps_call_deadline(), ranks, pool_info, - pool_layout_ver, upgrade_layout_ver); + return dsc_pool_svc_query(pool_uuid, svc_ranks, mgmt_ps_call_deadline(), enabled_ranks, + disabled_ranks, pool_info, pool_layout_ver, upgrade_layout_ver); } /** diff --git a/src/mgmt/tests/mocks.c b/src/mgmt/tests/mocks.c index 3b62d64d6a5..fa3ebed0417 100644 --- a/src/mgmt/tests/mocks.c +++ b/src/mgmt/tests/mocks.c @@ -1,5 +1,5 @@ /* - * (C) Copyright 2019-2023 Intel Corporation. + * (C) Copyright 2019-2024 Intel Corporation. * * SPDX-License-Identifier: BSD-2-Clause-Patent */ @@ -274,17 +274,18 @@ void mock_ds_mgmt_pool_list_cont_teardown(void) } } -int ds_mgmt_pool_query_return; -uuid_t ds_mgmt_pool_query_uuid; -daos_pool_info_t ds_mgmt_pool_query_info_out; -daos_pool_info_t ds_mgmt_pool_query_info_in; -void *ds_mgmt_pool_query_info_ptr; -d_rank_list_t *ds_mgmt_pool_query_ranks_out; +int ds_mgmt_pool_query_return; +uuid_t ds_mgmt_pool_query_uuid; +daos_pool_info_t ds_mgmt_pool_query_info_out; +daos_pool_info_t ds_mgmt_pool_query_info_in; +void *ds_mgmt_pool_query_info_ptr; +d_rank_list_t *ds_mgmt_pool_query_enabled_ranks_out; +d_rank_list_t *ds_mgmt_pool_query_disabled_ranks_out; int -ds_mgmt_pool_query(uuid_t pool_uuid, d_rank_list_t *svc_ranks, d_rank_list_t **ranks, - daos_pool_info_t *pool_info, uint32_t *pool_layout_ver, - uint32_t *upgrade_layout_ver) +ds_mgmt_pool_query(uuid_t pool_uuid, d_rank_list_t *svc_ranks, d_rank_list_t **enabled_ranks, + d_rank_list_t **disabled_ranks, daos_pool_info_t *pool_info, + uint32_t *pool_layout_ver, uint32_t *upgrade_layout_ver) { /* If function is to return with an error, pool_info and ranks will not be filled. */ if (ds_mgmt_pool_query_return != 0) @@ -292,13 +293,21 @@ ds_mgmt_pool_query(uuid_t pool_uuid, d_rank_list_t *svc_ranks, d_rank_list_t **r uuid_copy(ds_mgmt_pool_query_uuid, pool_uuid); ds_mgmt_pool_query_info_ptr = (void *)pool_info; + if (pool_info != NULL && (pool_info->pi_bits & DPI_ENGINES_ENABLED) != 0) { + D_ASSERT(enabled_ranks != NULL); + + *enabled_ranks = d_rank_list_alloc(8); /* 0-7 ; caller must free this */ + ds_mgmt_pool_query_enabled_ranks_out = *enabled_ranks; + } + if (pool_info != NULL && (pool_info->pi_bits & DPI_ENGINES_DISABLED) != 0) { + D_ASSERT(disabled_ranks != NULL); + + *disabled_ranks = d_rank_list_alloc(4); /* 0-4 ; caller must free this */ + ds_mgmt_pool_query_disabled_ranks_out = *disabled_ranks; + } if (pool_info != NULL) { ds_mgmt_pool_query_info_in = *pool_info; - *pool_info = ds_mgmt_pool_query_info_out; - } - if (ranks != NULL) { - *ranks = d_rank_list_alloc(8); /* 0-7 ; caller must free this */ - ds_mgmt_pool_query_ranks_out = *ranks; + *pool_info = ds_mgmt_pool_query_info_out; } return ds_mgmt_pool_query_return; /* 0 */ } @@ -310,7 +319,8 @@ mock_ds_mgmt_pool_query_setup(void) uuid_clear(ds_mgmt_pool_query_uuid); ds_mgmt_pool_query_info_ptr = NULL; memset(&ds_mgmt_pool_query_info_out, 0, sizeof(daos_pool_info_t)); - ds_mgmt_pool_query_ranks_out = NULL; + ds_mgmt_pool_query_enabled_ranks_out = NULL; + ds_mgmt_pool_query_disabled_ranks_out = NULL; } int ds_mgmt_pool_query_targets_return; diff --git a/src/mgmt/tests/mocks.h b/src/mgmt/tests/mocks.h index 385986f6dda..f8d83b4b680 100644 --- a/src/mgmt/tests/mocks.h +++ b/src/mgmt/tests/mocks.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 2019-2022 Intel Corporation. + * (C) Copyright 2019-2024 Intel Corporation. * * SPDX-License-Identifier: BSD-2-Clause-Patent */ @@ -103,12 +103,14 @@ void mock_ds_mgmt_pool_extend_setup(void); /* * Mock ds_mgmt_pool_query */ -extern int ds_mgmt_pool_query_return; -extern uuid_t ds_mgmt_pool_query_uuid; -extern daos_pool_info_t ds_mgmt_pool_query_info_in; -extern daos_pool_info_t ds_mgmt_pool_query_info_out; -extern void *ds_mgmt_pool_query_info_ptr; -extern d_rank_list_t *ds_mgmt_pool_query_ranks_out; +extern int ds_mgmt_pool_query_return; +extern uuid_t ds_mgmt_pool_query_uuid; +extern daos_pool_info_t ds_mgmt_pool_query_info_in; +extern daos_pool_info_t ds_mgmt_pool_query_info_out; +extern void *ds_mgmt_pool_query_info_ptr; +extern d_rank_list_t *ds_mgmt_pool_query_enabled_ranks_out; +extern d_rank_list_t *ds_mgmt_pool_query_disabled_ranks_out; + void mock_ds_mgmt_pool_query_setup(void); /* diff --git a/src/mgmt/tests/srv_drpc_tests.c b/src/mgmt/tests/srv_drpc_tests.c index 4d93b5e6728..25bb811997c 100644 --- a/src/mgmt/tests/srv_drpc_tests.c +++ b/src/mgmt/tests/srv_drpc_tests.c @@ -1269,22 +1269,6 @@ expect_drpc_pool_query_resp_with_error(Drpc__Response *resp, int expected_err) mgmt__pool_query_resp__free_unpacked(pq_resp, NULL); } -static void -test_drpc_pool_query_incompat_ranks_flags(void **state) -{ - Drpc__Call call = DRPC__CALL__INIT; - Drpc__Response resp = DRPC__RESPONSE__INIT; - - setup_pool_query_drpc_call(&call, TEST_UUID, DPI_ENGINES_DISABLED | DPI_ENGINES_ENABLED); - - ds_mgmt_drpc_pool_query(&call, &resp); - - expect_drpc_pool_query_resp_with_error(&resp, -DER_NOTSUPPORTED); - - D_FREE(call.body.data); - D_FREE(resp.body.data); -} - static void test_drpc_pool_query_bad_uuid(void **state) { @@ -1429,7 +1413,7 @@ test_drpc_pool_query_success(void **state) init_test_rebuild_status(&exp_info.pi_rebuild_st); ds_mgmt_pool_query_info_out = exp_info; - setup_pool_query_drpc_call(&call, TEST_UUID, DPI_ENGINES_ENABLED); + setup_pool_query_drpc_call(&call, TEST_UUID, DPI_ENGINES_ENABLED | DPI_ENGINES_DISABLED); ds_mgmt_drpc_pool_query(&call, &resp); @@ -1438,9 +1422,10 @@ test_drpc_pool_query_success(void **state) return; assert_int_equal(uuid_compare(exp_uuid, ds_mgmt_pool_query_uuid), 0); assert_non_null(ds_mgmt_pool_query_info_ptr); - assert_non_null(ds_mgmt_pool_query_ranks_out); + assert_non_null(ds_mgmt_pool_query_enabled_ranks_out); + assert_non_null(ds_mgmt_pool_query_disabled_ranks_out); assert_int_equal(ds_mgmt_pool_query_info_in.pi_bits, - DEFAULT_QUERY_BITS | DPI_ENGINES_ENABLED); + DEFAULT_QUERY_BITS | DPI_ENGINES_ENABLED | DPI_ENGINES_DISABLED); expect_query_resp_with_info(&exp_info, MGMT__POOL_REBUILD_STATUS__STATE__IDLE, @@ -3111,7 +3096,6 @@ main(void) POOL_EXTEND_TEST(test_drpc_extend_mgmt_svc_fails), POOL_EXTEND_TEST(test_drpc_extend_success), REINTEGRATE_TEST(test_drpc_reintegrate_bad_uuid), - QUERY_TEST(test_drpc_pool_query_incompat_ranks_flags), QUERY_TEST(test_drpc_pool_query_bad_uuid), QUERY_TEST(test_drpc_pool_query_mgmt_svc_fails), QUERY_TEST(test_drpc_pool_query_success), diff --git a/src/pool/srv_cli.c b/src/pool/srv_cli.c index 1decb57b3ec..1dfd0d57fcc 100644 --- a/src/pool/srv_cli.c +++ b/src/pool/srv_cli.c @@ -1,5 +1,5 @@ /* - * (C) Copyright 2017-2023 Intel Corporation. + * (C) Copyright 2017-2024 Intel Corporation. * * SPDX-License-Identifier: BSD-2-Clause-Patent */ @@ -335,13 +335,14 @@ dsc_pool_svc_call(uuid_t uuid, d_rank_list_t *ranks, struct dsc_pool_svc_call_cb } struct pool_query_arg { - d_rank_list_t **pqa_ranks; - daos_pool_info_t *pqa_info; - uint32_t *pqa_layout_ver; - uint32_t *pqa_upgrade_layout_ver; - crt_bulk_t pqa_bulk; - struct pool_buf *pqa_map_buf; - uint32_t pqa_map_size; + d_rank_list_t **pqa_enabled_ranks; + d_rank_list_t **pqa_disabled_ranks; + daos_pool_info_t *pqa_info; + uint32_t *pqa_layout_ver; + uint32_t *pqa_upgrade_layout_ver; + crt_bulk_t pqa_bulk; + struct pool_buf *pqa_map_buf; + uint32_t pqa_map_size; }; static int @@ -367,46 +368,67 @@ pool_query_init(uuid_t pool_uuid, crt_rpc_t *rpc, void *varg) } static int -process_query_result(d_rank_list_t **ranks, daos_pool_info_t *info, uuid_t pool_uuid, - uint32_t map_version, uint32_t leader_rank, struct daos_pool_space *ps, +process_query_result(d_rank_list_t **enabled_ranks, d_rank_list_t **disabled_ranks, + daos_pool_info_t *info, uuid_t pool_uuid, uint32_t map_version, + uint32_t leader_rank, struct daos_pool_space *ps, struct daos_rebuild_status *rs, struct pool_buf *map_buf) { - struct pool_map *map; - int rc; - unsigned int num_disabled = 0; + struct pool_map *map = NULL; + unsigned int num_disabled = 0; + d_rank_list_t *enabled_rank_list = NULL; + d_rank_list_t *disabled_rank_list = NULL; + int rc; rc = pool_map_create(map_buf, map_version, &map); if (rc != 0) { - D_ERROR(DF_UUID": failed to create local pool map, "DF_RC"\n", - DP_UUID(pool_uuid), DP_RC(rc)); - return rc; + DL_ERROR(rc, DF_UUID ": failed to create local pool map", DP_UUID(pool_uuid)); + D_GOTO(error, rc = rc); } rc = pool_map_find_failed_tgts(map, NULL, &num_disabled); if (rc != 0) { - D_ERROR(DF_UUID": failed to get num disabled tgts, "DF_RC"\n", - DP_UUID(pool_uuid), DP_RC(rc)); - goto out; + DL_ERROR(rc, DF_UUID ": failed to get num disabled tgts", DP_UUID(pool_uuid)); + D_GOTO(error, rc = rc); } - info->pi_ndisabled = num_disabled; - if (ranks != NULL) { - bool get_enabled = (info ? ((info->pi_bits & DPI_ENGINES_ENABLED) != 0) : false); + if (info != NULL && (info->pi_bits & DPI_ENGINES_ENABLED) != 0) { + D_ASSERT(enabled_ranks != NULL); - rc = pool_map_get_ranks(pool_uuid, map, get_enabled, ranks); + rc = pool_map_get_ranks(pool_uuid, map, true, &enabled_rank_list); if (rc != 0) { - D_ERROR(DF_UUID": pool_map_get_ranks() failed, "DF_RC"\n", - DP_UUID(pool_uuid), DP_RC(rc)); - goto out; + DL_ERROR(rc, DF_UUID ": pool_map_get_ranks() failed", DP_UUID(pool_uuid)); + D_GOTO(error, rc = rc); } - D_DEBUG(DB_MD, DF_UUID": found %u %s ranks in pool map\n", - DP_UUID(pool_uuid), (*ranks)->rl_nr, get_enabled ? "ENABLED" : "DISABLED"); + D_DEBUG(DB_MD, DF_UUID ": found %" PRIu32 " enabled ranks in pool map", + DP_UUID(pool_uuid), enabled_rank_list->rl_nr); } - pool_query_reply_to_info(pool_uuid, map_buf, map_version, leader_rank, ps, rs, info); + if (info != NULL && (info->pi_bits & DPI_ENGINES_DISABLED) != 0) { + D_ASSERT(disabled_ranks != NULL); + rc = pool_map_get_ranks(pool_uuid, map, false, &disabled_rank_list); + if (rc != 0) { + DL_ERROR(rc, DF_UUID ": pool_map_get_ranks() failed", DP_UUID(pool_uuid)); + D_GOTO(error, rc = rc); + } + D_DEBUG(DB_MD, DF_UUID ": found %" PRIu32 " disabled ranks in pool map", + DP_UUID(pool_uuid), disabled_rank_list->rl_nr); + } + + pool_query_reply_to_info(pool_uuid, map_buf, map_version, leader_rank, ps, rs, info); + info->pi_ndisabled = num_disabled; + if (enabled_rank_list != NULL) + *enabled_ranks = enabled_rank_list; + if (disabled_rank_list != NULL) + *disabled_ranks = disabled_rank_list; + D_GOTO(out, rc = -DER_SUCCESS); + +error: + d_rank_list_free(disabled_rank_list); + d_rank_list_free(enabled_rank_list); out: - pool_map_decref(map); + if (map != NULL) + pool_map_decref(map); return rc; } @@ -432,9 +454,10 @@ pool_query_consume(uuid_t pool_uuid, crt_rpc_t *rpc, void *varg) D_DEBUG(DB_MGMT, DF_UUID": Successfully queried pool\n", DP_UUID(pool_uuid)); - rc = process_query_result(arg->pqa_ranks, arg->pqa_info, pool_uuid, - out->pqo_op.po_map_version, out->pqo_op.po_hint.sh_rank, - &out->pqo_space, &out->pqo_rebuild_st, arg->pqa_map_buf); + rc = + process_query_result(arg->pqa_enabled_ranks, arg->pqa_disabled_ranks, arg->pqa_info, + pool_uuid, out->pqo_op.po_map_version, out->pqo_op.po_hint.sh_rank, + &out->pqo_space, &out->pqo_rebuild_st, arg->pqa_map_buf); if (arg->pqa_layout_ver) *arg->pqa_layout_ver = out->pqo_pool_layout_ver; if (arg->pqa_upgrade_layout_ver) @@ -468,12 +491,8 @@ static struct dsc_pool_svc_call_cbs pool_query_cbs = { * \param[in] pool_uuid UUID of the pool * \param[in] ps_ranks Ranks of pool svc replicas * \param[in] deadline Unix time deadline in milliseconds - * \param[out] ranks Optional, returned storage ranks in this pool. - * If #pool_info is NULL, engines with disabled targets. - * If #pool_info is passed, engines with enabled or disabled - * targets according to #pi_bits (DPI_ENGINES_ENABLED bit). - * Note: ranks may be empty (i.e., *ranks->rl_nr may be 0). - * The caller must free the list with d_rank_list_free(). + * \param[out] enabled_ranks Optional, returned storage ranks with enabled targets. + * \param[out] disabled_ranks Optional, returned storage ranks with disabled targets. * \param[out] pool_info Results of the pool query * \param[out] pool_layout_ver Results of the current pool global version * \param[out] pool_upgrade_layout_ver Results of the target latest pool global version @@ -481,18 +500,23 @@ static struct dsc_pool_svc_call_cbs pool_query_cbs = { * \return 0 Success * -DER_INVAL Invalid input * Negative value Error + * + * \note The enabled_ranks and disabled_ranks may be empty (i.e., *ranks->rl_nr may be 0). + * \note The caller must free the lists enabled_ranks and disabled_ranks with d_rank_list_free(). */ int dsc_pool_svc_query(uuid_t pool_uuid, d_rank_list_t *ps_ranks, uint64_t deadline, - d_rank_list_t **ranks, daos_pool_info_t *pool_info, uint32_t *pool_layout_ver, + d_rank_list_t **enabled_ranks, d_rank_list_t **disabled_ranks, + daos_pool_info_t *pool_info, uint32_t *pool_layout_ver, uint32_t *upgrade_layout_ver) { struct pool_query_arg arg = { - .pqa_ranks = ranks, - .pqa_info = pool_info, - .pqa_layout_ver = pool_layout_ver, - .pqa_upgrade_layout_ver = upgrade_layout_ver, - .pqa_map_size = 127 /* 4 KB */ + .pqa_enabled_ranks = enabled_ranks, + .pqa_disabled_ranks = disabled_ranks, + .pqa_info = pool_info, + .pqa_layout_ver = pool_layout_ver, + .pqa_upgrade_layout_ver = upgrade_layout_ver, + .pqa_map_size = 127 /* 4 KB */ }; return dsc_pool_svc_call(pool_uuid, ps_ranks, &pool_query_cbs, &arg, deadline); diff --git a/src/tests/ftest/control/dmg_pool_query_ranks.py b/src/tests/ftest/control/dmg_pool_query_ranks.py index d0cadef0754..92ad0614a20 100644 --- a/src/tests/ftest/control/dmg_pool_query_ranks.py +++ b/src/tests/ftest/control/dmg_pool_query_ranks.py @@ -1,5 +1,5 @@ """ - (C) Copyright 2022-2023 Intel Corporation. + (C) Copyright 2022-2024 Intel Corporation. SPDX-License-Identifier: BSD-2-Clause-Patent """ @@ -71,27 +71,16 @@ def test_pool_query_ranks_basic(self): "Invalid disabled_ranks field: want=[], got={}".format( data['response']['disabled_ranks'])) - def test_pool_query_ranks_error(self): - """Test that ranks state option are mutually exclusive. - - Test Description: - Check that options '--show-enabled' and '--show-disabled" are mutually exclusive. - - :avocado: tags=all,daily_regression - :avocado: tags=vm - :avocado: tags=dmg,control,pool_query,pool_query_ranks - :avocado: tags=DmgPoolQueryRanks,test_pool_query_ranks_error - """ - self.log.info("Tests of pool query with incompatible options") - - # Disable raising an exception if the dmg command fails - self.dmg.exit_status_exception = False - try: - data = self.dmg.pool_query(self.pool.identifier, show_enabled=True, show_disabled=True) - self.assertIsNotNone(data["error"], "Expected error not returned") - self.assertIn(r'may not be mixed with', str(data['error']), "Invalid error message") - finally: - self.dmg.exit_status_exception = True + self.log.debug("Checking enabled and disabled ranks state information") + data = self.dmg.pool_query(self.pool.identifier, show_enabled=True, show_disabled=True) + self.assertListEqual( + data['response']['enabled_ranks'], [0, 1, 2], + "Invalid enabled_ranks field: want=[0, 1, 2], got={}".format( + data['response']['enabled_ranks'])) + self.assertListEqual( + data['response']['disabled_ranks'], [], + "Invalid disabled_ranks field: want=[], got={}".format( + data['response']['disabled_ranks'])) def test_pool_query_ranks_mgmt(self): """Test the state of ranks after excluding and reintegrate them. @@ -121,14 +110,12 @@ def test_pool_query_ranks_mgmt(self): disabled_ranks = sorted(disabled_ranks + [rank]) self.log.debug("Checking enabled ranks state information") - data = self.dmg.pool_query(self.pool.identifier, show_enabled=True) + data = self.dmg.pool_query( + self.pool.identifier, show_enabled=True, show_disabled=True) self.assertListEqual( data['response']['enabled_ranks'], enabled_ranks, "Invalid enabled_ranks field: want={}, got={}".format( enabled_ranks, data['response']['enabled_ranks'])) - - self.log.debug("Checking disabled ranks state information") - data = self.dmg.pool_query(self.pool.identifier, show_disabled=True) self.assertListEqual( data['response']['disabled_ranks'], disabled_ranks, "Invalid disabled_ranks field: want={}, got={}".format( @@ -158,14 +145,11 @@ def test_pool_query_ranks_mgmt(self): disabled_ranks.remove(rank) self.log.debug("Checking enabled ranks state information") - data = self.dmg.pool_query(self.pool.identifier, show_enabled=True) + data = self.dmg.pool_query(self.pool.identifier, show_enabled=True, show_disabled=True) self.assertListEqual( data['response']['enabled_ranks'], enabled_ranks, "Invalid enabled_ranks field: want={}, got={}".format( enabled_ranks, data['response']['enabled_ranks'])) - - self.log.debug("Checking disabled ranks state information") - data = self.dmg.pool_query(self.pool.identifier, show_disabled=True) self.assertListEqual( data['response']['disabled_ranks'], disabled_ranks, "Invalid disabled_ranks field: want={}, got={}".format(