Bug 1387265 - Expand talos tp6 to macosx; r=jmaher
authorRob Wood <rwood@mozilla.com>
Tue, 15 Aug 2017 15:30:23 -0400
changeset 427425 2619edc827ada43379ff483c26271284cfdd199a
parent 427424 0db049b28c65a83aa955155fbe82b86c69f7e91f
child 427426 d9fff5d93cb3c52c351a9449ef0692bac8a02b88
push id1567
push userjlorenzo@mozilla.com
push dateThu, 02 Nov 2017 12:36:05 +0000
treeherdermozilla-release@e512c14a0406 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjmaher
bugs1387265
milestone57.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1387265 - Expand talos tp6 to macosx; r=jmaher MozReview-Commit-ID: 78LGHEJNGz4
.hgignore
taskcluster/ci/test/test-sets.yml
taskcluster/ci/test/tests.yml
testing/mozharness/mozharness/mozilla/testing/talos.py
testing/talos/talos/mitmproxy/mitmproxy.py
--- a/.hgignore
+++ b/.hgignore
@@ -135,16 +135,19 @@ GPATH
 ^testing/talos/include/
 ^testing/talos/lib/
 ^testing/talos/talos/tests/tp5n.zip
 ^testing/talos/talos/tests/tp5n.tar.gz
 ^testing/talos/talos/tests/tp5n
 ^testing/talos/talos/tests/devtools/damp.manifest.develop
 ^talos-venv
 ^py3venv
+^testing/talos/talos/mitmproxy/mitmdump
+^testing/talos/talos/mitmproxy/mitmproxy
+^testing/talos/talos/mitmproxy/mitmweb
 
 # Ignore files created when running a reftest.
 ^lextab.py$
 
 # tup database
 ^\.tup
 
 # Ignore Visual Studio Code workspace files.
--- a/taskcluster/ci/test/test-sets.yml
+++ b/taskcluster/ci/test/test-sets.yml
@@ -224,16 +224,17 @@ macosx64-tests-talos:
     - talos-g2
     - talos-g4
     - talos-g5
     - talos-other
     - talos-svgr
     - talos-tp5o
     - talos-perf-reftest
     - talos-perf-reftest-singletons
+    - talos-tp6
 
 linux32-tests:
     - cppunit
     - crashtest
     - firefox-ui-functional-local
     - firefox-ui-functional-remote
     - gtest
     - jittest
--- a/taskcluster/ci/test/tests.yml
+++ b/taskcluster/ci/test/tests.yml
@@ -1849,16 +1849,17 @@ talos-tp5o-stylo:
 talos-tp6:
     description: "Talos Tp6"
     suite: talos
     try-name: tp6
     treeherder-symbol: tc-T(tp6)
     run-on-projects:
         by-test-platform:
             windows.*: ['mozilla-beta', 'mozilla-central', 'mozilla-inbound', 'autoland', 'try', 'date']
+            macosx.*: ['mozilla-beta', 'mozilla-central', 'mozilla-inbound', 'autoland', 'try', 'date']
             default: []
     max-run-time: 3600
     mozharness:
         script: talos_script.py
         no-read-buildbot-config: true
         config:
             by-test-platform:
                 macosx.*:
