diff --git a/apps/sdnip/src/test/java/org/onosproject/sdnip/SdnIpFibTest.java b/apps/sdnip/src/test/java/org/onosproject/sdnip/SdnIpFibTest.java
new file mode 100644
index 0000000..762ce52
--- /dev/null
+++ b/apps/sdnip/src/test/java/org/onosproject/sdnip/SdnIpFibTest.java
@@ -0,0 +1,643 @@
+/*
+ * Copyright 2015-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.sdnip;
+
+import com.google.common.collect.Lists;
+import com.google.common.collect.Sets;
+import org.junit.Before;
+import org.junit.Test;
+import org.onlab.packet.Ethernet;
+import org.onlab.packet.Ip4Address;
+import org.onlab.packet.Ip4Prefix;
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.IpPrefix;
+import org.onlab.packet.MacAddress;
+import org.onlab.packet.VlanId;
+import org.onosproject.TestApplicationId;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.core.CoreServiceAdapter;
+import org.onosproject.incubator.net.intf.Interface;
+import org.onosproject.incubator.net.intf.InterfaceEvent;
+import org.onosproject.incubator.net.intf.InterfaceListener;
+import org.onosproject.incubator.net.intf.InterfaceService;
+import org.onosproject.incubator.net.intf.InterfaceServiceAdapter;
+import org.onosproject.incubator.net.routing.ResolvedRoute;
+import org.onosproject.incubator.net.routing.RouteEvent;
+import org.onosproject.incubator.net.routing.RouteListener;
+import org.onosproject.incubator.net.routing.RouteServiceAdapter;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.FilteredConnectPoint;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.flow.DefaultTrafficSelector;
+import org.onosproject.net.flow.DefaultTrafficTreatment;
+import org.onosproject.net.flow.TrafficSelector;
+import org.onosproject.net.flow.TrafficTreatment;
+import org.onosproject.net.host.InterfaceIpAddress;
+import org.onosproject.net.intent.AbstractIntentTest;
+import org.onosproject.net.intent.Key;
+import org.onosproject.net.intent.MultiPointToSinglePointIntent;
+import org.onosproject.routing.IntentSynchronizationService;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+
+import static org.easymock.EasyMock.anyObject;
+import static org.easymock.EasyMock.createMock;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.expectLastCall;
+import static org.easymock.EasyMock.replay;
+import static org.easymock.EasyMock.reset;
+import static org.easymock.EasyMock.verify;
+import static org.onosproject.routing.TestIntentServiceHelper.eqExceptId;
+
+/**
+ * Unit tests for SdnIpFib.
+ */
+public class SdnIpFibTest extends AbstractIntentTest {
+
+    private InterfaceService interfaceService;
+
+    private static final ConnectPoint SW1_ETH1 = new ConnectPoint(
+            DeviceId.deviceId("of:0000000000000001"),
+            PortNumber.portNumber(1));
+
+    private static final ConnectPoint SW2_ETH1 = new ConnectPoint(
+            DeviceId.deviceId("of:0000000000000002"),
+            PortNumber.portNumber(1));
+
+    private static final ConnectPoint SW3_ETH1 = new ConnectPoint(
+            DeviceId.deviceId("of:0000000000000003"),
+            PortNumber.portNumber(1));
+
+    private static final ConnectPoint SW4_ETH1 = new ConnectPoint(
+            DeviceId.deviceId("of:0000000000000004"),
+            PortNumber.portNumber(1));
+
+    private static final MacAddress MAC1 = MacAddress.valueOf("00:00:00:00:00:01");
+    private static final MacAddress MAC2 = MacAddress.valueOf("00:00:00:00:00:02");
+    private static final MacAddress MAC3 = MacAddress.valueOf("00:00:00:00:00:03");
+    private static final MacAddress MAC4 = MacAddress.valueOf("00:00:00:00:00:04");
+
+    private static final VlanId NO_VLAN = VlanId.NONE;
+    private static final VlanId VLAN10 = VlanId.vlanId(Short.valueOf("10"));
+    private static final VlanId VLAN20 = VlanId.vlanId(Short.valueOf("20"));
+
+    private static final InterfaceIpAddress IIP1 =
+            InterfaceIpAddress.valueOf("192.168.10.101/24");
+    private static final InterfaceIpAddress IIP2 =
+            InterfaceIpAddress.valueOf("192.168.20.101/24");
+    private static final InterfaceIpAddress IIP3 =
+            InterfaceIpAddress.valueOf("192.168.30.101/24");
+    private static final InterfaceIpAddress IIP4 =
+            InterfaceIpAddress.valueOf("192.168.40.101/24");
+
+    private static final IpAddress IP1 = Ip4Address.valueOf("192.168.10.1");
+    private static final IpAddress IP2 = Ip4Address.valueOf("192.168.20.1");
+    private static final IpAddress IP3 = Ip4Address.valueOf("192.168.30.1");
+
+    private static final IpPrefix PREFIX1 = Ip4Prefix.valueOf("1.1.1.0/24");
+    private static final IpPrefix PREFIX2 = Ip4Prefix.valueOf("1.1.2.0/24");
+
+    private SdnIpFib sdnipFib;
+    private IntentSynchronizationService intentSynchronizer;
+    private final Set<Interface> interfaces = Sets.newHashSet();
+
+    private static final ApplicationId APPID = TestApplicationId.create("SDNIP");
+
+    private RouteListener routeListener;
+    private InterfaceListener interfaceListener;
+
+    @Before
+    public void setUp() throws Exception {
+        super.setUp();
+
+        interfaceService = createMock(InterfaceService.class);
+
+        interfaceService.addListener(anyObject(InterfaceListener.class));
+        expectLastCall().andDelegateTo(new InterfaceServiceDelegate());
+
+        // These will set expectations on routingConfig and interfaceService
+        setUpInterfaceService();
+
+        replay(interfaceService);
+
+        intentSynchronizer = createMock(IntentSynchronizationService.class);
+
+        sdnipFib = new SdnIpFib();
+        sdnipFib.routeService = new TestRouteService();
+        sdnipFib.coreService = new TestCoreService();
+        sdnipFib.interfaceService = interfaceService;
+        sdnipFib.intentSynchronizer = intentSynchronizer;
+
+        sdnipFib.activate();
+    }
+
+    /**
+     * Sets up the interface service.
+     */
+    private void setUpInterfaceService() {
+        List<InterfaceIpAddress> iIps1 = Lists.newArrayList();
+        iIps1.add(IIP1);
+        Interface sw1Eth1 = new Interface("sw1-eth1", SW1_ETH1, iIps1, MAC1, VLAN10);
+        interfaces.add(sw1Eth1);
+
+        List<InterfaceIpAddress> iIps2 = Lists.newArrayList();
+        iIps2.add(IIP2);
+        Interface sw2Eth1 = new Interface("sw2-eth1", SW2_ETH1, iIps2, MAC2, VLAN20);
+        interfaces.add(sw2Eth1);
+
+        List<InterfaceIpAddress> iIps3 = Lists.newArrayList();
+        iIps3.add(IIP3);
+        Interface sw3Eth1 = new Interface("sw3-eth1", SW3_ETH1, iIps3, MAC3, NO_VLAN);
+        interfaces.add(sw3Eth1);
+
+        expect(interfaceService.getInterfacesByPort(SW1_ETH1)).andReturn(
+                Collections.singleton(sw1Eth1)).anyTimes();
+        expect(interfaceService.getMatchingInterface(IP1))
+                .andReturn(sw1Eth1).anyTimes();
+        expect(interfaceService.getInterfacesByPort(SW2_ETH1)).andReturn(
+                Collections.singleton(sw2Eth1)).anyTimes();
+        expect(interfaceService.getMatchingInterface(IP2))
+                .andReturn(sw2Eth1).anyTimes();
+        expect(interfaceService.getInterfacesByPort(SW3_ETH1)).andReturn(
+                Collections.singleton(sw3Eth1)).anyTimes();
+        expect(interfaceService.getMatchingInterface(IP3))
+                .andReturn(sw3Eth1).anyTimes();
+        expect(interfaceService.getInterfaces()).andReturn(interfaces).anyTimes();
+    }
+
+    /**
+     * Tests adding a route. The egress interface has no VLAN configured.
+     *
+     * We verify that the synchronizer records the correct state and that the
+     * correct intent is submitted to the IntentService.
+     */
+    @Test
+    public void testRouteAddToNoVlan() {
+        // Build the expected route
+        ResolvedRoute route = new ResolvedRoute(PREFIX1, IP3, MAC3);
+
+        MultiPointToSinglePointIntent intent =
+                createIntentToThreeSrcOneTwo(PREFIX1);
+
+        // Setup the expected intents
+        intentSynchronizer.submit(eqExceptId(intent));
+        replay(intentSynchronizer);
+
+        // Send in the added event
+        routeListener.event(new RouteEvent(RouteEvent.Type.ROUTE_ADDED, route));
+
+        verify(intentSynchronizer);
+    }
+
+    /**
+     * Tests adding a route. The egress interface has a VLAN configured.
+     *
+     * We verify that the synchronizer records the correct state and that the
+     * correct intent is submitted to the IntentService.
+     */
+    @Test
+    public void testRouteAddToVlan() {
+        // Build the expected route
+        ResolvedRoute route = new ResolvedRoute(PREFIX2, IP1, MAC1);
+
+        MultiPointToSinglePointIntent intent = createIntentToOne(PREFIX2);
+
+        // Setup the expected intents
+        intentSynchronizer.submit(eqExceptId(intent));
+        replay(intentSynchronizer);
+
+        // Send in the added event
+        routeListener.event(new RouteEvent(RouteEvent.Type.ROUTE_ADDED, route));
+
+        verify(intentSynchronizer);
+    }
+
+    /**
+     * Tests updating a route.
+     *
+     * We first add a route from a next-hop with no vlan. We then announce the
+     * same route from another next-hop with a vlan.
+     *
+     * We verify that the synchronizer records the correct state and that the
+     * correct intent is submitted to the IntentService.
+     */
+    @Test
+    public void testRouteUpdatesToVlan() {
+        // Add a route first to a destination with no VLAN
+        testRouteAddToNoVlan();
+
+        // Build the new route entries for prefix1 and prefix2
+        ResolvedRoute routePrefixOne = new ResolvedRoute(PREFIX1, IP1, MAC1);
+
+        // Create the new expected intents
+        MultiPointToSinglePointIntent newPrefixOneIntent = createIntentToOne(PREFIX1);
+
+        // Set up test expectation
+        reset(intentSynchronizer);
+
+        // Setup the expected intents
+        intentSynchronizer.submit(eqExceptId(newPrefixOneIntent));
+        replay(intentSynchronizer);
+
+        // Send in the update events
+        routeListener.event(new RouteEvent(RouteEvent.Type.ROUTE_UPDATED,
+                                           routePrefixOne));
+
+        verify(intentSynchronizer);
+    }
+
+    /**
+     * Tests updating a route.
+     *
+     * We first add a route from a next-hop with a vlan. We then announce the
+     * same route from another next-hop with no vlan.
+     *
+     * We verify that the synchronizer records the correct state and that the
+     * correct intent is submitted to the IntentService.
+     */
+    @Test
+    public void testRouteUpdatesToNoVlan() {
+        // Add a route first to a destination with no VLAN
+        testRouteAddToVlan();
+
+        // Build the new route entries for prefix1 and prefix2
+        ResolvedRoute routePrefix = new ResolvedRoute(PREFIX2, IP3, MAC3);
+
+        // Create the new expected intents
+        MultiPointToSinglePointIntent newPrefixIntent =
+                createIntentToThreeSrcOneTwo(PREFIX2);
+
+        // Set up test expectation
+        reset(intentSynchronizer);
+
+        // Setup the expected intents
+        intentSynchronizer.submit(eqExceptId(newPrefixIntent));
+        replay(intentSynchronizer);
+
+        // Send in the update events
+        routeListener.event(new RouteEvent(RouteEvent.Type.ROUTE_UPDATED,
+                                           routePrefix));
+
+        verify(intentSynchronizer);
+    }
+
+    /**
+     * Tests deleting a route.
+     *
+     * We verify that the synchronizer records the correct state and that the
+     * correct intent is withdrawn from the IntentService.
+     */
+    @Test
+    public void testRouteDelete() {
+        // Add a route first
+        testRouteAddToNoVlan();
+
+        // Construct the existing route entry
+        ResolvedRoute route = new ResolvedRoute(PREFIX1, null, null);
+
+        // Create existing intent
+        MultiPointToSinglePointIntent removedIntent =
+                createIntentToThreeSrcOneTwo(PREFIX1);
+
+        // Set up expectation
+        reset(intentSynchronizer);
+        // Setup the expected intents
+        intentSynchronizer.withdraw(eqExceptId(removedIntent));
+        replay(intentSynchronizer);
+
+        // Send in the removed event
+        routeListener.event(new RouteEvent(RouteEvent.Type.ROUTE_REMOVED, route));
+
+        verify(intentSynchronizer);
+    }
+
+    /**
+     * Tests adding a new interface.
+     *
+     * We verify that the synchronizer records the correct state and that the
+     * correct intent is withdrawn from the IntentService.
+     */
+    @Test
+    public void testAddInterface() {
+        // Add a route first
+        testRouteAddToNoVlan();
+
+        // Create the new expected intent
+        MultiPointToSinglePointIntent addedIntent =
+                createIntentToThreeSrcOneTwoFour(PREFIX1);
+
+        reset(intentSynchronizer);
+
+        intentSynchronizer.submit(eqExceptId(addedIntent));
+        expectLastCall().once();
+
+        replay(intentSynchronizer);
+
+        // Create the new interface and add notify it
+        Interface intf = new Interface("sw4-eth1", SW4_ETH1,
+                                       Collections.singletonList(IIP4),
+                                       MAC4, NO_VLAN);
+        InterfaceEvent intfEvent =
+                new InterfaceEvent(InterfaceEvent.Type.INTERFACE_ADDED, intf);
+
+        interfaceListener.event(intfEvent);
+
+        verify(intentSynchronizer);
+    }
+
+    /**
+     * Tests removing an existing interface.
+     *
+     * We first push an intent with destination sw3 and source sw1 and sw2. We
+     * then remove the ingress interface on sw1.
+     *
+     * We verify that the synchronizer records the correct state and that the
+     * correct intent is withdrawn from the IntentService.
+     */
+    @Test
+    public void testRemoveIngressInterface() {
+        // Add a route first
+        testRouteAddToNoVlan();
+
+        // Create the new expected intent
+        MultiPointToSinglePointIntent remainingIntent =
+                createIntentToThreeSrcTwo(PREFIX1);
+
+        reset(intentSynchronizer);
+
+        intentSynchronizer.submit(eqExceptId(remainingIntent));
+        expectLastCall().once();
+
+        replay(intentSynchronizer);
+
+        // Define the existing ingress interface and remove it
+        Interface intf = new Interface("sw1-eth1", SW1_ETH1,
+                                       Collections.singletonList(IIP1),
+                                       MAC1, VLAN10);
+        InterfaceEvent intfEvent =
+                new InterfaceEvent(InterfaceEvent.Type.INTERFACE_REMOVED, intf);
+        interfaceListener.event(intfEvent);
+
+        verify(intentSynchronizer);
+    }
+
+    /**
+     * Tests removing an existing egress interface.
+     *
+     * We first push an intent with destination sw3 and source sw1 and sw2. We
+     * then remove the egress interface on sw3.
+     *
+     * We verify that the synchronizer records the correct state and that the
+     * correct intent is withdrawn from the IntentService.
+     */
+    @Test
+    public void testRemoveEgressInterface() {
+        // Add a route first
+        testRouteAddToNoVlan();
+
+        // Create existing intent
+        MultiPointToSinglePointIntent removedIntent =
+                createIntentToThreeSrcOneTwo(PREFIX1);
+
+        // Set up expectation
+        reset(intentSynchronizer);
+        // Setup the expected intents
+        intentSynchronizer.withdraw(eqExceptId(removedIntent));
+        replay(intentSynchronizer);
+
+        // Define the existing egress interface and remove it
+        Interface intf = new Interface("sw3-eth1", SW3_ETH1,
+                                       Collections.singletonList(IIP3),
+                                       MAC3, VlanId.NONE);
+        InterfaceEvent intfEvent =
+                new InterfaceEvent(InterfaceEvent.Type.INTERFACE_REMOVED, intf);
+        interfaceListener.event(intfEvent);
+
+        verify(intentSynchronizer);
+    }
+
+    /*
+     * Builds a MultiPointToSinglePointIntent with dest sw1 (VLAN Id) and src
+     * sw2, sw3.
+     */
+    private MultiPointToSinglePointIntent createIntentToOne(IpPrefix ipPrefix) {
+        // Build the expected treatment
+        TrafficTreatment.Builder treatmentBuilder =
+                DefaultTrafficTreatment.builder();
+        treatmentBuilder.setEthDst(MAC1);
+
+        // Build the expected egress FilteredConnectPoint
+        TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
+        selector.matchVlanId(VLAN10);
+        FilteredConnectPoint egressFilteredCP =
+                new FilteredConnectPoint(SW1_ETH1, selector.build());
+
+        // Build the expected selectors
+        Set<FilteredConnectPoint> ingressFilteredCPs = Sets.newHashSet();
+
+        // Build the expected ingress FilteredConnectPoint for sw2
+        selector = DefaultTrafficSelector.builder();
+        selector.matchVlanId(VLAN20);
+        selector.matchEthType(Ethernet.TYPE_IPV4);
+        selector.matchIPDst(ipPrefix);
+        FilteredConnectPoint ingressFilteredCP =
+                new FilteredConnectPoint(SW2_ETH1, selector.build());
+        ingressFilteredCPs.add(ingressFilteredCP);
+
+        // Build the expected ingress FilteredConnectPoint for sw3
+        selector = DefaultTrafficSelector.builder();
+        selector.matchEthType(Ethernet.TYPE_IPV4);
+        selector.matchIPDst(ipPrefix);
+        ingressFilteredCP = new FilteredConnectPoint(SW3_ETH1, selector.build());
+        ingressFilteredCPs.add(ingressFilteredCP);
+
+        // Build the expected intent
+        MultiPointToSinglePointIntent intent =
+                MultiPointToSinglePointIntent.builder()
+                        .appId(APPID)
+                        .key(Key.of(ipPrefix.toString(), APPID))
+                        .filteredIngressPoints(ingressFilteredCPs)
+                        .filteredEgressPoint(egressFilteredCP)
+                        .treatment(treatmentBuilder.build())
+                        .constraints(SdnIpFib.CONSTRAINTS)
+                        .build();
+
+        return intent;
+    }
+
+    /*
+     * Builds a MultiPointToSinglePointIntent with dest sw3 (no VLAN Id) and src
+     * sw1, sw2.
+     */
+    private MultiPointToSinglePointIntent createIntentToThreeSrcOneTwo(IpPrefix ipPrefix) {
+        // Build the expected treatment
+        TrafficTreatment.Builder treatmentBuilder =
+                DefaultTrafficTreatment.builder();
+        treatmentBuilder.setEthDst(MAC3);
+
+        // Build the expected egress FilteredConnectPoint
+        FilteredConnectPoint egressFilteredCP = new FilteredConnectPoint(SW3_ETH1);
+
+        // Build the expected selectors
+        Set<FilteredConnectPoint> ingressFilteredCPs = Sets.newHashSet();
+
+        // Build the expected ingress FilteredConnectPoint for sw1
+        TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
+        selector.matchVlanId(VLAN10);
+        selector.matchEthType(Ethernet.TYPE_IPV4);
+        selector.matchIPDst(ipPrefix);
+        FilteredConnectPoint ingressFilteredCP =
+                new FilteredConnectPoint(SW1_ETH1, selector.build());
+        ingressFilteredCPs.add(ingressFilteredCP);
+
+        // Build the expected ingress FilteredConnectPoint for sw2
+        selector = DefaultTrafficSelector.builder();
+        selector.matchVlanId(VLAN20);
+        selector.matchEthType(Ethernet.TYPE_IPV4);
+        selector.matchIPDst(ipPrefix);
+        ingressFilteredCP = new FilteredConnectPoint(SW2_ETH1, selector.build());
+        ingressFilteredCPs.add(ingressFilteredCP);
+
+        // Build the expected intent
+        MultiPointToSinglePointIntent intent =
+                MultiPointToSinglePointIntent.builder()
+                        .appId(APPID)
+                        .key(Key.of(ipPrefix.toString(), APPID))
+                        .filteredIngressPoints(ingressFilteredCPs)
+                        .filteredEgressPoint(egressFilteredCP)
+                        .treatment(treatmentBuilder.build())
+                        .constraints(SdnIpFib.CONSTRAINTS)
+                        .build();
+
+        return intent;
+    }
+
+    /*
+     * Builds a MultiPointToSinglePointIntent with dest sw3 (no VLAN Id) and src
+     * sw2.
+     */
+    private MultiPointToSinglePointIntent createIntentToThreeSrcTwo(IpPrefix ipPrefix) {
+        // Build the expected treatment
+        TrafficTreatment.Builder treatmentBuilder =
+                DefaultTrafficTreatment.builder();
+        treatmentBuilder.setEthDst(MAC3);
+
+        // Build the expected egress FilteredConnectPoint
+        FilteredConnectPoint egressFilteredCP = new FilteredConnectPoint(SW3_ETH1);
+
+        // Build the expected ingress FilteredConnectPoint for sw2
+        Set<FilteredConnectPoint> ingressFilteredCPs = Sets.newHashSet();
+        TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
+        selector.matchVlanId(VLAN20);
+        selector.matchEthType(Ethernet.TYPE_IPV4);
+        selector.matchIPDst(ipPrefix);
+        FilteredConnectPoint ingressFilteredCP =
+                new FilteredConnectPoint(SW2_ETH1, selector.build());
+        ingressFilteredCPs.add(ingressFilteredCP);
+
+        // Build the expected intent
+        MultiPointToSinglePointIntent intent =
+                MultiPointToSinglePointIntent.builder()
+                        .appId(APPID)
+                        .key(Key.of(ipPrefix.toString(), APPID))
+                        .filteredIngressPoints(ingressFilteredCPs)
+                        .filteredEgressPoint(egressFilteredCP)
+                        .treatment(treatmentBuilder.build())
+                        .constraints(SdnIpFib.CONSTRAINTS)
+                        .build();
+
+        return intent;
+    }
+
+    /*
+     * Builds a MultiPointToSinglePointIntent with dest sw3 (no VLAN Id) and src
+     * sw1, sw2, sw4.
+     */
+    private MultiPointToSinglePointIntent createIntentToThreeSrcOneTwoFour(IpPrefix ipPrefix) {
+        // Build the expected treatment
+        TrafficTreatment.Builder treatmentBuilder =
+                DefaultTrafficTreatment.builder();
+        treatmentBuilder.setEthDst(MAC3);
+
+        // Build the expected egress FilteredConnectPoint
+        FilteredConnectPoint egressFilteredCP = new FilteredConnectPoint(SW3_ETH1);
+
+        // Build the expected selectors
+        Set<FilteredConnectPoint> ingressFilteredCPs = Sets.newHashSet();
+
+        // Build the expected ingress FilteredConnectPoint for sw1
+        TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
+        selector.matchVlanId(VLAN10);
+        selector.matchEthType(Ethernet.TYPE_IPV4);
+        selector.matchIPDst(ipPrefix);
+        FilteredConnectPoint ingressFilteredCP =
+                new FilteredConnectPoint(SW1_ETH1, selector.build());
+        ingressFilteredCPs.add(ingressFilteredCP);
+
+        // Build the expected ingress FilteredConnectPoint for sw2
+        selector = DefaultTrafficSelector.builder();
+        selector.matchVlanId(VLAN20);
+        selector.matchEthType(Ethernet.TYPE_IPV4);
+        selector.matchIPDst(ipPrefix);
+        ingressFilteredCP = new FilteredConnectPoint(SW2_ETH1, selector.build());
+        ingressFilteredCPs.add(ingressFilteredCP);
+
+        // Build the expected ingress FilteredConnectPoint for sw4
+        selector = DefaultTrafficSelector.builder();
+        selector.matchEthType(Ethernet.TYPE_IPV4);
+        selector.matchIPDst(ipPrefix);
+        ingressFilteredCP = new FilteredConnectPoint(SW4_ETH1, selector.build());
+        ingressFilteredCPs.add(ingressFilteredCP);
+
+        // Build the expected intent
+        MultiPointToSinglePointIntent intent =
+                MultiPointToSinglePointIntent.builder()
+                        .appId(APPID)
+                        .key(Key.of(ipPrefix.toString(), APPID))
+                        .filteredIngressPoints(ingressFilteredCPs)
+                        .filteredEgressPoint(egressFilteredCP)
+                        .treatment(treatmentBuilder.build())
+                        .constraints(SdnIpFib.CONSTRAINTS)
+                        .build();
+
+        return intent;
+    }
+
+    private class TestCoreService extends CoreServiceAdapter {
+        @Override
+        public ApplicationId getAppId(String name) {
+            return APPID;
+        }
+    }
+
+    private class TestRouteService extends RouteServiceAdapter {
+        @Override
+        public void addListener(RouteListener routeListener) {
+            SdnIpFibTest.this.routeListener = routeListener;
+        }
+    }
+
+    private class InterfaceServiceDelegate extends InterfaceServiceAdapter {
+        @Override
+        public void addListener(InterfaceListener listener) {
+            SdnIpFibTest.this.interfaceListener = listener;
+        }
+    }
+}
