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.parser.BGPDocumentedException;
25 import org.opendaylight.protocol.bgp.parser.BGPError;
26 import org.opendaylight.protocol.bgp.parser.BGPParameter;
27 import org.opendaylight.protocol.bgp.parser.BGPTableType;
28 import org.opendaylight.protocol.bgp.parser.impl.BGPMessageFactoryImpl;
29 import org.opendaylight.protocol.bgp.parser.message.BGPNotificationMessage;
30 import org.opendaylight.protocol.bgp.parser.message.BGPOpenMessage;
31 import org.opendaylight.protocol.bgp.parser.parameter.GracefulCapability;
32 import org.opendaylight.protocol.bgp.parser.parameter.MultiprotocolCapability;
33 import org.opendaylight.protocol.concepts.IPv4Address;
34 import org.opendaylight.protocol.framework.DeserializerException;
35 import org.opendaylight.protocol.framework.DocumentedException;
36 import org.opendaylight.protocol.framework.ProtocolMessageFactory;
37 import org.opendaylight.protocol.util.ByteArray;
38 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.AsNumber;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev130918.LinkstateAddressFamily;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130918.Keepalive;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130918.KeepaliveBuilder;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.Ipv4AddressFamily;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.UnicastSubsequentAddressFamily;
44 import org.opendaylight.yangtools.yang.binding.Notification;
46 import com.google.common.collect.Lists;
47 import com.google.common.collect.Maps;
49 public class ParserTest {
51 public static final byte[] openBMsg = new byte[] { (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
52 (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
53 (byte) 0xff, (byte) 0x00, (byte) 0x1d, (byte) 0x01, (byte) 0x04, (byte) 0x00, (byte) 0x64, (byte) 0x00, (byte) 0xb4,
54 (byte) 0x14, (byte) 0x14, (byte) 0x14, (byte) 0x14, (byte) 0x00 };
56 public static final byte[] keepAliveBMsg = new byte[] { (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
57 (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
58 (byte) 0xff, (byte) 0x00, (byte) 0x13, (byte) 0x04 };
60 public static final byte[] notificationBMsg = new byte[] { (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
61 (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
62 (byte) 0xff, (byte) 0xff, (byte) 0x00, (byte) 0x17, (byte) 0x03, (byte) 0x02, (byte) 0x04, (byte) 0x04, (byte) 0x09 };
64 final ProtocolMessageFactory<Notification> factory = new BGPMessageFactoryImpl();
67 public void testHeaderErrors() throws DeserializerException, DocumentedException {
68 byte[] wrong = new byte[] { (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
69 (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x00 };
70 wrong = ByteArray.cutBytes(wrong, 16);
72 this.factory.parse(wrong);
73 fail("Exception should have occcured.");
74 } catch (final IllegalArgumentException e) {
75 assertEquals("Too few bytes in passed array. Passed: " + wrong.length + ". Expected: >= "
76 + BGPMessageFactoryImpl.COMMON_HEADER_LENGTH + ".", e.getMessage());
83 public void testBadMsgType() throws DeserializerException {
84 final byte[] bytes = new byte[] { (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
85 (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
86 (byte) 0x00, (byte) 0x13, (byte) 0x08 };
88 this.factory.parse(bytes);
89 fail("Exception should have occured.");
90 } catch (final DocumentedException e) {
91 assertEquals(BGPError.BAD_MSG_TYPE, ((BGPDocumentedException) e).getError());
98 public void testKeepAliveMsg() throws DeserializerException, DocumentedException {
99 final Notification keepAlive = new KeepaliveBuilder().build();
100 final byte[] bytes = this.factory.put(keepAlive);
101 assertArrayEquals(keepAliveBMsg, bytes);
103 final Notification m = this.factory.parse(bytes).get(0);
105 assertTrue(m instanceof Keepalive);
109 public void testBadKeepAliveMsg() throws DeserializerException {
110 final byte[] bytes = new byte[] { (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) 0xff,
112 (byte) 0x00, (byte) 0x14, (byte) 0x04, (byte) 0x05 };
115 this.factory.parse(bytes);
116 fail("Exception should have occured.");
117 } catch (final DocumentedException e) {
118 assertThat(e.getMessage(), containsString("Message length field not within valid range."));
119 assertEquals(BGPError.BAD_MSG_LENGTH, ((BGPDocumentedException) e).getError());
126 public void testOpenMessage() throws UnknownHostException, DeserializerException, DocumentedException {
127 final Notification open = new BGPOpenMessage(new AsNumber((long) 100), (short) 180, new IPv4Address(InetAddress.getByName("20.20.20.20")), null);
128 final byte[] bytes = this.factory.put(open);
129 assertArrayEquals(openBMsg, bytes);
131 final Notification m = this.factory.parse(bytes).get(0);
133 assertTrue(m instanceof BGPOpenMessage);
134 assertEquals(new AsNumber((long) 100), ((BGPOpenMessage) m).getMyAS());
135 assertEquals((short) 180, ((BGPOpenMessage) m).getHoldTime());
136 assertEquals(new IPv4Address(InetAddress.getByName("20.20.20.20")), ((BGPOpenMessage) m).getBgpId());
137 assertTrue(((BGPOpenMessage) m).getOptParams().isEmpty());
141 public void testBadHoldTimeError() throws DeserializerException {
142 final byte[] bMsg = new byte[] { (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
143 (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
144 (byte) 0x00, (byte) 0x1d, (byte) 0x01, (byte) 0x04, (byte) 0x00, (byte) 0x64, (byte) 0x00, (byte) 0x01, (byte) 0x14,
145 (byte) 0x14, (byte) 0x14, (byte) 0x14, (byte) 0x00 };
148 this.factory.parse(bMsg);
149 fail("Exception should have occured.");
150 } catch (final DocumentedException e) {
151 assertEquals("Hold time value not acceptable.", e.getMessage());
152 assertEquals(BGPError.HOLD_TIME_NOT_ACC, ((BGPDocumentedException) e).getError());
159 public void testBadMsgLength() throws DeserializerException {
160 final byte[] bMsg = new byte[] { (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
161 (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
162 (byte) 0x00, (byte) 0x1b, (byte) 0x01, (byte) 0x04, (byte) 0x00, (byte) 0x64, (byte) 0x00, (byte) 0xb4, (byte) 0xff,
163 (byte) 0xff, (byte) 0xff };
166 this.factory.parse(bMsg);
167 fail("Exception should have occured.");
168 } catch (final DocumentedException e) {
169 assertEquals("Open message too small.", e.getMessage());
170 assertEquals(BGPError.BAD_MSG_LENGTH, ((BGPDocumentedException) e).getError());
175 public void testBadVersion() throws DeserializerException {
176 final byte[] bMsg = new byte[] { (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
177 (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
178 (byte) 0x00, (byte) 0x1d, (byte) 0x01, (byte) 0x08, (byte) 0x00, (byte) 0x64, (byte) 0x00, (byte) 0xb4, (byte) 0x14,
179 (byte) 0x14, (byte) 0x14, (byte) 0x14, (byte) 0x00 };
182 this.factory.parse(bMsg);
183 fail("Exception should have occured.");
184 } catch (final DocumentedException e) {
185 assertEquals("BGP Protocol version 8 not supported.", e.getMessage());
186 assertEquals(BGPError.VERSION_NOT_SUPPORTED, ((BGPDocumentedException) e).getError());
193 public void testNotificationMsg() throws DeserializerException, DocumentedException {
194 Notification notMsg = new BGPNotificationMessage(BGPError.OPT_PARAM_NOT_SUPPORTED, new byte[] { 4, 9 });
195 byte[] bytes = this.factory.put(notMsg);
196 assertArrayEquals(notificationBMsg, bytes);
198 Notification m = this.factory.parse(bytes).get(0);
200 assertTrue(m instanceof BGPNotificationMessage);
201 assertEquals(BGPError.OPT_PARAM_NOT_SUPPORTED, ((BGPNotificationMessage) m).getError());
202 assertArrayEquals(new byte[] { 4, 9 }, ((BGPNotificationMessage) m).getData());
204 notMsg = new BGPNotificationMessage(BGPError.CONNECTION_NOT_SYNC);
205 bytes = this.factory.put(notMsg);
207 m = this.factory.parse(bytes).get(0);
209 assertTrue(m instanceof BGPNotificationMessage);
210 assertEquals(BGPError.CONNECTION_NOT_SYNC, ((BGPNotificationMessage) m).getError());
211 assertNull(((BGPNotificationMessage) m).getData());
215 public void testWrongLength() throws DeserializerException {
216 final byte[] bMsg = new byte[] { (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
217 (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
218 (byte) 0x00, (byte) 0x14, (byte) 0x03, (byte) 0x02 };
221 this.factory.parse(bMsg);
222 fail("Exception should have occured.");
223 } catch (final DocumentedException e) {
224 assertEquals("Notification message too small.", e.getMessage());
225 assertEquals(BGPError.BAD_MSG_LENGTH, ((BGPDocumentedException) e).getError());
232 public void testUnrecognizedError() throws DeserializerException, DocumentedException {
233 final byte[] bMsg = new byte[] { (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
234 (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
235 (byte) 0x00, (byte) 0x15, (byte) 0x03, (byte) 0x02, (byte) 0xaa };
238 this.factory.parse(bMsg);
239 fail("Exception should have occured.");
240 } catch (final IllegalArgumentException e) {
241 assertEquals("BGP Error code 2 and subcode 170 not recognized.", e.getMessage());
248 public void testTLVParser() throws UnknownHostException {
250 final BGPTableType t1 = new BGPTableType(Ipv4AddressFamily.class, UnicastSubsequentAddressFamily.class);
251 final BGPTableType t2 = new BGPTableType(LinkstateAddressFamily.class, UnicastSubsequentAddressFamily.class);
253 final List<BGPParameter> tlvs = Lists.newArrayList();
254 tlvs.add(new MultiprotocolCapability(t1));
255 tlvs.add(new MultiprotocolCapability(t2));
256 final Map<BGPTableType, Boolean> tableTypes = Maps.newHashMap();
257 tableTypes.put(t1, true);
258 tableTypes.put(t2, true);
259 tlvs.add(new GracefulCapability(true, 0, tableTypes));
260 final BGPOpenMessage open = new BGPOpenMessage(new AsNumber((long) 72), (short) 180, new IPv4Address(InetAddress.getByName("172.20.160.170")), tlvs);
262 this.factory.put(open);
264 // assertArrayEquals(openWithCpblt, bytes);