Bug 650887 - desktop talos runner in mozharness;r=aki
authorJeff Hammel <jhammel@mozilla.com>
Mon, 14 Nov 2011 11:34:29 -0800
changeset 582 1d1144817b2a96afcde0090872a1727b20d9abbd
parent 581 8a7bf13d27e4852cb306037196f70d4cccd7d400
child 583 3efc12f56e35cb2395180acb68c7a9805adcb192
push id116
push userjhammel@mozilla.com
push dateMon, 14 Nov 2011 19:34:54 +0000
reviewersaki
bugs650887
Bug 650887 - desktop talos runner in mozharness;r=aki
mozharness/base/log.py
mozharness/base/script.py
scripts/peptest.py
scripts/talos_script.py
--- a/mozharness/base/log.py
+++ b/mozharness/base/log.py
@@ -52,17 +52,16 @@ import traceback
 FATAL_LEVEL = logging.CRITICAL + 10
 logging.addLevelName(FATAL_LEVEL, 'FATAL')
 
 # mozharness log levels.
 DEBUG, INFO, WARNING, ERROR, CRITICAL, FATAL, IGNORE = (
     'debug', 'info', 'warning', 'error', 'critical', 'fatal', 'ignore')
 
 
-
 # LogMixin {{{1
 class LogMixin(object):
     """This is a mixin for any object to access similar logging
     functionality -- more so, of course, for those objects with
     self.config and self.log_obj, of course.
     """
 
     def _log_level_at_least(self, level):
