blob: 177769b43d8fa58905f89c7b639e151fa3f4d4f6 [file] [log] [blame]
Jonathan Hart627f10c2013-01-16 14:20:03 -08001package net.floodlightcontroller.core.internal;
2
Jonathan Hartd1c5a1c2013-01-23 00:56:14 -08003import static org.junit.Assert.assertEquals;
4import static org.junit.Assert.assertFalse;
5import static org.junit.Assert.assertTrue;
6import static org.junit.Assert.fail;
Jonathan Hart627f10c2013-01-16 14:20:03 -08007
Pavlin Radoslavov5185fac2013-01-29 16:40:10 -08008import java.util.ArrayList;
Jonathan Hart627f10c2013-01-16 14:20:03 -08009import java.util.Iterator;
Pavlin Radoslavov5185fac2013-01-29 16:40:10 -080010import java.util.List;
Jonathan Hart627f10c2013-01-16 14:20:03 -080011
Jonathan Hart627f10c2013-01-16 14:20:03 -080012import net.floodlightcontroller.core.ISwitchStorage;
13import net.floodlightcontroller.core.ISwitchStorage.SwitchState;
14
15import org.junit.After;
16import org.junit.Before;
Jonathan Hartd1c5a1c2013-01-23 00:56:14 -080017import org.junit.Ignore;
Jonathan Hart627f10c2013-01-16 14:20:03 -080018import org.junit.Test;
19import org.openflow.protocol.OFPhysicalPort;
20
21import com.thinkaurelius.titan.core.TitanGraph;
Pavlin Radoslavov5185fac2013-01-29 16:40:10 -080022import com.tinkerpop.blueprints.Direction;
Jonathan Hart627f10c2013-01-16 14:20:03 -080023import com.tinkerpop.blueprints.Vertex;
Pavlin Radoslavov5185fac2013-01-29 16:40:10 -080024import com.tinkerpop.gremlin.groovy.Gremlin;
Jonathan Hart627f10c2013-01-16 14:20:03 -080025import com.tinkerpop.gremlin.java.GremlinPipeline;
Pavlin Radoslavov5185fac2013-01-29 16:40:10 -080026import com.tinkerpop.pipes.Pipe;
27import com.tinkerpop.pipes.PipeFunction;
28import com.tinkerpop.pipes.branch.LoopPipe;
29import com.tinkerpop.pipes.branch.LoopPipe.LoopBundle;
30import com.tinkerpop.pipes.filter.FilterPipe.Filter;
31import com.tinkerpop.pipes.util.PipesFluentPipeline;
32
33import javax.script.ScriptContext;
34import javax.script.ScriptEngine;
35import javax.script.ScriptException;
36import com.tinkerpop.gremlin.groovy.jsr223.GremlinGroovyScriptEngine;
37
Jonathan Hart627f10c2013-01-16 14:20:03 -080038
Jonathan Hartd1c5a1c2013-01-23 00:56:14 -080039public class SwitchStorageImplTest {
Jonathan Hart627f10c2013-01-16 14:20:03 -080040
Jonathan Hartd1c5a1c2013-01-23 00:56:14 -080041 private ISwitchStorage switchStorage;
42 private TitanGraph titanGraph;
Jonathan Hart627f10c2013-01-16 14:20:03 -080043
44 @Before
Jonathan Hartd1c5a1c2013-01-23 00:56:14 -080045 public void setUp() throws Exception {
Jonathan Hart627f10c2013-01-16 14:20:03 -080046 titanGraph = TestDatabaseManager.getTestDatabase();
47 TestDatabaseManager.populateTestData(titanGraph);
48
49 switchStorage = new TestableSwitchStorageImpl(titanGraph);
50 }
51
52 @After
Jonathan Hartd1c5a1c2013-01-23 00:56:14 -080053 public void tearDown() throws Exception {
54 titanGraph.shutdown();
Jonathan Hart627f10c2013-01-16 14:20:03 -080055 }
56
Jonathan Hartd1c5a1c2013-01-23 00:56:14 -080057 @Ignore @Test
Jonathan Hart627f10c2013-01-16 14:20:03 -080058 public void testUpdate() {
59 fail("Not yet implemented");
60 }
61
62 @Test
63 public void testAddPort() {
64
65 String dpid = "00:00:00:00:00:00:0a:01";
66 short portNumber = 5;
67
68 OFPhysicalPort portToAdd = new OFPhysicalPort();
69 portToAdd.setName("port 5 at SEA switch");
70 portToAdd.setCurrentFeatures(OFPhysicalPort.OFPortFeatures.OFPPF_100MB_FD.getValue());
71 portToAdd.setPortNumber(portNumber);
72
73 switchStorage.addPort(dpid, portToAdd);
74
75 Vertex sw = titanGraph.getVertices("dpid", dpid).iterator().next();
76
77 GremlinPipeline<Vertex, Vertex> pipe = new GremlinPipeline<Vertex, Vertex>();
78 pipe.start(sw).out("on").has("number", portNumber);
79
80 assertTrue(pipe.hasNext());
81 Vertex addedPort = pipe.next();
82 assertFalse(pipe.hasNext());
83
84 assertEquals(addedPort.getProperty("number"), portNumber);
85 }
86
Jonathan Hartd1c5a1c2013-01-23 00:56:14 -080087 @Ignore @Test
Jonathan Hart627f10c2013-01-16 14:20:03 -080088 public void testGetPorts() {
89 fail("Not yet implemented");
90 }
91
Jonathan Hartd1c5a1c2013-01-23 00:56:14 -080092 @Ignore @Test
Jonathan Hart627f10c2013-01-16 14:20:03 -080093 public void testGetPortStringShort() {
94 fail("Not yet implemented");
95 }
96
Jonathan Hartd1c5a1c2013-01-23 00:56:14 -080097 @Ignore @Test
Jonathan Hart627f10c2013-01-16 14:20:03 -080098 public void testGetPortStringString() {
99 fail("Not yet implemented");
100 }
101
102 @Test
103 public void testAddSwitch() {
104 String dpid = "00:00:00:00:00:00:0a:07";
105
106 switchStorage.addSwitch(dpid);
107
108 Iterator<Vertex> it = titanGraph.getVertices("dpid", dpid).iterator();
109 assertTrue(it.hasNext());
110 Vertex addedSwitch = it.next();
111 assertFalse(it.hasNext());
112
113 assertEquals(addedSwitch.getProperty("type"), "switch");
114 assertEquals(addedSwitch.getProperty("dpid"), dpid);
115 assertEquals(addedSwitch.getProperty("state"), SwitchState.ACTIVE.toString());
116 }
117
118
Jonathan Hart627f10c2013-01-16 14:20:03 -0800119 @Test
120 public void testDeleteSwitch() {
121 String dpid = "00:00:00:00:00:00:0a:01";
122
123 switchStorage.deleteSwitch(dpid);
124
125 Iterator<Vertex> it = titanGraph.getVertices("dpid", dpid).iterator();
126 assertFalse(it.hasNext());
127 }
128
Jonathan Hart627f10c2013-01-16 14:20:03 -0800129 @Test
130 public void testDeletePortByPortNum() {
131 //FIXME fails because query for the port is wrong in SwitchStorageImpl
132
133 String dpid = "00:00:00:00:00:00:0a:01";
134 short portNum = 3;
135
136 switchStorage.deletePort(dpid, portNum);
137
138 Vertex sw = titanGraph.getVertices("dpid", dpid).iterator().next();
139
Jonathan Hartd1c5a1c2013-01-23 00:56:14 -0800140 /*
Jonathan Hart627f10c2013-01-16 14:20:03 -0800141 Iterator<Vertex> it = sw.getVertices(Direction.OUT, "on").iterator();
142
143 while (it.hasNext()){
144 System.out.println(it.next());
145 }
Jonathan Hartd1c5a1c2013-01-23 00:56:14 -0800146 */
Jonathan Hart627f10c2013-01-16 14:20:03 -0800147
148 GremlinPipeline<Vertex, Vertex> pipe = new GremlinPipeline<Vertex, Vertex>();
Jonathan Hartd1c5a1c2013-01-23 00:56:14 -0800149 pipe.start(sw).out("on").has("number", portNum);
Jonathan Hart627f10c2013-01-16 14:20:03 -0800150 assertFalse(pipe.hasNext());
151 }
152
Jonathan Hartd1c5a1c2013-01-23 00:56:14 -0800153 @Ignore @Test
Jonathan Hart627f10c2013-01-16 14:20:03 -0800154 public void testDeletePortStringString() {
155 fail("Not yet implemented");
156 }
157
Jonathan Hartd1c5a1c2013-01-23 00:56:14 -0800158 @Ignore @Test
Jonathan Hart627f10c2013-01-16 14:20:03 -0800159 public void testGetActiveSwitches() {
160 fail("Not yet implemented");
161 }
Pavlin Radoslavov5185fac2013-01-29 16:40:10 -0800162
163 static class MyLoopFunction implements PipeFunction<LoopBundle<Vertex>, Boolean> {
164 String dpid;
165 public MyLoopFunction(String dpid) {
166 super();
167 this.dpid = dpid;
168 }
169 public Boolean compute(LoopBundle<Vertex> bundle) {
170 Boolean output = false;
171 if ((bundle.getObject().getProperty("dpid") != dpid) &&
172 (bundle.getLoops() < 10)) {
173 output = true;
174 }
175 return output;
176 }
177 }
178
179 @Test
180 public void testShortestPath() {
181 String dpid_src = "00:00:00:00:00:00:0a:01";
182 String dpid_dest = "00:00:00:00:00:00:0a:06";
183
184 //
185 // Implement the Shortest Path between two vertices by using
186 // the following Gremlin code:
187 // results = []; v_src.as('x').out.out.in.has("type", "switch").dedup().loop('x'){it.object.dpid != v_dest.dpid & it.loops < 10}.path().fill(results)
188 //
189
190 String gremlin = "v_src.as(\"x\").out.out.in.has(\"type\", \"switch\").dedup().loop(\"x\"){it.object.dpid != v_dest.dpid & it.loops < 10}.path().fill(results)";
191
192 // Get the source vertex
193 Iterator<Vertex> iter = titanGraph.getVertices("dpid", dpid_src).iterator();
194 if (! iter.hasNext())
195 return; // Source vertex not found
196 Vertex v_src = iter.next();
197
198 // Get the destination vertex
199 iter = titanGraph.getVertices("dpid", dpid_dest).iterator();
200 if (! iter.hasNext())
201 return; // Destination vertex not found
202 Vertex v_dest = iter.next();
203
204 //
205 // Implement the Gremlin script and run it
206 //
207 ScriptEngine engine = new GremlinGroovyScriptEngine();
208
209 ArrayList<ArrayList<Vertex>> results = new ArrayList<ArrayList<Vertex>>();
210 engine.getBindings(ScriptContext.ENGINE_SCOPE).put("g", titanGraph);
211 engine.getBindings(ScriptContext.ENGINE_SCOPE).put("v_src", v_src);
212 engine.getBindings(ScriptContext.ENGINE_SCOPE).put("v_dest", v_dest);
213 engine.getBindings(ScriptContext.ENGINE_SCOPE).put("results", results);
214
215 try {
216 engine.eval(gremlin);
217 } catch (ScriptException e) {
218 System.err.println("Caught ScriptException running Gremlin script: " + e.getMessage());
219 return;
220 }
221
222 //
223 // Extract the result and compose it into a string
224 //
225 String results_str = "";
226 // System.out.println("BEGIN " + results.size());
227 for (ArrayList<Vertex> lv : results) {
228 // System.out.println(lv);
229 for (Vertex v: lv) {
230 // System.out.println(v);
231 String type = v.getProperty("type").toString();
232 results_str += "[type: " + type;
233 // System.out.println("type: " + type);
234 if (type.equals("port")) {
235 String number = v.getProperty("number").toString();
236 // System.out.println("number: " + number);
237 results_str += " number: " + number + "]";
238 }
239 if (type.equals("switch")) {
240 String dpid = v.getProperty("dpid").toString();
241 // System.out.println("dpid: " + dpid);
242 results_str += " dpid: " + dpid + "]";
243 }
244 }
245 }
246 // System.out.println("END\n");
247 System.out.println(results_str);
248
249 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]";
250
251
252 // Pipe<Vertex, Vertex> pipe = Gremlin.compile(gremlin);
253 // pipe.setStarts(new SingleIterator<Vertex>(v1));
254
255 //
256 // XXX: An alternative (faster?) solution that fails to compile
257 //
258 MyLoopFunction whileFunction = new MyLoopFunction(dpid_dest);
259 GremlinPipeline<Vertex, Vertex> pipe = new GremlinPipeline<Vertex, Vertex>();
260 // pipe.start(v_src).as("x").out().out().in().has("type", "switch").dedup().loop("x", whileFunction);
261
262 // Check the result
263 assertEquals(results_str, expected_result);
264 }
Jonathan Hart627f10c2013-01-16 14:20:03 -0800265}