Home | History | Annotate | Download | only in platform_TraceClockMonotonic
      1 #!/usr/bin/python
      2 #
      3 # Copyright (c) 2015 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 
      7 import os
      8 
      9 from autotest_lib.client.bin import test, utils
     10 from autotest_lib.client.common_lib import error
     11 
     12 
     13 class platform_TraceClockMonotonic(test.test):
     14     """
     15     This verifies that the kernel supports monotonic clock timestamps for
     16     ftrace events.  This is the same clock that Chrome will use for
     17     timestamping its trace events.
     18     """
     19     version = 1
     20 
     21     executable = 'ftrace-clock-monotonic'
     22 
     23     TRACE_PATH = '/sys/kernel/debug/tracing/'
     24     TRACE_CLOCK = TRACE_PATH + 'trace_clock'
     25     TRACE_FILE = TRACE_PATH + 'trace'
     26     TRACE_ENABLE = TRACE_PATH + 'tracing_on'
     27 
     28     def _setup_trace(self):
     29         """
     30         Verify that the system supports the monotonic trace clock and set up
     31         the trace system to use it, and clean up any old stuff in the trace
     32         and enable it.
     33         """
     34         with open(self.TRACE_CLOCK, 'r+') as clock:
     35             content = clock.read()
     36             if not 'mono' in content:
     37                 raise error.TestFail('Kernel does not support monotonic clock')
     38 
     39             # Set up to use the monotonic clock
     40             clock.write('mono')
     41 
     42         # clear out the trace
     43         with open(self.TRACE_FILE, 'w') as trace:
     44             trace.write('')
     45 
     46         # enable tracing
     47         with open(self.TRACE_ENABLE, 'w') as enable:
     48             enable.write('1')
     49 
     50     def setup(self):
     51         """Cleans and makes ftrace-clock-monotonic.c.
     52 
     53         Prepares environment for tests by removing directory we will extract
     54         to (if it exists), extracting tarball of tests, and making them.
     55         """
     56         os.chdir(self.srcdir)
     57         utils.make('clean')
     58         utils.make()
     59 
     60     def process_trace(self):
     61         """Opens the trace file and processes it.
     62 
     63         Looks for the 3 markers that are written out by the binary.  The binary
     64         gets a clock timestamp and then writes it out into the trace three times.
     65         This looks at each entry and the content of the entry, and verifies that
     66         they are all in chronological order.
     67         Example trace file without the header:
     68            <...>-16484 [003] ...1 509651.512676: tracing_mark_write: start: 509651.512651785
     69            <...>-16484 [003] ...1 509651.512680: tracing_mark_write: middle: 509651.512678312
     70            <...>-16484 [003] ...1 509651.512682: tracing_mark_write: end: 509651.512680934
     71         """
     72         with open(self.TRACE_FILE, 'r') as trace:
     73             prev_timestamp = 0
     74             for line in trace:
     75                 if 'tracing_mark_write' not in line:
     76                     continue
     77 
     78                 columns = line.split()
     79                 entry_timestamp = float(columns[3].replace(':',''))
     80                 sample_timestamp = float(columns[6])
     81                 if sample_timestamp > entry_timestamp:
     82                     raise error.TestFail('sample timestamp after trace marker entry')
     83 
     84                 if sample_timestamp < prev_timestamp:
     85                     raise error.TestFail('sample timestamp before previous timestamp')
     86                 prev_timestamp = entry_timestamp
     87 
     88             if prev_timestamp == 0:
     89                 raise error.TestFail('no valid timestamps seen in trace file')
     90 
     91     def run_once(self):
     92         self._setup_trace()
     93         binpath = os.path.join(self.srcdir, self.executable)
     94         utils.system_output(binpath, retain_output = True)
     95         self.process_trace()
     96