actually include tests for OFPacketProvider
Change-Id: Ia0173204f6c21ed387ccb9d85c8b22e0af0283fa
Showing
1 changed file
with
419 additions
and
0 deletions
1 | +package org.onlab.onos.provider.of.packet.impl; | ||
2 | + | ||
3 | +import static org.junit.Assert.assertEquals; | ||
4 | +import static org.junit.Assert.assertNotNull; | ||
5 | +import static org.junit.Assert.assertNull; | ||
6 | + | ||
7 | +import java.nio.ByteBuffer; | ||
8 | +import java.util.ArrayList; | ||
9 | +import java.util.List; | ||
10 | +import java.util.Set; | ||
11 | + | ||
12 | +import org.junit.After; | ||
13 | +import org.junit.Before; | ||
14 | +import org.junit.Test; | ||
15 | +import org.onlab.onos.net.DeviceId; | ||
16 | +import org.onlab.onos.net.PortNumber; | ||
17 | +import org.onlab.onos.net.flow.DefaultTrafficTreatment; | ||
18 | +import org.onlab.onos.net.flow.TrafficTreatment; | ||
19 | +import org.onlab.onos.net.flow.instructions.Instruction; | ||
20 | +import org.onlab.onos.net.flow.instructions.Instructions; | ||
21 | +import org.onlab.onos.net.packet.DefaultOutboundPacket; | ||
22 | +import org.onlab.onos.net.packet.OutboundPacket; | ||
23 | +import org.onlab.onos.net.packet.PacketContext; | ||
24 | +import org.onlab.onos.net.packet.PacketProvider; | ||
25 | +import org.onlab.onos.net.packet.PacketProviderRegistry; | ||
26 | +import org.onlab.onos.net.packet.PacketProviderService; | ||
27 | +import org.onlab.onos.net.provider.ProviderId; | ||
28 | +import org.onlab.onos.openflow.controller.DefaultOpenFlowPacketContext; | ||
29 | +import org.onlab.onos.openflow.controller.Dpid; | ||
30 | +import org.onlab.onos.openflow.controller.OpenFlowController; | ||
31 | +import org.onlab.onos.openflow.controller.OpenFlowEventListener; | ||
32 | +import org.onlab.onos.openflow.controller.OpenFlowPacketContext; | ||
33 | +import org.onlab.onos.openflow.controller.OpenFlowSwitch; | ||
34 | +import org.onlab.onos.openflow.controller.OpenFlowSwitchListener; | ||
35 | +import org.onlab.onos.openflow.controller.PacketListener; | ||
36 | +import org.onlab.onos.openflow.controller.RoleState; | ||
37 | +import org.onlab.packet.ARP; | ||
38 | +import org.onlab.packet.Ethernet; | ||
39 | +import org.onlab.packet.IpAddress; | ||
40 | +import org.projectfloodlight.openflow.protocol.OFFactory; | ||
41 | +import org.projectfloodlight.openflow.protocol.OFMessage; | ||
42 | +import org.projectfloodlight.openflow.protocol.OFPacketIn; | ||
43 | +import org.projectfloodlight.openflow.protocol.OFPacketInReason; | ||
44 | +import org.projectfloodlight.openflow.protocol.OFPortDesc; | ||
45 | +import org.projectfloodlight.openflow.protocol.ver10.OFFactoryVer10; | ||
46 | +import org.projectfloodlight.openflow.types.MacAddress; | ||
47 | +import org.projectfloodlight.openflow.types.OFBufferId; | ||
48 | +import org.projectfloodlight.openflow.types.OFPort; | ||
49 | + | ||
50 | +import com.google.common.collect.Lists; | ||
51 | +import com.google.common.collect.Sets; | ||
52 | + | ||
53 | + | ||
54 | +public class OpenFlowPacketProviderTest { | ||
55 | + | ||
56 | + private static final int PN1 = 100; | ||
57 | + private static final int PN2 = 200; | ||
58 | + private static final int PN3 = 300; | ||
59 | + private static final short VLANID = (short) 100; | ||
60 | + | ||
61 | + private static final DeviceId DID = DeviceId.deviceId("of:1"); | ||
62 | + private static final DeviceId DID_MISSING = DeviceId.deviceId("of:2"); | ||
63 | + private static final DeviceId DID_WRONG = DeviceId.deviceId("test:1"); | ||
64 | + private static final PortNumber P1 = PortNumber.portNumber(PN1); | ||
65 | + private static final PortNumber P2 = PortNumber.portNumber(PN2); | ||
66 | + private static final PortNumber P3 = PortNumber.portNumber(PN3); | ||
67 | + | ||
68 | + private static final Instruction INST1 = Instructions.createOutput(P1); | ||
69 | + private static final Instruction INST2 = Instructions.createOutput(P2); | ||
70 | + private static final Instruction INST3 = Instructions.createOutput(P3); | ||
71 | + | ||
72 | + private static final OFPortDesc PD1 = portDesc(PN1); | ||
73 | + private static final OFPortDesc PD2 = portDesc(PN2); | ||
74 | + | ||
75 | + private static final List<OFPortDesc> PLIST = Lists.newArrayList(PD1, PD2); | ||
76 | + private static final TrafficTreatment TR = treatment(INST1, INST2); | ||
77 | + private static final TrafficTreatment TR_MISSING = treatment(INST1, INST3); | ||
78 | + | ||
79 | + private final OpenFlowPacketProvider provider = new OpenFlowPacketProvider(); | ||
80 | + private final TestPacketRegistry registry = new TestPacketRegistry(); | ||
81 | + private final TestController controller = new TestController(); | ||
82 | + | ||
83 | + private final TestOpenFlowSwitch sw = new TestOpenFlowSwitch(PLIST); | ||
84 | + | ||
85 | + @Before | ||
86 | + public void startUp() { | ||
87 | + provider.providerRegistry = registry; | ||
88 | + provider.controller = controller; | ||
89 | + provider.activate(); | ||
90 | + assertNotNull("listener should be registered", registry.listener); | ||
91 | + } | ||
92 | + | ||
93 | + @After | ||
94 | + public void teardown() { | ||
95 | + provider.deactivate(); | ||
96 | + assertNull("listeners shouldn't be registered", registry.listener); | ||
97 | + provider.controller = null; | ||
98 | + provider.providerRegistry = null; | ||
99 | + } | ||
100 | + | ||
101 | + @Test(expected = IllegalArgumentException.class) | ||
102 | + public void scheme() { | ||
103 | + sw.setRole(RoleState.MASTER); | ||
104 | + //device has wrong scheme | ||
105 | + OutboundPacket schemeFailPkt = outPacket(DID_WRONG, TR, null); | ||
106 | + provider.emit(schemeFailPkt); | ||
107 | + assertEquals("message sent incorrectly", 0, sw.sent.size()); | ||
108 | + } | ||
109 | + | ||
110 | + @Test | ||
111 | + public void emit() { | ||
112 | + | ||
113 | + MacAddress mac1 = MacAddress.of("00:00:00:11:00:01"); | ||
114 | + MacAddress mac2 = MacAddress.of("00:00:00:22:00:02"); | ||
115 | + | ||
116 | + ARP arp = new ARP(); | ||
117 | + arp.setSenderProtocolAddress(IpAddress.ANY) | ||
118 | + .setSenderHardwareAddress(mac1.getBytes()) | ||
119 | + .setTargetHardwareAddress(mac2.getBytes()) | ||
120 | + .setTargetProtocolAddress(IpAddress.ANY) | ||
121 | + .setHardwareType((short) 0) | ||
122 | + .setProtocolType((short) 0) | ||
123 | + .setHardwareAddressLength((byte) 6) | ||
124 | + .setProtocolAddressLength((byte) 4) | ||
125 | + .setOpCode((byte) 0); | ||
126 | + | ||
127 | + Ethernet eth = new Ethernet(); | ||
128 | + eth.setVlanID(VLANID) | ||
129 | + .setEtherType(Ethernet.TYPE_ARP) | ||
130 | + .setSourceMACAddress("00:00:00:11:00:01") | ||
131 | + .setDestinationMACAddress("00:00:00:22:00:02") | ||
132 | + .setPayload(arp); | ||
133 | + | ||
134 | + //the should-be working setup. | ||
135 | + OutboundPacket passPkt = outPacket(DID, TR, eth); | ||
136 | + sw.setRole(RoleState.MASTER); | ||
137 | + provider.emit(passPkt); | ||
138 | + assertEquals("invalid switch", sw, controller.current); | ||
139 | + assertEquals("message not sent", PLIST.size(), sw.sent.size()); | ||
140 | + sw.sent.clear(); | ||
141 | + | ||
142 | + //wrong Role | ||
143 | + sw.setRole(RoleState.SLAVE); | ||
144 | + provider.emit(passPkt); | ||
145 | + assertEquals("invalid switch", sw, controller.current); | ||
146 | + assertEquals("message sent incorrectly", 0, sw.sent.size()); | ||
147 | + | ||
148 | + sw.setRole(RoleState.MASTER); | ||
149 | + | ||
150 | + //missing switch | ||
151 | + OutboundPacket swFailPkt = outPacket(DID_MISSING, TR, eth); | ||
152 | + provider.emit(swFailPkt); | ||
153 | + assertNull("invalid switch", controller.current); | ||
154 | + assertEquals("message sent incorrectly", 0, sw.sent.size()); | ||
155 | + | ||
156 | + //to missing port | ||
157 | + OutboundPacket portFailPkt = outPacket(DID, TR_MISSING, eth); | ||
158 | + provider.emit(portFailPkt); | ||
159 | + assertEquals("extra message sent", 1, sw.sent.size()); | ||
160 | + | ||
161 | + } | ||
162 | + | ||
163 | + @Test | ||
164 | + public void handlePacket() { | ||
165 | + OFPacketIn pkt = sw.factory().buildPacketIn() | ||
166 | + .setBufferId(OFBufferId.NO_BUFFER) | ||
167 | + .setInPort(OFPort.NO_MASK) | ||
168 | + .setReason(OFPacketInReason.INVALID_TTL) | ||
169 | + .build(); | ||
170 | + | ||
171 | + controller.processPacket(null, pkt); | ||
172 | + assertNotNull("message unprocessed", registry.ctx); | ||
173 | + | ||
174 | + } | ||
175 | + | ||
176 | + private static OFPortDesc portDesc(int port) { | ||
177 | + OFPortDesc.Builder builder = OFFactoryVer10.INSTANCE.buildPortDesc(); | ||
178 | + builder.setPortNo(OFPort.of(port)); | ||
179 | + | ||
180 | + return builder.build(); | ||
181 | + } | ||
182 | + | ||
183 | + private static TrafficTreatment treatment(Instruction ... insts) { | ||
184 | + TrafficTreatment.Builder builder = new DefaultTrafficTreatment.Builder(); | ||
185 | + for (Instruction i : insts) { | ||
186 | + builder.add(i); | ||
187 | + } | ||
188 | + return builder.build(); | ||
189 | + } | ||
190 | + | ||
191 | + private static OutboundPacket outPacket( | ||
192 | + DeviceId d, TrafficTreatment t, Ethernet e) { | ||
193 | + ByteBuffer buf = null; | ||
194 | + if (e != null) { | ||
195 | + buf = ByteBuffer.wrap(e.serialize()); | ||
196 | + } | ||
197 | + return new DefaultOutboundPacket(d, t, buf); | ||
198 | + } | ||
199 | + | ||
200 | + private class TestPacketRegistry implements PacketProviderRegistry { | ||
201 | + | ||
202 | + PacketProvider listener = null; | ||
203 | + PacketContext ctx = null; | ||
204 | + | ||
205 | + @Override | ||
206 | + public PacketProviderService register(PacketProvider provider) { | ||
207 | + listener = provider; | ||
208 | + return new TestPacketProviderService(); | ||
209 | + } | ||
210 | + | ||
211 | + @Override | ||
212 | + public void unregister(PacketProvider provider) { | ||
213 | + listener = null; | ||
214 | + } | ||
215 | + | ||
216 | + @Override | ||
217 | + public Set<ProviderId> getProviders() { | ||
218 | + return Sets.newHashSet(listener.id()); | ||
219 | + } | ||
220 | + | ||
221 | + private class TestPacketProviderService implements PacketProviderService { | ||
222 | + | ||
223 | + @Override | ||
224 | + public PacketProvider provider() { | ||
225 | + return null; | ||
226 | + } | ||
227 | + | ||
228 | + @Override | ||
229 | + public void processPacket(PacketContext context) { | ||
230 | + ctx = context; | ||
231 | + } | ||
232 | + | ||
233 | + } | ||
234 | + } | ||
235 | + | ||
236 | + private class TestController implements OpenFlowController { | ||
237 | + | ||
238 | + int prio; | ||
239 | + PacketListener pktListener; | ||
240 | + OpenFlowSwitch current; | ||
241 | + | ||
242 | + @Override | ||
243 | + public Iterable<OpenFlowSwitch> getSwitches() { | ||
244 | + return null; | ||
245 | + } | ||
246 | + | ||
247 | + @Override | ||
248 | + public Iterable<OpenFlowSwitch> getMasterSwitches() { | ||
249 | + return null; | ||
250 | + } | ||
251 | + | ||
252 | + @Override | ||
253 | + public Iterable<OpenFlowSwitch> getEqualSwitches() { | ||
254 | + return null; | ||
255 | + } | ||
256 | + | ||
257 | + @Override | ||
258 | + public OpenFlowSwitch getSwitch(Dpid dpid) { | ||
259 | + if (dpid.equals(Dpid.dpid(DID.uri()))) { | ||
260 | + current = sw; | ||
261 | + } else { | ||
262 | + current = null; | ||
263 | + } | ||
264 | + return current; | ||
265 | + } | ||
266 | + | ||
267 | + @Override | ||
268 | + public OpenFlowSwitch getMasterSwitch(Dpid dpid) { | ||
269 | + return null; | ||
270 | + } | ||
271 | + | ||
272 | + @Override | ||
273 | + public OpenFlowSwitch getEqualSwitch(Dpid dpid) { | ||
274 | + return null; | ||
275 | + } | ||
276 | + | ||
277 | + @Override | ||
278 | + public void addListener(OpenFlowSwitchListener listener) { | ||
279 | + } | ||
280 | + | ||
281 | + @Override | ||
282 | + public void removeListener(OpenFlowSwitchListener listener) { | ||
283 | + } | ||
284 | + | ||
285 | + @Override | ||
286 | + public void addPacketListener(int priority, PacketListener listener) { | ||
287 | + prio = priority; | ||
288 | + pktListener = listener; | ||
289 | + } | ||
290 | + | ||
291 | + @Override | ||
292 | + public void removePacketListener(PacketListener listener) { | ||
293 | + } | ||
294 | + | ||
295 | + @Override | ||
296 | + public void addEventListener(OpenFlowEventListener listener) { | ||
297 | + } | ||
298 | + | ||
299 | + @Override | ||
300 | + public void removeEventListener(OpenFlowEventListener listener) { | ||
301 | + } | ||
302 | + | ||
303 | + @Override | ||
304 | + public void write(Dpid dpid, OFMessage msg) { | ||
305 | + } | ||
306 | + | ||
307 | + @Override | ||
308 | + public void processPacket(Dpid dpid, OFMessage msg) { | ||
309 | + OpenFlowPacketContext pktCtx = | ||
310 | + DefaultOpenFlowPacketContext. | ||
311 | + packetContextFromPacketIn(sw, (OFPacketIn) msg); | ||
312 | + pktListener.handlePacket(pktCtx); | ||
313 | + } | ||
314 | + | ||
315 | + @Override | ||
316 | + public void setRole(Dpid dpid, RoleState role) { | ||
317 | + } | ||
318 | + | ||
319 | + } | ||
320 | + | ||
321 | + private class TestPacketProviderService implements PacketProviderService { | ||
322 | + | ||
323 | + @Override | ||
324 | + public PacketProvider provider() { | ||
325 | + return null; | ||
326 | + } | ||
327 | + | ||
328 | + @Override | ||
329 | + public void processPacket(PacketContext context) { | ||
330 | + } | ||
331 | + | ||
332 | + } | ||
333 | + | ||
334 | + private class TestOpenFlowSwitch implements OpenFlowSwitch { | ||
335 | + | ||
336 | + List<OFPortDesc> ports; | ||
337 | + RoleState state; | ||
338 | + List<OFMessage> sent = new ArrayList<OFMessage>(); | ||
339 | + OFFactory factory = OFFactoryVer10.INSTANCE; | ||
340 | + | ||
341 | + TestOpenFlowSwitch(List<OFPortDesc> p) { | ||
342 | + ports = p; | ||
343 | + } | ||
344 | + | ||
345 | + @Override | ||
346 | + public void sendMsg(OFMessage msg) { | ||
347 | + sent.add(msg); | ||
348 | + } | ||
349 | + | ||
350 | + @Override | ||
351 | + public void sendMsg(List<OFMessage> msgs) { | ||
352 | + } | ||
353 | + | ||
354 | + @Override | ||
355 | + public void handleMessage(OFMessage fromSwitch) { | ||
356 | + } | ||
357 | + | ||
358 | + @Override | ||
359 | + public void setRole(RoleState role) { | ||
360 | + state = role; | ||
361 | + } | ||
362 | + | ||
363 | + @Override | ||
364 | + public RoleState getRole() { | ||
365 | + return state; | ||
366 | + } | ||
367 | + | ||
368 | + @Override | ||
369 | + public List<OFPortDesc> getPorts() { | ||
370 | + return ports; | ||
371 | + } | ||
372 | + | ||
373 | + @Override | ||
374 | + public OFFactory factory() { | ||
375 | + return factory; | ||
376 | + } | ||
377 | + | ||
378 | + @Override | ||
379 | + public String getStringId() { | ||
380 | + return null; | ||
381 | + } | ||
382 | + | ||
383 | + @Override | ||
384 | + public long getId() { | ||
385 | + return 0; | ||
386 | + } | ||
387 | + | ||
388 | + @Override | ||
389 | + public String manfacturerDescription() { | ||
390 | + return null; | ||
391 | + } | ||
392 | + | ||
393 | + @Override | ||
394 | + public String datapathDescription() { | ||
395 | + return null; | ||
396 | + } | ||
397 | + | ||
398 | + @Override | ||
399 | + public String hardwareDescription() { | ||
400 | + return null; | ||
401 | + } | ||
402 | + | ||
403 | + @Override | ||
404 | + public String softwareDescription() { | ||
405 | + return null; | ||
406 | + } | ||
407 | + | ||
408 | + @Override | ||
409 | + public String serialNumber() { | ||
410 | + return null; | ||
411 | + } | ||
412 | + | ||
413 | + @Override | ||
414 | + public void disconnectSwitch() { | ||
415 | + } | ||
416 | + | ||
417 | + } | ||
418 | + | ||
419 | +} |
-
Please register or login to post a comment