16 package org.openkilda.pce.provider;
30 import org.junit.After;
31 import org.junit.AfterClass;
32 import org.junit.Assert;
33 import org.junit.BeforeClass;
34 import org.junit.Ignore;
35 import org.junit.Test;
36 import org.neo4j.driver.v1.AuthTokens;
37 import org.neo4j.driver.v1.Driver;
38 import org.neo4j.driver.v1.GraphDatabase;
39 import org.neo4j.graphdb.GraphDatabaseService;
40 import org.neo4j.graphdb.Label;
41 import org.neo4j.graphdb.Node;
42 import org.neo4j.graphdb.Relationship;
43 import org.neo4j.graphdb.RelationshipType;
44 import org.neo4j.graphdb.Transaction;
45 import org.neo4j.graphdb.factory.GraphDatabaseFactory;
46 import org.neo4j.io.fs.FileUtils;
47 import org.neo4j.kernel.configuration.BoltConnector;
50 import java.util.Arrays;
51 import java.util.LinkedList;
52 import java.util.List;
60 private static GraphDatabaseService graphDb;
62 private static final File databaseDirectory =
new File(
"target/neo4j-test-db");
63 private static Driver driver;
68 FileUtils.deleteRecursively(databaseDirectory);
71 BoltConnector bolt =
new BoltConnector(
"0");
72 graphDb =
new GraphDatabaseFactory()
73 .newEmbeddedDatabaseBuilder(databaseDirectory)
74 .setConfig(bolt.type,
"BOLT")
75 .setConfig(bolt.enabled,
"true")
76 .setConfig(bolt.listen_address,
"localhost:7878")
79 driver = GraphDatabase.driver(
"bolt://localhost:7878", AuthTokens.basic(
"neo4j",
"password"));
92 try (Transaction tx = graphDb.beginTx()) {
93 graphDb.execute(
"MATCH (n) DETACH DELETE n");
100 try (Transaction tx = graphDb.beginTx()) {
102 node1 = graphDb.createNode(Label.label(
"switch"));
103 node1.setProperty(
"name",
"00:03");
105 node2 = graphDb.createNode(Label.label(
"switch"));
106 node2.setProperty(
"name",
"00:04");
107 Relationship rel1 = node1.createRelationshipTo(node2, RelationshipType.withName(
"flow"));
108 rel1.setProperty(
"flowid",
"f1");
109 rel1.setProperty(
"cookie", 3);
110 rel1.setProperty(
"meter_id", 2);
111 rel1.setProperty(
"transit_vlan", 1);
112 rel1.setProperty(
"src_switch",
"00:03");
117 Assert.assertEquals(fi.get(0).getFlowId(),
"f1");
118 Assert.assertEquals(fi.get(0).getCookie(), 3);
119 Assert.assertEquals(fi.get(0).getMeterId(), 2);
120 Assert.assertEquals(fi.get(0).getTransitVlanId(), 1);
121 Assert.assertEquals(fi.get(0).getSrcSwitchId(),
"00:03");
124 private Node createNode(String
name) {
125 Node n = graphDb.createNode(Label.label(
"switch"));
126 n.setProperty(
"name",
name);
127 n.setProperty(
"state",
"active");
131 private Relationship addRel(Node n1, Node n2, String
status, String actual,
int cost,
long bw,
int port) {
133 rel = n1.createRelationshipTo(n2, RelationshipType.withName(
"isl"));
134 rel.setProperty(
"status",
status);
135 rel.setProperty(
"actual", actual);
137 rel.setProperty(
"cost", cost);
139 rel.setProperty(
"available_bandwidth", bw);
140 rel.setProperty(
"latency", 5);
141 rel.setProperty(
"src_port",
port);
142 rel.setProperty(
"dst_port",
port);
143 rel.setProperty(
"src_switch", n1.getProperty(
"name"));
144 rel.setProperty(
"dst_switch", n2.getProperty(
"name"));
148 private Relationship addRelAsString(Node n1, Node n2, String
status, String actual, String cost,
int bw,
int port) {
150 rel = n1.createRelationshipTo(n2, RelationshipType.withName(
"isl"));
151 rel.setProperty(
"status",
status);
152 rel.setProperty(
"actual", actual);
153 if (cost != null && !cost.isEmpty()) {
154 rel.setProperty(
"cost", cost);
156 rel.setProperty(
"available_bandwidth", bw);
157 rel.setProperty(
"latency", 5);
158 rel.setProperty(
"src_port",
port);
159 rel.setProperty(
"dst_port",
port);
160 rel.setProperty(
"src_switch", n1.getProperty(
"name"));
161 rel.setProperty(
"dst_switch", n2.getProperty(
"name"));
168 private void createDiamondAsString(String pathBstatus, String pathCstatus, String pathBcost, String pathCcost,
169 String switchStart,
int startIndex) {
170 try (Transaction tx = graphDb.beginTx()) {
173 int index = startIndex;
174 Node nodeA = createNode(switchStart + String.format(
"%02X",
index++));
175 Node nodeB = createNode(switchStart + String.format(
"%02X",
index++));
176 Node nodeC = createNode(switchStart + String.format(
"%02X",
index++));
177 Node nodeD = createNode(switchStart + String.format(
"%02X",
index++));
178 String actual = (pathBstatus.equals(
"active") && pathCstatus.equals(
"active")) ?
"active" :
"inactive";
179 addRelAsString(nodeA, nodeB, pathBstatus, actual, pathBcost, 1000, 5);
180 addRelAsString(nodeA, nodeC, pathCstatus, actual, pathCcost, 1000, 6);
181 addRelAsString(nodeB, nodeD, pathBstatus, actual, pathBcost, 1000, 6);
182 addRelAsString(nodeC, nodeD, pathCstatus, actual, pathCcost, 1000, 5);
183 addRelAsString(nodeB, nodeA, pathBstatus, actual, pathBcost, 1000, 5);
184 addRelAsString(nodeC, nodeA, pathCstatus, actual, pathCcost, 1000, 6);
185 addRelAsString(nodeD, nodeB, pathBstatus, actual, pathBcost, 1000, 6);
186 addRelAsString(nodeD, nodeC, pathCstatus, actual, pathCcost, 1000, 5);
191 private void createDiamond(String pathBstatus, String pathCstatus,
int pathBcost,
int pathCcost) {
192 createDiamond(pathBstatus, pathCstatus, pathBcost, pathCcost,
"00:", 1);
195 private void createDiamond(String pathBstatus, String pathCstatus,
int pathBcost,
int pathCcost,
196 String switchStart,
int startIndex) {
197 try (Transaction tx = graphDb.beginTx()) {
200 int index = startIndex;
201 Node nodeA = createNode(switchStart + String.format(
"%02X",
index++));
202 Node nodeB = createNode(switchStart + String.format(
"%02X",
index++));
203 Node nodeC = createNode(switchStart + String.format(
"%02X",
index++));
204 Node nodeD = createNode(switchStart + String.format(
"%02X",
index++));
205 String actual = (pathBstatus.equals(
"active") && pathCstatus.equals(
"active")) ?
"active" :
"inactive";
206 addRel(nodeA, nodeB, pathBstatus, actual, pathBcost, 1000, 5);
207 addRel(nodeA, nodeC, pathCstatus, actual, pathCcost, 1000, 6);
208 addRel(nodeB, nodeD, pathBstatus, actual, pathBcost, 1000, 6);
209 addRel(nodeC, nodeD, pathCstatus, actual, pathCcost, 1000, 5);
210 addRel(nodeB, nodeA, pathBstatus, actual, pathBcost, 1000, 5);
211 addRel(nodeC, nodeA, pathCstatus, actual, pathCcost, 1000, 6);
212 addRel(nodeD, nodeB, pathBstatus, actual, pathBcost, 1000, 6);
213 addRel(nodeD, nodeC, pathCstatus, actual, pathCcost, 1000, 5);
218 private void connectDiamonds(SwitchId switchA, SwitchId switchB, String
status,
int cost,
int port) {
219 try (Transaction tx = graphDb.beginTx()) {
222 Node nodeA = graphDb.findNode(Label.label(
"switch"),
"name", switchA);
223 Node nodeB = graphDb.findNode(Label.label(
"switch"),
"name", switchB);
230 private void createTriangleTopo(String pathABstatus,
int pathABcost,
int pathCcost) {
231 createTriangleTopo(pathABstatus, pathABcost, pathCcost,
"00:", 1);
234 private void createTriangleTopo(String pathABstatus,
int pathABcost,
int pathCcost,
235 String switchStart,
int startIndex) {
236 try (Transaction tx = graphDb.beginTx()) {
239 int index = startIndex;
241 Node nodeA = createNode(switchStart + String.format(
"%02X",
index++));
242 Node nodeB = createNode(switchStart + String.format(
"%02X",
index++));
243 Node nodeC = createNode(switchStart + String.format(
"%02X",
index++));
245 addRel(nodeA, nodeB, pathABstatus, pathABstatus, pathABcost, 1000, 5);
246 addRel(nodeB, nodeA, pathABstatus, pathABstatus, pathABcost, 1000, 5);
247 addRel(nodeA, nodeC,
"active",
"active", pathCcost, 1000, 6);
248 addRel(nodeC, nodeA,
"active",
"active", pathCcost, 1000, 6);
249 addRel(nodeC, nodeB,
"active",
"active", pathCcost, 1000, 7);
250 addRel(nodeB, nodeC,
"active",
"active", pathCcost, 1000, 7);
260 createDiamond(
"active",
"active", 10, 20);
262 f.setSourceSwitch(
new SwitchId(
"00:01"));
263 f.setDestinationSwitch(
new SwitchId(
"00:04"));
267 Assert.assertNotNull(
path);
268 Assert.assertEquals(4,
path.left.getPath().size());
269 Assert.assertEquals(
new SwitchId(
"00:02"),
path.left.getPath().get(1).getSwitchId());
278 createDiamondAsString(
"active",
"active",
"10",
"20",
"FF:", 1);
280 f.setSourceSwitch(
new SwitchId(
"FF:01"));
281 f.setDestinationSwitch(
new SwitchId(
"FF:04"));
285 Assert.assertNotNull(
path);
286 Assert.assertEquals(4,
path.left.getPath().size());
287 Assert.assertEquals(
new SwitchId(
"FF:02"),
path.left.getPath().get(1).getSwitchId());
296 createDiamond(
"inactive",
"active", 10, 20,
"01:", 1);
298 f.setSourceSwitch(
new SwitchId(
"01:01"));
299 f.setDestinationSwitch(
new SwitchId(
"01:04"));
304 Assert.assertNotNull(
path);
305 Assert.assertEquals(4,
path.left.getPath().size());
307 Assert.assertEquals(
new SwitchId(
"01:03"),
path.left.getPath().get(1).getSwitchId());
315 createTriangleTopo(
"inactive", 5, 20,
"02:", 1);
317 f.setSourceSwitch(
new SwitchId(
"02:01"));
318 f.setDestinationSwitch(
new SwitchId(
"02:02"));
323 System.out.println(
"path = " +
path);
324 Assert.assertNotNull(
path);
325 Assert.assertEquals(4,
path.left.getPath().size());
327 Assert.assertEquals(
new SwitchId(
"02:03"),
path.left.getPath().get(1).getSwitchId());
335 createDiamond(
"active",
"active", -1, 2000,
"03:", 1);
337 f.setSourceSwitch(
new SwitchId(
"03:01"));
338 f.setDestinationSwitch(
new SwitchId(
"03:04"));
344 Assert.assertNotNull(
path);
345 Assert.assertEquals(4,
path.left.getPath().size());
347 Assert.assertEquals(
new SwitchId(
"03:02"),
path.left.getPath().get(1).getSwitchId());
356 createDiamond(
"inactive",
"inactive", 10, 30,
"04:", 1);
358 f.setSourceSwitch(
new SwitchId(
"04:01"));
359 f.setDestinationSwitch(
new SwitchId(
"04:04"));
370 createDiamond(
"active",
"active", 10, 20,
"05:", 1);
371 boolean ignoreBw =
false;
373 long time = System.currentTimeMillis();
374 System.out.println(
"start = " + time);
376 System.out.println(
"\nNETWORK = " + network);
378 System.out.println(
"AvailableNetwork = " + (System.currentTimeMillis() - time));
379 System.out.println(
"network.getCounts() = " + network.
getCounts());
381 time = System.currentTimeMillis();
383 System.out.println(
"network.getCounts() = " + network.
getCounts());
384 System.out.println(
"After Counts = " + (System.currentTimeMillis() - time));
386 time = System.currentTimeMillis();
388 System.out.println(
"2nd AvailableNetwork = " + (System.currentTimeMillis() - time));
390 Arrays.sort(network.
getSwitches().values().toArray(switches));
391 Assert.assertEquals(4, switches.length);
392 Assert.assertEquals(
new SwitchId(
"05:01"), switches[0].dpid);
393 Assert.assertEquals(
new SwitchId(
"05:04"), switches[3].dpid);
394 Assert.assertEquals(2, switches[0].outbound.size());
395 Assert.assertEquals(1, switches[0].outbound.get(
new SwitchId(
"05:02")).size());
396 Assert.assertEquals(10, switches[0].outbound.get(
new SwitchId(
"05:02")).iterator().next().getCost());
397 Assert.assertEquals(1, switches[0].outbound.get(
new SwitchId(
"05:03")).size());
398 Assert.assertEquals(20, switches[0].outbound.get(
new SwitchId(
"05:03")).iterator().next().getCost());
400 time = System.currentTimeMillis();
404 System.out.println(
"TIME: SimpleGetShortestPath.getPath -> " + (System.currentTimeMillis() - time));
405 System.out.println(
"result = " +
result);
407 time = System.currentTimeMillis();
410 System.out.println(
"TIME: SimpleGetShortestPath.getPath -> " + (System.currentTimeMillis() - time));
411 System.out.println(
"result = " +
result);
420 createDiamond(
"active",
"active", 10, 20,
"06:", 1);
421 createDiamond(
"active",
"active", 10, 20,
"07:", 1);
422 boolean ignoreBw =
false;
428 long time = System.currentTimeMillis();
432 System.out.println(
"TIME: SimpleGetShortestPath.getPath -> " + (System.currentTimeMillis() - time));
433 System.out.println(
"result = " +
result);
436 time = System.currentTimeMillis();
439 System.out.println(
"TIME: SimpleGetShortestPath.getPath -> " + (System.currentTimeMillis() - time));
440 System.out.println(
"result = " +
result);
450 createDiamond(
"active",
"active", 10, 20,
"08:", 1);
452 for (
int i = 0;
i < 50;
i++) {
453 createDiamond(
"active",
"active", 10, 20,
"10:", 4 *
i + 1);
454 createDiamond(
"active",
"active", 10, 20,
"11:", 4 *
i + 1);
455 createDiamond(
"active",
"active", 10, 20,
"12:", 4 *
i + 1);
456 createDiamond(
"active",
"active", 10, 20,
"13:", 4 *
i + 1);
458 for (
int i = 0;
i < 49;
i++) {
459 String prev = String.format(
"%02X", 4 *
i + 4);
460 String next = String.format(
"%02X", 4 *
i + 5);
461 connectDiamonds(
new SwitchId(
"10:" + prev),
new SwitchId(
"10:" + next),
"active", 20, 50);
462 connectDiamonds(
new SwitchId(
"11:" + prev),
new SwitchId(
"11:" + next),
"active", 20, 50);
463 connectDiamonds(
new SwitchId(
"12:" + prev),
new SwitchId(
"12:" + next),
"active", 20, 50);
464 connectDiamonds(
new SwitchId(
"13:" + prev),
new SwitchId(
"13:" + next),
"active", 20, 50);
466 connectDiamonds(
new SwitchId(
"10:99"),
new SwitchId(
"11:22"),
"active", 20, 50);
467 connectDiamonds(
new SwitchId(
"11:99"),
new SwitchId(
"12:22"),
"active", 20, 50);
468 connectDiamonds(
new SwitchId(
"12:99"),
new SwitchId(
"13:22"),
"active", 20, 50);
469 connectDiamonds(
new SwitchId(
"13:99"),
new SwitchId(
"10:22"),
"active", 20, 50);
471 boolean ignoreBw =
false;
475 System.out.println(
"network.getCounts() = " + network.
getCounts());
478 long time = System.currentTimeMillis();
482 System.out.println(
"TIME: SimpleGetShortestPath.getPath -> " + (System.currentTimeMillis() - time));
483 System.out.println(
"Path Length = " +
result.size());
486 time = System.currentTimeMillis();
489 System.out.println(
"TIME: SimpleGetShortestPath.getPath -> " + (System.currentTimeMillis() - time));
490 System.out.println(
"Path Length = " +
result.size());
500 createDiamond(
"active",
"active", 10, 20,
"09:", 1);
504 flow.setSourceSwitch(start);
505 flow.setDestinationSwitch(end);
507 flow.setBandwidth(10);
510 List<PathNode> left =
result.left.getPath();
511 Assert.assertEquals(start, left.get(0).getSwitchId());
512 Assert.assertEquals(end, left.get(left.size() - 1).getSwitchId());
513 List<PathNode> right =
result.right.getPath();
514 Assert.assertEquals(end, right.get(0).getSwitchId());
515 Assert.assertEquals(start, right.get(right.size() - 1).getSwitchId());
523 int flowBandwidth = 1000;
526 flow.setBandwidth(flowBandwidth);
527 flow.setSourceSwitch(
new SwitchId(
"A1:01"));
528 flow.setDestinationSwitch(
new SwitchId(
"A1:03"));
530 flow.setFlowId(
"flow-A1:01-A1:03");
532 long availableBandwidth = 0L;
533 createLinearTopoWithFlowSegments(10,
"A1:", 1, availableBandwidth, flow.getFlowId(), flow.getBandwidth());
538 Assert.assertEquals(4,
result.getLeft().getPath().size());
539 Assert.assertEquals(4,
result.getRight().getPath().size());
547 long originFlowBandwidth = 1000L;
550 flow.setBandwidth(originFlowBandwidth);
551 flow.setSourceSwitch(
new SwitchId(
"A1:01"));
552 flow.setDestinationSwitch(
new SwitchId(
"A1:03"));
554 flow.setFlowId(
"flow-A1:01-A1:03");
557 long availableBandwidth = 0L;
558 createLinearTopoWithFlowSegments(10,
"A1:", 1, availableBandwidth, flow.getFlowId(), flow.getBandwidth());
560 long updatedFlowBandwidth = originFlowBandwidth + 1;
567 private void createLinearTopoWithFlowSegments(
int cost, String switchStart,
int startIndex,
long linkBw,
568 String flowId,
long flowBandwidth) {
569 try (Transaction tx = graphDb.beginTx()) {
570 int index = startIndex;
572 Node nodeA = createNode(switchStart + String.format(
"%02X",
index++));
573 Node nodeB = createNode(switchStart + String.format(
"%02X",
index++));
574 Node nodeC = createNode(switchStart + String.format(
"%02X",
index));
575 addRel(nodeA, nodeB,
"active",
"active", cost, linkBw, 5);
576 addRel(nodeB, nodeC,
"active",
"active", cost, linkBw, 6);
577 addRel(nodeC, nodeB,
"active",
"active", cost, linkBw, 6);
578 addRel(nodeB, nodeA,
"active",
"active", cost, linkBw, 5);
580 addFlowSegment(flowId, flowBandwidth, nodeA, nodeB, 5, 5);
581 addFlowSegment(flowId, flowBandwidth, nodeB, nodeA, 5, 5);
582 addFlowSegment(flowId, flowBandwidth, nodeB, nodeC, 6, 6);
583 addFlowSegment(flowId, flowBandwidth, nodeC, nodeB, 6, 6);
588 private void addFlowSegment(String flowId,
long flowBandwidth, Node src, Node dst,
int srcPort,
int dstPort) {
590 rel = src.createRelationshipTo(dst, RelationshipType.withName(
"flow_segment"));
591 rel.setProperty(
"src_switch", src.getProperty(
"name"));
592 rel.setProperty(
"dst_switch", dst.getProperty(
"name"));
593 rel.setProperty(
"src_port", srcPort);
594 rel.setProperty(
"dst_port", dstPort);
595 rel.setProperty(
"flowid", flowId);
596 rel.setProperty(
"bandwidth", flowBandwidth);
void setIgnoreBandwidth(Boolean ignoreBandwidth)
void verifyConversionToPair()
LinkedList< SimpleIsl > getPath()
void testGetPathByCostActive()
void getPathTest_InitState()
Map< String, Integer > getCounts()
Map< SwitchId, SimpleSwitch > getSwitches()
ImmutablePair< PathInfoData, PathInfoData > getPath(Flow flow, Strategy strategy)
void testGetPathByCostNoCost()
void testGetPathByCostInactive()
void shouldAlwaysFindPathForExistedFlow()
static void teatDownOnce()
AvailableNetwork removeSelfLoops()
void getPathTest_Islands()
AvailableNetwork getAvailableNetwork(boolean ignoreBandwidth, long requestedBandwidth)
void shouldNotFindPathForExistedFlowAndIncreasedBandwidth()
void testGetPathByCostActive_AsStr()
List< FlowInfo > getFlowInfo()
void testGetPathByCostInactiveOnTriangleTopo()
void addIslsOccupiedByFlow(String flowId, boolean ignoreBandwidth, long flowBandwidth)