зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1554328: Fix minor typos in Raptor's control_server.py r=perftest-reviewers,sparky
Differential Revision: https://phabricator.services.mozilla.com/D43278 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
620c07b2bb
Коммит
3e05e8ace5
|
@ -1,3 +1,5 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
@ -17,17 +19,14 @@ import time
|
|||
|
||||
from logger.logger import RaptorLogger
|
||||
|
||||
LOG = RaptorLogger(component='raptor-control-server')
|
||||
LOG = RaptorLogger(component="raptor-control-server")
|
||||
|
||||
here = os.path.abspath(os.path.dirname(__file__))
|
||||
|
||||
|
||||
def MakeCustomHandlerClass(results_handler,
|
||||
shutdown_browser,
|
||||
handle_gecko_profile,
|
||||
background_app,
|
||||
foreground_app):
|
||||
|
||||
def MakeCustomHandlerClass(
|
||||
results_handler, shutdown_browser, handle_gecko_profile, background_app, foreground_app
|
||||
):
|
||||
class MyHandler(BaseHTTPServer.BaseHTTPRequestHandler, object):
|
||||
"""
|
||||
Control server expects messages of the form
|
||||
|
@ -40,25 +39,25 @@ def MakeCustomHandlerClass(results_handler,
|
|||
otherwise
|
||||
the key is data['type'].
|
||||
|
||||
The contol server can be forced to wait before performing an
|
||||
The control server can be forced to wait before performing an
|
||||
action requested via POST by sending a special message
|
||||
|
||||
{'type': 'wait-set', 'data': key}
|
||||
|
||||
where key is the key of the message control server should
|
||||
where key is the key of the message for which the control server should
|
||||
perform a wait before processing. The handler will store
|
||||
this key in the wait_after_messages dict as a True value.
|
||||
|
||||
wait_after_messages[key] = True
|
||||
|
||||
For subsequent requests the handler will check the key of
|
||||
the incoming message against wait_for_messages and if it is
|
||||
found and its value is True, the handler will assign the key
|
||||
For subsequent requests, the handler will check the key of
|
||||
the incoming message against wait_for_messages; if found
|
||||
and its value is True, the handler will assign the key
|
||||
to waiting_in_state and will loop until the key is removed
|
||||
or until its value is changed to False.
|
||||
|
||||
Control server will stop waiting for a state to be continued
|
||||
or cleared after wait_timeout seconds after which the wait
|
||||
The control server will stop waiting for a state to be continued
|
||||
or cleared after wait_timeout seconds, after which the wait
|
||||
will be removed and the control server will finish processing
|
||||
the current POST request. wait_timeout defaults to 60 seconds
|
||||
but can be set globally for all wait states by sending the
|
||||
|
@ -77,13 +76,13 @@ def MakeCustomHandlerClass(results_handler,
|
|||
key is recorded in wait_after_messages and is waiting before
|
||||
completing the request.
|
||||
|
||||
The control server can be told to stop waiting and to finish
|
||||
The control server can be told to stop waiting and finish
|
||||
processing the current request while keeping the wait for
|
||||
subsequent requests by sending
|
||||
|
||||
{'type': 'wait-continue', 'data': ''}
|
||||
|
||||
The control server can be told to stop waiting and to finish
|
||||
The control server can be told to stop waiting and finish
|
||||
processing the current request while removing the wait for
|
||||
subsequent requests by sending
|
||||
|
||||
|
@ -101,6 +100,7 @@ def MakeCustomHandlerClass(results_handler,
|
|||
if the key matches the value in waiting_in_state,
|
||||
then waiting_in_state is set to None
|
||||
"""
|
||||
|
||||
wait_after_messages = {}
|
||||
waiting_in_state = None
|
||||
wait_timeout = 60
|
||||
|
@ -113,46 +113,46 @@ def MakeCustomHandlerClass(results_handler,
|
|||
self.foreground_app = foreground_app
|
||||
super(MyHandler, self).__init__(*args, **kwargs)
|
||||
|
||||
def log_request(self, code='-', size='-'):
|
||||
def log_request(self, code="-", size="-"):
|
||||
if code != 200:
|
||||
super(MyHandler, self).log_request(code, size)
|
||||
|
||||
def do_GET(self):
|
||||
# get handler, received request for test settings from web ext runner
|
||||
# get handler, received request for test settings from webext runner
|
||||
self.send_response(200)
|
||||
head, tail = os.path.split(self.path)
|
||||
|
||||
if tail.startswith('raptor') and tail.endswith('.json'):
|
||||
LOG.info('reading test settings from json/' + tail)
|
||||
if tail.startswith("raptor") and tail.endswith(".json"):
|
||||
LOG.info("reading test settings from json/" + tail)
|
||||
try:
|
||||
with open("json/{}".format(tail)) as json_settings:
|
||||
self.send_header('Access-Control-Allow-Origin', '*')
|
||||
self.send_header('Content-type', 'application/json')
|
||||
self.send_header("Access-Control-Allow-Origin", "*")
|
||||
self.send_header("Content-type", "application/json")
|
||||
self.end_headers()
|
||||
self.wfile.write(json.dumps(json.load(json_settings)))
|
||||
self.wfile.close()
|
||||
LOG.info('sent test settings to web ext runner')
|
||||
LOG.info("sent test settings to webext runner")
|
||||
except Exception as ex:
|
||||
LOG.info('control server exception')
|
||||
LOG.info("control server exception")
|
||||
LOG.info(ex)
|
||||
else:
|
||||
LOG.info('received request for unknown file: ' + self.path)
|
||||
LOG.info("received request for unknown file: " + self.path)
|
||||
|
||||
def do_POST(self):
|
||||
# post handler, received something from webext
|
||||
self.send_response(200)
|
||||
self.send_header('Access-Control-Allow-Origin', '*')
|
||||
self.send_header('Content-type', 'text/html')
|
||||
self.send_header("Access-Control-Allow-Origin", "*")
|
||||
self.send_header("Content-type", "text/html")
|
||||
self.end_headers()
|
||||
content_len = int(self.headers.getheader('content-length'))
|
||||
content_len = int(self.headers.getheader("content-length"))
|
||||
post_body = self.rfile.read(content_len)
|
||||
# could have received a status update or test results
|
||||
data = json.loads(post_body)
|
||||
|
||||
if data['type'] == 'webext_status':
|
||||
wait_key = "%s/%s" % (data['type'], data['data'])
|
||||
if data["type"] == "webext_status":
|
||||
wait_key = "%s/%s" % (data["type"], data["data"])
|
||||
else:
|
||||
wait_key = data['type']
|
||||
wait_key = data["type"]
|
||||
|
||||
if MyHandler.wait_after_messages.get(wait_key, None):
|
||||
LOG.info("Waiting in %s" % wait_key)
|
||||
|
@ -165,73 +165,75 @@ def MakeCustomHandlerClass(results_handler,
|
|||
if elapsed_time > datetime.timedelta(seconds=MyHandler.wait_timeout):
|
||||
del MyHandler.wait_after_messages[wait_key]
|
||||
MyHandler.waiting_in_state = None
|
||||
LOG.error("TEST-UNEXPECTED-ERROR | "
|
||||
"ControlServer wait %s exceeded %s seconds" %
|
||||
(wait_key, MyHandler.wait_timeout))
|
||||
LOG.error(
|
||||
"TEST-UNEXPECTED-ERROR | "
|
||||
"control server wait %s exceeded %s seconds"
|
||||
% (wait_key, MyHandler.wait_timeout)
|
||||
)
|
||||
|
||||
if MyHandler.wait_after_messages.get(wait_key, None) is not None:
|
||||
# If the wait is False, it was continued and we just set it back
|
||||
# to True for the next time. If it was removed by clear, we
|
||||
# leave it alone so it will not cause a wait any more.
|
||||
# If the wait is False, it was continued, so we set it back
|
||||
# to True for the next time. If removed by clear, we
|
||||
# leave it alone so it will not cause further waits.
|
||||
MyHandler.wait_after_messages[wait_key] = True
|
||||
|
||||
if data['type'] == "webext_gecko_profile":
|
||||
if data["type"] == "webext_gecko_profile":
|
||||
# received file name of the saved gecko profile
|
||||
filename = str(data['data'])
|
||||
filename = str(data["data"])
|
||||
LOG.info("received gecko profile filename: {}".format(filename))
|
||||
self.handle_gecko_profile(filename)
|
||||
|
||||
elif data['type'] == 'webext_results':
|
||||
LOG.info("received " + data['type'] + ": " + str(data['data']))
|
||||
self.results_handler.add(data['data'])
|
||||
elif data['type'] == "webext_raptor-page-timeout":
|
||||
LOG.info("received " + data['type'] + ": " + str(data['data']))
|
||||
elif data["type"] == "webext_results":
|
||||
LOG.info("received " + data["type"] + ": " + str(data["data"]))
|
||||
self.results_handler.add(data["data"])
|
||||
elif data["type"] == "webext_raptor-page-timeout":
|
||||
LOG.info("received " + data["type"] + ": " + str(data["data"]))
|
||||
|
||||
if len(data['data']) == 2:
|
||||
data['data'].append("")
|
||||
if len(data["data"]) == 2:
|
||||
data["data"].append("")
|
||||
# pageload test has timed out; record it as a failure
|
||||
self.results_handler.add_page_timeout(str(data['data'][0]),
|
||||
str(data['data'][1]),
|
||||
dict(data['data'][2]))
|
||||
elif data['type'] == "webext_shutdownBrowser":
|
||||
self.results_handler.add_page_timeout(
|
||||
str(data["data"][0]), str(data["data"][1]), dict(data["data"][2])
|
||||
)
|
||||
elif data["type"] == "webext_shutdownBrowser":
|
||||
LOG.info("received request to shutdown the browser")
|
||||
self.shutdown_browser()
|
||||
elif data['type'] == 'webext_start_background':
|
||||
elif data["type"] == "webext_start_background":
|
||||
LOG.info("received request to background app")
|
||||
self.background_app()
|
||||
elif data['type'] == 'webext_end_background':
|
||||
elif data["type"] == "webext_end_background":
|
||||
LOG.info("received request to foreground app")
|
||||
self.foreground_app()
|
||||
elif data['type'] == 'webext_screenshot':
|
||||
LOG.info("received " + data['type'])
|
||||
self.results_handler.add_image(str(data['data'][0]),
|
||||
str(data['data'][1]),
|
||||
str(data['data'][2]))
|
||||
elif data['type'] == 'webext_status':
|
||||
LOG.info("received " + data['type'] + ": " + str(data['data']))
|
||||
elif data['type'] == 'wait-set':
|
||||
LOG.info("received " + data['type'] + ": " + str(data['data']))
|
||||
MyHandler.wait_after_messages[str(data['data'])] = True
|
||||
elif data['type'] == 'wait-timeout':
|
||||
LOG.info("received " + data['type'] + ": " + str(data['data']))
|
||||
MyHandler.wait_timeout = data['data']
|
||||
elif data['type'] == 'wait-get':
|
||||
elif data["type"] == "webext_screenshot":
|
||||
LOG.info("received " + data["type"])
|
||||
self.results_handler.add_image(
|
||||
str(data["data"][0]), str(data["data"][1]), str(data["data"][2])
|
||||
)
|
||||
elif data["type"] == "webext_status":
|
||||
LOG.info("received " + data["type"] + ": " + str(data["data"]))
|
||||
elif data["type"] == "wait-set":
|
||||
LOG.info("received " + data["type"] + ": " + str(data["data"]))
|
||||
MyHandler.wait_after_messages[str(data["data"])] = True
|
||||
elif data["type"] == "wait-timeout":
|
||||
LOG.info("received " + data["type"] + ": " + str(data["data"]))
|
||||
MyHandler.wait_timeout = data["data"]
|
||||
elif data["type"] == "wait-get":
|
||||
self.wfile.write(MyHandler.waiting_in_state)
|
||||
elif data['type'] == 'wait-continue':
|
||||
LOG.info("received " + data['type'] + ": " + str(data['data']))
|
||||
elif data["type"] == "wait-continue":
|
||||
LOG.info("received " + data["type"] + ": " + str(data["data"]))
|
||||
if MyHandler.waiting_in_state:
|
||||
MyHandler.wait_after_messages[MyHandler.waiting_in_state] = False
|
||||
MyHandler.waiting_in_state = None
|
||||
elif data['type'] == 'wait-clear':
|
||||
LOG.info("received " + data['type'] + ": " + str(data['data']))
|
||||
clear_key = str(data['data'])
|
||||
if clear_key == '':
|
||||
elif data["type"] == "wait-clear":
|
||||
LOG.info("received " + data["type"] + ": " + str(data["data"]))
|
||||
clear_key = str(data["data"])
|
||||
if clear_key == "":
|
||||
if MyHandler.waiting_in_state:
|
||||
del MyHandler.wait_after_messages[MyHandler.waiting_in_state]
|
||||
MyHandler.waiting_in_state = None
|
||||
else:
|
||||
pass
|
||||
elif clear_key == 'all':
|
||||
elif clear_key == "all":
|
||||
MyHandler.wait_after_messages = {}
|
||||
MyHandler.waiting_in_state = None
|
||||
elif clear_key not in MyHandler.wait_after_messages:
|
||||
|
@ -241,12 +243,12 @@ def MakeCustomHandlerClass(results_handler,
|
|||
if MyHandler.waiting_in_state == clear_key:
|
||||
MyHandler.waiting_in_state = None
|
||||
else:
|
||||
LOG.info("received " + data['type'] + ": " + str(data['data']))
|
||||
LOG.info("received " + data["type"] + ": " + str(data["data"]))
|
||||
|
||||
def do_OPTIONS(self):
|
||||
self.send_response(200, "ok")
|
||||
self.send_header('Access-Control-Allow-Origin', '*')
|
||||
self.send_header('Access-Control-Allow-Methods', 'GET, POST, OPTIONS')
|
||||
self.send_header("Access-Control-Allow-Origin", "*")
|
||||
self.send_header("Access-Control-Allow-Methods", "GET, POST, OPTIONS")
|
||||
self.send_header("Access-Control-Allow-Headers", "X-Requested-With")
|
||||
self.send_header("Access-Control-Allow-Headers", "Content-Type")
|
||||
self.end_headers()
|
||||
|
@ -258,8 +260,10 @@ class ThreadedHTTPServer(BaseHTTPServer.HTTPServer):
|
|||
# See
|
||||
# https://stackoverflow.com/questions/19537132/threaded-basehttpserver-one-thread-per-request#30312766
|
||||
def process_request(self, request, client_address):
|
||||
thread = threading.Thread(target=self.__new_request,
|
||||
args=(self.RequestHandlerClass, request, client_address, self))
|
||||
thread = threading.Thread(
|
||||
target=self.__new_request,
|
||||
args=(self.RequestHandlerClass, request, client_address, self),
|
||||
)
|
||||
thread.start()
|
||||
|
||||
def __new_request(self, handlerClass, request, address, server):
|
||||
|
@ -267,11 +271,11 @@ class ThreadedHTTPServer(BaseHTTPServer.HTTPServer):
|
|||
self.shutdown_request(request)
|
||||
|
||||
|
||||
class RaptorControlServer():
|
||||
class RaptorControlServer:
|
||||
"""Container class for Raptor Control Server"""
|
||||
|
||||
def __init__(self, results_handler, debug_mode=False):
|
||||
self.raptor_venv = os.path.join(os.getcwd(), 'raptor-venv')
|
||||
self.raptor_venv = os.path.join(os.getcwd(), "raptor-venv")
|
||||
self.server = None
|
||||
self._server_thread = None
|
||||
self.port = None
|
||||
|
@ -285,22 +289,24 @@ class RaptorControlServer():
|
|||
self.user_profile = None
|
||||
|
||||
def start(self):
|
||||
config_dir = os.path.join(here, 'tests')
|
||||
config_dir = os.path.join(here, "tests")
|
||||
os.chdir(config_dir)
|
||||
|
||||
# pick a free port
|
||||
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
sock.bind(('', 0))
|
||||
sock.bind(("", 0))
|
||||
self.port = sock.getsockname()[1]
|
||||
sock.close()
|
||||
server_address = ('', self.port)
|
||||
server_address = ("", self.port)
|
||||
|
||||
server_class = ThreadedHTTPServer
|
||||
handler_class = MakeCustomHandlerClass(self.results_handler,
|
||||
self.shutdown_browser,
|
||||
self.handle_gecko_profile,
|
||||
self.background_app,
|
||||
self.foreground_app)
|
||||
handler_class = MakeCustomHandlerClass(
|
||||
self.results_handler,
|
||||
self.shutdown_browser,
|
||||
self.handle_gecko_profile,
|
||||
self.background_app,
|
||||
self.foreground_app,
|
||||
)
|
||||
|
||||
httpd = server_class(server_address, handler_class)
|
||||
|
||||
|
@ -322,7 +328,7 @@ class RaptorControlServer():
|
|||
LOG.info("shutting down android app %s" % self.app_name)
|
||||
else:
|
||||
LOG.info("shutting down browser (pid: %d)" % self.browser_proc.pid)
|
||||
self.kill_thread = threading.Thread(target=self.wait_for_quit, kwargs={'timeout': 0})
|
||||
self.kill_thread = threading.Thread(target=self.wait_for_quit, kwargs={"timeout": 0})
|
||||
self.kill_thread.daemon = True
|
||||
self.kill_thread.start()
|
||||
|
||||
|
@ -350,9 +356,7 @@ class RaptorControlServer():
|
|||
LOG.info("%s was successfully backgrounded" % self.app_name)
|
||||
|
||||
def foreground_app(self):
|
||||
self.device.shell_output(
|
||||
"am start --activity-single-top %s" % self.app_name
|
||||
)
|
||||
self.device.shell_output("am start --activity-single-top %s" % self.app_name)
|
||||
self.device.shell_output("dumpsys deviceidle enable")
|
||||
if self.is_app_in_background():
|
||||
LOG.critical("%s is still in background after foreground request" % self.app_name)
|
||||
|
@ -372,12 +376,12 @@ class RaptorControlServer():
|
|||
self._finished = True
|
||||
|
||||
def submit_supporting_data(self, supporting_data):
|
||||
'''
|
||||
"""
|
||||
Allow the submission of supporting data i.e. power data.
|
||||
This type of data is measured outside of the webext; so
|
||||
we can submit directly to the control server instead of
|
||||
doing an http post.
|
||||
'''
|
||||
"""
|
||||
self.results_handler.add_supporting_data(supporting_data)
|
||||
|
||||
def stop(self):
|
||||
|
|
Загрузка…
Ссылка в новой задаче