/*
 * Copyright 2017-present Open Networking Foundation
 *
 * 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.segmentrouting;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import org.junit.Before;
import org.junit.Test;
import org.onlab.packet.IpAddress;
import org.onlab.packet.IpPrefix;
import org.onlab.packet.MacAddress;
import org.onlab.packet.VlanId;
import org.onosproject.net.config.ConfigApplyDelegate;
import org.onosproject.net.ConnectPoint;
import org.onosproject.net.DefaultHost;
import org.onosproject.net.DeviceId;
import org.onosproject.net.Host;
import org.onosproject.net.HostId;
import org.onosproject.net.HostLocation;
import org.onosproject.net.PortNumber;
import org.onosproject.net.config.NetworkConfigRegistryAdapter;
import org.onosproject.net.flow.TrafficTreatment;
import org.onosproject.net.host.HostEvent;
import org.onosproject.net.host.HostService;
import org.onosproject.net.intf.Interface;
import org.onosproject.net.provider.ProviderId;
import org.onosproject.routeservice.ResolvedRoute;
import org.onosproject.routeservice.Route;
import org.onosproject.routeservice.RouteEvent;
import org.onosproject.segmentrouting.config.DeviceConfiguration;
import org.onosproject.segmentrouting.config.SegmentRoutingDeviceConfig;
import org.onosproject.store.service.StorageService;
import org.onosproject.store.service.TestConsistentMap;
import org.onosproject.store.service.TestConsistentMultimap;

import java.util.Map;
import java.util.Set;

import static org.easymock.EasyMock.expect;
import static org.easymock.EasyMock.reset;
import static org.junit.Assert.*;
import static org.easymock.EasyMock.createMock;
import static org.easymock.EasyMock.expectLastCall;
import static org.easymock.EasyMock.replay;
import static org.easymock.EasyMock.verify;

/**
 * Unit test for {@link RouteHandler}.
 */
public class RouteHandlerTest {
    private SegmentRoutingManager srManager;
    private RouteHandler routeHandler;
    private HostService hostService;

    // Mocked routing and bridging tables
    private static final Map<MockBridgingTableKey, MockBridgingTableValue> BRIDGING_TABLE =
            Maps.newConcurrentMap();
    private static final Map<MockRoutingTableKey, MockRoutingTableValue> ROUTING_TABLE =
            Maps.newConcurrentMap();
    private static final Map<ConnectPoint, Set<IpPrefix>> SUBNET_TABLE = Maps.newConcurrentMap();
    // Mocked Next Id
    private static final Map<Integer, TrafficTreatment> NEXT_TABLE = Maps.newConcurrentMap();
    private static final Map<IpPrefix, Set<ResolvedRoute>> ROUTE_STORE = Maps.newConcurrentMap();

    private static final IpPrefix P1 = IpPrefix.valueOf("10.0.0.0/24");

    // Single homed router 1
    private static final IpAddress N1 = IpAddress.valueOf("10.0.1.254");
    private static final MacAddress M1 = MacAddress.valueOf("00:00:00:00:00:01");
    private static final VlanId V1 = VlanId.vlanId((short) 1);
    private static final ConnectPoint CP1 = ConnectPoint.deviceConnectPoint("of:0000000000000001/1");
    private static final Route R1 = new Route(Route.Source.STATIC, P1, N1);
    private static final ResolvedRoute RR1 = new ResolvedRoute(R1, M1, V1);

    // Single homed router 2
    private static final IpAddress N2 = IpAddress.valueOf("10.0.2.254");
    private static final MacAddress M2 = MacAddress.valueOf("00:00:00:00:00:02");
    private static final VlanId V2 = VlanId.vlanId((short) 2);
    private static final ConnectPoint CP2 = ConnectPoint.deviceConnectPoint("of:0000000000000002/2");
    private static final Route R2 = new Route(Route.Source.STATIC, P1, N2);
    private static final ResolvedRoute RR2 = new ResolvedRoute(R2, M2, V2);

    // Dual homed router 1
    private static final IpAddress N3 = IpAddress.valueOf("10.0.3.254");
    private static final MacAddress M3 = MacAddress.valueOf("00:00:00:00:00:03");
    private static final VlanId V3 = VlanId.vlanId((short) 3);
    private static final Route R3 = new Route(Route.Source.STATIC, P1, N3);
    private static final ResolvedRoute RR3 = new ResolvedRoute(R3, M3, V3);

