2 * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
8 package org.opendaylight.protocol.bgp.rib.impl;
10 import static org.junit.Assert.assertArrayEquals;
11 import static org.junit.Assert.assertEquals;
12 import static org.junit.Assert.assertNull;
13 import static org.junit.Assert.assertThat;
14 import static org.junit.Assert.assertTrue;
15 import static org.junit.Assert.fail;
16 import static org.junit.matchers.JUnitMatchers.containsString;
18 import java.net.InetAddress;
19 import java.net.UnknownHostException;
20 import java.util.List;
23 import org.junit.Test;
24 import org.opendaylight.protocol.bgp.concepts.BGPTableType;
25 import org.opendaylight.protocol.bgp.parser.BGPDocumentedException;
26 import org.opendaylight.protocol.bgp.parser.BGPError;
27 import org.opendaylight.protocol.bgp.parser.BGPParameter;
28 import org.opendaylight.protocol.bgp.parser.impl.BGPMessageFactoryImpl;
29 import org.opendaylight.protocol.bgp.parser.message.BGPKeepAliveMessage;
30 import org.opendaylight.protocol.bgp.parser.message.BGPNotificationMessage;
31 import org.opendaylight.protocol.bgp.parser.message.BGPOpenMessage;
32 import org.opendaylight.protocol.bgp.parser.parameter.GracefulCapability;
33 import org.opendaylight.protocol.bgp.parser.parameter.MultiprotocolCapability;
34 import org.opendaylight.protocol.concepts.IPv4Address;
35 import org.opendaylight.protocol.framework.DeserializerException;
36 import org.opendaylight.protocol.framework.DocumentedException;
37 import org.opendaylight.protocol.framework.ProtocolMessageFactory;
38 import org.opendaylight.protocol.util.ByteArray;
39 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.AsNumber;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.LinkstateAddressFamily;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.Ipv4AddressFamily;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.UnicastSubsequentAddressFamily;
43 import org.opendaylight.yangtools.yang.binding.Notification;
45 import com.google.common.collect.Lists;
46 import com.google.common.collect.Maps;
48 public class ParserTest {
50 public static final byte[] openBMsg = new byte[] { (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
51 (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
52 (byte) 0xff, (byte) 0x00, (byte) 0x1d, (byte) 0x01, (byte) 0x04, (byte) 0x00, (byte) 0x64, (byte) 0x00, (byte) 0xb4,
53 (byte) 0x14, (byte) 0x14, (byte) 0x14, (byte) 0x14, (byte) 0x00 };
55 public static final byte[] keepAliveBMsg = new byte[] { (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
56 (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
57 (byte) 0xff, (byte) 0x00, (byte) 0x13, (byte) 0x04 };
59 public static final byte[] notificationBMsg = new byte[] { (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
60 (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
61 (byte) 0xff, (byte) 0xff, (byte) 0x00, (byte) 0x17, (byte) 0x03, (byte) 0x02, (byte) 0x04, (byte) 0x04, (byte) 0x09 };
63 final ProtocolMessageFactory<Notification> factory = new BGPMessageFactoryImpl();
66 public void testHeaderErrors() throws DeserializerException, DocumentedException {
67 byte[] wrong = new byte[] { (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
68 (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x00 };
69 wrong = ByteArray.cutBytes(wrong, 16);
71 this.factory.parse(wrong);
72 fail("Exception should have occcured.");
73 } catch (final IllegalArgumentException e) {
74 assertEquals("Too few bytes in passed array. Passed: " + wrong.length + ". Expected: >= "
75 + BGPMessageFactoryImpl.COMMON_HEADER_LENGTH + ".", e.getMessage());
82 public void testBadMsgType() throws DeserializerException {
83 final byte[] bytes = new byte[] { (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
84 (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
85 (byte) 0x00, (byte) 0x13, (byte) 0x08 };
87 this.factory.parse(bytes);
88 fail("Exception should have occured.");
89 } catch (final DocumentedException e) {
90 assertEquals(BGPError.BAD_MSG_TYPE, ((BGPDocumentedException) e).getError());
97 public void testKeepAliveMsg() throws DeserializerException, DocumentedException {
98 final Notification keepAlive = new BGPKeepAliveMessage();
99 final byte[] bytes = this.factory.put(keepAlive);
100 assertArrayEquals(keepAliveBMsg, bytes);
102 final Notification m = this.factory.parse(bytes).get(0);
104 assertTrue(m instanceof BGPKeepAliveMessage);
108 public void testBadKeepAliveMsg() throws DeserializerException {
109 final byte[] bytes = new byte[] { (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
110 (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
111 (byte) 0x00, (byte) 0x14, (byte) 0x04, (byte) 0x05 };
114 this.factory.parse(bytes);
115 fail("Exception should have occured.");
116 } catch (final DocumentedException e) {
117 assertThat(e.getMessage(), containsString("Message length field not within valid range."));
118 assertEquals(BGPError.BAD_MSG_LENGTH, ((BGPDocumentedException) e).getError());
125 public void testOpenMessage() throws UnknownHostException, DeserializerException, DocumentedException {
126 final Notification open = new BGPOpenMessage(new AsNumber((long) 100), (short) 180, new IPv4Address(InetAddress.getByName("20.20.20.20")), null);
127 final byte[] bytes = this.factory.put(open);
128 assertArrayEquals(openBMsg, bytes);
130 final Notification m = this.factory.parse(bytes).get(0);
132 assertTrue(m instanceof BGPOpenMessage);
133 assertEquals(new AsNumber((long) 100), ((BGPOpenMessage) m).getMyAS());
134 assertEquals((short) 180, ((BGPOpenMessage) m).getHoldTime());
135 assertEquals(new IPv4Address(InetAddress.getByName("20.20.20.20")), ((BGPOpenMessage) m).getBgpId());
136 assertTrue(((BGPOpenMessage) m).getOptParams().isEmpty());
140 public void testBadHoldTimeError() throws DeserializerException {
141 final byte[] bMsg = new byte[] { (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
142 (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
143 (byte) 0x00, (byte) 0x1d, (byte) 0x01, (byte) 0x04, (byte) 0x00, (byte) 0x64, (byte) 0x00, (byte) 0x01, (byte) 0x14,
144 (byte) 0x14, (byte) 0x14, (byte) 0x14, (byte) 0x00 };
147 this.factory.parse(bMsg);
148 fail("Exception should have occured.");
149 } catch (final DocumentedException e) {
150 assertEquals("Hold time value not acceptable.", e.getMessage());
151 assertEquals(BGPError.HOLD_TIME_NOT_ACC, ((BGPDocumentedException) e).getError());
158 public void testBadMsgLength() throws DeserializerException {
159 final byte[] bMsg = new byte[] { (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
160 (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
161 (byte) 0x00, (byte) 0x1b, (byte) 0x01, (byte) 0x04, (byte) 0x00, (byte) 0x64, (byte) 0x00, (byte) 0xb4, (byte) 0xff,
162 (byte) 0xff, (byte) 0xff };
165 this.factory.parse(bMsg);
166 fail("Exception should have occured.");
167 } catch (final DocumentedException e) {
168 assertEquals("Open message too small.", e.getMessage());
169 assertEquals(BGPError.BAD_MSG_LENGTH, ((BGPDocumentedException) e).getError());
174 public void testBadVersion() throws DeserializerException {
175 final byte[] bMsg = new byte[] { (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
176 (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
177 (byte) 0x00, (byte) 0x1d, (byte) 0x01, (byte) 0x08, (byte) 0x00, (byte) 0x64, (byte) 0x00, (byte) 0xb4, (byte) 0x14,
178 (byte) 0x14, (byte) 0x14, (byte) 0x14, (byte) 0x00 };
181 this.factory.parse(bMsg);
182 fail("Exception should have occured.");
183 } catch (final DocumentedException e) {
184 assertEquals("BGP Protocol version 8 not supported.", e.getMessage());
185 assertEquals(BGPError.VERSION_NOT_SUPPORTED, ((BGPDocumentedException) e).getError());
192 public void testNotificationMsg() throws DeserializerException, DocumentedException {
193 Notification notMsg = new BGPNotificationMessage(BGPError.OPT_PARAM_NOT_SUPPORTED, new byte[] { 4, 9 });
194 byte[] bytes = this.factory.put(notMsg);
195 assertArrayEquals(notificationBMsg, bytes);
197 Notification m = this.factory.parse(bytes).get(0);
199 assertTrue(m instanceof BGPNotificationMessage);
200 assertEquals(BGPError.OPT_PARAM_NOT_SUPPORTED, ((BGPNotificationMessage) m).getError());
201 assertArrayEquals(new byte[] { 4, 9 }, ((BGPNotificationMessage) m).getData());
203 notMsg = new BGPNotificationMessage(BGPError.CONNECTION_NOT_SYNC);
204 bytes = this.factory.put(notMsg);
206 m = this.factory.parse(bytes).get(0);
208 assertTrue(m instanceof BGPNotificationMessage);
209 assertEquals(BGPError.CONNECTION_NOT_SYNC, ((BGPNotificationMessage) m).getError());
210 assertNull(((BGPNotificationMessage) m).getData());
214 public void testWrongLength() throws DeserializerException {
215 final byte[] bMsg = new byte[] { (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
216 (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
217 (byte) 0x00, (byte) 0x14, (byte) 0x03, (byte) 0x02 };
220 this.factory.parse(bMsg);
221 fail("Exception should have occured.");
222 } catch (final DocumentedException e) {
223 assertEquals("Notification message too small.", e.getMessage());
224 assertEquals(BGPError.BAD_MSG_LENGTH, ((BGPDocumentedException) e).getError());
231 public void testUnrecognizedError() throws DeserializerException, DocumentedException {
232 final byte[] bMsg = new byte[] { (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
233 (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
234 (byte) 0x00, (byte) 0x15, (byte) 0x03, (byte) 0x02, (byte) 0xaa };
237 this.factory.parse(bMsg);
238 fail("Exception should have occured.");
239 } catch (final IllegalArgumentException e) {
240 assertEquals("BGP Error code 2 and subcode 170 not recognized.", e.getMessage());
247 public void testTLVParser() throws UnknownHostException {
249 final BGPTableType t1 = new BGPTableType(Ipv4AddressFamily.class, UnicastSubsequentAddressFamily.class);
250 final BGPTableType t2 = new BGPTableType(LinkstateAddressFamily.class, UnicastSubsequentAddressFamily.class);
252 final List<BGPParameter> tlvs = Lists.newArrayList();
253 tlvs.add(new MultiprotocolCapability(t1));
254 tlvs.add(new MultiprotocolCapability(t2));
255 final Map<BGPTableType, Boolean> tableTypes = Maps.newHashMap();
256 tableTypes.put(t1, true);
257 tableTypes.put(t2, true);
258 tlvs.add(new GracefulCapability(true, 0, tableTypes));
259 final BGPOpenMessage open = new BGPOpenMessage(new AsNumber((long) 72), (short) 180, new IPv4Address(InetAddress.getByName("172.20.160.170")), tlvs);
261 this.factory.put(open);
263 // assertArrayEquals(openWithCpblt, bytes);