blob: b0577a58b378d17ff52d885577fa0d26a479688c [file] [log] [blame]
HIGUCHI Yuta08137932013-06-17 14:11:50 -07001package net.onrc.onos.ofcontroller.core.internal;
Jonathan Hartb7e3d2c2013-01-15 18:45:19 -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;
6
mininet403d5892013-06-05 03:48:17 -07007import java.util.ArrayList;
Naoki Shiota5f9197a2013-06-20 17:36:29 -07008import java.util.HashMap;
9import java.util.Iterator;
Jonathan Hartc86a2ea2013-01-15 22:39:42 -080010import java.util.List;
Naoki Shiota5f9197a2013-06-20 17:36:29 -070011import java.util.Map;
Jonathan Hartb7e3d2c2013-01-15 18:45:19 -080012
Jonathan Hartb7e3d2c2013-01-15 18:45:19 -080013import net.floodlightcontroller.routing.Link;
HIGUCHI Yuta2d011582013-06-15 01:47:11 -070014import net.onrc.onos.ofcontroller.core.ILinkStorage;
HIGUCHI Yuta20514902013-06-12 11:24:16 -070015import net.onrc.onos.ofcontroller.core.INetMapStorage.DM_OPERATION;
Naoki Shiota5f9197a2013-06-20 17:36:29 -070016import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IPortObject;
17import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.ISwitchObject;
18import net.onrc.onos.ofcontroller.linkdiscovery.LinkInfo;
Naoki Shiotac88d9562013-06-18 15:21:56 -070019import net.onrc.onos.util.GraphDBConnection;
20import net.onrc.onos.util.GraphDBOperation;
Jonathan Hartb7e3d2c2013-01-15 18:45:19 -080021
Naoki Shiota5f9197a2013-06-20 17:36:29 -070022import org.easymock.*;
Jonathan Hartb7e3d2c2013-01-15 18:45:19 -080023import org.junit.After;
24import org.junit.Before;
Jonathan Hartd1c5a1c2013-01-23 00:56:14 -080025import org.junit.Ignore;
Jonathan Hartb7e3d2c2013-01-15 18:45:19 -080026import org.junit.Test;
mininet37dc5892013-06-04 10:58:44 -070027import org.junit.runner.RunWith;
Naoki Shiotacae568a2013-06-05 17:53:41 -070028import org.openflow.protocol.OFPhysicalPort;
mininet403d5892013-06-05 03:48:17 -070029import org.openflow.util.HexString;
mininet37dc5892013-06-04 10:58:44 -070030import org.powermock.api.easymock.PowerMock;
31import org.powermock.core.classloader.annotations.PrepareForTest;
32import org.powermock.modules.junit4.PowerMockRunner;
Naoki Shiotac88d9562013-06-18 15:21:56 -070033import org.slf4j.Logger;
34import org.slf4j.LoggerFactory;
Jonathan Hartb7e3d2c2013-01-15 18:45:19 -080035
mininet37dc5892013-06-04 10:58:44 -070036@RunWith(PowerMockRunner.class)
Naoki Shiotac88d9562013-06-18 15:21:56 -070037@PrepareForTest({LinkStorageImpl.class, GraphDBConnection.class, GraphDBOperation.class})
Jonathan Hartd1c5a1c2013-01-23 00:56:14 -080038public class LinkStorageImplTest {
Naoki Shiotac88d9562013-06-18 15:21:56 -070039 protected static Logger log = LoggerFactory.getLogger(LinkStorageImplTest.class);
40
Jonathan Hartb7e3d2c2013-01-15 18:45:19 -080041 private static ILinkStorage linkStorage;
Jonathan Hartb7e3d2c2013-01-15 18:45:19 -080042
Naoki Shiotac88d9562013-06-18 15:21:56 -070043 // Mock GraphDBConnection (do nothing)
44 private static GraphDBConnection conn;
45
46 // Mock GraphDBOperation (mocks port-related methods only)
Naoki Shiota5f9197a2013-06-20 17:36:29 -070047 private static GraphDBOperation ope;
48
49 // Uncommitted actions executed in LinkStorageImpl
50 private static ArrayList<LinkEvent> actions;
51
52 // Dictionary of mock IPortObject to information of port
53 // -> Used to refer DPID from IPortObject
54 private static Map<IPortObject,PortInfo> mockToPortInfoMap;
55
56
57 // Links existing in virtual graph
58 private List<Link> links;
59
60 //================ Utility classes for logging actions in LinkStorageImpl ===========
61 private enum LinkEventType {
62 ADD, DELETE
63 }
64
65 private class LinkEvent {
66 private Long src_dpid = null;
67 private Long dst_dpid = null;
68 private Short src_port = null;
69 private Short dst_port = null;
70
71 public LinkEventType type;
72
73 public LinkEvent(Link link, LinkEventType type) {
74 this.src_dpid = link.getSrc();
75 this.src_port = link.getSrcPort();
76 this.dst_dpid = link.getDst();
77 this.dst_port = link.getDstPort();
78
79 this.type = type;
80 }
81
82 public Long getSrcDpid() { return src_dpid; }
83 public Short getSrcPort() { return src_port; }
84 public Long getDstDpid() { return dst_dpid; }
85 public Short getDstPort() { return dst_port; }
86 public LinkEventType getType() { return type; }
87 }
88
89 private class PortInfo {
90 public Long dpid = null;
91 public Short port = null;
92
93 public PortInfo(Long dpid, Short port) { this.dpid = dpid; this.port = port; }
94 }
mininet37dc5892013-06-04 10:58:44 -070095
mininet9d203de2013-06-05 08:40:45 -070096 /**
97 * Setup code called before each tests.
98 * Read test graph data and replace DB access by test graph data.
99 * @throws Exception
100 */
Jonathan Hartb7e3d2c2013-01-15 18:45:19 -0800101 @Before
Jonathan Hart627f10c2013-01-16 14:20:03 -0800102 public void setUp() throws Exception{
Naoki Shiotac88d9562013-06-18 15:21:56 -0700103 PowerMock.mockStatic(GraphDBConnection.class);
104 PowerMock.suppress(PowerMock.constructor(GraphDBConnection.class));
105 conn = PowerMock.createNiceMock(GraphDBConnection.class);
106 EasyMock.expect(GraphDBConnection.getInstance((String)EasyMock.anyObject())).andReturn(conn).anyTimes();
107 PowerMock.replay(GraphDBConnection.class);
Jonathan Hartb7e3d2c2013-01-15 18:45:19 -0800108
Naoki Shiota5f9197a2013-06-20 17:36:29 -0700109 ope = createMockGraphDBOperation();
110 PowerMock.expectNew(GraphDBOperation.class, new Class<?>[] {GraphDBConnection.class}, EasyMock.anyObject(GraphDBConnection.class)).andReturn(ope).anyTimes();
Naoki Shiotac88d9562013-06-18 15:21:56 -0700111 PowerMock.replay(GraphDBOperation.class);
Naoki Shiota5f9197a2013-06-20 17:36:29 -0700112
113 actions = new ArrayList<LinkEvent>();
114 mockToPortInfoMap = new HashMap<IPortObject,PortInfo>();
115
mininet403d5892013-06-05 03:48:17 -0700116 linkStorage = new LinkStorageImpl();
Naoki Shiotac88d9562013-06-18 15:21:56 -0700117 linkStorage.init("/dummy/path/to/conf");
mininet403d5892013-06-05 03:48:17 -0700118
Naoki Shiotac88d9562013-06-18 15:21:56 -0700119 initLinks();
Jonathan Hartb7e3d2c2013-01-15 18:45:19 -0800120 }
121
mininet9d203de2013-06-05 08:40:45 -0700122 /**
123 * Closing code called after each tests.
124 * Discard test graph data.
125 * @throws Exception
126 */
Jonathan Hartd1c5a1c2013-01-23 00:56:14 -0800127 @After
mininet403d5892013-06-05 03:48:17 -0700128 public void tearDown() throws Exception {
129 // finish code
130 linkStorage.close();
Jonathan Hartb7e3d2c2013-01-15 18:45:19 -0800131 }
132
Naoki Shiotacae568a2013-06-05 17:53:41 -0700133 // TODO: remove @Ignore after UPDATE method is implemented
Naoki Shiota1b972862013-06-05 19:49:09 -0700134 /**
135 * Test if update() can correctly updates LinkInfo for a Link.
136 */
mininet403d5892013-06-05 03:48:17 -0700137 @Ignore @Test
138 public void testUpdate_UpdateSingleLink() {
139 Link linkToUpdate= createExistingLink();
Naoki Shiotacae568a2013-06-05 17:53:41 -0700140 long currentTime = System.currentTimeMillis();
141 LinkInfo infoToUpdate = createFeasibleLinkInfo(currentTime);
142 LinkInfo infoToVerify = createFeasibleLinkInfo(currentTime);
mininet403d5892013-06-05 03:48:17 -0700143
144 linkStorage.update(linkToUpdate, infoToUpdate, ILinkStorage.DM_OPERATION.UPDATE);
145
Naoki Shiotacae568a2013-06-05 17:53:41 -0700146 doTestLinkHasStateOf(linkToUpdate, infoToVerify);
mininet403d5892013-06-05 03:48:17 -0700147 }
148
Naoki Shiota1b972862013-06-05 19:49:09 -0700149 /**
150 * Test if update() can correctly creates a Link.
151 */
mininet403d5892013-06-05 03:48:17 -0700152 @Test
153 public void testUpdate_CreateSingleLink() {
154 Link linkToCreate = createFeasibleLink();
155 Link linkToVerify = createFeasibleLink();
156
157 //Use the link storage API to add the link
158 linkStorage.update(linkToCreate, ILinkStorage.DM_OPERATION.CREATE);
Naoki Shiotac88d9562013-06-18 15:21:56 -0700159 doTestLinkExist(linkToVerify);
Naoki Shiota5f9197a2013-06-20 17:36:29 -0700160
161 // Avoiding duplication is out of scope. DBOperation is responsible for this.
162// // Add same link
163// Link linkToCreateTwice = createFeasibleLink();
164// linkStorage.update(linkToCreateTwice, ILinkStorage.DM_OPERATION.CREATE);
165//
166// // this occurs assertion failure if there are two links in titanGraph
167// doTestLinkIsInGraph(linkToVerify);
mininet403d5892013-06-05 03:48:17 -0700168 }
169
Naoki Shiota1b972862013-06-05 19:49:09 -0700170 /**
171 * Test if update() can correctly inserts a Link.
172 */
Jonathan Hartb7e3d2c2013-01-15 18:45:19 -0800173 @Test
mininet403d5892013-06-05 03:48:17 -0700174 public void testUpdate_InsertSingleLink(){
175 Link linkToInsert = createFeasibleLink();
176 Link linkToVerify = createFeasibleLink();
Jonathan Hartb7e3d2c2013-01-15 18:45:19 -0800177
178 //Use the link storage API to add the link
mininet403d5892013-06-05 03:48:17 -0700179 linkStorage.update(linkToInsert, ILinkStorage.DM_OPERATION.INSERT);
Naoki Shiotac88d9562013-06-18 15:21:56 -0700180 doTestLinkExist(linkToVerify);
Jonathan Hartb7e3d2c2013-01-15 18:45:19 -0800181 }
182
Naoki Shiota1b972862013-06-05 19:49:09 -0700183 /**
184 * Test if update() can correctly deletes a Link.
185 */
mininet403d5892013-06-05 03:48:17 -0700186 @Test
187 public void testUpdate_DeleteSingleLink(){
188 Link linkToDelete = createExistingLink();
189 Link linkToVerify = createExistingLink();
190
191 // Test deletion of existing link
192 linkStorage.update(linkToDelete, DM_OPERATION.DELETE);
Naoki Shiotac88d9562013-06-18 15:21:56 -0700193 doTestLinkNotExist(linkToVerify);
mininet403d5892013-06-05 03:48:17 -0700194 }
Naoki Shiota1b972862013-06-05 19:49:09 -0700195
196 /**
197 * Test if update() can correctly creates multiple Links.
198 */
mininet403d5892013-06-05 03:48:17 -0700199 @Test
200 public void testUpdate_CreateLinks(){
201 List<Link> linksToCreate = createFeasibleLinks();
202 List<Link> linksToVerify = createFeasibleLinks();
203
204 // Test creation of new links
205 linkStorage.update(linksToCreate, ILinkStorage.DM_OPERATION.CREATE);
206 for(Link l : linksToVerify) {
Naoki Shiotac88d9562013-06-18 15:21:56 -0700207 doTestLinkExist(l);
mininet403d5892013-06-05 03:48:17 -0700208 }
Naoki Shiota5f9197a2013-06-20 17:36:29 -0700209
210 // Out of scope: DBOperation is responsible for avoiding duplication.
211// // Test creation of existing links
212// linksToCreate = createFeasibleLinks();
213// linkStorage.update(linksToCreate, ILinkStorage.DM_OPERATION.CREATE);
214// for(Link l : linksToVerify) {
215// doTestLinkIsInGraph(l);
216// }
mininet403d5892013-06-05 03:48:17 -0700217 }
218
Naoki Shiota1b972862013-06-05 19:49:09 -0700219 /**
220 * Test if update() can handle mixture of normal/abnormal input for creation of Links.
Naoki Shiotac88d9562013-06-18 15:21:56 -0700221 * Deprecated: DBOperation is responsible.
Naoki Shiota1b972862013-06-05 19:49:09 -0700222 */
Naoki Shiotac88d9562013-06-18 15:21:56 -0700223 @Ignore @Test
mininet9d203de2013-06-05 08:40:45 -0700224 public void testUpdate_CreateLinks_Mixuture(){
mininet403d5892013-06-05 03:48:17 -0700225 List<Link> linksToCreate = new ArrayList<Link>();
226 linksToCreate.add(createFeasibleLink());
227 linksToCreate.add(createExistingLink());
228
229 // Test creation of mixture of new/existing links
230 linkStorage.update(linksToCreate, ILinkStorage.DM_OPERATION.CREATE);
Naoki Shiotac88d9562013-06-18 15:21:56 -0700231 doTestLinkExist(createFeasibleLink());
232 doTestLinkExist(createExistingLink());
mininet403d5892013-06-05 03:48:17 -0700233 }
234
Naoki Shiota1b972862013-06-05 19:49:09 -0700235 /**
236 * Test if update() can correctly inserts multiple Links.
237 */
mininet403d5892013-06-05 03:48:17 -0700238 @Test
239 public void testUpdate_InsertLinks(){
240 List<Link> linksToInsert = createFeasibleLinks();
241 List<Link> linksToVerify = createFeasibleLinks();
242
243 // Test insertion of new links
244 linkStorage.update(linksToInsert, ILinkStorage.DM_OPERATION.INSERT);
245 for(Link l : linksToVerify) {
Naoki Shiotac88d9562013-06-18 15:21:56 -0700246 doTestLinkExist(l);
mininet403d5892013-06-05 03:48:17 -0700247 }
248 }
249
Naoki Shiota1b972862013-06-05 19:49:09 -0700250 /**
251 * Test if update() can handle mixture of normal/abnormal input for creation of Links.
252 */
Naoki Shiotac88d9562013-06-18 15:21:56 -0700253 @Ignore @Test
mininet9d203de2013-06-05 08:40:45 -0700254 public void testUpdate_InsertLinks_Mixuture(){
mininet403d5892013-06-05 03:48:17 -0700255 List<Link> linksToInsert = new ArrayList<Link>();
256 linksToInsert.add(createFeasibleLink());
257 linksToInsert.add(createExistingLink());
258
259 // Test insertion of mixture of new/existing links
260 linkStorage.update(linksToInsert, ILinkStorage.DM_OPERATION.INSERT);
Naoki Shiotac88d9562013-06-18 15:21:56 -0700261 doTestLinkExist(createFeasibleLink());
262 doTestLinkExist(createExistingLink());
mininet403d5892013-06-05 03:48:17 -0700263 }
264
Naoki Shiota1b972862013-06-05 19:49:09 -0700265 /**
266 * Test if update() can correctly deletes multiple Links.
267 */
mininet403d5892013-06-05 03:48:17 -0700268 @Test
269 public void testUpdate_DeleteLinks(){
270 List<Link> linksToDelete = createExistingLinks();
271 List<Link> linksToVerify = createExistingLinks();
272
273 // Test deletion of existing links
274 linkStorage.update(linksToDelete, ILinkStorage.DM_OPERATION.DELETE);
275 for(Link l : linksToVerify) {
Naoki Shiotac88d9562013-06-18 15:21:56 -0700276 doTestLinkNotExist(l);
mininet403d5892013-06-05 03:48:17 -0700277 }
278 }
279
Naoki Shiota1b972862013-06-05 19:49:09 -0700280 /**
281 * Test if update() can handle mixture of normal/abnormal input for deletion of Links.
282 */
Naoki Shiotac88d9562013-06-18 15:21:56 -0700283 @Ignore @Test
mininet9d203de2013-06-05 08:40:45 -0700284 public void testUpdate_DeleteLinks_Mixuture(){
mininet403d5892013-06-05 03:48:17 -0700285 List<Link> linksToDelete = new ArrayList<Link>();
286 linksToDelete.add(createFeasibleLink());
287 linksToDelete.add(createExistingLink());
288
289 // Test deletion of mixture of new/existing links
290 linkStorage.update(linksToDelete, ILinkStorage.DM_OPERATION.DELETE);
Naoki Shiotac88d9562013-06-18 15:21:56 -0700291 doTestLinkNotExist(createFeasibleLink());
292 doTestLinkNotExist(createExistingLink());
mininet403d5892013-06-05 03:48:17 -0700293 }
294
Naoki Shiotacae568a2013-06-05 17:53:41 -0700295 // TODO: remove @Ignore after UPDATE method is implemented
Naoki Shiota1b972862013-06-05 19:49:09 -0700296 /**
297 * Test if updateLink() can correctly updates LinkInfo for a Link.
298 */
mininet9d203de2013-06-05 08:40:45 -0700299 @Ignore @Test
Naoki Shiota1b972862013-06-05 19:49:09 -0700300 public void testUpdateLink_Update() {
mininet9d203de2013-06-05 08:40:45 -0700301 Link linkToUpdate= createExistingLink();
Naoki Shiotacae568a2013-06-05 17:53:41 -0700302 long currentTime = System.currentTimeMillis();
303 LinkInfo infoToUpdate = createFeasibleLinkInfo(currentTime);
304 LinkInfo infoToVerify = createFeasibleLinkInfo(currentTime);
mininet9d203de2013-06-05 08:40:45 -0700305
Naoki Shiota1b972862013-06-05 19:49:09 -0700306 linkStorage.updateLink(linkToUpdate, infoToUpdate, ILinkStorage.DM_OPERATION.UPDATE);
mininet9d203de2013-06-05 08:40:45 -0700307
Naoki Shiotacae568a2013-06-05 17:53:41 -0700308 doTestLinkHasStateOf(linkToUpdate, infoToVerify);
mininet403d5892013-06-05 03:48:17 -0700309 }
310
Naoki Shiota1b972862013-06-05 19:49:09 -0700311 /**
312 * Test if updateLink() can correctly creates a Link.
313 */
mininet403d5892013-06-05 03:48:17 -0700314 @Test
Naoki Shiota1b972862013-06-05 19:49:09 -0700315 public void testUpdateLink_Create() {
mininet9d203de2013-06-05 08:40:45 -0700316 Link linkToCreate = createFeasibleLink();
317 Link linkToVerify = createFeasibleLink();
mininet403d5892013-06-05 03:48:17 -0700318
mininet9d203de2013-06-05 08:40:45 -0700319 //Use the link storage API to add the link
Naoki Shiota1b972862013-06-05 19:49:09 -0700320 linkStorage.updateLink(linkToCreate, null, ILinkStorage.DM_OPERATION.CREATE);
Naoki Shiotac88d9562013-06-18 15:21:56 -0700321 doTestLinkExist(linkToVerify);
mininet403d5892013-06-05 03:48:17 -0700322 }
323
Naoki Shiota1b972862013-06-05 19:49:09 -0700324 /**
325 * Test if updateLink() can correctly inserts a Link.
326 */
mininet403d5892013-06-05 03:48:17 -0700327 @Test
Naoki Shiota1b972862013-06-05 19:49:09 -0700328 public void testUpdateLink_Insert() {
mininet9d203de2013-06-05 08:40:45 -0700329 Link linkToInsert = createFeasibleLink();
330 Link linkToVerify = createFeasibleLink();
mininet403d5892013-06-05 03:48:17 -0700331
mininet9d203de2013-06-05 08:40:45 -0700332 //Use the link storage API to add the link
Naoki Shiota1b972862013-06-05 19:49:09 -0700333 linkStorage.updateLink(linkToInsert, null, ILinkStorage.DM_OPERATION.INSERT);
mininet9d203de2013-06-05 08:40:45 -0700334
Naoki Shiotac88d9562013-06-18 15:21:56 -0700335 doTestLinkExist(linkToVerify);
mininet9d203de2013-06-05 08:40:45 -0700336 }
337
338 // TODO: Check if addOrUpdateLink() should accept DELETE operation. If not, remove this test.
Naoki Shiota1b972862013-06-05 19:49:09 -0700339 /**
340 * Test if updateLink() can correctly deletes a Link.
341 */
mininet9d203de2013-06-05 08:40:45 -0700342 @Ignore @Test
Naoki Shiota1b972862013-06-05 19:49:09 -0700343 public void testUpdateLink_Delete() {
mininet9d203de2013-06-05 08:40:45 -0700344 Link linkToDelete = createExistingLink();
345 Link linkToVerify = createExistingLink();
346
347 // Test deletion of existing link
Naoki Shiota1b972862013-06-05 19:49:09 -0700348 linkStorage.updateLink(linkToDelete, null, DM_OPERATION.DELETE);
Naoki Shiotac88d9562013-06-18 15:21:56 -0700349 doTestLinkNotExist(linkToVerify);
mininet9d203de2013-06-05 08:40:45 -0700350
351 linkToDelete = createFeasibleLink();
352 linkToVerify = createFeasibleLink();
353
354 // Test deletion of not-existing link
Naoki Shiota1b972862013-06-05 19:49:09 -0700355 linkStorage.updateLink(linkToDelete, null, DM_OPERATION.DELETE);
Naoki Shiotac88d9562013-06-18 15:21:56 -0700356 doTestLinkNotExist(linkToVerify);
mininet9d203de2013-06-05 08:40:45 -0700357 }
358
Naoki Shiota1b972862013-06-05 19:49:09 -0700359 /**
360 * Test if getLinks() can correctly return Links connected to specific DPID and port.
361 */
mininet9d203de2013-06-05 08:40:45 -0700362 @Test
363 public void testGetLinks_ByDpidPort(){
364 Link linkToVerify = createExistingLink();
365 Long dpid = linkToVerify.getSrc();
366 short port = (short)linkToVerify.getSrcPort();
367
368 List<Link> list = linkStorage.getLinks(dpid, port);
Jonathan Hartb7e3d2c2013-01-15 18:45:19 -0800369
Naoki Shiota5f9197a2013-06-20 17:36:29 -0700370 assertEquals(1, list.size());
Jonathan Hartc86a2ea2013-01-15 22:39:42 -0800371
372 Link l = list.get(0);
mininet403d5892013-06-05 03:48:17 -0700373 assertEquals(l.getSrc(), linkToVerify.getSrc());
374 assertEquals(l.getSrcPort(), linkToVerify.getSrcPort());
375 assertEquals(l.getDst(), linkToVerify.getDst());
376 assertEquals(l.getDstPort(), linkToVerify.getDstPort());
377
378 Link linkToVerifyNot = createFeasibleLink();
379
380 List<Link> list2 = linkStorage.getLinks(linkToVerifyNot.getSrc(), (short)linkToVerifyNot.getSrcPort());
381
Naoki Shiota5f9197a2013-06-20 17:36:29 -0700382 assertEquals(0, list2.size());
Jonathan Hartc86a2ea2013-01-15 22:39:42 -0800383 }
384
Naoki Shiota1b972862013-06-05 19:49:09 -0700385 /**
386 * Test if getLinks() can correctly return Links connected to specific MAC address.
387 */
mininet403d5892013-06-05 03:48:17 -0700388 @Test
mininet9d203de2013-06-05 08:40:45 -0700389 public void testGetLinks_ByString() {
mininet403d5892013-06-05 03:48:17 -0700390 Link linkToVeryfy = createExistingLink();
mininet9d203de2013-06-05 08:40:45 -0700391 String dpid = HexString.toHexString(linkToVeryfy.getSrc());
Jonathan Hartc86a2ea2013-01-15 22:39:42 -0800392
mininet9d203de2013-06-05 08:40:45 -0700393 List<Link> links = linkStorage.getLinks(dpid);
mininet403d5892013-06-05 03:48:17 -0700394 assertTrue(links.contains(linkToVeryfy));
395
396 Link linkToVerifyNot = createFeasibleLink();
397 assertFalse(links.contains(linkToVerifyNot));
Jonathan Hartc86a2ea2013-01-15 22:39:42 -0800398 }
399
Naoki Shiota1b972862013-06-05 19:49:09 -0700400 /**
401 * Test if deleteLink() can correctly delete a Link.
402 */
mininet403d5892013-06-05 03:48:17 -0700403 @Test
404 public void testDeleteLink() {
405 // Deletion of existing link
406 Link linkToDelete = createExistingLink();
407 Link linkToVerify = createExistingLink();
408
409 linkStorage.deleteLink(linkToDelete);
Naoki Shiotac88d9562013-06-18 15:21:56 -0700410 doTestLinkNotExist(linkToVerify);
mininet403d5892013-06-05 03:48:17 -0700411 }
412
Naoki Shiota1b972862013-06-05 19:49:09 -0700413 /**
414 * Test if deleteLinks() can correctly delete Links.
415 */
mininet403d5892013-06-05 03:48:17 -0700416 @Test
Jonathan Hartc86a2ea2013-01-15 22:39:42 -0800417 public void testDeleteLinks(){
mininet403d5892013-06-05 03:48:17 -0700418 List<Link> linksToDelete = createExistingLinks();
419 List<Link> linksToVerify = createExistingLinks();
Jonathan Hartc86a2ea2013-01-15 22:39:42 -0800420
mininet403d5892013-06-05 03:48:17 -0700421 linkStorage.deleteLinks(linksToDelete);
422 for(Link l : linksToVerify) {
Naoki Shiotac88d9562013-06-18 15:21:56 -0700423 doTestLinkNotExist(l);
mininet403d5892013-06-05 03:48:17 -0700424 }
425 }
426
Naoki Shiota1b972862013-06-05 19:49:09 -0700427 /**
428 * Test if deleteLinks() can handle mixture of normal/abnormal input.
429 */
Naoki Shiotac88d9562013-06-18 15:21:56 -0700430 @Ignore @Test
mininet9d203de2013-06-05 08:40:45 -0700431 public void testDeleteLinks_Mixture(){
432 List<Link> linksToDelete = new ArrayList<Link>();
433 linksToDelete.add(createFeasibleLink());
434 linksToDelete.add(createExistingLink());
435
436 // Test deletion of mixture of new/existing links
437 linkStorage.deleteLinks(linksToDelete);
Naoki Shiotac88d9562013-06-18 15:21:56 -0700438 doTestLinkNotExist(createFeasibleLink());
439 doTestLinkNotExist(createExistingLink());
mininet9d203de2013-06-05 08:40:45 -0700440 }
441
Naoki Shiota1b972862013-06-05 19:49:09 -0700442 /**
443 * Test if getActiveLinks() can correctly return active Links.
444 */
mininet9d203de2013-06-05 08:40:45 -0700445 @Test
mininet403d5892013-06-05 03:48:17 -0700446 public void testGetActiveLinks() {
447 Link existingLink = createExistingLink();
448 Link notExistingLink = createFeasibleLink();
449
450 List<Link> links = linkStorage.getActiveLinks();
Jonathan Hartc86a2ea2013-01-15 22:39:42 -0800451
mininet403d5892013-06-05 03:48:17 -0700452 assertTrue(links.contains(existingLink));
453 assertFalse(links.contains(notExistingLink));
454 }
455
Naoki Shiota1b972862013-06-05 19:49:09 -0700456 /**
457 * Test if deleteLinksOnPort() can delete Links.
458 */
mininet403d5892013-06-05 03:48:17 -0700459 @Test
460 public void testDeleteLinksOnPort() {
461 Link linkToDelete = createExistingLink();
462 Link linkToVerify = createExistingLink();
463
464 linkStorage.deleteLinksOnPort(linkToDelete.getSrc(), linkToDelete.getSrcPort());
465
Naoki Shiotac88d9562013-06-18 15:21:56 -0700466 doTestLinkNotExist(linkToVerify);
mininet403d5892013-06-05 03:48:17 -0700467 }
mininet9d203de2013-06-05 08:40:45 -0700468
mininet403d5892013-06-05 03:48:17 -0700469 /**
Naoki Shiota5f9197a2013-06-20 17:36:29 -0700470 * Test if specific link exists
mininet9d203de2013-06-05 08:40:45 -0700471 * @param link
mininet403d5892013-06-05 03:48:17 -0700472 */
Naoki Shiotac88d9562013-06-18 15:21:56 -0700473 private void doTestLinkExist(Link link) {
Naoki Shiota5f9197a2013-06-20 17:36:29 -0700474 int count = 0;
475 for(Link lt : links) {
476 if(lt.equals(link)) {
477 ++count;
478 }
479 }
480
481 assertTrue(count == 1);
Jonathan Hartb7e3d2c2013-01-15 18:45:19 -0800482 }
483
mininet403d5892013-06-05 03:48:17 -0700484 /**
Naoki Shiota5f9197a2013-06-20 17:36:29 -0700485 * Test if specific link doesn't exist
mininet403d5892013-06-05 03:48:17 -0700486 * @param link
487 */
Naoki Shiotac88d9562013-06-18 15:21:56 -0700488 private void doTestLinkNotExist(Link link) {
Naoki Shiota5f9197a2013-06-20 17:36:29 -0700489 assertFalse(links.contains(link));
mininet403d5892013-06-05 03:48:17 -0700490 }
Naoki Shiotacae568a2013-06-05 17:53:41 -0700491
492 /**
493 * Test if titanGraph has specific Link with specific LinkInfo
494 * @param link
495 */
496 private void doTestLinkHasStateOf(Link link, LinkInfo info) {
Naoki Shiotacae568a2013-06-05 17:53:41 -0700497 }
Naoki Shiotac88d9562013-06-18 15:21:56 -0700498
Naoki Shiota5f9197a2013-06-20 17:36:29 -0700499 /**
500 * Class defines a function called back when IPortObject#removeLink is called.
501 * @author Naoki Shiota
502 *
503 */
504 private class RemoveLinkCallback implements IAnswer<Object> {
505 private long dpid;
506 private short port;
507 public RemoveLinkCallback(long dpid, short port) {
508 this.dpid = dpid; this.port = port;
509 }
510
511 @Override
512 public Object answer() throws Throwable {
513 IPortObject dstPort = (IPortObject) EasyMock.getCurrentArguments()[0];
514 PortInfo dst = mockToPortInfoMap.get(dstPort);
515
516 Link linkToRemove = new Link(this.dpid,this.port,dst.dpid,dst.port);
517 actions.add(new LinkEvent(linkToRemove,LinkEventType.DELETE));
518
519 return null;
520 }
521 }
522
523 /**
524 * Class defines a function called back when IPortObject#setLinkPort is called.
525 * @author Naoki Shiota
526 *
527 */
528 private class SetLinkPortCallback implements IAnswer<Object> {
529 private long dpid;
530 private short port;
531 public SetLinkPortCallback(long dpid, short port) {
532 this.dpid = dpid; this.port = port;
533 }
534
535 @Override
536 public Object answer() throws Throwable {
537 IPortObject dstPort = (IPortObject) EasyMock.getCurrentArguments()[0];
538 PortInfo dst = mockToPortInfoMap.get(dstPort);
539
540 Link linkToAdd = new Link(this.dpid,this.port,dst.dpid,dst.port);
541 actions.add(new LinkEvent(linkToAdd,LinkEventType.ADD));
542
543 return null;
544 }
545
546 }
547
548 /**
549 * Class defines a function called back when IPortObject#getSwitch is called.
550 * @author Naoki Shiota
551 *
552 */
553 private class GetSwitchCallback implements IAnswer<ISwitchObject> {
554 private long dpid;
555
556 public GetSwitchCallback(long dpid) {
557 this.dpid = dpid;
558 }
559
560 @Override
561 public ISwitchObject answer() throws Throwable {
562 ISwitchObject sw = createMockSwitch(dpid);
563 return sw;
564 }
565 }
566
567 /**
568 * Class defines a function called back when IPortObject#getLinkedPorts is called.
569 * @author Naoki Shiota
570 *
571 */
572 private class GetLinkedPortsCallback implements IAnswer< Iterable<IPortObject> > {
573 private long dpid;
574 private short port;
575
576 public GetLinkedPortsCallback(long dpid, short port) {
577 this.dpid = dpid;
578 this.port = port;
579 }
580
581 @Override
582 public Iterable<IPortObject> answer() throws Throwable {
583 List<IPortObject> ports = new ArrayList<IPortObject>();
584
585 for(Link lk : links) {
586 if(lk.getSrc() == dpid && lk.getSrcPort() == port) {
587 ports.add(createMockPort(lk.getDst(), lk.getDstPort()));
588 }
589 }
590
591 return ports;
592 }
593
594 }
595
596 /**
597 * Class defines a function called back when ISwitchObject#getPorts is called.
598 * @author Naoki Shiota
599 *
600 */
601 private class GetPortsCallback implements IAnswer< Iterable <IPortObject> > {
602 private long dpid;
603
604 public GetPortsCallback(long dpid) {
605 this.dpid = dpid;
606 }
607
608 @Override
609 public Iterable<IPortObject> answer() throws Throwable {
610 List<IPortObject> ports = new ArrayList<IPortObject>();
611
612 for(Short number : getPorts(dpid)) {
613 ports.add(createMockPort(dpid, number));
614 }
615
616 return ports;
617 }
618 }
619
620 // ------------------------Creation of Mock-----------------------------
621 /**
622 * Create a mock GraphDBOperation which hooks port-related methods.
623 * @return EasyMock-wrapped GraphDBOperation object.
624 */
625 @SuppressWarnings("serial")
626 private GraphDBOperation createMockGraphDBOperation() {
627 GraphDBOperation mockDBOpe = EasyMock.createNiceMock(GraphDBOperation.class);
628
629 // Mock searchPort() method to create new mock IPortObject.
630 EasyMock.expect(mockDBOpe.searchPort((String)EasyMock.anyObject(), EasyMock.anyShort())).
631 andAnswer(new IAnswer<IPortObject>() {
632 @Override
633 public IPortObject answer() throws Throwable {
634 long dpid = HexString.toLong((String)EasyMock.getCurrentArguments()[0]);
635 short port = (Short) EasyMock.getCurrentArguments()[1];
636 IPortObject ret = createMockPort(dpid,port);
637
638 return ret;
639 }
640 }).anyTimes();
641
642 // Mock searchSwitch() method to create new mock ISwitchObject.
643 EasyMock.expect(mockDBOpe.searchSwitch((String)EasyMock.anyObject())).
644 andAnswer(new IAnswer<ISwitchObject>() {
645 @Override
646 public ISwitchObject answer() throws Throwable {
647 long dpid = HexString.toLong((String)EasyMock.getCurrentArguments()[0]);
648 ISwitchObject ret = createMockSwitch(dpid);
649
650 return ret;
651 }
652 }).anyTimes();
653
654 // Mock getActiveSwitches() method to create list of mock ISwitchObject.
655 EasyMock.expect(mockDBOpe.getActiveSwitches()).andReturn(new ArrayList<ISwitchObject> () {{
656 for(Long dpid : getDpids()) {
657 add(createMockSwitch(dpid));
658 }
659 }}).anyTimes();
660
661 // Mock commit() method to commit change of link information
662 mockDBOpe.commit();
663 EasyMock.expectLastCall().andAnswer(new IAnswer<Object>() {
664 @Override
665 public Object answer() throws Throwable {
666 for(LinkEvent action : actions) {
667 if(action.getType().equals(LinkEventType.ADD)) {
668 Link linkToAdd = new Link(
669 action.getSrcDpid(),
670 action.getSrcPort(),
671 action.getDstDpid(),
672 action.getDstPort());
673 links.add(linkToAdd);
674 } else if(action.getType().equals(LinkEventType.DELETE)) {
675 Link linkToRemove = new Link(
676 action.getSrcDpid(),
677 action.getSrcPort(),
678 action.getDstDpid(),
679 action.getDstPort());
680 links.remove(linkToRemove);
681 } else {
682 log.error("mock commit(): unexpected action {}", new Object[]{action.getType()});
683 }
684 }
685 actions.clear();
686 return null;
687 }
688 }).atLeastOnce();
689
690 EasyMock.replay(mockDBOpe);
691 return mockDBOpe;
692 }
693
694 /**
695 * Create a mock IPortObject using given DPID and port number.
696 * IPortObject can't store DPID, so DPID is stored to mockToPortInfoMap for later use.
697 * Duplication is not checked.
698 * @param dpid DPID of a port
699 * @param number Port Number
700 * @return EasyMock-wrapped IPortObject
701 */
702 private IPortObject createMockPort(long dpid, short number) {
703 IPortObject mockPort = EasyMock.createNiceMock(IPortObject.class);
704
705 EasyMock.expect(mockPort.getNumber()).andReturn(number);
706
707 // Mock removeLink() method
708 mockPort.removeLink((IPortObject) EasyMock.anyObject());
709 EasyMock.expectLastCall().andAnswer(new RemoveLinkCallback(dpid, number)).anyTimes();
710
711 // Mock setLinkPort() method
712 mockPort.setLinkPort((IPortObject) EasyMock.anyObject());
713 EasyMock.expectLastCall().andAnswer(new SetLinkPortCallback(dpid, number)).anyTimes();
714
715 // Mock getLinkPorts() method
716 EasyMock.expect(mockPort.getLinkedPorts()).andAnswer(new GetLinkedPortsCallback(dpid, number)).anyTimes();
717
718 // Mock getSwitch() method
719 EasyMock.expect(mockPort.getSwitch()).andAnswer(new GetSwitchCallback(dpid)).anyTimes();
720
721 mockToPortInfoMap.put(mockPort, new PortInfo(dpid,number));
722 EasyMock.replay(mockPort);
723
724 return mockPort;
725 }
726
727 /**
728 * Create a mock ISwitchObject using given DPID number.
729 * Duplication is not checked.
730 * @param dpid DPID of a switch
731 * @return EasyMock-wrapped ISwitchObject
732 */
733 private ISwitchObject createMockSwitch(long dpid) {
734 ISwitchObject mockSw = EasyMock.createNiceMock(ISwitchObject.class);
735
736 EasyMock.expect(mockSw.getPorts()).andAnswer(new GetPortsCallback(dpid)).anyTimes();
737 EasyMock.expect(mockSw.getDPID()).andReturn(HexString.toHexString(dpid)).anyTimes();
738 EasyMock.expect(mockSw.getState()).andReturn("ACTIVE").anyTimes();
739
740 EasyMock.replay(mockSw);
741 return mockSw;
742 }
743
744
mininet403d5892013-06-05 03:48:17 -0700745 //----------------- Creation of test data -----------------------
Naoki Shiotac88d9562013-06-18 15:21:56 -0700746 // Assume a network shown below.
747 //
748 // [dpid1]--+--[port:1]----[port:1]--+--[dpid2]
749 // | |
750 // +--[port:2] [port:2]--+
751 // |
752 // +--[port:3] [port:1]--+--[dpid3]
753 // | |
754 // +--[port:4]----[port:2]--+
755 //
756 // dpid1 : 00:00:00:00:0a:01
757 // dpid2 : 00:00:00:00:0a:02
758 // dpid3 : 00:00:00:00:0a:03
759
Naoki Shiota5f9197a2013-06-20 17:36:29 -0700760 /**
761 * Initialize links member to represent test topology above.
762 */
Naoki Shiotac88d9562013-06-18 15:21:56 -0700763 private void initLinks() {
Naoki Shiota5f9197a2013-06-20 17:36:29 -0700764 links = new ArrayList<Link>();
Naoki Shiotac88d9562013-06-18 15:21:56 -0700765
Naoki Shiota5f9197a2013-06-20 17:36:29 -0700766 links.add(new Link(Long.decode("0x0000000000000a01"), 1, Long.decode("0x0000000000000a02"), 1));
767 links.add(new Link(Long.decode("0x0000000000000a01"), 4, Long.decode("0x0000000000000a03"), 2));
mininet403d5892013-06-05 03:48:17 -0700768 }
769
mininet9d203de2013-06-05 08:40:45 -0700770 /**
Naoki Shiota5f9197a2013-06-20 17:36:29 -0700771 * Returns list of port number attached to the switch specified by given DPID.
772 * @param dpid DPID of the switch
773 * @return List of port number
774 */
775 @SuppressWarnings("serial")
776 private List<Short> getPorts(long dpid) {
777 List<Short> ports;
778
779 if(dpid == Long.decode("0x0000000000000a01")) {
780 ports = new ArrayList<Short>() {{
781 add((short)1);
782 add((short)2);
783 add((short)3);
784 add((short)4);
785 }};
786 } else if(dpid == Long.decode("0x0000000000000a02") || dpid == Long.decode("0x0000000000000a03")) {
787 ports = new ArrayList<Short>() {{
788 add((short)1);
789 add((short)2);
790 }};
791 } else {
792 ports = new ArrayList<Short>();
793 }
794
795 return ports;
796 }
797
798 /**
799 * Returns list of DPIDs in test topology.
800 * @return List of DPIDs
801 */
802 @SuppressWarnings("serial")
803 private List<Long> getDpids() {
804 List<Long> dpids = new ArrayList<Long>() {{
805 add(Long.decode("0x0000000000000a01"));
806 add(Long.decode("0x0000000000000a02"));
807 add(Long.decode("0x0000000000000a03"));
808 }};
809
810 return dpids;
811 }
812
813 /**
814 * Returns new Link object of an existing link
Naoki Shiotac88d9562013-06-18 15:21:56 -0700815 * @return new Link object
816 */
817 private Link createExistingLink() {
818 return new Link(Long.decode("0x0000000000000a01"), 1, Long.decode("0x0000000000000a02"), 1);
819 }
820
821 /**
Naoki Shiota5f9197a2013-06-20 17:36:29 -0700822 * Returns new Link object of a not-existing but feasible link
mininet9d203de2013-06-05 08:40:45 -0700823 * @return new Link object
824 */
mininet403d5892013-06-05 03:48:17 -0700825 private Link createFeasibleLink() {
Naoki Shiotac88d9562013-06-18 15:21:56 -0700826 return new Link(Long.decode("0x0000000000000a01"), 3, Long.decode("0x0000000000000a03"), 1);
mininet403d5892013-06-05 03:48:17 -0700827 }
828
mininet9d203de2013-06-05 08:40:45 -0700829 // make NO sense while test-network data doesn't define physical network (i.e. any link is feasible)
mininet403d5892013-06-05 03:48:17 -0700830 @SuppressWarnings("unused")
831 private Link createInfeasibleLink() {
Naoki Shiotac88d9562013-06-18 15:21:56 -0700832 return new Link(Long.decode("0x0000000000000a01"), 1, Long.decode("0x0000000000000a03"), 3);
mininet403d5892013-06-05 03:48:17 -0700833 }
834
mininet9d203de2013-06-05 08:40:45 -0700835 /**
836 * Returns list of Link objects which all has information of existing link in titanGraph
837 * @return ArrayList of new Link objects
838 */
mininet403d5892013-06-05 03:48:17 -0700839 private List<Link> createExistingLinks() {
840 List<Link> links = new ArrayList<Link>();
Naoki Shiotac88d9562013-06-18 15:21:56 -0700841 links.add(new Link(Long.decode("0x0000000000000a01"), 1, Long.decode("0x0000000000000a02"), 1));
842 links.add(new Link(Long.decode("0x0000000000000a01"), 4, Long.decode("0x0000000000000a03"), 2));
mininet403d5892013-06-05 03:48:17 -0700843 return links;
844 }
845
mininet9d203de2013-06-05 08:40:45 -0700846 /**
847 * Returns list of Link objects which all has information of not-existing but feasible link
848 * @return ArrayList of new Link objects
849 */
mininet403d5892013-06-05 03:48:17 -0700850 private List<Link> createFeasibleLinks() {
851 List<Link> links = new ArrayList<Link>();
Naoki Shiotac88d9562013-06-18 15:21:56 -0700852 links.add(new Link(Long.decode("0x0000000000000a01"), 2, Long.decode("0x0000000000000a02"), 2));
853 links.add(new Link(Long.decode("0x0000000000000a01"), 3, Long.decode("0x0000000000000a03"), 1));
mininet403d5892013-06-05 03:48:17 -0700854 return links;
855 }
Naoki Shiotacae568a2013-06-05 17:53:41 -0700856
857 /**
858 * Returns new LinkInfo object with convenient values.
859 * @return LinkInfo object
860 */
861 private LinkInfo createFeasibleLinkInfo(long time) {
862 long time_first = time;
863 long time_last_lldp = time + 50;
864 long time_last_bddp = time + 100;
865 int state_src = OFPhysicalPort.OFPortState.OFPPS_STP_FORWARD.getValue();
866 int state_dst = OFPhysicalPort.OFPortState.OFPPS_STP_LISTEN.getValue();
867
868 return new LinkInfo(time_first,
869 time_last_lldp,
870 time_last_bddp,
871 state_src,
872 state_dst);
873 }
mininet403d5892013-06-05 03:48:17 -0700874 //---------------------------------------------------------------
Jonathan Hartb7e3d2c2013-01-15 18:45:19 -0800875}