--- a/mozharness/base/script.py
+++ b/mozharness/base/script.py
@@ -599,16 +599,23 @@ class BaseScript(ShellMixin, OSMixin, Lo
         for log_name in self.log_obj.log_files.keys():
             log_file = self.log_obj.log_files[log_name]
             self.copy_to_upload_dir(os.path.join(dirs['abs_log_dir'], log_file),
                                     dest=os.path.join('logs', log_file),
                                     short_desc='%s log' % log_name,
                                     long_desc='%s log' % log_name)
         sys.exit(self.return_code)
 
+    def clobber(self):
+        """
+        Delete the working directory
+        """
+        dirs = self.query_abs_dirs()
+        self.rmtree(dirs['abs_work_dir'])
+        
     def query_abs_dirs(self):
         if self.abs_dirs:
             return self.abs_dirs
         c = self.config
         dirs = {}
         dirs['abs_work_dir'] = os.path.join(c['base_work_dir'], c['work_dir'])
         dirs['abs_upload_dir'] = os.path.join(dirs['abs_work_dir'], 'upload')
         dirs['abs_log_dir'] = os.path.join(c['base_work_dir'], c.get('log_dir', 'logs'))
@@ -729,12 +736,11 @@ class BaseScript(ShellMixin, OSMixin, Lo
         self.copyfile(target, dest)
         if os.path.exists(dest):
             return dest
         else:
             self.log("%s doesn't exist after copy!" % dest, level=error_level)
             return None
 
 
-
 # __main__ {{{1
 if __name__ == '__main__':
     pass
--- a/scripts/peptest.py
+++ b/scripts/peptest.py
@@ -163,23 +163,16 @@ class PepTest(VirtualenvMixin, BaseScrip
             peptest = self.extract(peptest, delete=True, error_level=FATAL)[0]
 
         python = self.query_python_path()
         self.run_command(python + " setup.py install",
                          cwd=peptest,
                          error_list=PythonErrorList)
         self.rmtree(peptest)
 
-    def clobber(self):
-        """
-        Delete the working directory
-        """
-        dirs = self.query_abs_dirs()
-        self.rmtree(dirs['abs_work_dir'])
-
     def get_latest_tinderbox(self):
         """
         Find the url to the latest-tinderbox build and
         point the appname at it
         """
         if not self.query_python_path():
             self.create_virtualenv()
         dirs = self.query_abs_dirs()
new file mode 100644
--- /dev/null
+++ b/scripts/talos_script.py
@@ -0,0 +1,140 @@
+#!/usr/bin/env python
+
+"""
+run talos test suites in a virtualenv
+"""
+
+import os
+import subprocess
+import sys
+import urllib2
+
+from mozharness.base.log import DEBUG, INFO, WARNING, ERROR, CRITICAL, FATAL, IGNORE
+from mozharness.base.python import virtualenv_config_options, VirtualenvMixin
+from mozharness.base.script import BaseScript
+
+class Talos(VirtualenvMixin, BaseScript):
+    """
+    install and run Talos tests:
+    https://wiki.mozilla.org/Buildbot/Talos
+    """
+
+    config_options = [
+        [["--title"],
+         {"action": "store",
+          "dest": "title",
+          "default": None,
+          "help": "talos run title"}],
+        [["--talos-url"],
+         {"action": "store",
+          "dest": "talos_url",
+          "default": "http://hg.mozilla.org/build/talos/archive/tip.tar.gz",
+          "help": "Specify the talos package url"
+          }],
+        [["--talos-branch"],
+         {"action": "store",
+          "dest": "talos_branch",
+          "default": "Mozilla-Central",
+          "help": "Specify the branch name",
+          }],
+        [["--pyyaml-url"],
+         {"action": "store",
+          "dest": "pyyaml_url",
+          "default": "http://pypi.python.org/packages/source/P/PyYAML/PyYAML-3.10.tar.gz", # note that this is subject to package-rot
+          "help": "URL to PyYAML package"
+          }],
+        [["--pageloader-url"],
+         {"action": "store",
+          "dest": "pageloader_url",
+          "default": "http://hg.mozilla.org/build/pageloader/archive/tip.zip",
+          "help": "URL to PageLoader extension"
+          }],
+        [["-a", "--activeTests"],
+         {"action": "extend",
+          "dest": "activeTests",
+          "default": [],
+          "help": "Specify the tests to run"
+          }],
+        [["--appname"],
+         {"action": "store",
+          "dest": "appname",
+          "default": None,
+          "help": "Path to the Firefox binary to run tests on",
+          }],
+        [["--add-options"],
+          {"action": "extend",
+           "dest": "addOptions",
+           "default": None,
+           "help": "extra options to PerfConfigurator"
+           }],
+        ] + virtualenv_config_options
+
+    def __init__(self, require_config_file=False):
+        BaseScript.__init__(self,
+                            config_options=self.config_options,
+                            all_actions=['clobber',
+                                         'create-virtualenv',
+                                         'install-pageloader',
+                                         'generate-config',
+                                         'run-tests'
+                                         ],
+                            default_actions=['clobber',
+                                             'create-virtualenv',
+                                             'install-pageloader',
+                                             'generate-config',
+                                             'run-tests'
+                                             ],
+                            require_config_file=require_config_file,
+                            config={"virtualenv_modules": ["pyyaml", "talos"]},
+                            )
+
+    def _set_talos_dir(self):
+        """XXX this is required as talos must be run out of its directory"""
+        python = self.query_python_path()
+        self.talos_dir = self.get_output_from_command([python, '-c', 'import os, talos; print os.path.dirname(os.path.abspath(talos.__file__))'])
+        if not self.talos_dir:
+            self.fatal("Talos directory could not be found")
+        self.info('Talos directory: %s' % self.talos_dir)
+
+    def install_pageloader(self):
+        """install pageloader"""
+        if not hasattr(self, 'talos_dir'):
+            self._set_talos_dir()
+        dest = os.path.join(self.talos_dir, 'page_load_test', 'pageloader.xpi')
+        self.download_file(self.config['pageloader_url'], dest)
+
+    def generate_config(self):
+        """generate talos configuration"""
+
+        firefox = self.config.get('appname')
+        if not firefox:
+            self.fatal("No appname specified; please specify --appname")
+        firefox = os.path.abspath(firefox)
+        tests = self.config['activeTests']
+        if not tests:
+            self.fatal("No tests specified; please specify --activeTests")
+        tests = ':'.join(tests) # Talos expects this format
+        if not hasattr(self, 'talos_dir'):
+            self._set_talos_dir()
+        python = self.query_python_path()
+        command = [python, 'PerfConfigurator.py', '-v', '-e', firefox, '-a', tests, '--output', 'talos.yml', '-b', self.config['talos_branch'], '--branchName', self.config['talos_branch']]
+        if self.config.get('title'):
+            command += ["-t", self.config['title']]
+        if self.config.get('addOptions'):
+            command += self.config['addOptions']
+        self.run_command(command, cwd=self.talos_dir)
+        self.talos_conf = os.path.join(self.talos_dir, 'talos.yml')
+
+    def run_tests(self):
+        if not hasattr(self, 'talos_conf'):
+            self.generate_config()
+
+        # run talos tests
+        # assumes a webserver is appropriately running
+        python = self.query_python_path()
+        code = self.run_command([python, 'run_tests.py', '--noisy', self.talos_conf], cwd=self.talos_dir)
+
+
+if __name__ == '__main__':
+    talos = Talos()
+    talos.run()