"""
Copyright 2015 Open Networking Foundation ( ONF )

Please refer questions to either the onos test mailing list at <onos-test@onosproject.org>,
the System Testing Plans and Results wiki page at <https://wiki.onosproject.org/x/voMg>,
or the System Testing Guide page at <https://wiki.onosproject.org/x/WYQg>

    TestON is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 2 of the License, or
    ( at your option ) any later version.

    TestON is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with TestON.  If not, see <http://www.gnu.org/licenses/>.


    Wrapper functions for FuncIntent
    This functions include Onosclidriver and Mininetclidriver driver functions
    Author: kelvin@onlab.us
"""
import time
import json
import os


def __init__( self ):
    self.default = ''

hostIntentFailFlag = False
pointIntentFailFlag = False
singleToMultiFailFlag = False
multiToSingleFailFlag = False


def installHostIntent( main,
                       name,
                       host1,
                       host2,
                       onosNode=0,
                       ethType="",
                       bandwidth="",
                       lambdaAlloc=False,
                       ipProto="",
                       ipAddresses="",
                       tcp="",
                       sw1="",
                       sw2="",
                       setVlan="",
                       encap="" ):
    """
    Installs a Host Intent

    Description:
        Install a host intent using
        add-host-intent

    Steps:
        - Fetch host data if not given
        - Add host intent
            - Ingress device is the first sender host
            - Egress devices are the recipient devices
            - Ports if defined in senders or recipients
            - MAC address ethSrc loaded from Ingress device
        - Check intent state with retry
    Required:
        name - Type of point intent to add eg. IPV4 | VLAN | Dualstack
        host1 - Dictionary for host1
            { "name":"h8", "id":"of:0000000000000005/8" }
        host2 - Dictionary for host2
            { "name":"h16", "id":"of:0000000000000006/8" }
    Optional:
        onosNode - ONOS node to install the intents in main.CLIs[ ]
                   0 by default so that it will always use the first
                   ONOS node
        ethType - Ethernet type eg. IPV4, IPV6
        bandwidth - Bandwidth capacity
        lambdaAlloc - Allocate lambda, defaults to False
        ipProto - IP protocol
        tcp - TCP ports in the same order as the hosts in hostNames
    """
    assert main, "There is no main variable"
    assert host1, "You must specify host1"
    assert host2, "You must specify host2"

    global itemName  # The name of this run. Used for logs.
    itemName = name

    global hostIntentFailFlag
    hostIntentFailFlag = False

    main.log.info( itemName + ": Adding single point to multi point intents" )
    try:
        if not host1.get( "id" ):
            main.log.warn( "ID not given for host1 {0}. Loading from main.hostData".format( host1.get( "name" ) ) )
            main.log.debug( main.hostsData.get( host1.get( "name" ) ) )
            host1[ "id" ] = main.hostsData.get( host1.get( "name" ) ).get( "id" )

        if not host2.get( "id" ):
            main.log.warn( "ID not given for host2 {0}. Loading from main.hostData".format( host2.get( "name" ) ) )
            host2[ "id" ] = main.hostsData.get( host2.get( "name" ) ).get( "id" )

        # Adding point intent
        vlanId = host1.get( "vlan" )
        intentId = main.Cluster.active( onosNode ).CLI.addHostIntent( hostIdOne=host1.get( "id" ),
                                                                      hostIdTwo=host2.get( "id" ),
                                                                      vlanId=vlanId,
                                                                      setVlan=setVlan,
                                                                      encap=encap )
    except( KeyError, TypeError ):
        errorMsg = "There was a problem loading the hosts data."
        if intentId:
            errorMsg += "  There was a problem installing host to host intent."
        main.log.error( errorMsg )
        return main.FALSE

    # Check intents state
    if utilities.retry( f=checkIntentState,
                        retValue=main.FALSE,
                        args=( main, [ intentId ] ),
                        sleep=main.checkIntentSleep,
                        attempts=50 ):
        main.assertReturnString += 'Install Intent State Passed\n'

        # Check VLAN if test encapsulation
        if encap != "":
            if EncapsulatedIntentCheck( main, tag=encap ):
                main.assertReturnString += 'Encapsulation intents check Passed\n'
            else:
                main.assertReturnString += 'Encapsulation intents check failed\n'
        if bandwidth != "":
            allocationsFile = open( os.path.dirname( main.testFile ) + main.params[ 'DEPENDENCY' ][ 'filePath' ], 'r' )
            expectedFormat = allocationsFile.read()
            bandwidthCheck = checkBandwidthAllocations( main, expectedFormat )
            allocationsFile.close()
            if bandwidthCheck:
                main.assertReturnString += 'Bandwidth Allocation check Passed\n'
            else:
                main.assertReturnString += 'Bandwidth Allocation check Failed\n'
                return main.FALSE

        if flowDuration( main ):
            main.assertReturnString += 'Flow duration check Passed\n'
            return intentId
        else:
            main.assertReturnString += 'Flow duration check Failed\n'
            return main.FALSE

    else:
        main.log.error( "Host Intent did not install correctly" )
        hostIntentFailFlag = True
        main.assertReturnString += 'Install Intent State Failed\n'
        return main.FALSE


def testHostIntent( main,
                    name,
                    intentId,
                    host1,
                    host2,
                    onosNode=0,
                    sw1="s5",
                    sw2="s2",
                    expectedLink=0 ):
    """
    Test a Host Intent

    Description:
        Test a host intent of given ID between given hosts

    Steps:
        - Fetch host data if not given
        - Check Intent State
        - Check Flow State
        - Check Connectivity
        - Check Lack of Connectivity Between Hosts not in the Intent
        - Reroute
            - Take Expected Link Down
            - Check Intent State
            - Check Flow State
            - Check Topology
            - Check Connectivity
            - Bring Expected Link Up
            - Check Intent State
            - Check Flow State
            - Check Topology
            - Check Connectivity
        - Remove Topology

    Required:
        name - Type of point intent to add eg. IPV4 | VLAN | Dualstack
        intentId - intent ID to be tested ( and removed )
        host1 - Dictionary for host1
            { "name":"h8", "id":"of:0000000000000005/8" }
        host2 - Dictionary for host2
            { "name":"h16", "id":"of:0000000000000006/8" }
    Optional:
        onosNode - ONOS node to install the intents in main.CLIs[ ]
                   0 by default so that it will always use the first
                   ONOS node
        sw1 - First switch to bring down & up for rerouting purpose
        sw2 - Second switch to bring down & up for rerouting purpose
        expectedLink - Expected link when the switches are down, it should
                       be two links lower than the links before the two
                       switches are down

    """
    # Parameter Validity Check
    assert main, "There is no main variable"
    assert host1, "You must specify host1"
    assert host2, "You must specify host2"

    global itemName
    itemName = name

    global hostIntentFailFlag

    main.log.info( itemName + ": Testing Host Intent" )

    try:
        if not host1.get( "id" ):
            main.log.warn( "Id not given for host1 {0}. Loading from main.hostData".format( host1.get( "name" ) ) )
            host1[ "id" ] = main.hostsData.get( host1.get( "name" ) ).get( "location" )

        if not host2.get( "id" ):
            main.log.warn( "Id not given for host2 {0}. Loading from main.hostData".format( host2.get( "name" ) ) )
            host2[ "id" ] = main.hostsData.get( host2.get( "name" ) ).get( "location" )

        senderNames = [ host1.get( "name" ), host2.get( "name" ) ]
        recipientNames = [ host1.get( "name" ), host2.get( "name" ) ]
        vlanId = host1.get( "vlan" )

        testResult = main.TRUE
    except( KeyError, TypeError ):
        main.log.error( "There was a problem loading the hosts data." )
        return main.FALSE

    main.log.info( itemName + ": Testing Host to Host intents" )

    # Check intent state
    if hostIntentFailFlag:
        attempts = main.minimumAttemptsNum
    else:
        attempts = main.generalAttemptsNum
    if utilities.retry( f=checkIntentState,
                        retValue=main.FALSE,
                        args=( main, [ intentId ] ),
                        sleep=main.checkIntentSleep,
                        attempts=attempts ):
        main.assertReturnString += 'Initial Intent State Passed\n'
    else:
        main.assertReturnString += 'Initial Intent State Failed\n'
        testResult = main.FALSE
        attempts = main.minimumAttemptsNum

    # Check flows count in each node
    if utilities.retry( f=checkFlowsCount,
                        retValue=main.FALSE,
                        args=[ main ],
                        sleep=main.checkFlowCountSleep,
                        attempts=3 ) and utilities.retry( f=checkFlowsState,
                                                          retValue=main.FALSE,
                                                          args=[ main ],
                                                          sleep=main.checkFlowCountSleep,
                                                          attempts=3 ):
        main.assertReturnString += 'Initial Flow State Passed\n'
    else:
        main.assertReturnString += 'Intial Flow State Failed\n'
        testResult = main.FALSE

    # Check Connectivity
    if utilities.retry( f=scapyCheckConnection,
                        retValue=main.FALSE,
                        attempts=main.checkConnectionAttNum,
                        sleep=main.checkConnectionSleep,
                        args=( main, senderNames, recipientNames, vlanId ),
                        getRetryingTime=True ):
        main.assertReturnString += 'Initial Ping Passed\n'
    else:
        main.assertReturnString += 'Initial Ping Failed\n'
        testResult = main.FALSE

    # Test rerouting if these variables exist
    if sw1 and sw2 and expectedLink:
        # Take link down
        if utilities.retry( f=link,
                            retValue=main.FALSE,
                            args=( main, sw1, sw2, "down" ) ):
            main.assertReturnString += 'Link Down Passed\n'
        else:
            main.assertReturnString += 'Link Down Failed\n'
            testResult = main.FALSE

        # Check intent state
        if utilities.retry( f=checkIntentState,
                            retValue=main.FALSE,
                            args=( main, [ intentId ] ),
                            sleep=main.checkIntentHostSleep,
                            attempts=attempts ):
            main.assertReturnString += 'Link Down Intent State Passed\n'
        else:
            main.assertReturnString += 'Link Down Intent State Failed\n'
            testResult = main.FALSE

        # Check flows count in each node
        if utilities.retry( f=checkFlowsCount,
                            retValue=main.FALSE,
                            args=[ main ],
                            sleep=main.checkFlowCountSleep,
                            attempts=attempts ) and utilities.retry( f=checkFlowsState,
                                                                     retValue=main.FALSE,
                                                                     args=[ main ],
                                                                     sleep=main.checkFlowCountSleep,
                                                                     attempts=attempts ):
            main.assertReturnString += 'Link Down Flow State Passed\n'
        else:
            main.assertReturnString += 'Link Down Flow State Failed\n'
            testResult = main.FALSE

        # Check OnosTopology
        if utilities.retry( f=checkTopology,
                            retValue=main.FALSE,
                            args=( main, expectedLink ) ):
            main.assertReturnString += 'Link Down Topology State Passed\n'
        else:
            main.assertReturnString += 'Link Down Topology State Failed\n'
            testResult = main.FALSE

        # Check Connection
        if utilities.retry( f=scapyCheckConnection,
                            retValue=main.FALSE,
                            args=( main, senderNames, recipientNames, vlanId ),
                            sleep=main.checkConnectionSleep,
                            attempts=main.checkConnectionAttNum,
                            getRetryingTime=True ):
            main.assertReturnString += 'Link Down Pingall Passed\n'
        else:
            main.assertReturnString += 'Link Down Pingall Failed\n'
            testResult = main.FALSE

        # Bring link up
        if utilities.retry( f=link,
                            retValue=main.FALSE,
                            args=( main, sw1, sw2, "up" ) ):
            main.assertReturnString += 'Link Up Passed\n'
        else:
            main.assertReturnString += 'Link Up Failed\n'
            testResult = main.FALSE

        # Wait for reroute
        main.log.info( "Sleeping {} seconds".format( main.rerouteSleep ) )
        time.sleep( main.rerouteSleep )

        # Check Intents
        if utilities.retry( f=checkIntentState,
                            retValue=main.FALSE,
                            attempts=attempts * 2,
                            args=( main, [ intentId ] ),
                            sleep=main.checkIntentSleep ):
            main.assertReturnString += 'Link Up Intent State Passed\n'
        else:
            main.assertReturnString += 'Link Up Intent State Failed\n'
            testResult = main.FALSE

        # Check flows count in each node
        if utilities.retry( f=checkFlowsCount,
                            retValue=main.FALSE,
                            args=[ main ],
                            sleep=main.checkFlowCountSleep,
                            attempts=3 ) and utilities.retry( f=checkFlowsState,
                                                              retValue=main.FALSE,
                                                              args=[ main ],
                                                              sleep=main.checkFlowCountSleep,
                                                              attempts=3 ):
            main.assertReturnString += 'Link Up Flow State Passed\n'
        else:
            main.assertReturnString += 'Link Up Flow State Failed\n'
            testResult = main.FALSE

        # Check OnosTopology
        if utilities.retry( f=checkTopology,
                            retValue=main.FALSE,
                            args=( main, main.numLinks ) ):
            main.assertReturnString += 'Link Up Topology State Passed\n'
        else:
            main.assertReturnString += 'Link Up Topology State Failed\n'
            testResult = main.FALSE

        # Check Connection
        if utilities.retry( f=scapyCheckConnection,
                            retValue=main.FALSE,
                            args=( main, senderNames, recipientNames, vlanId ),
                            getRetryingTime=True ):
            main.assertReturnString += 'Link Up Pingall Passed\n'
        else:
            main.assertReturnString += 'Link Up Pingall Failed\n'
            testResult = main.FALSE

    # Remove all intents
    if utilities.retry( f=removeAllIntents,
                        retValue=main.FALSE,
                        attempts=main.removeIntentAttNum,
                        args=( main, [ intentId ] ) ):
        main.assertReturnString += 'Remove Intents Passed'
    else:
        main.assertReturnString += 'Remove Intents Failed'
        testResult = main.FALSE

    return testResult