    // Single homed router 3
    private static final IpAddress N4 = IpAddress.valueOf("10.0.4.254");
    private static final MacAddress M4 = MacAddress.valueOf("00:00:00:00:00:04");
    private static final VlanId V4 = VlanId.vlanId((short) 4);
    private static final ConnectPoint CP4 = ConnectPoint.deviceConnectPoint("of:0000000000000004/4");
    private static final Route R4 = new Route(Route.Source.STATIC, P1, N4);
    private static final ResolvedRoute RR4 = new ResolvedRoute(R4, M4, V4);

    // Hosts
    private static final Host H1 = new DefaultHost(ProviderId.NONE, HostId.hostId(M1, V1), M1, V1,
            Sets.newHashSet(new HostLocation(CP1, 0)), Sets.newHashSet(N1), false);
    private static final Host H2 = new DefaultHost(ProviderId.NONE, HostId.hostId(M2, V2), M2, V2,
            Sets.newHashSet(new HostLocation(CP2, 0)), Sets.newHashSet(N2), false);
    private static final Host H3D = new DefaultHost(ProviderId.NONE, HostId.hostId(M3, V3), M3, V3,
            Sets.newHashSet(new HostLocation(CP1, 0), new HostLocation(CP2, 0)), Sets.newHashSet(N3), false);
    private static final Host H3S = new DefaultHost(ProviderId.NONE, HostId.hostId(M3, V3), M3, V3,
            Sets.newHashSet(new HostLocation(CP1, 0)), Sets.newHashSet(N3), false);
    private static final Host H4 = new DefaultHost(ProviderId.NONE, HostId.hostId(M4, V4), M4, V4,
            Sets.newHashSet(new HostLocation(CP4, 0)), Sets.newHashSet(N4), false);

    // Pair Local Port
    private static final PortNumber P9 = PortNumber.portNumber(9);

    // A set of hosts
    private static final Set<Host> HOSTS = Sets.newHashSet(H1, H2, H3D, H4);
    private static final Set<Host> HOSTS_ONE_FAIL = Sets.newHashSet(H1, H2, H3S);
    private static final Set<Host> HOSTS_BOTH_FAIL = Sets.newHashSet(H1, H2);
    // A set of devices of which we have mastership
    private static final Set<DeviceId> LOCAL_DEVICES = Sets.newHashSet(CP1.deviceId(), CP2.deviceId());
    // A set of interfaces
    private static final Set<Interface> INTERFACES = Sets.newHashSet();

    @Before
    public void setUp() {
        ObjectMapper mapper = new ObjectMapper();
        ConfigApplyDelegate delegate = config -> { };

        SegmentRoutingDeviceConfig dev1Config = new SegmentRoutingDeviceConfig();
        JsonNode dev1Tree = mapper.createObjectNode();
        dev1Config.init(CP1.deviceId(), "host-handler-test", dev1Tree, mapper, delegate);
        dev1Config.setPairDeviceId(CP2.deviceId()).setPairLocalPort(P9);

        SegmentRoutingDeviceConfig dev2Config = new SegmentRoutingDeviceConfig();
        JsonNode dev2Tree = mapper.createObjectNode();
        dev2Config.init(CP2.deviceId(), "host-handler-test", dev2Tree, mapper, delegate);
        dev2Config.setPairDeviceId(CP1.deviceId()).setPairLocalPort(P9);

        MockNetworkConfigRegistry mockNetworkConfigRegistry = new MockNetworkConfigRegistry();
        mockNetworkConfigRegistry.applyConfig(dev1Config);
        mockNetworkConfigRegistry.applyConfig(dev2Config);

        // Initialize Segment Routing Manager
        srManager = new MockSegmentRoutingManager(NEXT_TABLE);
        srManager.storageService = createMock(StorageService.class);
        expect(srManager.storageService.consistentMapBuilder()).andReturn(new TestConsistentMap.Builder<>()).anyTimes();
        expect(srManager.storageService.consistentMultimapBuilder()).andReturn(
                new TestConsistentMultimap.Builder<>()).anyTimes();
        replay(srManager.storageService);
        srManager.cfgService = new NetworkConfigRegistryAdapter();
        srManager.deviceConfiguration = createMock(DeviceConfiguration.class);
        srManager.flowObjectiveService = new MockFlowObjectiveService(BRIDGING_TABLE, NEXT_TABLE);
        srManager.routingRulePopulator = new MockRoutingRulePopulator(srManager, ROUTING_TABLE);
        srManager.defaultRoutingHandler = new MockDefaultRoutingHandler(srManager, SUBNET_TABLE, ROUTING_TABLE);
        srManager.interfaceService = new MockInterfaceService(INTERFACES);
        srManager.mastershipService = new MockMastershipService(LOCAL_DEVICES);
        hostService = new MockHostService(HOSTS);
        srManager.hostService = hostService;
        srManager.cfgService = mockNetworkConfigRegistry;
        srManager.routeService = new MockRouteService(ROUTE_STORE);

        routeHandler = new RouteHandler(srManager);

        ROUTING_TABLE.clear();
        BRIDGING_TABLE.clear();
        SUBNET_TABLE.clear();
    }

