コード例 #1
0
ファイル: DeviceTests.py プロジェクト: orickman/TKperf
 def __init__(self, testname, device, options):
     '''
     Constructor.
     '''
     super(SsdTPTest, self).__init__(testname, device, options)
     ## A list of matrices with the collected fio measurement values of each round.
     self.__roundMatrices = []
     self.__stdyState = StdyState()
コード例 #2
0
ファイル: DeviceTests.py プロジェクト: orickman/TKperf
 def __init__(self, testname, device, options=None):
     '''
     Constructor.
     '''
     super(SsdIopsTest, self).__init__(testname, device, options)
     ## A list of matrices with the collected fio measurement values of each round.
     self.__roundMatrices = []
     self.__stdyState = StdyState()
     self.getFioJob().addKVArg("rw", "randrw")
コード例 #3
0
 def __init__(self, testname, device, options):
     '''
     Constructor.
     '''
     super(SsdTPTest, self).__init__(testname, device, options)
     ## Labels of block sizes to run tests with
     self.__bsLabels = ["1024k", "64k", "8k", "4k", "512"]
     ## A list of matrices with the collected fio measurement values of each round.
     self.__roundMatrices = []
     self.__stdyState = StdyState()
コード例 #4
0
 def __init__(self, testname, device, options=None):
     '''
     Constructor.
     '''
     super(SsdIopsTest, self).__init__(testname, device, options)
     ## Labels of block sizes to run tests with
     self.__bsLabels = [
         "1024k", "128k", "64k", "32k", "16k", "8k", "4k", "512"
     ]
     ## A list of matrices with the collected fio measurement values of each round.
     self.__roundMatrices = []
     self.__stdyState = StdyState()
     self.getFioJob().addKVArg("rw", "randrw")
コード例 #5
0
ファイル: DeviceTests.py プロジェクト: orickman/TKperf
 def __init__(self, testname, device, options=None):
     '''
     Constructor.
     '''
     ## Keep user options
     self.__userOptions = options
     if options != None:
         #For latency the specification says to use 1 job/thread, 1 outstanding IO
         wsoptions = Options(1, 1)
         if options.getXargs() != None:
             wsoptions.setXargs(options.getXargs())
     super(SsdLatencyTest, self).__init__(testname, device, wsoptions)
     ## A list of matrices with the collected fio measurement values of each round.
     self.__roundMatrices = []
     self.__stdyState = StdyState()
     self.getFioJob().addKVArg("rw", "randrw")
コード例 #6
0
ファイル: DeviceTests.py プロジェクト: Fateast/TKperf
 def __init__(self,testname,device,options):
     '''
     Constructor.
     '''
     super(SsdTPTest,self).__init__(testname,device,options)
     ## A list of matrices with the collected fio measurement values of each round.
     self.__roundMatrices = []
     self.__stdyState = StdyState()
コード例 #7
0
ファイル: DeviceTests.py プロジェクト: Fateast/TKperf
 def __init__(self,testname,device,options=None):
     '''
     Constructor.
     '''
     super(SsdIopsTest,self).__init__(testname,device,options)
     ## A list of matrices with the collected fio measurement values of each round.
     self.__roundMatrices = []
     self.__stdyState = StdyState()
     self.getFioJob().addKVArg("rw","randrw")
コード例 #8
0
ファイル: DeviceTests.py プロジェクト: Fateast/TKperf
 def __init__(self,testname,device,options=None):
     '''
     Constructor.
     '''
     ## Keep user options
     self.__userOptions = options
     if options != None:
         #For latency the specification says to use 1 job/thread, 1 outstanding IO
         wsoptions = Options(1,1)
         if options.getXargs() != None:
             wsoptions.setXargs(options.getXargs())
     super(SsdLatencyTest,self).__init__(testname,device,wsoptions)
     ## A list of matrices with the collected fio measurement values of each round.
     self.__roundMatrices = []
     self.__stdyState = StdyState()
     self.getFioJob().addKVArg("rw","randrw")