def installPointIntent( main,
                        name,
                        senders,
                        recipients,
                        onosNode=0,
                        ethType="",
                        bandwidth="",
                        lambdaAlloc=False,
                        protected=False,
                        ipProto="",
                        ipSrc="",
                        ipDst="",
                        tcpSrc="",
                        tcpDst="",
                        setVlan="",
                        encap="" ):
    """
    Installs a Single to Single Point Intent

    Description:
        Install a single to single point intent

    Steps:
        - Fetch host data if not given
        - Add point intent
            - Ingress device is the first sender device
            - Egress device is the first recipient device
            - Ports if defined in senders or recipients
            - MAC address ethSrc loaded from Ingress device
        - Check intent state with retry
    Required:
        name - Type of point intent to add eg. IPV4 | VLAN | Dualstack
        senders - List of host dictionaries i.e.
            [ { "name":"h8", "device":"of:0000000000000005/8","mac":"00:00:00:00:00:08" } ]
        recipients - List of host dictionaries i.e.
            [ { "name":"h16", "device":"of:0000000000000006/8", "mac":"00:00:00:00:00:10" } ]
    Optional:
        onosNode - ONOS node to install the intents in main.CLIs[ ]
                   0 by default so that it will always use the first
                   ONOS node
        ethType - Ethernet type eg. IPV4, IPV6
        bandwidth - Bandwidth capacity
        lambdaAlloc - Allocate lambda, defaults to False
        ipProto - IP protocol
        tcp - TCP ports in the same order as the hosts in hostNames
        sw1 - First switch to bring down & up for rerouting purpose
        sw2 - Second switch to bring down & up for rerouting purpose
        expectedLink - Expected link when the switches are down, it should
                       be two links lower than the links before the two
                       switches are down
    """
    assert main, "There is no main variable"
    assert senders, "You must specify a sender"
    assert recipients, "You must specify a recipient"
    # Assert devices or main.hostsData, "You must specify devices"

    global itemName  # The name of this run. Used for logs.
    itemName = name

    global pointIntentFailFlag
    pointIntentFailFlag = False

    main.log.info( itemName + ": Adding point to point intents" )

    try:
        for sender in senders:
            if not sender.get( "device" ):
                main.log.warn( "Device not given for sender {0}. Loading from main.hostData".format( sender.get( "name" ) ) )
                sender[ "device" ] = main.hostsData.get( sender.get( "name" ) ).get( "location" )

        for recipient in recipients:
            if not recipient.get( "device" ):
                main.log.warn( "Device not given for recipient {0}. Loading from main.hostData".format( recipient.get( "name" ) ) )
                recipient[ "device" ] = main.hostsData.get( recipient.get( "name" ) ).get( "location" )

        ingressDevice = senders[ 0 ].get( "device" )
        egressDevice = recipients[ 0 ].get( "device" )

        portIngress = senders[ 0 ].get( "port", "" )
        portEgress = recipients[ 0 ].get( "port", "" )

        dstMac = recipients[ 0 ].get( "mac" )

        ipSrc = senders[ 0 ].get( "ip" )
        ipDst = recipients[ 0 ].get( "ip" )

        vlanId = senders[ 0 ].get( "vlan" )

        # Adding point intent
        intentId = main.Cluster.active( onosNode ).CLI.addPointIntent(
                                                                        ingressDevice=ingressDevice,
                                                                        egressDevice=egressDevice,
                                                                        portIngress=portIngress,
                                                                        portEgress=portEgress,
                                                                        ethType=ethType,
                                                                        ethDst=dstMac,
                                                                        bandwidth=bandwidth,
                                                                        lambdaAlloc=lambdaAlloc,
                                                                        protected=protected,
                                                                        ipProto=ipProto,
                                                                        ipSrc=ipSrc,
                                                                        ipDst=ipDst,
                                                                        tcpSrc=tcpSrc,
                                                                        tcpDst=tcpDst,
                                                                        vlanId=vlanId,
                                                                        setVlan=setVlan,
                                                                        encap=encap )
    except( KeyError, TypeError ):
        errorMsg = "There was a problem loading the hosts data."
        if intentId:
            errorMsg += "  There was a problem installing Point to Point intent."
        main.log.error( errorMsg )
        return main.FALSE

    # Check intents state
    if utilities.retry( f=checkIntentState,
                        retValue=main.FALSE,
                        args=( main, [ intentId ] ),
                        sleep=main.checkIntentSleep,
                        attempts=50 ):
        main.assertReturnString += 'Install Intent State Passed\n'

        if bandwidth != "":
            allocationsFile = open( os.path.dirname( main.testFile ) + main.params[ 'DEPENDENCY' ][ 'filePath' ], 'r' )
            expectedFormat = allocationsFile.read()
            bandwidthCheck = checkBandwidthAllocations( main, expectedFormat )
            allocationsFile.close()
            if bandwidthCheck:
                main.assertReturnString += 'Bandwidth Allocation check Passed\n'
            else:
                main.assertReturnString += 'Bandwidth Allocation check Failed\n'
                return main.FALSE

        # Check VLAN if test encapsulation
        if encap != "":
            if EncapsulatedIntentCheck( main, tag=encap ):
                main.assertReturnString += 'Encapsulation intents check Passed\n'
            else:
                main.assertReturnString += 'Encapsulation intents check failed\n'

        if flowDuration( main ):
            main.assertReturnString += 'Flow duration check Passed\n'
            return intentId
        else:
            main.assertReturnString += 'Flow duration check failed\n'
            return main.FALSE
    else:
        main.log.error( "Point Intent did not install correctly" )
        pointIntentFailFlag = True
        return main.FALSE


