/*
 * Copyright 2014 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.Sets;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import org.onlab.junit.TestUtils;
import org.onlab.junit.TestUtils.TestUtilsException;
import org.onosproject.core.ApplicationId;
import org.onosproject.net.ConnectPoint;
import org.onosproject.net.DeviceId;
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.Intent;
import org.onosproject.net.intent.IntentOperations;
import org.onosproject.net.intent.IntentService;
import org.onosproject.net.intent.PointToPointIntent;
import org.onosproject.sdnip.bgp.BgpConstants;
import org.onosproject.sdnip.config.BgpPeer;
import org.onosproject.sdnip.config.BgpSpeaker;
import org.onosproject.sdnip.config.Interface;
import org.onosproject.sdnip.config.InterfaceAddress;
import org.onosproject.sdnip.config.SdnIpConfigurationService;
import org.onlab.packet.Ethernet;
import org.onlab.packet.IPv4;
import org.onlab.packet.IpAddress;
import org.onlab.packet.IpPrefix;
import org.onlab.packet.MacAddress;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import static org.easymock.EasyMock.*;

/**
 * Unit tests for PeerConnectivityManager interface.
 */
public class PeerConnectivityManagerTest extends AbstractIntentTest {

    private static final ApplicationId APPID = new ApplicationId() {
        @Override
        public short id() {
            return 0;
        }

        @Override
        public String name() {
            return "foo";
        }
    };

    private PeerConnectivityManager peerConnectivityManager;
    private IntentSynchronizer intentSynchronizer;
    private SdnIpConfigurationService configInfoService;
    private InterfaceService interfaceService;
    private IntentService intentService;

    private Map<String, BgpSpeaker> bgpSpeakers;
    private Map<String, Interface> interfaces;
    private Map<IpAddress, BgpPeer> peers;

    private Map<String, BgpSpeaker> configuredBgpSpeakers;
    private Map<String, Interface> configuredInterfaces;
    private Map<IpAddress, BgpPeer> configuredPeers;
    private List<PointToPointIntent> intentList;

    private final String dpid1 = "00:00:00:00:00:00:00:01";
    private final String dpid2 = "00:00:00:00:00:00:00:02";

    private final DeviceId deviceId1 =
            DeviceId.deviceId(SdnIp.dpidToUri(dpid1));
    private final DeviceId deviceId2 =
            DeviceId.deviceId(SdnIp.dpidToUri(dpid2));

    // Interfaces connected to BGP speakers
    private final ConnectPoint s1Eth100 =
            new ConnectPoint(deviceId1, PortNumber.portNumber(100));
    private final ConnectPoint s2Eth100 =
            new ConnectPoint(deviceId2, PortNumber.portNumber(100));

    // Interfaces connected to BGP peers
    private final ConnectPoint s1Eth1 =
            new ConnectPoint(deviceId1, PortNumber.portNumber(1));
    private final ConnectPoint s2Eth1 =
            new ConnectPoint(deviceId2, PortNumber.portNumber(1));

    private final TrafficTreatment noTreatment =
            DefaultTrafficTreatment.builder().build();

    @Before
    public void setUp() throws Exception {
        super.setUp();
        bgpSpeakers = Collections.unmodifiableMap(setUpBgpSpeakers());
        interfaces = Collections.unmodifiableMap(setUpInterfaces());
        peers = Collections.unmodifiableMap(setUpPeers());

        initPeerConnectivity();
        intentList = setUpIntentList();
    }