コード例 #9
0
ファイル: DeviceTests.py プロジェクト: orickman/TKperf
class SsdTPTest(DeviceTest):
    '''
    A class to carry out the Throughput test.
    '''
    ##Labels of block sizes for throughput test
    bsLabels = [
        "1024k",
        "64k",
        "8k",
        "4k",
        "512",
    ]

    def __init__(self, testname, device, options):
        '''
        Constructor.
        '''
        super(SsdTPTest, self).__init__(testname, device, options)
        ## A list of matrices with the collected fio measurement values of each round.
        self.__roundMatrices = []
        self.__stdyState = StdyState()

    def getRndMatrices(self):
        return self.__roundMatrices

    def getStdyState(self):
        return self.__stdyState

    def toLog(self):
        '''
        Log information about the steady state and how it 
        has been reached.
        '''
        logging.info("Round matrices: ")
        logging.info(self.__roundMatrices)
        self.getStdyState().toLog()

    def testRound(self, bs):
        '''    
        Carry out one test round of the throughput test.
        Read and Write throughput is tested with the given block size
        @param bs The current block size to use.
        @return Read and Write bandwidths [tpRead,tpWrite]
        '''
        self.getFioJob().addKVArg("bs", bs)
        jobOut = ''
        tpRead = 0  #read bandwidth
        tpWrite = 0  #write bandwidth

        #start read tests
        self.getFioJob().addKVArg("rw", "read")
        call, jobOut = self.getFioJob().start()
        if call == False:
            exit(1)
        logging.info("Read TP test:")
        logging.info(jobOut)
        logging.info("######")
        tpRead = self.getFioJob().getTPRead(jobOut)

        #start write tests
        self.getFioJob().addKVArg("rw", "write")
        call, jobOut = self.getFioJob().start()
        if call == False:
            exit(1)
        logging.info("Write TP test:")
        logging.info(jobOut)
        logging.info("######")
        tpWrite = self.getFioJob().getTPWrite(jobOut)
        return [tpRead, tpWrite]

    def runRounds(self):
        '''
        Carry out the throughput/bandwidth test rounds and check if the steady state is reached.
         @return True if the steady state has been reached, False if not.
        '''
        stdyValsWrite = deque([])  #List of 1M sequential write IOPS
        xrangesWrite = deque([])  #Rounds of current measurement window

        #rounds are the same for IOPS and throughput
        for j in SsdTPTest.bsLabels:
            try:
                self.getDevice().secureErase()
            except RuntimeError:
                logging.error("# Could not carry out secure erase for " +
                              self.getDevice().getDevPath())
                raise

            tpRead_l = []
            tpWrite_l = []
            logging.info("#################")
            logging.info("Current block size. " + str(j))

            for i in range(StdyState.testRnds):
                logging.info("######")
                logging.info("Round nr. " + str(i))
                tpRead, tpWrite = self.testRound(j)
                tpRead_l.append(tpRead)
                tpWrite_l.append(tpWrite)

                #if the rounds have been set by steady state for 1M block size
                #we need to carry out only i rounds for the other block sizes
                #as steady state has already been reached
                if self.getStdyState().getRnds() != 0 and self.getStdyState(
                ).getRnds() == i:
                    self.getRndMatrices().append([tpRead_l, tpWrite_l])
                    break

                # Use 1M block sizes sequential write for steady state detection
                if j == "1024k":
                    stdyValsWrite.append(tpWrite)
                    xrangesWrite.append(i)
                    if i > 4:
                        xrangesWrite.popleft()
                        stdyValsWrite.popleft()
                        #check if the steady state has been reached in the last 5 rounds
                    if i >= 4:
                        steadyState = self.getStdyState().checkSteadyState(
                            xrangesWrite, stdyValsWrite, i)
                        #reached a steady state
                        if steadyState == True:
                            logging.info("Reached steady state at round %d", i)
                        #running from 0 to 24
                        if i == ((StdyState.testRnds) - 1):
                            self.getStdyState().setReachStdyState(False)
                            logging.warn(
                                "#Did not reach steady state for bs %s", j)
                        #In both cases we are done with steady state checking
                        if steadyState == True or i == ((StdyState.testRnds) -
                                                        1):
                            self.getRndMatrices().append([tpRead_l, tpWrite_l])
                            #Done with 1M block size
                            break
        #Return current steady state
        return self.getStdyState().isSteady()

    def run(self):
        '''
        Start the rounds, log the steady state infos.
        @return True if all tests were run
        '''
        logging.info("########### Starting Throughput Test ###########")
        steadyState = self.runRounds()
        if steadyState == False:
            logging.info(
                "# Steady State has not been reached for Throughput Test.")
        self.toLog()
        return True

    def toXml(self, root):
        '''
        Get the Xml representation of the test.
        @param root Name of the new root Xml node
        @return An xml root element containing the information about the test
        '''
        r = etree.Element(root)
        # Add Fio version to xml
        self.getFioJob().appendXml(r)
        # Add the options to xml
        self.getOptions().appendXml(r)
        data = json.dumps(self.__roundMatrices)
        e = etree.SubElement(r, 'roundmat')
        e.text = data
        self.getStdyState().appendXml(r)
        return r

    def fromXml(self, root):
        '''
        Load and set from an XML representation of a test.
        @param root Name of root element from which to load values
        '''
        logging.info("########### Loading TP test from " + self.getTestname() +
                     ".xml ###########")
        self.__roundMatrices = json.loads(root.findtext('roundmat'))
        self.__stdyState.fromXml(root)
        self.getFioJob().fromXml(root)
        self.getOptions().fromXml(root)
        self.toLog()

    def genPlots(self):
        ''' Generate plots for throughput. '''
        import plots.genPlots as pgp
        pgp.tpRWStdyStConvPlt(self)
        pgp.stdyStVerPlt(self, "TP")
        pgp.tpMes2DPlt(self)
