HONEYCOMB-116: utility for stubbing jvpp methods
[honeycomb.git] / v3po / v3po2vpp / src / test / java / io / fd / honeycomb / translate / v3po / interfaces / VxlanCustomizerTest.java
1 /*
2  * Copyright (c) 2016 Cisco and/or its affiliates.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at:
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 package io.fd.honeycomb.translate.v3po.interfaces;
18
19 import static io.fd.honeycomb.translate.v3po.test.ContextTestUtils.getMapping;
20 import static io.fd.honeycomb.translate.v3po.test.ContextTestUtils.getMappingIid;
21 import static org.junit.Assert.assertArrayEquals;
22 import static org.junit.Assert.assertEquals;
23 import static org.junit.Assert.assertTrue;
24 import static org.junit.Assert.fail;
25 import static org.mockito.Matchers.any;
26 import static org.mockito.Matchers.eq;
27 import static org.mockito.Mockito.doReturn;
28 import static org.mockito.Mockito.times;
29 import static org.mockito.Mockito.verify;
30 import static org.mockito.Mockito.when;
31
32 import com.google.common.net.InetAddresses;
33 import io.fd.honeycomb.translate.v3po.DisabledInterfacesManager;
34 import io.fd.honeycomb.translate.v3po.test.ContextTestUtils;
35 import io.fd.honeycomb.translate.v3po.util.NamingContext;
36 import io.fd.honeycomb.translate.write.WriteFailedException;
37 import io.fd.honeycomb.vpp.test.write.WriterCustomizerTest;
38 import org.junit.Test;
39 import org.mockito.ArgumentCaptor;
40 import org.mockito.Mock;
41 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
42 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address;
43 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.Interfaces;
44 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
45 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VppInterfaceAugmentation;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VxlanVni;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces._interface.Vxlan;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces._interface.VxlanBuilder;
50 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
51 import org.openvpp.jvpp.VppBaseCallException;
52 import org.openvpp.jvpp.VppInvocationException;
53 import org.openvpp.jvpp.core.dto.VxlanAddDelTunnel;
54 import org.openvpp.jvpp.core.dto.VxlanAddDelTunnelReply;
55
56 public class VxlanCustomizerTest extends WriterCustomizerTest {
57
58     private static final byte ADD_VXLAN = 1;
59     private static final byte DEL_VXLAN = 0;
60
61     @Mock
62     private DisabledInterfacesManager disableContext;
63
64     private VxlanCustomizer customizer;
65     private String ifaceName;
66     private InstanceIdentifier<Vxlan> id;
67
68     @Override
69     public void setUp() throws Exception {
70         InterfaceTypeTestUtils.setupWriteContext(writeContext,
71             org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VxlanTunnel.class);
72
73         customizer =
74             new VxlanCustomizer(api, new NamingContext("generateInterfaceNAme", "test-instance"), disableContext);
75
76         ifaceName = "eth0";
77         id = InstanceIdentifier.create(Interfaces.class).child(Interface.class, new InterfaceKey(ifaceName))
78             .augmentation(VppInterfaceAugmentation.class).child(Vxlan.class);
79     }
80
81     private void whenVxlanAddDelTunnelThenSuccess() {
82         when(api.vxlanAddDelTunnel(any(VxlanAddDelTunnel.class))).thenReturn(future(new VxlanAddDelTunnelReply()));
83     }
84
85     private void whenVxlanAddDelTunnelThenFailure() {
86         doReturn(failedFuture()).when(api).vxlanAddDelTunnel(any(VxlanAddDelTunnel.class));
87     }
88
89     private VxlanAddDelTunnel verifyVxlanAddDelTunnelWasInvoked(final Vxlan vxlan) throws VppInvocationException {
90         ArgumentCaptor<VxlanAddDelTunnel> argumentCaptor = ArgumentCaptor.forClass(VxlanAddDelTunnel.class);
91         verify(api).vxlanAddDelTunnel(argumentCaptor.capture());
92         final VxlanAddDelTunnel actual = argumentCaptor.getValue();
93         assertEquals(0, actual.isIpv6);
94         assertEquals(-1, actual.decapNextIndex);
95         assertArrayEquals(InetAddresses.forString(vxlan.getSrc().getIpv4Address().getValue()).getAddress(),
96             actual.srcAddress);
97         assertArrayEquals(InetAddresses.forString(vxlan.getDst().getIpv4Address().getValue()).getAddress(),
98             actual.dstAddress);
99         assertEquals(vxlan.getEncapVrfId().intValue(), actual.encapVrfId);
100         assertEquals(vxlan.getVni().getValue().intValue(), actual.vni);
101         return actual;
102     }
103
104     private void verifyVxlanAddWasInvoked(final Vxlan vxlan) throws VppInvocationException {
105         final VxlanAddDelTunnel actual = verifyVxlanAddDelTunnelWasInvoked(vxlan);
106         assertEquals(ADD_VXLAN, actual.isAdd);
107     }
108
109     private void verifyVxlanDeleteWasInvoked(final Vxlan vxlan) throws VppInvocationException {
110         final VxlanAddDelTunnel actual = verifyVxlanAddDelTunnelWasInvoked(vxlan);
111         assertEquals(DEL_VXLAN, actual.isAdd);
112     }
113
114     private static Vxlan generateVxlan(long vni) {
115         final VxlanBuilder builder = new VxlanBuilder();
116         builder.setSrc(new IpAddress(new Ipv4Address("192.168.20.10")));
117         builder.setDst(new IpAddress(new Ipv4Address("192.168.20.11")));
118         builder.setEncapVrfId(Long.valueOf(123));
119         builder.setVni(new VxlanVni(Long.valueOf(vni)));
120         return builder.build();
121     }
122
123     private static Vxlan generateVxlan() {
124         return generateVxlan(Long.valueOf(11));
125     }
126
127     @Test
128     public void testWriteCurrentAttributes() throws Exception {
129         final Vxlan vxlan = generateVxlan();
130
131         whenVxlanAddDelTunnelThenSuccess();
132         ContextTestUtils.mockEmptyMapping(mappingContext, ifaceName, "test-instance");
133
134         customizer.writeCurrentAttributes(id, vxlan, writeContext);
135         verifyVxlanAddWasInvoked(vxlan);
136         verify(mappingContext).put(eq(getMappingIid(ifaceName, "test-instance")), eq(getMapping(ifaceName, 0).get()));
137     }
138
139     @Test
140     public void testWriteCurrentAttributesWithExistingVxlanPlaceholder() throws Exception {
141         final Vxlan vxlan = generateVxlan();
142
143         whenVxlanAddDelTunnelThenSuccess();
144         ContextTestUtils.mockEmptyMapping(mappingContext, ifaceName, "test-instance");
145         doReturn(true).when(disableContext).isInterfaceDisabled(0, mappingContext);
146
147         customizer.writeCurrentAttributes(id, vxlan, writeContext);
148         verifyVxlanAddWasInvoked(vxlan);
149         verify(mappingContext).put(eq(getMappingIid(ifaceName, "test-instance")), eq(getMapping(ifaceName, 0).get()));
150         verify(disableContext).removeDisabledInterface(0, mappingContext);
151     }
152
153     @Test
154     public void testWriteCurrentAttributesMappingAlreadyPresent() throws Exception {
155         final Vxlan vxlan = generateVxlan();
156         final int ifaceId = 0;
157
158         whenVxlanAddDelTunnelThenSuccess();
159         ContextTestUtils.mockMapping(mappingContext, ifaceName, ifaceId, "test-instance");
160
161         customizer.writeCurrentAttributes(id, vxlan, writeContext);
162         verifyVxlanAddWasInvoked(vxlan);
163
164         // Remove the first mapping before putting in the new one
165         verify(mappingContext).delete(eq(getMappingIid(ifaceName, "test-instance")));
166         verify(mappingContext)
167             .put(eq(getMappingIid(ifaceName, "test-instance")), eq(getMapping(ifaceName, ifaceId).get()));
168     }
169
170     @Test
171     public void testWriteCurrentAttributesFailed() throws Exception {
172         final Vxlan vxlan = generateVxlan();
173
174         whenVxlanAddDelTunnelThenFailure();
175
176         try {
177             customizer.writeCurrentAttributes(id, vxlan, writeContext);
178         } catch (WriteFailedException.CreateFailedException e) {
179             assertTrue(e.getCause() instanceof VppBaseCallException);
180             verifyVxlanAddWasInvoked(vxlan);
181             // Mapping not stored due to failure
182             verify(mappingContext, times(0))
183                 .put(eq(getMappingIid(ifaceName, "test-instance")), eq(getMapping(ifaceName, 0).get()));
184             return;
185         }
186         fail("WriteFailedException.CreateFailedException was expected");
187     }
188
189     @Test
190     public void testUpdateCurrentAttributes() throws Exception {
191         try {
192             customizer.updateCurrentAttributes(id, generateVxlan(10), generateVxlan(11), writeContext);
193         } catch (WriteFailedException.UpdateFailedException e) {
194             assertEquals(UnsupportedOperationException.class, e.getCause().getClass());
195             return;
196         }
197         fail("WriteFailedException.UpdateFailedException was expected");
198     }
199
200     @Test
201     public void testDeleteCurrentAttributes() throws Exception {
202         final Vxlan vxlan = generateVxlan();
203
204         whenVxlanAddDelTunnelThenSuccess();
205         ContextTestUtils.mockMapping(mappingContext, ifaceName, 1, "test-instance");
206
207         customizer.deleteCurrentAttributes(id, vxlan, writeContext);
208         verifyVxlanDeleteWasInvoked(vxlan);
209         verify(mappingContext).delete(eq(getMappingIid(ifaceName, "test-instance")));
210         verify(disableContext).disableInterface(1, mappingContext);
211     }
212
213     @Test
214     public void testDeleteCurrentAttributesaFailed() throws Exception {
215         final Vxlan vxlan = generateVxlan();
216
217         whenVxlanAddDelTunnelThenFailure();
218         ContextTestUtils.mockMapping(mappingContext, ifaceName, 1, "test-instance");
219
220         try {
221             customizer.deleteCurrentAttributes(id, vxlan, writeContext);
222         } catch (WriteFailedException.DeleteFailedException e) {
223             assertTrue(e.getCause() instanceof VppBaseCallException);
224             verifyVxlanDeleteWasInvoked(vxlan);
225             verify(mappingContext, times(0)).delete(eq(getMappingIid(ifaceName, "test-instance")));
226             return;
227         }
228         fail("WriteFailedException.DeleteFailedException was expected");
229     }
230 }