blob: 7bbabeb9eba90c0d1927156ed0bcf8b8add5c977 [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 Hart20d8e512014-10-16 11:05:52 -070019package org.onlab.onos.sdnip.bgp;
20
21import static org.easymock.EasyMock.createMock;
22import static org.easymock.EasyMock.expect;
23import static org.easymock.EasyMock.replay;
24import static org.hamcrest.Matchers.is;
25import static org.hamcrest.Matchers.not;
26import static org.junit.Assert.assertThat;
27
28import java.util.ArrayList;
29
30import org.junit.Before;
31import org.junit.Test;
32import org.onlab.packet.IpAddress;
33import org.onlab.packet.IpPrefix;
34
35/**
36 * Unit tests for the BgpRouteEntry class.
37 */
38public class BgpRouteEntryTest {
39 private BgpSession bgpSession;
40 private static final IpAddress BGP_SESSION_BGP_ID =
41 IpAddress.valueOf("10.0.0.1");
42 private static final IpAddress BGP_SESSION_IP_ADDRESS =
43 IpAddress.valueOf("20.0.0.1");
44
45 private BgpSession bgpSession2;
46 private static final IpAddress BGP_SESSION_BGP_ID2 =
47 IpAddress.valueOf("10.0.0.2");
48 private static final IpAddress BGP_SESSION_IP_ADDRESS2 =
49 IpAddress.valueOf("20.0.0.1");
50
51 private BgpSession bgpSession3;
52 private static final IpAddress BGP_SESSION_BGP_ID3 =
53 IpAddress.valueOf("10.0.0.1");
54 private static final IpAddress BGP_SESSION_IP_ADDRESS3 =
55 IpAddress.valueOf("20.0.0.2");
56
57 @Before
58 public void setUp() throws Exception {
59 // Mock objects for testing
60 bgpSession = createMock(BgpSession.class);
61 bgpSession2 = createMock(BgpSession.class);
62 bgpSession3 = createMock(BgpSession.class);
63
64 // Setup the BGP Sessions
65 expect(bgpSession.getRemoteBgpId())
66 .andReturn(BGP_SESSION_BGP_ID).anyTimes();
67 expect(bgpSession.getRemoteIp4Address())
68 .andReturn(BGP_SESSION_IP_ADDRESS).anyTimes();
69 //
70 expect(bgpSession2.getRemoteBgpId())
71 .andReturn(BGP_SESSION_BGP_ID2).anyTimes();
72 expect(bgpSession2.getRemoteIp4Address())
73 .andReturn(BGP_SESSION_IP_ADDRESS2).anyTimes();
74 //
75 expect(bgpSession3.getRemoteBgpId())
76 .andReturn(BGP_SESSION_BGP_ID3).anyTimes();
77 expect(bgpSession3.getRemoteIp4Address())
78 .andReturn(BGP_SESSION_IP_ADDRESS3).anyTimes();
79
80 replay(bgpSession);
81 replay(bgpSession2);
82 replay(bgpSession3);
83 }
84
85 /**
86 * Generates a BGP Route Entry.
87 *
88 * @return a generated BGP Route Entry
89 */
90 private BgpRouteEntry generateBgpRouteEntry() {
91 IpPrefix prefix = IpPrefix.valueOf("1.2.3.0/24");
92 IpAddress nextHop = IpAddress.valueOf("5.6.7.8");
93 byte origin = BgpConstants.Update.Origin.IGP;
94 // Setup the AS Path
95 ArrayList<BgpRouteEntry.PathSegment> pathSegments = new ArrayList<>();
96 byte pathSegmentType1 = (byte) BgpConstants.Update.AsPath.AS_SEQUENCE;
97 ArrayList<Long> segmentAsNumbers1 = new ArrayList<>();
98 segmentAsNumbers1.add((long) 1);
99 segmentAsNumbers1.add((long) 2);
100 segmentAsNumbers1.add((long) 3);
101 BgpRouteEntry.PathSegment pathSegment1 =
102 new BgpRouteEntry.PathSegment(pathSegmentType1, segmentAsNumbers1);
103 pathSegments.add(pathSegment1);
104 //
105 byte pathSegmentType2 = (byte) BgpConstants.Update.AsPath.AS_SET;
106 ArrayList<Long> segmentAsNumbers2 = new ArrayList<>();
107 segmentAsNumbers2.add((long) 4);
108 segmentAsNumbers2.add((long) 5);
109 segmentAsNumbers2.add((long) 6);
110 BgpRouteEntry.PathSegment pathSegment2 =
111 new BgpRouteEntry.PathSegment(pathSegmentType2, segmentAsNumbers2);
112 pathSegments.add(pathSegment2);
113 //
114 BgpRouteEntry.AsPath asPath = new BgpRouteEntry.AsPath(pathSegments);
115 //
116 long localPref = 100;
117 long multiExitDisc = 20;
118
119 BgpRouteEntry bgpRouteEntry =
120 new BgpRouteEntry(bgpSession, prefix, nextHop, origin, asPath,
121 localPref);
122 bgpRouteEntry.setMultiExitDisc(multiExitDisc);
123
124 return bgpRouteEntry;
125 }
126
127 /**
128 * Tests valid class constructor.
129 */
130 @Test
131 public void testConstructor() {
132 BgpRouteEntry bgpRouteEntry = generateBgpRouteEntry();
133
134 String expectedString =
135 "BgpRouteEntry{prefix=1.2.3.0/24, nextHop=5.6.7.8, " +
136 "bgpId=10.0.0.1, origin=0, asPath=AsPath{pathSegments=" +
137 "[PathSegment{type=2, segmentAsNumbers=[1, 2, 3]}, " +
138 "PathSegment{type=1, segmentAsNumbers=[4, 5, 6]}]}, " +
139 "localPref=100, multiExitDisc=20}";
140 assertThat(bgpRouteEntry.toString(), is(expectedString));
141 }
142
143 /**
144 * Tests invalid class constructor for null BGP Session.
145 */
146 @Test(expected = NullPointerException.class)
147 public void testInvalidConstructorNullBgpSession() {
148 BgpSession bgpSessionNull = null;
149 IpPrefix prefix = IpPrefix.valueOf("1.2.3.0/24");
150 IpAddress nextHop = IpAddress.valueOf("5.6.7.8");
151 byte origin = BgpConstants.Update.Origin.IGP;
152 // Setup the AS Path
153 ArrayList<BgpRouteEntry.PathSegment> pathSegments = new ArrayList<>();
154 BgpRouteEntry.AsPath asPath = new BgpRouteEntry.AsPath(pathSegments);
155 //
156 long localPref = 100;
157
158 new BgpRouteEntry(bgpSessionNull, prefix, nextHop, origin, asPath,
159 localPref);
160 }
161
162 /**
163 * Tests invalid class constructor for null AS Path.
164 */
165 @Test(expected = NullPointerException.class)
166 public void testInvalidConstructorNullAsPath() {
167 IpPrefix prefix = IpPrefix.valueOf("1.2.3.0/24");
168 IpAddress nextHop = IpAddress.valueOf("5.6.7.8");
169 byte origin = BgpConstants.Update.Origin.IGP;
170 BgpRouteEntry.AsPath asPath = null;
171 long localPref = 100;
172
173 new BgpRouteEntry(bgpSession, prefix, nextHop, origin, asPath,
174 localPref);
175 }
176
177 /**
178 * Tests getting the fields of a BGP route entry.
179 */
180 @Test
181 public void testGetFields() {
182 // Create the fields to compare against
183 IpPrefix prefix = IpPrefix.valueOf("1.2.3.0/24");
184 IpAddress nextHop = IpAddress.valueOf("5.6.7.8");
185 byte origin = BgpConstants.Update.Origin.IGP;
186 // Setup the AS Path
187 ArrayList<BgpRouteEntry.PathSegment> pathSegments = new ArrayList<>();
188 byte pathSegmentType1 = (byte) BgpConstants.Update.AsPath.AS_SEQUENCE;
189 ArrayList<Long> segmentAsNumbers1 = new ArrayList<>();
190 segmentAsNumbers1.add((long) 1);
191 segmentAsNumbers1.add((long) 2);
192 segmentAsNumbers1.add((long) 3);
193 BgpRouteEntry.PathSegment pathSegment1 =
194 new BgpRouteEntry.PathSegment(pathSegmentType1, segmentAsNumbers1);
195 pathSegments.add(pathSegment1);
196 //
197 byte pathSegmentType2 = (byte) BgpConstants.Update.AsPath.AS_SET;
198 ArrayList<Long> segmentAsNumbers2 = new ArrayList<>();
199 segmentAsNumbers2.add((long) 4);
200 segmentAsNumbers2.add((long) 5);
201 segmentAsNumbers2.add((long) 6);
202 BgpRouteEntry.PathSegment pathSegment2 =
203 new BgpRouteEntry.PathSegment(pathSegmentType2, segmentAsNumbers2);
204 pathSegments.add(pathSegment2);
205 //
206 BgpRouteEntry.AsPath asPath = new BgpRouteEntry.AsPath(pathSegments);
207 //
208 long localPref = 100;
209 long multiExitDisc = 20;
210
211 // Generate the entry to test
212 BgpRouteEntry bgpRouteEntry = generateBgpRouteEntry();
213
214 assertThat(bgpRouteEntry.prefix(), is(prefix));
215 assertThat(bgpRouteEntry.nextHop(), is(nextHop));
216 assertThat(bgpRouteEntry.getBgpSession(), is(bgpSession));
217 assertThat(bgpRouteEntry.getOrigin(), is(origin));
218 assertThat(bgpRouteEntry.getAsPath(), is(asPath));
219 assertThat(bgpRouteEntry.getLocalPref(), is(localPref));
220 assertThat(bgpRouteEntry.getMultiExitDisc(), is(multiExitDisc));
221 }
222
223 /**
224 * Tests whether a BGP route entry is a local route.
225 */
226 @Test
227 public void testIsLocalRoute() {
228 //
229 // Test non-local route
230 //
231 BgpRouteEntry bgpRouteEntry = generateBgpRouteEntry();
232 assertThat(bgpRouteEntry.isLocalRoute(), is(false));
233
234 //
235 // Test local route with AS Path that begins with AS_SET
236 //
237 IpPrefix prefix = IpPrefix.valueOf("1.2.3.0/24");
238 IpAddress nextHop = IpAddress.valueOf("5.6.7.8");
239 byte origin = BgpConstants.Update.Origin.IGP;
240 // Setup the AS Path
241 ArrayList<BgpRouteEntry.PathSegment> pathSegments = new ArrayList<>();
242 byte pathSegmentType1 = (byte) BgpConstants.Update.AsPath.AS_SET;
243 ArrayList<Long> segmentAsNumbers1 = new ArrayList<>();
244 segmentAsNumbers1.add((long) 1);
245 segmentAsNumbers1.add((long) 2);
246 segmentAsNumbers1.add((long) 3);
247 BgpRouteEntry.PathSegment pathSegment1 =
248 new BgpRouteEntry.PathSegment(pathSegmentType1, segmentAsNumbers1);
249 pathSegments.add(pathSegment1);
250 //
251 byte pathSegmentType2 = (byte) BgpConstants.Update.AsPath.AS_SEQUENCE;
252 ArrayList<Long> segmentAsNumbers2 = new ArrayList<>();
253 segmentAsNumbers2.add((long) 4);
254 segmentAsNumbers2.add((long) 5);
255 segmentAsNumbers2.add((long) 6);
256 BgpRouteEntry.PathSegment pathSegment2 =
257 new BgpRouteEntry.PathSegment(pathSegmentType2, segmentAsNumbers2);
258 pathSegments.add(pathSegment2);
259 //
260 BgpRouteEntry.AsPath asPath = new BgpRouteEntry.AsPath(pathSegments);
261 //
262 long localPref = 100;
263 long multiExitDisc = 20;
264 //
265 bgpRouteEntry =
266 new BgpRouteEntry(bgpSession, prefix, nextHop, origin, asPath,
267 localPref);
268 bgpRouteEntry.setMultiExitDisc(multiExitDisc);
269 assertThat(bgpRouteEntry.isLocalRoute(), is(true));
270
271 //
272 // Test local route with empty AS Path
273 //
274 pathSegments = new ArrayList<>();
275 asPath = new BgpRouteEntry.AsPath(pathSegments);
276 bgpRouteEntry =
277 new BgpRouteEntry(bgpSession, prefix, nextHop, origin, asPath,
278 localPref);
279 bgpRouteEntry.setMultiExitDisc(multiExitDisc);
280 assertThat(bgpRouteEntry.isLocalRoute(), is(true));
281 }
282
283 /**
284 * Tests getting the BGP Neighbor AS number for a route.
285 */
286 @Test
287 public void testGetNeighborAs() {
288 //
289 // Get neighbor AS for non-local route
290 //
291 BgpRouteEntry bgpRouteEntry = generateBgpRouteEntry();
292 assertThat(bgpRouteEntry.getNeighborAs(), is((long) 1));
293
294 //
295 // Get neighbor AS for a local route
296 //
297 IpPrefix prefix = IpPrefix.valueOf("1.2.3.0/24");
298 IpAddress nextHop = IpAddress.valueOf("5.6.7.8");
299 byte origin = BgpConstants.Update.Origin.IGP;
300 // Setup the AS Path
301 ArrayList<BgpRouteEntry.PathSegment> pathSegments = new ArrayList<>();
302 BgpRouteEntry.AsPath asPath = new BgpRouteEntry.AsPath(pathSegments);
303 //
304 long localPref = 100;
305 long multiExitDisc = 20;
306 //
307 bgpRouteEntry =
308 new BgpRouteEntry(bgpSession, prefix, nextHop, origin, asPath,
309 localPref);
310 bgpRouteEntry.setMultiExitDisc(multiExitDisc);
311 assertThat(bgpRouteEntry.getNeighborAs(), is(BgpConstants.BGP_AS_0));
312 }
313
314 /**
315 * Tests whether a BGP route entry has AS Path loop.
316 */
317 @Test
318 public void testHasAsPathLoop() {
319 BgpRouteEntry bgpRouteEntry = generateBgpRouteEntry();
320
321 // Test for loops: test each AS number in the interval [1, 6]
322 for (int i = 1; i <= 6; i++) {
323 assertThat(bgpRouteEntry.hasAsPathLoop(i), is(true));
324 }
325
326 // Test for non-loops
327 assertThat(bgpRouteEntry.hasAsPathLoop(500), is(false));
328 }
329
330 /**
331 * Tests the BGP Decision Process comparison of BGP routes.
332 */
333 @Test
334 public void testBgpDecisionProcessComparison() {
335 BgpRouteEntry bgpRouteEntry1 = generateBgpRouteEntry();
336 BgpRouteEntry bgpRouteEntry2 = generateBgpRouteEntry();
337
338 //
339 // Compare two routes that are same
340 //
341 assertThat(bgpRouteEntry1.isBetterThan(bgpRouteEntry2), is(true));
342 assertThat(bgpRouteEntry2.isBetterThan(bgpRouteEntry1), is(true));
343
344 //
345 // Compare two routes with different LOCAL_PREF
346 //
347 IpPrefix prefix = IpPrefix.valueOf("1.2.3.0/24");
348 IpAddress nextHop = IpAddress.valueOf("5.6.7.8");
349 byte origin = BgpConstants.Update.Origin.IGP;
350 // Setup the AS Path
351 ArrayList<BgpRouteEntry.PathSegment> pathSegments = new ArrayList<>();
352 byte pathSegmentType1 = (byte) BgpConstants.Update.AsPath.AS_SEQUENCE;
353 ArrayList<Long> segmentAsNumbers1 = new ArrayList<>();
354 segmentAsNumbers1.add((long) 1);
355 segmentAsNumbers1.add((long) 2);
356 segmentAsNumbers1.add((long) 3);
357 BgpRouteEntry.PathSegment pathSegment1 =
358 new BgpRouteEntry.PathSegment(pathSegmentType1, segmentAsNumbers1);
359 pathSegments.add(pathSegment1);
360 //
361 byte pathSegmentType2 = (byte) BgpConstants.Update.AsPath.AS_SET;
362 ArrayList<Long> segmentAsNumbers2 = new ArrayList<>();
363 segmentAsNumbers2.add((long) 4);
364 segmentAsNumbers2.add((long) 5);
365 segmentAsNumbers2.add((long) 6);
366 BgpRouteEntry.PathSegment pathSegment2 =
367 new BgpRouteEntry.PathSegment(pathSegmentType2, segmentAsNumbers2);
368 pathSegments.add(pathSegment2);
369 //
370 BgpRouteEntry.AsPath asPath = new BgpRouteEntry.AsPath(pathSegments);
371 //
372 long localPref = 50; // Different
373 long multiExitDisc = 20;
374 bgpRouteEntry2 =
375 new BgpRouteEntry(bgpSession, prefix, nextHop, origin, asPath,
376 localPref);
377 bgpRouteEntry2.setMultiExitDisc(multiExitDisc);
378 //
379 assertThat(bgpRouteEntry1.isBetterThan(bgpRouteEntry2), is(true));
380 assertThat(bgpRouteEntry2.isBetterThan(bgpRouteEntry1), is(false));
381 localPref = bgpRouteEntry1.getLocalPref(); // Restore
382
383 //
384 // Compare two routes with different AS_PATH length
385 //
386 ArrayList<BgpRouteEntry.PathSegment> pathSegments2 = new ArrayList<>();
387 pathSegments2.add(pathSegment1);
388 // Different AS Path
389 BgpRouteEntry.AsPath asPath2 = new BgpRouteEntry.AsPath(pathSegments2);
390 bgpRouteEntry2 =
391 new BgpRouteEntry(bgpSession, prefix, nextHop, origin, asPath2,
392 localPref);
393 bgpRouteEntry2.setMultiExitDisc(multiExitDisc);
394 //
395 assertThat(bgpRouteEntry1.isBetterThan(bgpRouteEntry2), is(false));
396 assertThat(bgpRouteEntry2.isBetterThan(bgpRouteEntry1), is(true));
397
398 //
399 // Compare two routes with different ORIGIN
400 //
401 origin = BgpConstants.Update.Origin.EGP; // Different
402 bgpRouteEntry2 =
403 new BgpRouteEntry(bgpSession, prefix, nextHop, origin, asPath,
404 localPref);
405 bgpRouteEntry2.setMultiExitDisc(multiExitDisc);
406 //
407 assertThat(bgpRouteEntry1.isBetterThan(bgpRouteEntry2), is(true));
408 assertThat(bgpRouteEntry2.isBetterThan(bgpRouteEntry1), is(false));
409 origin = bgpRouteEntry1.getOrigin(); // Restore
410
411 //
412 // Compare two routes with different MULTI_EXIT_DISC
413 //
414 multiExitDisc = 10; // Different
415 bgpRouteEntry2 =
416 new BgpRouteEntry(bgpSession, prefix, nextHop, origin, asPath,
417 localPref);
418 bgpRouteEntry2.setMultiExitDisc(multiExitDisc);
419 //
420 assertThat(bgpRouteEntry1.isBetterThan(bgpRouteEntry2), is(true));
421 assertThat(bgpRouteEntry2.isBetterThan(bgpRouteEntry1), is(false));
422 multiExitDisc = bgpRouteEntry1.getMultiExitDisc(); // Restore
423
424 //
425 // Compare two routes with different BGP ID
426 //
427 bgpRouteEntry2 =
428 new BgpRouteEntry(bgpSession2, prefix, nextHop, origin, asPath,
429 localPref);
430 bgpRouteEntry2.setMultiExitDisc(multiExitDisc);
431 //
432 assertThat(bgpRouteEntry1.isBetterThan(bgpRouteEntry2), is(true));
433 assertThat(bgpRouteEntry2.isBetterThan(bgpRouteEntry1), is(false));
434
435 //
436 // Compare two routes with different BGP address
437 //
438 bgpRouteEntry2 =
439 new BgpRouteEntry(bgpSession3, prefix, nextHop, origin, asPath,
440 localPref);
441 bgpRouteEntry2.setMultiExitDisc(multiExitDisc);
442 //
443 assertThat(bgpRouteEntry1.isBetterThan(bgpRouteEntry2), is(true));
444 assertThat(bgpRouteEntry2.isBetterThan(bgpRouteEntry1), is(false));
445 }
446
447 /**
448 * Tests equality of {@link BgpRouteEntry}.
449 */
450 @Test
451 public void testEquality() {
452 BgpRouteEntry bgpRouteEntry1 = generateBgpRouteEntry();
453 BgpRouteEntry bgpRouteEntry2 = generateBgpRouteEntry();
454
455 assertThat(bgpRouteEntry1, is(bgpRouteEntry2));
456 }
457
458 /**
459 * Tests non-equality of {@link BgpRouteEntry}.
460 */
461 @Test
462 public void testNonEquality() {
463 BgpRouteEntry bgpRouteEntry1 = generateBgpRouteEntry();
464
465 // Setup BGP Route 2
466 IpPrefix prefix = IpPrefix.valueOf("1.2.3.0/24");
467 IpAddress nextHop = IpAddress.valueOf("5.6.7.8");
468 byte origin = BgpConstants.Update.Origin.IGP;
469 // Setup the AS Path
470 ArrayList<BgpRouteEntry.PathSegment> pathSegments = new ArrayList<>();
471 byte pathSegmentType1 = (byte) BgpConstants.Update.AsPath.AS_SEQUENCE;
472 ArrayList<Long> segmentAsNumbers1 = new ArrayList<>();
473 segmentAsNumbers1.add((long) 1);
474 segmentAsNumbers1.add((long) 2);
475 segmentAsNumbers1.add((long) 3);
476 BgpRouteEntry.PathSegment pathSegment1 =
477 new BgpRouteEntry.PathSegment(pathSegmentType1, segmentAsNumbers1);
478 pathSegments.add(pathSegment1);
479 //
480 byte pathSegmentType2 = (byte) BgpConstants.Update.AsPath.AS_SET;
481 ArrayList<Long> segmentAsNumbers2 = new ArrayList<>();
482 segmentAsNumbers2.add((long) 4);
483 segmentAsNumbers2.add((long) 5);
484 segmentAsNumbers2.add((long) 6);
485 BgpRouteEntry.PathSegment pathSegment2 =
486 new BgpRouteEntry.PathSegment(pathSegmentType2, segmentAsNumbers2);
487 pathSegments.add(pathSegment2);
488 //
489 BgpRouteEntry.AsPath asPath = new BgpRouteEntry.AsPath(pathSegments);
490 //
491 long localPref = 500; // Different
492 long multiExitDisc = 20;
493 BgpRouteEntry bgpRouteEntry2 =
494 new BgpRouteEntry(bgpSession, prefix, nextHop, origin, asPath,
495 localPref);
496 bgpRouteEntry2.setMultiExitDisc(multiExitDisc);
497
498 assertThat(bgpRouteEntry1, is(not(bgpRouteEntry2)));
499 }
500
501 /**
502 * Tests object string representation.
503 */
504 @Test
505 public void testToString() {
506 BgpRouteEntry bgpRouteEntry = generateBgpRouteEntry();
507
508 String expectedString =
509 "BgpRouteEntry{prefix=1.2.3.0/24, nextHop=5.6.7.8, " +
510 "bgpId=10.0.0.1, origin=0, asPath=AsPath{pathSegments=" +
511 "[PathSegment{type=2, segmentAsNumbers=[1, 2, 3]}, " +
512 "PathSegment{type=1, segmentAsNumbers=[4, 5, 6]}]}, " +
513 "localPref=100, multiExitDisc=20}";
514 assertThat(bgpRouteEntry.toString(), is(expectedString));
515 }
516}