#!/usr/bin/python
#
# Copyright (c) 2012 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

import logging
import os
import re
import tempfile

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

class kernel_PerfEventRename(test.test):
    """
    Test perf's ability to deal with processes which have changed their name
    after perf record starts.  Older versions of perf lost their data about
    which executables or libraries were mapped so all the samples would end
    up being called unknown and this would make the profiles useless.

    Good output:
        97.43%        149  foobar_name  perf-rename-test   [.] 0x000006f8
    Bad output:
        96.54%        140  foobar_name  [unknown]          [.] 0x777046f3
    """
    version = 1
    executable = 'perf-rename-test'

    # This runs during the build process
    def setup(self):
        os.chdir(self.srcdir)
        utils.make(self.executable)

    def run_once(self):
        # the rename program runs a crc loop for a while to ensure that we get
        # a good number of samples
        loops = 10 * 1000 * 1000
        rename_name = 'foobar_name'
        (data_tmpfile, data_name) = tempfile.mkstemp(
            prefix='perfEventRename_data.', dir='/tmp')

        utils.system('perf record -o %s %s %s %s' %
                     (data_name, os.path.join(self.srcdir,
                                              self.executable),
                      rename_name, loops),
                     timeout=60)
        report = utils.system_output('perf report -n -i %s' % (data_name))
        logging.debug('report output: %s' % report)
        os.unlink(data_name)

        for line in report.splitlines():
            # The first several lines of output should be comments with '#'
            if re.match('^#', line):
                continue

            stuff = line.split()
            # there's a slight risk that we might get an unknown sample
            # somewhere in the mix, and I've seen this more often on some
            # platforms where there is high "skid" or imprecision.
            # So we'll mitigate that by only checking the first line after
            # the comments, which should be in the crc loop and the majority
            # of samples
            if stuff[3] == '[unknown]':
                logging.info('bad report entry: %s' % line)
                raise error.TestFail
            else:
                return True