コード例 #10
0
ファイル: DeviceTests.py プロジェクト: orickman/TKperf
class SsdLatencyTest(DeviceTest):
    '''
    Representing a Latency test for a ssd based device.
    '''
    ##Percentages of mixed workloads.
    mixWlds = [100, 65, 0]
    ##Labels of block sizes.
    bsLabels = ["8k", "4k", "512"]

    def __init__(self, testname, device, options=None):
        '''
        Constructor.
        '''
        ## Keep user options
        self.__userOptions = options
        if options != None:
            #For latency the specification says to use 1 job/thread, 1 outstanding IO
            wsoptions = Options(1, 1)
            if options.getXargs() != None:
                wsoptions.setXargs(options.getXargs())
        super(SsdLatencyTest, self).__init__(testname, device, wsoptions)
        ## A list of matrices with the collected fio measurement values of each round.
        self.__roundMatrices = []
        self.__stdyState = StdyState()
        self.getFioJob().addKVArg("rw", "randrw")

    def getRndMatrices(self):
        return self.__roundMatrices

    def getStdyState(self):
        return self.__stdyState

    def toLog(self):
        '''
        Log information about the steady state and how it 
        has been reached.
        '''
        logging.info("Round matrices: ")
        logging.info(self.__roundMatrices)
        self.getStdyState().toLog()

    def testRound(self):
        '''
        Carry out one latency test round.
        The round consists of two inner loops: one iterating over the
        percentage of random reads/writes in the mixed workload, the other
        over different block sizes.
        @return A matrix containing [min,max,mean] latencies of the round.
        '''
        jobOut = ''
        rndMatrix = []
        for i in SsdLatencyTest.mixWlds:
            rwRow = []
            for j in SsdLatencyTest.bsLabels:
                self.getFioJob().addKVArg("rwmixread", str(i))
                self.getFioJob().addKVArg("bs", j)
                call, jobOut = self.getFioJob().start()
                if call == False:
                    exit(1)
                logging.info("mixLoad: " + str(i))
                logging.info("bs: " + j)
                logging.info(jobOut)
                logging.info("######")
                if i == 65:
                    #if we have a mixed workload weight the latencies
                    l = [0, 0, 0]
                    r = self.getFioJob().getReadLats(jobOut)
                    w = self.getFioJob().getWriteLats(jobOut)
                    #FIXME Is this also correct for Min and Max?
                    l[0] = (0.65 * r[0]) + (0.35 * w[0])
                    l[1] = (0.65 * r[1]) + (0.35 * w[1])
                    l[2] = (0.65 * r[2]) + (0.35 * w[2])
                else:
                    l = self.getFioJob().getTotLats(jobOut)
                rwRow.append(l)
            rndMatrix.append(rwRow)
        return rndMatrix

    def runRounds(self):
        '''
        Carry out the latency test rounds and check if the steady state is reached.
        For a maximum of 25 rounds the test loop is carried out. After each
        test round we check for a measurement window of the last 5 rounds if
        the steady state has been reached.
        @return True if the steady state has been reached, False if not.
        '''
        rndMatrix = []
        steadyValues = deque([])
        xranges = deque([])  #Rounds of current measurement window

        for i in range(StdyState.testRnds):
            logging.info("#################")
            logging.info("Round nr. " + str(i))
            rndMatrix = self.testRound()
            self.getRndMatrices().append(rndMatrix)
            #Latencies always consist of [min,max,mean] latency
            #Take mean/average for steady state detection
            steadyValues.append(rndMatrix[-1][-2][2])
            xranges.append(i)
            if i > 4:
                xranges.popleft()
                steadyValues.popleft()
            #check if the steady state has been reached in the last 5 rounds
            if i >= 4:
                steadyState = self.getStdyState().checkSteadyState(
                    xranges, steadyValues, i)
                if steadyState == True:
                    break
        #Return current steady state
        return self.getStdyState().isSteady()

    def run(self):
        '''
        Start the rounds, log the steady state infos.
        @return True if all tests were run
        '''
        try:
            self.getDevice().secureErase()
        except RuntimeError:
            logging.error("# Could not carry out secure erase for " +
                          self.getDevice().getDevPath())
            raise
        try:
            if self.__userOptions == None:
                self.getDevice().precondition(1, 1)
            else:
                if self.__userOptions.getNj() != None:
                    nj = self.__userOptions.getNj()
                if self.__userOptions.getIod() != None:
                    iod = self.__userOptions.getIod()
                self.getDevice().precondition(nj, iod)
        except RuntimeError:
            logging.error("# Could not carry out preconditioning for " +
                          self.getDevice().getDevPath())
            raise
        logging.info("########### Starting Latency Test ###########")
        steadyState = self.runRounds()
        if steadyState == False:
            logging.info(
                "# Steady State has not been reached for Latency Test.")
        self.toLog()
        return True

    def toXml(self, root):
        '''
        Get the Xml representation of the test.
        @param root Name of the new root Xml node
        @return An xml root element containing the information about the test
        '''
        r = etree.Element(root)
        # Add Fio version to xml
        self.getFioJob().appendXml(r)
        # Add the options to xml
        self.getOptions().appendXml(r)
        data = json.dumps(self.__roundMatrices)
        e = etree.SubElement(r, 'roundmat')
        e.text = data
        self.getStdyState().appendXml(r)
        return r

    def fromXml(self, root):
        '''
        Load and set from an XML representation of a test.
        @param root Name of root element from which to load values
        '''
        logging.info("########### Loading latency test from " +
                     self.getTestname() + ".xml ###########")
        self.__roundMatrices = json.loads(root.findtext('roundmat'))
        self.__stdyState.fromXml(root)
        self.getFioJob().fromXml(root)
        self.getOptions().fromXml(root)
        self.toLog()

    def genPlots(self):
        ''' Generate plots for latency. '''
        import plots.genPlots as pgp
        pgp.stdyStConvPlt(self, "LAT")
        pgp.stdyStVerPlt(self, "LAT")
        pgp.mes2DPlt(self, "avg-LAT")
        pgp.mes2DPlt(self, "max-LAT")
        pgp.latMes3DPlt(self)
