def getCapFile(self, port, typeOfCapture='data', saveToTempLocation='c:\\Temp', localLinuxLocation='.', appendToSavedCapturedFile=None):
        """
        Get the latest captured .cap file from ReST API server to local Linux drive.

        Parameters
            port: Format:[IxiaIpAddress, slotNumber, cardNumber]
                  Example: [ixChassisIp, '2', '1']
            typeOfCapture: data|control
            saveToTempLocation: Where to temporary save the .cap file on the ReST API server: C:\\Temp
                                The folder will be created if it doesn't exists.
            localLinuxLocation: Where to save the .cap file on the Linux machine.
            appendToSavedCapturedFile: Add a text string to the captured file.

        Example:
            captureObj.getCapFile([ixChassisIp, '2', '1'], 'control', 'c:\\Temp', '/home/hgee/test')
        """
        if appendToSavedCapturedFile != None:
            data = {'arg1': saveToTempLocation, 'arg2': appendToSavedCapturedFile}
        else:
            data = {'arg1': saveToTempLocation}
        self.ixnObj.post(self.ixnObj.sessionUrl+'/operations/savecapture', data=data)

        if typeOfCapture == 'control':
            capFileToGet = saveToTempLocation+'\\'+port[1]+'-'+port[2]+'_SW.cap'
        if typeOfCapture == 'data':
            capFileToGet = saveToTempLocation+'\\'+port[1]+'-'+port[2]+'_HW.cap'

        fileMgmtObj = FileMgmt(self.ixnObj)

        if self.ixnObj.serverOs in ['windows', 'windowsConnectionMgr']:
            fileMgmtObj.copyFileWindowsToLocalLinux(windowsPathAndFileName=capFileToGet, localPath=localLinuxLocation,
                                                    renameDestinationFile=None)
        if self.ixnObj.serverOs == 'linux':
            fileMgmtObj.copyFileLinuxToLocalLinux(linuxApiServerPathAndFileName=capFileToGet, localPath=localLinuxLocation,
                                                  renameDestinationFile=None)
Пример #2
0
class Statistics(object):
    def __init__(self, ixnObj=None):
        self.ixnObj = ixnObj

        # For takesnapshot()
        self.fileMgmtObj = FileMgmt(self.ixnObj)

    def setMainObject(self, mainObject):
        """
        Description
            For Python Robot Framework support.
        """
        self.ixnObj = mainObject

    def getStats(self,
                 viewObject=None,
                 viewName='Flow Statistics',
                 csvFile=None,
                 csvEnableFileTimestamp=False,
                 displayStats=True,
                 silentMode=True,
                 ignoreError=False):
        """
        Description
            Get stats by the statistic name or get stats by providing a view object handle.

        Parameters
            csvFile = None or <filename.csv>.
                      None will not create a CSV file.
                      Provide a <filename>.csv to record all stats to a CSV file.
                      Example: getStats(sessionUrl, csvFile='Flow_Statistics.csv')

            csvEnableFileTimestamp = True or False. If True, timestamp will be appended to the filename.

            displayStats: True or False. True=Display stats.

            ignoreError: True or False.  Returns None if viewName is not found.

            viewObject: The view object: http://{apiServerIp:port}/api/v1/sessions/2/ixnetwork/statistics/view/13
                        A view object handle could be obtained by calling getViewObject().

            viewName options (Not case sensitive):
               NOTE: Not all statistics are listed here.
                  You could get the statistic viewName directly from the IxNetwork GUI in the statistics.

            'Port Statistics'
            'Tx-Rx Frame Rate Statistics'
            'Port CPU Statistics'
            'Global Protocol Statistics'
            'Protocols Summary'
            'Port Summary'
            'BGP Peer Per Port'
            'OSPFv2-RTR Drill Down'
            'OSPFv2-RTR Per Port'
            'IPv4 Drill Down'
            'L2-L3 Test Summary Statistics'
            'Flow Statistics'
            'Traffic Item Statistics'
            'IGMP Host Drill Down'
            'IGMP Host Per Port'
            'IPv6 Drill Down'
            'MLD Host Drill Down'
            'MLD Host Per Port'
            'PIMv6 IF Drill Down'
            'PIMv6 IF Per Port'
            'Flow View'

         Note: Not all of the viewNames are listed here. You have to get the exact names from
               the IxNetwork GUI in statistics based on your protocol(s).

         Return a dictionary of all the stats: statDict[rowNumber][columnName] == statValue
           Get stats on row 2 for 'Tx Frames' = statDict[2]['Tx Frames']
        """
        if viewObject == None:
            viewList = self.ixnObj.get(
                '%s/%s/%s' % (self.ixnObj.sessionUrl, 'statistics', 'view'),
                silentMode=silentMode)
            views = [
                '%s/%s/%s/%s' %
                (self.ixnObj.sessionUrl, 'statistics', 'view', str(i['id']))
                for i in viewList.json()
            ]
            if silentMode is False:
                self.ixnObj.logInfo(
                    '\ngetStats: Searching for viewObj for viewName: %s' %
                    viewName)
            for view in views:
                #print('\nview:', view)
                # GetAttribute
                response = self.ixnObj.get('%s' % view, silentMode=silentMode)
                captionMatch = re.match(viewName,
                                        response.json()['caption'], re.I)
                if captionMatch:
                    # viewObj: sessionUrl + /statistics/view/11'
                    viewObject = view
                    break

            if viewObject == None and ignoreError == False:
                raise IxNetRestApiException(
                    "viewObj wasn't found for viewName: %s" % viewName)
            if viewObject == None and ignoreError == True:
                return None

        if silentMode is False:
            self.ixnObj.logInfo('\nviewObj: %s' % viewObject)

        for counter in range(0, 31):
            response = self.ixnObj.get(viewObject + '/page',
                                       silentMode=silentMode)
            totalPages = response.json()['totalPages']
            if totalPages == 'null':
                self.ixnObj.logInfo(
                    '\nGetting total pages is not ready yet. Waiting %d/30 seconds'
                    % counter,
                    timestamp=False)
                time.sleep(1)
            if totalPages != 'null':
                break
            if totalPages == 'null' and counter == 30:
                self.ixnObj.logInfo('\ngetStats failed: Getting total pages')
                return 1

        if csvFile != None:
            import csv
            csvFileName = csvFile.replace(' ', '_')
            if csvEnableFileTimestamp:
                import datetime
                timestamp = datetime.datetime.now().strftime('%H%M%S')
                if '.' in csvFileName:
                    csvFileNameTemp = csvFileName.split('.')[0]
                    csvFileNameExtension = csvFileName.split('.')[1]
                    csvFileName = csvFileNameTemp + '_' + timestamp + '.' + csvFileNameExtension
                else:
                    csvFileName = csvFileName + '_' + timestamp

            csvFile = open(csvFileName, 'w')
            csvWriteObj = csv.writer(csvFile)

        # Get the stat column names
        columnList = response.json()['columnCaptions']
        if csvFile != None:
            csvWriteObj.writerow(columnList)

        flowNumber = 1
        statDict = {}
        # Get the stat values
        for pageNumber in range(1, totalPages + 1):
            self.ixnObj.patch(viewObject + '/page',
                              data={'currentPage': pageNumber},
                              silentMode=silentMode)
            response = self.ixnObj.get(viewObject + '/page',
                                       silentMode=silentMode)
            statValueList = response.json()['pageValues']
            for statValue in statValueList:
                if csvFile != None:
                    csvWriteObj.writerow(statValue[0])
                if displayStats:
                    self.ixnObj.logInfo('\nRow: %d' % flowNumber,
                                        timestamp=False)
                statDict[flowNumber] = {}
                index = 0
                for statValue in statValue[0]:
                    statName = columnList[index]
                    statDict[flowNumber].update({statName: statValue})
                    if displayStats:
                        self.ixnObj.logInfo('\t%s: %s' % (statName, statValue),
                                            timestamp=False)
                    index += 1
                flowNumber += 1

        if csvFile != None:
            csvFile.close()
        return statDict

        # Flow Statistics dictionary output example
        '''
        Flow: 50
            Tx Port: Ethernet - 002
            Rx Port: Ethernet - 001
            Traffic Item: OSPF T1 to T2
            Source/Dest Value Pair: 2.0.21.1-1.0.21.1
            Flow Group: OSPF T1 to T2-FlowGroup-1 - Flow Group 0002
            Tx Frames: 35873
            Rx Frames: 35873
            Packet Loss Duration (ms):  11.106
            Frames Delta: 0
            Loss %: 0
            Tx Frame Rate: 3643.5
            Rx Frame Rate: 3643.5
            Tx L1 Rate (bps): 4313904
            Rx L1 Rate (bps): 4313904
            Rx Bytes: 4591744
            Tx Rate (Bps): 466368
            Rx Rate (Bps): 466368
            Tx Rate (bps): 3730944
            Rx Rate (bps): 3730944
            Tx Rate (Kbps): 3730.944
            Rx Rate (Kbps): 3730.944
            Tx Rate (Mbps): 3.731
            Rx Rate (Mbps): 3.731
            Store-Forward Avg Latency (ns): 0
            Store-Forward Min Latency (ns): 0
            Store-Forward Max Latency (ns): 0
            First TimeStamp: 00:00:00.722
            Last TimeStamp: 00:00:10.568
        '''

    def removeAllTclViews(self):
        """
        Description
           Removes all created stat views.
        """
        removeAllTclViewsUrl = self.ixnObj.sessionUrl + '/operations/removealltclviews'
        response = self.ixnObj.post(removeAllTclViewsUrl)
        self.ixnObj.waitForComplete(
            response, removeAllTclViewsUrl + '/' + response.json()['id'])

    def clearStats(self):
        """
        Description
           Clears all stats

        Syntax
           POST = https://{apiServerIp:port}/api/v1/sessions/<id>/ixnetwork/operations/clearstats
        """
        self.ixnObj.post(self.ixnObj.sessionUrl + '/operations/clearstats')

    def takeSnapshot(self,
                     viewName='Flow Statistics',
                     windowsPath=None,
                     localLinuxPath=None,
                     renameDestinationFile=None,
                     includeTimestamp=False,
                     mode='overwrite'):
        """
        Description
            Take a snapshot of the vieweName statistics.  This is a two step process.
            1> Take a snapshot of the statistics and store it in the C: drive.
            2> Copy the statistics from the c: drive to remote Linux.

        Parameters
            viewName: The name of the statistics to get.
            windowsPath: A C: drive + path to store the snapshot: c:\\Results
            localLinuxPath: None|A path. If None, this API won't copy the stat file to local Linux.
                       The stat file will remain on Windows c: drive.
            renameDestinationFile: None or a name of the file other than the viewName.
            includeTimestamp: True|False: To include a timestamp at the end of the file.
            mode: append|overwrite: append=To append stats to an existing stat file.
                                    overwrite=Don't append stats. Create a new stat file.

        Example:
            takeSnapshot(viewName='Flow Statistics', windowsPath='C:\\Results', localLinuxPath='/home/hgee',
                        renameDestinationFile='my_renamed_stat_file.csv', includeTimestamp=True)
        """
        # TODO: For Linux API server
        #    POST /api/v1/sessions/1/ixnetwork/operations/getdefaultsnapshotsettings
        #    "Snapshot.View.Csv.Location: \"/root/.local/share/Ixia/IxNetwork/data/logs/Snapshot CSV\""

        if windowsPath is None:
            raise IxNetRestApiException('\nMust include windowsPath\n')

        if mode == 'append':
            mode = 'kAppendCSVFile'
        if mode == 'overwrite':
            mode = 'kOverwriteCSVFile'

        data = {
            'arg1': [viewName],
            'arg2': [
                "Snapshot.View.Contents: \"allPages\"",
                "Snapshot.View.Csv.Location: \"{0}\"".format(windowsPath),
                "Snapshot.View.Csv.GeneratingMode: \"%s\"" % mode,
                "Snapshot.View.Csv.StringQuotes: \"True\"",
                "Snapshot.View.Csv.SupportsCSVSorting: \"False\"",
                "Snapshot.View.Csv.FormatTimestamp: \"True\"",
                "Snapshot.View.Csv.DumpTxPortLabelMap: \"False\"",
                "Snapshot.View.Csv.DecimalPrecision: \"3\""
            ]
        }
        url = self.ixnObj.sessionUrl + '/operations/takeviewcsvsnapshot'
        response = self.ixnObj.post(url, data=data)
        self.ixnObj.waitForComplete(response,
                                    url + '/' + response.json()['id'])

        #response = self.ixnObj.get(self.ixnObj.sessionUrl+'/files?filename=Flow Statistics.csv&absolute=c:\\Results', ignoreError=True)
        if localLinuxPath:
            # Get the snapshot. Use the csvFilename that was specified and the location
            self.fileMgmtObj.copyFileWindowsToLocalLinux(
                '{0}\\{1}.csv'.format(windowsPath, viewName),
                localLinuxPath,
                renameDestinationFile=renameDestinationFile,
                includeTimestamp=includeTimestamp)

    def getViewObject(self, viewName='Flow Statistics'):
        """
        Description
            To get just the statistic view object.
            Mainly used by internal APIs such as takeCsvSnapshot that
            requires the statistics view object handle.

        Parameter
         viewName:  Options (case sensitive):
            "Port Statistics"
            "Tx-Rx Frame Rate Statistics"
            "Port CPU Statistics"
            "Global Protocol Statistics"
            "Protocols Summary"
            "Port Summary"
            "OSPFv2-RTR Drill Down"
            "OSPFv2-RTR Per Port"
            "IPv4 Drill Down"
            "L2-L3 Test Summary Statistics"
            "Flow Statistics"
            "Traffic Item Statistics"
        """
        self.ixnObj.logInfo('\ngetStats: %s' % viewName)
        viewList = self.ixnObj.get(
            "%s/%s/%s" % (self.ixnObj.sessionUrl, "statistics", "view"))
        views = [
            "%s/%s/%s/%s" %
            (self.ixnObj.sessionUrl, "statistics", "view", str(i["id"]))
            for i in viewList.json()
        ]
        for view in views:
            # GetAttribute
            response = self.ixnObj.get(view)
            caption = response.json()["caption"]
            if viewName == caption:
                # viewObj: sessionUrl + "/statistics/view/11"
                viewObj = view
                return viewObj
        return None

    def clearStats(self):
        """
        Description
            Clear all stats and wait for API server to finish.
        """
        url = self.ixnObj.sessionUrl + '/operations/clearStats'
        response = self.ixnObj.post(url,
                                    data={'arg1': ['waitForPortStatsRefresh']})
