blob: e3e489679b4c73c9028c44d9cef53f88c6f5345b [file] [log] [blame]
Thomas Vachuska781d18b2014-10-27 10:31:25 -07001/*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
Jonathan Hartce430a42014-10-16 20:44:29 -070019package org.onlab.onos.sdnip;
20
Thomas Vachuskab97cf282014-10-20 23:31:12 -070021import com.google.common.collect.Sets;
Jonathan Hartce430a42014-10-16 20:44:29 -070022import org.easymock.IArgumentMatcher;
23import org.junit.Before;
24import org.junit.Ignore;
25import org.junit.Test;
Thomas Vachuskab97cf282014-10-20 23:31:12 -070026import org.onlab.onos.ApplicationId;
Jonathan Hartce430a42014-10-16 20:44:29 -070027import org.onlab.onos.net.ConnectPoint;
28import org.onlab.onos.net.DeviceId;
29import org.onlab.onos.net.PortNumber;
30import org.onlab.onos.net.flow.DefaultTrafficSelector;
31import org.onlab.onos.net.flow.DefaultTrafficTreatment;
32import org.onlab.onos.net.flow.TrafficSelector;
33import org.onlab.onos.net.flow.TrafficTreatment;
Jonathan Hartce430a42014-10-16 20:44:29 -070034import org.onlab.onos.net.intent.IntentService;
35import org.onlab.onos.net.intent.PointToPointIntent;
36import org.onlab.onos.sdnip.bgp.BgpConstants;
37import org.onlab.onos.sdnip.config.BgpPeer;
38import org.onlab.onos.sdnip.config.BgpSpeaker;
39import org.onlab.onos.sdnip.config.Interface;
40import org.onlab.onos.sdnip.config.InterfaceAddress;
41import org.onlab.onos.sdnip.config.SdnIpConfigService;
42import org.onlab.packet.Ethernet;
43import org.onlab.packet.IPv4;
44import org.onlab.packet.IpAddress;
45import org.onlab.packet.IpPrefix;
46import org.onlab.packet.MacAddress;
47
Thomas Vachuskab97cf282014-10-20 23:31:12 -070048import java.util.ArrayList;
49import java.util.Collections;
50import java.util.HashMap;
51import java.util.LinkedList;
52import java.util.List;
53import java.util.Map;
54
55import static org.easymock.EasyMock.*;
Jonathan Hartce430a42014-10-16 20:44:29 -070056
57/**
58 * Unit tests for PeerConnectivityManager interface.
59 */
60public class PeerConnectivityManagerTest {
61
Thomas Vachuskab97cf282014-10-20 23:31:12 -070062 private static final ApplicationId APPID = new ApplicationId() {
63 @Override
64 public short id() {
65 return 0;
66 }
67
68 @Override
69 public String name() {
70 return "foo";
71 }
72 };
73
Jonathan Hartce430a42014-10-16 20:44:29 -070074 private PeerConnectivityManager peerConnectivityManager;
75 private IntentService intentService;
76 private SdnIpConfigService configInfoService;
77 private InterfaceService interfaceService;
78
79 private Map<String, BgpSpeaker> bgpSpeakers;
80 private Map<String, Interface> interfaces;
81 private Map<IpAddress, BgpPeer> peers;
82
83 private Map<String, BgpSpeaker> configuredBgpSpeakers;
84 private Map<String, Interface> configuredInterfaces;
85 private Map<IpAddress, BgpPeer> configuredPeers;
86 private List<PointToPointIntent> intentList;
87
88 private final String dpid1 = "00:00:00:00:00:00:00:01";
89 private final String dpid2 = "00:00:00:00:00:00:00:02";
90
91 private final DeviceId deviceId1 =
92 DeviceId.deviceId(SdnIp.dpidToUri(dpid1));
93 private final DeviceId deviceId2 =
94 DeviceId.deviceId(SdnIp.dpidToUri(dpid2));
95
96 // Interfaces connected to BGP speakers
97 private final ConnectPoint s1Eth100 =
98 new ConnectPoint(deviceId1, PortNumber.portNumber(100));
99 private final ConnectPoint s2Eth100 =
100 new ConnectPoint(deviceId2, PortNumber.portNumber(100));
101
102 // Interfaces connected to BGP peers
103 private final ConnectPoint s1Eth1 =
104 new ConnectPoint(deviceId1, PortNumber.portNumber(1));
105 private final ConnectPoint s2Eth1 =
106 new ConnectPoint(deviceId2, PortNumber.portNumber(1));
107
Jonathan Hartce430a42014-10-16 20:44:29 -0700108 private final TrafficTreatment noTreatment =
109 DefaultTrafficTreatment.builder().build();
110
111 @Before
112 public void setUp() throws Exception {
113 bgpSpeakers = Collections.unmodifiableMap(setUpBgpSpeakers());
114 interfaces = Collections.unmodifiableMap(setUpInterfaces());
115 peers = Collections.unmodifiableMap(setUpPeers());
116
117 initPeerConnectivity();
118 intentList = setUpIntentList();
119 }
120
121 /**
122 * Sets up BGP speakers.
123 *
124 * @return configured BGP speakers as a map from speaker name to speaker
125 */
126 private Map<String, BgpSpeaker> setUpBgpSpeakers() {
127
128 configuredBgpSpeakers = new HashMap<>();
129
130 BgpSpeaker bgpSpeaker1 = new BgpSpeaker(
131 "bgpSpeaker1",
132 "00:00:00:00:00:00:00:01", 100,
133 "00:00:00:00:00:01");
134 List<InterfaceAddress> interfaceAddresses1 =
135 new LinkedList<InterfaceAddress>();
136 interfaceAddresses1.add(new InterfaceAddress(dpid1, 1, "192.168.10.101"));
137 interfaceAddresses1.add(new InterfaceAddress(dpid2, 1, "192.168.20.101"));
138 bgpSpeaker1.setInterfaceAddresses(interfaceAddresses1);
139 configuredBgpSpeakers.put(bgpSpeaker1.name(), bgpSpeaker1);
140
141 // BGP speaker2 is attached to the same switch port with speaker1
142 BgpSpeaker bgpSpeaker2 = new BgpSpeaker(
143 "bgpSpeaker2",
144 "00:00:00:00:00:00:00:01", 100,
145 "00:00:00:00:00:02");
146 List<InterfaceAddress> interfaceAddresses2 =
147 new LinkedList<InterfaceAddress>();
148 interfaceAddresses2.add(new InterfaceAddress(dpid1, 1, "192.168.10.102"));
149 interfaceAddresses2.add(new InterfaceAddress(dpid2, 1, "192.168.20.102"));
150 bgpSpeaker2.setInterfaceAddresses(interfaceAddresses2);
151 configuredBgpSpeakers.put(bgpSpeaker2.name(), bgpSpeaker2);
152
153 BgpSpeaker bgpSpeaker3 = new BgpSpeaker(
154 "bgpSpeaker3",
155 "00:00:00:00:00:00:00:02", 100,
156 "00:00:00:00:00:03");
157 List<InterfaceAddress> interfaceAddresses3 =
158 new LinkedList<InterfaceAddress>();
159 interfaceAddresses3.add(new InterfaceAddress(dpid1, 1, "192.168.10.103"));
160 interfaceAddresses3.add(new InterfaceAddress(dpid2, 1, "192.168.20.103"));
161 bgpSpeaker3.setInterfaceAddresses(interfaceAddresses3);
162 configuredBgpSpeakers.put(bgpSpeaker3.name(), bgpSpeaker3);
163
164 return configuredBgpSpeakers;
165 }
166
167 /**
168 * Sets up logical interfaces, which emulate the configured interfaces
169 * in SDN-IP application.
170 *
171 * @return configured interfaces as a MAP from Interface name to Interface
172 */
173 private Map<String, Interface> setUpInterfaces() {
174
175 configuredInterfaces = new HashMap<>();
176
177 String interfaceSw1Eth1 = "s1-eth1";
178 Interface intfsw1eth1 = new Interface(s1Eth1,
179 Collections.singleton(IpPrefix.valueOf("192.168.10.0/24")),
180 MacAddress.valueOf("00:00:00:00:00:01"));
181
182 configuredInterfaces.put(interfaceSw1Eth1, intfsw1eth1);
183 String interfaceSw2Eth1 = "s2-eth1";
184 Interface intfsw2eth1 = new Interface(s2Eth1,
185 Collections.singleton(IpPrefix.valueOf("192.168.20.0/24")),
186 MacAddress.valueOf("00:00:00:00:00:02"));
187 configuredInterfaces.put(interfaceSw2Eth1, intfsw2eth1);
188
189 interfaceService = createMock(InterfaceService.class);
190
191 expect(interfaceService.getInterface(s1Eth1))
192 .andReturn(intfsw1eth1).anyTimes();
193 expect(interfaceService.getInterface(s2Eth1))
194 .andReturn(intfsw2eth1).anyTimes();
195
196 // Non-existent interface used during one of the tests
197 expect(interfaceService.getInterface(new ConnectPoint(
198 DeviceId.deviceId(SdnIp.dpidToUri("00:00:00:00:00:00:01:00")),
199 PortNumber.portNumber(1))))
200 .andReturn(null).anyTimes();
201
202 expect(interfaceService.getInterfaces()).andReturn(
203 Sets.newHashSet(configuredInterfaces.values())).anyTimes();
204 replay(interfaceService);
205
206 return configuredInterfaces;
207 }
208
209 /**
210 * Sets up BGP daemon peers.
211 *
212 * @return configured BGP peers as a MAP from peer IP address to BgpPeer
213 */
214 private Map<IpAddress, BgpPeer> setUpPeers() {
215
216 configuredPeers = new HashMap<>();
217
218 String peerSw1Eth1 = "192.168.10.1";
219 configuredPeers.put(IpAddress.valueOf(peerSw1Eth1),
220 new BgpPeer(dpid1, 1, peerSw1Eth1));
221
222 // Two BGP peers are connected to switch 2 port 1.
223 String peer1Sw2Eth1 = "192.168.20.1";
224 configuredPeers.put(IpAddress.valueOf(peer1Sw2Eth1),
225 new BgpPeer(dpid2, 1, peer1Sw2Eth1));
226
227 String peer2Sw2Eth1 = "192.168.20.2";
228 configuredPeers.put(IpAddress.valueOf(peer2Sw2Eth1),
229 new BgpPeer(dpid2, 1, peer2Sw2Eth1));
230
231 return configuredPeers;
232 }
233
234 /**
235 * Sets up expected point to point intent list.
236 *
237 * @return point to point intent list
238 */
239 private List<PointToPointIntent> setUpIntentList() {
240
241 intentList = new ArrayList<PointToPointIntent>();
242
243 setUpBgpIntents();
244 setUpIcmpIntents();
245
246 return intentList;
247
248 }
249
250 /**
251 * Constructs a BGP intent and put it into the intentList.
252 * <p/>
253 * The purpose of this method is too simplify the setUpBgpIntents() method,
254 * and to make the setUpBgpIntents() easy to read.
255 *
256 * @param srcPrefix source IP prefix to match
257 * @param dstPrefix destination IP prefix to match
258 * @param srcTcpPort source TCP port to match
259 * @param dstTcpPort destination TCP port to match
260 * @param srcConnectPoint source connect point for PointToPointIntent
261 * @param dstConnectPoint destination connect point for PointToPointIntent
262 */
263 private void bgpPathintentConstructor(String srcPrefix, String dstPrefix,
264 Short srcTcpPort, Short dstTcpPort,
265 ConnectPoint srcConnectPoint, ConnectPoint dstConnectPoint) {
266
267 TrafficSelector.Builder builder = DefaultTrafficSelector.builder()
268 .matchEthType(Ethernet.TYPE_IPV4)
269 .matchIPProtocol(IPv4.PROTOCOL_TCP)
270 .matchIPSrc(IpPrefix.valueOf(srcPrefix))
271 .matchIPDst(IpPrefix.valueOf(dstPrefix));
272
273 if (srcTcpPort != null) {
274 builder.matchTcpSrc(srcTcpPort);
275 }
276 if (dstTcpPort != null) {
277 builder.matchTcpDst(dstTcpPort);
278 }
279
280 PointToPointIntent intent = new PointToPointIntent(
Thomas Vachuskab97cf282014-10-20 23:31:12 -0700281 APPID, builder.build(), noTreatment,
Jonathan Hartce430a42014-10-16 20:44:29 -0700282 srcConnectPoint, dstConnectPoint);
283
284 intentList.add(intent);
285 }
286
287 /**
288 * Sets up intents for BGP paths.
289 */
290 private void setUpBgpIntents() {
291
292 Short bgpPort = Short.valueOf((short) BgpConstants.BGP_PORT);
293
294 // Start to build intents between BGP speaker1 and BGP peer1
295 bgpPathintentConstructor(
296 "192.168.10.101/32", "192.168.10.1/32", null, bgpPort,
297 s1Eth100, s1Eth1);
298 bgpPathintentConstructor(
299 "192.168.10.101/32", "192.168.10.1/32", bgpPort, null,
300 s1Eth100, s1Eth1);
301
302 bgpPathintentConstructor(
303 "192.168.10.1/32", "192.168.10.101/32", null, bgpPort,
304 s1Eth1, s1Eth100);
305 bgpPathintentConstructor(
306 "192.168.10.1/32", "192.168.10.101/32", bgpPort, null,
307 s1Eth1, s1Eth100);
308
309 // Start to build intents between BGP speaker1 and BGP peer2
310 bgpPathintentConstructor(
311 "192.168.20.101/32", "192.168.20.1/32", null, bgpPort,
312 s1Eth100, s2Eth1);
313 bgpPathintentConstructor(
314 "192.168.20.101/32", "192.168.20.1/32", bgpPort, null,
315 s1Eth100, s2Eth1);
316
317 bgpPathintentConstructor(
318 "192.168.20.1/32", "192.168.20.101/32", null, bgpPort,
319 s2Eth1, s1Eth100);
320 bgpPathintentConstructor(
321 "192.168.20.1/32", "192.168.20.101/32", bgpPort, null,
322 s2Eth1, s1Eth100);
323
324 // Start to build intents between BGP speaker1 and BGP peer3
325 bgpPathintentConstructor(
326 "192.168.20.101/32", "192.168.20.2/32", null, bgpPort,
327 s1Eth100, s2Eth1);
328 bgpPathintentConstructor(
329 "192.168.20.101/32", "192.168.20.2/32", bgpPort, null,
330 s1Eth100, s2Eth1);
331
332 bgpPathintentConstructor(
333 "192.168.20.2/32", "192.168.20.101/32", null, bgpPort,
334 s2Eth1, s1Eth100);
335 bgpPathintentConstructor(
336 "192.168.20.2/32", "192.168.20.101/32", bgpPort, null,
337 s2Eth1, s1Eth100);
338
339 //
340 // Start to build intents between BGP speaker2 and BGP peer1
341 bgpPathintentConstructor(
342 "192.168.10.102/32", "192.168.10.1/32", null, bgpPort,
343 s1Eth100, s1Eth1);
344 bgpPathintentConstructor(
345 "192.168.10.102/32", "192.168.10.1/32", bgpPort, null,
346 s1Eth100, s1Eth1);
347
348 bgpPathintentConstructor(
349 "192.168.10.1/32", "192.168.10.102/32", null, bgpPort,
350 s1Eth1, s1Eth100);
351 bgpPathintentConstructor(
352 "192.168.10.1/32", "192.168.10.102/32", bgpPort, null,
353 s1Eth1, s1Eth100);
354 // Start to build intents between BGP speaker2 and BGP peer2
355 bgpPathintentConstructor(
356 "192.168.20.102/32", "192.168.20.1/32", null, bgpPort,
357 s1Eth100, s2Eth1);
358 bgpPathintentConstructor(
359 "192.168.20.102/32", "192.168.20.1/32", bgpPort, null,
360 s1Eth100, s2Eth1);
361
362 bgpPathintentConstructor(
363 "192.168.20.1/32", "192.168.20.102/32", null, bgpPort,
364 s2Eth1, s1Eth100);
365 bgpPathintentConstructor(
366 "192.168.20.1/32", "192.168.20.102/32", bgpPort, null,
367 s2Eth1, s1Eth100);
368
369 // Start to build intents between BGP speaker2 and BGP peer3
370 bgpPathintentConstructor(
371 "192.168.20.102/32", "192.168.20.2/32", null, bgpPort,
372 s1Eth100, s2Eth1);
373 bgpPathintentConstructor(
374 "192.168.20.102/32", "192.168.20.2/32", bgpPort, null,
375 s1Eth100, s2Eth1);
376
377 bgpPathintentConstructor(
378 "192.168.20.2/32", "192.168.20.102/32", null, bgpPort,
379 s2Eth1, s1Eth100);
380 bgpPathintentConstructor(
381 "192.168.20.2/32", "192.168.20.102/32", bgpPort, null,
382 s2Eth1, s1Eth100);
383
384 //
385 // Start to build intents between BGP speaker3 and BGP peer1
386 bgpPathintentConstructor(
387 "192.168.10.103/32", "192.168.10.1/32", null, bgpPort,
388 s2Eth100, s1Eth1);
389 bgpPathintentConstructor(
390 "192.168.10.103/32", "192.168.10.1/32", bgpPort, null,
391 s2Eth100, s1Eth1);
392
393 bgpPathintentConstructor(
394 "192.168.10.1/32", "192.168.10.103/32", null, bgpPort,
395 s1Eth1, s2Eth100);
396 bgpPathintentConstructor(
397 "192.168.10.1/32", "192.168.10.103/32", bgpPort, null,
398 s1Eth1, s2Eth100);
399
400 // Start to build intents between BGP speaker3 and BGP peer2
401 bgpPathintentConstructor(
402 "192.168.20.103/32", "192.168.20.1/32", null, bgpPort,
403 s2Eth100, s2Eth1);
404 bgpPathintentConstructor(
405 "192.168.20.103/32", "192.168.20.1/32", bgpPort, null,
406 s2Eth100, s2Eth1);
407
408 bgpPathintentConstructor(
409 "192.168.20.1/32", "192.168.20.103/32", null, bgpPort,
410 s2Eth1, s2Eth100);
411 bgpPathintentConstructor(
412 "192.168.20.1/32", "192.168.20.103/32", bgpPort, null,
413 s2Eth1, s2Eth100);
414
415 // Start to build intents between BGP speaker3 and BGP peer3
416 bgpPathintentConstructor(
417 "192.168.20.103/32", "192.168.20.2/32", null, bgpPort,
418 s2Eth100, s2Eth1);
419 bgpPathintentConstructor(
420 "192.168.20.103/32", "192.168.20.2/32", bgpPort, null,
421 s2Eth100, s2Eth1);
422
423 bgpPathintentConstructor(
424 "192.168.20.2/32", "192.168.20.103/32", null, bgpPort,
425 s2Eth1, s2Eth100);
426 bgpPathintentConstructor(
427 "192.168.20.2/32", "192.168.20.103/32", bgpPort, null,
428 s2Eth1, s2Eth100);
429 }
430
431 /**
432 * Constructs a BGP intent and put it into the intentList.
433 * <p/>
434 * The purpose of this method is too simplify the setUpBgpIntents() method,
435 * and to make the setUpBgpIntents() easy to read.
436 *
437 * @param srcPrefix source IP prefix to match
438 * @param dstPrefix destination IP prefix to match
439 * @param srcConnectPoint source connect point for PointToPointIntent
440 * @param dstConnectPoint destination connect point for PointToPointIntent
441 */
442 private void icmpPathintentConstructor(String srcPrefix, String dstPrefix,
443 ConnectPoint srcConnectPoint, ConnectPoint dstConnectPoint) {
444
445 TrafficSelector selector = DefaultTrafficSelector.builder()
446 .matchEthType(Ethernet.TYPE_IPV4)
447 .matchIPProtocol(IPv4.PROTOCOL_ICMP)
448 .matchIPSrc(IpPrefix.valueOf(srcPrefix))
449 .matchIPDst(IpPrefix.valueOf(dstPrefix))
450 .build();
451
452 PointToPointIntent intent = new PointToPointIntent(
Thomas Vachuskab97cf282014-10-20 23:31:12 -0700453 APPID, selector, noTreatment,
Jonathan Hartce430a42014-10-16 20:44:29 -0700454 srcConnectPoint, dstConnectPoint);
455
456 intentList.add(intent);
457 }
458
459 /**
460 * Sets up intents for ICMP paths.
461 */
462 private void setUpIcmpIntents() {
463
464 // Start to build intents between BGP speaker1 and BGP peer1
465 icmpPathintentConstructor(
466 "192.168.10.101/32", "192.168.10.1/32", s1Eth100, s1Eth1);
467 icmpPathintentConstructor(
468 "192.168.10.1/32", "192.168.10.101/32", s1Eth1, s1Eth100);
469
470 // Start to build intents between BGP speaker1 and BGP peer2
471 icmpPathintentConstructor(
472 "192.168.20.101/32", "192.168.20.1/32", s1Eth100, s2Eth1);
473 icmpPathintentConstructor(
474 "192.168.20.1/32", "192.168.20.101/32", s2Eth1, s1Eth100);
475
476 // Start to build intents between BGP speaker1 and BGP peer3
477 icmpPathintentConstructor(
478 "192.168.20.101/32", "192.168.20.2/32", s1Eth100, s2Eth1);
479 icmpPathintentConstructor(
480 "192.168.20.2/32", "192.168.20.101/32", s2Eth1, s1Eth100);
481
482 //
483 // Start to build intents between BGP speaker2 and BGP peer1
484 icmpPathintentConstructor(
485 "192.168.10.102/32", "192.168.10.1/32", s1Eth100, s1Eth1);
486 icmpPathintentConstructor(
487 "192.168.10.1/32", "192.168.10.102/32", s1Eth1, s1Eth100);
488
489 // Start to build intents between BGP speaker2 and BGP peer2
490 icmpPathintentConstructor(
491 "192.168.20.102/32", "192.168.20.1/32", s1Eth100, s2Eth1);
492 icmpPathintentConstructor(
493 "192.168.20.1/32", "192.168.20.102/32", s2Eth1, s1Eth100);
494
495 // Start to build intents between BGP speaker2 and BGP peer3
496 icmpPathintentConstructor(
497 "192.168.20.102/32", "192.168.20.2/32", s1Eth100, s2Eth1);
498 icmpPathintentConstructor(
499 "192.168.20.2/32", "192.168.20.102/32", s2Eth1, s1Eth100);
500
501 //
502 // Start to build intents between BGP speaker3 and BGP peer1
503 icmpPathintentConstructor(
504 "192.168.10.103/32", "192.168.10.1/32", s2Eth100, s1Eth1);
505 icmpPathintentConstructor(
506 "192.168.10.1/32", "192.168.10.103/32", s1Eth1, s2Eth100);
507
508 // Start to build intents between BGP speaker3 and BGP peer2
509 icmpPathintentConstructor(
510 "192.168.20.103/32", "192.168.20.1/32", s2Eth100, s2Eth1);
511 icmpPathintentConstructor(
512 "192.168.20.1/32", "192.168.20.103/32", s2Eth1, s2Eth100);
513
514 // Start to build intents between BGP speaker3 and BGP peer3
515 icmpPathintentConstructor(
516 "192.168.20.103/32", "192.168.20.2/32", s2Eth100, s2Eth1);
517 icmpPathintentConstructor(
518 "192.168.20.2/32", "192.168.20.103/32", s2Eth1, s2Eth100);
519
520 }
521
522 /**
523 * Initializes peer connectivity testing environment.
524 */
525 private void initPeerConnectivity() {
526
527 configInfoService = createMock(SdnIpConfigService.class);
528 expect(configInfoService.getBgpPeers()).andReturn(peers).anyTimes();
529 expect(configInfoService.getBgpSpeakers()).andReturn(bgpSpeakers).anyTimes();
530 replay(configInfoService);
531
532 intentService = createMock(IntentService.class);
533 replay(intentService);
534
Thomas Vachuskab97cf282014-10-20 23:31:12 -0700535 peerConnectivityManager = new PeerConnectivityManager(APPID, configInfoService,
Jonathan Hartce430a42014-10-16 20:44:29 -0700536 interfaceService, intentService);
537 }
538
539 /*
540 * EasyMock matcher that matches {@link PointToPointIntent}s but
541 * ignores the {@link IntentId} when matching.
542 * <p/>
543 * The normal intent equals method tests that the intent IDs are equal,
544 * however in these tests we can't know what the intent IDs will be in
545 * advance, so we can't set up expected intents with the correct IDs. Thus,
546 * the solution is to use an EasyMock matcher that verifies that all the
547 * value properties of the provided intent match the expected values, but
548 * ignores the intent ID when testing equality.
549 */
550 private static final class IdAgnosticPointToPointIntentMatcher implements
551 IArgumentMatcher {
552
553 private final PointToPointIntent intent;
554 private String providedIntentString;
555
556 /**
557 * Constructor taking the expected intent to match against.
558 *
559 * @param intent the expected intent
560 */
561 public IdAgnosticPointToPointIntentMatcher(PointToPointIntent intent) {
562 this.intent = intent;
563 }
564
565 @Override
566 public void appendTo(StringBuffer strBuffer) {
567 strBuffer.append("PointToPointIntentMatcher unable to match: "
568 + providedIntentString);
569 }
570
571 @Override
572 public boolean matches(Object object) {
573 if (!(object instanceof PointToPointIntent)) {
574 return false;
575 }
576
577 PointToPointIntent providedIntent = (PointToPointIntent) object;
578 providedIntentString = providedIntent.toString();
579
580 PointToPointIntent matchIntent =
Thomas Vachuskab97cf282014-10-20 23:31:12 -0700581 new PointToPointIntent(providedIntent.appId(),
Jonathan Hartce430a42014-10-16 20:44:29 -0700582 intent.selector(), intent.treatment(),
583 intent.ingressPoint(), intent.egressPoint());
584
585 return matchIntent.equals(providedIntent);
586 }
587 }
588
589 /**
590 * Matcher method to set an expected intent to match against (ignoring the
591 * the intent ID).
592 *
593 * @param intent the expected intent
594 * @return something of type PointToPointIntent
595 */
596 private static PointToPointIntent eqExceptId(
597 PointToPointIntent intent) {
598 reportMatcher(new IdAgnosticPointToPointIntentMatcher(intent));
599 return null;
600 }
601
602 /**
603 * Tests whether peer connectivity manager can set up correct BGP and
604 * ICMP intents according to specific configuration.
605 * <p/>
606 * Two tricky cases included in the configuration are: 2 peers on a same
607 * switch port, peer on the same switch with BGPd.
608 */
609 @Test
610 public void testConnectionSetup() {
611
612 reset(intentService);
613
614 // Sets up the expected PointToPoint intents.
615 for (int i = 0; i < intentList.size(); i++) {
616 intentService.submit(eqExceptId(intentList.get(i)));
617 }
618
619 replay(intentService);
620
621 // Running the interface to be tested.
622 peerConnectivityManager.start();
623
624 verify(intentService);
625
626 }
627
628 /**
629 * Tests a corner case, when there are no interfaces in the configuration.
630 */
631 @Test
632 public void testNullInterfaces() {
633 reset(interfaceService);
634 expect(interfaceService.getInterfaces()).andReturn(
635 Sets.<Interface>newHashSet()).anyTimes();
636 expect(interfaceService.getInterface(s2Eth1))
637 .andReturn(null).anyTimes();
638 expect(interfaceService.getInterface(s1Eth1))
639 .andReturn(null).anyTimes();
640 replay(interfaceService);
641
642 reset(configInfoService);
643 expect(configInfoService.getBgpPeers()).andReturn(peers).anyTimes();
644 expect(configInfoService.getBgpSpeakers()).andReturn(bgpSpeakers).anyTimes();
645 replay(configInfoService);
646
647 reset(intentService);
648 replay(intentService);
649 peerConnectivityManager.start();
650 verify(intentService);
651 }
652
653 /**
654 * Tests a corner case, when there are no BGP peers in the configuration.
655 */
656 @Test
657 public void testNullBgpPeers() {
658 reset(interfaceService);
659 expect(interfaceService.getInterfaces()).andReturn(
660 Sets.newHashSet(interfaces.values())).anyTimes();
661 replay(interfaceService);
662
663 reset(configInfoService);
664 expect(configInfoService.getBgpPeers()).andReturn(
665 new HashMap<IpAddress, BgpPeer>()).anyTimes();
666 expect(configInfoService.getBgpSpeakers()).andReturn(
667 bgpSpeakers).anyTimes();
668 replay(configInfoService);
669
670 reset(intentService);
671 replay(intentService);
672 peerConnectivityManager.start();
673 verify(intentService);
674 }
675
676 /**
677 * Tests a corner case, when there is no BGP speakers in the configuration.
678 */
679 @Test
680 public void testNullBgpSpeakers() {
681 reset(interfaceService);
682 expect(interfaceService.getInterfaces()).andReturn(
683 Sets.newHashSet(interfaces.values())).anyTimes();
684 replay(interfaceService);
685
686 reset(configInfoService);
687 expect(configInfoService.getBgpPeers()).andReturn(
688 peers).anyTimes();
689 expect(configInfoService.getBgpSpeakers()).andReturn(
690 null).anyTimes();
691 replay(configInfoService);
692
693 reset(intentService);
694 replay(intentService);
695 peerConnectivityManager.start();
696 verify(intentService);
697 }
698
699 /**
700 * Tests a corner case, when there is no Interface configured for one BGP
701 * peer.
702 */
703 @Test
704 public void testNoPeerInterface() {
705 String peerSw100Eth1 = "192.168.200.1";
706 configuredPeers.put(IpAddress.valueOf(peerSw100Eth1),
707 new BgpPeer("00:00:00:00:00:00:01:00", 1, peerSw100Eth1));
708 testConnectionSetup();
709 }
710
711 /**
712 * Tests a corner case, when there is no Interface configured for one BGP
713 * speaker.
714 * TODO: we should add a configuration correctness checking module/method
715 * before testing this corner case.
716 */
717 @Ignore
718 @Test
719 public void testNoSpeakerInterface() {
720 BgpSpeaker bgpSpeaker100 = new BgpSpeaker(
721 "bgpSpeaker100",
722 "00:00:00:00:00:00:01:00", 100,
723 "00:00:00:00:01:00");
724 List<InterfaceAddress> interfaceAddresses100 =
725 new LinkedList<InterfaceAddress>();
726 interfaceAddresses100.add(new InterfaceAddress(dpid1, 1, "192.168.10.201"));
727 interfaceAddresses100.add(new InterfaceAddress(dpid2, 1, "192.168.20.201"));
728 bgpSpeaker100.setInterfaceAddresses(interfaceAddresses100);
729 configuredBgpSpeakers.put(bgpSpeaker100.name(), bgpSpeaker100);
730 testConnectionSetup();
731 }
732}