    @Test
    public void init() {
        ROUTE_STORE.put(P1, Sets.newHashSet(RR1));

        routeHandler.init(CP1.deviceId());

        assertEquals(1, ROUTING_TABLE.size());
        MockRoutingTableValue rtv1 = ROUTING_TABLE.get(new MockRoutingTableKey(CP1.deviceId(), P1));
        assertEquals(M1, rtv1.macAddress);
        assertEquals(V1, rtv1.vlanId);
        assertEquals(CP1.port(), rtv1.portNumber);

        assertEquals(1, SUBNET_TABLE.size());
        assertTrue(SUBNET_TABLE.get(CP1).contains(P1));
    }

    @Test
    public void initTwoNextHops() {
        ROUTE_STORE.put(P1, Sets.newHashSet(RR1, RR2));

        routeHandler.init(CP1.deviceId());

        assertEquals(2, ROUTING_TABLE.size());
        MockRoutingTableValue rtv1 = ROUTING_TABLE.get(new MockRoutingTableKey(CP1.deviceId(), P1));
        assertEquals(M1, rtv1.macAddress);
        assertEquals(V1, rtv1.vlanId);
        assertEquals(CP1.port(), rtv1.portNumber);
        MockRoutingTableValue rtv2 = ROUTING_TABLE.get(new MockRoutingTableKey(CP2.deviceId(), P1));
        assertEquals(M2, rtv2.macAddress);
        assertEquals(V2, rtv2.vlanId);
        assertEquals(CP2.port(), rtv2.portNumber);

        assertEquals(2, SUBNET_TABLE.size());
        assertTrue(SUBNET_TABLE.get(CP1).contains(P1));
        assertTrue(SUBNET_TABLE.get(CP2).contains(P1));
    }

    @Test
    public void processRouteAdded() {
        reset(srManager.deviceConfiguration);
        srManager.deviceConfiguration.addSubnet(CP1, P1);
        expectLastCall().once();
        replay(srManager.deviceConfiguration);

        RouteEvent re = new RouteEvent(RouteEvent.Type.ROUTE_ADDED, RR1, Sets.newHashSet(RR1));
        routeHandler.processRouteAdded(re);

        assertEquals(1, ROUTING_TABLE.size());
        MockRoutingTableValue rtv1 = ROUTING_TABLE.get(new MockRoutingTableKey(CP1.deviceId(), P1));
        assertEquals(M1, rtv1.macAddress);
        assertEquals(V1, rtv1.vlanId);
        assertEquals(CP1.port(), rtv1.portNumber);

        assertEquals(1, SUBNET_TABLE.size());
        assertTrue(SUBNET_TABLE.get(CP1).contains(P1));

        verify(srManager.deviceConfiguration);
    }