Пример #3
0
    def getCapFile(self,
                   port,
                   typeOfCapture='data',
                   saveToTempLocation='c:\\Temp',
                   localLinuxLocation='.',
                   appendToSavedCapturedFile=None):
        """
        Get the latest captured .cap file from ReST API server to local Linux drive.

        Parameters
            port: Format:[IxiaIpAddress, slotNumber, cardNumber]
                  Example: [ixChassisIp, '2', '1']

            typeOfCapture: data|control

            saveToTempLocation: For Windows:
                                    Where to temporary save the .cap file on the ReST API server: 
                                    Provide any path with double backslashes: C:\\Temp.
                                    The folder will be created if it doesn't exists.

                                For Linux, value= 'linux'.
 
            localLinuxLocation: Where to save the .cap file on the local Linux machine.

            appendToSavedCapturedFile: Add a text string to the captured file.

        Example:
            captureObj.getCapFile([ixChassisIp, '2', '1'], 'control', 'c:\\Temp', '/home/hgee/test')

        Syntaxes:
               PATCH: /vport/2
               DATA: {'rxMode': 'captureAndMeasure'}

               PATCH: /vport/2/capture
               DATA: {'softwareEnabled': False, 'hardwareEnabled': True}
 
               # Set traffic item to send continuous packets
               PATCH: /traffic/trafficItem/1/configElement/<id>/transmissionControl
               DATA: {'type': 'continuous'}

               POST: /traffic/trafficItem/operations/generate
               DATA: {"arg1": ["/api/v1/sessions/<id>/ixnetwork/traffic/trafficItem/1"]}

               POST: /traffic/operations/apply
               DATA: {"arg1": "/api/v1/sessions/<id>/ixnetwork/traffic"}

               POST: /traffic/operations/start
               DATA: {"arg1": "https://192.168.70.12/api/v1/sessions/<id>/ixnetwork/traffic"}

               Start continuous traffic

               POST: /ixnetwork/operations/startcapture
               POST: /ixnetwork/operations/stopcapture
               POST: /ixnetwork/operations/savecapturefiles
               DATA: {"arg1": "packetCaptureFolder"}  <-- This could be any name.  Just a temporary folder to store the captured file.

               Wait for the /operations/savecapturefiles/<id> to complete.  May take up to a minute or more.

               For Windows API server:
                  POST: /ixnetwork/operations/copyfile
                  DATA: {"arg1": "c:\\Results\\port2_HW.cap", "arg2": "/api/v1/sessions/1/ixnetwork/files/port2_HW.cap"}
                  GET: /ixnetwork/files?filename=port2_HW.cap

               For Linux API server:
                  POST: /ixnetwork/operations/copyfile
                  DATA: {"arg1": "captures/packetCaptureFolder/port2_HW.cap", "arg2": "/api/v1/sessions/<id>/ixnetwork/files/port2_HW.cap"}
                  GET: /ixnetwork/files?filename=captures/packetCaptureFolder/port2_HW.cap
        """

        # For Linux API server
        if '\\' not in saveToTempLocation:
            # For Linux API server, need to give a name for a temporary folder
            saveToTempLocation = 'packetCaptureFolder'

            # For Linux API server, must get the vport name and cannot modify the vport name.
            vport = self.portMgmtObj.getVports([port])[0]
            response = self.ixnObj.get(self.ixnObj.httpHeader + vport)
            vportName = response.json()['name']

            vportName = vportName.replace('/', '_')
            vportName = vportName.replace(' ', '_')
            self.ixnObj.logInfo('vportName: {}'.format(vportName))

        if appendToSavedCapturedFile != None:
            data = {
                'arg1': saveToTempLocation,
                'arg2': appendToSavedCapturedFile
            }
        else:
            data = {'arg1': saveToTempLocation}

        response = self.ixnObj.post(self.ixnObj.sessionUrl +
                                    '/operations/savecapturefiles',
                                    data=data)
        self.ixnObj.waitForComplete(response,
                                    self.ixnObj.httpHeader +
                                    response.json()['url'],
                                    timeout=300)
        capfilePathName = response.json()['result'][0]
        # example capfilePathName: 'c:\\Results\\1-7-2_HW.cap'
        if typeOfCapture == 'control':
            if '\\' not in saveToTempLocation:
                # For Linux
                capFileToGet = '/home/ixia_apps/web/platform/apps-resources/ixnetworkweb/configs/captures/{0}/{1}_SW.cap'.format(
                    saveToTempLocation, vportName)
            else:
                # For Windows
                capFileToGet = capfilePathName

        if typeOfCapture == 'data':
            if '\\' not in saveToTempLocation:
                # For Linux
                capFileToGet = '/home/ixia_apps/web/platform/apps-resources/ixnetworkweb/configs/captures/{0}/{1}_HW.cap'.format(
                    saveToTempLocation, vportName)
            else:
                capFileToGet = capfilePathName

        fileMgmtObj = FileMgmt(self.ixnObj)

        if self.ixnObj.serverOs in ['windows', 'windowsConnectionMgr']:
            fileMgmtObj.copyFileWindowsToLocalLinux(
                windowsPathAndFileName=capFileToGet,
                localPath=localLinuxLocation,
                renameDestinationFile=None)
        if self.ixnObj.serverOs == 'linux':
            # Parse out captures/packetCaptureFolder/<vportName>_HW.cap
            match = re.search('.*(captures.*)', capFileToGet)
            pathExtension = match.group(1)

            fileMgmtObj.copyFileLinuxToLocalLinux(
                linuxApiServerPathAndFileName=capFileToGet,
                localPath=localLinuxLocation,
                renameDestinationFile=None,
                linuxApiServerPathExtension=pathExtension)
Пример #4
0
                          serverIpPort='443',
                          username='******',
                          password='******',
                          deleteSessionAfterTest=deleteSessionAfterTest,
                          verifySslCert=False,
                          serverOs=connectToApiServer)

    if connectToApiServer == 'windows':
        mainObj = Connect(apiServerIp='192.168.70.3', serverIpPort='11009')

    ixChassisIp = '192.168.70.11'
    # [chassisIp, cardNumber, slotNumber]
    portList = [[ixChassisIp, '1', '1'], [ixChassisIp, '2', '2']]

    fileMgmtObj = FileMgmt(mainObj)
    fileMgmtObj.copyFileWindowsToLocalLinux('c:\\Results\\test', '.')
    sys.exit()

    protocolObj = Protocol(mainObj)
    #protocolObj.verifyProtocolSessionsNgpf(['/api/v1/sessions/1/ixnetwork/topology/1/deviceGroup/1/ethernet/1/ipv4/1/bgpIpv4Peer/1'])
    protocolObj.verifyArp()
    #protocolObj.getNgpfGatewayIpMacAddress('1.1.1.2')
    sys.exit()

    response = protocolObj.configRsvpTeLsps(
        ipv4Obj=
        '/api/v1/sessions/1/ixnetwork/topology/1/deviceGroup/1/ethernet/1/ipv4/1'
    )
    #protocolObj.deleteRsvpTeLsps(rsvpTunnelObj='/api/v1/sessions/1/ixnetwork/topology/1/deviceGroup/1/ethernet/1/ipv4/1/rsvpteLsps/16')
    #protocolObj.startAllRsvpTeLsps()
    #protocolObj.startAllRsvpTeIf()
