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