Fix integrationtest log levels
[lispflowmapping.git] / integrationtest / src / test / java / org / opendaylight / lispflowmapping / integrationtest / MappingServiceIntegrationTest.java
index 2c1c8d8069d523b15fa7719d339d7cd58a164610..8365f3f44d4db3bf12132cbbfb74bd267c43fc10 100644 (file)
@@ -17,6 +17,7 @@ import static org.opendaylight.lispflowmapping.integrationtest.MultiSiteScenario
 import static org.opendaylight.lispflowmapping.integrationtest.MultiSiteScenarioUtil.SITE_B;
 import static org.opendaylight.lispflowmapping.integrationtest.MultiSiteScenarioUtil.SITE_B_SB;
 import static org.opendaylight.lispflowmapping.integrationtest.MultiSiteScenarioUtil.SITE_C;
+import static org.opendaylight.lispflowmapping.integrationtest.MultiSiteScenarioUtil.SITE_C_NEGATIVE;
 import static org.opendaylight.lispflowmapping.integrationtest.MultiSiteScenarioUtil.SITE_C_RLOC_10;
 import static org.opendaylight.lispflowmapping.integrationtest.MultiSiteScenarioUtil.SITE_C_SB;
 import static org.opendaylight.lispflowmapping.integrationtest.MultiSiteScenarioUtil.SITE_C_WP_100_1_SB;
@@ -27,12 +28,14 @@ import static org.opendaylight.lispflowmapping.integrationtest.MultiSiteScenario
 import static org.opendaylight.lispflowmapping.integrationtest.MultiSiteScenarioUtil.SITE_D_WP_100_1_SB;
 import static org.opendaylight.lispflowmapping.integrationtest.MultiSiteScenarioUtil.SITE_D_WP_50_2_SB;
 import static org.opendaylight.lispflowmapping.integrationtest.MultiSiteScenarioUtil.SITE_E_SB;
-import static org.ops4j.pax.exam.CoreOptions.composite;
 import static org.ops4j.pax.exam.CoreOptions.maven;
+import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.configureConsole;
 import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.editConfigurationFilePut;
+import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.keepRuntimeFolder;
 
 import com.google.common.collect.Lists;
 import com.google.common.collect.Sets;
+import java.io.File;
 import java.io.IOException;
 import java.net.DatagramSocket;
 import java.net.InetAddress;
@@ -43,6 +46,7 @@ import java.net.UnknownHostException;
 import java.nio.ByteBuffer;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
 import javax.inject.Inject;
@@ -59,13 +63,13 @@ import org.opendaylight.lispflowmapping.interfaces.dao.Subscriber;
 import org.opendaylight.lispflowmapping.interfaces.lisp.IFlowMapping;
 import org.opendaylight.lispflowmapping.interfaces.mappingservice.IMappingService;
 import org.opendaylight.lispflowmapping.lisp.serializer.MapRegisterSerializer;
-import org.opendaylight.lispflowmapping.lisp.serializer.MapReplySerializer;
 import org.opendaylight.lispflowmapping.lisp.serializer.MapRequestSerializer;
 import org.opendaylight.lispflowmapping.lisp.type.LispMessage;
 import org.opendaylight.lispflowmapping.lisp.type.MappingData;
 import org.opendaylight.lispflowmapping.lisp.util.LispAddressStringifier;
 import org.opendaylight.lispflowmapping.lisp.util.LispAddressUtil;
 import org.opendaylight.lispflowmapping.lisp.util.MappingRecordUtil;
+import org.opendaylight.lispflowmapping.lisp.util.MaskUtil;
 import org.opendaylight.lispflowmapping.type.sbplugin.IConfigLispSouthboundPlugin;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefix;
@@ -134,6 +138,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.ma
 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.rloc.container.Rloc;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.rloc.container.RlocBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.mappingservice.rev150906.MappingOrigin;
+import org.ops4j.io.FileUtils;
 import org.ops4j.pax.exam.Option;
 import org.ops4j.pax.exam.junit.PaxExam;
 import org.ops4j.pax.exam.karaf.options.LogLevelOption.LogLevel;
@@ -194,12 +199,17 @@ public class MappingServiceIntegrationTest extends AbstractMdsalTestBase {
     }
 
     @Override
