moved BGP Table type from concepts to parser-api.
[bgpcep.git] / bgp / rib-impl / src / test / java / org / opendaylight / protocol / bgp / rib / 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.rib.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 java.net.InetAddress;
19 import java.net.UnknownHostException;
20 import java.util.List;
21 import java.util.Map;
22
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;
45
46 import com.google.common.collect.Lists;
47 import com.google.common.collect.Maps;
48
49 public class ParserTest {
50
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 };
55
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 };
59
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 };
63
64         final ProtocolMessageFactory<Notification> factory = new BGPMessageFactoryImpl();
65
66         @Test
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);
71                 try {
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());
77                         return;
78                 }
79                 fail();
80         }
81
82         @Test
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 };
87                 try {
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());
92                         return;
93                 }
94                 fail();
95         }
96
97         @Test
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);
102
103                 final Notification m = this.factory.parse(bytes).get(0);
104
105                 assertTrue(m instanceof Keepalive);
106         }
107
108         @Test
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 };
113
114                 try {
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());
120                         return;
121                 }
122                 fail();
123         }
124
125         @Test
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);
130
131                 final Notification m = this.factory.parse(bytes).get(0);
132
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());
138         }
139
140         @Test
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 };
146
147                 try {
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());
153                         return;
154                 }
155                 fail();
156         }
157
158         @Test
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 };
164
165                 try {
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());
171                 }
172         }
173
174         @Test
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 };
180
181                 try {
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());
187                         return;
188                 }
189                 fail();
190         }
191
192         @Test
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);
197
198                 Notification m = this.factory.parse(bytes).get(0);
199
200                 assertTrue(m instanceof BGPNotificationMessage);
201                 assertEquals(BGPError.OPT_PARAM_NOT_SUPPORTED, ((BGPNotificationMessage) m).getError());
202                 assertArrayEquals(new byte[] { 4, 9 }, ((BGPNotificationMessage) m).getData());
203
204                 notMsg = new BGPNotificationMessage(BGPError.CONNECTION_NOT_SYNC);
205                 bytes = this.factory.put(notMsg);
206
207                 m = this.factory.parse(bytes).get(0);
208
209                 assertTrue(m instanceof BGPNotificationMessage);
210                 assertEquals(BGPError.CONNECTION_NOT_SYNC, ((BGPNotificationMessage) m).getError());
211                 assertNull(((BGPNotificationMessage) m).getData());
212         }
213
214         @Test
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 };
219
220                 try {
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());
226                         return;
227                 }
228                 fail();
229         }
230
231         @Test
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 };
236
237                 try {
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());
242                         return;
243                 }
244                 fail();
245         }
246
247         @Test
248         public void testTLVParser() throws UnknownHostException {
249
250                 final BGPTableType t1 = new BGPTableType(Ipv4AddressFamily.class, UnicastSubsequentAddressFamily.class);
251                 final BGPTableType t2 = new BGPTableType(LinkstateAddressFamily.class, UnicastSubsequentAddressFamily.class);
252
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);
261
262                 this.factory.put(open);
263
264                 // assertArrayEquals(openWithCpblt, bytes);
265         }
266 }