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