コード例 #11
0
ファイル: DeviceTests.py プロジェクト: orickman/TKperf
class SsdIopsTest(DeviceTest):
    '''
    Representing an IOPS test for a ssd based device.
    '''
    ##Labels of block sizes
    bsLabels = ["1024k", "128k", "64k", "32k", "16k", "8k", "4k", "512"]
    ##Percentages of mixed workloads
    mixWlds = [100, 95, 65, 50, 35, 5, 0]

    def __init__(self, testname, device, options=None):
        '''
        Constructor.
        '''
        super(SsdIopsTest, self).__init__(testname, device, options)
        ## A list of matrices with the collected fio measurement values of each round.
        self.__roundMatrices = []
        self.__stdyState = StdyState()
        self.getFioJob().addKVArg("rw", "randrw")

    def getRndMatrices(self):
        return self.__roundMatrices

    def getStdyState(self):
        return self.__stdyState

    def toLog(self):
        '''
        Log information about the steady state and how it 
        has been reached.
        '''
        logging.info("Round matrices: ")
        logging.info(self.__roundMatrices)
        self.getStdyState().toLog()

    def testRound(self):
        '''
        Carry out one IOPS test round.
        The round consists of two inner loops: one iterating over the
        percentage of random reads/writes in the mixed workload, the other
        over different block sizes.
        @return A matrix containing the sum of average IOPS.
        '''
        jobOut = ''  #Fio job output
        rndMatrix = []
        for i in SsdIopsTest.mixWlds:
            rwRow = []
            for j in SsdIopsTest.bsLabels:
                self.getFioJob().addKVArg("rwmixread", str(i))
                self.getFioJob().addKVArg("bs", j)
                call, jobOut = self.getFioJob().start()
                if call == False:
                    exit(1)
                logging.info("mixLoad: " + str(i))
                logging.info("bs: " + j)
                logging.info(jobOut)
                logging.info("######")
                rwRow.append(self.getFioJob().getIOPS(jobOut))
            rndMatrix.append(rwRow)
        return rndMatrix

    def runRounds(self):
        '''
        Carry out the IOPS test rounds and check if the steady state is reached.
        For a maximum of 25 rounds the test loop is carried out. After each
        test round we check for a measurement window of the last 5 rounds if
        the steady state has been reached.
        @return True if the steady state has been reached, False if not.
        '''
        rndMatrix = []
        steadyValues = deque([])  #List of 4k random writes IOPS
        xranges = deque([])  #Rounds of current measurement window

        for i in range(StdyState.testRnds):
            logging.info("#################")
            logging.info("Round nr. " + str(i))
            rndMatrix = self.testRound()
            self.getRndMatrices().append(rndMatrix)
            # Use the last row and its next to last value
            #-> 0/100% r/w and 4k for steady state detection
            steadyValues.append(rndMatrix[-1][-2])
            xranges.append(i)
            if i > 4:
                xranges.popleft()
                steadyValues.popleft()
            #check if the steady state has been reached in the last 5 rounds
            if i >= 4:
                steadyState = self.getStdyState().checkSteadyState(
                    xranges, steadyValues, i)
                if steadyState == True:
                    break
        #Return current steady state
        return self.getStdyState().isSteady()

    def run(self):
        '''
        Start the rounds, log the steady state infos.
        @return True if all tests were run
        '''
        try:
            self.getDevice().secureErase()
        except RuntimeError:
            logging.error("# Could not carry out secure erase for " +
                          self.getDevice().getDevPath())
            raise
        try:
            if self.getOptions() == None:
                self.getDevice().precondition(1, 1)
            else:
                if self.getOptions().getNj() != None:
                    nj = self.getOptions().getNj()
                if self.getOptions().getIod() != None:
                    iod = self.getOptions().getIod()
                self.getDevice().precondition(nj, iod)
        except RuntimeError:
            logging.error("# Could not carry out preconditioning for " +
                          self.getDevice().getDevPath())
            raise
        logging.info("########### Starting IOPS Test ###########")
        steadyState = self.runRounds()
        if steadyState == False:
            logging.info("# Steady State has not been reached for IOPS Test.")
        self.toLog()
        return True

    def toXml(self, root):
        '''
        Get the Xml representation of the test.
        @param root Name of the new root Xml node
        @return An xml root element containing the information about the test
        '''
        r = etree.Element(root)
        # Add Fio version to xml
        self.getFioJob().appendXml(r)
        # Add the options to xml
        self.getOptions().appendXml(r)
        data = json.dumps(self.__roundMatrices)
        e = etree.SubElement(r, 'roundmat')
        e.text = data
        self.getStdyState().appendXml(r)
        return r

    def fromXml(self, root):
        '''
        Load and set from an XML representation of a test.
        @param root Name of root element from which to load values
        '''
        logging.info("########### Loading IOPS test from " +
                     self.getTestname() + ".xml ###########")
        self.__roundMatrices = json.loads(root.findtext('roundmat'))
        self.__stdyState.fromXml(root)
        self.getFioJob().fromXml(root)
        self.getOptions().fromXml(root)
        self.toLog()

    def genPlots(self):
        ''' Generate plots for IOPS. '''
        import plots.genPlots as pgp
        pgp.stdyStConvPlt(self, "IOPS")
        pgp.stdyStVerPlt(self, "IOPS")
        pgp.mes2DPlt(self, "IOPS")
        pgp.mes3DPlt(self, "IOPS")