def pointIntentTcp( main,
                    name,
                    host1,
                    host2,
                    onosNode=0,
                    deviceId1="",
                    deviceId2="",
                    port1="",
                    port2="",
                    ethType="",
                    mac1="",
                    mac2="",
                    bandwidth="",
                    lambdaAlloc=False,
                    ipProto="",
                    ip1="",
                    ip2="",
                    tcp1="",
                    tcp2="",
                    sw1="",
                    sw2="",
                    expectedLink=0 ):
    """
    Description:
        Verify add-point-intent only for TCP
    Steps:
        - Get device ids | ports
        - Add point intents
        - Check intents
        - Verify flows
        - Ping hosts
        - Reroute
            - Link down
            - Verify flows
            - Check topology
            - Ping hosts
            - Link up
            - Verify flows
            - Check topology
            - Ping hosts
        - Remove intents
    Required:
        name - Type of point intent to add eg. IPV4 | VLAN | Dualstack
        host1 - Name of first host
        host2 - Name of second host
    Optional:
        onosNode - ONOS node to install the intents in main.CLIs[ ]
                   0 by default so that it will always use the first
                   ONOS node
        deviceId1 - ONOS device id of the first switch, the same as the
                    location of the first host eg. of:0000000000000001/1,
                    located at device 1 port 1
        deviceId2 - ONOS device id of the second switch
        port1 - The port number where the first host is attached
        port2 - The port number where the second host is attached
        ethType - Ethernet type eg. IPV4, IPV6
        mac1 - Mac address of first host
        mac2 - Mac address of the second host
        bandwidth - Bandwidth capacity
        lambdaAlloc - Allocate lambda, defaults to False
        ipProto - IP protocol
        ip1 - IP address of first host
        ip2 - IP address of second host
        tcp1 - TCP port of first host
        tcp2 - TCP port of second host
        sw1 - First switch to bring down & up for rerouting purpose
        sw2 - Second switch to bring down & up for rerouting purpose
        expectedLink - Expected link when the switches are down, it should
                       be two links lower than the links before the two
                       switches are down
    """
    assert main, "There is no main variable"
    assert name, "variable name is empty"
    assert host1 and host2, "You must specify hosts"

    global itemName
    itemName = name
    host1 = host1
    host2 = host2
    intentsId = []

    iperfResult = main.TRUE
    linkDownResult = main.TRUE
    linkUpResult = main.TRUE

    # Adding bidirectional point  intents
    main.log.info( itemName + ": Adding point intents" )
    ctrl = main.Cluster.active( onosNode )
    intent1 = ctrl.CLI.addPointIntent( ingressDevice=deviceId1,
                                       egressDevice=deviceId2,
                                       portIngress=port1,
                                       portEgress=port2,
                                       ethType=ethType,
                                       ethSrc=mac1,
                                       ethDst=mac2,
                                       bandwidth=bandwidth,
                                       lambdaAlloc=lambdaAlloc,
                                       ipProto=ipProto,
                                       ipSrc=ip1,
                                       ipDst=ip2,
                                       tcpSrc=tcp1,
                                       tcpDst="" )

    intent2 = ctrl.CLI.addPointIntent( ingressDevice=deviceId2,
                                       egressDevice=deviceId1,
                                       portIngress=port2,
                                       portEgress=port1,
                                       ethType=ethType,
                                       ethSrc=mac2,
                                       ethDst=mac1,
                                       bandwidth=bandwidth,
                                       lambdaAlloc=lambdaAlloc,
                                       ipProto=ipProto,
                                       ipSrc=ip2,
                                       ipDst=ip1,
                                       tcpSrc=tcp2,
                                       tcpDst="" )

    intent3 = ctrl.CLI.addPointIntent( ingressDevice=deviceId1,
                                       egressDevice=deviceId2,
                                       portIngress=port1,
                                       portEgress=port2,
                                       ethType=ethType,
                                       ethSrc=mac1,
                                       ethDst=mac2,
                                       bandwidth=bandwidth,
                                       lambdaAlloc=lambdaAlloc,
                                       ipProto=ipProto,
                                       ipSrc=ip1,
                                       ipDst=ip2,
                                       tcpSrc="",
                                       tcpDst=tcp2 )

    intent4 = ctrl.CLI.addPointIntent( ingressDevice=deviceId2,
                                       egressDevice=deviceId1,
                                       portIngress=port2,
                                       portEgress=port1,
                                       ethType=ethType,
                                       ethSrc=mac2,
                                       ethDst=mac1,
                                       bandwidth=bandwidth,
                                       lambdaAlloc=lambdaAlloc,
                                       ipProto=ipProto,
                                       ipSrc=ip2,
                                       ipDst=ip1,
                                       tcpSrc="",
                                       tcpDst=tcp1 )
    intentsId.append( intent1 )
    intentsId.append( intent2 )
    intentsId.append( intent3 )
    intentsId.append( intent4 )

    # Check intents state
    main.log.info( "Sleeping {} seconds".format( main.checkIntentSleep ) )
    time.sleep( main.checkIntentSleep )
    intentResult = utilities.retry( f=checkIntentState,
                                    retValue=main.FALSE,
                                    args=( main, intentsId ),
                                    sleep=1,
                                    attempts=50 )
    # Check flows count in each node
    checkFlowsCount( main )

    # Check intents state again if first check fails...
    if not intentResult:
        intentResult = utilities.retry( f=checkIntentState,
                                        retValue=main.FALSE,
                                        args=( main, intentsId ),
                                        sleep=1,
                                        attempts=50 )

    # Check flows count in each node
    checkFlowsCount( main )

    # Verify flows
    checkFlowsState( main )

    # Run iperf to both host
    iperfTemp = main.Network.iperftcp( host1, host2, 10 )
    iperfResult = iperfResult and iperfTemp
    if iperfTemp:
        main.assertReturnString += 'Initial Iperf Passed\n'
    else:
        main.assertReturnString += 'Initial Iperf Failed\n'

    # Test rerouting if these variables exist
    if sw1 and sw2 and expectedLink:
        # link down
        linkDownResult = link( main, sw1, sw2, "down" )

        if linkDownResult:
            main.assertReturnString += 'Link Down Passed\n'
        else:
            main.assertReturnString += 'Link Down Failed\n'

        # Check flows count in each node
        checkFlowsCount( main )
        # Verify flows
        checkFlowsState( main )

        # Check OnosTopology
        topoResult = checkTopology( main, expectedLink )
        if topoResult:
            main.assertReturnString += 'Link Down Topology State Passed\n'
        else:
            main.assertReturnString += 'Link Down Topology State Failed\n'

        # Run iperf to both host
        iperfTemp = main.Network.iperftcp( host1, host2, 10 )
        iperfResult = iperfResult and iperfTemp
        if iperfTemp:
            main.assertReturnString += 'Link Down Iperf Passed\n'
        else:
            main.assertReturnString += 'Link Down Iperf Failed\n'

        # Check intent state
        intentTemp = utilities.retry( f=checkIntentState,
                                      retValue=main.FALSE,
                                      args=( main, intentsId ),
                                      sleep=1,
                                      attempts=50 )
        intentResult = intentResult and intentTemp
        if intentTemp:
            main.assertReturnString += 'Link Down Intent State Passed\n'
        else:
            main.assertReturnString += 'Link Down Intent State Failed\n'

        # Checks ONOS state in link down
        if linkDownResult and topoResult and iperfResult and intentResult:
            main.log.info( itemName + ": Successfully brought link down" )
        else:
            main.log.error( itemName + ": Failed to bring link down" )

        # link up
        linkUpResult = link( main, sw1, sw2, "up" )
        if linkUpResult:
            main.assertReturnString += 'Link Up Passed\n'
        else:
            main.assertReturnString += 'Link Up Failed\n'

        main.log.info( "Sleeping {} seconds".format( main.rerouteSleep ) )
        time.sleep( main.rerouteSleep )

        # Check flows count in each node
        checkFlowsCount( main )
        # Verify flows
        checkFlowsState( main )

        # Check OnosTopology
        topoResult = checkTopology( main, main.numLinks )

        if topoResult:
            main.assertReturnString += 'Link Up Topology State Passed\n'
        else:
            main.assertReturnString += 'Link Up Topology State Failed\n'

        # Run iperf to both host
        iperfTemp = main.Network.iperftcp( host1, host2, 10 )
        iperfResult = iperfResult and iperfTemp
        if iperfTemp:
            main.assertReturnString += 'Link Up Iperf Passed\n'
        else:
            main.assertReturnString += 'Link Up Iperf Failed\n'

        # Check intent state
        intentTemp = utilities.retry( f=checkIntentState,
                                      retValue=main.FALSE,
                                      args=( main, intentsId ),
                                      sleep=1,
                                      attempts=50 )
        intentResult = intentResult and intentTemp
        if intentTemp:
            main.assertReturnString += 'Link Down Intent State Passed\n'
        else:
            main.assertReturnString += 'Link Down Intent State Failed\n'

        # Checks ONOS state in link up
        if linkUpResult and topoResult and iperfResult and intentResult:
            main.log.info( itemName + ": Successfully brought link back up" )
        else:
            main.log.error( itemName + ": Failed to bring link back up" )

    # Remove all intents
    removeIntentResult = removeAllIntents( main, intentsId )
    if removeIntentResult:
        main.assertReturnString += 'Remove Intents Passed'
    else:
        main.assertReturnString += 'Remove Intents Failed'

    stepResult = iperfResult and linkDownResult and linkUpResult \
                 and intentResult and removeIntentResult

    return stepResult


def installSingleToMultiIntent( main,
                                name,
                                senders,
                                recipients,
                                onosNode=0,
                                ethType="",
                                bandwidth="",
                                lambdaAlloc=False,
                                ipProto="",
                                ipAddresses="",
                                tcp="",
                                sw1="",
                                sw2="",
                                setVlan="",
                                partial=False,
                                encap="" ):
    """
    Installs a Single to Multi Point Intent

    Description:
        Install a single to multi point intent using
        add-single-to-multi-intent

    Steps:
        - Fetch host data if not given
        - Add single to multi intent
            - Ingress device is the first sender host
            - Egress devices are the recipient devices
            - Ports if defined in senders or recipients
            - MAC address ethSrc loaded from Ingress device
        - Check intent state with retry
    Required:
        name - Type of point intent to add eg. IPV4 | VLAN | Dualstack
        senders - List of host dictionaries i.e.
            { "name":"h8", "device":"of:0000000000000005/8","mac":"00:00:00:00:00:08" }
        recipients - List of host dictionaries i.e.
            { "name":"h16", "device":"of:0000000000000006/8", "mac":"00:00:00:00:00:10" }
    Optional:
        onosNode - ONOS node to install the intents in main.CLIs[ ]
                   0 by default so that it will always use the first
                   ONOS node
        ethType - Ethernet type eg. IPV4, IPV6
        bandwidth - Bandwidth capacity
        lambdaAlloc - Allocate lambda, defaults to False
        ipProto - IP protocol
        tcp - TCP ports in the same order as the hosts in hostNames
        sw1 - First switch to bring down & up for rerouting purpose
        sw2 - Second switch to bring down & up for rerouting purpose
        expectedLink - Expected link when the switches are down, it should
                       be two links lower than the links before the two
                       switches are down
    """
    assert main, "There is no main variable"
    assert senders, "You must specify a sender"
    assert recipients, "You must specify a recipient"
    # Assert devices or main.hostsData, "You must specify devices"

    global itemName  # The name of this run. Used for logs.
    itemName = name

    global singleToMultiFailFlag
    singleToMultiFailFlag = False

    main.log.info( itemName + ": Adding single point to multi point intents" )

    try:
        for sender in senders:
            if not sender.get( "device" ):
                main.log.warn( "Device not given for sender {0}. Loading from main.hostData".format( sender.get( "name" ) ) )
                sender[ "device" ] = main.hostsData.get( sender.get( "name" ) ).get( "location" )

        for recipient in recipients:
            if not recipient.get( "device" ):
                main.log.warn( "Device not given for recipient {0}. Loading from main.hostData".format( recipient.get( "name" ) ) )
                recipient[ "device" ] = main.hostsData.get( recipient.get( "name" ) ).get( "location" )

        ingressDevice = senders[ 0 ].get( "device" )
        egressDeviceList = [ x.get( "device" ) for x in recipients if x.get( "device" ) ]

        portIngress = senders[ 0 ].get( "port", "" )
        portEgressList = [ x.get( "port" ) for x in recipients if x.get( "port" ) ]
        if not portEgressList:
            portEgressList = None

        srcMac = senders[ 0 ].get( "mac" )
        vlanId = senders[ 0 ].get( "vlan" )

        # Adding point intent
        intentId = main.Cluster.active( onosNode ).CLI.addSinglepointToMultipointIntent(
                                                                                   ingressDevice=ingressDevice,
                                                                                   egressDeviceList=egressDeviceList,
                                                                                   portIngress=portIngress,
                                                                                   portEgressList=portEgressList,
                                                                                   ethType=ethType,
                                                                                   ethSrc=srcMac,
                                                                                   bandwidth=bandwidth,
                                                                                   lambdaAlloc=lambdaAlloc,
                                                                                   ipProto=ipProto,
                                                                                   ipSrc="",
                                                                                   ipDst="",
                                                                                   tcpSrc="",
                                                                                   tcpDst="",
                                                                                   vlanId=vlanId,
                                                                                   setVlan=setVlan,
                                                                                   partial=partial,
                                                                                   encap=encap )
    except( KeyError, TypeError ):
        errorMsg = "There was a problem loading the hosts data."
        if intentId:
            errorMsg += "  There was a problem installing Singlepoint to Multipoint intent."
        main.log.error( errorMsg )
        singleToMultiFailFlag = True
        return main.FALSE

    # Check intents state
    if singleToMultiFailFlag:
        attempts = main.middleAttemptsNum
    else:
        attempts = main.generalAttemptsNum

    if utilities.retry( f=checkIntentState,
                        retValue=main.FALSE,
                        args=( main, [ intentId ] ),
                        sleep=main.checkIntentSleep,
                        attempts=attempts ):
        main.assertReturnString += 'Install Intent State Passed\n'
        if bandwidth != "":
            allocationsFile = open( os.path.dirname( main.testFile ) + main.params[ 'DEPENDENCY' ][ 'filePath' ], 'r' )
            expectedFormat = allocationsFile.read()
            bandwidthCheck = checkBandwidthAllocations( main, expectedFormat )
            allocationsFile.close()
            if bandwidthCheck:
                main.assertReturnString += 'Bandwidth Allocation check Passed\n'
            else:
                main.assertReturnString += 'Bandwidth Allocation check Failed\n'
                return main.FALSE

        if flowDuration( main ):
            main.assertReturnString += 'Flow duration check Passed\n'
            return intentId
        else:
            main.assertReturnString += 'Flow duration check failed\n'
            return main.FALSE
    else:
        main.log.error( "Single to Multi Intent did not install correctly" )
        singleToMultiFailFlag = True
        return main.FALSE


