| OLD | NEW |
| (Empty) |
| 1 # coding=utf8 | |
| 2 # Copyright (c) 2011 The Chromium Authors. All rights reserved. | |
| 3 # Use of this source code is governed by a BSD-style license that can be | |
| 4 # found in the LICENSE file. | |
| 5 """Runs presubmit check on the source tree.""" | |
| 6 | |
| 7 import logging | |
| 8 import os | |
| 9 import sys | |
| 10 import time | |
| 11 | |
| 12 from verification import base | |
| 13 | |
| 14 import find_depot_tools # pylint: disable=W0611 | |
| 15 import subprocess2 | |
| 16 | |
| 17 | |
| 18 class PresubmitCheckVerifier(base.VerifierCheckout): | |
| 19 name = 'presubmit' | |
| 20 | |
| 21 def __init__(self, context_obj, timeout=6*60): | |
| 22 super(PresubmitCheckVerifier, self).__init__(context_obj) | |
| 23 self.root_dir = os.path.dirname(os.path.abspath(__file__)) | |
| 24 self.execution_timeout = timeout | |
| 25 | |
| 26 def verify(self, pending): | |
| 27 """Runs the presubmit script synchronously. | |
| 28 | |
| 29 TODO(maruel): Now that it runs out of process, it should be run | |
| 30 asynchronously. That means that the PRESUBMIT checks needs to be better | |
| 31 written, if an integration tests starts a service, it needs to be able to | |
| 32 use an ephemeral port and not an hardcoded port. | |
| 33 """ | |
| 34 logging.info('Presubmit check for %s' % ','.join(pending.files)) | |
| 35 cmd = [ | |
| 36 sys.executable, | |
| 37 os.path.join(self.root_dir, 'presubmit_shim.py'), | |
| 38 '--commit', | |
| 39 '--author', str(pending.owner), | |
| 40 '--issue', str(pending.issue), | |
| 41 '--patchset', str(pending.patchset), | |
| 42 '--name', pending.pending_name(), | |
| 43 '--description', pending.description, | |
| 44 '--rietveld_url', self.context.rietveld.url, | |
| 45 ] | |
| 46 cmd.extend(pending.files) | |
| 47 start = time.time() | |
| 48 self.send_status(pending, {}) | |
| 49 | |
| 50 # Disable breakpad, no need to notify maintainers on internal crashes. | |
| 51 env = os.environ.copy() | |
| 52 env['NO_BREAKPAD'] = '1' | |
| 53 | |
| 54 try: | |
| 55 # Do not pass them through the command line. | |
| 56 data = '%s\n%s\n' % ( | |
| 57 self.context.rietveld.email, self.context.rietveld.password) | |
| 58 # Use check_output() so stdout is kept when an exception is thrown. | |
| 59 output = subprocess2.check_output( | |
| 60 cmd, | |
| 61 timeout=self.execution_timeout, | |
| 62 stderr=subprocess2.STDOUT, | |
| 63 stdin=data, | |
| 64 env=env, | |
| 65 preexec_fn=os.setpgrp) | |
| 66 pending.verifications[self.name] = base.SimpleStatus(state=base.SUCCEEDED) | |
| 67 self.send_status( | |
| 68 pending, | |
| 69 { | |
| 70 'duration': time.time() - start, | |
| 71 'output': output, | |
| 72 }) | |
| 73 except subprocess2.CalledProcessError as e: | |
| 74 output = ( | |
| 75 'Presubmit check for %s failed and returned exit status %s.\n') % ( | |
| 76 pending.pending_name(), e.returncode) | |
| 77 duration = time.time() - start | |
| 78 timed_out = duration > self.execution_timeout | |
| 79 if timed_out: | |
| 80 output += ( | |
| 81 'The presubmit check was hung. It took %2.1f seconds to execute ' | |
| 82 'and the time limit is %2.1f seconds.\n') % ( | |
| 83 duration, self.execution_timeout) | |
| 84 output += '\n%s' % e.stdout | |
| 85 pending.verifications[self.name] = base.SimpleStatus( | |
| 86 state=base.FAILED, error_message=output) | |
| 87 self.send_status( | |
| 88 pending, | |
| 89 { | |
| 90 'duration': duration, | |
| 91 'output': e.stdout, | |
| 92 'return': e.returncode, | |
| 93 'timed_out': timed_out, | |
| 94 }) | |
| 95 | |
| 96 def update_status(self, queue): | |
| 97 pass | |
| OLD | NEW |