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 |