def installMultiToSingleIntent( main,
                                name,
                                senders,
                                recipients,
                                onosNode=0,
                                ethType="",
                                bandwidth="",
                                lambdaAlloc=False,
                                ipProto="",
                                ipAddresses="",
                                tcp="",
                                sw1="",
                                sw2="",
                                setVlan="",
                                partial=False,
                                encap="" ):
    """
    Installs a Multi to Single Point Intent

    Description:
        Install a multi to single point intent using
        add-multi-to-single-intent

    Steps:
        - Fetch host data if not given
        - Add multi to single intent
            - Ingress devices are the senders devices
            - Egress device is the first recipient host
            - Ports if defined in senders or recipients
            - MAC address ethSrc loaded from Ingress device
        - Check intent state with retry
    Required:
        name - Type of point intent to add eg. IPV4 | VLAN | Dualstack
        senders - List of host dictionaries i.e.
            [ { "name":"h8", "device":"of:0000000000000005/8","mac":"00:00:00:00:00:08" } ]
        recipients - List of host dictionaries i.e.
            [ { "name":"h16", "device":"of:0000000000000006/8", "mac":"00:00:00:00:00:10" } ]
    Optional:
        onosNode - ONOS node to install the intents in main.CLIs[ ]
                   0 by default so that it will always use the first
                   ONOS node
        ethType - Ethernet type eg. IPV4, IPV6
        bandwidth - Bandwidth capacity
        lambdaAlloc - Allocate lambda, defaults to False
        ipProto - IP protocol
        tcp - TCP ports in the same order as the hosts in hostNames
        sw1 - First switch to bring down & up for rerouting purpose
        sw2 - Second switch to bring down & up for rerouting purpose
        expectedLink - Expected link when the switches are down, it should
                       be two links lower than the links before the two
                       switches are down
    """
    assert main, "There is no main variable"
    assert senders, "You must specify a sender"
    assert recipients, "You must specify a recipient"
    # Assert devices or main.hostsData, "You must specify devices"

    global itemName  # The name of this run. Used for logs.
    itemName = name

    global multiToSingleFailFlag
    multiToSingleFailFlag = False

    main.log.info( itemName + ": Adding mutli to single point intents" )

    try:
        for sender in senders:
            if not sender.get( "device" ):
                main.log.warn( "Device not given for sender {0}. Loading from main.hostData".format( sender.get( "name" ) ) )
                sender[ "device" ] = main.hostsData.get( sender.get( "name" ) ).get( "location" )

        for recipient in recipients:
            if not recipient.get( "device" ):
                main.log.warn( "Device not given for recipient {0}. Loading from main.hostData".format( recipient.get( "name" ) ) )
                recipient[ "device" ] = main.hostsData.get( recipient.get( "name" ) ).get( "location" )

        ingressDeviceList = [ x.get( "device" ) for x in senders if x.get( "device" ) ]
        egressDevice = recipients[ 0 ].get( "device" )

        portIngressList = [ x.get( "port" ) for x in senders if x.get( "port" ) ]
        portEgress = recipients[ 0 ].get( "port", "" )
        if not portIngressList:
            portIngressList = None

        dstMac = recipients[ 0 ].get( "mac" )
        vlanId = senders[ 0 ].get( "vlan" )

        # Adding point intent
        intentId = main.Cluster.active( onosNode ).CLI.addMultipointToSinglepointIntent(
                                                                ingressDeviceList=ingressDeviceList,
                                                                egressDevice=egressDevice,
                                                                portIngressList=portIngressList,
                                                                portEgress=portEgress,
                                                                ethType=ethType,
                                                                ethDst=dstMac,
                                                                bandwidth=bandwidth,
                                                                lambdaAlloc=lambdaAlloc,
                                                                ipProto=ipProto,
                                                                ipSrc="",
                                                                ipDst="",
                                                                tcpSrc="",
                                                                tcpDst="",
                                                                vlanId=vlanId,
                                                                setVlan=setVlan,
                                                                partial=partial,
                                                                encap=encap )
    except( KeyError, TypeError ):
        errorMsg = "There was a problem loading the hosts data."
        if intentId:
            errorMsg += "  There was a problem installing Multipoint to Singlepoint intent."
        main.log.error( errorMsg )
        multiToSingleFailFlag = True
        return main.FALSE

    # Check intents state
    if multiToSingleFailFlag:
        attempts = main.middleAttemptsNum
    else:
        attempts = main.generalAttemptsNum

    if utilities.retry( f=checkIntentState,
                        retValue=main.FALSE,
                        args=( main, [ intentId ] ),
                        sleep=main.checkIntentSleep,
                        attempts=attempts ):
        main.assertReturnString += 'Install Intent State Passed\n'
        if bandwidth != "":
            allocationsFile = open( os.path.dirname( main.testFile ) + main.params[ 'DEPENDENCY' ][ 'filePath' ], 'r' )
            expectedFormat = allocationsFile.read()
            bandwidthCheck = checkBandwidthAllocations( main, expectedFormat )
            allocationsFile.close()
            if bandwidthCheck:
                main.assertReturnString += 'Bandwidth Allocation check Passed\n'
            else:
                main.assertReturnString += 'Bandwidth Allocation check Failed\n'
                return main.FALSE

        if flowDuration( main ):
            main.assertReturnString += 'Flow duration check Passed\n'
            return intentId
        else:
            main.assertReturnString += 'Flow duration check failed\n'
            return main.FALSE
    else:
        main.log.error( "Multi to Single Intent did not install correctly" )
        multiToSingleFailFlag = True
        return main.FALSE