    /**
     * Sets up BGP speakers.
     *
     * @return configured BGP speakers as a map from speaker name to speaker
     */
    private Map<String, BgpSpeaker> setUpBgpSpeakers() {

        configuredBgpSpeakers = new HashMap<>();

        BgpSpeaker bgpSpeaker1 = new BgpSpeaker(
                "bgpSpeaker1",
                "00:00:00:00:00:00:00:01", 100,
                "00:00:00:00:00:01");
        List<InterfaceAddress> interfaceAddresses1 =
                new LinkedList<InterfaceAddress>();
        interfaceAddresses1.add(new InterfaceAddress(dpid1, 1, "192.168.10.101"));
        interfaceAddresses1.add(new InterfaceAddress(dpid2, 1, "192.168.20.101"));
        bgpSpeaker1.setInterfaceAddresses(interfaceAddresses1);
        configuredBgpSpeakers.put(bgpSpeaker1.name(), bgpSpeaker1);

        // BGP speaker2 is attached to the same switch port with speaker1
        BgpSpeaker bgpSpeaker2 = new BgpSpeaker(
                "bgpSpeaker2",
                "00:00:00:00:00:00:00:01", 100,
                "00:00:00:00:00:02");
        List<InterfaceAddress> interfaceAddresses2 =
                new LinkedList<InterfaceAddress>();
        interfaceAddresses2.add(new InterfaceAddress(dpid1, 1, "192.168.10.102"));
        interfaceAddresses2.add(new InterfaceAddress(dpid2, 1, "192.168.20.102"));
        bgpSpeaker2.setInterfaceAddresses(interfaceAddresses2);
        configuredBgpSpeakers.put(bgpSpeaker2.name(), bgpSpeaker2);

        BgpSpeaker bgpSpeaker3 = new BgpSpeaker(
                "bgpSpeaker3",
                "00:00:00:00:00:00:00:02", 100,
                "00:00:00:00:00:03");
        List<InterfaceAddress> interfaceAddresses3 =
                new LinkedList<InterfaceAddress>();
        interfaceAddresses3.add(new InterfaceAddress(dpid1, 1, "192.168.10.103"));
        interfaceAddresses3.add(new InterfaceAddress(dpid2, 1, "192.168.20.103"));
        bgpSpeaker3.setInterfaceAddresses(interfaceAddresses3);
        configuredBgpSpeakers.put(bgpSpeaker3.name(), bgpSpeaker3);

        return configuredBgpSpeakers;
    }

    /**
     * Sets up logical interfaces, which emulate the configured interfaces
     * in SDN-IP application.
     *
     * @return configured interfaces as a MAP from Interface name to Interface
     */
    private Map<String, Interface> setUpInterfaces() {

        configuredInterfaces = new HashMap<>();

        String interfaceSw1Eth1 = "s1-eth1";
        InterfaceIpAddress ia1 =
            new InterfaceIpAddress(IpAddress.valueOf("192.168.10.1"),
                                   IpPrefix.valueOf("192.168.10.0/24"));
        Interface intfsw1eth1 = new Interface(s1Eth1,
                Collections.singleton(ia1),
                MacAddress.valueOf("00:00:00:00:00:01"));

        configuredInterfaces.put(interfaceSw1Eth1, intfsw1eth1);
        String interfaceSw2Eth1 = "s2-eth1";
        InterfaceIpAddress ia2 =
            new InterfaceIpAddress(IpAddress.valueOf("192.168.20.2"),
                                   IpPrefix.valueOf("192.168.20.0/24"));
        Interface intfsw2eth1 = new Interface(s2Eth1,
                Collections.singleton(ia2),
                MacAddress.valueOf("00:00:00:00:00:02"));
        configuredInterfaces.put(interfaceSw2Eth1, intfsw2eth1);

        interfaceService = createMock(InterfaceService.class);

        expect(interfaceService.getInterface(s1Eth1))
                .andReturn(intfsw1eth1).anyTimes();
        expect(interfaceService.getInterface(s2Eth1))
                .andReturn(intfsw2eth1).anyTimes();

        // Non-existent interface used during one of the tests
        expect(interfaceService.getInterface(new ConnectPoint(
                    DeviceId.deviceId(SdnIp.dpidToUri("00:00:00:00:00:00:01:00")),
                    PortNumber.portNumber(1))))
                    .andReturn(null).anyTimes();

        expect(interfaceService.getInterfaces()).andReturn(
                Sets.newHashSet(configuredInterfaces.values())).anyTimes();
        replay(interfaceService);

        return configuredInterfaces;
    }

    /**
     * Sets up BGP daemon peers.
     *
     * @return configured BGP peers as a MAP from peer IP address to BgpPeer
     */
    private Map<IpAddress, BgpPeer> setUpPeers() {

        configuredPeers = new HashMap<>();

        String peerSw1Eth1 = "192.168.10.1";
        configuredPeers.put(IpAddress.valueOf(peerSw1Eth1),
                new BgpPeer(dpid1, 1, peerSw1Eth1));

        // Two BGP peers are connected to switch 2 port 1.
        String peer1Sw2Eth1 = "192.168.20.1";
        configuredPeers.put(IpAddress.valueOf(peer1Sw2Eth1),
                new BgpPeer(dpid2, 1, peer1Sw2Eth1));

        String peer2Sw2Eth1 = "192.168.20.2";
        configuredPeers.put(IpAddress.valueOf(peer2Sw2Eth1),
                new BgpPeer(dpid2, 1, peer2Sw2Eth1));

        return configuredPeers;
    }

