5ed37aa40d0e47ac8960c89beb9d93dd25e60209
[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 org.junit.Assert.assertEquals;
22 import static org.junit.Assert.fail;
23 import static org.mockito.Matchers.any;
24 import static org.mockito.Matchers.eq;
25 import static org.mockito.Mockito.doReturn;
26 import static org.mockito.Mockito.never;
27 import static org.mockito.Mockito.times;
28 import static org.mockito.Mockito.verify;
29 import static org.mockito.MockitoAnnotations.initMocks;
30
31 import com.google.common.base.Optional;
32 import io.fd.honeycomb.v3po.translate.MappingContext;
33 import io.fd.honeycomb.v3po.translate.v3po.test.TestHelperUtils;
34 import io.fd.honeycomb.v3po.translate.v3po.util.NamingContext;
35 import io.fd.honeycomb.v3po.translate.write.WriteContext;
36 import io.fd.honeycomb.v3po.translate.write.WriteFailedException;
37 import java.util.ArrayList;
38 import java.util.List;
39 import java.util.concurrent.CompletableFuture;
40 import java.util.concurrent.ExecutionException;
41 import org.junit.Before;
42 import org.junit.Test;
43 import org.mockito.ArgumentCaptor;
44 import org.mockito.Mock;
45 import org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.naming.context.rev160513.contexts.naming.context.mappings.Mapping;
46 import org.opendaylight.yang.gen.v1.urn.ieee.params.xml.ns.yang.dot1q.types.rev150626.CVlan;
47 import org.opendaylight.yang.gen.v1.urn.ieee.params.xml.ns.yang.dot1q.types.rev150626.Dot1qTagVlanType;
48 import org.opendaylight.yang.gen.v1.urn.ieee.params.xml.ns.yang.dot1q.types.rev150626.Dot1qVlanId;
49 import org.opendaylight.yang.gen.v1.urn.ieee.params.xml.ns.yang.dot1q.types.rev150626.SVlan;
50 import org.opendaylight.yang.gen.v1.urn.ieee.params.xml.ns.yang.dot1q.types.rev150626.dot1q.tag.or.any.Dot1qTag;
51 import org.opendaylight.yang.gen.v1.urn.ieee.params.xml.ns.yang.dot1q.types.rev150626.dot1q.tag.or.any.Dot1qTagBuilder;
52 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.Interfaces;
53 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
54 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev150527.SubinterfaceAugmentation;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev150527._802dot1ad;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev150527.interfaces._interface.SubInterfaces;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev150527.interfaces._interface.sub.interfaces.SubInterface;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev150527.interfaces._interface.sub.interfaces.SubInterfaceBuilder;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev150527.interfaces._interface.sub.interfaces.SubInterfaceKey;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev150527.match.attributes.match.type.vlan.tagged.VlanTaggedBuilder;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev150527.sub._interface.base.attributes.Match;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev150527.sub._interface.base.attributes.MatchBuilder;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev150527.sub._interface.base.attributes.TagsBuilder;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev150527.sub._interface.base.attributes.tags.Tag;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev150527.sub._interface.base.attributes.tags.TagBuilder;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev150527.sub._interface.base.attributes.tags.TagKey;
68 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
69 import org.openvpp.jvpp.VppBaseCallException;
70 import org.openvpp.jvpp.VppInvocationException;
71 import org.openvpp.jvpp.dto.CreateSubif;
72 import org.openvpp.jvpp.dto.CreateSubifReply;
73 import org.openvpp.jvpp.dto.SwInterfaceSetFlags;
74 import org.openvpp.jvpp.dto.SwInterfaceSetFlagsReply;
75 import org.openvpp.jvpp.future.FutureJVpp;
76
77 import java.util.concurrent.CompletableFuture;
78 import java.util.concurrent.ExecutionException;
79
80 import static org.junit.Assert.assertEquals;
81 import static org.junit.Assert.assertTrue;
82 import static org.junit.Assert.fail;
83 import static org.mockito.Matchers.any;
84 import static org.mockito.Matchers.eq;
85 import static org.mockito.Mockito.*;
86 import static org.mockito.MockitoAnnotations.initMocks;
87
88 public class SubInterfaceCustomizerTest {
89
90     @Mock
91     private FutureJVpp api;
92     @Mock
93     private WriteContext writeContext;
94     @Mock
95     private MappingContext mappingContext;
96
97     private NamingContext namingContext;
98     private SubInterfaceCustomizer customizer;
99     public static final String SUPER_IF_NAME = "local0";
100     public static final int SUPER_IF_ID = 1;
101
102     @Before
103     public void setUp() throws Exception {
104         initMocks(this);
105         namingContext = new NamingContext("generatedSubInterfaceName", "test-instance");
106         doReturn(mappingContext).when(writeContext).getMappingContext();
107         // TODO create base class for tests using vppApi
108         customizer = new SubInterfaceCustomizer(api, namingContext);
109         doReturn(getMapping(SUPER_IF_NAME, SUPER_IF_ID)).when(mappingContext)
110                 .read(getMappingIid(SUPER_IF_NAME, "test-instance"));
111     }
112
113     private SubInterface generateSubInterface(final String superIfName, final boolean enabled) {
114         SubInterfaceBuilder builder = new SubInterfaceBuilder();
115         builder.setVlanType(_802dot1ad.class);
116         builder.setIdentifier(11L);
117         final TagsBuilder tags = new TagsBuilder();
118         final List<Tag> list = new ArrayList<>();
119         list.add(generateTag((short) 0, SVlan.class,  new Dot1qTag.VlanId(new Dot1qVlanId(100))));
120         list.add(generateTag((short) 1, CVlan.class,  new Dot1qTag.VlanId(new Dot1qVlanId(200))));
121
122         tags.setTag(list);
123
124         builder.setTags(tags.build());
125
126         builder.setMatch(generateMatch());
127         builder.setEnabled(enabled);
128         return builder.build();
129     }
130
131     private static Tag generateTag(final short index, final Class<? extends Dot1qTagVlanType> tagType,
132                                    final Dot1qTag.VlanId vlanId) {
133         TagBuilder tag = new TagBuilder();
134         tag.setIndex(index);
135         tag.setKey(new TagKey(index));
136         final Dot1qTagBuilder dtag = new Dot1qTagBuilder();
137         dtag.setTagType(tagType);
138         dtag.setVlanId(vlanId);
139         tag.setDot1qTag(dtag.build());
140         return tag.build();
141     }
142
143     private static Match generateMatch() {
144         final MatchBuilder match = new MatchBuilder();
145         final VlanTaggedBuilder tagged = new VlanTaggedBuilder();
146         tagged.setMatchExactTags(true);
147         match.setMatchType(
148                 new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev150527.match.attributes.match.type.VlanTaggedBuilder()
149                         .setVlanTagged(tagged.build()).build());
150         return match.build();
151     }
152
153     private CreateSubif generateSubInterfaceRequest(final int superIfId) {
154         CreateSubif request = new CreateSubif();
155         request.subId = 11;
156         request.swIfIndex = superIfId;
157         request.twoTags = 1;
158         request.dot1Ad = 1;
159         request.outerVlanId = 100;
160         request.innerVlanId = 200;
161         return request;
162     }
163
164     private SwInterfaceSetFlags generateSwInterfaceEnableRequest(final int swIfIndex) {
165         SwInterfaceSetFlags request = new SwInterfaceSetFlags();
166         request.swIfIndex = swIfIndex;
167         request.adminUpDown = 1;
168         return request;
169     }
170
171     private InstanceIdentifier<SubInterface> getSubInterfaceId(final String name, final long index) {
172         return InstanceIdentifier.create(Interfaces.class).child(Interface.class, new InterfaceKey(name)).augmentation(
173                 SubinterfaceAugmentation.class).child(SubInterfaces.class).child(SubInterface.class, new SubInterfaceKey(index));
174     }
175
176     private void whenCreateSubifThen() throws ExecutionException, InterruptedException, VppBaseCallException {
177         final CompletableFuture<CreateSubifReply> replyFuture = new CompletableFuture<>();
178         final CreateSubifReply reply = new CreateSubifReply();
179         replyFuture.complete(reply);
180         doReturn(replyFuture).when(api).createSubif(any(CreateSubif.class));
181     }
182
183     /**
184      * Failure response send
185      */
186     private void whenCreateSubifFailedThen(final int retval) throws ExecutionException, InterruptedException, VppBaseCallException {
187         doReturn(TestHelperUtils.<CreateSubifReply>createFutureException(retval)).when(api).createSubif(any(CreateSubif.class));
188     }
189     
190     private void whenSwInterfaceSetFlagsThen(final int retval) throws ExecutionException, InterruptedException, VppBaseCallException {
191         final CompletableFuture<SwInterfaceSetFlagsReply> replyFuture = new CompletableFuture<>();
192         final SwInterfaceSetFlagsReply reply = new SwInterfaceSetFlagsReply();
193         replyFuture.complete(reply);
194         doReturn(replyFuture).when(api).swInterfaceSetFlags(any(SwInterfaceSetFlags.class));
195     }
196
197     private void whenCreateSubifThenSuccess() throws ExecutionException, InterruptedException, VppBaseCallException {
198         whenCreateSubifThen();
199     }
200
201     private void whenCreateSubifThenFailure() throws ExecutionException, InterruptedException, VppBaseCallException {
202         whenCreateSubifFailedThen(-1);
203     }
204     
205     private void whenSwInterfaceSetFlagsThenSuccess() throws ExecutionException, InterruptedException, VppBaseCallException {
206         whenSwInterfaceSetFlagsThen(0);
207     }
208
209     private CreateSubif verifyCreateSubifWasInvoked(final CreateSubif expected) throws VppBaseCallException {
210         ArgumentCaptor<CreateSubif> argumentCaptor = ArgumentCaptor.forClass(CreateSubif.class);
211         verify(api).createSubif(argumentCaptor.capture());
212         final CreateSubif actual = argumentCaptor.getValue();
213
214         assertEquals(expected.swIfIndex, actual.swIfIndex);
215         assertEquals(expected.subId, actual.subId);
216         assertEquals(expected.noTags, actual.noTags);
217         assertEquals(expected.oneTag, actual.oneTag);
218         assertEquals(expected.twoTags, actual.twoTags);
219         assertEquals(expected.dot1Ad, actual.dot1Ad);
220         assertEquals(expected.exactMatch, actual.exactMatch);
221         assertEquals(expected.defaultSub, actual.defaultSub);
222         assertEquals(expected.outerVlanIdAny, actual.outerVlanIdAny);
223         assertEquals(expected.innerVlanIdAny, actual.innerVlanIdAny);
224         assertEquals(expected.outerVlanId, actual.outerVlanId);
225         assertEquals(expected.innerVlanId, actual.innerVlanId);
226         return actual;
227     }
228
229     private SwInterfaceSetFlags verifySwInterfaceSetFlagsWasInvoked(final SwInterfaceSetFlags expected) throws VppBaseCallException{
230         ArgumentCaptor<SwInterfaceSetFlags> argumentCaptor = ArgumentCaptor.forClass(SwInterfaceSetFlags.class);
231         verify(api).swInterfaceSetFlags(argumentCaptor.capture());
232         final SwInterfaceSetFlags actual = argumentCaptor.getValue();
233
234         assertEquals(expected.swIfIndex, actual.swIfIndex);
235         assertEquals(expected.adminUpDown, actual.adminUpDown);
236         return actual;
237     }
238
239     @Test
240     public void testCreate() throws Exception {
241         final SubInterface subInterface = generateSubInterface(SUPER_IF_NAME, false);
242         final String superIfName = "local0";
243         final String subIfaceName = "local0.11";
244         final long subifIndex = 11;
245         final InstanceIdentifier<SubInterface> id = getSubInterfaceId(superIfName, subifIndex);
246
247         whenCreateSubifThenSuccess();
248         whenSwInterfaceSetFlagsThenSuccess();
249
250         customizer.writeCurrentAttributes(id, subInterface, writeContext);
251
252         verifyCreateSubifWasInvoked(generateSubInterfaceRequest(SUPER_IF_ID));
253         verify(mappingContext)
254                 .put(eq(getMappingIid(subIfaceName, "test-instance")), eq(getMapping(subIfaceName, 0).get()));
255     }
256
257     @Test
258     public void testCreateFailed() throws Exception {
259         final SubInterface subInterface = generateSubInterface(SUPER_IF_NAME, false);
260         final String superIfName = "local0";
261         final String subIfaceName = "local0.11";
262         final long subifIndex = 11;
263         final InstanceIdentifier<SubInterface> id = getSubInterfaceId(superIfName, subifIndex);
264
265         whenCreateSubifThenFailure();
266
267         try {
268             customizer.writeCurrentAttributes(id, subInterface, writeContext);
269         } catch (WriteFailedException.CreateFailedException e) {
270             assertTrue(e.getCause() instanceof VppBaseCallException );
271             verifyCreateSubifWasInvoked(generateSubInterfaceRequest(SUPER_IF_ID));
272             verify(mappingContext, times(0)).put(
273                     eq(getMappingIid(subIfaceName, "test-instance")),
274                     eq(getMapping(subIfaceName, 0).get()));
275             return;
276         }
277         fail("WriteFailedException.CreateFailedException was expected");
278     }
279
280     @Test
281     public void testUpdate() throws Exception {
282         final SubInterface before = generateSubInterface("eth0", false);
283         final SubInterface after = generateSubInterface("eth1", true);
284         final String superIfName = "local0";
285         final String subIfaceName = "local0.11";
286         final int subifIndex = 11;
287         final InstanceIdentifier<SubInterface> id = getSubInterfaceId(superIfName, subifIndex);
288
289         whenSwInterfaceSetFlagsThenSuccess();
290         final Optional<Mapping> ifcMapping = getMapping(subIfaceName, subifIndex);
291         doReturn(ifcMapping).when(mappingContext).read(any());
292
293         customizer.updateCurrentAttributes(id, before, after, writeContext);
294
295         verifySwInterfaceSetFlagsWasInvoked(generateSwInterfaceEnableRequest(subifIndex));
296     }
297
298     @Test
299     public void testUpdateNoStateChange() throws Exception {
300         final SubInterface before = generateSubInterface(SUPER_IF_NAME, false);
301         final SubInterface after = generateSubInterface(SUPER_IF_NAME, false);
302         customizer.updateCurrentAttributes(null, before, after, writeContext);
303
304         verify(api, never()).swInterfaceSetFlags(any());
305     }
306
307     @Test(expected = UnsupportedOperationException.class)
308     public void testDelete() throws Exception {
309         final SubInterface subInterface = generateSubInterface("eth0", false);
310         customizer.deleteCurrentAttributes(null, subInterface, writeContext);
311     }
312 }