def testPointIntent( main,
                     name,
                     intentId,
                     senders,
                     recipients,
                     badSenders={},
                     badRecipients={},
                     onosNode=0,
                     ethType="",
                     bandwidth="",
                     lambdaAlloc=False,
                     protected=False,
                     ipProto="",
                     ipAddresses="",
                     tcp="",
                     sw1="s5",
                     sw2="s2",
                     expectedLink=0,
                     useTCP=False ):
    """
    Test a Point Intent

    Description:
        Test a point intent

    Steps:
        - Fetch host data if not given
        - Check Intent State
        - Check Flow State
        - Check Connectivity
        - Check Lack of Connectivity Between Hosts not in the Intent
        - Reroute
            - Take Expected Link Down
            - Check Intent State
            - Check Flow State
            - Check Topology
            - Check Connectivity
            - Bring Expected Link Up
            - Check Intent State
            - Check Flow State
            - Check Topology
            - Check Connectivity
        - Remove Topology

    Required:
        name - Type of point intent to add eg. IPV4 | VLAN | Dualstack

        senders - List of host dictionaries i.e.
            { "name":"h8", "device":"of:0000000000000005/8","mac":"00:00:00:00:00:08" }
        recipients - List of host dictionaries i.e.
            { "name":"h16", "device":"of:0000000000000006/8", "mac":"00:00:00:00:00:10" }
    Optional:
        onosNode - ONOS node to install the intents in main.CLIs[ ]
                   0 by default so that it will always use the first
                   ONOS node
        ethType - Ethernet type eg. IPV4, IPV6
        bandwidth - Bandwidth capacity
        lambdaAlloc - Allocate lambda, defaults to False
        ipProto - IP protocol
        tcp - TCP ports in the same order as the hosts in hostNames
        sw1 - First switch to bring down & up for rerouting purpose
        sw2 - Second switch to bring down & up for rerouting purpose
        expectedLink - Expected link when the switches are down, it should
                       be two links lower than the links before the two
                       switches are down

    """
    # Parameter Validity Check
    assert main, "There is no main variable"
    assert senders, "You must specify a sender"
    assert recipients, "You must specify a recipient"

    global itemName
    itemName = name

    global pointIntentFailFlag
    global singleToMultiFailFlag
    global multiToSingleFailFlag

    main.log.info( itemName + ": Testing Point Intent" )

    try:
        # Names for scapy
        senderNames = [ x.get( "name" ) for x in senders ]
        recipientNames = [ x.get( "name" ) for x in recipients ]
        badSenderNames = [ x.get( "name" ) for x in badSenders ]
        badRecipientNames = [ x.get( "name" ) for x in badRecipients ]

        for sender in senders:
            if not sender.get( "device" ):
                main.log.warn( "Device not given for sender {0}. Loading from main.hostData".format( sender.get( "name" ) ) )
                sender[ "device" ] = main.hostsData.get( sender.get( "name" ) ).get( "location" )

        for recipient in recipients:
            if not recipient.get( "device" ):
                main.log.warn( "Device not given for recipient {0}. Loading from main.hostData".format( recipient.get( "name" ) ) )
                recipient[ "device" ] = main.hostsData.get( recipient.get( "name" ) ).get( "location" )
        vlanId = senders[ 0 ].get( "vlan" )
    except( KeyError, TypeError ):
        main.log.error( "There was a problem loading the hosts data." )
        return main.FALSE

    testResult = main.TRUE
    main.log.info( itemName + ": Adding single point to multi point intents" )

    if pointIntentFailFlag or singleToMultiFailFlag or multiToSingleFailFlag:
        attempts = main.minimumAttemptsNum
    else:
        attempts = main.generalAttemptsNum

    # Check intent state
    if utilities.retry( f=checkIntentState,
                        retValue=main.FALSE,
                        args=( main, [ intentId ] ),
                        sleep=main.checkIntentSleep,
                        attempts=attempts ):
        main.assertReturnString += 'Initial Intent State Passed\n'
    else:
        main.assertReturnString += 'Initial Intent State Failed\n'
        testResult = main.FALSE
        attempts = main.minimumAttemptsNum

    # Check flows count in each node
    if utilities.retry( f=checkFlowsCount,
                        retValue=main.FALSE,
                        args=[ main ],
                        sleep=main.checkFlowCountSleep,
                        attempts=attempts ) and utilities.retry( f=checkFlowsState,
                                                                 retValue=main.FALSE,
                                                                 args=[ main ],
                                                                 sleep=main.checkFlowCountSleep,
                                                                 attempts=attempts ):
        main.assertReturnString += 'Initial Flow State Passed\n'
    else:
        main.assertReturnString += 'Intial Flow State Failed\n'
        testResult = main.FALSE

    # Check Connectivity
    if utilities.retry( f=scapyCheckConnection,
                        retValue=main.FALSE,
                        args=( main, senderNames, recipientNames, vlanId, useTCP ),
                        attempts=main.checkConnectionAttNum,
                        sleep=main.checkConnectionSleep,
                        getRetryingTime=True ):
        main.assertReturnString += 'Initial Ping Passed\n'
    else:
        main.assertReturnString += 'Initial Ping Failed\n'
        testResult = main.FALSE

    # Check connections that shouldn't work
    if badSenderNames:
        main.log.info( "Checking that packets from incorrect sender do not go through" )
        if utilities.retry( f=scapyCheckConnection,
                            retValue=main.FALSE,
                            args=( main, badSenderNames, recipientNames ),
                            kwargs={ "expectFailure": True },
                            getRetryingTime=True ):
            main.assertReturnString += 'Bad Sender Ping Passed\n'
        else:
            main.assertReturnString += 'Bad Sender Ping Failed\n'
            testResult = main.FALSE

    if badRecipientNames:
        main.log.info( "Checking that packets to incorrect recipients do not go through" )
        if utilities.retry( f=scapyCheckConnection,
                            retValue=main.FALSE,
                            args=( main, senderNames, badRecipientNames ),
                            kwargs={ "expectFailure": True },
                            getRetryingTime=True ):
            main.assertReturnString += 'Bad Recipient Ping Passed\n'
        else:
            main.assertReturnString += 'Bad Recipient Ping Failed\n'
            testResult = main.FALSE

    # Test rerouting if these variables exist
    if sw1 and sw2 and expectedLink:
        # Take link down
        if utilities.retry( f=link,
                            retValue=main.FALSE,
                            args=( main, sw1, sw2, "down" ) ):
            main.assertReturnString += 'Link Down Passed\n'
        else:
            main.assertReturnString += 'Link Down Failed\n'
            testResult = main.FALSE

        if protected:
            # Check Connection
            if utilities.retry( f=scapyCheckConnection,
                                retValue=main.FALSE,
                                args=( main, senderNames, recipientNames, vlanId, useTCP ),
                                getRetryingTime=True ):
                main.assertReturnString += 'Link down Scapy Packet Received Passed\n'
            else:
                main.assertReturnString += 'Link down Scapy Packet Recieved Failed\n'
                testResult = main.FALSE

            if ProtectedIntentCheck( main ):
                main.assertReturnString += 'Protected Intent Check Passed\n'
            else:
                main.assertReturnString += 'Protected Intent Check Failed\n'
                testResult = main.FALSE

        # Check intent state
        if utilities.retry( f=checkIntentState,
                            retValue=main.FALSE,
                            args=( main, [ intentId ] ),
                            sleep=main.checkIntentPointSleep,
                            attempts=attempts ):
            main.assertReturnString += 'Link Down Intent State Passed\n'
        else:
            main.assertReturnString += 'Link Down Intent State Failed\n'
            testResult = main.FALSE

        # Check flows count in each node
        if utilities.retry( f=checkFlowsCount,
                            retValue=main.FALSE,
                            args=[ main ],
                            sleep=main.checkFlowCountSleep,
                            attempts=attempts ) and utilities.retry( f=checkFlowsState,
                                                                         retValue=main.FALSE,
                                                                         args=[ main ],
                                                                         sleep=main.checkFlowCountSleep,
                                                                         attempts=attempts ):
            main.assertReturnString += 'Link Down Flow State Passed\n'
        else:
            main.assertReturnString += 'Link Down Flow State Failed\n'
            testResult = main.FALSE

        # Check OnosTopology
        if utilities.retry( f=checkTopology,
                            retValue=main.FALSE,
                            args=( main, expectedLink ) ):
            main.assertReturnString += 'Link Down Topology State Passed\n'
        else:
            main.assertReturnString += 'Link Down Topology State Failed\n'
            testResult = main.FALSE

        # Check Connection
        if utilities.retry( f=scapyCheckConnection,
                            retValue=main.FALSE,
                            args=( main, senderNames, recipientNames, vlanId, useTCP ),
                            sleep=main.checkConnectionSleep,
                            attempts=main.checkConnectionAttNum,
                            getRetryingTime=True ):
            main.assertReturnString += 'Link Down Pingall Passed\n'
        else:
            main.assertReturnString += 'Link Down Pingall Failed\n'
            testResult = main.FALSE

        # Bring link up
        if utilities.retry( f=link,
                            retValue=main.FALSE,
                            args=( main, sw1, sw2, "up" ) ):
            main.assertReturnString += 'Link Up Passed\n'
        else:
            main.assertReturnString += 'Link Up Failed\n'
            testResult = main.FALSE

        # Wait for reroute
        main.log.info( "Sleeping {} seconds".format( main.rerouteSleep ) )
        time.sleep( main.rerouteSleep )

        # Check Intents
        if utilities.retry( f=checkIntentState,
                            retValue=main.FALSE,
                            attempts=attempts * 2,
                            args=( main, [ intentId ] ),
                            sleep=main.checkIntentSleep ):
            main.assertReturnString += 'Link Up Intent State Passed\n'
        else:
            main.assertReturnString += 'Link Up Intent State Failed\n'
            testResult = main.FALSE

        # Check flows count in each node
        if utilities.retry( f=checkFlowsCount,
                            retValue=main.FALSE,
                            args=[ main ],
                            sleep=main.checkFlowCountSleep,
                            attempts=attempts ) and utilities.retry( f=checkFlowsState,
                                                                     retValue=main.FALSE,
                                                                     args=[ main ],
                                                                     sleep=main.checkFlowCountSleep,
                                                                     attempts=attempts ):
            main.assertReturnString += 'Link Up Flow State Passed\n'
        else:
            main.assertReturnString += 'Link Up Flow State Failed\n'
            testResult = main.FALSE

        # Check OnosTopology
        if utilities.retry( f=checkTopology,
                            retValue=main.FALSE,
                            args=( main, main.numLinks ) ):
            main.assertReturnString += 'Link Up Topology State Passed\n'
        else:
            main.assertReturnString += 'Link Up Topology State Failed\n'
            testResult = main.FALSE

        # Check Connection
        if utilities.retry( f=scapyCheckConnection,
                            retValue=main.FALSE,
                            sleep=main.checkConnectionSleep,
                            attempts=main.checkConnectionAttNum,
                            args=( main, senderNames, recipientNames, vlanId, useTCP ),
                            getRetryingTime=True ):
            main.assertReturnString += 'Link Up Scapy Packet Received Passed\n'
        else:
            main.assertReturnString += 'Link Up Scapy Packet Recieved Failed\n'
            testResult = main.FALSE

    # Remove all intents
    if utilities.retry( f=removeAllIntents,
                        retValue=main.FALSE,
                        attempts=main.removeIntentAttNum,
                        args=( main, [ intentId ] ) ):
        main.assertReturnString += 'Remove Intents Passed'
    else:
        main.assertReturnString += 'Remove Intents Failed'
        testResult = main.FALSE

    return testResult


