blob: ebfb53228faf16ad96100d1a17396bdfb2def58b [file] [log] [blame]
HIGUCHI Yuta08137932013-06-17 14:11:50 -07001package net.onrc.onos.ofcontroller.core.internal;
Jonathan Hart627f10c2013-01-16 14:20:03 -08002
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 Radoslavov6e849c62013-03-19 22:56:30 -07008import java.util.Collection;
9import java.util.List;
Pavlin Radoslavov5185fac2013-01-29 16:40:10 -080010import java.util.ArrayList;
Jonathan Hart627f10c2013-01-16 14:20:03 -080011import java.util.Iterator;
12
HIGUCHI Yuta20514902013-06-12 11:24:16 -070013import net.onrc.onos.ofcontroller.core.ISwitchStorage;
14import net.onrc.onos.ofcontroller.core.ISwitchStorage.SwitchState;
Jonathan Hart627f10c2013-01-16 14:20:03 -080015
16import org.junit.After;
17import org.junit.Before;
Jonathan Hartd1c5a1c2013-01-23 00:56:14 -080018import org.junit.Ignore;
Jonathan Hart627f10c2013-01-16 14:20:03 -080019import org.junit.Test;
20import org.openflow.protocol.OFPhysicalPort;
21
22import com.thinkaurelius.titan.core.TitanGraph;
Jonathan Hart627f10c2013-01-16 14:20:03 -080023import com.tinkerpop.blueprints.Vertex;
24import com.tinkerpop.gremlin.java.GremlinPipeline;
Pavlin Radoslavov5185fac2013-01-29 16:40:10 -080025import com.tinkerpop.pipes.PipeFunction;
Pavlin Radoslavov5185fac2013-01-29 16:40:10 -080026import com.tinkerpop.pipes.branch.LoopPipe.LoopBundle;
Pavlin Radoslavov5185fac2013-01-29 16:40:10 -080027
28import javax.script.ScriptContext;
29import javax.script.ScriptEngine;
30import javax.script.ScriptException;
31import com.tinkerpop.gremlin.groovy.jsr223.GremlinGroovyScriptEngine;
32
Jonathan Hart627f10c2013-01-16 14:20:03 -080033
Jonathan Hartd1c5a1c2013-01-23 00:56:14 -080034public class SwitchStorageImplTest {
Jonathan Hart627f10c2013-01-16 14:20:03 -080035
Jonathan Hartd1c5a1c2013-01-23 00:56:14 -080036 private ISwitchStorage switchStorage;
37 private TitanGraph titanGraph;
Jonathan Hart627f10c2013-01-16 14:20:03 -080038
39 @Before
Jonathan Hartd1c5a1c2013-01-23 00:56:14 -080040 public void setUp() throws Exception {
Jonathan Hart627f10c2013-01-16 14:20:03 -080041 titanGraph = TestDatabaseManager.getTestDatabase();
42 TestDatabaseManager.populateTestData(titanGraph);
43
Pankaj Berde15193092013-03-21 17:30:14 -070044 switchStorage = new TestableSwitchStorageImpl();
Jonathan Hart627f10c2013-01-16 14:20:03 -080045 }
46
47 @After
Jonathan Hartd1c5a1c2013-01-23 00:56:14 -080048 public void tearDown() throws Exception {
49 titanGraph.shutdown();
Jonathan Hart627f10c2013-01-16 14:20:03 -080050 }
51
Jonathan Hartd1c5a1c2013-01-23 00:56:14 -080052 @Ignore @Test
Jonathan Hart627f10c2013-01-16 14:20:03 -080053 public void testUpdate() {
54 fail("Not yet implemented");
55 }
56
57 @Test
58 public void testAddPort() {
59
60 String dpid = "00:00:00:00:00:00:0a:01";
61 short portNumber = 5;
62
63 OFPhysicalPort portToAdd = new OFPhysicalPort();
64 portToAdd.setName("port 5 at SEA switch");
65 portToAdd.setCurrentFeatures(OFPhysicalPort.OFPortFeatures.OFPPF_100MB_FD.getValue());
66 portToAdd.setPortNumber(portNumber);
67
68 switchStorage.addPort(dpid, portToAdd);
69
70 Vertex sw = titanGraph.getVertices("dpid", dpid).iterator().next();
71
72 GremlinPipeline<Vertex, Vertex> pipe = new GremlinPipeline<Vertex, Vertex>();
73 pipe.start(sw).out("on").has("number", portNumber);
74
75 assertTrue(pipe.hasNext());
76 Vertex addedPort = pipe.next();
77 assertFalse(pipe.hasNext());
78
79 assertEquals(addedPort.getProperty("number"), portNumber);
80 }
81
Jonathan Hartd1c5a1c2013-01-23 00:56:14 -080082 @Ignore @Test
Jonathan Hart627f10c2013-01-16 14:20:03 -080083 public void testGetPorts() {
84 fail("Not yet implemented");
85 }
86
Jonathan Hartd1c5a1c2013-01-23 00:56:14 -080087 @Ignore @Test
Jonathan Hart627f10c2013-01-16 14:20:03 -080088 public void testGetPortStringShort() {
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 testGetPortStringString() {
94 fail("Not yet implemented");
95 }
96
97 @Test
98 public void testAddSwitch() {
99 String dpid = "00:00:00:00:00:00:0a:07";
100
101 switchStorage.addSwitch(dpid);
102
103 Iterator<Vertex> it = titanGraph.getVertices("dpid", dpid).iterator();
104 assertTrue(it.hasNext());
105 Vertex addedSwitch = it.next();
106 assertFalse(it.hasNext());
107
108 assertEquals(addedSwitch.getProperty("type"), "switch");
109 assertEquals(addedSwitch.getProperty("dpid"), dpid);
110 assertEquals(addedSwitch.getProperty("state"), SwitchState.ACTIVE.toString());
111 }
112
113
Jonathan Hart627f10c2013-01-16 14:20:03 -0800114 @Test
115 public void testDeleteSwitch() {
116 String dpid = "00:00:00:00:00:00:0a:01";
117
118 switchStorage.deleteSwitch(dpid);
119
120 Iterator<Vertex> it = titanGraph.getVertices("dpid", dpid).iterator();
121 assertFalse(it.hasNext());
122 }
123
Jonathan Hart627f10c2013-01-16 14:20:03 -0800124 @Test
125 public void testDeletePortByPortNum() {
126 //FIXME fails because query for the port is wrong in SwitchStorageImpl
127
128 String dpid = "00:00:00:00:00:00:0a:01";
129 short portNum = 3;
130
131 switchStorage.deletePort(dpid, portNum);
132
133 Vertex sw = titanGraph.getVertices("dpid", dpid).iterator().next();
134
Jonathan Hartd1c5a1c2013-01-23 00:56:14 -0800135 /*
Jonathan Hart627f10c2013-01-16 14:20:03 -0800136 Iterator<Vertex> it = sw.getVertices(Direction.OUT, "on").iterator();
137
138 while (it.hasNext()){
139 System.out.println(it.next());
140 }
Jonathan Hartd1c5a1c2013-01-23 00:56:14 -0800141 */
Jonathan Hart627f10c2013-01-16 14:20:03 -0800142
143 GremlinPipeline<Vertex, Vertex> pipe = new GremlinPipeline<Vertex, Vertex>();
Jonathan Hartd1c5a1c2013-01-23 00:56:14 -0800144 pipe.start(sw).out("on").has("number", portNum);
Jonathan Hart627f10c2013-01-16 14:20:03 -0800145 assertFalse(pipe.hasNext());
146 }
147
Jonathan Hartd1c5a1c2013-01-23 00:56:14 -0800148 @Ignore @Test
Jonathan Hart627f10c2013-01-16 14:20:03 -0800149 public void testDeletePortStringString() {
150 fail("Not yet implemented");
151 }
152
Jonathan Hartd1c5a1c2013-01-23 00:56:14 -0800153 @Ignore @Test
Jonathan Hart627f10c2013-01-16 14:20:03 -0800154 public void testGetActiveSwitches() {
155 fail("Not yet implemented");
156 }
Pavlin Radoslavov5185fac2013-01-29 16:40:10 -0800157
158 static class MyLoopFunction implements PipeFunction<LoopBundle<Vertex>, Boolean> {
159 String dpid;
160 public MyLoopFunction(String dpid) {
161 super();
162 this.dpid = dpid;
163 }
164 public Boolean compute(LoopBundle<Vertex> bundle) {
165 Boolean output = false;
Pavlin Radoslavov6e849c62013-03-19 22:56:30 -0700166 if (! bundle.getObject().getProperty("dpid").equals(dpid)) {
Pavlin Radoslavov5185fac2013-01-29 16:40:10 -0800167 output = true;
168 }
169 return output;
170 }
171 }
172
173 @Test
174 public void testShortestPath() {
175 String dpid_src = "00:00:00:00:00:00:0a:01";
176 String dpid_dest = "00:00:00:00:00:00:0a:06";
177
178 //
179 // Implement the Shortest Path between two vertices by using
Pavlin Radoslavov544d3132013-02-13 10:16:52 -0800180 // the following Gremlin CLI code:
181 // 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}
182 // The equivalent code used here is:
183 // results = []; v_src.as("x").out("on").out("link").in("on").dedup().loop("x"){it.object.dpid != v_dest.dpid}.path().fill(results)
Pavlin Radoslavov5185fac2013-01-29 16:40:10 -0800184 //
185
Pavlin Radoslavov5185fac2013-01-29 16:40:10 -0800186 // Get the source vertex
187 Iterator<Vertex> iter = titanGraph.getVertices("dpid", dpid_src).iterator();
188 if (! iter.hasNext())
189 return; // Source vertex not found
190 Vertex v_src = iter.next();
191
192 // Get the destination vertex
193 iter = titanGraph.getVertices("dpid", dpid_dest).iterator();
194 if (! iter.hasNext())
195 return; // Destination vertex not found
196 Vertex v_dest = iter.next();
Pavlin Radoslavov6e849c62013-03-19 22:56:30 -0700197
Pavlin Radoslavov5185fac2013-01-29 16:40:10 -0800198 //
199 // Implement the Gremlin script and run it
200 //
Pavlin Radoslavov6e849c62013-03-19 22:56:30 -0700201 // NOTE: This mechanism is slower. The code is kept here
202 // for future reference.
203 //
204 /*
205 String gremlin = "v_src.as(\"x\").out(\"on\").out(\"link\").in(\"on\").dedup().loop(\"x\"){it.object.dpid != v_dest.dpid}.path().fill(results)";
Pavlin Radoslavov5185fac2013-01-29 16:40:10 -0800206
Pavlin Radoslavov6e849c62013-03-19 22:56:30 -0700207 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)";
208
209 ScriptEngine engine = new GremlinGroovyScriptEngine();
Pavlin Radoslavov5185fac2013-01-29 16:40:10 -0800210 ArrayList<ArrayList<Vertex>> results = new ArrayList<ArrayList<Vertex>>();
211 engine.getBindings(ScriptContext.ENGINE_SCOPE).put("g", titanGraph);
212 engine.getBindings(ScriptContext.ENGINE_SCOPE).put("v_src", v_src);
213 engine.getBindings(ScriptContext.ENGINE_SCOPE).put("v_dest", v_dest);
214 engine.getBindings(ScriptContext.ENGINE_SCOPE).put("results", results);
215
216 try {
217 engine.eval(gremlin);
218 } catch (ScriptException e) {
219 System.err.println("Caught ScriptException running Gremlin script: " + e.getMessage());
220 return;
221 }
222
Pavlin Radoslavov6e849c62013-03-19 22:56:30 -0700223 for (ArrayList<Vertex> lv : results) {
224 ...
225 }
226 */
227
228 MyLoopFunction whileFunction = new MyLoopFunction(dpid_dest);
229 GremlinPipeline<Vertex, Vertex> pipe = new GremlinPipeline<Vertex, Vertex>();
230 Collection<List> results = new ArrayList<List>();
231 GremlinPipeline<Vertex, List> path;
232 path = pipe.start(v_src).as("x").out("on").out("link").in("on").dedup().loop("x", whileFunction).path();
233 path.fill(results);
234
Pavlin Radoslavov5185fac2013-01-29 16:40:10 -0800235 //
236 // Extract the result and compose it into a string
237 //
238 String results_str = "";
239 // System.out.println("BEGIN " + results.size());
Pavlin Radoslavov6e849c62013-03-19 22:56:30 -0700240 for (List l : results) {
241 for (Object o: l) {
242 Vertex v = (Vertex)(o);
Pavlin Radoslavov5185fac2013-01-29 16:40:10 -0800243 // System.out.println(v);
244 String type = v.getProperty("type").toString();
245 results_str += "[type: " + type;
246 // System.out.println("type: " + type);
247 if (type.equals("port")) {
248 String number = v.getProperty("number").toString();
249 // System.out.println("number: " + number);
250 results_str += " number: " + number + "]";
251 }
252 if (type.equals("switch")) {
253 String dpid = v.getProperty("dpid").toString();
254 // System.out.println("dpid: " + dpid);
255 results_str += " dpid: " + dpid + "]";
256 }
257 }
258 }
259 // System.out.println("END\n");
260 System.out.println(results_str);
Pavlin Radoslavov6e849c62013-03-19 22:56:30 -0700261
262 //
263 // Check the result
264 //
Pavlin Radoslavov5185fac2013-01-29 16:40:10 -0800265 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]";
266
Pavlin Radoslavov5185fac2013-01-29 16:40:10 -0800267 assertEquals(results_str, expected_result);
Pavlin Radoslavov544d3132013-02-13 10:16:52 -0800268
269 //
270 // Test Shortest-Path computation to non-existing destination
271 //
272 results.clear();
Pavlin Radoslavov6e849c62013-03-19 22:56:30 -0700273 MyLoopFunction noDestWhileFunction = new MyLoopFunction("NO-SUCH-DPID");
274 path = pipe.start(v_src).as("x").out("on").out("link").in("on").dedup().loop("x", noDestWhileFunction).path();
275 path.fill(results);
Pavlin Radoslavov544d3132013-02-13 10:16:52 -0800276 assertTrue(results.size() == 0);
Pavlin Radoslavov5185fac2013-01-29 16:40:10 -0800277 }
Jonathan Hart627f10c2013-01-16 14:20:03 -0800278}