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