def testEndPointFail( main,
                      name,
                      intentId,
                      senders,
                      recipients,
                      isolatedSenders,
                      isolatedRecipients,
                      onosNode=0,
                      ethType="",
                      bandwidth="",
                      lambdaAlloc=False,
                      ipProto="",
                      ipAddresses="",
                      tcp="",
                      sw1="",
                      sw2="",
                      sw3="",
                      sw4="",
                      sw5="",
                      expectedLink1=0,
                      expectedLink2=0,
                      partial=False ):
    """
    Test Multi point to single point intent Topology for Endpoint failures
    """
    # Parameter Validity Check
    assert main, "There is no main variable"
    assert senders, "You must specify a sender"
    assert recipients, "You must specify a recipient"

    global itemName
    itemName = name

    global singleToMultiFailFlag
    global multiToSingleFailFlag

    main.log.info( itemName + ": Testing Point Intent" )

    try:
        # Names for scapy
        senderNames = [ x.get( "name" ) for x in senders ]
        recipientNames = [ x.get( "name" ) for x in recipients ]
        isolatedSenderNames = [ x.get( "name" ) for x in isolatedSenders ]
        isolatedRecipientNames = [ x.get( "name" ) for x in isolatedRecipients ]
        connectedSenderNames = [ x.get( "name" ) for x in senders if x.get( "name" ) not in isolatedSenderNames ]
        connectedRecipientNames = [ x.get( "name" ) for x in recipients if x.get( "name" ) not in isolatedRecipientNames ]

        for sender in senders:
            if not sender.get( "device" ):
                main.log.warn( "Device not given for sender {0}. Loading from main.hostData".format( sender.get( "name" ) ) )
                sender[ "device" ] = main.hostsData.get( sender.get( "name" ) ).get( "location" )

        for recipient in recipients:
            if not recipient.get( "device" ):
                main.log.warn( "Device not given for recipient {0}. Loading from " +
                                main.hostData.format( recipient.get( "name" ) ) )
                recipient[ "device" ] = main.hostsData.get( recipient.get( "name" ) ).get( "location" )
    except( KeyError, TypeError ):
        main.log.error( "There was a problem loading the hosts data." )
        return main.FALSE

    testResult = main.TRUE
    main.log.info( itemName + ": Adding multi point to single point intents" )

    # Check intent state
    if singleToMultiFailFlag or multiToSingleFailFlag:
        attempts = main.minimumAttemptsNum
    else:
        attempts = main.generalAttemptsNum

    if utilities.retry( f=checkIntentState,
                        retValue=main.FALSE,
                        args=( main, [ intentId ] ),
                        sleep=main.checkIntentSleep,
                        attempts=attempts ):
        main.assertReturnString += 'Initial Intent State Passed\n'
    else:
        main.assertReturnString += 'Initial Intent State Failed\n'
        testResult = main.FALSE
        attempts = main.minimumAttemptsNum

    # Check flows count in each node
    if utilities.retry( f=checkFlowsCount,
                        retValue=main.FALSE,
                        args=[ main ],
                        attempts=5 ) and utilities.retry( f=checkFlowsState,
                                                          retValue=main.FALSE,
                                                          args=[ main ],
                                                          attempts=5 ):
        main.assertReturnString += 'Initial Flow State Passed\n'
    else:
        main.assertReturnString += 'Intial Flow State Failed\n'
        testResult = main.FALSE

    # Check Connectivity
    if utilities.retry( f=scapyCheckConnection,
                        retValue=main.FALSE,
                        args=( main, senderNames, recipientNames ),
                        getRetryingTime=True ):
        main.assertReturnString += 'Initial Connectivity Check Passed\n'
    else:
        main.assertReturnString += 'Initial Connectivity Check Failed\n'
        testResult = main.FALSE

    # Take two links down
    # Take first link down
    if utilities.retry( f=link,
                        retValue=main.FALSE,
                        args=( main, sw1, sw2, "down" ) ):
        main.assertReturnString += 'Link Down Passed\n'
    else:
        main.assertReturnString += 'Link Down Failed\n'
        testResult = main.FALSE

    # Take second link down
    if utilities.retry( f=link,
                        retValue=main.FALSE,
                        args=( main, sw3, sw4, "down" ) ):
        main.assertReturnString += 'Link Down Passed\n'
    else:
        main.assertReturnString += 'Link Down Failed\n'
        testResult = main.FALSE

    # Check intent state
    if utilities.retry( f=checkIntentState,
                        retValue=main.FALSE,
                        attempts=attempts,
                        args=( main, [ intentId ] ),
                        sleep=main.checkIntentSleep ):
        main.assertReturnString += 'Link Down Intent State Passed\n'
    else:
        main.assertReturnString += 'Link Down Intent State Failed\n'
        testResult = main.FALSE

    # Check flows count in each node
    if utilities.retry( f=checkFlowsCount,
                        retValue=main.FALSE,
                        sleep=1,
                        attempts=attempts,
                        args=[ main ] ) and utilities.retry( f=checkFlowsState,
                                                             retValue=main.FALSE,
                                                             sleep=1,
                                                             attempts=attempts,
                                                             args=[ main ] ):
        main.assertReturnString += 'Link Down Flow State Passed\n'
    else:
        main.assertReturnString += 'Link Down Flow State Failed\n'
        testResult = main.FALSE

    # Check OnosTopology
    if utilities.retry( f=checkTopology,
                        retValue=main.FALSE,
                        args=( main, expectedLink1 ) ):
        main.assertReturnString += 'Link Down Topology State Passed\n'
    else:
        main.assertReturnString += 'Link Down Topology State Failed\n'
        testResult = main.FALSE

    # Check Connection
    if utilities.retry( f=scapyCheckConnection,
                        retValue=main.FALSE,
                        args=( main, senderNames, recipientNames ),
                        getRetryingTime=True ):
        main.assertReturnString += 'Link Down Connectivity Check Passed\n'
    else:
        main.assertReturnString += 'Link Down Connectivity Check Failed\n'
        testResult = main.FALSE

    # Take a third link down to isolate one node
    if utilities.retry( f=link,
                        retValue=main.FALSE,
                        args=( main, sw3, sw5, "down" ) ):
        main.assertReturnString += 'Isolation link Down Passed\n'
    else:
        main.assertReturnString += 'Isolation link Down Failed\n'
        testResult = main.FALSE

    if partial:
        # Check intent state
        if utilities.retry( f=checkIntentState,
                            retValue=main.FALSE,
                            args=( main, [ intentId ] ),
                            sleep=main.checkIntentSleep,
                            attempts=attempts ):
            main.assertReturnString += 'Partial failure isolation link Down Intent State Passed\n'
        else:
            main.assertReturnString += 'Partial failure isolation link Down Intent State Failed\n'
            testResult = main.FALSE

        # Check flows count in each node
        if utilities.retry( f=checkFlowsCount,
                            retValue=main.FALSE,
                            args=[ main ],
                            attempts=5 ) and utilities.retry( f=checkFlowsState,
                                                              retValue=main.FALSE,
                                                              args=[ main ],
                                                              attempts=5 ):
            main.assertReturnString += 'Partial failure isolation link Down Flow State Passed\n'
        else:
            main.assertReturnString += 'Partial failure isolation link Down Flow State Failed\n'
            testResult = main.FALSE

        # Check OnosTopology
        if utilities.retry( f=checkTopology,
                            retValue=main.FALSE,
                            args=( main, expectedLink2 ) ):
            main.assertReturnString += 'Partial failure isolation link Down Topology State Passed\n'
        else:
            main.assertReturnString += 'Partial failure isolation link Down Topology State Failed\n'
            testResult = main.FALSE

        # Check Connectivity
        # First check connectivity of any isolated senders to recipients
        if isolatedSenderNames:
            if scapyCheckConnection( main,
                                     isolatedSenderNames,
                                     recipientNames,
                                     None,
                                     None,
                                     None,
                                     None,
                                     main.TRUE ):
                main.assertReturnString += 'Partial failure isolation link Down Connectivity Check Passed\n'
            else:
                main.assertReturnString += 'Partial failure isolation link Down Connectivity Check Failed\n'
                testResult = main.FALSE

        # Next check connectivity of senders to any isolated recipients
        if isolatedRecipientNames:
            if scapyCheckConnection( main,
                                     senderNames,
                                     isolatedRecipientNames,
                                     None,
                                     None,
                                     None,
                                     None,
                                     main.TRUE ):
                main.assertReturnString += 'Partial failure isolation link Down Connectivity Check Passed\n'
            else:
                main.assertReturnString += 'Partial failure isolation link Down Connectivity Check Failed\n'
                testResult = main.FALSE

        # Next check connectivity of connected senders and recipients
        if utilities.retry( f=scapyCheckConnection,
                            retValue=main.FALSE,
                            attempts=main.checkConnectionAttNum,
                            args=( main, connectedSenderNames, connectedRecipientNames ),
                            getRetryingTime=True ):
            main.assertReturnString += 'Partial failure isolation link Down Connectivity Check Passed\n'
        else:
            main.assertReturnString += 'Partial failure isolation link Down Connectivity Check Failed\n'
            testResult = main.FALSE
    else:
        # Check intent state
        if not utilities.retry( f=checkIntentState,
                                retValue=main.TRUE,
                                args=( main, [ intentId ] ),
                                sleep=main.checkIntentSleep,
                                attempts=attempts ):
            main.assertReturnString += 'Isolation link Down Intent State Passed\n'
        else:
            main.assertReturnString += 'Isolation link Down Intent State Failed\n'
            testResult = main.FALSE

        # Check flows count in each node
        if utilities.retry( f=checkFlowsCount,
                            retValue=main.FALSE,
                            args=[ main ],
                            attempts=5 ) and utilities.retry( f=checkFlowsState,
                                                              retValue=main.FALSE,
                                                              args=[ main ],
                                                              attempts=5 ):
            main.assertReturnString += 'Isolation link Down Flow State Passed\n'
        else:
            main.assertReturnString += 'Isolation link Down Flow State Failed\n'
            testResult = main.FALSE

        # Check OnosTopology
        if utilities.retry( f=checkTopology,
                            retValue=main.FALSE,
                            args=( main, expectedLink2 ) ):
            main.assertReturnString += 'Isolation link Down Topology State Passed\n'
        else:
            main.assertReturnString += 'Isolation link Down Topology State Failed\n'
            testResult = main.FALSE

        # Check Connectivity
        # First check connectivity of any isolated senders to recipients
        if isolatedSenderNames:
            if scapyCheckConnection( main,
                                     isolatedSenderNames,
                                     recipientNames,
                                     None,
                                     None,
                                     None,
                                     None,
                                     main.TRUE ):
                main.assertReturnString += 'Isolation link Down Connectivity Check Passed\n'
            else:
                main.assertReturnString += 'Isolation link Down Connectivity Check Failed\n'
                testResult = main.FALSE

        # Next check connectivity of senders to any isolated recipients
        if isolatedRecipientNames:
            if scapyCheckConnection( main,
                                     senderNames,
                                     isolatedRecipientNames,
                                     None,
                                     None,
                                     None,
                                     None,
                                     main.TRUE ):
                main.assertReturnString += 'Isolation link Down Connectivity Check Passed\n'
            else:
                main.assertReturnString += 'Isolation link Down Connectivity Check Failed\n'
                testResult = main.FALSE

        # Next check connectivity of connected senders and recipients
        if utilities.retry( f=scapyCheckConnection,
                            retValue=main.TRUE,
                            args=( main, connectedSenderNames, connectedRecipientNames, None, None, None, None, main.TRUE ),
                            getRetryingTime=True ):
            main.assertReturnString += 'Isolation link Down Connectivity Check Passed\n'
        else:
            main.assertReturnString += 'Isolation link Down Connectivity Check Failed\n'
            testResult = main.FALSE

    # Bring the links back up
    # Bring first link up
    if utilities.retry( f=link,
                        retValue=main.FALSE,
                        args=( main, sw1, sw2, "up" ) ):
        main.assertReturnString += 'Link Up Passed\n'
    else:
        main.assertReturnString += 'Link Up Failed\n'
        testResult = main.FALSE

    # Bring second link up
    if utilities.retry( f=link,
                        retValue=main.FALSE,
                        args=( main, sw3, sw5, "up" ) ):
        main.assertReturnString += 'Link Up Passed\n'
    else:
        main.assertReturnString += 'Link Up Failed\n'
        testResult = main.FALSE

    # Bring third link up
    if utilities.retry( f=link,
                        retValue=main.FALSE,
                        args=( main, sw3, sw4, "up" ) ):
        main.assertReturnString += 'Link Up Passed\n'
    else:
        main.assertReturnString += 'Link Up Failed\n'
        testResult = main.FALSE

    # Wait for reroute
    main.log.info( "Sleeping {} seconds".format( main.rerouteSleep ) )
    time.sleep( main.rerouteSleep )

    # Check Intents
    if utilities.retry( f=checkIntentState,
                        retValue=main.FALSE,
                        attempts=attempts,
                        args=( main, [ intentId ] ),
                        sleep=main.checkIntentHostSleep ):
        main.assertReturnString += 'Link Up Intent State Passed\n'
    else:
        main.assertReturnString += 'Link Up Intent State Failed\n'
        testResult = main.FALSE

    # Check flows count in each node
    if utilities.retry( f=checkFlowsCount,
                        retValue=main.FALSE,
                        args=[ main ],
                        sleep=main.checkFlowCountSleep,
                        attempts=attempts ) and utilities.retry( f=checkFlowsState,
                                                                 retValue=main.FALSE,
                                                                 args=[ main ],
                                                                 sleep=main.checkFlowCountSleep,
                                                                 attempts=attempts ):
        main.assertReturnString += 'Link Up Flow State Passed\n'
    else:
        main.assertReturnString += 'Link Up Flow State Failed\n'
        testResult = main.FALSE

    # Check OnosTopology
    if utilities.retry( f=checkTopology,
                        retValue=main.FALSE,
                        args=( main, main.numLinks ) ):
        main.assertReturnString += 'Link Up Topology State Passed\n'
    else:
        main.assertReturnString += 'Link Up Topology State Failed\n'
        testResult = main.FALSE

    # Check Connection
    if utilities.retry( f=scapyCheckConnection,
                        retValue=main.FALSE,
                        sleep=main.checkConnectionSleep,
                        attempts=main.checkConnectionAttNum,
                        args=( main, senderNames, recipientNames ),
                        getRetryingTime=True ):
        main.assertReturnString += 'Link Up Scapy Packet Received Passed\n'
    else:
        main.assertReturnString += 'Link Up Scapy Packet Recieved Failed\n'
        testResult = main.FALSE

    # Remove all intents
    if utilities.retry( f=removeAllIntents,
                        retValue=main.FALSE,
                        attempts=main.removeIntentAttNum,
                        args=( main, [ intentId ] ) ):
        main.assertReturnString += 'Remove Intents Passed'
    else:
        main.assertReturnString += 'Remove Intents Failed'
        testResult = main.FALSE

    return testResult


