def calculate_upstream_throughput(self):
        '''
        Procedure that calculates the upstream throughput taking modcod and symbolrate from linecard
        :return: If return_code = 0, its a PASS. Return value contains throughput
        '''

        ret = ReturnValue('calculate_upstream_throughput')

        #Fetch upstream modcod and symbol rate from LC
        response = self.lc.getCmdOutputFromLCProcess('mcd channel show')

        if response.return_code > 2:
            ret = response
            ret.return_msg = 'Unable to fetch upstream modcod and symrate from Linecard because of the following error: '+response.return_msg
            return ret

        lc_output = response.return_value

        response = commonLib.splitByLineValue(lc_output, 'Symbol Rate',':','sym')

        if response.return_value == []:
            ret = response
            ret.return_msg = 'Unable to fetch Symbol Rate from "mcd channel show" because of the following error: '+response.return_msg
            return ret

        up_symrate = response.return_value[0]

        response = commonLib.splitByLineValue(lc_output, 'Modulation',':','')

        if response.return_value == []:
            ret = response
            ret.return_msg = 'Unable to fetch upstream Modulation from "mcd channel show" because of the following error: '+response.return_msg

            return ret

        up_modulation = self.modulation_map[response.return_value[0]]

        response = commonLib.splitByLineValue(lc_output, 'FEC','(',')')

        if response.return_value == []:
            ret = response
            ret.return_msg = 'Unable to fetch upstream FEC from "mcd channel show" because of the following error: '+response.return_msg
            return ret

        up_fecrate = response.return_value[0]

        log('DEBUG',up_symrate)
        log('DEBUG',up_modulation)
        log('DEBUG',int(up_fecrate.split("/")[0]))
        log('DEBUG',int(up_fecrate.split("/")[1]))

        #Calculate upstream throughput based on modulation, fecrate and symbolrate for upstream
        up_throughput = int((int(up_symrate)*int(up_modulation))/(1/(float(up_fecrate.split("/")[0])/int(up_fecrate.split("/")[1]))))/1000000

        ret.return_value = up_throughput
        ret.return_msg = 'Upstream throughput calculated successfully. Throughput is '+str(up_throughput)+' Mbps'
        ret.return_code = 0

        return ret
    def calculate_downstream_throughput(self):
        '''
        Procedure that calculates the downstream throughput taking modcod from PP_TPA and symbolrate from remote
        :return: If return_code = 0, its a PASS. Return value contains throughput
        '''

        ret = ReturnValue('calculate_downstream_throughput')

        #Fetch downstream modcod from PP_TPA
        response = self.pp.getCmdOutputFromPPProcess('pp_tpa', 'premote dvbs2_stats')

        if response.return_code > 2:
            ret = response
            ret.return_msg = 'Unable to fetch downstream modcod from PP because of the following error: '+response.return_msg
            return ret

        response = commonLib.splitByLineValue(response.return_value, 'cur_modcod_name','= "','"')

        if response.return_value == []:
            ret = response
            ret.return_msg = 'Unable to fetch downstream modcod from "premote dvbs2_stats" because of the following error: '+response.return_msg
            return ret

        down_modulation = self.modulation_map[response.return_value[0].split('_')[0]]
        down_fecrate = response.return_value[0].split('_')[1]

        #Fetch downstream symbolrate from remote falcon
        response = self.remote.getCmdOutputFromFalcon('rx symrate')

        if response.return_code > 2:
            ret = response
            ret.return_msg = 'Unable to fetch downstream symrate from Remote because of the following error: '+response.return_msg
            return ret

        response = commonLib.splitByLineValue(response.return_value, 'Rx Symrate','=','sym')

        if response.return_value == []:
            ret = response
            ret.return_msg = 'Unable to fetch downstream modcod from "Rx Symrate" because of the following error: '+response.return_msg
            return ret

        down_symrate = response.return_value[0]

        log('DEBUG', down_symrate)
        log('DEBUG', down_modulation)
        log('DEBUG', down_fecrate)

        #Calculate downstream throughput
        down_throughput = int(int(down_symrate)*int(down_modulation)*(float(down_fecrate.split("/")[0])/int(down_fecrate.split("/")[1])))/1000000

        ret.return_value = down_throughput
        ret.return_msg = 'Downstream throughput calculated successfully. Throughput is '+str(down_throughput)+' Mbps'
        ret.return_code = 0

        return ret
    def findPPWithRemoteIP(self):
        '''
        This procedure helps in finding out the PP which handles that remote with the remote IP as input.
        :return: If return_code = 0, its a PASS. return_value contains pp_ip
        '''
        ret = ReturnValue('findPPWithRemoteIP')
        response = self.pulse.getDIDWithEth0IP(self.terminal_ip)

        if response.return_code > 2:
            ret = response
            ret.return_msg = 'Unable to fetch serial number with terminal ip '+str(self.terminal_ip)+' because of the following error: '+response.return_msg
            return ret

        serial_number = response.return_value

        response = self.pp.getPPWithRemoteDID(serial_number, self.network_info['pp_ip_set'], pp_password=self.network_info['pp_password'])

        if response.return_code > 2:
            ret = response
            ret.return_msg = 'Unable to fetch PP IP with serial number '+str(serial_number)+' because of the following error: '+response.return_msg
            return ret

        pp_ip = response.return_value[0]

        ret.return_code = 0
        ret.return_value = pp_ip
        ret.return_msg = 'PP which handles remote '+str(self.terminal_ip)+' is '+str(pp_ip)

        return ret
 def validate_qos_status(self, sl_name):
     ret = ReturnValue("validate_qos_status")
     ret9 = rmt_obj.get_did('DID', 'CX751')
     if ret9.return_code != 0:
         ret = ret9
         return ret
     did = ret9.return_value
     if 'DOWN' in str(sl_name):
         ret10 = pp_obj.check_qos_status('Bps',
                                         row_key=sl_name,
                                         min_expected_val=28000000,
                                         max_expected_val=34000000,
                                         velo='yes',
                                         did=did)
         if ret10.return_code != 0:
             ret = ret10
             chkpt_fail('validate_qos_status', ret.return_msg)
             return ret
         else:
             ret.return_code = 0
             ret.return_value = None
             ret.return_msg = "Traffic rate is in range for DOWNSTREAM"
     if 'UP' in str(sl_name):
         ret11 = rmt_obj.check_qos_status('Out_bps',
                                          min_expected_val=3800000,
                                          max_expected_val=4300000,
                                          velo='yes',
                                          row_key=sl_name)
         if ret11.return_code != 0:
             ret = ret11
             chkpt_fail('validate_qos_status', ret.return_msg)
             return ret
         else:
             ret.return_code = 0
             ret.return_value = None
             ret.return_msg = "Traffic rate is in range for UPSTREAM"
     return ret
 def configure_mir_api(self, element_name, sspp_name, unconfig="no"):
     ret = ReturnValue("configure_mir_api")
     if unconfig == "no":
         ret1 = nms_api.getParameterOnMatch(
             'query?obj_name=' + str(element_name), ['obj_name'],
             [str(element_name)], 'obj_id')
         if ret1.return_code != 0:
             ret = ret1
             chkpt_fail('API call', ret.return_msg)
             return ret
         self.terminal_id = ret1.return_value
         sspp_name = sspp_name[0]
         ret2 = nms_api.getParameterOnMatch(
             'query?obj_name="' + str(sspp_name) + '"', ['obj_name'],
             [str(sspp_name)], 'obj_id')
         if ret2.return_code != 0:
             ret = ret2
             chkpt_fail('API call', ret.return_msg)
             return ret
         self.sspp_id = ret2.return_value
         component = 'terminalserviceplan'
         tsp_id = nms_api.getParameterOnMatch(str(component),
                                              ['obj_parentid'],
                                              [str(self.terminal_id)],
                                              'obj_id')
         input_url = 'sspc/query?obj_parent_id=' + str(
             tsp_id.return_value) + '&profile_id=' + str(self.sspp_id)
         print input_url
         ret3 = self.ws_api.get(str(input_url))
         if ret3.return_code != 0:
             ret = ret3
             chkpt_fail('API call', ret.return_msg)
             return ret
         sspc_id = ret3.return_value['data']['obj_id']
         component = 'terminalqosapplication'
         ret2 = self.ws_api.get(input_url=str(component))
         if ret2.return_code != 0:
             ret = ret2
             chkpt_fail('API call', ret.return_msg)
             return ret
         output = ret2.return_value
         count = output['meta']['count']
         self.ibound_id = []
         self.obound_id = []
         for x in range(0, count):
             if output['data'][x]['obj_parent_id'] == int(sspc_id):
                 if output['data'][x]['obj_attributes'][
                         'direction'] == "Inbound":
                     self.ibound_id.append(output['data'][x]['obj_id'])
                     continue
                 if output['data'][x]['obj_attributes'][
                         'direction'] == "Outbound":
                     self.obound_id.append(output['data'][x]['obj_id'])
         input_url = str(component) + '/' + str(self.ibound_id[0])
         ret3 = self.ws_api.get(input_url)
         if ret3.return_code != 0:
             ret = ret3
             chkpt_fail('API call', ret.return_msg)
             return ret
         print "output of inbound id is," + str(ret3.return_value)
         output = ret3.return_value
         self.original_mir_ib = output['data']['obj_attributes']['mir']
         input_mir = {"mir": "4"}
         ret4 = self.ws_api.patch(input_url, input_data_dict=input_mir)
         if ret4.return_code != 0:
             ret = ret4
             chkpt_fail('Patching component', ret.return_msg)
             return ret
         input_url = str(component) + '/' + str(self.obound_id[0])
         ret5 = self.ws_api.get(input_url)
         if ret5.return_code != 0:
             ret = ret5
             chkpt_fail('API call', ret.return_msg)
             return ret
         output = ret5.return_value
         self.original_mir_ob = output['data']['obj_attributes']['mir']
         input_mir = {"mir": "30"}
         ret6 = self.ws_api.patch(input_url, input_data_dict=input_mir)
         if ret6.return_code != 0:
             ret = ret6
             chkpt_fail('Patching component', ret.return_msg)
             return ret
         ret8 = self.ws_api.apply(str(self.terminal_id),
                                  input_data_dict=input_mir)
         if ret8.return_code != 0:
             ret = ret8
             chkpt_fail('API call', ret.return_msg)
             return ret
         ret = ret8
         return ret
     if unconfig == "yes":
         component = 'terminalqosapplication'
         input_url = str(component) + '/' + str(self.ibound_id[0])
         input_mir = {"mir": str(self.original_mir_ib)}
         ret4 = self.ws_api.patch(input_url, input_data_dict=input_mir)
         if ret4.return_code != 0:
             ret = ret4
             chkpt_fail('Patching component', ret.return_msg)
             return ret
         input_mir = {"mir": str(self.original_mir_ob)}
         input_url = str(component) + '/' + str(self.obound_id[0])
         ret6 = self.ws_api.patch(input_url, input_data_dict=input_mir)
         if ret6.return_code != 0:
             ret = ret6
             chkpt_fail('Patching component', ret.return_msg)
             return ret
         ret8 = self.ws_api.apply(str(self.terminal_id),
                                  input_data_dict=input_mir)
         if ret8.return_code != 0:
             ret = ret8
             chkpt_fail('API call', ret.return_msg)
             return ret
         ret = ret8
         return ret
    def find_right_throughput(self, throughput, spirent_cfg):
        '''
        Procedure that finds out the optimized throughput after passing through course and fine way of tuning it
        :param throughput: Initial throughput from network
        :param spirent_cfg: Spirent configuration file for traffic
        :return: If return_code = 0, its a PASS else FAIL, return_value contains optimized throughput
        '''
        ret = ReturnValue('find_right_throughput')

        optimized_throughput = throughput*int(self.throughput_expected_threshold)/100

        initial_throughput = optimized_throughput

        chkpt_info('Iteration 1 - Coarse tuning FPS.Small test time','Coarse tuning with FPS variations in steps of 0.5 Mbps with a test time of 30 seconds to find out an approximate throughput')

        #First test the setup with a smaller test time - which is 30 seconds
        commonLib.execCommand('sed -i "s/set TESTTIME .*/set TESTTIME \\"30\\"/g" '+spirent_cfg)

        #This loop below does coarse tuning, where decrements are done in steps of 0.5 Mbps. If it fails it decreases and iterates, if its PASSes it breaks the loop
        optimized_throughput = self.coarse_tuning(optimized_throughput, spirent_cfg)

        if optimized_throughput == 0:
            ret.return_msg = "Failed to get pass throughput threshold even after reducing the throughput by 10 Mbps from the expected throughput: "+str(initial_throughput)
            ret.return_value = 500
            return ret

        optimized_throughput += 100000

        chkpt_info('Iteration 2 - Coarse tuning FPS.Larger test time','Coarse tuning with FPS variations in steps of 0.5 Mbps with a test time of 300 seconds to find out an approximate throughput')

        #Above loop does coarse tuning until it passes, This loop below does fine tuning to check if it still passes - until we fail and break.
        while 1:
            #Now that we found the threshold, now test the setup with a bigger test time - which is 300 seconds or 5 minutes
            commonLib.execCommand('sed -i "s/set TESTTIME .*/set TESTTIME \\"300\\"/g" '+spirent_cfg)
            response = SpirentVelocityAPI_obj.send_spirent_traffic_cir(
                            spirent_config=str(spirent_cfg),
                            cir=optimized_throughput)

            if response.return_code > 0:
                optimized_throughput -= 100000

                #This loop below does fine tuning for larger testtime, where decrements are done in steps of 0.5 Mbps. If it fails it decreases and iterates, if its PASSes it breaks the loop
                optimized_throughput = self.coarse_tuning(optimized_throughput, spirent_cfg, tuning=500000)

                if optimized_throughput == 0:
                    ret.return_msg = "Failed to get pass throughput threshold even after reducing the throughput by 10 Mbps from the expected throughput: "+str(initial_throughput)
                    ret.return_value = 501
                    return ret

                break

            else:
                optimized_throughput += 100000

        chkpt_info('Iteration 3 - Fine tuning FPS.Larger test time','Fine tuning with minute FPS variations in steps of 0.1 Mbps with a test time of 300 seconds to find out an approximate throughput')

        #Fine tuning round 2
        while 1:

            response = SpirentVelocityAPI_obj.send_spirent_traffic_cir(
                            spirent_config=str(spirent_cfg),
                            cir=optimized_throughput)

            if response.return_code > 0:
                optimized_throughput -= 100000

                #This loop below does fine tuning for larger testtime, where decrements are done in steps of 0.1 Mbps. If it fails it decreases and iterates, if its PASSes it breaks the loop
                optimized_throughput = self.coarse_tuning(optimized_throughput, spirent_cfg, tuning=100000)

                if optimized_throughput == 0:
                    ret.return_msg = "Failed to get pass throughput threshold even after reducing the throughput by 2 Mbps from the expected throughput: "+str(initial_throughput)
                    ret.return_value = 501
                    return ret

                break

            else:
                optimized_throughput += 100000

        if optimized_throughput < initial_throughput:
            ret.return_value = optimized_throughput
            ret.return_msg = "Calculated throughput threshold for successful traffic is "+str(float(optimized_throughput)/1000000)+" Mbps which is not inline with the expected throughput "+str(float(initial_throughput)/1000000)+" Mbps ("+str(self.throughput_expected_threshold)+" percent of "+str(float(throughput)/1000000)+")"
            ret.return_code = 500
        else:
            ret.return_value = optimized_throughput
            ret.return_msg = "Calculated throughput threshold for successful traffic is "+str(float(optimized_throughput)/1000000)+" Mbps which is inline with the expected throughput "+str(float(initial_throughput)/1000000)+" Mbps ("+str(self.throughput_expected_threshold)+" percent of "+str(float(throughput)/1000000)+")"
            ret.return_code = 0

        return ret
    def update_ip_information(self, traffic_type, ip_info, vlan_id, direction, spirent_cfg_file_path, **kwargs):
        '''
        Procedure that updates unidirectional/bidirectional information to tcl configuration file
        :param traffic_type: UDP/TCP/MULTICAST
        :param ip_info: List that contains hub/remote information
        :param vlan_id: VLAN id information for traffic
        :param direction: upstream/downstream/bidirectional
        :param spirent_cfg_file_path: Spirent configuration path
        :return: If return_code = 0, its a PASS else FAIL
        '''
        ret = ReturnValue('update_ip_information')
        SRCIP = SRCMASK = SRCGW = DSTIP = DSTMASK = DSTGW = VLANID = DIR = STREAMNAME = FRAMELENGTHMODE = PS = FPS = NOOFCONNECTIONS = FILESIZE = ''

        #Decide if its unidirectional or bidirectional
        if 'bidirectional' in direction:
            for index in xrange(0, len(ip_info[0])):
                SRCIP += '\\"'+ip_info[0][index][0]+'\\" \\"'+ip_info[0][index][1]+'\\" '
                SRCMASK += '\\"'+ip_info[1][index][0]+'\\" \\"'+ip_info[1][index][1]+'\\" '
                SRCGW += '\\"'+ip_info[2][index][0]+'\\" \\"'+ip_info[2][index][1]+'\\" '
                DSTIP += '\\"'+ip_info[3][index][0]+'\\" \\"'+ip_info[3][index][1]+'\\" '
                DSTMASK += '\\"'+ip_info[4][index][0]+'\\" \\"'+ip_info[4][index][1]+'\\" '
                DSTGW += '\\"'+ip_info[5][index][0]+'\\" \\"'+ip_info[5][index][1]+'\\" '
                VLANID += '\\"'+str(vlan_id)+'\\" \\"'+str(vlan_id)+'\\" '
                DIR += '\\"DOWNSTREAM\\" \\"UPSTREAM\\" '
                STREAMNAME += '\\"DS\\" \\"US\\" '
                FRAMELENGTHMODE += '\\"FIXED\\" \\"FIXED\\" '
                if 'PS' in kwargs:
                    PS += '\\"'+kwargs['PS']+'\\" \\"'+kwargs['PS']+'\\" '
                if 'FPS' in kwargs:
                    FPS += '\\"'+kwargs['FPS']+'\\" \\"'+kwargs['FPS']+'\\" '
                if 'NOOFCONNECTIONS' in kwargs:
                    NOOFCONNECTIONS += '\\"'+kwargs['NOOFCONNECTIONS']+'\\" \\"'+kwargs['NOOFCONNECTIONS']+'\\" '
                if 'FILESIZE' in kwargs:
                    FILESIZE += '\\"'+kwargs['FILESIZE']+'\\" \\"'+kwargs['FILESIZE']+'\\" '
        elif direction == "downstream":
            for index in xrange(0, len(ip_info[0])):
                SRCIP += '\\"'+ip_info[0][index][0]+'\\" '
                SRCMASK += '\\"'+ip_info[1][index][0]+'\\" '
                SRCGW += '\\"'+ip_info[2][index][0]+'\\" '
                DSTIP += '\\"'+ip_info[3][index][0]+'\\" '
                DSTMASK += '\\"'+ip_info[4][index][0]+'\\" '
                DSTGW += '\\"'+ip_info[5][index][0]+'\\" '
                VLANID += '\\"'+str(vlan_id)+'\\" '
                DIR += '\\"DOWNSTREAM\\" '
                STREAMNAME += '\\"DS\\" '
                FRAMELENGTHMODE += '\\"FIXED\\" '
        elif direction == "upstream":
            for index in xrange(0, len(ip_info[0])):
                SRCIP += '\\"'+ip_info[3][index][0]+'\\" '
                SRCMASK += '\\"'+ip_info[4][index][0]+'\\" '
                SRCGW += '\\"'+ip_info[5][index][0]+'\\" '
                DSTIP += '\\"'+ip_info[0][index][0]+'\\" '
                DSTMASK += '\\"'+ip_info[1][index][0]+'\\" '
                DSTGW += '\\"'+ip_info[2][index][0]+'\\" '
                VLANID += '\\"'+str(vlan_id)+'\\" '
                DIR += '\\"UPSTREAM\\" '
                STREAMNAME += '\\"US\\" '
                FRAMELENGTHMODE += '\\"FIXED\\" '

        if direction != "bidirectional":
            if 'PS' in kwargs:
                PS += '\\"'+kwargs['PS']+'\\" '
            if 'FPS' in kwargs:
                FPS += '\\"'+kwargs['FPS']+'\\" '
            if 'NOOFCONNECTIONS' in kwargs:
                NOOFCONNECTIONS += '\\"'+kwargs['NOOFCONNECTIONS']+'\\" '
            if 'FILESIZE' in kwargs:
                FILESIZE += '\\"'+kwargs['FILESIZE']+'\\" '

        #Patch all Traffic_Type, IP addresses, vlan id in config file
        command_list = {'TRAFFIC_TYPE': 'sed -i "s/set TRAFFIC_TYPE .*/set TRAFFIC_TYPE \\"'+traffic_type+'\\"/g" '+spirent_cfg_file_path,
                        'SRCIP': 'sed -i "s/set SRCIP .*/set SRCIP {'+SRCIP+'}/g" '+spirent_cfg_file_path,
                        'SRCMASK': 'sed -i "s/set SRCMASK .*/set SRCMASK {'+SRCMASK+'}/g" '+spirent_cfg_file_path,
                        'SRCGW': 'sed -i "s/set SRCGW .*/set SRCGW {'+SRCGW+'}/g" '+spirent_cfg_file_path,
                        'DSTIP': 'sed -i "s/set DSTIP .*/set DSTIP {'+DSTIP+'}/g" '+spirent_cfg_file_path,
                        'DSTMASK': 'sed -i "s/set DSTMASK .*/set DSTMASK {'+DSTMASK+'}/g" '+spirent_cfg_file_path,
                        'DSTGW': 'sed -i "s/set DSTGW .*/set DSTGW {'+DSTGW+'}/g" '+spirent_cfg_file_path,
                        'VLANID': 'sed -i "s/set VLANID .*/set VLANID {'+VLANID+'}/g" '+spirent_cfg_file_path,
                        'DIR': 'sed -i "s/set DIR .*/set DIR {'+DIR+'}/g" '+spirent_cfg_file_path,
                        'STREAMNAME': 'sed -i "s/set STREAMNAME .*/set STREAMNAME {'+STREAMNAME+'}/g" '+spirent_cfg_file_path,
                        'FRAMELENGTHMODE': 'sed -i "s/set FRAMELENGTHMODE .*/set FRAMELENGTHMODE {'+FRAMELENGTHMODE+'}/g" '+spirent_cfg_file_path
                        }

        if PS != '':
            command_list['PS'] = 'sed -i "s/set PS .*/set PS {'+PS+'}/g" '+spirent_cfg_file_path
        if FPS != '':
            command_list['FPS'] = 'sed -i "s/set FPS .*/set FPS {'+FPS+'}/g" '+spirent_cfg_file_path
        if NOOFCONNECTIONS != '':
            command_list['NOOFCONNECTIONS'] = 'sed -i "s/set NOOFCONNECTIONS .*/set NOOFCONNECTIONS {'+NOOFCONNECTIONS+'}/g" '+spirent_cfg_file_path
        if FILESIZE != '':
            command_list['FILESIZE'] = 'sed -i "s/set FILESIZE .*/set FILESIZE {'+PS+'}/g" '+spirent_cfg_file_path

        for key in command_list:
            pre_ret3 = commonLib.execCommand(str(command_list[key]))

            if pre_ret3.return_value != '':
                ret = pre_ret3
                ret.return_msg = 'Failed to set '+str(key)+' for UDP traffic VLAN '+str(vlan_id)+': '+pre_ret3.return_msg
                return ret

        ret.return_code = 0
        ret.return_msg = 'Updated hub/remote info successfully'

        return ret