pierventre | 3ee58d3 | 2022-02-19 18:30:19 -0800 | [diff] [blame] | 1 | class PMastership: |
| 2 | |
| 3 | def __init__(self): |
| 4 | self.default = '' |
| 5 | |
| 6 | def CASE1(self, main): |
| 7 | main.case("PMastership Test") |
| 8 | """ |
| 9 | Verify there are no pending flows and groups |
| 10 | Get flows and group counts |
| 11 | Verify that are not 0 |
| 12 | Get the master of leaf2 (look at the params file for the config) |
| 13 | Verify that has the master |
| 14 | Kill switch leaf2 |
| 15 | Set label on switch K8S node to prevent K8S to redeploy stratum |
| 16 | Verify there are no pending flows and groups related to segment routing |
| 17 | Verify that the master of leaf2 is still the same as before |
| 18 | Wait for the switch to be up again |
| 19 | Verify there are no pending flows and groups |
| 20 | """ |
| 21 | try: |
| 22 | from tests.USECASE.SegmentRouting.dependencies.Testcaselib import \ |
| 23 | Testcaselib as run |
| 24 | from tests.USECASE.SegmentRouting.SRStaging.dependencies.SRStagingTest import \ |
| 25 | SRStagingTest |
| 26 | import time |
| 27 | except ImportError as e: |
| 28 | main.log.error("Import not found. Exiting the test") |
| 29 | main.log.error(e) |
| 30 | main.cleanAndExit() |
| 31 | # Retrieves the params of the test |
| 32 | n_switches = int(main.params["TOPO"]["switchNum"]) |
| 33 | switch_to_kill = main.params["PMastership"]["PMastership_dataplane_fail"]["switch_to_kill"] |
| 34 | k8s_switch_node = main.params["PMastership"]["PMastership_dataplane_fail"]["k8s_switch_node"] |
| 35 | k8s_label = main.params["PMastership"]["PMastership_dataplane_fail"]["k8s_label"] |
| 36 | k8s_label_value_test = main.params["PMastership"]["PMastership_dataplane_fail"]["k8s_label_value_test"] |
| 37 | k8s_label_value_normal = main.params["PMastership"]["PMastership_dataplane_fail"]["k8s_label_value_normal"] |
| 38 | # Init the main components and variables |
| 39 | run.initTest(main) |
| 40 | main.log.info(main.Cluster.numCtrls) |
| 41 | main.Cluster.setRunningNode(3) |
| 42 | run.installOnos(main, skipPackage=True, cliSleep=5) |
| 43 | onos_cli = main.Cluster.active(0).CLI |
| 44 | kubectl = main.Cluster.active(0).Bench |
| 45 | kubeconfig = main.Cluster.active(0).k8s.kubeConfig |
| 46 | namespace = main.params['kubernetes']['namespace'] |
| 47 | |
| 48 | main.step("Verify there are added flows") |
| 49 | initial_flows_count = onos_cli.checkFlowCount() |
| 50 | empty = main.TRUE if ( initial_flows_count == 0 ) else main.FALSE |
| 51 | utilities.assert_equal( |
| 52 | expect=main.FALSE, |
| 53 | actual=empty, |
| 54 | onpass="There are " + str(initial_flows_count) + " added flows", |
| 55 | onfail="There are no added flows", |
| 56 | ) |
| 57 | |
| 58 | main.step("Verify there are added groups") |
| 59 | initial_groups_count = onos_cli.checkGroupCount() |
| 60 | empty = main.TRUE if ( initial_groups_count == 0 ) else main.FALSE |
| 61 | utilities.assert_equal( |
| 62 | expect=main.FALSE, |
| 63 | actual=empty, |
| 64 | onpass="There are " + str(initial_groups_count) + " added groups", |
| 65 | onfail="There are no added groups", |
| 66 | ) |
| 67 | |
| 68 | no_pending_flows = utilities.retry(onos_cli.checkFlowsState, |
| 69 | [False, None], |
| 70 | kwargs={"isPENDING": False}, |
| 71 | attempts=20, |
| 72 | getRetryingTime=True) |
| 73 | |
| 74 | main.step("Verify there are no pending flows") |
| 75 | utilities.assert_equal( |
| 76 | expect=main.TRUE, |
| 77 | actual=no_pending_flows, |
| 78 | onpass="There are no pending flows", |
| 79 | onfail="There are pending flows", |
| 80 | ) |
| 81 | |
| 82 | no_pending_groups = utilities.retry(onos_cli.checkGroupsState, |
| 83 | [False, None], |
| 84 | kwargs={"isPENDING": False}, |
| 85 | attempts=20, |
| 86 | getRetryingTime=True) |
| 87 | |
| 88 | main.step("Verify there are no pending groups") |
| 89 | utilities.assert_equal( |
| 90 | expect=main.TRUE, |
| 91 | actual=no_pending_groups, |
| 92 | onpass="There are no pending groups", |
| 93 | onfail="There are pending groups", |
| 94 | ) |
| 95 | |
| 96 | main.step("Retrieving " + switch_to_kill + " master") |
| 97 | initial_master = onos_cli.getMaster("device:" + k8s_switch_node) |
| 98 | no_master = main.TRUE if ( initial_master is None ) else main.FALSE |
| 99 | utilities.assert_equal( |
| 100 | expect=main.FALSE, |
| 101 | actual=no_master, |
| 102 | onpass=initial_master + " is the master of " + switch_to_kill, |
| 103 | onfail="There is no master for " + switch_to_kill, |
| 104 | ) |
| 105 | |
| 106 | main.step("Set label to switch k8s node and kill Stratum") |
| 107 | # K8s node name correspond to the switch name in lowercase |
| 108 | utilities.assert_equal( |
| 109 | expect=main.TRUE, |
| 110 | actual=kubectl.kubectlSetLabel( |
| 111 | nodeName=k8s_switch_node, |
| 112 | label=k8s_label, |
| 113 | value=k8s_label_value_test, |
| 114 | kubeconfig=kubeconfig, |
| 115 | namespace=namespace, |
| 116 | ), |
| 117 | onpass="Label has been set correctly on node %s" % k8s_switch_node, |
| 118 | onfail="Label has not been set on node %s" % k8s_switch_node |
| 119 | ) |
| 120 | |
| 121 | try: |
| 122 | def checkNumberStratumPods(n_value): |
| 123 | pods = kubectl.kubectlGetPodNames( |
| 124 | kubeconfig=kubeconfig, |
| 125 | namespace=namespace, |
| 126 | name="stratum" |
| 127 | ) |
| 128 | main.log.info("PODS: " + str(pods)) |
| 129 | return n_value == len(pods) if pods is not main.FALSE else False |
| 130 | # Execute the following in try/except/finally to be sure to restore the |
| 131 | # k8s label even in case of unhandled exception. |
| 132 | |
| 133 | # Wait for stratum pod to be removed from the switch |
| 134 | removed = utilities.retry(checkNumberStratumPods, |
| 135 | False, |
| 136 | args=[n_switches - 1], |
| 137 | attempts=50) |
| 138 | main.log.info("Stratum has been removed from the switch? %s" % removed) |
| 139 | |
| 140 | sleepTime = 20 |
| 141 | switch_component = getattr(main, switch_to_kill) |
| 142 | main.log.info("Sleeping %s seconds for ONOS to react" % sleepTime) |
| 143 | time.sleep(sleepTime) |
| 144 | |
| 145 | available = utilities.retry(SRStagingTest.switchIsConnected, |
| 146 | True, |
| 147 | args=[switch_component], |
| 148 | attempts=300, |
| 149 | getRetryingTime=True) |
| 150 | main.log.info("Switch %s is available in ONOS? %s" % ( |
| 151 | switch_to_kill, available)) |
| 152 | utilities.assert_equal( |
| 153 | expect=True, |
| 154 | actual=not available and removed, |
| 155 | onpass="Stratum was removed from switch k8s node", |
| 156 | onfail="Stratum was not removed from switch k8s node" |
| 157 | ) |
| 158 | |
| 159 | main.step("Verify there are no segmentrouting flows after the failure") |
| 160 | raw_flows = onos_cli.flows(device="device:" + k8s_switch_node) |
| 161 | sr_flows = main.TRUE if "segmentrouting" in raw_flows else main.FALSE |
| 162 | utilities.assert_equal( |
| 163 | expect=main.FALSE, |
| 164 | actual=sr_flows, |
| 165 | onpass="There are no segmentrouting flows", |
| 166 | onfail="There are segmentrouting flows", |
| 167 | ) |
| 168 | |
| 169 | main.step("Verify there are no segmentrouting groups after the failure") |
| 170 | raw_groups = onos_cli.groups(device="device:" + k8s_switch_node) |
| 171 | sr_groups = main.TRUE if "segmentrouting" in raw_groups else main.FALSE |
| 172 | utilities.assert_equal( |
| 173 | expect=main.FALSE, |
| 174 | actual=sr_groups, |
| 175 | onpass="There are no segmentrouting groups", |
| 176 | onfail="There are segmentrouting groups", |
| 177 | ) |
| 178 | |
| 179 | main.step("Verify " + initial_master + " is still the master of " + switch_to_kill) |
| 180 | after_master = onos_cli.getMaster("device:" + k8s_switch_node) |
| 181 | no_master = main.TRUE if ( initial_master is None ) else main.FALSE |
| 182 | utilities.assert_equal( |
| 183 | expect=main.FALSE, |
| 184 | actual=no_master, |
| 185 | onpass=initial_master + " is the master of " + switch_to_kill, |
| 186 | onfail="There is no master for " + switch_to_kill, |
| 187 | ) |
| 188 | |
| 189 | same_master = main.TRUE if ( initial_master == after_master ) else main.FALSE |
| 190 | utilities.assert_equal( |
| 191 | expect=main.TRUE, |
| 192 | actual=same_master, |
| 193 | onpass=initial_master + " is still the master of " + switch_to_kill, |
| 194 | onfail="Master for " + switch_to_kill + " is " + after_master, |
| 195 | ) |
| 196 | |
| 197 | except Exception as e: |
| 198 | main.log.error("Unhandled exception!") |
| 199 | main.log.error(e) |
| 200 | finally: |
| 201 | utilities.assert_equal( |
| 202 | expect=main.TRUE, |
| 203 | actual=kubectl.kubectlSetLabel( |
| 204 | nodeName=k8s_switch_node, |
| 205 | label=k8s_label, |
| 206 | value=k8s_label_value_normal, |
| 207 | kubeconfig=kubeconfig, |
| 208 | namespace=namespace, |
| 209 | ), |
| 210 | onpass="Label has been set correctly on node %s" % k8s_switch_node, |
| 211 | onfail="Label has not been set on node %s" % k8s_switch_node |
| 212 | ) |
| 213 | |
| 214 | # Wait for stratum pod to be re-deployed on the switch |
| 215 | deployed = utilities.retry(checkNumberStratumPods, |
| 216 | False, |
| 217 | args=[n_switches], |
| 218 | attempts=50) |
| 219 | main.log.info("Stratum has been redeployed on the switch? %s" % deployed) |
| 220 | |
| 221 | # Wait switch to be back in ONOS |
| 222 | available = utilities.retry(SRStagingTest.switchIsConnected, |
| 223 | False, |
| 224 | args=[switch_component], |
| 225 | sleep=2, |
| 226 | attempts=300, |
| 227 | getRetryingTime=True) |
| 228 | main.log.info("Switch %s is available in ONOS? %s" % ( |
| 229 | switch_to_kill, available)) |
| 230 | utilities.assert_equal( |
| 231 | expect=True, |
| 232 | actual=available and deployed, |
| 233 | onpass="Switch is back available in ONOS and stratum has been redeployed", |
| 234 | onfail="Switch is not available in ONOS, may influence subsequent tests!" |
| 235 | ) |
| 236 | |
| 237 | sleepTime = 10 |
| 238 | main.log.info("Sleeping %s seconds for ONOS to react and assure flows/groups are ADDED" % sleepTime) |
| 239 | time.sleep(sleepTime) |
| 240 | |
| 241 | main.step("Verify there are added flows after reboot") |
| 242 | after_flows_count = onos_cli.checkFlowCount() |
| 243 | empty = main.TRUE if ( after_flows_count == 0 ) else main.FALSE |
| 244 | utilities.assert_equal( |
| 245 | expect=main.FALSE, |
| 246 | actual=empty, |
| 247 | onpass="There are " + str(after_flows_count) + " added flows", |
| 248 | onfail="There are no added flows", |
| 249 | ) |
| 250 | |
| 251 | main.step("Verify there are added groups after reboot") |
| 252 | after_groups_count = onos_cli.checkGroupCount() |
| 253 | empty = main.TRUE if ( after_groups_count == 0 ) else main.FALSE |
| 254 | utilities.assert_equal( |
| 255 | expect=main.FALSE, |
| 256 | actual=empty, |
| 257 | onpass="There are " + str(after_groups_count) + " added groups", |
| 258 | onfail="There are no added groups", |
| 259 | ) |
| 260 | |
| 261 | no_pending_flows = utilities.retry(onos_cli.checkFlowsState, |
| 262 | [False, None], |
| 263 | kwargs={"isPENDING": False}, |
| 264 | attempts=20, |
| 265 | getRetryingTime=True) |
| 266 | |
| 267 | main.step("Verify there are no pending flows after reboot") |
| 268 | utilities.assert_equal( |
| 269 | expect=main.TRUE, |
| 270 | actual=no_pending_flows, |
| 271 | onpass="There are no pending flows", |
| 272 | onfail="There are pending flows", |
| 273 | ) |
| 274 | |
| 275 | no_pending_groups = utilities.retry(onos_cli.checkGroupsState, |
| 276 | [False, None], |
| 277 | kwargs={"isPENDING": False}, |
| 278 | attempts=20, |
| 279 | getRetryingTime=True) |
| 280 | |
| 281 | main.step("Verify there are no pending groups after reboot") |
| 282 | utilities.assert_equal( |
| 283 | expect=main.TRUE, |
| 284 | actual=no_pending_groups, |
| 285 | onpass="There are no pending groups", |
| 286 | onfail="There are pending groups", |
| 287 | ) |