github.com/yrj2011/jx-test-infra@v0.0.0-20190529031832-7a2065ee98eb/experiment/parse_build_log.py (about)

     1  #!/usr/bin/python
     2  
     3  # Copyright 2018 The Kubernetes Authors.
     4  #
     5  # Licensed under the Apache License, Version 2.0 (the "License");
     6  # you may not use this file except in compliance with the License.
     7  # You may obtain a copy of the License at
     8  #
     9  #     http://www.apache.org/licenses/LICENSE-2.0
    10  #
    11  # Unless required by applicable law or agreed to in writing, software
    12  # distributed under the License is distributed on an "AS IS" BASIS,
    13  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    14  # See the License for the specific language governing permissions and
    15  # limitations under the License.
    16  
    17  """Parser for e2e test logs.
    18  
    19  Useful for finding which tests overlapped with a certain event.
    20  """
    21  
    22  import argparse
    23  import datetime
    24  import re
    25  
    26  
    27  _LINE_RE = re.compile(r'^[IWE]111[45] \d\d:\d\d:\d\d\.\d\d\d\] ?(.*)')
    28  _DATE_FORMAT = '%Y-%m-%d %H:%M:%S'
    29  _CURRENT_YEAR = datetime.datetime.utcnow().year
    30  
    31  
    32  class TestOutput(object):
    33      def __init__(self):
    34          self._lines = []
    35          self._start = None
    36          self._end = None
    37          self._it = None
    38  
    39      def append(self, line):
    40          self._lines.append(line)
    41          try:
    42              timestamp = datetime.datetime.strptime(line[:19], '%b %d %H:%M:%S.%f').replace(
    43                  year=_CURRENT_YEAR)
    44          except:  # pylint: disable=bare-except
    45              pass
    46          else:
    47              if not self._start:
    48                  self._start = timestamp
    49              self._end = timestamp
    50          if line.startswith('[It] '):
    51              self._it = line
    52          if line.startswith('[BeforeEach] ') and not self._it:
    53              self._it = line
    54  
    55      def overlaps(self, after, before):
    56          if self._end and after and self._end < after:
    57              return False
    58          if self._start and before and self._start > before:
    59              return False
    60          return True
    61  
    62      def __len__(self):
    63          return len(self._lines)
    64  
    65      def __str__(self):
    66          if not self._lines:
    67              return '<empty>'
    68          return 'Test %s->%s (%5d lines) %s' % (
    69              self._start, self._end, len(self), self._it if self._it else '')
    70  
    71  
    72  def _get_tests(log):
    73      current_test = TestOutput()
    74      for line in log:
    75          line = line.rstrip()
    76          match = _LINE_RE.match(line)
    77          if not match:
    78              raise Exception('line %s does not match' % line)
    79          if '------------------------------' in line:
    80              ended_test = current_test
    81              current_test = TestOutput()
    82              if len(ended_test) <= 1:
    83                  continue
    84              else:
    85                  yield ended_test
    86          else:
    87              current_test.append(match.group(1))
    88      yield current_test
    89  
    90  
    91  def main():
    92      parser = argparse.ArgumentParser(description=__doc__)
    93      parser.add_argument('--log_year', default=_CURRENT_YEAR,
    94                          help=('Year in which the log was created. '
    95                                'Needed because the year is omitted in the log.'))
    96      parser.add_argument('--after',
    97                          help=('Show tests which ended at or after this time '
    98                                '(format: %s).' % _DATE_FORMAT.replace('%', '%%')))
    99      parser.add_argument('--before',
   100                          help=('Show tests which started at or before this time '
   101                                '(format: %s).' % _DATE_FORMAT.replace('%', '%%')))
   102      parser.add_argument('file')
   103  
   104      args = parser.parse_args()
   105      after = datetime.datetime.strptime(args.after, _DATE_FORMAT) if args.after else None
   106      before = datetime.datetime.strptime(args.before, _DATE_FORMAT) if args.before else None
   107      if after and before and after.year != before.year:
   108          raise Exception('Logs spanning year boundary are not supported.')
   109      if not args.log_year and (after or before):
   110          year = after.year if after else before.year
   111          if year != _CURRENT_YEAR:
   112              raise Exception('Please explicitly specify the year in which the log was created.')
   113      with open(args.file) as log:
   114          for test in _get_tests(log):
   115              if test.overlaps(after, before):
   116                  print str(test)
   117  
   118  
   119  if __name__ == '__main__':
   120      main()