Bug 1301781 - Add test harness for telemetry tests draft
authorJohn Dorlus <jdorlus@mozilla.com>
Wed, 29 Mar 2017 17:10:52 -0400
changeset 553783 e043f746976581b2d1273f5b272238f7e5da7f99
parent 553751 3364cc17988c013c36f2a8123315db2855393011
child 622195 c3b1b3df2ef5f95457d4fb44929c0f0aa4cf7c80
push id51777
push userbmo:jdorlus@mozilla.com
push dateThu, 30 Mar 2017 18:12:04 +0000
bugs1301781
milestone55.0a1
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
toolkit/components/telemetry/tests/marionette/harness/__init__.py
toolkit/components/telemetry/tests/marionette/harness/requirements.txt
toolkit/components/telemetry/tests/marionette/harness/setup.py
toolkit/components/telemetry/tests/marionette/harness/telemetry_harness/__init__.py
toolkit/components/telemetry/tests/marionette/harness/telemetry_harness/runtests.py
toolkit/components/telemetry/tests/marionette/harness/telemetry_harness/testcase.py
toolkit/components/telemetry/tests/marionette/harness/www/.hgempty
toolkit/components/telemetry/tests/marionette/tests/manifest.ini
toolkit/components/telemetry/tests/marionette/tests/unit/manifest.ini
toolkit/components/telemetry/tests/marionette/tests/unit/test_ping_server_received_ping.py
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
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']