summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/InterfacesWriterFactory.java2
-rw-r--r--v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/ProxyArpCustomizer.java17
-rw-r--r--v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/InterfaceCustomizerTest.java116
-rw-r--r--v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/L2CustomizerTest.java150
-rw-r--r--v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/ProxyArpCustomizerTest.java63
-rw-r--r--v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/RoutingCustomizerTest.java98
-rw-r--r--v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/SubInterfaceAclCustomizerTest.java139
-rw-r--r--v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/SubInterfaceL2CustomizerTest.java109
-rw-r--r--v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/ip/Ipv4AddressCustomizerTest.java35
-rw-r--r--v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/ip/Ipv4NeighbourCustomizerTest.java112
-rw-r--r--v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/ip/SubInterfaceIpv4AddressCustomizerTest.java143
-rw-r--r--v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfacesstate/ip/Ipv4CustomizerTest.java44
12 files changed, 951 insertions, 77 deletions
diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/InterfacesWriterFactory.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/InterfacesWriterFactory.java
index 39e328a9e..baccf619f 100644
--- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/InterfacesWriterFactory.java
+++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/InterfacesWriterFactory.java
@@ -176,7 +176,7 @@ public final class InterfacesWriterFactory implements WriterFactory {
SubinterfaceAugmentationWriterFactory.SUB_IFC_ID);
// Proxy Arp (execute after specific interface customizers)
registry.addAfter(
- new GenericWriter<>(VPP_IFC_AUG_ID.child(ProxyArp.class), new ProxyArpCustomizer(jvpp, ifcNamingContext)),
+ new GenericWriter<>(VPP_IFC_AUG_ID.child(ProxyArp.class), new ProxyArpCustomizer(jvpp)),
specificIfcTypes);
// ACL (execute after classify table and session writers)
// also handles L2Acl, Ip4Acl and Ip6Acl:
diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/ProxyArpCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/ProxyArpCustomizer.java
index 002cc4c77..229902cdb 100644
--- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/ProxyArpCustomizer.java
+++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/ProxyArpCustomizer.java
@@ -20,7 +20,6 @@ import com.google.common.net.InetAddresses;
import io.fd.honeycomb.translate.spi.write.WriterCustomizer;
import io.fd.honeycomb.translate.v3po.util.FutureJVppCustomizer;
import io.fd.honeycomb.translate.v3po.util.JvppReplyConsumer;
-import io.fd.honeycomb.translate.v3po.util.NamingContext;
import io.fd.honeycomb.translate.write.WriteContext;
import io.fd.honeycomb.translate.write.WriteFailedException;
import java.net.InetAddress;
@@ -37,15 +36,12 @@ import org.openvpp.jvpp.core.future.FutureJVppCore;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-
public class ProxyArpCustomizer extends FutureJVppCustomizer implements WriterCustomizer<ProxyArp>, JvppReplyConsumer {
private static final Logger LOG = LoggerFactory.getLogger(ProxyArpCustomizer.class);
- private final NamingContext interfaceContext;
- public ProxyArpCustomizer(final FutureJVppCore vppApi, final NamingContext interfaceContext) {
+ public ProxyArpCustomizer(final FutureJVppCore vppApi) {
super(vppApi);
- this.interfaceContext = interfaceContext;
}
@Override
@@ -54,10 +50,10 @@ public class ProxyArpCustomizer extends FutureJVppCustomizer implements WriterCu
final String swIfName = id.firstKeyOf(Interface.class).getName();
try {
- setProxyArp(id, swIfName, dataAfter, writeContext, (byte) 1 /* 1 is add */);
+ setProxyArp(id, swIfName, dataAfter, (byte) 1 /* 1 is add */);
} catch (VppBaseCallException e) {
LOG.error("Failed to set Proxy ARP settings: {}, for interface: {}", dataAfter, swIfName);
- throw new WriteFailedException(id, dataAfter.toString(), e);
+ throw new WriteFailedException.CreateFailedException(id, dataAfter, e);
}
}
@@ -75,16 +71,15 @@ public class ProxyArpCustomizer extends FutureJVppCustomizer implements WriterCu
final String swIfName = id.firstKeyOf(Interface.class).getName();
try {
- setProxyArp(id, swIfName, dataBefore, writeContext, (byte) 0 /* 0 is delete */);
+ setProxyArp(id, swIfName, dataBefore, (byte) 0 /* 0 is delete */);
} catch (VppBaseCallException e) {
LOG.debug("Failed to delete Proxy ARP settings: {}, for interface: {}", dataBefore, swIfName);
throw new WriteFailedException.DeleteFailedException(id, e);
}
}
- private void setProxyArp(InstanceIdentifier<ProxyArp> id, String swIfName, ProxyArp proxyArp, WriteContext
- writeContext, byte operation) throws VppBaseCallException, WriteFailedException {
-
+ private void setProxyArp(InstanceIdentifier<ProxyArp> id, String swIfName, ProxyArp proxyArp, byte operation)
+ throws VppBaseCallException, WriteFailedException {
LOG.debug("Setting Proxy ARP settings for interface: {}", swIfName);
final InetAddress srcAddress = InetAddresses.forString(getv4AddressString(proxyArp.getLowAddr()));
final InetAddress dstAddress = InetAddresses.forString(getv4AddressString(proxyArp.getHighAddr()));
diff --git a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/InterfaceCustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/InterfaceCustomizerTest.java
new file mode 100644
index 000000000..fc3dd8379
--- /dev/null
+++ b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/InterfaceCustomizerTest.java
@@ -0,0 +1,116 @@
+/*
+ * Copyright (c) 2016 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.honeycomb.translate.v3po.interfaces;
+
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyZeroInteractions;
+import static org.mockito.Mockito.when;
+
+import io.fd.honeycomb.translate.v3po.util.ByteDataTranslator;
+import io.fd.honeycomb.translate.v3po.util.NamingContext;
+import io.fd.honeycomb.translate.write.WriteFailedException;
+import io.fd.honeycomb.vpp.test.write.WriterCustomizerTest;
+import org.junit.Test;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.Interfaces;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.openvpp.jvpp.VppBaseCallException;
+import org.openvpp.jvpp.core.dto.SwInterfaceSetFlags;
+import org.openvpp.jvpp.core.dto.SwInterfaceSetFlagsReply;
+
+public class InterfaceCustomizerTest extends WriterCustomizerTest implements ByteDataTranslator {
+ private static final String IFACE_CTX_NAME = "interface-ctx";
+ private static final String IF_NAME = "eth1";
+ private static final int IF_INDEX = 1;
+
+ private InterfaceCustomizer customizer;
+ private InstanceIdentifier<Interface> IID =
+ InstanceIdentifier.create(Interfaces.class).child(Interface.class, new InterfaceKey(IF_NAME));
+
+ @Override
+ protected void setUp() throws Exception {
+ customizer = new InterfaceCustomizer(api, new NamingContext("ifacePrefix", IFACE_CTX_NAME));
+ defineMapping(mappingContext, IF_NAME, IF_INDEX, IFACE_CTX_NAME);
+ }
+
+ @Test
+ public void testWrite() throws WriteFailedException {
+ final boolean enabled = true;
+ when(api.swInterfaceSetFlags(any())).thenReturn(future(new SwInterfaceSetFlagsReply()));
+ customizer.writeCurrentAttributes(IID, iface(enabled), writeContext);
+ verify(api).swInterfaceSetFlags(expectedRequest(enabled));
+ }
+
+ @Test
+ public void testWriteFailed() {
+ final boolean enabled = false;
+ when(api.swInterfaceSetFlags(any())).thenReturn(failedFuture());
+ try {
+ customizer.writeCurrentAttributes(IID, iface(enabled), writeContext);
+ } catch (WriteFailedException e) {
+ assertTrue(e.getCause() instanceof VppBaseCallException);
+ verify(api).swInterfaceSetFlags(expectedRequest(enabled));
+ return;
+ }
+ fail("WriteFailedException expected");
+ }
+
+ @Test
+ public void testUpdate() throws WriteFailedException {
+ when(api.swInterfaceSetFlags(any())).thenReturn(future(new SwInterfaceSetFlagsReply()));
+ customizer.updateCurrentAttributes(IID, iface(false), iface(true), writeContext);
+ verify(api).swInterfaceSetFlags(expectedRequest(true));
+ }
+
+ @Test
+ public void testUpdateFailed() {
+ when(api.swInterfaceSetFlags(any())).thenReturn(failedFuture());
+ try {
+ customizer.updateCurrentAttributes(IID, iface(false), iface(true), writeContext);
+ } catch (WriteFailedException e) {
+ assertTrue(e.getCause() instanceof VppBaseCallException);
+ verify(api).swInterfaceSetFlags(expectedRequest(true));
+ return;
+ }
+ fail("WriteFailedException expected");
+ }
+
+ @Test
+ public void testDelete() throws WriteFailedException {
+ customizer.deleteCurrentAttributes(IID, mock(Interface.class), writeContext);
+ verifyZeroInteractions(api);
+ }
+
+ private Interface iface(final boolean enabled) {
+ return new InterfaceBuilder().setName(IF_NAME).setEnabled(enabled).build();
+ }
+
+ private SwInterfaceSetFlags expectedRequest(final boolean enabled) {
+ final SwInterfaceSetFlags request = new SwInterfaceSetFlags();
+ request.deleted = 0;
+ request.adminUpDown = booleanToByte(enabled);
+ request.linkUpDown = booleanToByte(enabled);
+ request.swIfIndex = IF_INDEX;
+ return request;
+ }
+} \ No newline at end of file
diff --git a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/L2CustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/L2CustomizerTest.java
new file mode 100644
index 000000000..7f9ba1119
--- /dev/null
+++ b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/L2CustomizerTest.java
@@ -0,0 +1,150 @@
+/*
+ * Copyright (c) 2016 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.honeycomb.translate.v3po.interfaces;
+
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import io.fd.honeycomb.translate.v3po.util.ByteDataTranslator;
+import io.fd.honeycomb.translate.v3po.util.NamingContext;
+import io.fd.honeycomb.translate.write.WriteFailedException;
+import io.fd.honeycomb.vpp.test.write.WriterCustomizerTest;
+import org.junit.Test;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.Interfaces;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VppInterfaceAugmentation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces._interface.L2;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces._interface.L2Builder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.l2.base.attributes.Interconnection;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.l2.base.attributes.interconnection.BridgeBased;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.l2.base.attributes.interconnection.BridgeBasedBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.l2.base.attributes.interconnection.XconnectBased;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.l2.base.attributes.interconnection.XconnectBasedBuilder;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.openvpp.jvpp.VppBaseCallException;
+import org.openvpp.jvpp.core.dto.SwInterfaceSetL2Bridge;
+import org.openvpp.jvpp.core.dto.SwInterfaceSetL2BridgeReply;
+import org.openvpp.jvpp.core.dto.SwInterfaceSetL2Xconnect;
+import org.openvpp.jvpp.core.dto.SwInterfaceSetL2XconnectReply;
+
+public class L2CustomizerTest extends WriterCustomizerTest implements ByteDataTranslator {
+ private static final String IFACE_CTX_NAME = "interface-ctx";
+ private static final String BD_CTX_NAME = "bd-ctx";
+ private static final String IF1_NAME = "eth1";
+ private static final int IF1_INDEX = 1;
+ private static final String IF2_NAME = "eth2";
+ private static final int IF2_INDEX = 2;
+ private static final InstanceIdentifier<L2> IID =
+ InstanceIdentifier.create(Interfaces.class).child(Interface.class, new InterfaceKey(IF1_NAME))
+ .augmentation(VppInterfaceAugmentation.class).child(L2.class);
+ private static final String BD_NAME = "test_bd";
+ private static final int BD_INDEX = 13;
+
+ private L2Customizer customizer;
+
+ @Override
+ protected void setUp() throws Exception {
+ customizer = new L2Customizer(api, new NamingContext("ifacePrefix", IFACE_CTX_NAME),
+ new NamingContext("bdPrefix", BD_CTX_NAME));
+ defineMapping(mappingContext, IF1_NAME, IF1_INDEX, IFACE_CTX_NAME);
+ defineMapping(mappingContext, IF2_NAME, IF2_INDEX, IFACE_CTX_NAME);
+ defineMapping(mappingContext, BD_NAME, BD_INDEX, BD_CTX_NAME);
+ }
+
+ @Test
+ public void testWrite() throws WriteFailedException {
+ when(api.swInterfaceSetL2Xconnect(any())).thenReturn(future(new SwInterfaceSetL2XconnectReply()));
+ customizer.writeCurrentAttributes(IID, l2(xconnectBased()), writeContext);
+ verify(api).swInterfaceSetL2Xconnect(xconnectRequest(true));
+ }
+
+ @Test
+ public void testWriteFailed() {
+ when(api.swInterfaceSetL2Bridge(any())).thenReturn(failedFuture());
+ try {
+ customizer.writeCurrentAttributes(IID, l2(bridgeBased(false)), writeContext);
+ } catch (WriteFailedException e) {
+ assertTrue(e.getCause() instanceof VppBaseCallException);
+ verify(api).swInterfaceSetL2Bridge(bridgeRequest(false, true));
+ return;
+ }
+ fail("WriteFailedException expected");
+ }
+
+ @Test
+ public void testUpdate() throws WriteFailedException {
+ when(api.swInterfaceSetL2Bridge(any())).thenReturn(future(new SwInterfaceSetL2BridgeReply()));
+ customizer.updateCurrentAttributes(IID, l2(bridgeBased(false)), l2(bridgeBased(true)), writeContext);
+ verify(api).swInterfaceSetL2Bridge(bridgeRequest(true, true));
+ }
+
+ @Test
+ public void testDelete() throws WriteFailedException {
+ when(api.swInterfaceSetL2Xconnect(any())).thenReturn(future(new SwInterfaceSetL2XconnectReply()));
+ customizer.deleteCurrentAttributes(IID, l2(xconnectBased()), writeContext);
+ verify(api).swInterfaceSetL2Xconnect(xconnectRequest(false));
+ }
+
+ @Test
+ public void testDeleteFailed() {
+ when(api.swInterfaceSetL2Bridge(any())).thenReturn(failedFuture());
+ try {
+ customizer.deleteCurrentAttributes(IID, l2(bridgeBased(true)), writeContext);
+ } catch (WriteFailedException e) {
+ assertTrue(e.getCause() instanceof VppBaseCallException);
+ verify(api).swInterfaceSetL2Bridge(bridgeRequest(true, false));
+ return;
+ }
+ fail("WriteFailedException expected");
+ }
+
+ private XconnectBased xconnectBased() {
+ return new XconnectBasedBuilder().setXconnectOutgoingInterface(IF2_NAME).build();
+ }
+
+ private SwInterfaceSetL2Xconnect xconnectRequest(final boolean enable) {
+ final SwInterfaceSetL2Xconnect request = new SwInterfaceSetL2Xconnect();
+ request.rxSwIfIndex = IF1_INDEX;
+ request.txSwIfIndex = IF2_INDEX;
+ request.enable = booleanToByte(enable);
+ return request;
+ }
+
+ private BridgeBased bridgeBased(final boolean bvi) {
+ return new BridgeBasedBuilder().setBridgedVirtualInterface(bvi)
+ .setBridgeDomain(BD_NAME).setSplitHorizonGroup((short) 123).build();
+ }
+
+ private SwInterfaceSetL2Bridge bridgeRequest(final boolean bvi, final boolean enable) {
+ final SwInterfaceSetL2Bridge request = new SwInterfaceSetL2Bridge();
+ request.bdId = BD_INDEX;
+ request.rxSwIfIndex = IF1_INDEX;
+ request.bvi = booleanToByte(bvi);
+ request.enable = booleanToByte(enable);
+ request.shg = 123;
+ return request;
+ }
+
+
+ private L2 l2(final Interconnection interconnection) {
+ return new L2Builder().setInterconnection(interconnection).build();
+ }
+} \ No newline at end of file
diff --git a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/ProxyArpCustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/ProxyArpCustomizerTest.java
index caac8a37b..81561789d 100644
--- a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/ProxyArpCustomizerTest.java
+++ b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/ProxyArpCustomizerTest.java
@@ -16,33 +16,78 @@
package io.fd.honeycomb.translate.v3po.interfaces;
-import static org.mockito.Mockito.mock;
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
-import io.fd.honeycomb.vpp.test.write.WriterCustomizerTest;
-import io.fd.honeycomb.translate.v3po.util.NamingContext;
+import io.fd.honeycomb.translate.v3po.util.ByteDataTranslator;
import io.fd.honeycomb.translate.write.WriteFailedException;
+import io.fd.honeycomb.vpp.test.write.WriterCustomizerTest;
import org.junit.Test;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4AddressNoZone;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.Interfaces;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VppInterfaceAugmentation;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces._interface.ProxyArp;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces._interface.ProxyArpBuilder;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.openvpp.jvpp.core.dto.ProxyArpAddDel;
+import org.openvpp.jvpp.core.dto.ProxyArpAddDelReply;
-public class ProxyArpCustomizerTest extends WriterCustomizerTest {
+public class ProxyArpCustomizerTest extends WriterCustomizerTest implements ByteDataTranslator {
+ private static final String IF_NAME = "eth1";
private ProxyArpCustomizer customizer;
@Override
public void setUp() throws Exception {
- customizer = new ProxyArpCustomizer(api, new NamingContext("generatedSubInterfaceName", "test-instance"));
+ customizer = new ProxyArpCustomizer(api);
+ }
+
+ @Test
+ public void testWrite() throws WriteFailedException {
+ when(api.proxyArpAddDel(any())).thenReturn(future(new ProxyArpAddDelReply()));
+ customizer.writeCurrentAttributes(getProxyArpId(IF_NAME), proxyArp(), writeContext);
+ verify(api).proxyArpAddDel(expectedRequest(true));
+ }
+
+ @Test(expected = WriteFailedException.class)
+ public void testWriteFailed() throws WriteFailedException {
+ when(api.proxyArpAddDel(any())).thenReturn(failedFuture());
+ customizer.writeCurrentAttributes(getProxyArpId(IF_NAME), proxyArp(), writeContext);
}
@Test(expected = WriteFailedException.UpdateFailedException.class)
- public void testUpdate() throws Exception {
- final ProxyArp dataBefore = mock(ProxyArp.class);
- final ProxyArp dataAfter = mock(ProxyArp.class);
- customizer.updateCurrentAttributes(getProxyArpId("eth0"), dataBefore, dataAfter, writeContext);
+ public void testUpdate() throws WriteFailedException.UpdateFailedException {
+ customizer.updateCurrentAttributes(getProxyArpId(IF_NAME), proxyArp(), proxyArp(), writeContext);
+ }
+
+ @Test
+ public void testDelete() throws WriteFailedException {
+ when(api.proxyArpAddDel(any())).thenReturn(future(new ProxyArpAddDelReply()));
+ customizer.deleteCurrentAttributes(getProxyArpId(IF_NAME), proxyArp(), writeContext);
+ verify(api).proxyArpAddDel(expectedRequest(false));
+ }
+
+ @Test(expected = WriteFailedException.DeleteFailedException.class)
+ public void testDeleteFailed() throws WriteFailedException {
+ when(api.proxyArpAddDel(any())).thenReturn(failedFuture());
+ customizer.deleteCurrentAttributes(getProxyArpId(IF_NAME), proxyArp(), writeContext);
+ }
+
+ private ProxyArp proxyArp() {
+ return new ProxyArpBuilder().setVrfId(123L).setHighAddr(new Ipv4AddressNoZone("10.1.1.2"))
+ .setLowAddr(new Ipv4AddressNoZone("10.1.1.1")).build();
+ }
+
+ private ProxyArpAddDel expectedRequest(final boolean isAdd) {
+ final ProxyArpAddDel request = new ProxyArpAddDel();
+ request.isAdd = booleanToByte(isAdd);
+ request.vrfId = 123;
+ request.lowAddress = new byte[]{10,1,1,1};
+ request.hiAddress = new byte[]{10,1,1,2};
+ return request;
}
private InstanceIdentifier<ProxyArp> getProxyArpId(final String eth0) {
diff --git a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/RoutingCustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/RoutingCustomizerTest.java
new file mode 100644
index 000000000..d0db97f66
--- /dev/null
+++ b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/RoutingCustomizerTest.java
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2016 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.honeycomb.translate.v3po.interfaces;
+
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyZeroInteractions;
+import static org.mockito.Mockito.when;
+
+import io.fd.honeycomb.translate.v3po.util.NamingContext;
+import io.fd.honeycomb.translate.write.WriteFailedException;
+import io.fd.honeycomb.vpp.test.write.WriterCustomizerTest;
+import org.junit.Test;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.Interfaces;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VppInterfaceAugmentation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces._interface.Routing;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces._interface.RoutingBuilder;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.openvpp.jvpp.core.dto.SwInterfaceSetTable;
+import org.openvpp.jvpp.core.dto.SwInterfaceSetTableReply;
+
+public class RoutingCustomizerTest extends WriterCustomizerTest {
+ private static final String IFACE_CTX_NAME = "interface-ctx";
+ private static final String IF_NAME = "eth1";
+ private static final int IF_INDEX = 1;
+ private static final InstanceIdentifier<Routing> IID =
+ InstanceIdentifier.create(Interfaces.class).child(Interface.class, new InterfaceKey(IF_NAME))
+ .augmentation(VppInterfaceAugmentation.class).child(Routing.class);
+
+ private RoutingCustomizer customizer;
+
+ @Override
+ protected void setUp() throws Exception {
+ customizer = new RoutingCustomizer(api, new NamingContext("ifacePrefix", IFACE_CTX_NAME));
+ defineMapping(mappingContext, IF_NAME, IF_INDEX, IFACE_CTX_NAME);
+ }
+
+ @Test
+ public void testWrite() throws WriteFailedException {
+ final int vrfId = 123;
+ when(api.swInterfaceSetTable(any())).thenReturn(future(new SwInterfaceSetTableReply()));
+ customizer.writeCurrentAttributes(IID, routing(vrfId), writeContext);
+ verify(api).swInterfaceSetTable(expectedRequest(vrfId));
+ }
+
+ @Test(expected = WriteFailedException.CreateFailedException.class)
+ public void testWriteFailed() throws WriteFailedException {
+ when(api.swInterfaceSetTable(any())).thenReturn(failedFuture());
+ customizer.writeCurrentAttributes(IID, routing(213), writeContext);
+ }
+
+ @Test
+ public void testUpdate() throws WriteFailedException {
+ when(api.swInterfaceSetTable(any())).thenReturn(future(new SwInterfaceSetTableReply()));
+ customizer.updateCurrentAttributes(IID, routing(123L), null, writeContext);
+ verifyZeroInteractions(api);
+ }
+
+ @Test(expected = WriteFailedException.UpdateFailedException.class)
+ public void testUpdateFailed() throws WriteFailedException {
+ when(api.swInterfaceSetTable(any())).thenReturn(failedFuture());
+ customizer.updateCurrentAttributes(IID, routing(123L), routing(321L), writeContext);
+ }
+
+ @Test
+ public void testDelete() throws WriteFailedException {
+ customizer.deleteCurrentAttributes(IID, routing(123), writeContext);
+ verifyZeroInteractions(api);
+ }
+
+ private Routing routing(final long vrfId) {
+ return new RoutingBuilder().setVrfId(vrfId).build();
+ }
+
+ private SwInterfaceSetTable expectedRequest(final int vrfId) {
+ final SwInterfaceSetTable request = new SwInterfaceSetTable();
+ request.isIpv6 = 0;
+ request.swIfIndex = IF_INDEX;
+ request.vrfId = vrfId;
+ return request;
+ }
+} \ No newline at end of file
diff --git a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/SubInterfaceAclCustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/SubInterfaceAclCustomizerTest.java
new file mode 100644
index 000000000..779cdc6a3
--- /dev/null
+++ b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/SubInterfaceAclCustomizerTest.java
@@ -0,0 +1,139 @@
+/*
+ * Copyright (c) 2016 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.honeycomb.translate.v3po.interfaces;
+
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import io.fd.honeycomb.translate.v3po.util.NamingContext;
+import io.fd.honeycomb.translate.v3po.vppclassifier.VppClassifierContextManager;
+import io.fd.honeycomb.translate.write.WriteFailedException;
+import io.fd.honeycomb.vpp.test.write.WriterCustomizerTest;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.Interfaces;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.acl.base.attributes.Ip4Acl;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.acl.base.attributes.Ip4AclBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.acl.base.attributes.Ip6Acl;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.acl.base.attributes.Ip6AclBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev150527.SubinterfaceAugmentation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev150527.interfaces._interface.SubInterfaces;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev150527.interfaces._interface.sub.interfaces.SubInterface;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev150527.interfaces._interface.sub.interfaces.SubInterfaceKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev150527.sub._interface.base.attributes.Acl;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev150527.sub._interface.base.attributes.AclBuilder;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.openvpp.jvpp.core.dto.InputAclSetInterface;
+import org.openvpp.jvpp.core.dto.InputAclSetInterfaceReply;
+
+public class SubInterfaceAclCustomizerTest extends WriterCustomizerTest {
+ private static final String IFC_TEST_INSTANCE = "ifc-test-instance";
+ private static final String IF_NAME = "local0";
+ private static final int IF_INDEX = 1;
+ private static final String SUBIF_NAME = "local0.0";
+ private static final int SUBIF_INDEX = 11;
+ private static final long SUBIF_ID = 0;
+ private static final String TABLE_NAME = "table0";
+ private static final int TABLE_INDEX = 123;
+
+ private static final InstanceIdentifier<Acl> IID =
+ InstanceIdentifier.create(Interfaces.class).child(Interface.class, new InterfaceKey(IF_NAME)).augmentation(
+ SubinterfaceAugmentation.class).child(SubInterfaces.class)
+ .child(SubInterface.class, new SubInterfaceKey(SUBIF_ID)).child(Acl.class);
+
+ @Mock
+ private VppClassifierContextManager classifyTableContext;
+
+ private SubInterfaceAclCustomizer customizer;
+
+ @Override
+ protected void setUp() throws Exception {
+ customizer = new SubInterfaceAclCustomizer(api, new NamingContext("prefix", IFC_TEST_INSTANCE),
+ classifyTableContext);
+ defineMapping(mappingContext, IF_NAME, IF_INDEX, IFC_TEST_INSTANCE);
+ defineMapping(mappingContext, SUBIF_NAME, SUBIF_INDEX, IFC_TEST_INSTANCE);
+ when(classifyTableContext.getTableIndex(TABLE_NAME, mappingContext)).thenReturn(TABLE_INDEX);
+ }
+
+ @Test
+ public void testCreate() throws WriteFailedException {
+ when(api.inputAclSetInterface(any())).thenReturn(future(new InputAclSetInterfaceReply()));
+ customizer.writeCurrentAttributes(IID, ip4Acl(), writeContext);
+ verify(api).inputAclSetInterface(expectedIp4AclRequest());
+ }
+
+ @Test(expected = WriteFailedException.CreateFailedException.class)
+ public void testCreateFailed() throws WriteFailedException {
+ when(api.inputAclSetInterface(any())).thenReturn(failedFuture());
+ customizer.writeCurrentAttributes(IID, ip4Acl(), writeContext);
+ }
+
+ @Test(expected = UnsupportedOperationException.class)
+ public void testUpdate() throws WriteFailedException {
+ customizer.updateCurrentAttributes(IID, ip4Acl(), ip6Acl(), writeContext);
+ }
+
+ @Test
+ public void testDelete() throws Exception {
+ when(api.inputAclSetInterface(any())).thenReturn(future(new InputAclSetInterfaceReply()));
+ customizer.deleteCurrentAttributes(IID, ip6Acl(), writeContext);
+ verify(api).inputAclSetInterface(expectedIp6AclRequest());
+ }
+
+ @Test(expected = WriteFailedException.DeleteFailedException.class)
+ public void testDeleteFailed() throws WriteFailedException {
+ when(api.inputAclSetInterface(any())).thenReturn(failedFuture());
+ customizer.deleteCurrentAttributes(IID, ip4Acl(), writeContext);
+ }
+
+ private Acl ip4Acl() {
+ final AclBuilder builder = new AclBuilder();
+ final Ip4Acl acl = new Ip4AclBuilder().setClassifyTable(TABLE_NAME).build();
+ builder.setIp4Acl(acl);
+ return builder.build();
+ }
+
+ private InputAclSetInterface expectedIp4AclRequest() {
+ final InputAclSetInterface request = new InputAclSetInterface();
+ request.isAdd = 1;
+ request.l2TableIndex = -1;
+ request.ip4TableIndex = TABLE_INDEX;
+ request.ip6TableIndex = -1;
+ request.swIfIndex = SUBIF_INDEX;
+ return request;
+ }
+
+ private Acl ip6Acl() {
+ final AclBuilder builder = new AclBuilder();
+ final Ip6Acl acl = new Ip6AclBuilder().setClassifyTable(TABLE_NAME).build();
+ builder.setIp6Acl(acl);
+ return builder.build();
+ }
+
+ private InputAclSetInterface expectedIp6AclRequest() {
+ final InputAclSetInterface request = new InputAclSetInterface();
+ request.isAdd = 0;
+ request.l2TableIndex = -1;
+ request.ip4TableIndex = -1;
+ request.ip6TableIndex = TABLE_INDEX;
+ request.swIfIndex = SUBIF_INDEX;
+ return request;
+ }
+} \ No newline at end of file
diff --git a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/SubInterfaceL2CustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/SubInterfaceL2CustomizerTest.java
new file mode 100644
index 000000000..0fa380e6b
--- /dev/null
+++ b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/SubInterfaceL2CustomizerTest.java
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 2016 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.honeycomb.translate.v3po.interfaces;
+
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import io.fd.honeycomb.translate.v3po.util.ByteDataTranslator;
+import io.fd.honeycomb.translate.v3po.util.NamingContext;
+import io.fd.honeycomb.translate.write.WriteFailedException;
+import io.fd.honeycomb.vpp.test.write.WriterCustomizerTest;
+import org.junit.Test;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.Interfaces;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.l2.base.attributes.interconnection.BridgeBasedBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev150527.SubinterfaceAugmentation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev150527.interfaces._interface.SubInterfaces;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev150527.interfaces._interface.sub.interfaces.SubInterface;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev150527.interfaces._interface.sub.interfaces.SubInterfaceKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev150527.sub._interface.base.attributes.L2;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev150527.sub._interface.base.attributes.L2Builder;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.openvpp.jvpp.core.dto.SwInterfaceSetL2Bridge;
+import org.openvpp.jvpp.core.dto.SwInterfaceSetL2BridgeReply;
+
+public class SubInterfaceL2CustomizerTest extends WriterCustomizerTest implements ByteDataTranslator {
+ private static final String IFACE_CTX_NAME = "interface-ctx";
+ private static final String IF_NAME = "local0";
+ private static final int IF_INDEX = 1;
+ private static final String SUBIF_NAME = "local0.0";
+ private static final int SUBIF_INDEX = 11;
+ private static final long SUBIF_ID = 0;
+
+ private static final InstanceIdentifier<L2> IID =
+ InstanceIdentifier.create(Interfaces.class).child(Interface.class, new InterfaceKey(IF_NAME)).augmentation(
+ SubinterfaceAugmentation.class).child(SubInterfaces.class)
+ .child(SubInterface.class, new SubInterfaceKey(SUBIF_ID)).child(L2.class);
+
+
+ private static final String BD_CTX_NAME = "bd-ctx";
+ private static final String BD_NAME = "test_bd";
+ private static final int BD_INDEX = 13;
+
+ private SubInterfaceL2Customizer customizer;
+
+ @Override
+ protected void setUp() throws Exception {
+ customizer = new SubInterfaceL2Customizer(api, new NamingContext("ifacePrefix", IFACE_CTX_NAME),
+ new NamingContext("bdPrefix", BD_CTX_NAME));
+ defineMapping(mappingContext, IF_NAME, IF_INDEX, IFACE_CTX_NAME);
+ defineMapping(mappingContext, SUBIF_NAME, SUBIF_INDEX, IFACE_CTX_NAME);
+ defineMapping(mappingContext, BD_NAME, BD_INDEX, BD_CTX_NAME);
+ }
+
+ @Test
+ public void testWrite() throws WriteFailedException {
+ final boolean bvi = true;
+ when(api.swInterfaceSetL2Bridge(any())).thenReturn(future(new SwInterfaceSetL2BridgeReply()));
+ customizer.writeCurrentAttributes(IID, l2(bvi), writeContext);
+ verify(api).swInterfaceSetL2Bridge(bridgeRequest(bvi, true));
+ }
+
+ @Test
+ public void testUpdate() throws WriteFailedException {
+ final boolean bvi = false;
+ when(api.swInterfaceSetL2Bridge(any())).thenReturn(future(new SwInterfaceSetL2BridgeReply()));
+ customizer.updateCurrentAttributes(IID, l2(true), l2(bvi), writeContext);
+ verify(api).swInterfaceSetL2Bridge(bridgeRequest(bvi, true));
+ }
+
+ @Test
+ public void testDelete() throws WriteFailedException {
+ final boolean bvi = true;
+ when(api.swInterfaceSetL2Bridge(any())).thenReturn(future(new SwInterfaceSetL2BridgeReply()));
+ customizer.deleteCurrentAttributes(IID, l2(bvi), writeContext);
+ verify(api).swInterfaceSetL2Bridge(bridgeRequest(bvi, false));
+ }
+
+ private L2 l2(final boolean bvi) {
+ return new L2Builder().setInterconnection(new BridgeBasedBuilder().setBridgedVirtualInterface(bvi)
+ .setBridgeDomain(BD_NAME).setSplitHorizonGroup((short) 123).build()).build();
+ }
+
+ private SwInterfaceSetL2Bridge bridgeRequest(final boolean bvi, final boolean enable) {
+ final SwInterfaceSetL2Bridge request = new SwInterfaceSetL2Bridge();
+ request.bdId = BD_INDEX;
+ request.rxSwIfIndex = SUBIF_INDEX;
+ request.bvi = booleanToByte(bvi);
+ request.enable = booleanToByte(enable);
+ request.shg = 123;
+ return request;
+ }
+} \ No newline at end of file
diff --git a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/ip/Ipv4AddressCustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/ip/Ipv4AddressCustomizerTest.java
index 56430cd46..e3857b9b1 100644
--- a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/ip/Ipv4AddressCustomizerTest.java
+++ b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/ip/Ipv4AddressCustomizerTest.java
@@ -23,6 +23,7 @@ import static org.mockito.Matchers.argThat;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.doThrow;
+import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -189,6 +190,12 @@ public class Ipv4AddressCustomizerTest extends WriterCustomizerTest {
};
}
+ @Test(expected = WriteFailedException.UpdateFailedException.class)
+ public void testUpdate() throws Exception {
+ final Address data = mock(Address.class);
+ customizer.updateCurrentAttributes(getAddressId(IFACE_NAME), data, data, writeContext);
+ }
+
private SwInterfaceAddDelAddress generateSwInterfaceAddDelAddressRequest(final byte[] address, final byte isAdd,
final byte prefixLength) {
final SwInterfaceAddDelAddress request = new SwInterfaceAddDelAddress();
@@ -241,6 +248,32 @@ public class Ipv4AddressCustomizerTest extends WriterCustomizerTest {
fail("WriteFailedException was expec16ted");
}
+ @Test
+ public void testNetmaskFailed() {
+ final int expectedPrefixLength = 1;
+ final String stringMask = "128.0.0.0";
+ final InstanceIdentifier<Address> id = getAddressId(IFACE_NAME);
+ when(writeContext.readBefore(id)).thenReturn(Optional.absent());
+
+ Ipv4AddressNoZone noZoneIp = new Ipv4AddressNoZone(new Ipv4Address("192.168.2.1"));
+ Netmask subnet = new NetmaskBuilder().setNetmask(new DottedQuad(stringMask)).build();
+ Address data = new AddressBuilder().setIp(noZoneIp).setSubnet(subnet).build();
+
+ defineMapping(mappingContext, IFACE_NAME, IFACE_ID, IFC_CTX_NAME);
+ whenSwInterfaceAddDelAddressThenFailure();
+
+ try {
+ customizer.writeCurrentAttributes(id, data, writeContext);
+ } catch (WriteFailedException e) {
+ assertTrue(e.getCause() instanceof VppBaseCallException);
+ verify(api).swInterfaceAddDelAddress(generateSwInterfaceAddDelAddressRequest(new byte[]{-64, -88, 2, 1},
+ (byte) 1, (byte) expectedPrefixLength));
+ return;
+ }
+ fail("WriteFailedException was expec16ted");
+
+ }
+
private void testSingleNetmask(final int expectedPrefixLength, final String stringMask) throws Exception {
final InstanceIdentifier<Address> id = getAddressId(IFACE_NAME);
when(writeContext.readBefore(id)).thenReturn(Optional.absent());
@@ -255,7 +288,7 @@ public class Ipv4AddressCustomizerTest extends WriterCustomizerTest {
customizer.writeCurrentAttributes(id, data, writeContext);
verify(api).swInterfaceAddDelAddress(generateSwInterfaceAddDelAddressRequest(new byte[]{-64, -88, 2, 1},
- (byte) 1, (byte) expectedPrefixLength));
+ (byte) 1, (byte) expectedPrefixLength));
}
private void testSingleIllegalNetmask(final String stringMask) throws Exception {
diff --git a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/ip/Ipv4NeighbourCustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/ip/Ipv4NeighbourCustomizerTest.java
index e9acdbe88..a3fff0858 100644
--- a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/ip/Ipv4NeighbourCustomizerTest.java
+++ b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/ip/Ipv4NeighbourCustomizerTest.java
@@ -16,20 +16,16 @@
package io.fd.honeycomb.translate.v3po.interfaces.ip;
-import static org.junit.Assert.assertEquals;
+import static junit.framework.TestCase.assertTrue;
+import static org.junit.Assert.fail;
import static org.mockito.Matchers.any;
-import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
-
-import com.google.common.io.BaseEncoding;
import io.fd.honeycomb.translate.v3po.util.Ipv4Translator;
import io.fd.honeycomb.translate.v3po.util.NamingContext;
import io.fd.honeycomb.translate.write.WriteFailedException;
import io.fd.honeycomb.vpp.test.write.WriterCustomizerTest;
-import org.junit.Before;
import org.junit.Test;
-import org.mockito.ArgumentCaptor;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4AddressNoZone;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.Interfaces;
@@ -41,6 +37,7 @@ import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev14061
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.ipv4.NeighborBuilder;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.PhysAddress;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.openvpp.jvpp.VppBaseCallException;
import org.openvpp.jvpp.core.dto.IpNeighborAddDel;
import org.openvpp.jvpp.core.dto.IpNeighborAddDelReply;
@@ -49,70 +46,75 @@ public class Ipv4NeighbourCustomizerTest extends WriterCustomizerTest implements
private static final String IFC_CTX_NAME = "ifc-test-instance";
private static final String IFACE_NAME = "parent";
private static final int IFACE_ID = 5;
+ private static final InstanceIdentifier<Neighbor> IID =
+ InstanceIdentifier.create(Interfaces.class).child(Interface.class, new InterfaceKey(IFACE_NAME))
+ .augmentation(Interface1.class).child(Ipv4.class).child(Neighbor.class);
- private ArgumentCaptor<IpNeighborAddDel> requestCaptor;
private Ipv4NeighbourCustomizer customizer;
- @Before
- public void init() {
+ @Override
+ public void setUp() {
defineMapping(mappingContext, IFACE_NAME, IFACE_ID, IFC_CTX_NAME);
customizer = new Ipv4NeighbourCustomizer(api, new NamingContext("prefix", IFC_CTX_NAME));
-
- requestCaptor = ArgumentCaptor.forClass(IpNeighborAddDel.class);
- when(api.ipNeighborAddDel(any())).thenReturn(future(new IpNeighborAddDelReply()));
}
@Test
public void testWriteCurrentAttributes() throws WriteFailedException {
+ when(api.ipNeighborAddDel(any())).thenReturn(future(new IpNeighborAddDelReply()));
+ customizer.writeCurrentAttributes(IID, getData(), writeContext);
+ verify(api).ipNeighborAddDel(getExpectedRequest(true));
+ }
- InterfaceKey intfKey = new InterfaceKey(IFACE_NAME);
-
- InstanceIdentifier<Neighbor> id = InstanceIdentifier.builder(Interfaces.class).child(Interface.class, intfKey)
- .augmentation(Interface1.class).child(Ipv4.class).child(Neighbor.class).build();
-
- Ipv4AddressNoZone noZoneIp = new Ipv4AddressNoZone(new Ipv4Address("192.168.2.1"));
- PhysAddress mac = new PhysAddress("aa:bb:cc:ee:11:22");
-
- Neighbor data = new NeighborBuilder().setIp(noZoneIp).setLinkLayerAddress(mac).build();
-
- customizer.writeCurrentAttributes(id, data, writeContext);
-
- verify(api, times(1)).ipNeighborAddDel(requestCaptor.capture());
-
- IpNeighborAddDel request = requestCaptor.getValue();
-
- assertEquals(0, request.isIpv6);
- assertEquals(1, request.isAdd);
- assertEquals(1, request.isStatic);
- assertEquals("1.2.168.192", arrayToIpv4AddressNoZone(request.dstAddress).getValue());
- assertEquals("aabbccee1122", BaseEncoding.base16().lowerCase().encode(request.macAddress));
- assertEquals(5, request.swIfIndex);
+ @Test
+ public void testWriteCurrentAttributesFailed() {
+ when(api.ipNeighborAddDel(any())).thenReturn(failedFuture());
+ try {
+ customizer.writeCurrentAttributes(IID, getData(), writeContext);
+ } catch (WriteFailedException e) {
+ assertTrue(e.getCause() instanceof VppBaseCallException);
+ verify(api).ipNeighborAddDel(getExpectedRequest(true));
+ return;
+ }
+ fail("WriteFailedException expected");
+ }
+ @Test(expected = UnsupportedOperationException.class)
+ public void testUpdateCurrentAttributes() throws WriteFailedException {
+ customizer.updateCurrentAttributes(IID, getData(), getData(), writeContext);
}
@Test
public void testDeleteCurrentAttributes() throws WriteFailedException {
- InterfaceKey intfKey = new InterfaceKey(IFACE_NAME);
-
- InstanceIdentifier<Neighbor> id = InstanceIdentifier.builder(Interfaces.class).child(Interface.class, intfKey)
- .augmentation(Interface1.class).child(Ipv4.class).child(Neighbor.class).build();
-
- Ipv4AddressNoZone noZoneIp = new Ipv4AddressNoZone(new Ipv4Address("192.168.2.1"));
- PhysAddress mac = new PhysAddress("aa:bb:cc:ee:11:22");
-
- Neighbor data = new NeighborBuilder().setIp(noZoneIp).setLinkLayerAddress(mac).build();
-
- customizer.deleteCurrentAttributes(id, data, writeContext);
-
- verify(api, times(1)).ipNeighborAddDel(requestCaptor.capture());
-
- IpNeighborAddDel request = requestCaptor.getValue();
+ when(api.ipNeighborAddDel(any())).thenReturn(future(new IpNeighborAddDelReply()));
+ customizer.deleteCurrentAttributes(IID, getData(), writeContext);
+ verify(api).ipNeighborAddDel(getExpectedRequest(false));
+ }
- assertEquals(0, request.isIpv6);
- assertEquals(0, request.isAdd);
- assertEquals(1, request.isStatic);
- assertEquals("1.2.168.192", arrayToIpv4AddressNoZone(request.dstAddress).getValue());
- assertEquals("aabbccee1122", BaseEncoding.base16().lowerCase().encode(request.macAddress));
- assertEquals(5, request.swIfIndex);
+ @Test
+ public void testDeleteCurrentAttributesFailed() {
+ when(api.ipNeighborAddDel(any())).thenReturn(failedFuture());
+ try {
+ customizer.deleteCurrentAttributes(IID, getData(), writeContext);
+ } catch (WriteFailedException e) {
+ assertTrue(e.getCause() instanceof VppBaseCallException);
+ verify(api).ipNeighborAddDel(getExpectedRequest(false));
+ return;
+ }
+ fail("WriteFailedException expected");
}
+ private Neighbor getData() {
+ final Ipv4AddressNoZone noZoneIp = new Ipv4AddressNoZone(new Ipv4Address("192.168.2.1"));
+ final PhysAddress mac = new PhysAddress("aa:bb:cc:ee:11:22");
+ return new NeighborBuilder().setIp(noZoneIp).setLinkLayerAddress(mac).build();
+ }
+ private IpNeighborAddDel getExpectedRequest(final boolean isAdd) {
+ final IpNeighborAddDel request = new IpNeighborAddDel();
+ request.isIpv6 = 0;
+ request.isAdd = booleanToByte(isAdd);
+ request.isStatic = 1;
+ request.dstAddress = new byte[] {(byte) 192, (byte) 168, 2, 1};
+ request.macAddress = new byte[] {(byte) 0xaa, (byte) 0xbb, (byte) 0xcc, (byte) 0xee, 0x11, 0x22};
+ request.swIfIndex = IFACE_ID;
+ return request;
+ }
} \ No newline at end of file
diff --git a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/ip/SubInterfaceIpv4AddressCustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/ip/SubInterfaceIpv4AddressCustomizerTest.java
new file mode 100644
index 000000000..b5cb009ed
--- /dev/null
+++ b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfaces/ip/SubInterfaceIpv4AddressCustomizerTest.java
@@ -0,0 +1,143 @@
+/*
+ * Copyright (c) 2016 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.honeycomb.translate.v3po.interfaces.ip;
+
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import io.fd.honeycomb.translate.v3po.util.ByteDataTranslator;
+import io.fd.honeycomb.translate.v3po.util.NamingContext;
+import io.fd.honeycomb.translate.write.WriteFailedException;
+import io.fd.honeycomb.vpp.test.write.WriterCustomizerTest;
+import org.junit.Test;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4AddressNoZone;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.Interfaces;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.DottedQuad;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev150527.SubinterfaceAugmentation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev150527.interfaces._interface.SubInterfaces;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev150527.interfaces._interface.sub.interfaces.SubInterface;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev150527.interfaces._interface.sub.interfaces.SubInterfaceKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev150527.sub._interface.ip4.attributes.Ipv4;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev150527.sub._interface.ip4.attributes.ipv4.Address;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev150527.sub._interface.ip4.attributes.ipv4.AddressBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev150527.sub._interface.ip4.attributes.ipv4.address.Subnet;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev150527.sub._interface.ip4.attributes.ipv4.address.subnet.Netmask;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev150527.sub._interface.ip4.attributes.ipv4.address.subnet.NetmaskBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev150527.sub._interface.ip4.attributes.ipv4.address.subnet.PrefixLength;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev150527.sub._interface.ip4.attributes.ipv4.address.subnet.PrefixLengthBuilder;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.openvpp.jvpp.VppBaseCallException;
+import org.openvpp.jvpp.core.dto.SwInterfaceAddDelAddress;
+import org.openvpp.jvpp.core.dto.SwInterfaceAddDelAddressReply;
+
+public class SubInterfaceIpv4AddressCustomizerTest extends WriterCustomizerTest implements ByteDataTranslator {
+
+ private static final String IFC_CTX_NAME = "ifc-test-instance";
+ private static final String IFACE_NAME = "eth0";
+ private static final int IFACE_INDEX = 0;
+ private static final String SUBIF_NAME = "eth0.1";
+ private static final long SUBIF_ID = 1;
+ private static final int SUBIF_INDEX = 123;
+ private static final InstanceIdentifier<Address> IID =
+ InstanceIdentifier.create(Interfaces.class).child(Interface.class, new InterfaceKey(IFACE_NAME))
+ .augmentation(SubinterfaceAugmentation.class).child(SubInterfaces.class)
+ .child(SubInterface.class, new SubInterfaceKey(SUBIF_ID)).child(Ipv4.class).child(Address.class);
+
+ private SubInterfaceIpv4AddressCustomizer customizer;
+
+ @Override
+ protected void setUp() {
+ customizer = new SubInterfaceIpv4AddressCustomizer(api, new NamingContext("prefix", IFC_CTX_NAME));
+ defineMapping(mappingContext, IFACE_NAME, IFACE_INDEX, IFC_CTX_NAME);
+ defineMapping(mappingContext, SUBIF_NAME, SUBIF_INDEX, IFC_CTX_NAME);
+ }
+
+ @Test
+ public void testWrite() throws WriteFailedException {
+ when(api.swInterfaceAddDelAddress(any())).thenReturn(future(new SwInterfaceAddDelAddressReply()));
+ customizer.writeCurrentAttributes(IID, address(prefixLength()), writeContext);
+ verify(api).swInterfaceAddDelAddress(expectedRequest(true));
+ }
+
+ @Test
+ public void testWriteFailed() {
+ when(api.swInterfaceAddDelAddress(any())).thenReturn(failedFuture());
+ try {
+ customizer.writeCurrentAttributes(IID, address(prefixLength()), writeContext);
+ } catch (WriteFailedException e) {
+ assertTrue(e.getCause() instanceof VppBaseCallException);
+ verify(api).swInterfaceAddDelAddress(expectedRequest(true));
+ return;
+ }
+ fail("WriteFailedException expected");
+ }
+
+ @Test
+ public void testDelete() throws WriteFailedException {
+ when(api.swInterfaceAddDelAddress(any())).thenReturn(future(new SwInterfaceAddDelAddressReply()));
+ customizer.deleteCurrentAttributes(IID, address(netmask()), writeContext);
+ verify(api).swInterfaceAddDelAddress(expectedRequest(false));
+ }
+
+ @Test
+ public void testDeleteFailed() {
+ when(api.swInterfaceAddDelAddress(any())).thenReturn(failedFuture());
+ try {
+ customizer.deleteCurrentAttributes(IID, address(netmask()), writeContext);
+ } catch (WriteFailedException e) {
+ assertTrue(e.getCause() instanceof VppBaseCallException);
+ verify(api).swInterfaceAddDelAddress(expectedRequest(false));
+ return;
+ }
+ fail("WriteFailedException expected");
+ }
+
+ private SwInterfaceAddDelAddress expectedRequest(boolean isAdd) {
+ final SwInterfaceAddDelAddress request = new SwInterfaceAddDelAddress();
+ request.isAdd = booleanToByte(isAdd);
+ request.swIfIndex = SUBIF_INDEX;
+ request.isIpv6 = 0;
+ request.delAll = 0;
+ request.addressLength = 24;
+ request.address = new byte[] {(byte) 192, (byte) 168, 2, 1};
+ return request;
+ }
+
+ @Test(expected = WriteFailedException.UpdateFailedException.class)
+ public void testUpdate() throws Exception {
+ final Address address = address(prefixLength());
+ customizer.updateCurrentAttributes(IID, address, address, writeContext);
+ }
+
+ private Address address(final Subnet subnet) {
+ final Ipv4AddressNoZone noZoneIp = new Ipv4AddressNoZone(new Ipv4Address("192.168.2.1"));
+ return new AddressBuilder().setIp(noZoneIp).setSubnet(subnet).build();
+ }
+
+ private PrefixLength prefixLength() {
+ return new PrefixLengthBuilder().setPrefixLength(new Integer(24).shortValue()).build();
+ }
+
+ private Netmask netmask() {
+ return new NetmaskBuilder().setNetmask(new DottedQuad("255.255.255.0")).build();
+ }
+} \ No newline at end of file
diff --git a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfacesstate/ip/Ipv4CustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfacesstate/ip/Ipv4CustomizerTest.java
new file mode 100644
index 000000000..f536a37eb
--- /dev/null
+++ b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/translate/v3po/interfacesstate/ip/Ipv4CustomizerTest.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2016 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.honeycomb.translate.v3po.interfacesstate.ip;
+
+import static org.mockito.Mockito.verifyZeroInteractions;
+
+import io.fd.honeycomb.translate.spi.read.ReaderCustomizer;
+import io.fd.honeycomb.vpp.test.read.ReaderCustomizerTest;
+import org.junit.Test;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.Interface2Builder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces.state._interface.Ipv4;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces.state._interface.Ipv4Builder;
+
+public class Ipv4CustomizerTest extends ReaderCustomizerTest<Ipv4, Ipv4Builder> {
+
+ public Ipv4CustomizerTest() {
+ super(Ipv4.class, Interface2Builder.class);
+ }
+
+ @Test
+ public void testReadCurrentAttributes() throws Exception {
+ customizer.readCurrentAttributes(null, null, ctx);
+ verifyZeroInteractions(api);
+ }
+
+ @Override
+ protected ReaderCustomizer<Ipv4, Ipv4Builder> initCustomizer() {
+ return new Ipv4Customizer(api);
+ }
+} \ No newline at end of file