OLD | NEW |
1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
2 # Copyright 2014 The Swarming Authors. All rights reserved. | 2 # Copyright 2014 The Swarming Authors. All rights reserved. |
3 # Use of this source code is governed by the Apache v2.0 license that can be | 3 # Use of this source code is governed by the Apache v2.0 license that can be |
4 # found in the LICENSE file. | 4 # found in the LICENSE file. |
5 | 5 |
6 """Tools to control application running via dev_appserver.py. | 6 """Tools to control application running via dev_appserver.py. |
7 | 7 |
8 Useful for smoke and integration tests. | 8 Useful for smoke and integration tests. |
9 """ | 9 """ |
10 | 10 |
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
174 break | 174 break |
175 time.sleep(0.05) | 175 time.sleep(0.05) |
176 if not alive: | 176 if not alive: |
177 logging.error('Service %s did\'t come online', self.app_id) | 177 logging.error('Service %s did\'t come online', self.app_id) |
178 self.stop() | 178 self.stop() |
179 self.dump_log() | 179 self.dump_log() |
180 raise Exception('Failed to start %s' % self.app_id) | 180 raise Exception('Failed to start %s' % self.app_id) |
181 logging.info('Service %s is ready.', self.app_id) | 181 logging.info('Service %s is ready.', self.app_id) |
182 self._serving = True | 182 self._serving = True |
183 | 183 |
184 def stop(self): | 184 def stop(self, leak=False): |
185 """Stops dev_appserver, collects its log. | 185 """Stops dev_appserver, collects its log. |
186 | 186 |
187 Returns the process error code if applicable. | 187 Returns the process error code if applicable. |
188 """ | 188 """ |
189 if not self._proc: | 189 if not self._proc: |
190 return None | 190 return None |
191 exit_code = self._proc.poll() | 191 exit_code = self._proc.poll() |
192 try: | 192 try: |
193 logging.info('Stopping %s', self.app_id) | 193 logging.info('Stopping %s', self.app_id) |
194 if self._proc.poll() is None: | 194 if self._proc.poll() is None: |
195 try: | 195 try: |
196 # Send SIGTERM. | 196 # Send SIGTERM. |
197 self._proc.terminate() | 197 self._proc.terminate() |
198 except OSError: | 198 except OSError: |
199 pass | 199 pass |
200 deadline = time.time() + 5 | 200 deadline = time.time() + 5 |
201 while self._proc.poll() is None and time.time() < deadline: | 201 while self._proc.poll() is None and time.time() < deadline: |
202 time.sleep(0.05) | 202 time.sleep(0.05) |
203 exit_code = self._proc.poll() | 203 exit_code = self._proc.poll() |
204 if exit_code is None: | 204 if exit_code is None: |
205 logging.error('Leaking PID %d', self._proc.pid) | 205 logging.error('Leaking PID %d', self._proc.pid) |
206 finally: | 206 finally: |
207 with open(os.path.join(self._temp_root, 'dev_appserver.log'), 'r') as f: | 207 with open(os.path.join(self._temp_root, 'dev_appserver.log'), 'r') as f: |
208 self._log = f.read() | 208 self._log = f.read() |
209 try: | 209 if not leak: |
210 shutil.rmtree(self._temp_root) | 210 try: |
211 except OSError as e: | 211 shutil.rmtree(self._temp_root) |
212 # Log but ignore it to not mask other errors. | 212 except OSError as e: |
213 print >> sys.stderr, str(e) | 213 # Log but ignore it to not mask other errors. |
| 214 print >> sys.stderr, str(e) |
214 self._client = None | 215 self._client = None |
215 self._port = None | 216 self._port = None |
216 self._proc = None | 217 self._proc = None |
217 self._serving = False | 218 self._serving = False |
218 self._temp_root = None | 219 self._temp_root = None |
219 return exit_code | 220 return exit_code |
220 | 221 |
221 def wait(self): | 222 def wait(self): |
222 """Waits for the process to exit.""" | 223 """Waits for the process to exit.""" |
223 self._proc.wait() | 224 self._proc.wait() |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
292 | 293 |
293 It only works with apps that use 'auth' component. | 294 It only works with apps that use 'auth' component. |
294 """ | 295 """ |
295 if self._xsrf_token is None: | 296 if self._xsrf_token is None: |
296 resp = self.json_request( | 297 resp = self.json_request( |
297 '/auth/api/v1/accounts/self/xsrf_token', | 298 '/auth/api/v1/accounts/self/xsrf_token', |
298 body={}, | 299 body={}, |
299 headers={'X-XSRF-Token-Request': '1'}) | 300 headers={'X-XSRF-Token-Request': '1'}) |
300 self._xsrf_token = resp.body['xsrf_token'].encode('ascii') | 301 self._xsrf_token = resp.body['xsrf_token'].encode('ascii') |
301 return self._xsrf_token | 302 return self._xsrf_token |
OLD | NEW |