def pingallHosts( main, hostList ):
    """
        Ping all host in the hosts list variable
    """
    main.log.info( "Pinging: " + str( hostList ) )
    return main.Network.pingallHosts( hostList )


def fwdPingall( main ):
    """
        Use fwd app and pingall to discover all the hosts
    """
    appCheck = main.TRUE
    main.log.info( "Activating reactive forwarding app " )
    activateResult = main.Cluster.active( 0 ).CLI.activateApp( "org.onosproject.fwd" )

    # Wait for forward app activation to propagate
    main.log.info( "Sleeping {} seconds".format( main.fwdSleep ) )
    time.sleep( main.fwdSleep )

    # Check that forwarding is enabled on all nodes
    for ctrl in main.Cluster.active():
        appCheck = appCheck and ctrl.CLI.appToIDCheck()
        if appCheck != main.TRUE:
            main.log.warn( ctrl.CLI.apps() )
            main.log.warn( ctrl.CLI.appIDs() )

    # Send pingall in mininet
    main.log.info( "Run Pingall" )
    pingResult = main.Network.pingall( timeout=600 )

    main.log.info( "Deactivating reactive forwarding app " )
    deactivateResult = main.Cluster.active( 0 ).CLI.deactivateApp( "org.onosproject.fwd" )
    if activateResult and deactivateResult:
        main.log.info( "Successfully used fwd app to discover hosts" )
        getDataResult = main.TRUE
    else:
        main.log.info( "Failed to use fwd app to discover hosts" )
        getDataResult = main.FALSE
    return getDataResult


def confirmHostDiscovery( main ):
    """
        Confirms that all ONOS nodes have discovered all scapy hosts
    """
    import collections
    try:
        from tests.dependencies.topology import Topology
    except Exception:
        main.log.error( "Topology not found exiting the test" )
        main.cleanAndExit()
    try:
        main.topoRelated
    except Exception:
        main.topoRelated = Topology()
    hosts = main.topoRelated.getAll( "hosts", False )  # Get host data from each ONOS node
    hostFails = []  # Reset for each failed attempt

    #  Check for matching hosts on each node
    scapyHostIPs = [ x.hostIp for x in main.scapyHosts if x.hostIp != "0.0.0.0" ]
    for controller in range( main.Cluster.numCtrls ):
        controllerStr = str( controller + 1 )  # ONOS node number
        # Compare Hosts
        # Load hosts data for controller node
        try:
            if hosts[ controller ]:
                main.log.info( "Hosts discovered" )
            else:
                main.log.error( "Problem discovering hosts" )
            if hosts[ controller ] and "Error" not in hosts[ controller ]:
                try:
                    hostData = json.loads( hosts[ controller ] )
                except ( TypeError, ValueError ):
                    main.log.error( "Could not load json:" + str( hosts[ controller ] ) )
                    hostFails.append( controllerStr )
                else:
                    onosHostIPs = [ x.get( "ipAddresses" )[ 0 ]
                                    for x in hostData
                                    if len( x.get( "ipAddresses" ) ) > 0 ]
                    if not set( collections.Counter( scapyHostIPs ) ).issubset(
                            set( collections.Counter( onosHostIPs ) ) ):
                        main.log.warn( "Controller {0} only sees nodes with {1} IPs. It should see all of the following: {2}".format( controllerStr, onosHostIPs, scapyHostIPs ) )
                        hostFails.append( controllerStr )
            else:
                main.log.error( "Hosts returned nothing or an error." )
                hostFails.append( controllerStr )
        except IndexError:
            main.log.error( "Hosts returned nothing, Failed to discover hosts." )
            return main.FALSE

    if hostFails:
        main.log.error( "List of failed ONOS Nodes:" + ', '.join( map( str, hostFails ) ) )
        return main.FALSE
    else:
        return main.TRUE


def sendDiscoveryArp( main, hosts=None ):
    """
        Sends Discovery ARP packets from each host provided
        Defaults to each host in main.scapyHosts
    """
    # Send an arp ping from each host
    if not hosts:
        hosts = main.scapyHosts
    for host in hosts:
        pkt = 'Ether( src="{0}")/ARP( psrc="{1}")'.format( host.hostMac, host.hostIp )
        # Send from the VLAN interface if there is one so ONOS discovers the VLAN correctly
        iface = None
        for interface in host.getIfList():
            if '.' in interface:
                main.log.debug( "Detected VLAN interface {0}. Sending ARP packet from {0}".format( interface ) )
                iface = interface
                break
        host.sendPacket( packet=pkt, iface=iface )
        main.log.info( "Sending ARP packet from {0}".format( host.name ) )


def populateHostData( main ):
    """
        Populates hostsData
    """
    import json
    try:
        hostsJson = json.loads( main.Cluster.active( 0 ).CLI.hosts() )
        hosts = main.Network.getHosts().keys()
        # TODO: Make better use of new getHosts function
        for host in hosts:
            main.hostsData[ host ] = {}
            main.hostsData[ host ][ 'mac' ] =  \
                main.Network.getMacAddress( host ).upper()
            for hostj in hostsJson:
                if main.hostsData[ host ][ 'mac' ] == hostj[ 'mac' ]:
                    main.hostsData[ host ][ 'id' ] = hostj[ 'id' ]
                    main.hostsData[ host ][ 'vlan' ] = hostj[ 'vlan' ]
                    main.hostsData[ host ][ 'location' ] = \
                                hostj[ 'locations' ][ 0 ][ 'elementId' ] + '/' + \
                                hostj[ 'locations' ][ 0 ][ 'port' ]
                    main.hostsData[ host ][ 'ipAddresses' ] = hostj[ 'ipAddresses' ]
        return main.TRUE
    except ValueError:
        main.log.error( "ValueError while populating hostsData" )
        return main.FALSE
    except KeyError:
        main.log.error( "KeyError while populating hostsData" )
        return main.FALSE
    except IndexError:
        main.log.error( "IndexError while populating hostsData" )
        return main.FALSE
    except TypeError:
        main.log.error( "TypeError while populating hostsData" )
        return main.FALSE


def checkTopology( main, expectedLink ):
    statusResult = main.TRUE
    # Check onos topology
    main.log.info( itemName + ": Checking ONOS topology " )

    statusResult = main.Cluster.command( "checkStatus",
                                         args=[ main.numSwitch, expectedLink ],
                                         returnBool=True, specificDriver=2 )
    if not statusResult:
        main.log.error( itemName + ": Topology mismatch" )
    else:
        main.log.info( itemName + ": Topology match" )
    return statusResult


def checkIntentState( main, intentsId ):
    """
        This function will check intent state to make sure all the intents
        are in INSTALLED state
        Returns main.TRUE or main.FALSE
    """
    intentResult = main.TRUE
    stateCheckResults = main.Cluster.command( "checkIntentState",
                                              kwargs={ "intentsId": intentsId },
                                              returnBool=True, specificDriver=2 )
    if stateCheckResults:
        main.log.info( itemName + ": Intents state check passed" )
    else:
        main.log.warn( "Intents state check failed" )
        intentResult = main.FALSE
    return intentResult


def checkBandwidthAllocations( main, bandwidth ):
    """
        Compare the given bandwith allocation output to the cli output on each node
        Returns main.TRUE or main.FALSE
    """
    stateCheckResults = main.Cluster.command( "compareBandwidthAllocations",
                                              args=[ bandwidth ],
                                              returnBool=True, specificDriver=2 )
    if stateCheckResults:
        main.log.info( itemName + ": bandwidth check passed" )
        bandwidthResult = main.TRUE
    else:
        main.log.warn( itemName + ": bandwidth check failed" )
        bandwidthResult = main.FALSE
    return bandwidthResult


def checkFlowsState( main ):

    main.log.info( itemName + ": Check flows state" )
    checkFlowsResult = main.Cluster.active( 0 ).CLI.checkFlowsState( isPENDING=False )
    return checkFlowsResult


def link( main, sw1, sw2, option ):
    if main.usePortstate:
        # port down
        dpid = main.params[ 'MININET' ][ 'dpids' ][ sw1 ]
        port = main.params[ 'MININET' ][ 'ports' ][ sw1 ][ sw2 ]
        main.log.info( itemName + ": Bring port " + sw1 + "/" + port + " " + option )
        state = "disable" if option == "down" else "enable"
        result = main.Cluster.active( 0 ).CLI.portstate( dpid=dpid, port=port, state=state )
    else:
        # link down
        main.log.info( itemName + ": Bring link " + option + " between " +
                           sw1 + " and " + sw2 )
        result = main.Network.link( end1=sw1, end2=sw2, option=option )
    return result


