Skip to content

Commit

Permalink
[TEST]: Improvement: Verification of validation response
Browse files Browse the repository at this point in the history
  • Loading branch information
Yuliia Miroshnychenko committed Oct 2, 2024
1 parent 4922be0 commit c1dd3da
Show file tree
Hide file tree
Showing 10 changed files with 108 additions and 48 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package org.openkilda.functionaltests.helpers.model

import org.openkilda.northbound.dto.v1.flows.FlowValidationDto
import org.openkilda.northbound.dto.v1.flows.PathDiscrepancyDto
import org.openkilda.northbound.dto.v2.haflows.HaFlowValidationResult
import org.openkilda.northbound.dto.v2.yflows.YFlowValidationResult

import groovy.transform.ToString

@ToString
class ComplexFlowValidationResponse {
private static final String COOKIE_ID_IN_RULE_DISCREPANCY_STRING_REGEX = /-?\d{19}/

boolean asExpected
List<SubFlowValidationDiscrepancies> subFlowsDiscrepancies

ComplexFlowValidationResponse(YFlowValidationResult yFlowValidation) {
this.asExpected = yFlowValidation.asExpected
this.subFlowsDiscrepancies = collectDiscrepanciesPerSubFlow(yFlowValidation.subFlowValidationResults)
}

ComplexFlowValidationResponse(HaFlowValidationResult haFlowValidation) {
this.asExpected = haFlowValidation.asExpected
this.subFlowsDiscrepancies = collectDiscrepanciesPerSubFlow(haFlowValidation.subFlowValidationResults)

}

static private List<SubFlowValidationDiscrepancies> collectDiscrepanciesPerSubFlow(List<FlowValidationDto> subFlowValidationDetails) {
List<SubFlowValidationDiscrepancies> discrepanciesPerSubFlow = subFlowValidationDetails.groupBy { it.flowId }.collect{
HashMap<FlowDirection, List<PathDiscrepancyDto>> discrepancy = [:]
it.value.each {
verifyValidateLogic(it)
it.asExpected ?: discrepancy.put(FlowDirection.getByDirection(it.direction.toLowerCase()), it.discrepancies)
}
discrepancy.isEmpty() ? null : new SubFlowValidationDiscrepancies(subFlowId: it.key, flowDiscrepancies: discrepancy)

}.findAll()
discrepanciesPerSubFlow
}

static private void verifyValidateLogic(FlowValidationDto validationDto) {
assert (validationDto.asExpected && validationDto.discrepancies.isEmpty()) || (!validationDto.asExpected && !validationDto.discrepancies.isEmpty()),
"There is an error in the validation logic $validationDto"
}

Set<Long> retrieveAllRulesCookieFromDiscrepancy() {
def rules = subFlowsDiscrepancies.flowDiscrepancies*.values().flatten()
rules.collect { new Long((it =~ COOKIE_ID_IN_RULE_DISCREPANCY_STRING_REGEX)[0]) }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,11 @@ class HaFlowExtended {
northboundV2.validateHaFlow(haFlowId)
}

ComplexFlowValidationResponse validateAndCollectDiscrepancy() {
def validationResponse = validate()
new ComplexFlowValidationResponse(validationResponse)
}

HaFlowSyncResult sync() {
log.debug("Sync ha-flow '${haFlowId}'")
northboundV2.syncHaFlow(haFlowId)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package org.openkilda.functionaltests.helpers.model

import org.openkilda.northbound.dto.v1.flows.PathDiscrepancyDto

import groovy.transform.ToString
import groovy.transform.TupleConstructor

@TupleConstructor
@ToString
class SubFlowValidationDiscrepancies {
String subFlowId
Map<FlowDirection, List<PathDiscrepancyDto>> flowDiscrepancies
}
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,11 @@ class YFlowExtended {
northboundV2.validateYFlow(yFlowId)
}

ComplexFlowValidationResponse validateAndCollectDiscrepancy() {
def validationResponse = validate()
new ComplexFlowValidationResponse(validationResponse)
}

YFlowSyncResult sync() {
log.debug("Synchronize Y-Flow '${yFlowId}'")
northboundV2.synchronizeYFlow(yFlowId)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,9 +72,8 @@ class HaFlowDiversitySpec extends HealthCheckSpecification {
and: "HA-Flow passes flow validation"
withPool {
[haFlow1, haFlow2, haFlow3].eachParallel { HaFlowExtended haFlow ->
def validationResponse = haFlow.validate()
assert validationResponse.asExpected
assert validationResponse.getSubFlowValidationResults().every { it.getDiscrepancies().isEmpty() }
def validationResponse = haFlow.validateAndCollectDiscrepancy()
assert validationResponse.asExpected && validationResponse.subFlowsDiscrepancies.isEmpty()
}
}
}
Expand Down Expand Up @@ -127,9 +126,8 @@ class HaFlowDiversitySpec extends HealthCheckSpecification {
and: "HA-Flow passes flow validation"
withPool {
[haFlow1, haFlow2].eachParallel { HaFlowExtended haFlow ->
def validationResponse = haFlow.validate()
assert validationResponse.asExpected
assert validationResponse.getSubFlowValidationResults().every { it.getDiscrepancies().isEmpty()}
def validationResponse = haFlow.validateAndCollectDiscrepancy()
assert validationResponse.asExpected && validationResponse.subFlowsDiscrepancies.isEmpty()
}
}
}
Expand Down Expand Up @@ -181,9 +179,8 @@ class HaFlowDiversitySpec extends HealthCheckSpecification {
and: "HA-Flow passes flow validation"
withPool {
[haFlow1, haFlow2].eachParallel { HaFlowExtended haFlow ->
def validationResponse = haFlow.validate()
assert validationResponse.asExpected
assert validationResponse.getSubFlowValidationResults().every { it.getDiscrepancies().isEmpty()}
def validationResponse = haFlow.validateAndCollectDiscrepancy()
assert validationResponse.asExpected && validationResponse.subFlowsDiscrepancies.isEmpty()
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package org.openkilda.functionaltests.spec.flows.haflows

import static org.openkilda.functionaltests.extension.tags.Tag.HA_FLOW
import static org.openkilda.functionaltests.extension.tags.Tag.SMOKE
import static org.openkilda.functionaltests.helpers.model.SwitchRules.missingRuleCookieIds
import static org.openkilda.testing.Constants.RULES_DELETION_TIME

import org.openkilda.functionaltests.HealthCheckSpecification
Expand Down Expand Up @@ -39,11 +38,11 @@ class HaFlowValidationSpec extends HealthCheckSpecification {
def haFlow = haFlowFactory.getRandom(swT)

when: "Validate HA-Flow"
def validationResult = haFlow.validate()
def validationResult = haFlow.validateAndCollectDiscrepancy()

then: "HA-Flow is validated successfully"
validationResult.asExpected
validationResult.getSubFlowValidationResults().every { it.getDiscrepancies().isEmpty() }
validationResult.subFlowsDiscrepancies.isEmpty()
}

def "HA-Flow validation should fail in case of missing rule on #switchRole switch"() {
Expand All @@ -59,11 +58,11 @@ class HaFlowValidationSpec extends HealthCheckSpecification {

then: "HA-Flow validation returns deleted rule in 'Discrepancies' section"
Wrappers.wait(RULES_DELETION_TIME) {
def validationResponse = haFlow.validate()
assert !validationResponse.asExpected
def missingRules = validationResponse.getSubFlowValidationResults().collect { it.getDiscrepancies() }.flatten()
def discrepancies = haFlow.validateAndCollectDiscrepancy()
assert !discrepancies.asExpected
def missingRules = discrepancies.retrieveAllRulesCookieFromDiscrepancy()
assert missingRules.size() == 1, "We deleted only one rule"
assert missingRules.get(0).getRule().contains(haFlowRuleToDelete.getCookie().toString())
assert missingRules.first() == haFlowRuleToDelete.getCookie()
}

where:
Expand Down Expand Up @@ -91,11 +90,10 @@ class HaFlowValidationSpec extends HealthCheckSpecification {

then: "HA-Flow validation returns rules related to deleted meter in 'Discrepancies' section"
Wrappers.wait(RULES_DELETION_TIME) {
def validationResponse = haFlow.validate()
assert !validationResponse.asExpected
def missingMeters = validationResponse.getSubFlowValidationResults().collect { it.getDiscrepancies() }.flatten()
assert missingMeters.size() == expectedDeletedSwitchRules.size()
assert missingRuleCookieIds(missingMeters) == expectedDeletedSwitchRules.collect { it.getCookie() } as Set
def discrepancies = haFlow.validateAndCollectDiscrepancy()
assert !discrepancies.asExpected
def missingMeters = discrepancies.retrieveAllRulesCookieFromDiscrepancy()
assert missingMeters == expectedDeletedSwitchRules.collect { it.getCookie() } as Set
}

where:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,9 +73,9 @@ class YFlowCreateSpec extends HealthCheckSpecification {
def paths = yFlow.retrieveAllEntityPaths()

and: "Y-Flow passes flow validation"
with(yFlow.validate()) {
with(yFlow.validateAndCollectDiscrepancy()) {
it.asExpected
it.subFlowValidationResults.each { assert it.asExpected }
it.subFlowsDiscrepancies.isEmpty()
}

and: "Both sub-flows pass flow validation"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import org.openkilda.functionaltests.HealthCheckSpecification
import org.openkilda.functionaltests.error.yflow.YFlowNotFoundExpectedError
import org.openkilda.functionaltests.extension.tags.Tags
import org.openkilda.functionaltests.helpers.Wrappers
import org.openkilda.functionaltests.helpers.model.FlowDirection
import org.openkilda.functionaltests.helpers.model.YFlowFactory
import org.openkilda.functionaltests.model.stats.Direction
import org.openkilda.messaging.payload.flow.FlowState
Expand Down Expand Up @@ -94,25 +95,17 @@ class YFlowValidationSpec extends HealthCheckSpecification {
switchHelper.deleteSwitchRules(swIdToManipulate, cookieToDelete)
then: "Y-Flow is not valid"
def validateYFlowInfo = yFlow.validate()
!validateYFlowInfo.asExpected
def discrepancies = yFlow.validateAndCollectDiscrepancy()
!discrepancies.asExpected
and: "Discrepancies has been detected for broken sub-flow REVERSE direction"
def reverseBrokenSubFlow = validateYFlowInfo.subFlowValidationResults
.find { it.flowId == subFl_1.flowId && it.direction == Direction.REVERSE.name() }
assert !reverseBrokenSubFlow.asExpected && reverseBrokenSubFlow.discrepancies
assert discrepancies.subFlowsDiscrepancies.find { it.subFlowId == subFl_1.flowId }.flowDiscrepancies.get(FlowDirection.REVERSE)
and: "No discrepancies has been detected for broken sub-flow FORWARD direction"
def forwardBrokenSubFlow = validateYFlowInfo.subFlowValidationResults
.find { it.flowId == subFl_1.flowId && it.direction == Direction.FORWARD.name() }
assert forwardBrokenSubFlow.asExpected && forwardBrokenSubFlow.discrepancies.empty
assert !discrepancies.subFlowsDiscrepancies.find { it.subFlowId == subFl_1.flowId }.flowDiscrepancies.get(FlowDirection.FORWARD)
and: "No discrepancies has been detected for another sub-flow"
validateYFlowInfo.subFlowValidationResults
.findAll { it.flowId != subFl_1.flowId }.each {
assert it.asExpected && it.discrepancies.empty
}
assert !discrepancies.subFlowsDiscrepancies.find { it.subFlowId != subFl_1.flowId }
and: "Simple flow validation detects discrepancies for the subFlow_1 REVERSE direction only"
verifyAll(northbound.validateFlow(subFl_1.flowId)) { subFlow1 ->
Expand All @@ -138,7 +131,8 @@ class YFlowValidationSpec extends HealthCheckSpecification {
yFlow.waitForBeingInState(FlowState.UP)
then: "Y-Flow/subFlow passes flow validation"
yFlow.validate().asExpected
def discrepanciesAfterSync = yFlow.validateAndCollectDiscrepancy()
discrepanciesAfterSync.asExpected && discrepanciesAfterSync.subFlowsDiscrepancies.isEmpty()
yFlow.subFlows.each {
northbound.validateFlow(it.flowId).each { direction -> assert direction.asExpected }
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import org.openkilda.functionaltests.HealthCheckSpecification
import org.openkilda.functionaltests.extension.tags.Tags
import org.openkilda.functionaltests.helpers.HaFlowFactory
import org.openkilda.functionaltests.helpers.Wrappers
import org.openkilda.functionaltests.helpers.model.FlowDirection
import org.openkilda.functionaltests.helpers.model.HaFlowExtended
import org.openkilda.functionaltests.helpers.model.SwitchRulesFactory
import org.openkilda.functionaltests.helpers.model.SwitchTriplet
Expand Down Expand Up @@ -135,11 +136,10 @@ class Server42HaFlowRttSpec extends HealthCheckSpecification {
}

and: "Ha-Flow is valid and UP"
haFlow.validate().subFlowValidationResults.each { validationInfo ->
if (validationInfo.direction == "forward") {
assert !validationInfo.asExpected
} else {
assert validationInfo.asExpected
verifyAll(haFlow.validateAndCollectDiscrepancy()) { validationResult ->
assert !validationResult.asExpected
validationResult.subFlowsDiscrepancies.each {
assert it.flowDiscrepancies.get(FlowDirection.FORWARD) && !it.flowDiscrepancies.get(FlowDirection.REVERSE)
}
}
haFlow.retrieveDetails().status == FlowState.UP
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import org.openkilda.functionaltests.HealthCheckSpecification
import org.openkilda.functionaltests.extension.tags.Tags
import org.openkilda.functionaltests.helpers.Wrappers
import org.openkilda.functionaltests.helpers.builder.YFlowBuilder
import org.openkilda.functionaltests.helpers.model.FlowDirection
import org.openkilda.functionaltests.helpers.model.FlowWithSubFlowsEntityPath
import org.openkilda.functionaltests.helpers.model.SwitchRulesFactory
import org.openkilda.functionaltests.helpers.model.SwitchTriplet
Expand Down Expand Up @@ -412,13 +413,10 @@ class Server42YFlowRttSpec extends HealthCheckSpecification {
}

and: "Y-Flow is valid and UP"
verifyAll(yFlow.validate()) { validationResult ->
verifyAll(yFlow.validateAndCollectDiscrepancy()) { validationResult ->
assert !validationResult.asExpected
validationResult.getSubFlowValidationResults().findAll { it.direction == "FORWARD" }.each {
assert !it.asExpected
}
validationResult.getSubFlowValidationResults().findAll { it.direction == "REVERSE" }.each {
assert it.asExpected
validationResult.subFlowsDiscrepancies.each {
assert it.flowDiscrepancies.get(FlowDirection.FORWARD) && !it.flowDiscrepancies.get(FlowDirection.REVERSE)
}
}

Expand Down

0 comments on commit c1dd3da

Please sign in to comment.