import os, re
from autotest_lib.client.bin import test, utils
from autotest_lib.client.common_lib import error


class unixbench(test.test):
    version = 2

    def initialize(self):
        self.job.require_gcc()
        self.err = None


    # http://www.tux.org/pub/tux/niemi/unixbench/unixbench-4.1.0.tgz
    def setup(self, tarball = 'unixbench-4.1.0.tar.bz2'):
        tarball = utils.unmap_url(self.bindir, tarball, self.tmpdir)
        utils.extract_tarball_to_dir(tarball, self.srcdir)
        os.chdir(self.srcdir)

        utils.system('patch -p1 < ../unixbench.patch')
        utils.system('patch -p1 < ../Makefile.patch')
        utils.make()
        utils.system('rm pgms/select')


    def run_once(self, args='', stepsecs=0):
        vars = ('TMPDIR=\"%s\" RESULTDIR=\"%s\" FLAVOR=Linux' %
               (self.tmpdir, self.resultsdir))
        if stepsecs:
            # change time per subtest from unixbench's defaults of
            #   10 secs for small tests, 30 secs for bigger tests
            vars += ' systime=%i looper=%i seconds=%i'\
                    ' dhrytime=%i arithtime=%i' \
                    % ((stepsecs,)*5)

        os.chdir(self.srcdir)
        try:
            utils.system(vars + ' ./Run ' + args)
        finally:
            times_path = os.path.join(self.resultsdir, 'times')
            # The 'times' file can be needlessly huge as it contains warnings
            # and error messages printed out by small benchmarks that are
            # run in a loop.  It can easily compress 100x in such cases.
            if os.path.exists(times_path):
                utils.system("gzip -9 '%s'" % (times_path,), ignore_status=True)

        report_path = os.path.join(self.resultsdir, 'report')
        self.report_data = open(report_path).readlines()[9:]


    def cleanup(self):
        # check err string and possible throw
        if self.err is not None:
            raise error.TestError(self.err)


    def check_for_error(self, words):
        l = len(words)
        if l >= 3 and words[-3:l] == ['no', 'measured', 'results']:
            # found a problem so record it in err string
            key = '_'.join(words[:-3])
            if self.err is None:
                self.err = key
            else:
                self.err = self.err + " " + key
            return True
        else:
            return False


    def postprocess_iteration(self):
        keyval = {}
        for line in self.report_data:
            if not line.strip():
                break

            words = line.split()
            # look for problems first
            if self.check_for_error(words):
                continue

            # we should make sure that there are at least
            # 6 guys before we start accessing the array
            if len(words) >= 6:
                key = '_'.join(words[:-6])
                key = re.sub('\W', '', key)
                value = words[-6]
                keyval[key] = value
        for line in self.report_data:
            if 'FINAL SCORE' in line:
                keyval['score'] = line.split()[-1]
                break
        self.write_perf_keyval(keyval)


""" Here is a sample report file:

  BYTE UNIX Benchmarks (Version 4.1.0)
  System -- Linux adrianbg 2.6.18.5 #1 SMP Thu J  Start Benchmark Run: Tue Sep 1
   9 interactive users.
   21:03:50 up 5 days,  7:38,  9 users,  load average: 0.71, 0.40, 0.25
  lrwxrwxrwx 1 root root 4 Aug 15 09:53 /bin/sh -> bash
  /bin/sh: symbolic link to `bash'
  /dev/sda6            192149596  91964372  90424536  51% /home
Dhrystone 2 using register variables     7918001.7 lps   (10.0 secs, 10 samples)
System Call Overhead                     1427272.7 lps   (10.0 secs, 10 samples)
Process Creation                          11508.6 lps   (30.0 secs, 3 samples)
Execl Throughput                           4159.7 lps   (29.7 secs, 3 samples)
File Read 1024 bufsize 2000 maxblocks    1708109.0 KBps  (30.0 secs, 3 samples)
File Write 1024 bufsize 2000 maxblocks   788024.0 KBps  (30.0 secs, 3 samples)
File Copy 1024 bufsize 2000 maxblocks    452986.0 KBps  (30.0 secs, 3 samples)
File Read 256 bufsize 500 maxblocks      508752.0 KBps  (30.0 secs, 3 samples)
File Write 256 bufsize 500 maxblocks     214772.0 KBps  (30.0 secs, 3 samples)
File Copy 256 bufsize 500 maxblocks      143989.0 KBps  (30.0 secs, 3 samples)
File Read 4096 bufsize 8000 maxblocks    2626923.0 KBps  (30.0 secs, 3 samples)
File Write 4096 bufsize 8000 maxblocks   1175070.0 KBps  (30.0 secs, 3 samples)
File Copy 4096 bufsize 8000 maxblocks    793041.0 KBps  (30.0 secs, 3 samples)
Shell Scripts (1 concurrent)               4417.4 lpm   (60.0 secs, 3 samples)
Shell Scripts (8 concurrent)               1109.0 lpm   (60.0 secs, 3 samples)
Shell Scripts (16 concurrent)               578.3 lpm   (60.0 secs, 3 samples)
Arithmetic Test (type = short)           1843690.0 lps   (10.0 secs, 3 samples)
Arithmetic Test (type = int)             1873615.8 lps   (10.0 secs, 3 samples)
Arithmetic Test (type = long)            1888345.9 lps   (10.0 secs, 3 samples)
Arithmetic Test (type = float)           616260.3 lps   (10.0 secs, 3 samples)
Arithmetic Test (type = double)          615942.1 lps   (10.0 secs, 3 samples)
Arithoh                                  18864899.5 lps   (10.0 secs, 3 samples)
Dc: sqrt(2) to 99 decimal places         161726.0 lpm   (30.0 secs, 3 samples)
Recursion Test--Tower of Hanoi            89229.3 lps   (20.0 secs, 3 samples)


                     INDEX VALUES
TEST                                        BASELINE     RESULT      INDEX

Dhrystone 2 using register variables        116700.0  7918001.7      678.5
Double-Precision Whetstone                      55.0     1948.2      354.2
Execl Throughput                                43.0     4159.7      967.4
File Copy 1024 bufsize 2000 maxblocks         3960.0   452986.0     1143.9
File Copy 256 bufsize 500 maxblocks           1655.0   143989.0      870.0
File Copy 4096 bufsize 8000 maxblocks         5800.0   793041.0     1367.3
Pipe Throughput                              12440.0  1048491.9      842.8
Pipe-based Context Switching                  4000.0   300778.3      751.9
Process Creation                               126.0    11508.6      913.4
Shell Scripts (8 concurrent)                     6.0     1109.0     1848.3
System Call Overhead                         15000.0  1427272.7      951.5
                                                                 =========
     FINAL SCORE                                                     902.1
"""
