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