|
7 | 7 |
|
8 | 8 | from apricot import TestWithServers |
9 | 9 | from exception_utils import CommandFailure |
| 10 | +from recovery_utils import wait_for_check_complete |
10 | 11 |
|
11 | 12 |
|
12 | 13 | class DMGCheckStartCornerCaseTest(TestWithServers): |
@@ -63,3 +64,92 @@ def test_start_single_pool(self): |
63 | 64 | self.log.info("dmg check start invalid_label failed as expected.") |
64 | 65 |
|
65 | 66 | dmg_command.check_disable() |
| 67 | + |
| 68 | + def test_start_back_to_back(self): |
| 69 | + """Test dmg check start <pool_1> and <pool_2> back to back. |
| 70 | +
|
| 71 | + 1. Create two pools and a container. |
| 72 | + 2. Inject fault on both containers. |
| 73 | + 3. Enable checker. |
| 74 | + 4. Start with the first pool. |
| 75 | + 5. Immediately after starting the first pool, start the second pool. This may |
| 76 | + result in Operation already performed error. In that case, repeat. When the first |
| 77 | + pool is fixed, the second start should work. |
| 78 | + 6. Query checker and verify that they’re fixed. |
| 79 | + 7. Disable checker and start system. |
| 80 | + 8. Verify that the faults are actually fixed. |
| 81 | +
|
| 82 | + Jira ID: DAOS-17860 |
| 83 | +
|
| 84 | + :avocado: tags=all,full_regression |
| 85 | + :avocado: tags=vm |
| 86 | + :avocado: tags=recovery,cat_recov |
| 87 | + :avocado: tags=DMGCheckStartCornerCaseTest,test_start_back_to_back |
| 88 | + """ |
| 89 | + # 1. Create two pools and a container. |
| 90 | + self.log_step("Create two pools and a container.") |
| 91 | + pool_1 = self.get_pool(connect=False) |
| 92 | + pool_2 = self.get_pool(connect=False) |
| 93 | + container_1 = self.get_container(pool=pool_1) |
| 94 | + container_2 = self.get_container(pool=pool_2) |
| 95 | + |
| 96 | + # 2. Inject fault on both containers. |
| 97 | + self.log_step("Inject fault on both containers.") |
| 98 | + daos_command = self.get_daos_command() |
| 99 | + daos_command.faults_container( |
| 100 | + pool=pool_1.identifier, cont=container_1.identifier, |
| 101 | + location="DAOS_CHK_CONT_ORPHAN") |
| 102 | + daos_command.faults_container( |
| 103 | + pool=pool_2.identifier, cont=container_2.identifier, |
| 104 | + location="DAOS_CHK_CONT_ORPHAN") |
| 105 | + |
| 106 | + # 3. Enable checker. |
| 107 | + self.log_step("Enable checker.") |
| 108 | + dmg_command = self.get_dmg_command() |
| 109 | + dmg_command.check_enable() |
| 110 | + |
| 111 | + # 4. Start with the first pool. |
| 112 | + self.log_step("Start with the first pool.") |
| 113 | + dmg_command.check_start(pool=pool_1.identifier) |
| 114 | + |
| 115 | + # 5. Immediately after starting the first pool, start the second pool. |
| 116 | + self.log_step("Immediately after starting the first pool, start the second pool.") |
| 117 | + pool_2_started = False |
| 118 | + for count in range(8): |
| 119 | + try: |
| 120 | + dmg_command.check_start(pool=pool_2.identifier) |
| 121 | + self.log.info("dmg check start pool_2 worked. - %d", count) |
| 122 | + pool_2_started = True |
| 123 | + break |
| 124 | + except CommandFailure as command_failure: |
| 125 | + # Starting back to back may cause Operation already performed error. In |
| 126 | + # that case, repeat. When the first pool is fixed, the second start should |
| 127 | + # work. |
| 128 | + self.log.info( |
| 129 | + "dmg check start pool_2 failed. - %d; %s", count, command_failure) |
| 130 | + time.sleep(5) |
| 131 | + self.assertTrue(pool_2_started, "dmg check start pool_2 failed after 40 sec!") |
| 132 | + |
| 133 | + # 6. Query checker and verify that they’re fixed. |
| 134 | + self.log_step("Query checker and verify that they’re fixed.") |
| 135 | + wait_for_check_complete(dmg=dmg_command) |
| 136 | + |
| 137 | + # 7. Disable checker and start system. |
| 138 | + self.log_step("Disable checker and start system.") |
| 139 | + dmg_command.check_disable() |
| 140 | + |
| 141 | + # 8. Verify that the faults are actually fixed. |
| 142 | + self.log_step("Verify that the faults are actually fixed.") |
| 143 | + # In this case, check that the containers were removed. |
| 144 | + container_list_out_1 = daos_command.pool_list_containers(pool=pool_1.identifier) |
| 145 | + container_list_out_2 = daos_command.pool_list_containers(pool=pool_2.identifier) |
| 146 | + container_list_1 = container_list_out_1["response"] |
| 147 | + container_list_2 = container_list_out_2["response"] |
| 148 | + if container_list_1: |
| 149 | + self.fail(f"Pool 1 container wasn't removed! {container_list_1}") |
| 150 | + if container_list_2: |
| 151 | + self.fail(f"Pool 2 container wasn't removed! {container_list_2}") |
| 152 | + |
| 153 | + # Containers were removed by the checker. |
| 154 | + container_1.skip_cleanup() |
| 155 | + container_2.skip_cleanup() |
0 commit comments