コード例 #12
0
ファイル: DeviceTests.py プロジェクト: Fateast/TKperf
class SsdTPTest(DeviceTest):
    '''
    A class to carry out the Throughput test.
    '''
    ##Labels of block sizes for throughput test
    bsLabels = ["1024k","64k","8k","4k","512",]
    
    def __init__(self,testname,device,options):
        '''
        Constructor.
        '''
        super(SsdTPTest,self).__init__(testname,device,options)
        ## A list of matrices with the collected fio measurement values of each round.
        self.__roundMatrices = []
        self.__stdyState = StdyState()

    def getRndMatrices(self): return self.__roundMatrices
    def getStdyState(self): return self.__stdyState

    def toLog(self):
        '''
        Log information about the steady state and how it 
        has been reached.
        '''
        logging.info("Round matrices: ")
        logging.info(self.__roundMatrices)
        self.getStdyState().toLog()

    def testRound(self,bs):
        '''    
        Carry out one test round of the throughput test.
        Read and Write throughput is tested with the given block size
        @param bs The current block size to use.
        @return Read and Write bandwidths [tpRead,tpWrite]
        '''
        self.getFioJob().addKVArg("bs",bs)
        jobOut = ''
        tpRead = 0 #read bandwidth
        tpWrite = 0#write bandwidth

        #start read tests
        self.getFioJob().addKVArg("rw","read")
        call,jobOut = self.getFioJob().start()
        if call == False:
            exit(1)
        logging.info("Read TP test:")
        logging.info(jobOut)
        logging.info("######")
        tpRead = self.getFioJob().getTPRead(jobOut)
        
        #start write tests
        self.getFioJob().addKVArg("rw","write")
        call,jobOut = self.getFioJob().start()
        if call == False:
            exit(1)
        logging.info("Write TP test:")
        logging.info(jobOut)
        logging.info("######")
        tpWrite = self.getFioJob().getTPWrite(jobOut)
        return [tpRead,tpWrite]
    
    def runRounds(self):
        '''
        Carry out the throughput/bandwidth test rounds and check if the steady state is reached.
         @return True if the steady state has been reached, False if not.
        '''
        stdyValsWrite = deque([])#List of 1M sequential write IOPS
        xrangesWrite = deque([])#Rounds of current measurement window
        
        #rounds are the same for IOPS and throughput
        for j in SsdTPTest.bsLabels:
            try: 
                self.getDevice().secureErase()
            except RuntimeError:
                logging.error("# Could not carry out secure erase for "+self.getDevice().getDevPath())
                raise

            tpRead_l = []
            tpWrite_l = []
            logging.info("#################")
            logging.info("Current block size. "+str(j))
            
            for i in range(StdyState.testRnds):
                logging.info("######")
                logging.info("Round nr. "+str(i))
                tpRead,tpWrite = self.testRound(j)
                tpRead_l.append(tpRead)
                tpWrite_l.append(tpWrite)
                
                #if the rounds have been set by steady state for 1M block size
                #we need to carry out only i rounds for the other block sizes
                #as steady state has already been reached
                if self.getStdyState().getRnds() != 0 and self.getStdyState().getRnds() == i:
                    self.getRndMatrices().append([tpRead_l,tpWrite_l])
                    break
                
                # Use 1M block sizes sequential write for steady state detection
                if j == "1024k":
                    stdyValsWrite.append(tpWrite)
                    xrangesWrite.append(i)
                    if i > 4:
                        xrangesWrite.popleft()
                        stdyValsWrite.popleft()
                        #check if the steady state has been reached in the last 5 rounds
                    if i >= 4:
                        steadyState = self.getStdyState().checkSteadyState(xrangesWrite,stdyValsWrite,i)
                        #reached a steady state
                        if steadyState == True:
                            logging.info("Reached steady state at round %d",i)
                        #running from 0 to 24
                        if i == ((StdyState.testRnds) - 1):
                            self.getStdyState().setReachStdyState(False)
                            logging.warn("#Did not reach steady state for bs %s",j)
                        #In both cases we are done with steady state checking
                        if steadyState == True or i == ((StdyState.testRnds) - 1):
                            self.getRndMatrices().append([tpRead_l,tpWrite_l])
                            #Done with 1M block size
                            break
        #Return current steady state
        return self.getStdyState().isSteady()
        
    def run(self):
        '''
        Start the rounds, log the steady state infos.
        @return True if all tests were run
        '''
        logging.info("########### Starting Throughput Test ###########")
        steadyState = self.runRounds()
        if steadyState == False:
            logging.info("# Steady State has not been reached for Throughput Test.")
        self.toLog()
        return True

    def toXml(self,root):
        '''
        Get the Xml representation of the test.
        @param root Name of the new root Xml node
        @return An xml root element containing the information about the test
        ''' 
        r = etree.Element(root)
        # Add Fio version to xml
        self.getFioJob().appendXml(r)
        # Add the options to xml
        self.getOptions().appendXml(r)
        data = json.dumps(self.__roundMatrices)
        e = etree.SubElement(r,'roundmat')
        e.text = data
        self.getStdyState().appendXml(r)
        return r

    def fromXml(self,root):
        '''
        Load and set from an XML representation of a test.
        @param root Name of root element from which to load values
        '''
        logging.info("########### Loading TP test from "+self.getTestname()+".xml ###########")
        self.__roundMatrices = json.loads(root.findtext('roundmat'))
        self.__stdyState.fromXml(root)
        self.getFioJob().fromXml(root)
        self.getOptions().fromXml(root)
        self.toLog()

    def genPlots(self):
        ''' Generate plots for throughput. '''
        import plots.genPlots as pgp
        pgp.tpRWStdyStConvPlt(self)
        pgp.stdyStVerPlt(self,"TP")
        pgp.tpMes2DPlt(self)