def scapyCheckConnection( main,
                          senders,
                          recipients,
                          vlanId=None,
                          useTCP=False,
                          packet=None,
                          packetFilter=None,
                          expectFailure=False ):
    """
        Checks the connectivity between all given sender hosts and all given recipient hosts
        Packet may be specified. Defaults to Ether/IP packet
        Packet Filter may be specified. Defaults to Ether/IP from current sender MAC
            Todo: Optional packet and packet filter attributes for sender and recipients
        Expect Failure when the sender and recipient are not supposed to have connectivity
            Timeout of 1 second, returns main.TRUE if the filter is not triggered and kills the filter

    """
    connectionsFunctional = main.TRUE

    if not packetFilter:
        packetFilter = 'ether host {}'
    if useTCP:
        packetFilter += ' ip proto \\tcp tcp port {}'.format( main.params[ 'SDNIP' ][ 'dstPort' ] )
    if expectFailure:
        timeout = 1
    else:
        timeout = 10

    for sender in senders:
        try:
            senderComp = getattr( main, sender )
        except AttributeError:
            main.log.error( "main has no attribute {}".format( sender ) )
            connectionsFunctional = main.FALSE
            continue

        for recipient in recipients:
            # Do not send packets to self since recipient CLI will already be busy
            if recipient == sender:
                continue
            try:
                recipientComp = getattr( main, recipient )
            except AttributeError:
                main.log.error( "main has no attribute {}".format( recipient ) )
                connectionsFunctional = main.FALSE
                continue

            if vlanId:
                recipientComp.startFilter( pktFilter=( "vlan {}".format( vlanId ) + " && " + packetFilter.format( senderComp.hostMac ) ) )
            else:
                recipientComp.startFilter( pktFilter=packetFilter.format( senderComp.hostMac ) )

            if not packet:
                if vlanId:
                    pkt = 'Ether( src="{0}", dst="{2}" )/Dot1Q(vlan={4})/IP( src="{1}", dst="{3}" )'.format(
                        senderComp.hostMac,
                        senderComp.hostIp,
                        recipientComp.hostMac,
                        recipientComp.hostIp,
                        vlanId )
                else:
                    pkt = 'Ether( src="{0}", dst="{2}" )/IP( src="{1}", dst="{3}" )'.format(
                        senderComp.hostMac,
                        senderComp.hostIp,
                        recipientComp.hostMac,
                        recipientComp.hostIp )
            else:
                pkt = packet
            if vlanId:
                senderComp.sendPacket( iface=( "{0}-eth0.{1}".format( sender, vlanId ) ), packet = pkt )
            else:
                senderComp.sendPacket( packet=pkt )

            if recipientComp.checkFilter( timeout ):
                if expectFailure:
                    main.log.error( "Packet from {0} successfully received by {1} when it should not have been".format( sender, recipient ) )
                    connectionsFunctional = main.FALSE
                else:
                    main.log.info( "Packet from {0} successfully received by {1}".format( sender, recipient ) )
                    connectionsFunctional = main.TRUE
            else:
                recipientComp.killFilter()
                if expectFailure:
                    main.log.info( "As expected, packet from {0} was not received by {1}".format( sender, recipient ) )
                else:
                    main.log.error( "Packet from {0} was not received by {1}".format( sender, recipient ) )
                    connectionsFunctional = main.FALSE

        return connectionsFunctional


def removeAllIntents( main, intentsId ):
    """
        Remove all intents in the intentsId
    """
    onosSummary = []
    removeIntentResult = main.TRUE
    # Remove intents
    for intent in intentsId:
        main.Cluster.active( 0 ).CLI.removeIntent( intentId=intent, purge=True )

    main.log.info( "Sleeping {} seconds".format( main.removeIntentSleep ) )
    time.sleep( main.removeIntentSleep )

    # If there is remianing intents then remove intents should fail
    for ctrl in main.Cluster.active():
        onosSummary.append( json.loads( ctrl.CLI.summary() ) )

    for summary in onosSummary:
        if summary.get( 'intents' ) != 0:
            main.log.warn( itemName + ": There are " +
                           str( summary.get( 'intents' ) ) +
                           " intents remaining in node " +
                           str( summary.get( 'node' ) ) +
                           ", failed to remove all the intents " )
            removeIntentResult = main.FALSE

    if removeIntentResult:
        main.log.info( itemName + ": There are no more intents remaining, " +
                       "successfully removed all the intents." )

    return removeIntentResult


def checkFlowsCount( main ):
    """
        Check flows count in each node
    """
    flowsCount = []
    main.log.info( itemName + ": Checking flows count in each ONOS node" )
    for ctrl in main.Cluster.active():
        summaryResult = ctrl.CLI.summary()
        if not summaryResult:
            main.log.error( itemName + ": There is something wrong with " +
                            "summary command" )
            return main.FALSE
        else:
            summaryJson = json.loads( summaryResult )
            flowsCount.append( summaryJson.get( 'flows' ) )

    if flowsCount:
        if all( flows == flowsCount[ 0 ] for flows in flowsCount ):
            main.log.info( itemName + ": There are " + str( flowsCount[ 0 ] ) +
                           " flows in all ONOS node" )
        else:
            for i in range( main.Cluster.numCtrls ):
                main.log.debug( itemName + ": " + ctrl.name + " has " +
                                str( flowsCount[ ctrl.pos ] ) + " flows" )
    else:
        main.log.error( "Checking flows count failed, check summary command" )
        return main.FALSE

    return main.TRUE


def checkLeaderChange( leaders1, leaders2 ):
    """
        Checks for a change in intent partition leadership.

        Takes the output of leaders -c in json string format before and after
        a potential change as input

        Returns main.TRUE if no mismatches are detected
        Returns main.FALSE if there is a mismatch or on error loading the input
    """
    try:
        leaders1 = json.loads( leaders1 )
        leaders2 = json.loads( leaders2 )
    except( AttributeError, TypeError ):
        main.log.exception( "checkLeaderChange: Object not as expected" )
        return main.FALSE
    except Exception:
        main.log.exception( "checkLeaderChange: Uncaught exception!" )
        main.cleanAndExit()

    main.log.info( "Checking Intent Paritions for Change in Leadership" )
    mismatch = False
    for dict1 in leaders1:
        if "intent" in dict1.get( "topic", [] ):
            for dict2 in leaders2:
                if dict1.get( "topic", 0 ) == dict2.get( "topic", 0 ) and\
                        dict1.get( "leader", 0 ) != dict2.get( "leader", 0 ):
                    mismatch = True
                    main.log.error( "%s changed leader from %s to %s",
                                    dict1.get( "topic", "no-topic" ),
                                    dict1.get( "leader", "no-leader" ),
                                    dict2.get( "leader", "no-leader" ) )
    if mismatch:
        return main.FALSE
    else:
        return main.TRUE


def report( main ):
    """
        Report errors/warnings/exceptions
    """
    main.ONOSbench.logReport( main.Cluster.active( 0 ).ipAddress,
                              [ "INFO",
                                "FOLLOWER",
                                "WARN",
                                "flow",
                                "ERROR",
                                "Except" ],
                              "s" )

    main.log.info( "ERROR report: \n" )
    for ctrl in main.Cluster.active():
        main.ONOSbench.logReport( ctrl.ipAddress,
                                  [ "ERROR" ],
                                  "d" )

    main.log.info( "EXCEPTIONS report: \n" )
    for ctrl in main.Cluster.active():
        main.ONOSbench.logReport( ctrl.ipAddress,
                                  [ "Except" ],
                                  "d" )

    main.log.info( "WARNING report: \n" )
    for ctrl in main.Cluster.active():
        main.ONOSbench.logReport( ctrl.ipAddress,
                                  [ "WARN" ],
                                  "d" )


def flowDuration( main ):
    """
        Check age of flows to see if flows are being overwritten
    """
    main.log.info( "Getting current flow durations" )
    flowsJson1 = main.Cluster.active( 0 ).CLI.flows( noCore=True )
    try:
        flowsJson1 = json.loads( flowsJson1 )
    except ValueError:
        main.log.error( "Unable to read flows" )
        return main.FALSE
    flowLife = []
    waitFlowLife = []
    for device in flowsJson1:
        if device.get( 'flowcount', 0 ) > 0:
            for i in range( device[ 'flowCount' ] ):
                flowLife.append( device[ 'flows' ][ i ][ 'life' ] )
    main.log.info( "Sleeping for {} seconds".format( main.flowDurationSleep ) )
    time.sleep( main.flowDurationSleep )
    main.log.info( "Getting new flow durations" )
    flowsJson2 = main.Cluster.active( 0 ).CLI.flows( noCore=True )
    try:
        flowsJson2 = json.loads( flowsJson2 )
    except ValueError:
        main.log.error( "Unable to read flows" )
        return main.FALSE
    for device in flowsJson2:
        if device.get( 'flowcount', 0 ) > 0:
            for i in range( device[ 'flowCount' ] ):
                waitFlowLife.append( device[ 'flows' ][ i ][ 'life' ] )
    main.log.info( "Determining whether flows where overwritten" )
    if len( flowLife ) == len( waitFlowLife ):
        for i in range( len( flowLife ) ):
            if waitFlowLife[ i ] - flowLife[ i ] < main.flowDurationSleep:
                return main.FALSE
    else:
        return main.FALSE
    return main.TRUE


def EncapsulatedIntentCheck( main, tag="" ):
    """
        Check encapsulated intents
        tag: encapsulation tag ( e.g. VLAN, MPLS )

        Getting added flows
        Check tags on each flows
        If each direction has push or pop, passed
        else failed

    """
    main.log.info( "Checking encapsulated intent for " + tag + "." )
    HostJson = []
    Jflows = main.Cluster.active( 0 ).CLI.flows( noCore=True )
    try:
        Jflows = json.loads( Jflows )
    except ValueError:
        main.log.error( "Unable to read flows" )
        return main.FALSE

    for flow in Jflows:
        if len( flow[ "flows" ] ) != 0:
            HostJson.append( flow[ "flows" ] )

    totalflows = len( HostJson[ 0 ] )

    pop = 0
    push = 0

    PopTag = tag + "_POP"
    PushTag = tag + "_PUSH"
    main.log.info( "Host Json info :" )
    for EachHostJson in HostJson:
        for i in range( totalflows ):
            main.log.info( str( EachHostJson[ i ] ) )
            checkJson = EachHostJson[ i ][ "treatment" ][ "instructions" ][ 0 ]
            main.Cluster.active( 0 ).REST.pprint( checkJson )
            if 'subtype' in checkJson:
                if checkJson[ "subtype" ] == PopTag:
                    pop += 1
                elif checkJson[ "subtype" ] == PushTag:
                    push += 1

    if pop == totalflows and push == totalflows:
        return main.TRUE
    else:
        main.log.error( "Total " + PushTag + str( push ) )
        main.log.error( "Total " + PopTag + str( pop ) )
        return main.FALSE


def ProtectedIntentCheck( main ):
    intent = main.Cluster.active( 0 ).CLI.intents( jsonFormat=False )
    if "Protection" in intent:
        return main.TRUE
    return main.FALSE
