16 package org.openkilda.atdd;
18 import static java.lang.String.format;
19 import static org.hamcrest.MatcherAssert.assertThat;
20 import static org.hamcrest.Matchers.empty;
21 import static org.hamcrest.Matchers.hasItems;
22 import static org.junit.Assert.assertEquals;
23 import static org.junit.Assert.assertFalse;
24 import static org.junit.Assert.assertNotEquals;
25 import static org.junit.Assert.assertNotNull;
26 import static org.junit.Assert.assertNull;
27 import static org.junit.Assert.assertTrue;
45 import com.fasterxml.jackson.databind.ObjectMapper;
46 import cucumber.api.java.en.Given;
47 import cucumber.api.java.en.Then;
48 import cucumber.api.java.en.When;
49 import org.glassfish.jersey.client.ClientConfig;
50 import org.hamcrest.Matcher;
51 import org.hamcrest.Matchers;
54 import java.nio.file.Files;
55 import java.util.Arrays;
56 import java.util.List;
57 import java.util.concurrent.TimeUnit;
58 import java.util.stream.Collectors;
59 import javax.ws.rs.client.Client;
60 import javax.ws.rs.client.ClientBuilder;
61 import javax.ws.rs.core.Response;
65 private static final String fileName =
"topologies/nonrandom-topology.json";
67 @Given(
"^a nonrandom linear topology of 7 switches$")
69 ClassLoader classLoader = getClass().getClassLoader();
70 File file =
new File(classLoader.getResource(fileName).getFile());
71 String json =
new String(Files.readAllBytes(file.toPath()));
77 @When(
"^flow (.*) creation request with (.*) (\\d+) (\\d+) and (.*) (\\d+) (\\d+) and (\\d+) is successful$")
79 final
int sourceVlan, final String destinationSwitch, final
int destinationPort,
80 final
int destinationVlan, final
int bandwidth) throws Exception {
84 bandwidth,
false, flowId, null,
FlowState.
UP.getState());
87 assertNotNull(response);
88 response.setLastUpdated(null);
90 assertEquals(flowPayload, response);
93 @When(
"^flow (.*) creation request with (.*) (\\d+) (\\d+) and (.*) (\\d+) (\\d+) and (\\d+) is failed$")
94 public
void failedFlowCreation(final String flowId, final String sourceSwitch, final
int sourcePort,
95 final
int sourceVlan, final String destinationSwitch, final
int destinationPort,
96 final
int destinationVlan, final
int bandwidth) throws Exception {
104 assertNull(response);
107 @Then(
"^flow (.*) with (.*) (\\d+) (\\d+) and (.*) (\\d+) (\\d+) and (\\d+) could be created$")
108 public
void checkFlowCreation(final String flowId, final String sourceSwitch, final
int sourcePort,
109 final
int sourceVlan, final String destinationSwitch, final
int destinationPort,
110 final
int destinationVlan, final
int bandwidth) throws Exception {
113 new SwitchId(sourceSwitch),
new SwitchId(destinationSwitch), sourcePort, destinationPort,
114 sourceVlan, destinationVlan, 0, 0, null, null);
116 List<Flow> flows = validateFlowStored(expectedFlow);
118 assertFalse(flows.isEmpty());
119 assertTrue(flows.contains(expectedFlow));
122 @Then(
"^flow (.*) with (.*) (\\d+) (\\d+) and (.*) (\\d+) (\\d+) and (\\d+) could be read$")
123 public
void checkFlowRead(final String flowId, final String sourceSwitch, final
int sourcePort,
124 final
int sourceVlan, final String destinationSwitch, final
int destinationPort,
125 final
int destinationVlan, final
int bandwidth) throws Exception {
142 @Then(
"^flow (.*) with (.*) (\\d+) (\\d+) and (.*) (\\d+) (\\d+) and (\\d+) could be updated with (\\d+)$")
143 public
void checkFlowUpdate(final String flowId, final String sourceSwitch, final
int sourcePort,
144 final
int sourceVlan, final String destinationSwitch, final
int destinationPort,
145 final
int destinationVlan, final
int band, final
int newBand) throws Exception {
149 assertNotNull(response);
152 assertEquals(flowPayload, response);
154 checkFlowCreation(flowId, sourceSwitch, sourcePort, sourceVlan, destinationSwitch,
155 destinationPort, destinationVlan, newBand);
158 @Then(
"^flow (.*) with (.*) (\\d+) (\\d+) and (.*) (\\d+) (\\d+) and (\\d+) could be deleted$")
159 public
void checkFlowDeletion(final String flowId, final String sourceSwitch, final
int sourcePort,
160 final
int sourceVlan, final String destinationSwitch, final
int destinationPort,
161 final
int destinationVlan, final
int bandwidth) throws Exception {
162 int unknownFlowCount = -1;
163 int expectedFlowCount = getFlowCount(unknownFlowCount) - 2;
166 assertNotNull(response);
169 assertEquals(flowPayload, response);
173 TimeUnit.SECONDS.sleep(2);
179 int actualFlowCount = getFlowCount(expectedFlowCount);
180 assertEquals(expectedFlowCount, actualFlowCount);
183 @Then(
"^validation of flow (.*) is successful with no discrepancies$")
188 List<String> discrepancies = flowValidationResult.stream()
189 .peek(flowValidation -> {
190 assertEquals(flowId, flowValidation.getFlowId());
192 .flatMap(item -> item.getDiscrepancies().stream())
194 .filter(item -> !item.getField().equals(
"meterId"))
195 .map(PathDiscrepancyDto::toString)
196 .collect(Collectors.toList());
198 assertThat(
"The flow has discrepancies.", discrepancies, empty());
205 @Then(
"^validation of flow (.*) has completed with (\\d+) discrepancies on ([\\w:,]+) switches found$")
210 List<String> discrepancies = flowValidationResults.stream()
211 .flatMap(item -> item.getDiscrepancies().stream())
212 .map(PathDiscrepancyDto::getRule)
213 .collect(Collectors.toList());
215 assertEquals(discrepancyCount, discrepancies.size());
217 @SuppressWarnings(
"unchecked")
218 Matcher<String>[] expectedSwitches = Arrays.stream(switches.split(
","))
219 .map(Matchers::containsString)
220 .toArray(Matcher[]::
new);
221 assertThat(
"The discrepancies doesn't contain expected switches.", discrepancies, hasItems(expectedSwitches));
224 @Then(
"^rules with (.*) (\\d+) (\\d+) and (.*) (\\d+) (\\d+) and (\\d+) are installed$")
225 public
void checkRulesInstall(final String sourceSwitch, final
int sourcePort, final
int sourceVlan,
226 final String destinationSwitch, final
int destinationPort, final
int destinationVlan,
227 final
int bandwidth) throws Throwable {
231 @Then(
"^rules with (.*) (\\d+) (\\d+) and (.*) (\\d+) (\\d+) and (\\d+) are updated with (\\d+)$")
232 public
void checkRulesUpdate(final String sourceSwitch, final
int sourcePort, final
int sourceVlan,
233 final String destinationSwitch, final
int destinationPort, final
int destinationVlan,
234 final
int bandwidth, final
int newBandwidth) throws Throwable {
238 @Then(
"^rules with (.*) (\\d+) (\\d+) and (.*) (\\d+) (\\d+) and (\\d+) are deleted$")
239 public
void checkRulesDeletion(final String sourceSwitch, final
int sourcePort, final
int sourceVlan,
240 final String destinationSwitch, final
int destinationPort, final
int destinationVlan,
241 final
int bandwidth) throws Throwable {
245 private int checkTraffic(String sourceSwitch, String destSwitch,
246 int sourceVlan,
int destinationVlan,
int expectedStatus) {
247 if (isTrafficTestsEnabled()) {
248 System.out.print(
"=====> Send traffic");
250 long current = System.currentTimeMillis();
251 Client client = ClientBuilder.newClient(
new ClientConfig());
263 int fromNum = Integer.parseInt(sourceSwitch.substring(sourceSwitch.length() - 1));
264 int toNum = Integer.parseInt(destSwitch.substring(destSwitch.length() - 1));
265 String from =
"0000000" + (fromNum - 1);
266 String to =
"0000000" + (toNum + 1);
267 int fromPort = from.equals(
"00000001") ? 1 : 2;
269 System.out.println(
format(
"from:%s:%d::%d via %s, To:%s:%d::%d via %s",
270 from, fromPort, sourceVlan, sourceSwitch,
271 to, toPort, destinationVlan, destSwitch));
275 .target(trafficEndpoint)
276 .path(
"/checkflowtraffic")
277 .queryParam(
"srcswitch", from)
278 .queryParam(
"dstswitch", to)
279 .queryParam(
"srcport", fromPort)
280 .queryParam(
"dstport", toPort)
281 .queryParam(
"srcvlan", sourceVlan)
282 .queryParam(
"dstvlan", destinationVlan)
286 System.out.println(
format(
"======> Response = %s",
result.toString()));
287 System.out.println(
format(
"======> Send traffic Time: %,.3f", getTimeDuration(current)));
289 return result.getStatus();
291 return expectedStatus;
296 private int checkPingTraffic(String sourceSwitch, String destSwitch,
297 int sourceVlan,
int destinationVlan,
int expectedStatus) {
298 if (isTrafficTestsEnabled()) {
299 System.out.print(
"=====> Send PING traffic");
301 long current = System.currentTimeMillis();
302 Client client = ClientBuilder.newClient(
new ClientConfig());
314 int fromNum = Integer.parseInt(sourceSwitch.substring(sourceSwitch.length() - 1));
315 int toNum = Integer.parseInt(destSwitch.substring(destSwitch.length() - 1));
316 String from =
"0000000" + (fromNum - 1);
317 String to =
"0000000" + (toNum + 1);
318 int fromPort = from.equals(
"00000001") ? 1 : 2;
320 System.out.println(
format(
"from:%s:%d::%d via %s, To:%s:%d::%d via %s",
321 from, fromPort, sourceVlan, sourceSwitch,
322 to, toPort, destinationVlan, destSwitch));
326 .target(mininetEndpoint)
327 .path(
"/checkpingtraffic")
328 .queryParam(
"srcswitch", from)
329 .queryParam(
"dstswitch", to)
330 .queryParam(
"srcport", fromPort)
331 .queryParam(
"dstport", toPort)
332 .queryParam(
"srcvlan", sourceVlan)
333 .queryParam(
"dstvlan", destinationVlan)
338 String body =
result.readEntity(String.class);
339 System.out.println(
format(
"======> Response = %s, BODY = %s",
result.toString(), body));
340 System.out.println(
format(
"======> Send traffic Time: %,.3f", getTimeDuration(current)));
342 if (body.equals(
"NOOP")) {
343 return expectedStatus;
348 return expectedStatus;
358 @Then(
"^traffic through (.*) (\\d+) (\\d+) and (.*) (\\d+) (\\d+) and (\\d+) is forwarded$")
360 final String destinationSwitch, final
int destinationPort,
361 final
int destinationVlan, final
int bandwidth) throws Throwable {
362 TimeUnit.SECONDS.sleep(2);
363 int status = checkTraffic(sourceSwitch, destinationSwitch, sourceVlan, destinationVlan, 200);
364 assertEquals(200,
status);
367 @Then(
"^traffic through (.*) (\\d+) (\\d+) and (.*) (\\d+) (\\d+) and (\\d+) is not forwarded$")
369 final String destinationSwitch, final
int destinationPort,
370 final
int destinationVlan, final
int bandwidth) throws Throwable {
371 TimeUnit.SECONDS.sleep(2);
372 int status = checkTraffic(sourceSwitch, destinationSwitch, sourceVlan, destinationVlan, 503);
373 assertNotEquals(200,
status);
379 @Then(
"^traffic through (.*) (\\d+) (\\d+) and (.*) (\\d+) (\\d+) and (\\d+) is pingable$")
381 final String destinationSwitch, final
int destinationPort,
382 final
int destinationVlan, final
int bandwidth) throws Throwable {
383 TimeUnit.SECONDS.sleep(2);
384 int status = checkPingTraffic(sourceSwitch, destinationSwitch, sourceVlan, destinationVlan, 200);
385 assertEquals(200,
status);
388 @Then(
"^traffic through (.*) (\\d+) (\\d+) and (.*) (\\d+) (\\d+) and (\\d+) is not pingable$")
390 final String destinationSwitch, final
int destinationPort,
391 final
int destinationVlan, final
int bandwidth) throws Throwable {
392 TimeUnit.SECONDS.sleep(2);
393 int status = checkPingTraffic(sourceSwitch, destinationSwitch, sourceVlan, destinationVlan, 503);
394 assertNotEquals(200,
status);
397 @Then(
"^flows count is (\\d+)$")
399 int actualFlowCount = getFlowCount(expectedFlowsCount * 2);
400 assertEquals(expectedFlowsCount * 2, actualFlowCount);
403 @When(
"^flow (.*) push request for (.*) is successful$")
406 .readValue(getClass().getResourceAsStream(flowResource),
FlowInfoData.class);
411 flowInfoData.
getPayload().getLeft().setFlowId(flowName);
412 flowInfoData.
getPayload().getRight().setFlowId(flowName);
416 assertEquals(0,
result.getFailures());
417 assertEquals(2,
result.getSuccesses());
427 private List<Flow> validateFlowStored(
Flow expectedFlow)
throws Exception {
429 flows.forEach(this::resetImmaterialFields);
431 if (!flows.contains(expectedFlow) || flows.size() % 2 != 0) {
432 TimeUnit.SECONDS.sleep(2);
434 flows.forEach(this::resetImmaterialFields);
446 private int getFlowCount(
int expectedFlowsCount)
throws Exception {
447 List<Flow> flows = FlowUtils.dumpFlows();
450 if (expectedFlowsCount >= 0) {
451 int arbitraryCount = 3;
452 for (
int i = 0;
i < arbitraryCount;
i++) {
453 System.out.println(
format(
"\n=====> Flow Count is %d, expecting %d",
454 flows.size(), expectedFlowsCount));
455 if (expectedFlowsCount == flows.size()) {
458 TimeUnit.SECONDS.sleep(2);
459 flows = FlowUtils.dumpFlows();
461 if (expectedFlowsCount != flows.size()) {
462 System.out.println(
format(
"\n=====> FLOW COUNT doesn't match, flows: %s",
469 private void resetImmaterialFields(Flow flow) {
470 flow.setTransitVlan(0);
473 flow.setLastUpdated(null);
474 flow.setFlowPath(null);
void successfulPushFlowFromResource(String flowId, String flowResource)
static FlowPayload updateFlow(final String flowId, final FlowPayload payload)
void setMaximumBandwidth(long maximumBandwidth)
FlowEndpointPayload getDestination()
void checkFlowRead(final String flowId, final String sourceSwitch, final int sourcePort, final int sourceVlan, final String destinationSwitch, final int destinationPort, final int destinationVlan, final int bandwidth)
long getMaximumBandwidth()
void checkTrafficIsForwarded(final String sourceSwitch, final int sourcePort, final int sourceVlan, final String destinationSwitch, final int destinationPort, final int destinationVlan, final int bandwidth)
void checkFlowCreation(final String flowId, final String sourceSwitch, final int sourcePort, final int sourceVlan, final String destinationSwitch, final int destinationPort, final int destinationVlan, final int bandwidth)
static boolean isTrafficTestsEnabled()
static FlowPayload deleteFlow(final String flowId)
void checkTrafficIsNotForwarded(final String sourceSwitch, final int sourcePort, final int sourceVlan, final String destinationSwitch, final int destinationPort, final int destinationVlan, final int bandwidth)
static final String mininetEndpoint
static List< Flow > dumpFlows()
void checkFlowDeletion(final String flowId, final String sourceSwitch, final int sourcePort, final int sourceVlan, final String destinationSwitch, final int destinationPort, final int destinationVlan, final int bandwidth)
void checkFlowUpdate(final String flowId, final String sourceSwitch, final int sourcePort, final int sourceVlan, final String destinationSwitch, final int destinationPort, final int destinationVlan, final int band, final int newBand)
void checkRulesInstall(final String sourceSwitch, final int sourcePort, final int sourceVlan, final String destinationSwitch, final int destinationPort, final int destinationVlan, final int bandwidth)
static final String trafficEndpoint
ImmutablePair< Flow, Flow > getPayload()
void checkRulesHaveDiscrepancies(final String flowName, int discrepancyCount, String switches)
void setFlowId(String flowId)
void checkTrafficIsPingable(final String sourceSwitch, final int sourcePort, final int sourceVlan, final String destinationSwitch, final int destinationPort, final int destinationVlan, final int bandwidth)
static boolean CreateMininetTopology(String json)
void successfulFlowCreation(final String flowId, final String sourceSwitch, final int sourcePort, final int sourceVlan, final String destinationSwitch, final int destinationPort, final int destinationVlan, final int bandwidth)
void checkFlowCount(int expectedFlowsCount)
static FlowPayload getFlow(final String flowId)
static List< FlowValidationDto > validateFlow(final String flowId)
void checkTrafficIsNotPingable(final String sourceSwitch, final int sourcePort, final int sourceVlan, final String destinationSwitch, final int destinationPort, final int destinationVlan, final int bandwidth)
static FlowPayload putFlow(final FlowPayload payload)
void failedFlowCreation(final String flowId, final String sourceSwitch, final int sourcePort, final int sourceVlan, final String destinationSwitch, final int destinationPort, final int destinationVlan, final int bandwidth)
void checkRulesDeletion(final String sourceSwitch, final int sourcePort, final int sourceVlan, final String destinationSwitch, final int destinationPort, final int destinationVlan, final int bandwidth)
static BatchResults pushFlow(FlowInfoData flowInfo, boolean propagate)
void checkRulesInstalled(final String flowName)
FlowEndpointPayload getSource()
static String getFlowName(final String flowId)
void checkRulesUpdate(final String sourceSwitch, final int sourcePort, final int sourceVlan, final String destinationSwitch, final int destinationPort, final int destinationVlan, final int bandwidth, final int newBandwidth)
static double getTimeDuration(final long current)
void setLastUpdated(String lastUpdated)