1015f24c09ea50a2f6375e643f0c6ab25dff84c7
[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.ContextTestUtils.getMapping;
20 import static io.fd.honeycomb.v3po.translate.v3po.ContextTestUtils.getMappingIid;
21 import static org.junit.Assert.assertArrayEquals;
22 import static org.junit.Assert.assertEquals;
23 import static org.junit.Assert.assertNotNull;
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.mock;
29 import static org.mockito.Mockito.never;
30 import static org.mockito.Mockito.times;
31 import static org.mockito.Mockito.verify;
32 import static org.mockito.Mockito.verifyZeroInteractions;
33 import static org.mockito.Mockito.when;
34 import static org.mockito.MockitoAnnotations.initMocks;
35
36 import io.fd.honeycomb.v3po.translate.MappingContext;
37 import io.fd.honeycomb.v3po.translate.ModificationCache;
38 import io.fd.honeycomb.v3po.translate.v3po.util.NamingContext;
39 import io.fd.honeycomb.v3po.translate.v3po.util.VppApiInvocationException;
40 import io.fd.honeycomb.v3po.translate.v3po.utils.V3poUtils;
41 import io.fd.honeycomb.v3po.translate.write.WriteContext;
42 import io.fd.honeycomb.v3po.translate.write.WriteFailedException;
43 import java.util.concurrent.CompletableFuture;
44 import java.util.concurrent.CompletionStage;
45 import java.util.concurrent.ExecutionException;
46 import org.junit.Before;
47 import org.junit.Test;
48 import org.mockito.ArgumentCaptor;
49 import org.mockito.Mock;
50 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.Interfaces;
51 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
52 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VhostUserRole;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VppInterfaceAugmentation;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces._interface.VhostUser;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces._interface.VhostUserBuilder;
57 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
58 import org.openvpp.jvpp.dto.CreateVhostUserIf;
59 import org.openvpp.jvpp.dto.CreateVhostUserIfReply;
60 import org.openvpp.jvpp.dto.DeleteVhostUserIf;
61 import org.openvpp.jvpp.dto.DeleteVhostUserIfReply;
62 import org.openvpp.jvpp.dto.ModifyVhostUserIf;
63 import org.openvpp.jvpp.dto.ModifyVhostUserIfReply;
64 import org.openvpp.jvpp.future.FutureJVpp;
65
66 public class VhostUserCustomizerTest {
67
68     @Mock
69     private FutureJVpp api;
70     @Mock
71     private WriteContext writeContext;
72     @Mock
73     private MappingContext mappingContext;
74
75     private VhostUserCustomizer customizer;
76     private static final int IFACE_ID = 1;
77     private static final String IFACE_NAME = "eth0";
78     private static final InstanceIdentifier<VhostUser> ID =
79             InstanceIdentifier.create(Interfaces.class).child(Interface.class, new InterfaceKey(IFACE_NAME))
80                     .augmentation(VppInterfaceAugmentation.class).child(VhostUser.class);
81
82     @Before
83     public void setUp() throws Exception {
84         initMocks(this);
85         InterfaceTypeTestUtils.setupWriteContext(writeContext,
86             org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VhostUser.class);
87         final NamingContext namingContext = new NamingContext("generatedInterfaceName", "test-instance");
88         final ModificationCache toBeReturned = new ModificationCache();
89         doReturn(toBeReturned).when(writeContext).getModificationCache();
90         doReturn(mappingContext).when(writeContext).getMappingContext();
91
92         // TODO create base class for tests using vppApi
93         customizer = new VhostUserCustomizer(api, namingContext);
94     }
95
96     private void whenCreateVhostUserIfThen(final int retval) throws ExecutionException, InterruptedException {
97         final CompletionStage<CreateVhostUserIfReply> replyCS = mock(CompletionStage.class);
98         final CompletableFuture<CreateVhostUserIfReply> replyFuture = mock(CompletableFuture.class);
99         when(replyCS.toCompletableFuture()).thenReturn(replyFuture);
100         final CreateVhostUserIfReply reply = new CreateVhostUserIfReply();
101         reply.retval = retval;
102         when(replyFuture.get()).thenReturn(reply);
103         when(api.createVhostUserIf(any(CreateVhostUserIf.class))).thenReturn(replyCS);
104     }
105
106     private void whenCreateVhostUserIfThenSuccess() throws ExecutionException, InterruptedException {
107         whenCreateVhostUserIfThen(0);
108     }
109
110     private void whenVxlanAddDelTunnelThenFailure() throws ExecutionException, InterruptedException {
111         whenCreateVhostUserIfThen(-1);
112     }
113
114     private void whenModifyVhostUserIfThen(final int retval) throws ExecutionException, InterruptedException {
115         final CompletionStage<ModifyVhostUserIfReply> replyCS = mock(CompletionStage.class);
116         final CompletableFuture<ModifyVhostUserIfReply> replyFuture = mock(CompletableFuture.class);
117         when(replyCS.toCompletableFuture()).thenReturn(replyFuture);
118         final ModifyVhostUserIfReply reply = new ModifyVhostUserIfReply();
119         reply.retval = retval;
120         when(replyFuture.get()).thenReturn(reply);
121         when(api.modifyVhostUserIf(any(ModifyVhostUserIf.class))).thenReturn(replyCS);
122     }
123
124     private void whenModifyVhostUserIfThenSuccess() throws ExecutionException, InterruptedException {
125         whenModifyVhostUserIfThen(0);
126     }
127
128     private void whenModifyVhostUserIfThenFailure() throws ExecutionException, InterruptedException {
129         whenModifyVhostUserIfThen(-1);
130     }
131
132     private void whenDeleteVhostUserIfThen(final int retval) throws ExecutionException, InterruptedException {
133         final CompletionStage<DeleteVhostUserIfReply> replyCS = mock(CompletionStage.class);
134         final CompletableFuture<DeleteVhostUserIfReply> replyFuture = mock(CompletableFuture.class);
135         when(replyCS.toCompletableFuture()).thenReturn(replyFuture);
136         final DeleteVhostUserIfReply reply = new DeleteVhostUserIfReply();
137         reply.retval = retval;
138         when(replyFuture.get()).thenReturn(reply);
139         when(api.deleteVhostUserIf(any(DeleteVhostUserIf.class))).thenReturn(replyCS);
140     }
141
142     private void whenDeleteVhostUserIfThenSuccess() throws ExecutionException, InterruptedException {
143         whenDeleteVhostUserIfThen(0);
144     }
145
146     private void whenDeleteVhostUserIfThenFailure() throws ExecutionException, InterruptedException {
147         whenDeleteVhostUserIfThen(-1);
148     }
149
150     private CreateVhostUserIf verifyCreateVhostUserIfWasInvoked(final VhostUser vhostUser) {
151         ArgumentCaptor<CreateVhostUserIf> argumentCaptor = ArgumentCaptor.forClass(CreateVhostUserIf.class);
152         verify(api).createVhostUserIf(argumentCaptor.capture());
153         final CreateVhostUserIf actual = argumentCaptor.getValue();
154         assertEquals(0, actual.customDevInstance);
155
156         assertEquals(V3poUtils.booleanToByte(VhostUserRole.Server.equals(vhostUser.getRole())), actual.isServer);
157         assertEquals(0, actual.renumber);
158         assertEquals(0, actual.useCustomMac);
159         assertArrayEquals(vhostUser.getSocket().getBytes(), actual.sockFilename);
160         assertNotNull(actual.macAddress);
161         return actual;
162     }
163
164     private ModifyVhostUserIf verifyModifyVhostUserIfWasInvoked(final VhostUser vhostUser, final int swIfIndex) {
165         ArgumentCaptor<ModifyVhostUserIf> argumentCaptor = ArgumentCaptor.forClass(ModifyVhostUserIf.class);
166         verify(api).modifyVhostUserIf(argumentCaptor.capture());
167         final ModifyVhostUserIf actual = argumentCaptor.getValue();
168         assertEquals(0, actual.customDevInstance);
169
170         assertEquals(V3poUtils.booleanToByte(VhostUserRole.Server.equals(vhostUser.getRole())), actual.isServer);
171         assertEquals(0, actual.renumber);
172         assertEquals(swIfIndex, actual.swIfIndex);
173         assertArrayEquals(vhostUser.getSocket().getBytes(), actual.sockFilename);
174         return actual;
175     }
176
177     private DeleteVhostUserIf verifyDeleteVhostUserIfWasInvoked(final int swIfIndex) {
178         ArgumentCaptor<DeleteVhostUserIf> argumentCaptor = ArgumentCaptor.forClass(DeleteVhostUserIf.class);
179         verify(api).deleteVhostUserIf(argumentCaptor.capture());
180         final DeleteVhostUserIf actual = argumentCaptor.getValue();
181         assertEquals(swIfIndex, actual.swIfIndex);
182         return actual;
183     }
184
185     private static VhostUser generateVhostUser(final VhostUserRole role, final String socketName) {
186         VhostUserBuilder builder = new VhostUserBuilder();
187         builder.setRole(role);
188         builder.setSocket(socketName);
189         return builder.build();
190     }
191
192     @Test
193     public void testWriteCurrentAttributes() throws Exception {
194         final VhostUser vhostUser = generateVhostUser(VhostUserRole.Server, "socketName");
195
196         whenCreateVhostUserIfThenSuccess();
197
198         customizer.writeCurrentAttributes(ID, vhostUser, writeContext);
199         verifyCreateVhostUserIfWasInvoked(vhostUser);
200         verify(mappingContext).put(eq(getMappingIid(IFACE_NAME, "test-instance")), eq(getMapping(IFACE_NAME, 0).get()));
201     }
202
203     @Test
204     public void testWriteCurrentAttributesFailed() throws Exception {
205         final VhostUser vhostUser = generateVhostUser(VhostUserRole.Client, "socketName");
206
207         whenVxlanAddDelTunnelThenFailure();
208
209         try {
210             customizer.writeCurrentAttributes(ID, vhostUser, writeContext);
211         } catch (WriteFailedException.CreateFailedException e) {
212             assertEquals(VppApiInvocationException.class, e.getCause().getClass());
213             verifyCreateVhostUserIfWasInvoked(vhostUser);
214             verifyZeroInteractions(mappingContext);
215             return;
216         }
217         fail("WriteFailedException.CreateFailedException was expected");
218     }
219
220     @Test
221     public void testUpdateCurrentAttributes() throws Exception {
222         final VhostUser vhostUserBefore = generateVhostUser(VhostUserRole.Client, "socketName0");
223         final VhostUser vhostUserAfter = generateVhostUser(VhostUserRole.Server, "socketName1");
224         doReturn(getMapping(IFACE_NAME, IFACE_ID)).when(mappingContext).read(getMappingIid(IFACE_NAME, "test-instance"));
225
226         whenModifyVhostUserIfThenSuccess();
227
228         customizer.updateCurrentAttributes(ID, vhostUserBefore, vhostUserAfter, writeContext);
229         verifyModifyVhostUserIfWasInvoked(vhostUserAfter, IFACE_ID);
230     }
231
232     @Test
233     public void testUpdateCurrentAttributesNoUpdate() throws Exception {
234         final VhostUser vhostUserBefore = generateVhostUser(VhostUserRole.Server, "socketName");
235         final VhostUser vhostUserAfter = generateVhostUser(VhostUserRole.Server, "socketName");
236         customizer.updateCurrentAttributes(ID, vhostUserBefore, vhostUserAfter, writeContext);
237         verify(api, never()).modifyVhostUserIf(any(ModifyVhostUserIf.class));
238     }
239
240     @Test
241     public void testUpdateCurrentAttributesFailed() throws Exception {
242         final VhostUser vhostUserBefore = generateVhostUser(VhostUserRole.Client, "socketName0");
243         final VhostUser vhostUserAfter = generateVhostUser(VhostUserRole.Server, "socketName1");
244         doReturn(getMapping(IFACE_NAME, IFACE_ID)).when(mappingContext).read(getMappingIid(IFACE_NAME, "test-instance"));
245
246         whenModifyVhostUserIfThenFailure();
247
248         try {
249             customizer.updateCurrentAttributes(ID, vhostUserBefore, vhostUserAfter, writeContext);
250         } catch (WriteFailedException.UpdateFailedException e) {
251             assertEquals(VppApiInvocationException.class, e.getCause().getClass());
252             verifyModifyVhostUserIfWasInvoked(vhostUserAfter, IFACE_ID);
253             return;
254         }
255         fail("WriteFailedException.UpdateFailedException was expected");
256     }
257
258     @Test
259     public void testDeleteCurrentAttributes() throws Exception {
260         final VhostUser vhostUser = generateVhostUser(VhostUserRole.Client, "socketName");
261         doReturn(getMapping(IFACE_NAME, IFACE_ID)).when(mappingContext).read(getMappingIid(IFACE_NAME, "test-instance"));
262
263         whenDeleteVhostUserIfThenSuccess();
264
265         customizer.deleteCurrentAttributes(ID, vhostUser, writeContext);
266         verifyDeleteVhostUserIfWasInvoked(IFACE_ID);
267         verify(mappingContext).delete(eq(getMappingIid(IFACE_NAME, "test-instance")));
268     }
269
270     @Test
271     public void testDeleteCurrentAttributesFailed() throws Exception {
272         final VhostUser vhostUser = generateVhostUser(VhostUserRole.Client, "socketName");
273         doReturn(getMapping(IFACE_NAME, IFACE_ID)).when(mappingContext).read(getMappingIid(IFACE_NAME, "test-instance"));
274
275         whenDeleteVhostUserIfThenFailure();
276
277         try {
278             customizer.deleteCurrentAttributes(ID, vhostUser, writeContext);
279         } catch (WriteFailedException.DeleteFailedException e) {
280             assertEquals(VppApiInvocationException.class, e.getCause().getClass());
281             verifyDeleteVhostUserIfWasInvoked(IFACE_ID);
282             // Delete from context not invoked if delete from VPP failed
283             verify(mappingContext, times(0)).delete(eq(getMappingIid(IFACE_NAME, "test-instance")));
284             verify(mappingContext).read(eq(getMappingIid(IFACE_NAME, "test-instance")));
285             return;
286         }
287         fail("WriteFailedException.DeleteFailedException was expected");
288     }
289 }