Pingping
Committed by Pavlin Radoslavov

Unit test to Router class with Async ARP

Change-Id: I3797433ae5dcce06425159887e42ee75bcf621e4
...@@ -69,6 +69,8 @@ import com.google.common.collect.Sets; ...@@ -69,6 +69,8 @@ import com.google.common.collect.Sets;
69 /** 69 /**
70 * This class tests adding a route, updating a route, deleting a route, 70 * This class tests adding a route, updating a route, deleting a route,
71 * and adding a route whose next hop is the local BGP speaker. 71 * and adding a route whose next hop is the local BGP speaker.
72 + * <p/>
73 + * ARP module answers the MAC address synchronously.
72 */ 74 */
73 public class RouterTest { 75 public class RouterTest {
74 76
......
1 +package org.onlab.onos.sdnip;
2 +
3 +import static org.easymock.EasyMock.anyObject;
4 +import static org.easymock.EasyMock.createMock;
5 +import static org.easymock.EasyMock.expect;
6 +import static org.easymock.EasyMock.replay;
7 +import static org.easymock.EasyMock.reset;
8 +import static org.easymock.EasyMock.verify;
9 +import static org.junit.Assert.assertEquals;
10 +import static org.junit.Assert.assertTrue;
11 +
12 +import java.util.HashMap;
13 +import java.util.HashSet;
14 +import java.util.Map;
15 +import java.util.Set;
16 +import java.util.concurrent.ConcurrentHashMap;
17 +
18 +import org.junit.Before;
19 +import org.junit.Test;
20 +import org.onlab.junit.TestUtils;
21 +import org.onlab.junit.TestUtils.TestUtilsException;
22 +import org.onlab.onos.ApplicationId;
23 +import org.onlab.onos.net.ConnectPoint;
24 +import org.onlab.onos.net.DefaultHost;
25 +import org.onlab.onos.net.DeviceId;
26 +import org.onlab.onos.net.Host;
27 +import org.onlab.onos.net.HostId;
28 +import org.onlab.onos.net.HostLocation;
29 +import org.onlab.onos.net.PortNumber;
30 +import org.onlab.onos.net.flow.DefaultTrafficSelector;
31 +import org.onlab.onos.net.flow.DefaultTrafficTreatment;
32 +import org.onlab.onos.net.flow.TrafficSelector;
33 +import org.onlab.onos.net.flow.TrafficTreatment;
34 +import org.onlab.onos.net.host.HostEvent;
35 +import org.onlab.onos.net.host.HostService;
36 +import org.onlab.onos.net.host.InterfaceIpAddress;
37 +import org.onlab.onos.net.intent.IntentService;
38 +import org.onlab.onos.net.intent.MultiPointToSinglePointIntent;
39 +import org.onlab.onos.net.provider.ProviderId;
40 +import org.onlab.onos.sdnip.Router.InternalHostListener;
41 +import org.onlab.onos.sdnip.config.BgpPeer;
42 +import org.onlab.onos.sdnip.config.Interface;
43 +import org.onlab.onos.sdnip.config.SdnIpConfigService;
44 +import org.onlab.packet.Ethernet;
45 +import org.onlab.packet.IpAddress;
46 +import org.onlab.packet.IpPrefix;
47 +import org.onlab.packet.MacAddress;
48 +import org.onlab.packet.VlanId;
49 +
50 +import com.google.common.collect.Sets;
51 +import com.googlecode.concurrenttrees.radix.node.concrete.DefaultByteArrayNodeFactory;
52 +import com.googlecode.concurrenttrees.radixinverted.ConcurrentInvertedRadixTree;
53 +import com.googlecode.concurrenttrees.radixinverted.InvertedRadixTree;
54 +
55 +/**
56 + * This class tests adding a route, updating a route, deleting a route, and
57 + * the ARP module answers the MAC address asynchronously.
58 + */
59 +public class RouterTestWithAsyncArp {
60 +
61 + private SdnIpConfigService sdnIpConfigService;
62 + private InterfaceService interfaceService;
63 + private IntentService intentService;
64 + private HostService hostService;
65 +
66 + private static final ConnectPoint SW1_ETH1 = new ConnectPoint(
67 + DeviceId.deviceId("of:0000000000000001"),
68 + PortNumber.portNumber(1));
69 +
70 + private static final ConnectPoint SW2_ETH1 = new ConnectPoint(
71 + DeviceId.deviceId("of:0000000000000002"),
72 + PortNumber.portNumber(1));
73 +
74 + private static final ConnectPoint SW3_ETH1 = new ConnectPoint(
75 + DeviceId.deviceId("of:0000000000000003"),
76 + PortNumber.portNumber(1));
77 +
78 + private Router router;
79 + private InternalHostListener internalHostListener;
80 +
81 + private static final ApplicationId APPID = new ApplicationId() {
82 + @Override
83 + public short id() {
84 + return 1;
85 + }
86 +
87 + @Override
88 + public String name() {
89 + return "SDNIP";
90 + }
91 + };
92 +
93 + @Before
94 + public void setUp() throws Exception {
95 + setUpSdnIpConfigService();
96 + setUpInterfaceService();
97 + hostService = createMock(HostService.class);
98 + intentService = createMock(IntentService.class);
99 +
100 + router = new Router(APPID, intentService,
101 + hostService, sdnIpConfigService, interfaceService);
102 + internalHostListener = router.new InternalHostListener();
103 + }
104 +
105 + /**
106 + * Sets up SdnIpConfigService.
107 + */
108 + private void setUpSdnIpConfigService() {
109 +
110 + sdnIpConfigService = createMock(SdnIpConfigService.class);
111 +
112 + Map<IpAddress, BgpPeer> peers = new HashMap<>();
113 +
114 + String peerSw1Eth1 = "192.168.10.1";
115 + peers.put(IpAddress.valueOf(peerSw1Eth1),
116 + new BgpPeer("00:00:00:00:00:00:00:01", 1, peerSw1Eth1));
117 +
118 + // Two BGP peers are connected to switch 2 port 1.
119 + String peer1Sw2Eth1 = "192.168.20.1";
120 + peers.put(IpAddress.valueOf(peer1Sw2Eth1),
121 + new BgpPeer("00:00:00:00:00:00:00:02", 1, peer1Sw2Eth1));
122 +
123 + String peer2Sw2Eth1 = "192.168.20.2";
124 + peers.put(IpAddress.valueOf(peer2Sw2Eth1),
125 + new BgpPeer("00:00:00:00:00:00:00:02", 1, peer2Sw2Eth1));
126 +
127 + expect(sdnIpConfigService.getBgpPeers()).andReturn(peers).anyTimes();
128 + replay(sdnIpConfigService);
129 + }
130 +
131 + /**
132 + * Sets up InterfaceService.
133 + */
134 + private void setUpInterfaceService() {
135 +
136 + interfaceService = createMock(InterfaceService.class);
137 +
138 + Set<Interface> interfaces = Sets.newHashSet();
139 +
140 + Set<InterfaceIpAddress> interfaceIpAddresses1 = Sets.newHashSet();
141 + interfaceIpAddresses1.add(new InterfaceIpAddress(
142 + IpAddress.valueOf("192.168.10.101"),
143 + IpPrefix.valueOf("192.168.10.0/24")));
144 + Interface sw1Eth1 = new Interface(SW1_ETH1,
145 + interfaceIpAddresses1, MacAddress.valueOf("00:00:00:00:00:01"));
146 + interfaces.add(sw1Eth1);
147 +
148 + Set<InterfaceIpAddress> interfaceIpAddresses2 = Sets.newHashSet();
149 + interfaceIpAddresses2.add(new InterfaceIpAddress(
150 + IpAddress.valueOf("192.168.20.101"),
151 + IpPrefix.valueOf("192.168.20.0/24")));
152 + Interface sw2Eth1 = new Interface(SW2_ETH1,
153 + interfaceIpAddresses2, MacAddress.valueOf("00:00:00:00:00:02"));
154 + interfaces.add(sw2Eth1);
155 +
156 + Set<InterfaceIpAddress> interfaceIpAddresses3 = Sets.newHashSet();
157 + interfaceIpAddresses3.add(new InterfaceIpAddress(
158 + IpAddress.valueOf("192.168.30.101"),
159 + IpPrefix.valueOf("192.168.30.0/24")));
160 + Interface sw3Eth1 = new Interface(SW3_ETH1,
161 + interfaceIpAddresses3, MacAddress.valueOf("00:00:00:00:00:03"));
162 + interfaces.add(sw3Eth1);
163 +
164 + expect(interfaceService.getInterface(SW1_ETH1)).andReturn(sw1Eth1).anyTimes();
165 + expect(interfaceService.getInterface(SW2_ETH1)).andReturn(sw2Eth1).anyTimes();
166 + expect(interfaceService.getInterface(SW3_ETH1)).andReturn(sw3Eth1).anyTimes();
167 + expect(interfaceService.getInterfaces()).andReturn(interfaces).anyTimes();
168 + replay(interfaceService);
169 + }
170 +
171 + /**
172 + * This method tests adding a route entry.
173 + */
174 + @Test
175 + public void testProcessRouteAdd() throws TestUtilsException {
176 +
177 + // Construct a route entry
178 + RouteEntry routeEntry = new RouteEntry(
179 + IpPrefix.valueOf("1.1.1.0/24"),
180 + IpAddress.valueOf("192.168.10.1"));
181 +
182 + // Construct a route intent
183 + MultiPointToSinglePointIntent intent = staticIntentBuilder();
184 +
185 + // Set up test expectation
186 + reset(hostService);
187 + expect(hostService.getHostsByIp(anyObject(IpPrefix.class))).andReturn(
188 + new HashSet<Host>()).anyTimes();
189 + hostService.startMonitoringIp(IpAddress.valueOf("192.168.10.1"));
190 + replay(hostService);
191 +
192 + reset(intentService);
193 + intentService.submit(intent);
194 + replay(intentService);
195 +
196 + // Call the processRouteAdd() method in Router class
197 + router.leaderChanged(true);
198 + TestUtils.setField(router, "isActivatedLeader", true);
199 + router.processRouteAdd(routeEntry);
200 +
201 + Host host = new DefaultHost(ProviderId.NONE, HostId.NONE,
202 + MacAddress.valueOf("00:00:00:00:00:01"), VlanId.NONE,
203 + new HostLocation(
204 + SW1_ETH1.deviceId(),
205 + SW1_ETH1.port(), 1),
206 + Sets.newHashSet(IpPrefix.valueOf("192.168.10.1/32")));
207 + internalHostListener.event(
208 + new HostEvent(HostEvent.Type.HOST_ADDED, host));
209 +
210 + // Verify
211 + assertEquals(router.getRoutes().size(), 1);
212 + assertTrue(router.getRoutes().contains(routeEntry));
213 + assertEquals(router.getPushedRouteIntents().size(), 1);
214 + assertEquals(router.getPushedRouteIntents().iterator().next(),
215 + intent);
216 + verify(intentService);
217 + verify(hostService);
218 +
219 + }
220 +
221 + /**
222 + * This method tests updating a route entry.
223 + *
224 + * @throws TestUtilsException
225 + */
226 + @Test
227 + public void testRouteUpdate() throws TestUtilsException {
228 +
229 + // Construct the existing route entry
230 + RouteEntry routeEntry = new RouteEntry(
231 + IpPrefix.valueOf("1.1.1.0/24"),
232 + IpAddress.valueOf("192.168.10.1"));
233 +
234 + // Construct the existing MultiPointToSinglePointIntent intent
235 + MultiPointToSinglePointIntent intent = staticIntentBuilder();
236 +
237 + // Set up the bgpRoutes field of Router class with existing route, and
238 + // pushedRouteIntents field with the corresponding existing intent
239 + setBgpRoutesField(routeEntry);
240 + setPushedRouteIntentsField(routeEntry, intent);
241 +
242 + // Start to construct a new route entry and new intent
243 + RouteEntry routeEntryUpdate = new RouteEntry(
244 + IpPrefix.valueOf("1.1.1.0/24"),
245 + IpAddress.valueOf("192.168.20.1"));
246 +
247 + // Construct a new MultiPointToSinglePointIntent intent
248 + TrafficSelector.Builder selectorBuilderNew =
249 + DefaultTrafficSelector.builder();
250 + selectorBuilderNew.matchEthType(Ethernet.TYPE_IPV4).matchIPDst(
251 + routeEntryUpdate.prefix());
252 +
253 + TrafficTreatment.Builder treatmentBuilderNew =
254 + DefaultTrafficTreatment.builder();
255 + treatmentBuilderNew.setEthDst(MacAddress.valueOf("00:00:00:00:00:02"));
256 +
257 + Set<ConnectPoint> ingressPointsNew = new HashSet<ConnectPoint>();
258 + ingressPointsNew.add(SW1_ETH1);
259 + ingressPointsNew.add(SW3_ETH1);
260 +
261 + MultiPointToSinglePointIntent intentNew =
262 + new MultiPointToSinglePointIntent(APPID,
263 + selectorBuilderNew.build(),
264 + treatmentBuilderNew.build(),
265 + ingressPointsNew, SW2_ETH1);
266 +
267 + // Set up test expectation
268 + reset(hostService);
269 + expect(hostService.getHostsByIp(anyObject(IpPrefix.class))).andReturn(
270 + new HashSet<Host>()).anyTimes();
271 + hostService.startMonitoringIp(IpAddress.valueOf("192.168.20.1"));
272 + replay(hostService);
273 +
274 + reset(intentService);
275 + intentService.withdraw(intent);
276 + intentService.submit(intentNew);
277 + replay(intentService);
278 +
279 + // Call the processRouteAdd() method in Router class
280 + router.leaderChanged(true);
281 + TestUtils.setField(router, "isActivatedLeader", true);
282 + router.processRouteAdd(routeEntryUpdate);
283 +
284 + Host host = new DefaultHost(ProviderId.NONE, HostId.NONE,
285 + MacAddress.valueOf("00:00:00:00:00:02"), VlanId.NONE,
286 + new HostLocation(
287 + SW2_ETH1.deviceId(),
288 + SW2_ETH1.port(), 1),
289 + Sets.newHashSet(IpPrefix.valueOf("192.168.20.1/32")));
290 + internalHostListener.event(
291 + new HostEvent(HostEvent.Type.HOST_ADDED, host));
292 +
293 + // Verify
294 + assertEquals(router.getRoutes().size(), 1);
295 + assertTrue(router.getRoutes().contains(routeEntryUpdate));
296 + assertEquals(router.getPushedRouteIntents().size(), 1);
297 + assertEquals(router.getPushedRouteIntents().iterator().next(),
298 + intentNew);
299 + verify(intentService);
300 + verify(hostService);
301 + }
302 +
303 + /**
304 + * This method tests deleting a route entry.
305 + */
306 + @Test
307 + public void testProcessRouteDelete() throws TestUtilsException {
308 +
309 + // Construct the existing route entry
310 + RouteEntry routeEntry = new RouteEntry(
311 + IpPrefix.valueOf("1.1.1.0/24"),
312 + IpAddress.valueOf("192.168.10.1"));
313 +
314 + // Construct the existing MultiPointToSinglePointIntent intent
315 + MultiPointToSinglePointIntent intent = staticIntentBuilder();
316 +
317 + // Set up the bgpRoutes field of Router class with existing route, and
318 + // pushedRouteIntents field with the corresponding existing intent
319 + setBgpRoutesField(routeEntry);
320 + setPushedRouteIntentsField(routeEntry, intent);
321 +
322 + // Set up expectation
323 + reset(intentService);
324 + intentService.withdraw(intent);
325 + replay(intentService);
326 +
327 + // Call route deleting method in Router class
328 + router.leaderChanged(true);
329 + TestUtils.setField(router, "isActivatedLeader", true);
330 + router.processRouteDelete(routeEntry);
331 +
332 + // Verify
333 + assertEquals(router.getRoutes().size(), 0);
334 + assertEquals(router.getPushedRouteIntents().size(), 0);
335 + verify(intentService);
336 + }
337 +
338 + /**
339 + * Constructs a static MultiPointToSinglePointIntent.
340 + */
341 + private MultiPointToSinglePointIntent staticIntentBuilder() {
342 +
343 + TrafficSelector.Builder selectorBuilder =
344 + DefaultTrafficSelector.builder();
345 + selectorBuilder.matchEthType(Ethernet.TYPE_IPV4).matchIPDst(
346 + IpPrefix.valueOf("1.1.1.0/24"));
347 +
348 + TrafficTreatment.Builder treatmentBuilder =
349 + DefaultTrafficTreatment.builder();
350 + treatmentBuilder.setEthDst(MacAddress.valueOf("00:00:00:00:00:01"));
351 +
352 + Set<ConnectPoint> ingressPoints = new HashSet<ConnectPoint>();
353 + ingressPoints.add(SW2_ETH1);
354 + ingressPoints.add(SW3_ETH1);
355 +
356 + MultiPointToSinglePointIntent intent =
357 + new MultiPointToSinglePointIntent(APPID,
358 + selectorBuilder.build(), treatmentBuilder.build(),
359 + ingressPoints, SW1_ETH1);
360 +
361 + return intent;
362 + }
363 +
364 + /**
365 + * Sets bgpRoutesField in Router class.
366 + *
367 + * @throws TestUtilsException
368 + */
369 + private void setBgpRoutesField(RouteEntry routeEntry)
370 + throws TestUtilsException {
371 +
372 + InvertedRadixTree<RouteEntry> bgpRoutes =
373 + new ConcurrentInvertedRadixTree<>(
374 + new DefaultByteArrayNodeFactory());
375 + bgpRoutes.put(RouteEntry.createBinaryString(routeEntry.prefix()),
376 + routeEntry);
377 + TestUtils.setField(router, "bgpRoutes", bgpRoutes);
378 + }
379 +
380 + /**
381 + * Sets pushedRouteIntentsField in Router class.
382 + *
383 + * @throws TestUtilsException
384 + */
385 + private void setPushedRouteIntentsField(RouteEntry routeEntry,
386 + MultiPointToSinglePointIntent intent)
387 + throws TestUtilsException {
388 +
389 + ConcurrentHashMap<IpPrefix, MultiPointToSinglePointIntent>
390 + pushedRouteIntents = new ConcurrentHashMap<>();
391 + pushedRouteIntents.put(routeEntry.prefix(), intent);
392 + TestUtils.setField(router, "pushedRouteIntents", pushedRouteIntents);
393 + }
394 +}
...\ No newline at end of file ...\ No newline at end of file