class Statistics(object):
    def __init__(self, ixnObj=None):
        self.ixnObj = ixnObj

        # For takesnapshot()
        self.fileMgmtObj = FileMgmt(self.ixnObj)

    def setMainObject(self, mainObject):
        """
        Description
            For Python Robot Framework support.
        """
        self.ixnObj = mainObject

    def getStats(self, viewObject=None, viewName='Flow Statistics', csvFile=None, csvEnableFileTimestamp=False,
                 displayStats=True, silentMode=True, ignoreError=False):
        """
        Description
           Get stats for any viewName.
           The method calls two different methods based on the IxNetwork version that you are using.
           For IxNetwork version prior to 8.50, calls getStatsPage.
           For IxNetwork version >= 8.50, calls getStatsData. This has new APIs that is more robust and they don't
           work in versions prior to 8.50.

        Parameters
            csvFile = None or <filename.csv>.
                      None will not create a CSV file.
                      Provide a <filename>.csv to record all stats to a CSV file.
                      Example: getStats(sessionUrl, csvFile='Flow_Statistics.csv')

            csvEnableFileTimestamp = True or False. If True, timestamp will be appended to the filename.
            displayStats: True or False. True=Display stats.
            ignoreError: True or False.  Returns None if viewName is not found.
            viewObject: The view object: http://{apiServerIp:port}/api/v1/sessions/2/ixnetwork/statistics/view/13
                        A view object handle could be obtained by calling getViewObject().

            viewName options (Not case sensitive):
               NOTE: Not all statistics are listed here.
                  You could get the statistic viewName directly from the IxNetwork GUI in the statistics.
        """
        buildNumber = float(self.ixnObj.getIxNetworkVersion()[:3])
        if buildNumber >= 8.5:
            return self.getStatsData(viewObject=viewObject, viewName=viewName, csvFile=csvFile, csvEnableFileTimestamp=csvEnableFileTimestamp,
                                     displayStats=displayStats, silentMode=silentMode, ignoreError=ignoreError)
        else:
            return self.getStatsPage(viewObject=viewObject, viewName=viewName, csvFile=csvFile, csvEnableFileTimestamp=csvEnableFileTimestamp,
                                     displayStats=displayStats, silentMode=silentMode, ignoreError=ignoreError)
            
    def getStatsPage(self, viewObject=None, viewName='Flow Statistics', csvFile=None, csvEnableFileTimestamp=False,
                     displayStats=True, silentMode=True, ignoreError=False):
        """
        Description
            Get stats by the statistic name or get stats by providing a view object handle.
            This method uses deprecated APIs effective IxNetwork version 8.50: /statistics/statView/<id>/page
            Starting 8.50, the new API to use is: /statistics/statView/<id>/data, which is in getStatsData()

        Parameters
            csvFile = None or <filename.csv>.
                      None will not create a CSV file.
                      Provide a <filename>.csv to record all stats to a CSV file.
                      Example: getStats(sessionUrl, csvFile='Flow_Statistics.csv')

            csvEnableFileTimestamp = True or False. If True, timestamp will be appended to the filename.

            displayStats: True or False. True=Display stats.

            ignoreError: True or False.  Returns None if viewName is not found.

            viewObject: The view object: http://{apiServerIp:port}/api/v1/sessions/2/ixnetwork/statistics/view/13
                        A view object handle could be obtained by calling getViewObject().

            viewName options (Not case sensitive):
               NOTE: Not all statistics are listed here.
                  You could get the statistic viewName directly from the IxNetwork GUI in the statistics.

            'Port Statistics'
            'Tx-Rx Frame Rate Statistics'
            'Port CPU Statistics'
            'Global Protocol Statistics'
            'Protocols Summary'
            'Port Summary'
            'BGP Peer Per Port'
            'OSPFv2-RTR Drill Down'
            'OSPFv2-RTR Per Port'
            'IPv4 Drill Down'
            'L2-L3 Test Summary Statistics'
            'Flow Statistics'
            'Traffic Item Statistics'
            'IGMP Host Drill Down'
            'IGMP Host Per Port'
            'IPv6 Drill Down'
            'MLD Host Drill Down'
            'MLD Host Per Port'
            'PIMv6 IF Drill Down'
            'PIMv6 IF Per Port'
            'Flow View'

         Note: Not all of the viewNames are listed here. You have to get the exact names from
               the IxNetwork GUI in statistics based on your protocol(s).

         Return a dictionary of all the stats: statDict[rowNumber][columnName] == statValue
           Get stats on row 2 for 'Tx Frames' = statDict[2]['Tx Frames']
        """
        if viewObject == None:
            breakFlag = 0
            counterStop = 30
            for counter in range(1, counterStop+1):
                viewList = self.ixnObj.get('%s/%s/%s' % (self.ixnObj.sessionUrl, 'statistics', 'view'), silentMode=silentMode)
                views = ['%s/%s/%s/%s' % (self.ixnObj.sessionUrl, 'statistics', 'view', str(i['id'])) for i in viewList.json()]
                if silentMode is False:
                    self.ixnObj.logInfo('\ngetStats: Searching for viewObj for viewName: %s' % viewName)

                for view in views:
                    # GetAttribute
                    response = self.ixnObj.get('%s' % view, silentMode=silentMode)
                    captionMatch = re.match(viewName, response.json()['caption'], re.I)
                    if captionMatch:
                        # viewObj: sessionUrl + /statistics/view/11'
                        viewObject = view
                        breakFlag = 1
                        break

                if breakFlag == 1:
                    break

                if counter < counterStop:
                    self.ixnObj.logInfo('\nGetting statview [{0}] is not ready. Waiting {1}/{2} seconds.'.format(
                        viewName, counter, counterStop), timestamp=False)
                    time.sleep(1)
                    continue
                    
                if counter == counterStop:
                    if viewObject == None and ignoreError == False:
                        raise IxNetRestApiException("viewObj wasn't found for viewName: {0}".format(viewName))

                    if viewObject == None and ignoreError == True:
                        return None

        if silentMode is False:
            self.ixnObj.logInfo('\n[{0}] viewObj is: {1}'.format(viewName, viewObject))

        for counter in range(0,31):
            response = self.ixnObj.get(viewObject+'/page', silentMode=silentMode)
            totalPages = response.json()['totalPages']
            if totalPages == 'null':
                self.ixnObj.logInfo('\nGetting total pages is not ready yet. Waiting %d/30 seconds' % counter)
                time.sleep(1)

            if totalPages != 'null':
                break

            if counter == 30:
                raise IxNetRestApiException('getStatsPage failed: Getting total pages')

        if csvFile != None:
            import csv
            csvFileName = csvFile.replace(' ', '_')
            if csvEnableFileTimestamp:
                import datetime
                timestamp = datetime.datetime.now().strftime('%H%M%S')
                if '.' in csvFileName:
                    csvFileNameTemp = csvFileName.split('.')[0]
                    csvFileNameExtension = csvFileName.split('.')[1]
                    csvFileName = csvFileNameTemp+'_'+timestamp+'.'+csvFileNameExtension
                else:
                    csvFileName = csvFileName+'_'+timestamp

            csvFile = open(csvFileName, 'w')
            csvWriteObj = csv.writer(csvFile)

        # Get the stat column names
        columnList = response.json()['columnCaptions']
        if csvFile != None:
            csvWriteObj.writerow(columnList)

        flowNumber = 1
        statDict = {}
        # Get the stat values
        for pageNumber in range(1,totalPages+1):
            self.ixnObj.patch(viewObject+'/page', data={'currentPage': pageNumber}, silentMode=silentMode)

            response = self.ixnObj.get(viewObject+'/page', silentMode=silentMode)
            statValueList = response.json()['pageValues']

            for statValue in statValueList:
                if csvFile != None:
                    csvWriteObj.writerow(statValue[0])

                if displayStats:
                    self.ixnObj.logInfo('\nRow: %d' % flowNumber, timestamp=False)

                statDict[flowNumber] = {}
                index = 0
                for statValue in statValue[0]:
                    statName = columnList[index]
                    statDict[flowNumber].update({statName: statValue})
                    if displayStats:
                        self.ixnObj.logInfo('\t%s: %s' % (statName, statValue), timestamp=False)
                    index += 1
                flowNumber += 1

        if csvFile != None:
            csvFile.close()
        return statDict

    def getStatsData(self, viewObject=None, viewName='Flow Statistics', csvFile=None, csvEnableFileTimestamp=False,
                     displayStats=True, silentMode=False, ignoreError=False):
        """
        Description
            For IxNetwork version >= 8.50.   
            Get stats by the statistic name or get stats by providing a view object handle.
            This method get stats using /api/v1/sessions/{id}/ixnetwork/statistics/view/{id}/data to get
            attributes columnCaptions, pageValues and totalPages. This method uses new API starting in 
            version 8.50.

        Parameters
            csvFile = None or <filename.csv>.
                      None will not create a CSV file.
                      Provide a <filename>.csv to record all stats to a CSV file.
                      Example: getStats(sessionUrl, csvFile='Flow_Statistics.csv')

            csvEnableFileTimestamp = True or False. If True, timestamp will be appended to the filename.
            displayStats: True or False. True=Display stats.
            ignoreError: True or False.  Returns None if viewName is not found.
            viewObject: The view object: http://{apiServerIp:port}/api/v1/sessions/2/ixnetwork/statistics/view/13
                        A view object handle could be obtained by calling getViewObject().

            viewName options (Not case sensitive):
               NOTE: Not all statistics are listed here.
                  You could get the statistic viewName directly from the IxNetwork GUI in the statistics.

            'Port Statistics'
            'Tx-Rx Frame Rate Statistics'
            'Port CPU Statistics'
            'Global Protocol Statistics'
            'Protocols Summary'
            'Port Summary'
            'BGP Peer Per Port'
            'OSPFv2-RTR Drill Down'
            'OSPFv2-RTR Per Port'
            'IPv4 Drill Down'
            'L2-L3 Test Summary Statistics'
            'Flow Statistics'
            'Traffic Item Statistics'
            'IGMP Host Drill Down'
            'IGMP Host Per Port'
            'IPv6 Drill Down'
            'MLD Host Drill Down'
            'MLD Host Per Port'
            'PIMv6 IF Drill Down'
            'PIMv6 IF Per Port'
            'Flow View'

         Note: Not all of the viewNames are listed here. You have to get the exact names from
               the IxNetwork GUI in statistics based on your protocol(s).

         Return a dictionary of all the stats: statDict[rowNumber][columnName] == statValue
           Get stats on row 2 for 'Tx Frames' = statDict[2]['Tx Frames']
        """
        if viewObject == None:

            breakFlag = 0
            counterStop = 30
            for counter in range(1, counterStop+1):
                viewList = self.ixnObj.get('%s/%s/%s' % (self.ixnObj.sessionUrl, 'statistics', 'view'), silentMode=silentMode)
                views = ['%s/%s/%s/%s' % (self.ixnObj.sessionUrl, 'statistics', 'view', str(i['id'])) for i in viewList.json()]
                if silentMode is False:
                    self.ixnObj.logInfo('\ngetStats: Searching for viewObj for viewName: {0}'.format(
                        viewName), timestamp=False)

                for view in views:
                    #print('\nview:', view)
                    response = self.ixnObj.get('%s' % view, silentMode=True)
                    captionMatch = re.match(viewName, response.json()['caption'], re.I)
                    if captionMatch:
                        # viewObj: sessionUrl + /statistics/view/11'
                        viewObject = view
                        breakFlag = 1
                        break

                if breakFlag == 1:
                    break

                if counter < counterStop:
                    self.ixnObj.logInfo('\nGetting statview [{0}] is not ready. Waiting {1}/{2} seconds.'.format(
                        viewName, counter, counterStop), timestamp=False)
                    time.sleep(1)
                    continue
                    
                if counter == counterStop:
                    if viewObject == None and ignoreError == False:
                        raise IxNetRestApiException("viewObj wasn't found for viewName: {0}".format(viewName))

                    if viewObject == None and ignoreError == True:
                        return None

        if silentMode is False:
            self.ixnObj.logInfo('\n[{0}] viewObj is: {1}'.format(viewName, viewObject))

        counterStop = 30
        for counter in range(0, counterStop+1):
            response = self.ixnObj.get(viewObject+'/data', silentMode=silentMode)
            totalPages = response.json()['totalPages']
            #self.ixnObj.logInfo('totalPages: {0}'.format(totalPages), timestamp=False)

            if totalPages == 'null' and counter < counterStop:
                self.ixnObj.logInfo('\nGetting total pages is not ready yet. Waiting {0}/{1} seconds'.format(
                    counter, counterStop), timestamp=False)
                time.sleep(1)
                continue

            if totalPages != 'null' and counter < counterStop:
                break

            if counter == counterStop:
                raise IxNetRestApiException('getStats failed: Getting total pages')

        if csvFile != None:
            import csv
            csvFileName = csvFile.replace(' ', '_')
            if csvEnableFileTimestamp:
                import datetime
                timestamp = datetime.datetime.now().strftime('%H%M%S')
                if '.' in csvFileName:
                    csvFileNameTemp = csvFileName.split('.')[0]
                    csvFileNameExtension = csvFileName.split('.')[1]
                    csvFileName = csvFileNameTemp+'_'+timestamp+'.'+csvFileNameExtension
                else:
                    csvFileName = csvFileName+'_'+timestamp

            csvFile = open(csvFileName, 'w')
            csvWriteObj = csv.writer(csvFile)

        flowNumber = 1
        statDict = {}
        getColumnCaptionFlag = 0
        for pageNumber in range(1,totalPages+1):
            self.ixnObj.patch(viewObject+'/data', data={'currentPage': pageNumber}, silentMode=silentMode)

            counterStop = 30
            for counter in range(1, counterStop+1):
                response = self.ixnObj.get(viewObject+'/data', silentMode=silentMode)
                if counter < counterStop:
                    if response.json()['columnCaptions'] == [] or response.json()['pageValues'] == []:
                        self.ixnObj.logInfo('[{0}] stat values not ready yet. Wait {1}/{2} seconds.'.format(
                            viewName, counter, counterStop))
                        time.sleep(1)
                        continue

                    if response.json()['columnCaptions'] != [] or response.json()['pageValues'] != []:
                        break

                if counter == counterStop:
                    raise IxNetRestApiException('IxNetwork API server failed to provide stats')

            # Get the stat column names one time only
            if getColumnCaptionFlag == 0:
                getColumnCaptionFlag = 1
                columnList = response.json()['columnCaptions']
                if csvFile != None:
                    csvWriteObj.writerow(columnList)
                
            statValueList = response.json()['pageValues']
            for statValue in statValueList:
                if csvFile != None:
                    csvWriteObj.writerow(statValue[0])

                if displayStats:
                    self.ixnObj.logInfo('\nRow: %d' % flowNumber, timestamp=False)

                statDict[flowNumber] = {}
                index = 0
                for statValue in statValue[0]:
                    statName = columnList[index]
                    statDict[flowNumber].update({statName: statValue})
                    if displayStats:
                        self.ixnObj.logInfo('\t%s: %s' % (statName, statValue), timestamp=False)
                    index += 1
                flowNumber += 1

        if csvFile != None:
            csvFile.close()
        return statDict

    def removeAllTclViews(self):
        """
        Description
           Removes all created stat views.
        """
        removeAllTclViewsUrl = self.ixnObj.sessionUrl+'/operations/removealltclviews'
        response = self.ixnObj.post(removeAllTclViewsUrl)
        self.ixnObj.waitForComplete(response, self.ixnObj.httpHeader + response.json()['url'])

    def takeSnapshot(self, viewName='Flow Statistics', windowsPath=None, isLinux=False, localLinuxPath=None,
                     renameDestinationFile=None, includeTimestamp=False, mode='overwrite'):
        """
        Description
            Take a snapshot of the vieweName statistics.  This is a two step process.
            1> Take a snapshot of the statistics that you want and store it in the C: drive for Windows.
               For Linux, the snapshot goes to /home/ixia_logs.
            2> Copy the statistics from the snapshot locations to the local Linux where you ran the script..

        Parameters
            viewName: The name of the statistics to get.
            windowsPath: For Windows|WindowsConnectionMgr only.
                         The C: drive + path to store the snapshot: Example: c:\\Results.
            isLinux: <bool>: Defaults to False.  Set to True if you're getting the snapshot from Linux chassis.
            localLinuxPath: None|path. Provide the local Linux path to put the snapshot file.
                            If None, this API won't copy the stat file to local Linux.
                            The stat file will remain on Windows c: drive.
            renameDestinationFile: None or a name of the file other than the viewName.
            includeTimestamp: True|False: To include a timestamp at the end of the file.
            mode: append|overwrite: append=To append stats to an existing stat file.
                                    overwrite=Don't append stats. Create a new stat file.

        Example:
            For Windows:
               statObj.takeSnapshot(viewName='Flow Statistics', windowsPath='C:\\Results', localLinuxPath='/home/hgee',
                           renameDestinationFile='my_renamed_stat_file.csv', includeTimestamp=True)

            For Linux:
               statObj.takeSnapshot(viewName='Flow Statistics', isLinux=True, localLinuxPath='/home/hgee')
        """
        if mode == 'append':
            mode = 'kAppendCSVFile'

        if mode == 'overwrite':
            mode = 'kOverwriteCSVFile'

        if windowsPath:
            location = windowsPath

        if isLinux:
            location = '/home/ixia_logs'

        data = {'arg1': [viewName], 'arg2': [
                            "Snapshot.View.Contents: \"allPages\"",
                            "Snapshot.View.Csv.Location: \"{0}\"".format(location),
                            "Snapshot.View.Csv.GeneratingMode: \"%s\"" % mode,
                            "Snapshot.View.Csv.StringQuotes: \"True\"",
                            "Snapshot.View.Csv.SupportsCSVSorting: \"False\"",
                            "Snapshot.View.Csv.FormatTimestamp: \"True\"",
                            "Snapshot.View.Csv.DumpTxPortLabelMap: \"False\"",
                            "Snapshot.View.Csv.DecimalPrecision: \"3\""
                            ]
                }

        url = self.ixnObj.sessionUrl+'/operations/takeviewcsvsnapshot'
        response = self.ixnObj.post(url, data=data)
        self.ixnObj.waitForComplete(response, self.ixnObj.httpHeader + response.json()['url'])
        if isLinux:
            snapshotFile = location + '/' + viewName + '.csv'
            self.fileMgmtObj.copyFileLinuxToLocalLinux(linuxApiServerPathAndFileName=snapshotFile, localPath=localLinuxPath,
                                                        renameDestinationFile=renameDestinationFile,
                                                        includeTimestamp=includeTimestamp)

        if windowsPath and localLinuxPath:
            # Get the snapshot. Use the csvFilename that was specified and the location
            self.fileMgmtObj.copyFileWindowsToLocalLinux('{0}\\{1}.csv'.format(windowsPath, viewName), localLinuxPath,
                                                         renameDestinationFile=renameDestinationFile,
                                                         includeTimestamp=includeTimestamp)

    def getViewObject(self, viewName='Flow Statistics'):
        """
        Description
            To get just the statistic view object.
            Mainly used by internal APIs such as takeCsvSnapshot that
            requires the statistics view object handle.

        Parameter
         viewName:  Options (case sensitive):
            "Port Statistics"
            "Tx-Rx Frame Rate Statistics"
            "Port CPU Statistics"
            "Global Protocol Statistics"
            "Protocols Summary"
            "Port Summary"
            "OSPFv2-RTR Drill Down"
            "OSPFv2-RTR Per Port"
            "IPv4 Drill Down"
            "L2-L3 Test Summary Statistics"
            "Flow Statistics"
            "Traffic Item Statistics"
        """
        self.ixnObj.logInfo('\ngetStats: %s' % viewName)
        viewList = self.ixnObj.get("%s/%s/%s" % (self.ixnObj.sessionUrl, "statistics", "view"))
        views = ["%s/%s/%s/%s" % (self.ixnObj.sessionUrl, "statistics", "view", str(i["id"])) for i in viewList.json()]
        for view in views:
            # GetAttribute
            response = self.ixnObj.get(view)
            caption = response.json()["caption"]
            if viewName == caption:
                # viewObj: sessionUrl + "/statistics/view/11"
                viewObj = view
                return viewObj
        return None

    def clearStats(self):
        """
        Description
            Clear all stats and wait for API server to finish.
        """
        url = self.ixnObj.sessionUrl + '/operations/clearstats'
        response = self.ixnObj.post(url, data={'arg1': ['waitForPortStatsRefresh']})
        self.ixnObj.waitForComplete(response, self.ixnObj.httpHeader + response.json()['url'])