    @Test
    public void processRouteUpdated() {
        processRouteAdded();

        reset(srManager.deviceConfiguration);
        srManager.deviceConfiguration.removeSubnet(CP1, P1);
        expectLastCall().once();
        srManager.deviceConfiguration.addSubnet(CP2, P1);
        expectLastCall().once();
        replay(srManager.deviceConfiguration);

        RouteEvent re = new RouteEvent(RouteEvent.Type.ROUTE_UPDATED, RR2, RR1, Sets.newHashSet(RR2),
                Sets.newHashSet(RR1));
        routeHandler.processRouteUpdated(re);

        // Note: We shouldn't remove the old nexthop during the occasion of route update
        //       since the populate subnet will take care of it and point it to an ECMP group
        assertEquals(2, ROUTING_TABLE.size());
        MockRoutingTableValue rtv2 = ROUTING_TABLE.get(new MockRoutingTableKey(CP2.deviceId(), P1));
        assertEquals(M2, rtv2.macAddress);
        assertEquals(V2, rtv2.vlanId);
        assertEquals(CP2.port(), rtv2.portNumber);

        assertEquals(1, SUBNET_TABLE.size());
        assertTrue(SUBNET_TABLE.get(CP2).contains(P1));

        verify(srManager.deviceConfiguration);
    }

    @Test
    public void processRouteRemoved() {
        processRouteAdded();

        reset(srManager.deviceConfiguration);
        srManager.deviceConfiguration.removeSubnet(CP1, P1);
        expectLastCall().once();
        replay(srManager.deviceConfiguration);

        RouteEvent re = new RouteEvent(RouteEvent.Type.ROUTE_REMOVED, RR1, Sets.newHashSet(RR1));
        routeHandler.processRouteRemoved(re);

        assertEquals(0, ROUTING_TABLE.size());
        assertEquals(0, SUBNET_TABLE.size());

        verify(srManager.deviceConfiguration);
    }

    @Test
    public void testTwoSingleHomedAdded() {
        reset(srManager.deviceConfiguration);
        srManager.deviceConfiguration.addSubnet(CP1, P1);
        expectLastCall().once();
        srManager.deviceConfiguration.addSubnet(CP2, P1);
        expectLastCall().once();
        replay(srManager.deviceConfiguration);

        RouteEvent re = new RouteEvent(RouteEvent.Type.ROUTE_ADDED, RR1, Sets.newHashSet(RR1, RR2));
        routeHandler.processRouteAdded(re);

        assertEquals(2, ROUTING_TABLE.size());
        MockRoutingTableValue rtv1 = ROUTING_TABLE.get(new MockRoutingTableKey(CP1.deviceId(), P1));
        MockRoutingTableValue rtv2 = ROUTING_TABLE.get(new MockRoutingTableKey(CP2.deviceId(), P1));
        assertEquals(M1, rtv1.macAddress);
        assertEquals(M2, rtv2.macAddress);
        assertEquals(V1, rtv1.vlanId);
        assertEquals(V2, rtv2.vlanId);
        assertEquals(CP1.port(), rtv1.portNumber);
        assertEquals(CP2.port(), rtv2.portNumber);

        assertEquals(2, SUBNET_TABLE.size());
        assertTrue(SUBNET_TABLE.get(CP1).contains(P1));
        assertTrue(SUBNET_TABLE.get(CP2).contains(P1));

        verify(srManager.deviceConfiguration);
    }

    @Test
    public void testOneDualHomedAdded() {
        reset(srManager.deviceConfiguration);
        srManager.deviceConfiguration.addSubnet(CP1, P1);
        expectLastCall().once();
        srManager.deviceConfiguration.addSubnet(CP2, P1);
        expectLastCall().once();
        replay(srManager.deviceConfiguration);

        RouteEvent re = new RouteEvent(RouteEvent.Type.ROUTE_ADDED, RR3, Sets.newHashSet(RR3));
        routeHandler.processRouteAdded(re);

        assertEquals(2, ROUTING_TABLE.size());
        MockRoutingTableValue rtv1 = ROUTING_TABLE.get(new MockRoutingTableKey(CP1.deviceId(), P1));
        MockRoutingTableValue rtv2 = ROUTING_TABLE.get(new MockRoutingTableKey(CP2.deviceId(), P1));
        assertEquals(M3, rtv1.macAddress);
        assertEquals(M3, rtv2.macAddress);
        assertEquals(V3, rtv1.vlanId);
        assertEquals(V3, rtv2.vlanId);
        assertEquals(CP1.port(), rtv1.portNumber);
        assertEquals(CP2.port(), rtv2.portNumber);

        assertEquals(2, SUBNET_TABLE.size());
        assertTrue(SUBNET_TABLE.get(CP1).contains(P1));
        assertTrue(SUBNET_TABLE.get(CP2).contains(P1));

        verify(srManager.deviceConfiguration);
    }

