blob: b770705405418201e14ba7427e9be13ba96fafc2 [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;
Jonathan Hart5302b6c2014-08-13 15:57:59 -070034import net.onrc.onos.core.util.Dpid;
Ray Milkey10643572014-06-10 15:17:39 -070035import net.onrc.onos.core.util.IntegrationTest;
Naoki Shiota47993102014-07-09 14:00:54 -070036
Jonathan Hart5302b6c2014-08-13 15:57:59 -070037import org.junit.Ignore;
Naoki Shiota75b7dd62013-12-03 18:09:21 -080038import org.junit.Test;
Ray Milkey10643572014-06-10 15:17:39 -070039import org.junit.experimental.categories.Category;
Brian O'Connorc67f9fa2014-08-07 18:17:46 -070040import org.projectfloodlight.openflow.protocol.OFBarrierReply;
41import org.projectfloodlight.openflow.protocol.OFBarrierRequest;
42import org.projectfloodlight.openflow.protocol.OFFactories;
43import org.projectfloodlight.openflow.protocol.OFFactory;
44import org.projectfloodlight.openflow.protocol.OFFlowModify;
45import org.projectfloodlight.openflow.protocol.OFMessage;
46import org.projectfloodlight.openflow.protocol.OFType;
47import org.projectfloodlight.openflow.protocol.OFVersion;
48import org.projectfloodlight.openflow.protocol.action.OFAction;
49import org.projectfloodlight.openflow.protocol.match.Match;
50import org.projectfloodlight.openflow.types.OFBufferId;
51import org.projectfloodlight.openflow.types.OFPort;
52import org.projectfloodlight.openflow.types.U64;
Jonathan Hartce07f322014-08-13 14:40:53 -070053import org.projectfloodlight.openflow.util.HexString;
Brian O'Connorc67f9fa2014-08-07 18:17:46 -070054
Naoki Shiota75b7dd62013-12-03 18:09:21 -080055
Ray Milkey10643572014-06-10 15:17:39 -070056@Category(IntegrationTest.class)
Naoki Shiota75b7dd62013-12-03 18:09:21 -080057public class FlowPusherTest {
Ray Milkey269ffb92014-04-03 14:43:30 -070058 private FlowPusher pusher;
59 private FloodlightContext context;
60 private FloodlightModuleContext modContext;
Ray Milkey269ffb92014-04-03 14:43:30 -070061 private IFloodlightProviderService flProviderService;
62 private IThreadPoolService threadPoolService;
Naoki Shiota75b7dd62013-12-03 18:09:21 -080063
Brian O'Connorc67f9fa2014-08-07 18:17:46 -070064 private OFFactory factory10 = OFFactories.getFactory(OFVersion.OF_10);
65
Ray Milkey269ffb92014-04-03 14:43:30 -070066 /**
Jonathan Hart51bb27c2014-08-11 16:00:31 -070067 * Test single OFMessage is correctly sent to single switch.
Ray Milkey269ffb92014-04-03 14:43:30 -070068 */
69 @Test
70 public void testAddMessage() {
71 beginInitMock();
Naoki Shiota75b7dd62013-12-03 18:09:21 -080072
Jonathan Hart5302b6c2014-08-13 15:57:59 -070073 Dpid dpid = new Dpid(1L);
74
Sho SHIMIZU107344e2014-08-13 16:11:53 -070075 OFMessage msg = createMock(OFMessage.class);
76 expect(msg.getXid()).andReturn((long) 1).anyTimes();
Sho SHIMIZU107344e2014-08-13 16:11:53 -070077 replay(msg);
Naoki Shiota75b7dd62013-12-03 18:09:21 -080078
Jonathan Hart5302b6c2014-08-13 15:57:59 -070079 IOFSwitch sw = createConnectedSwitchMock(dpid.value());
Naoki Shiotad6ef3b32014-03-13 18:42:23 -070080
Ray Milkey269ffb92014-04-03 14:43:30 -070081 try {
Sho SHIMIZU107344e2014-08-13 16:11:53 -070082 sw.write(eq(msg), eq((FloodlightContext) null));
83 expectLastCall().once();
84 replay(sw);
Ray Milkey269ffb92014-04-03 14:43:30 -070085 } catch (IOException e1) {
Brian O'Connorc67f9fa2014-08-07 18:17:46 -070086 fail("Failed in IOFSwitch#write()");
Ray Milkey269ffb92014-04-03 14:43:30 -070087 }
Naoki Shiota75b7dd62013-12-03 18:09:21 -080088
Ray Milkey269ffb92014-04-03 14:43:30 -070089 endInitMock();
90 initPusher(1);
Naoki Shiotad6ef3b32014-03-13 18:42:23 -070091
Jonathan Hart5302b6c2014-08-13 15:57:59 -070092 boolean addResult = pusher.add(dpid, msg);
Yuta HIGUCHI44a0b352014-05-14 21:32:48 -070093 assertTrue(addResult);
Naoki Shiota75b7dd62013-12-03 18:09:21 -080094
Ray Milkey269ffb92014-04-03 14:43:30 -070095 try {
96 // wait until message is processed.
97 Thread.sleep(1000);
98 } catch (InterruptedException e) {
99 fail("Failed in Thread.sleep()");
100 }
Sho SHIMIZU107344e2014-08-13 16:11:53 -0700101 verify(msg);
102 verify(sw);
Ray Milkey269ffb92014-04-03 14:43:30 -0700103 verifyAll();
Naoki Shiota75b7dd62013-12-03 18:09:21 -0800104
Ray Milkey269ffb92014-04-03 14:43:30 -0700105 pusher.stop();
106 }
Naoki Shiota75b7dd62013-12-03 18:09:21 -0800107
Ray Milkey269ffb92014-04-03 14:43:30 -0700108 /**
Jonathan Hart51bb27c2014-08-11 16:00:31 -0700109 * Test bunch of OFMessages are correctly sent to single switch.
Ray Milkey269ffb92014-04-03 14:43:30 -0700110 */
111 @Test
112 public void testMassiveAddMessage() {
Yuta HIGUCHI7c39c842014-06-09 16:33:03 -0700113 // Some number larger than FlowPusher.MAX_MESSAGE_SEND
Yuta HIGUCHI91a8f502014-06-17 10:15:29 -0700114 final int numMsg = FlowPusher.MAX_MESSAGE_SEND * 2;
Naoki Shiotad6ef3b32014-03-13 18:42:23 -0700115
Ray Milkey269ffb92014-04-03 14:43:30 -0700116 beginInitMock();
Naoki Shiota75b7dd62013-12-03 18:09:21 -0800117
Jonathan Hart5302b6c2014-08-13 15:57:59 -0700118 Dpid dpid = new Dpid(1L);
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700119
Jonathan Hart5302b6c2014-08-13 15:57:59 -0700120 IOFSwitch sw = createConnectedSwitchMock(dpid.value());
Naoki Shiota75b7dd62013-12-03 18:09:21 -0800121
Ray Milkey269ffb92014-04-03 14:43:30 -0700122 List<OFMessage> messages = new ArrayList<OFMessage>();
Naoki Shiota75b7dd62013-12-03 18:09:21 -0800123
Yuta HIGUCHI91a8f502014-06-17 10:15:29 -0700124 for (int i = 0; i < numMsg; ++i) {
Sho SHIMIZU107344e2014-08-13 16:11:53 -0700125 OFMessage msg = createMock(OFMessage.class);
126 expect(msg.getXid()).andReturn((long) i).anyTimes();
127 replay(msg);
Ray Milkey269ffb92014-04-03 14:43:30 -0700128 messages.add(msg);
Naoki Shiota75b7dd62013-12-03 18:09:21 -0800129
Ray Milkey269ffb92014-04-03 14:43:30 -0700130 try {
Sho SHIMIZU107344e2014-08-13 16:11:53 -0700131 sw.write(eq(msg), eq((FloodlightContext) null));
132 expectLastCall().once();
Ray Milkey269ffb92014-04-03 14:43:30 -0700133 } catch (IOException e1) {
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700134 fail("Failed in IOFSwitch#write()");
Ray Milkey269ffb92014-04-03 14:43:30 -0700135 }
136 }
Sho SHIMIZU107344e2014-08-13 16:11:53 -0700137 replay(sw);
Ray Milkey269ffb92014-04-03 14:43:30 -0700138 endInitMock();
139 initPusher(1);
Naoki Shiota75b7dd62013-12-03 18:09:21 -0800140
Ray Milkey269ffb92014-04-03 14:43:30 -0700141 for (OFMessage msg : messages) {
Jonathan Hart5302b6c2014-08-13 15:57:59 -0700142 boolean addResult = pusher.add(dpid, msg);
Yuta HIGUCHI44a0b352014-05-14 21:32:48 -0700143 assertTrue(addResult);
Ray Milkey269ffb92014-04-03 14:43:30 -0700144 }
Naoki Shiota75b7dd62013-12-03 18:09:21 -0800145
Ray Milkey269ffb92014-04-03 14:43:30 -0700146 try {
147 // wait until message is processed.
Yuta HIGUCHI7c39c842014-06-09 16:33:03 -0700148 Thread.sleep(1000);
Ray Milkey269ffb92014-04-03 14:43:30 -0700149 } catch (InterruptedException e) {
150 fail("Failed in Thread.sleep()");
151 }
Naoki Shiotad6ef3b32014-03-13 18:42:23 -0700152
Ray Milkey269ffb92014-04-03 14:43:30 -0700153 for (OFMessage msg : messages) {
Sho SHIMIZU107344e2014-08-13 16:11:53 -0700154 verify(msg);
Ray Milkey269ffb92014-04-03 14:43:30 -0700155 }
Sho SHIMIZU107344e2014-08-13 16:11:53 -0700156 verify(sw);
Ray Milkey269ffb92014-04-03 14:43:30 -0700157 verifyAll();
158
159 pusher.stop();
160 }
161
162 /**
163 * Test bunch of OFMessages are correctly sent to multiple switches with single threads.
164 */
165 @Test
166 public void testMultiSwitchAddMessage() {
Yuta HIGUCHI91a8f502014-06-17 10:15:29 -0700167 final int numSwitch = 10;
168 final int numMsg = 100; // messages per thread
Ray Milkey269ffb92014-04-03 14:43:30 -0700169
170 beginInitMock();
171
Jonathan Hart5302b6c2014-08-13 15:57:59 -0700172 Map<IOFSwitch, List<OFMessage>> swMap = new HashMap<>();
Yuta HIGUCHI91a8f502014-06-17 10:15:29 -0700173 for (int i = 0; i < numSwitch; ++i) {
Jonathan Hart5302b6c2014-08-13 15:57:59 -0700174 Dpid dpid = new Dpid(i);
175
176 IOFSwitch sw = createConnectedSwitchMock(dpid.value());
Ray Milkey269ffb92014-04-03 14:43:30 -0700177
178 List<OFMessage> messages = new ArrayList<OFMessage>();
179
Yuta HIGUCHI91a8f502014-06-17 10:15:29 -0700180 for (int j = 0; j < numMsg; ++j) {
Sho SHIMIZU107344e2014-08-13 16:11:53 -0700181 OFMessage msg = createMock(OFMessage.class);
182 expect(msg.getXid()).andReturn((long) j).anyTimes();
183 replay(msg);
Ray Milkey269ffb92014-04-03 14:43:30 -0700184 messages.add(msg);
185
186 try {
Sho SHIMIZU107344e2014-08-13 16:11:53 -0700187 sw.write(eq(msg), eq((FloodlightContext) null));
188 expectLastCall().once();
Ray Milkey269ffb92014-04-03 14:43:30 -0700189 } catch (IOException e1) {
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700190 fail("Failed in IOFWrite#write()");
Ray Milkey269ffb92014-04-03 14:43:30 -0700191 }
192 }
Yuta HIGUCHI44a0b352014-05-14 21:32:48 -0700193 swMap.put(sw, messages);
Sho SHIMIZU107344e2014-08-13 16:11:53 -0700194 replay(sw);
Ray Milkey269ffb92014-04-03 14:43:30 -0700195 }
196
197 endInitMock();
198 initPusher(1);
199
Yuta HIGUCHI44a0b352014-05-14 21:32:48 -0700200 for (IOFSwitch sw : swMap.keySet()) {
201 for (OFMessage msg : swMap.get(sw)) {
Jonathan Hart5302b6c2014-08-13 15:57:59 -0700202 boolean addResult = pusher.add(new Dpid(sw.getId()), msg);
Yuta HIGUCHI44a0b352014-05-14 21:32:48 -0700203 assertTrue(addResult);
Ray Milkey269ffb92014-04-03 14:43:30 -0700204 }
205 }
206
207 try {
208 // wait until message is processed.
209 Thread.sleep(1000);
210 } catch (InterruptedException e) {
211 fail("Failed in Thread.sleep()");
212 }
213
Yuta HIGUCHI44a0b352014-05-14 21:32:48 -0700214 for (IOFSwitch sw : swMap.keySet()) {
215 for (OFMessage msg : swMap.get(sw)) {
Sho SHIMIZU107344e2014-08-13 16:11:53 -0700216 verify(msg);
Ray Milkey269ffb92014-04-03 14:43:30 -0700217 }
218
Sho SHIMIZU107344e2014-08-13 16:11:53 -0700219 verify(sw);
Ray Milkey269ffb92014-04-03 14:43:30 -0700220 }
221 verifyAll();
222
223 pusher.stop();
224 }
225
226 /**
227 * Test bunch of OFMessages are correctly sent to multiple switches using multiple threads.
228 */
229 @Test
230 public void testMultiThreadedAddMessage() {
Yuta HIGUCHI91a8f502014-06-17 10:15:29 -0700231 final int numThreads = 10;
232 final int numMsg = 100; // messages per thread
Ray Milkey269ffb92014-04-03 14:43:30 -0700233
234 beginInitMock();
235
Jonathan Hart5302b6c2014-08-13 15:57:59 -0700236 Map<IOFSwitch, List<OFMessage>> swMap = new HashMap<>();
Yuta HIGUCHI91a8f502014-06-17 10:15:29 -0700237 for (int i = 0; i < numThreads; ++i) {
Jonathan Hartce07f322014-08-13 14:40:53 -0700238 IOFSwitch sw = createConnectedSwitchMock(i);
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700239 //EasyMock.replay(sw);
Ray Milkey269ffb92014-04-03 14:43:30 -0700240
241 List<OFMessage> messages = new ArrayList<OFMessage>();
242
Yuta HIGUCHI91a8f502014-06-17 10:15:29 -0700243 for (int j = 0; j < numMsg; ++j) {
Sho SHIMIZU107344e2014-08-13 16:11:53 -0700244 OFMessage msg = createMock(OFMessage.class);
245 expect(msg.getXid()).andReturn((long) j).anyTimes();
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700246
Sho SHIMIZU107344e2014-08-13 16:11:53 -0700247 replay(msg);
Ray Milkey269ffb92014-04-03 14:43:30 -0700248 messages.add(msg);
249
250 try {
Sho SHIMIZU107344e2014-08-13 16:11:53 -0700251 sw.write(eq(msg), eq((FloodlightContext) null));
252 expectLastCall().once();
Ray Milkey269ffb92014-04-03 14:43:30 -0700253 } catch (IOException e1) {
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700254 fail("Failed in IOFWrite#write()");
Ray Milkey269ffb92014-04-03 14:43:30 -0700255 }
256 }
Yuta HIGUCHI44a0b352014-05-14 21:32:48 -0700257 swMap.put(sw, messages);
Sho SHIMIZU107344e2014-08-13 16:11:53 -0700258 replay(sw);
Ray Milkey269ffb92014-04-03 14:43:30 -0700259 }
260
261 endInitMock();
Yuta HIGUCHI91a8f502014-06-17 10:15:29 -0700262 initPusher(numThreads);
Yuta HIGUCHI44a0b352014-05-14 21:32:48 -0700263 for (IOFSwitch sw : swMap.keySet()) {
264 for (OFMessage msg : swMap.get(sw)) {
Jonathan Hart5302b6c2014-08-13 15:57:59 -0700265 boolean addResult = pusher.add(new Dpid(sw.getId()), msg);
Yuta HIGUCHI44a0b352014-05-14 21:32:48 -0700266 assertTrue(addResult);
Ray Milkey269ffb92014-04-03 14:43:30 -0700267 }
268 }
269
270 try {
271 // wait until message is processed.
272 Thread.sleep(1000);
273 } catch (InterruptedException e) {
274 fail("Failed in Thread.sleep()");
275 }
276
Yuta HIGUCHI44a0b352014-05-14 21:32:48 -0700277 for (IOFSwitch sw : swMap.keySet()) {
278 for (OFMessage msg : swMap.get(sw)) {
Sho SHIMIZU107344e2014-08-13 16:11:53 -0700279 verify(msg);
Ray Milkey269ffb92014-04-03 14:43:30 -0700280 }
281
Sho SHIMIZU107344e2014-08-13 16:11:53 -0700282 verify(sw);
Ray Milkey269ffb92014-04-03 14:43:30 -0700283 }
284 verifyAll();
285
286 pusher.stop();
287 }
288
289 private long barrierTime = 0;
290
291 /**
292 * Test rate limitation of messages works correctly.
293 */
Jonathan Hart5302b6c2014-08-13 15:57:59 -0700294 // XXX Disabling this test for now.
295 // This test doesn't seem to be correctly testing the rate limiting feature.
296 // It tries to measure the time taken to push a set of messages, however the
297 // 'end' timestamp is actually taken when the expectation is set up, before
298 // any messages have been pushed. This means generally when measuredRate is
299 // calculated it is a negative value, so is always less than the allowedRate
300 // and the test passes.
301 // However I was seeing some random failures caused by a divide-by-zero
302 // error, which occurs when the 'end' and 'start' timestamps are taken in
303 // the same millisecond.
304 // Furthermore, rate limits are set in bytes/ms and the rate limiter relies
305 // on being able to get the size of the packets, which is not possible
306 // with Loxi messages. Therefore the rate limiter currently does not work.
307 @Ignore
Ray Milkey269ffb92014-04-03 14:43:30 -0700308 @Test
309 public void testRateLimitedAddMessage() {
Yuta HIGUCHI91a8f502014-06-17 10:15:29 -0700310 final long limitRate = 100; // [bytes/ms]
311 final int numMsg = 1000;
Ray Milkey269ffb92014-04-03 14:43:30 -0700312
313 // Accuracy of FlowPusher's rate calculation can't be measured by unit test
314 // because switch doesn't return BARRIER_REPLY.
315 // In unit test we use approximate way to measure rate. This value is
316 // acceptable margin of measured rate.
Yuta HIGUCHI91a8f502014-06-17 10:15:29 -0700317 final double acceptableRate = limitRate * 1.2;
Ray Milkey269ffb92014-04-03 14:43:30 -0700318
319 beginInitMock();
320
Jonathan Hart5302b6c2014-08-13 15:57:59 -0700321 Dpid dpid = new Dpid(1L);
322
323 IOFSwitch sw = createConnectedSwitchMock(dpid.value());
Ray Milkey269ffb92014-04-03 14:43:30 -0700324
325 List<OFMessage> messages = new ArrayList<OFMessage>();
326
Yuta HIGUCHI91a8f502014-06-17 10:15:29 -0700327 for (int i = 0; i < numMsg; ++i) {
Sho SHIMIZU107344e2014-08-13 16:11:53 -0700328 OFMessage msg = createMock(OFMessage.class);
329 expect(msg.getXid()).andReturn((long) 1).anyTimes();
330 replay(msg);
Ray Milkey269ffb92014-04-03 14:43:30 -0700331 messages.add(msg);
332
333 try {
Sho SHIMIZU107344e2014-08-13 16:11:53 -0700334 sw.write(eq(msg), eq((FloodlightContext) null));
335 expectLastCall().once();
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700336 } catch (IOException e1) {
337 fail("Failed in IOFWrite#write()");
Ray Milkey269ffb92014-04-03 14:43:30 -0700338 }
339 }
340
341 try {
Sho SHIMIZU107344e2014-08-13 16:11:53 -0700342 sw.write(anyObject(OFBarrierRequest.class), eq((FloodlightContext) null));
343 expectLastCall().once();
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700344 barrierTime = System.currentTimeMillis();
Ray Milkey269ffb92014-04-03 14:43:30 -0700345 } catch (IOException e1) {
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700346 fail("Failed in IOFWrite#write()");
Ray Milkey269ffb92014-04-03 14:43:30 -0700347 }
348
Sho SHIMIZU107344e2014-08-13 16:11:53 -0700349 replay(sw);
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700350
Ray Milkey269ffb92014-04-03 14:43:30 -0700351 endInitMock();
352 initPusher(1);
353
Jonathan Hart5302b6c2014-08-13 15:57:59 -0700354 pusher.createQueue(dpid);
355 pusher.setRate(dpid, limitRate);
Ray Milkey269ffb92014-04-03 14:43:30 -0700356
357 long beginTime = System.currentTimeMillis();
358 for (OFMessage msg : messages) {
Jonathan Hart5302b6c2014-08-13 15:57:59 -0700359 boolean addResult = pusher.add(dpid, msg);
Yuta HIGUCHI44a0b352014-05-14 21:32:48 -0700360 assertTrue(addResult);
Ray Milkey269ffb92014-04-03 14:43:30 -0700361 }
362
Jonathan Hart5302b6c2014-08-13 15:57:59 -0700363 pusher.barrierAsync(dpid);
Ray Milkey269ffb92014-04-03 14:43:30 -0700364
365 try {
366 do {
367 Thread.sleep(1000);
368 } while (barrierTime == 0);
369 } catch (InterruptedException e) {
370 fail("Failed to sleep");
371 }
372
Yuta HIGUCHI91a8f502014-06-17 10:15:29 -0700373 double measuredRate = numMsg * 100 / (barrierTime - beginTime);
374 assertTrue(measuredRate < acceptableRate);
Ray Milkey269ffb92014-04-03 14:43:30 -0700375
376 for (OFMessage msg : messages) {
Sho SHIMIZU107344e2014-08-13 16:11:53 -0700377 verify(msg);
Ray Milkey269ffb92014-04-03 14:43:30 -0700378 }
Sho SHIMIZU107344e2014-08-13 16:11:53 -0700379 verify(sw);
Ray Milkey269ffb92014-04-03 14:43:30 -0700380 verifyAll();
381
382 pusher.stop();
383 }
384
385 /**
386 * Test barrier message is correctly sent to a switch.
387 */
388 @Test
389 public void testBarrierMessage() {
390 beginInitMock();
391
Jonathan Hart5302b6c2014-08-13 15:57:59 -0700392 Dpid dpid = new Dpid(1L);
393
394 IOFSwitch sw = createConnectedSwitchMock(dpid.value());
Sho SHIMIZU107344e2014-08-13 16:11:53 -0700395 expect(sw.getOFVersion()).andReturn(OFVersion.OF_10).once();
Ray Milkey269ffb92014-04-03 14:43:30 -0700396
397 try {
Sho SHIMIZU107344e2014-08-13 16:11:53 -0700398 sw.write((OFMessage) anyObject(), eq((FloodlightContext) null));
399 expectLastCall().once();
Ray Milkey269ffb92014-04-03 14:43:30 -0700400 } catch (IOException e1) {
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700401 fail("Failed in IOFWrite#write()");
Ray Milkey269ffb92014-04-03 14:43:30 -0700402 }
Sho SHIMIZU107344e2014-08-13 16:11:53 -0700403 replay(sw);
Ray Milkey269ffb92014-04-03 14:43:30 -0700404 endInitMock();
405 initPusher(1);
406
Jonathan Hart5302b6c2014-08-13 15:57:59 -0700407 OFMessageFuture<OFBarrierReply> future = pusher.barrierAsync(dpid);
Ray Milkey269ffb92014-04-03 14:43:30 -0700408
409 assertNotNull(future);
410
411 try {
412 Thread.sleep(1000);
413 } catch (InterruptedException e) {
414 fail("Failed to sleep");
415 }
416
417 verifyAll();
418
419 pusher.stop();
420 }
421
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700422 static final long XID_TO_VERIFY = 100;
Ray Milkey269ffb92014-04-03 14:43:30 -0700423 static final long DPID_TO_VERIFY = 10;
424
425 /**
426 * Test FlowObject is correctly converted to message and is sent to a switch.
427 */
428 @SuppressWarnings("unchecked")
429 @Test
430 public void testAddFlow() {
Jonathan Hart5302b6c2014-08-13 15:57:59 -0700431 Dpid dpid = new Dpid(DPID_TO_VERIFY);
432
Ray Milkey269ffb92014-04-03 14:43:30 -0700433 // instantiate required objects
Jonathan Hart5302b6c2014-08-13 15:57:59 -0700434 FlowEntry flowEntry1 =
435 new FlowEntry(DPID_TO_VERIFY, 1, 11, null,
436 null, 0, 0, Operator.ADD);
Ray Milkey269ffb92014-04-03 14:43:30 -0700437
438 beginInitMock();
439
Sho SHIMIZU107344e2014-08-13 16:11:53 -0700440 OFFlowModify fm = createMock(OFFlowModify.class);
Ray Milkey269ffb92014-04-03 14:43:30 -0700441
Sho SHIMIZU107344e2014-08-13 16:11:53 -0700442 OFFlowModify.Builder bld = createMock(OFFlowModify.Builder.class);
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700443
Sho SHIMIZU107344e2014-08-13 16:11:53 -0700444 expect(bld.setIdleTimeout(anyInt())).andReturn(bld);
445 expect(bld.setHardTimeout(anyInt())).andReturn(bld);
446 expect(bld.setPriority(anyShort())).andReturn(bld);
447 expect(bld.setBufferId(OFBufferId.NO_BUFFER)).andReturn(bld);
448 expect(bld.setCookie(U64.of(anyLong()))).andReturn(bld);
449 expect(bld.setMatch(anyObject(Match.class))).andReturn(bld);
450 expect(bld.setActions((List<OFAction>) anyObject())).andReturn(bld);
451 expect(bld.setOutPort(OFPort.of(anyInt()))).andReturn(bld).atLeastOnce();
452 expect(bld.build()).andReturn(fm);
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700453
Sho SHIMIZU107344e2014-08-13 16:11:53 -0700454 expect(fm.getXid()).andReturn(XID_TO_VERIFY).anyTimes();
455 expect(fm.getType()).andReturn(OFType.FLOW_MOD).anyTimes();
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700456
Jonathan Hartce07f322014-08-13 14:40:53 -0700457 IOFSwitch sw = createConnectedSwitchMock(DPID_TO_VERIFY);
Ray Milkey269ffb92014-04-03 14:43:30 -0700458
459 try {
Sho SHIMIZU107344e2014-08-13 16:11:53 -0700460 sw.write(anyObject(OFMessage.class), eq((FloodlightContext) null));
461 expectLastCall().once();
Ray Milkey269ffb92014-04-03 14:43:30 -0700462 } catch (IOException e1) {
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700463 fail("Failed in IOFWrite#write()");
Ray Milkey269ffb92014-04-03 14:43:30 -0700464 }
465
Sho SHIMIZU107344e2014-08-13 16:11:53 -0700466 replay(bld, fm);
467 replay(sw);
Ray Milkey269ffb92014-04-03 14:43:30 -0700468
469 endInitMock();
470 initPusher(1);
471
Jonathan Hart5302b6c2014-08-13 15:57:59 -0700472 pusher.pushFlowEntry(dpid, flowEntry1);
Ray Milkey269ffb92014-04-03 14:43:30 -0700473
474 try {
475 Thread.sleep(1000);
476 } catch (InterruptedException e) {
477 fail("Failed to sleep");
478 }
479
Sho SHIMIZU107344e2014-08-13 16:11:53 -0700480 verify(sw);
Ray Milkey269ffb92014-04-03 14:43:30 -0700481 verifyAll();
482
483 pusher.stop();
484 }
485
486 private void beginInitMock() {
Sho SHIMIZU107344e2014-08-13 16:11:53 -0700487 context = createMock(FloodlightContext.class);
488 modContext = createMock(FloodlightModuleContext.class);
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700489 // AAS: I don't think we should mock factories... the rabbit whole is too deep.
490 //factory10 = EasyMock.createMock(OFFactories.getFactory(OFVersion.OF_10).getClass());
Sho SHIMIZU107344e2014-08-13 16:11:53 -0700491 flProviderService = createMock(IFloodlightProviderService.class);
492 threadPoolService = createMock(IThreadPoolService.class);
Ray Milkey269ffb92014-04-03 14:43:30 -0700493
Sho SHIMIZU107344e2014-08-13 16:11:53 -0700494 expect(modContext.getServiceImpl(eq(IThreadPoolService.class)))
Ray Milkey269ffb92014-04-03 14:43:30 -0700495 .andReturn(threadPoolService).once();
Sho SHIMIZU107344e2014-08-13 16:11:53 -0700496 expect(modContext.getServiceImpl(eq(IFloodlightProviderService.class)))
Ray Milkey269ffb92014-04-03 14:43:30 -0700497 .andReturn(flProviderService).once();
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700498 // AAS: FlowPusher doesn't call the following anymore.
Sho SHIMIZU107344e2014-08-13 16:11:53 -0700499 flProviderService.addOFMessageListener(eq(OFType.BARRIER_REPLY),
500 anyObject(FlowPusher.class));
501 expectLastCall().once();
Ray Milkey269ffb92014-04-03 14:43:30 -0700502
Sho SHIMIZU107344e2014-08-13 16:11:53 -0700503 ScheduledExecutorService executor = createMock(ScheduledExecutorService.class);
504 expect(executor.schedule((Runnable) anyObject(), anyLong(),
505 (TimeUnit) anyObject())).andReturn(null).once();
506 replay(executor);
507 expect(threadPoolService.getScheduledExecutor()).andReturn(executor).anyTimes();
Ray Milkey269ffb92014-04-03 14:43:30 -0700508 }
509
510 private void endInitMock() {
Sho SHIMIZU107344e2014-08-13 16:11:53 -0700511 replay(threadPoolService);
512 replay(flProviderService);
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700513 //EasyMock.replay(factory10);
Sho SHIMIZU107344e2014-08-13 16:11:53 -0700514 replay(modContext);
515 replay(context);
Ray Milkey269ffb92014-04-03 14:43:30 -0700516 }
517
518 private void verifyAll() {
Sho SHIMIZU107344e2014-08-13 16:11:53 -0700519 verify(threadPoolService);
520 verify(flProviderService);
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700521 //EasyMock.verify(factory10);
Sho SHIMIZU107344e2014-08-13 16:11:53 -0700522 verify(modContext);
523 verify(context);
Ray Milkey269ffb92014-04-03 14:43:30 -0700524 }
525
Yuta HIGUCHI44a0b352014-05-14 21:32:48 -0700526 private void initPusher(int numThread) {
527 pusher = new FlowPusher(numThread);
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700528 pusher.init(modContext);
Ray Milkey269ffb92014-04-03 14:43:30 -0700529 pusher.start();
530 }
531
Jonathan Hartce07f322014-08-13 14:40:53 -0700532 private IOFSwitch createConnectedSwitchMock(long dpid) {
Sho SHIMIZU107344e2014-08-13 16:11:53 -0700533 IOFSwitch sw = createMock(IOFSwitch.class);
534 expect(sw.isConnected()).andReturn(true).anyTimes();
535 expect(sw.getId()).andReturn(dpid).anyTimes();
Jonathan Hartce07f322014-08-13 14:40:53 -0700536 expect(sw.getStringId()).andReturn(HexString.toHexString(dpid))
537 .anyTimes();
538 expect(sw.getNextTransactionId()).andReturn(1).times(0, 1);
539 // TODO 1.3ize
540 expect(sw.getFactory()).andReturn(factory10).anyTimes();
Naoki Shiota47993102014-07-09 14:00:54 -0700541 sw.flush();
Sho SHIMIZU107344e2014-08-13 16:11:53 -0700542 expectLastCall().anyTimes();
Naoki Shiota47993102014-07-09 14:00:54 -0700543
Jonathan Hart5302b6c2014-08-13 15:57:59 -0700544 expect(flProviderService.getMasterSwitch(dpid)).andReturn(sw)
545 .anyTimes();
546
Naoki Shiota47993102014-07-09 14:00:54 -0700547 return sw;
548 }
549
Naoki Shiota75b7dd62013-12-03 18:09:21 -0800550}