b0afc02717eaac76ec04c3070aeeef962456576d
[lispflowmapping.git] / integrationtest / src / test / java / org / opendaylight / lispflowmapping / integrationtest / MultiSiteScenario.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.integrationtest;
9
10 import static org.junit.Assert.assertEquals;
11 import static org.junit.Assert.assertNotNull;
12 import static org.junit.Assert.assertTrue;
13 import static org.junit.Assert.fail;
14 import static org.opendaylight.lispflowmapping.integrationtest.MappingServiceIntegrationTest.ourAddress;
15 import static org.opendaylight.lispflowmapping.integrationtest.MultiSiteScenarioUtil.SITE_A;
16 import static org.opendaylight.lispflowmapping.integrationtest.MultiSiteScenarioUtil.SITE_D5;
17
18 import com.google.common.net.InetAddresses;
19 import java.nio.ByteBuffer;
20 import java.util.ArrayList;
21 import java.util.Arrays;
22 import java.util.Collections;
23 import java.util.HashSet;
24 import java.util.List;
25 import java.util.Set;
26 import org.opendaylight.lispflowmapping.integrationtest.MultiSiteScenarioUtil.Site;
27 import org.opendaylight.lispflowmapping.interfaces.lisp.IFlowMapping;
28 import org.opendaylight.lispflowmapping.interfaces.mappingservice.IMappingService;
29 import org.opendaylight.lispflowmapping.lisp.serializer.MapRequestSerializer;
30 import org.opendaylight.lispflowmapping.lisp.type.MappingData;
31 import org.opendaylight.lispflowmapping.lisp.util.LispAddressStringifier;
32 import org.opendaylight.lispflowmapping.lisp.util.LispAddressUtil;
33 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.InstanceIdType;
34 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.lisp.address.Address;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.inet.binary.types.rev160303.Ipv4AddressBinary;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.binary.address.types.rev160504.augmented.lisp.address.address.Ipv4Binary;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.MapReply;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.MapRequest;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.SiteId;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.eid.container.Eid;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.eid.list.EidItem;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.eid.list.EidItemBuilder;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.locatorrecords.LocatorRecord;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.locatorrecords.LocatorRecordBuilder;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.mapping.authkey.container.MappingAuthkey;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.mapping.authkey.container.MappingAuthkeyBuilder;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.mapping.record.container.MappingRecord;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.mapping.record.container.MappingRecordBuilder;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.mapping.record.list.MappingRecordItem;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.mapping.record.list.MappingRecordItemBuilder;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.mapregisternotification.MapRegisterBuilder;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.maprequest.SourceEid;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.maprequest.SourceEidBuilder;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.maprequestnotification.MapRequestBuilder;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.rloc.container.Rloc;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.mappingservice.rev150906.MappingOrigin;
57 import org.slf4j.Logger;
58 import org.slf4j.LoggerFactory;
59
60 /**
61  * Contains methods for:
62  * - checking sites visibility (availability) - simulation of ping command
63  * - for preparing and processing data structures necessary for creating map request, map register LISP messages.
64  *
65  */
66 class MultiSiteScenario {
67
68     private final int DEFAULT_NETWORK_MASK = 24;
69     private final int IP_MASK = 32;
70
71     private final Integer TTL = 1440;
72     private final String MAP_RECORD_A = "MAP_RECORD_1";
73
74     private final Short DEFAULT_MULTICAST_PRIORITY = 255;
75     private final Short DEFAULT_MULTICAST_WEIGHT = 0;
76     private final Boolean DEFAULT_LOCAL_LOCATOR = true;
77     private final Boolean DEFAULT_RLOC_PROBED = false;
78     private final Boolean DEFAULT_ROUTED = true;
79     private final byte[] DEFAULT_SITE_ID = new byte[]{0, 0, 0, 0, 0, 0, 0, 0};
80
81     private final MappingAuthkey NULL_AUTH_KEY = new MappingAuthkeyBuilder().setKeyType(0).build();
82     private final IMappingService mapService;
83     private final IFlowMapping lms;
84
85     private static final Logger LOG = LoggerFactory.getLogger(MultiSiteScenario.class);
86
87     enum EidType {
88         EID_SRC_DST, EID_WITH_PREFIX
89     }
90
91     MultiSiteScenario(final IMappingService mapService, final IFlowMapping lms) {
92         this.mapService = mapService;
93         this.lms = lms;
94     }
95
96     private Ipv4AddressBinary verifyIpv4Address(final LocatorRecord locatorRecord) {
97         assertNotNull(locatorRecord);
98         final Rloc rloc = locatorRecord.getRloc();
99         assertNotNull(rloc);
100         final Address address = rloc.getAddress();
101         assertTrue(address instanceof Ipv4Binary);
102         return ((Ipv4Binary) address).getIpv4Binary();
103     }
104
105     private List<LocatorRecord> verifyLocatorRecordExists(final MappingRecord mappingRecord) {
106         final List<LocatorRecord> locatorRecords = mappingRecord.getLocatorRecord();
107         assertNotNull(locatorRecords);
108         return locatorRecords;
109     }
110
111     private MappingRecord verifyMappingRecord(MapReply mapReply) {
112         assertNotNull(mapReply);
113         final List<MappingRecordItem> mappingRecordItems = mapReply.getMappingRecordItem();
114         assertNotNull(mappingRecordItems);
115         assertEquals(1, mappingRecordItems.size());
116         final MappingRecordItem mappingRecordItem = mappingRecordItems.get(0);
117         assertNotNull(mappingRecordItem);
118         final MappingRecord mappingRecord = mappingRecordItem.getMappingRecord();
119         assertNotNull(mappingRecord);
120         return mappingRecord;
121     }
122
123     private void emitMapRegisterMessage(final Site dstSite, final boolean merge) {
124         final MapRegisterBuilder mapRegisterBuilder = new MapRegisterBuilder();
125         mapRegisterBuilder.setXtrSiteIdPresent(true);
126         mapRegisterBuilder.setXtrId(dstSite.getXtrId());
127         mapRegisterBuilder.setSiteId(new SiteId(DEFAULT_SITE_ID));
128         mapRegisterBuilder.setMergeEnabled(merge);
129         final MappingRecordItemBuilder mappingRecordItemBuilder = new MappingRecordItemBuilder();
130         mappingRecordItemBuilder.setMappingRecordItemId(MAP_RECORD_A);
131
132         final MappingRecordBuilder mrb = prepareMappingRecord(EidType.EID_WITH_PREFIX, null, dstSite);
133         mappingRecordItemBuilder.setMappingRecord(mrb.build());
134         mapRegisterBuilder.setMappingRecordItem(Collections.singletonList(mappingRecordItemBuilder.build()));
135
136         lms.handleMapRegister(mapRegisterBuilder.build());
137     }
138
139     void setCommonAuthentication() {
140         Eid eid = LispAddressUtil.asIpv4PrefixBinaryEid("0.0.0.0/0", SITE_A.getVNI());
141         mapService.addAuthenticationKey(eid, NULL_AUTH_KEY);
142
143         eid = LispAddressUtil.asIpv4PrefixBinaryEid("0.0.0.0/0", SITE_D5.getVNI());
144         mapService.addAuthenticationKey(eid, NULL_AUTH_KEY);
145         sleepForSeconds(1);
146     }
147
148     private Eid toEid(final String destSiteEidPrefix, final InstanceIdType vniValue, final int mask) {
149         return LispAddressUtil.asIpv4PrefixBinaryEid(destSiteEidPrefix + "/" + mask, vniValue);
150
151     }
152
153     private MapReply emitMapRequestMessage(final String siteFromEidPrefix, final String siteToEidPrefix, final
154     InstanceIdType vniValue) {
155         final MapRequestBuilder mapRequestBuilder = new MapRequestBuilder();
156         final EidItemBuilder eidItemBuilder = new EidItemBuilder();
157         Eid dstEid = toEid(siteToEidPrefix, vniValue, IP_MASK);
158
159         eidItemBuilder.setEid(dstEid);
160         eidItemBuilder.setEidItemId(siteFromEidPrefix + siteToEidPrefix);
161         final List<EidItem> eidItem = Collections.singletonList(eidItemBuilder.build());
162         final Eid srcEid = MappingServiceIntegrationTestUtil.removePrefixIfNecessary(
163                 toEid(siteFromEidPrefix, vniValue, IP_MASK));
164         mapRequestBuilder.setSourceEid(new SourceEidBuilder().setEid(srcEid).build());
165         mapRequestBuilder.setEidItem(eidItem);
166         mapRequestBuilder.setItrRloc(MappingServiceIntegrationTestUtil.getDefaultItrRlocList(
167                 LispAddressUtil.asIpv4Rloc(ourAddress)));
168         mapRequestBuilder.setSmrInvoked(false);
169         return lms.handleMapRequest(mapRequestBuilder.build());
170     }
171
172     void storeNorthMappingNegative(final Site dstSite, final MappingRecord.Action action) {
173         final Eid eidAsIpv4Prefix = LispAddressUtil.asIpv4PrefixBinaryEid(
174                 dstSite.getEidPrefix() + "/" + DEFAULT_NETWORK_MASK, dstSite.getVNI());
175
176         final MappingRecordBuilder mrbNegative = prepareMappingRecord(EidType.EID_WITH_PREFIX, null, dstSite);
177         mrbNegative.setEid(eidAsIpv4Prefix);
178         mrbNegative.setAction(action);
179
180         mapService.addMapping(MappingOrigin.Northbound, eidAsIpv4Prefix, new SiteId(DEFAULT_SITE_ID),
181                 new MappingData(mrbNegative.build()));
182     }
183
184     void deleteNorthMappingNegative(final Site dstSite) {
185         final Eid eidAsIpv4Prefix = LispAddressUtil.asIpv4PrefixBinaryEid(
186                 dstSite.getEidPrefix() + "/" + DEFAULT_NETWORK_MASK, dstSite.getVNI());
187
188         mapService.removeMapping(MappingOrigin.Northbound, eidAsIpv4Prefix);
189     }
190
191     void storeNorthMappingSrcDst(final Site srcSite, final Site ... dstSite) {
192         final MappingRecordBuilder mrb = prepareMappingRecord(EidType.EID_SRC_DST, srcSite,
193                 dstSite);
194         mapService.addMapping(MappingOrigin.Northbound, mrb.getEid(), new SiteId(DEFAULT_SITE_ID),
195                 new MappingData(mrb.build()));
196     }
197
198     void storeNorthMappingIpPrefix(final Site... dstSite) {
199         final MappingRecordBuilder mrb = prepareMappingRecord(EidType.EID_WITH_PREFIX, null, dstSite);
200         mapService.addMapping(MappingOrigin.Northbound, mrb.getEid(),  new SiteId(DEFAULT_SITE_ID),
201                 new MappingData(mrb.build()));
202     }
203
204     private void storeDestinationSiteMappingViaSouthbound(final Site dstSite, final boolean merge) {
205         emitMapRegisterMessage(dstSite, merge);
206     }
207
208     private MappingRecordBuilder prepareMappingRecordGeneral(final EidType eidType,
209                                                              final Site srcSite, final Site dstSite) {
210         final MappingRecordBuilder mrb = provideCommonMapRecordBuilder();
211         mrb.setXtrId(dstSite.getXtrId());
212
213         Eid eid = null;
214         if (EidType.EID_SRC_DST.equals(eidType)) {
215             if (srcSite != null && dstSite != null && srcSite.getEidPrefix() != null && dstSite.getEidPrefix() !=
216                     null) {
217                 eid = LispAddressUtil.asSrcDstEid(srcSite.getEidPrefix(), dstSite.getEidPrefix(), DEFAULT_NETWORK_MASK,
218                         DEFAULT_NETWORK_MASK, dstSite.getVNI().getValue().intValue());
219             }
220         }
221
222         mrb.setEid(eid == null ? toEid(dstSite.getEidPrefix(), dstSite.getVNI(), DEFAULT_NETWORK_MASK) : eid);
223         return mrb;
224     }
225
226     private MappingRecordBuilder prepareMappingRecord(final EidType eidType, final Site srcSite, final Site...
227             dstSites) {
228         assertTrue(isEidEquals(dstSites));
229         final MappingRecordBuilder mrb = prepareMappingRecordGeneral(eidType, srcSite, dstSites[0]);
230         final List<LocatorRecord> locatorRecords = new ArrayList<>();
231         if (!dstSites[0].isForDeletion) {
232             for (Site dstSite : dstSites) {
233                 if (dstSite.getRloc() != null) {
234                     locatorRecords.add(provideLocatorRecord(LispAddressUtil.asIpv4Rloc(dstSite.getRloc()),
235                             dstSite.getRloc(), dstSite.getWeight(), dstSite.getPriority()));
236                 }
237             }
238         }
239         mrb.setLocatorRecord(locatorRecords);
240
241         return mrb;
242     }
243
244     private boolean isEidEquals(final Site... sites) {
245         String commonEid = null;
246         for (Site site : sites) {
247             final String concreteEidPrefix = site.getEidPrefix();
248             if (!concreteEidPrefix.equals(commonEid)) {
249                 if (commonEid == null) {
250                     commonEid = concreteEidPrefix;
251                 } else {
252                     return false;
253                 }
254             }
255         }
256         return true;
257     }
258
259     private LocatorRecord provideLocatorRecord(final Rloc rloc, final String rlocStr, final short weight, final short
260             priority) {
261         final LocatorRecordBuilder locatorRecordBuilder = new LocatorRecordBuilder();
262         locatorRecordBuilder.setRloc(rloc);
263         locatorRecordBuilder.setLocatorId(rlocStr);
264         locatorRecordBuilder.setPriority(priority);
265         locatorRecordBuilder.setWeight(weight);
266         locatorRecordBuilder.setMulticastPriority(DEFAULT_MULTICAST_PRIORITY);
267         locatorRecordBuilder.setMulticastWeight(DEFAULT_MULTICAST_WEIGHT);
268         locatorRecordBuilder.setLocalLocator(DEFAULT_LOCAL_LOCATOR);
269         locatorRecordBuilder.setRlocProbed(DEFAULT_RLOC_PROBED);
270         locatorRecordBuilder.setRouted(DEFAULT_ROUTED);
271         return locatorRecordBuilder.build();
272     }
273
274     private MappingRecordBuilder provideCommonMapRecordBuilder() {
275         final MappingRecordBuilder mappingRecordBuilder = new MappingRecordBuilder();
276         mappingRecordBuilder.setRecordTtl(TTL);
277         mappingRecordBuilder.setAction(MappingRecord.Action.NoAction);
278         mappingRecordBuilder.setAuthoritative(true);
279         mappingRecordBuilder.setTimestamp(System.currentTimeMillis());
280         return mappingRecordBuilder;
281     }
282
283     void deleteNorthMapingSrcDst(final Site srcSite, final Site dstSite) {
284         final Eid eid = LispAddressUtil.asSrcDstEid(srcSite.getEidPrefix(), dstSite.getEidPrefix(),
285                 DEFAULT_NETWORK_MASK, DEFAULT_NETWORK_MASK, dstSite.getVNI().getValue().intValue());
286         mapService.removeMapping(MappingOrigin.Northbound, eid);
287     }
288
289     void deleteSouthboundMappings(final Site dstSite) {
290         emitMapRegisterMessage(dstSite, false);
291
292     }
293
294     void storeSouthboundMappings(final boolean merge, final Site ... sites) {
295         for (Site site : sites) {
296             storeDestinationSiteMappingViaSouthbound(site, merge);
297         }
298     }
299
300     boolean isPossibleAssertPingResultImmediately(final boolean expectedPingWorks, final boolean isPartialyWorking,
301                                                   final String  msg) {
302         //ping fail is unwanted. ping definitely failed
303         if (expectedPingWorks && !isPartialyWorking) {
304             fail(msg);
305         }
306
307         //ping fail is wanted. still can fail later
308         if (!expectedPingWorks && isPartialyWorking) {
309             return false;
310         }
311
312         //ping fail is unwanted. still can fail later
313         if (expectedPingWorks && isPartialyWorking) {
314             return false;
315         }
316
317         //ping fail is wanted. ping definitely failed.
318         if (!expectedPingWorks && !isPartialyWorking) {
319             return true;
320         }
321         return false;
322     }
323
324     boolean checkActionAndRloc(final Site dstSite, boolean expectedPingWorks, MapReply mapReplyFromSrcToDst, final
325                                 Site  ... additionalSitesFromMapping) {
326         final MappingRecord mappingRecord = verifyMappingRecord(mapReplyFromSrcToDst);
327         final boolean isNotDroppendSrcDst = !MappingRecord.Action.Drop.equals(mappingRecord.getAction());
328
329         if (isPossibleAssertPingResultImmediately(expectedPingWorks, isNotDroppendSrcDst, "Drop action has appeared " +
330                 "during ping")) {
331             return true;
332         }
333
334         final List<LocatorRecord> locatorRecords = verifyLocatorRecordExists(mappingRecord);
335         for (Site expectedTargetSite : concatenateSites(dstSite, additionalSitesFromMapping)) {
336             boolean expectedTargetFound = false;
337             for (LocatorRecord locatorRecord : locatorRecords) {
338                 if (expectedTargetSite.getRloc().equals(rlocToString(locatorRecord))) {
339                     final byte[] ipv4AddressSrcDst = verifyIpv4Address(locatorRecord).getValue();
340                     final byte[] rloc = InetAddresses.forString((expectedTargetSite.getRloc())).getAddress();
341                     final boolean isRlocSrcDstEqual = Arrays.equals(ipv4AddressSrcDst, rloc);
342                     if (isPossibleAssertPingResultImmediately(expectedPingWorks, isRlocSrcDstEqual, "Unexpected RLOC." +
343                             "Expected value " + rloc + ". Real value " + ipv4AddressSrcDst +
344                             ".")) {
345                         return true;
346                     }
347
348                     final boolean isWeightEquals = expectedTargetSite.getWeight() == locatorRecord.getWeight();
349                     if (isPossibleAssertPingResultImmediately(expectedPingWorks, isWeightEquals, "Weight isn't equal." +
350                             "Expected value " + expectedTargetSite.getWeight() + ". Value from mapping" +
351                             locatorRecord.getWeight() + ".")) {
352                         return true;
353                     }
354
355                     final boolean isPriorityEquals = expectedTargetSite.getPriority() == locatorRecord.getPriority();
356                     if (isPossibleAssertPingResultImmediately(expectedPingWorks, isPriorityEquals, "Priority isn't " +
357                             "equal. Expected value " + expectedTargetSite.getPriority() + ". Value from mapping" +
358                             locatorRecord.getPriority() + ".")) {
359                         return true;
360                     }
361
362                     expectedTargetFound = true;
363                     break;
364                 }
365             }
366             if (isPossibleAssertPingResultImmediately(expectedPingWorks, expectedTargetFound, "Mapping for " +
367                 expectedTargetSite.getRloc() + " was expected but wasn't returned from mapping service." +
368                 expectedTargetFound)) {
369                 return true;
370             }
371
372         }
373
374         return false;
375     }
376
377     private String rlocToString(final LocatorRecord locatorRecord) {
378         return LispAddressStringifier.getString(locatorRecord.getRloc());
379     }
380
381     private Iterable<Site> concatenateSites(final Site dstSite, final Site... additionalSitesFromMapping) {
382         final List<Site> sites = new ArrayList<>();
383         sites.add(dstSite);
384         for (Site additionalSite : additionalSitesFromMapping) {
385             sites.add(additionalSite);
386         }
387         return sites;
388     }
389
390     private void assertPing(final Site srcSite, final int srcHostIndex, final Site dstSite, final int dstHostIndex,
391                          boolean expectedPingWorks, final Site ... additionalSitesFromMapping) {
392         final MapReply mapReplyFromSrcToDst = emitMapRequestMessage(srcSite.getHost(srcHostIndex), dstSite.getHost
393                 (dstHostIndex), dstSite.getVNI());
394         if (checkActionAndRloc(dstSite, expectedPingWorks, mapReplyFromSrcToDst, additionalSitesFromMapping)) {
395             return;
396         }
397
398         final MapReply mapReplyFromDstToSrc = emitMapRequestMessage(dstSite.getHost(dstHostIndex), srcSite.getHost
399                 (srcHostIndex), srcSite.getVNI());
400         if (checkActionAndRloc(srcSite, expectedPingWorks, mapReplyFromDstToSrc)) {
401             return;
402         }
403
404         final InstanceIdType iidDst = mapReplyFromSrcToDst.getMappingRecordItem().get(0).getMappingRecord().getEid().
405                 getVirtualNetworkId();
406         final InstanceIdType iidSrc = mapReplyFromDstToSrc.getMappingRecordItem().get(0).getMappingRecord().getEid().
407                 getVirtualNetworkId();
408
409         final boolean isIIDEqual = iidDst.equals(iidSrc);
410
411         if (expectedPingWorks != isIIDEqual) {
412             fail("IID problem. Dst value " + iidDst.getValue() + ". Src value " + iidSrc.getValue() + ".");
413         }
414     }
415
416     void assertPingWorks(final Site srcSite, final int srcHostIndex, final Site dstSite, final int dstHostIndex,
417                          final Site ... additionalSitesFromMapping) {
418         assertPing(srcSite, srcHostIndex, dstSite, dstHostIndex, true, additionalSitesFromMapping);
419     }
420
421     void assertPingFails(final Site srcSite, final int srcHostIndex, final Site dstSite, final int dstHostIndex) {
422         assertPing(srcSite, srcHostIndex, dstSite, dstHostIndex, false);
423     }
424
425     private void sleepForSeconds(int seconds) {
426         try {
427             Thread.sleep(seconds * 1000);
428         } catch (InterruptedException e) {
429             LOG.trace("Interrupted while sleeping", e);
430         }
431     }
432
433
434     private List<MapRequest> translateBuffersToMapRequest(byte[][] buffers) {
435         final List<MapRequest> mapRequests = new ArrayList<>();
436         for (byte[] buffer : buffers) {
437             if (isBufferEmpty(buffer)) {
438                 LOG.error("Empty buffer while translating Map-Request");
439                 continue;
440             }
441             final MapRequest mapRequest = MapRequestSerializer.getInstance().deserialize(ByteBuffer.wrap(buffer), null);
442             assertNotNull(mapRequest);
443             mapRequests.add(mapRequest);
444         }
445         return mapRequests;
446     }
447
448     private Set<Eid> prepareExpectedEid(final String ... hosts) {
449         final Set<Eid> eids = new HashSet<>();
450         for (String host : hosts) {
451             eids.add(LispAddressUtil.asIpv4PrefixBinaryEid(host + "/" + IP_MASK,
452                     new InstanceIdType(MultiSiteScenarioUtil.VNI2)));
453         }
454         return eids;
455     }
456
457     private SourceEid prepareSourceEid(final String eidPrefix) {
458         final SourceEidBuilder sourceEidBuilder = new SourceEidBuilder();
459         final Eid eid = LispAddressUtil.asIpv4Eid(eidPrefix, MultiSiteScenarioUtil.VNI2);
460         return sourceEidBuilder.setEid(eid).build();
461     }
462
463     void checkSMR(final SocketReader socketReader, final String site, final String ... hosts) {
464         LOG.debug("\n" + mapService.prettyPrintMappings());
465         byte[][] buffers = socketReader.getBuffers(hosts.length);
466         if (areBuffersEmpty(buffers)) {
467             fail("No SMR received!");
468         }
469         List<MapRequest> mapRequests = translateBuffersToMapRequest(buffers);
470         if (hosts.length != mapRequests.size()) {
471             LOG.error("Expected {} SMRs, received {}", hosts.length, mapRequests.size());
472             fail("Unexpected number of SMRs received");
473         }
474         final Set<Eid> eids = prepareExpectedEid(hosts);
475         final SourceEid expectedSourceEid = prepareSourceEid(site);
476         for(MapRequest mapRequest : mapRequests) {
477             LOG.trace("Map-Request: {}", mapRequest);
478             assertTrue(mapRequest.isSmr());
479             final SourceEid receivedSourceEid = mapRequest.getSourceEid();
480             assertEquals(expectedSourceEid, receivedSourceEid);
481             final List<EidItem> currentEidItems = mapRequest.getEidItem();
482             assertNotNull(currentEidItems);
483             assertTrue(SMRContainsExpectedEid(eids, currentEidItems));
484             MappingServiceIntegrationTestUtil.sendSMRInvokedMapRequestMessage(mapRequest, lms);
485         }
486         //all expected eids should be after looping via mapRequests matched.
487         assertTrue("Expected eids wasn't/weren't found " + eids, eids.isEmpty());
488     }
489
490     private boolean SMRContainsExpectedEid(Set<Eid> eids, List<EidItem> currentEidItems) {
491         for (EidItem eidItem : currentEidItems) {
492             //if eid from map request is matched then it is removed from set of expected eids
493             if (!eids.remove(eidItem.getEid())) {
494                  fail("SMR contained EID `" + LispAddressStringifier.getString(eidItem.getEid())
495                          + "' which wasn't expected.");
496             }
497         }
498         return true;
499     }
500
501     private static boolean isBufferEmpty(byte[] buffer) {
502         for (byte b : buffer) {
503             if (b != 0) {
504                 return false;
505             }
506         }
507         return true;
508     }
509
510     protected static boolean areBuffersEmpty(byte[][] buffers) {
511         for (byte[] buffer : buffers) {
512             if (!isBufferEmpty(buffer)) {
513                 return false;
514             }
515         }
516         return true;
517     }
518 }