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.BGPMessageFactoryImpl;
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<BGPMessage> factory = new BGPMessageFactoryImpl();
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 + BGPMessageFactoryImpl.COMMON_HEADER_LENGTH + ".", e.getMessage());
81 public void testBadMsgType() throws DeserializerException {
82 final byte[] bytes = new byte[] { (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) 0xff,
84 (byte) 0x00, (byte) 0x13, (byte) 0x08 };
86 this.factory.parse(bytes);
87 fail("Exception should have occured.");
88 } catch (final DocumentedException e) {
89 assertEquals(BGPError.BAD_MSG_TYPE, ((BGPDocumentedException) e).getError());
96 public void testKeepAliveMsg() throws DeserializerException, DocumentedException {
97 final BGPMessage keepAlive = new BGPKeepAliveMessage();
98 final byte[] bytes = this.factory.put(keepAlive);
99 assertArrayEquals(keepAliveBMsg, bytes);
101 final BGPMessage m = this.factory.parse(bytes).get(0);
103 assertTrue(m instanceof BGPKeepAliveMessage);
107 public void testBadKeepAliveMsg() throws DeserializerException {
108 final byte[] bytes = new byte[] { (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
109 (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
110 (byte) 0x00, (byte) 0x14, (byte) 0x04, (byte) 0x05 };
113 this.factory.parse(bytes);
114 fail("Exception should have occured.");
115 } catch (final DocumentedException e) {
116 assertThat(e.getMessage(), containsString("Message length field not within valid range."));
117 assertEquals(BGPError.BAD_MSG_LENGTH, ((BGPDocumentedException) e).getError());
124 public void testOpenMessage() throws UnknownHostException, DeserializerException, DocumentedException {
125 final BGPMessage open = new BGPOpenMessage(new ASNumber(100), (short) 180, new IPv4Address(InetAddress.getByName("20.20.20.20")), null);
126 final byte[] bytes = this.factory.put(open);
127 assertArrayEquals(openBMsg, bytes);
129 final BGPMessage m = this.factory.parse(bytes).get(0);
131 assertTrue(m instanceof BGPOpenMessage);
132 assertEquals(new ASNumber(100), ((BGPOpenMessage) m).getMyAS());
133 assertEquals((short) 180, ((BGPOpenMessage) m).getHoldTime());
134 assertEquals(new IPv4Address(InetAddress.getByName("20.20.20.20")), ((BGPOpenMessage) m).getBgpId());
135 assertTrue(((BGPOpenMessage) m).getOptParams().isEmpty());
139 public void testBadHoldTimeError() throws DeserializerException {
140 final byte[] bMsg = new byte[] { (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
141 (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
142 (byte) 0x00, (byte) 0x1d, (byte) 0x01, (byte) 0x04, (byte) 0x00, (byte) 0x64, (byte) 0x00, (byte) 0x01, (byte) 0x14,
143 (byte) 0x14, (byte) 0x14, (byte) 0x14, (byte) 0x00 };
146 this.factory.parse(bMsg);
147 fail("Exception should have occured.");
148 } catch (final DocumentedException e) {
149 assertEquals("Hold time value not acceptable.", e.getMessage());
150 assertEquals(BGPError.HOLD_TIME_NOT_ACC, ((BGPDocumentedException) e).getError());
157 public void testBadMsgLength() throws DeserializerException {
158 final byte[] bMsg = new byte[] { (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
159 (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
160 (byte) 0x00, (byte) 0x1b, (byte) 0x01, (byte) 0x04, (byte) 0x00, (byte) 0x64, (byte) 0x00, (byte) 0xb4, (byte) 0xff,
161 (byte) 0xff, (byte) 0xff };
164 this.factory.parse(bMsg);
165 fail("Exception should have occured.");
166 } catch (final DocumentedException e) {
167 assertEquals("Open message too small.", e.getMessage());
168 assertEquals(BGPError.BAD_MSG_LENGTH, ((BGPDocumentedException) e).getError());
173 public void testBadVersion() throws DeserializerException {
174 final byte[] bMsg = new byte[] { (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
175 (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
176 (byte) 0x00, (byte) 0x1d, (byte) 0x01, (byte) 0x08, (byte) 0x00, (byte) 0x64, (byte) 0x00, (byte) 0xb4, (byte) 0x14,
177 (byte) 0x14, (byte) 0x14, (byte) 0x14, (byte) 0x00 };
180 this.factory.parse(bMsg);
181 fail("Exception should have occured.");
182 } catch (final DocumentedException e) {
183 assertEquals("BGP Protocol version 8 not supported.", e.getMessage());
184 assertEquals(BGPError.VERSION_NOT_SUPPORTED, ((BGPDocumentedException) e).getError());
191 public void testNotificationMsg() throws DeserializerException, DocumentedException {
192 BGPMessage notMsg = new BGPNotificationMessage(BGPError.OPT_PARAM_NOT_SUPPORTED, new byte[] { 4, 9 });
193 byte[] bytes = this.factory.put(notMsg);
194 assertArrayEquals(notificationBMsg, bytes);
196 BGPMessage m = this.factory.parse(bytes).get(0);
198 assertTrue(m instanceof BGPNotificationMessage);
199 assertEquals(BGPError.OPT_PARAM_NOT_SUPPORTED, ((BGPNotificationMessage) m).getError());
200 assertArrayEquals(new byte[] { 4, 9 }, ((BGPNotificationMessage) m).getData());
202 notMsg = new BGPNotificationMessage(BGPError.CONNECTION_NOT_SYNC);
203 bytes = this.factory.put(notMsg);
205 m = this.factory.parse(bytes).get(0);
207 assertTrue(m instanceof BGPNotificationMessage);
208 assertEquals(BGPError.CONNECTION_NOT_SYNC, ((BGPNotificationMessage) m).getError());
209 assertNull(((BGPNotificationMessage) m).getData());
213 public void testWrongLength() throws DeserializerException {
214 final byte[] bMsg = new byte[] { (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
215 (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
216 (byte) 0x00, (byte) 0x14, (byte) 0x03, (byte) 0x02 };
219 this.factory.parse(bMsg);
220 fail("Exception should have occured.");
221 } catch (final DocumentedException e) {
222 assertEquals("Notification message too small.", e.getMessage());
223 assertEquals(BGPError.BAD_MSG_LENGTH, ((BGPDocumentedException) e).getError());
230 public void testUnrecognizedError() throws DeserializerException, DocumentedException {
231 final byte[] bMsg = new byte[] { (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
232 (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
233 (byte) 0x00, (byte) 0x15, (byte) 0x03, (byte) 0x02, (byte) 0xaa };
236 this.factory.parse(bMsg);
237 fail("Exception should have occured.");
238 } catch (final IllegalArgumentException e) {
239 assertEquals("BGP Error code 2 and subcode 170 not recognized.", e.getMessage());
246 public void testTLVParser() throws UnknownHostException {
248 final BGPTableType t1 = new BGPTableType(BGPAddressFamily.IPv4, BGPSubsequentAddressFamily.Unicast);
249 final BGPTableType t2 = new BGPTableType(BGPAddressFamily.LinkState, BGPSubsequentAddressFamily.Unicast);
251 final List<BGPParameter> tlvs = Lists.newArrayList();
252 tlvs.add(new MultiprotocolCapability(t1));
253 tlvs.add(new MultiprotocolCapability(t2));
254 final Map<BGPTableType, Boolean> tableTypes = Maps.newHashMap();
255 tableTypes.put(t1, true);
256 tableTypes.put(t2, true);
257 tlvs.add(new GracefulCapability(true, 0, tableTypes));
258 final BGPOpenMessage open = new BGPOpenMessage(new ASNumber(72), (short) 180, new IPv4Address(InetAddress.getByName("172.20.160.170")), tlvs);
260 // System.out.println(Arrays.toString(this.factory.put(open)));
262 this.factory.put(open);
264 // assertArrayEquals(openWithCpblt, bytes);