diff options
5 files changed, 167 insertions, 0 deletions
diff --git a/nat/nat2vpp/pom.xml b/nat/nat2vpp/pom.xml index a136961aa..4cd4ab6e4 100644 --- a/nat/nat2vpp/pom.xml +++ b/nat/nat2vpp/pom.xml @@ -122,5 +122,11 @@ <artifactId>hamcrest-all</artifactId> <scope>test</scope> </dependency> + <dependency> + <groupId>io.fd.honeycomb.infra</groupId> + <artifactId>test-tools</artifactId> + <version>${project.version}</version> + <scope>test</scope> + </dependency> </dependencies> </project> diff --git a/nat/nat2vpp/src/main/java/io/fd/hc2vpp/nat/write/MappingEntryCustomizer.java b/nat/nat2vpp/src/main/java/io/fd/hc2vpp/nat/write/MappingEntryCustomizer.java index c5417d925..b2852fa4f 100644 --- a/nat/nat2vpp/src/main/java/io/fd/hc2vpp/nat/write/MappingEntryCustomizer.java +++ b/nat/nat2vpp/src/main/java/io/fd/hc2vpp/nat/write/MappingEntryCustomizer.java @@ -150,6 +150,7 @@ final class MappingEntryCustomizer implements ListWriterCustomizer<MappingEntry, request.localIpAddress = ipv4AddressNoZoneToArray(dataAfter.getInternalSrcAddress().getIpv4Address().getValue()); request.externalIpAddress = ipv4AddressNoZoneToArray(dataAfter.getExternalSrcAddress().getValue()); + request.externalSwIfIndex = -1; // external ip address is ignored if externalSwIfIndex is given Optional<Short> internalPortNumber = getPortNumber(id, dataAfter, (entry) -> Optional.fromNullable(entry.getInternalSrcPort()).transform(PortNumber::getPortType)); diff --git a/nat/nat2vpp/src/test/java/io/fd/hc2vpp/nat/NatTestSchemaContext.java b/nat/nat2vpp/src/test/java/io/fd/hc2vpp/nat/NatTestSchemaContext.java new file mode 100644 index 000000000..fea58dee9 --- /dev/null +++ b/nat/nat2vpp/src/test/java/io/fd/hc2vpp/nat/NatTestSchemaContext.java @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2017 Cisco and/or its affiliates. + * + * 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 io.fd.hc2vpp.nat; + +import com.google.common.collect.ImmutableSet; +import io.fd.honeycomb.test.tools.annotations.SchemaContextProvider; +import org.opendaylight.yangtools.sal.binding.generator.impl.ModuleInfoBackedContext; + +public interface NatTestSchemaContext { + + @SchemaContextProvider + default ModuleInfoBackedContext context() { + ModuleInfoBackedContext context = ModuleInfoBackedContext.create(); + context.addModuleInfos(ImmutableSet + .of(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.$YangModuleInfoImpl + .getInstance(), + org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.$YangModuleInfoImpl + .getInstance(), + org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.$YangModuleInfoImpl + .getInstance(), + org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.nat.rev150908.$YangModuleInfoImpl + .getInstance(), + org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang._interface.nat.rev161214.$YangModuleInfoImpl + .getInstance())); + return context; + } +} diff --git a/nat/nat2vpp/src/test/java/io/fd/hc2vpp/nat/write/MappingEntryCustomizerTest.java b/nat/nat2vpp/src/test/java/io/fd/hc2vpp/nat/write/MappingEntryCustomizerTest.java new file mode 100644 index 000000000..2627cba4d --- /dev/null +++ b/nat/nat2vpp/src/test/java/io/fd/hc2vpp/nat/write/MappingEntryCustomizerTest.java @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2017 Cisco and/or its affiliates. + * + * 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 io.fd.hc2vpp.nat.write; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import io.fd.hc2vpp.common.test.write.WriterCustomizerTest; +import io.fd.hc2vpp.nat.NatTestSchemaContext; +import io.fd.hc2vpp.nat.util.MappingEntryContext; +import io.fd.honeycomb.test.tools.HoneycombTestRunner; +import io.fd.honeycomb.test.tools.annotations.InjectTestData; +import io.fd.honeycomb.translate.write.WriteFailedException; +import io.fd.vpp.jvpp.snat.dto.SnatAddStaticMapping; +import io.fd.vpp.jvpp.snat.dto.SnatAddStaticMappingReply; +import io.fd.vpp.jvpp.snat.future.FutureJVppSnatFacade; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.nat.rev150908.NatConfig; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.nat.rev150908.nat.config.NatInstances; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.nat.rev150908.nat.config.nat.instances.NatInstance; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.nat.rev150908.nat.config.nat.instances.NatInstanceKey; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.nat.rev150908.nat.config.nat.instances.nat.instance.MappingTable; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.nat.rev150908.nat.config.nat.instances.nat.instance.mapping.table.MappingEntry; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.nat.rev150908.nat.config.nat.instances.nat.instance.mapping.table.MappingEntryKey; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +@RunWith(HoneycombTestRunner.class) +public class MappingEntryCustomizerTest extends WriterCustomizerTest implements NatTestSchemaContext { + + private static final long NAT_INSTANCE_ID = 1; + private static final long MAPPING_ID = 22; + private static final InstanceIdentifier<MappingEntry> IID = InstanceIdentifier.create(NatConfig.class) + .child(NatInstances.class).child(NatInstance.class, new NatInstanceKey(NAT_INSTANCE_ID)) + .child(MappingTable.class).child(MappingEntry.class, new MappingEntryKey(MAPPING_ID)); + + private static final String MAPPING_TABLE_PATH = "/ietf-nat:nat-config/ietf-nat:nat-instances/" + + "ietf-nat:nat-instance[ietf-nat:id='" + NAT_INSTANCE_ID + "']/ietf-nat:mapping-table"; + + @Mock + private FutureJVppSnatFacade jvppSnat; + @Mock + private MappingEntryContext mappingContext; + private MappingEntryCustomizer customizer; + + @Override + public void setUpTest() { + customizer = new MappingEntryCustomizer(jvppSnat, mappingContext); + when(jvppSnat.snatAddStaticMapping(any())).thenReturn(future(new SnatAddStaticMappingReply())); + } + + @Test + public void testWrite( + @InjectTestData(resourcePath = "/nat/static-mapping.json", id = MAPPING_TABLE_PATH) MappingTable data) + throws WriteFailedException { + customizer.writeCurrentAttributes(IID, extractMappingEntry(data), writeContext); + final SnatAddStaticMapping expectedRequest = getExpectedRequest(); + expectedRequest.isAdd = 1; + verify(jvppSnat).snatAddStaticMapping(expectedRequest); + } + + @Test(expected = WriteFailedException.UpdateFailedException.class) + public void testUpdate() throws WriteFailedException { + final MappingEntry data = mock(MappingEntry.class); + customizer.updateCurrentAttributes(IID, data, data, writeContext); + } + + @Test + public void testDelete( + @InjectTestData(resourcePath = "/nat/static-mapping.json", id = MAPPING_TABLE_PATH) MappingTable data) + throws WriteFailedException { + customizer.deleteCurrentAttributes(IID, extractMappingEntry(data), writeContext); + verify(jvppSnat).snatAddStaticMapping(getExpectedRequest()); + } + + private static MappingEntry extractMappingEntry(MappingTable data) { + // assumes single nat instance and single mapping entry + return data.getMappingEntry().get(0); + } + + private static SnatAddStaticMapping getExpectedRequest() { + final SnatAddStaticMapping expectedRequest = new SnatAddStaticMapping(); + expectedRequest.isIp4 = 1; + expectedRequest.addrOnly = 1; + expectedRequest.vrfId = (int) NAT_INSTANCE_ID; + expectedRequest.externalSwIfIndex = -1; + expectedRequest.localIpAddress = new byte[] {(byte) 192, (byte) 168, 1, 87}; + expectedRequest.externalIpAddress = new byte[] {45, 1, 5, 7}; + return expectedRequest; + } +}
\ No newline at end of file diff --git a/nat/nat2vpp/src/test/resources/nat/static-mapping.json b/nat/nat2vpp/src/test/resources/nat/static-mapping.json new file mode 100644 index 000000000..293e5be2b --- /dev/null +++ b/nat/nat2vpp/src/test/resources/nat/static-mapping.json @@ -0,0 +1,11 @@ +{ + "mapping-table" : { + "mapping-entry": { + "index": 22, + "type": "static", + "internal-src-address": "192.168.1.87", + "external-src-address": "45.1.5.7" + } + } +} + |