12424999f42e60712cf59015e1c3d33ec6a475d9
[hc2vpp.git] /
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.v3po.translate.v3po.interfaces;
18
19 import static io.fd.honeycomb.v3po.translate.v3po.test.ContextTestUtils.getMapping;
20 import static io.fd.honeycomb.v3po.translate.v3po.test.ContextTestUtils.getMappingIid;
21 import static java.util.Collections.singletonList;
22 import static org.junit.Assert.assertArrayEquals;
23 import static org.junit.Assert.assertEquals;
24 import static org.junit.Assert.assertTrue;
25 import static org.junit.Assert.fail;
26 import static org.mockito.Matchers.any;
27 import static org.mockito.Matchers.anyLong;
28 import static org.mockito.Matchers.eq;
29 import static org.mockito.Mockito.doReturn;
30 import static org.mockito.Mockito.mock;
31 import static org.mockito.Mockito.times;
32 import static org.mockito.Mockito.verify;
33 import static org.mockito.Mockito.when;
34 import static org.mockito.MockitoAnnotations.initMocks;
35
36 import com.google.common.base.Optional;
37 import com.google.common.net.InetAddresses;
38 import io.fd.honeycomb.v3po.translate.MappingContext;
39 import io.fd.honeycomb.v3po.translate.ModificationCache;
40 import io.fd.honeycomb.v3po.translate.v3po.test.TestHelperUtils;
41 import io.fd.honeycomb.v3po.translate.v3po.util.NamingContext;
42 import io.fd.honeycomb.v3po.translate.write.WriteContext;
43 import io.fd.honeycomb.v3po.translate.write.WriteFailedException;
44 import java.util.concurrent.CompletableFuture;
45 import java.util.concurrent.CompletionStage;
46 import java.util.concurrent.ExecutionException;
47 import java.util.concurrent.TimeUnit;
48 import java.util.concurrent.TimeoutException;
49 import org.junit.Before;
50 import org.junit.Test;
51 import org.mockito.ArgumentCaptor;
52 import org.mockito.Mock;
53 import org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.naming.context.rev160513.contexts.naming.context.Mappings;
54 import org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.naming.context.rev160513.contexts.naming.context.MappingsBuilder;
55 import org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.naming.context.rev160513.contexts.naming.context.mappings.Mapping;
56 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
57 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address;
58 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.Interfaces;
59 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
60 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VppInterfaceAugmentation;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VxlanGpeNextProtocol;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VxlanGpeVni;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces._interface.VxlanGpe;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces._interface.VxlanGpeBuilder;
66 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
67 import org.openvpp.jvpp.VppBaseCallException;
68 import org.openvpp.jvpp.dto.VxlanAddDelTunnelReply;
69 import org.openvpp.jvpp.dto.VxlanGpeAddDelTunnel;
70 import org.openvpp.jvpp.dto.VxlanGpeAddDelTunnelReply;
71 import org.openvpp.jvpp.future.FutureJVpp;
72
73 public class VxlanGpeCustomizerTest {
74
75     private static final byte ADD_VXLAN_GPE = 1;
76     private static final byte DEL_VXLAN_GPE = 0;
77
78     @Mock
79     private FutureJVpp api;
80     @Mock
81     private WriteContext writeContext;
82     @Mock
83     private MappingContext mappingContext;
84
85     private VxlanGpeCustomizer customizer;
86     private String ifaceName;
87     private InstanceIdentifier<VxlanGpe> id;
88
89     @Before
90     public void setUp() throws Exception {
91         initMocks(this);
92         InterfaceTypeTestUtils.setupWriteContext(writeContext,
93             org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VxlanGpeTunnel.class);
94         // TODO create base class for tests using vppApi
95         NamingContext namingContext = new NamingContext("generateInterfaceNAme", "test-instance");
96         final ModificationCache toBeReturned = new ModificationCache();
97         doReturn(toBeReturned).when(writeContext).getModificationCache();
98         doReturn(mappingContext).when(writeContext).getMappingContext();
99
100         customizer = new VxlanGpeCustomizer(api, namingContext);
101
102         ifaceName = "eth0";
103         id = InstanceIdentifier.create(Interfaces.class).child(Interface.class, new InterfaceKey(ifaceName))
104                         .augmentation(VppInterfaceAugmentation.class).child(VxlanGpe.class);
105     }
106
107     private void whenVxlanGpeAddDelTunnelThenSuccess()
108         throws ExecutionException, InterruptedException, VppBaseCallException, TimeoutException {
109         final CompletionStage<VxlanGpeAddDelTunnelReply> replyCS = mock(CompletionStage.class);
110         final CompletableFuture<VxlanGpeAddDelTunnelReply> replyFuture = mock(CompletableFuture.class);
111         when(replyCS.toCompletableFuture()).thenReturn(replyFuture);
112         final VxlanGpeAddDelTunnelReply reply = new VxlanGpeAddDelTunnelReply();
113         when(replyFuture.get(anyLong(), eq(TimeUnit.SECONDS))).thenReturn(reply);
114         when(api.vxlanGpeAddDelTunnel(any(VxlanGpeAddDelTunnel.class))).thenReturn(replyCS);
115     }
116
117     /**
118      * Failure response send
119      */
120     private void whenVxlanGpeAddDelTunnelThenFailure()
121             throws ExecutionException, InterruptedException, VppBaseCallException {
122         doReturn(TestHelperUtils.<VxlanAddDelTunnelReply>createFutureException()).when(api)
123                 .vxlanGpeAddDelTunnel(any(VxlanGpeAddDelTunnel.class));
124     }
125
126     private VxlanGpeAddDelTunnel verifyVxlanGpeAddDelTunnelWasInvoked(final VxlanGpe vxlanGpe)
127             throws VppBaseCallException {
128         ArgumentCaptor<VxlanGpeAddDelTunnel> argumentCaptor = ArgumentCaptor.forClass(VxlanGpeAddDelTunnel.class);
129         verify(api).vxlanGpeAddDelTunnel(argumentCaptor.capture());
130         final VxlanGpeAddDelTunnel actual = argumentCaptor.getValue();
131         assertEquals(0, actual.isIpv6);
132         assertArrayEquals(InetAddresses.forString(vxlanGpe.getLocal().getIpv4Address().getValue()).getAddress(),
133                 actual.local);
134         assertArrayEquals(InetAddresses.forString(vxlanGpe.getRemote().getIpv4Address().getValue()).getAddress(),
135                 actual.remote);
136         assertEquals(vxlanGpe.getVni().getValue().intValue(), actual.vni);
137         assertEquals(vxlanGpe.getNextProtocol().getIntValue(), actual.protocol);
138         assertEquals(vxlanGpe.getEncapVrfId().intValue(), actual.encapVrfId);
139         assertEquals(vxlanGpe.getDecapVrfId().intValue(), actual.decapVrfId);
140         return actual;
141     }
142
143     private void verifyVxlanGpeAddWasInvoked(final VxlanGpe vxlanGpe) throws VppBaseCallException {
144         final VxlanGpeAddDelTunnel actual = verifyVxlanGpeAddDelTunnelWasInvoked(vxlanGpe);
145         assertEquals(ADD_VXLAN_GPE, actual.isAdd);
146     }
147
148     private void verifyVxlanGpeDeleteWasInvoked(final VxlanGpe vxlanGpe) throws VppBaseCallException{
149         final VxlanGpeAddDelTunnel actual = verifyVxlanGpeAddDelTunnelWasInvoked(vxlanGpe);
150         assertEquals(DEL_VXLAN_GPE, actual.isAdd);
151     }
152
153     private static VxlanGpe generateVxlanGpe(long vni) {
154         final VxlanGpeBuilder builder = new VxlanGpeBuilder();
155         builder.setLocal(new IpAddress(new Ipv4Address("192.168.20.10")));
156         builder.setRemote(new IpAddress(new Ipv4Address("192.168.20.11")));
157         builder.setVni(new VxlanGpeVni(Long.valueOf(vni)));
158         builder.setNextProtocol(VxlanGpeNextProtocol.forValue(1));
159         builder.setEncapVrfId(Long.valueOf(123));
160         builder.setDecapVrfId(Long.valueOf(456));
161         return builder.build();
162     }
163
164     private static VxlanGpe generateVxlanGpe() {
165         return generateVxlanGpe(Long.valueOf(11));
166     }
167
168     @Test
169     public void testWriteCurrentAttributes() throws Exception {
170         final VxlanGpe vxlanGpe = generateVxlanGpe();
171
172         whenVxlanGpeAddDelTunnelThenSuccess();
173
174         doReturn(Optional.absent())
175             .when(mappingContext).read(getMappingIid(ifaceName, "test-instance").firstIdentifierOf(Mappings.class));
176
177         customizer.writeCurrentAttributes(id, vxlanGpe, writeContext);
178         verifyVxlanGpeAddWasInvoked(vxlanGpe);
179         verify(mappingContext).put(eq(getMappingIid(ifaceName, "test-instance")), eq(getMapping(ifaceName, 0).get()));
180     }
181
182     @Test
183     public void testWriteCurrentAttributesMappingAlreadyPresent() throws Exception {
184         final VxlanGpe vxlanGpe = generateVxlanGpe();
185
186         whenVxlanGpeAddDelTunnelThenSuccess();
187         final Optional<Mapping> ifcMapping = getMapping(ifaceName, 0);
188
189         doReturn(Optional.of(new MappingsBuilder().setMapping(singletonList(ifcMapping.get())).build()))
190             .when(mappingContext).read(getMappingIid(ifaceName, "test-instance").firstIdentifierOf(Mappings.class));
191
192         customizer.writeCurrentAttributes(id, vxlanGpe, writeContext);
193         verifyVxlanGpeAddWasInvoked(vxlanGpe);
194
195         // Remove the first mapping before putting in the new one
196         verify(mappingContext).delete(eq(getMappingIid(ifaceName, "test-instance")));
197         verify(mappingContext).put(eq(getMappingIid(ifaceName, "test-instance")), eq(ifcMapping.get()));
198     }
199
200     @Test
201     public void testWriteCurrentAttributesFailed() throws Exception {
202         final VxlanGpe vxlanGpe = generateVxlanGpe();
203
204         whenVxlanGpeAddDelTunnelThenFailure();
205
206         try {
207             customizer.writeCurrentAttributes(id, vxlanGpe, writeContext);
208         } catch (WriteFailedException.CreateFailedException e) {
209             assertTrue(e.getCause() instanceof VppBaseCallException);
210             verifyVxlanGpeAddWasInvoked(vxlanGpe);
211             // Mapping not stored due to failure
212             verify(mappingContext, times(0))
213                     .put(eq(getMappingIid(ifaceName, "test-instance")), eq(getMapping(ifaceName, 0).get()));
214             return;
215         }
216         fail("WriteFailedException.CreateFailedException was expected");
217     }
218
219     @Test
220     public void testUpdateCurrentAttributes() throws Exception {
221         try {
222             customizer.updateCurrentAttributes(id, generateVxlanGpe(10), generateVxlanGpe(11), writeContext);
223         } catch (WriteFailedException.UpdateFailedException e) {
224             assertEquals(UnsupportedOperationException.class, e.getCause().getClass());
225             return;
226         }
227         fail("WriteFailedException.UpdateFailedException was expected");
228     }
229
230     @Test
231     public void testDeleteCurrentAttributes() throws Exception {
232         final VxlanGpe vxlanGpe = generateVxlanGpe();
233
234         whenVxlanGpeAddDelTunnelThenSuccess();
235         doReturn(getMapping(ifaceName, 1)).when(mappingContext).read(getMappingIid(ifaceName, "test-instance"));
236
237         customizer.deleteCurrentAttributes(id, vxlanGpe, writeContext);
238         verifyVxlanGpeDeleteWasInvoked(vxlanGpe);
239         verify(mappingContext).delete(eq(getMappingIid(ifaceName, "test-instance")));
240     }
241
242     @Test
243     public void testDeleteCurrentAttributesaFailed() throws Exception {
244         final VxlanGpe vxlanGpe = generateVxlanGpe();
245
246         whenVxlanGpeAddDelTunnelThenFailure();
247         doReturn(getMapping(ifaceName, 1)).when(mappingContext).read(getMappingIid(ifaceName, "test-instance"));
248
249         try {
250             customizer.deleteCurrentAttributes(id, vxlanGpe, writeContext);
251         } catch (WriteFailedException.DeleteFailedException e) {
252             assertTrue(e.getCause() instanceof VppBaseCallException);
253             verifyVxlanGpeDeleteWasInvoked(vxlanGpe);
254             verify(mappingContext, times(0)).delete(eq(getMappingIid(ifaceName, "test-instance")));
255             return;
256         }
257         fail("WriteFailedException.DeleteFailedException was expected");
258     }
259 }