    @Test
    public void testOneSingleHomedToTwoSingleHomed() {
        processRouteAdded();

        reset(srManager.deviceConfiguration);
        srManager.deviceConfiguration.addSubnet(CP2, P1);
        expectLastCall().once();
        replay(srManager.deviceConfiguration);

        RouteEvent re = new RouteEvent(RouteEvent.Type.ALTERNATIVE_ROUTES_CHANGED, RR1, null,
                Sets.newHashSet(RR1, RR2), Sets.newHashSet(RR1));
        routeHandler.processAlternativeRoutesChanged(re);

        assertEquals(2, ROUTING_TABLE.size());
        MockRoutingTableValue rtv1 = ROUTING_TABLE.get(new MockRoutingTableKey(CP1.deviceId(), P1));
        MockRoutingTableValue rtv2 = ROUTING_TABLE.get(new MockRoutingTableKey(CP2.deviceId(), P1));
        assertEquals(M1, rtv1.macAddress);
        assertEquals(M2, rtv2.macAddress);
        assertEquals(V1, rtv1.vlanId);
        assertEquals(V2, rtv2.vlanId);
        assertEquals(CP1.port(), rtv1.portNumber);
        assertEquals(CP2.port(), rtv2.portNumber);

        assertEquals(2, SUBNET_TABLE.size());
        assertTrue(SUBNET_TABLE.get(CP1).contains(P1));
        assertTrue(SUBNET_TABLE.get(CP2).contains(P1));

        verify(srManager.deviceConfiguration);
    }

    @Test
    public void testTwoSingleHomedToOneSingleHomed() {
        testTwoSingleHomedAdded();

        reset(srManager.deviceConfiguration);
        srManager.deviceConfiguration.removeSubnet(CP2, P1);
        expectLastCall().once();
        replay(srManager.deviceConfiguration);

        RouteEvent re = new RouteEvent(RouteEvent.Type.ALTERNATIVE_ROUTES_CHANGED, RR1, null,
                Sets.newHashSet(RR1), Sets.newHashSet(RR1, RR2));
        routeHandler.processAlternativeRoutesChanged(re);

        // Note: We shouldn't remove the old nexthop during the occasion of route update
        //       since the populate subnet will take care of it and point it to an ECMP group
        assertEquals(2, ROUTING_TABLE.size());
        MockRoutingTableValue rtv1 = ROUTING_TABLE.get(new MockRoutingTableKey(CP1.deviceId(), P1));
        assertEquals(M1, rtv1.macAddress);
        assertEquals(V1, rtv1.vlanId);
        assertEquals(CP1.port(), rtv1.portNumber);

        assertEquals(1, SUBNET_TABLE.size());
        assertTrue(SUBNET_TABLE.get(CP1).contains(P1));

        verify(srManager.deviceConfiguration);
    }

    // TODO Add test cases for two single homed next hop at same location

    @Test
    public void testDualHomedSingleLocationFail() {
        testOneDualHomedAdded();

        ROUTE_STORE.put(P1, Sets.newHashSet(RR3));

        reset(srManager.deviceConfiguration);
        expect(srManager.deviceConfiguration.getBatchedSubnets(H3D.id()))
                .andReturn(Lists.<Set<IpPrefix>>newArrayList(Sets.newHashSet(P1)));
        srManager.deviceConfiguration.removeSubnet(CP2, P1);
        expectLastCall().once();
        replay(srManager.deviceConfiguration);

        HostEvent he = new HostEvent(HostEvent.Type.HOST_MOVED, H3S, H3D);
        routeHandler.processHostMovedEvent(he);

        // We do not remove the route on CP2. Instead, we let the subnet population overrides it
        assertEquals(2, ROUTING_TABLE.size());
        MockRoutingTableValue rtv1 = ROUTING_TABLE.get(new MockRoutingTableKey(CP1.deviceId(), P1));
        assertEquals(M3, rtv1.macAddress);
        assertEquals(V3, rtv1.vlanId);
        assertEquals(CP1.port(), rtv1.portNumber);

        // ECMP route table hasn't changed
        assertEquals(1, SUBNET_TABLE.size());
        assertTrue(SUBNET_TABLE.get(CP1).contains(P1));

        verify(srManager.deviceConfiguration);
    }

