From 04b65af0a1266b55884f6d7dbaeddb9de8805791 Mon Sep 17 00:00:00 2001 From: Jozef Gloncak Date: Tue, 17 Mar 2015 12:50:15 +0100 Subject: [PATCH] Bug 2820 - LLDP TLV support and testing - enhancement: deserialization now supports custom TLV - tests: - LLDP.deserialize - LLDPTLV.createCustomValue - LLDPTLV.getCustomString - beautified (checkstyle) Change-Id: I56c807b46d889266fc43cdc9b35d00bf17bb4d09 Signed-off-by: Jozef Gloncak Signed-off-by: Michal Rehak (cherry picked from commit 91a47340196d4a5bbf9beaaed9a202bf4a8836d9) --- opendaylight/commons/liblldp/pom.xml | 1 - .../opendaylight/controller/liblldp/LLDP.java | 24 ++++- .../controller/liblldp/LLDPTLVTest.java | 81 ++++++++++++++++ .../controller/liblldp/LLDPTest.java | 92 +++++++++++++++++-- .../liblldp/src/test/resources/log4j.xml | 20 ++++ 5 files changed, 202 insertions(+), 16 deletions(-) create mode 100644 opendaylight/commons/liblldp/src/test/java/org/opendaylight/controller/liblldp/LLDPTLVTest.java create mode 100644 opendaylight/commons/liblldp/src/test/resources/log4j.xml diff --git a/opendaylight/commons/liblldp/pom.xml b/opendaylight/commons/liblldp/pom.xml index 286c68e677..5e14c92ee7 100644 --- a/opendaylight/commons/liblldp/pom.xml +++ b/opendaylight/commons/liblldp/pom.xml @@ -27,7 +27,6 @@ org.slf4j slf4j-log4j12 - test com.google.guava diff --git a/opendaylight/commons/liblldp/src/main/java/org/opendaylight/controller/liblldp/LLDP.java b/opendaylight/commons/liblldp/src/main/java/org/opendaylight/controller/liblldp/LLDP.java index 94f25c03a3..c7dc6915ad 100644 --- a/opendaylight/commons/liblldp/src/main/java/org/opendaylight/controller/liblldp/LLDP.java +++ b/opendaylight/commons/liblldp/src/main/java/org/opendaylight/controller/liblldp/LLDP.java @@ -8,7 +8,6 @@ package org.opendaylight.controller.liblldp; -import java.util.Collections; import com.google.common.collect.Iterables; import java.util.ArrayList; import java.util.LinkedHashMap; @@ -31,14 +30,15 @@ public class LLDP extends Packet { (byte) 0xc2, 0, 0, (byte) 0xe }; private Map tlvList; - private List customTlvList = Collections.emptyList(); + private List customTlvList; /** * Default constructor that creates the tlvList LinkedHashMap */ public LLDP() { super(); - tlvList = new LinkedHashMap(LLDPDefaultTlvs); + tlvList = new LinkedHashMap<>(LLDPDefaultTlvs); + customTlvList = new ArrayList<>(); } /** @@ -63,6 +63,8 @@ public class LLDP extends Packet { return LLDPTLV.TLVType.PortID.getValue(); } else if (typeDesc.equals(TTL)) { return LLDPTLV.TLVType.TTL.getValue(); + } else if (typeDesc.equals(SYSTEMNAMEID)) { + return LLDPTLV.TLVType.SystemName.getValue(); } else { return LLDPTLV.TLVType.Unknown.getValue(); } @@ -163,7 +165,8 @@ public class LLDP extends Packet { byte type = entry.getKey(); if ((type == LLDPTLV.TLVType.ChassisID.getValue()) || (type == LLDPTLV.TLVType.PortID.getValue()) - || (type == LLDPTLV.TLVType.TTL.getValue())) { + || (type == LLDPTLV.TLVType.TTL.getValue()) + || (type == LLDPTLV.TLVType.SystemName.getValue())) { continue; } else { list.add(entry.getValue()); @@ -172,6 +175,13 @@ public class LLDP extends Packet { return list; } + /** + * @return the customTlvList + */ + public List getCustomTlvList() { + return customTlvList; + } + /** * @param optionalTLVList * the optionalTLVList to set @@ -216,7 +226,11 @@ public class LLDP extends Packet { int tlvSize = tlv.getTLVSize(); // Size of current TLV in bits lldpOffset += tlvSize; lldpSize -= tlvSize; - this.tlvList.put(tlv.getType(), tlv); + if (tlv.getType() == LLDPTLV.TLVType.Custom.getValue()) { + customTlvList.add(tlv); + } else { + this.tlvList.put(tlv.getType(), tlv); + } } return this; } diff --git a/opendaylight/commons/liblldp/src/test/java/org/opendaylight/controller/liblldp/LLDPTLVTest.java b/opendaylight/commons/liblldp/src/test/java/org/opendaylight/controller/liblldp/LLDPTLVTest.java new file mode 100644 index 0000000000..23f8ae6f96 --- /dev/null +++ b/opendaylight/commons/liblldp/src/test/java/org/opendaylight/controller/liblldp/LLDPTLVTest.java @@ -0,0 +1,81 @@ +/** + * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.controller.liblldp; + +import org.junit.Assert; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.common.io.BaseEncoding; +import com.google.common.primitives.Bytes; + +/** + * + */ +public class LLDPTLVTest { + + /** dummy custom tlv value */ + private static final String CUSTOM_TLV_ULTIMATE = "What do you get when you multiply 6 by 9?"; + /** dummy custom tlv value in binary form */ + private static final byte[] CUSTOM_TLV_ULTIMATE_BIN = new byte[] { + 0x57, 0x68, 0x61, 0x74, 0x20, 0x64, 0x6f, 0x20, 0x79, 0x6f, 0x75, 0x20, 0x67, 0x65, 0x74, + 0x20, 0x77, 0x68, 0x65, 0x6e, 0x20, 0x79, 0x6f, 0x75, 0x20, 0x6d, 0x75, 0x6c, 0x74, 0x69, + 0x70, 0x6c, 0x79, 0x20, 0x36, 0x20, 0x62, 0x79, 0x20, 0x39, 0x3f + }; + + private static final Logger LOG = LoggerFactory.getLogger(LLDPTLVTest.class); + + /** + * Test method for + * {@link org.opendaylight.controller.liblldp.LLDPTLV#createCustomTLVValue(java.lang.String)} + * . + */ + @Test + public void testCreateCustomTLVValue() { + byte[] tlv = LLDPTLV.createCustomTLVValue(CUSTOM_TLV_ULTIMATE); + + byte[] expectedCustomTlv = Bytes.concat(new byte[] { + // custom type (7b) + length (9b) = 16b = 2B (skipped) + // 0x7f, 24, + // openflow OUI + 0x00, 0x26, (byte) 0xe1, + // subtype + 0x00}, + // custom value + CUSTOM_TLV_ULTIMATE_BIN); + + BaseEncoding be = BaseEncoding.base16().withSeparator(" ", 2).lowerCase(); + LOG.debug("expected: {}", be.encode(expectedCustomTlv)); + LOG.debug("actual : {}", be.encode(tlv)); + Assert.assertArrayEquals(expectedCustomTlv, tlv); + } + + /** + * Test method for + * {@link org.opendaylight.controller.liblldp.LLDPTLV#getCustomString(byte[], int)} + * . + * @throws Exception + */ + @Test + public void testGetCustomString() throws Exception { + byte[] inputCustomTlv = Bytes.concat(new byte[] { + // custom type (7b) + length (9b) = 16b = 2B (skipped) + // 0x7f, 24, + // openflow OUI + 0x00, 0x26, (byte) 0xe1, + // subtype + 0x00}, + // custom value + CUSTOM_TLV_ULTIMATE_BIN); + + String actual = LLDPTLV.getCustomString(inputCustomTlv, inputCustomTlv.length); + LOG.debug("actual custom TLV value as string: {}", actual); + Assert.assertEquals(CUSTOM_TLV_ULTIMATE, actual); + } +} diff --git a/opendaylight/commons/liblldp/src/test/java/org/opendaylight/controller/liblldp/LLDPTest.java b/opendaylight/commons/liblldp/src/test/java/org/opendaylight/controller/liblldp/LLDPTest.java index a9cfa727ce..1a14e0b650 100644 --- a/opendaylight/commons/liblldp/src/test/java/org/opendaylight/controller/liblldp/LLDPTest.java +++ b/opendaylight/commons/liblldp/src/test/java/org/opendaylight/controller/liblldp/LLDPTest.java @@ -10,17 +10,24 @@ package org.opendaylight.controller.liblldp; import static org.junit.Assert.assertArrayEquals; import java.util.ArrayList; - import java.util.List; -import org.junit.internal.ArrayComparisonFailure; -import org.junit.Test; + import org.apache.commons.lang3.ArrayUtils; +import org.junit.Assert; +import org.junit.Test; +import org.junit.internal.ArrayComparisonFailure; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.common.primitives.Bytes; /** * Test of {@link LLDP} serialization feature (TODO: and deserialization) */ public class LLDPTest { + private static final Logger LOG = LoggerFactory.getLogger(LLDPTest.class); + private static final byte[] CHASSIS_ID_VALUE = "chassis".getBytes(); private static final short CHASSIS_ID_LENGTH = (short) CHASSIS_ID_VALUE.length; @@ -49,6 +56,7 @@ public class LLDPTest { /** * Tests whether serialization of LLDP packet is correct + * * @see LLDP#serialize() * @throws PacketException */ @@ -82,14 +90,78 @@ public class LLDPTest { offset = checkTLV(serialized, offset, (byte) 0b00000010, "ChassisID", CHASSIS_ID_LENGTH, CHASSIS_ID_VALUE); offset = checkTLV(serialized, offset, (byte) 0b00000110, "TTL", TTL_LENGTH, TTL_VALUE); offset = checkTLV(serialized, offset, (byte) 0b00000100, "PortID", PORT_LENGTH, PORT_VALUE); - offset = checkTLV(serialized, offset, (byte) 0b00001010, "SystemName", SYSTEM_NAME_LENGTH, SYSTEM_NAME_VALUE); - offset = checkTLV(serialized, offset, (byte) 0b00010000, "System capabilities", SYSTEM_CAPABILITIES_LENGTH, - SYSTEM_CAPABILITIES_VALUE); - offset = checkTLV(serialized, offset, (byte) 0b11111110, "Custom subtype A", CUSTOM_SUBTYPE_A_LENGTH, - CUSTOM_SUBTYPE_A_VALUE, OUI[0], OUI[1], OUI[2], OUI_SUBTYPE_A[0]); - offset = checkTLV(serialized, offset, (byte) 0b11111110, "Custom subtype B", CUSTOM_SUBTYPE_B_LENGTH, - CUSTOM_SUBTYPE_B_VALUE, OUI[0], OUI[1], OUI[2], OUI_SUBTYPE_B[0]); + offset = checkTLV(serialized, offset, (byte) 0b00001010, "SystemName", SYSTEM_NAME_LENGTH, + SYSTEM_NAME_VALUE); + offset = checkTLV(serialized, offset, (byte) 0b00010000, "System capabilities", + SYSTEM_CAPABILITIES_LENGTH, SYSTEM_CAPABILITIES_VALUE); + offset = checkTLV(serialized, offset, (byte) 0b11111110, "Custom subtype A", + CUSTOM_SUBTYPE_A_LENGTH, CUSTOM_SUBTYPE_A_VALUE, OUI[0], OUI[1], OUI[2], + OUI_SUBTYPE_A[0]); + offset = checkTLV(serialized, offset, (byte) 0b11111110, "Custom subtype B", + CUSTOM_SUBTYPE_B_LENGTH, CUSTOM_SUBTYPE_B_VALUE, OUI[0], OUI[1], OUI[2], + OUI_SUBTYPE_B[0]); + + } + /** + * Tests whether serialization of LLDP packet is correct + * + * @see LLDP#deserialize(byte[], int, int) + * @throws Exception + */ + @Test + public void testDeserialize() throws Exception { + LLDP lldp = new LLDP(); + byte[] bytesBeforeCustomA = new byte[] { 0x00, 0x26, (byte) 0xe1, OUI_SUBTYPE_A[0] }; + byte[] bytesBeforeCustomB = new byte[] { 0x00, 0x26, (byte) 0xe1, OUI_SUBTYPE_B[0] }; + + byte[] rawLldpTlv = Bytes.concat( + awaitedBytes((byte) 0b00000010, CHASSIS_ID_LENGTH, CHASSIS_ID_VALUE, null), + awaitedBytes((byte) 0b00000110, TTL_LENGTH, TTL_VALUE, null), + awaitedBytes((byte) 0b00000100, PORT_LENGTH, PORT_VALUE, null), + awaitedBytes((byte) 0b00001010, SYSTEM_NAME_LENGTH, SYSTEM_NAME_VALUE, null), + awaitedBytes((byte) 0b00010010, SYSTEM_CAPABILITIES_LENGTH, + SYSTEM_CAPABILITIES_VALUE, null), + awaitedBytes((byte) 0b11111110, CUSTOM_SUBTYPE_A_LENGTH, CUSTOM_SUBTYPE_A_VALUE, + bytesBeforeCustomA), + awaitedBytes((byte) 0b11111110, CUSTOM_SUBTYPE_B_LENGTH, CUSTOM_SUBTYPE_B_VALUE, + bytesBeforeCustomB)); + + lldp.deserialize(rawLldpTlv, 0, rawLldpTlv.length * NetUtils.NumBitsInAByte); + Assert.assertEquals("chassis", new String(lldp.getChassisId().getValue())); + Assert.assertArrayEquals(TTL_VALUE, lldp.getTtl().getValue()); + Assert.assertEquals("dummy port id", new String(lldp.getPortId().getValue())); + Assert.assertEquals("dummy system name", new String(lldp.getSystemNameId().getValue())); + + // optional items check + List tlvOptionalList = lldp.getOptionalTLVList(); + Assert.assertEquals(1, tlvOptionalList.size()); + + LLDPTLV itemOpt0 = tlvOptionalList.get(0); + Assert.assertEquals(9, itemOpt0.getType()); + Assert.assertEquals("dummy system capabilities", new String(itemOpt0.getValue())); + + // custom items check + List tlvCustomList = lldp.getCustomTlvList(); + Assert.assertEquals(2, tlvCustomList.size()); + + checkCustomTlv(tlvCustomList.get(0), "first custom value A"); + checkCustomTlv(tlvCustomList.get(1), "second custom value B"); + } + + /** + * @param customItem + * @param expectedValue + */ + private static void checkCustomTlv(LLDPTLV customItem, String expectedValue) { + Assert.assertEquals(127, customItem.getType()); + LOG.debug("custom TLV1.length: {}", customItem.getLength()); + Assert.assertEquals(expectedValue, + new String( + LLDPTLV.getCustomString( + customItem.getValue(), + customItem.getLength())) + ); } private static int checkTLV(byte[] serializedData, int offset, byte typeTLVBits, String typeTLVName, short lengthTLV, diff --git a/opendaylight/commons/liblldp/src/test/resources/log4j.xml b/opendaylight/commons/liblldp/src/test/resources/log4j.xml new file mode 100644 index 0000000000..9196fc4af2 --- /dev/null +++ b/opendaylight/commons/liblldp/src/test/resources/log4j.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + + + -- 2.36.6