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.parser.impl;
10 import static org.hamcrest.CoreMatchers.containsString;
11 import static org.junit.Assert.assertArrayEquals;
12 import static org.junit.Assert.assertEquals;
13 import static org.junit.Assert.assertNull;
14 import static org.junit.Assert.assertThat;
15 import static org.junit.Assert.assertTrue;
16 import static org.junit.Assert.fail;
18 import io.netty.buffer.ByteBuf;
19 import io.netty.buffer.Unpooled;
20 import java.net.UnknownHostException;
21 import org.junit.BeforeClass;
22 import org.junit.Test;
23 import org.opendaylight.protocol.bgp.parser.BGPDocumentedException;
24 import org.opendaylight.protocol.bgp.parser.BGPError;
25 import org.opendaylight.protocol.bgp.parser.BGPParsingException;
26 import org.opendaylight.protocol.bgp.parser.spi.MessageRegistry;
27 import org.opendaylight.protocol.bgp.parser.spi.pojo.ServiceLoaderBGPExtensionProviderContext;
28 import org.opendaylight.protocol.util.ByteArray;
29 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.Keepalive;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.KeepaliveBuilder;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.Notify;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.NotifyBuilder;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.Open;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.OpenBuilder;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.ProtocolVersion;
37 import org.opendaylight.yangtools.yang.binding.Notification;
39 public class ParserTest {
41 private static final byte[] openBMsg = new byte[] { (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
42 (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
43 (byte) 0xff, (byte) 0x00, (byte) 0x1d, (byte) 0x01, (byte) 0x04, (byte) 0x00, (byte) 0x64, (byte) 0x00, (byte) 0xb4,
44 (byte) 0x14, (byte) 0x14, (byte) 0x14, (byte) 0x14, (byte) 0x00 };
46 private static final byte[] keepAliveBMsg = new byte[] { (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
47 (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
48 (byte) 0xff, (byte) 0x00, (byte) 0x13, (byte) 0x04 };
50 private static final byte[] notificationBMsg = new byte[] { (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) 0xff, (byte) 0x00, (byte) 0x17, (byte) 0x03, (byte) 0x02, (byte) 0x04, (byte) 0x04, (byte) 0x09 };
54 private static final byte[] updMsgWithUnrecognizedAttribute = new byte[] {
55 (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, (byte) 0xff, (byte) 0x00, (byte) 0x79, (byte) 0x02,
57 (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x62, (byte) 0x90, (byte) 0x0e, (byte) 0x00, (byte) 0x34, (byte) 0x40, (byte) 0x04, (byte) 0x47, (byte) 0x04, (byte) 0x0a, (byte) 0x19,
58 (byte) 0x02, (byte) 0x1b, (byte) 0x00, (byte) 0x00, (byte) 0x01, (byte) 0x00, (byte) 0x27, (byte) 0x02, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte)0x00,
59 (byte) 0x01, (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x1a, (byte) 0x02, (byte) 0x00, (byte) 0x00, (byte) 0x04, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x48, (byte) 0x02, (byte)0x01,
60 (byte) 0x00, (byte) 0x04, (byte) 0x28, (byte) 0x28, (byte) 0x28, (byte) 0x28, (byte) 0x02, (byte) 0x03, (byte) 0x00, (byte) 0x06, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte)0x00,
61 (byte) 0x43, (byte) 0x40, (byte) 0x01, (byte) 0x01, (byte) 0x00, (byte) 0x40, (byte) 0x02, (byte) 0x00, (byte) 0x40, (byte) 0x05, (byte) 0x04, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte)0x64,
62 (byte) 0x80, (byte) 0x63, (byte) 0x19, (byte) 0x04, (byte) 0x02, (byte) 0x00, (byte) 0x08, (byte) 0x4f, (byte) 0x66, (byte) 0x2d, (byte) 0x39, (byte) 0x6b, (byte) 0x2d, (byte) 0x30, (byte)0x33,
63 (byte) 0x04, (byte) 0x03, (byte) 0x00, (byte) 0x01, (byte) 0x72, (byte) 0x04, (byte) 0x04, (byte) 0x00, (byte) 0x04, (byte) 0x2b, (byte) 0x2b, (byte) 0x2b, (byte) 0x2b
66 static MessageRegistry reg;
69 public static void setupClass() throws Exception {
70 reg = ServiceLoaderBGPExtensionProviderContext.getSingletonInstance().getMessageRegistry();
74 public void testHeaderErrors() throws BGPParsingException, BGPDocumentedException {
75 byte[] wrong = new byte[] { (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x00 };
76 wrong = ByteArray.cutBytes(wrong, 16);
78 ParserTest.reg.parseMessage(Unpooled.copiedBuffer(wrong));
79 fail("Exception should have occcured.");
80 } catch (final IllegalArgumentException e) {
81 assertEquals("Too few bytes in passed array. Passed: " + wrong.length + ". Expected: >= 19.", e.getMessage());
88 public void testBadMsgType() throws BGPParsingException {
89 final byte[] bytes = { (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
90 (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
91 (byte) 0x00, (byte) 0x13, (byte) 0x08 };
93 ParserTest.reg.parseMessage(Unpooled.copiedBuffer(bytes));
94 fail("Exception should have occured.");
95 } catch (final BGPDocumentedException e) {
96 assertEquals(BGPError.BAD_MSG_TYPE, e.getError());
103 public void testKeepAliveMsg() throws BGPParsingException, BGPDocumentedException {
104 final Notification keepAlive = new KeepaliveBuilder().build();
105 final ByteBuf buffer = Unpooled.buffer();
106 ParserTest.reg.serializeMessage(keepAlive, buffer);
107 assertArrayEquals(keepAliveBMsg, ByteArray.getAllBytes(buffer));
109 final Notification m = ParserTest.reg.parseMessage(Unpooled.copiedBuffer(ByteArray.getAllBytes(buffer)));
111 assertTrue(m instanceof Keepalive);
115 public void testBadKeepAliveMsg() throws BGPParsingException {
116 final byte[] bytes = new byte[] { (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
117 (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
118 (byte) 0x00, (byte) 0x14, (byte) 0x04, (byte) 0x05 };
121 ParserTest.reg.parseMessage(Unpooled.copiedBuffer(bytes));
122 fail("Exception should have occured.");
123 } catch (final BGPDocumentedException e) {
124 assertThat(e.getMessage(), containsString("Message length field not within valid range."));
125 assertEquals(BGPError.BAD_MSG_LENGTH, e.getError());
132 public void testOpenMessage() throws UnknownHostException, BGPParsingException, BGPDocumentedException {
133 final Notification open = new OpenBuilder().setMyAsNumber(100).setHoldTimer(180).setBgpIdentifier(new Ipv4Address("20.20.20.20")).setVersion(
134 new ProtocolVersion((short) 4)).build();
135 final ByteBuf bytes = Unpooled.buffer();
136 ParserTest.reg.serializeMessage(open, bytes);
137 assertArrayEquals(openBMsg, ByteArray.getAllBytes(bytes));
139 final Notification m = ParserTest.reg.parseMessage(Unpooled.copiedBuffer(bytes));
141 assertTrue(m instanceof Open);
142 assertEquals(100, ((Open) m).getMyAsNumber().intValue());
143 assertEquals(180, ((Open) m).getHoldTimer().intValue());
144 assertEquals(new Ipv4Address("20.20.20.20"), ((Open) m).getBgpIdentifier());
145 assertTrue(((Open) m).getBgpParameters().isEmpty());
149 public void testBadHoldTimeError() throws BGPParsingException {
150 final byte[] bMsg = new byte[] { (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
151 (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
152 (byte) 0x00, (byte) 0x1d, (byte) 0x01, (byte) 0x04, (byte) 0x00, (byte) 0x64, (byte) 0x00, (byte) 0x01, (byte) 0x14,
153 (byte) 0x14, (byte) 0x14, (byte) 0x14, (byte) 0x00 };
156 ParserTest.reg.parseMessage(Unpooled.copiedBuffer(bMsg));
157 fail("Exception should have occured.");
158 } catch (final BGPDocumentedException e) {
159 assertEquals("Hold time value not acceptable.", e.getMessage());
160 assertEquals(BGPError.HOLD_TIME_NOT_ACC, e.getError());
167 public void testBadMsgLength() throws BGPParsingException {
168 final byte[] bMsg = new byte[] { (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
169 (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
170 (byte) 0x00, (byte) 0x1b, (byte) 0x01, (byte) 0x04, (byte) 0x00, (byte) 0x64, (byte) 0x00, (byte) 0xb4, (byte) 0xff,
171 (byte) 0xff, (byte) 0xff };
174 ParserTest.reg.parseMessage(Unpooled.copiedBuffer(bMsg));
175 fail("Exception should have occured.");
176 } catch (final BGPDocumentedException e) {
177 assertEquals("Open message too small.", e.getMessage());
178 assertEquals(BGPError.BAD_MSG_LENGTH, e.getError());
183 public void testBadVersion() throws BGPParsingException {
184 final byte[] bMsg = new byte[] { (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
185 (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
186 (byte) 0x00, (byte) 0x1d, (byte) 0x01, (byte) 0x08, (byte) 0x00, (byte) 0x64, (byte) 0x00, (byte) 0xb4, (byte) 0x14,
187 (byte) 0x14, (byte) 0x14, (byte) 0x14, (byte) 0x00 };
190 ParserTest.reg.parseMessage(Unpooled.copiedBuffer(bMsg));
191 fail("Exception should have occured.");
192 } catch (final BGPDocumentedException e) {
193 assertEquals("BGP Protocol version 8 not supported.", e.getMessage());
194 assertEquals(BGPError.VERSION_NOT_SUPPORTED, e.getError());
201 public void testNotificationMsg() throws BGPParsingException, BGPDocumentedException {
202 Notification notMsg = new NotifyBuilder().setErrorCode(BGPError.OPT_PARAM_NOT_SUPPORTED.getCode()).setErrorSubcode(
203 BGPError.OPT_PARAM_NOT_SUPPORTED.getSubcode()).setData(new byte[] { 4, 9 }).build();
204 final ByteBuf bytes = Unpooled.buffer();
205 ParserTest.reg.serializeMessage(notMsg, bytes);
206 assertArrayEquals(notificationBMsg, ByteArray.subByte(bytes.array(),0,bytes.writerIndex()));
208 Notification m = ParserTest.reg.parseMessage(Unpooled.copiedBuffer(bytes));
210 assertTrue(m instanceof Notify);
211 assertEquals(BGPError.OPT_PARAM_NOT_SUPPORTED, BGPError.forValue(((Notify) m).getErrorCode(), ((Notify) m).getErrorSubcode()));
212 assertArrayEquals(new byte[] { 4, 9 }, ((Notify) m).getData());
214 notMsg = new NotifyBuilder().setErrorCode(BGPError.CONNECTION_NOT_SYNC.getCode()).setErrorSubcode(
215 BGPError.CONNECTION_NOT_SYNC.getSubcode()).build();
219 ParserTest.reg.serializeMessage(notMsg, bytes);
221 m = ParserTest.reg.parseMessage(Unpooled.copiedBuffer(bytes));
223 assertTrue(m instanceof Notify);
224 assertEquals(BGPError.CONNECTION_NOT_SYNC, BGPError.forValue(((Notify) m).getErrorCode(), ((Notify) m).getErrorSubcode()));
225 assertNull(((Notify) m).getData());
229 public void testWrongLength() throws BGPParsingException {
230 final byte[] bMsg = new byte[] { (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
231 (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
232 (byte) 0x00, (byte) 0x14, (byte) 0x03, (byte) 0x02 };
235 ParserTest.reg.parseMessage(Unpooled.copiedBuffer(bMsg));
236 fail("Exception should have occured.");
237 } catch (final BGPDocumentedException e) {
238 assertEquals("Notification message too small.", e.getMessage());
239 assertEquals(BGPError.BAD_MSG_LENGTH, e.getError());
246 public void testUnrecognizedError() throws BGPParsingException, BGPDocumentedException {
247 final byte[] bMsg = new byte[] { (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
248 (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
249 (byte) 0x00, (byte) 0x15, (byte) 0x03, (byte) 0x02, (byte) 0xaa };
252 ParserTest.reg.parseMessage(Unpooled.copiedBuffer(bMsg));
253 fail("Exception should have occured.");
254 } catch (final IllegalArgumentException e) {
255 assertEquals("BGP Error code 2 and subcode 170 not recognized.", e.getMessage());
262 public void testParseUpdMsgWithUnrecognizedAttribute() throws BGPDocumentedException, BGPParsingException {
264 reg.parseMessage(Unpooled.copiedBuffer(updMsgWithUnrecognizedAttribute));
265 fail("Exception should have occured.");
266 } catch (final BGPDocumentedException e) {
267 assertEquals("Well known attribute not recognized.", e.getMessage());
268 assertEquals(BGPError.WELL_KNOWN_ATTR_NOT_RECOGNIZED, e.getError());