#copyright 2016-present Ciena Corporation
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
import unittest
from nose.tools import *
from scapy.all import *
from OnosCtrl import OnosCtrl
from OltConfig import OltConfig
from CordTestUtils import get_mac, get_controller, get_controllers, log_test
from OnosFlowCtrl import OnosFlowCtrl
from nose.twistedtools import reactor, deferred
from twisted.internet import defer
from onosclidriver import OnosCliDriver
from CordContainer import Container, Onos, Quagga
from CordTestServer import cord_test_onos_restart, cord_test_onos_shutdown, cord_test_onos_add_cluster, cord_test_quagga_restart, cord_test_restart_cluster
from portmaps import g_subscriber_port_map
from scapy.all import *
import time, monotonic
import threading
from threading import current_thread
from Cluster import *
from EapTLS import TLSAuthTest
from ACL import ACLTest
from OnosLog import OnosLog
from CordLogger import CordLogger
from CordTestConfig import setup_module
import os
import json
import random
import collections
log_test.setLevel('INFO')

class cluster_exchange(CordLogger):
    test_path = os.path.dirname(os.path.realpath(__file__))
    onos_config_path = os.path.join(test_path, '..', 'setup/onos-config')
    mac = RandMAC()._fix()
    flows_eth = Ether(src = RandMAC()._fix(), dst = RandMAC()._fix())
    igmp_eth = Ether(dst = '01:00:5e:00:00:16', type = ETH_P_IP)
    igmp_ip = IP(dst = '224.0.0.22')
    ONOS_INSTANCES = 3
    V_INF1 = 'veth0'
    TLS_TIMEOUT = 100
    device_id = 'of:' + get_mac()
    igmp = cluster_igmp()
    igmp_groups = igmp.mcast_ip_range(start_ip = '224.1.8.10',end_ip = '224.1.10.49')
    igmp_sources = igmp.source_ip_range(start_ip = '38.24.29.35',end_ip='38.24.35.56')
    tls = cluster_tls()
    flows = cluster_flows()
    proxyarp = cluster_proxyarp()
    vrouter = cluster_vrouter()
    acl = cluster_acl()
    dhcprelay = cluster_dhcprelay()
    subscriber = cluster_subscriber()
    testcaseLoggers = ('test_cluster_controller_restarts', 'test_cluster_graceful_controller_restarts',
                       'test_cluster_single_controller_restarts', 'test_cluster_restarts')
    ITERATIONS = int(os.getenv('ITERATIONS', 10))
    ARCHIVE_PARTITION = False

    def setUp(self):
        if self._testMethodName not in self.testcaseLoggers:
            super(cluster_exchange, self).setUp()

    def tearDown(self):
        if self._testMethodName not in self.testcaseLoggers:
            super(cluster_exchange, self).tearDown()

    def cliEnter(self, controller = None):
        retries = 0
        while retries < 30:
            self.cli = OnosCliDriver(controller = controller, connect = True)
            if self.cli.handle:
                break
            else:
                retries += 1
                time.sleep(2)

    def cliExit(self):
        self.cli.disconnect()

    def get_leader(self, controller = None):
        self.cliEnter(controller = controller)
        try:
            result = json.loads(self.cli.leaders(jsonFormat = True))
        except:
            result = None

        if result is None:
            log_test.info('Leaders command failure for controller %s' %controller)
        else:
            log_test.info('Leaders returned: %s' %result)
        self.cliExit()
        return result

    def onos_shutdown(self, controller = None):
        status = True
        self.cliEnter(controller = controller)
        try:
            self.cli.shutdown(timeout = 10)
        except:
            log_test.info('Graceful shutdown of ONOS failed for controller: %s' %controller)
            status = False

        self.cliExit()
        return status

    def log_set(self, level = None, app = 'org.onosproject', controllers = None):
        CordLogger.logSet(level = level, app = app, controllers = controllers, forced = True)

    def get_leaders(self, controller = None):
        result_map = {}
        if controller is None:
            controller = get_controller()
        if type(controller) in [ list, tuple ]:
            for c in controller:
                leaders = self.get_leader(controller = c)
                result_map[c] = leaders
        else:
            leaders = self.get_leader(controller = controller)
            result_map[controller] = leaders
        return result_map

    def verify_leaders(self, controller = None):
        leaders_map = self.get_leaders(controller = controller)
        failed = [ k for k,v in leaders_map.items() if v == None ]
        return failed

    def verify_cluster_status(self,controller = None,onos_instances=ONOS_INSTANCES,verify=False):
	tries = 0
	try:
            self.cliEnter(controller = controller)
	    while tries <= 10:
                cluster_summary = json.loads(self.cli.summary(jsonFormat = True))
                if cluster_summary:
	            log_test.info("cluster 'summary' command output is %s"%cluster_summary)
		    nodes = cluster_summary['nodes']
		    if verify:
		        if nodes == onos_instances:
		            self.cliExit()
		            return True
		        else:
		            tries += 1
		            time.sleep(1)
		    else:
			if nodes >= onos_instances:
                            self.cliExit()
                            return True
                        else:
                            tries += 1
                            time.sleep(1)
	        else:
	            tries += 1
	            time.sleep(1)
	    self.cliExit()
	    return False
        except:
            raise Exception('Failed to get cluster members')
	    return False

    def get_cluster_current_member_ips(self, controller = None, nodes_filter = None):
        tries = 0
	cluster_ips = []
        try:
            self.cliEnter(controller = controller)
            while tries <= 10:
                cluster_nodes = json.loads(self.cli.nodes(jsonFormat = True))
                if cluster_nodes:
                    log_test.info("cluster 'nodes' output is %s"%cluster_nodes)
                    if nodes_filter:
                        cluster_nodes = nodes_filter(cluster_nodes)
                    cluster_ips = map(lambda c: c['id'], cluster_nodes)
		    self.cliExit()
                    cluster_ips.sort(lambda i1,i2: int(i1.split('.')[-1]) - int(i2.split('.')[-1]))
		    return cluster_ips
		else:
		    tries += 1
	    self.cliExit()
	    return cluster_ips
        except:
            raise Exception('Failed to get cluster members')
            return cluster_ips

    def get_cluster_container_names_ips(self,controller=None):
        onos_names_ips = {}
        controllers = get_controllers()
        i = 0
        for controller in controllers:
            if i == 0:
                name = Onos.NAME
            else:
                name = '{}-{}'.format(Onos.NAME, i+1)
            onos_names_ips[controller] = name
            onos_names_ips[name] = controller
            i += 1
        return onos_names_ips
        # onos_ips = self.get_cluster_current_member_ips(controller=controller)
        # onos_names_ips[onos_ips[0]] = Onos.NAME
        # onos_names_ips[Onos.NAME] = onos_ips[0]
        # for i in range(1,len(onos_ips)):
        #     name = '{0}-{1}'.format(Onos.NAME,i+1)
        #     onos_names_ips[onos_ips[i]] = name
        #     onos_names_ips[name] = onos_ips[i]

        # return onos_names_ips

    #identifying current master of a connected device, not tested
    def get_cluster_current_master_standbys(self,controller=None,device_id=device_id):
	master = None
	standbys = []
	tries = 0
	try:
	    cli = self.cliEnter(controller = controller)
	    while tries <= 10:
	        roles = json.loads(self.cli.roles(jsonFormat = True))
	        log_test.info("cluster 'roles' command output is %s"%roles)
	        if roles:
	            for device in roles:
	                log_test.info('Verifying device info in line %s'%device)
	                if device['id'] == device_id:
	                    master = str(device['master'])
		            standbys = map(lambda d: str(d), device['standbys'])
		            log_test.info('Master and standbys for device %s are %s and %s'%(device_id, master, standbys))
			    self.cliExit()
		            return master, standbys
		    self.cliExit()
		    return master, standbys
	        else:
		    tries += 1
		    time.sleep(1)
	    self.cliExit()
	    return master,standbys
	except:
            raise Exception('Failed to get cluster members')
	    return master,standbys

    def get_cluster_current_master_standbys_of_connected_devices(self,controller=None):
	''' returns master and standbys of all the connected devices to ONOS cluster instance'''
        device_dict = {}
        tries = 0
        try:
            cli = self.cliEnter(controller = controller)
            while tries <= 10:
		device_dict = {}
                roles = json.loads(self.cli.roles(jsonFormat = True))
                log_test.info("cluster 'roles' command output is %s"%roles)
                if roles:
                    for device in roles:
			device_dict[str(device['id'])]= {'master':str(device['master']),'standbys':device['standbys']}
                        for i in range(len(device_dict[device['id']]['standbys'])):
			    device_dict[device['id']]['standbys'][i] = str(device_dict[device['id']]['standbys'][i])
                        log_test.info('master and standbys for device %s are %s and %s'%(device['id'],device_dict[device['id']]['master'],device_dict[device['id']]['standbys']))
                    self.cliExit()
                    return device_dict
                else:
                    tries += 1
                    time.sleep(1)
            self.cliExit()
            return device_dict
        except:
            raise Exception('Failed to get cluster members')
            return device_dict

    #identify current master of a connected device, not tested
    def get_cluster_connected_devices(self,controller=None):
	'''returns all the devices connected to ONOS cluster'''
        device_list = []
        tries = 0
        try:
            cli = self.cliEnter(controller = controller)
            while tries <= 10:
		device_list = []
                devices = json.loads(self.cli.devices(jsonFormat = True))
                log_test.info("cluster 'devices' command output is %s"%devices)
                if devices:
                    for device in devices:
			log_test.info('device id is %s'%device['id'])
			device_list.append(str(device['id']))
                    self.cliExit()
                    return device_list
                else:
                    tries += 1
                    time.sleep(1)
            self.cliExit()
            return device_list
        except:
            raise Exception('Failed to get cluster members')
            return device_list

    def get_number_of_devices_of_master(self,controller=None):
	'''returns master-device pairs, which master having what devices'''
	master_count = {}
	try:
	    cli = self.cliEnter(controller = controller)
	    masters = json.loads(self.cli.masters(jsonFormat = True))
	    if masters:
		for master in masters:
		    master_count[str(master['id'])] = {'size':int(master['size']),'devices':master['devices']}
		return master_count
	    else:
		return master_count
	except:
            raise Exception('Failed to get cluster members')
            return master_count

    def change_master_current_cluster(self,new_master=None,device_id=device_id,controller=None):
	if new_master is None: return False
	self.cliEnter(controller=controller)
        cmd = 'device-role' + ' ' + device_id + ' ' + new_master + ' ' + 'master'
        command = self.cli.command(cmd = cmd, jsonFormat = False)
        self.cliExit()
        time.sleep(60)
        master, standbys = self.get_cluster_current_master_standbys(controller=controller,device_id=device_id)
        assert_equal(master,new_master)
	log_test.info('Cluster master changed to %s successfully'%new_master)

    def withdraw_cluster_current_mastership(self,master_ip=None,device_id=device_id,controller=None):
	'''current master looses its mastership and hence new master will be elected'''
        self.cliEnter(controller=controller)
        cmd = 'device-role' + ' ' + device_id + ' ' + master_ip + ' ' + 'none'
        command = self.cli.command(cmd = cmd, jsonFormat = False)
        self.cliExit()
        time.sleep(60)
        new_master_ip, standbys = self.get_cluster_current_master_standbys(controller=controller,device_id=device_id)
        assert_not_equal(new_master_ip,master_ip)
	log_test.info('Device-role of device %s successfully changed to none for controller %s'%(device_id,master_ip))
	log_test.info('Cluster new master is %s'%new_master_ip)
	return True

    def cluster_controller_restarts(self, graceful = False):
        controllers = get_controllers()
        ctlr_len = len(controllers)
        if ctlr_len <= 1:
            log_test.info('ONOS is not running in cluster mode. This test only works for cluster mode')
            assert_greater(ctlr_len, 1)

        #this call would verify the cluster for once
        onos_map = self.get_cluster_container_names_ips()

        def check_exception(iteration, controller = None):
            adjacent_controller = None
            adjacent_controllers = None
            if controller:
                adjacent_controllers = list(set(controllers) - set([controller]))
                adjacent_controller = adjacent_controllers[0]
            for node in controllers:
                onosLog = OnosLog(host = node)
                ##check the logs for storage exception
                _, output = onosLog.get_log(('ERROR', 'Exception',))
                if output and output.find('StorageException$Timeout') >= 0:
                    log_test.info('\nStorage Exception Timeout found on node: %s\n' %node)
                    log_test.info('Dumping the ERROR and Exception logs for node: %s\n' %node)
                    log_test.info('\n' + '-' * 50 + '\n')
                    log_test.info('%s' %output)
                    log_test.info('\n' + '-' * 50 + '\n')
                    failed = self.verify_leaders(controllers)
                    if failed:
                        log_test.info('Leaders command failed on nodes: %s' %failed)
                        log_test.error('Test failed on ITERATION %d' %iteration)
                        CordLogger.archive_results(self._testMethodName,
                                                   controllers = controllers,
                                                   iteration = 'FAILED',
                                                   archive_partition = self.ARCHIVE_PARTITION)
                        assert_equal(len(failed), 0)
                    return controller

            try:
                ips = self.get_cluster_current_member_ips(controller = adjacent_controller)
                log_test.info('ONOS cluster formed with controllers: %s' %ips)
                st = True
            except:
                st = False

            failed = self.verify_leaders(controllers)
            if failed:
                log_test.error('Test failed on ITERATION %d' %iteration)
                CordLogger.archive_results(self._testMethodName,
                                           controllers = controllers,
                                           iteration = 'FAILED',
                                           archive_partition = self.ARCHIVE_PARTITION)
            assert_equal(len(failed), 0)
            if st is False:
                log_test.info('No storage exception and ONOS cluster was not formed successfully')
            else:
                controller = None

            return controller

        next_controller = None
        tries = self.ITERATIONS
        for num in range(tries):
            index = num % ctlr_len
            #index = random.randrange(0, ctlr_len)
            controller_name = onos_map[controllers[index]] if next_controller is None else onos_map[next_controller]
            controller = onos_map[controller_name]
            log_test.info('ITERATION: %d. Restarting Controller %s' %(num + 1, controller_name))
            try:
                #enable debug log for the other controllers before restarting this controller
                adjacent_controllers = list( set(controllers) - set([controller]) )
                self.log_set(controllers = adjacent_controllers)
                self.log_set(app = 'io.atomix', controllers = adjacent_controllers)
                if graceful is True:
                    log_test.info('Gracefully shutting down controller: %s' %controller)
                    self.onos_shutdown(controller)
                cord_test_onos_restart(node = controller, timeout = 0)
                self.log_set(controllers = controller)
                self.log_set(app = 'io.atomix', controllers = controller)
                time.sleep(60)
            except:
                time.sleep(5)
                continue

            #first archive the test case logs for this run
            CordLogger.archive_results(self._testMethodName,
                                       controllers = controllers,
                                       iteration = 'iteration_{}'.format(num+1),
                                       archive_partition = self.ARCHIVE_PARTITION)
            next_controller = check_exception(num, controller = controller)

    def test_cluster_controller_restarts(self):
        '''Test the cluster by repeatedly killing the controllers'''
        self.cluster_controller_restarts()

    def test_cluster_graceful_controller_restarts(self):
        '''Test the cluster by repeatedly restarting the controllers gracefully'''
        self.cluster_controller_restarts(graceful = True)

    def test_cluster_single_controller_restarts(self):
        '''Test the cluster by repeatedly restarting the same controller'''
        controllers = get_controllers()
        ctlr_len = len(controllers)
        if ctlr_len <= 1:
            log_test.info('ONOS is not running in cluster mode. This test only works for cluster mode')
            assert_greater(ctlr_len, 1)

        #this call would verify the cluster for once
        onos_map = self.get_cluster_container_names_ips()

        def check_exception(iteration, controller, inclusive = False):
            adjacent_controllers = list(set(controllers) - set([controller]))
            adjacent_controller = adjacent_controllers[0]
            controller_list = adjacent_controllers if inclusive == False else controllers
            storage_exceptions = []
            for node in controller_list:
                onosLog = OnosLog(host = node)
                ##check the logs for storage exception
                _, output = onosLog.get_log(('ERROR', 'Exception',))
                if output and output.find('StorageException$Timeout') >= 0:
                    log_test.info('\nStorage Exception Timeout found on node: %s\n' %node)
                    log_test.info('Dumping the ERROR and Exception logs for node: %s\n' %node)
                    log_test.info('\n' + '-' * 50 + '\n')
                    log_test.info('%s' %output)
                    log_test.info('\n' + '-' * 50 + '\n')
                    storage_exceptions.append(node)

            failed = self.verify_leaders(controller_list)
            if failed:
                log_test.info('Leaders command failed on nodes: %s' %failed)
                if storage_exceptions:
                    log_test.info('Storage exception seen on nodes: %s' %storage_exceptions)
                    log_test.error('Test failed on ITERATION %d' %iteration)
                    CordLogger.archive_results('test_cluster_single_controller_restarts',
                                               controllers = controllers,
                                               iteration = 'FAILED',
                                               archive_partition = self.ARCHIVE_PARTITION)
                    assert_equal(len(failed), 0)
                    return controller

            for ctlr in controller_list:
                ips = self.get_cluster_current_member_ips(controller = ctlr,
                                                          nodes_filter = \
                                                          lambda nodes: [ n for n in nodes if n['state'] in [ 'ACTIVE', 'READY'] ])
                log_test.info('ONOS cluster on node %s formed with controllers: %s' %(ctlr, ips))
                if controller in ips and inclusive is False:
                    log_test.info('Controller %s still ACTIVE on Node %s after it was shutdown' %(controller, ctlr))
                if controller not in ips and inclusive is True:
                    log_test.info('Controller %s still INACTIVE on Node %s after it was restarted' %(controller, ctlr))

            return controller

        tries = self.ITERATIONS
        #chose a random controller for shutdown/restarts
        controller = controllers[random.randrange(0, ctlr_len)]
        controller_name = onos_map[controller]
        ##enable the log level for the controllers
        self.log_set(controllers = controllers)
        self.log_set(app = 'io.atomix', controllers = controllers)
        for num in range(tries):
            log_test.info('ITERATION: %d. Shutting down Controller %s' %(num + 1, controller_name))
            try:
                cord_test_onos_shutdown(node = controller)
                time.sleep(20)
            except:
                time.sleep(5)
                continue
            #check for exceptions on the adjacent nodes
            check_exception(num, controller)
            #Now restart the controller back
            log_test.info('Restarting back the controller %s' %controller_name)
            cord_test_onos_restart(node = controller)
            self.log_set(controllers = controller)
            self.log_set(app = 'io.atomix', controllers = controller)
            time.sleep(60)
            #archive the logs for this run
            CordLogger.archive_results('test_cluster_single_controller_restarts',
                                       controllers = controllers,
                                       iteration = 'iteration_{}'.format(num+1),
                                       archive_partition = self.ARCHIVE_PARTITION)
            check_exception(num, controller, inclusive = True)

    def test_cluster_restarts(self):
        '''Test the cluster by repeatedly restarting the entire cluster'''
        controllers = get_controllers()
        ctlr_len = len(controllers)
        if ctlr_len <= 1:
            log_test.info('ONOS is not running in cluster mode. This test only works for cluster mode')
            assert_greater(ctlr_len, 1)

        #this call would verify the cluster for once
        onos_map = self.get_cluster_container_names_ips()

        def check_exception(iteration):
            controller_list = controllers
            storage_exceptions = []
            for node in controller_list:
                onosLog = OnosLog(host = node)
                ##check the logs for storage exception
                _, output = onosLog.get_log(('ERROR', 'Exception',))
                if output and output.find('StorageException$Timeout') >= 0:
                    log_test.info('\nStorage Exception Timeout found on node: %s\n' %node)
                    log_test.info('Dumping the ERROR and Exception logs for node: %s\n' %node)
                    log_test.info('\n' + '-' * 50 + '\n')
                    log_test.info('%s' %output)
                    log_test.info('\n' + '-' * 50 + '\n')
                    storage_exceptions.append(node)

            failed = self.verify_leaders(controller_list)
            if failed:
                log_test.info('Leaders command failed on nodes: %s' %failed)
                if storage_exceptions:
                    log_test.info('Storage exception seen on nodes: %s' %storage_exceptions)
                    log_test.error('Test failed on ITERATION %d' %iteration)
                    CordLogger.archive_results('test_cluster_restarts',
                                               controllers = controllers,
                                               iteration = 'FAILED',
                                               archive_partition = self.ARCHIVE_PARTITION)
                    assert_equal(len(failed), 0)
                    return

            for ctlr in controller_list:
                ips = self.get_cluster_current_member_ips(controller = ctlr,
                                                          nodes_filter = \
                                                          lambda nodes: [ n for n in nodes if n['state'] in [ 'ACTIVE', 'READY'] ])
                log_test.info('ONOS cluster on node %s formed with controllers: %s' %(ctlr, ips))
                if len(ips) != len(controllers):
                    log_test.error('Test failed on ITERATION %d' %iteration)
                    CordLogger.archive_results('test_cluster_restarts',
                                               controllers = controllers,
                                               iteration = 'FAILED',
                                               archive_partition = self.ARCHIVE_PARTITION)
                assert_equal(len(ips), len(controllers))

        tries = self.ITERATIONS
        for num in range(tries):
            log_test.info('ITERATION: %d. Restarting cluster with controllers at %s' %(num+1, controllers))
            try:
                cord_test_restart_cluster()
                self.log_set(controllers = controllers)
                self.log_set(app = 'io.atomix', controllers = controllers)
                log_test.info('Delaying before verifying cluster status')
                time.sleep(60)
            except:
                time.sleep(10)
                continue

            #archive the logs for this run before verification
            CordLogger.archive_results('test_cluster_restarts',
                                       controllers = controllers,
                                       iteration = 'iteration_{}'.format(num+1),
                                       archive_partition = self.ARCHIVE_PARTITION)
            #check for exceptions on the adjacent nodes
            check_exception(num)

    #pass
    def test_cluster_formation_and_verification(self,onos_instances = ONOS_INSTANCES):
	status = self.verify_cluster_status(onos_instances = onos_instances)
	assert_equal(status, True)
	log_test.info('Cluster exists with %d ONOS instances'%onos_instances)

    #nottest cluster not coming up properly if member goes down
    def test_cluster_adding_members(self, add = 2, onos_instances = ONOS_INSTANCES):
	status = self.verify_cluster_status(onos_instances = onos_instances)
	assert_equal(status, True)
        onos_ips = self.get_cluster_current_member_ips()
	onos_instances = len(onos_ips)+add
        log_test.info('Adding %d nodes to the ONOS cluster' %add)
        cord_test_onos_add_cluster(count = add)
	status = self.verify_cluster_status(onos_instances=onos_instances)
        assert_equal(status, True)

    def test_cluster_removing_master(self, onos_instances = ONOS_INSTANCES):
        status = self.verify_cluster_status(onos_instances = onos_instances)
        assert_equal(status, True)
	master, standbys = self.get_cluster_current_master_standbys()
        assert_equal(len(standbys),(onos_instances-1))
        onos_names_ips =  self.get_cluster_container_names_ips()
        master_onos_name = onos_names_ips[master]
        log_test.info('Removing cluster current master %s'%(master))
        cord_test_onos_shutdown(node = master)
        time.sleep(60)
        onos_instances -= 1
        status = self.verify_cluster_status(onos_instances = onos_instances,controller=standbys[0])
        assert_equal(status, True)
	new_master, standbys = self.get_cluster_current_master_standbys(controller=standbys[0])
	assert_not_equal(master,new_master)
	log_test.info('Successfully removed clusters master instance')

    def test_cluster_removing_one_member(self, onos_instances = ONOS_INSTANCES):
        status = self.verify_cluster_status(onos_instances = onos_instances)
        assert_equal(status, True)
	master, standbys = self.get_cluster_current_master_standbys()
        assert_equal(len(standbys),(onos_instances-1))
        onos_names_ips =  self.get_cluster_container_names_ips()
        member_onos_name = onos_names_ips[standbys[0]]
	log_test.info('Removing cluster member %s'%standbys[0])
        cord_test_onos_shutdown(node = standbys[0])
	time.sleep(60)
	onos_instances -= 1
        status = self.verify_cluster_status(onos_instances = onos_instances,controller=master)
        assert_equal(status, True)

    def test_cluster_removing_two_members(self,onos_instances = ONOS_INSTANCES):
        status = self.verify_cluster_status(onos_instances = onos_instances)
        assert_equal(status, True)
       	master, standbys = self.get_cluster_current_master_standbys()
        assert_equal(len(standbys),(onos_instances-1))
        onos_names_ips =  self.get_cluster_container_names_ips()
        member1_onos_name = onos_names_ips[standbys[0]]
        member2_onos_name = onos_names_ips[standbys[1]]
        log_test.info('Removing cluster member %s'%standbys[0])
        cord_test_onos_shutdown(node = standbys[0])
        log_test.info('Removing cluster member %s'%standbys[1])
        cord_test_onos_shutdown(node = standbys[1])
        time.sleep(60)
        onos_instances = onos_instances - 2
        status = self.verify_cluster_status(onos_instances = onos_instances,controller=master)
        assert_equal(status, True)

    def test_cluster_removing_N_members(self,remove = 2, onos_instances = ONOS_INSTANCES):
        status = self.verify_cluster_status(onos_instances = onos_instances)
        assert_equal(status, True)
	master, standbys = self.get_cluster_current_master_standbys()
        assert_equal(len(standbys),(onos_instances-1))
        onos_names_ips =  self.get_cluster_container_names_ips()
        for i in range(remove):
	    member_onos_name = onos_names_ips[standbys[i]]
            log_test.info('Removing onos container with name %s'%standbys[i])
            cord_test_onos_shutdown(node = standbys[i])
        time.sleep(60)
        onos_instances = onos_instances - remove
        status = self.verify_cluster_status(onos_instances = onos_instances, controller=master)
        assert_equal(status, True)

    #nottest test cluster not coming up properly if member goes down
    def test_cluster_adding_and_removing_members(self,onos_instances = ONOS_INSTANCES , add = 2, remove = 2):
        status = self.verify_cluster_status(onos_instances = onos_instances)
        assert_equal(status, True)
        onos_ips = self.get_cluster_current_member_ips()
        onos_instances = len(onos_ips)+add
        log_test.info('Adding %d ONOS instances to the cluster'%add)
        cord_test_onos_add_cluster(count = add)
        status = self.verify_cluster_status(onos_instances=onos_instances)
        assert_equal(status, True)
        log_test.info('Removing %d ONOS instances from the cluster'%remove)
        for i in range(remove):
            name = '{}-{}'.format(Onos.NAME, onos_instances - i)
            log_test.info('Removing onos container with name %s'%name)
            cord_test_onos_shutdown(node = name)
        time.sleep(60)
        onos_instances = onos_instances-remove
        status = self.verify_cluster_status(onos_instances=onos_instances)
        assert_equal(status, True)

    #nottest cluster not coming up properly if member goes down
    def test_cluster_removing_and_adding_member(self,onos_instances = ONOS_INSTANCES,add = 1, remove = 1):
        status = self.verify_cluster_status(onos_instances = onos_instances)
        assert_equal(status, True)
        onos_ips = self.get_cluster_current_member_ips()
        onos_instances = onos_instances-remove
        log_test.info('Removing %d ONOS instances from the cluster'%remove)
        for i in range(remove):
            name = '{}-{}'.format(Onos.NAME, len(onos_ips)-i)
            log_test.info('Removing onos container with name %s'%name)
            cord_test_onos_shutdown(node = name)
        time.sleep(60)
        status = self.verify_cluster_status(onos_instances=onos_instances)
        assert_equal(status, True)
        log_test.info('Adding %d ONOS instances to the cluster'%add)
        cord_test_onos_add_cluster(count = add)
        onos_instances = onos_instances+add
        status = self.verify_cluster_status(onos_instances=onos_instances)
        assert_equal(status, True)

    def test_cluster_restart(self, onos_instances = ONOS_INSTANCES):
	status = self.verify_cluster_status(onos_instances = onos_instances)
        assert_equal(status, True)
	log_test.info('Restarting cluster')
	cord_test_onos_restart()
	status = self.verify_cluster_status(onos_instances = onos_instances)
        assert_equal(status, True)

    def test_cluster_master_restart(self,onos_instances = ONOS_INSTANCES):
        status = self.verify_cluster_status(onos_instances = onos_instances)
        assert_equal(status, True)
	master, standbys = self.get_cluster_current_master_standbys()
        onos_names_ips =  self.get_cluster_container_names_ips()
        master_onos_name = onos_names_ips[master]
        log_test.info('Restarting cluster master %s'%master)
        cord_test_onos_restart(node = master)
        status = self.verify_cluster_status(onos_instances = onos_instances)
        assert_equal(status, True)
	log_test.info('Cluster came up after master restart as expected')

    #test fail. master changing after restart. Need to check correct behavior.
    def test_cluster_master_ip_after_master_restart(self,onos_instances = ONOS_INSTANCES):
        status = self.verify_cluster_status(onos_instances = onos_instances)
        assert_equal(status, True)
        master1, standbys = self.get_cluster_current_master_standbys()
        onos_names_ips =  self.get_cluster_container_names_ips()
        master_onos_name = onos_names_ips[master1]
        log_test.info('Restarting cluster master %s'%master1)
        cord_test_onos_restart(node = master1)
        status = self.verify_cluster_status(onos_instances = onos_instances)
        assert_equal(status, True)
	master2, standbys = self.get_cluster_current_master_standbys()
	assert_equal(master1,master2)
        log_test.info('Cluster master is same before and after cluster master restart as expected')

    def test_cluster_one_member_restart(self,onos_instances = ONOS_INSTANCES):
        status = self.verify_cluster_status(onos_instances = onos_instances)
        assert_equal(status, True)
	master, standbys = self.get_cluster_current_master_standbys()
	assert_equal(len(standbys),(onos_instances-1))
        onos_names_ips =  self.get_cluster_container_names_ips()
	member_onos_name = onos_names_ips[standbys[0]]
        log_test.info('Restarting cluster member %s'%standbys[0])
        cord_test_onos_restart(node = standbys[0])
        status = self.verify_cluster_status(onos_instances = onos_instances)
        assert_equal(status, True)
	log_test.info('Cluster came up as expected after restarting one member')

    def test_cluster_two_members_restart(self,onos_instances = ONOS_INSTANCES):
        status = self.verify_cluster_status(onos_instances = onos_instances)
        assert_equal(status, True)
	master, standbys = self.get_cluster_current_master_standbys()
        assert_equal(len(standbys),(onos_instances-1))
        onos_names_ips =  self.get_cluster_container_names_ips()
        member1_onos_name = onos_names_ips[standbys[0]]
        member2_onos_name = onos_names_ips[standbys[1]]
        log_test.info('Restarting cluster members %s and %s'%(standbys[0],standbys[1]))
        cord_test_onos_restart(node = standbys[0])
        cord_test_onos_restart(node = standbys[1])
        status = self.verify_cluster_status(onos_instances = onos_instances)
        assert_equal(status, True)
	log_test.info('Cluster came up as expected after restarting two members')

    def test_cluster_state_with_N_members_restart(self, members = 2, onos_instances = ONOS_INSTANCES):
        status = self.verify_cluster_status(onos_instances = onos_instances)
        assert_equal(status,True)
	master, standbys = self.get_cluster_current_master_standbys()
        assert_equal(len(standbys),(onos_instances-1))
        onos_names_ips =  self.get_cluster_container_names_ips()
	for i in range(members):
            member_onos_name = onos_names_ips[standbys[i]]
	    log_test.info('Restarting cluster member %s'%standbys[i])
            cord_test_onos_restart(node = standbys[i])

        status = self.verify_cluster_status(onos_instances = onos_instances)
        assert_equal(status, True)
	log_test.info('Cluster came up as expected after restarting %d members'%members)

    def test_cluster_state_with_master_change(self,onos_instances = ONOS_INSTANCES):
        status = self.verify_cluster_status(onos_instances=onos_instances)
        assert_equal(status, True)
        master, standbys = self.get_cluster_current_master_standbys()
	assert_equal(len(standbys),(onos_instances-1))
        log_test.info('Cluster current master of devices is %s'%master)
	self.change_master_current_cluster(new_master=standbys[0])
        log_test.info('Cluster master changed successfully')

    #tested on single onos setup.
    def test_cluster_with_vrouter_routes_in_cluster_members(self,networks = 5,onos_instances = ONOS_INSTANCES):
        status = self.verify_cluster_status(onos_instances = onos_instances)
        assert_equal(status, True)
	onos_ips = self.get_cluster_current_member_ips()
        self.vrouter.setUpClass()
        res = self.vrouter.vrouter_network_verify(networks, peers = 1)
        assert_equal(res, True)
        for onos_ip in onos_ips:
            tries = 0
            flag = False
            try:
                self.cliEnter(controller = onos_ip)
                while tries <= 5:
                    routes = json.loads(self.cli.routes(jsonFormat = True))
                    if routes:
                        assert_equal(len(routes['routes4']), networks)
                        self.cliExit()
                        flag = True
                        break
                    else:
                        tries += 1
                        time.sleep(1)
                assert_equal(flag, True)
            except:
                log_test.info('Exception occured while checking routes in onos instance %s'%onos_ip)
                raise

    #tested on single onos setup.
    def test_cluster_with_vrouter_and_master_down(self,networks = 5, onos_instances = ONOS_INSTANCES):
        status = self.verify_cluster_status(onos_instances = onos_instances)
        assert_equal(status, True)
        onos_ips = self.get_cluster_current_member_ips()
	master, standbys = self.get_cluster_current_master_standbys()
	onos_names_ips =  self.get_cluster_container_names_ips()
	master_onos_name = onos_names_ips[master]
        self.vrouter.setUpClass()
        res = self.vrouter.vrouter_network_verify(networks, peers = 1)
	assert_equal(res,True)
        cord_test_onos_shutdown(node = master)
	time.sleep(60)
	log_test.info('Verifying vrouter traffic after cluster master is down')
	self.vrouter.vrouter_traffic_verify()

    #tested on single onos setup.
    def test_cluster_with_vrouter_and_restarting_master(self,networks = 5,onos_instances = ONOS_INSTANCES):
        status = self.verify_cluster_status(onos_instances = onos_instances)
        assert_equal(status, True)
        onos_ips = self.get_cluster_current_member_ips()
        master, standbys = self.get_cluster_current_master_standbys()
        onos_names_ips =  self.get_cluster_container_names_ips()
        master_onos_name = onos_names_ips[master]
        self.vrouter.setUpClass()
        res = self.vrouter.vrouter_network_verify(networks, peers = 1)
        assert_equal(res, True)
        cord_test_onos_restart()
	self.vrouter.vrouter_traffic_verify()

    #tested on single onos setup.
    def test_cluster_deactivating_vrouter_app(self,networks = 5, onos_instances = ONOS_INSTANCES):
        status = self.verify_cluster_status(onos_instances = onos_instances)
        assert_equal(status, True)
        self.vrouter.setUpClass()
        res = self.vrouter.vrouter_network_verify(networks, peers = 1)
        assert_equal(res, True)
	self.vrouter.vrouter_activate(deactivate=True)
        time.sleep(15)
	self.vrouter.vrouter_traffic_verify(positive_test=False)
	self.vrouter.vrouter_activate(deactivate=False)

    #tested on single onos setup.
    def test_cluster_deactivating_vrouter_app_and_making_master_down(self,networks = 5,onos_instances = ONOS_INSTANCES):
        status = self.verify_cluster_status(onos_instances = onos_instances)
        assert_equal(status, True)
	master, standbys = self.get_cluster_current_master_standbys()
        onos_names_ips =  self.get_cluster_container_names_ips()
        master_onos_name = onos_names_ips[master]
        self.vrouter.setUpClass()
	log_test.info('Verifying vrouter before master down')
        res = self.vrouter.vrouter_network_verify(networks, peers = 1)
        assert_equal(res, True)
	self.vrouter.vrouter_activate(deactivate=True)
	log_test.info('Verifying vrouter traffic after app deactivated')
        time.sleep(15) ## Expecting vrouter should work properly if master of cluster goes down
        self.vrouter.vrouter_traffic_verify(positive_test=False)
	log_test.info('Verifying vrouter traffic after master down')
        cord_test_onos_shutdown(node = master)
	time.sleep(60)
	self.vrouter.vrouter_traffic_verify(positive_test=False)
        self.vrouter.vrouter_activate(deactivate=False)

    #tested on single onos setup.
    def test_cluster_for_vrouter_app_and_making_member_down(self, networks = 5,onos_instances = ONOS_INSTANCES):
        status = self.verify_cluster_status(onos_instances = onos_instances)
        assert_equal(status, True)
        master, standbys = self.get_cluster_current_master_standbys()
        onos_names_ips =  self.get_cluster_container_names_ips()
        member_onos_name = onos_names_ips[standbys[0]]
        self.vrouter.setUpClass()
        log_test.info('Verifying vrouter before cluster member down')
        res = self.vrouter.vrouter_network_verify(networks, peers = 1)
        assert_equal(res, True) # Expecting vrouter should work properly
        log_test.info('Verifying vrouter after cluster member down')
        cord_test_onos_shutdown(node = standbys[0])
	time.sleep(60)
	self.vrouter.vrouter_traffic_verify()# Expecting vrouter should work properly if member of cluster goes down

    #tested on single onos setup.
    def test_cluster_for_vrouter_app_and_restarting_member(self,networks = 5, onos_instances = ONOS_INSTANCES):
        status = self.verify_cluster_status(onos_instances = onos_instances)
        assert_equal(status, True)
        master, standbys = self.get_cluster_current_master_standbys()
        onos_names_ips =  self.get_cluster_container_names_ips()
        member_onos_name = onos_names_ips[standbys[1]]
        self.vrouter.setUpClass()
        log_test.info('Verifying vrouter traffic before cluster member restart')
        res = self.vrouter.vrouter_network_verify(networks, peers = 1)
        assert_equal(res, True) # Expecting vrouter should work properly
        cord_test_onos_restart(node = standbys[1])
	log_test.info('Verifying vrouter traffic after cluster member restart')
        self.vrouter.vrouter_traffic_verify()# Expecting vrouter should work properly if member of cluster restarts

    #tested on single onos setup.
    def test_cluster_for_vrouter_app_restarting_cluster(self,networks = 5, onos_instances = ONOS_INSTANCES):
        status = self.verify_cluster_status(onos_instances = onos_instances)
        assert_equal(status, True)
        self.vrouter.setUpClass()
        log_test.info('Verifying vrouter traffic before cluster restart')
        res = self.vrouter.vrouter_network_verify(networks, peers = 1)
        assert_equal(res, True) # Expecting vrouter should work properly
	cord_test_onos_restart()
        log_test.info('Verifying vrouter traffic after cluster restart')
        self.vrouter.vrouter_traffic_verify()# Expecting vrouter should work properly if member of cluster restarts


    #test fails because flow state is in pending_add in onos
    def test_cluster_for_flows_of_udp_port_and_making_master_down(self, onos_instances = ONOS_INSTANCES):
        status = self.verify_cluster_status(onos_instances = onos_instances)
        assert_equal(status, True)
	master, standbys = self.get_cluster_current_master_standbys()
	onos_names_ips =  self.get_cluster_container_names_ips()
        master_onos_name = onos_names_ips[master]
        self.flows.setUpClass()
        egress = 1
        ingress = 2
        egress_map = { 'ip': '192.168.30.1', 'udp_port': 9500 }
        ingress_map = { 'ip': '192.168.40.1', 'udp_port': 9000 }
        flow = OnosFlowCtrl(deviceId = self.device_id,
                            egressPort = egress,
                            ingressPort = ingress,
                            udpSrc = ingress_map['udp_port'],
                            udpDst = egress_map['udp_port'],
			    controller=master
                            )
        result = flow.addFlow()
        assert_equal(result, True)
        time.sleep(1)
        self.success = False
        def mac_recv_task():
            def recv_cb(pkt):
                log_test.info('Pkt seen with ingress UDP port %s, egress UDP port %s' %(pkt[UDP].sport, pkt[UDP].dport))
                self.success = True
            sniff(timeout=2,
             lfilter = lambda p: UDP in p and p[UDP].dport == egress_map['udp_port']
                                and p[UDP].sport == ingress_map['udp_port'], prn = recv_cb, iface = self.flows.port_map[egress])

	for i in [0,1]:
	    if i == 1:
                cord_test_onos_shutdown(node = master)
                log_test.info('Verifying flows traffic after master killed')
                time.sleep(45)
	    else:
		log_test.info('Verifying flows traffic before master killed')
            t = threading.Thread(target = mac_recv_task)
            t.start()
            L2 = self.flows_eth #Ether(src = ingress_map['ether'], dst = egress_map['ether'])
            L3 = IP(src = ingress_map['ip'], dst = egress_map['ip'])
            L4 = UDP(sport = ingress_map['udp_port'], dport = egress_map['udp_port'])
            pkt = L2/L3/L4
            log_test.info('Sending packets to verify if flows are correct')
            sendp(pkt, count=50, iface = self.flows.port_map[ingress])
            t.join()
            assert_equal(self.success, True)

    def test_cluster_state_changing_master_and_flows_of_ecn(self,onos_instances = ONOS_INSTANCES):
        status = self.verify_cluster_status(onos_instances=onos_instances)
        assert_equal(status, True)
	master, standbys = self.get_cluster_current_master_standbys()
        self.flows.setUpClass()
        egress = 1
        ingress = 2
        egress_map = { 'ip': '192.168.30.1' }
        ingress_map = { 'ip': '192.168.40.1' }
        flow = OnosFlowCtrl(deviceId = self.device_id,
                            egressPort = egress,
                            ingressPort = ingress,
                            ecn = 1,
			    controller=master
                            )
        result = flow.addFlow()
        assert_equal(result, True)
        ##wait for flows to be added to ONOS
        time.sleep(1)
        self.success = False
        def mac_recv_task():
            def recv_cb(pkt):
                log_test.info('Pkt seen with ingress ip %s, egress ip %s and Type of Service %s' %(pkt[IP].src, pkt[IP].dst, pkt[IP].tos))
                self.success = True
            sniff(count=2, timeout=5,
                  lfilter = lambda p: IP in p and p[IP].dst == egress_map['ip'] and p[IP].src == ingress_map['ip']
                        and int(bin(p[IP].tos).split('b')[1][-2:],2) == 1,prn = recv_cb,
                                iface = self.flows.port_map[egress])
	for i in [0,1]:
	    if i == 1:
		log_test.info('Changing cluster master to %s'%standbys[0])
		self.change_master_current_cluster(new_master=standbys[0])
		log_test.info('Verifying flow traffic after cluster master chnaged')
	    else:
		log_test.info('Verifying flow traffic  before cluster master changed')
            t = threading.Thread(target = mac_recv_task)
            t.start()
            L2 = self.flows_eth # Ether(src = ingress_map['ether'], dst = egress_map['ether'])
            L3 = IP(src = ingress_map['ip'], dst = egress_map['ip'], tos = 1)
            pkt = L2/L3
            log_test.info('Sending a packet to verify if flows are correct')
            sendp(pkt, count=50, iface = self.flows.port_map[ingress])
            t.join()
            assert_equal(self.success, True)

    #pass
    def test_cluster_flow_for_ipv6_extension_header_and_master_restart(self,onos_instances = ONOS_INSTANCES):
        status = self.verify_cluster_status(onos_instances=onos_instances)
        assert_equal(status, True)
	master,standbys = self.get_cluster_current_master_standbys()
	onos_names_ips =  self.get_cluster_container_names_ips()
        master_onos_name = onos_names_ips[master]
        self.flows.setUpClass()
        egress = 1
        ingress = 2
        egress_map = { 'ipv6': '2001:db8:a0b:12f0:1010:1010:1010:1001' }
        ingress_map = { 'ipv6': '2001:db8:a0b:12f0:1010:1010:1010:1002' }
        flow = OnosFlowCtrl(deviceId = self.device_id,
                            egressPort = egress,
                            ingressPort = ingress,
                            ipv6_extension = 0,
			    controller=master
                            )

        result = flow.addFlow()
        assert_equal(result, True)
        ##wait for flows to be added to ONOS
        time.sleep(1)
        self.success = False
        def mac_recv_task():
            def recv_cb(pkt):
                log_test.info('Pkt seen with ingress ip %s, egress ip %s, Extension Header Type %s'%(pkt[IPv6].src, pkt[IPv6].dst, pkt[IPv6].nh))
                self.success = True
            sniff(timeout=2,count=5,
                  lfilter = lambda p: IPv6 in p and p[IPv6].nh == 0, prn = recv_cb, iface = self.flows.port_map[egress])
	for i in [0,1]:
	    if i == 1:
		log_test.info('Restart cluster current master %s'%master)
                Container(master_onos_name,Onos.IMAGE).restart()
                time.sleep(45)
	        log_test.info('Verifying flow traffic after master restart')
	    else:
		log_test.info('Verifying flow traffic before master restart')
            t = threading.Thread(target = mac_recv_task)
            t.start()
            L2 = self.flows_eth
            L3 = IPv6(src = ingress_map['ipv6'] , dst = egress_map['ipv6'], nh = 0)
            pkt = L2/L3
            log_test.info('Sending packets to verify if flows are correct')
            sendp(pkt, count=50, iface = self.flows.port_map[ingress])
            t.join()
            assert_equal(self.success, True)

    def send_multicast_data_traffic(self, group, intf= 'veth2',source = '1.2.3.4'):
        dst_mac = self.igmp.iptomac(group)
        eth = Ether(dst= dst_mac)
        ip = IP(dst=group,src=source)
        data = repr(monotonic.monotonic())
        sendp(eth/ip/data,count=20, iface = intf)
        pkt = (eth/ip/data)
        log_test.info('multicast traffic packet %s'%pkt.show())

    def verify_igmp_data_traffic(self, group, intf='veth0', source='1.2.3.4' ):
        log_test.info('verifying multicast traffic for group %s from source %s'%(group,source))
        self.success = False
        def recv_task():
            def igmp_recv_cb(pkt):
                log_test.info('multicast data received for group %s from source %s'%(group,source))
                self.success = True
            sniff(prn = igmp_recv_cb,lfilter = lambda p: IP in p and p[IP].dst == group and p[IP].src == source, count=1,timeout = 2, iface='veth0')
        t = threading.Thread(target = recv_task)
        t.start()
        self.send_multicast_data_traffic(group,source=source)
        t.join()
        return self.success

    #pass
    def test_cluster_with_igmp_include_exclude_modes_and_restarting_master(self, onos_instances=ONOS_INSTANCES):
	status = self.verify_cluster_status(onos_instances=onos_instances)
        assert_equal(status, True)
	master, standbys = self.get_cluster_current_master_standbys()
        assert_equal(len(standbys), (onos_instances-1))
	onos_names_ips =  self.get_cluster_container_names_ips()
        master_onos_name = onos_names_ips[master]
	self.igmp.setUp(controller=master)
        groups = ['224.2.3.4','230.5.6.7']
        src_list = ['2.2.2.2','3.3.3.3']
        self.igmp.onos_ssm_table_load(groups, src_list=src_list, controller=master)
        self.igmp.send_igmp_join(groups = [groups[0]], src_list = src_list,record_type = IGMP_V3_GR_TYPE_INCLUDE,
                             iface = self.V_INF1, delay = 2)
        self.igmp.send_igmp_join(groups = [groups[1]], src_list = src_list,record_type = IGMP_V3_GR_TYPE_EXCLUDE,
                             iface = self.V_INF1, delay = 2)
        status = self.verify_igmp_data_traffic(groups[0],intf=self.V_INF1,source=src_list[0])
        assert_equal(status,True)
        status = self.verify_igmp_data_traffic(groups[1],intf = self.V_INF1,source= src_list[1])
        assert_equal(status,False)
	log_test.info('restarting cluster master %s'%master)
	Container(master_onos_name,Onos.IMAGE).restart()
	time.sleep(60)
	log_test.info('verifying multicast data traffic after master restart')
	status = self.verify_igmp_data_traffic(groups[0],intf=self.V_INF1,source=src_list[0])
        assert_equal(status,True)
        status = self.verify_igmp_data_traffic(groups[1],intf = self.V_INF1,source= src_list[1])
        assert_equal(status,False)

    #pass
    def test_cluster_with_igmp_include_exclude_modes_and_making_master_down(self, onos_instances=ONOS_INSTANCES):
        status = self.verify_cluster_status(onos_instances=onos_instances)
        assert_equal(status, True)
        master, standbys = self.get_cluster_current_master_standbys()
        assert_equal(len(standbys), (onos_instances-1))
        onos_names_ips =  self.get_cluster_container_names_ips()
        master_onos_name = onos_names_ips[master]
        self.igmp.setUp(controller=master)
        groups = [self.igmp.random_mcast_ip(),self.igmp.random_mcast_ip()]
        src_list = [self.igmp.randomsourceip()]
        self.igmp.onos_ssm_table_load(groups, src_list=src_list,controller=master)
        self.igmp.send_igmp_join(groups = [groups[0]], src_list = src_list,record_type = IGMP_V3_GR_TYPE_INCLUDE,
                             iface = self.V_INF1, delay = 2)
        self.igmp.send_igmp_join(groups = [groups[1]], src_list = src_list,record_type = IGMP_V3_GR_TYPE_EXCLUDE,
                             iface = self.V_INF1, delay = 2)
        status = self.verify_igmp_data_traffic(groups[0],intf=self.V_INF1,source=src_list[0])
        assert_equal(status,True)
        status = self.verify_igmp_data_traffic(groups[1],intf = self.V_INF1,source= src_list[0])
        assert_equal(status,False)
        log_test.info('Killing cluster master %s'%master)
        Container(master_onos_name,Onos.IMAGE).kill()
        time.sleep(60)
	status = self.verify_cluster_status(onos_instances=onos_instances-1,controller=standbys[0])
        assert_equal(status, True)
        log_test.info('Verifying multicast data traffic after cluster master down')
        status = self.verify_igmp_data_traffic(groups[0],intf=self.V_INF1,source=src_list[0])
        assert_equal(status,True)
        status = self.verify_igmp_data_traffic(groups[1],intf = self.V_INF1,source= src_list[0])
        assert_equal(status,False)

    def test_cluster_with_igmp_include_mode_checking_traffic_recovery_time_after_master_is_down(self, onos_instances=ONOS_INSTANCES):
        status = self.verify_cluster_status(onos_instances=onos_instances)
        assert_equal(status, True)
        master, standbys = self.get_cluster_current_master_standbys()
        assert_equal(len(standbys), (onos_instances-1))
        onos_names_ips =  self.get_cluster_container_names_ips()
        master_onos_name = onos_names_ips[master]
        self.igmp.setUp(controller=master)
        groups = [self.igmp.random_mcast_ip()]
        src_list = [self.igmp.randomsourceip()]
        self.igmp.onos_ssm_table_load(groups, src_list=src_list,controller=master)
        self.igmp.send_igmp_join(groups = [groups[0]], src_list = src_list,record_type = IGMP_V3_GR_TYPE_INCLUDE,
                             iface = self.V_INF1, delay = 2)
        status = self.verify_igmp_data_traffic(groups[0],intf=self.V_INF1,source=src_list[0])
        assert_equal(status,True)
        log_test.info('Killing clusters master %s'%master)
        Container(master_onos_name,Onos.IMAGE).kill()
	count = 0
	for i in range(60):
            log_test.info('Verifying multicast data traffic after cluster master down')
            status = self.verify_igmp_data_traffic(groups[0],intf=self.V_INF1,source=src_list[0])
	    if status:
		break
	    else:
		count += 1
	        time.sleep(1)
	assert_equal(status, True)
	log_test.info('Time taken to recover traffic after clusters master down is %d seconds'%count)


    #pass
    def test_cluster_state_with_igmp_leave_group_after_master_change(self, onos_instances=ONOS_INSTANCES):
        status = self.verify_cluster_status(onos_instances=onos_instances)
        assert_equal(status, True)
        master, standbys = self.get_cluster_current_master_standbys()
	assert_equal(len(standbys), (onos_instances-1))
        self.igmp.setUp(controller=master)
        groups = [self.igmp.random_mcast_ip()]
        src_list = [self.igmp.randomsourceip()]
        self.igmp.onos_ssm_table_load(groups, src_list=src_list,controller=master)
        self.igmp.send_igmp_join(groups = [groups[0]], src_list = src_list,record_type = IGMP_V3_GR_TYPE_INCLUDE,
                             iface = self.V_INF1, delay = 2)
        status = self.verify_igmp_data_traffic(groups[0],intf=self.V_INF1,source=src_list[0])
        assert_equal(status,True)
	log_test.info('Changing cluster master %s to %s'%(master,standbys[0]))
	self.change_cluster_current_master(new_master=standbys[0])
	log_test.info('Verifying multicast traffic after cluster master change')
	status = self.verify_igmp_data_traffic(groups[0],intf=self.V_INF1,source=src_list[0])
        assert_equal(status,True)
        log_test.info('Sending igmp TO_EXCLUDE message to leave the group %s'%groups[0])
        self.igmp.send_igmp_join(groups = [groups[0]], src_list = src_list,record_type = IGMP_V3_GR_TYPE_CHANGE_TO_EXCLUDE,
                             iface = self.V_INF1, delay = 1)
	time.sleep(10)
        status = self.verify_igmp_data_traffic(groups[0],intf = self.V_INF1,source= src_list[0])
        assert_equal(status,False)

    #pass
    def test_cluster_state_with_igmp_join_before_and_after_master_change(self,onos_instances=ONOS_INSTANCES):
        status = self.verify_cluster_status(onos_instances=onos_instances)
        assert_equal(status, True)
	master,standbys = self.get_cluster_current_master_standbys()
	assert_equal(len(standbys), (onos_instances-1))
        self.igmp.setUp(controller=master)
        groups = [self.igmp.random_mcast_ip()]
        src_list = [self.igmp.randomsourceip()]
        self.igmp.onos_ssm_table_load(groups, src_list=src_list,controller=master)
	log_test.info('Changing cluster master %s to %s'%(master,standbys[0]))
	self.change_cluster_current_master(new_master = standbys[0])
        self.igmp.send_igmp_join(groups = [groups[0]], src_list = src_list,record_type = IGMP_V3_GR_TYPE_INCLUDE,
                             iface = self.V_INF1, delay = 2)
	time.sleep(1)
	self.change_cluster_current_master(new_master = master)
        status = self.verify_igmp_data_traffic(groups[0],intf=self.V_INF1,source=src_list[0])
        assert_equal(status,True)

    #pass
    @deferred(TLS_TIMEOUT)
    def test_cluster_with_eap_tls_traffic(self,onos_instances=ONOS_INSTANCES):
	status = self.verify_cluster_status(onos_instances=onos_instances)
        assert_equal(status, True)
	master, standbys = self.get_cluster_current_master_standbys()
        assert_equal(len(standbys), (onos_instances-1))
	self.tls.setUp(controller=master)
        df = defer.Deferred()
        def eap_tls_verify(df):
            tls = TLSAuthTest()
            tls.runTest()
            df.callback(0)
        reactor.callLater(0, eap_tls_verify, df)
        return df

    @deferred(120)
    def test_cluster_for_eap_tls_traffic_before_and_after_master_change(self,onos_instances=ONOS_INSTANCES):
	master, standbys = self.get_cluster_current_master_standbys()
        assert_equal(len(standbys), (onos_instances-1))
        self.tls.setUp()
        df = defer.Deferred()
	def eap_tls_verify2(df2):
            tls = TLSAuthTest()
            tls.runTest()
            df.callback(0)
        for i in [0,1]:
	    if i == 1:
		log_test.info('Changing cluster master %s to %s'%(master, standbys[0]))
		self.change_master_current_cluster(new_master=standbys[0])
                log_test.info('Verifying tls authentication after cluster master changed to %s'%standbys[0])
	    else:
		log_test.info('Verifying tls authentication before cluster master change')
            reactor.callLater(0, eap_tls_verify, df)
        return df

    @deferred(TLS_TIMEOUT)
    def test_cluster_for_eap_tls_traffic_before_and_after_making_master_down(self,onos_instances=ONOS_INSTANCES):
        status = self.verify_cluster_status(onos_instances=onos_instances)
        assert_equal(status, True)
        master, standbys = self.get_cluster_current_master_standbys()
        assert_equal(len(standbys), (onos_instances-1))
	onos_names_ips =  self.get_cluster_container_names_ips()
        master_onos_name = onos_names_ips[master]
        self.tls.setUp()
        df = defer.Deferred()
        def eap_tls_verify(df):
            tls = TLSAuthTest()
            tls.runTest()
            df.callback(0)
        for i in [0,1]:
            if i == 1:
                log_test.info('Killing cluster current master %s'%master)
                cord_test_onos_shutdown(node = master)
		time.sleep(20)
                status = self.verify_cluster_status(controller=standbys[0],onos_instances=onos_instances-1,verify=True)
		assert_equal(status, True)
		log_test.info('Cluster came up with %d instances after killing master'%(onos_instances-1))
                log_test.info('Verifying tls authentication after killing cluster master')
            reactor.callLater(0, eap_tls_verify, df)
        return df

    @deferred(TLS_TIMEOUT)
    def test_cluster_for_eap_tls_with_no_cert_before_and_after_member_is_restarted(self,onos_instances=ONOS_INSTANCES):
	status = self.verify_cluster_status(onos_instances=onos_instances)
        assert_equal(status, True)
	master, standbys = self.get_cluster_current_master_standbys()
        assert_equal(len(standbys), (onos_instances-1))
        onos_names_ips =  self.get_cluster_container_names_ips()
        member_onos_name = onos_names_ips[standbys[0]]
	self.tls.setUp()
        df = defer.Deferred()
        def eap_tls_no_cert(df):
            def tls_no_cert_cb():
                log_test.info('TLS authentication failed with no certificate')
            tls = TLSAuthTest(fail_cb = tls_no_cert_cb, client_cert = '')
            tls.runTest()
            assert_equal(tls.failTest, True)
            df.callback(0)
	for i in [0,1]:
	    if i == 1:
	        log_test.info('Restart cluster member %s'%standbys[0])
                Container(member_onos_name,Onos.IMAGE).restart()
                time.sleep(20)
                status = self.verify_cluster_status(onos_instances=onos_instances)
                assert_equal(status, True)
                log_test.info('Cluster came up with %d instances after member restart'%(onos_instances))
                log_test.info('Verifying tls authentication after member restart')
        reactor.callLater(0, eap_tls_no_cert, df)
        return df

    #pass
    def test_cluster_proxyarp_master_change_and_app_deactivation(self,onos_instances=ONOS_INSTANCES,hosts = 3):
	status = self.verify_cluster_status(onos_instances=onos_instances)
        assert_equal(status,True)
	master,standbys = self.get_cluster_current_master_standbys()
        assert_equal(len(standbys),(onos_instances-1))
	self.proxyarp.setUpClass()
        ports_map, egress_map,hosts_config = self.proxyarp.proxyarp_config(hosts = hosts,controller=master)
        ingress = hosts+1
        for hostip, hostmac in hosts_config:
            self.proxyarp.proxyarp_arpreply_verify(ingress,hostip,hostmac,PositiveTest = True)
            time.sleep(1)
	log_test.info('changing cluster current master from %s to %s'%(master,standbys[0]))
	self.change_cluster_current_master(new_master=standbys[0])
	log_test.info('verifying proxyarp after master change')
	for hostip, hostmac in hosts_config:
            self.proxyarp.proxyarp_arpreply_verify(ingress,hostip,hostmac,PositiveTest = True)
            time.sleep(1)
        log_test.info('Deactivating proxyarp  app and expecting proxyarp functionality not to work')
        self.proxyarp.proxyarp_activate(deactivate = True,controller=standbys[0])
	time.sleep(3)
        for hostip, hostmac in hosts_config:
            self.proxyarp.proxyarp_arpreply_verify(ingress,hostip,hostmac,PositiveTest = False)
            time.sleep(1)
        log_test.info('activating proxyarp  app and expecting to get arp reply from ONOS')
        self.proxyarp.proxyarp_activate(deactivate = False,controller=standbys[0])
	time.sleep(3)
        for hostip, hostmac in hosts_config:
            self.proxyarp.proxyarp_arpreply_verify(ingress,hostip,hostmac,PositiveTest = True)
            time.sleep(1)

    #pass
    def test_cluster_with_proxyarp_and_one_member_down(self,hosts=3,onos_instances=ONOS_INSTANCES):
	status = self.verify_cluster_status(onos_instances=onos_instances)
        assert_equal(status, True)
	master, standbys = self.get_cluster_current_master_standbys()
        assert_equal(len(standbys), (onos_instances-1))
        onos_names_ips =  self.get_cluster_container_names_ips()
        member_onos_name = onos_names_ips[standbys[1]]
	self.proxyarp.setUpClass()
        ports_map, egress_map,hosts_config = self.proxyarp.proxyarp_config(hosts = hosts,controller=master)
        ingress = hosts+1
        for hostip, hostmac in hosts_config:
            self.proxyarp.proxyarp_arpreply_verify(ingress,hostip,hostmac,PositiveTest = True)
            time.sleep(1)
	log_test.info('killing cluster member %s'%standbys[1])
        Container(member_onos_name,Onos.IMAGE).kill()
        time.sleep(20)
        status = self.verify_cluster_status(onos_instances=onos_instances-1,controller=master,verify=True)
        assert_equal(status, True)
        log_test.info('cluster came up with %d instances after member down'%(onos_instances-1))
        log_test.info('verifying proxy arp functionality after cluster member down')
	for hostip, hostmac in hosts_config:
            self.proxyarp.proxyarp_arpreply_verify(ingress,hostip,hostmac,PositiveTest = True)
            time.sleep(1)

    #pass
    def test_cluster_with_proxyarp_and_concurrent_requests_with_multiple_host_and_different_interfaces(self,hosts=10,onos_instances=ONOS_INSTANCES):
	status = self.verify_cluster_status(onos_instances=onos_instances)
        assert_equal(status, True)
	self.proxyarp.setUpClass()
	master, standbys = self.get_cluster_current_master_standbys()
        assert_equal(len(standbys), (onos_instances-1))
        ports_map, egress_map, hosts_config = self.proxyarp.proxyarp_config(hosts = hosts, controller=master)
        self.success = True
        ingress = hosts+1
        ports = range(ingress,ingress+10)
        hostmac = []
        hostip = []
        for ip,mac in hosts_config:
            hostmac.append(mac)
            hostip.append(ip)
        success_dir = {}
        def verify_proxyarp(*r):
            ingress, hostmac, hostip = r[0],r[1],r[2]
            def mac_recv_task():
                def recv_cb(pkt):
                    log_test.info('Arp Reply seen with source Mac is %s' %(pkt[ARP].hwsrc))
                    success_dir[current_thread().name] = True
                sniff(count=1, timeout=5,lfilter = lambda p: ARP in p and p[ARP].op == 2 and p[ARP].hwsrc == hostmac,
                    prn = recv_cb, iface = self.proxyarp.port_map[ingress])
            t = threading.Thread(target = mac_recv_task)
            t.start()
            pkt = (Ether(dst = 'ff:ff:ff:ff:ff:ff')/ARP(op=1,pdst= hostip))
            log_test.info('Sending arp request  for dest ip %s on interface %s' %
                 (hostip,self.proxyarp.port_map[ingress]))
            sendp(pkt, count = 10,iface = self.proxyarp.port_map[ingress])
            t.join()
        t = []
        for i in range(10):
            t.append(threading.Thread(target = verify_proxyarp, args = [ports[i],hostmac[i],hostip[i]]))
        for i in range(10):
            t[i].start()
	time.sleep(2)
        for i in range(10):
            t[i].join()
        if len(success_dir) != 10:
                self.success = False
        assert_equal(self.success, True)

    #pass
    def test_cluster_with_acl_rule_before_master_change_and_remove_acl_rule_after_master_change(self,onos_instances=ONOS_INSTANCES):
	status = self.verify_cluster_status(onos_instances=onos_instances)
        assert_equal(status, True)
	master,standbys = self.get_cluster_current_master_standbys()
        assert_equal(len(standbys),(onos_instances-1))
	self.acl.setUp()
        acl_rule = ACLTest()
        status,code = acl_rule.adding_acl_rule('v4', srcIp=self.acl.ACL_SRC_IP, dstIp =self.acl.ACL_DST_IP, action = 'allow',controller=master)
        if status is False:
            log_test.info('JSON request returned status %d' %code)
            assert_equal(status, True)
        result = acl_rule.get_acl_rules(controller=master)
        aclRules1 = result.json()['aclRules']
	log_test.info('Added acl rules is %s'%aclRules1)
        acl_Id = map(lambda d: d['id'], aclRules1)
	log_test.info('Changing cluster current master from %s to %s'%(master,standbys[0]))
	self.change_cluster_current_master(new_master=standbys[0])
        status,code = acl_rule.remove_acl_rule(acl_Id[0],controller=standbys[0])
        if status is False:
            log_test.info('JSON request returned status %d' %code)
            assert_equal(status, True)

    #pass
    def test_cluster_verifying_acl_rule_in_new_master_after_current_master_is_down(self,onos_instances=ONOS_INSTANCES):
        status = self.verify_cluster_status(onos_instances=onos_instances)
        assert_equal(status, True)
        master,standbys = self.get_cluster_current_master_standbys()
        assert_equal(len(standbys),(onos_instances-1))
	onos_names_ips =  self.get_cluster_container_names_ips()
	master_onos_name = onos_names_ips[master]
        self.acl.setUp()
        acl_rule = ACLTest()
        status,code = acl_rule.adding_acl_rule('v4', srcIp=self.acl.ACL_SRC_IP, dstIp =self.acl.ACL_DST_IP, action = 'allow',controller=master)
        if status is False:
            log_test.info('JSON request returned status %d' %code)
            assert_equal(status, True)
        result1 = acl_rule.get_acl_rules(controller=master)
        aclRules1 = result1.json()['aclRules']
        log_test.info('Added acl rules is %s'%aclRules1)
        acl_Id1 = map(lambda d: d['id'], aclRules1)
        log_test.info('Killing cluster current master %s'%master)
	Container(master_onos_name,Onos.IMAGE).kill()
	time.sleep(45)
	status = self.verify_cluster_status(onos_instances=onos_instances,controller=standbys[0])
        assert_equal(status, True)
        new_master,standbys = self.get_cluster_current_master_standbys(controller=standbys[0])
	assert_equal(len(standbys),(onos_instances-2))
	assert_not_equal(new_master,master)
        result2 = acl_rule.get_acl_rules(controller=new_master)
        aclRules2 = result2.json()['aclRules']
	acl_Id2 = map(lambda d: d['id'], aclRules2)
	log_test.info('Acl Ids before and after master down are %s and %s'%(acl_Id1,acl_Id2))
	assert_equal(acl_Id2,acl_Id1)

    #acl traffic scenario not working as acl rule is not getting added to onos
    def test_cluster_with_acl_traffic_before_and_after_two_members_down(self,onos_instances=ONOS_INSTANCES):
	status = self.verify_cluster_status(onos_instances=onos_instances)
        assert_equal(status, True)
	master,standbys = self.get_cluster_current_master_standbys()
        assert_equal(len(standbys),(onos_instances-1))
	onos_names_ips =  self.get_cluster_container_names_ips()
        member1_onos_name = onos_names_ips[standbys[0]]
        member2_onos_name = onos_names_ips[standbys[1]]
        ingress = self.acl.ingress_iface
        egress = self.acl.CURRENT_PORT_NUM
        acl_rule = ACLTest()
        status, code, host_ip_mac = acl_rule.generate_onos_interface_config(iface_num= self.acl.CURRENT_PORT_NUM, iface_name = 'b1',iface_count = 1, iface_ip = self.acl.HOST_DST_IP)
        self.acl.CURRENT_PORT_NUM += 1
        time.sleep(5)
        if status is False:
            log_test.info('JSON request returned status %d' %code)
            assert_equal(status, True)
        srcMac = '00:00:00:00:00:11'
        dstMac = host_ip_mac[0][1]
        self.acl.acl_hosts_add(dstHostIpMac = host_ip_mac, egress_iface_count = 1,  egress_iface_num = egress )
        status, code = acl_rule.adding_acl_rule('v4', srcIp=self.acl.ACL_SRC_IP, dstIp =self.acl.ACL_DST_IP, action = 'deny',controller=master)
        time.sleep(10)
        if status is False:
            log_test.info('JSON request returned status %d' %code)
            assert_equal(status, True)
        self.acl.acl_rule_traffic_send_recv(srcMac = srcMac, dstMac = dstMac ,srcIp =self.acl.ACL_SRC_IP, dstIp = self.acl.ACL_DST_IP,ingress =ingress, egress = egress, ip_proto = 'UDP', positive_test = False)
	log_test.info('killing cluster members %s and %s'%(standbys[0],standbys[1]))
        Container(member1_onos_name, Onos.IMAGE).kill()
        Container(member2_onos_name, Onos.IMAGE).kill()
	time.sleep(40)
	status = self.verify_cluster_status(onos_instances=onos_instances-2,verify=True,controller=master)
        assert_equal(status, True)
	self.acl.acl_rule_traffic_send_recv(srcMac = srcMac, dstMac = dstMac ,srcIp =self.acl.ACL_SRC_IP, dstIp = self.acl.ACL_DST_IP,ingress =ingress, egress = egress, ip_proto = 'UDP', positive_test = False)
        self.acl.acl_hosts_remove(egress_iface_count = 1,  egress_iface_num = egress)

    #pass
    def test_cluster_with_dhcpRelay_releasing_dhcp_ip_after_master_change(self, iface = 'veth0',onos_instances=ONOS_INSTANCES):
	status = self.verify_cluster_status(onos_instances=onos_instances)
        assert_equal(status, True)
	master,standbys = self.get_cluster_current_master_standbys()
        assert_equal(len(standbys),(onos_instances-1))
	self.dhcprelay.setUpClass(controller=master)
        mac = self.dhcprelay.get_mac(iface)
        self.dhcprelay.host_load(iface)
        ##we use the defaults for this test that serves as an example for others
        ##You don't need to restart dhcpd server if retaining default config
        config = self.dhcprelay.default_config
        options = self.dhcprelay.default_options
        subnet = self.dhcprelay.default_subnet_config
        dhcpd_interface_list = self.dhcprelay.relay_interfaces
        self.dhcprelay.dhcpd_start(intf_list = dhcpd_interface_list,
                         config = config,
                         options = options,
                         subnet = subnet,
			 controller=master)
        self.dhcprelay.dhcp = DHCPTest(seed_ip = '10.10.100.10', iface = iface)
        cip, sip = self.dhcprelay.send_recv(mac)
	log_test.info('Changing cluster current master from %s to %s'%(master, standbys[0]))
	self.change_master_current_cluster(new_master=standbys[0])
        log_test.info('Releasing ip %s to server %s' %(cip, sip))
        assert_equal(self.dhcprelay.dhcp.release(cip), True)
        log_test.info('Triggering DHCP discover again after release')
        cip2, sip2 = self.dhcprelay.send_recv(mac)
        log_test.info('Verifying released IP was given back on rediscover')
        assert_equal(cip, cip2)
        log_test.info('Test done. Releasing ip %s to server %s' %(cip2, sip2))
        assert_equal(self.dhcprelay.dhcp.release(cip2), True)
	self.dhcprelay.tearDownClass(controller=standbys[0])


    def test_cluster_with_dhcpRelay_and_verify_dhcp_ip_after_master_down(self, iface = 'veth0',onos_instances=ONOS_INSTANCES):
	status = self.verify_cluster_status(onos_instances=onos_instances)
        assert_equal(status, True)
        master,standbys = self.get_cluster_current_master_standbys()
        assert_equal(len(standbys),(onos_instances-1))
	onos_names_ips =  self.get_cluster_container_names_ips()
        master_onos_name = onos_names_ips[master]
        self.dhcprelay.setUpClass(controller=master)
        mac = self.dhcprelay.get_mac(iface)
        self.dhcprelay.host_load(iface)
        ##we use the defaults for this test that serves as an example for others
        ##You don't need to restart dhcpd server if retaining default config
        config = self.dhcprelay.default_config
        options = self.dhcprelay.default_options
        subnet = self.dhcprelay.default_subnet_config
        dhcpd_interface_list = self.dhcprelay.relay_interfaces
        self.dhcprelay.dhcpd_start(intf_list = dhcpd_interface_list,
                         config = config,
                         options = options,
                         subnet = subnet,
			 controller=master)
        self.dhcprelay.dhcp = DHCPTest(seed_ip = '10.10.10.1', iface = iface)
        log_test.info('Initiating dhcp process from client %s'%mac)
        cip, sip = self.dhcprelay.send_recv(mac)
        log_test.info('Killing cluster current master %s'%master)
	Container(master_onos_name, Onos.IMAGE).kill()
	time.sleep(60)
	status = self.verify_cluster_status(onos_instances=onos_instances-1,verify=True,controller=standbys[0])
        assert_equal(status, True)
	mac = self.dhcprelay.dhcp.get_mac(cip)[0]
        log_test.info("Verifying dhcp clients gets same IP after cluster master restarts")
        new_cip, new_sip = self.dhcprelay.dhcp.only_request(cip, mac)
        assert_equal(new_cip, cip)
	self.dhcprelay.tearDownClass(controller=standbys[0])

    #pass
    def test_cluster_with_dhcpRelay_and_simulate_client_by_changing_master(self, iface = 'veth0',onos_instances=ONOS_INSTANCES):
	status = self.verify_cluster_status(onos_instances=onos_instances)
        assert_equal(status, True)
	master,standbys = self.get_cluster_current_master_standbys()
        assert_equal(len(standbys),(onos_instances-1))
	self.dhcprelay.setUpClass(controller=master)
        macs = ['e4:90:5e:a3:82:c1','e4:90:5e:a3:82:c2','e4:90:5e:a3:82:c3']
        self.dhcprelay.host_load(iface)
        ##we use the defaults for this test that serves as an example for others
        ##You don't need to restart dhcpd server if retaining default config
        config = self.dhcprelay.default_config
        options = self.dhcprelay.default_options
        subnet = self.dhcprelay.default_subnet_config
        dhcpd_interface_list = self.dhcprelay.relay_interfaces
        self.dhcprelay.dhcpd_start(intf_list = dhcpd_interface_list,
                         config = config,
                         options = options,
                         subnet = subnet,
			 controller=master)
        self.dhcprelay.dhcp = DHCPTest(seed_ip = '10.10.10.1', iface = iface)
	cip1, sip1 = self.dhcprelay.send_recv(macs[0])
	assert_not_equal(cip1,None)
        log_test.info('Got dhcp client IP %s for mac %s when cluster master is %s'%(cip1,macs[0],master))
        log_test.info('Changing cluster master from %s to %s'%(master, standbys[0]))
	self.change_master_current_cluster(new_master=standbys[0])
	cip2, sip2 = self.dhcprelay.send_recv(macs[1])
	assert_not_equal(cip2,None)
	log_test.info('Got dhcp client IP %s for mac %s when cluster master is %s'%(cip2,macs[1],standbys[0]))
	self.change_master_current_cluster(new_master=master)
        log_test.info('Changing cluster master from %s to %s'%(standbys[0],master))
        cip3, sip3 = self.dhcprelay.send_recv(macs[2])
	assert_not_equal(cip3,None)
	log_test.info('Got dhcp client IP %s for mac %s when cluster master is %s'%(cip2,macs[2],master))
	self.dhcprelay.tearDownClass(controller=standbys[0])

    def test_cluster_with_cord_subscriber_joining_next_channel_before_and_after_cluster_restart(self,onos_instances=ONOS_INSTANCES):
	status = self.verify_cluster_status(onos_instances=onos_instances)
        assert_equal(status, True)
	self.subscriber.setUpClass(controller=master)
        self.subscriber.num_subscribers = 5
        self.subscriber.num_channels = 10
	for i in [0,1]:
	    if i == 1:
		cord_test_onos_restart()
		time.sleep(45)
		status = self.verify_cluster_status(onos_instances=onos_instances)
		assert_equal(status, True)
		log_test.info('Verifying cord subscriber functionality after cluster restart')
	    else:
		log_test.info('Verifying cord subscriber functionality before cluster restart')
            test_status = self.subscriber.subscriber_join_verify(num_subscribers = self.subscriber.num_subscribers,
                                                    num_channels = self.subscriber.num_channels,
                                                    cbs = (self.subscriber.tls_verify, self.subscriber.dhcp_next_verify,
                                                           self.subscriber.igmp_next_verify, self.subscriber.traffic_verify),
                                                    port_list = self.subscriber.generate_port_list(self.subscriber.num_subscribers,
                                                                                        self.subscriber.num_channels))
            assert_equal(test_status, True)
	self.subscriber.tearDownClass(controller=master)

    #not validated on cluster setup because ciena-cordigmp-multitable-2.0 app installation fails on cluster
    def test_cluster_with_cord_subscriber_join_next_channel_before_and_after_cluster_mastership_is_withdrawn(self,onos_instances=ONOS_INSTANCES):
        status = self.verify_cluster_status(onos_instances=onos_instances)
        assert_equal(status, True)
	master,standbys = self.get_cluster_current_master_standbys()
        assert_equal(len(standbys),(onos_instances-1))
        self.subscriber.setUpClass(controller=master)
        self.subscriber.num_subscribers = 5
        self.subscriber.num_channels = 10
        for i in [0,1]:
            if i == 1:
		status=self.withdraw_cluster_current_mastership(master_ip=master)
		asser_equal(status, True)
		master,standbys = self.get_cluster_current_master_standbys()
                log_test.info('verifying cord subscriber functionality after cluster current master withdraw mastership')
            else:
		 log_test.info('verifying cord subscriber functionality before cluster master withdraw mastership')
            test_status = self.subscriber.subscriber_join_verify(num_subscribers = self.subscriber.num_subscribers,
                                                    num_channels = self.subscriber.num_channels,
                                                    cbs = (self.subscriber.tls_verify, self.subscriber.dhcp_next_verify,
                                                           self.subscriber.igmp_next_verify, self.subscriber.traffic_verify),
                                                    port_list = self.subscriber.generate_port_list(self.subscriber.num_subscribers,
                                                                                        self.subscriber.num_channels),controller=master)
            assert_equal(test_status, True)
        self.subscriber.tearDownClass(controller=master)

    #not validated on cluster setup because ciena-cordigmp-multitable-2.0 app installation fails on cluster
    def test_cluster_with_cord_subscriber_join_recv_traffic_from_10channels_and_making_one_cluster_member_down(self,onos_instances=ONOS_INSTANCES):
	status = self.verify_cluster_status(onos_instances=onos_instances)
        assert_equal(status, True)
	master, standbys = self.get_cluster_current_master_standbys()
        assert_equal(len(standbys),(onos_instances-1))
        onos_names_ips =  self.get_cluster_container_names_ips()
        member_onos_name = onos_names_ips[standbys[0]]
	self.subscriber.setUpClass(controller=master)
	num_subscribers = 1
        num_channels = 10
	for i in [0,1]:
	    if i == 1:
                cord_test_onos_shutdown(node = standbys[0])
		time.sleep(30)
		status = self.verify_cluster_status(onos_instances=onos_instances-1,verify=True,controller=master)
                assert_equal(status, True)
		log_test.info('Verifying cord subscriber functionality after cluster member %s is down'%standbys[0])
	    else:
		log_test.info('Verifying cord subscriber functionality before cluster member %s is down'%standbys[0])
            test_status = self.subscriber.subscriber_join_verify(num_subscribers = num_subscribers,
                                                    num_channels = num_channels,
                                                    cbs = (self.subscriber.tls_verify, self.subscriber.dhcp_verify,
                                                              self.subscriber.igmp_verify, self.subscriber.traffic_verify),
                                                    port_list = self.subscriber.generate_port_list(num_subscribers, num_channels),
                                                    negative_subscriber_auth = 'all',controller=master)
            assert_equal(test_status, True)
	self.subscriber.tearDownClass(controller=master)

    def test_cluster_with_cord_subscriber_joining_next_10channels_making_two_cluster_members_down(self,onos_instances=ONOS_INSTANCES):
	status = self.verify_cluster_status(onos_instances=onos_instances)
        assert_equal(status, True)
	master, standbys = self.get_cluster_current_master_standbys()
        assert_equal(len(standbys),(onos_instances-1))
        onos_names_ips =  self.get_cluster_container_names_ips()
        member1_onos_name = onos_names_ips[standbys[0]]
	member2_onos_name = onos_names_ips[standbys[1]]
	self.subscriber.setUpClass(controller=master)
        num_subscribers = 1
        num_channels = 10
	for i in [0,1]:
	    if i == 1:
                cord_test_onos_shutdown(node = standbys[0])
                cord_test_onos_shutdown(node = standbys[1])
		time.sleep(60)
		status = self.verify_cluster_status(onos_instances=onos_instances-2)
                assert_equal(status, True)
		log_test.info('Verifying cord subscriber funtionality after cluster two members %s and %s down'%(standbys[0],standbys[1]))
	    else:
		log_test.info('Verifying cord subscriber funtionality before cluster two members %s and %s down'%(standbys[0],standbys[1]))
	    test_status = self.subscriber.subscriber_join_verify(num_subscribers = num_subscribers,
                                                    num_channels = num_channels,
                                                    cbs = (self.subscriber.tls_verify, self.subscriber.dhcp_next_verify,
                                                           self.subscriber.igmp_next_verify, self.subscriber.traffic_verify),
                                                    port_list = self.subscriber.generate_port_list(num_subscribers, num_channels),
                                                    negative_subscriber_auth = 'all')
            assert_equal(test_status, True)
	self.subscriber.tearDownClass(controller=master)

    #pass
    def test_cluster_with_multiple_ovs_switches(self,onos_instances = ONOS_INSTANCES):
	status = self.verify_cluster_status(onos_instances=onos_instances)
        assert_equal(status, True)
	device_dict = self.get_cluster_current_master_standbys_of_connected_devices()
	for device in device_dict.keys():
	    log_test.info("Device is %s"%device_dict[device])
	    assert_not_equal(device_dict[device]['master'],'none')
	    log_test.info('Master and standbys for device %s are %s and %s'%(device,device_dict[device]['master'],device_dict[device]['standbys']))
	    assert_equal(len(device_dict[device]['standbys']), onos_instances-1)

    #pass
    def test_cluster_state_in_multiple_ovs_switches(self,onos_instances = ONOS_INSTANCES):
        status = self.verify_cluster_status(onos_instances=onos_instances)
        assert_equal(status, True)
        device_dict = self.get_cluster_current_master_standbys_of_connected_devices()
	cluster_ips = self.get_cluster_current_member_ips()
	for ip in cluster_ips:
	    device_dict= self.get_cluster_current_master_standbys_of_connected_devices(controller = ip)
	    assert_equal(len(device_dict.keys()),onos_instances)
            for device in device_dict.keys():
                log_test.info("Device is %s"%device_dict[device])
                assert_not_equal(device_dict[device]['master'],'none')
                log_test.info('Master and standbys for device %s are %s and %s'%(device,device_dict[device]['master'],device_dict[device]['standbys']))
                assert_equal(len(device_dict[device]['standbys']), onos_instances-1)

    #pass
    def test_cluster_verifying_multiple_ovs_switches_after_master_is_restarted(self,onos_instances = ONOS_INSTANCES):
        status = self.verify_cluster_status(onos_instances=onos_instances)
        assert_equal(status, True)
	onos_names_ips =  self.get_cluster_container_names_ips()
	master_count = self.get_number_of_devices_of_master()
        log_test.info('Master count information is %s'%master_count)
	total_devices = 0
	for master in master_count.keys():
	    total_devices += master_count[master]['size']
	    if master_count[master]['size'] != 0:
		restart_ip = master
	assert_equal(total_devices,onos_instances)
	member_onos_name = onos_names_ips[restart_ip]
	log_test.info('Restarting cluster member %s having ip %s'%(member_onos_name,restart_ip))
        Container(member_onos_name, Onos.IMAGE).restart()
	time.sleep(40)
	master_count = self.get_number_of_devices_of_master()
	log_test.info('Master count information after restart is %s'%master_count)
	total_devices = 0
        for master in master_count.keys():
            total_devices += master_count[master]['size']
	    if master == restart_ip:
		assert_equal(master_count[master]['size'], 0)
	assert_equal(total_devices,onos_instances)

    #pass
    def test_cluster_verifying_multiple_ovs_switches_with_one_master_down(self,onos_instances = ONOS_INSTANCES):
        status = self.verify_cluster_status(onos_instances=onos_instances)
        assert_equal(status, True)
        onos_names_ips =  self.get_cluster_container_names_ips()
        master_count = self.get_number_of_devices_of_master()
        log_test.info('Master count information is %s'%master_count)
        total_devices = 0
        for master in master_count.keys():
            total_devices += master_count[master]['size']
            if master_count[master]['size'] != 0:
                restart_ip = master
        assert_equal(total_devices,onos_instances)
        master_onos_name = onos_names_ips[restart_ip]
        log_test.info('Shutting down cluster member %s having ip %s'%(master_onos_name,restart_ip))
        Container(master_onos_name, Onos.IMAGE).kill()
        time.sleep(40)
	for ip in onos_names_ips.keys():
	    if ip != restart_ip:
		controller_ip = ip
	status = self.verify_cluster_status(onos_instances=onos_instances-1,controller=controller_ip)
        assert_equal(status, True)
        master_count = self.get_number_of_devices_of_master(controller=controller_ip)
        log_test.info('Master count information after restart is %s'%master_count)
        total_devices = 0
        for master in master_count.keys():
            total_devices += master_count[master]['size']
            if master == restart_ip:
                assert_equal(master_count[master]['size'], 0)
        assert_equal(total_devices,onos_instances)

    #pass
    def test_cluster_verifying_multiple_ovs_switches_with_current_master_withdrawing_mastership(self,onos_instances = ONOS_INSTANCES):
        status = self.verify_cluster_status(onos_instances=onos_instances)
        assert_equal(status, True)
        master_count = self.get_number_of_devices_of_master()
        log_test.info('Master count information is %s'%master_count)
        total_devices = 0
        for master in master_count.keys():
            total_devices += int(master_count[master]['size'])
            if master_count[master]['size'] != 0:
                master_ip = master
		log_test.info('Devices of master %s are %s'%(master_count[master]['devices'],master))
		device_id = str(master_count[master]['devices'][0])
		device_count = master_count[master]['size']
        assert_equal(total_devices,onos_instances)
	log_test.info('Withdrawing mastership of device %s for controller %s'%(device_id,master_ip))
	status=self.withdraw_cluster_current_mastership(master_ip=master_ip,device_id = device_id)
        assert_equal(status, True)
        master_count = self.get_number_of_devices_of_master()
        log_test.info('Master count information after cluster mastership withdraw is %s'%master_count)
        total_devices = 0
        for master in master_count.keys():
            total_devices += int(master_count[master]['size'])
            if master == master_ip:
                assert_equal(master_count[master]['size'], device_count-1)
        assert_equal(total_devices,onos_instances)

    #pass
    def test_cluster_verifying_multiple_ovs_switches_and_restarting_cluster(self,onos_instances = ONOS_INSTANCES):
        status = self.verify_cluster_status(onos_instances=onos_instances)
        assert_equal(status, True)
        master_count = self.get_number_of_devices_of_master()
        log_test.info('Master count information is %s'%master_count)
        total_devices = 0
        for master in master_count.keys():
            total_devices += master_count[master]['size']
        assert_equal(total_devices,onos_instances)
        log_test.info('Restarting cluster')
	cord_test_onos_restart()
	time.sleep(60)
        master_count = self.get_number_of_devices_of_master()
        log_test.info('Master count information after restart is %s'%master_count)
        total_devices = 0
        for master in master_count.keys():
            total_devices += master_count[master]['size']
        assert_equal(total_devices,onos_instances)
