Bug 1520463 - Raptor python unit tests: add support for python 3 r=ahal

Differential Revision: https://phabricator.services.mozilla.com/D48768

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Rob Wood 2019-10-21 20:26:15 +00:00
parent e5617f8407
commit be2b8eab04
12 changed files with 118 additions and 92 deletions

View File

@ -122,7 +122,6 @@ per-file-ignores =
python/mozversioncontrol/**: F821
taskcluster/**: F821
testing/mozharness/**: F821
testing/raptor/**: F821
testing/talos/**: F821
toolkit/components/telemetry/**: F821
tools/tryselect/**: F821

View File

@ -204,8 +204,9 @@ raptor:
description: testing/raptor unit tests
platform:
- linux64/opt
- macosx1014-64/opt
- windows10-64/opt
python-version: [2]
python-version: [2, 3]
treeherder:
symbol: rap
run:

View File

@ -11,6 +11,7 @@ from __future__ import absolute_import, print_function, unicode_literals
import json
import os
import shutil
import six
import socket
import subprocess
import sys
@ -234,10 +235,10 @@ class MachRaptor(MachCommandBase):
adbhost = ADBHost(verbose=True)
device_serial = "{}:5555".format(device.get_ip_address())
device.command_output(["tcpip", "5555"])
raw_input("Please disconnect your device from USB then press Enter/return...")
six.input("Please disconnect your device from USB then press Enter/return...")
adbhost.command_output(["connect", device_serial])
while len(adbhost.devices()) > 1:
raw_input("You must disconnect your device from USB before continuing.")
six.input("You must disconnect your device from USB before continuing.")
# must reset the environment DEVICE_SERIAL which was set during
# verify_android_device to match our new tcpip value.
os.environ["DEVICE_SERIAL"] = device_serial
@ -248,7 +249,7 @@ class MachRaptor(MachCommandBase):
finally:
try:
if is_android and kwargs['power_test']:
raw_input("Connect device via USB and press Enter/return...")
six.input("Connect device via USB and press Enter/return...")
device = ADBAndroid(device=device_serial, verbose=True)
device.command_output(["usb"])
adbhost.command_output(["disconnect", device_serial])

View File

@ -8,15 +8,20 @@
# communicates with the raptor browser webextension
from __future__ import absolute_import
import BaseHTTPServer
import datetime
import json
import os
import shutil
import six
import socket
import threading
import time
try:
from http import server # py3
except ImportError:
import BaseHTTPServer as server # py2
from logger.logger import RaptorLogger
LOG = RaptorLogger(component="raptor-control-server")
@ -27,7 +32,7 @@ here = os.path.abspath(os.path.dirname(__file__))
def MakeCustomHandlerClass(
results_handler, shutdown_browser, handle_gecko_profile, background_app, foreground_app
):
class MyHandler(BaseHTTPServer.BaseHTTPRequestHandler, object):
class MyHandler(server.BaseHTTPRequestHandler, object):
"""
Control server expects messages of the form
{'type': 'messagetype', 'data':...}
@ -144,9 +149,16 @@ def MakeCustomHandlerClass(
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"))
if six.PY2:
content_len = int(self.headers.getheader("content-length"))
elif six.PY3:
content_len = int(self.headers.get("content-length"))
post_body = self.rfile.read(content_len)
# could have received a status update or test results
if isinstance(post_body, six.binary_type):
post_body = post_body.decode('utf-8')
data = json.loads(post_body)
if data["type"] == "webext_status":
@ -218,7 +230,12 @@ def MakeCustomHandlerClass(
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)
state = MyHandler.waiting_in_state
if state is None:
state = 'None'
if isinstance(state, six.text_type):
state = state.encode('utf-8')
self.wfile.write(state)
elif data["type"] == "wait-continue":
LOG.info("received " + data["type"] + ": " + str(data["data"]))
if MyHandler.waiting_in_state:
@ -256,7 +273,7 @@ def MakeCustomHandlerClass(
return MyHandler
class ThreadedHTTPServer(BaseHTTPServer.HTTPServer):
class ThreadedHTTPServer(server.HTTPServer):
# See
# https://stackoverflow.com/questions/19537132/threaded-basehttpserver-one-thread-per-request#30312766
def process_request(self, request, client_address):

View File

@ -5,8 +5,8 @@ from __future__ import absolute_import
import json
import os
from urlparse import parse_qs, urlsplit, urlunsplit
from urllib import urlencode, unquote
from six.moves.urllib.parse import parse_qs, urlsplit, urlunsplit, urlencode, unquote
from logger.logger import RaptorLogger
from manifestparser import TestManifest

View File

@ -3,14 +3,15 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
from __future__ import absolute_import
import cStringIO
import hashlib
import os
import platform
import subprocess
import urllib2
import zipfile
from distutils import spawn
from six.moves import cStringIO
from six.moves.urllib.request import urlopen
from .symFileManager import SymFileManager
from .symLogging import LogMessage
@ -144,8 +145,8 @@ class ProfileSymbolicator:
LogMessage("Retrieving symbol zip from {symbol_zip_url}...".format(
symbol_zip_url=symbol_zip_url))
try:
io = urllib2.urlopen(symbol_zip_url, None, 30)
with zipfile.ZipFile(cStringIO.StringIO(io.read())) as zf:
io = urlopen(symbol_zip_url, None, 30)
with zipfile.ZipFile(cStringIO(io.read())) as zf:
self.integrate_symbol_zip(zf)
self._create_file_if_not_exists(self._marker_file(symbol_zip_url))
except IOError:

View File

@ -5,7 +5,8 @@ from __future__ import absolute_import
import json
import re
import urllib2
from six.moves.urllib.request import Request, urlopen
from .symLogging import LogTrace, LogError
@ -203,9 +204,10 @@ class SymbolicationRequest:
}
requestJson = json.dumps(requestObj)
headers = {"Content-Type": "application/json"}
requestHandle = urllib2.Request(url, requestJson, headers)
requestHandle = Request(url, requestJson, headers)
try:
response = urllib2.urlopen(requestHandle)
response = urlopen(requestHandle)
except Exception as e:
if requestVersion == 4:
# Try again with version 3

View File

@ -12,6 +12,7 @@ import os
import posixpath
import shutil
import signal
import six
import sys
import tempfile
import time
@ -495,7 +496,7 @@ class Browsertime(Perftest):
ffmpeg_dir = os.path.dirname(os.path.abspath(self.browsertime_ffmpeg))
old_path = env.setdefault('PATH', '')
new_path = os.pathsep.join([ffmpeg_dir, old_path])
if isinstance(new_path, unicode):
if isinstance(new_path, six.text_type):
# Python 2 doesn't like unicode in the environment.
new_path = new_path.encode('utf-8', 'strict')
env['PATH'] = new_path
@ -723,27 +724,27 @@ class Raptor(Perftest):
def control_server_wait_set(self, state):
response = requests.post("http://127.0.0.1:%s/" % self.control_server.port,
json={"type": "wait-set", "data": state})
return response.content
return response.text
def control_server_wait_timeout(self, timeout):
response = requests.post("http://127.0.0.1:%s/" % self.control_server.port,
json={"type": "wait-timeout", "data": timeout})
return response.content
return response.text
def control_server_wait_get(self):
response = requests.post("http://127.0.0.1:%s/" % self.control_server.port,
json={"type": "wait-get", "data": ""})
return response.content
return response.text
def control_server_wait_continue(self):
response = requests.post("http://127.0.0.1:%s/" % self.control_server.port,
json={"type": "wait-continue", "data": ""})
return response.content
return response.text
def control_server_wait_clear(self, state):
response = requests.post("http://127.0.0.1:%s/" % self.control_server.port,
json={"type": "wait-clear", "data": state})
return response.content
return response.text
class RaptorDesktop(Raptor):
@ -1510,7 +1511,7 @@ def main(args=sys.argv[1:]):
for _page in pages_that_timed_out:
message = [("TEST-UNEXPECTED-FAIL", "test '%s'" % _page['test_name']),
("timed out loading test page", _page['url'])]
if raptor_test.get("type") == 'pageload':
if _page.get('pending_metrics') is not None:
message.append(("pending metrics", _page['pending_metrics']))
LOG.critical(" ".join("%s: %s" % (subject, msg) for subject, msg in message))

View File

@ -1,13 +1,14 @@
[DEFAULT]
subsuite = raptor
skip-if = python == 3
[test_cmdline.py]
[test_manifest.py]
skip-if = python == 3 # bug 1428705 - [manifestparser] add support for py3
[test_control_server.py]
[test_utils.py]
[test_playback.py]
[test_print_tests.py]
skip-if = python == 3 # bug 1428705 - [manifestparser] add support for py3
[test_raptor.py]
[test_cpu.py]
[test_power.py]

View File

@ -6,7 +6,11 @@ import requests
import sys
import mock
from BaseHTTPServer import HTTPServer
try:
from http.server import HTTPServer # py3
except ImportError:
from BaseHTTPServer import HTTPServer # py2
from mozlog.structuredlog import set_default_logger, StructuredLogger
from raptor.control_server import RaptorControlServer
@ -108,5 +112,67 @@ def test_server_android_app_backgrounding():
assert not control._server_thread.is_alive()
def test_server_wait_states(raptor):
import datetime
def post_state():
requests.post("http://127.0.0.1:%s/" % raptor.control_server.port,
json={"type": "webext_status",
"data": "test status"})
wait_time = 5
message_state = 'webext_status/test status'
rhc = raptor.control_server.server.RequestHandlerClass
# Test initial state
assert rhc.wait_after_messages == {}
assert rhc.waiting_in_state is None
assert rhc.wait_timeout == 60
assert raptor.control_server_wait_get() == 'None'
# Test setting a state
assert raptor.control_server_wait_set(message_state) == ''
assert message_state in rhc.wait_after_messages
assert rhc.wait_after_messages[message_state]
# Test clearing a non-existent state
assert raptor.control_server_wait_clear('nothing') == ''
assert message_state in rhc.wait_after_messages
# Test clearing a state
assert raptor.control_server_wait_clear(message_state) == ''
assert message_state not in rhc.wait_after_messages
# Test clearing all states
assert raptor.control_server_wait_set(message_state) == ''
assert message_state in rhc.wait_after_messages
assert raptor.control_server_wait_clear('all') == ''
assert rhc.wait_after_messages == {}
# Test wait timeout
# Block on post request
assert raptor.control_server_wait_set(message_state) == ''
assert rhc.wait_after_messages[message_state]
assert raptor.control_server_wait_timeout(wait_time) == ''
assert rhc.wait_timeout == wait_time
start = datetime.datetime.now()
post_state()
assert datetime.datetime.now() - start < datetime.timedelta(seconds=wait_time + 2)
assert raptor.control_server_wait_get() == 'None'
assert message_state not in rhc.wait_after_messages
raptor.clean_up()
assert not raptor.control_server._server_thread.is_alive()
def test_clean_up_stop_server(raptor):
assert raptor.control_server._server_thread.is_alive()
assert raptor.control_server.port is not None
assert raptor.control_server.server is not None
raptor.clean_up()
assert not raptor.control_server._server_thread.is_alive()
if __name__ == '__main__':
mozunit.main()

View File

@ -6,7 +6,7 @@ import os
import pytest
import sys
from urlparse import parse_qs, urlsplit
from six.moves.urllib.parse import parse_qs, urlsplit
# need this so raptor imports work both from /raptor and via mach
here = os.path.abspath(os.path.dirname(__file__))

View File

@ -2,7 +2,6 @@ from __future__ import absolute_import, unicode_literals
from six import reraise
import os
import requests
import sys
import threading
import time
@ -67,68 +66,6 @@ def test_build_profile(options, raptor_class, app_name, get_prefs):
assert raptor_pref in prefs
def test_start_and_stop_server(raptor):
assert raptor.control_server._server_thread.is_alive()
assert raptor.control_server.port is not None
assert raptor.control_server.server is not None
raptor.clean_up()
assert not raptor.control_server._server_thread.is_alive()
def test_server_wait_states(raptor):
import datetime
def post_state():
requests.post("http://127.0.0.1:%s/" % raptor.control_server.port,
json={"type": "webext_status",
"data": "test status"})
wait_time = 5
message_state = 'webext_status/test status'
rhc = raptor.control_server.server.RequestHandlerClass
# Test initial state
assert rhc.wait_after_messages == {}
assert rhc.waiting_in_state is None
assert rhc.wait_timeout == 60
assert raptor.control_server_wait_get() == 'None'
# Test setting a state
assert raptor.control_server_wait_set(message_state) == ''
assert message_state in rhc.wait_after_messages
assert rhc.wait_after_messages[message_state]
# Test clearing a non-existent state
assert raptor.control_server_wait_clear('nothing') == ''
assert message_state in rhc.wait_after_messages
# Test clearing a state
assert raptor.control_server_wait_clear(message_state) == ''
assert message_state not in rhc.wait_after_messages
# Test clearing all states
assert raptor.control_server_wait_set(message_state) == ''
assert message_state in rhc.wait_after_messages
assert raptor.control_server_wait_clear('all') == ''
assert rhc.wait_after_messages == {}
# Test wait timeout
# Block on post request
assert raptor.control_server_wait_set(message_state) == ''
assert rhc.wait_after_messages[message_state]
assert raptor.control_server_wait_timeout(wait_time) == ''
assert rhc.wait_timeout == wait_time
start = datetime.datetime.now()
post_state()
assert datetime.datetime.now() - start < datetime.timedelta(seconds=wait_time + 2)
assert raptor.control_server_wait_get() == 'None'
assert message_state not in rhc.wait_after_messages
raptor.clean_up()
assert not raptor.control_server._server_thread.is_alive()
@pytest.mark.parametrize('app', [
'firefox',
pytest.mark.xfail('chrome'),