blob: d963dedc57e5c392ebb18341c76ef818f1aedba0 [file] [log] [blame]
Jonathan Hart23701d12014-04-03 10:45:48 -07001package net.onrc.onos.core.flowprogrammer;
Naoki Shiota75b7dd62013-12-03 18:09:21 -08002
Brian O'Connorc67f9fa2014-08-07 18:17:46 -07003
Sho SHIMIZU107344e2014-08-13 16:11:53 -07004import static org.easymock.EasyMock.anyInt;
5import static org.easymock.EasyMock.anyLong;
6import static org.easymock.EasyMock.anyObject;
7import static org.easymock.EasyMock.anyShort;
8import static org.easymock.EasyMock.createMock;
9import static org.easymock.EasyMock.eq;
10import static org.easymock.EasyMock.expect;
11import static org.easymock.EasyMock.expectLastCall;
12import static org.easymock.EasyMock.replay;
13import static org.easymock.EasyMock.verify;
Naoki Shiota47993102014-07-09 14:00:54 -070014import static org.junit.Assert.assertNotNull;
15import static org.junit.Assert.assertTrue;
16import static org.junit.Assert.fail;
17
18import java.io.IOException;
19import java.util.ArrayList;
20import java.util.HashMap;
21import java.util.List;
22import java.util.Map;
23import java.util.concurrent.ScheduledExecutorService;
24import java.util.concurrent.TimeUnit;
25
Naoki Shiota75b7dd62013-12-03 18:09:21 -080026import net.floodlightcontroller.core.FloodlightContext;
27import net.floodlightcontroller.core.IFloodlightProviderService;
28import net.floodlightcontroller.core.IOFSwitch;
Brian O'Connorc67f9fa2014-08-07 18:17:46 -070029import net.floodlightcontroller.core.internal.OFMessageFuture;
Naoki Shiota75b7dd62013-12-03 18:09:21 -080030import net.floodlightcontroller.core.module.FloodlightModuleContext;
31import net.floodlightcontroller.threadpool.IThreadPoolService;
Brian O'Connorc67f9fa2014-08-07 18:17:46 -070032import net.onrc.onos.core.intent.FlowEntry;
33import net.onrc.onos.core.intent.IntentOperation.Operator;
Ray Milkey10643572014-06-10 15:17:39 -070034import net.onrc.onos.core.util.IntegrationTest;
Naoki Shiota47993102014-07-09 14:00:54 -070035
Naoki Shiota75b7dd62013-12-03 18:09:21 -080036import org.junit.Test;
Ray Milkey10643572014-06-10 15:17:39 -070037import org.junit.experimental.categories.Category;
Brian O'Connorc67f9fa2014-08-07 18:17:46 -070038import org.projectfloodlight.openflow.protocol.OFBarrierReply;
39import org.projectfloodlight.openflow.protocol.OFBarrierRequest;
40import org.projectfloodlight.openflow.protocol.OFFactories;
41import org.projectfloodlight.openflow.protocol.OFFactory;
42import org.projectfloodlight.openflow.protocol.OFFlowModify;
43import org.projectfloodlight.openflow.protocol.OFMessage;
44import org.projectfloodlight.openflow.protocol.OFType;
45import org.projectfloodlight.openflow.protocol.OFVersion;
46import org.projectfloodlight.openflow.protocol.action.OFAction;
47import org.projectfloodlight.openflow.protocol.match.Match;
48import org.projectfloodlight.openflow.types.OFBufferId;
49import org.projectfloodlight.openflow.types.OFPort;
50import org.projectfloodlight.openflow.types.U64;
51
Naoki Shiota75b7dd62013-12-03 18:09:21 -080052
Ray Milkey10643572014-06-10 15:17:39 -070053@Category(IntegrationTest.class)
Naoki Shiota75b7dd62013-12-03 18:09:21 -080054public class FlowPusherTest {
Ray Milkey269ffb92014-04-03 14:43:30 -070055 private FlowPusher pusher;
56 private FloodlightContext context;
57 private FloodlightModuleContext modContext;
Ray Milkey269ffb92014-04-03 14:43:30 -070058 private IFloodlightProviderService flProviderService;
59 private IThreadPoolService threadPoolService;
Naoki Shiota75b7dd62013-12-03 18:09:21 -080060
Brian O'Connorc67f9fa2014-08-07 18:17:46 -070061 private OFFactory factory10 = OFFactories.getFactory(OFVersion.OF_10);
62
Ray Milkey269ffb92014-04-03 14:43:30 -070063 /**
Jonathan Hart51bb27c2014-08-11 16:00:31 -070064 * Test single OFMessage is correctly sent to single switch.
Ray Milkey269ffb92014-04-03 14:43:30 -070065 */
66 @Test
67 public void testAddMessage() {
68 beginInitMock();
Naoki Shiota75b7dd62013-12-03 18:09:21 -080069
Sho SHIMIZU107344e2014-08-13 16:11:53 -070070 OFMessage msg = createMock(OFMessage.class);
71 expect(msg.getXid()).andReturn((long) 1).anyTimes();
Brian O'Connorc67f9fa2014-08-07 18:17:46 -070072 //EasyMock.expect(msg.()).andReturn((short) 100).anyTimes();
Sho SHIMIZU107344e2014-08-13 16:11:53 -070073 replay(msg);
Naoki Shiota75b7dd62013-12-03 18:09:21 -080074
Naoki Shiota47993102014-07-09 14:00:54 -070075 IOFSwitch sw = createConnectedSwitchMock(1, false);
Brian O'Connorc67f9fa2014-08-07 18:17:46 -070076
77
Naoki Shiotad6ef3b32014-03-13 18:42:23 -070078
Ray Milkey269ffb92014-04-03 14:43:30 -070079 try {
Sho SHIMIZU107344e2014-08-13 16:11:53 -070080 sw.write(eq(msg), eq((FloodlightContext) null));
81 expectLastCall().once();
82 replay(sw);
Ray Milkey269ffb92014-04-03 14:43:30 -070083 } catch (IOException e1) {
Brian O'Connorc67f9fa2014-08-07 18:17:46 -070084 fail("Failed in IOFSwitch#write()");
Ray Milkey269ffb92014-04-03 14:43:30 -070085 }
Naoki Shiota75b7dd62013-12-03 18:09:21 -080086
Ray Milkey269ffb92014-04-03 14:43:30 -070087 endInitMock();
88 initPusher(1);
Naoki Shiotad6ef3b32014-03-13 18:42:23 -070089
Yuta HIGUCHI44a0b352014-05-14 21:32:48 -070090 boolean addResult = pusher.add(sw, msg);
91 assertTrue(addResult);
Naoki Shiota75b7dd62013-12-03 18:09:21 -080092
Ray Milkey269ffb92014-04-03 14:43:30 -070093 try {
94 // wait until message is processed.
95 Thread.sleep(1000);
96 } catch (InterruptedException e) {
97 fail("Failed in Thread.sleep()");
98 }
Sho SHIMIZU107344e2014-08-13 16:11:53 -070099 verify(msg);
100 verify(sw);
Ray Milkey269ffb92014-04-03 14:43:30 -0700101 verifyAll();
Naoki Shiota75b7dd62013-12-03 18:09:21 -0800102
Ray Milkey269ffb92014-04-03 14:43:30 -0700103 pusher.stop();
104 }
Naoki Shiota75b7dd62013-12-03 18:09:21 -0800105
Ray Milkey269ffb92014-04-03 14:43:30 -0700106 /**
Jonathan Hart51bb27c2014-08-11 16:00:31 -0700107 * Test bunch of OFMessages are correctly sent to single switch.
Ray Milkey269ffb92014-04-03 14:43:30 -0700108 */
109 @Test
110 public void testMassiveAddMessage() {
Yuta HIGUCHI7c39c842014-06-09 16:33:03 -0700111 // Some number larger than FlowPusher.MAX_MESSAGE_SEND
Yuta HIGUCHI91a8f502014-06-17 10:15:29 -0700112 final int numMsg = FlowPusher.MAX_MESSAGE_SEND * 2;
Naoki Shiotad6ef3b32014-03-13 18:42:23 -0700113
Ray Milkey269ffb92014-04-03 14:43:30 -0700114 beginInitMock();
Naoki Shiota75b7dd62013-12-03 18:09:21 -0800115
Naoki Shiota47993102014-07-09 14:00:54 -0700116 IOFSwitch sw = createConnectedSwitchMock(1, false);
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700117
Naoki Shiota75b7dd62013-12-03 18:09:21 -0800118
Ray Milkey269ffb92014-04-03 14:43:30 -0700119 List<OFMessage> messages = new ArrayList<OFMessage>();
Naoki Shiota75b7dd62013-12-03 18:09:21 -0800120
Yuta HIGUCHI91a8f502014-06-17 10:15:29 -0700121 for (int i = 0; i < numMsg; ++i) {
Sho SHIMIZU107344e2014-08-13 16:11:53 -0700122 OFMessage msg = createMock(OFMessage.class);
123 expect(msg.getXid()).andReturn((long) i).anyTimes();
124 replay(msg);
Ray Milkey269ffb92014-04-03 14:43:30 -0700125 messages.add(msg);
Naoki Shiota75b7dd62013-12-03 18:09:21 -0800126
Ray Milkey269ffb92014-04-03 14:43:30 -0700127 try {
Sho SHIMIZU107344e2014-08-13 16:11:53 -0700128 sw.write(eq(msg), eq((FloodlightContext) null));
129 expectLastCall().once();
Ray Milkey269ffb92014-04-03 14:43:30 -0700130 } catch (IOException e1) {
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700131 fail("Failed in IOFSwitch#write()");
Ray Milkey269ffb92014-04-03 14:43:30 -0700132 }
133 }
Sho SHIMIZU107344e2014-08-13 16:11:53 -0700134 replay(sw);
Ray Milkey269ffb92014-04-03 14:43:30 -0700135 endInitMock();
136 initPusher(1);
Naoki Shiota75b7dd62013-12-03 18:09:21 -0800137
Ray Milkey269ffb92014-04-03 14:43:30 -0700138 for (OFMessage msg : messages) {
Yuta HIGUCHI44a0b352014-05-14 21:32:48 -0700139 boolean addResult = pusher.add(sw, msg);
140 assertTrue(addResult);
Ray Milkey269ffb92014-04-03 14:43:30 -0700141 }
Naoki Shiota75b7dd62013-12-03 18:09:21 -0800142
Ray Milkey269ffb92014-04-03 14:43:30 -0700143 try {
144 // wait until message is processed.
Yuta HIGUCHI7c39c842014-06-09 16:33:03 -0700145 Thread.sleep(1000);
Ray Milkey269ffb92014-04-03 14:43:30 -0700146 } catch (InterruptedException e) {
147 fail("Failed in Thread.sleep()");
148 }
Naoki Shiotad6ef3b32014-03-13 18:42:23 -0700149
Ray Milkey269ffb92014-04-03 14:43:30 -0700150 for (OFMessage msg : messages) {
Sho SHIMIZU107344e2014-08-13 16:11:53 -0700151 verify(msg);
Ray Milkey269ffb92014-04-03 14:43:30 -0700152 }
Sho SHIMIZU107344e2014-08-13 16:11:53 -0700153 verify(sw);
Ray Milkey269ffb92014-04-03 14:43:30 -0700154 verifyAll();
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() {
Yuta HIGUCHI91a8f502014-06-17 10:15:29 -0700164 final int numSwitch = 10;
165 final int numMsg = 100; // messages per thread
Ray Milkey269ffb92014-04-03 14:43:30 -0700166
167 beginInitMock();
168
Yuta HIGUCHI44a0b352014-05-14 21:32:48 -0700169 Map<IOFSwitch, List<OFMessage>> swMap = new HashMap<IOFSwitch, List<OFMessage>>();
Yuta HIGUCHI91a8f502014-06-17 10:15:29 -0700170 for (int i = 0; i < numSwitch; ++i) {
Naoki Shiota47993102014-07-09 14:00:54 -0700171 IOFSwitch sw = createConnectedSwitchMock(i, false);
Ray Milkey269ffb92014-04-03 14:43:30 -0700172
173 List<OFMessage> messages = new ArrayList<OFMessage>();
174
Yuta HIGUCHI91a8f502014-06-17 10:15:29 -0700175 for (int j = 0; j < numMsg; ++j) {
Sho SHIMIZU107344e2014-08-13 16:11:53 -0700176 OFMessage msg = createMock(OFMessage.class);
177 expect(msg.getXid()).andReturn((long) j).anyTimes();
178 replay(msg);
Ray Milkey269ffb92014-04-03 14:43:30 -0700179 messages.add(msg);
180
181 try {
Sho SHIMIZU107344e2014-08-13 16:11:53 -0700182 sw.write(eq(msg), eq((FloodlightContext) null));
183 expectLastCall().once();
Ray Milkey269ffb92014-04-03 14:43:30 -0700184 } catch (IOException e1) {
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700185 fail("Failed in IOFWrite#write()");
Ray Milkey269ffb92014-04-03 14:43:30 -0700186 }
187 }
Yuta HIGUCHI44a0b352014-05-14 21:32:48 -0700188 swMap.put(sw, messages);
Sho SHIMIZU107344e2014-08-13 16:11:53 -0700189 replay(sw);
Ray Milkey269ffb92014-04-03 14:43:30 -0700190 }
191
192 endInitMock();
193 initPusher(1);
194
Yuta HIGUCHI44a0b352014-05-14 21:32:48 -0700195 for (IOFSwitch sw : swMap.keySet()) {
196 for (OFMessage msg : swMap.get(sw)) {
197 boolean addResult = pusher.add(sw, msg);
198 assertTrue(addResult);
Ray Milkey269ffb92014-04-03 14:43:30 -0700199 }
200 }
201
202 try {
203 // wait until message is processed.
204 Thread.sleep(1000);
205 } catch (InterruptedException e) {
206 fail("Failed in Thread.sleep()");
207 }
208
Yuta HIGUCHI44a0b352014-05-14 21:32:48 -0700209 for (IOFSwitch sw : swMap.keySet()) {
210 for (OFMessage msg : swMap.get(sw)) {
Sho SHIMIZU107344e2014-08-13 16:11:53 -0700211 verify(msg);
Ray Milkey269ffb92014-04-03 14:43:30 -0700212 }
213
Sho SHIMIZU107344e2014-08-13 16:11:53 -0700214 verify(sw);
Ray Milkey269ffb92014-04-03 14:43:30 -0700215 }
216 verifyAll();
217
218 pusher.stop();
219 }
220
221 /**
222 * Test bunch of OFMessages are correctly sent to multiple switches using multiple threads.
223 */
224 @Test
225 public void testMultiThreadedAddMessage() {
Yuta HIGUCHI91a8f502014-06-17 10:15:29 -0700226 final int numThreads = 10;
227 final int numMsg = 100; // messages per thread
Ray Milkey269ffb92014-04-03 14:43:30 -0700228
229 beginInitMock();
230
Yuta HIGUCHI44a0b352014-05-14 21:32:48 -0700231 Map<IOFSwitch, List<OFMessage>> swMap = new HashMap<IOFSwitch, List<OFMessage>>();
Yuta HIGUCHI91a8f502014-06-17 10:15:29 -0700232 for (int i = 0; i < numThreads; ++i) {
Naoki Shiota47993102014-07-09 14:00:54 -0700233 IOFSwitch sw = createConnectedSwitchMock(i, false);
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700234 //EasyMock.replay(sw);
Ray Milkey269ffb92014-04-03 14:43:30 -0700235
236 List<OFMessage> messages = new ArrayList<OFMessage>();
237
Yuta HIGUCHI91a8f502014-06-17 10:15:29 -0700238 for (int j = 0; j < numMsg; ++j) {
Sho SHIMIZU107344e2014-08-13 16:11:53 -0700239 OFMessage msg = createMock(OFMessage.class);
240 expect(msg.getXid()).andReturn((long) j).anyTimes();
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700241
Sho SHIMIZU107344e2014-08-13 16:11:53 -0700242 replay(msg);
Ray Milkey269ffb92014-04-03 14:43:30 -0700243 messages.add(msg);
244
245 try {
Sho SHIMIZU107344e2014-08-13 16:11:53 -0700246 sw.write(eq(msg), eq((FloodlightContext) null));
247 expectLastCall().once();
Ray Milkey269ffb92014-04-03 14:43:30 -0700248 } catch (IOException e1) {
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700249 fail("Failed in IOFWrite#write()");
Ray Milkey269ffb92014-04-03 14:43:30 -0700250 }
251 }
Yuta HIGUCHI44a0b352014-05-14 21:32:48 -0700252 swMap.put(sw, messages);
Sho SHIMIZU107344e2014-08-13 16:11:53 -0700253 replay(sw);
Ray Milkey269ffb92014-04-03 14:43:30 -0700254 }
255
256 endInitMock();
Yuta HIGUCHI91a8f502014-06-17 10:15:29 -0700257 initPusher(numThreads);
Yuta HIGUCHI44a0b352014-05-14 21:32:48 -0700258 for (IOFSwitch sw : swMap.keySet()) {
259 for (OFMessage msg : swMap.get(sw)) {
260 boolean addResult = pusher.add(sw, msg);
261 assertTrue(addResult);
Ray Milkey269ffb92014-04-03 14:43:30 -0700262 }
263 }
264
265 try {
266 // wait until message is processed.
267 Thread.sleep(1000);
268 } catch (InterruptedException e) {
269 fail("Failed in Thread.sleep()");
270 }
271
Yuta HIGUCHI44a0b352014-05-14 21:32:48 -0700272 for (IOFSwitch sw : swMap.keySet()) {
273 for (OFMessage msg : swMap.get(sw)) {
Sho SHIMIZU107344e2014-08-13 16:11:53 -0700274 verify(msg);
Ray Milkey269ffb92014-04-03 14:43:30 -0700275 }
276
Sho SHIMIZU107344e2014-08-13 16:11:53 -0700277 verify(sw);
Ray Milkey269ffb92014-04-03 14:43:30 -0700278 }
279 verifyAll();
280
281 pusher.stop();
282 }
283
284 private long barrierTime = 0;
285
286 /**
287 * Test rate limitation of messages works correctly.
288 */
289 @Test
290 public void testRateLimitedAddMessage() {
Yuta HIGUCHI91a8f502014-06-17 10:15:29 -0700291 final long limitRate = 100; // [bytes/ms]
292 final int numMsg = 1000;
Ray Milkey269ffb92014-04-03 14:43:30 -0700293
294 // Accuracy of FlowPusher's rate calculation can't be measured by unit test
295 // because switch doesn't return BARRIER_REPLY.
296 // In unit test we use approximate way to measure rate. This value is
297 // acceptable margin of measured rate.
Yuta HIGUCHI91a8f502014-06-17 10:15:29 -0700298 final double acceptableRate = limitRate * 1.2;
Ray Milkey269ffb92014-04-03 14:43:30 -0700299
300 beginInitMock();
301
Naoki Shiota47993102014-07-09 14:00:54 -0700302 IOFSwitch sw = createConnectedSwitchMock(1, true);
Sho SHIMIZU107344e2014-08-13 16:11:53 -0700303 expect(sw.getOFVersion()).andReturn(OFVersion.OF_10).once();
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700304
Ray Milkey269ffb92014-04-03 14:43:30 -0700305
306 List<OFMessage> messages = new ArrayList<OFMessage>();
307
Yuta HIGUCHI91a8f502014-06-17 10:15:29 -0700308 for (int i = 0; i < numMsg; ++i) {
Sho SHIMIZU107344e2014-08-13 16:11:53 -0700309 OFMessage msg = createMock(OFMessage.class);
310 expect(msg.getXid()).andReturn((long) 1).anyTimes();
311 replay(msg);
Ray Milkey269ffb92014-04-03 14:43:30 -0700312 messages.add(msg);
313
314 try {
Sho SHIMIZU107344e2014-08-13 16:11:53 -0700315 sw.write(eq(msg), eq((FloodlightContext) null));
316 expectLastCall().once();
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700317 } catch (IOException e1) {
318 fail("Failed in IOFWrite#write()");
Ray Milkey269ffb92014-04-03 14:43:30 -0700319 }
320 }
321
322 try {
Sho SHIMIZU107344e2014-08-13 16:11:53 -0700323 sw.write(anyObject(OFBarrierRequest.class), eq((FloodlightContext) null));
324 expectLastCall().once();
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700325 barrierTime = System.currentTimeMillis();
Ray Milkey269ffb92014-04-03 14:43:30 -0700326 } catch (IOException e1) {
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700327 fail("Failed in IOFWrite#write()");
Ray Milkey269ffb92014-04-03 14:43:30 -0700328 }
329
Sho SHIMIZU107344e2014-08-13 16:11:53 -0700330 replay(sw);
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700331
Ray Milkey269ffb92014-04-03 14:43:30 -0700332 endInitMock();
333 initPusher(1);
334
335 pusher.createQueue(sw);
Yuta HIGUCHI91a8f502014-06-17 10:15:29 -0700336 pusher.setRate(sw, limitRate);
Ray Milkey269ffb92014-04-03 14:43:30 -0700337
338 long beginTime = System.currentTimeMillis();
339 for (OFMessage msg : messages) {
Yuta HIGUCHI44a0b352014-05-14 21:32:48 -0700340 boolean addResult = pusher.add(sw, msg);
341 assertTrue(addResult);
Ray Milkey269ffb92014-04-03 14:43:30 -0700342 }
343
344 pusher.barrierAsync(sw);
345
346 try {
347 do {
348 Thread.sleep(1000);
349 } while (barrierTime == 0);
350 } catch (InterruptedException e) {
351 fail("Failed to sleep");
352 }
353
Yuta HIGUCHI91a8f502014-06-17 10:15:29 -0700354 double measuredRate = numMsg * 100 / (barrierTime - beginTime);
355 assertTrue(measuredRate < acceptableRate);
Ray Milkey269ffb92014-04-03 14:43:30 -0700356
357 for (OFMessage msg : messages) {
Sho SHIMIZU107344e2014-08-13 16:11:53 -0700358 verify(msg);
Ray Milkey269ffb92014-04-03 14:43:30 -0700359 }
Sho SHIMIZU107344e2014-08-13 16:11:53 -0700360 verify(sw);
Ray Milkey269ffb92014-04-03 14:43:30 -0700361 verifyAll();
362
363 pusher.stop();
364 }
365
366 /**
367 * Test barrier message is correctly sent to a switch.
368 */
369 @Test
370 public void testBarrierMessage() {
371 beginInitMock();
372
Naoki Shiota47993102014-07-09 14:00:54 -0700373 IOFSwitch sw = createConnectedSwitchMock(1, true);
Sho SHIMIZU107344e2014-08-13 16:11:53 -0700374 expect(sw.getOFVersion()).andReturn(OFVersion.OF_10).once();
Ray Milkey269ffb92014-04-03 14:43:30 -0700375
376 try {
Sho SHIMIZU107344e2014-08-13 16:11:53 -0700377 sw.write((OFMessage) anyObject(), eq((FloodlightContext) null));
378 expectLastCall().once();
Ray Milkey269ffb92014-04-03 14:43:30 -0700379 } catch (IOException e1) {
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700380 fail("Failed in IOFWrite#write()");
Ray Milkey269ffb92014-04-03 14:43:30 -0700381 }
Sho SHIMIZU107344e2014-08-13 16:11:53 -0700382 replay(sw);
Ray Milkey269ffb92014-04-03 14:43:30 -0700383 endInitMock();
384 initPusher(1);
385
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700386 OFMessageFuture<OFBarrierReply> future = pusher.barrierAsync(sw);
Ray Milkey269ffb92014-04-03 14:43:30 -0700387
388 assertNotNull(future);
389
390 try {
391 Thread.sleep(1000);
392 } catch (InterruptedException e) {
393 fail("Failed to sleep");
394 }
395
396 verifyAll();
397
398 pusher.stop();
399 }
400
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700401 static final long XID_TO_VERIFY = 100;
Ray Milkey269ffb92014-04-03 14:43:30 -0700402 static final long DPID_TO_VERIFY = 10;
403
404 /**
405 * Test FlowObject is correctly converted to message and is sent to a switch.
406 */
407 @SuppressWarnings("unchecked")
408 @Test
409 public void testAddFlow() {
410 // instantiate required objects
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700411 FlowEntry flowEntry1 = new FlowEntry(DPID_TO_VERIFY, 1, 11, null, null, 0, 0, Operator.ADD);
412 /*
Ray Milkey269ffb92014-04-03 14:43:30 -0700413 flowEntry1.setDpid(new Dpid(DPID_TO_VERIFY));
414 flowEntry1.setFlowId(new FlowId(1));
Yuta HIGUCHIfb564502014-06-16 21:29:00 -0700415 flowEntry1.setInPort(new PortNumber((short) 1));
416 flowEntry1.setOutPort(new PortNumber((short) 11));
Ray Milkey269ffb92014-04-03 14:43:30 -0700417 flowEntry1.setFlowEntryId(new FlowEntryId(1));
418 flowEntry1.setFlowEntryMatch(new FlowEntryMatch());
419 flowEntry1.setFlowEntryActions(new FlowEntryActions());
420 flowEntry1.setFlowEntryErrorState(new FlowEntryErrorState());
421 flowEntry1.setFlowEntryUserState(FlowEntryUserState.FE_USER_ADD);
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700422 */
Ray Milkey269ffb92014-04-03 14:43:30 -0700423
424 beginInitMock();
425
Sho SHIMIZU107344e2014-08-13 16:11:53 -0700426 OFFlowModify fm = createMock(OFFlowModify.class);
Ray Milkey269ffb92014-04-03 14:43:30 -0700427
Sho SHIMIZU107344e2014-08-13 16:11:53 -0700428 OFFlowModify.Builder bld = createMock(OFFlowModify.Builder.class);
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700429
Sho SHIMIZU107344e2014-08-13 16:11:53 -0700430 expect(bld.setIdleTimeout(anyInt())).andReturn(bld);
431 expect(bld.setHardTimeout(anyInt())).andReturn(bld);
432 expect(bld.setPriority(anyShort())).andReturn(bld);
433 expect(bld.setBufferId(OFBufferId.NO_BUFFER)).andReturn(bld);
434 expect(bld.setCookie(U64.of(anyLong()))).andReturn(bld);
435 expect(bld.setMatch(anyObject(Match.class))).andReturn(bld);
436 expect(bld.setActions((List<OFAction>) anyObject())).andReturn(bld);
437 expect(bld.setOutPort(OFPort.of(anyInt()))).andReturn(bld).atLeastOnce();
438 expect(bld.build()).andReturn(fm);
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700439
Sho SHIMIZU107344e2014-08-13 16:11:53 -0700440 expect(fm.getXid()).andReturn(XID_TO_VERIFY).anyTimes();
441 expect(fm.getType()).andReturn(OFType.FLOW_MOD).anyTimes();
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700442
443
444
Ray Milkey269ffb92014-04-03 14:43:30 -0700445
Naoki Shiota47993102014-07-09 14:00:54 -0700446 IOFSwitch sw = createConnectedSwitchMock(DPID_TO_VERIFY, false);
Sho SHIMIZU107344e2014-08-13 16:11:53 -0700447 expect(sw.getStringId()).andReturn("1").anyTimes();
448 expect(sw.getOFVersion()).andReturn(OFVersion.OF_10).once();
Ray Milkey269ffb92014-04-03 14:43:30 -0700449
450 try {
Sho SHIMIZU107344e2014-08-13 16:11:53 -0700451 sw.write(anyObject(OFMessage.class), eq((FloodlightContext) null));
452 expectLastCall().once();
Ray Milkey269ffb92014-04-03 14:43:30 -0700453 } catch (IOException e1) {
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700454 fail("Failed in IOFWrite#write()");
Ray Milkey269ffb92014-04-03 14:43:30 -0700455 }
456
Sho SHIMIZU107344e2014-08-13 16:11:53 -0700457 replay(bld, fm);
458 replay(sw);
Ray Milkey269ffb92014-04-03 14:43:30 -0700459
460 endInitMock();
461 initPusher(1);
462
463 pusher.pushFlowEntry(sw, flowEntry1);
464
465 try {
466 Thread.sleep(1000);
467 } catch (InterruptedException e) {
468 fail("Failed to sleep");
469 }
470
Sho SHIMIZU107344e2014-08-13 16:11:53 -0700471 verify(sw);
Ray Milkey269ffb92014-04-03 14:43:30 -0700472 verifyAll();
473
474 pusher.stop();
475 }
476
477 private void beginInitMock() {
Sho SHIMIZU107344e2014-08-13 16:11:53 -0700478 context = createMock(FloodlightContext.class);
479 modContext = createMock(FloodlightModuleContext.class);
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700480 // AAS: I don't think we should mock factories... the rabbit whole is too deep.
481 //factory10 = EasyMock.createMock(OFFactories.getFactory(OFVersion.OF_10).getClass());
Sho SHIMIZU107344e2014-08-13 16:11:53 -0700482 flProviderService = createMock(IFloodlightProviderService.class);
483 threadPoolService = createMock(IThreadPoolService.class);
Ray Milkey269ffb92014-04-03 14:43:30 -0700484
Sho SHIMIZU107344e2014-08-13 16:11:53 -0700485 expect(modContext.getServiceImpl(eq(IThreadPoolService.class)))
Ray Milkey269ffb92014-04-03 14:43:30 -0700486 .andReturn(threadPoolService).once();
Sho SHIMIZU107344e2014-08-13 16:11:53 -0700487 expect(modContext.getServiceImpl(eq(IFloodlightProviderService.class)))
Ray Milkey269ffb92014-04-03 14:43:30 -0700488 .andReturn(flProviderService).once();
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700489 // AAS: FlowPusher doesn't call the following anymore.
Sho SHIMIZU107344e2014-08-13 16:11:53 -0700490 flProviderService.addOFMessageListener(eq(OFType.BARRIER_REPLY),
491 anyObject(FlowPusher.class));
492 expectLastCall().once();
Ray Milkey269ffb92014-04-03 14:43:30 -0700493
Sho SHIMIZU107344e2014-08-13 16:11:53 -0700494 ScheduledExecutorService executor = createMock(ScheduledExecutorService.class);
495 expect(executor.schedule((Runnable) anyObject(), anyLong(),
496 (TimeUnit) anyObject())).andReturn(null).once();
497 replay(executor);
498 expect(threadPoolService.getScheduledExecutor()).andReturn(executor).anyTimes();
Ray Milkey269ffb92014-04-03 14:43:30 -0700499 }
500
501 private void endInitMock() {
Sho SHIMIZU107344e2014-08-13 16:11:53 -0700502 replay(threadPoolService);
503 replay(flProviderService);
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700504 //EasyMock.replay(factory10);
Sho SHIMIZU107344e2014-08-13 16:11:53 -0700505 replay(modContext);
506 replay(context);
Ray Milkey269ffb92014-04-03 14:43:30 -0700507 }
508
509 private void verifyAll() {
Sho SHIMIZU107344e2014-08-13 16:11:53 -0700510 verify(threadPoolService);
511 verify(flProviderService);
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700512 //EasyMock.verify(factory10);
Sho SHIMIZU107344e2014-08-13 16:11:53 -0700513 verify(modContext);
514 verify(context);
Ray Milkey269ffb92014-04-03 14:43:30 -0700515 }
516
Yuta HIGUCHI44a0b352014-05-14 21:32:48 -0700517 private void initPusher(int numThread) {
518 pusher = new FlowPusher(numThread);
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700519 pusher.init(modContext);
Ray Milkey269ffb92014-04-03 14:43:30 -0700520 pusher.start();
521 }
522
Naoki Shiota47993102014-07-09 14:00:54 -0700523 private IOFSwitch createConnectedSwitchMock(long dpid, boolean useBarrier) {
Sho SHIMIZU107344e2014-08-13 16:11:53 -0700524 IOFSwitch sw = createMock(IOFSwitch.class);
525 expect(sw.isConnected()).andReturn(true).anyTimes();
526 expect(sw.getId()).andReturn(dpid).anyTimes();
Naoki Shiota47993102014-07-09 14:00:54 -0700527 sw.flush();
Sho SHIMIZU107344e2014-08-13 16:11:53 -0700528 expectLastCall().anyTimes();
Naoki Shiota47993102014-07-09 14:00:54 -0700529 if (useBarrier) {
530 prepareBarrier(sw);
531 }
532
533 return sw;
534 }
535
Ray Milkey269ffb92014-04-03 14:43:30 -0700536 private void prepareBarrier(IOFSwitch sw) {
Sho SHIMIZU107344e2014-08-13 16:11:53 -0700537 OFBarrierRequest.Builder bld = createMock(factory10.buildBarrierRequest().getClass());
538 expect(bld.setXid(anyInt())).andReturn(bld);
539 expect(bld.getXid()).andReturn((long) 1).anyTimes();
540 expect(bld.getType()).andReturn(OFType.BARRIER_REQUEST).anyTimes();
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700541
Sho SHIMIZU107344e2014-08-13 16:11:53 -0700542 OFBarrierRequest req = createMock(OFBarrierRequest.class);
543 expect(bld.build()).andReturn(req).anyTimes();
544 replay(bld);
545 expect(sw.getNextTransactionId()).andReturn(1);
Ray Milkey269ffb92014-04-03 14:43:30 -0700546 }
547
Naoki Shiota75b7dd62013-12-03 18:09:21 -0800548}