2 * Copyright (c) 2017 Cisco and/or its affiliates.
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:
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 package io.fd.hc2vpp.lisp.gpe.translate.write;
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;
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;
53 @RunWith(HoneycombTestRunner.class)
54 public class GpeForwardEntryCustomizerTest extends WriterCustomizerTest
55 implements InjectablesProcessor, ByteDataTranslator {
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};
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)};
74 private static final GpeLocator[] BABA_LOCATORS = {
75 ABAB_LOCATORS[1], ABAB_LOCATORS[0], ABAB_LOCATORS[3], ABAB_LOCATORS[2]};
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;
82 private NamingContext gpeEntryMappingContext;
85 private ArgumentCaptor<GpeAddDelFwdEntry> requestCaptor;
88 private GpeStateCheckService gpeStateCheckService;
90 private InstanceIdentifier<GpeEntry> id;
91 private GpeForwardEntryCustomizer customizer;
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);
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
106 org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.gpe.rev170801.$YangModuleInfoImpl
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());
122 private static GpeAddDelFwdEntryReply entryReply() {
123 final GpeAddDelFwdEntryReply reply = new GpeAddDelFwdEntryReply();
124 reply.fwdEntryIndex = GPE_FWD_ENTRY_INDEX;
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());
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());
155 * Gpe entry allows no local eid
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());
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 {
175 customizer.writeCurrentAttributes(id, entryTable.getGpeEntry().get(0), writeContext);
176 } catch (IllegalArgumentException e) {
177 verifyZeroInteractions(api);
180 fail("Test should have failed");
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));
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));
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));
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));
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 {
235 customizer.deleteCurrentAttributes(id, entryTable.getGpeEntry().get(0), writeContext);
236 } catch (IllegalArgumentException e) {
237 verifyZeroInteractions(api);
240 fail("Test should have failed");
243 private void assertActionLessNoLeidRequest(final boolean add, final GpeAddDelFwdEntry actual) {
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));
255 private void assertActionLessRequest(final boolean add, final GpeAddDelFwdEntry actual) {
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);
265 private void assertLocatorLessRequest(final boolean add, final GpeAddDelFwdEntry actual) {
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);
280 private void assertFullRequest(final boolean add, final GpeAddDelFwdEntry actual) {
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));
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;