c54206270c2b19462055239ad9f104d686c326c4
[hc2vpp.git] /
1 /*
2  * Copyright (c) 2017 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.hc2vpp.lisp.gpe.translate.write;
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.ArgumentMatchers.any;
23 import static org.mockito.Mockito.times;
24 import static org.mockito.Mockito.verify;
25 import static org.mockito.Mockito.verifyZeroInteractions;
26 import static org.mockito.Mockito.when;
27
28 import com.google.common.collect.ImmutableSet;
29 import io.fd.hc2vpp.common.test.write.WriterCustomizerTest;
30 import io.fd.hc2vpp.common.translate.util.ByteDataTranslator;
31 import io.fd.hc2vpp.common.translate.util.NamingContext;
32 import io.fd.hc2vpp.lisp.gpe.translate.ctx.GpeLocatorPair;
33 import io.fd.hc2vpp.lisp.gpe.translate.ctx.GpeLocatorPairMappingContext;
34 import io.fd.hc2vpp.lisp.gpe.translate.service.GpeStateCheckService;
35 import io.fd.honeycomb.test.tools.HoneycombTestRunner;
36 import io.fd.honeycomb.test.tools.annotations.InjectTestData;
37 import io.fd.honeycomb.test.tools.annotations.InjectablesProcessor;
38 import io.fd.honeycomb.test.tools.annotations.SchemaContextProvider;
39 import io.fd.vpp.jvpp.core.dto.GpeAddDelFwdEntry;
40 import io.fd.vpp.jvpp.core.dto.GpeAddDelFwdEntryReply;
41 import io.fd.vpp.jvpp.core.types.GpeLocator;
42 import org.junit.Test;
43 import org.junit.runner.RunWith;
44 import org.mockito.ArgumentCaptor;
45 import org.mockito.Captor;
46 import org.mockito.Mock;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.gpe.rev170518.gpe.entry.table.grouping.GpeEntryTable;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.gpe.rev170518.gpe.entry.table.grouping.gpe.entry.table.GpeEntry;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.gpe.rev170518.gpe.entry.table.grouping.gpe.entry.table.GpeEntryKey;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.gpe.rev170518.gpe.entry.table.grouping.gpe.entry.table.gpe.entry.LocatorPairs;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev170315.$YangModuleInfoImpl;
52 import org.opendaylight.mdsal.binding.generator.impl.ModuleInfoBackedContext;
53 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
54
55 @RunWith(HoneycombTestRunner.class)
56 public class GpeForwardEntryCustomizerTest extends WriterCustomizerTest
57         implements InjectablesProcessor, ByteDataTranslator {
58
59     private static final String GPE_ENTRY_ID = "gpe-fwd-entry-1";
60     private static final String GPE_ENTRY_PATH = "/gpe:gpe" +
61             "/gpe:gpe-feature-data" +
62             "/gpe:gpe-entry-table";
63     private static final byte[] LOCAL_EID_ADDRESS = {-64, -88, 2, 0};
64     private static final byte[] REMOTE_EID_ADDRESS = {-64, -88, 3, 0};
65     private static final byte[] PAIR_2_LOCAL_ADDRESS = {-64, -88, 5, 1};
66     private static final byte[] PAIR_1_LOCAL_ADDRESS = {-64, -88, 4, 1};
67     private static final byte[] PAIR_2_REMOTE_ADDRESS = {-64, -88, 5, 2};
68     private static final byte[] PAIR_1_REMOTE_ADDRESS = {-64, -88, 4, 2};
69     private static final int LOCAL_EID_PREFIX = 24;
70     private static final int REMOTE_EID_PREFIX = 16;
71     public static final String GPE_ENTRY_CTX = "gpe-entry-ctx";
72     public static final int GPE_FWD_ENTRY_INDEX = 4;
73
74     private NamingContext gpeEntryMappingContext;
75
76     @Captor
77     private ArgumentCaptor<GpeAddDelFwdEntry> requestCaptor;
78
79     @Mock
80     private GpeLocatorPairMappingContext gpeLocatorPairMappingContext;
81
82     @Mock
83     private GpeStateCheckService gpeStateCheckService;
84
85     private InstanceIdentifier<GpeEntry> id;
86     private GpeForwardEntryCustomizer customizer;
87
88     @Override
89     protected void setUpTest() throws Exception {
90         gpeEntryMappingContext = new NamingContext("gpe-entry-", GPE_ENTRY_CTX);
91         id = InstanceIdentifier.create(GpeEntryTable.class)
92                 .child(GpeEntry.class, new GpeEntryKey(GPE_ENTRY_ID));
93         customizer = new GpeForwardEntryCustomizer(api, gpeStateCheckService, gpeEntryMappingContext,
94                 gpeLocatorPairMappingContext);
95     }
96
97     @SchemaContextProvider
98     public ModuleInfoBackedContext schemaContext() {
99         return provideSchemaContextFor(ImmutableSet.of($YangModuleInfoImpl.getInstance(),
100                 org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.$YangModuleInfoImpl
101                         .getInstance(),
102                 org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.gpe.rev170518.$YangModuleInfoImpl
103                         .getInstance()));
104     }
105
106     @Test
107     public void testWriteCurrentAttributesFull(@InjectTestData(resourcePath = "/gpe/gpe-fwd-entry-full.json",
108             id = GPE_ENTRY_PATH) GpeEntryTable entryTable) throws Exception {
109         when(api.gpeAddDelFwdEntry(any())).thenReturn(future(entryReply()));
110         final GpeEntry entry = entryTable.getGpeEntry().get(0);
111         customizer.writeCurrentAttributes(id, entry, writeContext);
112         verify(api, times(1)).gpeAddDelFwdEntry(requestCaptor.capture());
113         assertEquals(expectedFullRequest(true), requestCaptor.getValue());
114         verify(mappingContext, times(1))
115                 .put(mappingIid(entry.getId(), GPE_ENTRY_CTX), mapping(entry.getId(), GPE_FWD_ENTRY_INDEX).get());
116
117         final LocatorPairs locatorPairFirst = entry.getLocatorPairs().get(0);
118         final LocatorPairs locatorPairSecond = entry.getLocatorPairs().get(1);
119         verify(gpeLocatorPairMappingContext, times(1))
120                 .addMapping(entry.getId(), locatorPairFirst.getId(),
121                         GpeLocatorPair.fromLocatorPair(locatorPairFirst), mappingContext);
122         verify(gpeLocatorPairMappingContext, times(1))
123                 .addMapping(entry.getId(), locatorPairSecond.getId(),
124                         GpeLocatorPair.fromLocatorPair(locatorPairSecond), mappingContext);
125     }
126
127     private static GpeAddDelFwdEntryReply entryReply() {
128         final GpeAddDelFwdEntryReply reply = new GpeAddDelFwdEntryReply();
129         reply.fwdEntryIndex = GPE_FWD_ENTRY_INDEX;
130         return reply;
131     }
132
133     @Test
134     public void testWriteCurrentAttributesWithoutLocators(
135             @InjectTestData(resourcePath = "/gpe/gpe-fwd-entry-without-locators.json",
136                     id = GPE_ENTRY_PATH) GpeEntryTable entryTable) throws Exception {
137         when(api.gpeAddDelFwdEntry(any())).thenReturn(future(entryReply()));
138         final GpeEntry entry = entryTable.getGpeEntry().get(0);
139         customizer.writeCurrentAttributes(id, entry, writeContext);
140         verify(api, times(1)).gpeAddDelFwdEntry(requestCaptor.capture());
141         assertEquals(expectedLocatorLessRequest(true), requestCaptor.getValue());
142         verify(mappingContext, times(1))
143                 .put(mappingIid(entry.getId(), GPE_ENTRY_CTX), mapping(entry.getId(), GPE_FWD_ENTRY_INDEX).get());
144         verifyZeroInteractions(gpeLocatorPairMappingContext);
145     }
146
147     @Test
148     public void testWriteCurrentAttributesWithoutAction(
149             @InjectTestData(resourcePath = "/gpe/gpe-fwd-entry-without-action.json",
150                     id = GPE_ENTRY_PATH) GpeEntryTable entryTable) throws Exception {
151         when(api.gpeAddDelFwdEntry(any())).thenReturn(future(entryReply()));
152         final GpeEntry entry = entryTable.getGpeEntry().get(0);
153         customizer.writeCurrentAttributes(id, entry, writeContext);
154         verify(api, times(1)).gpeAddDelFwdEntry(requestCaptor.capture());
155         assertEquals(expectedActionLessRequest(true), requestCaptor.getValue());
156         verify(mappingContext, times(1))
157                 .put(mappingIid(entry.getId(), GPE_ENTRY_CTX), mapping(entry.getId(), GPE_FWD_ENTRY_INDEX).get());
158         verifyZeroInteractions(gpeLocatorPairMappingContext);
159     }
160
161     /**
162      * Gpe entry allows no local eid
163      * */
164     @Test
165     public void testWriteCurrentAttributesNoLocalEid(
166             @InjectTestData(resourcePath = "/gpe/invalid/invalid-gpe-fwd-entry-no-local-eid.json",
167                     id = GPE_ENTRY_PATH) GpeEntryTable entryTable) throws Exception {
168         when(api.gpeAddDelFwdEntry(any())).thenReturn(future(entryReply()));
169         final GpeEntry entry = entryTable.getGpeEntry().get(0);
170         customizer.writeCurrentAttributes(id, entry, writeContext);
171         verify(api, times(1)).gpeAddDelFwdEntry(requestCaptor.capture());
172         assertEquals(expectedActionLessNoLeidRequest(true), requestCaptor.getValue());
173         verify(mappingContext, times(1))
174                 .put(mappingIid(entry.getId(), GPE_ENTRY_CTX), mapping(entry.getId(), GPE_FWD_ENTRY_INDEX).get());
175
176         final LocatorPairs locatorPairFirst = entry.getLocatorPairs().get(0);
177         final LocatorPairs locatorPairSecond = entry.getLocatorPairs().get(1);
178         verify(gpeLocatorPairMappingContext, times(1))
179                 .addMapping(entry.getId(), locatorPairFirst.getId(),
180                         GpeLocatorPair.fromLocatorPair(locatorPairFirst), mappingContext);
181         verify(gpeLocatorPairMappingContext, times(1))
182                 .addMapping(entry.getId(), locatorPairSecond.getId(),
183                         GpeLocatorPair.fromLocatorPair(locatorPairSecond), mappingContext);
184     }
185
186     @Test
187     public void testWriteCurrentAttributesFailNoRemoteEid(
188             @InjectTestData(resourcePath = "/gpe/invalid/invalid-gpe-fwd-entry-no-remote-eid.json",
189                     id = GPE_ENTRY_PATH) GpeEntryTable entryTable) throws Exception {
190         try {
191             customizer.writeCurrentAttributes(id, entryTable.getGpeEntry().get(0), writeContext);
192         } catch (IllegalArgumentException e) {
193             verifyZeroInteractions(api);
194             return;
195         }
196         fail("Test should have failed");
197     }
198
199     @Test
200     public void testDeleteCurrentAttributesFull(@InjectTestData(resourcePath = "/gpe/gpe-fwd-entry-full.json",
201             id = GPE_ENTRY_PATH) GpeEntryTable entryTable) throws Exception {
202         when(api.gpeAddDelFwdEntry(any())).thenReturn(future(new GpeAddDelFwdEntryReply()));
203         final GpeEntry entry = entryTable.getGpeEntry().get(0);
204         customizer.deleteCurrentAttributes(id, entry, writeContext);
205         verify(api, times(1)).gpeAddDelFwdEntry(requestCaptor.capture());
206         assertEquals(expectedFullRequest(false), requestCaptor.getValue());
207         verify(mappingContext, times(1)).delete(mappingIid(entry.getId(), GPE_ENTRY_CTX));
208         verify(gpeLocatorPairMappingContext, times(1))
209                 .removeMapping(entry.getId(), mappingContext);
210     }
211
212     @Test
213     public void testDeleteCurrentAttributesWithoutLocators(
214             @InjectTestData(resourcePath = "/gpe/gpe-fwd-entry-without-locators.json",
215                     id = GPE_ENTRY_PATH) GpeEntryTable entryTable) throws Exception {
216         when(api.gpeAddDelFwdEntry(any())).thenReturn(future(new GpeAddDelFwdEntryReply()));
217         final GpeEntry entry = entryTable.getGpeEntry().get(0);
218         customizer.deleteCurrentAttributes(id, entry, writeContext);
219         verify(api, times(1)).gpeAddDelFwdEntry(requestCaptor.capture());
220         assertEquals(expectedLocatorLessRequest(false), requestCaptor.getValue());
221         verify(mappingContext, times(1)).delete(mappingIid(entry.getId(), GPE_ENTRY_CTX));
222         verify(gpeLocatorPairMappingContext, times(1))
223                 .removeMapping(entry.getId(), mappingContext);
224     }
225
226     @Test
227     public void testDeleteCurrentAttributesWithoutAction(
228             @InjectTestData(resourcePath = "/gpe/gpe-fwd-entry-without-action.json",
229                     id = GPE_ENTRY_PATH) GpeEntryTable entryTable) throws Exception {
230         when(api.gpeAddDelFwdEntry(any())).thenReturn(future(new GpeAddDelFwdEntryReply()));
231         final GpeEntry entry = entryTable.getGpeEntry().get(0);
232         customizer.deleteCurrentAttributes(id, entry, writeContext);
233         verify(api, times(1)).gpeAddDelFwdEntry(requestCaptor.capture());
234         assertEquals(expectedActionLessRequest(false), requestCaptor.getValue());
235         verify(mappingContext, times(1)).delete(mappingIid(entry.getId(), GPE_ENTRY_CTX));
236         verify(gpeLocatorPairMappingContext, times(1))
237                 .removeMapping(entry.getId(), mappingContext);
238     }
239
240     @Test
241     public void testDeleteCurrentAttributesNoLocalEid(
242             @InjectTestData(resourcePath = "/gpe/invalid/invalid-gpe-fwd-entry-no-local-eid.json",
243                     id = GPE_ENTRY_PATH) GpeEntryTable entryTable) throws Exception {
244         when(api.gpeAddDelFwdEntry(any())).thenReturn(future(new GpeAddDelFwdEntryReply()));
245         final GpeEntry entry = entryTable.getGpeEntry().get(0);
246         customizer.deleteCurrentAttributes(id, entry, writeContext);
247         verify(api, times(1)).gpeAddDelFwdEntry(requestCaptor.capture());
248         assertEquals(expectedActionLessNoLeidRequest(false), requestCaptor.getValue());
249         verify(mappingContext, times(1)).delete(mappingIid(entry.getId(), GPE_ENTRY_CTX));
250         verify(gpeLocatorPairMappingContext, times(1))
251                 .removeMapping(entry.getId(), mappingContext);
252     }
253
254     @Test
255     public void testDeleteCurrentAttributesFailNoRemoteEid(
256             @InjectTestData(resourcePath = "/gpe/invalid/invalid-gpe-fwd-entry-no-remote-eid.json",
257                     id = GPE_ENTRY_PATH) GpeEntryTable entryTable) throws Exception {
258         try {
259             customizer.deleteCurrentAttributes(id, entryTable.getGpeEntry().get(0), writeContext);
260         } catch (IllegalArgumentException e) {
261             verifyZeroInteractions(api);
262             return;
263         }
264         fail("Test should have failed");
265     }
266
267     private GpeAddDelFwdEntry expectedActionLessNoLeidRequest(final boolean add) {
268         final GpeAddDelFwdEntry request = new GpeAddDelFwdEntry();
269
270         request.isAdd = booleanToByte(add);
271         request.dpTable = 10;
272         request.vni = 12;
273         request.eidType = 0;
274         request.action = 0;
275         request.rmtEid = REMOTE_EID_ADDRESS;
276         request.rmtLen = REMOTE_EID_PREFIX;
277         request.locNum = 4;
278         request.locs = new GpeLocator[]{
279                 gpeLocator(PAIR_1_LOCAL_ADDRESS, 1, 3),
280                 gpeLocator(PAIR_2_LOCAL_ADDRESS, 1, 2),
281                 gpeLocator(PAIR_1_REMOTE_ADDRESS, 1, 0),
282                 gpeLocator(PAIR_2_REMOTE_ADDRESS, 1, 0)
283         };
284         return request;
285     }
286
287     private GpeAddDelFwdEntry expectedActionLessRequest(final boolean add) {
288         final GpeAddDelFwdEntry request = new GpeAddDelFwdEntry();
289
290         request.isAdd = booleanToByte(add);
291         request.dpTable = 10;
292         request.vni = 12;
293         request.eidType = 0;
294         request.action = 0;
295         request.lclEid = LOCAL_EID_ADDRESS;
296         request.lclLen = LOCAL_EID_PREFIX;
297         request.rmtEid = REMOTE_EID_ADDRESS;
298         request.rmtLen = REMOTE_EID_PREFIX;
299         request.locNum = 0;
300         return request;
301     }
302
303     private GpeAddDelFwdEntry expectedLocatorLessRequest(final boolean add) {
304         final GpeAddDelFwdEntry request = new GpeAddDelFwdEntry();
305
306         request.isAdd = booleanToByte(add);
307         request.dpTable = 10;
308         request.vni = 12;
309         request.eidType = 0;
310         request.action = 1;
311         request.lclEid = LOCAL_EID_ADDRESS;
312         request.lclLen = LOCAL_EID_PREFIX;
313         request.rmtEid = REMOTE_EID_ADDRESS;
314         request.rmtLen = REMOTE_EID_PREFIX;
315         request.locNum = 0;
316         return request;
317     }
318
319
320     private GpeAddDelFwdEntry expectedFullRequest(final boolean add) {
321         final GpeAddDelFwdEntry request = new GpeAddDelFwdEntry();
322
323         request.isAdd = booleanToByte(add);
324         request.dpTable = 10;
325         request.vni = 12;
326         request.eidType = 0;
327         request.action = 1;
328         request.lclEid = LOCAL_EID_ADDRESS;
329         request.lclLen = LOCAL_EID_PREFIX;
330         request.rmtEid = REMOTE_EID_ADDRESS;
331         request.rmtLen = REMOTE_EID_PREFIX;
332         request.locNum = 4;
333         request.locs = new GpeLocator[]{
334                 gpeLocator(PAIR_1_LOCAL_ADDRESS, 1, 3),
335                 gpeLocator(PAIR_2_LOCAL_ADDRESS, 1, 2),
336                 gpeLocator(PAIR_1_REMOTE_ADDRESS, 1, 0),
337                 gpeLocator(PAIR_2_REMOTE_ADDRESS, 1, 0)
338         };
339
340         return request;
341     }
342
343     private GpeLocator gpeLocator(final byte[] address, final int isIpv4, final int weight) {
344         GpeLocator locator = new GpeLocator();
345         locator.isIp4 = (byte) isIpv4;
346         locator.weight = (byte) weight;
347         locator.addr = address;
348
349         return locator;
350     }
351 }