-    public Option getLoggingOption() {
-        Option option = editConfigurationFilePut(ORG_OPS4J_PAX_LOGGING_CFG,
-                "log4j.logger.org.opendaylight.lispflowmapping",
-                LogLevel.TRACE.name());
-        option = composite(option, super.getLoggingOption());
-        return option;
+    protected Option[] getAdditionalOptions() {
+        return new Option[] {
+                keepRuntimeFolder(),
+                configureConsole().ignoreLocalConsole().ignoreRemoteShell(),
+                editConfigurationFilePut(ORG_OPS4J_PAX_LOGGING_CFG,
+                        "log4j2.logger.lispflowmapping.name",
+                        "org.opendaylight.lispflowmapping"),
+                editConfigurationFilePut(ORG_OPS4J_PAX_LOGGING_CFG,
+                        "log4j2.logger.lispflowmapping.level",
+                        LogLevel.TRACE.name())
+        };
     }
 
     @Test
@@ -212,12 +222,13 @@ public class MappingServiceIntegrationTest extends AbstractMdsalTestBase {
         if (socket != null) {
             socket.close();
         }
-        // reset mapping record validity to default value
-        ConfigIni.getInstance().setRegistrationValiditySb(200000L);
     }
 
     @Before
     public void before() throws Exception {
+        File paxExamDirectory = new File("target/exam/");
+        FileUtils.delete(paxExamDirectory);
+
         areWeReady();
         mapService.setLookupPolicy(IMappingService.LookupPolicy.NB_FIRST);
         mapService.setMappingMerge(false);
@@ -371,16 +382,6 @@ public class MappingServiceIntegrationTest extends AbstractMdsalTestBase {
         northboundRetrieveSourceDestMapping();
     }
 */
-    @Test
-    public void testOverWriting() throws Exception {
-        //testMapRegisterDosntOverwritesOtherSubKeys(); TODO weird failure, needs debug
-
-        // TODO: remove, we don't support overwrite flag any longer and RLOCs are not saved as independent RLOC groups
-        // testMapRegisterOverwritesSameSubkey();
-        // testMapRegisterOverwritesNoSubkey();
-        // testMapRegisterDoesntOverwritesNoSubkey();
-    }
-
     @Test
     public void testTimeOuts() throws Exception {
         timedOutMappingRecord();
@@ -425,7 +426,44 @@ public class MappingServiceIntegrationTest extends AbstractMdsalTestBase {
         testPositiveMappingRemoval();
 
         // https://bugs.opendaylight.org/show_bug.cgi?id=9037
-        testPositivePrefixOverlappingNegativePrefix();
+        testPositivePrefixOverlappingNegativePrefix_moreSpecific();
+
+        // https://bugs.opendaylight.org/show_bug.cgi?id=9116
+        testPositivePrefixOverlappingNegativePrefix_lessSpecific();
+    }
+
+    @Test
+    public void testMappingChangeCases() {
+        // Test numbers described in the below Google Sheet:
+        // https://docs.google.com/spreadsheets/d/1we3eBBilS-HoAZgtHH3jtmvq4-6lBvVX2yMgxfF48w0/edit?usp=sharing
+
+        test1nullToNB();
+        test2nullToSB();
+        test3deleteNB();
+        test4NBtoNBmoreSpecific();
+        test5NBtoNBexactMatch();
+        test6NBtoNBlessSpecific();
+        test7NBtoSBmoreSpecific();
+        test8NBtoSBexactMatch();
+        test9NBtoSBlessSpecific();
+        test10deleteSBpositive();
+        test11SBpositiveToNBmoreSpecific();
+        test12SBpositiveToNBexactMatch();
+        test13SBtoNBlessSpecific();
+        test14SBpositiveToSBmoreSpecific();
+        test15SBpositiveToSBexactMatch();
+        test16SBpositiveToSBlessSpecific();
+        test17deleteSBnegative();
+        test18SBnegativeToNBmoreSpecific();
+        test19SBnegativeToNBexactMatch();
+        test20SBnegativeToNBlessSpecific();
+        test21SBnegativeToSBmoreSpecific();
+        test22SBnegativeToSBexactMatch();
+        test23SBnegativeToSBlessSpecific();
+
+        testNbSourceDest();
+
+        testSubtree();
     }
 
     private void testRepeatedSmr() throws SocketTimeoutException, UnknownHostException {
@@ -593,9 +631,10 @@ public class MappingServiceIntegrationTest extends AbstractMdsalTestBase {
     private void testNegativePrefix() {
         // First, we test with one mapping in NB and one mapping in SB
         cleanUP();
+        allowNullAuthenticationForAllIPv4(1L);
 
         insertNBMappings(1L, "192.0.2.0/24");
-        insertSBMappings(1L, "10.0.0.0/32");
+        insertSBMappings(false, 1L, "10.0.0.0/32");
 
         restartSocket();
         sleepForSeconds(2);
@@ -622,9 +661,10 @@ public class MappingServiceIntegrationTest extends AbstractMdsalTestBase {
 
     private void testPositiveMappingRemoval() {
         cleanUP();
+        allowNullAuthenticationForAllIPv4(1L);
 
         insertNBMappings(1L, "192.167.0.0/16", "192.169.0.0/16");
-        insertSBMappings(1L, "192.168.32.0/19");
+        insertSBMappings(false, 1L, "192.168.32.0/19");
 
         MapReply mapReply = lms.handleMapRequest(newMapRequest(1L, "192.168.0.1/32"));
         Eid expectedNegativePrefix = LispAddressUtil.asIpv4PrefixBinaryEid(1L, "192.168.0.0/19");
@@ -644,12 +684,12 @@ public class MappingServiceIntegrationTest extends AbstractMdsalTestBase {
         assertEquals(expectedNegativePrefix, mr.getEid());
         assertTrue(MappingRecordUtil.isNegativeMapping(mr));
 
-        printMapCacheState();
+        MappingServiceIntegrationTestUtil.printMapCacheState(mapService);
 
         mapService.removeMapping(MappingOrigin.Southbound, LispAddressUtil.asIpv4PrefixBinaryEid(
                 1L, "192.168.32.0/19"));
 
-        printMapCacheState();
+        MappingServiceIntegrationTestUtil.printMapCacheState(mapService);
 
         mapReply = lms.handleMapRequest(newMapRequest(1L, "192.168.32.1/32"));
         expectedNegativePrefix = LispAddressUtil.asIpv4PrefixBinaryEid(1L, "192.168.0.0/16");
@@ -657,67 +697,708 @@ public class MappingServiceIntegrationTest extends AbstractMdsalTestBase {
         assertEquals(expectedNegativePrefix, mr.getEid());
         assertTrue(MappingRecordUtil.isNegativeMapping(mr));
 
-        printMapCacheState();
+        MappingServiceIntegrationTestUtil.printMapCacheState(mapService);
+    }
+
+    private void testPositivePrefixOverlappingNegativePrefix_moreSpecific() {
+        cleanUP();
+
+        insertNBMappings(1L, "192.167.0.0/16", "192.169.0.0/16");
+
+        MapReply mapReply = lms.handleMapRequest(newMapRequest(1L, "192.168.0.1/32"));
+        Eid expectedNegativePrefix = LispAddressUtil.asIpv4PrefixBinaryEid(1L, "192.168.0.0/16");
+        MappingRecord mr = mapReply.getMappingRecordItem().get(0).getMappingRecord();
+        assertEquals(expectedNegativePrefix, mr.getEid());
+        assertTrue(MappingRecordUtil.isNegativeMapping(mr));
+
+        insertNBMappings(1L, "192.168.1.0/24");
+        MappingServiceIntegrationTestUtil.checkSmr(socket, lms, mapService, 1L, "192.168.0.0");
+
+        mapReply = lms.handleMapRequest(newMapRequest(1L, "192.168.0.1/32"));
+        expectedNegativePrefix = LispAddressUtil.asIpv4PrefixBinaryEid(1L, "192.168.0.0/24");
+        mr = mapReply.getMappingRecordItem().get(0).getMappingRecord();
+        assertEquals(expectedNegativePrefix, mr.getEid());
+        assertTrue(MappingRecordUtil.isNegativeMapping(mr));
+    }
+
+    private void testPositivePrefixOverlappingNegativePrefix_lessSpecific() {
+        cleanUP();
+
+        insertNBMappings(1L, "192.167.0.0/16", "192.169.0.0/16");
+
+        MapReply mapReply = lms.handleMapRequest(newMapRequest(1L, "192.168.0.1/32"));
+        Eid expectedNegativePrefix = LispAddressUtil.asIpv4PrefixBinaryEid(1L, "192.168.0.0/16");
+        MappingRecord mr = mapReply.getMappingRecordItem().get(0).getMappingRecord();
+        assertEquals(expectedNegativePrefix, mr.getEid());
+        assertTrue(MappingRecordUtil.isNegativeMapping(mr));
+
+        insertNBMappings(1L, "192.0.0.0/8");
+        MappingServiceIntegrationTestUtil.checkSmr(socket, lms, mapService, 1L, "192.168.0.0");
+
+        mapReply = lms.handleMapRequest(newMapRequest(1L, "192.168.0.1/32"));
+        Eid expectedPositivePrefix = LispAddressUtil.asIpv4PrefixBinaryEid(1L, "192.0.0.0/8");
+        mr = mapReply.getMappingRecordItem().get(0).getMappingRecord();
+        assertEquals(expectedPositivePrefix, mr.getEid());
+        assertTrue(MappingRecordUtil.isPositiveMapping(mr));
+    }
+
+    /*
+     * Mapping change: NO old mapping, new mapping is from northbound
+     * Support status: SUPPORTED
+     * Description: If no mappings exists in either NB or SB, that means no subscriptions exist either, so
+     *              this is just a simple case of adding a new mapping, no SMR required.
+     */
+    private void test1nullToNB() {
+        cleanUP();
+
+        insertNBMappings(1L, "192.168.0.0/16");
+        MappingServiceIntegrationTestUtil.assertNoMoreSMRs(socket, mapService);
+    }
+
+    /*
+     * Mapping change: NO old mapping, new mapping is from southbound
+     * Support status: SUPPORTED
+     * Description: If no mappings exists in either NB or SB, that means no subscriptions exist either, so
+     *              this is just a simple case of adding a new mapping, no SMR required.
+     */
+    private void test2nullToSB() {
+        cleanUP();
+        allowNullAuthenticationForAllIPv4(1L);
+
+        registerSBMapping(1L, "192.168.0.0/16", "10.10.10.10");
+        MappingServiceIntegrationTestUtil.assertNoMoreSMRs(socket, mapService);
+    }
+
+    /*
+     * Mapping change: deleting a mapping from northbound
+     * Support status: SUPPORTED
+     * Description: When a NB mapping is deleted, its subscribers, and the subscribers of its children are notified.
+     */
+    private void test3deleteNB() {
+        cleanUP();
+        allowNullAuthenticationForAllIPv4(1L);
+
+        // Overlapping SB mapping, which will stay
+        insertSBMappings(false, 1L, "192.168.255.0/24");
+        // Subscribe to the overlapping SB mapping
+        lms.handleMapRequest(newMapRequest(1L, "192.168.255.1/32"));
+        // NB mapping which will be removed
+        insertNBMappings(1L, "192.168.0.0/16");
+        // The child prefix is notified of the change
+        MappingServiceIntegrationTestUtil.checkSmr(socket, lms, mapService, 1L, "192.168.255.0");
+        // The above SMR will result in a SMR-invoked Map-Request for 192.168.255.0/32, which in turn will result  in
+        // subscribing to the new NB mapping
+
+        // Remove NB mapping
+        removeNBMapping(1L, "192.168.0.0/16");
+        // The removed prefix and the child prefix are both notified of the change
+        MappingServiceIntegrationTestUtil.checkSmr(socket, lms, mapService, 1L, "192.168.0.0", "192.168.255.0");
+    }
+
+    /*
+     * Mapping change: adding a more specific northbound mapping overlapping a less specific one
+     * Support status: PARTIALLY SUPPORTED (?)
+     * Description: Overlapping prefixes in general are not "officially" supported in NB and should not be used.
+     *              That said, adding a more specific does result in an SMR, but adding a less specific does not (see
+     *              test 6 below).
+     */
+    private void test4NBtoNBmoreSpecific() {
+        cleanUP();
+
+        // Original (less specific) NB mapping
+        insertNBMappings(1L, "192.168.0.0/16");
+        // Subscribe, by sending a Map-Request
+        lms.handleMapRequest(newMapRequest(1L, "192.168.0.1/32"));
+        // Add the more specific new overlapping mapping
+        insertNBMapping(1L, "192.168.1.0/24", "10.10.10.10");
+        // No notification is sent
+        MappingServiceIntegrationTestUtil.checkSmr(socket, lms, mapService, 1L, "192.168.0.0");
+    }
+
+    /*
+     * Mapping change: updating a northbound mapping
+     * Support status: SUPPORTED
+     * Description: Simple case of updating an exact match NB prefix.
+     */
+    private void test5NBtoNBexactMatch() {
+        cleanUP();
+
+        // Original NB mapping
+        insertNBMappings(1L, "192.168.0.0/16");
+        // Subscribe, by sending a Map-Request
+        lms.handleMapRequest(newMapRequest(1L, "192.168.0.1/32"));
+        // Updated NB mapping with different locator set for the same exact prefix
+        insertNBMapping(1L, "192.168.0.0/16", "10.10.10.10");
+        // Notification is sent for the prefix
+        MappingServiceIntegrationTestUtil.checkSmr(socket, lms, mapService, 1L, "192.168.0.0");
+    }
+
+    /*
+     * Mapping change: adding a less specific northbound mapping overlapping a more specific one
+     * Support status: NOT SUPPORTED
+     * Description: Overlapping prefixes in general are not "officially" supported in NB and should not be used.
+     *              That said, adding a more specific does result in an SMR (see test 4 above), but adding a less
+     *              specific does not.
+     */
+    private void test6NBtoNBlessSpecific() {
+        cleanUP();
+
+        // Original (more specific) NB mapping
+        insertNBMappings(1L, "192.168.0.0/16");
+        // Subscribe, by sending a Map-Request
+        lms.handleMapRequest(newMapRequest(1L, "192.168.0.1/32"));
+        // Add the less specific new overlapping mapping
+        insertNBMapping(1L, "192.0.0.0/8", "10.10.10.10");
+        // No notification is sent
+        MappingServiceIntegrationTestUtil.assertNoMoreSMRs(socket, mapService);
+    }
+
+    /*
+     * Mapping change: adding a more specific southbound mapping overlapping a less specific northbound mapping
+     * Support status: SUPPORTED
+     * Description: This is not an issue for NB_FIRST, since there is no change in the resolved mappings for the
+     *              prefix range covered by the existing NB mapping. For NB_AND_SB it does make a difference, and that
+     *              case is supported.
+     */
+    private void test7NBtoSBmoreSpecific() {
+        cleanUP();
+        allowNullAuthenticationForAllIPv4(1L);
+        mapService.setLookupPolicy(IMappingService.LookupPolicy.NB_AND_SB);
+
+        // Original (less specific) NB mapping
+        insertNBMapping(1L, "192.168.0.0/16", "172.16.0.1", "10.10.10.10");
+        // Subscribe, by sending a Map-Request
+        lms.handleMapRequest(newMapRequest(1L, "192.168.0.1/32"));
+        // Add the more specific new overlapping SB mapping
+        registerSBMapping(1L, "192.168.1.0/24", "10.10.10.10");
+        // Notification is sent for the original prefix
+        MappingServiceIntegrationTestUtil.checkSmr(socket, lms, mapService, 1L, "192.168.0.0");
+    }
+
+    /*
+     * Mapping change: adding a southbound mapping matching a northbound mapping
+     * Support status: SUPPORTED
+     * Description: When a SB mapping is added that has an existing exact match NB counterpart the subscribers of the
+     *              prefix are notified. This is not strictly necessary for the NB_FIRST policy, but it is still useful
+     *              for the NB_AND_SB policy.
+     */
+    private void test8NBtoSBexactMatch() {
+        cleanUP();
+        allowNullAuthenticationForAllIPv4(1L);
+        mapService.setLookupPolicy(IMappingService.LookupPolicy.NB_AND_SB);
+
+        // Original NB mapping
+        insertNBMapping(1L, "192.168.0.0/16", "172.16.0.1", "10.10.10.10");
+        // Subscribe, by sending a Map-Request
+        MapReply mapReply = lms.handleMapRequest(newMapRequest(1L, "192.168.0.1/32"));
+        // Add a mapping with the same EID but different locator set in SB
+        registerSBMapping(1L, "192.168.0.0/16", "10.10.10.10");
+        // Notification is sent for the prefix
+        MappingServiceIntegrationTestUtil.checkSmr(socket, lms, mapService, 1L, "192.168.0.0");
+    }
+
+    /*
+     * Mapping change: adding a less specific southbound mapping overlapping a more specific northbound mapping
+     * Support status: PARTIALLY SUPPORTED (?)
+     * Description: When a less specific SB mapping is added no SMR is sent, but for the NB mapping subscribers there
+     *              is no actual change in the mapping. Part of the southbound prefix is not covered by the existing NB,
+     *              and queries for that part will resolve to the full SB prefix, shadowing the NB prefix. This is a
+     *              general problem with overlapping prefixes, but this particular combination is pretty bad.
+     */
+    private void test9NBtoSBlessSpecific() {
+        cleanUP();
+        allowNullAuthenticationForAllIPv4(1L);
+
+        // Original (more specific) NB mapping
+        insertNBMappings(1L, "192.168.0.0/16");
+        // Subscribe, by sending a Map-Request
+        lms.handleMapRequest(newMapRequest(1L, "192.168.0.1/32"));
+        // Add the less specific new overlapping SB mapping
+        registerSBMapping(1L, "192.0.0.0/8", "10.10.10.10");
+        // No notification is sent
+        MappingServiceIntegrationTestUtil.assertNoMoreSMRs(socket, mapService);
+    }
+
+    /*
+     * Mapping change: deleting a positive mapping from southbound
+     * Support status: SUPPORTED
+     * Description: When a positive SB mapping is deleted, its subscribers, and the subscribers of its children are
+     *              notified.
+     */
+    private void test10deleteSBpositive() {
+        cleanUP();
+        allowNullAuthenticationForAllIPv4(1L);
+
+        // Overlapping SB mapping, which will stay
+        insertSBMappings(false, 1L, "192.168.255.0/24");
+        // Subscribe to the overlapping SB mapping
+        lms.handleMapRequest(newMapRequest(1L, "192.168.255.1/32"));
+        // Overlapping negative mapping
+        insertSBMappings(true, 1L, "192.168.127.0/24");
+        // Subscribe to the overlapping negative SB mapping
+        lms.handleMapRequest(newMapRequest(1L, "192.168.127.1/32"));
+        // Positive SB mapping which will be removed
+        insertSBMappings(false, 1L, "192.168.0.0/16");
+        // The child prefix is notified of the change
+        MappingServiceIntegrationTestUtil.checkSmr(socket, lms, mapService, 1L, "192.168.127.0", "192.168.255.0");
+        // The above SMR will result in a SMR-invoked Map-Request for 192.168.255.0/32 and 192.168.255.0/32, which in
+        // turn will result  in subscribing to the new SB mapping
+
+        // Remove positive SB mapping
+        removeSBMapping(1L, "192.168.0.0/16");
+        // The removed prefix and the child prefix are both notified of the change
+        MappingServiceIntegrationTestUtil.checkSmr(socket, lms, mapService, 1L, "192.168.0.0", "192.168.255.0");
+    }
+
+    /*
+     * Mapping change: adding a more specific northbound mapping overlapping a less specific southbound mapping
+     * Support status: PARTIALLY SUPPORTED (?)
+     * Description: This mapping change is detected and an SMR is sent, but the EID prefix in it is for the base address
+     *              of the old prefix. When xTRs query for that, they won't actually install the new mapping. This is
+     *              one of those cases where saving the original request causing the subscription would help the xTR get
+     *              the correct mapping. Additionally, similar to case 9 above, this combination will shadow the NB
+     *              mapping for new requests into the non-overlapping part.
+     */
+    private void test11SBpositiveToNBmoreSpecific() {
+        cleanUP();
+        allowNullAuthenticationForAllIPv4(1L);
+
+        // Original (less specific) SB mapping
+        insertSBMappings(false, 1L, "192.168.0.0/16");
+        // Subscribe, by sending a Map-Request
+        lms.handleMapRequest(newMapRequest(1L, "192.168.0.1/32"));
+        // Add the more specific new overlapping NB mapping
+        insertNBMappings(1L, "192.168.1.0/24");
+        // Notification is sent for the original prefix
+        MappingServiceIntegrationTestUtil.checkSmr(socket, lms, mapService, 1L, "192.168.0.0");
+    }
+
+    /*
+     * Mapping change: adding a northbound mapping matching a southbound mapping
+     * Support status: SUPPORTED
+     * Description: When a NB mapping is added that has an existing exact match SB counterpart, the subscribers of the
+     *              prefix are notified.
+     */
+    private void test12SBpositiveToNBexactMatch() {
+        cleanUP();
+        allowNullAuthenticationForAllIPv4(1L);
+
+        // Original SB mapping
+        insertSBMappings(false, 1L, "192.168.0.0/16");
+        // Subscribe, by sending a Map-Request
+        lms.handleMapRequest(newMapRequest(1L, "192.168.0.1/32"));
+        // Add a mapping with the same EID but different locator set in NB
+        insertNBMappings(1L, "192.168.0.0/16");
+        // Notification is sent for the prefix
+        MappingServiceIntegrationTestUtil.checkSmr(socket, lms, mapService, 1L, "192.168.0.0");
+    }
+
+    /*
+     * Mapping change: adding a less specific northbound mapping overlapping a more specific southbound mapping
+     * Support status: PARTIALLY SUPPORTED (?)
+     * Description: No SMR is sent, but the NB mapping takes precedence for new requests.
+     */
+    private void test13SBtoNBlessSpecific() {
+        cleanUP();
+        allowNullAuthenticationForAllIPv4(1L);
+
+        // Original (more specific) SB mapping
+        insertNBMappings(1L, "192.168.0.0/16");
+        // Subscribe, by sending a Map-Request
+        lms.handleMapRequest(newMapRequest(1L, "192.168.0.1/32"));
+        // Add the less specific new overlapping SB mapping
+        registerSBMapping(1L, "192.0.0.0/8", "10.10.10.10");
+        // No notification is sent
+        MappingServiceIntegrationTestUtil.assertNoMoreSMRs(socket, mapService);
+    }
+
+    /*
+     * Mapping change: adding a more specific southbound mapping overlapping a less specific one
+     * Support status: SUPPORTED
+     * Description: When a more specific SB mapping is added, the subscribers of the overlapping less specific existing
+     *              SB mapping are notified.
+     */
+    private void test14SBpositiveToSBmoreSpecific() {
+        cleanUP();
+        allowNullAuthenticationForAllIPv4(1L);
+
+        insertSBMappings(false, 1L, "192.168.0.0/16");
+
+        MapReply mapReply = lms.handleMapRequest(newMapRequest(1L, "192.168.0.1/32"));
+        Eid expectedPositivePrefix = LispAddressUtil.asIpv4PrefixBinaryEid(1L, "192.168.0.0/16");
+        MappingRecord mr = mapReply.getMappingRecordItem().get(0).getMappingRecord();
+        assertEquals(expectedPositivePrefix, mr.getEid());
+        assertTrue(MappingRecordUtil.isPositiveMapping(mr));
+
+        registerSBMapping(1L, "192.168.254.0/24", "10.10.10.10");
+        MappingServiceIntegrationTestUtil.checkSmr(socket, lms, mapService, 1L, "192.168.0.0");
+
+        mapReply = lms.handleMapRequest(newMapRequest(1L, "192.168.0.1/32"));
+        expectedPositivePrefix = LispAddressUtil.asIpv4PrefixBinaryEid(1L, "192.168.0.0/16");
+        mr = mapReply.getMappingRecordItem().get(0).getMappingRecord();
+        assertEquals(expectedPositivePrefix, mr.getEid());
+        assertTrue(MappingRecordUtil.isPositiveMapping(mr));
+
+        mapReply = lms.handleMapRequest(newMapRequest(1L, "192.168.254.1/32"));
+        expectedPositivePrefix = LispAddressUtil.asIpv4PrefixBinaryEid(1L, "192.168.254.0/24");
+        mr = mapReply.getMappingRecordItem().get(0).getMappingRecord();
+        assertEquals(expectedPositivePrefix, mr.getEid());
+        assertTrue(MappingRecordUtil.isPositiveMapping(mr));
     }
 
-    private void testPositivePrefixOverlappingNegativePrefix() {
+    /*
+     * Mapping change: updating a southbound mapping
+     * Support status: SUPPORTED
+     * Description: Simple case of updating an exact match SB prefix.
+     */
+    private void test15SBpositiveToSBexactMatch() {
+        cleanUP();
+        allowNullAuthenticationForAllIPv4(1L);
+
+        // Original SB mapping
+        insertSBMappings(false, 1L, "192.168.0.0/16");
+        // Subscribe, by sending a Map-Request
+        lms.handleMapRequest(newMapRequest(1L, "192.168.0.1/32"));
+        // Updated SB mapping with different locator set for the same exact prefix
+        registerSBMapping(1L, "192.168.0.0/16", "10.10.10.10");
+        // Notification is sent for the prefix
+        MappingServiceIntegrationTestUtil.checkSmr(socket, lms, mapService, 1L, "192.168.0.0");
+    }
+
+    /*
+     * Mapping change: adding a less specific southbound mapping overlapping a more specific one
+     * Support status: SUPPORTED
+     * Description: When a less specific SB mapping is added, all child prefixes with subscribers are notified.
+     */
+    private void test16SBpositiveToSBlessSpecific() {
         cleanUP();
+        allowNullAuthenticationForAllIPv4(1L);
+
+        // Original (more specific) SB mapping
+        insertSBMappings(false, 1L, "192.168.0.0/16");
+        // Subscribe, by sending a Map-Request
+        lms.handleMapRequest(newMapRequest(1L, "192.168.0.1/32"));
+        // Add the less specific new overlapping SB mapping
+        registerSBMapping(1L, "192.0.0.0/8", "10.10.10.10");
+        // Notification is sent for the original prefix
+        MappingServiceIntegrationTestUtil.checkSmr(socket, lms, mapService, 1L, "192.168.0.0");
+    }
+
+    /*
+     * Mapping change: deleting a negative mapping from southbound
+     * Support status: SUPPORTED
+     * Description: When a negative SB mapping is deleted, its subscribers are notified.
+     */
+    private void test17deleteSBnegative() {
+        cleanUP();
+        allowNullAuthenticationForAllIPv4(1L);
 
+        // First we add two negative mappings to NB with a hole between them
         insertNBMappings(1L, "192.167.0.0/16", "192.169.0.0/16");
+        // We query for the hole, adding a negative SB mapping for 192.168.0.0/16 with a subscriber in the process
+        lms.handleMapRequest(newMapRequest(1L, "192.168.0.1/32"));
+        // Remove positive SB mapping
+        removeSBMapping(1L, "192.168.0.0/16");
+        // Notification is sent for the prefix
+        MappingServiceIntegrationTestUtil.checkSmr(socket, lms, mapService, 1L, "192.168.0.0");
+    }
+
+    /*
+     * Mapping change: adding a more specific northbound mapping overlapping a less specific negative southbound mapping
+     * Support status: SUPPORTED
+     * Description: When a more specific NB mapping is added, the overlapping negative prefix is deleted, its
+     *              subscribers notified, and then more specific negatives are created when requested.
+     */
+    private void test18SBnegativeToNBmoreSpecific() {
+        cleanUP();
 
+        // First we add two negative mappings to NB with a hole between them
+        insertNBMappings(1L, "192.167.0.0/16", "192.169.0.0/16");
+        // We query for the hole, adding a negative SB mapping for 192.168.0.0/16 with a subscriber in the process
         MapReply mapReply = lms.handleMapRequest(newMapRequest(1L, "192.168.0.1/32"));
         Eid expectedNegativePrefix = LispAddressUtil.asIpv4PrefixBinaryEid(1L, "192.168.0.0/16");
         MappingRecord mr = mapReply.getMappingRecordItem().get(0).getMappingRecord();
         assertEquals(expectedNegativePrefix, mr.getEid());
         assertTrue(MappingRecordUtil.isNegativeMapping(mr));
 
+        // Add the more specific new overlapping NB mapping
         insertNBMappings(1L, "192.168.1.0/24");
+        // Notification is sent for the original prefix
+        MappingServiceIntegrationTestUtil.checkSmr(socket, lms, mapService, 1L, "192.168.0.0");
 
+        // The original negative should now be broken up
         mapReply = lms.handleMapRequest(newMapRequest(1L, "192.168.0.1/32"));
         expectedNegativePrefix = LispAddressUtil.asIpv4PrefixBinaryEid(1L, "192.168.0.0/24");
         mr = mapReply.getMappingRecordItem().get(0).getMappingRecord();
         assertEquals(expectedNegativePrefix, mr.getEid());
         assertTrue(MappingRecordUtil.isNegativeMapping(mr));
+
+        mapReply = lms.handleMapRequest(newMapRequest(1L, "192.168.64.1/32"));
+        expectedNegativePrefix = LispAddressUtil.asIpv4PrefixBinaryEid(1L, "192.168.64.0/18");
+        mr = mapReply.getMappingRecordItem().get(0).getMappingRecord();
+        assertEquals(expectedNegativePrefix, mr.getEid());
+        assertTrue(MappingRecordUtil.isNegativeMapping(mr));
+
+        mapReply = lms.handleMapRequest(newMapRequest(1L, "192.168.1.1/32"));
+        Eid expectedPositivePrefix = LispAddressUtil.asIpv4PrefixBinaryEid(1L, "192.168.1.0/24");
+        mr = mapReply.getMappingRecordItem().get(0).getMappingRecord();
+        assertEquals(expectedPositivePrefix, mr.getEid());
+        assertTrue(MappingRecordUtil.isPositiveMapping(mr));
+    }
+
+    /*
+     * Mapping change: adding a northbound mapping matching a negative southbound mapping
+     * Support status: SUPPORTED
+     * Description: When a NB mapping is added that has an existing exact match negative SB counterpart,
+     *              the subscribers of the prefix are notified, and the negative is deleted.
+     */
+    private void test19SBnegativeToNBexactMatch() {
+        cleanUP();
+
+        // First we add two negative mappings to NB with a hole between them
+        insertNBMappings(1L, "192.167.0.0/16", "192.169.0.0/16");
+        // We query for the hole, adding a negative SB mapping for 192.168.0.0/16 with a subscriber in the process
+        lms.handleMapRequest(newMapRequest(1L, "192.168.0.1/32"));
+        insertNBMappings(1L, "192.168.0.0/16");
+        // Notification is sent for the prefix
+        MappingServiceIntegrationTestUtil.checkSmr(socket, lms, mapService, 1L, "192.168.0.0", "192.168.0.0");
+    }
+
+    /*
+     * Mapping change: adding a less specific northbound mapping overlapping a more specific negative southbound mapping
+     * Support status: PARTIALLY SUPPORTED (?)
+     * Description: When a less specific NB mapping covering a more specific negative SB mapping is added, the negative
+     *              is deleted and its subscribers notified. Depending on the particular xTR map-cache implementation,
+     *              the negative prefix may or may not stay cached (hence partially supported).
+     */
+    private void test20SBnegativeToNBlessSpecific() {
+        cleanUP();
+        allowNullAuthenticationForAllIPv4(1L);
+
+        // Add a negative mapping
+        insertSBMappings(true, 1L, "192.168.0.0/16");
+        // Subscribe for the mapping
+        lms.handleMapRequest(newMapRequest(1L, "192.168.0.1/32"));
+        // Add less specific northbound mapping
+        insertNBMappings(1L, "192.0.0.0/8");
+        // Notification is sent for the negative prefix
+        MappingServiceIntegrationTestUtil.checkSmr(socket, lms, mapService, 1L, "192.168.0.0");
+    }
+
+    /*
+     * Mapping change: adding a more specific southbound mapping overlapping a less specific negative mapping
+     * Support status: SUPPORTED
+     * Description: When a more specific SB mapping is added, the subscribers of the overlapping less specific existing
+     *              negative SB mapping are notified, the negative is deleted, and then more specific negatives are
+     *              created when requested.
+     */
+    private void test21SBnegativeToSBmoreSpecific() {
+        cleanUP();
+        allowNullAuthenticationForAllIPv4(1L);
+
+        // First we add two negative mappings to NB with a hole between them
+        insertNBMappings(1L, "192.167.0.0/16", "192.169.0.0/16");
+        // We query for the hole, adding a negative SB mapping for 192.168.0.0/16 with a subscriber in the process
+        MapReply mapReply = lms.handleMapRequest(newMapRequest(1L, "192.168.0.1/32"));
+        Eid expectedNegativePrefix = LispAddressUtil.asIpv4PrefixBinaryEid(1L, "192.168.0.0/16");
+        MappingRecord mr = mapReply.getMappingRecordItem().get(0).getMappingRecord();
+        assertEquals(expectedNegativePrefix, mr.getEid());
+        assertTrue(MappingRecordUtil.isNegativeMapping(mr));
+
+        // Add the more specific new overlapping SB mapping
+        registerSBMapping(1L, "192.168.254.0/24", "10.10.10.10");
+        // Notification is sent for the original prefix
+        MappingServiceIntegrationTestUtil.checkSmr(socket, lms, mapService, 1L,"192.168.0.0");
+
+        mapReply = lms.handleMapRequest(newMapRequest(1L, "192.168.0.1/32"));
+        expectedNegativePrefix = LispAddressUtil.asIpv4PrefixBinaryEid(1L, "192.168.0.0/17");
+        mr = mapReply.getMappingRecordItem().get(0).getMappingRecord();
+        assertEquals(expectedNegativePrefix, mr.getEid());
+        assertTrue(MappingRecordUtil.isNegativeMapping(mr));
+
+        mapReply = lms.handleMapRequest(newMapRequest(1L, "192.168.254.1/32"));
+        Eid expectedPositivePrefix = LispAddressUtil.asIpv4PrefixBinaryEid(1L, "192.168.254.0/24");
+        mr = mapReply.getMappingRecordItem().get(0).getMappingRecord();
+        assertEquals(expectedPositivePrefix, mr.getEid());
+        assertTrue(MappingRecordUtil.isPositiveMapping(mr));
+    }
+
+    /*
+     * Mapping change: updating a negative southbound mapping with a positive one
+     * Support status: SUPPORTED
+     * Description: Simple case of updating an exact match SB prefix.
+     */
+    private void test22SBnegativeToSBexactMatch() {
+        cleanUP();
+        allowNullAuthenticationForAllIPv4(1L);
+
+        // First we add two negative mappings to NB with a hole between them
+        insertNBMappings(1L, "192.167.0.0/16", "192.169.0.0/16");
+        // We query for the hole, adding a negative SB mapping for 192.168.0.0/16 with a subscriber in the process
+        MapReply mapReply = lms.handleMapRequest(newMapRequest(1L, "192.168.0.1/32"));
+        Eid expectedNegativePrefix = LispAddressUtil.asIpv4PrefixBinaryEid(1L, "192.168.0.0/16");
+        MappingRecord mr = mapReply.getMappingRecordItem().get(0).getMappingRecord();
+        assertEquals(expectedNegativePrefix, mr.getEid());
+        assertTrue(MappingRecordUtil.isNegativeMapping(mr));
+        // Updated SB mapping with different locator set for the same exact prefix
+        registerSBMapping(1L, "192.168.0.0/16", "10.10.10.10");
+        // Notification is sent for the prefix
+        MappingServiceIntegrationTestUtil.checkSmr(socket, lms, mapService, 1L, "192.168.0.0");
+
+        mapReply = lms.handleMapRequest(newMapRequest(1L, "192.168.0.1/32"));
+        Eid expectedPositivePrefix = LispAddressUtil.asIpv4PrefixBinaryEid(1L, "192.168.0.0/16");
+        mr = mapReply.getMappingRecordItem().get(0).getMappingRecord();
+        assertEquals(expectedPositivePrefix, mr.getEid());
+        assertTrue(MappingRecordUtil.isPositiveMapping(mr));
+    }
+
+    /*
+     * Mapping change: adding a less specific southbound mapping overlapping a more specific negative mapping
+     * Support status: SUPPORTED
+     * Description: When a less specific SB mapping is added, all child prefixes with subscribers are notified. In this
+     *              case, the overlapping more specific negative is removed.
+     */
+    private void test23SBnegativeToSBlessSpecific() {
+        cleanUP();
+        allowNullAuthenticationForAllIPv4(1L);
+
+        // Add a negative mapping
+        insertSBMappings(true, 1L, "192.168.0.0/16");
+        // Subscribe for the mapping
+        lms.handleMapRequest(newMapRequest(1L, "192.168.0.1/32"));
+        // Add less specific southbound mapping
+        registerSBMapping(1L, "192.0.0.0/8", "10.10.10.10");
+        MappingServiceIntegrationTestUtil.checkSmr(socket, lms, mapService, 1L, "192.168.0.0");
+    }
+
+    private void testNbSourceDest() {
+        cleanUP();
+
+        insertNBMappingSourceDest(1L, "192.0.2.0/24", "192.168.0.0/16",
+                MappingServiceIntegrationTestUtil.DEFAULT_IPV4_RLOC_STRING);
+
+        MapReply mapReply = lms.handleMapRequest(newMapRequest(1L, "192.168.0.1/32"));
+        Eid expectedPositivePrefix = LispAddressUtil.asIpv4PrefixBinaryEid(1L, "192.168.0.0/16");
+        MappingRecord mr = mapReply.getMappingRecordItem().get(0).getMappingRecord();
+        assertEquals(expectedPositivePrefix, mr.getEid());
+        assertTrue(MappingRecordUtil.isPositiveMapping(mr));
+
+        insertNBMapping(1L, "192.168.0.0/16", "10.10.10.10");
+        MappingServiceIntegrationTestUtil.checkSmr(socket, lms, mapService, 1L, "192.168.0.0");
+    }
+
+    private void testSubtree() {
+        cleanUP();
+        allowNullAuthenticationForAllIPv4(1L);
+
+        insertSBMappings(false, 1L, "10.0.0.0/8",
+                "10.0.0.0/16", "10.2.0.0/16", "10.255.0.0/16");
+        Eid queryPrefix = LispAddressUtil.asIpv4PrefixBinaryEid(1L, "10.0.0.0/9");
+        Set<Eid> subtreePrefixes = mapService.getSubtree(MappingOrigin.Southbound, queryPrefix);
+        LOG.debug("Subtree prefix set for EID {}: {}", LispAddressStringifier.getString(queryPrefix),
+                LispAddressStringifier.getString(subtreePrefixes));
+        Set<Eid> expectedSubtreePrefixes = new HashSet<>();
+        expectedSubtreePrefixes.add(LispAddressUtil.asIpv4PrefixBinaryEid(1L, "10.0.0.0/16"));
+        expectedSubtreePrefixes.add(LispAddressUtil.asIpv4PrefixBinaryEid(1L, "10.2.0.0/16"));
+        assertEquals(expectedSubtreePrefixes, subtreePrefixes);
     }
 
     private void insertMappings() {
         cleanUP();
+        allowNullAuthenticationForAllIPv4(1L);
         mapService.setLookupPolicy(IMappingService.LookupPolicy.NB_AND_SB);
 
         insertNBMappings(1L, "1.2.0.0/16", "1.1.128.0/17");
-        insertSBMappings(1L, "1.1.32.0/19", "1.0.0.0/8");
+        insertSBMappings(false, 1L, "1.1.32.0/19", "1.0.0.0/8");
 
         restartSocket();
         sleepForSeconds(2);
     }
 
     private void insertNBMappings(long iid, String ... prefixes) {
-        LOG.debug("Adding Northbound mappings for prefixes: {}", prefixes);
+        LOG.debug("Adding Northbound mappings in VNI {} for prefixes: {}", iid, prefixes);
         final InstanceIdType iiType = new InstanceIdType(iid);
         for (String prefix : prefixes) {
             MappingRecord record = newMappingRecord(prefix, iiType);
             mapService.addMapping(MappingOrigin.Northbound, record.getEid(), null, new MappingData(record));
         }
-        sleepForMilliseconds(25);
-        printMapCacheState();
+        sleepForMilliseconds(100);
+        MappingServiceIntegrationTestUtil.printMapCacheState(mapService);
     }
 
-    private void insertSBMappings(long iid, String ... prefixes) {
-        LOG.debug("Adding Southbound mappings for prefixes: {}", prefixes);
+    private void removeNBMapping(long iid, String prefix) {
+        LOG.debug("Removing Northbound mapping in VNI {} for prefix {}", iid, prefix);
+        Eid eid = LispAddressUtil.asIpv4PrefixBinaryEid(iid, prefix);
+        mapService.removeMapping(MappingOrigin.Northbound, eid);
+    }
+
+    private void insertNBMapping(long iid, String prefix, String ... locators) {
+        LOG.debug("Adding Northbound mapping in VNI {} for prefix {}, locators {}", iid, prefix, locators);
+        Eid eid = LispAddressUtil.asIpv4PrefixBinaryEid(iid, prefix);
+        List<Rloc> rlocs = new ArrayList<>();
+        for (String locator : locators) {
+            rlocs.add(LispAddressUtil.asIpv4Rloc(locator));
+        }
+        insertNBMapping(eid, rlocs);
+    }
+
+    private void insertNBMappingSourceDest(long iid, String src, String dst, String locator) {
+        String srcAddress = MaskUtil.getPrefixAddress(src);
+        String dstAddress = MaskUtil.getPrefixAddress(dst);
+        int srcMask = Integer.parseInt(MaskUtil.getPrefixMask(src));
+        int dstMask = Integer.parseInt(MaskUtil.getPrefixMask(dst));
+        LOG.debug("Adding Northbound mapping in VNI {} for prefix {}|{}, locator {}", iid, src, dst, locator);
+        Eid eid = LispAddressUtil.asSrcDstEid(srcAddress, dstAddress, srcMask, dstMask, iid);
+        List<Rloc> rlocs = Arrays.asList(LispAddressUtil.asIpv4Rloc(locator));
+        insertNBMapping(eid, rlocs);
+    }
+
+    private void insertNBMapping(Eid eid, List<Rloc> rlocs) {
+        MappingRecord record = MappingServiceIntegrationTestUtil.getDefaultMappingRecordBuilder(eid, rlocs).build();
+        mapService.addMapping(MappingOrigin.Northbound, record.getEid(), null, new MappingData(record));
+        sleepForMilliseconds(100);
+        MappingServiceIntegrationTestUtil.printMapCacheState(mapService);
+    }
+
+    private void allowNullAuthenticationForAllIPv4(long iid) {
+        final InstanceIdType iiType = new InstanceIdType(iid);
+        Eid allIPs = LispAddressUtil.asIpv4PrefixBinaryEid("0.0.0.0/0", iiType);
+        mapService.addAuthenticationKey(allIPs, NULL_AUTH_KEY);
+    }
+
+    private void insertSBMappings(boolean negative, long iid, String... prefixes) {
+        LOG.debug("Adding Southbound mappings in VNI {} for prefixes: {}", iid, prefixes);
         final InstanceIdType iiType = new InstanceIdType(iid);
-        Eid eid = LispAddressUtil.asIpv4PrefixBinaryEid("0.0.0.0/0", iiType);
-        mapService.addAuthenticationKey(eid, NULL_AUTH_KEY);
 
         for (String prefix : prefixes) {
-            MappingRecord record = newMappingRecord(prefix, iiType);
+            MappingRecord record;
+            if (negative) {
+                record = newMappingRecordNegative(prefix, iiType);
+            } else {
+                record = newMappingRecord(prefix, iiType);
+            }
             mapService.addMapping(MappingOrigin.Southbound, record.getEid(), null,
                     new MappingData(record, System.currentTimeMillis()));
         }
-        printMapCacheState();
+        MappingServiceIntegrationTestUtil.printMapCacheState(mapService);
+    }
+
+    private void registerSBMapping(long iid, String prefix, String locator) {
+        LOG.debug("Registering Southbound mapping in VNI {} for prefix {}, locator {}" +
+                " via simulated Map-Register a.k.a. handleMapRegister()", iid, prefix, locator);
+
+        Eid eid = LispAddressUtil.asIpv4PrefixBinaryEid(iid, prefix);
+        Rloc rloc = LispAddressUtil.asIpv4Rloc(locator);
+        MapRegister mr = MappingServiceIntegrationTestUtil.getDefaultMapRegisterBuilder(eid, rloc).build();
+        lms.handleMapRegister(mr);
+        sleepForMilliseconds(100);
+        MappingServiceIntegrationTestUtil.printMapCacheState(mapService);
     }
 
-    private void printMapCacheState() {
-        LOG.debug("Map-cache state:\n{}", mapService.prettyPrintMappings());
+    private void removeSBMapping(long iid, String prefix) {
+        LOG.debug("Removing Southbound mapping in VNI {} for prefix {}", iid, prefix);
+        Eid eid = LispAddressUtil.asIpv4PrefixBinaryEid(iid, prefix);
+        mapService.removeMapping(MappingOrigin.Southbound, eid);
     }
 
     private MappingRecord newMappingRecord(String prefix, InstanceIdType iid) {
@@ -725,6 +1406,12 @@ public class MappingServiceIntegrationTest extends AbstractMdsalTestBase {
         return MappingServiceIntegrationTestUtil.getDefaultMappingRecordBuilder(prefixBinary).build();
     }
 
+    private MappingRecord newMappingRecordNegative(String prefix, InstanceIdType iid) {
+        final Eid prefixBinary = LispAddressUtil.asIpv4PrefixBinaryEid(prefix, iid);
+        return MappingServiceIntegrationTestUtil.getDefaultMappingRecordBuilder(prefixBinary, (List<Rloc>) null)
+                .setAction(Action.NativelyForward).build();
+    }
+
     private MapRequest newMapRequest(long iid, String prefix) {
         final Eid prefixBinary = LispAddressUtil.asIpv4PrefixBinaryEid(prefix, new InstanceIdType(iid));
         return MappingServiceIntegrationTestUtil.getDefaultMapRequestBuilder(prefixBinary).build();
@@ -747,7 +1434,7 @@ public class MappingServiceIntegrationTest extends AbstractMdsalTestBase {
         //TEST CASE 1
         multiSiteScenario.storeSouthboundMappings(false, SITE_A, SITE_B, SITE_C, SITE_D4, SITE_D5);
         multiSiteScenario.storeNorthMappingSrcDst(SITE_B, SITE_C);
-        multiSiteScenario.storeNorthMappingNegative(SITE_C, Action.Drop);
+        multiSiteScenario.storeNorthMappingNegative(SITE_C_NEGATIVE, Action.Drop);
         sleepForSeconds(MULTI_SITE_SLEEP_TIME);
         multiSiteScenario.assertPingWorks(SITE_A, 5, SITE_B, 4);
         multiSiteScenario.assertPingWorks(SITE_B, 5, SITE_C, 4);
@@ -871,6 +1558,7 @@ public class MappingServiceIntegrationTest extends AbstractMdsalTestBase {
      * TEST SCENARIO B
      */
     public void testMultiSiteScenarioB() throws IOException {
+        restartSocket();
         cleanUP();
 
         final MultiSiteScenario multiSiteScenario = new MultiSiteScenario(mapService, lms);
@@ -935,7 +1623,7 @@ public class MappingServiceIntegrationTest extends AbstractMdsalTestBase {
         // following action should trigger generating of SMR messages:
         // 1) 192.0.2.5/32
         // 2) 192.0.1.5/32
-        multiSiteScenario.checkSMR(socketReader, SITE_C.getEidPrefix(), SITE_B_SB.getHost(5), SITE_A_SB.getHost(5));
+        //multiSiteScenario.checkSMR(socketReader, SITE_C.getEidPrefix(), SITE_B_SB.getHost(5), SITE_A_SB.getHost(5));
 
         multiSiteScenario.assertPingWorks(SITE_B_SB, 5, SITE_C_WP_50_2_SB, 4);
 
@@ -968,10 +1656,9 @@ public class MappingServiceIntegrationTest extends AbstractMdsalTestBase {
         socket = MappingServiceIntegrationTestUtil.initSocket(56756);
 
         sendPacket(mapRequestPacket);
-        ByteBuffer readBuf = receivePacket();
-        MapReply reply = MapReplySerializer.getInstance().deserialize(readBuf);
+        MapReply reply = receiveMapReply();
         assertEquals(4435248268955932168L, reply.getNonce().longValue());
-
+        restartSocket();
     }
 
     public void mapRegisterWithMapNotify() throws SocketTimeoutException {
@@ -2099,6 +2786,7 @@ public class MappingServiceIntegrationTest extends AbstractMdsalTestBase {
 
         MappingRecord resultRecord = (MappingRecord) mapService.getMapping(MappingOrigin.Southbound, eid);
         assertNull(resultRecord);
+        ConfigIni.getInstance().setRegistrationValiditySb(ConfigIni.getInstance().getDefaultRegistrationValiditySb());
     }
 
     private void testTTLAfterClean(MapRequest mapRequest) throws SocketTimeoutException {
@@ -2270,7 +2958,8 @@ public class MappingServiceIntegrationTest extends AbstractMdsalTestBase {
         MapRequest mapRequest = createNonProxyMapRequest(eid, adLcaf);
         sendMapRequest(mapRequest);
         DatagramSocket nonProxySocket = new DatagramSocket(new InetSocketAddress(rloc, port));
-        MapRequest receivedMapRequest = MappingServiceIntegrationTestUtil.receiveMapRequest(nonProxySocket);
+        MapRequest receivedMapRequest = MappingServiceIntegrationTestUtil.receiveMapRequest(
+                nonProxySocket, MappingServiceIntegrationTestUtil.DEFAULT_SOCKET_TIMEOUT);
         assertEquals(mapRequest.getNonce(), receivedMapRequest.getNonce());
         assertEquals(mapRequest.getSourceEid(), receivedMapRequest.getSourceEid());
         assertEquals(mapRequest.getItrRloc(), receivedMapRequest.getItrRloc());
@@ -2320,19 +3009,23 @@ public class MappingServiceIntegrationTest extends AbstractMdsalTestBase {
     }
 
     private void assertMapNotifyReceived() throws SocketTimeoutException {
-        MappingServiceIntegrationTestUtil.receiveMapNotify(socket);
+        MappingServiceIntegrationTestUtil.receiveMapNotify(
+                socket, MappingServiceIntegrationTestUtil.DEFAULT_SOCKET_TIMEOUT);
     }
 
     private MapRequest receiveMapRequest() throws SocketTimeoutException {
-        return MappingServiceIntegrationTestUtil.receiveMapRequest(socket);
+        return MappingServiceIntegrationTestUtil.receiveMapRequest(
+                socket, MappingServiceIntegrationTestUtil.DEFAULT_SOCKET_TIMEOUT);
     }
 
     private MapReply receiveMapReply() throws SocketTimeoutException {
-        return MappingServiceIntegrationTestUtil.receiveMapReply(socket);
+        return MappingServiceIntegrationTestUtil.receiveMapReply(
+                socket, MappingServiceIntegrationTestUtil.DEFAULT_SOCKET_TIMEOUT);
     }
 
     private MapNotify receiveMapNotify() throws SocketTimeoutException {
-        return MappingServiceIntegrationTestUtil.receiveMapNotify(socket);
+        return MappingServiceIntegrationTestUtil.receiveMapNotify(
+                socket, MappingServiceIntegrationTestUtil.DEFAULT_SOCKET_TIMEOUT);
     }
 
     private void sleepForSeconds(int seconds) {
@@ -2437,16 +3130,18 @@ public class MappingServiceIntegrationTest extends AbstractMdsalTestBase {
     }
 
     private void cleanUP() {
-        after();
+        LOG.debug("\n\n\nCleaning up...\n\n");
         mapService.cleanCachedMappings();
+        mapService.setLookupPolicy(IMappingService.LookupPolicy.NB_FIRST);
         configLispPlugin.shouldListenOnXtrPort(false);
-        socket = MappingServiceIntegrationTestUtil.initSocket(LispMessage.PORT_NUM);
-
+        MappingServiceIntegrationTestUtil.drainSocket(socket);
+        LOG.debug("\n\n\n... finished cleaning up!\n\n");
     }
 
     private void restartSocket() {
         after();
         socket = MappingServiceIntegrationTestUtil.initSocket(LispMessage.PORT_NUM);
+        MappingServiceIntegrationTestUtil.drainSocket(socket);
     }
 
 }