blob: ba01f3a54e41e2303d4da2c64e2d718389692c33 [file] [log] [blame]
Jonathan Hartb7e3d2c2013-01-15 18:45:19 -08001package net.floodlightcontroller.linkdiscovery.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;
6
mininet403d5892013-06-05 03:48:17 -07007import java.util.ArrayList;
Naoki Shiota0dae8332013-06-13 08:44:30 -07008import java.util.HashMap;
Jonathan Hartb7e3d2c2013-01-15 18:45:19 -08009import java.util.Iterator;
Jonathan Hartc86a2ea2013-01-15 22:39:42 -080010import java.util.List;
Naoki Shiota0dae8332013-06-13 08:44:30 -070011import java.util.Map;
Jonathan Hartb7e3d2c2013-01-15 18:45:19 -080012
mininet403d5892013-06-05 03:48:17 -070013import net.floodlightcontroller.linkdiscovery.LinkInfo;
Jonathan Hartb7e3d2c2013-01-15 18:45:19 -080014import net.floodlightcontroller.routing.Link;
HIGUCHI Yuta20514902013-06-12 11:24:16 -070015import net.onrc.onos.ofcontroller.core.INetMapStorage.DM_OPERATION;
Naoki Shiota0dae8332013-06-13 08:44:30 -070016import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IPortObject;
HIGUCHI Yuta80c3ab82013-06-12 13:17:05 -070017import net.onrc.onos.ofcontroller.linkdiscovery.ILinkStorage;
Naoki Shiota0dae8332013-06-13 08:44:30 -070018import net.onrc.onos.util.GraphDBConnection;
19import net.onrc.onos.util.GraphDBOperation;
Jonathan Hartb7e3d2c2013-01-15 18:45:19 -080020
Naoki Shiota0dae8332013-06-13 08:44:30 -070021import org.easymock.*;
Jonathan Hartb7e3d2c2013-01-15 18:45:19 -080022import org.junit.After;
23import org.junit.Before;
Jonathan Hartd1c5a1c2013-01-23 00:56:14 -080024import org.junit.Ignore;
Jonathan Hartb7e3d2c2013-01-15 18:45:19 -080025import org.junit.Test;
mininet37dc5892013-06-04 10:58:44 -070026import org.junit.runner.RunWith;
Naoki Shiotacae568a2013-06-05 17:53:41 -070027import org.openflow.protocol.OFPhysicalPort;
mininet403d5892013-06-05 03:48:17 -070028import org.openflow.util.HexString;
mininet37dc5892013-06-04 10:58:44 -070029import org.powermock.api.easymock.PowerMock;
30import org.powermock.core.classloader.annotations.PrepareForTest;
31import org.powermock.modules.junit4.PowerMockRunner;
Naoki Shiota0dae8332013-06-13 08:44:30 -070032import org.slf4j.Logger;
33import org.slf4j.LoggerFactory;
Jonathan Hartb7e3d2c2013-01-15 18:45:19 -080034
mininet37dc5892013-06-04 10:58:44 -070035@RunWith(PowerMockRunner.class)
Naoki Shiota0dae8332013-06-13 08:44:30 -070036@PrepareForTest({LinkStorageImpl.class, GraphDBConnection.class, GraphDBOperation.class})
Jonathan Hartd1c5a1c2013-01-23 00:56:14 -080037public class LinkStorageImplTest {
Naoki Shiota0dae8332013-06-13 08:44:30 -070038 protected static Logger log = LoggerFactory.getLogger(LinkStorageImplTest.class);
39
Jonathan Hartb7e3d2c2013-01-15 18:45:19 -080040 private static ILinkStorage linkStorage;
Jonathan Hartb7e3d2c2013-01-15 18:45:19 -080041
Naoki Shiota0dae8332013-06-13 08:44:30 -070042 // Mock GraphDBConnection (do nothing)
43 private static GraphDBConnection conn;
44
45 // Mock GraphDBOperation (mocks port-related methods only)
46 private static GraphDBOperation ope;
47
48 // Uncommitted actions executed in LinkStorageImpl
49 private static ArrayList<LinkEvent> actions;
50
51 // Dictionary of mock IPortObject to information of port
52 // -> Used to refer DPID from IPortObject
53 private static Map<Object,PortInfo> mockToPortInfoMap;
54
55 // Links existing in virtual graph
56 private List<Link> links;
57
58
59 //================ Utility classes for logging actions in LinkStorageImpl ===========
60 // Not used for now
61 private enum LinkEventType {
62 ADD("ADD", 1),
63 DELETE("DELETE", 2);
64
65 private String name;
66 private int number;
67
68 LinkEventType(String name, int number) {
69 this.name = name;
70 this.number = number;
71 }
72 public String getName() { return name; }
73 public int getNumber() { return number; }
74 }
75
76 private class LinkEvent {
77 private Long src_dpid = null;
78 private Long dst_dpid = null;
79 private Short src_port = null;
80 private Short dst_port = null;
81
82 public LinkEventType type;
83
84 public LinkEvent(Link link, LinkEventType type) {
85 this.src_dpid = link.getSrc();
86 this.src_port = link.getSrcPort();
87 this.dst_dpid = link.getDst();
88 this.dst_port = link.getDstPort();
89
90 this.type = type;
91 }
92
93 public LinkEvent(Long src_dpid, Short src_port, Long dst_dpid, Short dst_port, LinkEventType type) {
94 this.src_dpid = src_dpid;
95 this.src_port = src_port;
96 this.dst_dpid = dst_dpid;
97 this.dst_port = dst_port;
98
99 this.type = type;
100 }
101
102 public Long getSrcDpid() { return src_dpid; }
103 public Short getSrcPort() { return src_port; }
104 public Long getDstDpid() { return dst_dpid; }
105 public Short getDstPort() { return dst_port; }
106 public LinkEventType getType() { return type; }
107 }
108
109 private class PortInfo {
110 public Long dpid = null;
111 public Short port = null;
112
113 public PortInfo(Long dpid, Short port) { this.dpid = dpid; this.port = port; }
114 }
mininet37dc5892013-06-04 10:58:44 -0700115
mininet9d203de2013-06-05 08:40:45 -0700116 /**
117 * Setup code called before each tests.
118 * Read test graph data and replace DB access by test graph data.
119 * @throws Exception
120 */
Jonathan Hartb7e3d2c2013-01-15 18:45:19 -0800121 @Before
Jonathan Hart627f10c2013-01-16 14:20:03 -0800122 public void setUp() throws Exception{
Naoki Shiota0dae8332013-06-13 08:44:30 -0700123 PowerMock.mockStatic(GraphDBConnection.class);
124 PowerMock.suppress(PowerMock.constructor(GraphDBConnection.class));
125 conn = PowerMock.createNiceMock(GraphDBConnection.class);
126 EasyMock.expect(GraphDBConnection.getInstance((String)EasyMock.anyObject())).andReturn(conn).anyTimes();
127 PowerMock.replay(GraphDBConnection.class);
128
129 ope = createMockGraphDBOperation();
130 PowerMock.expectNew(GraphDBOperation.class, (GraphDBConnection)EasyMock.anyObject()).andReturn(ope).anyTimes();
131 PowerMock.replay(GraphDBOperation.class);
132
133 actions = new ArrayList<LinkEvent>();
134 mockToPortInfoMap = new HashMap<Object,PortInfo>();
Jonathan Hartb7e3d2c2013-01-15 18:45:19 -0800135
mininet403d5892013-06-05 03:48:17 -0700136 linkStorage = new LinkStorageImpl();
Naoki Shiota0dae8332013-06-13 08:44:30 -0700137 linkStorage.init("/dummy/path/to/conf");
mininet403d5892013-06-05 03:48:17 -0700138
Naoki Shiota0dae8332013-06-13 08:44:30 -0700139 initLinks();
Jonathan Hartb7e3d2c2013-01-15 18:45:19 -0800140 }
141
mininet9d203de2013-06-05 08:40:45 -0700142 /**
143 * Closing code called after each tests.
144 * Discard test graph data.
145 * @throws Exception
146 */
Jonathan Hartd1c5a1c2013-01-23 00:56:14 -0800147 @After
mininet403d5892013-06-05 03:48:17 -0700148 public void tearDown() throws Exception {
149 // finish code
150 linkStorage.close();
Jonathan Hartb7e3d2c2013-01-15 18:45:19 -0800151 }
152
Naoki Shiotacae568a2013-06-05 17:53:41 -0700153 // TODO: remove @Ignore after UPDATE method is implemented
Naoki Shiota1b972862013-06-05 19:49:09 -0700154 /**
155 * Test if update() can correctly updates LinkInfo for a Link.
156 */
mininet403d5892013-06-05 03:48:17 -0700157 @Ignore @Test
158 public void testUpdate_UpdateSingleLink() {
159 Link linkToUpdate= createExistingLink();
Naoki Shiotacae568a2013-06-05 17:53:41 -0700160 long currentTime = System.currentTimeMillis();
161 LinkInfo infoToUpdate = createFeasibleLinkInfo(currentTime);
162 LinkInfo infoToVerify = createFeasibleLinkInfo(currentTime);
mininet403d5892013-06-05 03:48:17 -0700163
164 linkStorage.update(linkToUpdate, infoToUpdate, ILinkStorage.DM_OPERATION.UPDATE);
165
Naoki Shiotacae568a2013-06-05 17:53:41 -0700166 doTestLinkHasStateOf(linkToUpdate, infoToVerify);
mininet403d5892013-06-05 03:48:17 -0700167 }
168
Naoki Shiota1b972862013-06-05 19:49:09 -0700169 /**
170 * Test if update() can correctly creates a Link.
171 */
mininet403d5892013-06-05 03:48:17 -0700172 @Test
173 public void testUpdate_CreateSingleLink() {
174 Link linkToCreate = createFeasibleLink();
175 Link linkToVerify = createFeasibleLink();
176
177 //Use the link storage API to add the link
178 linkStorage.update(linkToCreate, ILinkStorage.DM_OPERATION.CREATE);
179 doTestLinkIsInGraph(linkToVerify);
180
Naoki Shiota0dae8332013-06-13 08:44:30 -0700181 // Avoiding duplication is out of scope. DBOperation is responsible for this.
182// // Add same link
183// Link linkToCreateTwice = createFeasibleLink();
184// linkStorage.update(linkToCreateTwice, ILinkStorage.DM_OPERATION.CREATE);
185//
186// // this occurs assertion failure if there are two links in titanGraph
187// doTestLinkIsInGraph(linkToVerify);
mininet403d5892013-06-05 03:48:17 -0700188 }
189
Naoki Shiota1b972862013-06-05 19:49:09 -0700190 /**
191 * Test if update() can correctly inserts a Link.
192 */
Jonathan Hartb7e3d2c2013-01-15 18:45:19 -0800193 @Test
mininet403d5892013-06-05 03:48:17 -0700194 public void testUpdate_InsertSingleLink(){
195 Link linkToInsert = createFeasibleLink();
196 Link linkToVerify = createFeasibleLink();
Jonathan Hartb7e3d2c2013-01-15 18:45:19 -0800197
198 //Use the link storage API to add the link
mininet403d5892013-06-05 03:48:17 -0700199 linkStorage.update(linkToInsert, ILinkStorage.DM_OPERATION.INSERT);
mininet403d5892013-06-05 03:48:17 -0700200 doTestLinkIsInGraph(linkToVerify);
Jonathan Hartb7e3d2c2013-01-15 18:45:19 -0800201 }
202
Naoki Shiota1b972862013-06-05 19:49:09 -0700203 /**
204 * Test if update() can correctly deletes a Link.
205 */
mininet403d5892013-06-05 03:48:17 -0700206 @Test
207 public void testUpdate_DeleteSingleLink(){
208 Link linkToDelete = createExistingLink();
209 Link linkToVerify = createExistingLink();
210
211 // Test deletion of existing link
212 linkStorage.update(linkToDelete, DM_OPERATION.DELETE);
213 doTestLinkIsNotInGraph(linkToVerify);
mininet403d5892013-06-05 03:48:17 -0700214 }
Naoki Shiota1b972862013-06-05 19:49:09 -0700215
216 /**
217 * Test if update() can correctly creates multiple Links.
218 */
mininet403d5892013-06-05 03:48:17 -0700219 @Test
220 public void testUpdate_CreateLinks(){
221 List<Link> linksToCreate = createFeasibleLinks();
222 List<Link> linksToVerify = createFeasibleLinks();
223
224 // Test creation of new links
225 linkStorage.update(linksToCreate, ILinkStorage.DM_OPERATION.CREATE);
226 for(Link l : linksToVerify) {
227 doTestLinkIsInGraph(l);
228 }
Naoki Shiota0dae8332013-06-13 08:44:30 -0700229
230 // Out of scope: DBOperation is responsible for avoiding duplication.
231// // Test creation of existing links
232// linksToCreate = createFeasibleLinks();
233// linkStorage.update(linksToCreate, ILinkStorage.DM_OPERATION.CREATE);
234// for(Link l : linksToVerify) {
235// doTestLinkIsInGraph(l);
236// }
mininet403d5892013-06-05 03:48:17 -0700237 }
238
Naoki Shiota1b972862013-06-05 19:49:09 -0700239 /**
240 * Test if update() can handle mixture of normal/abnormal input for creation of Links.
Naoki Shiota0dae8332013-06-13 08:44:30 -0700241 * Deprecated: DBOperation is responsible.
Naoki Shiota1b972862013-06-05 19:49:09 -0700242 */
Naoki Shiota0dae8332013-06-13 08:44:30 -0700243 @Ignore @Test
mininet9d203de2013-06-05 08:40:45 -0700244 public void testUpdate_CreateLinks_Mixuture(){
mininet403d5892013-06-05 03:48:17 -0700245 List<Link> linksToCreate = new ArrayList<Link>();
246 linksToCreate.add(createFeasibleLink());
247 linksToCreate.add(createExistingLink());
248
249 // Test creation of mixture of new/existing links
250 linkStorage.update(linksToCreate, ILinkStorage.DM_OPERATION.CREATE);
251 doTestLinkIsInGraph(createFeasibleLink());
252 doTestLinkIsInGraph(createExistingLink());
253 }
254
Naoki Shiota1b972862013-06-05 19:49:09 -0700255 /**
256 * Test if update() can correctly inserts multiple Links.
257 */
mininet403d5892013-06-05 03:48:17 -0700258 @Test
259 public void testUpdate_InsertLinks(){
260 List<Link> linksToInsert = createFeasibleLinks();
261 List<Link> linksToVerify = createFeasibleLinks();
262
263 // Test insertion of new links
264 linkStorage.update(linksToInsert, ILinkStorage.DM_OPERATION.INSERT);
265 for(Link l : linksToVerify) {
266 doTestLinkIsInGraph(l);
267 }
mininet403d5892013-06-05 03:48:17 -0700268 }
269
Naoki Shiota1b972862013-06-05 19:49:09 -0700270 /**
271 * Test if update() can handle mixture of normal/abnormal input for creation of Links.
272 */
Naoki Shiota0dae8332013-06-13 08:44:30 -0700273 @Ignore @Test
mininet9d203de2013-06-05 08:40:45 -0700274 public void testUpdate_InsertLinks_Mixuture(){
mininet403d5892013-06-05 03:48:17 -0700275 List<Link> linksToInsert = new ArrayList<Link>();
276 linksToInsert.add(createFeasibleLink());
277 linksToInsert.add(createExistingLink());
278
279 // Test insertion of mixture of new/existing links
280 linkStorage.update(linksToInsert, ILinkStorage.DM_OPERATION.INSERT);
281 doTestLinkIsInGraph(createFeasibleLink());
282 doTestLinkIsInGraph(createExistingLink());
283 }
284
Naoki Shiota1b972862013-06-05 19:49:09 -0700285 /**
286 * Test if update() can correctly deletes multiple Links.
287 */
mininet403d5892013-06-05 03:48:17 -0700288 @Test
289 public void testUpdate_DeleteLinks(){
290 List<Link> linksToDelete = createExistingLinks();
291 List<Link> linksToVerify = createExistingLinks();
292
293 // Test deletion of existing links
294 linkStorage.update(linksToDelete, ILinkStorage.DM_OPERATION.DELETE);
295 for(Link l : linksToVerify) {
296 doTestLinkIsNotInGraph(l);
297 }
mininet403d5892013-06-05 03:48:17 -0700298 }
299
Naoki Shiota1b972862013-06-05 19:49:09 -0700300 /**
301 * Test if update() can handle mixture of normal/abnormal input for deletion of Links.
302 */
Naoki Shiota0dae8332013-06-13 08:44:30 -0700303 @Ignore @Test
mininet9d203de2013-06-05 08:40:45 -0700304 public void testUpdate_DeleteLinks_Mixuture(){
mininet403d5892013-06-05 03:48:17 -0700305 List<Link> linksToDelete = new ArrayList<Link>();
306 linksToDelete.add(createFeasibleLink());
307 linksToDelete.add(createExistingLink());
308
309 // Test deletion of mixture of new/existing links
310 linkStorage.update(linksToDelete, ILinkStorage.DM_OPERATION.DELETE);
311 doTestLinkIsNotInGraph(createFeasibleLink());
312 doTestLinkIsNotInGraph(createExistingLink());
313 }
314
Naoki Shiotacae568a2013-06-05 17:53:41 -0700315 // TODO: remove @Ignore after UPDATE method is implemented
Naoki Shiota1b972862013-06-05 19:49:09 -0700316 /**
317 * Test if updateLink() can correctly updates LinkInfo for a Link.
318 */
mininet9d203de2013-06-05 08:40:45 -0700319 @Ignore @Test
Naoki Shiota1b972862013-06-05 19:49:09 -0700320 public void testUpdateLink_Update() {
mininet9d203de2013-06-05 08:40:45 -0700321 Link linkToUpdate= createExistingLink();
Naoki Shiotacae568a2013-06-05 17:53:41 -0700322 long currentTime = System.currentTimeMillis();
323 LinkInfo infoToUpdate = createFeasibleLinkInfo(currentTime);
324 LinkInfo infoToVerify = createFeasibleLinkInfo(currentTime);
mininet9d203de2013-06-05 08:40:45 -0700325
Naoki Shiota1b972862013-06-05 19:49:09 -0700326 linkStorage.updateLink(linkToUpdate, infoToUpdate, ILinkStorage.DM_OPERATION.UPDATE);
mininet9d203de2013-06-05 08:40:45 -0700327
Naoki Shiotacae568a2013-06-05 17:53:41 -0700328 doTestLinkHasStateOf(linkToUpdate, infoToVerify);
mininet403d5892013-06-05 03:48:17 -0700329 }
330
Naoki Shiota1b972862013-06-05 19:49:09 -0700331 /**
332 * Test if updateLink() can correctly creates a Link.
333 */
mininet403d5892013-06-05 03:48:17 -0700334 @Test
Naoki Shiota1b972862013-06-05 19:49:09 -0700335 public void testUpdateLink_Create() {
mininet9d203de2013-06-05 08:40:45 -0700336 Link linkToCreate = createFeasibleLink();
337 Link linkToVerify = createFeasibleLink();
mininet403d5892013-06-05 03:48:17 -0700338
mininet9d203de2013-06-05 08:40:45 -0700339 //Use the link storage API to add the link
Naoki Shiota1b972862013-06-05 19:49:09 -0700340 linkStorage.updateLink(linkToCreate, null, ILinkStorage.DM_OPERATION.CREATE);
mininet9d203de2013-06-05 08:40:45 -0700341 doTestLinkIsInGraph(linkToVerify);
mininet403d5892013-06-05 03:48:17 -0700342 }
343
Naoki Shiota1b972862013-06-05 19:49:09 -0700344 /**
345 * Test if updateLink() can correctly inserts a Link.
346 */
mininet403d5892013-06-05 03:48:17 -0700347 @Test
Naoki Shiota1b972862013-06-05 19:49:09 -0700348 public void testUpdateLink_Insert() {
mininet9d203de2013-06-05 08:40:45 -0700349 Link linkToInsert = createFeasibleLink();
350 Link linkToVerify = createFeasibleLink();
mininet403d5892013-06-05 03:48:17 -0700351
mininet9d203de2013-06-05 08:40:45 -0700352 //Use the link storage API to add the link
Naoki Shiota1b972862013-06-05 19:49:09 -0700353 linkStorage.updateLink(linkToInsert, null, ILinkStorage.DM_OPERATION.INSERT);
mininet9d203de2013-06-05 08:40:45 -0700354
355 doTestLinkIsInGraph(linkToVerify);
mininet9d203de2013-06-05 08:40:45 -0700356 }
357
358 // TODO: Check if addOrUpdateLink() should accept DELETE operation. If not, remove this test.
Naoki Shiota1b972862013-06-05 19:49:09 -0700359 /**
360 * Test if updateLink() can correctly deletes a Link.
361 */
mininet9d203de2013-06-05 08:40:45 -0700362 @Ignore @Test
Naoki Shiota1b972862013-06-05 19:49:09 -0700363 public void testUpdateLink_Delete() {
mininet9d203de2013-06-05 08:40:45 -0700364 Link linkToDelete = createExistingLink();
365 Link linkToVerify = createExistingLink();
366
367 // Test deletion of existing link
Naoki Shiota1b972862013-06-05 19:49:09 -0700368 linkStorage.updateLink(linkToDelete, null, DM_OPERATION.DELETE);
mininet9d203de2013-06-05 08:40:45 -0700369 doTestLinkIsNotInGraph(linkToVerify);
370
371 linkToDelete = createFeasibleLink();
372 linkToVerify = createFeasibleLink();
373
374 // Test deletion of not-existing link
Naoki Shiota1b972862013-06-05 19:49:09 -0700375 linkStorage.updateLink(linkToDelete, null, DM_OPERATION.DELETE);
mininet9d203de2013-06-05 08:40:45 -0700376 doTestLinkIsNotInGraph(linkToVerify);
377 }
378
Naoki Shiota1b972862013-06-05 19:49:09 -0700379 /**
380 * Test if getLinks() can correctly return Links connected to specific DPID and port.
381 */
mininet9d203de2013-06-05 08:40:45 -0700382 @Test
383 public void testGetLinks_ByDpidPort(){
384 Link linkToVerify = createExistingLink();
385 Long dpid = linkToVerify.getSrc();
386 short port = (short)linkToVerify.getSrcPort();
387
388 List<Link> list = linkStorage.getLinks(dpid, port);
Jonathan Hartb7e3d2c2013-01-15 18:45:19 -0800389
Jonathan Hartc86a2ea2013-01-15 22:39:42 -0800390 assertEquals(list.size(), 1);
391
392 Link l = list.get(0);
mininet403d5892013-06-05 03:48:17 -0700393 assertEquals(l.getSrc(), linkToVerify.getSrc());
394 assertEquals(l.getSrcPort(), linkToVerify.getSrcPort());
395 assertEquals(l.getDst(), linkToVerify.getDst());
396 assertEquals(l.getDstPort(), linkToVerify.getDstPort());
397
398 Link linkToVerifyNot = createFeasibleLink();
399
400 List<Link> list2 = linkStorage.getLinks(linkToVerifyNot.getSrc(), (short)linkToVerifyNot.getSrcPort());
401
402 assertEquals(list2.size(), 0);
Jonathan Hartc86a2ea2013-01-15 22:39:42 -0800403 }
404
Naoki Shiota1b972862013-06-05 19:49:09 -0700405 /**
406 * Test if getLinks() can correctly return Links connected to specific MAC address.
407 */
mininet403d5892013-06-05 03:48:17 -0700408 @Test
mininet9d203de2013-06-05 08:40:45 -0700409 public void testGetLinks_ByString() {
mininet403d5892013-06-05 03:48:17 -0700410 Link linkToVeryfy = createExistingLink();
mininet9d203de2013-06-05 08:40:45 -0700411 String dpid = HexString.toHexString(linkToVeryfy.getSrc());
Jonathan Hartc86a2ea2013-01-15 22:39:42 -0800412
mininet9d203de2013-06-05 08:40:45 -0700413 List<Link> links = linkStorage.getLinks(dpid);
mininet403d5892013-06-05 03:48:17 -0700414 assertTrue(links.contains(linkToVeryfy));
415
416 Link linkToVerifyNot = createFeasibleLink();
417 assertFalse(links.contains(linkToVerifyNot));
Jonathan Hartc86a2ea2013-01-15 22:39:42 -0800418 }
419
Naoki Shiota1b972862013-06-05 19:49:09 -0700420 /**
421 * Test if deleteLink() can correctly delete a Link.
422 */
mininet403d5892013-06-05 03:48:17 -0700423 @Test
424 public void testDeleteLink() {
425 // Deletion of existing link
426 Link linkToDelete = createExistingLink();
427 Link linkToVerify = createExistingLink();
428
429 linkStorage.deleteLink(linkToDelete);
430 doTestLinkIsNotInGraph(linkToVerify);
mininet403d5892013-06-05 03:48:17 -0700431 }
432
Naoki Shiota1b972862013-06-05 19:49:09 -0700433 /**
434 * Test if deleteLinks() can correctly delete Links.
435 */
mininet403d5892013-06-05 03:48:17 -0700436 @Test
Jonathan Hartc86a2ea2013-01-15 22:39:42 -0800437 public void testDeleteLinks(){
mininet403d5892013-06-05 03:48:17 -0700438 List<Link> linksToDelete = createExistingLinks();
439 List<Link> linksToVerify = createExistingLinks();
Jonathan Hartc86a2ea2013-01-15 22:39:42 -0800440
mininet403d5892013-06-05 03:48:17 -0700441 linkStorage.deleteLinks(linksToDelete);
442 for(Link l : linksToVerify) {
443 doTestLinkIsNotInGraph(l);
444 }
445 }
446
Naoki Shiota1b972862013-06-05 19:49:09 -0700447 /**
448 * Test if deleteLinks() can handle mixture of normal/abnormal input.
449 */
Naoki Shiota0dae8332013-06-13 08:44:30 -0700450 @Ignore @Test
mininet9d203de2013-06-05 08:40:45 -0700451 public void testDeleteLinks_Mixture(){
452 List<Link> linksToDelete = new ArrayList<Link>();
453 linksToDelete.add(createFeasibleLink());
454 linksToDelete.add(createExistingLink());
455
456 // Test deletion of mixture of new/existing links
457 linkStorage.deleteLinks(linksToDelete);
458 doTestLinkIsNotInGraph(createFeasibleLink());
459 doTestLinkIsNotInGraph(createExistingLink());
460 }
461
Naoki Shiota1b972862013-06-05 19:49:09 -0700462 /**
463 * Test if getActiveLinks() can correctly return active Links.
464 */
mininet9d203de2013-06-05 08:40:45 -0700465 @Test
mininet403d5892013-06-05 03:48:17 -0700466 public void testGetActiveLinks() {
467 Link existingLink = createExistingLink();
468 Link notExistingLink = createFeasibleLink();
469
470 List<Link> links = linkStorage.getActiveLinks();
Jonathan Hartc86a2ea2013-01-15 22:39:42 -0800471
mininet403d5892013-06-05 03:48:17 -0700472 assertTrue(links.contains(existingLink));
473 assertFalse(links.contains(notExistingLink));
474 }
475
Naoki Shiota1b972862013-06-05 19:49:09 -0700476 /**
477 * Test if deleteLinksOnPort() can delete Links.
478 */
mininet403d5892013-06-05 03:48:17 -0700479 @Test
480 public void testDeleteLinksOnPort() {
481 Link linkToDelete = createExistingLink();
482 Link linkToVerify = createExistingLink();
483
484 linkStorage.deleteLinksOnPort(linkToDelete.getSrc(), linkToDelete.getSrcPort());
485
486 doTestLinkIsNotInGraph(linkToVerify);
487 }
mininet9d203de2013-06-05 08:40:45 -0700488
mininet403d5892013-06-05 03:48:17 -0700489 /**
mininet9d203de2013-06-05 08:40:45 -0700490 * Test if titanGraph has specific link
491 * @param link
mininet403d5892013-06-05 03:48:17 -0700492 */
493 private void doTestLinkIsInGraph(Link link) {
Naoki Shiota0dae8332013-06-13 08:44:30 -0700494 int count = 0;
495 for(Link lt : links) {
496 if(lt.equals(link)) {
497 ++count;
498 }
499 }
mininet403d5892013-06-05 03:48:17 -0700500
Naoki Shiota0dae8332013-06-13 08:44:30 -0700501 assertTrue(count == 1);
Jonathan Hartb7e3d2c2013-01-15 18:45:19 -0800502 }
503
mininet403d5892013-06-05 03:48:17 -0700504 /**
505 * Test if titanGraph doesn't have specific link
506 * @param link
507 */
508 private void doTestLinkIsNotInGraph(Link link) {
Naoki Shiota0dae8332013-06-13 08:44:30 -0700509 assertFalse(links.contains(link));
mininet403d5892013-06-05 03:48:17 -0700510 }
Naoki Shiotacae568a2013-06-05 17:53:41 -0700511
512 /**
513 * Test if titanGraph has specific Link with specific LinkInfo
514 * @param link
515 */
516 private void doTestLinkHasStateOf(Link link, LinkInfo info) {
Naoki Shiota0dae8332013-06-13 08:44:30 -0700517 }
518
519 private class RemoveLinkCallback implements IAnswer<Object> {
520 private long dpid;
521 private short port;
522 public RemoveLinkCallback(long dpid, short port) {
523 this.dpid = dpid; this.port = port;
524 }
Naoki Shiotacae568a2013-06-05 17:53:41 -0700525
Naoki Shiota0dae8332013-06-13 08:44:30 -0700526 @Override
527 public Object answer() throws Throwable {
528 IPortObject dstPort = (IPortObject) EasyMock.getCurrentArguments()[0];
529 PortInfo dst = mockToPortInfoMap.get(dstPort);
Naoki Shiotacae568a2013-06-05 17:53:41 -0700530
Naoki Shiota0dae8332013-06-13 08:44:30 -0700531 Link linkToRemove = new Link(this.dpid,this.port,dst.dpid,dst.port);
532 actions.add(new LinkEvent(linkToRemove,LinkEventType.DELETE));
533
534 return null;
535 }
536 }
537
538 private class SetLinkPortCallback implements IAnswer<Object> {
539 private long dpid;
540 private short port;
541 public SetLinkPortCallback(long dpid, short port) {
542 this.dpid = dpid; this.port = port;
543 }
544
545 @Override
546 public Object answer() throws Throwable {
547 IPortObject dstPort = (IPortObject) EasyMock.getCurrentArguments()[0];
548 PortInfo dst = mockToPortInfoMap.get(dstPort);
549
550 Link linkToAdd = new Link(this.dpid,this.port,dst.dpid,dst.port);
551 actions.add(new LinkEvent(linkToAdd,LinkEventType.ADD));
552
553 return null;
554 }
555
556 }
557
558 // ------------------------Creation of Mock-----------------------------
559 /**
560 * Create mock of GraphDBOperation which hooks port-related methods.
561 * @return
562 */
563 private GraphDBOperation createMockGraphDBOperation() {
564 GraphDBOperation mockDBOpe = EasyMock.createMock(GraphDBOperation.class);
565
566 // Mock searchPort() method to create new mock IPortObject.
567 EasyMock.expect(mockDBOpe.searchPort((String)EasyMock.anyObject(), EasyMock.anyShort())).
568 andAnswer(new IAnswer<IPortObject>() {
569 @Override
570 public IPortObject answer() throws Throwable {
571 long dpid = HexString.toLong((String)EasyMock.getCurrentArguments()[0]);
572 short port = (Short) EasyMock.getCurrentArguments()[1];
Naoki Shiotacae568a2013-06-05 17:53:41 -0700573
Naoki Shiota0dae8332013-06-13 08:44:30 -0700574 IPortObject ret = createMockPort(dpid,port);
575 mockToPortInfoMap.put(ret, new PortInfo(dpid,port));
576
577 return ret;
578 }
579 }).anyTimes();
580
581 // Mock commit() method to remember "COMMIT" event.
582 mockDBOpe.commit();
583 EasyMock.expectLastCall().andAnswer(new IAnswer<Object>() {
584 @Override
585 public Object answer() throws Throwable {
586 for(LinkEvent action : actions) {
587 if(action.getType().equals(LinkEventType.ADD)) {
588 Link linkToAdd = new Link(
589 action.getSrcDpid(),
590 action.getSrcPort(),
591 action.getDstDpid(),
592 action.getDstPort());
593 links.add(linkToAdd);
594 } else if(action.getType().equals(LinkEventType.DELETE)) {
595 Link linkToRemove = new Link(
596 action.getSrcDpid(),
597 action.getSrcPort(),
598 action.getDstDpid(),
599 action.getDstPort());
600 links.remove(linkToRemove);
601 } else {
602 log.error("mock commit(): unexpected action {}", new Object[]{action.getType()});
Naoki Shiotacae568a2013-06-05 17:53:41 -0700603 }
604 }
Naoki Shiota0dae8332013-06-13 08:44:30 -0700605 actions.clear();
Naoki Shiotacae568a2013-06-05 17:53:41 -0700606 return null;
607 }
Naoki Shiota0dae8332013-06-13 08:44:30 -0700608 }).anyTimes();
Naoki Shiotacae568a2013-06-05 17:53:41 -0700609
Naoki Shiota0dae8332013-06-13 08:44:30 -0700610 EasyMock.replay(mockDBOpe);
611 return mockDBOpe;
612 }
613
614 private IPortObject createMockPort(long dpid, short number) {
615 IPortObject mockPort = EasyMock.createMock(IPortObject.class);
616
617 EasyMock.expect(mockPort.getNumber()).andReturn(number);
618
619 // Mock removeLink() method
620 mockPort.removeLink((IPortObject) EasyMock.anyObject());
621 EasyMock.expectLastCall().andAnswer(new RemoveLinkCallback(dpid, number)).anyTimes();
622
623 // Mock setLinkPort() method
624 mockPort.setLinkPort((IPortObject) EasyMock.anyObject());
625 EasyMock.expectLastCall().andAnswer(new SetLinkPortCallback(dpid, number)).anyTimes();
626
627 // Mock getLinkPorts() method
628 // -> Always empty list for now
629 EasyMock.expect(mockPort.getLinkedPorts()).andAnswer(new IAnswer< Iterable<IPortObject> >() {
630 @Override
631 public Iterable<IPortObject> answer() throws Throwable {
632 return new Iterable<IPortObject> () {
633 @Override
634 public Iterator<IPortObject> iterator() {
635 // create empty list and returns its iterator
636 return new ArrayList<IPortObject>().iterator();
637 }
638 };
639 }
640 }).anyTimes();
641
642 EasyMock.replay(mockPort);
643 return mockPort;
Naoki Shiotacae568a2013-06-05 17:53:41 -0700644 }
645
mininet403d5892013-06-05 03:48:17 -0700646
647 //----------------- Creation of test data -----------------------
Naoki Shiota0dae8332013-06-13 08:44:30 -0700648 // Assume a network shown below.
649 //
650 // [dpid1]--+--[port:1]----[port:1]--+--[dpid2]
651 // | |
652 // +--[port:2] [port:2]--+
653 // |
654 // +--[port:3] [port:1]--+--[dpid3]
655 // | |
656 // +--[port:4]----[port:2]--+
657 //
658 // dpid1 : 00:00:00:00:0a:01
659 // dpid2 : 00:00:00:00:0a:02
660 // dpid3 : 00:00:00:00:0a:03
661
662 private void initLinks() {
663 links = new ArrayList<Link>();
664
665 links.add(new Link(Long.decode("0x0000000000000a01"), 1, Long.decode("0x0000000000000a02"), 1));
666 links.add(new Link(Long.decode("0x0000000000000a01"), 3, Long.decode("0x0000000000000a03"), 2));
mininet403d5892013-06-05 03:48:17 -0700667 }
668
mininet9d203de2013-06-05 08:40:45 -0700669 /**
Naoki Shiota0dae8332013-06-13 08:44:30 -0700670 * Returns new Link object of existing link
671 * @return new Link object
672 */
673 private Link createExistingLink() {
674 return new Link(Long.decode("0x0000000000000a01"), 1, Long.decode("0x0000000000000a02"), 1);
675 }
676
677 /**
678 * Returns new Link object of not-existing but feasible link
mininet9d203de2013-06-05 08:40:45 -0700679 * @return new Link object
680 */
mininet403d5892013-06-05 03:48:17 -0700681 private Link createFeasibleLink() {
Naoki Shiota0dae8332013-06-13 08:44:30 -0700682 return new Link(Long.decode("0x0000000000000a01"), 3, Long.decode("0x0000000000000a03"), 1);
mininet403d5892013-06-05 03:48:17 -0700683 }
684
mininet9d203de2013-06-05 08:40:45 -0700685 // make NO sense while test-network data doesn't define physical network (i.e. any link is feasible)
mininet403d5892013-06-05 03:48:17 -0700686 @SuppressWarnings("unused")
687 private Link createInfeasibleLink() {
Naoki Shiota0dae8332013-06-13 08:44:30 -0700688 return new Link(Long.decode("0x0000000000000a01"), 1, Long.decode("0x0000000000000a03"), 3);
mininet403d5892013-06-05 03:48:17 -0700689 }
690
mininet9d203de2013-06-05 08:40:45 -0700691 /**
692 * Returns list of Link objects which all has information of existing link in titanGraph
693 * @return ArrayList of new Link objects
694 */
mininet403d5892013-06-05 03:48:17 -0700695 private List<Link> createExistingLinks() {
696 List<Link> links = new ArrayList<Link>();
Naoki Shiota0dae8332013-06-13 08:44:30 -0700697 links.add(new Link(Long.decode("0x0000000000000a01"), 1, Long.decode("0x0000000000000a02"), 1));
698 links.add(new Link(Long.decode("0x0000000000000a01"), 4, Long.decode("0x0000000000000a03"), 2));
mininet403d5892013-06-05 03:48:17 -0700699 return links;
700 }
701
mininet9d203de2013-06-05 08:40:45 -0700702 /**
703 * Returns list of Link objects which all has information of not-existing but feasible link
704 * @return ArrayList of new Link objects
705 */
mininet403d5892013-06-05 03:48:17 -0700706 private List<Link> createFeasibleLinks() {
707 List<Link> links = new ArrayList<Link>();
Naoki Shiota0dae8332013-06-13 08:44:30 -0700708 links.add(new Link(Long.decode("0x0000000000000a01"), 2, Long.decode("0x0000000000000a02"), 2));
709 links.add(new Link(Long.decode("0x0000000000000a01"), 3, Long.decode("0x0000000000000a03"), 1));
mininet403d5892013-06-05 03:48:17 -0700710 return links;
711 }
Naoki Shiotacae568a2013-06-05 17:53:41 -0700712
713 /**
714 * Returns new LinkInfo object with convenient values.
715 * @return LinkInfo object
716 */
717 private LinkInfo createFeasibleLinkInfo(long time) {
718 long time_first = time;
719 long time_last_lldp = time + 50;
720 long time_last_bddp = time + 100;
721 int state_src = OFPhysicalPort.OFPortState.OFPPS_STP_FORWARD.getValue();
722 int state_dst = OFPhysicalPort.OFPortState.OFPPS_STP_LISTEN.getValue();
723
724 return new LinkInfo(time_first,
725 time_last_lldp,
726 time_last_bddp,
727 state_src,
728 state_dst);
729 }
mininet403d5892013-06-05 03:48:17 -0700730 //---------------------------------------------------------------
Jonathan Hartb7e3d2c2013-01-15 18:45:19 -0800731}