import os, re
from autotest_lib.client.bin import test, utils
import postprocessing


class iozone(test.test):
    """
    This autotest module runs the IOzone filesystem benchmark. The benchmark
    generates and measures a variety of file operations. Iozone has been ported
    to many machines and runs under many operating systems.

    Iozone is useful for performing a broad filesystem analysis of a vendor's
    computer platform. The benchmark tests file I/O performance for the
    following operations:

    Read, write, re-read, re-write, read backwards, read strided, fread, fwrite,
    random read, pread ,mmap, aio_read, aio_write

    @author: Ying Tao (yingtao@cn.ibm.com)
    @see: http://www.iozone.org
    """
    version = 3

    def initialize(self):
        self.job.require_gcc()


    def setup(self, tarball='iozone3_347.tar'):
        """
        Builds the given version of IOzone from a tarball.
        @param tarball: Tarball with IOzone
        @see: http://www.iozone.org/src/current/iozone3_347.tar
        """
        tarball = utils.unmap_url(self.bindir, tarball, self.tmpdir)
        utils.extract_tarball_to_dir(tarball, self.srcdir)
        os.chdir(os.path.join(self.srcdir, 'src/current'))
        utils.system('patch -p3 < ../../../makefile.patch')
        utils.system('patch -p3 < ../../../clang_fortify.patch')

        ctarget = os.getenv('CTARGET_default')

        if (ctarget == 'armv7a-cros-linux-gnueabihf'):
            utils.make('linux-arm')
        elif (ctarget == 'i686-pc-linux-gnu'):
            utils.make('linux')
        elif (ctarget == 'x86_64-cros-linux-gnu'):
            utils.make('linux-AMD64')
        else:
            utils.make('linux')

    def run_once(self, dir=None, args=None):
        """
        Runs IOzone with appropriate parameters, record raw results in a per
        iteration raw output file as well as in the results attribute

        @param dir: IOzone file generation dir.
        @param args: Arguments to the iozone program.
        """
        if not dir:
            dir = self.tmpdir
        os.chdir(dir)
        if not args:
            args = '-a'

        cmd = os.path.join(self.srcdir, 'src', 'current', 'iozone')
        self.results = utils.system_output('%s %s' % (cmd, args))
        self.auto_mode = ("-a" in args)

        self.results_path = os.path.join(self.resultsdir,
                                         'raw_output_%s' % self.iteration)
        self.analysisdir = os.path.join(self.resultsdir,
                                        'analysis_%s' % self.iteration)

        utils.open_write_close(self.results_path, self.results)


    def __get_section_name(self, desc):
        return desc.strip().replace(' ', '_')


    def generate_keyval(self):
        """
        Generates a keylist.
        """
        keylist = {}

        if self.auto_mode:
            labels = ('write', 'rewrite', 'read', 'reread', 'randread',
                      'randwrite', 'bkwdread', 'recordrewrite',
                      'strideread', 'fwrite', 'frewrite', 'fread', 'freread')
            for line in self.results.splitlines():
                fields = line.split()
                if len(fields) != 15:
                    continue
                try:
                    fields = tuple([int(i) for i in fields])
                except ValueError:
                    continue
                for l, v in zip(labels, fields[2:]):
                    key_name = "%d-%d-%s" % (fields[0], fields[1], l)
                    keylist[key_name] = v
        else:
            child_regexp  = re.compile('Children see throughput for[\s]+'
                            '([\d]+)\s+([-\w]+[-\w\s]*)\=[\s]+([\d\.]*) KB/sec')
            parent_regexp = re.compile('Parent sees throughput for[\s]+'
                            '([\d]+)\s+([-\w]+[-\w\s]*)\=[\s]+([\d\.]*) KB/sec')

            KBsec_regexp  = re.compile('\=[\s]+([\d\.]*) KB/sec')
            KBval_regexp  = re.compile('\=[\s]+([\d\.]*) KB')

            section = None
            w_count = 0

            for line in self.results.splitlines():
                line = line.strip()

                # Check for the beginning of a new result section
                match = child_regexp.search(line)
                if match:
                    # Extract the section name and the worker count
                    w_count = int(match.group(1))
                    section = self.__get_section_name(match.group(2))

                    # Output the appropriate keyval pair
                    key_name = '%s-%d-kids' % (section, w_count)
                    keylist[key_name] = match.group(3)
                    continue

                # Check for any other interesting lines
                if '=' in line:
                    # Is it something we recognize? First check for parent.
                    match = parent_regexp.search(line)
                    if match:
                        # The section name and the worker count better match
                        p_count = int(match.group(1))
                        p_secnt = self.__get_section_name(match.group(2))
                        if p_secnt != section or p_count != w_count:
                            continue

                        # Set the base name for the keyval
                        basekey = 'parent'
                    else:
                        # Check for the various 'throughput' values
                        if line[3:26] == ' throughput per thread ':
                            basekey = line[0:3]
                            match_x = KBsec_regexp
                        else:
                            # The only other thing we expect is 'Min xfer'
                            if not line.startswith('Min xfer '):
                                continue
                            basekey = 'MinXfer'
                            match_x = KBval_regexp

                        match = match_x.search(line)
                        if match:
                            result = match.group(1)
                            key_name = "%s-%d-%s" % (section, w_count, basekey)
                            keylist[key_name] = result

        self.write_perf_keyval(keylist)


    def postprocess_iteration(self):
        self.generate_keyval()
        if self.auto_mode:
            a = postprocessing.IOzoneAnalyzer(list_files=[self.results_path],
                                              output_dir=self.analysisdir)
            a.analyze()
            p = postprocessing.IOzonePlotter(results_file=self.results_path,
                                             output_dir=self.analysisdir)
            p.plot_all()
