2 * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
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
8 package org.opendaylight.protocol.bgp.parser.impl;
10 import static org.hamcrest.CoreMatchers.containsString;
11 import static org.junit.Assert.assertArrayEquals;
12 import static org.junit.Assert.assertEquals;
13 import static org.junit.Assert.assertNotNull;
14 import static org.junit.Assert.assertNull;
15 import static org.junit.Assert.assertThat;
16 import static org.junit.Assert.assertTrue;
17 import static org.junit.Assert.fail;
18 import com.google.common.collect.Lists;
19 import com.google.common.collect.Maps;
20 import io.netty.buffer.ByteBuf;
21 import io.netty.buffer.Unpooled;
22 import java.net.UnknownHostException;
23 import java.util.Arrays;
24 import java.util.List;
26 import org.junit.BeforeClass;
27 import org.junit.Test;
28 import org.opendaylight.protocol.bgp.parser.BGPDocumentedException;
29 import org.opendaylight.protocol.bgp.parser.BGPError;
30 import org.opendaylight.protocol.bgp.parser.BGPParsingException;
31 import org.opendaylight.protocol.bgp.parser.BgpTableTypeImpl;
32 import org.opendaylight.protocol.bgp.parser.spi.MessageRegistry;
33 import org.opendaylight.protocol.bgp.parser.spi.pojo.ServiceLoaderBGPExtensionProviderContext;
34 import org.opendaylight.protocol.util.ByteArray;
35 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.LinkstateAddressFamily;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.LinkstateSubsequentAddressFamily;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.Keepalive;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.KeepaliveBuilder;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.Notify;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.NotifyBuilder;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.Open;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.OpenBuilder;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.ProtocolVersion;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.Update;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.open.BgpParameters;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.open.BgpParametersBuilder;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.open.bgp.parameters.OptionalCapabilities;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.open.bgp.parameters.OptionalCapabilitiesBuilder;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.BgpTableType;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.open.bgp.parameters.optional.capabilities.c.parameters.MultiprotocolCaseBuilder;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.open.bgp.parameters.optional.capabilities.c.parameters.multiprotocol._case.MultiprotocolCapabilityBuilder;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.Ipv4AddressFamily;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.UnicastSubsequentAddressFamily;
55 import org.opendaylight.yangtools.yang.binding.Notification;
57 public class ParserTest {
59 private static final byte[] openBMsg = new byte[] { (byte) 0xff, (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) 0x00, (byte) 0x1d, (byte) 0x01, (byte) 0x04, (byte) 0x00, (byte) 0x64, (byte) 0x00, (byte) 0xb4,
62 (byte) 0x14, (byte) 0x14, (byte) 0x14, (byte) 0x14, (byte) 0x00 };
64 private static final byte[] keepAliveBMsg = new byte[] { (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, (byte) 0xff,
66 (byte) 0xff, (byte) 0x00, (byte) 0x13, (byte) 0x04 };
68 private static final byte[] notificationBMsg = new byte[] { (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) 0xff,
70 (byte) 0xff, (byte) 0xff, (byte) 0x00, (byte) 0x17, (byte) 0x03, (byte) 0x02, (byte) 0x04, (byte) 0x04, (byte) 0x09 };
72 private static final byte[] openWithCpblt1 = new byte[] { (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
73 (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
74 (byte) 0xff, (byte) 0x00, (byte) 0x2b, (byte) 0x01, (byte) 0x04, (byte) 0x00, (byte) 0x48, (byte) 0x00, (byte) 0xb4,
75 (byte) 0xac, (byte) 0x14, (byte) 0xa0, (byte) 0xaa, (byte) 0x0e, (byte) 0x02, (byte) 0x0C, (byte) 0x01, (byte) 0x04,
76 (byte) 0x00, (byte) 0x01, (byte) 0x00, (byte) 0x01, (byte) 0x01, (byte) 0x04, (byte) 0x40,
77 (byte) 0x04, (byte) 0x00, (byte) 0x47 };
79 private static final byte[] openWithCpblt2 = new byte[] { (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
80 (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
81 (byte) 0xff, (byte) 0x00, (byte) 0x2b, (byte) 0x01, (byte) 0x04, (byte) 0x00, (byte) 0x48, (byte) 0x00, (byte) 0xb4,
82 (byte) 0xac, (byte) 0x14, (byte) 0xa0, (byte) 0xaa, (byte) 0x0e, (byte) 0x02, (byte) 0x0C, (byte) 0x01, (byte) 0x04,
83 (byte) 0x40, (byte) 0x04, (byte) 0x00, (byte) 0x47, (byte) 0x01, (byte) 0x04, (byte) 0x00,
84 (byte) 0x01, (byte) 0x00, (byte) 0x01 };
86 private static final byte[] updMsgWithUnrecognizedAttribute = new byte[] {
87 (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
88 (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x00, (byte) 0x79, (byte) 0x02,
89 (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x62, (byte) 0x90, (byte) 0x0e, (byte) 0x00, (byte) 0x34, (byte) 0x40, (byte) 0x04, (byte) 0x47, (byte) 0x04, (byte) 0x0a, (byte) 0x19,
90 (byte) 0x02, (byte) 0x1b, (byte) 0x00, (byte) 0x00, (byte) 0x01, (byte) 0x00, (byte) 0x27, (byte) 0x02, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte)0x00,
91 (byte) 0x01, (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x1a, (byte) 0x02, (byte) 0x00, (byte) 0x00, (byte) 0x04, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x48, (byte) 0x02, (byte)0x01,
92 (byte) 0x00, (byte) 0x04, (byte) 0x28, (byte) 0x28, (byte) 0x28, (byte) 0x28, (byte) 0x02, (byte) 0x03, (byte) 0x00, (byte) 0x06, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte)0x00,
93 (byte) 0x43, (byte) 0x40, (byte) 0x01, (byte) 0x01, (byte) 0x00, (byte) 0x40, (byte) 0x02, (byte) 0x00, (byte) 0x40, (byte) 0x05, (byte) 0x04, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte)0x64,
94 (byte) 0x80, (byte) 0x63, (byte) 0x19, (byte) 0x04, (byte) 0x02, (byte) 0x00, (byte) 0x08, (byte) 0x4f, (byte) 0x66, (byte) 0x2d, (byte) 0x39, (byte) 0x6b, (byte) 0x2d, (byte) 0x30, (byte)0x33,
95 (byte) 0x04, (byte) 0x03, (byte) 0x00, (byte) 0x01, (byte) 0x72, (byte) 0x04, (byte) 0x04, (byte) 0x00, (byte) 0x04, (byte) 0x2b, (byte) 0x2b, (byte) 0x2b, (byte) 0x2b
98 static MessageRegistry reg;
101 public static void setupClass() throws Exception {
102 reg = ServiceLoaderBGPExtensionProviderContext.getSingletonInstance().getMessageRegistry();
106 public void testHeaderErrors() throws BGPParsingException, BGPDocumentedException {
107 byte[] wrong = new byte[] { (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x00 };
108 wrong = ByteArray.cutBytes(wrong, 16);
110 ParserTest.reg.parseMessage(Unpooled.copiedBuffer(wrong));
111 fail("Exception should have occcured.");
112 } catch (final IllegalArgumentException e) {
113 assertEquals("Too few bytes in passed array. Passed: " + wrong.length + ". Expected: >= 19.", e.getMessage());
120 public void testBadMsgType() throws BGPParsingException {
121 final byte[] bytes = { (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, (byte) 0xff,
123 (byte) 0x00, (byte) 0x13, (byte) 0x08 };
125 ParserTest.reg.parseMessage(Unpooled.copiedBuffer(bytes));
126 fail("Exception should have occured.");
127 } catch (final BGPDocumentedException e) {
128 assertEquals(BGPError.BAD_MSG_TYPE, e.getError());
135 public void testKeepAliveMsg() throws BGPParsingException, BGPDocumentedException {
136 final Notification keepAlive = new KeepaliveBuilder().build();
137 final ByteBuf buffer = Unpooled.buffer();
138 ParserTest.reg.serializeMessage(keepAlive, buffer);
139 assertArrayEquals(keepAliveBMsg, ByteArray.getAllBytes(buffer));
141 final Notification m = ParserTest.reg.parseMessage(Unpooled.copiedBuffer(ByteArray.getAllBytes(buffer)));
143 assertTrue(m instanceof Keepalive);
147 public void testBadKeepAliveMsg() throws BGPParsingException {
148 final byte[] bytes = new byte[] { (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, (byte) 0xff,
150 (byte) 0x00, (byte) 0x14, (byte) 0x04, (byte) 0x05 };
153 ParserTest.reg.parseMessage(Unpooled.copiedBuffer(bytes));
154 fail("Exception should have occured.");
155 } catch (final BGPDocumentedException e) {
156 assertThat(e.getMessage(), containsString("Message length field not within valid range."));
157 assertEquals(BGPError.BAD_MSG_LENGTH, e.getError());
164 public void testOpenMessage() throws UnknownHostException, BGPParsingException, BGPDocumentedException {
165 final Notification open = new OpenBuilder().setMyAsNumber(100).setHoldTimer(180).setBgpIdentifier(new Ipv4Address("20.20.20.20")).setVersion(
166 new ProtocolVersion((short) 4)).build();
167 final ByteBuf bytes = Unpooled.buffer();
168 ParserTest.reg.serializeMessage(open, bytes);
169 assertArrayEquals(openBMsg, ByteArray.getAllBytes(bytes));
171 final Notification m = ParserTest.reg.parseMessage(Unpooled.copiedBuffer(bytes));
173 assertTrue(m instanceof Open);
174 assertEquals(100, ((Open) m).getMyAsNumber().intValue());
175 assertEquals(180, ((Open) m).getHoldTimer().intValue());
176 assertEquals(new Ipv4Address("20.20.20.20"), ((Open) m).getBgpIdentifier());
177 assertTrue(((Open) m).getBgpParameters().isEmpty());
181 public void testBadHoldTimeError() throws BGPParsingException {
182 final byte[] bMsg = new byte[] { (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
183 (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
184 (byte) 0x00, (byte) 0x1d, (byte) 0x01, (byte) 0x04, (byte) 0x00, (byte) 0x64, (byte) 0x00, (byte) 0x01, (byte) 0x14,
185 (byte) 0x14, (byte) 0x14, (byte) 0x14, (byte) 0x00 };
188 ParserTest.reg.parseMessage(Unpooled.copiedBuffer(bMsg));
189 fail("Exception should have occured.");
190 } catch (final BGPDocumentedException e) {
191 assertEquals("Hold time value not acceptable.", e.getMessage());
192 assertEquals(BGPError.HOLD_TIME_NOT_ACC, e.getError());
199 public void testBadMsgLength() 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) 0x1b, (byte) 0x01, (byte) 0x04, (byte) 0x00, (byte) 0x64, (byte) 0x00, (byte) 0xb4, (byte) 0xff,
203 (byte) 0xff, (byte) 0xff };
206 ParserTest.reg.parseMessage(Unpooled.copiedBuffer(bMsg));
207 fail("Exception should have occured.");
208 } catch (final BGPDocumentedException e) {
209 assertEquals("Open message too small.", e.getMessage());
210 assertEquals(BGPError.BAD_MSG_LENGTH, e.getError());
215 public void testBadVersion() throws BGPParsingException {
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) 0x1d, (byte) 0x01, (byte) 0x08, (byte) 0x00, (byte) 0x64, (byte) 0x00, (byte) 0xb4, (byte) 0x14,
219 (byte) 0x14, (byte) 0x14, (byte) 0x14, (byte) 0x00 };
222 ParserTest.reg.parseMessage(Unpooled.copiedBuffer(bMsg));
223 fail("Exception should have occured.");
224 } catch (final BGPDocumentedException e) {
225 assertEquals("BGP Protocol version 8 not supported.", e.getMessage());
226 assertEquals(BGPError.VERSION_NOT_SUPPORTED, e.getError());
233 public void testNotificationMsg() throws BGPParsingException, BGPDocumentedException {
234 Notification notMsg = new NotifyBuilder().setErrorCode(BGPError.OPT_PARAM_NOT_SUPPORTED.getCode()).setErrorSubcode(
235 BGPError.OPT_PARAM_NOT_SUPPORTED.getSubcode()).setData(new byte[] { 4, 9 }).build();
236 final ByteBuf bytes = Unpooled.buffer();
237 ParserTest.reg.serializeMessage(notMsg, bytes);
238 assertArrayEquals(notificationBMsg, ByteArray.subByte(bytes.array(),0,bytes.writerIndex()));
240 Notification m = ParserTest.reg.parseMessage(Unpooled.copiedBuffer(bytes));
242 assertTrue(m instanceof Notify);
243 assertEquals(BGPError.OPT_PARAM_NOT_SUPPORTED, BGPError.forValue(((Notify) m).getErrorCode(), ((Notify) m).getErrorSubcode()));
244 assertArrayEquals(new byte[] { 4, 9 }, ((Notify) m).getData());
246 notMsg = new NotifyBuilder().setErrorCode(BGPError.CONNECTION_NOT_SYNC.getCode()).setErrorSubcode(
247 BGPError.CONNECTION_NOT_SYNC.getSubcode()).build();
251 ParserTest.reg.serializeMessage(notMsg, bytes);
253 m = ParserTest.reg.parseMessage(Unpooled.copiedBuffer(bytes));
255 assertTrue(m instanceof Notify);
256 assertEquals(BGPError.CONNECTION_NOT_SYNC, BGPError.forValue(((Notify) m).getErrorCode(), ((Notify) m).getErrorSubcode()));
257 assertNull(((Notify) m).getData());
261 public void testWrongLength() throws BGPParsingException {
262 final byte[] bMsg = new byte[] { (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
263 (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
264 (byte) 0x00, (byte) 0x14, (byte) 0x03, (byte) 0x02 };
267 ParserTest.reg.parseMessage(Unpooled.copiedBuffer(bMsg));
268 fail("Exception should have occured.");
269 } catch (final BGPDocumentedException e) {
270 assertEquals("Notification message too small.", e.getMessage());
271 assertEquals(BGPError.BAD_MSG_LENGTH, e.getError());
278 public void testUnrecognizedError() throws BGPParsingException, BGPDocumentedException {
279 final byte[] bMsg = new byte[] { (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
280 (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
281 (byte) 0x00, (byte) 0x15, (byte) 0x03, (byte) 0x02, (byte) 0xaa };
284 ParserTest.reg.parseMessage(Unpooled.copiedBuffer(bMsg));
285 fail("Exception should have occured.");
286 } catch (final IllegalArgumentException e) {
287 assertEquals("BGP Error code 2 and subcode 170 not recognized.", e.getMessage());
294 public void testTLVParser() throws UnknownHostException {
296 final BgpTableType t1 = new BgpTableTypeImpl(Ipv4AddressFamily.class, UnicastSubsequentAddressFamily.class);
297 final BgpTableType t2 = new BgpTableTypeImpl(LinkstateAddressFamily.class, UnicastSubsequentAddressFamily.class);
299 final List<OptionalCapabilities> capas = Lists.newArrayList();
301 capas.add(new OptionalCapabilitiesBuilder().setCParameters(
302 new MultiprotocolCaseBuilder().setMultiprotocolCapability(
303 new MultiprotocolCapabilityBuilder().setAfi(LinkstateAddressFamily.class).setSafi(
304 LinkstateSubsequentAddressFamily.class).build()).build()).build());
305 capas.add(new OptionalCapabilitiesBuilder().setCParameters(
306 new MultiprotocolCaseBuilder().setMultiprotocolCapability(
307 new MultiprotocolCapabilityBuilder().setAfi(Ipv4AddressFamily.class).setSafi(UnicastSubsequentAddressFamily.class).build()).build()).build());
308 final List<BgpParameters> tlvs = Lists.newArrayList(new BgpParametersBuilder().setOptionalCapabilities(capas).build());
310 final Map<BgpTableType, Boolean> tableTypes = Maps.newHashMap();
311 tableTypes.put(t1, true);
312 tableTypes.put(t2, true);
313 final Open open = new OpenBuilder().setMyAsNumber(72).setHoldTimer(180).setBgpIdentifier(new Ipv4Address("172.20.160.170")).setVersion(
314 new ProtocolVersion((short) 4)).setBgpParameters(tlvs).build();
316 final ByteBuf result = Unpooled.buffer();
317 ParserTest.reg.serializeMessage(open, result);
319 // the capabilities can be swapped.
320 assertTrue(Arrays.equals(openWithCpblt1, ByteArray.getAllBytes(result)) || Arrays.equals(openWithCpblt2, ByteArray.getAllBytes(result)));
324 public void testParseUpdMsgWithUnrecognizedAttribute() throws BGPDocumentedException, BGPParsingException {
325 final Update updMsg = (Update) reg.parseMessage(Unpooled.copiedBuffer(updMsgWithUnrecognizedAttribute));
326 assertNotNull(updMsg.getPathAttributes());