Пример #6
0
class QuickTest(object):
    def __init__(self, ixnObj=None, fileMgmtObj=None):
        self.ixnObj = ixnObj
        if fileMgmtObj:
            self.fileMgmtObj = fileMgmtObj
        else:
            self.fileMgmtObj = FileMgmt(ixnObj)

    def setMainObject(self, mainObject):
        # For Python Robot Framework support
        self.ixnObj = mainObject
        self.fileMgmtObj.setMainObject(mainObject)

    def getAllQuickTestHandles(self):
        """
        Description
            Get all the Quick Test object handles

        Returns:
            ['/api/v1/sessions/1/ixnetwork/quickTest/rfc2544throughput/2',
             '/api/v1/sessions/1/ixnetwork/quickTest/rfc2889broadcastRate/1',
             '/api/v1/sessions/1/ixnetwork/quickTest/rfc2889broadcastRate/2']
        """
        response = self.ixnObj.get(self.ixnObj.sessionUrl + '/quickTest')
        quickTestHandles = []
        for eachTestId in response.json()['testIds']:
            quickTestHandles.append(eachTestId)
        return quickTestHandles

    def getAllQuickTestNames(self):
        quickTestNameList = []
        for eachQtHandle in self.getAllQuickTestHandles():
            response = self.ixnObj.get(self.ixnObj.httpHeader + eachQtHandle)
            quickTestNameList.append(response.json()['name'])
        return quickTestNameList

    def getQuickTestHandleByName(self, quickTestName):
        """
        Description
            Get the Quick Test object handle by the name.

        Parameter
            quickTestName: The name of the Quick Test.
        """
        for quickTestHandle in self.getAllQuickTestHandles():
            response = self.ixnObj.get(self.ixnObj.httpHeader +
                                       quickTestHandle)
            currentQtName = response.json()['name']
            if (bool(re.match(quickTestName, currentQtName, re.I))):
                return quickTestHandle

    def getQuickTestNameByHandle(self, quickTestHandle):
        """
        quickTestHandle = /api/v1/sessions/1/ixnetwork/quickTest/rfc2544throughput/2
        """
        response = self.ixnObj.get(self.ixnObj.httpHeader + quickTestHandle)
        return response.json()['name']

    def getQuickTestDuration(self, quickTestHandle):
        """
        quickTestHandle = /api/v1/sessions/1/ixnetwork/quickTest/rfc2544throughput/2
        """
        response = self.ixnObj.get(self.ixnObj.httpHeader + quickTestHandle +
                                   '/testConfig')
        return response.json()['duration']

    def getQuickTestTotalFrameSizesToTest(self, quickTestHandle):
        """
        quickTestHandle = /api/v1/sessions/1/ixnetwork/quickTest/rfc2544throughput/2
        """
        response = self.ixnObj.get(self.ixnObj.httpHeader + quickTestHandle +
                                   '/testConfig')
        return response.json()['framesizeList']

    def applyQuickTest(self, qtHandle):
        """
        Description
            Apply Quick Test configurations

        Parameter
            qtHandle: The Quick Test object handle
        """
        response = self.ixnObj.post(self.ixnObj.sessionUrl +
                                    '/quickTest/operations/apply',
                                    data={'arg1': qtHandle})
        if self.ixnObj.waitForComplete(
                response, self.ixnObj.sessionUrl +
                '/quickTest/operations/apply/' + response.json()['id']) == 1:
            raise IxNetRestApiException('applyTraffic: waitForComplete failed')

    def getQuickTestCurrentAction(self, quickTestHandle):
        """
        quickTestHandle = /api/v1/sessions/1/ixnetwork/quickTest/rfc2544throughput/2
        """
        ixNetworkVersion = self.ixnObj.getIxNetworkVersion()
        match = re.match('([0-9]+)\.[^ ]+ *', ixNetworkVersion)
        if int(match.group(1)) >= 8:
            timer = 10
            for counter in range(1, timer + 1):
                response = self.ixnObj.get(self.ixnObj.httpHeader +
                                           quickTestHandle + '/results',
                                           silentMode=True)
                if counter < timer and response.json()['currentActions'] == []:
                    self.ixnObj.logInfo(
                        'getQuickTestCurrentAction is empty. Waiting %s/%s' %
                        (counter, timer))
                    time.sleep(1)
                    continue
                if counter < timer and response.json()['currentActions'] != []:
                    break
                if counter == timer and response.json(
                )['currentActions'] == []:
                    IxNetRestApiException(
                        'getQuickTestCurrentActions: Has no action')

            return response.json()['currentActions'][-1]['arg2']
        else:
            response = self.ixnObj.get(self.ixnObj.httpHeader +
                                       quickTestHandle + '/results')
            return response.json()['progress']

    def verifyQuickTestInitialization(self, quickTestHandle):
        """
        quickTestHandle = /api/v1/sessions/1/ixnetwork/quickTest/rfc2544throughput/2
        """
        for timer in range(1, 20 + 1):
            currentAction = self.getQuickTestCurrentAction(quickTestHandle)
            print('verifyQuickTestInitialization currentState: %s' %
                  currentAction)
            if timer < 20:
                if currentAction == 'TestEnded' or currentAction == 'None':
                    self.ixnObj.logInfo(
                        '\nverifyQuickTestInitialization CurrentState = %s\n\tWaiting %s/20 seconds to change state'
                        % (currentAction, timer))
                    time.sleep(1)
                    continue
                else:
                    break
            if timer >= 20:
                if currentAction == 'TestEnded' or currentAction == 'None':
                    self.ixnObj.showErrorMessage()
                    raise IxNetRestApiException(
                        'Quick Test is stuck at TestEnded.')

        ixNetworkVersionNumber = int(
            self.ixnObj.getIxNetworkVersion().split('.')[0])
        applyQuickTestCounter = 60
        for counter in range(1, applyQuickTestCounter + 1):
            quickTestApplyStates = [
                'InitializingTest', 'ApplyFlowGroups',
                'SetupStatisticsCollection'
            ]
            currentAction = self.getQuickTestCurrentAction(quickTestHandle)
            if currentAction == None:
                currentAction = 'ApplyingAndInitializing'

            print(
                '\nverifyQuickTestInitialization: %s  Expecting: TransmittingFrames\n\tWaiting %s/%s seconds'
                % (currentAction, counter, applyQuickTestCounter))
            if ixNetworkVersionNumber >= 8:
                if counter < applyQuickTestCounter and currentAction != 'TransmittingFrames':
                    time.sleep(1)
                    continue

                if counter < applyQuickTestCounter and currentAction == 'TransmittingFrames':
                    self.ixnObj.logInfo(
                        '\nVerifyQuickTestInitialization is done applying configuration and has started transmitting frames\n'
                    )
                break

            if ixNetworkVersionNumber < 8:
                if counter < applyQuickTestCounter and currentAction == 'ApplyingAndInitializing':
                    time.sleep(1)
                    continue

                if counter < applyQuickTestCounter and currentAction == 'ApplyingAndInitializing':
                    self.ixnObj.logInfo(
                        '\nVerifyQuickTestInitialization is done applying configuration and has started transmitting frames\n'
                    )
                break

            if counter == applyQuickTestCounter:
                if ixNetworkVersionNumber >= 8 and currentAction != 'TransmittingFrames':
                    self.ixnObj.showErrorMessage()
                    if currentAction == 'ApplyFlowGroups':
                        self.ixnObj.logInfo(
                            '\nIxNetwork is stuck on Applying Flow Groups. You need to go to the session to FORCE QUIT it.\n'
                        )
                    raise IxNetRestApiException(
                        '\nVerifyQuickTestInitialization is stuck on %s. Waited %s/%s seconds'
                        % (currentAction, counter, applyQuickTestCounter))

                if ixNetworkVersionNumber < 8 and currentAction != 'Trial':
                    self.ixnObj.showErrorMessage()
                    raise IxNetRestApiException(
                        '\nVerifyQuickTestInitialization is stuck on %s. Waited %s/%s seconds'
                        % (currentAction, counter, applyQuickTestCounter))

    def startQuickTest(self, quickTestHandle):
        """
        Description
            Start a Quick Test

        Parameter
            quickTestHandle: The Quick Test object handle.
            /api/v1/sessions/{id}/ixnetwork/quickTest/rfc2544throughput/2

        Syntax
           POST: http://{apiServerIp:port}/api/v1/sessions/{1}/ixnetwork/quickTest/operations/start
                 data={arg1: '/api/v1/sessions/{id}/ixnetwork/quickTest/rfc2544throughput/2'}
                 headers={'content-type': 'application/json'}
        """
        url = self.ixnObj.sessionUrl + '/quickTest/operations/start'
        self.ixnObj.logInfo('\nstartQuickTest:%s' % url)
        response = self.ixnObj.post(url, data={'arg1': quickTestHandle})
        if self.ixnObj.waitForComplete(response,
                                       url + '/' + response.json()['id']) == 1:
            raise IxNetRestApiException

    def stopQuickTest(self, quickTestHandle):
        """
        Description
            Stop the Quick Test.

        Parameter
            quickTestHandle: The Quick Test object handle.
            /api/v1/sessions/{id}/ixnetwork/quickTest/rfc2544throughput/2

        Syntax
           POST: http://{apiServerIp:port}/api/v1/sessions/{1}/ixnetwork/quickTest/operations/stop
                 data={arg1: '/api/v1/sessions/{id}/ixnetwork/quickTest/rfc2544throughput/2'}
                 headers={'content-type': 'application/json'}
        """
        url = self.ixnObj.sessionUrl + '/quickTest/operations/stop'
        response = self.ixnObj.post(url, data={'arg1': quickTestHandle})
        if self.ixnObj.waitForComplete(response,
                                       url + '/' + response.json()['id']) == 1:
            raise IxNetRestApiException

    def monitorQuickTestRunningProgress(self,
                                        quickTestHandle,
                                        getProgressInterval=10):
        """
        Description
            monitor the Quick Test running progress.
            For Linux API server only, it must be a NGPF configuration. (Classic Framework is not supported in REST)

        Parameters
            quickTestHandle: /api/v1/sessions/{1}/ixnetwork/quickTest/rfc2544throughput/2
        """
        isRunningBreakFlag = 0
        trafficStartedFlag = 0
        waitForRunningProgressCounter = 0
        counter = 1

        while True:
            response = self.ixnObj.get(self.ixnObj.httpHeader +
                                       quickTestHandle + '/results',
                                       silentMode=True)
            isRunning = response.json()['isRunning']
            if isRunning == True:
                response = self.ixnObj.get(self.ixnObj.httpHeader +
                                           quickTestHandle + '/results',
                                           silentMode=True)
                currentRunningProgress = response.json()['progress']
                if bool(re.match('^Trial.*', currentRunningProgress)) == False:
                    if waitForRunningProgressCounter < 30:
                        self.ixnObj.logInfo(
                            'isRunning=True. Waiting for trial runs {0}/30 seconds'
                            .format(waitForRunningProgressCounter))
                        waitForRunningProgressCounter += 1
                        time.sleep(1)
                    if waitForRunningProgressCounter == 30:
                        raise IxNetRestApiException(
                            'isRunning=True. No quick test stats showing.')
                else:
                    trafficStartedFlag = 1
                    self.ixnObj.logInfo(currentRunningProgress)
                    counter += 1
                    time.sleep(getProgressInterval)
                    continue
            else:
                if trafficStartedFlag == 1:
                    # We only care about traffic not running in the beginning.
                    # If traffic ran and stopped, then break out.
                    self.ixnObj.logInfo(
                        '\nisRunning=False. Quick Test is complete')
                    return 0
                if isRunningBreakFlag < 20:
                    print('isRunning=False. Wait {0}/20 seconds'.format(
                        isRunningBreakFlag))
                    isRunningBreakFlag += 1
                    time.sleep(1)
                    continue
                if isRunningBreakFlag == 20:
                    raise IxNetRestApiException('Quick Test failed to start:',
                                                response.json()['status'])

    def getQuickTestResultPath(self, quickTestHandle):
        """
        quickTestHandle = /api/v1/sessions/1/ixnetwork/quickTest/rfc2544throughput/2
        """
        response = self.ixnObj.get(self.ixnObj.httpHeader + quickTestHandle +
                                   '/results')
        # "resultPath": "C:\\Users\\hgee\\AppData\\Local\\Ixia\\IxNetwork\\data\\result\\DP.Rfc2544Tput\\10694b39-6a8a-4e70-b1cd-52ec756910c3\\Run0001"
        return response.json()['resultPath']

    def getQuickTestResult(self, quickTestHandle, attribute):
        """
        Description
            Get Quick Test result attributes

        Parameter
            quickTestHandle: The Quick Test object handle

        attribute options to get:
           result - Returns pass
           status - Returns none
           progress - blank or Trial 1/1 Iteration 1, Size 64, Rate 10 % Wait for 2 seconds Wait 70.5169449%complete
           startTime - Returns 04/21/17 14:35:42
           currentActions
           waitingStatus
           resultPath
           isRunning - Returns True or False
           trafficStatus
           duration - Returns 00:01:03
           currentViews
        """
        response = self.ixnObj.get(quickTestHandle + '/results')
        return response.json()[attribute]

    def getQuickTestCsvFiles(self, quickTestHandle, copyToPath, csvFile='all'):
        """
        Description
            Copy Quick Test CSV result files to a specified path on either Windows or Linux.
            Note: Currently only supports copying from Windows.
                  Copy from Linux is coming in November.

        quickTestHandle: The Quick Test handle.
        copyToPath: The destination path to copy to.
                    If copy to Windows: c:\\Results\\Path
                    If copy to Linux: /home/user1/results/path

        csvFile: A list of CSV files to get: 'all', one or more CSV files to get:
                 AggregateResults.csv, iteration.csv, results.csv, logFile.txt, portMap.csv
        """
        resultsPath = self.getQuickTestResultPath(quickTestHandle)
        self.ixnObj.logInfo('\ngetQuickTestCsvFiles: %s' % resultsPath)
        if csvFile == 'all':
            getCsvFiles = [
                'AggregateResults.csv', 'iteration.csv', 'results.csv',
                'logFile.txt', 'portMap.csv'
            ]
        else:
            if type(csvFile) is not list:
                getCsvFiles = [csvFile]
            else:
                getCsvFiles = csvFile

        for eachCsvFile in getCsvFiles:
            # Backslash indicates the results resides on a Windows OS.
            if '\\' in resultsPath:
                if bool(re.match('[a-z]:.*', copyToPath, re.I)):
                    self.fileMgmtObj.copyFileWindowsToLocalWindows(
                        resultsPath + '\\{0}'.format(eachCsvFile), copyToPath)
                else:
                    self.fileMgmtObj.copyFileWindowsToLocalLinux(
                        resultsPath + '\\{0}'.format(eachCsvFile), copyToPath)
            else:
                # TODO: Copy from Linux to Windows and Linux to Linux.
                pass

    def getQuickTestPdf(self,
                        quickTestHandle,
                        copyToLocalPath,
                        where='remoteLinux',
                        renameDestinationFile=None,
                        includeTimestamp=False):
        """
        Description
           Generate Quick Test result to PDF and retrieve the PDF result file.

        Parameter
           where: localWindows|remoteWindows|remoteLinux. The destination.
           copyToLocalPath: The local destination path to store the PDF result file.
           renameDestinationFile: Rename the PDF file.
           includeTimestamp: True|False.  Set to True if you don't want to overwrite previous result file.
        """
        response = self.ixnObj.post(self.ixnObj.httpHeader + quickTestHandle +
                                    '/operations/generateReport',
                                    data={'arg1': quickTestHandle})
        if response.json()['url'] != '':
            if self.ixnObj.waitForComplete(
                    response,
                    self.ixnObj.httpHeader + response.json()['url']) == 1:
                raise IxNetRestApiException

            if where == 'localWindows':
                response = self.ixnObj.get(self.ixnObj.httpHeader +
                                           response.json()['url'])
                self.fileMgmtObj.copyFileWindowsToLocalWindows(
                    response.json()['result'], copyToLocalPath,
                    renameDestinationFile, includeTimestamp)
            if where == 'remoteWindows':
                # TODO: Work in progress.  Not sure if this is possible.
                resultPath = self.getQuickTestResultPath(quickTestHandle)
                #self.ixnObj.copyFileWindowsToRemoteWindows(response.json()['result'], copyToLocalPath, renameDestinationFile, includeTimestamp)
                self.fileMgmtObj.copyFileWindowsToRemoteWindows(
                    resultPath, copyToLocalPath, renameDestinationFile,
                    includeTimestamp)
            if where == 'remoteLinux':
                linuxResultPath = self.getQuickTestResultPath(quickTestHandle)
                self.fileMgmtObj.copyFileWindowsToLocalLinux(
                    linuxResultPath + '\\TestReport.pdf', copyToLocalPath,
                    renameDestinationFile, includeTimestamp)
        else:
            self.ixnObj.logInfo('\ngetQuickTestPdf failed. Result path = %s' %
                                response.json()['result'])