コード例 #13
0
ファイル: DeviceTests.py プロジェクト: Fateast/TKperf
class SsdLatencyTest(DeviceTest):
    '''
    Representing a Latency test for a ssd based device.
    '''
    ##Percentages of mixed workloads.
    mixWlds = [100,65,0]
    ##Labels of block sizes.
    bsLabels = ["8k","4k","512"]

    def __init__(self,testname,device,options=None):
        '''
        Constructor.
        '''
        ## Keep user options
        self.__userOptions = options
        if options != None:
            #For latency the specification says to use 1 job/thread, 1 outstanding IO
            wsoptions = Options(1,1)
            if options.getXargs() != None:
                wsoptions.setXargs(options.getXargs())
        super(SsdLatencyTest,self).__init__(testname,device,wsoptions)
        ## A list of matrices with the collected fio measurement values of each round.
        self.__roundMatrices = []
        self.__stdyState = StdyState()
        self.getFioJob().addKVArg("rw","randrw")

    def getRndMatrices(self): return self.__roundMatrices
    def getStdyState(self): return self.__stdyState

    def toLog(self):
        '''
        Log information about the steady state and how it 
        has been reached.
        '''
        logging.info("Round matrices: ")
        logging.info(self.__roundMatrices)
        self.getStdyState().toLog()

    def testRound(self):
        '''
        Carry out one latency test round.
        The round consists of two inner loops: one iterating over the
        percentage of random reads/writes in the mixed workload, the other
        over different block sizes.
        @return A matrix containing [min,max,mean] latencies of the round.
        '''
        jobOut = ''
        rndMatrix = []        
        for i in SsdLatencyTest.mixWlds:
            rwRow = []
            for j in SsdLatencyTest.bsLabels:
                self.getFioJob().addKVArg("rwmixread",str(i))
                self.getFioJob().addKVArg("bs",j)
                call,jobOut = self.getFioJob().start()
                if call == False:
                    exit(1)
                logging.info("mixLoad: " +str(i))
                logging.info("bs: "+j)
                logging.info(jobOut)
                logging.info("######")
                if i == 65:
                    #if we have a mixed workload weight the latencies
                    l = [0,0,0]
                    r = self.getFioJob().getReadLats(jobOut)
                    w = self.getFioJob().getWriteLats(jobOut)
                    #FIXME Is this also correct for Min and Max?
                    l[0] = (0.65 * r[0]) + (0.35 * w[0])
                    l[1] = (0.65 * r[1]) + (0.35 * w[1])
                    l[2] = (0.65 * r[2]) + (0.35 * w[2])
                else:
                    l = self.getFioJob().getTotLats(jobOut)
                rwRow.append(l)
            rndMatrix.append(rwRow)
        return rndMatrix

    def runRounds(self):
        '''
        Carry out the latency test rounds and check if the steady state is reached.
        For a maximum of 25 rounds the test loop is carried out. After each
        test round we check for a measurement window of the last 5 rounds if
        the steady state has been reached.
        @return True if the steady state has been reached, False if not.
        '''
        rndMatrix = []
        steadyValues = deque([])
        xranges = deque([])#Rounds of current measurement window
        
        for i in range(StdyState.testRnds):
            logging.info("#################")
            logging.info("Round nr. "+str(i))
            rndMatrix = self.testRound()
            self.getRndMatrices().append(rndMatrix)
            #Latencies always consist of [min,max,mean] latency
            #Take mean/average for steady state detection
            steadyValues.append(rndMatrix[-1][-2][2])
            xranges.append(i)
            if i > 4:
                xranges.popleft()
                steadyValues.popleft()
            #check if the steady state has been reached in the last 5 rounds
            if i >= 4:
                steadyState = self.getStdyState().checkSteadyState(xranges,steadyValues,i)
                if steadyState == True:
                    break
        #Return current steady state
        return self.getStdyState().isSteady()

    def run(self):
        '''
        Start the rounds, log the steady state infos.
        @return True if all tests were run
        '''
        try: 
            self.getDevice().secureErase()
        except RuntimeError:
            logging.error("# Could not carry out secure erase for "+self.getDevice().getDevPath())
            raise
        try:
            if self.__userOptions == None:
                self.getDevice().precondition(1,1)
            else:
                if self.__userOptions.getNj() != None:
                    nj = self.__userOptions.getNj()
                if self.__userOptions.getIod() != None:
                    iod = self.__userOptions.getIod()
                self.getDevice().precondition(nj,iod)
        except RuntimeError:
            logging.error("# Could not carry out preconditioning for "+self.getDevice().getDevPath())
            raise
        logging.info("########### Starting Latency Test ###########")
        steadyState = self.runRounds()
        if steadyState == False:
            logging.info("# Steady State has not been reached for Latency Test.")
        self.toLog()
        return True

    def toXml(self,root):
        '''
        Get the Xml representation of the test.
        @param root Name of the new root Xml node
        @return An xml root element containing the information about the test
        ''' 
        r = etree.Element(root)
        # Add Fio version to xml
        self.getFioJob().appendXml(r)
        # Add the options to xml
        self.getOptions().appendXml(r)
        data = json.dumps(self.__roundMatrices)
        e = etree.SubElement(r,'roundmat')
        e.text = data
        self.getStdyState().appendXml(r)
        return r

    def fromXml(self,root):
        '''
        Load and set from an XML representation of a test.
        @param root Name of root element from which to load values
        '''
        logging.info("########### Loading latency test from "+self.getTestname()+".xml ###########")
        self.__roundMatrices = json.loads(root.findtext('roundmat'))
        self.__stdyState.fromXml(root)
        self.getFioJob().fromXml(root)
        self.getOptions().fromXml(root)
        self.toLog()

    def genPlots(self):
        ''' Generate plots for latency. '''
        import plots.genPlots as pgp
        pgp.stdyStConvPlt(self,"LAT")
        pgp.stdyStVerPlt(self,"LAT")
        pgp.mes2DPlt(self,"avg-LAT")
        pgp.mes2DPlt(self,"max-LAT")
        pgp.latMes3DPlt(self)
