blob: ebfb53228faf16ad96100d1a17396bdfb2def58b [file] [log] [blame]
package net.onrc.onos.ofcontroller.core.internal;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import java.util.Collection;
import java.util.List;
import java.util.ArrayList;
import java.util.Iterator;
import net.onrc.onos.ofcontroller.core.ISwitchStorage;
import net.onrc.onos.ofcontroller.core.ISwitchStorage.SwitchState;
import org.junit.After;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import org.openflow.protocol.OFPhysicalPort;
import com.thinkaurelius.titan.core.TitanGraph;
import com.tinkerpop.blueprints.Vertex;
import com.tinkerpop.gremlin.java.GremlinPipeline;
import com.tinkerpop.pipes.PipeFunction;
import com.tinkerpop.pipes.branch.LoopPipe.LoopBundle;
import javax.script.ScriptContext;
import javax.script.ScriptEngine;
import javax.script.ScriptException;
import com.tinkerpop.gremlin.groovy.jsr223.GremlinGroovyScriptEngine;
public class SwitchStorageImplTest {
private ISwitchStorage switchStorage;
private TitanGraph titanGraph;
@Before
public void setUp() throws Exception {
titanGraph = TestDatabaseManager.getTestDatabase();
TestDatabaseManager.populateTestData(titanGraph);
switchStorage = new TestableSwitchStorageImpl();
}
@After
public void tearDown() throws Exception {
titanGraph.shutdown();
}
@Ignore @Test
public void testUpdate() {
fail("Not yet implemented");
}
@Test
public void testAddPort() {
String dpid = "00:00:00:00:00:00:0a:01";
short portNumber = 5;
OFPhysicalPort portToAdd = new OFPhysicalPort();
portToAdd.setName("port 5 at SEA switch");
portToAdd.setCurrentFeatures(OFPhysicalPort.OFPortFeatures.OFPPF_100MB_FD.getValue());
portToAdd.setPortNumber(portNumber);
switchStorage.addPort(dpid, portToAdd);
Vertex sw = titanGraph.getVertices("dpid", dpid).iterator().next();
GremlinPipeline<Vertex, Vertex> pipe = new GremlinPipeline<Vertex, Vertex>();
pipe.start(sw).out("on").has("number", portNumber);
assertTrue(pipe.hasNext());
Vertex addedPort = pipe.next();
assertFalse(pipe.hasNext());
assertEquals(addedPort.getProperty("number"), portNumber);
}
@Ignore @Test
public void testGetPorts() {
fail("Not yet implemented");
}
@Ignore @Test
public void testGetPortStringShort() {
fail("Not yet implemented");
}
@Ignore @Test
public void testGetPortStringString() {
fail("Not yet implemented");
}
@Test
public void testAddSwitch() {
String dpid = "00:00:00:00:00:00:0a:07";
switchStorage.addSwitch(dpid);
Iterator<Vertex> it = titanGraph.getVertices("dpid", dpid).iterator();
assertTrue(it.hasNext());
Vertex addedSwitch = it.next();
assertFalse(it.hasNext());
assertEquals(addedSwitch.getProperty("type"), "switch");
assertEquals(addedSwitch.getProperty("dpid"), dpid);
assertEquals(addedSwitch.getProperty("state"), SwitchState.ACTIVE.toString());
}
@Test
public void testDeleteSwitch() {
String dpid = "00:00:00:00:00:00:0a:01";
switchStorage.deleteSwitch(dpid);
Iterator<Vertex> it = titanGraph.getVertices("dpid", dpid).iterator();
assertFalse(it.hasNext());
}
@Test
public void testDeletePortByPortNum() {
//FIXME fails because query for the port is wrong in SwitchStorageImpl
String dpid = "00:00:00:00:00:00:0a:01";
short portNum = 3;
switchStorage.deletePort(dpid, portNum);
Vertex sw = titanGraph.getVertices("dpid", dpid).iterator().next();
/*
Iterator<Vertex> it = sw.getVertices(Direction.OUT, "on").iterator();
while (it.hasNext()){
System.out.println(it.next());
}
*/
GremlinPipeline<Vertex, Vertex> pipe = new GremlinPipeline<Vertex, Vertex>();
pipe.start(sw).out("on").has("number", portNum);
assertFalse(pipe.hasNext());
}
@Ignore @Test
public void testDeletePortStringString() {
fail("Not yet implemented");
}
@Ignore @Test
public void testGetActiveSwitches() {
fail("Not yet implemented");
}
static class MyLoopFunction implements PipeFunction<LoopBundle<Vertex>, Boolean> {
String dpid;
public MyLoopFunction(String dpid) {
super();
this.dpid = dpid;
}
public Boolean compute(LoopBundle<Vertex> bundle) {
Boolean output = false;
if (! bundle.getObject().getProperty("dpid").equals(dpid)) {
output = true;
}
return output;
}
}
@Test
public void testShortestPath() {
String dpid_src = "00:00:00:00:00:00:0a:01";
String dpid_dest = "00:00:00:00:00:00:0a:06";
//
// Implement the Shortest Path between two vertices by using
// the following Gremlin CLI code:
// v_src.as("x").out("on").out("link").in("on").dedup().loop("x"){it.object.dpid != v_dest.dpid}.path(){it.dpid}{it.number}{it.number}
// The equivalent code used here is:
// results = []; v_src.as("x").out("on").out("link").in("on").dedup().loop("x"){it.object.dpid != v_dest.dpid}.path().fill(results)
//
// Get the source vertex
Iterator<Vertex> iter = titanGraph.getVertices("dpid", dpid_src).iterator();
if (! iter.hasNext())
return; // Source vertex not found
Vertex v_src = iter.next();
// Get the destination vertex
iter = titanGraph.getVertices("dpid", dpid_dest).iterator();
if (! iter.hasNext())
return; // Destination vertex not found
Vertex v_dest = iter.next();
//
// Implement the Gremlin script and run it
//
// NOTE: This mechanism is slower. The code is kept here
// for future reference.
//
/*
String gremlin = "v_src.as(\"x\").out(\"on\").out(\"link\").in(\"on\").dedup().loop(\"x\"){it.object.dpid != v_dest.dpid}.path().fill(results)";
String gremlin_nopath = "v_src.as(\"x\").out(\"on\").out(\"link\").in(\"on\").dedup().loop(\"x\"){it.object.dpid != \"NO-SUCH-DPID\"}.path().fill(results)";
ScriptEngine engine = new GremlinGroovyScriptEngine();
ArrayList<ArrayList<Vertex>> results = new ArrayList<ArrayList<Vertex>>();
engine.getBindings(ScriptContext.ENGINE_SCOPE).put("g", titanGraph);
engine.getBindings(ScriptContext.ENGINE_SCOPE).put("v_src", v_src);
engine.getBindings(ScriptContext.ENGINE_SCOPE).put("v_dest", v_dest);
engine.getBindings(ScriptContext.ENGINE_SCOPE).put("results", results);
try {
engine.eval(gremlin);
} catch (ScriptException e) {
System.err.println("Caught ScriptException running Gremlin script: " + e.getMessage());
return;
}
for (ArrayList<Vertex> lv : results) {
...
}
*/
MyLoopFunction whileFunction = new MyLoopFunction(dpid_dest);
GremlinPipeline<Vertex, Vertex> pipe = new GremlinPipeline<Vertex, Vertex>();
Collection<List> results = new ArrayList<List>();
GremlinPipeline<Vertex, List> path;
path = pipe.start(v_src).as("x").out("on").out("link").in("on").dedup().loop("x", whileFunction).path();
path.fill(results);
//
// Extract the result and compose it into a string
//
String results_str = "";
// System.out.println("BEGIN " + results.size());
for (List l : results) {
for (Object o: l) {
Vertex v = (Vertex)(o);
// System.out.println(v);
String type = v.getProperty("type").toString();
results_str += "[type: " + type;
// System.out.println("type: " + type);
if (type.equals("port")) {
String number = v.getProperty("number").toString();
// System.out.println("number: " + number);
results_str += " number: " + number + "]";
}
if (type.equals("switch")) {
String dpid = v.getProperty("dpid").toString();
// System.out.println("dpid: " + dpid);
results_str += " dpid: " + dpid + "]";
}
}
}
// System.out.println("END\n");
System.out.println(results_str);
//
// Check the result
//
String expected_result = "[type: switch dpid: 00:00:00:00:00:00:0a:01][type: port number: 2][type: port number: 1][type: switch dpid: 00:00:00:00:00:00:0a:03][type: port number: 2][type: port number: 2][type: switch dpid: 00:00:00:00:00:00:0a:04][type: port number: 3][type: port number: 1][type: switch dpid: 00:00:00:00:00:00:0a:06]";
assertEquals(results_str, expected_result);
//
// Test Shortest-Path computation to non-existing destination
//
results.clear();
MyLoopFunction noDestWhileFunction = new MyLoopFunction("NO-SUCH-DPID");
path = pipe.start(v_src).as("x").out("on").out("link").in("on").dedup().loop("x", noDestWhileFunction).path();
path.fill(results);
assertTrue(results.size() == 0);
}
}