Skip to content
This repository has been archived by the owner on Aug 4, 2022. It is now read-only.

Commit

Permalink
Bug 1520463 - Raptor python unit tests: add support for python 3 r=ahal
Browse files Browse the repository at this point in the history
  • Loading branch information
Rob Wood committed Oct 21, 2019
1 parent da11b95 commit a77685b
Show file tree
Hide file tree
Showing 12 changed files with 118 additions and 92 deletions.
1 change: 0 additions & 1 deletion .flake8
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
3 changes: 2 additions & 1 deletion taskcluster/ci/source-test/python.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
7 changes: 4 additions & 3 deletions testing/raptor/mach_commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import json
import os
import shutil
import six
import socket
import subprocess
import sys
Expand Down Expand Up @@ -234,10 +235,10 @@ def run_raptor(self, **kwargs):
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
Expand All @@ -248,7 +249,7 @@ def run_raptor(self, **kwargs):
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])
Expand Down
27 changes: 22 additions & 5 deletions testing/raptor/raptor/control_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -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")
Expand All @@ -27,7 +32,7 @@
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':...}
Expand Down Expand Up @@ -144,9 +149,16 @@ def do_POST(self):
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":
Expand Down Expand Up @@ -218,7 +230,12 @@ def do_POST(self):
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:
Expand Down Expand Up @@ -256,7 +273,7 @@ def do_OPTIONS(self):
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):
Expand Down
4 changes: 2 additions & 2 deletions testing/raptor/raptor/manifest.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@

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
Expand Down
9 changes: 5 additions & 4 deletions testing/raptor/raptor/profiler/symbolication.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -144,8 +145,8 @@ def integrate_symbol_zip_from_url(self, symbol_zip_url):
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:
Expand Down
8 changes: 5 additions & 3 deletions testing/raptor/raptor/profiler/symbolicationRequest.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@

import json
import re
import urllib2

from six.moves.urllib.request import Request, urlopen

from .symLogging import LogTrace, LogError

Expand Down Expand Up @@ -203,9 +204,10 @@ def ForwardRequest(self, indexes, stack, modules, symbolicatedStack):
}
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
Expand Down
15 changes: 8 additions & 7 deletions testing/raptor/raptor/raptor.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import posixpath
import shutil
import signal
import six
import sys
import tempfile
import time
Expand Down Expand Up @@ -495,7 +496,7 @@ def run_test(self, test, timeout):
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
Expand Down Expand Up @@ -723,27 +724,27 @@ def clean_up(self):
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):
Expand Down Expand Up @@ -1510,7 +1511,7 @@ def raptor_class(*inner_args, **inner_kwargs):
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))
Expand Down
3 changes: 2 additions & 1 deletion testing/raptor/test/python.ini
Original file line number Diff line number Diff line change
@@ -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]
68 changes: 67 additions & 1 deletion testing/raptor/test/test_control_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,11 @@
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

Expand Down Expand Up @@ -108,5 +112,67 @@ def post_end_background():
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()
2 changes: 1 addition & 1 deletion testing/raptor/test/test_manifest.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
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__))
Expand Down
Loading

0 comments on commit a77685b

Please sign in to comment.