    @Test
    public void testDualHomedBothLocationFail() {
        testDualHomedSingleLocationFail();

        hostService = new MockHostService(HOSTS_ONE_FAIL);

        reset(srManager.deviceConfiguration);
        srManager.deviceConfiguration.removeSubnet(CP1, P1);
        expectLastCall().once();
        srManager.deviceConfiguration.removeSubnet(CP2, P1);
        expectLastCall().once();
        replay(srManager.deviceConfiguration);

        RouteEvent re = new RouteEvent(RouteEvent.Type.ROUTE_REMOVED, RR3, Sets.newHashSet(RR3));
        routeHandler.processRouteRemoved(re);

        assertEquals(0, ROUTING_TABLE.size());
        assertEquals(0, SUBNET_TABLE.size());

        verify(srManager.deviceConfiguration);
    }

    @Test
    public void testSingleHomedToDualHomed() {
        testDualHomedSingleLocationFail();

        reset(srManager.deviceConfiguration);
        expect(srManager.deviceConfiguration.getBatchedSubnets(H3S.id()))
                .andReturn(Lists.<Set<IpPrefix>>newArrayList(Sets.newHashSet(P1)));
        srManager.deviceConfiguration.addSubnet(CP2, P1);
        expectLastCall().once();
        replay(srManager.deviceConfiguration);

        HostEvent he = new HostEvent(HostEvent.Type.HOST_MOVED, H3D, H3S);
        routeHandler.processHostMovedEvent(he);

        assertEquals(2, ROUTING_TABLE.size());
        MockRoutingTableValue rtv1 = ROUTING_TABLE.get(new MockRoutingTableKey(CP1.deviceId(), P1));
        MockRoutingTableValue rtv2 = ROUTING_TABLE.get(new MockRoutingTableKey(CP2.deviceId(), P1));
        assertEquals(M3, rtv1.macAddress);
        assertEquals(M3, rtv2.macAddress);
        assertEquals(V3, rtv1.vlanId);
        assertEquals(V3, rtv2.vlanId);
        assertEquals(CP1.port(), rtv1.portNumber);
        assertEquals(CP2.port(), rtv2.portNumber);

        assertEquals(2, SUBNET_TABLE.size());
        assertTrue(SUBNET_TABLE.get(CP1).contains(P1));
        assertTrue(SUBNET_TABLE.get(CP2).contains(P1));

        verify(srManager.deviceConfiguration);
    }

    @Test
    public void testTwoSingleHomedRemoved() {
        testTwoSingleHomedAdded();

        hostService = new MockHostService(HOSTS_BOTH_FAIL);

        reset(srManager.deviceConfiguration);
        srManager.deviceConfiguration.removeSubnet(CP1, P1);
        expectLastCall().once();
        srManager.deviceConfiguration.removeSubnet(CP2, P1);
        expectLastCall().once();
        replay(srManager.deviceConfiguration);

        RouteEvent re = new RouteEvent(RouteEvent.Type.ROUTE_REMOVED, RR1, Sets.newHashSet(RR1, RR2));
        routeHandler.processRouteRemoved(re);

        assertEquals(0, ROUTING_TABLE.size());
        assertEquals(0, SUBNET_TABLE.size());

        verify(srManager.deviceConfiguration);
    }

    @Test
    public void testOneDualHomeRemoved() {
        testOneDualHomedAdded();

        reset(srManager.deviceConfiguration);
        srManager.deviceConfiguration.removeSubnet(CP1, P1);
        expectLastCall().once();
        srManager.deviceConfiguration.removeSubnet(CP2, P1);
        expectLastCall().once();
        replay(srManager.deviceConfiguration);

        RouteEvent re = new RouteEvent(RouteEvent.Type.ROUTE_REMOVED, RR3, Sets.newHashSet(RR3));
        routeHandler.processRouteRemoved(re);

        assertEquals(0, ROUTING_TABLE.size());
        assertEquals(0, SUBNET_TABLE.size());

        verify(srManager.deviceConfiguration);
    }