Пример #7
0
class Statistics(object):
    def __init__(self, ixnObj=None):
        self.ixnObj = ixnObj
        self.fileMgmtObj = FileMgmt(self.ixnObj)
        self.ixNetwork = ixnObj.ixNetwork

    def setMainObject(self, mainObject):
        """
        Description
            For Python Robot Framework support.
        """
        self.ixnObj = mainObject

    def getStats(self,
                 viewObject=None,
                 viewName='Flow Statistics',
                 csvFile=None,
                 csvEnableFileTimestamp=False,
                 displayStats=True,
                 silentMode=True,
                 ignoreError=False):
        """
        Description
           Get stats for any viewName.
           The method calls two different methods based on the IxNetwork version that you are using.
           For IxNetwork version prior to 8.50, calls getStatsPage.

        Parameters
            csvFile = None or <filename.csv>.
                      None will not create a CSV file.
                      Provide a <filename>.csv to record all stats to a CSV file.
                      Example: getStats(sessionUrl, csvFile='Flow_Statistics.csv')

            csvEnableFileTimestamp = True or False. If True, timestamp will be appended to the
            filename.
            displayStats: True or False. True=Display stats.
            ignoreError: True or False.  Returns None if viewName is not found.
            viewObject: The view object:
                        A view object handle could be obtained by calling getViewObject().

            viewName options (Not case sensitive):
               NOTE: Not all statistics are listed here.
                  You could get the statistic viewName directly from the IxNetwork GUI in the
                   statistics.
        """

        return self.getStatsData(viewObject=viewObject,
                                 viewName=viewName,
                                 csvFile=csvFile,
                                 csvEnableFileTimestamp=csvEnableFileTimestamp,
                                 displayStats=displayStats,
                                 silentMode=silentMode,
                                 ignoreError=ignoreError)

    def getStatsPage(self,
                     viewObject=None,
                     viewName='Flow Statistics',
                     csvFile=None,
                     csvEnableFileTimestamp=False,
                     displayStats=True,
                     silentMode=True,
                     ignoreError=False):
        """
        Description
            Get stats by the statistic name or get stats by providing a view object handle.

        Parameters
            csvFile = None or <filename.csv>.
                      None will not create a CSV file.
                      Provide a <filename>.csv to record all stats to a CSV file.
                      Example: getStats(sessionUrl, csvFile='Flow_Statistics.csv')

            csvEnableFileTimestamp = True or False. If True,
                                    timestamp will be appended to the filename.

            displayStats: True or False. True=Display stats.

            ignoreError: True or False.  Returns None if viewName is not found.

            viewObject: The view object:
                        A view object handle could be obtained by calling getViewObject().

            viewName options (Not case sensitive):
               NOTE: Not all statistics are listed here.
                  You could get the statistic viewName directly from the IxNetwork GUI in the
                  statistics.

            'Port Statistics'
            'Tx-Rx Frame Rate Statistics'
            'Port CPU Statistics'
            'Global Protocol Statistics'
            'Protocols Summary'
            'Port Summary'
            'BGP Peer Per Port'
            'OSPFv2-RTR Drill Down'
            'OSPFv2-RTR Per Port'
            'IPv4 Drill Down'
            'L2-L3 Test Summary Statistics'
            'Flow Statistics'
            'Traffic Item Statistics'
            'IGMP Host Drill Down'
            'IGMP Host Per Port'
            'IPv6 Drill Down'
            'MLD Host Drill Down'
            'MLD Host Per Port'
            'PIMv6 IF Drill Down'
            'PIMv6 IF Per Port'
            'Flow View'

         Note: Not all of the viewNames are listed here. You have to get the exact names from
               the IxNetwork GUI in statistics based on your protocol(s).

         Return a dictionary of all the stats: statDict[rowNumber][columnName] == statValue
           Get stats on row 2 for 'Tx Frames' = statDict[2]['Tx Frames']
        """
        rowStats = None
        try:
            TrafficItemStats = StatViewAssistant(self.ixNetwork, viewName)
        except Exception as err:
            self.ixnObj.logInfo("Error in getstats {}".format(err))
            raise Exception('getStats: Failed to get stats values')

        trafficItemStatsDict = {}
        columnCaptions = TrafficItemStats.ColumnHeaders

        if csvFile is not None:
            csvFileName = csvFile.replace(' ', '_')
            if csvEnableFileTimestamp:
                timestamp = datetime.datetime.now().strftime('%H%M%S')
                if '.' in csvFileName:
                    csvFileNameTemp = csvFileName.split('.')[0]
                    csvFileNameExtension = csvFileName.split('.')[1]
                    csvFileName = csvFileNameTemp + '_' + timestamp + '.' + csvFileNameExtension
                else:
                    csvFileName = csvFileName + '_' + timestamp

            csvFile = open(csvFileName, 'w')
            csvWriteObj = csv.writer(csvFile)
            csvWriteObj.writerow(columnCaptions)
            for rowNumber, stat in enumerate(TrafficItemStats.Rows):
                rowStats = stat.RawData
            for row in rowStats:
                csvWriteObj.writerow(row)
            csvFile.close()

        for rowNumber, stat in enumerate(TrafficItemStats.Rows):
            if displayStats:
                self.ixnObj.logInfo('\n Row: {}'.format(rowNumber + 1),
                                    timestamp=False)
            statsDict = {}
            for column in columnCaptions:
                statsDict[column] = stat[column]
                if displayStats:
                    self.ixnObj.logInfo('\t%s: %s' % (column, stat[column]),
                                        timestamp=False)
            trafficItemStatsDict[rowNumber + 1] = statsDict

        return trafficItemStatsDict

    def getStatsData(self,
                     viewObject=None,
                     viewName='Flow Statistics',
                     csvFile=None,
                     csvEnableFileTimestamp=False,
                     displayStats=True,
                     silentMode=False,
                     ignoreError=False):
        """
        Description
            Get stats by the statistic name or get stats by providing a view object handle.


        Parameters
            csvFile = None or <filename.csv>.
                      None will not create a CSV file.
                      Provide a <filename>.csv to record all stats to a CSV file.
                      Example: getStats(sessionUrl, csvFile='Flow_Statistics.csv')

            csvEnableFileTimestamp = True or False. If True,
                                    timestamp will be appended to the filename.
            displayStats: True or False. True=Display stats.
            ignoreError: True or False.  Returns None if viewName is not found.
            viewObject: The view object:
                        A view object handle could be obtained by calling getViewObject().

            viewName options (Not case sensitive):
               NOTE: Not all statistics are listed here.
                  You could get the statistic viewName directly from the IxNetwork GUI
                  in the statistics.

            'Port Statistics'
            'Tx-Rx Frame Rate Statistics'
            'Port CPU Statistics'
            'Global Protocol Statistics'
            'Protocols Summary'
            'Port Summary'
            'BGP Peer Per Port'
            'OSPFv2-RTR Drill Down'
            'OSPFv2-RTR Per Port'
            'IPv4 Drill Down'
            'L2-L3 Test Summary Statistics'
            'Flow Statistics'
            'Traffic Item Statistics'
            'IGMP Host Drill Down'
            'IGMP Host Per Port'
            'IPv6 Drill Down'
            'MLD Host Drill Down'
            'MLD Host Per Port'
            'PIMv6 IF Drill Down'
            'PIMv6 IF Per Port'
            'Flow View'

         Note: Not all of the viewNames are listed here. You have to get the exact names from
               the IxNetwork GUI in statistics based on your protocol(s).

         Return a dictionary of all the stats: statDict[rowNumber][columnName] == statValue
           Get stats on row 2 for 'Tx Frames' = statDict[2]['Tx Frames']
        #Ignore vieobject,silentMode in Restpy as it is taken care by StatViewAssistant internally
        viewObject = None
        silentMode = False

        """
        rowStats = None
        try:
            TrafficItemStats = StatViewAssistant(self.ixNetwork, viewName)
        except Exception as err:
            self.ixnObj.logInfo("Error in getting stats {}".format(err))
            raise Exception('getStats: Failed to get stats values')

        trafficItemStatsDict = {}
        columnCaptions = TrafficItemStats.ColumnHeaders

        if csvFile is not None:
            csvFileName = csvFile.replace(' ', '_')
            if csvEnableFileTimestamp:
                timestamp = datetime.datetime.now().strftime('%H%M%S')
                if '.' in csvFileName:
                    csvFileNameTemp = csvFileName.split('.')[0]
                    csvFileNameExtension = csvFileName.split('.')[1]
                    csvFileName = csvFileNameTemp + '_' + timestamp + '.' + csvFileNameExtension
                else:
                    csvFileName = csvFileName + '_' + timestamp

            csvFile = open(csvFileName, 'w')
            csvWriteObj = csv.writer(csvFile)
            csvWriteObj.writerow(columnCaptions)
            for rowNumber, stat in enumerate(TrafficItemStats.Rows):
                rowStats = stat.RawData
            for row in rowStats:
                csvWriteObj.writerow(row)
            csvFile.close()

        for rowNumber, stat in enumerate(TrafficItemStats.Rows):
            if displayStats:
                self.ixnObj.logInfo('\n Row: {}'.format(rowNumber + 1),
                                    timestamp=False)
            statsDict = {}
            for column in columnCaptions:
                statsDict[column] = stat[column]
                if displayStats:
                    self.ixnObj.logInfo('\t%s: %s' % (column, stat[column]),
                                        timestamp=False)
            trafficItemStatsDict[rowNumber + 1] = statsDict

        return trafficItemStatsDict

    def removeAllTclViews(self):
        """
        Description
           Removes all created stat views.
        """
        self.ixnObj.logInfo("Remove all tcl views")
        self.ixNetwork.RemoveAllTclViews()

    def takeSnapshot(self,
                     viewName='Flow Statistics',
                     windowsPath=None,
                     isLinux=False,
                     localLinuxPath=None,
                     renameDestinationFile=None,
                     includeTimestamp=False,
                     mode='overwrite'):
        """
        Description
            Take a snapshot of the vieweName statistics.  This is a two step process.
            1> Take a snapshot of the statistics that you want and store it in the C: drive
               for Windows.
               For Linux, the snapshot goes to /home/ixia_logs.
            2> Copy the statistics from the snapshot locations to the local Linux
               where you ran the script..

        Parameters
            viewName: The name of the statistics to get.
            windowsPath: For Windows|WindowsConnectionMgr only.
                         The C: drive + path to store the snapshot: Example: c:\\Results.
            isLinux: <bool>: Defaults to False.
                             Set to True if you're getting the snapshot from Linux chassis.
            localLinuxPath: None|path. Provide the local Linux path to put the snapshot file.
                            If None, this API won't copy the stat file to local Linux.
                            The stat file will remain on Windows c: drive.
            renameDestinationFile: None or a name of the file other than the viewName.
            includeTimestamp: True|False: To include a timestamp at the end of the file.
            mode: append|overwrite: append=To append stats to an existing stat file.
                                    overwrite=Don't append stats. Create a new stat file.

        Example:
            For Windows:
               statObj.takeSnapshot(viewName='Flow Statistics', windowsPath='C:\\Results',
                                    localLinuxPath='/home/hgee',
                                    renameDestinationFile='my_renamed_stat_file.csv',
                                    includeTimestamp=True)

            For Linux:
               statObj.takeSnapshot(viewName='Flow Statistics',
                                    isLinux=True, localLinuxPath='/home/hgee')
        """
        location = None
        if mode == 'append':
            mode = 'kAppendCSVFile'

        if mode == 'overwrite':
            mode = 'kOverwriteCSVFile'

        if windowsPath:
            location = windowsPath

        if isLinux:
            location = '/home/ixia_logs'
        self.ixNetwork.TakeViewCSVSnapshot(
            Arg1=[viewName],
            Arg2=[
                "Snapshot.View.Contents: \"allPages\"",
                "Snapshot.View.Csv.Location: \"{0}\"".format(location),
                "Snapshot.View.Csv.GeneratingMode: \"%s\"" % mode,
                "Snapshot.View.Csv.StringQuotes: \"True\"",
                "Snapshot.View.Csv.SupportsCSVSorting: \"False\"",
                "Snapshot.View.Csv.FormatTimestamp: \"True\"",
                "Snapshot.View.Csv.DumpTxPortLabelMap: \"False\"",
                "Snapshot.View.Csv.DecimalPrecision: \"3\""
            ])

        if isLinux:
            snapshotFile = location + '/' + viewName + '.csv'
            self.fileMgmtObj.copyFileLinuxToLocalLinux(
                linuxApiServerPathAndFileName=snapshotFile,
                localPath=localLinuxPath,
                renameDestinationFile=renameDestinationFile,
                includeTimestamp=includeTimestamp)

        if windowsPath and localLinuxPath:
            self.fileMgmtObj.copyFileWindowsToLocalLinux(
                '{0}\\{1}.csv'.format(windowsPath, viewName),
                localLinuxPath,
                renameDestinationFile=renameDestinationFile,
                includeTimestamp=includeTimestamp)

    def getViewObject(self, viewName='Flow Statistics'):
        """
        Description
            To get just the statistic view object.
            Mainly used by internal APIs such as takeCsvSnapshot that requires the statistics
            view object handle.

        Parameter
         viewName:  Options (case sensitive):
            "Port Statistics"
            "Tx-Rx Frame Rate Statistics"
            "Port CPU Statistics"
            "Global Protocol Statistics"
            "Protocols Summary"
            "Port Summary"
            "OSPFv2-RTR Drill Down"
            "OSPFv2-RTR Per Port"
            "IPv4 Drill Down"
            "L2-L3 Test Summary Statistics"
            "Flow Statistics"
            "Traffic Item Statistics"
        """
        for viewObj in self.ixNetwork.Statistics.View.find():
            if viewObj.Caption == viewName:
                return viewObj
        else:
            raise Exception(
                "View object not available for view name {}".format(viewName))

    def clearStats(self):
        """
        Description
            Clear all stats and wait for API server to finish.
        """
        self.ixnObj.logInfo("Clearing all statistics")
        self.ixNetwork.ClearStats(Arg1=['waitForPortStatsRefresh'])
