a6032b6c65882a8bd0d01c2806038b325f329d1b
[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.concepts.BGPAddressFamily;
25 import org.opendaylight.protocol.bgp.concepts.BGPSubsequentAddressFamily;
26 import org.opendaylight.protocol.bgp.concepts.BGPTableType;
27 import org.opendaylight.protocol.bgp.parser.BGPDocumentedException;
28 import org.opendaylight.protocol.bgp.parser.BGPError;
29 import org.opendaylight.protocol.bgp.parser.BGPMessage;
30 import org.opendaylight.protocol.bgp.parser.BGPParameter;
31 import org.opendaylight.protocol.bgp.parser.impl.BGPMessageFactory;
32 import org.opendaylight.protocol.bgp.parser.message.BGPKeepAliveMessage;
33 import org.opendaylight.protocol.bgp.parser.message.BGPNotificationMessage;
34 import org.opendaylight.protocol.bgp.parser.message.BGPOpenMessage;
35 import org.opendaylight.protocol.bgp.parser.parameter.GracefulCapability;
36 import org.opendaylight.protocol.bgp.parser.parameter.MultiprotocolCapability;
37 import org.opendaylight.protocol.concepts.ASNumber;
38 import org.opendaylight.protocol.concepts.IPv4Address;
39 import org.opendaylight.protocol.framework.DeserializerException;
40 import org.opendaylight.protocol.framework.DocumentedException;
41 import org.opendaylight.protocol.framework.ProtocolMessageFactory;
42 import org.opendaylight.protocol.util.ByteArray;
43
44 import com.google.common.collect.Lists;
45 import com.google.common.collect.Maps;
46
47 public class ParserTest {
48
49         public static final byte[] openBMsg = new byte[] { (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
50                         (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
51                         (byte) 0xff, (byte) 0x00, (byte) 0x1d, (byte) 0x01, (byte) 0x04, (byte) 0x00, (byte) 0x64, (byte) 0x00, (byte) 0xb4,
52                         (byte) 0x14, (byte) 0x14, (byte) 0x14, (byte) 0x14, (byte) 0x00 };
53
54         public static final byte[] keepAliveBMsg = new byte[] { (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
55                         (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
56                         (byte) 0xff, (byte) 0x00, (byte) 0x13, (byte) 0x04 };
57
58         public static final byte[] notificationBMsg = new byte[] { (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,
60                         (byte) 0xff, (byte) 0xff, (byte) 0x00, (byte) 0x17, (byte) 0x03, (byte) 0x02, (byte) 0x04, (byte) 0x04, (byte) 0x09 };
61
62         final ProtocolMessageFactory factory = new BGPMessageFactory();
63
64         @Test
65         public void testHeaderErrors() throws DeserializerException, DocumentedException {
66                 byte[] wrong = new byte[] { (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
67                                 (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x00 };
68                 wrong = ByteArray.cutBytes(wrong, 16);
69                 try {
70                         this.factory.parse(wrong);
71                         fail("Exception should have occcured.");
72                 } catch (final IllegalArgumentException e) {
73                         assertEquals("Too few bytes in passed array. Passed: " + wrong.length + ". Expected: >= "
74                                         + BGPMessageFactory.COMMON_HEADER_LENGTH + ".", e.getMessage());
75                         return;
76                 }
77                 fail();
78         }
79
80         @Test
81         public void testBadMsgType() throws DeserializerException {
82                 final byte[] bytes = new byte[] { (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
83                                 (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
84                                 (byte) 0x00, (byte) 0x13, (byte) 0x08 };
85                 try {
86                         this.factory.parse(bytes);
87                         fail("Exception should have occured.");
88                 } catch (final DocumentedException e) {
89                         assertEquals(BGPError.BAD_MSG_TYPE, ((BGPDocumentedException) e).getError());
90                         return;
91                 }
92                 fail();
93         }
94
95         @Test
96         public void testKeepAliveMsg() throws DeserializerException, DocumentedException {
97                 final BGPMessage keepAlive = new BGPKeepAliveMessage();
98                 final byte[] bytes = this.factory.put(keepAlive);
99                 assertArrayEquals(keepAliveBMsg, bytes);
100
101                 final BGPMessage m = (BGPMessage) this.factory.parse(bytes);
102
103                 assertTrue(m instanceof BGPKeepAliveMessage);
104         }
105
106         @Test
107         public void testBadKeepAliveMsg() throws DeserializerException {
108                 final byte[] bytes = new byte[] { (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
109                                 (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
110                                 (byte) 0x00, (byte) 0x14, (byte) 0x04, (byte) 0x05 };
111
112                 try {
113                         this.factory.parse(bytes);
114                         fail("Exception should have occured.");
115                 } catch (final DocumentedException e) {
116                         assertThat(e.getMessage(), containsString("Message length field not within valid range."));
117                         assertEquals(BGPError.BAD_MSG_LENGTH, ((BGPDocumentedException) e).getError());
118                         return;
119                 }
120                 fail();
121         }
122
123         @Test
124         public void testOpenMessage() throws UnknownHostException, DeserializerException, DocumentedException {
125                 final BGPMessage open = new BGPOpenMessage(new ASNumber(100), (short) 180, new IPv4Address(InetAddress.getByName("20.20.20.20")), null);
126                 final byte[] bytes = this.factory.put(open);
127                 assertArrayEquals(openBMsg, bytes);
128
129                 final BGPMessage m = (BGPMessage) this.factory.parse(bytes);
130
131                 assertTrue(m instanceof BGPOpenMessage);
132                 assertEquals(new ASNumber(100), ((BGPOpenMessage) m).getMyAS());
133                 assertEquals((short) 180, ((BGPOpenMessage) m).getHoldTime());
134                 assertEquals(new IPv4Address(InetAddress.getByName("20.20.20.20")), ((BGPOpenMessage) m).getBgpId());
135                 assertTrue(((BGPOpenMessage) m).getOptParams().isEmpty());
136         }
137
138         @Test
139         public void testBadHoldTimeError() throws DeserializerException {
140                 final byte[] bMsg = new byte[] { (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
141                                 (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
142                                 (byte) 0x00, (byte) 0x1d, (byte) 0x01, (byte) 0x04, (byte) 0x00, (byte) 0x64, (byte) 0x00, (byte) 0x01, (byte) 0x14,
143                                 (byte) 0x14, (byte) 0x14, (byte) 0x14, (byte) 0x00 };
144
145                 try {
146                         this.factory.parse(bMsg);
147                         fail("Exception should have occured.");
148                 } catch (final DocumentedException e) {
149                         assertEquals("Hold time value not acceptable.", e.getMessage());
150                         assertEquals(BGPError.HOLD_TIME_NOT_ACC, ((BGPDocumentedException) e).getError());
151                         return;
152                 }
153                 fail();
154         }
155
156         @Test
157         public void testBadMsgLength() throws DeserializerException {
158                 final byte[] bMsg = new byte[] { (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
159                                 (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
160                                 (byte) 0x00, (byte) 0x1b, (byte) 0x01, (byte) 0x04, (byte) 0x00, (byte) 0x64, (byte) 0x00, (byte) 0xb4, (byte) 0xff,
161                                 (byte) 0xff, (byte) 0xff };
162
163                 try {
164                         this.factory.parse(bMsg);
165                         fail("Exception should have occured.");
166                 } catch (final DocumentedException e) {
167                         assertEquals("Open message too small.", e.getMessage());
168                         assertEquals(BGPError.BAD_MSG_LENGTH, ((BGPDocumentedException) e).getError());
169                 }
170         }
171
172         @Test
173         public void testBadVersion() throws DeserializerException {
174                 final byte[] bMsg = new byte[] { (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
175                                 (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
176                                 (byte) 0x00, (byte) 0x1d, (byte) 0x01, (byte) 0x08, (byte) 0x00, (byte) 0x64, (byte) 0x00, (byte) 0xb4, (byte) 0x14,
177                                 (byte) 0x14, (byte) 0x14, (byte) 0x14, (byte) 0x00 };
178
179                 try {
180                         this.factory.parse(bMsg);
181                         fail("Exception should have occured.");
182                 } catch (final DocumentedException e) {
183                         assertEquals("BGP Protocol version 8 not supported.", e.getMessage());
184                         assertEquals(BGPError.VERSION_NOT_SUPPORTED, ((BGPDocumentedException) e).getError());
185                         return;
186                 }
187                 fail();
188         }
189
190         @Test
191         public void testNotificationMsg() throws DeserializerException, DocumentedException {
192                 BGPMessage notMsg = new BGPNotificationMessage(BGPError.OPT_PARAM_NOT_SUPPORTED, new byte[] { 4, 9 });
193                 byte[] bytes = this.factory.put(notMsg);
194                 assertArrayEquals(notificationBMsg, bytes);
195
196                 BGPMessage m = (BGPMessage) this.factory.parse(bytes);
197
198                 assertTrue(m instanceof BGPNotificationMessage);
199                 assertEquals(BGPError.OPT_PARAM_NOT_SUPPORTED, ((BGPNotificationMessage) m).getError());
200                 assertArrayEquals(new byte[] { 4, 9 }, ((BGPNotificationMessage) m).getData());
201
202                 notMsg = new BGPNotificationMessage(BGPError.CONNECTION_NOT_SYNC);
203                 bytes = this.factory.put(notMsg);
204
205                 m = (BGPMessage) this.factory.parse(bytes);
206
207                 assertTrue(m instanceof BGPNotificationMessage);
208                 assertEquals(BGPError.CONNECTION_NOT_SYNC, ((BGPNotificationMessage) m).getError());
209                 assertNull(((BGPNotificationMessage) m).getData());
210         }
211
212         @Test
213         public void testWrongLength() throws DeserializerException {
214                 final byte[] bMsg = new byte[] { (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
215                                 (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
216                                 (byte) 0x00, (byte) 0x14, (byte) 0x03, (byte) 0x02 };
217
218                 try {
219                         this.factory.parse(bMsg);
220                         fail("Exception should have occured.");
221                 } catch (final DocumentedException e) {
222                         assertEquals("Notification message too small.", e.getMessage());
223                         assertEquals(BGPError.BAD_MSG_LENGTH, ((BGPDocumentedException) e).getError());
224                         return;
225                 }
226                 fail();
227         }
228
229         @Test
230         public void testUnrecognizedError() throws DeserializerException, DocumentedException {
231                 final byte[] bMsg = new byte[] { (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
232                                 (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
233                                 (byte) 0x00, (byte) 0x15, (byte) 0x03, (byte) 0x02, (byte) 0xaa };
234
235                 try {
236                         this.factory.parse(bMsg);
237                         fail("Exception should have occured.");
238                 } catch (final IllegalArgumentException e) {
239                         assertEquals("BGP Error code 2 and subcode 170 not recognized.", e.getMessage());
240                         return;
241                 }
242                 fail();
243         }
244
245         @Test
246         public void testTLVParser() throws UnknownHostException {
247
248                 final BGPTableType t1 = new BGPTableType(BGPAddressFamily.IPv4, BGPSubsequentAddressFamily.Unicast);
249                 final BGPTableType t2 = new BGPTableType(BGPAddressFamily.LinkState, BGPSubsequentAddressFamily.Unicast);
250
251                 final List<BGPParameter> tlvs = Lists.newArrayList();
252                 tlvs.add(new MultiprotocolCapability(t1));
253                 tlvs.add(new MultiprotocolCapability(t2));
254                 final Map<BGPTableType, Boolean> tableTypes = Maps.newHashMap();
255                 tableTypes.put(t1, true);
256                 tableTypes.put(t2, true);
257                 tlvs.add(new GracefulCapability(true, 0, tableTypes));
258                 final BGPOpenMessage open = new BGPOpenMessage(new ASNumber(72), (short) 180, new IPv4Address(InetAddress.getByName("172.20.160.170")), tlvs);
259
260                 // System.out.println(Arrays.toString(this.factory.put(open)));
261
262                 this.factory.put(open);
263
264                 // assertArrayEquals(openWithCpblt, bytes);
265         }
266 }