1#!/usr/bin/python
2#
3# Copyright (c) 2012 The Chromium Authors. All rights reserved.
4# Use of this source code is governed by a BSD-style license that can be
5# found in the LICENSE file.
6
7import logging
8import os
9import re
10import tempfile
11
12from autotest_lib.client.bin import test, utils
13from autotest_lib.client.common_lib import error
14
15class kernel_PerfEventRename(test.test):
16    """
17    Test perf's ability to deal with processes which have changed their name
18    after perf record starts.  Older versions of perf lost their data about
19    which executables or libraries were mapped so all the samples would end
20    up being called unknown and this would make the profiles useless.
21
22    Good output:
23        97.43%        149  foobar_name  perf-rename-test   [.] 0x000006f8
24    Bad output:
25        96.54%        140  foobar_name  [unknown]          [.] 0x777046f3
26    """
27    version = 1
28    executable = 'perf-rename-test'
29
30    # This runs during the build process
31    def setup(self):
32        os.chdir(self.srcdir)
33        utils.make(self.executable)
34
35    def run_once(self):
36        # the rename program runs a crc loop for a while to ensure that we get
37        # a good number of samples
38        loops = 10 * 1000 * 1000
39        rename_name = 'foobar_name'
40        (data_tmpfile, data_name) = tempfile.mkstemp(
41            prefix='perfEventRename_data.', dir='/tmp')
42
43        utils.system('perf record -o %s %s %s %s' %
44                     (data_name, os.path.join(self.srcdir,
45                                              self.executable),
46                      rename_name, loops),
47                     timeout=60)
48        report = utils.system_output('perf report -n -i %s' % (data_name))
49        logging.debug('report output: %s' % report)
50        os.unlink(data_name)
51
52        for line in report.splitlines():
53            # The first several lines of output should be comments with '#'
54            if re.match('^#', line):
55                continue
56
57            stuff = line.split()
58            # there's a slight risk that we might get an unknown sample
59            # somewhere in the mix, and I've seen this more often on some
60            # platforms where there is high "skid" or imprecision.
61            # So we'll mitigate that by only checking the first line after
62            # the comments, which should be in the crc loop and the majority
63            # of samples
64            if stuff[3] == '[unknown]':
65                logging.info('bad report entry: %s' % line)
66                raise error.TestFail
67            else:
68                return True
69
70