    /**
     * Sets up expected point to point intent list.
     *
     * @return point to point intent list
     */
    private List<PointToPointIntent> setUpIntentList() {

        intentList = new ArrayList<PointToPointIntent>();

        setUpBgpIntents();
        setUpIcmpIntents();

        return intentList;

    }

    /**
     * Constructs a BGP intent and put it into the intentList.
     * <p/>
     * The purpose of this method is too simplify the setUpBgpIntents() method,
     * and to make the setUpBgpIntents() easy to read.
     *
     * @param srcPrefix source IP prefix to match
     * @param dstPrefix destination IP prefix to match
     * @param srcTcpPort source TCP port to match
     * @param dstTcpPort destination TCP port to match
     * @param srcConnectPoint source connect point for PointToPointIntent
     * @param dstConnectPoint destination connect point for PointToPointIntent
     */
    private void bgpPathintentConstructor(String srcPrefix, String dstPrefix,
            Short srcTcpPort, Short dstTcpPort,
            ConnectPoint srcConnectPoint, ConnectPoint dstConnectPoint) {

        TrafficSelector.Builder builder = DefaultTrafficSelector.builder()
                .matchEthType(Ethernet.TYPE_IPV4)
                .matchIPProtocol(IPv4.PROTOCOL_TCP)
                .matchIPSrc(IpPrefix.valueOf(srcPrefix))
                .matchIPDst(IpPrefix.valueOf(dstPrefix));

        if (srcTcpPort != null) {
            builder.matchTcpSrc(srcTcpPort);
        }
        if (dstTcpPort != null) {
            builder.matchTcpDst(dstTcpPort);
        }

        PointToPointIntent intent = new PointToPointIntent(
                APPID, builder.build(), noTreatment,
                srcConnectPoint, dstConnectPoint);

        intentList.add(intent);
    }