Пример #8
0
class QuickTest(object):
    def __init__(self, ixnObj=None, fileMgmtObj=None):
        self.ixnObj = ixnObj
        self.ixNetwork = ixnObj.ixNetwork
        if fileMgmtObj:
            self.fileMgmtObj = fileMgmtObj
        else:
            self.fileMgmtObj = FileMgmt(ixnObj)

    def setMainObject(self, mainObject):
        self.ixnObj = mainObject
        self.fileMgmtObj.setMainObject(mainObject)

    def getAllQuickTestHandles(self):
        """
        Description
            Get all the Quick Test object handles

        Returns:
            [   <ixnetwork_restpy.testplatform.sessions.ixnetwork.quicktest
                    .openflowlayer2learningrate_3db88746f7f375303f2eda376386a9a8
                    .OpenFlowLayer2LearningRate object at 0x03AAE2B0>]
        """
        quickTestObjects = []
        for testId in self.ixNetwork.QuickTest.TestIds:
            qtType = testId.split("/")[-2]
            qtType = qtType[0].upper() + qtType[1:]
            qtObj = getattr(self.ixNetwork.QuickTest, qtType)
            quickTestObjects.append(qtObj.find())
        return quickTestObjects

    def getAllQuickTestNames(self):
        """
        Description
            Get all the Quick Test name.
        """
        quickTestNameList = []
        for eachQtHandle in self.getAllQuickTestHandles():
            qtName = eachQtHandle.Name
            if qtName:
                quickTestNameList.append(qtName)
        return quickTestNameList

    def getQuickTestHandleByName(self, quickTestName):
        """
        Description
            Get the Quick Test object handle by the name.
        Parameter
            quickTestName: The name of the Quick Test.
        """
        for quickTestHandle in self.getAllQuickTestHandles():
            if bool(re.match(quickTestName, quickTestHandle.Name, re.I)):
                return quickTestHandle
        else:
            raise Exception(
                "Unable to find quicktest with name {}".format(quickTestName))

    def getQuickTestNameByHandle(self, quickTestHandle):
        """
        Description :
            Get the Quick Test Name by quick test Handle
        Parameter :
            quickTestHandle = <ixnetwork_restpy.testplatform.sessions.ixnetwork.quicktest
                                    .rfc2544throughput_5a77c9a28f5fa2bb9ce9f4280eb5122f
                                    .Rfc2544throughput object at 0x03800D00>
        """
        if quickTestHandle.Name:
            return quickTestHandle.Name
        else:
            raise Exception("Unable to find quicktest name for given handle")

    def getQuickTestDuration(self, quickTestHandle):
        """
        Description :
            Get Quick Test Test Duration Time in Sec
        Parameter :
            quickTestHandle = <ixnetwork_restpy.testplatform.sessions.ixnetwork.quicktest
                                    .rfc2544throughput_5a77c9a28f5fa2bb9ce9f4280eb5122f
                                    .Rfc2544throughput object at 0x03800D00>
        """

        return quickTestHandle.TestConfig.Duration

    def getQuickTestTotalFrameSizesToTest(self, quickTestHandle):
        """
        Description :
            Get Quick Test Test Total Frame Sizes
        Parameter :
            quickTestHandle = <ixnetwork_restpy.testplatform.sessions.ixnetwork.quicktest
                                    .rfc2544throughput_5a77c9a28f5fa2bb9ce9f4280eb5122f
                                    .Rfc2544throughput object at 0x03800D00>
        """

        return quickTestHandle.TestConfig.FramesizeList

    def applyQuickTest(self, qtHandle):
        """
        Description
            Apply Quick Test configurations

        Parameter
            qtHandle: The Quick Test object handle
        """
        try:
            qtHandle.Apply()
        except Exception as err:
            raise Exception(
                "Operation apply quicktest failed with error :\n {}".format(
                    err))

    def getQuickTestCurrentAction(self, quickTestHandle):
        """
        Description :
            Returns current action like 'InitializingTest', 'ApplyFlowGroups',
            'SetupStatisticsCollection', etc.
        Parameter :
            quickTestHandle = <ixnetwork_restpy.testplatform.sessions.ixnetwork.quicktest
                                    .rfc2544throughput_5a77c9a28f5fa2bb9ce9f4280eb5122f
                                    .Rfc2544throughput object at 0x03800D00>
        """
        timer = 10
        currentActions = None
        for counter in range(1, timer + 1):
            currentActions = quickTestHandle.Results.CurrentActions
            self.ixnObj.logInfo('\n\ngetQuickTestCurrentAction:\n')
            for eachCurrentAction in quickTestHandle.Results.CurrentActions:
                self.ixnObj.logInfo('\t{}'.format(eachCurrentAction['arg2']))
            self.ixnObj.logInfo('\n')
            if counter < timer and currentActions == []:
                self.ixnObj.logInfo(
                    '\n getQuickTestCurrentAction is empty. Waiting %s/%s \n' %
                    (counter, timer))
                time.sleep(1)
                continue
            if counter < timer and currentActions != []:
                break
            if counter == timer and currentActions == []:
                raise Exception(
                    '\n\ngetQuickTestCurrentActions: Has no action')

        return currentActions[-1]['arg2']

    def verifyQuickTestInitialization(self, quickTestHandle):
        """
        Parameter :
            quickTestHandle = <ixnetwork_restpy.testplatform.sessions.ixnetwork.quicktest
                                    .rfc2544throughput_5a77c9a28f5fa2bb9ce9f4280eb5122f
                                    .Rfc2544throughput object at 0x03800D00>
        """

        for timer in range(1, 20 + 1):
            currentAction = self.getQuickTestCurrentAction(quickTestHandle)
            self.ixnObj.logInfo(
                'verifyQuickTestInitialization currentState: %s' %
                currentAction)
            if timer < 20:
                if currentAction == 'TestEnded' or currentAction == 'None':
                    self.ixnObj.logInfo(
                        '\nverifyQuickTestInitialization CurrentState = %s\n\tWaiting %s/20 '
                        'seconds to change state' % (currentAction, timer))
                    time.sleep(1)
                    continue
                else:
                    break
            if timer >= 20:
                if currentAction == 'TestEnded' or currentAction == 'None':
                    raise IxNetRestApiException(
                        'Quick Test is stuck at TestEnded.')

        applyQuickTestCounter = 60
        for counter in range(1, applyQuickTestCounter + 1):
            currentAction = self.getQuickTestCurrentAction(quickTestHandle)
            if currentAction is None:
                currentAction = 'ApplyingAndInitializing'

            self.ixnObj.logInfo(
                '\n verifyQuickTestInitialization: %s  Expecting: TransmittingFrames\n\tWaiting'
                ' %s/%s seconds' %
                (currentAction, counter, applyQuickTestCounter))
            if counter < applyQuickTestCounter and currentAction != 'TransmittingFrames':
                time.sleep(1)
                continue

            if counter < applyQuickTestCounter and currentAction == 'TransmittingFrames':
                self.ixnObj.logInfo(
                    '\n VerifyQuickTestInitialization is done applying configuration and'
                    ' has started transmitting frames\n')
                break

            if counter == applyQuickTestCounter:
                if currentAction == 'ApplyFlowGroups':
                    self.ixnObj.logInfo(
                        '\nIxNetwork is stuck on Applying Flow Groups. You need to go to the '
                        'session to FORCE QUIT it.\n')
                raise IxNetRestApiException(
                    '\nVerifyQuickTestInitialization is stuck on %s. Waited %s/%s seconds'
                    % (currentAction, counter, applyQuickTestCounter))

    def startQuickTest(self, quickTestHandle):
        """
        Description
            Start a Quick Test

        Parameter
            quickTestHandle: The Quick Test object handle.

        """
        try:
            quickTestHandle.Apply()
            quickTestHandle.Start()
        except Exception as err:
            self.ixnObj.logInfo("Error : \n {}".format(err))
            raise Exception("Failed Starting QuickTest for {}".format(
                quickTestHandle.Name))

    def stopQuickTest(self, quickTestHandle):
        """
        Description
            Stop the Quick Test.

        Parameter
            quickTestHandle: The Quick Test object handle.

        """
        try:
            quickTestHandle.Stop()
        except Exception as err:
            self.ixnObj.logInfo("Error in stop quicktest : \n {}".format(err))
            raise Exception("Failed Stopping QuickTest for {}".format(
                quickTestHandle.Name))

    def monitorQuickTestRunningProgress(self,
                                        quickTestHandle,
                                        getProgressInterval=10):
        """
        Description
            monitor the Quick Test running progress.
            For Linux API server only, it must be a NGPF configuration.

        Parameters
            quickTestHandle: quick test handle
        """
        isRunningBreakFlag = 0
        trafficStartedFlag = 0
        waitForRunningProgressCounter = 0
        counter = 1

        while True:
            isRunning = quickTestHandle.Results.IsRunning
            if isRunning:
                currentRunningProgress = quickTestHandle.Results.Progress
                self.ixnObj.logInfo(currentRunningProgress)
                if not bool(re.match('^Trial.*', currentRunningProgress)):
                    if waitForRunningProgressCounter < 30:
                        self.ixnObj.logInfo(
                            'isRunning=True. Waiting for trial runs {0}/30 '
                            'seconds'.format(waitForRunningProgressCounter))
                        waitForRunningProgressCounter += 1
                        time.sleep(1)
                    if waitForRunningProgressCounter == 30:
                        raise IxNetRestApiException(
                            'isRunning=True. No quick test stats showing.')
                else:
                    trafficStartedFlag = 1
                    self.ixnObj.logInfo(currentRunningProgress)
                    counter += 1
                    time.sleep(getProgressInterval)
                    continue
            else:
                if trafficStartedFlag == 1:
                    # We only care about traffic not running in the beginning.
                    # If traffic ran and stopped, then break out.
                    self.ixnObj.logInfo(
                        '\nisRunning=False. Quick Test is complete')
                    return 0
                if isRunningBreakFlag < 20:
                    self.ixnObj.logInfo(
                        'isRunning=False. Wait {0}/20 seconds'.format(
                            isRunningBreakFlag))
                    isRunningBreakFlag += 1
                    time.sleep(1)
                    continue
                if isRunningBreakFlag == 20:
                    raise IxNetRestApiException('Quick Test failed to start:')

    def getQuickTestResultPath(self, quickTestHandle):
        """
        quickTestHandle = The quick test handle
        """
        resultsPath = quickTestHandle.Results.ResultPath
        if not resultsPath:
            raise Exception("no result path found for quicktest {}".format(
                quickTestHandle.Name))
        return resultsPath

    def getQuickTestResult(self, quickTestHandle, attribute):
        """
        Description
            Get Quick Test result attributes

        Parameter
            quickTestHandle: The Quick Test object handle

        attribute options to get:
           result - Returns pass
           status - Returns none
           progress - blank or Trial 1/1 Iteration 1, Size 64,
                      Rate 10 % Wait for 2 seconds Wait 70.5169449%complete
           startTime - Returns 04/21/17 14:35:42
           currentActions
           waitingStatus
           resultPath
           isRunning - Returns True or False
           trafficStatus
           duration - Returns 00:01:03
           currentViews
        """
        attribute = attribute[0].upper() + attribute[1:]
        result = getattr(quickTestHandle.Results, attribute)
        return result

    def getQuickTestCsvFiles(self, quickTestHandle, copyToPath, csvFile='all'):
        """
        Description
            Copy Quick Test CSV result files to a specified path on either Windows or Linux.
            Note: Currently only supports copying from Windows.
                  Copy from Linux is coming in November.

        quickTestHandle: The Quick Test handle.
        copyToPath: The destination path to copy to.
                    If copy to Windows: c:\\Results\\Path
                    If copy to Linux: /home/user1/results/path

        csvFile: A list of CSV files to get: 'all', one or more CSV files to get:
                 AggregateResults.csv, iteration.csv, results.csv, logFile.txt, portMap.csv
        """
        resultsPath = quickTestHandle.Results.ResultPath
        self.ixnObj.logInfo('\ngetQuickTestCsvFiles: %s' % resultsPath)

        if csvFile == 'all':
            getCsvFiles = [
                'AggregateResults.csv', 'iteration.csv', 'results.csv',
                'logFile.txt', 'portMap.csv'
            ]
        else:
            if type(csvFile) is not list:
                getCsvFiles = [csvFile]
            else:
                getCsvFiles = csvFile

        for eachCsvFile in getCsvFiles:
            # Backslash indicates the results resides on a Windows OS.
            if '\\' in resultsPath:
                windowsSource = resultsPath + '\\{0}'.format(eachCsvFile)
                if '\\' in copyToPath:
                    self.fileMgmtObj.copyFileWindowsToLocalWindows(
                        windowsSource, copyToPath)
                else:
                    self.fileMgmtObj.copyFileWindowsToLocalLinux(
                        windowsSource, copyToPath)

            else:
                linuxSource = resultsPath + '/{0}'.format(eachCsvFile)
                self.fileMgmtObj.copyFileLinuxToLocalLinux(
                    linuxSource, copyToPath)

    def getQuickTestPdf(self,
                        quickTestHandle,
                        copyToLocalPath,
                        where='remoteLinux',
                        renameDestinationFile=None,
                        includeTimestamp=False):
        """
        Description
           Generate Quick Test result to PDF and retrieve the PDF result file.

        Parameter
           where: localWindows|remoteWindows|remoteLinux. The destination.
           copyToLocalPath: The local destination path to store the PDF result file.
           renameDestinationFile: Rename the PDF file.
           includeTimestamp: True|False.  Set to True if you don't want to overwrite previous
           result file.
        """

        try:
            reportFile = quickTestHandle.GenerateReport()
        except Exception as err:
            raise Exception(
                "Generate quicktest report file failed. Error : \n {}".format(
                    err))

        if where == 'localWindows':
            self.fileMgmtObj.copyFileWindowsToLocalWindows(
                reportFile, copyToLocalPath, renameDestinationFile,
                includeTimestamp)
        if where == 'remoteWindows':
            self.fileMgmtObj.copyFileWindowsToRemoteWindows(
                reportFile, copyToLocalPath, renameDestinationFile,
                includeTimestamp)
        if where == 'remoteLinux':
            self.fileMgmtObj.copyFileWindowsToLocalLinux(
                reportFile, copyToLocalPath, renameDestinationFile,
                includeTimestamp)

    def runQuickTest(self, quickTestName, timeout=90):
        """
        Description
            Run the Quick test

        Parameter
            quickTestName: <str>: name of the quick test to run
            timeout: <int>: timeout duration handles internally in Restpy

        Example
            runQuickTest("Macro_17_57_14_294", timeout=180)

        Return

        Note: operation run will keep checking the status of execution for the specified timeout
        """
        eventSchedulerHandle = self.getQuickTestHandleByName(quickTestName)
        try:
            eventSchedulerHandle.Run()
        except Exception as err:
            raise Exception(
                "Run quicktest operation failed with error : \n {}".format(
                    err))

    def deleteQuickTest(self, quickTestName):
        """
        Description
            Delete the  Quick test.

        Parameter
            quickTestName: <str>: name of the quick test to delete

        Example
            deleteQuickTest("Macro_17_57_14_294")

        Return
        """
        eventSchedulerHandle = self.getQuickTestHandleByName(quickTestName)
        try:
            eventSchedulerHandle.remove()
        except Exception as err:
            raise Exception(
                "Delete quicktest by quicktest name failed with error : \n {}".
                format(err))

    def configQuickTest(self, quickTestName, numOfTrials=1):
        """
        Description
            Configure a quick test

        Parameter
            quickTestName: <str>: name of the quick test to configure
            numOfTrials: <int>: number of iterations to run the quick test, default is 1

        Example
            configQuickTest("Macro_17_57_14_294")
            configQuickTest("Macro_17_57_14_294", numOfTrials=2)

        Return
            event scheduler handle on success or exception on failure
        """
        try:
            eventSchedulerHandle = self.ixNetwork.QuickTest.EventScheduler.add(
            )
            eventSchedulerHandle.Name = quickTestName
            eventSchedulerHandle.Mode = "existingMode"
            eventSchedulerHandle.ForceApplyQTConfig = True
            eventSchedulerHandle.TestConfig.NumTrials = numOfTrials
            return eventSchedulerHandle
        except Exception as err:
            raise Exception(
                "Unable to configure quick test. Error : \n {}".format(err))