diff --git a/src/chk/chk_common.c b/src/chk/chk_common.c index 4f4bc5bf682..608ea45d53c 100644 --- a/src/chk/chk_common.c +++ b/src/chk/chk_common.c @@ -902,6 +902,8 @@ chk_prop_prepare(d_rank_t leader, uint32_t flags, int phase, int i; prop->cp_leader = leader; + if (!(flags & CHK__CHECK_FLAG__CF_DRYRUN)) + prop->cp_flags &= ~CHK__CHECK_FLAG__CF_DRYRUN; if (flags & CHK__CHECK_FLAG__CF_NO_FAILOUT) prop->cp_flags &= ~CHK__CHECK_FLAG__CF_FAILOUT; if (flags & CHK__CHECK_FLAG__CF_NO_AUTO) diff --git a/src/chk/chk_engine.c b/src/chk/chk_engine.c index 86a1692026e..ef58b0943d7 100644 --- a/src/chk/chk_engine.c +++ b/src/chk/chk_engine.c @@ -460,6 +460,10 @@ chk_engine_pm_dangling(struct chk_pool_rec *cpr, struct pool_map *map, struct po case CHK__CHECK_INCONSIST_ACTION__CIA_IGNORE: /* Report the inconsistency without repair. */ cbk->cb_statistics.cs_ignored++; + /* + * For the pool with dangling map entry, if not repair, then the subsequent + * check (based on pool map) may fail, then have to skip to avoid confusing. + */ cpr->cpr_skip = 1; break; default: @@ -1972,8 +1976,8 @@ chk_engine_start_prep(struct chk_instance *ins, uint32_t rank_nr, d_rank_t *rank init: if (!chk_is_on_leader(gen, leader, true)) { - rc = chk_prop_prepare(leader, api_flags | prop->cp_flags, phase, - policy_nr, policies, rank_list, prop); + rc = chk_prop_prepare(leader, api_flags, phase, policy_nr, policies, rank_list, + prop); if (rc != 0) goto out; @@ -2209,9 +2213,10 @@ chk_engine_start(uint64_t gen, uint32_t rank_nr, d_rank_t *ranks, uint32_t polic chk_destroy_pool_tree(ins); out_log: if (rc >= 0) { - D_INFO(DF_ENGINE" started on rank %u with api_flags %x, phase %d, leader %u, " - "flags %x: rc %d\n", - DP_ENGINE(ins), myrank, api_flags, phase, leader, flags, rc); + D_INFO(DF_ENGINE " %s on rank %u with api_flags %x, phase %d, leader %u, " + "flags %x: rc %d\n", + DP_ENGINE(ins), chk_is_ins_reset(ins, api_flags) ? "start" : "resume", + myrank, api_flags, phase, leader, flags, rc); chk_ranks_dump(ins->ci_ranks->rl_nr, ins->ci_ranks->rl_ranks); chk_pools_dump(&ins->ci_pool_list, pool_nr, pools); diff --git a/src/chk/chk_internal.h b/src/chk/chk_internal.h index 3f8999f1de4..f9086b95e4a 100644 --- a/src/chk/chk_internal.h +++ b/src/chk/chk_internal.h @@ -810,6 +810,12 @@ void chk_vos_init(void); void chk_vos_fini(void); +static inline bool +chk_is_ins_reset(struct chk_instance *ins, uint32_t flags) +{ + return flags & CHK__CHECK_FLAG__CF_RESET || ins->ci_start_flags & CSF_RESET_ALL; +} + static inline void chk_ins_set_fail(struct chk_instance *ins, uint32_t phase) { diff --git a/src/chk/chk_leader.c b/src/chk/chk_leader.c index 3f91056594b..69f6599725a 100644 --- a/src/chk/chk_leader.c +++ b/src/chk/chk_leader.c @@ -707,8 +707,6 @@ chk_leader_orphan_pool(struct chk_pool_rec *cpr) clue->pc_svc_clue->psc_db_clue.bcl_replicas); if (result != 0) { cbk->cb_statistics.cs_failed++; - /* Skip the pool if failed to register to MS. */ - cpr->cpr_skip = 1; } else { cbk->cb_statistics.cs_repaired++; cpr->cpr_exist_on_ms = 1; @@ -738,8 +736,6 @@ chk_leader_orphan_pool(struct chk_pool_rec *cpr) case CHK__CHECK_INCONSIST_ACTION__CIA_IGNORE: /* Report the inconsistency without repair. */ cbk->cb_statistics.cs_ignored++; - /* If ignore the orphan pool, then skip subsequent check. */ - cpr->cpr_skip = 1; break; default: /* @@ -755,7 +751,6 @@ chk_leader_orphan_pool(struct chk_pool_rec *cpr) /* Ignore the inconsistency if admin does not want interaction. */ act = CHK__CHECK_INCONSIST_ACTION__CIA_IGNORE; cbk->cb_statistics.cs_ignored++; - cpr->cpr_skip = 1; } else { act = CHK__CHECK_INCONSIST_ACTION__CIA_INTERACT; @@ -806,8 +801,6 @@ chk_leader_orphan_pool(struct chk_pool_rec *cpr) if (rc < 0 && option_nr > 0) { cbk->cb_statistics.cs_failed++; - /* Skip the orphan if failed to interact with admin for further action. */ - cpr->cpr_skip = 1; result = rc; } @@ -832,8 +825,6 @@ chk_leader_orphan_pool(struct chk_pool_rec *cpr) case CHK__CHECK_INCONSIST_ACTION__CIA_IGNORE: act = CHK__CHECK_INCONSIST_ACTION__CIA_IGNORE; cbk->cb_statistics.cs_ignored++; - /* If ignore the orphan pool, then skip subsequent check. */ - cpr->cpr_skip = 1; break; case CHK__CHECK_INCONSIST_ACTION__CIA_DISCARD: act = CHK__CHECK_INCONSIST_ACTION__CIA_DISCARD; @@ -866,8 +857,6 @@ chk_leader_orphan_pool(struct chk_pool_rec *cpr) clue->pc_svc_clue->psc_db_clue.bcl_replicas); if (result != 0) { cbk->cb_statistics.cs_failed++; - /* Skip the pool if failed to register to MS. */ - cpr->cpr_skip = 1; } else { cbk->cb_statistics.cs_repaired++; cpr->cpr_exist_on_ms = 1; @@ -1857,6 +1846,11 @@ chk_leader_need_stop(struct chk_instance *ins) } if (!dangling) { + /* + * "ci_stopping" means that the user wants to stop checker for some pools. + * But the specified pools may be not in checking. "ci_pool_stopped" means + * the checker for some pools are really stopped. + */ if (ins->ci_pool_stopped) { D_ASSERT(ins->ci_stopping); return 0; @@ -2325,7 +2319,7 @@ chk_leader_start_prep(struct chk_instance *ins, uint32_t rank_nr, d_rank_t *rank if (rc != 0) goto out; - ins->ci_start_flags |= CSF_RESET_ALL; + ins->ci_start_flags = CSF_RESET_ALL; if (pool_nr <= 0) ins->ci_start_flags |= CSF_ORPHAN_POOL; @@ -2334,8 +2328,7 @@ chk_leader_start_prep(struct chk_instance *ins, uint32_t rank_nr, d_rank_t *rank cbk->cb_version = DAOS_CHK_VERSION; init: - rc = chk_prop_prepare(leader, flags | prop->cp_flags, phase, - policy_nr, policies, rank_list, prop); + rc = chk_prop_prepare(leader, flags, phase, policy_nr, policies, rank_list, prop); if (rc != 0) goto out; @@ -2768,10 +2761,10 @@ chk_leader_start(uint32_t rank_nr, d_rank_t *ranks, uint32_t policy_nr, struct c goto out_stop_pools; } - D_INFO("Leader %s check with api_flags %x, phase %d, leader %u, flags %x, gen " - DF_X64": rc %d\n", - (flags & CHK__CHECK_FLAG__CF_RESET || ins->ci_start_flags & CSF_RESET_ALL) ? - "start" : "resume", api_flags, phase, myrank, ins->ci_start_flags, cbk->cb_gen, rc); + D_INFO("Leader %s check with api_flags %x, phase %d, leader %u, flags %x, gen " DF_X64 + ": rc %d\n", + chk_is_ins_reset(ins, flags) ? "start" : "resume", api_flags, phase, myrank, + ins->ci_start_flags, cbk->cb_gen, rc); chk_ranks_dump(ins->ci_ranks->rl_nr, ins->ci_ranks->rl_ranks); chk_pools_dump(&ins->ci_pool_list, c_pool_nr > 0 ? c_pool_nr : pool_nr, @@ -2821,7 +2814,7 @@ chk_leader_start(uint32_t rank_nr, d_rank_t *ranks, uint32_t policy_nr, struct c ins->ci_starting = 0; /* Notify the control plane that the check (re-)starts from the scratch. */ - if (flags & CHK__CHECK_FLAG__CF_RESET || ins->ci_start_flags & CSF_RESET_ALL) + if (chk_is_ins_reset(ins, flags)) rc = 1; if (c_pools != NULL && c_pools != pools) diff --git a/src/tests/ftest/recovery/pass_1.py b/src/tests/ftest/recovery/pass_1.py index 904f7166b3a..b78059c5d7e 100644 --- a/src/tests/ftest/recovery/pass_1.py +++ b/src/tests/ftest/recovery/pass_1.py @@ -17,18 +17,113 @@ class Pass1Test(TestWithServers): :avocado: recursive """ + def chk_query_inconsistency(self): + """Wait DAOS checker to complete and return checker query result. + + Returns: + The string that contains detected inconsistency or empty if timeout (40 seconds). + + """ + dmg_command = self.get_dmg_command() + + query_msg = "" + for _ in range(8): + check_query_out = dmg_command.check_query() + if check_query_out["response"]["status"] == "COMPLETED": + query_msg = check_query_out["response"]["reports"][0]["msg"] + break + time.sleep(5) + + return query_msg + + def chk_dist_checker(self, inconsistency, policies=None): + """Run DAOS checker with kinds of options. + + 1. Enable check mode. + 2. Run checker under dry-run mode. + 3. Set repair policy as interaction. + 4. Run checker under auto mode and verify that it detects inconsistency. + 5. Reset repair policy as default. + 6. Run checker under regular mode, that will repair the inconsistency. + 7. Disable check mode. + + Jira ID: DAOS-13047 + + Args: + inconsistency (str): The message string for the inconsistency to be detected. + policies (str, optional): Policies used during dmg check start. Defaults to None. + + Returns: + list: Errors. + + """ + errors = [] + + dmg_command = self.get_dmg_command() + # 1. Enable check mode. + dmg_command.check_enable() + + # 2.1 Start checker with "dry-run" option. + # that will detect the inconsistency but not really repair it. + dmg_command.check_start(dry_run=True) + + # 2.2 Query the checker. + query_msg = self.chk_query_inconsistency() + + # 2.3 Verify that the checker detected the inconsistency. + if inconsistency not in query_msg: + errors.append( + "Checker didn't detect the {} (1)! msg = {}".format(inconsistency, query_msg)) + dmg_command.check_disable() + return errors + + # 3. Set the repair policy to interaction. + dmg_command.check_set_policy(all_interactive=True) + + # 4.1 start checker with "auto" option, + # that will detect the inconsistency but skip interaction. + dmg_command.check_start(auto="on") + + # 4.2. Query the checker. + query_msg = self.chk_query_inconsistency() + + # 4.3 Verify that the checker detected the inconsistency. + if inconsistency not in query_msg: + errors.append( + "Checker didn't detect the {} (2)! msg = {}".format(inconsistency, query_msg)) + dmg_command.check_disable() + return errors + + # 5. Reset the repair policy to default. + dmg_command.check_set_policy(reset_defaults=True) + + # 6.1 Start check with auto=off, + # that will find the inconsistency and repair it. + dmg_command.check_start(auto="off", policies=policies) + + # 6.2 Query the checker. + query_msg = self.chk_query_inconsistency() + + # 6.3 Verify that the checker detected the inconsistency. + if inconsistency not in query_msg: + errors.append( + "Checker didn't detect the {} (3)! msg = {}".format(inconsistency, query_msg)) + + # 7. Disable check mode. + dmg_command.check_disable() + + return errors + def test_dangling_pool(self): """Test dangling pool. 1. Create a pool. - 2. Remove the pool from the pool service (PS) on engine by calling: + 2. Remove the pool from the pool shards on engine by calling: dmg faults pool-svc CIC_POOL_NONEXIST_ON_ENGINE 3. Show dangling pool entry by calling: dmg pool list --no-query - 4. Enable and start the checker. - 5. Query the checker and verify the message regarding dangling pool. - 6. Disable the checker. - 7. Verify that the dangling pool was removed. Call dmg pool list and it should + 4. Run DAOS checker under kinds of mode. + 5. Verify that the dangling pool was removed. Call dmg pool list and it should return an empty list. Jira ID: DAOS-11711 @@ -41,7 +136,7 @@ def test_dangling_pool(self): # 1. Create a pool. self.pool = self.get_pool(connect=False) - # 2. Remove the pool from the pool service (PS) on engine. + # 2. Remove the pool shards on engine. dmg_command = self.get_dmg_command() dmg_command.faults_pool_svc( pool=self.pool.identifier, checker_report_class="CIC_POOL_NONEXIST_ON_ENGINE") @@ -49,33 +144,13 @@ def test_dangling_pool(self): # 3. Show dangling pool entry. pools = dmg_command.get_pool_list_labels(no_query=True) if self.pool.identifier not in pools: - self.fail("Dangling pool not found after removing pool from PS!") - - # 4. Enable and start the checker. - dmg_command.check_enable() - # Calling dmg check start will automatically fix the issue with the default - # option, which is to remove the dangling pool in this failure type. - dmg_command.check_start() + self.fail("Dangling pool was not found!") - # 5. Query the checker. - query_msg = "" - for _ in range(8): - check_query_out = dmg_command.check_query() - if check_query_out["response"]["status"] == "COMPLETED": - query_msg = check_query_out["response"]["reports"][0]["msg"] - break - time.sleep(5) - - # Verify that the checker detected dangling pool. errors = [] - if "dangling pool" not in query_msg: - errors.append( - "Checker didn't detect dangling pool! msg = {}".format(query_msg)) + # 4. Run DAOS checker under kinds of mode. + errors = self.chk_dist_checker(inconsistency="dangling pool") - # 6. Call dmg check disable. - dmg_command.check_disable() - - # 7. Verify that the dangling pool was removed. + # 5. Verify that the dangling pool was removed. pools = dmg_command.get_pool_list_labels() if pools: errors.append(f"Dangling pool was not removed! {pools}") @@ -86,16 +161,14 @@ def test_dangling_pool(self): report_errors(test=self, errors=errors) def run_checker_on_orphan_pool(self, policies=None): - """Run step 1 to 6 of the orphan pool tests. + """Run step 1 to 4 of the orphan pool tests. 1. Create a pool. 2. Remove the PS entry on management service (MS) by calling: dmg faults mgmt-svc pool CIC_POOL_NONEXIST_ON_MS 3. At this point, MS doesn't recognize any pool, but it exists on engine (orphan pool). Call dmg pool list and verify that it doesn't return any pool. - 4. Enable and start the checker. Use policies for trust MS test. - 5. Query the checker and verify the message regarding orphan pool. - 6. Disable the checker. + 4. Run DAOS checker under kinds of mode. Args: policies (str): Policies used during dmg check start. Defaults to None. @@ -118,30 +191,10 @@ def run_checker_on_orphan_pool(self, policies=None): msg = f"MS recognized a pool after injecting CIC_POOL_NONEXIST_ON_MS! {pools}" self.fail(msg) - # 4. Enable and start the checker. - dmg_command.check_enable() - # Calling dmg check start will automatically fix the issue with the default - # option, which is to recreate the MS pool entry. We can specify policy to let the - # checker trust MS and remove the pool. - dmg_command.check_start(policies=policies) - - # 5. Query the checker. - query_msg = "" - for _ in range(8): - check_query_out = dmg_command.check_query() - if check_query_out["response"]["status"] == "COMPLETED": - query_msg = check_query_out["response"]["reports"][0]["msg"] - break - time.sleep(5) - - # Verify that the checker detected orphan pool. errors = [] - if "orphan pool" not in query_msg: - errors.append( - "Checker didn't detect orphan pool! msg = {}".format(query_msg)) - - # 6. Call dmg check disable. - dmg_command.check_disable() + # 4. Run DAOS checker under kinds of mode. + errors = self.chk_dist_checker( + inconsistency="orphan pool", policies=policies) return errors @@ -165,20 +218,9 @@ def verify_pool_dir_removed(self, errors): return errors - def test_orphan_pool_trus_ps(self): + def test_orphan_pool_trust_ps(self): """Test orphan pool with trust PS (default option). - 1. Create a pool. - 2. Remove the PS entry on management service (MS) by calling: - dmg faults mgmt-svc pool CIC_POOL_NONEXIST_ON_MS - 3. At this point, MS doesn't recognize any pool, but it exists on engine (orphan - pool). Call dmg pool list and verify that it doesn't return any pool. - 4. Enable and start the checker. - 5. Query the checker and verify the message regarding orphan pool. - 6. Disable the checker. - 7. Verify that the orphan pool was reconstructed. Call dmg pool list and it - should return the pool created at step 1. - Jira ID: DAOS-11712 :avocado: tags=all,pr @@ -187,10 +229,10 @@ def test_orphan_pool_trus_ps(self): :avocado: tags=Pass1Test,test_orphan_pool_trust_ps """ errors = [] - # Run step 1 to 6. + # 1. Run DAOS checker under kinds of mode with trusting PS (by default). errors = self.run_checker_on_orphan_pool() - # 7. Verify that the orphan pool was reconstructed. + # 2. Verify that the orphan pool was reconstructed. dmg_command = self.get_dmg_command() pools = dmg_command.get_pool_list_labels() if self.pool.identifier not in pools: @@ -198,21 +240,9 @@ def test_orphan_pool_trus_ps(self): report_errors(test=self, errors=errors) - def test_orphan_pool_trus_ms(self): + def test_orphan_pool_trust_ms(self): """Test orphan pool with trust MS. - 1. Create a pool. - 2. Remove the PS entry on management service (MS) by calling: - dmg faults mgmt-svc pool CIC_POOL_NONEXIST_ON_MS - 3. At this point, MS doesn't recognize any pool, but it exists on engine (orphan - pool). Call dmg pool list and verify that it doesn't return any pool. - 4. Enable and start the checker with POOL_NONEXIST_ON_MS:CIA_TRUST_MS. - 5. Query the checker and verify the message regarding orphan pool. - 6. Disable the checker. - 7. Verify that the orphan pool was removed. Call dmg pool list and it should - return empty. - 8. Verify that the pool directory is removed from the mount point. - Jira ID: DAOS-11712 :avocado: tags=all,pr @@ -221,17 +251,17 @@ def test_orphan_pool_trus_ms(self): :avocado: tags=Pass1Test,test_orphan_pool_trust_ms """ errors = [] - # Run step 1 to 6 with the policies to trust MS during dmg check start. + # 1. Run DAOS checker under kinds of mode with trusting MS. errors = self.run_checker_on_orphan_pool( policies="POOL_NONEXIST_ON_MS:CIA_TRUST_MS") - # 7. Verify that the orphan pool was removed. + # 2. Verify that the orphan pool was destroyed. dmg_command = self.get_dmg_command() pools = dmg_command.get_pool_list_labels() if pools: - errors.append(f"Orphan pool was not removed! Pools = {pools}") + errors.append(f"Orphan pool was not destroyed! Pools = {pools}") - # 8. Verify that the pool directory is removed from the mount point. + # 3. Verify that the pool directory is removed from the mount point. errors = self.verify_pool_dir_removed(errors=errors) # Don't try to destroy the pool during tearDown. @@ -242,16 +272,13 @@ def test_orphan_pool_trus_ms(self): def test_lost_majority_ps_replicas(self): """Test lost the majority of PS replicas. - 1. Create a pool with --nsvc=3. Rank 0, 1, and 2 will be service replicas. + 1. Create a pool with --nsvc=3. Rank 0, 1, and 2 will be pool service replicas. 2. Stop servers. 3. Remove /mnt/daos//rdb-pool from rank 0 and 2. 4. Start servers. - 5. Enable and start the checker. It should retrieve the rdb-pool on any of the two - ranks (except rank 1, which already has it). - 6. Query the checker and verify the message - 7. Disable the checker. - 8. Try creating a container. The pool can be started, so it should succeed. - 9. Show that rdb-pool are recovered. i.e., at least three out of four ranks + 5. Run DAOS checker under kinds of mode. + 6. Try creating a container. The pool can be started now, so create should succeed. + 7. Show that rdb-pool are recovered. i.e., at least three out of four ranks should have rdb-pool. Jira ID: DAOS-12029 @@ -279,30 +306,12 @@ def test_lost_majority_ps_replicas(self): # 4. Start servers. dmg_command.system_start() - # 5. Enable and start the checker. - dmg_command.check_enable() - # Calling dmg check start will automatically fix the issue with the default - # option, which is to retrieve the rdb-pool on any of the two ranks. - dmg_command.check_start() - - # 6. Query the checker and verify the message - query_msg = "" - for _ in range(8): - check_query_out = dmg_command.check_query() - if check_query_out["response"]["status"] == "COMPLETED": - query_msg = check_query_out["response"]["reports"][0]["msg"] - break - time.sleep(5) - errors = [] - if "corrupted pool without quorum" not in query_msg: - errors.append( - "Checker didn't detect orphan pool! msg = {}".format(query_msg)) + # 5. Run DAOS checker under kinds of mode. + errors = self.chk_dist_checker( + inconsistency="corrupted pool without quorum") - # 7. Disable the checker. - dmg_command.check_disable() - - # 8. Try creating a container. It should succeed. + # 6. Try creating a container. It should succeed. cont_create_success = False for _ in range(5): time.sleep(5) @@ -318,7 +327,7 @@ def test_lost_majority_ps_replicas(self): if not cont_create_success: errors.append("Container create failed after running checker!") - # 9. Show that rdb-pool are recovered. i.e., at least three out of four ranks + # 7. Show that rdb-pool are recovered. i.e., at least three out of four ranks # should have rdb-pool. hosts = list(set(self.server_managers[0].ranks.values())) count = 0 @@ -336,18 +345,16 @@ def test_lost_majority_ps_replicas(self): report_errors(test=self, errors=errors) def test_lost_all_rdb(self): - """Remove rdb-pool from all mount point from all nodes. Now the pool can’t be + """Remove rdb-pool from all mount point from all nodes. Now the pool cannot be recovered, so checker should remove it from both MS and engine. 1. Create a pool. 2. Stop servers. 3. Remove /mnt/daos0//rdb-pool from all ranks. 4. Start servers. - 5. Enable and start the checker. It should remove pool from MS and engine. - 6. Query the checker and verify the message. - 7. Disable the checker. - 8. Check that the pool does not appear with dmg pool list. - 9. Verify that the pool directory was removed from the mount point. + 5. Run DAOS checker under kinds of mode. + 6. Check that the pool does not appear with dmg pool list. + 7. Verify that the pool directory was removed from the mount point. Jira ID: DAOS-12067 @@ -377,36 +384,17 @@ def test_lost_all_rdb(self): # 4. Start servers. dmg_command.system_start() - # 5. Enable and start the checker. - dmg_command.check_enable() - # Calling dmg check start will automatically fix the issue with the default - # option, which is to discard the pool. - dmg_command.check_start() - - # 6. Query the checker and verify the message. - query_msg = "" - for _ in range(8): - check_query_out = dmg_command.check_query() - if check_query_out["response"]["status"] == "COMPLETED": - if check_query_out["response"]["reports"]: - query_msg = check_query_out["response"]["reports"][0]["msg"] - break - time.sleep(5) - errors = [] - if "corrupted pool without quorum" not in query_msg: - errors.append( - "Checker didn't detect orphan pool! msg = {}".format(query_msg)) - - # 7. Disable the checker. - dmg_command.check_disable() + # 5. Run DAOS checker under kinds of mode. + errors = self.chk_dist_checker( + inconsistency="corrupted pool without quorum") - # 8. Check that the pool does not appear with dmg pool list. + # 6. Check that the pool does not appear with dmg pool list. pools = dmg_command.get_pool_list_all() if pools: errors.append(f"Pool still exists after running checker! {pools}") - # 9. Verify that the pool directory was removed from the mount point. + # 7. Verify that the pool directory was removed from the mount point. errors = self.verify_pool_dir_removed(errors=errors) # Don't try to destroy the pool during tearDown. diff --git a/src/tests/ftest/util/dmg_utils.py b/src/tests/ftest/util/dmg_utils.py index 4f59abe7e46..143363c943a 100644 --- a/src/tests/ftest/util/dmg_utils.py +++ b/src/tests/ftest/util/dmg_utils.py @@ -1351,6 +1351,22 @@ def check_enable(self, pool=None, stop=True): return self._get_json_result(("check", "enable"), pool=pool) + def check_set_policy(self, reset_defaults=False, all_interactive=False, policies=None): + """Call dmg check set-policy [options] [policies]. + + Args: + reset_defaults (bool, optional): Set all policies to default action. Defaults to False. + all_interactive (bool, optional): Set all policies to interactive. Defaults to False. + policies (str, optional): The policies for DAOS checker. Defaults to None. + + Returns: + dict: the dmg json command output converted to a python dictionary. + + """ + return self._get_json_result( + ("check", "set-policy"), reset_defaults=reset_defaults, + all_interactive=all_interactive, policies=policies) + def check_start(self, pool=None, dry_run=False, reset=False, failout=None, auto=None, find_orphans=False, policies=None): """Call dmg check start. diff --git a/src/tests/ftest/util/dmg_utils_base.py b/src/tests/ftest/util/dmg_utils_base.py index 7e5df84a39f..ced9de6d036 100644 --- a/src/tests/ftest/util/dmg_utils_base.py +++ b/src/tests/ftest/util/dmg_utils_base.py @@ -127,6 +127,8 @@ def get_sub_command_class(self): self.sub_command_class = self.QuerySubCommand() elif self.sub_command.value == "repair": self.sub_command_class = self.RepairSubCommand() + elif self.sub_command.value == "set-policy": + self.sub_command_class = self.SetpolicySubCommand() elif self.sub_command.value == "start": self.sub_command_class = self.StartSubCommand() elif self.sub_command.value == "stop": @@ -176,6 +178,16 @@ def __init__(self): self.action = BasicParameter(None, position=2) self.for_all = FormattedParameter("--for-all", False) + class SetpolicySubCommand(CommandWithParameters): + """Defines an object for the dmg check set-policy command.""" + + def __init__(self): + """Create a dmg check set-policy object.""" + super().__init__("/run/dmg/check/start/*", "set-policy") + self.reset_defaults = FormattedParameter("--reset-defaults", False) + self.all_interactive = FormattedParameter("--all-interactive", False) + self.policies = FormattedParameter("--policies={}", None) + class StartSubCommand(CommandWithParameters): """Defines an object for the dmg check start command."""