From 5ca8b0243c9398bc03558d53dbf69f5245486147 Mon Sep 17 00:00:00 2001 From: pkazlenka Date: Fri, 8 Mar 2024 13:43:29 +0100 Subject: [PATCH] 5560: [TEST]: Add methods to break/restore ISLs in test Implements #5560 * Replaced places in tests where port is set up/down with waiting for ISL get up/down with reusable methods --- .../functionaltests/helpers/IslHelper.groovy | 90 ++++++ .../functionaltests/BaseSpecification.groovy | 5 +- .../spec/flows/AutoRerouteSpec.groovy | 165 +++------- .../spec/flows/FlowCrudSpec.groovy | 25 +- .../spec/flows/FlowCrudV1Spec.groovy | 38 +-- .../spec/flows/FlowDiversitySpec.groovy | 19 +- .../spec/flows/FlowLoopSpec.groovy | 14 +- .../spec/flows/FlowMonitoringSpec.groovy | 7 +- .../spec/flows/MaxLatencySpec.groovy | 21 +- .../spec/flows/MultiRerouteSpec.groovy | 7 +- .../spec/flows/PinnedFlowSpec.groovy | 23 +- .../spec/flows/ProtectedPathSpec.groovy | 305 ++++++------------ .../spec/flows/ProtectedPathV1Spec.groovy | 56 +--- .../spec/flows/SwapEndpointSpec.groovy | 123 ++----- .../spec/flows/ThrottlingRerouteSpec.groovy | 1 - .../spec/flows/haflows/HaFlowPingSpec.groovy | 6 +- .../flows/haflows/HaFlowRerouteSpec.groovy | 53 +-- .../flows/yflows/YFlowPathSwapSpec.groovy | 22 +- .../spec/flows/yflows/YFlowRerouteSpec.groovy | 19 +- .../spec/links/LinkMaintenanceSpec.groovy | 33 +- .../spec/links/LinkSpec.groovy | 51 +-- .../spec/links/RoundTripIslSpec.groovy | 38 +-- .../spec/links/UnstableIslSpec.groovy | 31 +- .../spec/stats/FlowStatSpec.groovy | 44 +-- .../spec/switches/FlowRulesSpec.groovy | 7 +- .../spec/switches/PortAntiflapSpec.groovy | 25 +- .../spec/switches/PortHistorySpec.groovy | 73 +---- .../spec/switches/PortPropertiesSpec.groovy | 8 +- .../spec/switches/SwitchDeleteSpec.groovy | 42 +-- .../spec/switches/SwitchFailuresSpec.groovy | 2 +- .../switches/SwitchMaintenanceSpec.groovy | 18 +- .../spec/switches/SwitchPortConfigSpec.groovy | 32 +- .../spec/switches/SwitchesSpec.groovy | 19 +- .../spec/toggles/FeatureTogglesV2Spec.groovy | 67 +--- .../spec/xresilience/RetriesSpec.groovy | 62 +--- 35 files changed, 420 insertions(+), 1131 deletions(-) create mode 100644 src-java/testing/functional-tests/src/main/groovy/org/openkilda/functionaltests/helpers/IslHelper.groovy diff --git a/src-java/testing/functional-tests/src/main/groovy/org/openkilda/functionaltests/helpers/IslHelper.groovy b/src-java/testing/functional-tests/src/main/groovy/org/openkilda/functionaltests/helpers/IslHelper.groovy new file mode 100644 index 00000000000..28d25ac1c45 --- /dev/null +++ b/src-java/testing/functional-tests/src/main/groovy/org/openkilda/functionaltests/helpers/IslHelper.groovy @@ -0,0 +1,90 @@ +package org.openkilda.functionaltests.helpers + +import groovy.util.logging.Slf4j +import org.openkilda.messaging.info.event.IslChangeType +import org.openkilda.testing.model.topology.TopologyDefinition +import org.openkilda.testing.model.topology.TopologyDefinition.Isl +import org.openkilda.testing.service.northbound.NorthboundService +import org.openkilda.testing.service.northbound.NorthboundServiceV2 +import org.openkilda.testing.tools.IslUtils +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.beans.factory.annotation.Qualifier +import org.springframework.context.annotation.Scope +import org.springframework.stereotype.Component + +import static groovyx.gpars.GParsExecutorsPool.withPool +import static org.openkilda.messaging.info.event.IslChangeType.DISCOVERED +import static org.openkilda.messaging.info.event.IslChangeType.FAILED +import static org.springframework.beans.factory.config.ConfigurableBeanFactory.SCOPE_PROTOTYPE + +/** + * Holds utility methods for manipulating y-flows. + */ +@Component +@Slf4j +@Scope(SCOPE_PROTOTYPE) +class IslHelper { + @Autowired + TopologyDefinition topology + @Autowired @Qualifier("islandNbV2") + NorthboundServiceV2 northboundV2 + @Autowired @Qualifier("islandNb") + NorthboundService northbound + @Autowired + IslUtils islUtils + @Autowired + PortAntiflapHelper antiflapHelper + + + def breakIsl(Isl islToBreak) { + if (getIslStatus(islToBreak).equals(DISCOVERED)) { + antiflapHelper.portDown(islToBreak.getSrcSwitch().getDpId(), islToBreak.getSrcPort()) + } + islUtils.waitForIslStatus([islToBreak], FAILED) + } + + def breakIsls(Set islsToBreak) { + withPool { + islsToBreak.eachParallel{ + breakIsl(it) + } + } + } + + def breakIsls(List islsToBreak) { + breakIsls(islsToBreak as Set) + } + + def restoreIsl(Isl islToRestore) { + if(!getIslStatus(islToRestore).equals(DISCOVERED)) { + withPool{ + [{antiflapHelper.portUp(islToRestore.getSrcSwitch().getDpId(), islToRestore.getSrcPort())}, + {antiflapHelper.portUp(islToRestore.getDstSwitch().getDpId(), islToRestore.getDstPort())} + ].eachParallel{it()} + } + } + islUtils.waitForIslStatus([islToRestore], DISCOVERED) + } + + def restoreIsls(Set islsToRestore) { + withPool { + islsToRestore.eachParallel{ + restoreIsl(it) + } + } + } + + def restoreIsls(List islsToRestore) { + restoreIsls(islsToRestore as Set) + } + + def getIslStatus(Isl isl) { + def islInfo = islUtils.getIslInfo(isl) + if (islInfo.isPresent()) { + return islInfo.get().state + } else { + return null + } + + } +} diff --git a/src-java/testing/functional-tests/src/test/groovy/org/openkilda/functionaltests/BaseSpecification.groovy b/src-java/testing/functional-tests/src/test/groovy/org/openkilda/functionaltests/BaseSpecification.groovy index d78b84ebda6..44413798e51 100644 --- a/src-java/testing/functional-tests/src/test/groovy/org/openkilda/functionaltests/BaseSpecification.groovy +++ b/src-java/testing/functional-tests/src/test/groovy/org/openkilda/functionaltests/BaseSpecification.groovy @@ -1,5 +1,6 @@ package org.openkilda.functionaltests +import org.openkilda.functionaltests.helpers.IslHelper import org.openkilda.functionaltests.helpers.model.SwitchPairs import static groovyx.gpars.GParsPool.withPool @@ -13,11 +14,9 @@ import org.openkilda.functionaltests.helpers.StatsHelper import org.openkilda.functionaltests.helpers.SwitchHelper import org.openkilda.functionaltests.helpers.TopologyHelper import org.openkilda.functionaltests.helpers.Wrappers -import org.openkilda.model.SwitchId import org.openkilda.testing.model.topology.TopologyDefinition import org.openkilda.testing.service.database.Database import org.openkilda.testing.service.floodlight.FloodlightsHelper -import org.openkilda.testing.service.labservice.LabService import org.openkilda.testing.service.lockkeeper.LockKeeperService import org.openkilda.testing.service.northbound.NorthboundService import org.openkilda.testing.service.northbound.NorthboundServiceV2 @@ -71,6 +70,8 @@ class BaseSpecification extends Specification { StatsHelper statsHelper @Autowired @Shared SwitchPairs switchPairs + @Autowired @Shared + IslHelper islHelper @Value('${spring.profiles.active}') @Shared String profile diff --git a/src-java/testing/functional-tests/src/test/groovy/org/openkilda/functionaltests/spec/flows/AutoRerouteSpec.groovy b/src-java/testing/functional-tests/src/test/groovy/org/openkilda/functionaltests/spec/flows/AutoRerouteSpec.groovy index 23569e67cf8..4f440fb9b38 100644 --- a/src-java/testing/functional-tests/src/test/groovy/org/openkilda/functionaltests/spec/flows/AutoRerouteSpec.groovy +++ b/src-java/testing/functional-tests/src/test/groovy/org/openkilda/functionaltests/spec/flows/AutoRerouteSpec.groovy @@ -66,8 +66,7 @@ class AutoRerouteSpec extends HealthCheckSpecification { def flowIsls = pathHelper.getInvolvedIsls(flowPath) allFlowPaths.findAll { it != flowPath }.each { altFlowIsls.addAll(pathHelper.getInvolvedIsls(it)) } def islToFail = flowIsls.find { !(it in altFlowIsls) && !(it.reversed in altFlowIsls) } - antiflap.portDown(islToFail.srcSwitch.dpId, islToFail.srcPort) - wait(WAIT_OFFSET) { northbound.getLink(islToFail).state == FAILED } + islHelper.breakIsl(islToFail) then: "The flow was rerouted after reroute delay" wait(rerouteDelay + WAIT_OFFSET) { @@ -77,10 +76,7 @@ class AutoRerouteSpec extends HealthCheckSpecification { cleanup: "Revive the ISL back (bring switch port up) and delete the flow" flow && flowHelperV2.deleteFlow(flow.flowId) - islToFail && antiflap.portUp(islToFail.srcSwitch.dpId, islToFail.srcPort) - wait(discoveryInterval + WAIT_OFFSET) { - assert northbound.getActiveLinks().size() == topology.islsForActiveSwitches.size() * 2 - } + islHelper.restoreIsl(islToFail) where: description | flowData @@ -125,7 +121,7 @@ class AutoRerouteSpec extends HealthCheckSpecification { def flowIsls = pathHelper.getInvolvedIsls(flowPath) allFlowPaths.findAll { it != flowPath }.each { altFlowIsls.addAll(pathHelper.getInvolvedIsls(it)) } def islToFail = flowIsls.find { !(it in altFlowIsls) && !(it.reversed in altFlowIsls) } - def portDown = antiflap.portDown(islToFail.srcSwitch.dpId, islToFail.srcPort) + islHelper.breakIsl(islToFail) then: "Flow history shows 3 retry attempts, eventually bringing flow to Down" List history @@ -178,12 +174,7 @@ class AutoRerouteSpec extends HealthCheckSpecification { cleanup: flow && flowHelperV2.deleteFlow(flow.flowId) helperFlows && helperFlows.each { it && flowHelperV2.deleteFlow(it.flowId) } - if (portDown && !portUp) { - antiflap.portUp(islToFail.srcSwitch.dpId, islToFail.srcPort) - wait(discoveryInterval + WAIT_OFFSET) { - assert islUtils.getIslInfo(islToFail).get().state == IslChangeType.DISCOVERED - } - } + islHelper.restoreIsl(islToFail) } @Tags(ISL_RECOVER_ON_FAIL) @@ -205,24 +196,14 @@ class AutoRerouteSpec extends HealthCheckSpecification { } when: "Other isl fails" - def isIslFailed = false def islToFail = topology.isls.find() {isl-> isl.srcSwitch != sw && isl.dstSwitch != sw} - antiflap.portDown(islToFail.srcSwitch.dpId, islToFail.srcPort) - isIslFailed = true - wait(WAIT_OFFSET) { - assert northbound.getLink(islToFail).state == IslChangeType.FAILED - } + islHelper.breakIsl(islToFail) then: "Flow remains 'DOWN'" assert northboundV2.getFlowStatus(flow.flowId).status == FlowState.DOWN when: "Other isl is back online" - antiflap.portUp(islToFail.srcSwitch.dpId, islToFail.srcPort) - isIslFailed = false - - wait(WAIT_OFFSET) { - assert northbound.getLink(islToFail).state == IslChangeType.DISCOVERED - } + islHelper.restoreIsl(islToFail) then: "Flow remains 'DOWN'" assert northboundV2.getFlowStatus(flow.flowId).status == FlowState.DOWN @@ -242,12 +223,7 @@ class AutoRerouteSpec extends HealthCheckSpecification { cleanup: "Remove the flow" flow && flowHelperV2.deleteFlow(flow.flowId) isSwitchDisconnected && switchHelper.reviveSwitch(sw, blockData, true) - if (isIslFailed) { - antiflap.portUp(islToFail.srcSwitch.dpId, islToFail.srcPort) - wait(discoveryInterval + WAIT_OFFSET) { - assert northbound.getLink(islToFail).actualState == IslChangeType.DISCOVERED - } - } + islHelper.restoreIsl(islToFail) } @Tags([SMOKE, ISL_RECOVER_ON_FAIL]) @@ -261,21 +237,16 @@ class AutoRerouteSpec extends HealthCheckSpecification { def flowPath = PathHelper.convert(northbound.getFlowPath(flow.flowId)) def altPaths = allFlowPaths.findAll { it != flowPath } def involvedIsls = pathHelper.getInvolvedIsls(flowPath) - def broughtDownIsls = [] - altPaths.collectMany { pathHelper.getInvolvedIsls(it).findAll { !(it in involvedIsls || it.reversed in involvedIsls) } } - .unique { a, b -> (a == b || a == b.reversed) ? 0 : 1 }.each { - antiflap.portDown(it.srcSwitch.dpId, it.srcPort) - broughtDownIsls << it - } - wait(WAIT_OFFSET) { - assert northbound.getAllLinks().findAll { - it.state == FAILED - }.size() == broughtDownIsls.size() * 2 + def broughtDownIsls = altPaths.collectMany { + pathHelper.getInvolvedIsls(it) + .findAll { !(it in involvedIsls || it.reversed in involvedIsls) } } + .unique { a, b -> (a == b || a == b.reversed) ? 0 : 1 } + islHelper.breakIsls(broughtDownIsls) when: "One of the flow ISLs goes down" def isl = involvedIsls.first() - def portDown = antiflap.portDown(isl.dstSwitch.dpId, isl.dstPort) + islHelper.breakIsl(isl) then: "The flow becomes 'Down'" wait(rerouteDelay + WAIT_OFFSET * 2) { @@ -286,10 +257,7 @@ class AutoRerouteSpec extends HealthCheckSpecification { } when: "ISL goes back up" - def portUp = antiflap.portUp(isl.dstSwitch.dpId, isl.dstPort) - wait(antiflapCooldown + discoveryInterval + WAIT_OFFSET) { - assert islUtils.getIslInfo(isl).get().state == IslChangeType.DISCOVERED - } + islHelper.restoreIsl(isl) then: "The flow becomes 'Up'" wait(rerouteDelay + WAIT_OFFSET) { @@ -301,11 +269,8 @@ class AutoRerouteSpec extends HealthCheckSpecification { cleanup: "Restore topology to the original state, remove the flow" flow && flowHelperV2.deleteFlow(flow.flowId) - portDown && !portUp && antiflap.portUp(isl.dstSwitch.dpId, isl.dstPort) - broughtDownIsls.each { antiflap.portUp(it.srcSwitch.dpId, it.srcPort) } - wait(discoveryInterval + WAIT_OFFSET) { - assert northbound.getActiveLinks().size() == topology.islsForActiveSwitches.size() * 2 - } + islHelper.restoreIsl(isl) + islHelper.restoreIsls(broughtDownIsls) where: strictBw | reroutesCount @@ -324,12 +289,10 @@ class AutoRerouteSpec extends HealthCheckSpecification { def flowPath = PathHelper.convert(northbound.getFlowPath(flow.flowId)) when: "Bring all ports down on the source switch that are involved in the current and alternative paths" - List broughtDownPorts = [] - allFlowPaths.unique { it.first() }.each { path -> - def src = path.first() - broughtDownPorts.add(src) - antiflap.portDown(src.switchId, src.portNo) + def broughtDownIsls = allFlowPaths.unique { it.first() }.collect { path -> + pathHelper.getInvolvedIsls(path).first() } + islHelper.breakIsls(broughtDownIsls) then: "The flow goes to 'Down' status" wait(rerouteDelay + WAIT_OFFSET) { @@ -349,12 +312,7 @@ class AutoRerouteSpec extends HealthCheckSpecification { } } when: "Bring all ports up on the source switch that are involved in the alternative paths" - broughtDownPorts.findAll { - it.portNo != flowPath.first().portNo - }.each { - antiflap.portUp(it.switchId, it.portNo) - } - def broughtDownPortsUp = true + islHelper.restoreIsls(broughtDownIsls.findAll {it.srcPort != flowPath.first().getPortNo()}) then: "The flow goes to 'Up' status" and: "The flow was rerouted" @@ -366,11 +324,7 @@ class AutoRerouteSpec extends HealthCheckSpecification { cleanup: "Bring port involved in the original path up and delete the flow" flow && flowHelperV2.deleteFlow(flow.flowId) - !broughtDownPortsUp && broughtDownPorts.each { antiflap.portUp(it.switchId, it.portNo) } - flowPath && broughtDownPortsUp && antiflap.portUp(flowPath.first().switchId, flowPath.first().portNo) - wait(discoveryInterval + WAIT_OFFSET) { - assert northbound.getActiveLinks().size() == topology.islsForActiveSwitches.size() * 2 - } + islHelper.restoreIsls(broughtDownIsls) } @Tags([SMOKE, ISL_RECOVER_ON_FAIL]) @@ -390,33 +344,19 @@ class AutoRerouteSpec extends HealthCheckSpecification { def islToFail = topology.islsForActiveSwitches.find { !involvedIsls.contains(it) && !involvedIsls.contains(it.reversed) } - antiflap.portDown(islToFail.srcSwitch.dpId, islToFail.srcPort) + islHelper.breakIsl(islToFail) - then: "Link status becomes 'FAILED'" - wait(WAIT_OFFSET) { assert islUtils.getIslInfo(islToFail).get().state == IslChangeType.FAILED } + and: "Failed link goes up" + islHelper.restoreIsl(islToFail) - when: "Failed link goes up" - antiflap.portUp(islToFail.srcSwitch.dpId, islToFail.srcPort) - - then: "Link status becomes 'DISCOVERED'" - wait(discoveryInterval + WAIT_OFFSET) { - assert islUtils.getIslInfo(islToFail).get().state == IslChangeType.DISCOVERED - } - def islIsUp = true - - and: "The flow is not rerouted and doesn't use more preferable path" + then: "The flow is not rerouted and doesn't use more preferable path" TimeUnit.SECONDS.sleep(rerouteDelay + WAIT_OFFSET) northboundV2.getFlowStatus(flow.flowId).status == FlowState.UP PathHelper.convert(northbound.getFlowPath(flow.flowId)) == flowPath cleanup: flow && flowHelperV2.deleteFlow(flow.flowId) - if (!islIsUp) { - islToFail && antiflap.portUp(islToFail.srcSwitch.dpId, islToFail.srcPort) - wait(discoveryInterval + WAIT_OFFSET) { - assert islUtils.getIslInfo(islToFail).get().state == IslChangeType.DISCOVERED - } - } + islHelper.restoreIsl(islToFail) } @Tags([SMOKE]) @@ -564,14 +504,10 @@ class AutoRerouteSpec extends HealthCheckSpecification { def islsToBreak = altPaths.collectMany { pathHelper.getInvolvedIsls(it) } .collectMany { [it, it.reversed] }.unique() .findAll { !untouchableIsls.contains(it) }.unique { [it, it.reversed].sort() } - withPool { islsToBreak.eachParallel { Isl isl -> antiflap.portDown(isl.srcSwitch.dpId, isl.srcPort) } } - wait(WAIT_OFFSET) { - assert northbound.getAllLinks().findAll { it.state == FAILED }.size() == islsToBreak.size() * 2 - } + islHelper.breakIsls(islsToBreak) //move the flow to DOWN status def islToBreak = pathHelper.getInvolvedIsls(flowPath).first() - antiflap.portDown(islToBreak.srcSwitch.dpId, islToBreak.srcPort) - wait(WAIT_OFFSET) { assert northboundV2.getFlowStatus(flow.flowId).status == FlowState.DOWN } + islHelper.breakIsl(islToBreak) when: "Generate switchUp event on switch which is not related to the flow" def involvedSwitches = pathHelper.getInvolvedSwitches(flowPath)*.dpId @@ -601,12 +537,9 @@ class AutoRerouteSpec extends HealthCheckSpecification { cleanup: "Restore topology, delete the flow and reset costs" flow && flowHelperV2.deleteFlow(flow.flowId) - islToBreak && antiflap.portUp(islToBreak.srcSwitch.dpId, islToBreak.srcPort) + islHelper.restoreIsl(islToBreak) !isSwitchActivated && blockData && switchHelper.reviveSwitch(switchToManipulate, blockData) - islsToBreak && withPool { islsToBreak.eachParallel { antiflap.portUp(it.srcSwitch.dpId, it.srcPort) } } - wait(discoveryInterval + WAIT_OFFSET) { - assert northbound.getActiveLinks().size() == topology.islsForActiveSwitches.size() * 2 - } + islHelper.restoreIsls(islsToBreak) } @Tags(ISL_RECOVER_ON_FAIL) @@ -703,14 +636,7 @@ triggering one more reroute of the current path" cleanup: swPair && lockKeeper.cleanupTrafficShaperRules(swPair.dst.regions) flow && flowHelperV2.deleteFlow(flow.flowId) - withPool { - [mainPathUniqueIsl, commonIsl].eachParallel { Isl isl -> - antiflap.portUp(isl.srcSwitch.dpId, isl.srcPort) - wait(WAIT_OFFSET + discoveryInterval) { - assert northbound.getLink(isl).state == IslChangeType.DISCOVERED - } - } - } + islHelper.restoreIsls([mainPathUniqueIsl, commonIsl]) } def singleSwitchFlow() { @@ -788,14 +714,8 @@ class AutoRerouteIsolatedSpec extends HealthCheckSpecification { def islsToBreak = (altPaths1 + altPaths2).collectMany { pathHelper.getInvolvedIsls(it) } .collectMany { [it, it.reversed] }.unique() .findAll { !untouchableIsls.contains(it) }.unique { [it, it.reversed].sort() } - withPool { - islsToBreak.eachParallel { Isl isl -> antiflap.portDown(isl.srcSwitch.dpId, isl.srcPort) } - } - wait(antiflapMin + WAIT_OFFSET) { - assert northbound.getAllLinks().findAll { - it.state == FAILED - }.size() == islsToBreak.size() * 2 - } + + islHelper.breakIsls(islsToBreak) //firstFlowMainPath path more preferable than the firstFlowBackupPath pathHelper.makePathMorePreferable(firstFlowMainPath, firstFlowBackupPath) @@ -901,11 +821,7 @@ Failed to find path with requested bandwidth= ignored" wait(WAIT_OFFSET) { assert northbound.getSwitch(switchPair1.src.dpId).state == SwitchChangeType.ACTIVATED } - islToBreak && antiflap.portUp(islToBreak.dstSwitch.dpId, islToBreak.dstPort) - islsToBreak && withPool { islsToBreak.eachParallel { antiflap.portUp(it.srcSwitch.dpId, it.srcPort) } } - wait(discoveryInterval + WAIT_OFFSET) { - assert northbound.getActiveLinks().size() == topology.islsForActiveSwitches.size() * 2 - } + islHelper.restoreIsls(islsToBreak + islToBreak) northbound.deleteLinkProps(northbound.getLinkProps(topology.isls)) database.resetCosts(topology.isls) } @@ -944,7 +860,7 @@ Failed to find path with requested bandwidth= ignored" Set altFlowIsls = [] allFlowPaths.findAll { it != flowPath }.each { altFlowIsls.addAll(pathHelper.getInvolvedIsls(it)) } def islToFail = involvedIsls.get(0) - def portDown = antiflap.portDown(islToFail.srcSwitch.dpId, islToFail.srcPort) + islHelper.breakIsl(islToFail) then: "Flow history shows two reroute attempts, second one succeeds with ignore bw" List history @@ -984,9 +900,7 @@ Failed to find path with requested bandwidth= ignored" [it.srcSwitch.dpId, it.dstSwitch.dpId].intersect([flow.source.switchId, flow.destination.switchId]).empty } antiflap.portDown(islToBlink.srcSwitch.dpId, islToBlink.srcPort) - def islToBlinkIsDown = true antiflap.portUp(islToBlink.srcSwitch.dpId, islToBlink.srcPort) - islToBlinkIsDown = false then: "System tries to reroute the DEGRADED flow" and: "Flow remains DEGRADED and on the same path" @@ -1000,7 +914,7 @@ Failed to find path with requested bandwidth= ignored" PathHelper.convert(northbound.getFlowPath(flow.flowId)) == pathAfterReroute1 when: "Broken ISL on the original path is back online" - def portUp = antiflap.portUp(islToFail.srcSwitch.dpId, islToFail.srcPort) + islHelper.restoreIsl(islToFail) then: "Flow is rerouted to the original path to UP state" wait(rerouteDelay + WAIT_OFFSET) { @@ -1010,12 +924,7 @@ Failed to find path with requested bandwidth= ignored" cleanup: flow && flowHelperV2.deleteFlow(flow.flowId) helperFlows && helperFlows.each { it && flowHelperV2.deleteFlow(it.flowId) } - (portDown && !portUp) && antiflap.portUp(islToFail.srcSwitch.dpId, islToFail.srcPort) - islToBlinkIsDown && antiflap.portUp(islToBlink.srcSwitch.dpId, islToBlink.srcPort) - wait(discoveryInterval + WAIT_OFFSET) { - assert islUtils.getIslInfo(islToFail).get().state == IslChangeType.DISCOVERED - assert islUtils.getIslInfo(islToBlink).get().state == IslChangeType.DISCOVERED - } + islHelper.restoreIsls([islToFail, islToBlink]) database.resetCosts() } diff --git a/src-java/testing/functional-tests/src/test/groovy/org/openkilda/functionaltests/spec/flows/FlowCrudSpec.groovy b/src-java/testing/functional-tests/src/test/groovy/org/openkilda/functionaltests/spec/flows/FlowCrudSpec.groovy index a141deba673..14286b41a89 100644 --- a/src-java/testing/functional-tests/src/test/groovy/org/openkilda/functionaltests/spec/flows/FlowCrudSpec.groovy +++ b/src-java/testing/functional-tests/src/test/groovy/org/openkilda/functionaltests/spec/flows/FlowCrudSpec.groovy @@ -468,16 +468,8 @@ class FlowCrudSpec extends HealthCheckSpecification { given: "A switch that has no connection to other switches" def isolatedSwitch = switchPairs.all().nonNeighbouring().random().src def flow = data.getFlow(isolatedSwitch) - topology.getBusyPortsForSwitch(isolatedSwitch).each { port -> - antiflap.portDown(isolatedSwitch.dpId, port) - } - //wait until ISLs are actually got failed - wait(WAIT_OFFSET) { - def islData = northbound.getAllLinks() - topology.getRelatedIsls(isolatedSwitch).each { - assert islUtils.getIslInfo(islData, it).get().state == FAILED - } - } + def connectedIsls = topology.getRelatedIsls(isolatedSwitch) + islHelper.breakIsls(connectedIsls) when: "Try building a flow using the isolated switch" flowHelperV2.addFlow(flow) @@ -489,12 +481,7 @@ class FlowCrudSpec extends HealthCheckSpecification { cleanup: "Restore connection to the isolated switch and reset costs" !error && flowHelperV2.deleteFlow(flow.flowId) - topology.getBusyPortsForSwitch(isolatedSwitch).each { port -> - antiflap.portUp(isolatedSwitch.dpId, port) - } - wait(discoveryInterval + WAIT_OFFSET) { - northbound.getAllLinks().each { assert it.state == DISCOVERED } - } + islHelper.restoreIsls(connectedIsls) database.resetCosts(topology.isls) where: @@ -703,8 +690,7 @@ Failed to find path with requested bandwidth=${IMPOSSIBLY_HIGH_BANDWIDTH}/) given: "An inactive isl with failed state" Isl isl = topology.islsForActiveSwitches.find { it.aswitch && it.dstSwitch } assumeTrue(isl as boolean, "Unable to find required isl") - antiflap.portDown(isl.srcSwitch.dpId, isl.srcPort) - islUtils.waitForIslStatus([isl, isl.reversed], FAILED) + islHelper.breakIsl(isl) when: "Try to create a flow using ISL src port" def flow = flowHelperV2.randomFlow(isl.srcSwitch, isl.dstSwitch) @@ -718,8 +704,7 @@ Failed to find path with requested bandwidth=${IMPOSSIBLY_HIGH_BANDWIDTH}/) cleanup: "Restore state of the ISL" !exc && flow && flowHelperV2.deleteFlow(flow.flowId) - antiflap.portUp(isl.srcSwitch.dpId, isl.srcPort) - islUtils.waitForIslStatus([isl, isl.reversed], DISCOVERED) + islHelper.restoreIsl(isl) database.resetCosts(topology.isls) } diff --git a/src-java/testing/functional-tests/src/test/groovy/org/openkilda/functionaltests/spec/flows/FlowCrudV1Spec.groovy b/src-java/testing/functional-tests/src/test/groovy/org/openkilda/functionaltests/spec/flows/FlowCrudV1Spec.groovy index d603aaeb32e..d7d6fc461ce 100644 --- a/src-java/testing/functional-tests/src/test/groovy/org/openkilda/functionaltests/spec/flows/FlowCrudV1Spec.groovy +++ b/src-java/testing/functional-tests/src/test/groovy/org/openkilda/functionaltests/spec/flows/FlowCrudV1Spec.groovy @@ -500,16 +500,8 @@ class FlowCrudV1Spec extends HealthCheckSpecification { given: "A switch that has no connection to other switches" def isolatedSwitch = switchPairs.all().nonNeighbouring().random().src def flow = data.getFlow(isolatedSwitch) - topology.getBusyPortsForSwitch(isolatedSwitch).each { port -> - antiflap.portDown(isolatedSwitch.dpId, port) - } - //wait until ISLs are actually got failed - Wrappers.wait(WAIT_OFFSET) { - def islData = northbound.getAllLinks() - topology.getRelatedIsls(isolatedSwitch).each { - assert islUtils.getIslInfo(islData, it).get().state == IslChangeType.FAILED - } - } + def connectedIsls = topology.getRelatedIsls(isolatedSwitch) + islHelper.breakIsls(connectedIsls) when: "Try building a flow using the isolated switch" flowHelper.addFlow(flow) @@ -522,12 +514,7 @@ Failed to find path with requested bandwidth=$flow.maximumBandwidth/).matches(er cleanup: !error && flowHelper.deleteFlow(flow.id) - topology.getBusyPortsForSwitch(isolatedSwitch).each { port -> - antiflap.portUp(isolatedSwitch.dpId, port) - } - Wrappers.wait(discoveryInterval + WAIT_OFFSET) { - northbound.getAllLinks().each { assert it.state == DISCOVERED } - } + islHelper.restoreIsls(connectedIsls) database.resetCosts(topology.isls) where: @@ -676,8 +663,7 @@ Failed to find path with requested bandwidth=$flow.maximumBandwidth/).matches(er given: "An inactive isl with failed state" Isl isl = topology.islsForActiveSwitches.find { it.aswitch && it.dstSwitch } assumeTrue(isl as boolean, "Unable to find required isl") - antiflap.portDown(isl.srcSwitch.dpId, isl.srcPort) - islUtils.waitForIslStatus([isl, isl.reversed], FAILED) + islHelper.breakIsl(isl) when: "Try to create a flow using ISL src port" def flow = flowHelper.randomFlow(isl.srcSwitch, isl.dstSwitch) @@ -689,8 +675,7 @@ Failed to find path with requested bandwidth=$flow.maximumBandwidth/).matches(er new FlowNotCreatedExpectedError(getPortViolationError("source", isl.srcPort, isl.srcSwitch.dpId)).matches(exc) cleanup: !exc && flow && flowHelper.deleteFlow(flow.id) - antiflap.portUp(isl.srcSwitch.dpId, isl.srcPort) - islUtils.waitForIslStatus([isl, isl.reversed], DISCOVERED) + islHelper.restoreIsl(isl) database.resetCosts(topology.isls) } @@ -877,10 +862,7 @@ are not connected to the controller/).matches(exc) def islsToBreak = altPaths.collectMany { pathHelper.getInvolvedIsls(it) } .collectMany { [it, it.reversed] }.unique() .findAll { !untouchableIsls.contains(it) }.unique { [it, it.reversed].sort() } - withPool { islsToBreak.eachParallel { Isl isl -> antiflap.portDown(isl.srcSwitch.dpId, isl.srcPort) } } - Wrappers.wait(WAIT_OFFSET) { - assert northbound.getAllLinks().findAll { it.state == FAILED }.size() == islsToBreak.size() * 2 - } + islHelper.breakIsls(islsToBreak) and: "Update reverse path to have not enough bandwidth to handle the flow" //Forward path is still have enough bandwidth @@ -900,14 +882,10 @@ are not connected to the controller/).matches(exc) then: "Flow is not created" def e = thrown(HttpClientErrorException) new FlowNotCreatedWithMissingPathExpectedError(~/Not enough bandwidth or no path found./).matches(e) + cleanup: "Restore topology, delete the flow and reset costs" !e && flowHelperV2.deleteFlow(flow.id) - if (islsToBreak) { - withPool { islsToBreak.eachParallel { Isl isl -> antiflap.portUp(isl.srcSwitch.dpId, isl.srcPort) } } - Wrappers.wait(discoveryInterval + WAIT_OFFSET) { - assert northbound.getActiveLinks().size() == topology.islsForActiveSwitches.size() * 2 - } - } + islHelper.restoreIsls(islsToBreak) database.resetCosts(topology.isls) islsToModify.each { database.resetIslBandwidth(it) diff --git a/src-java/testing/functional-tests/src/test/groovy/org/openkilda/functionaltests/spec/flows/FlowDiversitySpec.groovy b/src-java/testing/functional-tests/src/test/groovy/org/openkilda/functionaltests/spec/flows/FlowDiversitySpec.groovy index 3569034e61b..3bc2f197658 100644 --- a/src-java/testing/functional-tests/src/test/groovy/org/openkilda/functionaltests/spec/flows/FlowDiversitySpec.groovy +++ b/src-java/testing/functional-tests/src/test/groovy/org/openkilda/functionaltests/spec/flows/FlowDiversitySpec.groovy @@ -218,17 +218,9 @@ class FlowDiversitySpec extends HealthCheckSpecification { def flow1Path = PathHelper.convert(northbound.getFlowPath(flow1.flowId)) and: "Make all alternative paths unavailable (bring ports down on the source switch)" - List broughtDownPorts = [] - switchPair.paths.findAll { it != flow1Path }.unique { it.first() }.each { path -> - def src = path.first() - broughtDownPorts.add(src) - antiflap.portDown(src.switchId, src.portNo) - } - Wrappers.wait(WAIT_OFFSET) { - assert northbound.getAllLinks().findAll { - it.state == IslChangeType.FAILED - }.size() == broughtDownPorts.size() * 2 - } + def broughtDownIsls = topology.getRelatedIsls(switchPair.getSrc()) + .findAll {it.srcPort != flow1Path.first().portNo} + islHelper.breakIsls(broughtDownIsls) when: "Create the second flow with diversity enabled" def flow2 = flowHelperV2.randomFlow(switchPair, false, [flow1]).tap { it.diverseFlowId = flow1.flowId } @@ -240,10 +232,7 @@ class FlowDiversitySpec extends HealthCheckSpecification { cleanup: "Restore topology, delete flows and reset costs" [flow1, flow2].each { it && flowHelperV2.deleteFlow(it.flowId) } - broughtDownPorts.each { antiflap.portUp(it.switchId, it.portNo) } - Wrappers.wait(discoveryInterval + WAIT_OFFSET) { - northbound.getAllLinks().each { assert it.state != IslChangeType.FAILED } - } + islHelper.restoreIsls(broughtDownIsls) database.resetCosts(topology.isls) } diff --git a/src-java/testing/functional-tests/src/test/groovy/org/openkilda/functionaltests/spec/flows/FlowLoopSpec.groovy b/src-java/testing/functional-tests/src/test/groovy/org/openkilda/functionaltests/spec/flows/FlowLoopSpec.groovy index d7db157c9cf..4be78acc47a 100644 --- a/src-java/testing/functional-tests/src/test/groovy/org/openkilda/functionaltests/spec/flows/FlowLoopSpec.groovy +++ b/src-java/testing/functional-tests/src/test/groovy/org/openkilda/functionaltests/spec/flows/FlowLoopSpec.groovy @@ -299,7 +299,7 @@ class FlowLoopSpec extends HealthCheckSpecification { when: "Fail a flow ISL (bring switch port down)" def islToFail = pathHelper.getInvolvedIsls(flowPath).last() - antiflap.portDown(islToFail.srcSwitch.dpId, islToFail.srcPort) + islHelper.breakIsl(islToFail) then: "The flow was rerouted" Wrappers.wait(rerouteDelay + WAIT_OFFSET) { @@ -336,7 +336,7 @@ class FlowLoopSpec extends HealthCheckSpecification { cleanup: "Revive the ISL back (bring switch port up) and delete the flow" flow && flowHelperV2.deleteFlow(flow.flowId) - islToFail && antiflap.portUp(islToFail.srcSwitch.dpId, islToFail.srcPort) + islHelper.restoreIsl(islToFail) Wrappers.wait(discoveryInterval + WAIT_OFFSET) { assert northbound.getActiveLinks().size() == topology.islsForActiveSwitches.size() * 2 } @@ -454,8 +454,7 @@ class FlowLoopSpec extends HealthCheckSpecification { def currentPath = pathHelper.convert(flowPathInfo) def currentProtectedPath = pathHelper.convert(flowPathInfo.protectedPath) def islToBreak = pathHelper.getInvolvedIsls(currentPath)[0] - antiflap.portDown(islToBreak.srcSwitch.dpId, islToBreak.srcPort) - def portIsDown = true + islHelper.breakIsl(islToBreak) then: "Flow is switched to protected path" Wrappers.wait(PROTECTED_PATH_INSTALLATION_TIME) { @@ -495,12 +494,7 @@ class FlowLoopSpec extends HealthCheckSpecification { cleanup: "Revert system to original state" flow && flowHelperV2.deleteFlow(flow.flowId) - if (portIsDown) { - antiflap.portUp(islToBreak.srcSwitch.dpId, islToBreak.srcPort) - Wrappers.wait(WAIT_OFFSET + discoveryInterval) { - assert islUtils.getIslInfo(islToBreak).get().state == IslChangeType.DISCOVERED - } - } + islHelper.restoreIsl(islToBreak) database.resetCosts(topology.isls) } diff --git a/src-java/testing/functional-tests/src/test/groovy/org/openkilda/functionaltests/spec/flows/FlowMonitoringSpec.groovy b/src-java/testing/functional-tests/src/test/groovy/org/openkilda/functionaltests/spec/flows/FlowMonitoringSpec.groovy index 7dc2f8f1d9d..84b59057b94 100644 --- a/src-java/testing/functional-tests/src/test/groovy/org/openkilda/functionaltests/spec/flows/FlowMonitoringSpec.groovy +++ b/src-java/testing/functional-tests/src/test/groovy/org/openkilda/functionaltests/spec/flows/FlowMonitoringSpec.groovy @@ -69,7 +69,7 @@ class FlowMonitoringSpec extends HealthCheckSpecification { islsToBreak = switchPair.paths.findAll { !paths.contains(it) } .collect { pathHelper.getInvolvedIsls(it).find { !isls.contains(it) && !isls.contains(it.reversed) } } .unique { [it, it.reversed].sort() } - islsToBreak.each { antiflap.portDown(it.srcSwitch.dpId, it.srcPort) } + islHelper.breakIsls(islsToBreak) } @ResourceLock(S42_TOGGLE) @@ -209,10 +209,7 @@ and flowLatencyMonitoringReactions is disabled in featureToggle"() { } def cleanupSpec() { - islsToBreak.each { getAntiflap().portUp(it.srcSwitch.dpId, it.srcPort) } - wait(getDiscoveryInterval() + WAIT_OFFSET) { - assert getNorthbound().getActiveLinks().size() == getTopology().islsForActiveSwitches.size() * 2 - } + islHelper.restoreIsls(islsToBreak) getDatabase().resetCosts(getTopology().isls) } } diff --git a/src-java/testing/functional-tests/src/test/groovy/org/openkilda/functionaltests/spec/flows/MaxLatencySpec.groovy b/src-java/testing/functional-tests/src/test/groovy/org/openkilda/functionaltests/spec/flows/MaxLatencySpec.groovy index 956c254336c..b4b555c82ad 100644 --- a/src-java/testing/functional-tests/src/test/groovy/org/openkilda/functionaltests/spec/flows/MaxLatencySpec.groovy +++ b/src-java/testing/functional-tests/src/test/groovy/org/openkilda/functionaltests/spec/flows/MaxLatencySpec.groovy @@ -65,7 +65,7 @@ class MaxLatencySpec extends HealthCheckSpecification { islsToBreak = switchPair.paths.findAll { !paths.contains(it) } .collect { pathHelper.getInvolvedIsls(it).find { !isls.contains(it) && !isls.contains(it.reversed) } } .unique { [it, it.reversed].sort() } - islsToBreak.each { antiflap.portDown(it.srcSwitch.dpId, it.srcPort) } + islHelper.breakIsls(islsToBreak) } def "Able to create protected flow with max_latency strategy if both paths satisfy SLA"() { @@ -212,7 +212,7 @@ class MaxLatencySpec extends HealthCheckSpecification { and: "Init auto reroute (bring port down on the src switch)" setLatencyForPaths(10, 15) def islToBreak = pathHelper.getInvolvedIsls(mainPath).first() - antiflap.portDown(islToBreak.srcSwitch.dpId, islToBreak.srcPort) + islHelper.breakIsl(islToBreak) then: "Flow is rerouted and goes to the DEGRADED state" wait(rerouteDelay + WAIT_OFFSET) { @@ -228,10 +228,7 @@ class MaxLatencySpec extends HealthCheckSpecification { cleanup: flow && flowHelperV2.deleteFlow(flow.flowId) - if (islToBreak) { - antiflap.portUp(islToBreak.srcSwitch.dpId, islToBreak.srcPort) - wait(discoveryInterval + WAIT_OFFSET) { assert islUtils.getIslInfo(islToBreak).get().state == DISCOVERED } - } + islHelper.restoreIsl(islToBreak) database.resetCosts(topology.isls) } @@ -317,7 +314,7 @@ but satisfies max_latency_tier2" when: "Break the flow path to init autoReroute" def islToBreak = pathHelper.getInvolvedIsls(mainPath).first() - antiflap.portDown(islToBreak.srcSwitch.dpId, islToBreak.srcPort) + islHelper.breakIsl(islToBreak) then: "Flow is not rerouted and moved to the DOWN state" wait(WAIT_OFFSET) { @@ -330,10 +327,7 @@ but satisfies max_latency_tier2" cleanup: flow && flowHelperV2.deleteFlow(flow.flowId) - if (islToBreak) { - antiflap.portUp(islToBreak.srcSwitch.dpId, islToBreak.srcPort) - wait(WAIT_OFFSET) { assert northbound.getLink(islToBreak).state == IslChangeType.FAILED } - } + islHelper.restoreIsl(islToBreak) database.resetCosts(topology.isls) } @@ -352,10 +346,7 @@ but satisfies max_latency_tier2" } def cleanupSpec() { - islsToBreak.each { getAntiflap().portUp(it.srcSwitch.dpId, it.srcPort) } - wait(getDiscoveryInterval() + WAIT_OFFSET) { - assert getNorthbound().getActiveLinks().size() == getTopology().islsForActiveSwitches.size() * 2 - } + islHelper.restoreIsls(islsToBreak) getDatabase().resetCosts(topology.isls) } } diff --git a/src-java/testing/functional-tests/src/test/groovy/org/openkilda/functionaltests/spec/flows/MultiRerouteSpec.groovy b/src-java/testing/functional-tests/src/test/groovy/org/openkilda/functionaltests/spec/flows/MultiRerouteSpec.groovy index e130def8bef..84d9bb880f4 100644 --- a/src-java/testing/functional-tests/src/test/groovy/org/openkilda/functionaltests/spec/flows/MultiRerouteSpec.groovy +++ b/src-java/testing/functional-tests/src/test/groovy/org/openkilda/functionaltests/spec/flows/MultiRerouteSpec.groovy @@ -58,7 +58,7 @@ class MultiRerouteSpec extends HealthCheckSpecification { isls + isls*.reversed }.unique() def islToBreak = currentIsls.find { !notCurrentIsls.contains(it) } - antiflap.portDown(islToBreak.srcSwitch.dpId, islToBreak.srcPort) + islHelper.breakIsl(islToBreak) TimeUnit.SECONDS.sleep(rerouteDelay - 1) then: "Half of the flows are hosted on the preferable path" @@ -91,12 +91,9 @@ class MultiRerouteSpec extends HealthCheckSpecification { cleanup: "revert system to original state" flows.each { it && flowHelperV2.deleteFlow(it.flowId) } - antiflap.portUp(islToBreak.srcSwitch.dpId, islToBreak.srcPort) + islHelper.restoreIsl(islToBreak) [thinIsl, thinIsl.reversed].each { database.resetIslBandwidth(it) } northbound.deleteLinkProps(northbound.getLinkProps(topology.isls)) - wait(WAIT_OFFSET + discoveryInterval) { - assert northbound.getLink(islToBreak).state == IslChangeType.DISCOVERED - } database.resetCosts(topology.isls) } } diff --git a/src-java/testing/functional-tests/src/test/groovy/org/openkilda/functionaltests/spec/flows/PinnedFlowSpec.groovy b/src-java/testing/functional-tests/src/test/groovy/org/openkilda/functionaltests/spec/flows/PinnedFlowSpec.groovy index 02057150093..9f0e39cbf23 100644 --- a/src-java/testing/functional-tests/src/test/groovy/org/openkilda/functionaltests/spec/flows/PinnedFlowSpec.groovy +++ b/src-java/testing/functional-tests/src/test/groovy/org/openkilda/functionaltests/spec/flows/PinnedFlowSpec.groovy @@ -113,7 +113,7 @@ class PinnedFlowSpec extends HealthCheckSpecification { }*.meterId] } - antiflap.portDown(islsToBreak[0].srcSwitch.dpId, islsToBreak[0].srcPort) + islHelper.breakIsl(islsToBreak[0]) then: "Flow is not rerouted and marked as DOWN when the first ISL is broken" Wrappers.wait(WAIT_OFFSET) { @@ -123,9 +123,7 @@ class PinnedFlowSpec extends HealthCheckSpecification { assert pathHelper.convert(northbound.getFlowPath(flow.flowId)) == currentPath } } - islsToBreak[1..-1].each { islToBreak -> - antiflap.portDown(islToBreak.srcSwitch.dpId, islToBreak.srcPort) - } + islHelper.breakIsls(islsToBreak[1..-1]) and: "Rules and meters are not changed" def cookiesMapAfterReroute = involvedSwitches.collectEntries { sw -> @@ -143,9 +141,7 @@ class PinnedFlowSpec extends HealthCheckSpecification { metersMap.sort() == metersMapAfterReroute.sort() when: "The broken ISLs are restored one by one" - islsToBreak[0..-2].each { islToBreak -> - antiflap.portUp(islToBreak.srcSwitch.dpId, islToBreak.srcPort) - } + islHelper.restoreIsls(islsToBreak[0..-2]) TimeUnit.SECONDS.sleep(rerouteDelay) Wrappers.wait(WAIT_OFFSET + discoveryInterval) { islsToBreak[0..-2].each { assert islUtils.getIslInfo(it).get().state == IslChangeType.DISCOVERED } @@ -153,23 +149,18 @@ class PinnedFlowSpec extends HealthCheckSpecification { assert pathHelper.convert(northbound.getFlowPath(flow.flowId)) == currentPath } + and: "Restore the last ISL" + islHelper.restoreIsl(islsToBreak[-1]) + then: "Flow is marked as UP when the last ISL is restored" - antiflap.portUp(islsToBreak[-1].srcSwitch.dpId, islsToBreak[-1].srcPort) Wrappers.wait(WAIT_OFFSET * 2) { - assert islUtils.getIslInfo(islsToBreak[-1]).get().state == IslChangeType.DISCOVERED assert northboundV2.getFlowStatus(flow.flowId).status == FlowState.UP assert pathHelper.convert(northbound.getFlowPath(flow.flowId)) == currentPath } - def islsAreUp = true cleanup: flow && flowHelperV2.deleteFlow(flow.flowId) - if (islsToBreak && !islsAreUp) { - islsToBreak.each { antiflap.portUp(it.srcSwitch.dpId, it.srcPort) } - Wrappers.wait(WAIT_OFFSET + discoveryInterval) { - assert northbound.getActiveLinks().size() == topology.islsForActiveSwitches.size() * 2 - } - } + islHelper.restoreIsls(islsToBreak) northbound.deleteLinkProps(northbound.getLinkProps(topology.isls)) database.resetCosts(topology.isls) } diff --git a/src-java/testing/functional-tests/src/test/groovy/org/openkilda/functionaltests/spec/flows/ProtectedPathSpec.groovy b/src-java/testing/functional-tests/src/test/groovy/org/openkilda/functionaltests/spec/flows/ProtectedPathSpec.groovy index 2cb9568a9cd..74bd0f65dd9 100644 --- a/src-java/testing/functional-tests/src/test/groovy/org/openkilda/functionaltests/spec/flows/ProtectedPathSpec.groovy +++ b/src-java/testing/functional-tests/src/test/groovy/org/openkilda/functionaltests/spec/flows/ProtectedPathSpec.groovy @@ -1,31 +1,11 @@ package org.openkilda.functionaltests.spec.flows -import static groovyx.gpars.GParsPool.withPool -import static org.junit.jupiter.api.Assumptions.assumeTrue -import static org.openkilda.functionaltests.extension.tags.Tag.ISL_PROPS_DB_RESET -import static org.openkilda.functionaltests.extension.tags.Tag.ISL_RECOVER_ON_FAIL -import static org.openkilda.functionaltests.extension.tags.Tag.LOW_PRIORITY -import static org.openkilda.functionaltests.extension.tags.Tag.SMOKE -import static org.openkilda.functionaltests.extension.tags.Tag.SMOKE_SWITCHES -import static org.openkilda.functionaltests.helpers.FlowHistoryConstants.REROUTE_ACTION -import static org.openkilda.functionaltests.helpers.FlowHistoryConstants.REROUTE_FAIL -import static org.openkilda.functionaltests.helpers.SwitchHelper.isDefaultMeter -import static org.openkilda.messaging.info.event.IslChangeType.FAILED -import static org.openkilda.model.MeterId.MAX_SYSTEM_RULE_METER_ID -import static org.openkilda.model.cookie.CookieBase.CookieType.SERVICE_OR_FLOW_SEGMENT -import static org.openkilda.testing.Constants.NON_EXISTENT_FLOW_ID -import static org.openkilda.testing.Constants.PATH_INSTALLATION_TIME -import static org.openkilda.testing.Constants.PROTECTED_PATH_INSTALLATION_TIME -import static org.openkilda.testing.Constants.RULES_INSTALLATION_TIME -import static org.openkilda.testing.Constants.WAIT_OFFSET - +import groovy.util.logging.Slf4j import org.openkilda.functionaltests.HealthCheckSpecification import org.openkilda.functionaltests.extension.tags.IterationTag import org.openkilda.functionaltests.extension.tags.Tags import org.openkilda.functionaltests.helpers.Wrappers import org.openkilda.messaging.error.MessageError -import org.openkilda.messaging.info.event.IslChangeType -import org.openkilda.messaging.info.event.PathNode import org.openkilda.messaging.payload.flow.FlowState import org.openkilda.model.StatusInfo import org.openkilda.model.SwitchId @@ -35,8 +15,6 @@ import org.openkilda.northbound.dto.v2.switches.SwitchPatchDto import org.openkilda.testing.model.topology.TopologyDefinition.Isl import org.openkilda.testing.service.traffexam.TraffExamService import org.openkilda.testing.tools.FlowTrafficExamBuilder - -import groovy.util.logging.Slf4j import org.springframework.beans.factory.annotation.Autowired import org.springframework.web.client.HttpClientErrorException import spock.lang.Narrative @@ -45,6 +23,24 @@ import spock.lang.Shared import javax.inject.Provider +import static groovyx.gpars.GParsPool.withPool +import static org.junit.jupiter.api.Assumptions.assumeTrue +import static org.openkilda.functionaltests.extension.tags.Tag.ISL_PROPS_DB_RESET +import static org.openkilda.functionaltests.extension.tags.Tag.ISL_RECOVER_ON_FAIL +import static org.openkilda.functionaltests.extension.tags.Tag.LOW_PRIORITY +import static org.openkilda.functionaltests.extension.tags.Tag.SMOKE +import static org.openkilda.functionaltests.extension.tags.Tag.SMOKE_SWITCHES +import static org.openkilda.functionaltests.helpers.FlowHistoryConstants.REROUTE_ACTION +import static org.openkilda.functionaltests.helpers.FlowHistoryConstants.REROUTE_FAIL +import static org.openkilda.functionaltests.helpers.SwitchHelper.isDefaultMeter +import static org.openkilda.model.MeterId.MAX_SYSTEM_RULE_METER_ID +import static org.openkilda.model.cookie.CookieBase.CookieType.SERVICE_OR_FLOW_SEGMENT +import static org.openkilda.testing.Constants.NON_EXISTENT_FLOW_ID +import static org.openkilda.testing.Constants.PATH_INSTALLATION_TIME +import static org.openkilda.testing.Constants.PROTECTED_PATH_INSTALLATION_TIME +import static org.openkilda.testing.Constants.RULES_INSTALLATION_TIME +import static org.openkilda.testing.Constants.WAIT_OFFSET + @Slf4j @See("https://github.com/telstra/open-kilda/tree/develop/docs/design/solutions/protected-paths") @Narrative("""Protected path - it is pre-calculated, reserved, and deployed (except ingress rule), @@ -350,8 +346,7 @@ class ProtectedPathSpec extends HealthCheckSpecification { when: "Break ISL on the main path (bring port down) to init auto swap" def islToBreak = pathHelper.getInvolvedIsls(currentPath)[0] - def portDown = antiflap.portDown(islToBreak.srcSwitch.dpId, islToBreak.srcPort) - Wrappers.wait(WAIT_OFFSET) { assert northbound.getLink(islToBreak).state == IslChangeType.FAILED } + islHelper.breakIsl(islToBreak) then: "Flows are switched to protected paths" Wrappers.wait(PROTECTED_PATH_INSTALLATION_TIME) { @@ -368,22 +363,14 @@ class ProtectedPathSpec extends HealthCheckSpecification { } when: "Restore port status" - def portUp = antiflap.portUp(islToBreak.srcSwitch.dpId, islToBreak.srcPort) - Wrappers.wait(WAIT_OFFSET + discoveryInterval) { - assert islUtils.getIslInfo(islToBreak).get().state == IslChangeType.DISCOVERED - } + islHelper.restoreIsl(islToBreak) then: "Path of the flow is not changed" flows.each { assert pathHelper.convert(northbound.getFlowPath(it.flowId)) == currentProtectedPath } cleanup: "Revert system to original state" flows.each { it && flowHelperV2.deleteFlow(it.flowId) } - if (portDown && !portUp) { - antiflap.portUp(islToBreak.srcSwitch.dpId, islToBreak.srcPort) - Wrappers.wait(WAIT_OFFSET + discoveryInterval) { - assert islUtils.getIslInfo(islToBreak).get().state == IslChangeType.DISCOVERED - } - } + islHelper.restoreIsl(islToBreak) northbound.deleteLinkProps(northbound.getLinkProps(topology.isls)) database.resetCosts(topology.isls) @@ -396,7 +383,13 @@ class ProtectedPathSpec extends HealthCheckSpecification { @Tags([ISL_RECOVER_ON_FAIL, ISL_PROPS_DB_RESET]) def "Flow swaps to protected path when main path gets broken, becomes DEGRADED if protected path is unable to reroute(no bw)"() { given: "Two switches with 2 diverse paths at least" - def switchPair = switchPairs.all().withAtLeastNNonOverlappingPaths(2).random() + //def switchPair = switchPairs.all().withAtLeastNNonOverlappingPaths(2).random() + //https://github.com/telstra/open-kilda/issues/5608 + def switchesWhere5608IsReproducible = topology.activeSwitches.findAll {it.dpId.toString().endsWith("08") + ||it.dpId.toString().endsWith("09")} + def switchPair = switchPairs.all() + .excludeSwitches(switchesWhere5608IsReproducible) + .withAtLeastNNonOverlappingPaths(2).random() when: "Create flow with protected path" def flow = flowHelperV2.randomFlow(switchPair).tap { allocateProtectedPath = true } @@ -414,7 +407,7 @@ class ProtectedPathSpec extends HealthCheckSpecification { and: "Main flow path breaks" def mainIsl = pathHelper.getInvolvedIsls(path).first() - def mainIslDown = antiflap.portDown(mainIsl.srcSwitch.dpId, mainIsl.srcPort) + islHelper.breakIsl(mainIsl) then: "Main path swaps to protected, flow becomes degraded, main path UP, protected DOWN" Wrappers.wait(WAIT_OFFSET) { @@ -431,8 +424,7 @@ Failed to find path with requested bandwidth=$flow.maximumBandwidth/ } when: "ISL gets back up" - def mainIslUp = antiflap.portUp(mainIsl.srcSwitch.dpId, mainIsl.srcPort) - Wrappers.wait(WAIT_OFFSET) { assert northbound.getLink(mainIsl).state == IslChangeType.DISCOVERED } + islHelper.restoreIsl(mainIsl) then: "Main path remains the same, flow becomes UP, main path UP, protected UP" Wrappers.wait(WAIT_OFFSET) { @@ -447,16 +439,22 @@ Failed to find path with requested bandwidth=$flow.maximumBandwidth/ cleanup: flow && flowHelperV2.deleteFlow(flow.flowId) - mainIslDown && !mainIslUp && antiflap.portUp(mainIsl.srcSwitch.dpId, mainIsl.srcPort) + islHelper.restoreIsl(mainIsl) otherIsls && otherIsls.collectMany{[it, it.reversed]}.each { database.resetIslBandwidth(it) } - Wrappers.wait(WAIT_OFFSET) { assert northbound.getLink(mainIsl).state == IslChangeType.DISCOVERED } database.resetCosts(topology.isls) } @Tags(ISL_RECOVER_ON_FAIL) def "Flow swaps to protected path when main path gets broken, becomes DEGRADED if protected path is unable to reroute(no path)"() { given: "Two switches with 2 diverse paths at least" - def switchPair = switchPairs.all().withAtLeastNNonOverlappingPaths(2).random() + //def switchPair = switchPairs.all().withAtLeastNNonOverlappingPaths(2).random() + //https://github.com/telstra/open-kilda/issues/5608 + def switchesWhere5608IsReproducible = topology.activeSwitches.findAll {it.dpId.toString().endsWith("08") + ||it.dpId.toString().endsWith("09")} + def switchPair = switchPairs.all() + .excludeSwitches(switchesWhere5608IsReproducible) + .withAtLeastNNonOverlappingPaths(2).random() + when: "Create flow with protected path" def flow = flowHelperV2.randomFlow(switchPair).tap { allocateProtectedPath = true } @@ -471,19 +469,11 @@ Failed to find path with requested bandwidth=$flow.maximumBandwidth/ it != originalProtectedPath }.collectMany { pathHelper.getInvolvedIsls(it) } .findAll {!usedIsls.contains(it) } .unique { a, b -> a == b || a == b.reversed ? 0 : 1 } - withPool { - otherIsls.eachParallel { - antiflap.portDown(it.srcSwitch.dpId, it.srcPort) - } - } - Wrappers.wait(WAIT_OFFSET) { - def links = northbound.getAllLinks() - assert otherIsls.each {islUtils.getIslInfo(links, it).get().state == FAILED} - } + islHelper.breakIsls(otherIsls) and: "Main flow path breaks" def mainIsl = pathHelper.getInvolvedIsls(path).first() - def mainIslDown = antiflap.portDown(mainIsl.srcSwitch.dpId, mainIsl.srcPort) + islHelper.breakIsl(mainIsl) then: "Main path swaps to protected, flow becomes degraded, main path UP, protected DOWN" Wrappers.wait(WAIT_OFFSET) { @@ -498,8 +488,7 @@ Failed to find path with requested bandwidth=$flow.maximumBandwidth/ } when: "ISL on broken path gets back up" - def mainIslUp = antiflap.portUp(mainIsl.srcSwitch.dpId, mainIsl.srcPort) - Wrappers.wait(WAIT_OFFSET) { assert northbound.getLink(mainIsl).state == IslChangeType.DISCOVERED } + islHelper.restoreIsl(mainIsl) then: "Main path remains the same (no swap), flow becomes UP, main path remains UP, protected path becomes UP" Wrappers.wait(WAIT_OFFSET) { @@ -515,10 +504,7 @@ Failed to find path with requested bandwidth=$flow.maximumBandwidth/ cleanup: flow && flowHelperV2.deleteFlow(flow.flowId) - mainIslDown && !mainIslUp && antiflap.portUp(mainIsl.srcSwitch.dpId, mainIsl.srcPort) - otherIsls && otherIsls.each { antiflap.portUp(it.srcSwitch.dpId, it.srcPort) } - Wrappers.wait(discoveryInterval + WAIT_OFFSET) { - northbound.getAllLinks().each { assert it.state == IslChangeType.DISCOVERED } } + islHelper.restoreIsls(otherIsls + mainIsl) database.resetCosts(topology.isls) } @@ -606,7 +592,7 @@ Failed to find path with requested bandwidth=$flow.maximumBandwidth/ and: "Break ISL on the main path (bring port down) to init auto swap" def islToBreak = pathHelper.getInvolvedIsls(currentPath)[0] - def portDown = antiflap.portDown(islToBreak.srcSwitch.dpId, islToBreak.srcPort) + islHelper.breakIsl(islToBreak) then: "Flow is switched to protected path" Wrappers.wait(PROTECTED_PATH_INSTALLATION_TIME) { @@ -624,22 +610,14 @@ Failed to find path with requested bandwidth=$flow.maximumBandwidth/ } when: "Restore port status" - def portUp = antiflap.portUp(islToBreak.srcSwitch.dpId, islToBreak.srcPort) - Wrappers.wait(WAIT_OFFSET + discoveryInterval) { - assert islUtils.getIslInfo(islToBreak).get().state == IslChangeType.DISCOVERED - } + islHelper.restoreIsl(islToBreak) then: "Path of the flow is not changed" pathHelper.convert(northbound.getFlowPath(flow.flowId)) == currentProtectedPath cleanup: "Revert system to original state" flow && flowHelperV2.deleteFlow(flow.flowId) - if (portDown && !portUp) { - antiflap.portUp(islToBreak.srcSwitch.dpId, islToBreak.srcPort) - Wrappers.wait(WAIT_OFFSET + discoveryInterval) { - assert islUtils.getIslInfo(islToBreak).get().state == IslChangeType.DISCOVERED - } - } + islHelper.restoreIsl(islToBreak) northbound.deleteLinkProps(northbound.getLinkProps(topology.isls)) database.resetCosts(topology.isls) @@ -773,11 +751,7 @@ Failed to find path with requested bandwidth=$flow.maximumBandwidth/ when: "Break ISL on the protected path (bring port down) to init the recalculate procedure" def islToBreakProtectedPath = protectedIsls[0] - def portDown = antiflap.portDown(islToBreakProtectedPath.dstSwitch.dpId, islToBreakProtectedPath.dstPort) - - Wrappers.wait(WAIT_OFFSET + discoveryInterval) { - assert islUtils.getIslInfo(islToBreakProtectedPath).get().state == IslChangeType.FAILED - } + islHelper.breakIsl(islToBreakProtectedPath) then: "Protected path is recalculated" def newProtectedPath @@ -816,22 +790,14 @@ Failed to find path with requested bandwidth=$flow.maximumBandwidth/ originInfoBrokenIsl.availableBandwidth == currentInfoBrokenIsl.availableBandwidth when: "Restore port status" - def portUp = antiflap.portUp(islToBreakProtectedPath.dstSwitch.dpId, islToBreakProtectedPath.dstPort) - Wrappers.wait(WAIT_OFFSET + discoveryInterval) { - assert islUtils.getIslInfo(islToBreakProtectedPath).get().state == IslChangeType.DISCOVERED - } + islHelper.restoreIsl(islToBreakProtectedPath) then: "Path is not recalculated again" pathHelper.convert(northbound.getFlowPath(flow.flowId).protectedPath) == newProtectedPath cleanup: "Revert system to original state" flow && flowHelperV2.deleteFlow(flow.flowId) - if (portDown && !portUp) { - antiflap.portUp(islToBreakProtectedPath.dstSwitch.dpId, islToBreakProtectedPath.dstPort) - Wrappers.wait(WAIT_OFFSET + discoveryInterval) { - assert islUtils.getIslInfo(islToBreakProtectedPath).get().state == IslChangeType.DISCOVERED - } - } + islHelper.restoreIsl(islToBreakProtectedPath) database.resetCosts(topology.isls) } @@ -850,18 +816,11 @@ Failed to find path with requested bandwidth=$flow.maximumBandwidth/ flowHelperV2.addFlow(flow) and: "All alternative paths are unavailable (bring ports down on the source switch)" - List broughtDownPorts = [] - switchPair.paths.findAll { it != pathHelper.convert(northbound.getFlowPath(flow.flowId)) }.unique { it.first() } - .each { path -> - def src = path.first() - broughtDownPorts.add(src) - antiflap.portDown(src.switchId, src.portNo) - } - Wrappers.wait(WAIT_OFFSET) { - assert northbound.getAllLinks().findAll { - it.state == IslChangeType.FAILED - }.size() == broughtDownPorts.size() * 2 - } + def flowPathPortOnSourceSwitch = pathHelper.convert(northbound.getFlowPath(flow.flowId)).first().portNo + def broughtDownIsls = topology.getRelatedIsls(switchPair.getSrc()) + .findAll{it.srcSwitch == switchPair.getSrc() && it.srcPort != flowPathPortOnSourceSwitch } + islHelper.breakIsls(broughtDownIsls) + when: "Update flow: enable protected path(allocateProtectedPath=true)" northboundV2.updateFlow(flow.flowId, flow.tap { it.allocateProtectedPath = true }) @@ -874,10 +833,7 @@ Failed to find path with requested bandwidth=$flow.maximumBandwidth/ cleanup: "Restore topology, delete flows and reset costs" flow && flowHelperV2.deleteFlow(flow.flowId) - broughtDownPorts.every { antiflap.portUp(it.switchId, it.portNo) } - Wrappers.wait(discoveryInterval + WAIT_OFFSET) { - northbound.getAllLinks().each { assert it.state != IslChangeType.FAILED } - } + islHelper.restoreIsls(broughtDownIsls) database.resetCosts(topology.isls) where: @@ -909,12 +865,7 @@ Failed to find path with requested bandwidth=$flow.maximumBandwidth/ def islsToBreak = altPaths.collectMany { pathHelper.getInvolvedIsls(it) } .collectMany { [it, it.reversed] }.unique() .findAll { !untouchableIsls.contains(it) }.unique { [it, it.reversed].sort() } - withPool { islsToBreak.eachParallel { Isl isl -> antiflap.portDown(isl.srcSwitch.dpId, isl.srcPort) } } - Wrappers.wait(WAIT_OFFSET) { - assert northbound.getAllLinks().findAll { - it.state == IslChangeType.FAILED - }.size() == islsToBreak.size() * 2 - } + islHelper.breakIsls(islsToBreak) then: "Flow status is DEGRADED" Wrappers.wait(WAIT_OFFSET) { @@ -939,10 +890,7 @@ Failed to find path with requested bandwidth=$flow.maximumBandwidth/ cleanup: "Restore topology, delete flow and reset costs" flow && flowHelperV2.deleteFlow(flow.flowId) - withPool { islsToBreak.eachParallel { Isl isl -> antiflap.portUp(isl.srcSwitch.dpId, isl.srcPort) } } - Wrappers.wait(discoveryInterval + WAIT_OFFSET) { - northbound.getAllLinks().each { assert it.state != IslChangeType.FAILED } - } + islHelper.restoreIsls(islsToBreak) database.resetCosts(topology.isls) where: @@ -966,17 +914,13 @@ Failed to find path with requested bandwidth=$flow.maximumBandwidth/ def mainPathIsl = pathHelper.getInvolvedIsls(mainPath).first() def protectedPath = pathHelper.convert(paths.protectedPath) def protectedPathIsl = pathHelper.getInvolvedIsls(protectedPath).first() - antiflap.portDown(mainPathIsl.srcSwitch.dpId, mainPathIsl.srcPort) - Wrappers.wait(3, 0) { - assert northbound.getLink(mainPathIsl).state == IslChangeType.FAILED - } + islHelper.breakIsl(mainPathIsl) and: "Protected path breaks when swap is in progress" //we want to break the second ISL right when the protected path reroute starts. race here //+750ms correction was found experimentally. helps to hit the race condition more often (local env) sleep(Math.max(0, (rerouteDelay - antiflapMin) * 1000 + 750)) - antiflap.portDown(protectedPathIsl.srcSwitch.dpId, protectedPathIsl.srcPort) - def portsDown = true + islHelper.breakIsl(protectedPathIsl) then: "Both paths are successfully evacuated from broken isls and the flow is UP" log.debug("original main: $mainPath\n original protected: $protectedPath") @@ -994,14 +938,9 @@ Failed to find path with requested bandwidth=$flow.maximumBandwidth/ cleanup: flow && flowHelperV2.deleteFlow(flow.flowId) - if(portsDown) { - [mainPathIsl, protectedPathIsl].each { antiflap.portUp(it.srcSwitch.dpId, it.srcPort) } - Wrappers.wait(discoveryInterval + WAIT_OFFSET) { - assert northbound.getLink(mainPathIsl).state == IslChangeType.DISCOVERED - assert northbound.getLink(protectedPathIsl).state == IslChangeType.DISCOVERED - } - database.resetCosts(topology.isls) - } + islHelper.restoreIsls([mainPathIsl, protectedPathIsl]) + database.resetCosts(topology.isls) + } def "System reuses current protected path when can't find new non overlapping protected path while intentional\ @@ -1129,22 +1068,9 @@ Failed to find path with requested bandwidth=$flow.maximumBandwidth/ } and: "All alternative paths unavailable (bring ports down on the source switch)" - List broughtDownPorts = [] - def altPaths = allPaths.findAll { !(it in allPathsWithThreeSwitches) } - altPaths*.first().unique().findAll { - !(it in allPathsWithThreeSwitches*.first().unique()) - }.each { broughtDownPorts.add(it) } - altPaths*.last().unique().findAll { - !(it in allPathsWithThreeSwitches*.last().unique()) - }.each { broughtDownPorts.add(it) } - broughtDownPorts.each { - antiflap.portDown(it.switchId, it.portNo) - } - Wrappers.wait(WAIT_OFFSET) { - assert northbound.getAllLinks().findAll { - it.state == IslChangeType.FAILED - }.size() == broughtDownPorts.size() * 2 - } + List broughtDownIsls = topology.getRelatedIsls(swPair.src) - + [mainPath1, mainPath2, protectedPath].collect {pathHelper.getInvolvedIsls(it).first()} + islHelper.breakIsls(broughtDownIsls) when: "Create a protected flow" /** At this point we have the following topology: @@ -1180,16 +1106,13 @@ Failed to find path with requested bandwidth=$flow.maximumBandwidth/ cleanup: northbound.deleteLinkProps(northbound.getLinkProps(topology.isls)) flow && flowHelperV2.deleteFlow(flow.flowId) - broughtDownPorts && broughtDownPorts.every { antiflap.portUp(it.switchId, it.portNo) } - Wrappers.wait(discoveryInterval + WAIT_OFFSET) { - assert northbound.getActiveLinks().size() == topology.islsForActiveSwitches.size() * 2 - } + islHelper.restoreIsls(broughtDownIsls) withPool { (involvedSwP1 + involvedSwP2 + involvedSwProtected).unique().eachParallel { swId -> northboundV2.partialSwitchUpdate(swId, new SwitchPatchDto().tap { it.pop = "" }) } } - broughtDownPorts && database.resetCosts(topology.isls) + database.resetCosts(topology.isls) } @Tags(LOW_PRIORITY) @@ -1261,7 +1184,10 @@ Failed to find path with requested bandwidth=$flow.maximumBandwidth/ @Tags([LOW_PRIORITY, ISL_RECOVER_ON_FAIL]) def "Unable to swap paths for an inactive flow"() { given: "Two active neighboring switches with two not overlapping paths at least" - def switchPair = switchPairs.all().neighbouring().withAtLeastNNonOverlappingPaths(2).random() + def switchPair = switchPairs.all().neighbouring() + //https://github.com/telstra/open-kilda/issues/5608 + .excludeSwitches(topology.activeSwitches.findAll {it.dpId.toString().endsWith("08")}) + .withAtLeastNNonOverlappingPaths(2).random() and: "A flow with protected path" def flow = flowHelperV2.randomFlow(switchPair) @@ -1269,22 +1195,9 @@ Failed to find path with requested bandwidth=$flow.maximumBandwidth/ flowHelperV2.addFlow(flow) and: "All alternative paths are unavailable (bring ports down on the source switch)" - List broughtDownPorts = [] - switchPair.paths.findAll { - it != pathHelper.convert(northbound.getFlowPath(flow.flowId)) && - it != pathHelper.convert(northbound.getFlowPath(flow.flowId).protectedPath) - }.unique { - it.first() - }.each { path -> - def src = path.first() - broughtDownPorts.add(src) - antiflap.portDown(src.switchId, src.portNo) - } - Wrappers.wait(WAIT_OFFSET) { - assert northbound.getAllLinks().findAll { - it.state == IslChangeType.FAILED - }.size() == broughtDownPorts.size() * 2 - } + def flowPathIsl = pathHelper.getInvolvedIsls(pathHelper.convert(northbound.getFlowPath(flow.flowId))) + def broughtDownIsls = topology.getRelatedIsls(switchPair.src) - flowPathIsl + islHelper.breakIsls(broughtDownIsls) when: "Break ISL on a protected path (bring port down) for changing the flow state to DEGRADED" def flowPathInfo = northbound.getFlowPath(flow.flowId) @@ -1292,7 +1205,7 @@ Failed to find path with requested bandwidth=$flow.maximumBandwidth/ def currentProtectedPath = pathHelper.convert(flowPathInfo.protectedPath) def protectedIsls = pathHelper.getInvolvedIsls(currentProtectedPath) def currentIsls = pathHelper.getInvolvedIsls(currentPath) - antiflap.portDown(protectedIsls[0].dstSwitch.dpId, protectedIsls[0].dstPort) + islHelper.breakIsl(protectedIsls[0]) then: "Flow state is changed to DEGRADED" Wrappers.wait(WAIT_OFFSET) { assert northboundV2.getFlowStatus(flow.flowId).status == FlowState.DEGRADED } @@ -1302,7 +1215,7 @@ Failed to find path with requested bandwidth=$flow.maximumBandwidth/ } when: "Break ISL on the main path (bring port down) for changing the flow state to DOWN" - antiflap.portDown(currentIsls[0].dstSwitch.dpId, currentIsls[0].dstPort) + islHelper.breakIsl(currentIsls[0]) then: "Flow state is changed to DOWN" Wrappers.wait(WAIT_OFFSET) { @@ -1326,8 +1239,7 @@ Failed to find path with requested bandwidth=$flow.maximumBandwidth/ "Could not swap paths: Protected flow path $flow.flowId is not in ACTIVE state" when: "Restore ISL for the main path only" - antiflap.portUp(currentIsls[0].srcSwitch.dpId, currentIsls[0].srcPort) - antiflap.portUp(currentIsls[0].dstSwitch.dpId, currentIsls[0].dstPort) + islHelper.restoreIsl(currentIsls[0]) then: "Flow state is still DEGRADED" Wrappers.wait(PROTECTED_PATH_INSTALLATION_TIME) { @@ -1351,8 +1263,7 @@ Failed to find path with requested bandwidth=$flow.maximumBandwidth/ "Could not swap paths: Protected flow path $flow.flowId is not in ACTIVE state" when: "Restore ISL for the protected path" - antiflap.portUp(protectedIsls[0].srcSwitch.dpId, protectedIsls[0].srcPort) - antiflap.portUp(protectedIsls[0].dstSwitch.dpId, protectedIsls[0].dstPort) + islHelper.restoreIsl(protectedIsls[0]) then: "Flow state is changed to UP" //it often fails in scope of the whole spec on the hardware env, that's why '* 1.5' is added @@ -1362,10 +1273,7 @@ Failed to find path with requested bandwidth=$flow.maximumBandwidth/ cleanup: "Restore topology, delete flows and reset costs" flow && flowHelperV2.deleteFlow(flow.flowId) - broughtDownPorts.every { antiflap.portUp(it.switchId, it.portNo) } - Wrappers.wait(discoveryInterval + WAIT_OFFSET) { - northbound.getAllLinks().each { assert it.state != IslChangeType.FAILED } - } + islHelper.restoreIsls(broughtDownIsls) database.resetCosts(topology.isls) } @@ -1418,20 +1326,8 @@ Failed to find path with requested bandwidth=$flow.maximumBandwidth/ def "Unable to create #flowDescription flow with protected path if all alternative paths are unavailable"() { given: "Two active neighboring switches without alt paths" def switchPair = switchPairs.all().neighbouring().random() - List broughtDownPorts = [] - - switchPair.paths.sort { it.size() }[1..-1].unique { - it.first() - }.each { path -> - def src = path.first() - broughtDownPorts.add(src) - antiflap.portDown(src.switchId, src.portNo) - } - Wrappers.wait(WAIT_OFFSET) { - assert northbound.getAllLinks().findAll { - it.state == IslChangeType.FAILED - }.size() == broughtDownPorts.size() * 2 - } + def broughtDownIsls = topology.getRelatedIsls(switchPair.src)[1..-1] + islHelper.breakIsls(broughtDownIsls) when: "Try to create a new flow with protected path" def flow = flowHelperV2.randomFlow(switchPair) @@ -1450,10 +1346,7 @@ Failed to find path with requested bandwidth=$flow.maximumBandwidth/ cleanup: "Restore topology, delete flows and reset costs" !exc && flowHelperV2.deleteFlow(flow.flowId) - broughtDownPorts.every { antiflap.portUp(it.switchId, it.portNo) } - Wrappers.wait(discoveryInterval + WAIT_OFFSET) { - northbound.getAllLinks().each { assert it.state != IslChangeType.FAILED } - } + islHelper.restoreIsls(broughtDownIsls) database.resetCosts(topology.isls) where: @@ -1477,25 +1370,14 @@ Failed to find path with requested bandwidth=$flow.maximumBandwidth/ and: "All alternative paths are unavailable (bring ports down on the source switch)" def flowPathInfo = northbound.getFlowPath(flow.flowId) def currentPath = pathHelper.convert(flowPathInfo) + def currentPathIsls = pathHelper.getInvolvedIsls(currentPath) def currentProtectedPath = pathHelper.convert(flowPathInfo.protectedPath) - List broughtDownPorts = [] - switchPair.paths.findAll { it != currentPath && it != currentProtectedPath }.unique { - it.first() - }.each { path -> - def src = path.first() - broughtDownPorts.add(src) - antiflap.portDown(src.switchId, src.portNo) - } - Wrappers.wait(WAIT_OFFSET) { - assert northbound.getAllLinks().findAll { - it.state == IslChangeType.FAILED - }.size() == broughtDownPorts.size() * 2 - } - - and: "ISL on a protected path is broken(bring port down) for changing the flow state to DEGRADED" def protectedIslToBreak = pathHelper.getInvolvedIsls(currentProtectedPath)[0] - antiflap.portDown(protectedIslToBreak.dstSwitch.dpId, protectedIslToBreak.dstPort) + def broughtDownIsls = topology.getRelatedIsls(switchPair.src) - currentPathIsls.first() - protectedIslToBreak + islHelper.breakIsls(broughtDownIsls) + and: "ISL on a protected path is broken(bring port down) for changing the flow state to DEGRADED" + islHelper.breakIsl(protectedIslToBreak) Wrappers.wait(WAIT_OFFSET) { assert northboundV2.getFlowStatus(flow.flowId).status == FlowState.DEGRADED } when: "Make the current path less preferable than alternative path" @@ -1509,10 +1391,7 @@ Failed to find path with requested bandwidth=$flow.maximumBandwidth/ assert northbound.getLink(currentIsl).cost > northbound.getLink(alternativeIsl).cost and: "Make alternative path available(bring port up on the source switch)" - antiflap.portUp(alternativeIsl.srcSwitch.dpId, alternativeIsl.srcPort) - Wrappers.wait(discoveryInterval + WAIT_OFFSET) { - assert islUtils.getIslInfo(alternativeIsl).get().state == IslChangeType.DISCOVERED - } + islHelper.restoreIsl(alternativeIsl) then: "Flow state is changed to UP" Wrappers.wait(WAIT_OFFSET) { assert northboundV2.getFlowStatus(flow.flowId).status == FlowState.UP } @@ -1524,11 +1403,7 @@ Failed to find path with requested bandwidth=$flow.maximumBandwidth/ cleanup: "Restore topology, delete flow and reset costs" flow && flowHelperV2.deleteFlow(flow.flowId) - antiflap.portUp(protectedIslToBreak.dstSwitch.dpId, protectedIslToBreak.dstPort) - broughtDownPorts.each { antiflap.portUp(it.switchId, it.portNo) } - Wrappers.wait(discoveryInterval + WAIT_OFFSET) { - assert northbound.getActiveLinks().size() == topology.islsForActiveSwitches.size() * 2 - } + islHelper.restoreIsls(broughtDownIsls + protectedIslToBreak) northbound.deleteLinkProps(northbound.getLinkProps(topology.isls)) database.resetCosts(topology.isls) } diff --git a/src-java/testing/functional-tests/src/test/groovy/org/openkilda/functionaltests/spec/flows/ProtectedPathV1Spec.groovy b/src-java/testing/functional-tests/src/test/groovy/org/openkilda/functionaltests/spec/flows/ProtectedPathV1Spec.groovy index 66790fb741b..c95d665d3c5 100644 --- a/src-java/testing/functional-tests/src/test/groovy/org/openkilda/functionaltests/spec/flows/ProtectedPathV1Spec.groovy +++ b/src-java/testing/functional-tests/src/test/groovy/org/openkilda/functionaltests/spec/flows/ProtectedPathV1Spec.groovy @@ -217,20 +217,8 @@ class ProtectedPathV1Spec extends HealthCheckSpecification { def "Unable to create #flowDescription flow with protected path if all alternative paths are unavailable"() { given: "Two active neighboring switches without alt paths" def switchPair = switchPairs.all().neighbouring().random() - List broughtDownPorts = [] - - switchPair.paths.sort { it.size() }[1..-1].unique { - it.first() - }.each { path -> - def src = path.first() - broughtDownPorts.add(src) - antiflap.portDown(src.switchId, src.portNo) - } - Wrappers.wait(WAIT_OFFSET) { - assert northbound.getAllLinks().findAll { - it.state == IslChangeType.FAILED - }.size() == broughtDownPorts.size() * 2 - } + def broughtDownIsls = topology.getRelatedIsls(switchPair.src)[1..-1] + islHelper.breakIsls(broughtDownIsls) when: "Try to create a new flow with protected path" def flow = flowHelper.randomFlow(switchPair) @@ -249,10 +237,7 @@ class ProtectedPathV1Spec extends HealthCheckSpecification { cleanup: !exc && flowHelper.deleteFlow(flow.id) - broughtDownPorts.every { antiflap.portUp(it.switchId, it.portNo) } - Wrappers.wait(discoveryInterval + WAIT_OFFSET) { - northbound.getAllLinks().each { assert it.state != IslChangeType.FAILED } - } + islHelper.restoreIsls(broughtDownIsls) database.resetCosts(topology.isls) where: @@ -455,22 +440,9 @@ class ProtectedPathV1Spec extends HealthCheckSpecification { flowHelper.addFlow(flow) and: "All alternative paths are unavailable (bring ports down on the source switch)" - List broughtDownPorts = [] - switchPair.paths.findAll { - it != pathHelper.convert(northbound.getFlowPath(flow.id)) && - it != pathHelper.convert(northbound.getFlowPath(flow.id).protectedPath) - }.unique { - it.first() - }.each { path -> - def src = path.first() - broughtDownPorts.add(src) - antiflap.portDown(src.switchId, src.portNo) - } - Wrappers.wait(WAIT_OFFSET) { - assert northbound.getAllLinks().findAll { - it.state == IslChangeType.FAILED - }.size() == broughtDownPorts.size() * 2 - } + def flowPathIsl = pathHelper.getInvolvedIsls(pathHelper.convert(northbound.getFlowPath(flow.id).forwardPath)) + def broughtDownIsls = topology.getRelatedIsls(switchPair.src) - flowPathIsl + islHelper.breakIsls(broughtDownIsls) when: "Break ISL on a protected path (bring port down) for changing the flow state to DEGRADED" def flowPathInfo = northbound.getFlowPath(flow.id) @@ -478,7 +450,7 @@ class ProtectedPathV1Spec extends HealthCheckSpecification { def currentProtectedPath = pathHelper.convert(flowPathInfo.protectedPath) def protectedIsls = pathHelper.getInvolvedIsls(currentProtectedPath) def currentIsls = pathHelper.getInvolvedIsls(currentPath) - antiflap.portDown(protectedIsls[0].dstSwitch.dpId, protectedIsls[0].dstPort) + islHelper.breakIsl(protectedIsls[0]) then: "Flow state is changed to DEGRADED" Wrappers.wait(WAIT_OFFSET) { assert northbound.getFlowStatus(flow.id).status == FlowState.DEGRADED } @@ -488,8 +460,7 @@ class ProtectedPathV1Spec extends HealthCheckSpecification { } when: "Break ISL on the main path (bring port down) for changing the flow state to DOWN" - antiflap.portDown(currentIsls[0].dstSwitch.dpId, currentIsls[0].dstPort) - Wrappers.wait(WAIT_OFFSET) { assert northbound.getLink(currentIsls[0]).state == IslChangeType.FAILED } + islHelper.breakIsl(currentIsls[0]) then: "Flow state is changed to DOWN" Wrappers.wait(WAIT_OFFSET) { @@ -513,8 +484,7 @@ class ProtectedPathV1Spec extends HealthCheckSpecification { "Could not swap paths: Protected flow path $flow.id is not in ACTIVE state" when: "Restore ISL for the main path only" - antiflap.portUp(currentIsls[0].srcSwitch.dpId, currentIsls[0].srcPort) - antiflap.portUp(currentIsls[0].dstSwitch.dpId, currentIsls[0].dstPort) + islHelper.restoreIsl(currentIsls[0]) then: "Flow state is still DEGRADED" Wrappers.wait(PROTECTED_PATH_INSTALLATION_TIME) { @@ -537,8 +507,7 @@ class ProtectedPathV1Spec extends HealthCheckSpecification { "Could not swap paths: Protected flow path $flow.id is not in ACTIVE state" when: "Restore ISL for the protected path" - antiflap.portUp(protectedIsls[0].srcSwitch.dpId, protectedIsls[0].srcPort) - antiflap.portUp(protectedIsls[0].dstSwitch.dpId, protectedIsls[0].dstPort) + islHelper.restoreIsl(protectedIsls[0]) then: "Flow state is changed to UP" //it often fails in scope of the whole spec on the hardware env, that's why '* 1.5' is added @@ -548,10 +517,7 @@ class ProtectedPathV1Spec extends HealthCheckSpecification { cleanup: "Restore topology, delete flows and reset costs" flow && flowHelper.deleteFlow(flow.id) - broughtDownPorts.every { antiflap.portUp(it.switchId, it.portNo) } - Wrappers.wait(discoveryInterval + WAIT_OFFSET) { - northbound.getAllLinks().each { assert it.state != IslChangeType.FAILED } - } + islHelper.restoreIsls(broughtDownIsls) database.resetCosts(topology.isls) } diff --git a/src-java/testing/functional-tests/src/test/groovy/org/openkilda/functionaltests/spec/flows/SwapEndpointSpec.groovy b/src-java/testing/functional-tests/src/test/groovy/org/openkilda/functionaltests/spec/flows/SwapEndpointSpec.groovy index 3d571b16bc2..9e09b90108d 100644 --- a/src-java/testing/functional-tests/src/test/groovy/org/openkilda/functionaltests/spec/flows/SwapEndpointSpec.groovy +++ b/src-java/testing/functional-tests/src/test/groovy/org/openkilda/functionaltests/spec/flows/SwapEndpointSpec.groovy @@ -780,18 +780,9 @@ switches"() { Wrappers.wait(FLOW_CRUD_TIMEOUT) { assert northbound.getFlowStatus(flow1.id).status == FlowState.UP } and: "Break all alternative paths for the first flow" - def altPaths = flow1SwitchPair.paths.findAll { it != flow1Path } - List broughtDownPorts = [] - altPaths.unique { it.first() }.each { path -> - def src = path.first() - broughtDownPorts.add(src) - antiflap.portDown(src.switchId, src.portNo) - } - Wrappers.wait(WAIT_OFFSET) { - assert northbound.getAllLinks().findAll { - it.state == IslChangeType.FAILED - }.size() == broughtDownPorts.size() * 2 - } + def broughtDownIsls = topology.getRelatedIsls(flow1SwitchPair.src) - flow1Isl + islHelper.breakIsls(broughtDownIsls) + and: "Update max bandwidth for the second flow's link so that it is equal to max bandwidth of the first flow" def flow2Path = PathHelper.convert(northbound.getFlowPath(flow2.id)) @@ -800,17 +791,9 @@ switches"() { flow2Isl.dstPort, flow1IslMaxBw) and: "Break all alternative paths for the second flow" - altPaths = flow2SwitchPair.paths.findAll { it != flow2Path && it[1].switchId != flow1SwitchPair.src.dpId } - altPaths.unique { it.first() }.each { path -> - def src = path.first() - broughtDownPorts.add(src) - antiflap.portDown(src.switchId, src.portNo) - } - Wrappers.wait(WAIT_OFFSET) { - assert northbound.getAllLinks().findAll { - it.state == IslChangeType.FAILED - }.size() == broughtDownPorts.size() * 2 - } + def flow2BroughtDownIsls = topology.getRelatedIsls(flow2SwitchPair.src) - flow2Isl - broughtDownIsls + islHelper.breakIsls(flow2BroughtDownIsls) + broughtDownIsls += flow2BroughtDownIsls when: "Try to swap endpoints for two flows" def flow1Src = flow2.source @@ -837,11 +820,8 @@ switches"() { cleanup: "Restore topology and delete flows" [flow1, flow2].each { it && flowHelper.deleteFlow(it.id) } - broughtDownPorts.every { antiflap.portUp(it.switchId, it.portNo) } + islHelper.restoreIsls(broughtDownIsls) northbound.deleteLinkProps(northbound.getLinkProps(topology.isls)) - Wrappers.wait(discoveryInterval + WAIT_OFFSET) { - northbound.getAllLinks().each { assert it.state != IslChangeType.FAILED } - } if (!isSwitchValid) { switchHelper.synchronizeAndCollectFixedDiscrepancies([flow1SwitchPair.src.dpId, flow1SwitchPair.dst.dpId, @@ -876,18 +856,8 @@ switches"() { Wrappers.wait(FLOW_CRUD_TIMEOUT) { assert northbound.getFlowStatus(flow1.id).status == FlowState.UP } and: "Break all alternative paths for the first flow" - def altPaths = flow1SwitchPair.paths.findAll { it != flow1Path } - List broughtDownPorts = [] - altPaths.unique { it.first() }.each { path -> - def src = path.first() - broughtDownPorts.add(src) - antiflap.portDown(src.switchId, src.portNo) - } - Wrappers.wait(WAIT_OFFSET) { - assert northbound.getAllLinks().findAll { - it.state == IslChangeType.FAILED - }.size() == broughtDownPorts.size() * 2 - } + def broughtDownIsls = topology.getRelatedIsls(flow1SwitchPair.src) - flow1Isl + islHelper.breakIsls(broughtDownIsls) and: "Update max bandwidth for the second flow's link so that it is not enough bandwidth for the first flow" def flow2Path = PathHelper.convert(northbound.getFlowPath(flow2.id)) @@ -896,17 +866,9 @@ switches"() { flow2Isl.dstPort, flow1IslMaxBw - 1) and: "Break all alternative paths for the second flow" - altPaths = flow2SwitchPair.paths.findAll { it != flow2Path && it[1].switchId != flow1SwitchPair.src.dpId } - altPaths.unique { it.first() }.each { path -> - def src = path.first() - broughtDownPorts.add(src) - antiflap.portDown(src.switchId, src.portNo) - } - Wrappers.wait(WAIT_OFFSET) { - assert northbound.getAllLinks().findAll { - it.state == IslChangeType.FAILED - }.size() == broughtDownPorts.size() * 2 - } + def flow2BroughtDownIsls = topology.getRelatedIsls(flow2SwitchPair.src) - flow2Isl - broughtDownIsls + islHelper.breakIsls(flow2BroughtDownIsls) + broughtDownIsls += flow2BroughtDownIsls when: "Try to swap endpoints for two flows" def flow1Src = flow2.source @@ -929,11 +891,8 @@ switches"() { cleanup: "Restore topology and delete flows" [flow1, flow2].each { it && flowHelper.deleteFlow(it.id) } - broughtDownPorts.every { antiflap.portUp(it.switchId, it.portNo) } + islHelper.restoreIsls(broughtDownIsls) northbound.deleteLinkProps(northbound.getLinkProps(topology.isls)) - Wrappers.wait(discoveryInterval + WAIT_OFFSET) { - northbound.getAllLinks().each { assert it.state != IslChangeType.FAILED } - } if (!isTestCompleted) { switchHelper.synchronizeAndCollectFixedDiscrepancies([flow1SwitchPair.src.dpId, flow1SwitchPair.dst.dpId, @@ -968,18 +927,8 @@ switches"() { Wrappers.wait(FLOW_CRUD_TIMEOUT) { assert northbound.getFlowStatus(flow1.id).status == FlowState.UP } and: "Break all alternative paths for the first flow" - def altPaths = flow1SwitchPair.paths.findAll { it != flow1Path } - List broughtDownPorts = [] - altPaths.unique { it.first() }.each { path -> - def src = path.first() - broughtDownPorts.add(src) - antiflap.portDown(src.switchId, src.portNo) - } - Wrappers.wait(WAIT_OFFSET) { - assert northbound.getAllLinks().findAll { - it.state == IslChangeType.FAILED - }.size() == broughtDownPorts.size() * 2 - } + def broughtDownIsls = topology.getRelatedIsls(flow1SwitchPair.src) - flow1Isl + islHelper.breakIsls(broughtDownIsls) and: "Update max bandwidth for the second flow's link so that it is not enough bandwidth for the first flow" def flow2Path = PathHelper.convert(northbound.getFlowPath(flow2.id)) @@ -988,17 +937,9 @@ switches"() { flow2Isl.dstPort, flow1IslMaxBw - 1) and: "Break all alternative paths for the second flow" - altPaths = flow2SwitchPair.paths.findAll { it != flow2Path && it[1].switchId != flow1SwitchPair.src.dpId } - altPaths.unique { it.first() }.each { path -> - def src = path.first() - broughtDownPorts.add(src) - antiflap.portDown(src.switchId, src.portNo) - } - Wrappers.wait(WAIT_OFFSET) { - assert northbound.getAllLinks().findAll { - it.state == IslChangeType.FAILED - }.size() == broughtDownPorts.size() * 2 - } + def flow2BroughtDownIsls = topology.getRelatedIsls(flow2SwitchPair.src) - flow2Isl - broughtDownIsls + islHelper.breakIsls(flow2BroughtDownIsls) + broughtDownIsls += flow2BroughtDownIsls when: "Try to swap endpoints for two flows" def flow1Src = flow2.source @@ -1025,11 +966,8 @@ switches"() { cleanup: "Restore topology and delete flows" [flow1, flow2].each { it && flowHelper.deleteFlow(it.id) } - broughtDownPorts.every { antiflap.portUp(it.switchId, it.portNo) } + islHelper.restoreIsls(broughtDownIsls) northbound.deleteLinkProps(northbound.getLinkProps(topology.isls)) - Wrappers.wait(discoveryInterval + WAIT_OFFSET) { - northbound.getAllLinks().each { assert it.state != IslChangeType.FAILED } - } if (!isSwitchValid) { switchHelper.synchronizeAndCollectFixedDiscrepancies([flow1SwitchPair.src.dpId, flow1SwitchPair.dst.dpId, @@ -1062,21 +1000,9 @@ switches"() { ).unique() and: "Break all paths for the first flow" - List broughtDownPorts = [] - flow1SwitchPair.paths.unique { it.first() }.each { path -> - def src = path.first() - broughtDownPorts.add(src) - antiflap.portDown(src.switchId, src.portNo) - } - Wrappers.wait(rerouteDelay + WAIT_OFFSET) { - assert northbound.getAllLinks().findAll { - it.state == IslChangeType.FAILED - }.size() == broughtDownPorts.size() * 2 - assert northbound.getFlowStatus(flow1.id).status == FlowState.DOWN - assert flowHelper.getHistoryEntriesByAction(flow1.id, REROUTE_ACTION).find { - it.taskId =~ (/.+ : retry #1 ignore_bw true/) - }?.payload?.last()?.action == REROUTE_FAIL - } + def broughtDownIsls = topology.getRelatedIsls(flow1SwitchPair.src) + islHelper.breakIsls(broughtDownIsls) + when: "Try to swap endpoints for two flows" northbound.swapFlowEndpoint( @@ -1099,10 +1025,7 @@ switches"() { cleanup: "Restore topology and delete flows" [flow1, flow2].each { it && flowHelper.deleteFlow(it.id) } - broughtDownPorts.every { antiflap.portUp(it.switchId, it.portNo) } - Wrappers.wait(discoveryInterval + WAIT_OFFSET) { - northbound.getAllLinks().each { assert it.state != IslChangeType.FAILED } - } + islHelper.restoreIsls(broughtDownIsls) database.resetCosts(topology.isls) } diff --git a/src-java/testing/functional-tests/src/test/groovy/org/openkilda/functionaltests/spec/flows/ThrottlingRerouteSpec.groovy b/src-java/testing/functional-tests/src/test/groovy/org/openkilda/functionaltests/spec/flows/ThrottlingRerouteSpec.groovy index 979f55478ad..0edb647c487 100644 --- a/src-java/testing/functional-tests/src/test/groovy/org/openkilda/functionaltests/spec/flows/ThrottlingRerouteSpec.groovy +++ b/src-java/testing/functional-tests/src/test/groovy/org/openkilda/functionaltests/spec/flows/ThrottlingRerouteSpec.groovy @@ -232,6 +232,5 @@ class ThrottlingRerouteSpec extends HealthCheckSpecification { assert northbound.getLink(brokenIsl).state == IslChangeType.FAILED } return brokenIsl - } } diff --git a/src-java/testing/functional-tests/src/test/groovy/org/openkilda/functionaltests/spec/flows/haflows/HaFlowPingSpec.groovy b/src-java/testing/functional-tests/src/test/groovy/org/openkilda/functionaltests/spec/flows/haflows/HaFlowPingSpec.groovy index 2a56f8d69bb..bd31b288a3d 100644 --- a/src-java/testing/functional-tests/src/test/groovy/org/openkilda/functionaltests/spec/flows/haflows/HaFlowPingSpec.groovy +++ b/src-java/testing/functional-tests/src/test/groovy/org/openkilda/functionaltests/spec/flows/haflows/HaFlowPingSpec.groovy @@ -98,8 +98,7 @@ class HaFlowPingSpec extends HealthCheckSpecification { String subFlowWithActiveIsl = paths.subFlowPaths.flowId.find { it != subFlowWithBrokenIsl } when: "Fail one of the HA-subflows ISL (bring switch port down)" - antiflap.portDown(islToFail.srcSwitch.dpId, islToFail.srcPort) - wait(WAIT_OFFSET) { assert northbound.getLink(islToFail).state == FAILED } + islHelper.breakIsl(islToFail) def afterFailTime = new Date().getTime() then: "Periodic pings are still enabled" @@ -123,8 +122,7 @@ class HaFlowPingSpec extends HealthCheckSpecification { cleanup: haFlow && haFlow.delete() - islToFail && antiflap.portUp(islToFail.srcSwitch.dpId, islToFail.srcPort) - wait(WAIT_OFFSET) { assert northbound.getLink(islToFail).state == DISCOVERED } + islHelper.restoreIsl(islToFail) database.resetCosts(topology.isls) } diff --git a/src-java/testing/functional-tests/src/test/groovy/org/openkilda/functionaltests/spec/flows/haflows/HaFlowRerouteSpec.groovy b/src-java/testing/functional-tests/src/test/groovy/org/openkilda/functionaltests/spec/flows/haflows/HaFlowRerouteSpec.groovy index 59ac7cb3ff6..73e9f3eb286 100644 --- a/src-java/testing/functional-tests/src/test/groovy/org/openkilda/functionaltests/spec/flows/haflows/HaFlowRerouteSpec.groovy +++ b/src-java/testing/functional-tests/src/test/groovy/org/openkilda/functionaltests/spec/flows/haflows/HaFlowRerouteSpec.groovy @@ -55,8 +55,7 @@ class HaFlowRerouteSpec extends HealthCheckSpecification { def islToFail = initialPaths.subFlowPaths.first().getInvolvedIsls(true).first() when: "Fail an HA-flow ISL (bring switch port down)" - antiflap.portDown(islToFail.srcSwitch.dpId, islToFail.srcPort) - wait(WAIT_OFFSET) { assert northbound.getLink(islToFail).state == FAILED } + islHelper.breakIsl(islToFail) then: "The HA-flow was rerouted after reroute delay" def newPaths = null @@ -114,8 +113,7 @@ class HaFlowRerouteSpec extends HealthCheckSpecification { cleanup: haFlow && haFlow.delete() - islToFail && antiflap.portUp(islToFail.srcSwitch.dpId, islToFail.srcPort) - wait(WAIT_OFFSET) { assert northbound.getLink(islToFail).state == DISCOVERED } + islHelper.restoreIsl(islToFail) database.resetCosts(topology.isls) } @@ -135,33 +133,24 @@ class HaFlowRerouteSpec extends HealthCheckSpecification { def alternativePaths = (swT.pathsEp1 + swT.pathsEp2).unique { it.first() } .findAll { !initialPathNodesView.contains(it.first()) } def alternativeIsls = alternativePaths.collect { pathHelper.getInvolvedIsls(it).first() } - withPool { - alternativeIsls.each {isl -> - antiflap.portDown(isl.srcSwitch.dpId, isl.srcPort) - } - } - waitForIslsFail(alternativeIsls) + islHelper.breakIsls(alternativeIsls) assert haFlow.retrieveDetails().status == FlowState.UP //to avoid automatic rerouting an actual flow port is the last one to switch off. - antiflap.portDown(subFlowsFirstIsls.first().srcSwitch.dpId, subFlowsFirstIsls.first().srcPort) + islHelper.breakIsls(subFlowsFirstIsls) then: "The HA-flow goes to 'Down' status" haFlow.waitForBeingInState(FlowState.DOWN, rerouteDelay + WAIT_OFFSET) when: "Bring all ports up on the shared switch that are involved in the alternative paths" - withPool { - alternativeIsls.each {isl -> - antiflap.portUp(isl.srcSwitch.dpId, isl.srcPort) - } - } - def broughtDownPortsUp = true + alternativeIsls.each {islHelper.restoreIsl(it)} //fails on jenkins if do it asynchronously then: "The HA-flow goes to 'Up' state and the HA-flow was rerouted" def newPaths = null wait(rerouteDelay + discoveryInterval + WAIT_OFFSET) { def haFlowDetails = haFlow.retrieveDetails() - assert haFlowDetails.status == FlowState.UP && haFlowDetails.subFlows.every { it.status == FlowState.UP.toString() } + assert haFlowDetails.status == FlowState.UP && + haFlowDetails.subFlows.every { it.status == FlowState.UP.toString() } newPaths = haFlow.retrievedAllEntityPaths() assert newPaths != initialPaths } @@ -179,11 +168,7 @@ class HaFlowRerouteSpec extends HealthCheckSpecification { cleanup: "Bring port involved in the original path up and delete the HA-flow" haFlow && haFlow.delete() - !broughtDownPortsUp && alternativeIsls.each { antiflap.portUp(it.srcSwitch.dpId, it.srcPort) } - subFlowsFirstIsls && antiflap.portUp(subFlowsFirstIsls.first().srcSwitch.dpId, subFlowsFirstIsls.first().srcPort) - wait(discoveryInterval + WAIT_OFFSET) { - assert northbound.getActiveLinks().size() == topology.islsForActiveSwitches.size() * 2 - } + islHelper.restoreIsls(alternativeIsls + subFlowsFirstIsls) } @Tags([SMOKE, ISL_RECOVER_ON_FAIL]) @@ -202,17 +187,11 @@ class HaFlowRerouteSpec extends HealthCheckSpecification { def alternativePaths = (swT.pathsEp1 + swT.pathsEp2).unique { it.first() } .findAll { !initialPathNodesView.contains(it.first()) } def alternativeIsls = alternativePaths.collect { pathHelper.getInvolvedIsls(it).first() } - withPool { - alternativeIsls.each {isl -> - antiflap.portDown(isl.srcSwitch.dpId, isl.srcPort) - } - } - waitForIslsFail(alternativeIsls) + islHelper.breakIsls(alternativeIsls) assert haFlow.retrieveDetails().status == FlowState.UP when: "Bring port down of ISL which is involved in the current HA-flow paths" - antiflap.portDown(subFlowsFirstIsls.first().srcSwitch.dpId, subFlowsFirstIsls.first().srcPort) - waitForIslsFail(subFlowsFirstIsls) + islHelper.breakIsl(subFlowsFirstIsls.first()) then: "The HA-flow goes to 'Down' status" haFlow.waitForBeingInState(FlowState.DOWN, rerouteDelay + WAIT_OFFSET) @@ -228,17 +207,7 @@ class HaFlowRerouteSpec extends HealthCheckSpecification { cleanup: "Bring port involved in the original path up and delete the HA-flow" haFlow && haFlow.delete() - if (alternativeIsls) { - withPool { - alternativeIsls.each { isl -> - antiflap.portUp(isl.srcSwitch.dpId, isl.srcPort) - } - } - } - subFlowsFirstIsls && antiflap.portUp(subFlowsFirstIsls.first().srcSwitch.dpId, subFlowsFirstIsls.first().srcPort) - wait(discoveryInterval + WAIT_OFFSET) { - assert northbound.getActiveLinks().size() == topology.islsForActiveSwitches.size() * 2 - } + islHelper.restoreIsls(alternativeIsls + subFlowsFirstIsls.first()) } private boolean waitForIslsFail(List islsToFail) { diff --git a/src-java/testing/functional-tests/src/test/groovy/org/openkilda/functionaltests/spec/flows/yflows/YFlowPathSwapSpec.groovy b/src-java/testing/functional-tests/src/test/groovy/org/openkilda/functionaltests/spec/flows/yflows/YFlowPathSwapSpec.groovy index 255cf3cca02..c5b316f60f4 100644 --- a/src-java/testing/functional-tests/src/test/groovy/org/openkilda/functionaltests/spec/flows/yflows/YFlowPathSwapSpec.groovy +++ b/src-java/testing/functional-tests/src/test/groovy/org/openkilda/functionaltests/spec/flows/yflows/YFlowPathSwapSpec.groovy @@ -198,8 +198,7 @@ class YFlowPathSwapSpec extends HealthCheckSpecification { when: "Break ISL on the main path (bring port down) to init auto swap" def islToBreak = pathHelper.getInvolvedIsls(sFlow1InitialPrimary)[-1] - def portDown = antiflap.portDown(islToBreak.dstSwitch.dpId, islToBreak.dstPort) - Wrappers.wait(WAIT_OFFSET) { assert northbound.getLink(islToBreak).state == IslChangeType.FAILED } + islHelper.breakIsl(islToBreak) then: "The sub-flows are switched to protected paths" Wrappers.wait(PROTECTED_PATH_INSTALLATION_TIME) { @@ -244,10 +243,7 @@ class YFlowPathSwapSpec extends HealthCheckSpecification { switchHelper.synchronizeAndCollectFixedDiscrepancies(involvedSwitches).isEmpty() when: "Restore port status" - def portUp = antiflap.portUp(islToBreak.dstSwitch.dpId, islToBreak.dstPort) - Wrappers.wait(WAIT_OFFSET + discoveryInterval) { - assert islUtils.getIslInfo(islToBreak).get().state == IslChangeType.DISCOVERED - } + islHelper.restoreIsl(islToBreak) then: "Paths of the y-flow is not changed" Wrappers.wait(WAIT_OFFSET) { @@ -283,9 +279,8 @@ class YFlowPathSwapSpec extends HealthCheckSpecification { cleanup: "Revert system to original state" yFlow && yFlowHelper.deleteYFlow(yFlow.YFlowId) - portDown && !portUp && antiflap.portUp(islToBreak.dstSwitch.dpId, islToBreak.dstPort) + islHelper.restoreIsl(islToBreak) topology.getIslsForActiveSwitches().collectMany { [it, it.reversed] }.each { database.resetIslBandwidth(it) } - islToBreak && Wrappers.wait(WAIT_OFFSET) { assert northbound.getLink(islToBreak).state == IslChangeType.DISCOVERED } database.resetCosts(topology.isls) } @@ -373,8 +368,7 @@ class YFlowPathSwapSpec extends HealthCheckSpecification { when: "Break ISL on the protected path (bring port down) to make it INACTIVE" def islToBreak = pathHelper.getInvolvedIsls(sFlow1InitialProtected)[-1] - def portDown = antiflap.portDown(islToBreak.dstSwitch.dpId, islToBreak.dstPort) - Wrappers.wait(WAIT_OFFSET) { assert northbound.getLink(islToBreak).state == IslChangeType.FAILED } + islHelper.breakIsl(islToBreak) then: "The sub-flows are switched to protected paths" Wrappers.wait(PROTECTED_PATH_INSTALLATION_TIME) { @@ -417,10 +411,7 @@ class YFlowPathSwapSpec extends HealthCheckSpecification { "Could not swap y-flow paths: the protected path of sub-flow $sFlow1.flowId is not in ACTIVE state, but in INACTIVE/INACTIVE (forward/reverse) state" when: "Restore port status" - def portUp = antiflap.portUp(islToBreak.dstSwitch.dpId, islToBreak.dstPort) - Wrappers.wait(WAIT_OFFSET + discoveryInterval) { - assert islUtils.getIslInfo(islToBreak).get().state == IslChangeType.DISCOVERED - } + islHelper.restoreIsl(islToBreak) then: "Paths of the y-flow is not changed" Wrappers.wait(WAIT_OFFSET) { @@ -452,9 +443,8 @@ class YFlowPathSwapSpec extends HealthCheckSpecification { cleanup: "Revert system to original state" yFlow && yFlowHelper.deleteYFlow(yFlow.YFlowId) - portDown && !portUp && antiflap.portUp(islToBreak.dstSwitch.dpId, islToBreak.dstPort) + islHelper.restoreIsl(islToBreak) topology.getIslsForActiveSwitches().collectMany { [it, it.reversed] }.each { database.resetIslBandwidth(it) } - Wrappers.wait(WAIT_OFFSET) { assert northbound.getLink(islToBreak).state == IslChangeType.DISCOVERED } database.resetCosts(topology.isls) } diff --git a/src-java/testing/functional-tests/src/test/groovy/org/openkilda/functionaltests/spec/flows/yflows/YFlowRerouteSpec.groovy b/src-java/testing/functional-tests/src/test/groovy/org/openkilda/functionaltests/spec/flows/yflows/YFlowRerouteSpec.groovy index 56a68632fef..6f1ce40bf44 100644 --- a/src-java/testing/functional-tests/src/test/groovy/org/openkilda/functionaltests/spec/flows/yflows/YFlowRerouteSpec.groovy +++ b/src-java/testing/functional-tests/src/test/groovy/org/openkilda/functionaltests/spec/flows/yflows/YFlowRerouteSpec.groovy @@ -1,5 +1,7 @@ package org.openkilda.functionaltests.spec.flows.yflows +import org.openkilda.functionaltests.helpers.Wrappers + import static org.openkilda.functionaltests.extension.tags.Tag.ISL_RECOVER_ON_FAIL import static org.openkilda.functionaltests.extension.tags.Tag.LOW_PRIORITY @@ -81,8 +83,7 @@ class YFlowRerouteSpec extends HealthCheckSpecification { def islToFail = pathHelper.getInvolvedIsls(PathHelper.convert(paths.subFlowPaths[0].forward)).first() when: "Fail a flow ISL (bring switch port down)" - antiflap.portDown(islToFail.srcSwitch.dpId, islToFail.srcPort) - wait(WAIT_OFFSET) { northbound.getLink(islToFail).state == FAILED } + islHelper.breakIsl(islToFail) then: "The flow was rerouted after reroute delay" and: "History has relevant entries about y-flow reroute" @@ -141,8 +142,7 @@ class YFlowRerouteSpec extends HealthCheckSpecification { cleanup: yFlow && yFlowHelper.deleteYFlow(yFlow.YFlowId) - islToFail && antiflap.portUp(islToFail.srcSwitch.dpId, islToFail.srcPort) - wait(WAIT_OFFSET) { northbound.getLink(islToFail).state == DISCOVERED } + islHelper.restoreIsl(islToFail) database.resetCosts(topology.isls) } @@ -300,10 +300,8 @@ class YFlowRerouteSpec extends HealthCheckSpecification { and: "Switch off all ports on the terminal switch of not intersected ISLs" Switch terminalSwitch = notIntersectedIsls.last().dstSwitch - List portsDown = [] - topology.getRelatedIsls(terminalSwitch).each { - portsDown.add(antiflap.portDown(terminalSwitch.dpId, it.srcSwitch == terminalSwitch ? it.srcPort : it.dstPort)) - } + def broughtDownIsls = topology.getRelatedIsls(terminalSwitch) + islHelper.breakIsls(broughtDownIsls) wait(FLOW_CRUD_TIMEOUT) { northboundV2.getYFlow(yFlow.YFlowId).status == FlowState.DEGRADED.getState() } @@ -323,7 +321,10 @@ class YFlowRerouteSpec extends HealthCheckSpecification { } cleanup: - portsDown && portsDown.each { antiflap.portUp(terminalSwitch.dpId, it.portNumber)} + islHelper.restoreIsls(broughtDownIsls) + wait(WAIT_OFFSET) { + northboundV2.getYFlow(yFlow.YFlowId).status == FlowState.UP.toString() + } yFlow && yFlowHelper.deleteYFlow(yFlow.YFlowId) } } diff --git a/src-java/testing/functional-tests/src/test/groovy/org/openkilda/functionaltests/spec/links/LinkMaintenanceSpec.groovy b/src-java/testing/functional-tests/src/test/groovy/org/openkilda/functionaltests/spec/links/LinkMaintenanceSpec.groovy index 388ddcdaff3..808a90f37dc 100644 --- a/src-java/testing/functional-tests/src/test/groovy/org/openkilda/functionaltests/spec/links/LinkMaintenanceSpec.groovy +++ b/src-java/testing/functional-tests/src/test/groovy/org/openkilda/functionaltests/spec/links/LinkMaintenanceSpec.groovy @@ -112,32 +112,16 @@ class LinkMaintenanceSpec extends HealthCheckSpecification { assert flow1Path == flow2Path and: "Make only one alternative path available for both flows" - def altPaths = switchPair.paths.findAll { - it != flow1Path && it.first().portNo != flow1Path.first().portNo - }.sort { it.size() } - def availablePath = altPaths.first() - - List broughtDownPorts = [] - altPaths[1..-1].unique { it.first() }.findAll { - it.first().portNo != availablePath.first().portNo - }.each { path -> - def src = path.first() - broughtDownPorts.add(src) - antiflap.portDown(src.switchId, src.portNo) - } - Wrappers.wait(antiflapMin + WAIT_OFFSET) { - assert northbound.getAllLinks().findAll { - it.state == IslChangeType.FAILED - }.size() == broughtDownPorts.size() * 2 - } + def flow1ActualIsl = pathHelper.getInvolvedIsls(flow1Path).first() + def altIsls = topology.getRelatedIsls(switchPair.src) - flow1ActualIsl + islHelper.breakIsls(altIsls[1..-1]) and: "Set maintenance mode for the first link involved in alternative path" - def islUnderMaintenance = pathHelper.getInvolvedIsls(availablePath).first() + def islUnderMaintenance = altIsls.first() northbound.setLinkMaintenance(islUtils.toLinkUnderMaintenance(islUnderMaintenance, true, false)) when: "Force flows to reroute by bringing port down on the source switch" - broughtDownPorts.add(flow1Path.first()) - antiflap.portDown(flow1Path.first().switchId, flow1Path.first().portNo) + islHelper.breakIsl(flow1ActualIsl) then: "Flows are rerouted to alternative path with link under maintenance" Wrappers.wait(rerouteDelay + WAIT_OFFSET*2) { @@ -154,13 +138,10 @@ class LinkMaintenanceSpec extends HealthCheckSpecification { } cleanup: "Restore topology, delete flows, unset maintenance mode and reset costs" - broughtDownPorts.each { it && antiflap.portUp(it.switchId, it.portNo) } - [flow1, flow2].each { it && flowHelperV2.deleteFlow(it.flowId) } islUnderMaintenance && northbound.setLinkMaintenance(islUtils.toLinkUnderMaintenance( islUnderMaintenance, false, false)) - Wrappers.wait(discoveryInterval + WAIT_OFFSET) { - northbound.getAllLinks().each { assert it.state != IslChangeType.FAILED } - } + islHelper.restoreIsls(altIsls + flow1ActualIsl) + [flow1, flow2].each { it && flowHelperV2.deleteFlow(it.flowId) } database.resetCosts(topology.isls) } } diff --git a/src-java/testing/functional-tests/src/test/groovy/org/openkilda/functionaltests/spec/links/LinkSpec.groovy b/src-java/testing/functional-tests/src/test/groovy/org/openkilda/functionaltests/spec/links/LinkSpec.groovy index 5ed9ab84dd2..218c067b261 100644 --- a/src-java/testing/functional-tests/src/test/groovy/org/openkilda/functionaltests/spec/links/LinkSpec.groovy +++ b/src-java/testing/functional-tests/src/test/groovy/org/openkilda/functionaltests/spec/links/LinkSpec.groovy @@ -175,10 +175,8 @@ class LinkSpec extends HealthCheckSpecification { [flow3, flow4].each { assert !(it.flowId in linkFlows*.id) } when: "Bring all ports down on source switch that are involved in current and alternative paths" - topology.getBusyPortsForSwitch(switchPair.src).each { port -> - antiflap.portDown(switchPair.src.dpId, port) - } - def portsAreDown = true + def allSourceSwithIsls = topology.getRelatedIsls(switchPair.src) + islHelper.breakIsls(allSourceSwithIsls) then: "All flows go to 'Down' status" Wrappers.wait(rerouteDelay + WAIT_OFFSET) { @@ -206,13 +204,7 @@ class LinkSpec extends HealthCheckSpecification { [flow3, flow4].each { assert !(it.flowId in linkFlows*.id) } when: "Bring ports up" - topology.getBusyPortsForSwitch(switchPair.src).each { port -> - antiflap.portUp(switchPair.src.dpId, port) - } - Wrappers.wait(discoveryInterval + WAIT_OFFSET) { - northbound.getAllLinks().every { it.state == DISCOVERED } - } - portsAreDown = false + islHelper.restoreIsls(allSourceSwithIsls) then: "All flows go to 'Up' status" Wrappers.wait(rerouteDelay + PATH_INSTALLATION_TIME) { @@ -221,14 +213,7 @@ class LinkSpec extends HealthCheckSpecification { cleanup: "Delete all created flows and reset costs" [flow1, flow2, flow3, flow4].each { it && flowHelperV2.deleteFlow(it.flowId) } - if (portsAreDown) { - topology.getBusyPortsForSwitch(switchPair.src).each { port -> - antiflap.portUp(switchPair.src.dpId, port) - } - Wrappers.wait(discoveryInterval + WAIT_OFFSET) { - northbound.getAllLinks().every { it.state == DISCOVERED } - } - } + islHelper.restoreIsls(allSourceSwithIsls) database.resetCosts(topology.isls) } @@ -366,12 +351,7 @@ class LinkSpec extends HealthCheckSpecification { def "Able to delete an inactive #islDescription link and re-discover it back afterwards"() { given: "An inactive link" assumeTrue(isl as boolean, "Unable to locate $islDescription ISL for this test") - antiflap.portDown(isl.srcSwitch.dpId, isl.srcPort) - def portIsDown = true - TimeUnit.SECONDS.sleep(2) //receive any in-progress disco packets - Wrappers.wait(WAIT_OFFSET) { - assert northbound.getLink(isl).actualState == FAILED - } + islHelper.breakIsl(isl) when: "Try to delete the link" def response = northbound.deleteLink(islUtils.toLinkParameters(isl)) @@ -383,7 +363,6 @@ class LinkSpec extends HealthCheckSpecification { when: "Removed link becomes active again (port brought UP)" antiflap.portUp(isl.srcSwitch.dpId, isl.srcPort) - portIsDown = false then: "The link is rediscovered in both directions" Wrappers.wait(discoveryExhaustedInterval + WAIT_OFFSET) { @@ -393,14 +372,7 @@ class LinkSpec extends HealthCheckSpecification { } cleanup: - if (portIsDown) { - antiflap.portUp(isl.srcSwitch.dpId, isl.srcPort) - Wrappers.wait(discoveryExhaustedInterval + WAIT_OFFSET) { - def links = northbound.getAllLinks() - assert islUtils.getIslInfo(links, isl.reversed).get().state == DISCOVERED - assert islUtils.getIslInfo(links, isl).get().state == DISCOVERED - } - } + islHelper.restoreIsl(isl) database.resetCosts(topology.isls) where: @@ -730,11 +702,7 @@ class LinkSpec extends HealthCheckSpecification { def flowPath = pathHelper.convert(northbound.getFlowPath(flow.flowId)) def isl = pathHelper.getInvolvedIsls(flowPath)[0] - antiflap.portDown(isl.srcSwitch.dpId, isl.srcPort) - TimeUnit.SECONDS.sleep(2) //receive any in-progress disco packets - Wrappers.wait(WAIT_OFFSET) { - assert northbound.getLink(isl).actualState == FAILED - } + islHelper.breakIsl(isl) when: "Try to delete the link" northbound.deleteLink(islUtils.toLinkParameters(isl)) @@ -747,10 +715,7 @@ class LinkSpec extends HealthCheckSpecification { cleanup: flow && flowHelperV2.deleteFlow(flow.flowId) - !linkIsActive && antiflap.portUp(isl.srcSwitch.dpId, isl.srcPort) - Wrappers.wait(discoveryInterval + WAIT_OFFSET) { - assert northbound.getActiveLinks().size() == topology.islsForActiveSwitches.size() * 2 - } + islHelper.restoreIsl(isl) database.resetCosts(topology.isls) } diff --git a/src-java/testing/functional-tests/src/test/groovy/org/openkilda/functionaltests/spec/links/RoundTripIslSpec.groovy b/src-java/testing/functional-tests/src/test/groovy/org/openkilda/functionaltests/spec/links/RoundTripIslSpec.groovy index 422f74642b2..8b1c2016b01 100644 --- a/src-java/testing/functional-tests/src/test/groovy/org/openkilda/functionaltests/spec/links/RoundTripIslSpec.groovy +++ b/src-java/testing/functional-tests/src/test/groovy/org/openkilda/functionaltests/spec/links/RoundTripIslSpec.groovy @@ -46,16 +46,9 @@ class RoundTripIslSpec extends HealthCheckSpecification { bfd && northboundV2.setLinkBfd(isl) when: "Port down event happens" - antiflap.portDown(isl.srcSwitch.dpId, isl.srcPort) - cleanupActions << { antiflap.portUp(isl.srcSwitch.dpId, isl.srcPort) } + islHelper.breakIsl(isl) - then: "ISL changed status to FAILED" - Wrappers.wait(WAIT_OFFSET) { - assert northbound.getLink(isl).state == FAILED - assert northbound.getLink(isl.reversed).state == FAILED - } - - when: "Port up event happens, but traffic goes only in one direction" + and: "Port up event happens, but traffic goes only in one direction" lockKeeper.removeFlows([isl.aswitch]) cleanupActions << { lockKeeper.addFlows([isl.aswitch]) } cleanupActions.pop().call() //antiflap.portUp(isl.srcSwitch.dpId, isl.srcPort) @@ -372,13 +365,7 @@ round trip latency rule is removed on the dst switch"() { it.dstSwitch.features.contains(SwitchFeature.NOVIFLOW_COPY_FIELD) } ?: assumeTrue(false, "Wasn't able to find a suitable link") - antiflap.portDown(roundTripIsl.srcSwitch.dpId, roundTripIsl.srcPort) - Wrappers.wait(WAIT_OFFSET) { - def links = northbound.getAllLinks() - assert islUtils.getIslInfo(links, roundTripIsl).get().state == FAILED - assert islUtils.getIslInfo(links, roundTripIsl.reversed).get().state == FAILED - } - def portIsUp = false + islHelper.breakIsl(roundTripIsl) Wrappers.wait(WAIT_OFFSET) { //https://github.com/telstra/open-kilda/issues/3847 Wrappers.silent { northbound.deleteLink(islUtils.toLinkParameters(roundTripIsl)) } @@ -392,17 +379,9 @@ round trip latency rule is removed on the dst switch"() { def portDiscoveryIsEnabledOnSrcPort = false and: "Revive the ISL back (bring switch port up)" - antiflap.portUp(roundTripIsl.srcSwitch.dpId, roundTripIsl.srcPort) - portIsUp = true + islHelper.restoreIsl(roundTripIsl) - then: "The ISL is rediscovered" - Wrappers.wait(discoveryInterval + WAIT_OFFSET) { - def links = northbound.getAllLinks() - assert islUtils.getIslInfo(links, roundTripIsl).get().state == DISCOVERED - assert islUtils.getIslInfo(links, roundTripIsl.reversed).get().state == DISCOVERED - } - - and: "The src/dst switches are valid" + then: "The src/dst switches are valid" //https://github.com/telstra/open-kilda/issues/3906 // switchHelper.synchronizeAndGetFixedEntries([roundTripIsl.srcSwitch, roundTripIsl.dstSwitch]).isEmpty() @@ -433,12 +412,7 @@ round trip latency rule is removed on the dst switch"() { roundTripIsl.srcPort, new PortPropertiesDto(discoveryEnabled: true)) !portDiscoveryIsEnabledOnDstPort && northboundV2.updatePortProperties(roundTripIsl.dstSwitch.dpId, roundTripIsl.dstPort, new PortPropertiesDto(discoveryEnabled: true)) - !portIsUp && antiflap.portUp(roundTripIsl.srcSwitch.dpId, roundTripIsl.srcPort) - Wrappers.wait(discoveryInterval + WAIT_OFFSET) { - def links = northbound.getAllLinks() - assert islUtils.getIslInfo(links, roundTripIsl).get().state == DISCOVERED - assert islUtils.getIslInfo(links, roundTripIsl.reversed).get().state == DISCOVERED - } } + islHelper.restoreIsl(roundTripIsl) } } diff --git a/src-java/testing/functional-tests/src/test/groovy/org/openkilda/functionaltests/spec/links/UnstableIslSpec.groovy b/src-java/testing/functional-tests/src/test/groovy/org/openkilda/functionaltests/spec/links/UnstableIslSpec.groovy index fe54e77eb06..c622322aa17 100644 --- a/src-java/testing/functional-tests/src/test/groovy/org/openkilda/functionaltests/spec/links/UnstableIslSpec.groovy +++ b/src-java/testing/functional-tests/src/test/groovy/org/openkilda/functionaltests/spec/links/UnstableIslSpec.groovy @@ -110,30 +110,18 @@ class UnstableIslSpec extends HealthCheckSpecification { and: "Two possible paths for further manipulation with them" def firstPath = switchPair.paths.min { it.size() } def secondPath = switchPair.paths.findAll { it != firstPath }.min { it.size() } - def altPaths = switchPair.paths.findAll { it != firstPath && it != secondPath } and: "All alternative paths are unavailable (bring ports down on the srcSwitch)" - List broughtDownPorts = [] - altPaths.unique { it.first() }.each { path -> - def src = path.first() - broughtDownPorts.add(src) - antiflap.portDown(src.switchId, src.portNo) - } - Wrappers.wait(antiflapMin + WAIT_OFFSET) { - assert northbound.getAllLinks().findAll { - it.state == FAILED - }.size() == broughtDownPorts.size() * 2 - } + def altPathsIsls = topology.getRelatedIsls(switchPair.src) - pathHelper.getInvolvedIsls(firstPath).first() - + pathHelper.getInvolvedIsls(secondPath).first() + islHelper.breakIsls(altPathsIsls) and: "First path is unstable (due to bringing port down/up)" // after bringing port down/up, the isl will be marked as unstable by updating the 'time_unstable' field in DB def islToBreak = pathHelper.getInvolvedIsls(firstPath).first() - [islToBreak, islToBreak.reversed].each { assert database.getIslTimeUnstable(it) == null } - antiflap.portDown(islToBreak.srcSwitch.dpId, islToBreak.srcPort) - Wrappers.wait(WAIT_OFFSET) { assert islUtils.getIslInfo(islToBreak).get().state == FAILED } + islHelper.breakIsl(islToBreak) [islToBreak, islToBreak.reversed].each { assert database.getIslTimeUnstable(it) != null } - antiflap.portUp(islToBreak.srcSwitch.dpId, islToBreak.srcPort) - Wrappers.wait(WAIT_OFFSET) { assert islUtils.getIslInfo(islToBreak).get().state == DISCOVERED } + islHelper.restoreIsl(islToBreak) and: "Cost of stable path is more preferable than the cost of unstable path (before penalties)" def involvedIslsInUnstablePath = pathHelper.getInvolvedIsls(firstPath) @@ -178,15 +166,8 @@ class UnstableIslSpec extends HealthCheckSpecification { cleanup: "Restore topology, delete the flow and reset costs" flow && flowHelperV2.deleteFlow(flow.flowId) - broughtDownPorts.each { it && antiflap.portUp(it.switchId, it.portNo) } + islHelper.restoreIsls(altPathsIsls + islToBreak) northbound.deleteLinkProps(northbound.getLinkProps(topology.isls)) - Wrappers.wait(discoveryInterval + WAIT_OFFSET) { - northbound.getAllLinks().each { - assert it.state != FAILED - assert it.actualState != FAILED - - } - } database.resetCosts(topology.isls) } } diff --git a/src-java/testing/functional-tests/src/test/groovy/org/openkilda/functionaltests/spec/stats/FlowStatSpec.groovy b/src-java/testing/functional-tests/src/test/groovy/org/openkilda/functionaltests/spec/stats/FlowStatSpec.groovy index 4e36d802ca8..6aeb4b0ea74 100644 --- a/src-java/testing/functional-tests/src/test/groovy/org/openkilda/functionaltests/spec/stats/FlowStatSpec.groovy +++ b/src-java/testing/functional-tests/src/test/groovy/org/openkilda/functionaltests/spec/stats/FlowStatSpec.groovy @@ -250,8 +250,7 @@ class FlowStatSpec extends HealthCheckSpecification { when: "Break ISL on the main path (bring port down) to init auto swap" def islToBreak = pathHelper.getInvolvedIsls(currentPath)[0] - antiflap.portDown(islToBreak.srcSwitch.dpId, islToBreak.srcPort) - def portIsDown = true + islHelper.breakIsl(islToBreak) Wrappers.wait(PROTECTED_PATH_INSTALLATION_TIME) { assert northboundV2.getFlowStatus(flow.id).status == FlowState.UP assert pathHelper.convert(northbound.getFlowPath(flow.id)) == currentProtectedPath @@ -275,10 +274,7 @@ class FlowStatSpec extends HealthCheckSpecification { cleanup: flow && flowHelper.deleteFlow(flow.id) - islToBreak && portIsDown && antiflap.portUp(islToBreak.srcSwitch.dpId, islToBreak.srcPort) - Wrappers.wait(WAIT_OFFSET + discoveryInterval) { - assert islUtils.getIslInfo(islToBreak).get().state == IslChangeType.DISCOVERED - } + islHelper.restoreIsl(islToBreak) database.resetCosts(topology.isls) } @@ -299,30 +295,17 @@ class FlowStatSpec extends HealthCheckSpecification { flowHelperV2.addFlow(flow) and: "All alternative paths are unavailable (bring ports down on the source switch)" - List broughtDownPorts = [] def flowPathInfo = northbound.getFlowPath(flow.flowId) - switchPair.paths.findAll { - it.first() != pathHelper.convert(flowPathInfo).first() && - it.first() != pathHelper.convert(flowPathInfo.protectedPath).first() - }.unique { - it.first() - }.each { path -> - def src = path.first() - broughtDownPorts.add(src) - antiflap.portDown(src.switchId, src.portNo) - } - def srcPortIsDown = true - Wrappers.wait(WAIT_OFFSET) { - assert northbound.getAllLinks().findAll { - it.state == IslChangeType.FAILED - }.size() == broughtDownPorts.size() * 2 - } - - when: "Break ISL on a protected path (bring port down) for changing the flow state to DEGRADED" def currentProtectedPath = pathHelper.convert(flowPathInfo.protectedPath) def protectedIsls = pathHelper.getInvolvedIsls(currentProtectedPath) - antiflap.portDown(protectedIsls[0].dstSwitch.dpId, protectedIsls[0].dstPort) - def dstPortIsDown = true + def altIsls = topology.getRelatedIsls(switchPair.src) - + pathHelper.getInvolvedIsls(pathHelper.convert(flowPathInfo.forwardPath)) - + protectedIsls.first() + islHelper.breakIsls(altIsls) + + + when: "Break ISL on a protected path (bring port down) for changing the flow state to DEGRADED" + islHelper.breakIsl(protectedIsls.first()) Wrappers.wait(WAIT_OFFSET) { verifyAll(northboundV2.getFlow(flow.flowId)) { status == "Degraded" @@ -351,12 +334,7 @@ class FlowStatSpec extends HealthCheckSpecification { cleanup: "Restore topology, delete flows and reset costs" flow && flowHelperV2.deleteFlow(flow.flowId) - protectedIsls && srcPortIsDown && antiflap.portUp(protectedIsls[0].srcSwitch.dpId, protectedIsls[0].srcPort) - protectedIsls && dstPortIsDown && antiflap.portUp(protectedIsls[0].dstSwitch.dpId, protectedIsls[0].dstPort) - broughtDownPorts && broughtDownPorts.every { antiflap.portUp(it.switchId, it.portNo) } - Wrappers.wait(discoveryInterval + WAIT_OFFSET) { - northbound.getAllLinks().each { assert it.state != IslChangeType.FAILED } - } + islHelper.restoreIsls(altIsls + protectedIsls.first()) database.resetCosts(topology.isls) } diff --git a/src-java/testing/functional-tests/src/test/groovy/org/openkilda/functionaltests/spec/switches/FlowRulesSpec.groovy b/src-java/testing/functional-tests/src/test/groovy/org/openkilda/functionaltests/spec/switches/FlowRulesSpec.groovy index c700cb1e53a..3ced950c2aa 100644 --- a/src-java/testing/functional-tests/src/test/groovy/org/openkilda/functionaltests/spec/switches/FlowRulesSpec.groovy +++ b/src-java/testing/functional-tests/src/test/groovy/org/openkilda/functionaltests/spec/switches/FlowRulesSpec.groovy @@ -631,7 +631,7 @@ class FlowRulesSpec extends HealthCheckSpecification { def flowPath = PathHelper.convert(northbound.getFlowPath(flow.flowId)) // Switches may have parallel links, so we need to get involved ISLs. def islToFail = pathHelper.getInvolvedIsls(flowPath).first() - def portDown = antiflap.portDown(islToFail.srcSwitch.dpId, islToFail.srcPort) + islHelper.breakIsl(islToFail) then: "The flow was rerouted after reroute timeout" def flowInfoAfterReroute @@ -694,10 +694,7 @@ class FlowRulesSpec extends HealthCheckSpecification { cleanup: "Revive the ISL back (bring switch port up), delete the flow and reset costs" flow && flowHelperV2.deleteFlow(flow.flowId) - portDown && antiflap.portUp(islToFail.srcSwitch.dpId, islToFail.srcPort) - Wrappers.wait(discoveryInterval + WAIT_OFFSET) { - northbound.getAllLinks().each { assert it.state != IslChangeType.FAILED } - } + islHelper.restoreIsl(islToFail) database.resetCosts(topology.isls) } diff --git a/src-java/testing/functional-tests/src/test/groovy/org/openkilda/functionaltests/spec/switches/PortAntiflapSpec.groovy b/src-java/testing/functional-tests/src/test/groovy/org/openkilda/functionaltests/spec/switches/PortAntiflapSpec.groovy index 3d95caac725..8dcbe20d667 100644 --- a/src-java/testing/functional-tests/src/test/groovy/org/openkilda/functionaltests/spec/switches/PortAntiflapSpec.groovy +++ b/src-java/testing/functional-tests/src/test/groovy/org/openkilda/functionaltests/spec/switches/PortAntiflapSpec.groovy @@ -127,12 +127,7 @@ timeout"() { } cleanup: "Bring port up" - islPort && antiflap.portUp(sw.dpId, islPort) - if (isl) { - Wrappers.wait(discoveryInterval + WAIT_OFFSET) { - islUtils.getIslInfo(isl).get().state == DISCOVERED - } - } + islHelper.restoreIsl(isl) } /** @@ -214,16 +209,10 @@ timeout"() { when: "Port down event happens" def timestampBefore = System.currentTimeMillis() - northbound.portDown(isl.srcSwitch.dpId, isl.srcPort) - def portIsDown = true - Wrappers.wait(WAIT_OFFSET) { - assert northbound.getLink(isl).state == FAILED - assert northbound.getLink(isl.reversed).state == FAILED - } + islHelper.breakIsl(isl) and: "Port up event happens" northbound.portUp(isl.srcSwitch.dpId, isl.srcPort) - portIsDown = false then: "The ISL is failed till 'antiflap' is deactivated" Wrappers.timedLoop(antiflapCooldown * 0.8) { @@ -248,15 +237,7 @@ timeout"() { } cleanup: - portIsDown && antiflap.portUp(isl.srcSwitch.dpId, isl.srcPort) - Wrappers.wait(antiflapCooldown + discoveryInterval + WAIT_OFFSET) { - def fr = northbound.getLink(isl) - def rv = northbound.getLink(isl.reversed) - assert fr.state == DISCOVERED - assert fr.actualState == DISCOVERED - assert rv.state == DISCOVERED - assert rv.actualState == DISCOVERED - } + islHelper.restoreIsl(isl) } def cleanup() { diff --git a/src-java/testing/functional-tests/src/test/groovy/org/openkilda/functionaltests/spec/switches/PortHistorySpec.groovy b/src-java/testing/functional-tests/src/test/groovy/org/openkilda/functionaltests/spec/switches/PortHistorySpec.groovy index 90734d55ee8..f500a927c87 100644 --- a/src-java/testing/functional-tests/src/test/groovy/org/openkilda/functionaltests/spec/switches/PortHistorySpec.groovy +++ b/src-java/testing/functional-tests/src/test/groovy/org/openkilda/functionaltests/spec/switches/PortHistorySpec.groovy @@ -45,10 +45,7 @@ class PortHistorySpec extends HealthCheckSpecification { def timestampBefore = System.currentTimeMillis() when: "Execute port DOWN on the src switch" - def portDown = antiflap.portDown(isl.srcSwitch.dpId, isl.srcPort) - Wrappers.wait(WAIT_OFFSET / 2) { - assert islUtils.getIslInfo(isl).get().state == IslChangeType.FAILED - } + islHelper.breakIsl(isl) then: "Port history is created on the src switch" Wrappers.wait(WAIT_OFFSET) { @@ -63,10 +60,7 @@ class PortHistorySpec extends HealthCheckSpecification { } when: "Execute port UP on the src switch" - def portUp = antiflap.portUp(isl.srcSwitch.dpId, isl.srcPort) - Wrappers.wait(WAIT_OFFSET + discoveryInterval) { - assert islUtils.getIslInfo(isl).get().state == IslChangeType.DISCOVERED - } + islHelper.restoreIsl(isl) then: "Port history is updated on the src switch" Wrappers.wait(WAIT_OFFSET) { @@ -104,12 +98,7 @@ class PortHistorySpec extends HealthCheckSpecification { northboundV2.getPortHistory(isl.srcSwitch.dpId, isl.srcPort).size() >= 4 cleanup: - if (portDown && !portUp) { - antiflap.portUp(isl.srcSwitch.dpId, isl.srcPort) - Wrappers.wait(WAIT_OFFSET + discoveryInterval) { - assert islUtils.getIslInfo(isl).get().state == IslChangeType.DISCOVERED - } - } + islHelper.restoreIsl(isl) where: [islDescription, historySizeOnDstSw, isl] << [ @@ -126,15 +115,9 @@ class PortHistorySpec extends HealthCheckSpecification { def timestampBefore = System.currentTimeMillis() def isl = getTopology().islsForActiveSwitches.find { !it.aswitch } - def portDown = antiflap.portDown(isl.srcSwitch.dpId, isl.srcPort) - Wrappers.wait(WAIT_OFFSET / 2) { - assert islUtils.getIslInfo(isl).get().state == IslChangeType.FAILED - } + islHelper.breakIsl(isl) - def portUp = antiflap.portUp(isl.srcSwitch.dpId, isl.srcPort) - Wrappers.wait(WAIT_OFFSET + discoveryInterval) { - assert islUtils.getIslInfo(isl).get().state == IslChangeType.DISCOVERED - } + islHelper.restoreIsl(isl) def timestampAfter = System.currentTimeMillis() def portHistory = northboundV2.getPortHistory(isl.srcSwitch.dpId, isl.srcPort, timestampBefore, timestampAfter) @@ -147,12 +130,7 @@ class PortHistorySpec extends HealthCheckSpecification { portH.isEmpty() cleanup: - if (portDown && !portUp) { - antiflap.portUp(isl.srcSwitch.dpId, isl.srcPort) - Wrappers.wait(WAIT_OFFSET + discoveryInterval) { - assert islUtils.getIslInfo(isl).get().state == IslChangeType.DISCOVERED - } - } + islHelper.restoreIsl(isl) } def "Port history should not be returned in case port/switch have never existed"() { @@ -170,15 +148,8 @@ class PortHistorySpec extends HealthCheckSpecification { def isl = getTopology().islsForActiveSwitches.find { !it.aswitch } when: "Execute port DOWN/UP on the src switch" - def portDown = antiflap.portDown(isl.srcSwitch.dpId, isl.srcPort) - Wrappers.wait(WAIT_OFFSET / 2) { - assert islUtils.getIslInfo(isl).get().state == IslChangeType.FAILED - } - - def portUp = antiflap.portUp(isl.srcSwitch.dpId, isl.srcPort) - Wrappers.wait(WAIT_OFFSET + discoveryInterval) { - assert islUtils.getIslInfo(isl).get().state == IslChangeType.DISCOVERED - } + islHelper.breakIsl(isl) + islHelper.restoreIsl(isl) def timestampAfter = System.currentTimeMillis() northboundV2.getPortHistory(isl.srcSwitch.dpId, isl.srcPort, timestampBefore, timestampAfter).size() == 4 @@ -190,12 +161,7 @@ class PortHistorySpec extends HealthCheckSpecification { northboundV2.getPortHistory(isl.srcSwitch.dpId, isl.srcPort, timestampBefore, timestampAfter).size() == 4 cleanup: "Revive the src switch" - if (portDown && !portUp) { - antiflap.portUp(isl.srcSwitch.dpId, isl.srcPort) - Wrappers.wait(WAIT_OFFSET + discoveryInterval) { - assert islUtils.getIslInfo(isl).get().state == IslChangeType.DISCOVERED - } - } + islHelper.restoreIsl(isl) switchToDisconnect && switchHelper.reviveSwitch(switchToDisconnect, blockData) } @@ -212,7 +178,6 @@ class PortHistorySpec extends HealthCheckSpecification { when: "Execute port DOWN on the src switch for activating antiflap" northbound.portDown(isl.srcSwitch.dpId, isl.srcPort) - def isPortDown = true Wrappers.wait(WAIT_OFFSET) { assert islUtils.getIslInfo(isl).get().state == IslChangeType.FAILED Long timestampAfterDown = System.currentTimeMillis() @@ -223,9 +188,7 @@ class PortHistorySpec extends HealthCheckSpecification { and: "Generate antiflap statistic" northbound.portUp(isl.srcSwitch.dpId, isl.srcPort) - isPortDown = false northbound.portDown(isl.srcSwitch.dpId, isl.srcPort) - isPortDown = true then: "Antiflap statistic is available in port history inside the ANTI_FLAP_DEACTIVATED event" Wrappers.wait(antiflapCooldown + WAIT_OFFSET) { @@ -242,10 +205,7 @@ class PortHistorySpec extends HealthCheckSpecification { } cleanup: "revert system to original state" - isPortDown && northbound.portUp(isl.srcSwitch.dpId, isl.srcPort) - Wrappers.wait(WAIT_OFFSET + discoveryInterval + antiflapCooldown) { - assert islUtils.getIslInfo(isl).get().state == IslChangeType.DISCOVERED - } + islHelper.restoreIsl(isl) } def cleanup() { @@ -284,10 +244,7 @@ class PortHistoryIsolatedSpec extends HealthCheckSpecification { when: "Execute port DOWN on the port" def timestampBefore = System.currentTimeMillis() - northbound.portDown(isl.srcSwitch.dpId, isl.srcPort) - Wrappers.wait(WAIT_OFFSET / 2) { - assert islUtils.getIslInfo(isl).get().state == IslChangeType.FAILED - } + islHelper.breakIsl(isl) then: "Port history is created for that port" Wrappers.wait(WAIT_OFFSET) { @@ -328,13 +285,7 @@ class PortHistoryIsolatedSpec extends HealthCheckSpecification { } cleanup: - if (isl) { - northbound.portUp(isl.srcSwitch.dpId, isl.srcPort) - Wrappers.wait(WAIT_OFFSET + discoveryInterval + antiflapCooldown) { - assert islUtils.getIslInfo(isl).get().state == IslChangeType.DISCOVERED - } - antiflap.waitPortIsStable(isl.srcSwitch.dpId, isl.srcPort) - } + islHelper.restoreIsl(isl) updateToogles && northbound.toggleFeature(FeatureTogglesDto.builder() .floodlightRoutePeriodicSync(true) .build()) diff --git a/src-java/testing/functional-tests/src/test/groovy/org/openkilda/functionaltests/spec/switches/PortPropertiesSpec.groovy b/src-java/testing/functional-tests/src/test/groovy/org/openkilda/functionaltests/spec/switches/PortPropertiesSpec.groovy index 7c3dd6dc24e..49bba11e404 100644 --- a/src-java/testing/functional-tests/src/test/groovy/org/openkilda/functionaltests/spec/switches/PortPropertiesSpec.groovy +++ b/src-java/testing/functional-tests/src/test/groovy/org/openkilda/functionaltests/spec/switches/PortPropertiesSpec.groovy @@ -127,11 +127,7 @@ class PortPropertiesSpec extends HealthCheckSpecification { .any { it.features.contains(SwitchFeature.NOVIFLOW_COPY_FIELD) } // Bring port down on the src switch - def portDown = antiflap.portDown(islToManipulate.srcSwitch.dpId, islToManipulate.srcPort) - TimeUnit.SECONDS.sleep(2) //receive any in-progress disco packets - Wrappers.wait(WAIT_OFFSET) { - assert northbound.getLink(islToManipulate).actualState == IslChangeType.FAILED - } + islHelper.breakIsl(islToManipulate) // delete link northbound.deleteLink(islUtils.toLinkParameters(islToManipulate)) @@ -196,7 +192,7 @@ class PortPropertiesSpec extends HealthCheckSpecification { assert islUtils.getIslInfo(islToManipulate.reversed).get().state == IslChangeType.DISCOVERED } cleanup: - portDown && !portUp && antiflap.portUp(islToManipulate.srcSwitch.dpId, islToManipulate.srcPort) + antiflap.portUp(islToManipulate.srcSwitch.dpId, islToManipulate.srcPort) srcPortDiscoveryOff && !srcPortDiscoveryOn && enableDiscoveryOnPort(islToManipulate.srcSwitch.dpId, islToManipulate.srcPort) dstPortDiscoveryOff && !dstPortDiscoveryOn && enableDiscoveryOnPort(islToManipulate.dstSwitch.dpId, islToManipulate.dstPort) switchStatus && switchStatus == SwitchChangeType.DEACTIVATED && switchHelper.reviveSwitch(sw, blockData, true) diff --git a/src-java/testing/functional-tests/src/test/groovy/org/openkilda/functionaltests/spec/switches/SwitchDeleteSpec.groovy b/src-java/testing/functional-tests/src/test/groovy/org/openkilda/functionaltests/spec/switches/SwitchDeleteSpec.groovy index 6b43c7492c0..8cdb2c82ab7 100644 --- a/src-java/testing/functional-tests/src/test/groovy/org/openkilda/functionaltests/spec/switches/SwitchDeleteSpec.groovy +++ b/src-java/testing/functional-tests/src/test/groovy/org/openkilda/functionaltests/spec/switches/SwitchDeleteSpec.groovy @@ -77,10 +77,7 @@ class SwitchDeleteSpec extends HealthCheckSpecification { def sw = topology.getActiveSwitches()[0] def swIsls = topology.getRelatedIsls(sw) // deactivate all active ISLs on switch - swIsls.each { antiflap.portDown(sw.dpId, it.srcPort) } - Wrappers.wait(WAIT_OFFSET) { - swIsls.each { assert islUtils.getIslInfo(it).get().state == IslChangeType.FAILED } - } + islHelper.breakIsls(swIsls) // deactivate switch def blockData = switchHelper.knockoutSwitch(sw, RW, false) @@ -95,11 +92,7 @@ class SwitchDeleteSpec extends HealthCheckSpecification { cleanup: "Activate the switch back and reset costs" switchHelper.reviveSwitch(sw, blockData, false) - swIsls.each { antiflap.portUp(sw.dpId, it.srcPort) } - Wrappers.wait(discoveryInterval + WAIT_OFFSET) { - def links = northbound.getAllLinks() - swIsls.each { assert islUtils.getIslInfo(links, it).get().state == IslChangeType.DISCOVERED } - } + islHelper.restoreIsls(swIsls) database.resetCosts(topology.isls) } @@ -137,11 +130,7 @@ class SwitchDeleteSpec extends HealthCheckSpecification { def initSwProps = switchHelper.getCachedSwProps(sw.dpId) def swIsls = topology.getRelatedIsls(sw) // port down on all active ISLs on switch - swIsls.each { antiflap.portDown(sw.dpId, it.srcPort) } - TimeUnit.SECONDS.sleep(2) //receive any in-progress disco packets - Wrappers.wait(WAIT_OFFSET) { - swIsls.each { assert islUtils.getIslInfo(it).get().state == IslChangeType.FAILED } - } + islHelper.breakIsls(swIsls) // delete all ISLs on switch swIsls.each { northbound.deleteLink(islUtils.toLinkParameters(it)) } // deactivate switch @@ -156,12 +145,8 @@ class SwitchDeleteSpec extends HealthCheckSpecification { cleanup: "Activate the switch back, restore ISLs and reset costs" switchHelper.reviveSwitch(sw, blockData) - swIsls.each { antiflap.portUp(sw.dpId, it.srcPort) } initSwProps && switchHelper.updateSwitchProperties(sw, initSwProps) - Wrappers.wait(discoveryInterval + WAIT_OFFSET) { - def links = northbound.getAllLinks() - swIsls.each { assert islUtils.getIslInfo(links, it).get().state == IslChangeType.DISCOVERED } - } + islHelper.restoreIsls(swIsls) database.resetCosts(topology.isls) } @@ -200,11 +185,7 @@ class SwitchDeleteSpec extends HealthCheckSpecification { } // port down on all active ISLs on switch - swIsls.each { antiflap.portDown(sw.dpId, it.srcPort) } - TimeUnit.SECONDS.sleep(2) //receive any in-progress disco packets - Wrappers.wait(WAIT_OFFSET) { - swIsls.each { assert islUtils.getIslInfo(it).get().state == IslChangeType.FAILED } - } + islHelper.breakIsls(swIsls) // delete all ISLs on switch swIsls.each { northbound.deleteLink(islUtils.toLinkParameters(it)) } // deactivate switch @@ -219,12 +200,8 @@ class SwitchDeleteSpec extends HealthCheckSpecification { cleanup: "Activate the switch back, restore ISLs, delete connected devices and reset costs" switchHelper.reviveSwitch(sw, blockData) - swIsls.each { antiflap.portUp(sw.dpId, it.srcPort) } + islHelper.restoreIsls(swIsls) initSwProps && switchHelper.updateSwitchProperties(sw, initSwProps) - Wrappers.wait(discoveryInterval + WAIT_OFFSET) { - def links = northbound.getAllLinks() - swIsls.each { assert islUtils.getIslInfo(links, it).get().state == IslChangeType.DISCOVERED } - } database.resetCosts(topology.isls) lldpData && database.removeConnectedDevices(sw.dpId) } @@ -263,12 +240,7 @@ class SwitchDeleteSpec extends HealthCheckSpecification { // restore ISLs swIsls.each { antiflap.portDown(it.srcSwitch.dpId, it.srcPort) } TimeUnit.SECONDS.sleep(antiflapMin) - swIsls.each { antiflap.portUp(it.srcSwitch.dpId, it.srcPort) } - Wrappers.wait(discoveryInterval + WAIT_OFFSET) { - def links = northbound.getAllLinks() - swIsls.collectMany { [it, it.reversed] } - .each { assert islUtils.getIslInfo(links, it).get().state == IslChangeType.DISCOVERED } - } + islHelper.restoreIsls(swIsls) initSwProps && switchHelper.updateSwitchProperties(sw, initSwProps) database.resetCosts(topology.isls) } diff --git a/src-java/testing/functional-tests/src/test/groovy/org/openkilda/functionaltests/spec/switches/SwitchFailuresSpec.groovy b/src-java/testing/functional-tests/src/test/groovy/org/openkilda/functionaltests/spec/switches/SwitchFailuresSpec.groovy index 3058cf37813..a612abf9380 100644 --- a/src-java/testing/functional-tests/src/test/groovy/org/openkilda/functionaltests/spec/switches/SwitchFailuresSpec.groovy +++ b/src-java/testing/functional-tests/src/test/groovy/org/openkilda/functionaltests/spec/switches/SwitchFailuresSpec.groovy @@ -122,7 +122,7 @@ class SwitchFailuresSpec extends HealthCheckSpecification { cleanup: lockKeeper.cleanupTrafficShaperRules(swPair.dst.regions) flow && flowHelperV2.deleteFlow(flow.flowId) - islToBreak && antiflap.portUp(islToBreak.srcSwitch.dpId, islToBreak.srcPort) + islHelper.restoreIsl(islToBreak) database.resetCosts(topology.isls) } diff --git a/src-java/testing/functional-tests/src/test/groovy/org/openkilda/functionaltests/spec/switches/SwitchMaintenanceSpec.groovy b/src-java/testing/functional-tests/src/test/groovy/org/openkilda/functionaltests/spec/switches/SwitchMaintenanceSpec.groovy index d2c3d88a524..b11b1217811 100644 --- a/src-java/testing/functional-tests/src/test/groovy/org/openkilda/functionaltests/spec/switches/SwitchMaintenanceSpec.groovy +++ b/src-java/testing/functional-tests/src/test/groovy/org/openkilda/functionaltests/spec/switches/SwitchMaintenanceSpec.groovy @@ -16,8 +16,6 @@ import org.openkilda.messaging.info.event.PathNode import org.openkilda.messaging.payload.flow.FlowState import org.openkilda.testing.model.topology.TopologyDefinition -import java.util.concurrent.TimeUnit - class SwitchMaintenanceSpec extends HealthCheckSpecification { @Tags(SMOKE) @@ -126,9 +124,7 @@ class SwitchMaintenanceSpec extends HealthCheckSpecification { def isl = topology.islsForActiveSwitches.first() and: "Bring port down on the switch to fail the link" - def portDown = antiflap.portDown(isl.srcSwitch.dpId, isl.srcPort) - TimeUnit.SECONDS.sleep(2) //receive any in-progress disco packets - Wrappers.wait(WAIT_OFFSET) { assert islUtils.getIslInfo(isl).get().state == IslChangeType.FAILED } + islHelper.breakIsl(isl) and: "Delete the link" northbound.deleteLink(islUtils.toLinkParameters(isl)) @@ -154,18 +150,8 @@ class SwitchMaintenanceSpec extends HealthCheckSpecification { } cleanup: - portDown && !portUp && antiflap.portUp(isl.srcSwitch.dpId, isl.srcPort) + islHelper.restoreIsl(isl) setSwMaintenance && northbound.setSwitchMaintenance(isl.srcSwitch.dpId, false, false) - Wrappers.wait(discoveryInterval + WAIT_OFFSET) { - def links = northbound.getAllLinks() - def islInfo = islUtils.getIslInfo(links, isl).get() - def reverseIslInfo = islUtils.getIslInfo(links, isl.reversed).get() - - [islInfo, reverseIslInfo].each { - assert it.state == IslChangeType.DISCOVERED - assert !it.underMaintenance - } - } database.resetCosts(topology.isls) } } diff --git a/src-java/testing/functional-tests/src/test/groovy/org/openkilda/functionaltests/spec/switches/SwitchPortConfigSpec.groovy b/src-java/testing/functional-tests/src/test/groovy/org/openkilda/functionaltests/spec/switches/SwitchPortConfigSpec.groovy index 4e9dbb57359..419411c66fc 100644 --- a/src-java/testing/functional-tests/src/test/groovy/org/openkilda/functionaltests/spec/switches/SwitchPortConfigSpec.groovy +++ b/src-java/testing/functional-tests/src/test/groovy/org/openkilda/functionaltests/spec/switches/SwitchPortConfigSpec.groovy @@ -33,46 +33,24 @@ class SwitchPortConfigSpec extends HealthCheckSpecification { def "Able to bring ISL-busy port down/up on an #isl.srcSwitch.ofVersion switch #isl.srcSwitch.dpId"() { when: "Bring port down on the switch" def portDownTime = new Date().getTime() - antiflap.portDown(isl.srcSwitch.dpId, isl.srcPort) + islHelper.breakIsl(isl) - then: "Forward and reverse ISLs between switches becomes 'FAILED'" - Wrappers.wait(WAIT_OFFSET) { - def links = northbound.getAllLinks() - assert islUtils.getIslInfo(links, isl).get().state == IslChangeType.FAILED - assert islUtils.getIslInfo(links, isl.reversed).get().state == IslChangeType.FAILED - } - - and: "Port failure is logged in TSDB" + then: "Port failure is logged in TSDB" def statsData = [:] Wrappers.wait(STATS_LOGGING_TIMEOUT) { switchStats.of(isl.getSrcSwitch().getDpId()).get(STATE, isl.getSrcPort()).hasValue(0) } when: "Bring port up on the switch" - def portUpTime = new Date() - antiflap.portUp(isl.srcSwitch.dpId, isl.srcPort) - - then: "Forward and reverse ISLs between switches becomes 'DISCOVERED'" - Wrappers.wait(discoveryInterval + WAIT_OFFSET) { - def links = northbound.getAllLinks() - assert islUtils.getIslInfo(links, isl).get().state == IslChangeType.DISCOVERED - assert islUtils.getIslInfo(links, isl.reversed).get().state == IslChangeType.DISCOVERED - } + islHelper.restoreIsl(isl) - and: "Port UP event is logged in TSDB" + then: "Port UP event is logged in TSDB" Wrappers.wait(STATS_LOGGING_TIMEOUT) { switchStats.of(isl.getSrcSwitch().getDpId()).get(STATE, isl.getSrcPort()).hasValue(1) } cleanup: - if (portDownTime && !portUpTime) { - antiflap.portUp(isl.srcSwitch.dpId, isl.srcPort) - Wrappers.wait(discoveryInterval + WAIT_OFFSET) { - def links = northbound.getAllLinks() - assert islUtils.getIslInfo(links, isl).get().state == IslChangeType.DISCOVERED - assert islUtils.getIslInfo(links, isl.reversed).get().state == IslChangeType.DISCOVERED - } - } + islHelper.restoreIsl(isl) database.resetCosts(topology.isls) where: diff --git a/src-java/testing/functional-tests/src/test/groovy/org/openkilda/functionaltests/spec/switches/SwitchesSpec.groovy b/src-java/testing/functional-tests/src/test/groovy/org/openkilda/functionaltests/spec/switches/SwitchesSpec.groovy index e38997decd5..7c0c04214cd 100644 --- a/src-java/testing/functional-tests/src/test/groovy/org/openkilda/functionaltests/spec/switches/SwitchesSpec.groovy +++ b/src-java/testing/functional-tests/src/test/groovy/org/openkilda/functionaltests/spec/switches/SwitchesSpec.groovy @@ -147,18 +147,8 @@ class SwitchesSpec extends HealthCheckSpecification { getSwitchFlowsResponse5*.id.sort() == [protectedFlow.flowId, singleFlow.flowId, defaultFlow.flowId].sort() when: "Bring down all ports on src switch to make flow DOWN" - def doPortDowns = true //helper var for cleanup - def portsToDown = topology.getBusyPortsForSwitch(switchPair.src) - withPool { - portsToDown.eachParallel { // https://github.com/telstra/open-kilda/issues/4014 - antiflap.portDown(switchPair.src.dpId, it) - } - } - Wrappers.wait(WAIT_OFFSET) { - assert northbound.getAllLinks().findAll { - it.state == IslChangeType.FAILED - }.size() == portsToDown.size() * 2 - } + def switchIsls = topology.getRelatedIsls(switchPair.src) + islHelper.breakIsls(switchIsls) and: "Get all flows going through the src switch" Wrappers.wait(WAIT_OFFSET * 2) { @@ -175,10 +165,7 @@ class SwitchesSpec extends HealthCheckSpecification { cleanup: "Delete the flows" [protectedFlow, singleFlow, defaultFlow].each { it && flowHelperV2.deleteFlow(it.flowId) } - doPortDowns && portsToDown.each { antiflap.portUp(switchPair.src.dpId, it) } - Wrappers.wait(discoveryInterval + WAIT_OFFSET) { - northbound.getAllLinks().each { assert it.state != IslChangeType.FAILED } - } + islHelper.restoreIsls(switchIsls) database.resetCosts(topology.isls) } diff --git a/src-java/testing/functional-tests/src/test/groovy/org/openkilda/functionaltests/spec/toggles/FeatureTogglesV2Spec.groovy b/src-java/testing/functional-tests/src/test/groovy/org/openkilda/functionaltests/spec/toggles/FeatureTogglesV2Spec.groovy index b0d4d3d27c6..4215aa9513e 100644 --- a/src-java/testing/functional-tests/src/test/groovy/org/openkilda/functionaltests/spec/toggles/FeatureTogglesV2Spec.groovy +++ b/src-java/testing/functional-tests/src/test/groovy/org/openkilda/functionaltests/spec/toggles/FeatureTogglesV2Spec.groovy @@ -156,10 +156,7 @@ feature toggle"() { and: "Init a flow reroute by breaking current path" def currentPath = pathHelper.convert(northbound.getFlowPath(flow.flowId)) def islToBreak = pathHelper.getInvolvedIsls(currentPath).first() - antiflap.portDown(islToBreak.srcSwitch.dpId, islToBreak.srcPort) - wait(WAIT_OFFSET) { - assert islUtils.getIslInfo(islToBreak).get().state == IslChangeType.FAILED - } + islHelper.breakIsl(islToBreak) then: "Flow is rerouted" wait(WAIT_OFFSET + rerouteDelay) { @@ -177,18 +174,12 @@ feature toggle"() { northbound.toggleFeature(FeatureTogglesDto.builder().flowsRerouteUsingDefaultEncapType(false).build()) and: "Restore previous path" - antiflap.portUp(islToBreak.srcSwitch.dpId, islToBreak.srcPort) - wait(discoveryInterval + WAIT_OFFSET) { - assert islUtils.getIslInfo(islToBreak).get().state == IslChangeType.DISCOVERED - } + islHelper.restoreIsl(islToBreak) and: "Init a flow reroute by breaking a new current path" def newCurrentPath = pathHelper.convert(northbound.getFlowPath(flow.flowId)) def newIslToBreak = pathHelper.getInvolvedIsls(newCurrentPath).first() - antiflap.portDown(newIslToBreak.srcSwitch.dpId, newIslToBreak.srcPort) - wait(WAIT_OFFSET) { - assert islUtils.getIslInfo(newIslToBreak).get().state == IslChangeType.FAILED - } + islHelper.breakIsl(newIslToBreak) then: "Flow is rerouted" wait(WAIT_OFFSET + rerouteDelay) { @@ -202,15 +193,7 @@ feature toggle"() { initFeatureToggle && northbound.toggleFeature(FeatureTogglesDto.builder() .flowsRerouteUsingDefaultEncapType(initFeatureToggle.flowsRerouteUsingDefaultEncapType).build()) flow && flowHelperV2.deleteFlow(flow.flowId) - islToBreak && !newIslToBreak && antiflap.portUp(islToBreak.srcSwitch.dpId, islToBreak.srcPort) - newIslToBreak && antiflap.portUp(newIslToBreak.srcSwitch.dpId, newIslToBreak.srcPort) - wait(discoveryInterval + WAIT_OFFSET) { - def links = northbound.getAllLinks() - assert islUtils.getIslInfo(links, islToBreak).get().state == IslChangeType.DISCOVERED - assert islUtils.getIslInfo(links, islToBreak.reversed).get().state == IslChangeType.DISCOVERED - assert islUtils.getIslInfo(links, newIslToBreak).get().state == IslChangeType.DISCOVERED - assert islUtils.getIslInfo(links, newIslToBreak.reversed).get().state == IslChangeType.DISCOVERED - } + islHelper.restoreIsls([islToBreak, newIslToBreak]) database.resetCosts(topology.isls) } @@ -246,10 +229,7 @@ feature toggle"() { and: "Init a flow reroute by breaking current path" def currentPath = pathHelper.convert(northbound.getFlowPath(flow.flowId)) def islToBreak = pathHelper.getInvolvedIsls(currentPath).first() - antiflap.portDown(islToBreak.srcSwitch.dpId, islToBreak.srcPort) - wait(WAIT_OFFSET) { - assert islUtils.getIslInfo(islToBreak).get().state == IslChangeType.FAILED - } + islHelper.breakIsl(islToBreak) then: "Flow is not rerouted" sleep(rerouteDelay * 1000) @@ -288,17 +268,12 @@ feature toggle"() { cleanup: flow && flowHelperV2.deleteFlow(flow.flowId) - islToBreak && antiflap.portUp(islToBreak.srcSwitch.dpId, islToBreak.srcPort) initFeatureToggle && northbound.toggleFeature(FeatureTogglesDto.builder() .flowsRerouteUsingDefaultEncapType(initFeatureToggle.flowsRerouteUsingDefaultEncapType).build()) initGlobalConfig && initGlobalConfig.flowEncapsulationType != vxlanEncapsulationType.toString().toLowerCase() && northbound.updateKildaConfiguration(initGlobalConfig) initSrcSwProps && northbound.updateSwitchProperties(swPair.src.dpId, initSrcSwProps) - wait(discoveryInterval + WAIT_OFFSET) { - def links = northbound.getAllLinks() - assert islUtils.getIslInfo(links, islToBreak).get().state == IslChangeType.DISCOVERED - assert islUtils.getIslInfo(links, islToBreak.reversed).get().state == IslChangeType.DISCOVERED - } + islHelper.restoreIsl(islToBreak) database.resetCosts(topology.isls) } @@ -312,14 +287,9 @@ feature toggle"() { //you have to break all altPaths to avoid rerouting when flowPath is broken def flowPath = pathHelper.convert(northbound.getFlowPath(flow.flowId)) - def altPaths = allFlowPaths.findAll { it != flowPath && it.first().portNo != flowPath.first().portNo } - List broughtDownPorts = [] - altPaths.unique { it.first() }.each { path -> - def src = path.first() - broughtDownPorts.add(src) - antiflap.portDown(src.switchId, src.portNo) - } - def altPortsAreDown = true + def flowInvolvedIsls = pathHelper.getInvolvedIsls(flowPath) + def altIsls = topology.getRelatedIsls(switchPair.src) - flowInvolvedIsls.first() + islHelper.breakIsls(altIsls) and: "Set flowsRerouteOnIslDiscovery=false" northbound.toggleFeature(FeatureTogglesDto.builder() @@ -328,10 +298,8 @@ feature toggle"() { def featureToogleIsUpdated = true when: "Break the flow path(bring port down on the src switch)" - def getInvolvedIsls = pathHelper.getInvolvedIsls(flowPath) - def islToBreak = getInvolvedIsls.first() - antiflap.portDown(islToBreak.srcSwitch.dpId, islToBreak.srcPort) - def mainPortIsDown = true + def islToBreak = flowInvolvedIsls.first() + islHelper.breakIsl(islToBreak) then: "The flow becomes 'Down'" wait(discoveryTimeout + rerouteDelay + WAIT_OFFSET * 2) { @@ -352,12 +320,7 @@ feature toggle"() { } } when: "Restore all possible flow paths" - withPool { - broughtDownPorts.everyParallel { antiflap.portUp(it.switchId, it.portNo) } - } - antiflap.portUp(islToBreak.srcSwitch.dpId, islToBreak.srcPort) - altPortsAreDown = false - mainPortIsDown = false + islHelper.restoreIsls(altIsls + islToBreak) then: "The flow is still in 'Down' status, because flows_reroute_on_isl_discovery: false" assert northboundV2.getFlowStatus(flow.flowId).status == FlowState.DOWN @@ -367,14 +330,10 @@ feature toggle"() { cleanup: "Restore topology to the original state, remove the flow, reset toggles" flow && flowHelperV2.deleteFlow(flow.flowId) - altPortsAreDown && broughtDownPorts.every { antiflap.portUp(it.switchId, it.portNo) } - mainPortIsDown && antiflap.portUp(islToBreak.srcSwitch.dpId, islToBreak.srcPort) + islHelper.restoreIsls(altIsls + islToBreak) featureToogleIsUpdated && northbound.toggleFeature(FeatureTogglesDto.builder() .flowsRerouteOnIslDiscoveryEnabled(true) .build()) - wait(discoveryInterval + WAIT_OFFSET) { - northbound.getAllLinks().each { assert it.state != IslChangeType.FAILED } - } database.resetCosts(topology.isls) } } diff --git a/src-java/testing/functional-tests/src/test/groovy/org/openkilda/functionaltests/spec/xresilience/RetriesSpec.groovy b/src-java/testing/functional-tests/src/test/groovy/org/openkilda/functionaltests/spec/xresilience/RetriesSpec.groovy index fcf65694ff3..2818515b2da 100644 --- a/src-java/testing/functional-tests/src/test/groovy/org/openkilda/functionaltests/spec/xresilience/RetriesSpec.groovy +++ b/src-java/testing/functional-tests/src/test/groovy/org/openkilda/functionaltests/spec/xresilience/RetriesSpec.groovy @@ -79,10 +79,7 @@ and at least 1 path must remain safe" database.setSwitchStatus(switchToBreak.dpId, SwitchStatus.ACTIVE) when: "Main path of the flow breaks initiating a reroute" - def portDown = antiflap.portDown(islToBreak.srcSwitch.dpId, islToBreak.srcPort) - wait(WAIT_OFFSET) { - assert northbound.getLink(islToBreak).state == IslChangeType.FAILED - } + islHelper.breakIsl(islToBreak) then: "System fails to install rules on desired path and tries to retry reroute and find new path (global retry)" wait(WAIT_OFFSET * 3, 0.1) { @@ -91,7 +88,7 @@ and at least 1 path must remain safe" } } - when: "Switch is officially marked as offline" + when: "Switch is marked as offline" database.setSwitchStatus(switchToBreak.dpId, SwitchStatus.INACTIVE) then: "System finds another working path and successfully reroutes the flow (one of the retries succeeds)" @@ -116,12 +113,7 @@ and at least 1 path must remain safe" database.setSwitchStatus(switchToBreak.dpId, SwitchStatus.INACTIVE) switchHelper.reviveSwitch(switchToBreak, blockData) } - if(portDown) { - antiflap.portUp(islToBreak.srcSwitch.dpId, islToBreak.srcPort) - } - wait(discoveryInterval + WAIT_OFFSET) { - assert northbound.getActiveLinks().size() == topology.islsForActiveSwitches.size() * 2 - } + islHelper.restoreIsl(islToBreak) northbound.deleteLinkProps(northbound.getLinkProps(topology.isls)) database.resetCosts(topology.isls) } @@ -136,21 +128,9 @@ and at least 1 path must remain safe" List protectedPath = allPaths.findAll { it != mainPath && it.size() != 2 }.min { it.size() } and: "All alternative paths unavailable (bring ports down)" - def broughtDownIsls = [] - def otherIsls = [] - def involvedIsls = (pathHelper.getInvolvedIsls(mainPath) + pathHelper.getInvolvedIsls(protectedPath)).unique() - allPaths.findAll { it != mainPath && it != protectedPath }.each { - pathHelper.getInvolvedIsls(it).findAll { !(it in involvedIsls || it.reversed in involvedIsls) }.each { - otherIsls.add(it) - } - } - broughtDownIsls = otherIsls.unique { a, b -> a == b || a == b.reversed ? 0 : 1 } - broughtDownIsls.every { northbound.portDown(it.srcSwitch.dpId, it.srcPort) } - wait(WAIT_OFFSET) { - assert northbound.getAllLinks().findAll { - it.state == IslChangeType.FAILED - }.size() == broughtDownIsls.size() * 2 - } + def altIsls = topology.getRelatedIsls(swPair.src) - pathHelper.getInvolvedIsls(mainPath).first() - + pathHelper.getInvolvedIsls(protectedPath).first() + islHelper.breakIsls(altIsls) and: "A protected flow" /** At this point we have the following topology: @@ -226,10 +206,7 @@ and at least 1 path must remain safe" switchHelper.reviveSwitch(swToManipulate, blockData) switchHelper.synchronize(swToManipulate.dpId) } - broughtDownIsls.every { northbound.portUp(it.srcSwitch.dpId, it.srcPort) } - wait(discoveryInterval + WAIT_OFFSET + antiflapCooldown) { - assert northbound.getActiveLinks().size() == topology.islsForActiveSwitches.size() * 2 - } + islHelper.restoreIsls(altIsls) database.resetCosts(topology.isls) where: @@ -291,21 +268,8 @@ and at least 1 path must remain safe" List backupPath = swPair.paths.findAll { it != mainPath && it.size() != 2 }.min { it.size() } and: "All alternative paths unavailable (bring ports down)" - def broughtDownIsls = [] - def otherIsls = [] - def involvedIsls = (pathHelper.getInvolvedIsls(mainPath) + pathHelper.getInvolvedIsls(backupPath)).unique() - swPair.paths.findAll { it != mainPath && it != backupPath }.each { - pathHelper.getInvolvedIsls(it).findAll { !(it in involvedIsls || it.reversed in involvedIsls) }.each { - otherIsls.add(it) - } - } - broughtDownIsls = otherIsls.unique { a, b -> a == b || a == b.reversed ? 0 : 1 } - broughtDownIsls.every { antiflap.portDown(it.srcSwitch.dpId, it.srcPort) } - wait(WAIT_OFFSET) { - assert northbound.getAllLinks().findAll { - it.state == IslChangeType.FAILED - }.size() == otherIsls.size() * 2 - } + def altIsls = topology.getRelatedIsls(swPair.src) - pathHelper.getInvolvedIsls(mainPath).first() - + pathHelper.getInvolvedIsls(backupPath).first() and: "A flow on the main path" def flow = flowHelperV2.randomFlow(swPair) @@ -367,10 +331,7 @@ and at least 1 path must remain safe" switchHelper.reviveSwitch(swToManipulate, blockData) switchHelper.synchronize(swToManipulate.dpId) } - broughtDownIsls.every { antiflap.portUp(it.srcSwitch.dpId, it.srcPort) } - wait(discoveryInterval + WAIT_OFFSET) { - assert northbound.getActiveLinks().size() == topology.islsForActiveSwitches.size() * 2 - } + islHelper.restoreIsls(altIsls) northbound.deleteLinkProps(northbound.getLinkProps(topology.isls)) database.resetCosts(topology.isls) } @@ -422,8 +383,7 @@ class RetriesIsolatedSpec extends HealthCheckSpecification { cleanup: lockKeeper.cleanupTrafficShaperRules(swPair.src.regions) flowHelperV2.deleteFlow(flow.flowId) - northbound.portUp(islToBreak.srcSwitch.dpId, islToBreak.srcPort) - wait(WAIT_OFFSET) { northbound.activeLinks.size() == topology.islsForActiveSwitches.size() * 2 } + islHelper.restoreIsl(islToBreak) database.resetCosts(topology.isls) } }