Bump versions to 0.21.7-SNAPSHOT
[bgpcep.git] / bgp / parser-impl / src / test / java / org / opendaylight / protocol / bgp / parser / impl / ParserTest.java
1 /*
2  * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
3  *
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
7  */
8 package org.opendaylight.protocol.bgp.parser.impl;
9
10 import static org.hamcrest.CoreMatchers.containsString;
11 import static org.hamcrest.CoreMatchers.instanceOf;
12 import static org.hamcrest.MatcherAssert.assertThat;
13 import static org.junit.Assert.assertArrayEquals;
14 import static org.junit.Assert.assertEquals;
15 import static org.junit.Assert.assertNull;
16 import static org.junit.Assert.assertThrows;
17 import static org.junit.Assert.assertTrue;
18
19 import io.netty.buffer.ByteBuf;
20 import io.netty.buffer.Unpooled;
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.impl.message.update.NextHopAttributeParser;
27 import org.opendaylight.protocol.bgp.parser.impl.message.update.OriginAttributeParser;
28 import org.opendaylight.protocol.bgp.parser.spi.MessageRegistry;
29 import org.opendaylight.protocol.bgp.parser.spi.pojo.DefaultBGPExtensionConsumerContext;
30 import org.opendaylight.protocol.util.ByteArray;
31 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address;
32 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4AddressNoZone;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev200120.Keepalive;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev200120.KeepaliveBuilder;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev200120.Notify;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev200120.NotifyBuilder;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev200120.Open;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev200120.OpenBuilder;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev200120.ProtocolVersion;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev200120.Update;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.RouteRefresh;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.RouteRefreshBuilder;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev200120.Ipv4AddressFamily;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev200120.UnicastSubsequentAddressFamily;
45 import org.opendaylight.yangtools.yang.binding.Notification;
46 import org.opendaylight.yangtools.yang.common.Uint16;
47 import org.opendaylight.yangtools.yang.common.Uint8;
48
49 public class ParserTest {
50     private static final byte[] OPEN_BMSG = new byte[] {
51         (byte) 0xff, (byte) 0xff, (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,
53         (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
55     };
56
57     private static final byte[] KEEPALIVE_BMSG = new byte[] {
58         (byte) 0xff, (byte) 0xff, (byte) 0xff, (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,
60         (byte) 0x00, (byte) 0x13, (byte) 0x04
61     };
62
63     private static final byte[] NOTIFICATION_BMSG = new byte[] {
64         (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
65         (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
66         (byte) 0x00, (byte) 0x17, (byte) 0x03, (byte) 0x02, (byte) 0x04, (byte) 0x04, (byte) 0x09
67     };
68
69     private static final byte[] UPD_MSG_WITH_UNRECOGNIZED_ATTRIBUTE = new byte[] {
70         (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
71         (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
72         (byte) 0xff, (byte) 0xff, (byte) 0x00, (byte) 0x79, (byte) 0x02, (byte) 0x00, (byte) 0x00, (byte) 0x00,
73         (byte) 0x62, (byte) 0x90, (byte) 0x0e, (byte) 0x00, (byte) 0x34, (byte) 0x40, (byte) 0x04, (byte) 0x47,
74         (byte) 0x04, (byte) 0x0a, (byte) 0x19, (byte) 0x02, (byte) 0x1b, (byte) 0x00, (byte) 0x00, (byte) 0x01,
75         (byte) 0x00, (byte) 0x27, (byte) 0x02, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
76         (byte) 0x00, (byte) 0x00, (byte) 0x01, (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x1a, (byte) 0x02,
77         (byte) 0x00, (byte) 0x00, (byte) 0x04, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x48, (byte) 0x02,
78         (byte) 0x01, (byte) 0x00, (byte) 0x04, (byte) 0x28, (byte) 0x28, (byte) 0x28, (byte) 0x28, (byte) 0x02,
79         (byte) 0x03, (byte) 0x00, (byte) 0x06, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
80         (byte) 0x43, (byte) 0x40, (byte) 0x01, (byte) 0x01, (byte) 0x00, (byte) 0x40, (byte) 0x02, (byte) 0x00,
81         (byte) 0x40, (byte) 0x05, (byte) 0x04, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte )0x64, (byte) 0x00,
82         (byte) 0x63, (byte) 0x19, (byte) 0x04, (byte) 0x02, (byte) 0x00, (byte) 0x08, (byte) 0x4f, (byte) 0x66,
83         (byte) 0x2d, (byte) 0x39, (byte) 0x6b, (byte) 0x2d, (byte) 0x30, (byte) 0x33, (byte) 0x04, (byte) 0x03,
84         (byte) 0x00, (byte) 0x01, (byte) 0x72, (byte) 0x04, (byte) 0x04, (byte) 0x00, (byte) 0x04, (byte) 0x2b,
85         (byte) 0x2b, (byte) 0x2b, (byte) 0x2b
86     };
87
88     // Update message with one IPv4 prefix NLRI and all mandatory path attributes present
89     private static final byte[] UPD_MSG_WITH_MANDATORY_ATTRIBUTES_PRESENT = new byte[] {
90         (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
91         (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
92         (byte) 0x00, (byte) 0x38, (byte) 0x02, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x1c, (byte) 0x40,
93         (byte) 0x01, (byte) 0x01, (byte) 0x00, (byte) 0x40, (byte) 0x02, (byte) 0x00, (byte) 0x40, (byte) 0x03,
94         (byte) 0x04, (byte) 0x0a, (byte) 0x12, (byte) 0xa2, (byte) 0xf1, (byte) 0x80, (byte) 0x04, (byte) 0x04,
95         (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x40, (byte) 0x05, (byte) 0x04, (byte) 0x00,
96         (byte) 0x00, (byte) 0x00, (byte) 0x64, (byte) 0x20, (byte) 0xc0, (byte) 0xa8, (byte) 0xfe, (byte) 0x03
97     };
98
99     // Update message with one IPv4 prefix NLRI and all mandatory path attributes except ORIGIN present
100     private static final byte[] UPD_MSG_WITH_ONE_MANDATORY_ATTRIBUTE_NOT_PRESENT = new byte[] {
101         (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
102         (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
103         (byte) 0x00, (byte) 0x34, (byte) 0x02, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x18, (byte) 0x40,
104         (byte) 0x02, (byte) 0x00, (byte) 0x40, (byte) 0x03, (byte) 0x04, (byte) 0x0a, (byte) 0x12, (byte) 0xa2,
105         (byte) 0xf1, (byte) 0x80, (byte) 0x04, (byte) 0x04, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
106         (byte) 0x40, (byte) 0x05, (byte) 0x04, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x64, (byte) 0x20,
107         (byte) 0xc0, (byte) 0xa8, (byte) 0xfe, (byte) 0x03
108     };
109
110     // Update message with one IPv4 prefix NLRI and ORIGIN, AS_PATH and NEXT_HOP mandatory path attributes not present
111     private static final byte[] UPD_MSG_WITH_MULTIPLE_MANDATORY_ATTRIBUTES_NOT_PRESENT = new byte[] {
112         (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
113         (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
114         (byte) 0x00, (byte) 0x2a, (byte) 0x02, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x0e, (byte) 0x80,
115         (byte) 0x04, (byte) 0x04, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x40, (byte) 0x05,
116         (byte) 0x04, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x64, (byte) 0x20, (byte) 0xc0, (byte) 0xa8,
117         (byte) 0xfe, (byte) 0x03
118     };
119
120     private static final byte[] RR_MSG = new byte[] {
121         (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
122         (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
123         (byte) 0x00, (byte) 0x17, (byte) 0x05, (byte) 0x00, (byte) 0x01, (byte) 0x00, (byte) 0x01
124     };
125
126     private static MessageRegistry reg;
127
128     @BeforeClass
129     public static void setupClass() throws Exception {
130         reg = new DefaultBGPExtensionConsumerContext().getMessageRegistry();
131     }
132
133     @Test
134     public void testHeaderErrors() throws BGPParsingException, BGPDocumentedException {
135         byte[] wrong = ByteArray.cutBytes(new byte[] {
136             (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
137             (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
138             (byte) 0x00
139         }, 16);
140         final IllegalArgumentException ex = assertThrows(IllegalArgumentException.class,
141             () -> ParserTest.reg.parseMessage(Unpooled.copiedBuffer(wrong), null));
142         assertEquals("Too few bytes in passed array. Passed: " + wrong.length + ". Expected: >= 19.", ex.getMessage());
143     }
144
145     @Test
146     public void testBadMsgType() throws BGPParsingException {
147         final byte[] bytes = {
148             (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
149             (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
150             (byte) 0x00, (byte) 0x13, (byte) 0x08
151         };
152
153         final BGPDocumentedException ex = assertThrows(BGPDocumentedException.class,
154             () -> reg.parseMessage(Unpooled.copiedBuffer(bytes), null));
155         assertEquals(BGPError.BAD_MSG_TYPE, ex.getError());
156     }
157
158     @Test
159     public void testKeepAliveMsg() throws BGPParsingException, BGPDocumentedException {
160         final Keepalive keepAlive = new KeepaliveBuilder().build();
161         final ByteBuf buffer = Unpooled.buffer();
162         ParserTest.reg.serializeMessage(keepAlive, buffer);
163         assertArrayEquals(KEEPALIVE_BMSG, ByteArray.getAllBytes(buffer));
164
165         final Notification<?> m = ParserTest.reg.parseMessage(Unpooled.copiedBuffer(ByteArray.getAllBytes(buffer)),
166             null);
167         assertThat(m, instanceOf(Keepalive.class));
168     }
169
170     @Test
171     public void testBadKeepAliveMsg() throws BGPParsingException {
172         final byte[] bytes = new byte[] {
173             (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
174             (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
175             (byte) 0x00, (byte) 0x14, (byte) 0x04, (byte) 0x05
176         };
177
178         final BGPDocumentedException ex = assertThrows(BGPDocumentedException.class,
179             () -> reg.parseMessage(Unpooled.copiedBuffer(bytes), null));
180         assertThat(ex.getMessage(), containsString("Message length field not within valid range."));
181         assertEquals(BGPError.BAD_MSG_LENGTH, ex.getError());
182     }
183
184     @Test
185     public void testOpenMessage() throws BGPParsingException, BGPDocumentedException {
186         final Open open = new OpenBuilder()
187                 .setMyAsNumber(Uint16.valueOf(100))
188                 .setHoldTimer(Uint16.valueOf(180))
189                 .setBgpIdentifier(new Ipv4AddressNoZone("20.20.20.20"))
190                 .setVersion(new ProtocolVersion(Uint8.valueOf(4)))
191                 .build();
192         final ByteBuf bytes = Unpooled.buffer();
193         ParserTest.reg.serializeMessage(open, bytes);
194         assertArrayEquals(OPEN_BMSG, ByteArray.getAllBytes(bytes));
195
196         final Notification<?> m = ParserTest.reg.parseMessage(Unpooled.copiedBuffer(bytes), null);
197         assertThat(m, instanceOf(Open.class));
198
199         final Open mo = (Open) m;
200         assertEquals(100, mo.getMyAsNumber().intValue());
201         assertEquals(180, mo.getHoldTimer().intValue());
202         assertEquals(new Ipv4Address("20.20.20.20"), mo.getBgpIdentifier());
203         assertNull(mo.getBgpParameters());
204     }
205
206     @Test
207     public void testBadHoldTimeError() {
208         final byte[] bMsg = new byte[] {
209             (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
210             (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
211             (byte) 0x00, (byte) 0x1d, (byte) 0x01, (byte) 0x04, (byte) 0x00, (byte) 0x64, (byte) 0x00, (byte) 0x01,
212             (byte) 0x14, (byte) 0x14, (byte) 0x14, (byte) 0x14, (byte) 0x00
213         };
214
215         final BGPDocumentedException ex = assertThrows(BGPDocumentedException.class,
216             () -> reg.parseMessage(Unpooled.copiedBuffer(bMsg), null));
217         assertEquals("Hold time value not acceptable.", ex.getMessage());
218         assertEquals(BGPError.HOLD_TIME_NOT_ACC, ex.getError());
219     }
220
221     @Test
222     public void testBadMsgLength() {
223         final byte[] bMsg = new byte[] {
224             (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
225             (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
226             (byte) 0x00, (byte) 0x1b, (byte) 0x01, (byte) 0x04, (byte) 0x00, (byte) 0x64, (byte) 0x00, (byte) 0xb4,
227             (byte) 0xff, (byte) 0xff, (byte) 0xff
228         };
229
230         final BGPDocumentedException ex = assertThrows(BGPDocumentedException.class,
231             () -> reg.parseMessage(Unpooled.copiedBuffer(bMsg), null));
232         assertEquals("Open message too small.", ex.getMessage());
233         assertEquals(BGPError.BAD_MSG_LENGTH, ex.getError());
234     }
235
236     @Test
237     public void testBadVersion() {
238         final byte[] bMsg = new byte[] {
239             (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
240             (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
241             (byte) 0x00, (byte) 0x1d, (byte) 0x01, (byte) 0x08, (byte) 0x00, (byte) 0x64, (byte) 0x00, (byte) 0xb4,
242             (byte) 0x14, (byte) 0x14, (byte) 0x14, (byte) 0x14, (byte) 0x00
243         };
244
245         final BGPDocumentedException ex = assertThrows(BGPDocumentedException.class,
246             () -> reg.parseMessage(Unpooled.copiedBuffer(bMsg), null));
247         assertEquals("BGP Protocol version 8 not supported.", ex.getMessage());
248         assertEquals(BGPError.VERSION_NOT_SUPPORTED, ex.getError());
249     }
250
251     @Test
252     public void testNotificationMsg() throws BGPParsingException, BGPDocumentedException {
253         Notify notMsg = new NotifyBuilder().setErrorCode(BGPError.OPT_PARAM_NOT_SUPPORTED.getCode())
254             .setErrorSubcode(BGPError.OPT_PARAM_NOT_SUPPORTED.getSubcode()).setData(new byte[] { 4, 9 }).build();
255         final ByteBuf bytes = Unpooled.buffer();
256         ParserTest.reg.serializeMessage(notMsg, bytes);
257         assertArrayEquals(NOTIFICATION_BMSG, ByteArray.subByte(bytes.array(),0,bytes.writerIndex()));
258
259         Notification<?> msg = ParserTest.reg.parseMessage(Unpooled.copiedBuffer(bytes), null);
260
261         assertTrue(msg instanceof Notify);
262         assertEquals(BGPError.OPT_PARAM_NOT_SUPPORTED, BGPError.forValue(((Notify) msg).getErrorCode(),
263             ((Notify) msg).getErrorSubcode()));
264         assertArrayEquals(new byte[] { 4, 9 }, ((Notify) msg).getData());
265
266         notMsg = new NotifyBuilder().setErrorCode(BGPError.CONNECTION_NOT_SYNC.getCode()).setErrorSubcode(
267             BGPError.CONNECTION_NOT_SYNC.getSubcode()).build();
268
269         bytes.clear();
270
271         ParserTest.reg.serializeMessage(notMsg, bytes);
272
273         msg = ParserTest.reg.parseMessage(Unpooled.copiedBuffer(bytes), null);
274
275         assertTrue(msg instanceof Notify);
276         assertEquals(BGPError.CONNECTION_NOT_SYNC, BGPError.forValue(((Notify) msg).getErrorCode(),
277             ((Notify) msg).getErrorSubcode()));
278         assertNull(((Notify) msg).getData());
279     }
280
281     @Test
282     public void testWrongLength() {
283         final byte[] bMsg = new byte[] {
284             (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
285             (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
286             (byte) 0x00, (byte) 0x14, (byte) 0x03, (byte) 0x02
287         };
288
289         final BGPDocumentedException ex = assertThrows(BGPDocumentedException.class,
290             () -> reg.parseMessage(Unpooled.copiedBuffer(bMsg), null));
291         assertEquals("Notification message too small.", ex.getMessage());
292         assertEquals(BGPError.BAD_MSG_LENGTH, ex.getError());
293     }
294
295     @Test
296     public void testUnrecognizedError() {
297         final byte[] bMsg = new byte[] {
298             (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
299             (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
300             (byte) 0x00, (byte) 0x15, (byte) 0x03, (byte) 0x02, (byte) 0xaa
301         };
302
303         final IllegalArgumentException ex = assertThrows(IllegalArgumentException.class,
304             () -> reg.parseMessage(Unpooled.copiedBuffer(bMsg), null));
305         assertEquals("BGP Error code 2 and subcode 170 not recognized.", ex.getMessage());
306     }
307
308     @Test
309     public void testParseUpdMsgWithUnrecognizedAttribute() {
310         final BGPDocumentedException ex = assertThrows(BGPDocumentedException.class,
311             () -> reg.parseMessage(Unpooled.copiedBuffer(UPD_MSG_WITH_UNRECOGNIZED_ATTRIBUTE), null));
312         assertEquals("Well known attribute not recognized.", ex.getMessage());
313         assertEquals(BGPError.WELL_KNOWN_ATTR_NOT_RECOGNIZED, ex.getError());
314     }
315
316     @Test
317     public void testParseUpdMsgWithMandatoryAttributesPresent() throws BGPDocumentedException, BGPParsingException {
318         final Notification<?> msg = reg.parseMessage(Unpooled.copiedBuffer(UPD_MSG_WITH_MANDATORY_ATTRIBUTES_PRESENT),
319             null);
320         assertThat(msg, instanceOf(Update.class));
321     }
322
323     @Test
324     public void testParseUpdMsgWithOneMandatoryAttributeNotPresent() {
325         final BGPDocumentedException ex = assertThrows(BGPDocumentedException.class,
326             () -> reg.parseMessage(Unpooled.copiedBuffer(UPD_MSG_WITH_ONE_MANDATORY_ATTRIBUTE_NOT_PRESENT), null));
327         assertEquals(BGPError.MANDATORY_ATTR_MISSING_MSG + "ORIGIN", ex.getMessage());
328         assertEquals(BGPError.WELL_KNOWN_ATTR_MISSING, ex.getError());
329         assertArrayEquals(new byte[] { OriginAttributeParser.TYPE }, ex.getData());
330     }
331
332     @Test
333     public void testParseUpdMsgWithMultipleMandatoryAttributesNotPresent() {
334         final BGPDocumentedException ex = assertThrows(BGPDocumentedException.class,
335             () -> reg.parseMessage(Unpooled.copiedBuffer(UPD_MSG_WITH_MULTIPLE_MANDATORY_ATTRIBUTES_NOT_PRESENT),
336                 null));
337         assertEquals(BGPError.MANDATORY_ATTR_MISSING_MSG + "NEXT_HOP", ex.getMessage());
338         assertEquals(BGPError.WELL_KNOWN_ATTR_MISSING, ex.getError());
339         assertArrayEquals(new byte[] { NextHopAttributeParser.TYPE }, ex.getData());
340     }
341
342     @Test
343     public void testRouteRefreshMsg() throws BGPDocumentedException, BGPParsingException {
344         final Notification<?> rrMsg = new RouteRefreshBuilder().setAfi(Ipv4AddressFamily.VALUE)
345             .setSafi(UnicastSubsequentAddressFamily.VALUE).build();
346         final ByteBuf buffer = Unpooled.buffer();
347         ParserTest.reg.serializeMessage(rrMsg, buffer);
348         assertArrayEquals(RR_MSG, ByteArray.getAllBytes(buffer));
349
350         final Notification<?> m = ParserTest.reg.parseMessage(
351             Unpooled.copiedBuffer(ByteArray.getAllBytes(buffer)), null);
352
353         assertThat(m, instanceOf(RouteRefresh.class));
354     }
355 }