| Index: chrome/test/kasko/py/kasko/crash_server.py
|
| diff --git a/chrome/test/kasko/py/kasko/crash_server.py b/chrome/test/kasko/py/kasko/crash_server.py
|
| deleted file mode 100755
|
| index 625531be105da1a546230a1d11bb79c96ba282f3..0000000000000000000000000000000000000000
|
| --- a/chrome/test/kasko/py/kasko/crash_server.py
|
| +++ /dev/null
|
| @@ -1,148 +0,0 @@
|
| -#!/usr/bin/env python
|
| -# Copyright 2016 The Chromium Authors. All rights reserved.
|
| -# Use of this source code is governed by a BSD-style license that can be
|
| -# found in the LICENSE file.
|
| -
|
| -"""Exceptions used by the Kasko integration test module."""
|
| -
|
| -import BaseHTTPServer
|
| -import cgi
|
| -import logging
|
| -import os
|
| -import socket
|
| -import threading
|
| -import time
|
| -import uuid
|
| -
|
| -
|
| -_LOGGER = logging.getLogger(os.path.basename(__file__))
|
| -
|
| -
|
| -class _StoppableHTTPServer(BaseHTTPServer.HTTPServer):
|
| - """An extension of BaseHTTPServer that uses timeouts and is interruptable."""
|
| -
|
| - def server_bind(self):
|
| - BaseHTTPServer.HTTPServer.server_bind(self)
|
| - self.socket.settimeout(1)
|
| - self.run_ = True
|
| -
|
| - def get_request(self):
|
| - while self.run_:
|
| - try:
|
| - sock, addr = self.socket.accept()
|
| - sock.settimeout(None)
|
| - return (sock, addr)
|
| - except socket.timeout:
|
| - pass
|
| -
|
| - def stop(self):
|
| - self.run_ = False
|
| -
|
| - def serve(self):
|
| - while self.run_:
|
| - self.handle_request()
|
| -
|
| -
|
| -class CrashServer(object):
|
| - """A simple crash server for testing."""
|
| -
|
| - def __init__(self):
|
| - self.server_ = None
|
| - self.lock_ = threading.Lock()
|
| - self.crashes_ = [] # Under lock_.
|
| -
|
| - def crash(self, index):
|
| - """Accessor for the list of crashes."""
|
| - with self.lock_:
|
| - if index >= len(self.crashes_):
|
| - return None
|
| - return self.crashes_[index]
|
| -
|
| - @property
|
| - def port(self):
|
| - """Returns the port associated with the server."""
|
| - if not self.server_:
|
| - return 0
|
| - return self.server_.server_port
|
| -
|
| - def start(self):
|
| - """Starts the server on another thread. Call from main thread only."""
|
| - page_handler = self.multipart_form_handler()
|
| - self.server_ = _StoppableHTTPServer(('127.0.0.1', 0), page_handler)
|
| - self.thread_ = self.server_thread()
|
| - self.thread_.start()
|
| -
|
| - def stop(self):
|
| - """Stops the running server. Call from main thread only."""
|
| - self.server_.stop()
|
| - self.thread_.join()
|
| - self.server_ = None
|
| - self.thread_ = None
|
| -
|
| - def wait_for_report(self, timeout):
|
| - """Waits until the server has received a crash report.
|
| -
|
| - Returns True if the a report has been received in the given time, or False
|
| - if a timeout occurred. Since Python condition variables have no notion of
|
| - timeout this is, sadly, a busy loop on the calling thread.
|
| - """
|
| - started = time.time()
|
| - elapsed = 0
|
| - while elapsed < timeout:
|
| - with self.lock_:
|
| - if len(self.crashes_):
|
| - return True
|
| - time.sleep(0.1)
|
| - elapsed = time.time() - started
|
| -
|
| - return False
|
| -
|
| -
|
| - def multipart_form_handler(crash_server):
|
| - """Returns a multi-part form handler class for use with a BaseHTTPServer."""
|
| -
|
| - class MultipartFormHandler(BaseHTTPServer.BaseHTTPRequestHandler):
|
| - """A multi-part form handler that processes crash reports.
|
| -
|
| - This class only handles multipart form POST messages, with all other
|
| - requests by default returning a '501 not implemented' error.
|
| - """
|
| -
|
| - def __init__(self, request, client_address, socket_server):
|
| - BaseHTTPServer.BaseHTTPRequestHandler.__init__(
|
| - self, request, client_address, socket_server)
|
| -
|
| - def log_message(self, format, *args):
|
| - _LOGGER.debug(format, *args)
|
| -
|
| - def do_POST(self):
|
| - """Handles POST messages contained multipart form data."""
|
| - content_type, parameters = cgi.parse_header(
|
| - self.headers.getheader('content-type'))
|
| - if content_type != 'multipart/form-data':
|
| - raise Exception('Unsupported Content-Type: ' + content_type)
|
| - post_multipart = cgi.parse_multipart(self.rfile, parameters)
|
| -
|
| - # Save the crash report.
|
| - report = dict(post_multipart.items())
|
| - report_id = str(uuid.uuid4())
|
| - report['report-id'] = [report_id]
|
| - with crash_server.lock_:
|
| - crash_server.crashes_.append(report)
|
| -
|
| - # Send the response.
|
| - self.send_response(200)
|
| - self.send_header("Content-Type", "text/plain")
|
| - self.end_headers()
|
| - self.wfile.write(report_id)
|
| -
|
| - return MultipartFormHandler
|
| -
|
| - def server_thread(crash_server):
|
| - """Returns a thread that hosts the webserver."""
|
| -
|
| - class ServerThread(threading.Thread):
|
| - def run(self):
|
| - crash_server.server_.serve()
|
| -
|
| - return ServerThread()
|
|
|