コード例 #14
0
ファイル: DeviceTests.py プロジェクト: Fateast/TKperf
class SsdIopsTest(DeviceTest):
    '''
    Representing an IOPS test for a ssd based device.
    '''
    ##Labels of block sizes
    bsLabels = ["1024k","128k","64k","32k","16k","8k","4k","512"]
    ##Percentages of mixed workloads
    mixWlds = [100,95,65,50,35,5,0]

    def __init__(self,testname,device,options=None):
        '''
        Constructor.
        '''
        super(SsdIopsTest,self).__init__(testname,device,options)
        ## A list of matrices with the collected fio measurement values of each round.
        self.__roundMatrices = []
        self.__stdyState = StdyState()
        self.getFioJob().addKVArg("rw","randrw")

    def getRndMatrices(self): return self.__roundMatrices
    def getStdyState(self): return self.__stdyState

    def toLog(self):
        '''
        Log information about the steady state and how it 
        has been reached.
        '''
        logging.info("Round matrices: ")
        logging.info(self.__roundMatrices)
        self.getStdyState().toLog()

    def testRound(self):
        '''
        Carry out one IOPS test round.
        The round consists of two inner loops: one iterating over the
        percentage of random reads/writes in the mixed workload, the other
        over different block sizes.
        @return A matrix containing the sum of average IOPS.
        '''
        jobOut = '' #Fio job output
        rndMatrix = []
        for i in SsdIopsTest.mixWlds:
            rwRow = []
            for j in SsdIopsTest.bsLabels:
                self.getFioJob().addKVArg("rwmixread",str(i))
                self.getFioJob().addKVArg("bs",j)
                call,jobOut = self.getFioJob().start()
                if call == False:
                    exit(1)
                logging.info("mixLoad: " +str(i))
                logging.info("bs: "+j)
                logging.info(jobOut)
                logging.info("######")
                rwRow.append(self.getFioJob().getIOPS(jobOut))
            rndMatrix.append(rwRow)
        return rndMatrix

    def runRounds(self):
        '''
        Carry out the IOPS test rounds and check if the steady state is reached.
        For a maximum of 25 rounds the test loop is carried out. After each
        test round we check for a measurement window of the last 5 rounds if
        the steady state has been reached.
        @return True if the steady state has been reached, False if not.
        '''
        rndMatrix = []
        steadyValues = deque([])#List of 4k random writes IOPS
        xranges = deque([])#Rounds of current measurement window
        
        for i in range(StdyState.testRnds):
            logging.info("#################")
            logging.info("Round nr. "+str(i))
            rndMatrix = self.testRound()
            self.getRndMatrices().append(rndMatrix)
            # Use the last row and its next to last value
            #-> 0/100% r/w and 4k for steady state detection
            steadyValues.append(rndMatrix[-1][-2])
            xranges.append(i)
            if i > 4:
                xranges.popleft()
                steadyValues.popleft()
            #check if the steady state has been reached in the last 5 rounds
            if i >= 4:
                steadyState = self.getStdyState().checkSteadyState(xranges,steadyValues,i)
                if steadyState == True:
                    break
        #Return current steady state
        return self.getStdyState().isSteady()

    def run(self):
        '''
        Start the rounds, log the steady state infos.
        @return True if all tests were run
        '''
        try: 
            self.getDevice().secureErase()
        except RuntimeError:
            logging.error("# Could not carry out secure erase for "+self.getDevice().getDevPath())
            raise
        try:
            if self.getOptions() == None:
                self.getDevice().precondition(1,1)
            else:
                if self.getOptions().getNj() != None:
                    nj = self.getOptions().getNj()
                if self.getOptions().getIod() != None:
                    iod = self.getOptions().getIod()
                self.getDevice().precondition(nj,iod)
        except RuntimeError:
            logging.error("# Could not carry out preconditioning for "+self.getDevice().getDevPath())
            raise
        logging.info("########### Starting IOPS Test ###########")
        steadyState = self.runRounds()
        if steadyState == False:
            logging.info("# Steady State has not been reached for IOPS Test.")
        self.toLog()
        return True

    def toXml(self,root):
        '''
        Get the Xml representation of the test.
        @param root Name of the new root Xml node
        @return An xml root element containing the information about the test
        ''' 
        r = etree.Element(root)
        # Add Fio version to xml
        self.getFioJob().appendXml(r)
        # Add the options to xml
        self.getOptions().appendXml(r)
        data = json.dumps(self.__roundMatrices)
        e = etree.SubElement(r,'roundmat')
        e.text = data
        self.getStdyState().appendXml(r)
        return r

    def fromXml(self,root):
        '''
        Load and set from an XML representation of a test.
        @param root Name of root element from which to load values
        '''
        logging.info("########### Loading IOPS test from "+self.getTestname()+".xml ###########")
        self.__roundMatrices = json.loads(root.findtext('roundmat'))
        self.__stdyState.fromXml(root)
        self.getFioJob().fromXml(root)
        self.getOptions().fromXml(root)
        self.toLog()

    def genPlots(self):
        ''' Generate plots for IOPS. '''
        import plots.genPlots as pgp
        pgp.stdyStConvPlt(self,"IOPS")
        pgp.stdyStVerPlt(self,"IOPS")
        pgp.mes2DPlt(self,"IOPS")
        pgp.mes3DPlt(self,"IOPS")