Removed checkstyle warnings.
[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.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;
17
18 import com.google.common.collect.Lists;
19 import com.google.common.collect.Maps;
20
21 import io.netty.buffer.Unpooled;
22
23 import java.net.UnknownHostException;
24 import java.util.Arrays;
25 import java.util.List;
26 import java.util.Map;
27
28 import org.junit.BeforeClass;
29 import org.junit.Test;
30 import org.opendaylight.protocol.bgp.parser.BGPDocumentedException;
31 import org.opendaylight.protocol.bgp.parser.BGPError;
32 import org.opendaylight.protocol.bgp.parser.BGPParsingException;
33 import org.opendaylight.protocol.bgp.parser.BgpTableTypeImpl;
34 import org.opendaylight.protocol.bgp.parser.spi.MessageRegistry;
35 import org.opendaylight.protocol.bgp.parser.spi.pojo.ServiceLoaderBGPExtensionProviderContext;
36 import org.opendaylight.protocol.util.ByteArray;
37 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev131125.LinkstateAddressFamily;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev131125.LinkstateSubsequentAddressFamily;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.Keepalive;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.KeepaliveBuilder;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.Notify;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.NotifyBuilder;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.Open;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.OpenBuilder;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.ProtocolVersion;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.open.BgpParameters;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.open.BgpParametersBuilder;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.BgpTableType;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.open.bgp.parameters.c.parameters.MultiprotocolCaseBuilder;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.open.bgp.parameters.c.parameters.multiprotocol._case.MultiprotocolCapabilityBuilder;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.Ipv4AddressFamily;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.UnicastSubsequentAddressFamily;
54 import org.opendaylight.yangtools.yang.binding.Notification;
55
56 public class ParserTest {
57
58     public static final byte[] openBMsg = new byte[] { (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, (byte) 0xff, (byte) 0xff,
60         (byte) 0x00, (byte) 0x1d, (byte) 0x01, (byte) 0x04, (byte) 0x00, (byte) 0x64, (byte) 0x00, (byte) 0xb4, (byte) 0x14, (byte) 0x14,
61         (byte) 0x14, (byte) 0x14, (byte) 0x00 };
62
63     public static final byte[] keepAliveBMsg = new byte[] { (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
64         (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
65         (byte) 0x00, (byte) 0x13, (byte) 0x04 };
66
67     public static final byte[] notificationBMsg = new byte[] { (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
68         (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
69         (byte) 0xff, (byte) 0x00, (byte) 0x17, (byte) 0x03, (byte) 0x02, (byte) 0x04, (byte) 0x04, (byte) 0x09 };
70
71     public static final byte[] openWithCpblt1 = new byte[] { (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
72         (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
73         (byte) 0x00, (byte) 0x2d, (byte) 0x01, (byte) 0x04, (byte) 0x00, (byte) 0x48, (byte) 0x00, (byte) 0xb4, (byte) 0xac, (byte) 0x14,
74         (byte) 0xa0, (byte) 0xaa, (byte) 0x10, (byte) 0x02, (byte) 0x06, (byte) 0x01, (byte) 0x04, (byte) 0x00, (byte) 0x01, (byte) 0x00,
75         (byte) 0x01, (byte) 0x02, (byte) 0x06, (byte) 0x01, (byte) 0x04, (byte) 0x40, (byte) 0x04, (byte) 0x00, (byte) 0x47 };
76
77     public static final byte[] openWithCpblt2 = new byte[] { (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
78         (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
79         (byte) 0x00, (byte) 0x2d, (byte) 0x01, (byte) 0x04, (byte) 0x00, (byte) 0x48, (byte) 0x00, (byte) 0xb4, (byte) 0xac, (byte) 0x14,
80         (byte) 0xa0, (byte) 0xaa, (byte) 0x10, (byte) 0x02, (byte) 0x06, (byte) 0x01, (byte) 0x04, (byte) 0x40, (byte) 0x04, (byte) 0x00,
81         (byte) 0x47, (byte) 0x02, (byte) 0x06, (byte) 0x01, (byte) 0x04, (byte) 0x00, (byte) 0x01, (byte) 0x00, (byte) 0x01 };
82
83     static MessageRegistry reg;
84
85     @BeforeClass
86     public static void setupClass() throws Exception {
87         reg = ServiceLoaderBGPExtensionProviderContext.getSingletonInstance().getMessageRegistry();
88     }
89
90     @Test
91     public void testHeaderErrors() throws BGPParsingException, BGPDocumentedException {
92         byte[] wrong = new byte[] { (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
93             (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x00 };
94         wrong = ByteArray.cutBytes(wrong, 16);
95         try {
96             ParserTest.reg.parseMessage(Unpooled.copiedBuffer(wrong));
97             fail("Exception should have occcured.");
98         } catch (final IllegalArgumentException e) {
99             assertEquals("Too few bytes in passed array. Passed: " + wrong.length + ". Expected: >= 19.", e.getMessage());
100             return;
101         }
102         fail();
103     }
104
105     @Test
106     public void testBadMsgType() throws BGPParsingException {
107         final byte[] bytes = new byte[] { (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
108             (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
109             (byte) 0x00, (byte) 0x13, (byte) 0x08 };
110         try {
111             ParserTest.reg.parseMessage(Unpooled.copiedBuffer(bytes));
112             fail("Exception should have occured.");
113         } catch (final BGPDocumentedException e) {
114             assertEquals(BGPError.BAD_MSG_TYPE, e.getError());
115             return;
116         }
117         fail();
118     }
119
120     @Test
121     public void testKeepAliveMsg() throws BGPParsingException, BGPDocumentedException {
122         final Notification keepAlive = new KeepaliveBuilder().build();
123         final byte[] bytes = ParserTest.reg.serializeMessage(keepAlive);
124         assertArrayEquals(keepAliveBMsg, bytes);
125
126         final Notification m = ParserTest.reg.parseMessage(Unpooled.copiedBuffer(bytes));
127
128         assertTrue(m instanceof Keepalive);
129     }
130
131     @Test
132     public void testBadKeepAliveMsg() throws BGPParsingException {
133         final byte[] bytes = new byte[] { (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
134             (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
135             (byte) 0x00, (byte) 0x14, (byte) 0x04, (byte) 0x05 };
136
137         try {
138             ParserTest.reg.parseMessage(Unpooled.copiedBuffer(bytes));
139             fail("Exception should have occured.");
140         } catch (final BGPDocumentedException e) {
141             assertThat(e.getMessage(), containsString("Message length field not within valid range."));
142             assertEquals(BGPError.BAD_MSG_LENGTH, e.getError());
143             return;
144         }
145         fail();
146     }
147
148     @Test
149     public void testOpenMessage() throws UnknownHostException, BGPParsingException, BGPDocumentedException {
150         final Notification open = new OpenBuilder().setMyAsNumber(100).setHoldTimer(180).setBgpIdentifier(new Ipv4Address("20.20.20.20")).setVersion(
151                 new ProtocolVersion((short) 4)).build();
152         final byte[] bytes = ParserTest.reg.serializeMessage(open);
153         assertArrayEquals(openBMsg, bytes);
154
155         final Notification m = ParserTest.reg.parseMessage(Unpooled.copiedBuffer(bytes));
156
157         assertTrue(m instanceof Open);
158         assertEquals(100, ((Open) m).getMyAsNumber().intValue());
159         assertEquals(180, ((Open) m).getHoldTimer().intValue());
160         assertEquals(new Ipv4Address("20.20.20.20"), ((Open) m).getBgpIdentifier());
161         assertTrue(((Open) m).getBgpParameters().isEmpty());
162     }
163
164     @Test
165     public void testBadHoldTimeError() throws BGPParsingException {
166         final byte[] bMsg = new byte[] { (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
167             (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
168             (byte) 0x00, (byte) 0x1d, (byte) 0x01, (byte) 0x04, (byte) 0x00, (byte) 0x64, (byte) 0x00, (byte) 0x01, (byte) 0x14,
169             (byte) 0x14, (byte) 0x14, (byte) 0x14, (byte) 0x00 };
170
171         try {
172             ParserTest.reg.parseMessage(Unpooled.copiedBuffer(bMsg));
173             fail("Exception should have occured.");
174         } catch (final BGPDocumentedException e) {
175             assertEquals("Hold time value not acceptable.", e.getMessage());
176             assertEquals(BGPError.HOLD_TIME_NOT_ACC, e.getError());
177             return;
178         }
179         fail();
180     }
181
182     @Test
183     public void testBadMsgLength() 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) 0x1b, (byte) 0x01, (byte) 0x04, (byte) 0x00, (byte) 0x64, (byte) 0x00, (byte) 0xb4, (byte) 0xff,
187             (byte) 0xff, (byte) 0xff };
188
189         try {
190             ParserTest.reg.parseMessage(Unpooled.copiedBuffer(bMsg));
191             fail("Exception should have occured.");
192         } catch (final BGPDocumentedException e) {
193             assertEquals("Open message too small.", e.getMessage());
194             assertEquals(BGPError.BAD_MSG_LENGTH, e.getError());
195         }
196     }
197
198     @Test
199     public void testBadVersion() throws BGPParsingException {
200         final byte[] bMsg = new byte[] { (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
201             (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
202             (byte) 0x00, (byte) 0x1d, (byte) 0x01, (byte) 0x08, (byte) 0x00, (byte) 0x64, (byte) 0x00, (byte) 0xb4, (byte) 0x14,
203             (byte) 0x14, (byte) 0x14, (byte) 0x14, (byte) 0x00 };
204
205         try {
206             ParserTest.reg.parseMessage(Unpooled.copiedBuffer(bMsg));
207             fail("Exception should have occured.");
208         } catch (final BGPDocumentedException e) {
209             assertEquals("BGP Protocol version 8 not supported.", e.getMessage());
210             assertEquals(BGPError.VERSION_NOT_SUPPORTED, e.getError());
211             return;
212         }
213         fail();
214     }
215
216     @Test
217     public void testNotificationMsg() throws BGPParsingException, BGPDocumentedException {
218         Notification notMsg = new NotifyBuilder().setErrorCode(BGPError.OPT_PARAM_NOT_SUPPORTED.getCode()).setErrorSubcode(
219                 BGPError.OPT_PARAM_NOT_SUPPORTED.getSubcode()).setData(new byte[] { 4, 9 }).build();
220         byte[] bytes = ParserTest.reg.serializeMessage(notMsg);
221         assertArrayEquals(notificationBMsg, bytes);
222
223         Notification m = ParserTest.reg.parseMessage(Unpooled.copiedBuffer(bytes));
224
225         assertTrue(m instanceof Notify);
226         assertEquals(BGPError.OPT_PARAM_NOT_SUPPORTED, BGPError.forValue(((Notify) m).getErrorCode(), ((Notify) m).getErrorSubcode()));
227         assertArrayEquals(new byte[] { 4, 9 }, ((Notify) m).getData());
228
229         notMsg = new NotifyBuilder().setErrorCode(BGPError.CONNECTION_NOT_SYNC.getCode()).setErrorSubcode(
230                 BGPError.CONNECTION_NOT_SYNC.getSubcode()).build();
231         bytes = ParserTest.reg.serializeMessage(notMsg);
232
233         m = ParserTest.reg.parseMessage(Unpooled.copiedBuffer(bytes));
234
235         assertTrue(m instanceof Notify);
236         assertEquals(BGPError.CONNECTION_NOT_SYNC, BGPError.forValue(((Notify) m).getErrorCode(), ((Notify) m).getErrorSubcode()));
237         assertNull(((Notify) m).getData());
238     }
239
240     @Test
241     public void testWrongLength() throws BGPParsingException {
242         final byte[] bMsg = new byte[] { (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
243             (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
244             (byte) 0x00, (byte) 0x14, (byte) 0x03, (byte) 0x02 };
245
246         try {
247             ParserTest.reg.parseMessage(Unpooled.copiedBuffer(bMsg));
248             fail("Exception should have occured.");
249         } catch (final BGPDocumentedException e) {
250             assertEquals("Notification message too small.", e.getMessage());
251             assertEquals(BGPError.BAD_MSG_LENGTH, e.getError());
252             return;
253         }
254         fail();
255     }
256
257     @Test
258     public void testUnrecognizedError() throws BGPParsingException, BGPDocumentedException {
259         final byte[] bMsg = new byte[] { (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
260             (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
261             (byte) 0x00, (byte) 0x15, (byte) 0x03, (byte) 0x02, (byte) 0xaa };
262
263         try {
264             ParserTest.reg.parseMessage(Unpooled.copiedBuffer(bMsg));
265             fail("Exception should have occured.");
266         } catch (final IllegalArgumentException e) {
267             assertEquals("BGP Error code 2 and subcode 170 not recognized.", e.getMessage());
268             return;
269         }
270         fail();
271     }
272
273     @Test
274     public void testTLVParser() throws UnknownHostException {
275
276         final BgpTableType t1 = new BgpTableTypeImpl(Ipv4AddressFamily.class, UnicastSubsequentAddressFamily.class);
277         final BgpTableType t2 = new BgpTableTypeImpl(LinkstateAddressFamily.class, UnicastSubsequentAddressFamily.class);
278
279         final List<BgpParameters> tlvs = Lists.newArrayList();
280
281         tlvs.add(new BgpParametersBuilder().setCParameters(
282                 new MultiprotocolCaseBuilder().setMultiprotocolCapability(
283                         new MultiprotocolCapabilityBuilder().setAfi(LinkstateAddressFamily.class).setSafi(
284                                 LinkstateSubsequentAddressFamily.class).build()).build()).build());
285         tlvs.add(new BgpParametersBuilder().setCParameters(
286                 new MultiprotocolCaseBuilder().setMultiprotocolCapability(
287                         new MultiprotocolCapabilityBuilder().setAfi(Ipv4AddressFamily.class).setSafi(UnicastSubsequentAddressFamily.class).build()).build()).build());
288
289         final Map<BgpTableType, Boolean> tableTypes = Maps.newHashMap();
290         tableTypes.put(t1, true);
291         tableTypes.put(t2, true);
292         final Open open = new OpenBuilder().setMyAsNumber(72).setHoldTimer(180).setBgpIdentifier(new Ipv4Address("172.20.160.170")).setVersion(
293                 new ProtocolVersion((short) 4)).setBgpParameters(tlvs).build();
294
295         final byte[] result = ParserTest.reg.serializeMessage(open);
296
297         // the capabilities can be swapped.
298         assertTrue(Arrays.equals(openWithCpblt1, result) || Arrays.equals(openWithCpblt2, result));
299     }
300 }