    /**
     * Sets up intents for BGP paths.
     */
    private void setUpBgpIntents() {

        Short bgpPort = Short.valueOf((short) BgpConstants.BGP_PORT);

        // Start to build intents between BGP speaker1 and BGP peer1
        bgpPathintentConstructor(
                "192.168.10.101/32", "192.168.10.1/32", null, bgpPort,
                s1Eth100, s1Eth1);
        bgpPathintentConstructor(
                "192.168.10.101/32", "192.168.10.1/32", bgpPort, null,
                s1Eth100, s1Eth1);

        bgpPathintentConstructor(
                "192.168.10.1/32", "192.168.10.101/32", null, bgpPort,
                s1Eth1, s1Eth100);
        bgpPathintentConstructor(
                "192.168.10.1/32", "192.168.10.101/32", bgpPort, null,
                s1Eth1, s1Eth100);

        // Start to build intents between BGP speaker1 and BGP peer2
        bgpPathintentConstructor(
                "192.168.20.101/32", "192.168.20.1/32", null, bgpPort,
                s1Eth100, s2Eth1);
        bgpPathintentConstructor(
                "192.168.20.101/32", "192.168.20.1/32", bgpPort, null,
                s1Eth100, s2Eth1);

        bgpPathintentConstructor(
                "192.168.20.1/32", "192.168.20.101/32", null, bgpPort,
                s2Eth1, s1Eth100);
        bgpPathintentConstructor(
                "192.168.20.1/32", "192.168.20.101/32", bgpPort, null,
                s2Eth1, s1Eth100);

        // Start to build intents between BGP speaker1 and BGP peer3
        bgpPathintentConstructor(
                "192.168.20.101/32", "192.168.20.2/32", null, bgpPort,
                s1Eth100, s2Eth1);
        bgpPathintentConstructor(
                "192.168.20.101/32", "192.168.20.2/32", bgpPort, null,
                s1Eth100, s2Eth1);

        bgpPathintentConstructor(
                "192.168.20.2/32", "192.168.20.101/32", null, bgpPort,
                s2Eth1, s1Eth100);
        bgpPathintentConstructor(
                "192.168.20.2/32", "192.168.20.101/32", bgpPort, null,
                s2Eth1, s1Eth100);

        //
        // Start to build intents between BGP speaker2 and BGP peer1
        bgpPathintentConstructor(
                "192.168.10.102/32", "192.168.10.1/32", null, bgpPort,
                s1Eth100, s1Eth1);
        bgpPathintentConstructor(
                "192.168.10.102/32", "192.168.10.1/32", bgpPort, null,
                s1Eth100, s1Eth1);

        bgpPathintentConstructor(
                "192.168.10.1/32", "192.168.10.102/32", null, bgpPort,
                s1Eth1, s1Eth100);
        bgpPathintentConstructor(
                "192.168.10.1/32", "192.168.10.102/32", bgpPort, null,
                s1Eth1, s1Eth100);
        // Start to build intents between BGP speaker2 and BGP peer2
        bgpPathintentConstructor(
                "192.168.20.102/32", "192.168.20.1/32", null, bgpPort,
                s1Eth100, s2Eth1);
        bgpPathintentConstructor(
                "192.168.20.102/32", "192.168.20.1/32", bgpPort, null,
                s1Eth100, s2Eth1);

        bgpPathintentConstructor(
                "192.168.20.1/32", "192.168.20.102/32", null, bgpPort,
                s2Eth1, s1Eth100);
        bgpPathintentConstructor(
                "192.168.20.1/32", "192.168.20.102/32", bgpPort, null,
                s2Eth1, s1Eth100);

        // Start to build intents between BGP speaker2 and BGP peer3
        bgpPathintentConstructor(
                "192.168.20.102/32", "192.168.20.2/32", null, bgpPort,
                s1Eth100, s2Eth1);
        bgpPathintentConstructor(
                "192.168.20.102/32", "192.168.20.2/32", bgpPort, null,
                s1Eth100, s2Eth1);

        bgpPathintentConstructor(
                "192.168.20.2/32", "192.168.20.102/32", null, bgpPort,
                s2Eth1, s1Eth100);
        bgpPathintentConstructor(
                "192.168.20.2/32", "192.168.20.102/32", bgpPort, null,
                s2Eth1, s1Eth100);

        //
        // Start to build intents between BGP speaker3 and BGP peer1
        bgpPathintentConstructor(
                "192.168.10.103/32", "192.168.10.1/32", null, bgpPort,
                s2Eth100, s1Eth1);
        bgpPathintentConstructor(
                "192.168.10.103/32", "192.168.10.1/32", bgpPort, null,
                s2Eth100, s1Eth1);

        bgpPathintentConstructor(
                "192.168.10.1/32", "192.168.10.103/32", null, bgpPort,
                s1Eth1, s2Eth100);
        bgpPathintentConstructor(
                "192.168.10.1/32", "192.168.10.103/32", bgpPort, null,
                s1Eth1, s2Eth100);

        // Start to build intents between BGP speaker3 and BGP peer2
        bgpPathintentConstructor(
                "192.168.20.103/32", "192.168.20.1/32", null, bgpPort,
                s2Eth100, s2Eth1);
        bgpPathintentConstructor(
                "192.168.20.103/32", "192.168.20.1/32", bgpPort, null,
                s2Eth100, s2Eth1);

        bgpPathintentConstructor(
                "192.168.20.1/32", "192.168.20.103/32", null, bgpPort,
                s2Eth1, s2Eth100);
        bgpPathintentConstructor(
                "192.168.20.1/32", "192.168.20.103/32", bgpPort, null,
                s2Eth1, s2Eth100);

        // Start to build intents between BGP speaker3 and BGP peer3
        bgpPathintentConstructor(
                "192.168.20.103/32", "192.168.20.2/32", null, bgpPort,
                s2Eth100, s2Eth1);
        bgpPathintentConstructor(
                "192.168.20.103/32", "192.168.20.2/32", bgpPort, null,
                s2Eth100, s2Eth1);

        bgpPathintentConstructor(
                "192.168.20.2/32", "192.168.20.103/32", null, bgpPort,
                s2Eth1, s2Eth100);
        bgpPathintentConstructor(
                "192.168.20.2/32", "192.168.20.103/32", bgpPort, null,
                s2Eth1, s2Eth100);
    }

    /**
     * Constructs a BGP intent and put it into the intentList.
     * <p/>
     * The purpose of this method is too simplify the setUpBgpIntents() method,
     * and to make the setUpBgpIntents() easy to read.
     *
     * @param srcPrefix source IP prefix to match
     * @param dstPrefix destination IP prefix to match
     * @param srcConnectPoint source connect point for PointToPointIntent
     * @param dstConnectPoint destination connect point for PointToPointIntent
     */
    private void icmpPathintentConstructor(String srcPrefix, String dstPrefix,
            ConnectPoint srcConnectPoint, ConnectPoint dstConnectPoint) {

        TrafficSelector selector = DefaultTrafficSelector.builder()
                .matchEthType(Ethernet.TYPE_IPV4)
                .matchIPProtocol(IPv4.PROTOCOL_ICMP)
                .matchIPSrc(IpPrefix.valueOf(srcPrefix))
                .matchIPDst(IpPrefix.valueOf(dstPrefix))
                .build();

        PointToPointIntent intent = new PointToPointIntent(
                APPID, selector, noTreatment,
                srcConnectPoint, dstConnectPoint);

        intentList.add(intent);
    }

