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