/* * Copyright 2017-present Open Networking Laboratory * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.onosproject.drivers.lisp.extensions; import com.fasterxml.jackson.databind.JsonNode; import com.google.common.collect.ImmutableList; import com.google.common.collect.Lists; import com.google.common.testing.EqualsTester; import org.hamcrest.MatcherAssert; import org.junit.Before; import org.junit.Test; import org.onlab.packet.IpAddress; import org.onlab.packet.IpPrefix; import org.onosproject.codec.CodecContext; import org.onosproject.codec.impl.CodecManager; import org.onosproject.drivers.lisp.extensions.codec.LispAppDataAddressCodecTest; import org.onosproject.drivers.lisp.extensions.codec.LispAsAddressCodecTest; import org.onosproject.drivers.lisp.extensions.codec.LispGcAddressCodecTest; import org.onosproject.drivers.lisp.extensions.codec.LispListAddressCodecTest; import org.onosproject.drivers.lisp.extensions.codec.LispMappingExtensionCodecContextAdapter; import org.onosproject.drivers.lisp.extensions.codec.LispMulticastAddressCodecTest; import org.onosproject.drivers.lisp.extensions.codec.LispNatAddressCodecTest; import org.onosproject.drivers.lisp.extensions.codec.LispNonceAddressCodecTest; import org.onosproject.drivers.lisp.extensions.codec.LispSegmentAddressCodecTest; import org.onosproject.drivers.lisp.extensions.codec.LispSrcDstAddressCodecTest; import org.onosproject.drivers.lisp.extensions.codec.LispTeAddressCodecTest; import org.onosproject.lisp.msg.types.LispAfiAddress; import org.onosproject.lisp.msg.types.LispIpv4Address; import org.onosproject.lisp.msg.types.LispIpv6Address; import org.onosproject.lisp.msg.types.lcaf.LispAppDataLcafAddress; import org.onosproject.lisp.msg.types.lcaf.LispAsLcafAddress; import org.onosproject.lisp.msg.types.lcaf.LispGeoCoordinateLcafAddress; import org.onosproject.lisp.msg.types.lcaf.LispLcafAddress; import org.onosproject.lisp.msg.types.lcaf.LispListLcafAddress; import org.onosproject.lisp.msg.types.lcaf.LispMulticastLcafAddress; import org.onosproject.lisp.msg.types.lcaf.LispNatLcafAddress; import org.onosproject.lisp.msg.types.lcaf.LispNonceLcafAddress; import org.onosproject.lisp.msg.types.lcaf.LispSegmentLcafAddress; import org.onosproject.lisp.msg.types.lcaf.LispSourceDestLcafAddress; import org.onosproject.lisp.msg.types.lcaf.LispTeLcafAddress; import org.onosproject.lisp.msg.types.lcaf.LispTeRecord; import org.onosproject.mapping.addresses.ExtensionMappingAddress; import org.onosproject.mapping.addresses.ExtensionMappingAddressType; import org.onosproject.mapping.addresses.MappingAddress; import org.onosproject.mapping.addresses.MappingAddresses; import java.io.IOException; import java.io.InputStream; import java.util.List; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.notNullValue; import static org.junit.Assert.assertTrue; import static org.onosproject.drivers.lisp.extensions.LispExtensionMappingAddressInterpreter.*; import static org.onosproject.mapping.addresses.ExtensionMappingAddressType.ExtensionMappingAddressTypes.*; /** * Unit tests for LispExtensionMappingAddressInterpreter. */ public class LispExtensionMappingAddressInterpreterTest { private static final String IPV4_STRING = "1.2.3.4"; private static final String IPV6_STRING = "1111:2222:3333:4444:5555:6666:7777:8886"; private static final IpPrefix IPV4_PREFIX = IpPrefix.valueOf(IPV4_STRING + "/32"); private static final IpPrefix IPV6_PREFIX = IpPrefix.valueOf(IPV6_STRING + "/128"); private static final IpAddress IPV4_ADDRESS = IpAddress.valueOf(IPV4_STRING); private static final IpAddress IPV6_ADDRESS = IpAddress.valueOf(IPV6_STRING); private static final int UNIQUE_INT = 1; private static final short UNIQUE_SHORT = (short) 1; private static final byte UNIQUE_BYTE = (byte) 1; private static final boolean UNIQUE_BOOLEAN = true; private LispExtensionMappingAddressInterpreter interpreter; private CodecContext context; private LispMappingExtensionCodecRegistrator registrator; private ExtensionMappingAddress listExtAddress; private ExtensionMappingAddress segmentExtAddress; private ExtensionMappingAddress asExtAddress; private ExtensionMappingAddress appDataExtAddress; private ExtensionMappingAddress gcExtAddress; private ExtensionMappingAddress natExtAddress; private ExtensionMappingAddress nonceExtAddress; private ExtensionMappingAddress multicastExtAddress; private ExtensionMappingAddress teExtAddress; private ExtensionMappingAddress srcDstExtAddress; private LispLcafAddress listLcafAddress; private LispLcafAddress segmentLcafAddress; private LispLcafAddress asLcafAddress; private LispLcafAddress appDataLcafAddress; private LispLcafAddress gcLcafAddress; private LispLcafAddress natLcafAddress; private LispLcafAddress nonceLcafAddress; private LispLcafAddress multicastLcafAddress; private LispLcafAddress teLcafAddress; private LispLcafAddress srcDstLcafAddress; @Before public void setUp() { interpreter = new LispExtensionMappingAddressInterpreter(); initExtAddresses(); initLcafAddresses(); CodecManager manager = new CodecManager(); registrator = new LispMappingExtensionCodecRegistrator(); registrator.codecService = manager; registrator.activate(); context = new LispMappingExtensionCodecContextAdapter(registrator.codecService); } /** * Initializes all extension mapping addresses. */ private void initExtAddresses() { listExtAddress = getExtMappingAddress(LIST_ADDRESS.type()); segmentExtAddress = getExtMappingAddress(SEGMENT_ADDRESS.type()); asExtAddress = getExtMappingAddress(AS_ADDRESS.type()); appDataExtAddress = getExtMappingAddress(APPLICATION_DATA_ADDRESS.type()); gcExtAddress = getExtMappingAddress(GEO_COORDINATE_ADDRESS.type()); natExtAddress = getExtMappingAddress(NAT_ADDRESS.type()); nonceExtAddress = getExtMappingAddress(NONCE_ADDRESS.type()); multicastExtAddress = getExtMappingAddress(MULTICAST_ADDRESS.type()); teExtAddress = getExtMappingAddress(TRAFFIC_ENGINEERING_ADDRESS.type()); srcDstExtAddress = getExtMappingAddress(SOURCE_DEST_ADDRESS.type()); } /** * Initializes all LCAF addresses. */ private void initLcafAddresses() { listLcafAddress = getLcafMappingAddress(LIST_ADDRESS.type()); segmentLcafAddress = getLcafMappingAddress(SEGMENT_ADDRESS.type()); asLcafAddress = getLcafMappingAddress(AS_ADDRESS.type()); appDataLcafAddress = getLcafMappingAddress(APPLICATION_DATA_ADDRESS.type()); gcLcafAddress = getLcafMappingAddress(GEO_COORDINATE_ADDRESS.type()); natLcafAddress = getLcafMappingAddress(NAT_ADDRESS.type()); nonceLcafAddress = getLcafMappingAddress(NONCE_ADDRESS.type()); multicastLcafAddress = getLcafMappingAddress(MULTICAST_ADDRESS.type()); teLcafAddress = getLcafMappingAddress(TRAFFIC_ENGINEERING_ADDRESS.type()); srcDstLcafAddress = getLcafMappingAddress(SOURCE_DEST_ADDRESS.type()); } /** * Tests supportability of a certain LISP extension mapping address. */ @Test public void testSupported() { assertTrue("List extension address should be supported", interpreter.supported(listExtAddress.type())); assertTrue("Segment extension address should be supported", interpreter.supported(segmentExtAddress.type())); assertTrue("AS extension address should be supported", interpreter.supported(asExtAddress.type())); assertTrue("Application data extension address should be supported", interpreter.supported(appDataExtAddress.type())); assertTrue("Geo Coordinate extension address should be supported", interpreter.supported(gcExtAddress.type())); assertTrue("NAT extension address should be supported ", interpreter.supported(natExtAddress.type())); assertTrue("Nonce extension address should be supported", interpreter.supported(nonceExtAddress.type())); assertTrue("Multicast extension address should be supported", interpreter.supported(multicastExtAddress.type())); assertTrue("Traffic engineering extension address should be supported", interpreter.supported(teExtAddress.type())); assertTrue("Source Destination extension address should be supported", interpreter.supported(srcDstExtAddress.type())); } /** * Tests conversion from LISP extension mapping address to LCAF address. */ @Test public void testMapMappingAddress() { new EqualsTester() .addEqualityGroup(listLcafAddress, interpreter.mapMappingAddress(listExtAddress)) .addEqualityGroup(segmentLcafAddress, interpreter.mapMappingAddress(segmentExtAddress)) .addEqualityGroup(asLcafAddress, interpreter.mapMappingAddress(asExtAddress)) .addEqualityGroup(appDataLcafAddress, interpreter.mapMappingAddress(appDataExtAddress)) .addEqualityGroup(gcLcafAddress, interpreter.mapMappingAddress(gcExtAddress)) .addEqualityGroup(natLcafAddress, interpreter.mapMappingAddress(natExtAddress)) .addEqualityGroup(nonceLcafAddress, interpreter.mapMappingAddress(nonceExtAddress)) .addEqualityGroup(multicastLcafAddress, interpreter.mapMappingAddress(multicastExtAddress)) .addEqualityGroup(teLcafAddress, interpreter.mapMappingAddress(teExtAddress)) .addEqualityGroup(srcDstLcafAddress, interpreter.mapMappingAddress(srcDstExtAddress)) .testEquals(); } /** * Tests conversion from LCAF address to LISP extension mapping address. */ @Test public void testMapLcafAddress() { new EqualsTester() .addEqualityGroup(listExtAddress, interpreter.mapLcafAddress(listLcafAddress)) .addEqualityGroup(segmentExtAddress, interpreter.mapLcafAddress(segmentLcafAddress)) .addEqualityGroup(asExtAddress, interpreter.mapLcafAddress(asLcafAddress)) .addEqualityGroup(appDataExtAddress, interpreter.mapLcafAddress(appDataLcafAddress)) .addEqualityGroup(gcExtAddress, interpreter.mapLcafAddress(gcLcafAddress)) .addEqualityGroup(natExtAddress, interpreter.mapLcafAddress(natLcafAddress)) .addEqualityGroup(nonceExtAddress, interpreter.mapLcafAddress(nonceLcafAddress)) .addEqualityGroup(multicastExtAddress, interpreter.mapLcafAddress(multicastLcafAddress)) .addEqualityGroup(teExtAddress, interpreter.mapLcafAddress(teLcafAddress)) .addEqualityGroup(srcDstExtAddress, interpreter.mapLcafAddress(srcDstLcafAddress)) .testEquals(); } /** * Tests encoding of an ExtensionMappingAddress object. */ @Test public void testAddressEncode() { JsonNode listAddressJson = interpreter.encode(listExtAddress, context).get(LISP_LIST_ADDRESS); JsonNode segmentAddressJson = interpreter.encode(segmentExtAddress, context).get(LISP_SEGMENT_ADDRESS); JsonNode asAddressJson = interpreter.encode(asExtAddress, context).get(LISP_AS_ADDRESS); JsonNode appDataAddressJson = interpreter.encode(appDataExtAddress, context).get(LISP_APPLICATION_DATA_ADDRESS); JsonNode gcAddressJson = interpreter.encode(gcExtAddress, context).get(LISP_GEO_COORDINATE_ADDRESS); JsonNode natAddressJson = interpreter.encode(natExtAddress, context).get(LISP_NAT_ADDRESS); JsonNode nonceAddressJson = interpreter.encode(nonceExtAddress, context).get(LISP_NONCE_ADDRESS); JsonNode multicastAddressJson = interpreter.encode(multicastExtAddress, context).get(LISP_MULTICAST_ADDRESS); JsonNode teAddressJson = interpreter.encode(teExtAddress, context).get(LISP_TRAFFIC_ENGINEERING_ADDRESS); JsonNode srcDstAddressJson = interpreter.encode(srcDstExtAddress, context).get(LISP_SOURCE_DEST_ADDRESS); MatcherAssert.assertThat("errors in encoding List address JSON", listAddressJson, LispListAddressCodecTest.LispListAddressJsonMatcher .matchesListAddress((LispListAddress) listExtAddress)); MatcherAssert.assertThat("errors in encoding Segment address JSON", segmentAddressJson, LispSegmentAddressCodecTest.LispSegmentAddressJsonMatcher .matchesSegmentAddress((LispSegmentAddress) segmentExtAddress)); MatcherAssert.assertThat("errors in encoding AS address JSON", asAddressJson, LispAsAddressCodecTest.LispAsAddressJsonMatcher .matchesAsAddress((LispAsAddress) asExtAddress)); MatcherAssert.assertThat("errors in encoding AppData address JSON", appDataAddressJson, LispAppDataAddressCodecTest.LispAppDataAddressJsonMatcher .matchesAppDataAddress((LispAppDataAddress) appDataExtAddress)); MatcherAssert.assertThat("errors in encoding GC address JSON", gcAddressJson, LispGcAddressCodecTest.LispGcAddressJsonMatcher .matchesGcAddress((LispGcAddress) gcExtAddress)); MatcherAssert.assertThat("errors in encoding NAT address JSON", natAddressJson, LispNatAddressCodecTest.LispNatAddressJsonMatcher .matchesNatAddress((LispNatAddress) natExtAddress)); MatcherAssert.assertThat("errors in encoding Nonce address JSON", nonceAddressJson, LispNonceAddressCodecTest.LispNonceAddressJsonMatcher .matchesNonceAddress((LispNonceAddress) nonceExtAddress)); MatcherAssert.assertThat("errors in encoding Multicast address JSON", multicastAddressJson, LispMulticastAddressCodecTest.LispMulticastAddressJsonMatcher .matchesMulticastAddress((LispMulticastAddress) multicastExtAddress)); MatcherAssert.assertThat("errors in encoding TE address JSON", teAddressJson, LispTeAddressCodecTest.LispTeAddressJsonMatcher .matchesTeAddress((LispTeAddress) teExtAddress)); MatcherAssert.assertThat("errors in encoding SrcDst address JSON", srcDstAddressJson, LispSrcDstAddressCodecTest.LispSrcDstAddressJsonMatcher .matchesSrcDstAddress((LispSrcDstAddress) srcDstExtAddress)); } /** * Tests decoding of an ExtensionMappingAddress JSON object. */ @Test public void testAddressDecode() throws IOException { List<ExtensionMappingAddress> addresses = getLispExtensionMappingAddresses("LispExtensionMappingAddress.json"); new EqualsTester() .addEqualityGroup(addresses.get(0), listExtAddress) .addEqualityGroup(addresses.get(1), segmentExtAddress) .addEqualityGroup(addresses.get(2), asExtAddress) .addEqualityGroup(addresses.get(3), appDataExtAddress) .addEqualityGroup(addresses.get(4), gcExtAddress) .addEqualityGroup(addresses.get(5), natExtAddress) .addEqualityGroup(addresses.get(6), nonceExtAddress) .addEqualityGroup(addresses.get(7), multicastExtAddress) .addEqualityGroup(addresses.get(8), teExtAddress) .addEqualityGroup(addresses.get(9), srcDstExtAddress) .testEquals(); } /** * Reads in a collection of LispExtensionMappingAddresses from the given resource and decodes it. * * @param resourceName resource to use to read the JSON for the rule * @return decoded LispExtensionMappingAddresses * @throws IOException if processing the resource fails */ private List<ExtensionMappingAddress> getLispExtensionMappingAddresses(String resourceName) throws IOException { InputStream jsonStream = LispExtensionMappingAddressInterpreterTest.class .getResourceAsStream(resourceName); JsonNode json = context.mapper().readTree(jsonStream); assertThat("JSON string should not be null", json, notNullValue()); final List<ExtensionMappingAddress> addresses = Lists.newArrayList(); for (int addrIndex = 0; addrIndex < json.size(); addrIndex++) { ExtensionMappingAddress address = interpreter.decode(json.get(addrIndex).deepCopy(), context); assertThat("decoded address should not be null", address, notNullValue()); addresses.add(address); } return addresses; } private LispLcafAddress getLcafMappingAddress(ExtensionMappingAddressType type) { LispLcafAddress address = null; LispAfiAddress ipv4Addr = new LispIpv4Address(IPV4_ADDRESS); LispAfiAddress ipv6Addr = new LispIpv6Address(IPV6_ADDRESS); if (type.equals(LIST_ADDRESS.type())) { address = new LispListLcafAddress(ImmutableList.of(ipv4Addr, ipv6Addr)); } if (type.equals(SEGMENT_ADDRESS.type())) { address = new LispSegmentLcafAddress.SegmentAddressBuilder() .withInstanceId(UNIQUE_INT) .withAddress(ipv4Addr) .build(); } if (type.equals(AS_ADDRESS.type())) { address = new LispAsLcafAddress.AsAddressBuilder() .withAsNumber(UNIQUE_INT) .withAddress(ipv4Addr) .build(); } if (type.equals(APPLICATION_DATA_ADDRESS.type())) { address = new LispAppDataLcafAddress.AppDataAddressBuilder() .withProtocol(UNIQUE_BYTE) .withIpTos(UNIQUE_INT) .withLocalPortLow(UNIQUE_SHORT) .withLocalPortHigh(UNIQUE_SHORT) .withRemotePortLow(UNIQUE_SHORT) .withRemotePortHigh(UNIQUE_SHORT) .withAddress(ipv4Addr) .build(); } if (type.equals(GEO_COORDINATE_ADDRESS.type())) { address = new LispGeoCoordinateLcafAddress.GeoCoordinateAddressBuilder() .withIsNorth(UNIQUE_BOOLEAN) .withLatitudeDegree(UNIQUE_SHORT) .withLatitudeMinute(UNIQUE_BYTE) .withLatitudeSecond(UNIQUE_BYTE) .withIsEast(UNIQUE_BOOLEAN) .withLongitudeDegree(UNIQUE_SHORT) .withLongitudeMinute(UNIQUE_BYTE) .withLongitudeSecond(UNIQUE_BYTE) .withAltitude(UNIQUE_INT) .withAddress(ipv4Addr) .build(); } if (type.equals(NAT_ADDRESS.type())) { address = new LispNatLcafAddress.NatAddressBuilder() .withMsUdpPortNumber(UNIQUE_SHORT) .withEtrUdpPortNumber(UNIQUE_SHORT) .withGlobalEtrRlocAddress(ipv4Addr) .withMsRlocAddress(ipv4Addr) .withPrivateEtrRlocAddress(ipv4Addr) .withRtrRlocAddresses(ImmutableList.of(ipv4Addr, ipv6Addr)) .build(); } if (type.equals(NONCE_ADDRESS.type())) { address = new LispNonceLcafAddress.NonceAddressBuilder() .withNonce(UNIQUE_INT) .withAddress(ipv4Addr) .build(); } if (type.equals(MULTICAST_ADDRESS.type())) { address = new LispMulticastLcafAddress.MulticastAddressBuilder() .withInstanceId(UNIQUE_INT) .withSrcMaskLength(UNIQUE_BYTE) .withSrcAddress(ipv4Addr) .withGrpMaskLength(UNIQUE_BYTE) .withGrpAddress(ipv4Addr) .build(); } if (type.equals(TRAFFIC_ENGINEERING_ADDRESS.type())) { LispTeRecord tr = new LispTeRecord.TeRecordBuilder() .withIsLookup(UNIQUE_BOOLEAN) .withIsRlocProbe(UNIQUE_BOOLEAN) .withIsStrict(UNIQUE_BOOLEAN) .withRtrRlocAddress(ipv4Addr) .build(); address = new LispTeLcafAddress.TeAddressBuilder() .withTeRecords(ImmutableList.of(tr)) .build(); } if (type.equals(SOURCE_DEST_ADDRESS.type())) { address = new LispSourceDestLcafAddress.SourceDestAddressBuilder() .withSrcMaskLength(UNIQUE_BYTE) .withSrcPrefix(ipv4Addr) .withDstMaskLength(UNIQUE_BYTE) .withDstPrefix(ipv4Addr) .build(); } return address; } private ExtensionMappingAddress getExtMappingAddress(ExtensionMappingAddressType type) { ExtensionMappingAddress address = null; MappingAddress ipv4Addr = MappingAddresses.ipv4MappingAddress(IPV4_PREFIX); MappingAddress ipv6Addr = MappingAddresses.ipv6MappingAddress(IPV6_PREFIX); if (type.equals(LIST_ADDRESS.type())) { address = new LispListAddress.Builder() .withIpv4(ipv4Addr) .withIpv6(ipv6Addr) .build(); } if (type.equals(SEGMENT_ADDRESS.type())) { address = new LispSegmentAddress.Builder() .withInstanceId(UNIQUE_INT) .withAddress(ipv4Addr) .build(); } if (type.equals(AS_ADDRESS.type())) { address = new LispAsAddress.Builder() .withAsNumber(UNIQUE_INT) .withAddress(ipv4Addr) .build(); } if (type.equals(APPLICATION_DATA_ADDRESS.type())) { address = new LispAppDataAddress.Builder() .withProtocol(UNIQUE_BYTE) .withIpTos(UNIQUE_INT) .withLocalPortLow(UNIQUE_SHORT) .withLocalPortHigh(UNIQUE_SHORT) .withRemotePortLow(UNIQUE_SHORT) .withRemotePortHigh(UNIQUE_SHORT) .withAddress(ipv4Addr) .build(); } if (type.equals(GEO_COORDINATE_ADDRESS.type())) { address = new LispGcAddress.Builder() .withIsNorth(UNIQUE_BOOLEAN) .withLatitudeDegree(UNIQUE_SHORT) .withLatitudeMinute(UNIQUE_BYTE) .withLatitudeSecond(UNIQUE_BYTE) .withIsEast(UNIQUE_BOOLEAN) .withLongitudeDegree(UNIQUE_SHORT) .withLongitudeMinute(UNIQUE_BYTE) .withLongitudeSecond(UNIQUE_BYTE) .withAltitude(UNIQUE_INT) .withAddress(ipv4Addr) .build(); } if (type.equals(NAT_ADDRESS.type())) { address = new LispNatAddress.Builder() .withMsUdpPortNumber(UNIQUE_SHORT) .withEtrUdpPortNumber(UNIQUE_SHORT) .withGlobalEtrRlocAddress(ipv4Addr) .withMsRlocAddress(ipv4Addr) .withPrivateEtrRlocAddress(ipv4Addr) .withRtrRlocAddresses(ImmutableList.of(ipv4Addr, ipv6Addr)) .build(); } if (type.equals(NONCE_ADDRESS.type())) { address = new LispNonceAddress.Builder() .withNonce(UNIQUE_INT) .withAddress(ipv4Addr) .build(); } if (type.equals(MULTICAST_ADDRESS.type())) { address = new LispMulticastAddress.Builder() .withInstanceId(UNIQUE_INT) .withSrcMaskLength(UNIQUE_BYTE) .withSrcAddress(ipv4Addr) .withGrpMaskLength(UNIQUE_BYTE) .withGrpAddress(ipv4Addr) .build(); } if (type.equals(TRAFFIC_ENGINEERING_ADDRESS.type())) { LispTeAddress.TeRecord tr = new LispTeAddress.TeRecord.Builder() .withIsLookup(UNIQUE_BOOLEAN) .withIsRlocProbe(UNIQUE_BOOLEAN) .withIsStrict(UNIQUE_BOOLEAN) .withRtrRlocAddress(ipv4Addr) .build(); address = new LispTeAddress.Builder() .withTeRecords(ImmutableList.of(tr)) .build(); } if (type.equals(SOURCE_DEST_ADDRESS.type())) { address = new LispSrcDstAddress.Builder() .withSrcMaskLength(UNIQUE_BYTE) .withSrcPrefix(ipv4Addr) .withDstMaskLength(UNIQUE_BYTE) .withDstPrefix(ipv4Addr) .build(); } return address; } }