    /**
     * Sets up intents for ICMP paths.
     */
    private void setUpIcmpIntents() {

        // Start to build intents between BGP speaker1 and BGP peer1
        icmpPathintentConstructor(
                "192.168.10.101/32", "192.168.10.1/32", s1Eth100, s1Eth1);
        icmpPathintentConstructor(
                "192.168.10.1/32", "192.168.10.101/32", s1Eth1, s1Eth100);

        // Start to build intents between BGP speaker1 and BGP peer2
        icmpPathintentConstructor(
                "192.168.20.101/32", "192.168.20.1/32", s1Eth100, s2Eth1);
        icmpPathintentConstructor(
                "192.168.20.1/32", "192.168.20.101/32", s2Eth1, s1Eth100);

        // Start to build intents between BGP speaker1 and BGP peer3
        icmpPathintentConstructor(
                "192.168.20.101/32", "192.168.20.2/32", s1Eth100, s2Eth1);
        icmpPathintentConstructor(
                "192.168.20.2/32", "192.168.20.101/32", s2Eth1, s1Eth100);

        //
        // Start to build intents between BGP speaker2 and BGP peer1
        icmpPathintentConstructor(
                "192.168.10.102/32", "192.168.10.1/32", s1Eth100, s1Eth1);
        icmpPathintentConstructor(
                "192.168.10.1/32", "192.168.10.102/32", s1Eth1, s1Eth100);

        // Start to build intents between BGP speaker2 and BGP peer2
        icmpPathintentConstructor(
                "192.168.20.102/32", "192.168.20.1/32", s1Eth100, s2Eth1);
        icmpPathintentConstructor(
                "192.168.20.1/32", "192.168.20.102/32", s2Eth1, s1Eth100);

        // Start to build intents between BGP speaker2 and BGP peer3
        icmpPathintentConstructor(
                "192.168.20.102/32", "192.168.20.2/32", s1Eth100, s2Eth1);
        icmpPathintentConstructor(
                "192.168.20.2/32", "192.168.20.102/32", s2Eth1, s1Eth100);

        //
        // Start to build intents between BGP speaker3 and BGP peer1
        icmpPathintentConstructor(
                "192.168.10.103/32", "192.168.10.1/32", s2Eth100, s1Eth1);
        icmpPathintentConstructor(
                "192.168.10.1/32", "192.168.10.103/32", s1Eth1, s2Eth100);

        // Start to build intents between BGP speaker3 and BGP peer2
        icmpPathintentConstructor(
                "192.168.20.103/32", "192.168.20.1/32", s2Eth100, s2Eth1);
        icmpPathintentConstructor(
                "192.168.20.1/32", "192.168.20.103/32", s2Eth1, s2Eth100);

        // Start to build intents between BGP speaker3 and BGP peer3
        icmpPathintentConstructor(
                "192.168.20.103/32", "192.168.20.2/32", s2Eth100, s2Eth1);
        icmpPathintentConstructor(
                "192.168.20.2/32", "192.168.20.103/32", s2Eth1, s2Eth100);

    }

    /**
     * Initializes peer connectivity testing environment.
     *
     * @throws TestUtilsException if exceptions when using TestUtils
     */
    private void initPeerConnectivity() throws TestUtilsException {

        configInfoService = createMock(SdnIpConfigurationService.class);
        expect(configInfoService.getBgpPeers()).andReturn(peers).anyTimes();
        expect(configInfoService.getBgpSpeakers()).andReturn(bgpSpeakers).anyTimes();
        replay(configInfoService);

        intentService = createMock(IntentService.class);
        replay(intentService);

        intentSynchronizer = new IntentSynchronizer(APPID, intentService);
        intentSynchronizer.leaderChanged(true);
        TestUtils.setField(intentSynchronizer, "isActivatedLeader", true);

        peerConnectivityManager =
            new PeerConnectivityManager(APPID, intentSynchronizer,
                                        configInfoService, interfaceService);
    }