--- a/testing/mozharness/mozharness/mozilla/testing/talos.py
+++ b/testing/mozharness/mozharness/mozilla/testing/talos.py
@@ -400,18 +400,26 @@ class Talos(TestingMixin, MercurialScrip
     def setup_mitmproxy(self):
         """Some talos tests require the use of mitmproxy to playback the pages,
         set it up here.
         """
         if not self.query_mitmproxy_recording_set():
             self.info("Skipping: mitmproxy is not required")
             return
 
-        # setup python 3.x virtualenv
-        self.setup_py3_virtualenv()
+        # tp6 is supported in production only on win and macosx
+        os_name = self.platform_name()
+        if 'win' not in os_name and os_name != 'macosx':
+            self.fatal("Aborting: this test is not supported on this platform.")
+
+        # on windows we need to install a pytyon 3 virtual env; on macosx we
+        # use a mitmdump pre-built binary that doesn't need an external python 3
+        if 'win' in os_name:
+            # setup python 3.x virtualenv
+            self.setup_py3_virtualenv()
 
         # install mitmproxy
         self.install_mitmproxy()
 
         # download the recording set; will be overridden by the --no-download
         if '--no-download' not in self.config['talos_extra_options']:
             self.download_mitmproxy_recording_set()
         else:
@@ -427,19 +435,28 @@ class Talos(TestingMixin, MercurialScrip
         self.py3_create_venv()
         requirements = [os.path.join(self.talos_path, 'talos', 'mitmproxy', 'mitmproxy_requirements.txt')]
         self.py3_install_requirement_files(requirements)
         # add py3 executables path to system path
         sys.path.insert(1, self.py3_path_to_executables())
 
     def install_mitmproxy(self):
         """Install the mitmproxy tool into the Python 3.x env"""
-        self.info("Installing mitmproxy")
-        self.py3_install_modules(modules=['mitmproxy'])
-        self.mitmdump = os.path.join(self.py3_path_to_executables(), 'mitmdump')
+        if 'win' in self.platform_name():
+            self.info("Installing mitmproxy")
+            self.py3_install_modules(modules=['mitmproxy'])
+            self.mitmdump = os.path.join(self.py3_path_to_executables(), 'mitmdump')
+        else:
+            # on macosx we use a prebuilt mitmproxy release binary
+            mitmproxy_bin_url = 'https://github.com/mitmproxy/mitmproxy/releases/download/v2.0.2/mitmproxy-2.0.2-osx.tar.gz'
+            mitmproxy_path = os.path.join(self.talos_path, 'talos', 'mitmproxy')
+            self.mitmdump = os.path.join(mitmproxy_path, 'mitmdump')
+            if not os.path.exists(self.mitmdump):
+                self.download_unpack(mitmproxy_bin_url, mitmproxy_path)
+            self.info('The mitmdump macosx binary is found at: %s' % self.mitmdump)
         self.run_command([self.mitmdump, '--version'], env=self.query_env())
 
     def query_mitmproxy_recording_set(self):
         """Mitmproxy requires external playback archives to be downloaded and extracted"""
         if self.mitmproxy_recording_set:
             return self.mitmproxy_recording_set
         if self.query_talos_json_config() and self.suite is not None:
             self.mitmproxy_recording_set = self.talos_json_config['suites'][self.suite].get('mitmproxy_recording_set', False)
--- a/testing/talos/talos/mitmproxy/mitmproxy.py
+++ b/testing/talos/talos/mitmproxy/mitmproxy.py
@@ -1,13 +1,14 @@
 '''This helps loading mitmproxy's cert and change proxy settings for Firefox.'''
 # 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 psutil
 import sys
 import subprocess
 import time
 
 import mozinfo
 
 from mozlog import get_proxy_logger
 
@@ -76,16 +77,20 @@ def is_mitmproxy_cert_installed():
     return True
 
 
 def install_mitmproxy_cert(mitmproxy_proc, browser_path, scripts_path):
     """Install the CA certificate generated by mitmproxy, into Firefox"""
     LOG.info("Installing mitmxproxy CA certficate into Firefox")
     # browser_path is exe, we want install dir
     browser_install = os.path.dirname(browser_path)
+    # on macosx we need to remove the last folders 'Content/MacOS'
+    if mozinfo.os == 'mac':
+        browser_install = browser_install[:-14]
+
     LOG.info('Calling configure_mitmproxy with browser folder: %s' % browser_install)
     configure_mitmproxy(browser_install, scripts_path)
     # cannot continue if failed to add CA cert to Firefox, need to check
     if not is_mitmproxy_cert_installed():
         LOG.error('Aborting: failed to install mitmproxy CA cert into Firefox')
         stop_mitmproxy_playback(mitmproxy_proc)
         sys.exit()
 
@@ -99,52 +104,57 @@ def start_mitmproxy_playback(mitmdump_pa
     # recording names can be provided in comma-separated list; build py list including path
     for recording in mitmproxy_recordings_list:
         mitmproxy_recordings.append(os.path.join(mitmproxy_recording_path, recording))
 
     # cmd line to start mitmproxy playback using custom playback script is as follows:
     # <path>/mitmdump -s "<path>mitmdump-alternate-server-replay/alternate-server-replay.py
     #  <path>recording-1.mp <path>recording-2.mp..."
     param = os.path.join(here, 'alternate-server-replay.py')
+    env = os.environ.copy()
 
     # this part is platform-specific
     if mozinfo.os == 'win':
         param2 = '""' + param.replace('\\', '\\\\\\') + ' ' + \
                  ' '.join(mitmproxy_recordings).replace('\\', '\\\\\\') + '""'
-        env = os.environ.copy()
         sys.path.insert(1, mitmdump_path)
         # mitmproxy needs some DLL's that are a part of Firefox itself, so add to path
         env["PATH"] = os.path.dirname(browser_path) + ";" + env["PATH"]
+    elif mozinfo.os == 'mac':
+        param2 = param + ' ' + ' '.join(mitmproxy_recordings)
+        env["PATH"] = os.path.dirname(browser_path)
     else:
         # TODO: support other platforms, Bug 1366355
-        LOG.error('Aborting: talos mitmproxy is currently only supported on Windows')
+        LOG.error('Aborting: talos mitmproxy is currently only supported on Windows and Mac')
         sys.exit()
 
     command = [mitmdump_path, '-k', '-s', param2]
 
     LOG.info("Starting mitmproxy playback using env path: %s" % env["PATH"])
     LOG.info("Starting mitmproxy playback using command: %s" % ' '.join(command))
     # to turn off mitmproxy log output, use these params for Popen:
     # Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, env=env)
     mitmproxy_proc = subprocess.Popen(command, env=env)
-    time.sleep(5)
+    time.sleep(10)
     data = mitmproxy_proc.poll()
     if data is None:
         LOG.info("Mitmproxy playback successfully started as pid %d" % mitmproxy_proc.pid)
         return mitmproxy_proc
     # cannot continue as we won't be able to playback the pages
     LOG.error('Aborting: mitmproxy playback process failed to start, poll returned: %s' % data)
     sys.exit()
 
 
 def stop_mitmproxy_playback(mitmproxy_proc):
     """Stop the mitproxy server playback"""
     LOG.info("Stopping mitmproxy playback, klling process %d" % mitmproxy_proc.pid)
-    mitmproxy_proc.kill()
-    time.sleep(5)
-    exit_code = mitmproxy_proc.poll()
-    if exit_code:
-        LOG.info("Successfully killed the mitmproxy playback process")
+    if mozinfo.os == 'mac':
+        mitmproxy_proc.terminate()
     else:
+        mitmproxy_proc.kill()
+    time.sleep(10)
+    if mitmproxy_proc.pid in psutil.pids():
         # I *think* we can still continue, as process will be automatically
         # killed anyway when mozharness is done (?) if not, we won't be able
         # to startup mitmxproy next time if it is already running
         LOG.error("Failed to kill the mitmproxy playback process")
+    else:
+        LOG.info("Successfully killed the mitmproxy playback process")