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.BGPAddressFamily;
25 import org.opendaylight.protocol.bgp.concepts.BGPSubsequentAddressFamily;
26 import org.opendaylight.protocol.bgp.concepts.BGPTableType;
27 import org.opendaylight.protocol.bgp.parser.BGPDocumentedException;
28 import org.opendaylight.protocol.bgp.parser.BGPError;
29 import org.opendaylight.protocol.bgp.parser.BGPMessage;
30 import org.opendaylight.protocol.bgp.parser.BGPParameter;
31 import org.opendaylight.protocol.bgp.parser.impl.BGPMessageFactory;
32 import org.opendaylight.protocol.bgp.parser.message.BGPKeepAliveMessage;
33 import org.opendaylight.protocol.bgp.parser.message.BGPNotificationMessage;
34 import org.opendaylight.protocol.bgp.parser.message.BGPOpenMessage;
35 import org.opendaylight.protocol.bgp.parser.parameter.GracefulCapability;
36 import org.opendaylight.protocol.bgp.parser.parameter.MultiprotocolCapability;
37 import org.opendaylight.protocol.concepts.ASNumber;
38 import org.opendaylight.protocol.concepts.IPv4Address;
39 import org.opendaylight.protocol.framework.DeserializerException;
40 import org.opendaylight.protocol.framework.DocumentedException;
41 import org.opendaylight.protocol.framework.ProtocolMessageFactory;
42 import org.opendaylight.protocol.util.ByteArray;
44 import com.google.common.collect.Lists;
45 import com.google.common.collect.Maps;
47 public class ParserTest {
49 public static final byte[] openBMsg = new byte[] { (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
50 (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
51 (byte) 0xff, (byte) 0x00, (byte) 0x1d, (byte) 0x01, (byte) 0x04, (byte) 0x00, (byte) 0x64, (byte) 0x00, (byte) 0xb4,
52 (byte) 0x14, (byte) 0x14, (byte) 0x14, (byte) 0x14, (byte) 0x00 };
54 public static final byte[] keepAliveBMsg = new byte[] { (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
55 (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
56 (byte) 0xff, (byte) 0x00, (byte) 0x13, (byte) 0x04 };
58 public static final byte[] notificationBMsg = new byte[] { (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
59 (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
60 (byte) 0xff, (byte) 0xff, (byte) 0x00, (byte) 0x17, (byte) 0x03, (byte) 0x02, (byte) 0x04, (byte) 0x04, (byte) 0x09 };
62 final ProtocolMessageFactory factory = new BGPMessageFactory();
65 public void testHeaderErrors() throws DeserializerException, DocumentedException {
66 byte[] wrong = new byte[] { (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
67 (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x00 };
68 wrong = ByteArray.cutBytes(wrong, 16);
70 this.factory.parse(wrong);
71 fail("Exception should have occcured.");
72 } catch (final IllegalArgumentException e) {
73 assertEquals("Too few bytes in passed array. Passed: " + wrong.length + ". Expected: >= "
74 + BGPMessageFactory.COMMON_HEADER_LENGTH + ".", e.getMessage());
81 public void testBadMsgType() throws DeserializerException {
82 byte[] bytes = new byte[] { (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
83 (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x00,
84 (byte) 0x13, (byte) 0x08 };
85 bytes = ByteArray.cutBytes(bytes, 16);
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 BGPMessage keepAlive = new BGPKeepAliveMessage();
99 byte[] bytes = this.factory.put(keepAlive);
100 assertArrayEquals(keepAliveBMsg, bytes);
102 bytes = ByteArray.cutBytes(bytes, 16);
103 final BGPMessage m = (BGPMessage) this.factory.parse(bytes);
105 assertTrue(m instanceof BGPKeepAliveMessage);
109 public void testBadKeepAliveMsg() throws DeserializerException {
110 byte[] bytes = new byte[] { (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
111 (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x00,
112 (byte) 0x14, (byte) 0x04, (byte) 0x05 };
114 bytes = ByteArray.cutBytes(bytes, 16);
116 this.factory.parse(bytes);
117 fail("Exception should have occured.");
118 } catch (final DocumentedException e) {
119 assertThat(e.getMessage(), containsString("Message length field not within valid range."));
120 assertEquals(BGPError.BAD_MSG_LENGTH, ((BGPDocumentedException) e).getError());
127 public void testOpenMessage() throws UnknownHostException, DeserializerException, DocumentedException {
128 final BGPMessage open = new BGPOpenMessage(new ASNumber(100), (short) 180, new IPv4Address(InetAddress.getByName("20.20.20.20")), null);
129 byte[] bytes = this.factory.put(open);
130 assertArrayEquals(openBMsg, bytes);
132 bytes = ByteArray.cutBytes(bytes, 16);
133 final BGPMessage m = (BGPMessage) this.factory.parse(bytes);
135 assertTrue(m instanceof BGPOpenMessage);
136 assertEquals(new ASNumber(100), ((BGPOpenMessage) m).getMyAS());
137 assertEquals((short) 180, ((BGPOpenMessage) m).getHoldTime());
138 assertEquals(new IPv4Address(InetAddress.getByName("20.20.20.20")), ((BGPOpenMessage) m).getBgpId());
139 assertTrue(((BGPOpenMessage) m).getOptParams().isEmpty());
143 public void testBadHoldTimeError() throws DeserializerException {
144 byte[] bMsg = new byte[] { (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
145 (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x00,
146 (byte) 0x1d, (byte) 0x01, (byte) 0x04, (byte) 0x00, (byte) 0x64, (byte) 0x00, (byte) 0x01, (byte) 0x14, (byte) 0x14,
147 (byte) 0x14, (byte) 0x14, (byte) 0x00 };
149 bMsg = ByteArray.cutBytes(bMsg, 16);
151 this.factory.parse(bMsg);
152 fail("Exception should have occured.");
153 } catch (final DocumentedException e) {
154 assertEquals("Hold time value not acceptable.", e.getMessage());
155 assertEquals(BGPError.HOLD_TIME_NOT_ACC, ((BGPDocumentedException) e).getError());
162 public void testBadMsgLength() throws DeserializerException {
163 byte[] bMsg = new byte[] { (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
164 (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x00,
165 (byte) 0x1b, (byte) 0x01, (byte) 0x04, (byte) 0x00, (byte) 0x64, (byte) 0x00, (byte) 0xb4, (byte) 0xff, (byte) 0xff,
168 bMsg = ByteArray.cutBytes(bMsg, 16);
170 this.factory.parse(bMsg);
171 fail("Exception should have occured.");
172 } catch (final DocumentedException e) {
173 assertEquals("Open message too small.", e.getMessage());
174 assertEquals(BGPError.BAD_MSG_LENGTH, ((BGPDocumentedException) e).getError());
179 public void testBadVersion() throws DeserializerException {
180 byte[] bMsg = new byte[] { (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
181 (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x00,
182 (byte) 0x1d, (byte) 0x01, (byte) 0x08, (byte) 0x00, (byte) 0x64, (byte) 0x00, (byte) 0xb4, (byte) 0x14, (byte) 0x14,
183 (byte) 0x14, (byte) 0x14, (byte) 0x00 };
185 bMsg = ByteArray.cutBytes(bMsg, 16);
187 this.factory.parse(bMsg);
188 fail("Exception should have occured.");
189 } catch (final DocumentedException e) {
190 assertEquals("BGP Protocol version 8 not supported.", e.getMessage());
191 assertEquals(BGPError.VERSION_NOT_SUPPORTED, ((BGPDocumentedException) e).getError());
198 public void testNotificationMsg() throws DeserializerException, DocumentedException {
199 BGPMessage notMsg = new BGPNotificationMessage(BGPError.OPT_PARAM_NOT_SUPPORTED, new byte[] { 4, 9 });
200 byte[] bytes = this.factory.put(notMsg);
201 assertArrayEquals(notificationBMsg, bytes);
203 bytes = ByteArray.cutBytes(bytes, 16);
204 BGPMessage m = (BGPMessage) this.factory.parse(bytes);
206 assertTrue(m instanceof BGPNotificationMessage);
207 assertEquals(BGPError.OPT_PARAM_NOT_SUPPORTED, ((BGPNotificationMessage) m).getError());
208 assertArrayEquals(new byte[] { 4, 9 }, ((BGPNotificationMessage) m).getData());
210 notMsg = new BGPNotificationMessage(BGPError.CONNECTION_NOT_SYNC);
211 bytes = this.factory.put(notMsg);
213 bytes = ByteArray.cutBytes(bytes, 16);
214 m = (BGPMessage) this.factory.parse(bytes);
216 assertTrue(m instanceof BGPNotificationMessage);
217 assertEquals(BGPError.CONNECTION_NOT_SYNC, ((BGPNotificationMessage) m).getError());
218 assertNull(((BGPNotificationMessage) m).getData());
222 public void testWrongLength() throws DeserializerException {
223 byte[] bMsg = new byte[] { (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
224 (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x00,
225 (byte) 0x14, (byte) 0x03, (byte) 0x02 };
227 bMsg = ByteArray.cutBytes(bMsg, 16);
229 this.factory.parse(bMsg);
230 fail("Exception should have occured.");
231 } catch (final DocumentedException e) {
232 assertEquals("Notification message too small.", e.getMessage());
233 assertEquals(BGPError.BAD_MSG_LENGTH, ((BGPDocumentedException) e).getError());
240 public void testUnrecognizedError() throws DeserializerException, DocumentedException {
241 byte[] bMsg = new byte[] { (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
242 (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x00,
243 (byte) 0x15, (byte) 0x03, (byte) 0x02, (byte) 0xaa };
245 bMsg = ByteArray.cutBytes(bMsg, 16);
247 this.factory.parse(bMsg);
248 fail("Exception should have occured.");
249 } catch (final IllegalArgumentException e) {
250 assertEquals("BGP Error code 2 and subcode 170 not recognized.", e.getMessage());
257 public void testTLVParser() throws UnknownHostException {
259 final BGPTableType t1 = new BGPTableType(BGPAddressFamily.IPv4, BGPSubsequentAddressFamily.Unicast);
260 final BGPTableType t2 = new BGPTableType(BGPAddressFamily.LinkState, BGPSubsequentAddressFamily.Unicast);
262 final List<BGPParameter> tlvs = Lists.newArrayList();
263 tlvs.add(new MultiprotocolCapability(t1));
264 tlvs.add(new MultiprotocolCapability(t2));
265 final Map<BGPTableType, Boolean> tableTypes = Maps.newHashMap();
266 tableTypes.put(t1, true);
267 tableTypes.put(t2, true);
268 tlvs.add(new GracefulCapability(true, 0, tableTypes));
269 final BGPOpenMessage open = new BGPOpenMessage(new ASNumber(72), (short) 180, new IPv4Address(InetAddress.getByName("172.20.160.170")), tlvs);
271 // System.out.println(Arrays.toString(this.factory.put(open)));
273 this.factory.put(open);
275 // assertArrayEquals(openWithCpblt, bytes);