    /**
     * Tests whether peer connectivity manager can set up correct BGP and
     * ICMP intents according to specific configuration.
     * <p/>
     * Two tricky cases included in the configuration are: 2 peers on a same
     * switch port, peer on the same switch with BGPd.
     */
    @Test
    public void testConnectionSetup() {

        reset(intentService);

        // Setup the expected intents
        IntentOperations.Builder builder = IntentOperations.builder(APPID);
        for (Intent intent : intentList) {
            builder.addSubmitOperation(intent);
        }
        intentService.execute(TestIntentServiceHelper.eqExceptId(
                                builder.build()));
        replay(intentService);

        // Running the interface to be tested.
        peerConnectivityManager.start();

        verify(intentService);

    }

    /**
     *  Tests a corner case, when there are no interfaces in the configuration.
     */
    @Test
    public void testNullInterfaces() {
        reset(interfaceService);
        expect(interfaceService.getInterfaces()).andReturn(
                Sets.<Interface>newHashSet()).anyTimes();
        expect(interfaceService.getInterface(s2Eth1))
                .andReturn(null).anyTimes();
        expect(interfaceService.getInterface(s1Eth1))
        .andReturn(null).anyTimes();
        replay(interfaceService);

        reset(configInfoService);
        expect(configInfoService.getBgpPeers()).andReturn(peers).anyTimes();
        expect(configInfoService.getBgpSpeakers()).andReturn(bgpSpeakers).anyTimes();
        replay(configInfoService);

        reset(intentService);
        IntentOperations.Builder builder = IntentOperations.builder(APPID);
        intentService.execute(builder.build());
        replay(intentService);
        peerConnectivityManager.start();
        verify(intentService);
    }

    /**
     *  Tests a corner case, when there are no BGP peers in the configuration.
     */
    @Test
    public void testNullBgpPeers() {
        reset(interfaceService);
        expect(interfaceService.getInterfaces()).andReturn(
                Sets.newHashSet(interfaces.values())).anyTimes();
        replay(interfaceService);

        reset(configInfoService);
        expect(configInfoService.getBgpPeers()).andReturn(
                new HashMap<IpAddress, BgpPeer>()).anyTimes();
        expect(configInfoService.getBgpSpeakers()).andReturn(
                bgpSpeakers).anyTimes();
        replay(configInfoService);

        reset(intentService);
        IntentOperations.Builder builder = IntentOperations.builder(APPID);
        intentService.execute(builder.build());
        replay(intentService);
        peerConnectivityManager.start();
        verify(intentService);
    }

    /**
     *  Tests a corner case, when there is no BGP speakers in the configuration.
     */
    @Test
    public void testNullBgpSpeakers() {
        reset(interfaceService);
        expect(interfaceService.getInterfaces()).andReturn(
                Sets.newHashSet(interfaces.values())).anyTimes();
        replay(interfaceService);

        reset(configInfoService);
        expect(configInfoService.getBgpPeers()).andReturn(
                peers).anyTimes();
        expect(configInfoService.getBgpSpeakers()).andReturn(
                null).anyTimes();
        replay(configInfoService);

        reset(intentService);
        replay(intentService);
        peerConnectivityManager.start();
        verify(intentService);
    }

    /**
     * Tests a corner case, when there is no Interface configured for one BGP
     * peer.
     */
    @Test
    public void testNoPeerInterface() {
        String peerSw100Eth1 = "192.168.200.1";
        configuredPeers.put(IpAddress.valueOf(peerSw100Eth1),
                new BgpPeer("00:00:00:00:00:00:01:00", 1, peerSw100Eth1));
        testConnectionSetup();
    }

    /**
     * Tests a corner case, when there is no Interface configured for one BGP
     * speaker.
     * TODO: we should add a configuration correctness checking module/method
     * before testing this corner case.
     */
    @Ignore
    @Test
    public void testNoSpeakerInterface() {
        BgpSpeaker bgpSpeaker100 = new BgpSpeaker(
                "bgpSpeaker100",
                "00:00:00:00:00:00:01:00", 100,
                "00:00:00:00:01:00");
        List<InterfaceAddress> interfaceAddresses100 =
                new LinkedList<InterfaceAddress>();
        interfaceAddresses100.add(new InterfaceAddress(dpid1, 1, "192.168.10.201"));
        interfaceAddresses100.add(new InterfaceAddress(dpid2, 1, "192.168.20.201"));
        bgpSpeaker100.setInterfaceAddresses(interfaceAddresses100);
        configuredBgpSpeakers.put(bgpSpeaker100.name(), bgpSpeaker100);
        testConnectionSetup();
    }
}