    @Test
    public void testMoreThanTwoNextHop() {
        // next hop = CP1, CP2
        reset(srManager.deviceConfiguration);
        srManager.deviceConfiguration.addSubnet(CP1, P1);
        srManager.deviceConfiguration.addSubnet(CP2, P1);
        expectLastCall().once();
        replay(srManager.deviceConfiguration);

        RouteEvent re = new RouteEvent(RouteEvent.Type.ROUTE_ADDED, RR1, Sets.newHashSet(RR1, RR2));
        routeHandler.processRouteAdded(re);

        assertEquals(2, ROUTING_TABLE.size());
        MockRoutingTableValue rtv1 = ROUTING_TABLE.get(new MockRoutingTableKey(CP1.deviceId(), P1));
        assertEquals(M1, rtv1.macAddress);
        assertEquals(V1, rtv1.vlanId);
        assertEquals(CP1.port(), rtv1.portNumber);
        MockRoutingTableValue rtv2 = ROUTING_TABLE.get(new MockRoutingTableKey(CP2.deviceId(), P1));
        assertEquals(M2, rtv2.macAddress);
        assertEquals(V2, rtv2.vlanId);
        assertEquals(CP2.port(), rtv2.portNumber);

        assertEquals(2, SUBNET_TABLE.size());
        assertTrue(SUBNET_TABLE.get(CP1).contains(P1));
        assertTrue(SUBNET_TABLE.get(CP2).contains(P1));

        verify(srManager.deviceConfiguration);

        // next hop = CP1, CP2, CP4 (invalid)
        re = new RouteEvent(RouteEvent.Type.ALTERNATIVE_ROUTES_CHANGED, RR1, null,
                Sets.newHashSet(RR1, RR2, RR4), Sets.newHashSet(RR1, RR2));
        routeHandler.processAlternativeRoutesChanged(re);

        assertEquals(2, ROUTING_TABLE.size());
        rtv1 = ROUTING_TABLE.get(new MockRoutingTableKey(CP1.deviceId(), P1));
        assertEquals(M1, rtv1.macAddress);
        assertEquals(V1, rtv1.vlanId);
        assertEquals(CP1.port(), rtv1.portNumber);
        rtv2 = ROUTING_TABLE.get(new MockRoutingTableKey(CP2.deviceId(), P1));
        assertEquals(M2, rtv2.macAddress);
        assertEquals(V2, rtv2.vlanId);
        assertEquals(CP2.port(), rtv2.portNumber);

        assertEquals(2, SUBNET_TABLE.size());
        assertTrue(SUBNET_TABLE.get(CP1).contains(P1));
        assertTrue(SUBNET_TABLE.get(CP2).contains(P1));

        // next hop = CP2, CP4
        reset(srManager.deviceConfiguration);
        srManager.deviceConfiguration.addSubnet(CP2, P1);
        srManager.deviceConfiguration.addSubnet(CP4, P1);
        expectLastCall().once();
        replay(srManager.deviceConfiguration);

        re = new RouteEvent(RouteEvent.Type.ALTERNATIVE_ROUTES_CHANGED, RR1, null,
                Sets.newHashSet(RR2, RR4), Sets.newHashSet(RR1, RR2, RR4));
        routeHandler.processAlternativeRoutesChanged(re);

        assertEquals(2, ROUTING_TABLE.size());
        rtv1 = ROUTING_TABLE.get(new MockRoutingTableKey(CP2.deviceId(), P1));
        assertEquals(M2, rtv1.macAddress);
        assertEquals(V2, rtv1.vlanId);
        assertEquals(CP2.port(), rtv1.portNumber);
        rtv2 = ROUTING_TABLE.get(new MockRoutingTableKey(CP4.deviceId(), P1));
        assertEquals(M4, rtv2.macAddress);
        assertEquals(V4, rtv2.vlanId);
        assertEquals(CP4.port(), rtv2.portNumber);

        assertEquals(2, SUBNET_TABLE.size());
        assertTrue(SUBNET_TABLE.get(CP2).contains(P1));
        assertTrue(SUBNET_TABLE.get(CP4).contains(P1));

        verify(srManager.deviceConfiguration);
    }
}
