Bug 1301781 - Add test harness for telemetry tests
These tests are for the testing of the telemetry client. The tests
spin up an http server to capture ping data sent from firefox. The test
test_ping_server_received_ping tests that the ping server is up and running
and that the harness properly waits for the ping data.
MozReview-Commit-ID: 5kIjqgX3YiW
new file mode 100755
--- /dev/null
+++ b/toolkit/components/telemetry/tests/marionette/harness/__init__.py
@@ -0,0 +1,3 @@
+# 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/.
new file mode 100644
--- /dev/null
+++ b/toolkit/components/telemetry/tests/marionette/harness/requirements.txt
@@ -0,0 +1,4 @@
+firefox-puppeteer >= 52.1.0, <53.0.0
+marionette-harness >= 4.0.0
+requests==2.11.1
+simplejson
\ No newline at end of file
new file mode 100755
--- /dev/null
+++ b/toolkit/components/telemetry/tests/marionette/harness/setup.py
@@ -0,0 +1,43 @@
+# 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/.
+
+import os
+
+from setuptools import setup, find_packages
+
+PACKAGE_VERSION = '0.1'
+
+THIS_DIR = os.path.dirname(os.path.realpath(__name__))
+
+
+def read(*parts):
+ with open(os.path.join(THIS_DIR, *parts)) as f:
+ return f.read()
+
+setup(name='telemetry-harness',
+ version=PACKAGE_VERSION,
+ description=("""Custom Marionette runner classes and entry scripts for Telemetry
+specific Marionette tests."""),
+ classifiers=[
+ 'Environment :: Console',
+ 'Intended Audience :: Developers',
+ 'License :: OSI Approved :: Mozilla Public License 2.0 (MPL 2.0)',
+ 'Natural Language :: English',
+ 'Operating System :: OS Independent',
+ 'Programming Language :: Python',
+ 'Topic :: Software Development :: Libraries :: Python Modules',
+ ],
+ keywords='mozilla',
+ author='Firefox Test Engineering Team',
+ author_email='firefox-test-engineering@mozilla.org',
+ url='https://hg.mozilla.org/mozilla-central/toolkit/telemetry/tests',
+ license='MPL 2.0',
+ packages=find_packages(),
+ zip_safe=False,
+ install_requires=read('requirements.txt').splitlines(),
+ include_package_data=True,
+ entry_points="""
+ [console_scripts]
+ telemetry-harness = telemetry_harness.runtests:cli
+ """)
new file mode 100644
--- /dev/null
+++ b/toolkit/components/telemetry/tests/marionette/harness/telemetry_harness/__init__.py
@@ -0,0 +1,3 @@
+# 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/.
new file mode 100755
--- /dev/null
+++ b/toolkit/components/telemetry/tests/marionette/harness/telemetry_harness/runtests.py
@@ -0,0 +1,13 @@
+# 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/.
+
+from marionette_harness.runtests import cli as mn_cli
+from testcase import TelemetryTestCase
+
+
+def cli():
+ mn_cli(testcase_class=TelemetryTestCase)
+
+if __name__ == '__main__':
+ cli()
new file mode 100755
--- /dev/null
+++ b/toolkit/components/telemetry/tests/marionette/harness/telemetry_harness/testcase.py
@@ -0,0 +1,61 @@
+# 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/.
+
+import os
+import re
+import simplejson as json
+import zlib
+
+from firefox_puppeteer import PuppeteerMixin
+from marionette_harness import MarionetteTestCase
+from marionette_harness.runner import httpd
+
+
+here = os.path.abspath(os.path.dirname(__file__))
+doc_root = os.path.join(os.path.dirname(here), "www")
+
+
+class TelemetryTestCase(PuppeteerMixin, MarionetteTestCase):
+
+ ping_list = []
+
+ def setUp(self, *args, **kwargs):
+ super(TelemetryTestCase, self).setUp()
+
+ # Start and configure server
+ self.httpd = httpd.FixtureServer(doc_root)
+ ping_route = [("POST", re.compile('/pings'), self.pings)]
+ self.httpd.routes.extend(ping_route)
+ self.httpd.start()
+ self.ping_server_url = '{}pings'.format(self.httpd.get_url('/'))
+
+ telemetry_prefs = {
+ 'toolkit.telemetry.send.overrideOfficialCheck': True,
+ 'toolkit.telemetry.server': self.ping_server_url,
+ 'toolkit.telemetry.initDelay': '1',
+ 'datareporting.healthreport.uploadEnabled': True,
+ 'datareporting.policy.dataSubmissionEnabled': True,
+ 'datareporting.policy.dataSubmissionPolicyBypassNotification': True,
+ 'toolkit.telemetry.log.level': 0,
+ 'toolkit.telemetry.log.dump': True
+ }
+
+ # Firefox will be forced to restart with the prefs enforced.
+ self.marionette.enforce_gecko_prefs(telemetry_prefs)
+
+ def tearDown(self, *args, **kwargs):
+ self.httpd.stop()
+ super(TelemetryTestCase, self).tearDown()
+
+ def pings(self, request, response):
+ json_data = json.loads(unpack(request.headers, request.body))
+ self.ping_list.append(json_data)
+ return 200
+
+
+def unpack(headers, data):
+ if "Content-Encoding" in headers and headers["Content-Encoding"] == "gzip":
+ return zlib.decompress(data, zlib.MAX_WBITS | 16)
+ else:
+ return data
new file mode 100644
--- /dev/null
+++ b/toolkit/components/telemetry/tests/marionette/tests/manifest.ini
@@ -0,0 +1,1 @@
+[include:unit/manifest.ini]
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/toolkit/components/telemetry/tests/marionette/tests/unit/manifest.ini
@@ -0,0 +1,4 @@
+[DEFAULT]
+tags = unit
+
+[test_ping_server_received_ping.py]
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/toolkit/components/telemetry/tests/marionette/tests/unit/test_ping_server_received_ping.py
@@ -0,0 +1,20 @@
+# 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/
+
+import requests
+import simplejson as json
+
+from telemetry_harness.testcase import TelemetryTestCase
+
+
+class TestPingServer(TelemetryTestCase):
+
+ def test_ping_server_received_ping(self):
+
+ data = {'sender': 'John', 'receiver': 'Joe', 'message': 'We did it!'}
+ headers = {'Content-type': 'application/json', 'Accept': 'text/plain'}
+ req = requests.post(self.ping_server_url, data=json.dumps(data), headers=headers)
+ assert req.status_code == 200
+ assert len(self.ping_list) == 1
+ assert data['sender'] == self.ping_list[-1]['sender']