Open Kilda Java Documentation
FlowCrudSteps.java
Go to the documentation of this file.
1 /* Copyright 2018 Telstra Open Source
2  *
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 package org.openkilda.atdd.staging.steps;
17 
18 import static com.nitorcreations.Matchers.reflectEquals;
19 import static java.lang.String.format;
20 import static java.util.stream.Collectors.toList;
21 import static org.hamcrest.MatcherAssert.assertThat;
22 import static org.hamcrest.Matchers.contains;
23 import static org.hamcrest.Matchers.containsInAnyOrder;
24 import static org.hamcrest.Matchers.empty;
25 import static org.hamcrest.Matchers.equalTo;
26 import static org.hamcrest.Matchers.everyItem;
27 import static org.hamcrest.Matchers.hasKey;
28 import static org.hamcrest.Matchers.hasProperty;
29 import static org.hamcrest.Matchers.is;
30 import static org.hamcrest.Matchers.isIn;
31 import static org.hamcrest.Matchers.not;
32 import static org.hamcrest.Matchers.notNullValue;
33 import static org.junit.Assert.assertEquals;
34 import static org.junit.Assert.assertFalse;
35 import static org.junit.Assert.assertNotNull;
36 import static org.junit.Assert.assertNull;
37 import static org.junit.Assert.assertTrue;
38 import static org.junit.Assert.fail;
39 
68 
69 import com.google.common.collect.ContiguousSet;
70 import com.google.common.collect.DiscreteDomain;
71 import com.google.common.collect.Range;
72 import com.google.common.collect.RangeSet;
73 import com.google.common.collect.TreeRangeSet;
74 import cucumber.api.java.en.And;
75 import cucumber.api.java.en.Given;
76 import cucumber.api.java.en.Then;
77 import cucumber.api.java.en.When;
78 import cucumber.api.java8.En;
79 import lombok.extern.slf4j.Slf4j;
80 import net.jodah.failsafe.Failsafe;
81 import net.jodah.failsafe.RetryPolicy;
82 import org.apache.commons.collections4.ListValuedMap;
83 import org.apache.commons.collections4.multimap.ArrayListValuedHashMap;
84 import org.springframework.beans.factory.annotation.Autowired;
85 import org.springframework.beans.factory.annotation.Qualifier;
86 
87 import java.text.SimpleDateFormat;
88 import java.util.ArrayList;
89 import java.util.Collections;
90 import java.util.Date;
91 import java.util.HashSet;
92 import java.util.List;
93 import java.util.Map;
94 import java.util.Map.Entry;
95 import java.util.Objects;
96 import java.util.Set;
97 import java.util.UUID;
98 import java.util.concurrent.TimeUnit;
99 import java.util.stream.Stream;
100 
101 @Slf4j
102 public class FlowCrudSteps implements En {
103 
104  @Autowired
105  private NorthboundService northboundService;
106 
107  @Autowired
108  private FloodlightService floodlightService;
109 
110  @Autowired
111  private TopologyEngineService topologyEngineService;
112 
113  @Autowired
114  private TopologyDefinition topologyDefinition;
115 
116  @Autowired
117  private TraffExamService traffExam;
118 
119  @Autowired
120  private FlowManager flowManager;
121 
122  @Autowired
123  @Qualifier("topologyUnderTest")
124  private TopologyUnderTest topologyUnderTest;
125 
126  private Set<FlowPayload> flows;
127  private Set<FlowPathPayload> flowPaths = new HashSet<>();
128  private FlowPayload flowResponse;
129 
130  @Given("^flows defined over active switches in the reference topology$")
132  flows = flowManager.allActiveSwitchesFlows();
133  }
134 
135  @Given("^flows defined over active traffgens in the reference topology$")
137  flows = flowManager.allActiveTraffgenFlows();
138  }
139 
140  @Given("Create (\\d+) flows? with A Switch used and at least (\\d+) alternate paths? between source and "
141  + "destination switch and (\\d+) bandwidth")
142  public void flowsWithAlternatePaths(int flowsAmount, int alternatePaths, int bw) {
143  Map<FlowPayload, List<TopologyDefinition.Isl>> flowIsls = topologyUnderTest.getFlowIsls();
144  flowIsls.putAll(flowManager.createFlowsWithASwitch(flowsAmount, alternatePaths, bw));
145  //temporary resaving flows before refactoring all methods to work with topologyUnderTest
146  flows = flowIsls.keySet();
147  flows.forEach(flow -> flowPaths.add(northboundService.getFlowPath(flow.getId())));
148  }
149 
150  @And("^flow paths? (?:is|are) changed")
151  public void flowPathIsChanged() {
152  Set<FlowPathPayload> actualFlowPaths = new HashSet<>();
153  flows.forEach(flow -> actualFlowPaths.add(northboundService.getFlowPath(flow.getId())));
154  assertThat(actualFlowPaths, everyItem(not(isIn(flowPaths))));
155 
156  // Save actual flow paths
157  flowPaths = actualFlowPaths;
158  }
159 
160  @And("^flow paths? (?:is|are) unchanged")
161  public void flowPathIsUnchanged() {
162  Set<FlowPathPayload> actualFlowPaths = new HashSet<>();
163  flows.forEach(flow -> actualFlowPaths.add(northboundService.getFlowPath(flow.getId())));
164  assertThat(actualFlowPaths, everyItem(isIn(flowPaths)));
165  }
166 
167  @And("Create defined flows?")
168  public void createFlows() {
171  }
172 
173  @And("^each flow has unique flow_id$")
175  flows.forEach(flow -> flow.setId(format("%s-%s", flow.getId(), UUID.randomUUID().toString())));
176  }
177 
178  @And("^each flow has flow_id with (.*) prefix$")
179  public void buildFlowIdToEachFlow(String flowIdPrefix) {
180  flows.forEach(flow -> flow.setId(format("%s-%s", flowIdPrefix, flow.getId())));
181  }
182 
183  @And("^(?:each )?flow has max bandwidth set to (\\d+)$")
184  public void setBandwidthToEachFlow(int bandwidth) {
185  flows.forEach(flow -> flow.setMaximumBandwidth(bandwidth));
186  }
187 
188  @When("^initialize creation of given flows$")
190  for (FlowPayload flow : flows) {
191  FlowPayload result = northboundService.addFlow(flow);
192  assertThat(format("A flow creation request for '%s' failed.", flow.getId()), result,
193  reflectEquals(flow, "lastUpdated", "status"));
194  assertThat(format("Flow status for '%s' was not set to '%s'. Received status: '%s'",
195  flow.getId(), FlowState.ALLOCATED, result.getStatus()),
196  result.getStatus(), equalTo(FlowState.ALLOCATED.toString()));
197  assertThat(format("The flow '%s' is missing lastUpdated field", flow.getId()), result,
198  hasProperty("lastUpdated", notNullValue()));
199  }
200  }
201 
202  @Then("^each flow is created and stored in TopologyEngine$")
204  List<Flow> expextedFlows = flows.stream()
205  .map(flow -> new Flow(flow.getId(),
206  flow.getMaximumBandwidth(),
207  flow.isIgnoreBandwidth(), 0,
208  flow.getDescription(), null,
209  flow.getSource().getSwitchDpId(),
210  flow.getDestination().getSwitchDpId(),
211  flow.getSource().getPortId(),
212  flow.getDestination().getPortId(),
213  flow.getSource().getVlanId(),
214  flow.getDestination().getVlanId(),
215  0, 0, null, null))
216  .collect(toList());
217 
218  for (Flow expectedFlow : expextedFlows) {
219  ImmutablePair<Flow, Flow> flowPair = Failsafe.with(retryPolicy()
220  .retryWhen(null))
221  .get(() -> topologyEngineService.getFlow(expectedFlow.getFlowId()));
222 
223  assertNotNull(format("The flow '%s' is missing in TopologyEngine.", expectedFlow.getFlowId()), flowPair);
224  assertThat(format("The flow '%s' in TopologyEngine is different from defined.", expectedFlow.getFlowId()),
225  flowPair.getLeft(), is(equalTo(expectedFlow)));
226  }
227  }
228 
229  @And("^(?:each )?flow is in UP state$")
230  public void eachFlowIsInUpState() {
231  eachFlowIsUp(flows);
232  }
233 
234  private void eachFlowIsUp(Set<FlowPayload> flows) {
235  for (FlowPayload flow : flows) {
236  FlowIdStatusPayload status = Failsafe.with(retryPolicy()
237  .retryIf(p -> p == null || ((FlowIdStatusPayload) p).getStatus() != FlowState.UP))
238  .get(() -> northboundService.getFlowStatus(flow.getId()));
239 
240  assertNotNull(format("The flow status for '%s' can't be retrived from Northbound.", flow.getId()), status);
241  assertThat(format("The flow '%s' in Northbound is different from defined.", flow.getId()),
242  status, hasProperty("id", equalTo(flow.getId())));
243  assertThat(format("The flow '%s' has wrong status in Northbound.", flow.getId()),
244  status, hasProperty("status", equalTo(FlowState.UP)));
245  }
246  }
247 
248  @And("^each flow can be read from Northbound$")
250  for (FlowPayload flow : flows) {
251  FlowPayload result = northboundService.getFlow(flow.getId());
252 
253  assertNotNull(format("The flow '%s' is missing in Northbound.", flow.getId()), result);
254  assertEquals(format("The flow '%s' in Northbound is different from defined.", flow.getId()), flow.getId(),
255  result.getId());
256  }
257  }
258 
259  @And("^(?:each )?flow is valid per Northbound validation$")
260  public void eachFlowIsValid() {
261  flows.forEach(flow -> {
262  List<FlowValidationDto> validations = northboundService.validateFlow(flow.getId());
263  validations.forEach(flowValidation -> {
264  assertEquals(flow.getId(), flowValidation.getFlowId());
265  assertTrue(format("The flow '%s' has discrepancies: %s", flow.getId(),
266  flowValidation.getDiscrepancies()), flowValidation.getDiscrepancies().isEmpty());
267  assertTrue(format("The flow '%s' didn't pass validation.", flow.getId()),
268  flowValidation.getAsExpected());
269  });
270 
271  });
272  }
273 
274  @And("^(?:each )?flow has traffic going with bandwidth not less than (\\d+) and not greater than (\\d+)$")
275  public void eachFlowHasTrafficGoingWithBandwidthNotLessThan(int bandwidthLowLimit, int bandwidthHighLimit)
276  throws Throwable {
277  List<Exam> examsInProgress = buildAndStartTraffExams();
278  SoftAssertions softAssertions = new SoftAssertions();
279  List<String> issues = new ArrayList<>();
280 
281  for (Exam exam : examsInProgress) {
282  String flowId = exam.getFlow().getId();
283 
284  ExamReport report = traffExam.waitExam(exam);
285  softAssertions.checkThat(format("The flow %s had errors: %s",
286  flowId, report.getErrors()), report.hasError(), is(false));
287  softAssertions.checkThat(format("The flow %s had no traffic.", flowId),
288  report.hasTraffic(), is(true));
289  softAssertions.checkThat(format("The flow %s had unexpected bandwidth: %s", flowId, report.getBandwidth()),
290  report.getBandwidth().getKbps() > bandwidthLowLimit
291  && report.getBandwidth().getKbps() < bandwidthHighLimit, is(true));
292  }
293  softAssertions.verify();
294  }
295 
296  @And("^each flow has no traffic$")
297  public void eachFlowHasNoTraffic() {
298  List<Exam> examsInProgress = buildAndStartTraffExams();
299 
300  List<ExamReport> hasTraffic = examsInProgress.stream()
301  .map(exam -> traffExam.waitExam(exam))
302  .filter(ExamReport::hasTraffic)
303  .collect(toList());
304 
305  assertThat("Detected unexpected traffic.", hasTraffic, empty());
306  }
307 
308  private List<Exam> buildAndStartTraffExams() {
309  FlowTrafficExamBuilder examBuilder = new FlowTrafficExamBuilder(topologyDefinition, traffExam);
310 
311  List<Exam> result = flows.stream()
312  .flatMap(flow -> {
313  try {
314  // Instruct TraffGen to produce traffic with maximum bandwidth.
315  return Stream.of(examBuilder.buildExam(flow, 0));
316  } catch (FlowNotApplicableException ex) {
317  log.info("Skip traffic exam. {}", ex.getMessage());
318  return Stream.empty();
319  }
320  })
321  .peek(exam -> {
322  try {
323  ExamResources resources = traffExam.startExam(exam);
324  exam.setResources(resources);
325  } catch (OperationalException ex) {
326  log.error("Unable to start traffic exam for {}.", exam.getFlow(), ex);
327  fail(ex.getMessage());
328  }
329  })
330  .collect(toList());
331 
332  log.info("{} of {} flow's traffic examination have been started", result.size(),
333  flows.size());
334 
335  return result;
336  }
337 
338  @Then("^each flow can be updated with (\\d+) max bandwidth( and new vlan)?$")
339  public void eachFlowCanBeUpdatedWithBandwidth(int bandwidth, String newVlanStr) {
340  final boolean newVlan = newVlanStr != null;
341  for (FlowPayload flow : flows) {
342  flow.setMaximumBandwidth(bandwidth);
343  if (newVlan) {
344  flow.getDestination().setVlanId(getAllowedVlan(flows, flow.getDestination().getSwitchDpId()));
345  flow.getSource().setVlanId(getAllowedVlan(flows, flow.getSource().getSwitchDpId()));
346  }
347  FlowPayload result = northboundService.updateFlow(flow.getId(), flow);
348  assertThat(format("A flow update request for '%s' failed.", flow.getId()), result,
349  reflectEquals(flow, "lastUpdated", "status"));
350  }
351  }
352 
353  private int getAllowedVlan(Set<FlowPayload> flows, SwitchId switchDpId) {
354  RangeSet<Integer> allocatedVlans = TreeRangeSet.create();
355  flows.forEach(f -> {
356  allocatedVlans.add(Range.singleton(f.getSource().getVlanId()));
357  allocatedVlans.add(Range.singleton(f.getDestination().getVlanId()));
358  });
359  RangeSet<Integer> availableVlansRange = TreeRangeSet.create();
360  Switch theSwitch = topologyDefinition.getSwitches().stream()
361  .filter(sw -> sw.getDpId().equals(switchDpId)).findFirst().get();
362  theSwitch.getOutPorts().forEach(port -> availableVlansRange.addAll(port.getVlanRange()));
363  availableVlansRange.removeAll(allocatedVlans);
364  return availableVlansRange.asRanges().stream()
365  .flatMap(range -> ContiguousSet.create(range, DiscreteDomain.integers()).stream())
366  .findFirst().get();
367  }
368 
369  @And("^each flow has meters installed with (\\d+) max bandwidth$")
370  public void eachFlowHasMetersInstalledWithBandwidth(long bandwidth) {
371  for (FlowPayload flow : flows) {
372  ImmutablePair<Flow, Flow> flowPair = topologyEngineService.getFlow(flow.getId());
373 
374  try {
375  MetersEntriesMap forwardSwitchMeters = floodlightService
376  .getMeters(flowPair.getLeft().getSourceSwitch());
377  int forwardMeterId = flowPair.getLeft().getMeterId();
378  assertThat(forwardSwitchMeters, hasKey(forwardMeterId));
379  MeterEntry forwardMeter = forwardSwitchMeters.get(forwardMeterId);
380  assertThat(forwardMeter.getEntries(), contains(hasProperty("rate", equalTo(bandwidth))));
381 
382  MetersEntriesMap reverseSwitchMeters = floodlightService
383  .getMeters(flowPair.getRight().getSourceSwitch());
384  int reverseMeterId = flowPair.getRight().getMeterId();
385  assertThat(reverseSwitchMeters, hasKey(reverseMeterId));
386  MeterEntry reverseMeter = reverseSwitchMeters.get(reverseMeterId);
387  assertThat(reverseMeter.getEntries(), contains(hasProperty("rate", equalTo(bandwidth))));
388  } catch (UnsupportedOperationException ex) {
389  //TODO: a workaround for not implemented dumpMeters on OF_12 switches.
390  log.warn("Switch doesn't support dumping of meters. {}", ex.getMessage());
391  }
392  }
393  }
394 
395  @And("^all active switches have no excessive meters installed$")
397  ListValuedMap<SwitchId, Integer> switchMeters = new ArrayListValuedHashMap<>();
398  for (FlowPayload flow : flows) {
399  ImmutablePair<Flow, Flow> flowPair = topologyEngineService.getFlow(flow.getId());
400  if (flowPair != null) {
401  switchMeters.put(flowPair.getLeft().getSourceSwitch(), flowPair.getLeft().getMeterId());
402  switchMeters.put(flowPair.getRight().getSourceSwitch(), flowPair.getRight().getMeterId());
403  }
404  }
405 
406  List<TopologyDefinition.Switch> switches = topologyDefinition.getActiveSwitches();
407  switches.forEach(sw -> {
408  List<Integer> expectedMeters = switchMeters.get(sw.getDpId());
409  try {
410  List<Integer> actualMeters = floodlightService.getMeters(sw.getDpId()).values().stream()
411  .map(MeterEntry::getMeterId)
412  .collect(toList());
413 
414  if (!expectedMeters.isEmpty() || !actualMeters.isEmpty()) {
415  assertThat(format("Meters of switch %s don't match expected.", sw), actualMeters,
416  containsInAnyOrder(expectedMeters));
417  }
418 
419  } catch (UnsupportedOperationException ex) {
420  //TODO: a workaround for not implemented dumpMeters on OF_12 switches.
421  log.warn("Switch doesn't support dumping of meters. {}", ex.getMessage());
422  }
423  });
424  }
425 
426  @Then("^each flow can be deleted$")
427  public void eachFlowCanBeDeleted() {
428  List<String> deletedFlowIds = new ArrayList<>();
429 
430  for (FlowPayload flow : flows) {
431  FlowPayload result = northboundService.deleteFlow(flow.getId());
432  if (result != null) {
433  deletedFlowIds.add(result.getId());
434  }
435  }
436 
437  assertThat("Deleted flows from Northbound don't match expected", deletedFlowIds, containsInAnyOrder(
438  flows.stream().map(flow -> equalTo(flow.getId())).collect(toList())));
439  }
440 
441  @And("^each flow can not be read from Northbound$")
443  for (FlowPayload flow : flows) {
444  FlowPayload result = Failsafe.with(retryPolicy()
445  .abortWhen(null)
446  .retryIf(Objects::nonNull))
447  .get(() -> northboundService.getFlow(flow.getId()));
448 
449  assertNull(format("The flow '%s' exists.", flow.getId()), result);
450  }
451  }
452 
453  @And("^each flow can not be read from TopologyEngine$")
455  for (FlowPayload flow : flows) {
456  ImmutablePair<Flow, Flow> result = Failsafe.with(retryPolicy()
457  .abortWhen(null)
458  .retryIf(Objects::nonNull))
459  .get(() -> topologyEngineService.getFlow(flow.getId()));
460 
461  assertNull(format("The flow '%s' exists.", flow.getId()), result);
462  }
463  }
464 
465  @And("^create flow between '(.*)' and '(.*)' and alias it as '(.*)'$")
466  public void createFlowBetween(String srcAlias, String dstAlias, String flowAlias) {
467  Switch srcSwitch = topologyUnderTest.getAliasedObject(srcAlias);
468  Switch dstSwitch = topologyUnderTest.getAliasedObject(dstAlias);
469  FlowPayload flow = new FlowSet().buildWithAnyPortsInUniqueVlan("auto" + getTimestamp(),
470  srcSwitch, dstSwitch, 1000);
471  northboundService.addFlow(flow);
472  topologyUnderTest.addAlias(flowAlias, flow);
473  }
474 
475  @And("^'(.*)' flow is in UP state$")
476  public void flowIsUp(String flowAlias) {
477  FlowPayload flow = topologyUnderTest.getAliasedObject(flowAlias);
478  eachFlowIsUp(Collections.singleton(flow));
479  }
480 
481  @When("^request all switch meters for switch '(.*)' and alias results as '(.*)'$")
482  public void requestMeters(String switchAlias, String meterAlias) {
483  Switch sw = topologyUnderTest.getAliasedObject(switchAlias);
484  topologyUnderTest.addAlias(meterAlias, floodlightService.getMeters(sw.getDpId()));
485 
486  }
487 
488  @And("^select first meter of '(.*)' and alias it as '(.*)'$")
489  public void selectFirstMeter(String metersAlias, String newMeterAlias) {
490  MetersEntriesMap meters = topologyUnderTest.getAliasedObject(metersAlias);
491  Entry<Integer, MeterEntry> firstMeter = meters.entrySet().iterator().next();
492  topologyUnderTest.addAlias(newMeterAlias, firstMeter);
493  }
494 
495  @Then("^meters '(.*)' does not have '(.*)'$")
496  public void doesNotHaveMeter(String metersAlias, String meterAlias) {
497  MetersEntriesMap meters = topologyUnderTest.getAliasedObject(metersAlias);
498  Entry<Integer, MeterEntry> meter = topologyUnderTest.getAliasedObject(meterAlias);
499  assertFalse(meters.containsKey(meter.getKey()));
500  }
501 
502  private RetryPolicy retryPolicy() {
503  return new RetryPolicy()
504  .withDelay(2, TimeUnit.SECONDS)
505  .withMaxRetries(10);
506  }
507 
508  @Given("^random flow aliased as '(.*)'$")
509  public void randomFlowAliasedAsFlow(String flowAlias) {
510  topologyUnderTest.addAlias(flowAlias, flowManager.randomFlow());
511  }
512 
513  @And("^change bandwidth of (.*) flow to (\\d+)$")
514  public void changeBandwidthOfFlow(String flowAlias, int newBw) {
515  FlowPayload flow = topologyUnderTest.getAliasedObject(flowAlias);
516  flow.setMaximumBandwidth(newBw);
517  }
518 
519  @When("^change bandwidth of (.*) flow to '(.*)'$")
520  public void changeBandwidthOfFlow(String flowAlias, String bwAlias) {
521  FlowPayload flow = topologyUnderTest.getAliasedObject(flowAlias);
522  long bw = topologyUnderTest.getAliasedObject(bwAlias);
523  flow.setMaximumBandwidth(bw);
524  }
525 
526  @And("^create flow '(.*)'$")
527  public void createFlow(String flowAlias) {
528  FlowPayload flow = topologyUnderTest.getAliasedObject(flowAlias);
529  flowResponse = northboundService.addFlow(flow);
530  }
531 
532  @And("^get available bandwidth and maximum speed for flow (.*) and alias them as '(.*)' "
533  + "and '(.*)' respectively$")
534  public void getAvailableBandwidthAndSpeed(String flowAlias, String bwAlias, String speedAlias) {
535  FlowPayload flow = topologyUnderTest.getAliasedObject(flowAlias);
536  List<PathNodePayload> flowPath = northboundService.getFlowPath(flow.getId()).getForwardPath();
537  List<IslInfoData> allLinks = northboundService.getAllLinks();
538  long minBw = Long.MAX_VALUE;
539  long minSpeed = Long.MAX_VALUE;
540 
541  /*
542  Take flow path and all links. Now for every pair in flow path find a link.
543  Take minimum available bandwidth and minimum available speed from those links
544  (flow's speed and left bandwidth depends on the weakest isl)
545  */
546  for (int i = 1; i < flowPath.size(); i++) {
547  PathNodePayload from = flowPath.get(i - 1);
548  PathNodePayload to = flowPath.get(i);
549  IslInfoData isl = allLinks.stream().filter(link ->
550  link.getPath().get(0).getSwitchId().equals(from.getSwitchId())
551  && link.getPath().get(1).getSwitchId().equals(to.getSwitchId()))
552  .findFirst().get();
553  minBw = Math.min(isl.getAvailableBandwidth(), minBw);
554  minSpeed = Math.min(isl.getSpeed(), minSpeed);
555  }
556  topologyUnderTest.addAlias(bwAlias, minBw);
557  topologyUnderTest.addAlias(speedAlias, minSpeed);
558  }
559 
560  @And("^update flow (.*)$")
561  public void updateFlow(String flowAlias) {
562  FlowPayload flow = topologyUnderTest.getAliasedObject(flowAlias);
563  flowResponse = northboundService.updateFlow(flow.getId(), flow);
564  }
565 
566  @When("^get info about flow (.*)$")
567  public void getInfoAboutFlow(String flowAlias) {
568  FlowPayload flow = topologyUnderTest.getAliasedObject(flowAlias);
569  flowResponse = northboundService.getFlow(flow.getId());
570  }
571 
572  @Then("^response flow has bandwidth equal to '(.*)'$")
573  public void responseFlowHasBandwidth(String bwAlias) {
574  long expectedBw = topologyUnderTest.getAliasedObject(bwAlias);
575  assertThat((long) flowResponse.getMaximumBandwidth(), equalTo(expectedBw));
576  }
577 
578  @Then("^response flow has bandwidth equal to (\\d+)$")
579  public void responseFlowHasBandwidth(long expectedBw) {
580  assertThat(flowResponse.getMaximumBandwidth(), equalTo(expectedBw));
581  }
582 
583  @And("^delete flow (.*)$")
584  public void deleteFlow(String flowAlias) {
585  FlowPayload flow = topologyUnderTest.getAliasedObject(flowAlias);
586  northboundService.deleteFlow(flow.getId());
587  }
588 
589  @And("^get path of '(.*)' and alias it as '(.*)'$")
590  public void getPathAndAlias(String flowAlias, String pathAlias) {
591  FlowPayload flow = topologyUnderTest.getAliasedObject(flowAlias);
592  topologyUnderTest.addAlias(pathAlias, northboundService.getFlowPath(flow.getId()));
593  }
594 
595  @And("^(.*) flow's path equals to '(.*)'$")
596  public void verifyFlowPath(String flowAlias, String pathAlias) {
597  FlowPayload flow = topologyUnderTest.getAliasedObject(flowAlias);
598  FlowPathPayload expectedPath = topologyUnderTest.getAliasedObject(pathAlias);
599  FlowPathPayload actualPath = northboundService.getFlowPath(flow.getId());
600  assertThat(actualPath, equalTo(expectedPath));
601  }
602 
603  private String getTimestamp() {
604  return new SimpleDateFormat("ddMMMHHmm").format(new Date());
605  }
606 }
Map< FlowPayload, List< TopologyDefinition.Isl > > createFlowsWithASwitch(int flowsAmount, int alternatePaths, int bandwidth)
void getPathAndAlias(String flowAlias, String pathAlias)
void setMaximumBandwidth(long maximumBandwidth)
void flowsWithAlternatePaths(int flowsAmount, int alternatePaths, int bw)
void doesNotHaveMeter(String metersAlias, String meterAlias)
void getAvailableBandwidthAndSpeed(String flowAlias, String bwAlias, String speedAlias)
List< FlowValidationDto > validateFlow(String flowId)
def status()
Definition: rest.py:593
Definition: MeterEntry.java:26
list result
Definition: plan-d.py:72
void createFlowBetween(String srcAlias, String dstAlias, String flowAlias)
void eachFlowHasTrafficGoingWithBandwidthNotLessThan(int bandwidthLowLimit, int bandwidthHighLimit)
void requestMeters(String switchAlias, String meterAlias)
void eachFlowHasMetersInstalledWithBandwidth(long bandwidth)
ImmutablePair< Flow, Flow > getFlow(String flowId)
void eachFlowCanBeUpdatedWithBandwidth(int bandwidth, String newVlanStr)
FlowPayload buildWithAnyPortsInUniqueVlan(String flowId, Switch srcSwitch, Switch destSwitch, int bandwidth)
Definition: FlowSet.java:80
void selectFirstMeter(String metersAlias, String newMeterAlias)
void verifyFlowPath(String flowAlias, String pathAlias)
net
Definition: plan-b.py:46
FlowPayload updateFlow(String flowId, FlowPayload payload)
void changeBandwidthOfFlow(String flowAlias, int newBw)
FlowIdStatusPayload getFlowStatus(String flowId)