blob: 184c4a2460b211ee6dff88c386039804f95477b2 [file] [log] [blame]
Naoki Shiota75b7dd62013-12-03 18:09:21 -08001package net.onrc.onos.ofcontroller.flowprogrammer;
2
3import static org.junit.Assert.*;
4import static org.powermock.api.easymock.PowerMock.createMock;
5
6import java.io.IOException;
7import java.util.ArrayList;
8import java.util.HashMap;
9import java.util.List;
10import java.util.Map;
11import java.util.concurrent.ScheduledExecutorService;
12import java.util.concurrent.TimeUnit;
13
14import net.floodlightcontroller.core.FloodlightContext;
15import net.floodlightcontroller.core.IFloodlightProviderService;
16import net.floodlightcontroller.core.IOFSwitch;
17import net.floodlightcontroller.core.module.FloodlightModuleContext;
18import net.floodlightcontroller.threadpool.IThreadPoolService;
19import net.floodlightcontroller.util.OFMessageDamper;
20import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IFlowEntry;
21import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IFlowPath;
22import net.onrc.onos.ofcontroller.util.CallerId;
23import net.onrc.onos.ofcontroller.util.DataPath;
24import net.onrc.onos.ofcontroller.util.Dpid;
25import net.onrc.onos.ofcontroller.util.FlowEntry;
26import net.onrc.onos.ofcontroller.util.FlowEntryAction;
27import net.onrc.onos.ofcontroller.util.FlowEntryActions;
28import net.onrc.onos.ofcontroller.util.FlowEntryErrorState;
29import net.onrc.onos.ofcontroller.util.FlowEntryId;
30import net.onrc.onos.ofcontroller.util.FlowEntryMatch;
31import net.onrc.onos.ofcontroller.util.FlowEntryUserState;
32import net.onrc.onos.ofcontroller.util.FlowId;
33import net.onrc.onos.ofcontroller.util.FlowPath;
34import net.onrc.onos.ofcontroller.util.FlowPathFlags;
35import net.onrc.onos.ofcontroller.util.FlowPathType;
36import net.onrc.onos.ofcontroller.util.FlowPathUserState;
37import net.onrc.onos.ofcontroller.util.Port;
38import net.onrc.onos.ofcontroller.util.SwitchPort;
39
40import org.easymock.EasyMock;
41import org.easymock.IAnswer;
42import org.junit.Ignore;
43import org.junit.Test;
44import org.openflow.protocol.OFBarrierRequest;
45import org.openflow.protocol.OFFlowMod;
46import org.openflow.protocol.OFMatch;
47import org.openflow.protocol.OFMessage;
48import org.openflow.protocol.OFType;
49import org.openflow.protocol.action.OFAction;
50import org.openflow.protocol.factory.BasicFactory;
51
52public class FlowPusherTest {
53 private FlowPusher pusher;
54 private FloodlightContext context;
55 private FloodlightModuleContext modContext;
56 private BasicFactory factory;
57 private OFMessageDamper damper;
58 private IFloodlightProviderService flservice;
59 private IThreadPoolService tpservice;
60
61 /**
62 * Test single OFMessage is correctly sent to single switch via MessageDamper.
63 */
64 @Test
65 public void testAddMessage() {
66 beginInitMock();
67
68 OFMessage msg = EasyMock.createMock(OFMessage.class);
69 EasyMock.expect(msg.getXid()).andReturn(1).anyTimes();
70 EasyMock.expect(msg.getLength()).andReturn((short)100).anyTimes();
71 EasyMock.replay(msg);
72
73 IOFSwitch sw = EasyMock.createMock(IOFSwitch.class);
74 EasyMock.expect(sw.getId()).andReturn((long)1).anyTimes();
75 sw.flush();
76 EasyMock.expectLastCall().once();
77 EasyMock.replay(sw);
78
79 try {
80 EasyMock.expect(damper.write(EasyMock.eq(sw), EasyMock.eq(msg), EasyMock.eq(context))).andReturn(true).once();
81 } catch (IOException e1) {
82 fail("Failed in OFMessageDamper#write()");
83 }
84
85 endInitMock();
86 initPusher(1);
87
88 boolean add_result = pusher.add(sw, msg);
89 assertTrue(add_result);
90
91 try {
92 // wait until message is processed.
93 Thread.sleep(1000);
94 } catch (InterruptedException e) {
95 fail("Failed in Thread.sleep()");
96 }
97
98 EasyMock.verify(msg);
99 EasyMock.verify(sw);
100
101 pusher.stop();
102 }
103
104 /**
105 * Test bunch of OFMessages are correctly sent to single switch via MessageDamper.
106 */
107 @Test
108 public void testMassiveAddMessage() {
109 final int NUM_MSG = 10000;
110
111 beginInitMock();
112
113 IOFSwitch sw = EasyMock.createMock(IOFSwitch.class);
114 EasyMock.expect(sw.getId()).andReturn((long)1).anyTimes();
115 sw.flush();
116 EasyMock.expectLastCall().atLeastOnce();
117 EasyMock.replay(sw);
118
119 List<OFMessage> messages = new ArrayList<OFMessage>();
120
121 for (int i = 0; i < NUM_MSG; ++i) {
122 OFMessage msg = EasyMock.createMock(OFMessage.class);
123 EasyMock.expect(msg.getXid()).andReturn(i).anyTimes();
124 EasyMock.expect(msg.getLength()).andReturn((short)100).anyTimes();
125 EasyMock.replay(msg);
126 messages.add(msg);
127
128 try {
129 EasyMock.expect(damper.write(EasyMock.eq(sw), EasyMock.eq(msg), EasyMock.eq(context)))
130 .andReturn(true).once();
131 } catch (IOException e1) {
132 fail("Failed in OFMessageDamper#write()");
133 }
134 }
135
136 endInitMock();
137 initPusher(1);
138
139 for (OFMessage msg : messages) {
140 boolean add_result = pusher.add(sw, msg);
141 assertTrue(add_result);
142 }
143
144 try {
145 // wait until message is processed.
146 Thread.sleep(1000);
147 } catch (InterruptedException e) {
148 fail("Failed in Thread.sleep()");
149 }
150
151 for (OFMessage msg : messages) {
152 EasyMock.verify(msg);
153 }
154 EasyMock.verify(sw);
155
156 pusher.stop();
157 }
158
159 /**
160 * Test bunch of OFMessages are correctly sent to multiple switches with single threads.
161 */
162 @Test
163 public void testMultiSwitchAddMessage() {
164 final int NUM_SWITCH = 10;
165 final int NUM_MSG = 100; // messages per thread
166
167 beginInitMock();
168
169 Map<IOFSwitch, List<OFMessage>> sw_map = new HashMap<IOFSwitch, List<OFMessage>>();
170 for (int i = 0; i < NUM_SWITCH; ++i) {
171 IOFSwitch sw = EasyMock.createMock(IOFSwitch.class);
172 EasyMock.expect(sw.getId()).andReturn((long)i).anyTimes();
173 sw.flush();
174 EasyMock.expectLastCall().atLeastOnce();
175 EasyMock.replay(sw);
176
177 List<OFMessage> messages = new ArrayList<OFMessage>();
178
179 for (int j = 0; j < NUM_MSG; ++j) {
180 OFMessage msg = EasyMock.createMock(OFMessage.class);
181 EasyMock.expect(msg.getXid()).andReturn(j).anyTimes();
182 EasyMock.expect(msg.getLength()).andReturn((short)100).anyTimes();
183 EasyMock.replay(msg);
184 messages.add(msg);
185
186 try {
187 EasyMock.expect(damper.write(EasyMock.eq(sw), EasyMock.eq(msg), EasyMock.eq(context)))
188 .andReturn(true).once();
189 } catch (IOException e1) {
190 fail("Failed in OFMessageDamper#write()");
191 }
192 }
193 sw_map.put(sw, messages);
194 }
195
196 endInitMock();
197 initPusher(1);
198
199 for (IOFSwitch sw : sw_map.keySet()) {
200 for (OFMessage msg : sw_map.get(sw)) {
201 boolean add_result = pusher.add(sw, msg);
202 assertTrue(add_result);
203 }
204 }
205
206 try {
207 // wait until message is processed.
208 Thread.sleep(1000);
209 } catch (InterruptedException e) {
210 fail("Failed in Thread.sleep()");
211 }
212
213 for (IOFSwitch sw : sw_map.keySet()) {
214 for (OFMessage msg : sw_map.get(sw)) {
215 EasyMock.verify(msg);
216 }
217
218 EasyMock.verify(sw);
219 }
220
221 pusher.stop();
222 }
223
224 /**
225 * Test bunch of OFMessages are correctly sent to multiple switches using multiple threads.
226 */
227 @Test
228 public void testMultiThreadedAddMessage() {
229 final int NUM_THREAD = 10;
230 final int NUM_MSG = 100; // messages per thread
231
232 beginInitMock();
233
234 Map<IOFSwitch, List<OFMessage>> sw_map = new HashMap<IOFSwitch, List<OFMessage>>();
235 for (int i = 0; i < NUM_THREAD; ++i) {
236 IOFSwitch sw = EasyMock.createMock(IOFSwitch.class);
237 EasyMock.expect(sw.getId()).andReturn((long)i).anyTimes();
238 sw.flush();
239 EasyMock.expectLastCall().atLeastOnce();
240 EasyMock.replay(sw);
241
242 List<OFMessage> messages = new ArrayList<OFMessage>();
243
244 for (int j = 0; j < NUM_MSG; ++j) {
245 OFMessage msg = EasyMock.createMock(OFMessage.class);
246 EasyMock.expect(msg.getXid()).andReturn(j).anyTimes();
247 EasyMock.expect(msg.getLength()).andReturn((short)100).anyTimes();
248 EasyMock.replay(msg);
249 messages.add(msg);
250
251 try {
252 EasyMock.expect(damper.write(EasyMock.eq(sw), EasyMock.eq(msg), EasyMock.eq(context)))
253 .andReturn(true).once();
254 } catch (IOException e1) {
255 fail("Failed in OFMessageDamper#write()");
256 }
257 }
258 sw_map.put(sw, messages);
259 }
260
261 endInitMock();
262 initPusher(NUM_THREAD);
263
264 for (IOFSwitch sw : sw_map.keySet()) {
265 for (OFMessage msg : sw_map.get(sw)) {
266 boolean add_result = pusher.add(sw, msg);
267 assertTrue(add_result);
268 }
269 }
270
271 try {
272 // wait until message is processed.
273 Thread.sleep(1000);
274 } catch (InterruptedException e) {
275 fail("Failed in Thread.sleep()");
276 }
277
278 for (IOFSwitch sw : sw_map.keySet()) {
279 for (OFMessage msg : sw_map.get(sw)) {
280 EasyMock.verify(msg);
281 }
282
283 EasyMock.verify(sw);
284 }
285
286 pusher.stop();
287 }
288
289 private long barrierTime = 0;
290 /**
291 * Test rate limitation of messages works correctly.
292 */
293 @Test
294 public void testRateLimitedAddMessage() {
295 final long LIMIT_RATE = 100; // [bytes/ms]
296 final int NUM_MSG = 1000;
297
298 // Accuracy of FlowPusher's rate calculation can't be measured by unit test
299 // because switch doesn't return BARRIER_REPLY.
300 // In unit test we use approximate way to measure rate. This value is
301 // acceptable margin of measured rate.
302 final double ACCEPTABLE_RATE = LIMIT_RATE * 1.2;
303
304 beginInitMock();
305
306 IOFSwitch sw = EasyMock.createMock(IOFSwitch.class);
307 EasyMock.expect(sw.getId()).andReturn((long)1).anyTimes();
308 sw.flush();
309 EasyMock.expectLastCall().atLeastOnce();
310 prepareBarrier(sw);
311 EasyMock.replay(sw);
312
313 List<OFMessage> messages = new ArrayList<OFMessage>();
314
315 for (int i = 0; i < NUM_MSG; ++i) {
316 OFMessage msg = EasyMock.createMock(OFMessage.class);
317 EasyMock.expect(msg.getXid()).andReturn(1).anyTimes();
318 EasyMock.expect(msg.getLength()).andReturn((short)100).anyTimes();
319 EasyMock.expect(msg.getLengthU()).andReturn(100).anyTimes();
320 EasyMock.replay(msg);
321 messages.add(msg);
322
323 try {
324 EasyMock.expect(damper.write(EasyMock.eq(sw), EasyMock.eq(msg), EasyMock.eq(context)))
325 .andReturn(true).once();
326 } catch (IOException e) {
327 fail("Failed in OFMessageDamper#write()");
328 }
329 }
330
331 try {
332 EasyMock.expect(damper.write(EasyMock.eq(sw), (OFMessage)EasyMock.anyObject(), EasyMock.eq(context)))
333 .andAnswer(new IAnswer<Boolean>() {
334 @Override
335 public Boolean answer() throws Throwable {
336 OFMessage msg = (OFMessage)EasyMock.getCurrentArguments()[1];
337 if (msg.getType() == OFType.BARRIER_REQUEST) {
338 barrierTime = System.currentTimeMillis();
339 }
340 return true;
341 }
342 }).once();
343 } catch (IOException e1) {
344 fail("Failed in OFMessageDamper#write()");
345 }
346
347 endInitMock();
348 initPusher(1);
349
350 pusher.createQueue(sw);
351 pusher.setRate(sw, LIMIT_RATE);
352
353 long beginTime = System.currentTimeMillis();
354 for (OFMessage msg : messages) {
355 boolean add_result = pusher.add(sw, msg);
356 assertTrue(add_result);
357 }
358
359 pusher.barrierAsync(sw);
360
361 try {
362 do {
363 Thread.sleep(1000);
364 } while (barrierTime == 0);
365 } catch (InterruptedException e) {
366 fail("Failed to sleep");
367 }
368
369 double measured_rate = NUM_MSG * 100 / (barrierTime - beginTime);
370 assertTrue(measured_rate < ACCEPTABLE_RATE);
371
372 for (OFMessage msg : messages) {
373 EasyMock.verify(msg);
374 }
375 EasyMock.verify(sw);
376
377 pusher.stop();
378 }
379
380 /**
381 * Test barrier message is correctly sent to a switch.
382 */
383 @Test
384 public void testBarrierMessage() {
385 beginInitMock();
386
387 IOFSwitch sw = EasyMock.createMock(IOFSwitch.class);
388 EasyMock.expect(sw.getId()).andReturn((long)1).anyTimes();
389 sw.flush();
390 EasyMock.expectLastCall().atLeastOnce();
391 prepareBarrier(sw);
392 EasyMock.replay(sw);
393
394 try {
395 EasyMock.expect(damper.write(EasyMock.eq(sw), (OFMessage)EasyMock.anyObject(), EasyMock.eq(context)))
396 .andReturn(true).once();
397 } catch (IOException e1) {
398 fail("Failed in OFMessageDamper#write()");
399 }
400
401 endInitMock();
402 initPusher(1);
403
404 OFBarrierReplyFuture future = pusher.barrierAsync(sw);
405
406 assertNotNull(future);
407 pusher.stop();
408 }
409
410 /**
411 * Test FlowObject is correctly converted to message and is sent to a switch.
412 */
413 @SuppressWarnings("unchecked")
414 @Test
415 public void testAddFlow() {
416 // Code below are copied from FlowManagerTest
417
418 // instantiate required objects
419 FlowEntry flowEntry1 = new FlowEntry();
420 flowEntry1.setDpid(new Dpid(1));
421 flowEntry1.setFlowId(new FlowId(1));
422 flowEntry1.setInPort(new Port((short) 1));
423 flowEntry1.setOutPort(new Port((short) 11));
424 flowEntry1.setFlowEntryId(new FlowEntryId(1));
425 flowEntry1.setFlowEntryMatch(new FlowEntryMatch());
426 flowEntry1.setFlowEntryActions(new FlowEntryActions());
427 flowEntry1.setFlowEntryErrorState(new FlowEntryErrorState());
428 flowEntry1.setFlowEntryUserState(FlowEntryUserState.FE_USER_ADD);
429
430 FlowEntry flowEntry2 = new FlowEntry();
431 flowEntry2.setDpid(new Dpid(2));
432 flowEntry2.setFlowId(new FlowId(2));
433 flowEntry2.setInPort(new Port((short) 22));
434 flowEntry2.setOutPort(new Port((short) 2));
435 flowEntry2.setFlowEntryId(new FlowEntryId(2));
436 flowEntry2.setFlowEntryMatch(new FlowEntryMatch());
437 flowEntry2.setFlowEntryActions(new FlowEntryActions());
438 flowEntry2.setFlowEntryErrorState(new FlowEntryErrorState());
439 flowEntry2.setFlowEntryUserState(FlowEntryUserState.FE_USER_ADD);
440
441 ArrayList<FlowEntry> flowEntries = new ArrayList<FlowEntry>();
442 flowEntries.add(flowEntry1);
443 flowEntries.add(flowEntry2);
444
445 DataPath dataPath = new DataPath();
446 dataPath.setSrcPort(new SwitchPort(new Dpid(0x1234), new Port((short)1)));
447 dataPath.setDstPort(new SwitchPort(new Dpid(0x5678), new Port((short)2)));
448 dataPath.setFlowEntries(flowEntries);
449
450 FlowEntryMatch match = new FlowEntryMatch();
451
452 FlowPath flowPath = new FlowPath();
453 flowPath.setFlowId(new FlowId(0x100));
454 flowPath.setInstallerId(new CallerId("installer id"));
455 flowPath.setFlowPathType(FlowPathType.valueOf("FP_TYPE_SHORTEST_PATH"));
456 flowPath.setFlowPathUserState(FlowPathUserState.valueOf("FP_USER_ADD"));
457 flowPath.setFlowPathFlags(new FlowPathFlags(0));
458 flowPath.setDataPath(dataPath);
459 flowPath.setFlowEntryMatch(match);
460
461 beginInitMock();
462
463 OFFlowMod msg = EasyMock.createMock(OFFlowMod.class);
464 EasyMock.expect(msg.setIdleTimeout(EasyMock.anyShort())).andReturn(msg);
465 EasyMock.expect(msg.setHardTimeout(EasyMock.anyShort())).andReturn(msg);
466 EasyMock.expect(msg.setPriority(EasyMock.anyShort())).andReturn(msg);
467 EasyMock.expect(msg.setBufferId(EasyMock.anyInt())).andReturn(msg);
468 EasyMock.expect(msg.setCookie(EasyMock.anyLong())).andReturn(msg);
469 EasyMock.expect(msg.setCommand(EasyMock.anyShort())).andReturn(msg);
470 EasyMock.expect(msg.setMatch(EasyMock.anyObject(OFMatch.class))).andReturn(msg);
471 EasyMock.expect(msg.setActions((List<OFAction>)EasyMock.anyObject())).andReturn(msg);
472 EasyMock.expect(msg.setLengthU(EasyMock.anyShort())).andReturn(msg);
473 EasyMock.expect(msg.setOutPort(EasyMock.anyShort())).andReturn(msg).atLeastOnce();
474 EasyMock.expect(msg.getXid()).andReturn(1).anyTimes();
475 EasyMock.expect(msg.getType()).andReturn(OFType.FLOW_MOD).anyTimes();
476 EasyMock.expect(msg.getLength()).andReturn((short)100).anyTimes();
477 EasyMock.replay(msg);
478
479 EasyMock.expect(factory.getMessage(EasyMock.eq(OFType.FLOW_MOD))).andReturn(msg);
480
481 ScheduledExecutorService executor = EasyMock.createMock(ScheduledExecutorService.class);
482 EasyMock.expect(executor.schedule((Runnable)EasyMock.anyObject(), EasyMock.anyLong(),
483 (TimeUnit)EasyMock.anyObject())).andReturn(null).once();
484 EasyMock.replay(executor);
485 EasyMock.expect(tpservice.getScheduledExecutor()).andReturn(executor);
486
487 IOFSwitch sw = EasyMock.createMock(IOFSwitch.class);
488 EasyMock.expect(sw.getId()).andReturn((long)1).anyTimes();
489 EasyMock.expect(sw.getStringId()).andReturn("1").anyTimes();
490 sw.flush();
491 EasyMock.expectLastCall().once();
492 EasyMock.replay(sw);
493
494 try {
495 EasyMock.expect(damper.write(EasyMock.eq(sw), EasyMock.anyObject(OFMessage.class), EasyMock.eq(context)))
496 .andAnswer(new IAnswer<Boolean>() {
497 @Override
498 public Boolean answer() throws Throwable {
499 OFMessage msg = (OFMessage)EasyMock.getCurrentArguments()[1];
500 assertEquals(msg.getType(), OFType.FLOW_MOD);
501 return true;
502 }
503 }).once();
504 } catch (IOException e1) {
505 fail("Failed in OFMessageDamper#write()");
506 }
507
508 endInitMock();
509 initPusher(1);
510
511 pusher.add(sw, flowPath, flowEntry1);
512
513 try {
514 Thread.sleep(1000);
515 } catch (InterruptedException e) {
516 fail("Failed to sleep");
517 }
518
519 EasyMock.verify(sw);
520
521 pusher.stop();
522 }
523
524 /**
525 * Test IFlowObject is correctly converted to message and is sent to a switch.
526 */
527 @SuppressWarnings("unchecked")
528 @Test
529 public void testAddIFlow() {
530 IFlowPath iFlowPath = createIFlowPathMock(1, "id", "FP_TYPE_SHORTEST_PATH", "FP_USER_ADD", 0, 1, 2, 3, 4);
531 IFlowEntry iFlowEntry = createMock(IFlowEntry.class);
532 BasicFactory basicFactory = createMock(BasicFactory.class);
533
534 FlowEntryAction action = new FlowEntryAction();
535 action.setActionOutput(new Port((short)2));
536 FlowEntryActions actions = new FlowEntryActions();
537 actions.addAction(action);
538
539 // setup expectations
540 EasyMock.expect(iFlowEntry.getFlowEntryId()).andReturn(new FlowEntryId(123).toString());
541 EasyMock.expect(iFlowEntry.getUserState()).andReturn("FE_USER_ADD");
542 iFlowEntry.setSwitchState("FE_SWITCH_UPDATED");
543 EasyMock.expect(iFlowEntry.getMatchInPort()).andReturn(new Short((short) 1));
544 EasyMock.expect(iFlowEntry.getMatchSrcMac()).andReturn("01:23:45:67:89:01");
545 EasyMock.expect(iFlowEntry.getMatchDstMac()).andReturn("01:23:45:67:89:02");
546 EasyMock.expect(iFlowEntry.getMatchEthernetFrameType()).andReturn(new Short((short)0x0800));
547 EasyMock.expect(iFlowEntry.getMatchVlanId()).andReturn(new Short((short)0x1234));
548 EasyMock.expect(iFlowEntry.getMatchVlanPriority()).andReturn(new Byte((byte)0x10));
549 EasyMock.expect(iFlowEntry.getMatchSrcIPv4Net()).andReturn("192.168.0.1");
550 EasyMock.expect(iFlowEntry.getMatchDstIPv4Net()).andReturn("192.168.0.2");
551 EasyMock.expect(iFlowEntry.getMatchIpProto()).andReturn(new Byte((byte)0x20));
552 EasyMock.expect(iFlowEntry.getMatchIpToS()).andReturn(new Byte((byte)0x3));
553 EasyMock.expect(iFlowEntry.getMatchSrcTcpUdpPort()).andReturn(new Short((short)40000));
554 EasyMock.expect(iFlowEntry.getMatchDstTcpUdpPort()).andReturn(new Short((short)80));
555 EasyMock.expect(iFlowEntry.getActions()).andReturn(actions.toString());
556 EasyMock.expect(basicFactory.getMessage(OFType.FLOW_MOD)).andReturn(new OFFlowMod());
557
558 EasyMock.replay(iFlowEntry);
559 EasyMock.replay(iFlowPath);
560
561 beginInitMock();
562
563 OFFlowMod msg = EasyMock.createMock(OFFlowMod.class);
564 EasyMock.expect(msg.setIdleTimeout(EasyMock.anyShort())).andReturn(msg);
565 EasyMock.expect(msg.setHardTimeout(EasyMock.anyShort())).andReturn(msg);
566 EasyMock.expect(msg.setPriority(EasyMock.anyShort())).andReturn(msg);
567 EasyMock.expect(msg.setBufferId(EasyMock.anyInt())).andReturn(msg);
568 EasyMock.expect(msg.setCookie(EasyMock.anyLong())).andReturn(msg);
569 EasyMock.expect(msg.setCommand(EasyMock.anyShort())).andReturn(msg);
570 EasyMock.expect(msg.setMatch(EasyMock.anyObject(OFMatch.class))).andReturn(msg);
571 EasyMock.expect(msg.setActions((List<OFAction>)EasyMock.anyObject())).andReturn(msg);
572 EasyMock.expect(msg.setLengthU(EasyMock.anyShort())).andReturn(msg);
573 EasyMock.expect(msg.setOutPort(EasyMock.anyShort())).andReturn(msg).atLeastOnce();
574 EasyMock.expect(msg.getXid()).andReturn(1).anyTimes();
575 EasyMock.expect(msg.getType()).andReturn(OFType.FLOW_MOD).anyTimes();
576 EasyMock.expect(msg.getLength()).andReturn((short)100).anyTimes();
577 EasyMock.replay(msg);
578
579 EasyMock.expect(factory.getMessage(EasyMock.eq(OFType.FLOW_MOD))).andReturn(msg);
580
581 ScheduledExecutorService executor = EasyMock.createMock(ScheduledExecutorService.class);
582 EasyMock.expect(executor.schedule((Runnable)EasyMock.anyObject(), EasyMock.anyLong(),
583 (TimeUnit)EasyMock.anyObject())).andReturn(null).once();
584 EasyMock.replay(executor);
585 EasyMock.expect(tpservice.getScheduledExecutor()).andReturn(executor);
586
587 IOFSwitch sw = EasyMock.createMock(IOFSwitch.class);
588 EasyMock.expect(sw.getId()).andReturn((long)1).anyTimes();
589 EasyMock.expect(sw.getStringId()).andReturn("1").anyTimes();
590 sw.flush();
591 EasyMock.expectLastCall().once();
592 EasyMock.replay(sw);
593
594 try {
595 EasyMock.expect(damper.write(EasyMock.eq(sw), EasyMock.anyObject(OFMessage.class), EasyMock.eq(context)))
596 .andAnswer(new IAnswer<Boolean>() {
597 @Override
598 public Boolean answer() throws Throwable {
599 OFMessage msg = (OFMessage)EasyMock.getCurrentArguments()[1];
600 assertEquals(msg.getType(), OFType.FLOW_MOD);
601 return true;
602 }
603 }).once();
604 } catch (IOException e1) {
605 fail("Failed in OFMessageDamper#write()");
606 }
607
608 endInitMock();
609 initPusher(1);
610
611 pusher.add(sw, iFlowPath, iFlowEntry);
612
613 try {
614 Thread.sleep(1000);
615 } catch (InterruptedException e) {
616 fail("Failed to sleep");
617 }
618
619 EasyMock.verify(sw);
620
621 pusher.stop();
622 }
623
624 private void beginInitMock() {
625 context = EasyMock.createMock(FloodlightContext.class);
626 modContext = EasyMock.createMock(FloodlightModuleContext.class);
627 factory = EasyMock.createMock(BasicFactory.class);
628 damper = EasyMock.createMock(OFMessageDamper.class);
629 flservice = EasyMock.createMock(IFloodlightProviderService.class);
630 tpservice = EasyMock.createMock(IThreadPoolService.class);
631
632 EasyMock.expect(modContext.getServiceImpl(EasyMock.eq(IThreadPoolService.class)))
633 .andReturn(tpservice).once();
634 EasyMock.expect(modContext.getServiceImpl(EasyMock.eq(IFloodlightProviderService.class)))
635 .andReturn(flservice).once();
636 flservice.addOFMessageListener(EasyMock.eq(OFType.BARRIER_REPLY),
637 (FlowPusher) EasyMock.anyObject());
638 EasyMock.expectLastCall().once();
639 }
640
641 private void endInitMock() {
642 EasyMock.replay(tpservice);
643 EasyMock.replay(flservice);
644 EasyMock.replay(damper);
645 EasyMock.replay(factory);
646 EasyMock.replay(modContext);
647 EasyMock.replay(context);
648 }
649
650 private void initPusher(int num_thread) {
651 pusher = new FlowPusher(num_thread);
652 pusher.init(context, modContext, factory, damper);
653 pusher.start();
654 }
655
656 private void prepareBarrier(IOFSwitch sw) {
657 OFBarrierRequest req = EasyMock.createMock(OFBarrierRequest.class);
658 req.setXid(EasyMock.anyInt());
659 EasyMock.expectLastCall().once();
660 EasyMock.expect(req.getXid()).andReturn(1).anyTimes();
661 EasyMock.expect(req.getType()).andReturn(OFType.BARRIER_REQUEST).anyTimes();
662 EasyMock.expect(req.getLength()).andReturn((short)100).anyTimes();
663 EasyMock.replay(req);
664 EasyMock.expect(factory.getMessage(EasyMock.eq(OFType.BARRIER_REQUEST))).andReturn(req);
665
666 ScheduledExecutorService executor = EasyMock.createMock(ScheduledExecutorService.class);
667 EasyMock.expect(executor.schedule((Runnable)EasyMock.anyObject(), EasyMock.anyLong(),
668 (TimeUnit)EasyMock.anyObject())).andReturn(null).once();
669 EasyMock.replay(executor);
670 EasyMock.expect(tpservice.getScheduledExecutor()).andReturn(executor);
671
672 EasyMock.expect(sw.getNextTransactionId()).andReturn(1);
673 }
674
675 // Copied from FlowManagerTest
676 private IFlowPath createIFlowPathMock(long flowId, String installerID,
677 String flowPathType, String flowPathUserState,
678 long flowPathFlags, long srcDpid, int srcPort,
679 long dstDpid, int dstPort) {
680 IFlowPath iFlowPath = EasyMock.createNiceMock(IFlowPath.class);
681 EasyMock.expect(iFlowPath.getFlowId()).andReturn(new FlowId(flowId).toString()).anyTimes();
682 EasyMock.expect(iFlowPath.getInstallerId()).andReturn(installerID).anyTimes();
683 EasyMock.expect(iFlowPath.getFlowPathType()).andReturn(flowPathType).anyTimes();
684 EasyMock.expect(iFlowPath.getFlowPathUserState()).andReturn(flowPathUserState).anyTimes();
685 EasyMock.expect(iFlowPath.getFlowPathFlags()).andReturn(new Long(flowPathFlags)).anyTimes();
686 EasyMock.expect(iFlowPath.getSrcSwitch()).andReturn(new Dpid(srcDpid).toString()).anyTimes();
687 EasyMock.expect(iFlowPath.getSrcPort()).andReturn(new Short((short)srcPort)).anyTimes();
688 EasyMock.expect(iFlowPath.getDstSwitch()).andReturn(new Dpid(dstDpid).toString()).anyTimes();
689 EasyMock.expect(iFlowPath.getDstPort()).andReturn(new Short((short)dstPort)).anyTimes();
690 return iFlowPath;
691 }
692
693}