Bump MRI upstreams
[lispflowmapping.git] / mappingservice / implementation / src / test / java / org / opendaylight / lispflowmapping / implementation / LispMappingServiceTest.java
1 /*
2  * Copyright (c) 2016 Cisco Systems, Inc. and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8 package org.opendaylight.lispflowmapping.implementation;
9
10 import static org.junit.Assert.assertEquals;
11 import static org.junit.Assert.assertNull;
12
13 import com.google.common.collect.Lists;
14 import java.lang.reflect.Field;
15 import java.util.ArrayList;
16 import java.util.List;
17 import org.apache.commons.lang3.tuple.ImmutablePair;
18 import org.apache.commons.lang3.tuple.MutablePair;
19 import org.apache.commons.lang3.tuple.Pair;
20 import org.junit.Test;
21 import org.junit.runner.RunWith;
22 import org.mockito.ArgumentMatcher;
23 import org.mockito.InjectMocks;
24 import org.mockito.Mock;
25 import org.mockito.Mockito;
26 import org.mockito.junit.MockitoJUnitRunner;
27 import org.opendaylight.lispflowmapping.interfaces.lisp.IMapResolverAsync;
28 import org.opendaylight.lispflowmapping.interfaces.lisp.IMapServerAsync;
29 import org.opendaylight.lispflowmapping.interfaces.mappingservice.IMappingService;
30 import org.opendaylight.lispflowmapping.lisp.type.LispMessage;
31 import org.opendaylight.lispflowmapping.lisp.util.LispAddressUtil;
32 import org.opendaylight.mdsal.binding.api.NotificationService;
33 import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceProvider;
34 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.PortNumber;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.inet.binary.types.rev160303.IpAddressBinary;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.inet.binary.types.rev160303.Ipv4AddressBinary;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.AddMapping;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.GotMapNotify;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.GotMapReply;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.MapNotify;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.MapRegister;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.MapReply;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.MappingKeepAlive;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.RequestMapping;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.XtrReplyMapping;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.XtrRequestMapping;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.eid.container.Eid;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.eid.list.EidItemBuilder;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.map.register.cache.metadata.container.MapRegisterCacheMetadata;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.map.register.cache.metadata.container.MapRegisterCacheMetadataBuilder;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.map.register.cache.metadata.container.map.register.cache.metadata.EidLispAddress;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.map.register.cache.metadata.container.map.register.cache.metadata.EidLispAddressBuilder;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.mapnotifymessage.MapNotifyBuilder;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.mapping._record.container.MappingRecordBuilder;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.mapping._record.list.MappingRecordItemBuilder;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.mapreplymessage.MapReplyBuilder;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.maprequest.SourceEidBuilder;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.maprequestmessage.MapRequest;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.maprequestmessage.MapRequestBuilder;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.rloc.container.Rloc;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.transport.address.TransportAddress;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.transport.address.TransportAddressBuilder;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.sb.rev150904.OdlLispSbService;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.sb.rev150904.SendMapNotifyInput;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.sb.rev150904.SendMapNotifyInputBuilder;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.sb.rev150904.SendMapReplyInputBuilder;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.sb.rev150904.SendMapRequestInputBuilder;
68 import org.opendaylight.yangtools.yang.binding.util.BindingMap;
69 import org.opendaylight.yangtools.yang.common.Uint16;
70
71 @RunWith(MockitoJUnitRunner.class)
72 public class LispMappingServiceTest {
73     @Mock private static MapRegister mapRegisterMock;
74     @Mock(name = "mapServer") private static IMapServerAsync mapServerMock;
75     @Mock(name = "mapResolver") private static IMapResolverAsync mapResolverMock;
76     @Mock(name = "tlsMapReply") private static ThreadLocal<MapReply> tlsMapReplyMock;
77     @Mock(name = "tlsMapNotify") private static ThreadLocal<Pair<MapNotify, List<TransportAddress>>> tlsMapNotifyMock;
78     @Mock(name = "tlsMapRequest") private static ThreadLocal<Pair<MapRequest, TransportAddress>> tlsMapRequestMock;
79
80     private final NotificationService notificationService = Mockito.mock(NotificationService.class);
81     private final IMappingService mappingService = Mockito.mock(IMappingService.class);
82     private final OdlLispSbService odlLispSbService = Mockito.mock(OdlLispSbService.class);
83     private final ClusterSingletonServiceProvider clusterSingletonService = Mockito.mock(
84             ClusterSingletonServiceProvider.class);
85
86     @InjectMocks
87     private final LispMappingService lispMappingService = new LispMappingService(
88             notificationService, mappingService, odlLispSbService, clusterSingletonService);
89
90     private static final byte[] IPV4_BYTES_1 =       new byte[] {1, 2, 3, 0};
91     private static final byte[] IPV4_BYTES_2 =       new byte[] {1, 2, 4, 0};
92     private static final String IPV4_STRING_1 =      "1.2.3.0";
93     private static final String IPV4_STRING_2 =      "1.2.3.1";
94     private static final String IPV4_SOURCE_STRING = "192.168.0.1";
95     private static final String IPV4_PREFIX_STRING = "/24";
96     private static final long TIMESTAMP = 1L;
97
98     private static final Eid IPV4_PREFIX_EID_1 = LispAddressUtil.asIpv4PrefixEid(IPV4_STRING_1 + IPV4_PREFIX_STRING);
99     private static final Eid IPV4_SOURCE_EID = LispAddressUtil.asIpv4Eid(IPV4_SOURCE_STRING);
100     private static final Eid IPV4_EID_1 = LispAddressUtil.asIpv4Eid(IPV4_STRING_1);
101     private static final Eid IPV4_EID_2 = LispAddressUtil.asIpv4Eid(IPV4_STRING_2);
102     private static final EidItemBuilder EID_ITEM_BUILDER = new EidItemBuilder()
103             .setEidItemId("eid-item-id")
104             .setEid(IPV4_PREFIX_EID_1);
105     private static final MappingRecordItemBuilder MAPPING_RECORD_ITEM_BUILDER = new MappingRecordItemBuilder()
106             .setMappingRecord(new MappingRecordBuilder().setEid(IPV4_PREFIX_EID_1).build());
107
108     private static final TransportAddress TRANSPORT_ADDRESS_1 = new TransportAddressBuilder()
109             .setIpAddress(new IpAddressBinary(new Ipv4AddressBinary(IPV4_BYTES_1)))
110             .setPort(new PortNumber(Uint16.valueOf(9999))).build();
111     private static final TransportAddress TRANSPORT_ADDRESS_2 = new TransportAddressBuilder()
112             .setIpAddress(new IpAddressBinary(new Ipv4AddressBinary(IPV4_BYTES_2)))
113             .setPort(new PortNumber(Uint16.valueOf(8888))).build();
114     private static final TransportAddress TRANSPORT_ADDRESS = new TransportAddressBuilder()
115             .setIpAddress(new IpAddressBinary(new Ipv4AddressBinary(IPV4_BYTES_1)))
116             .setPort(new PortNumber(LispMessage.PORT_NUMBER)).build();
117
118     /**
119      * Tests {@link LispMappingService#handleMapRequest} method.
120      */
121     @Test
122     public void handleMapRequestTest() {
123         final MapRequest mapRequest = Mockito.mock(MapRequest.class);
124         final MapReply mapReply = new MapReplyBuilder().build();
125         Mockito.when(tlsMapRequestMock.get()).thenReturn(null);
126         Mockito.when(tlsMapReplyMock.get()).thenReturn(mapReply);
127
128         final MapReply result = lispMappingService.handleMapRequest(mapRequest);
129
130         Mockito.verify(tlsMapRequestMock).set(null);
131         Mockito.verify(tlsMapRequestMock).get();
132         Mockito.verifyNoMoreInteractions(tlsMapRequestMock);
133         Mockito.verify(mapResolverMock).handleMapRequest(mapRequest);
134         Mockito.verify(tlsMapReplyMock).set(Mockito.any());
135         Mockito.verify(tlsMapReplyMock).get();
136
137         assertEquals(result, mapReply);
138     }
139
140     /**
141      * Tests {@link LispMappingService#handleMapRequest} method request from non-proxy xTR.
142      */
143     @Test
144     public void handleMapRequestTest_NonProxy() {
145         final MapRequest mapRequest = Mockito.mock(MapRequest.class);
146         final Pair<MapRequest, TransportAddress> pair = getDefaultMapRequestPair();
147         final SendMapRequestInputBuilder smrib = new SendMapRequestInputBuilder()
148                 .setMapRequest(pair.getLeft())
149                 .setTransportAddress(pair.getRight());
150
151         Mockito.when(tlsMapRequestMock.get()).thenReturn(pair);
152
153         assertNull(lispMappingService.handleMapRequest(mapRequest));
154         Mockito.verify(odlLispSbService).sendMapRequest(smrib.build());
155     }
156
157     /**
158      * Tests {@link LispMappingService#handleMapRegister} method.
159      */
160     @Test
161     @SuppressWarnings("unchecked")
162     public void handleMapRegisterTest() {
163         final Pair<MapNotify, List<TransportAddress>> pairMock = Mockito.mock(Pair.class);
164
165         Mockito.when(tlsMapNotifyMock.get()).thenReturn(pairMock);
166
167         lispMappingService.handleMapRegister(mapRegisterMock);
168         Mockito.verify(mapServerMock).handleMapRegister(mapRegisterMock);
169         Mockito.verify(tlsMapNotifyMock).set(Mockito.any());
170     }
171
172     /**
173      * Tests {@link LispMappingService#onAddMapping} method.
174      */
175     @Test
176     public void onAddMappingTest() {
177         final org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.mapregisternotification.MapRegister
178                 mapRegister = Mockito.mock(org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105
179                 .mapregisternotification.MapRegister.class);
180         final AddMapping addMapping = Mockito.mock(AddMapping.class);
181
182         Mockito.when(addMapping.getMapRegister()).thenReturn(mapRegister);
183         Mockito.when(tlsMapNotifyMock.get()).thenReturn(getDefaultMapNotifyPair());
184
185         lispMappingService.onAddMapping(addMapping);
186         Mockito.verify(odlLispSbService, Mockito.times(2)).sendMapNotify(Mockito.argThat(new TransportAddressMatch()));
187     }
188
189     /**
190      * Tests {@link LispMappingService#onAddMapping} method with no TransportAddress.
191      */
192     @Test
193     public void onAddMappingTest_noTransportAddress() {
194         final org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.mapregisternotification.MapRegister
195                 mapRegister = Mockito.mock(org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105
196                 .mapregisternotification.MapRegister.class);
197         final AddMapping addMapping = Mockito.mock(AddMapping.class);
198         final MapNotify mapNotify = new MapNotifyBuilder().setKeyId((short) 1).build();
199
200         Mockito.when(addMapping.getMapRegister()).thenReturn(mapRegister);
201         Mockito.when(tlsMapNotifyMock.get()).thenReturn(new MutablePair<>(mapNotify, null));
202         Mockito.when(addMapping.getTransportAddress()).thenReturn(TRANSPORT_ADDRESS_1);
203
204         // result
205         final SendMapNotifyInputBuilder smnib = new SendMapNotifyInputBuilder()
206                 .setMapNotify(new org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105
207                         .mapnotifymessage.MapNotifyBuilder().setKeyId((short) 1).build())
208                 .setTransportAddress(TRANSPORT_ADDRESS);
209
210         lispMappingService.onAddMapping(addMapping);
211         Mockito.verify(odlLispSbService).sendMapNotify(smnib.build());
212     }
213
214     /**
215      * Tests {@link LispMappingService#onRequestMapping} method.
216      */
217     @Test
218     public void onRequestMappingTest() {
219         final RequestMapping requestMapping = Mockito.mock(RequestMapping.class);
220         final org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.maprequestnotification.MapRequest
221                 mapRequest = Mockito.mock(org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105
222                     .maprequestnotification.MapRequest.class);
223         final MapReply mapReply = new MapReplyBuilder().build();
224
225         Mockito.when(requestMapping.getMapRequest()).thenReturn(mapRequest);
226         Mockito.when(requestMapping.getTransportAddress()).thenReturn(TRANSPORT_ADDRESS_1);
227         Mockito.when(tlsMapReplyMock.get()).thenReturn(mapReply);
228
229         // result
230         final SendMapReplyInputBuilder smrib = new SendMapReplyInputBuilder()
231                 .setMapReply(new MapReplyBuilder(mapReply).build())
232                 .setTransportAddress(TRANSPORT_ADDRESS_1);
233
234         lispMappingService.onRequestMapping(requestMapping);
235         Mockito.verify(odlLispSbService).sendMapReply(smrib.build());
236     }
237
238     /**
239      * Tests {@link LispMappingService#onRequestMapping} method with mapReply == null.
240      */
241     @Test
242     public void onRequestMappingTest_withNullMapReply() {
243         final RequestMapping requestMapping = Mockito.mock(RequestMapping.class);
244         final org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.maprequestnotification.MapRequest
245                 mapRequest = Mockito.mock(org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105
246                     .maprequestnotification.MapRequest.class);
247
248         Mockito.when(requestMapping.getMapRequest()).thenReturn(mapRequest);
249         Mockito.when(tlsMapReplyMock.get()).thenReturn(null);
250
251         lispMappingService.onRequestMapping(requestMapping);
252         Mockito.verifyZeroInteractions(odlLispSbService);
253     }
254
255     /**
256      * Tests {@link LispMappingService#onMappingKeepAlive} method.
257      */
258     @Test
259     public void onMappingKeepAliveTest() {
260         final MappingKeepAlive mappingKeepAlive = Mockito.mock(MappingKeepAlive.class);
261         Mockito.when(mappingKeepAlive.getMapRegisterCacheMetadata()).thenReturn(getDefaultMapRegisterCacheMetadata());
262
263         lispMappingService.onMappingKeepAlive(mappingKeepAlive);
264         Mockito.verify(mappingService).refreshMappingRegistration(IPV4_EID_1, null, TIMESTAMP);
265         Mockito.verify(mappingService).refreshMappingRegistration(IPV4_EID_2, null, TIMESTAMP);
266     }
267
268     /**
269      * Tests {@link LispMappingService#handleSMR} method.
270      */
271     @Test
272     public void handleSmrTest() {
273         final MapRequest mapRequest = Mockito.mock(MapRequest.class);
274         final Rloc subscriber = LispAddressUtil.asIpv4Rloc(IPV4_STRING_1);
275
276         Mockito.when(mapRequest.getSourceEid()).thenReturn(new SourceEidBuilder().setEid(IPV4_SOURCE_EID).build());
277         Mockito.when(mapRequest.getEidItem()).thenReturn(Lists.newArrayList(EID_ITEM_BUILDER.build()));
278
279         // result
280         final SendMapRequestInputBuilder smrib = new SendMapRequestInputBuilder()
281                 .setMapRequest(new MapRequestBuilder(mapRequest).build())
282                 .setTransportAddress(TRANSPORT_ADDRESS);
283
284         lispMappingService.handleSMR(mapRequest, subscriber);
285         Mockito.verify(odlLispSbService).sendMapRequest(smrib.build());
286     }
287
288     /**
289      * Tests {@link LispMappingService#setShouldUseSmr} method.
290      */
291     @Test
292     public void setShouldUseSmrTest() {
293         final boolean value = true;
294
295         lispMappingService.setShouldUseSmr(value);
296         Mockito.verify(mapServerMock).setSubscriptionService(value);
297         Mockito.verify(mapResolverMock).setSubscriptionService(value);
298     }
299
300     /**
301      * Tests {@link LispMappingService#handleMapNotify} method.
302      */
303     @Test
304     @SuppressWarnings("unchecked")
305     public void handleMapNotifyTest() {
306         final MapNotify mapNotify = Mockito.mock(MapNotify.class);
307         final List<TransportAddress> list = Mockito.mock(ArrayList.class);
308
309         lispMappingService.handleMapNotify(mapNotify, list);
310         Mockito.verify(tlsMapNotifyMock).set(Mockito.any(MutablePair.class));
311     }
312
313     /**
314      * Tests {@link LispMappingService#handleNonProxyMapRequest} method.
315      */
316     @Test
317     @SuppressWarnings("unchecked")
318     public void handleNonProxyMapRequestTest() {
319         final MapRequest mapRequest = Mockito.mock(MapRequest.class);
320         final TransportAddress transportAddress = Mockito.mock(TransportAddress.class);
321
322         lispMappingService.handleNonProxyMapRequest(mapRequest, transportAddress);
323         Mockito.verify(tlsMapRequestMock).set(Mockito.any(MutablePair.class));
324     }
325
326     /**
327      * Tests {@link LispMappingService#handleMapReply} method.
328      */
329     @Test
330     public void handleMapReplyTest() {
331         final MapReply mapReply = Mockito.mock(MapReply.class);
332
333         lispMappingService.handleMapReply(mapReply);
334         Mockito.verify(tlsMapReplyMock).set(Mockito.any(MapReply.class));
335     }
336
337     /**
338      * Tests {@link LispMappingService#close} method.
339      */
340     @Test
341     public void closeTest() throws Exception {
342         lispMappingService.close();
343
344         assertNull(getField("mapResolver"));
345         assertNull(getField("mapServer"));
346     }
347
348     /**
349      * Tests {@link LispMappingService} other setter and getter methods.
350      */
351     @Test
352     public void otherTest() throws Exception {
353         assertEquals(notificationService, lispMappingService.getNotificationService());
354         assertEquals(true, lispMappingService.shouldUseSmr());
355
356         lispMappingService.setShouldAuthenticate(true);
357         Mockito.verify(mapResolverMock).setShouldAuthenticate(true);
358
359         lispMappingService.onGotMapReply(Mockito.mock(GotMapReply.class));
360         lispMappingService.onGotMapNotify(Mockito.mock(GotMapNotify.class));
361         lispMappingService.onXtrRequestMapping(Mockito.mock(XtrRequestMapping.class));
362         lispMappingService.onXtrReplyMapping(Mockito.mock(XtrReplyMapping.class));
363     }
364
365     @SuppressWarnings("unchecked")
366     private <T> T getField(String fieldName) throws NoSuchFieldException, IllegalAccessException {
367         final Field field = LispMappingService.class.getDeclaredField(fieldName);
368         field.setAccessible(true);
369
370         return (T) field.get(lispMappingService);
371     }
372
373     private static Pair<MapNotify, List<TransportAddress>> getDefaultMapNotifyPair() {
374         final MapNotify mapNotify = new MapNotifyBuilder().setKeyId((short) 1).build();
375         return new MutablePair<>(mapNotify, Lists.newArrayList(TRANSPORT_ADDRESS_1, TRANSPORT_ADDRESS_2));
376     }
377
378     private static Pair<MapRequest, TransportAddress> getDefaultMapRequestPair() {
379         final MapRequestBuilder mapRequestBuilder = new MapRequestBuilder()
380                 .setEidItem(Lists.newArrayList(EID_ITEM_BUILDER.build()));
381
382         return new ImmutablePair<>(mapRequestBuilder.build(), TRANSPORT_ADDRESS_1);
383     }
384
385     private static MapRegisterCacheMetadata getDefaultMapRegisterCacheMetadata() {
386         final EidLispAddress eidLispAddress_1 = new EidLispAddressBuilder()
387                 .setEidLispAddressId("id-1")
388                 .setEid(IPV4_EID_1).build();
389         final EidLispAddress eidLispAddress_2 = new EidLispAddressBuilder()
390                 .setEidLispAddressId("id-2")
391                 .setEid(IPV4_EID_2).build();
392
393         return new MapRegisterCacheMetadataBuilder()
394                 .setEidLispAddress(BindingMap.ordered(eidLispAddress_1, eidLispAddress_2))
395                 .setTimestamp(TIMESTAMP).build();
396     }
397
398     class TransportAddressMatch implements ArgumentMatcher<SendMapNotifyInput> {
399         @Override
400         public boolean matches(SendMapNotifyInput sendMapNotify) {
401             final TransportAddress notifyTransportAddress = sendMapNotify.getTransportAddress();
402             return TRANSPORT_ADDRESS_1.equals(notifyTransportAddress)
403                     || TRANSPORT_ADDRESS_2.equals(notifyTransportAddress);
404         }
405     }
406 }