Backed out 2 changesets (bug 1258539) for mozharness failures a=backout
authorWes Kocher <wkocher@mozilla.com>
Fri, 29 Jul 2016 15:56:39 -0700
changeset 332502 ff43d3e4c4fc8732b460ded61155c586e9e32573
parent 332501 b9adb0648dba49e02092a473de7b89167662e4c8
child 332503 f60ec9e34d4d34958ff64d573862474dac8c0a6f
push id9858
push userjlund@mozilla.com
push dateMon, 01 Aug 2016 14:37:10 +0000
treeherdermozilla-aurora@203106ef6cb6 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbackout
bugs1258539
milestone50.0a1
backs out8322ffecd9d90d31ff451cd9763fe2cfa5ae09b4
cc2996a53b7107a36433b265318340469cc5eb6f
Backed out 2 changesets (bug 1258539) for mozharness failures a=backout Backed out changeset 8322ffecd9d9 (bug 1258539) Backed out changeset cc2996a53b71 (bug 1258539)
testing/mozharness/mozharness/base/script.py
testing/mozharness/mozharness/mozilla/testing/firefox_media_tests.py
testing/mozharness/mozharness/mozilla/testing/firefox_ui_tests.py
testing/mozharness/mozharness/mozilla/testing/talos.py
testing/mozharness/mozharness/mozilla/testing/testbase.py
testing/mozharness/mozharness/mozilla/testing/unittest.py
testing/mozharness/scripts/b2g_emulator_unittest.py
testing/mozharness/scripts/desktop_unittest.py
testing/mozharness/scripts/web_platform_tests.py
testing/mozharness/test/helper_files/archives/archive.tar
testing/mozharness/test/helper_files/archives/archive.tar.bz2
testing/mozharness/test/helper_files/archives/archive.tar.gz
testing/mozharness/test/helper_files/archives/archive.zip
testing/mozharness/test/helper_files/archives/archive_invalid_filename.zip
testing/mozharness/test/helper_files/archives/reference/bin/script.sh
testing/mozharness/test/helper_files/archives/reference/lorem.txt
testing/mozharness/test/helper_files/create_archives.sh
testing/mozharness/test/test_base_script.py
--- a/testing/mozharness/mozharness/base/script.py
+++ b/testing/mozharness/mozharness/base/script.py
@@ -10,34 +10,29 @@
 script.py, along with config.py and log.py, represents the core of
 mozharness.
 """
 
 import codecs
 from contextlib import contextmanager
 import datetime
 import errno
-import fnmatch
-import functools
 import gzip
 import inspect
-import itertools
 import os
 import platform
 import pprint
 import re
 import shutil
 import socket
 import subprocess
 import sys
-import tarfile
 import time
 import traceback
 import urllib2
-import zipfile
 import httplib
 import urlparse
 import hashlib
 if os.name == 'nt':
     try:
         import win32file
         import win32api
         PYWIN32 = True
@@ -47,20 +42,20 @@ if os.name == 'nt':
 try:
     import simplejson as json
     assert json
 except ImportError:
     import json
 
 from mozprocess import ProcessHandler
 from mozharness.base.config import BaseConfig
+from mozharness.base.errors import ZipErrorList
 from mozharness.base.log import SimpleFileLogger, MultiFileLogger, \
     LogMixin, OutputParser, DEBUG, INFO, ERROR, FATAL
 
-
 def platform_name():
     pm = PlatformMixin()
 
     if pm._is_linux() and pm._is_64_bit():
         return 'linux64'
     elif pm._is_linux() and not pm._is_64_bit():
         return 'linux'
     elif pm._is_darwin():
@@ -453,38 +448,49 @@ class ScriptMixin(PlatformMixin):
             kwargs = {"url": url, "file_name": file_name}
 
         return self.retry(
             download_func,
             kwargs=kwargs,
             **retry_args
         )
 
-    def download_unpack(self, url, extract_to, extract_dirs=None,
-                        error_level=FATAL):
-        """Generic method to download and extract a compressed file.
+    def download_unzip(self, url, parent_dir, target_unzip_dirs=None, halt_on_failure=True):
+        """Generic method to download and extract a zip file.
 
         The downloaded file will always be saved to the working directory and is not getting
         deleted after extracting.
 
         Args:
             url (str): URL where the file to be downloaded is located.
-            extract_to (str): directory where the downloaded file will
+            parent_dir (str): directory where the downloaded file will
                               be extracted to.
-            extract_dirs (list, optional): directories inside the archive to extract.
-                                           Defaults to `None`.
-            error_level (str, optional): log level to use in case an error occurs.
-                                         Defaults to `FATAL`.
+            target_unzip_dirs (list, optional): directories inside the zip file to extract.
+                                                Defaults to `None`.
+            halt_on_failure (bool, optional): whether or not to redefine the
+                                              log level as `FATAL` on errors. Defaults to True.
 
         """
         dirs = self.query_abs_dirs()
-        archive = self.download_file(url, parent_dir=dirs['abs_work_dir'],
-                                     error_level=error_level)
-        self.unpack(archive, extract_to, extract_dirs=extract_dirs,
-                    error_level=error_level)
+        zipfile = self.download_file(url, parent_dir=dirs['abs_work_dir'],
+                                     error_level=FATAL)
+
+        command = self.query_exe('unzip', return_type='list')
+        # Always overwrite to not get an input in a hidden pipe if files already exist
+        command.extend(['-q', '-o', zipfile, '-d', parent_dir])
+        if target_unzip_dirs:
+            command.extend(target_unzip_dirs)
+        # TODO error_list: http://www.info-zip.org/mans/unzip.html#DIAGNOSTICS
+        # unzip return code 11 is 'no matching files were found'
+        self.run_command(command,
+                         error_list=ZipErrorList,
+                         halt_on_failure=halt_on_failure,
+                         fatal_exit_code=3,
+                         success_codes=[0, 11],
+                         )
 
     def load_json_url(self, url, error_level=None, *args, **kwargs):
         """ Returns a json object from a url (it retries). """
         contents = self._retry_download(
             url=url, error_level=error_level, *args, **kwargs
         )
         return json.loads(contents.read())
 
@@ -1094,17 +1100,17 @@ class ScriptMixin(PlatformMixin):
             throw_exception (bool, optional): whether or not to raise an
               exception if the return value of the command doesn't match
               any of the `success_codes`. Defaults to False.
             output_parser (OutputParser, optional): lets you provide an
               instance of your own OutputParser subclass. Defaults to `OutputParser`.
             output_timeout (int): amount of seconds to wait for output before
               the process is killed.
             fatal_exit_code (int, optional): call `self.fatal` if the return value
-              of the command is not in `success_codes`. Defaults to 2.
+              of the command is not on in `success_codes`. Defaults to 2.
             error_level (str, optional): log level name to use on error. Defaults
               to `ERROR`.
             **kwargs: Arbitrary keyword arguments.
 
         Returns:
             int: -1 on error.
             Any: `command` return value is returned otherwise.
         """
@@ -1386,79 +1392,36 @@ class ScriptMixin(PlatformMixin):
         except OSError:
             try:
                 open(file_name, 'w').close()
             except IOError as e:
                 msg = "I/O error(%s): %s" % (e.errno, e.strerror)
                 self.log(msg, error_level=error_level)
         os.utime(file_name, times)
 
-    def unpack(self, filename, extract_to, extract_dirs=None,
-               error_level=ERROR, fatal_exit_code=2, verbose=False):
-        """The method allows to extract a file regardless of its extension.
+    def unpack(self, filename, extract_to):
+        '''
+        This method allows us to extract a file regardless of its extension
 
         Args:
             filename (str): filename of the compressed file.
             extract_to (str): where to extract the compressed file.
-            extract_dirs (list, optional): directories inside the archive file to extract.
-                                           Defaults to `None`.
-            fatal_exit_code (int, optional): call `self.fatal` if the return value
-              of the command is not in `success_codes`. Defaults to 2.
-            verbose (bool, optional): whether or not extracted content should be displayed.
-                                      Defaults to False.
-
-        Raises:
-            IOError: on `filename` file not found.
-
-        """
-        def _filter_entries(namelist):
-            """Filter entries of the archive based on the specified list of to extract dirs."""
-            filter_partial = functools.partial(fnmatch.filter, namelist)
-            for entry in itertools.chain(*map(filter_partial, extract_dirs or ['*'])):
-                yield entry
-
-        if not os.path.isfile(filename):
-            raise IOError('Could not find file to extract: %s' % filename)
-
-        if zipfile.is_zipfile(filename):
-            try:
-                self.info('Using ZipFile to extract {} to {}'.format(filename, extract_to))
-                with zipfile.ZipFile(filename) as bundle:
-                    for entry in _filter_entries(bundle.namelist()):
-                        if verbose:
-                            self.info(' %s' % entry)
-                        bundle.extract(entry, path=extract_to)
-
-                        # ZipFile doesn't preserve permissions during extraction:
-                        # http://bugs.python.org/issue15795
-                        fname = os.path.realpath(os.path.join(extract_to, entry))
-                        mode = bundle.getinfo(entry).external_attr >> 16 & 0x1FF
-                        # Only set permissions if attributes are available. Otherwise all
-                        # permissions will be removed eg. on Windows.
-                        if mode:
-                            os.chmod(fname, mode)
-            except zipfile.BadZipfile as e:
-                self.log('%s (%s)' % (e.message, filename),
-                         level=error_level, exit_code=fatal_exit_code)
-
-        # Bug 1211882 - is_tarfile cannot be trusted for dmg files
-        elif tarfile.is_tarfile(filename) and not filename.lower().endswith('.dmg'):
-            try:
-                self.info('Using TarFile to extract {} to {}'.format(filename, extract_to))
-                with tarfile.open(filename) as bundle:
-                    for entry in _filter_entries(bundle.getnames()):
-                        if verbose:
-                            self.info(' %s' % entry)
-                        bundle.extract(entry, path=extract_to)
-            except tarfile.TarError as e:
-                self.log('%s (%s)' % (e.message, filename),
-                         level=error_level, exit_code=fatal_exit_code)
+        '''
+        # XXX: Make sure that filename has a extension of one of our supported file formats
+        m = re.search('\.tar\.(bz2|gz)$', filename)
+        if m:
+            command = self.query_exe('tar', return_type='list')
+            tar_cmd = "jxfv"
+            if m.group(1) == "gz":
+                tar_cmd = "zxfv"
+            command.extend([tar_cmd, filename, "-C", extract_to])
+            self.run_command(command, halt_on_failure=True)
         else:
-            self.log('No extraction method found for: %s' % filename,
-                     level=error_level, exit_code=fatal_exit_code)
+            # XXX implement
+            pass
 
 
 def PreScriptRun(func):
     """Decorator for methods that will be called before script execution.
 
     Each method on a BaseScript having this decorator will be called at the
     beginning of BaseScript.run().
 
--- a/testing/mozharness/mozharness/mozilla/testing/firefox_media_tests.py
+++ b/testing/mozharness/mozharness/mozilla/testing/firefox_media_tests.py
@@ -158,24 +158,25 @@ class FirefoxMediaTestsBase(TestingMixin
 
     def download_and_extract(self):
         """Overriding method from TestingMixin for more specific behavior.
 
         We use the test_packages_url command line argument to check where to get the
         harness, puppeteer, and tests from and how to set them up.
 
         """
-        extract_dirs = ['config/*',
-                        'external-media-tests/*',
-                        'marionette/*',
-                        'mozbase/*',
-                        'puppeteer/*',
-                        'tools/wptserve/*',
-                        ]
-        super(FirefoxMediaTestsBase, self).download_and_extract(extract_dirs=extract_dirs)
+        target_unzip_dirs = ['config/*',
+                             'external-media-tests/*',
+                             'marionette/*',
+                             'mozbase/*',
+                             'puppeteer/*',
+                             'tools/wptserve/*',
+                             ]
+        super(FirefoxMediaTestsBase, self).download_and_extract(
+                target_unzip_dirs=target_unzip_dirs)
 
     def query_abs_dirs(self):
         if self.abs_dirs:
             return self.abs_dirs
         abs_dirs = super(FirefoxMediaTestsBase, self).query_abs_dirs()
         dirs = {
             'abs_test_install_dir' : os.path.join(abs_dirs['abs_work_dir'],
                                                     'tests')
--- a/testing/mozharness/mozharness/mozilla/testing/firefox_ui_tests.py
+++ b/testing/mozharness/mozharness/mozilla/testing/firefox_ui_tests.py
@@ -148,24 +148,24 @@ class FirefoxUITests(TestingMixin, VCSTo
 
     def download_and_extract(self):
         """Overriding method from TestingMixin for more specific behavior.
 
         We use the test_packages_url command line argument to check where to get the
         harness, puppeteer, and tests from and how to set them up.
 
         """
-        extract_dirs = ['config/*',
-                        'firefox-ui/*',
-                        'marionette/*',
-                        'mozbase/*',
-                        'puppeteer/*',
-                        'tools/wptserve/*',
-                        ]
-        super(FirefoxUITests, self).download_and_extract(extract_dirs=extract_dirs)
+        target_unzip_dirs = ['config/*',
+                             'firefox-ui/*',
+                             'marionette/*',
+                             'mozbase/*',
+                             'puppeteer/*',
+                             'tools/wptserve/*',
+                             ]
+        super(FirefoxUITests, self).download_and_extract(target_unzip_dirs=target_unzip_dirs)
 
     def query_abs_dirs(self):
         if self.abs_dirs:
             return self.abs_dirs
 
         abs_dirs = super(FirefoxUITests, self).query_abs_dirs()
         abs_tests_install_dir = os.path.join(abs_dirs['abs_work_dir'], 'tests')
 
@@ -294,16 +294,63 @@ class FirefoxUITests(TestingMixin, VCSTo
 
     def run_tests(self):
         """Run all the tests"""
         return self.run_test(
             binary_path=self.binary_path,
             env=self.query_env(),
         )
 
+    def download_unzip(self, url, parent_dir, target_unzip_dirs=None, halt_on_failure=True):
+        """Overwritten method from BaseScript until bug 1258539 is fixed.
+
+        The downloaded file will always be saved to the working directory and is not getting
+        deleted after extracting.
+
+        Args:
+            url (str): URL where the file to be downloaded is located.
+            parent_dir (str): directory where the downloaded file will
+                              be extracted to.
+            target_unzip_dirs (list, optional): directories inside the zip file to extract.
+                                                Defaults to `None`.
+            halt_on_failure (bool, optional): whether or not to redefine the
+                                              log level as `FATAL` on errors. Defaults to True.
+
+        """
+        import fnmatch
+        import itertools
+        import functools
+        import zipfile
+
+        def _filter_entries(namelist):
+            """Filter entries of the archive based on the specified list of extract_dirs."""
+            filter_partial = functools.partial(fnmatch.filter, namelist)
+            for entry in itertools.chain(*map(filter_partial, target_unzip_dirs or ['*'])):
+                yield entry
+
+        dirs = self.query_abs_dirs()
+        zip = self.download_file(url, parent_dir=dirs['abs_work_dir'],
+                                 error_level=FATAL)
+
+        try:
+            self.info('Using ZipFile to extract {0} to {1}'.format(zip, parent_dir))
+            with zipfile.ZipFile(zip) as bundle:
+                for entry in _filter_entries(bundle.namelist()):
+                    bundle.extract(entry, path=parent_dir)
+
+                    # ZipFile doesn't preserve permissions: http://bugs.python.org/issue15795
+                    fname = os.path.realpath(os.path.join(parent_dir, entry))
+                    mode = bundle.getinfo(entry).external_attr >> 16 & 0x1FF
+                    # Only set permissions if attributes are available.
+                    if mode:
+                        os.chmod(fname, mode)
+        except zipfile.BadZipfile as e:
+            self.log('{0} ({1})'.format(e.message, zip),
+                     level=FATAL, exit_code=2)
+
 
 class FirefoxUIFunctionalTests(FirefoxUITests):
 
     cli_script = 'cli_functional.py'
     default_tests = [
         os.path.join('puppeteer', 'manifest.ini'),
         os.path.join('functional', 'manifest.ini'),
     ]
--- a/testing/mozharness/mozharness/mozilla/testing/talos.py
+++ b/testing/mozharness/mozharness/mozilla/testing/talos.py
@@ -282,23 +282,23 @@ class Talos(TestingMixin, MercurialScrip
         if c.get('run_local'):
             self.talos_path = os.path.dirname(self.talos_json)
 
         src_talos_webdir = os.path.join(self.talos_path, 'talos')
 
         if self.query_pagesets_url():
             self.info("Downloading pageset...")
             src_talos_pageset = os.path.join(src_talos_webdir, 'tests')
-            self.download_unpack(self.pagesets_url, src_talos_pageset)
+            self.download_unzip(self.pagesets_url, src_talos_pageset)
 
     # Action methods. {{{1
     # clobber defined in BaseScript
     # read_buildbot_config defined in BuildbotMixin
 
-    def download_and_extract(self, extract_dirs=None, suite_categories=None):
+    def download_and_extract(self, target_unzip_dirs=None, suite_categories=None):
         return super(Talos, self).download_and_extract(
             suite_categories=['common', 'talos']
         )
 
     def create_virtualenv(self, **kwargs):
         """VirtualenvMixin.create_virtualenv() assuemes we're using
         self.config['virtualenv_modules']. Since we are installing
         talos from its source, we have to wrap that method here."""
--- a/testing/mozharness/mozharness/mozilla/testing/testbase.py
+++ b/testing/mozharness/mozharness/mozilla/testing/testbase.py
@@ -396,16 +396,27 @@ You can set this by:
 
 1. specifying --test-url URL, or
 2. running via buildbot and running the read-buildbot-config action
 
 """
         if message:
             self.fatal(message + "Can't run download-and-extract... exiting")
 
+        if self.config.get("developer_mode") and self._is_darwin():
+            # Bug 1066700 only affects Mac users that try to run mozharness locally
+            version = self._query_binary_version(
+                    regex=re.compile("UnZip\ (\d+\.\d+)\ .*", re.MULTILINE),
+                    cmd=[self.query_exe('unzip'), '-v']
+            )
+            if not version >= 6:
+                self.fatal("We require a more recent version of unzip to unpack our tests.zip files.\n"
+                        "You are currently using version %s. Please update to at least 6.0.\n"
+                        "You can visit http://www.info-zip.org/UnZip.html" % version)
+
     def _read_packages_manifest(self):
         dirs = self.query_abs_dirs()
         source = self.download_file(self.test_packages_url,
                                     parent_dir=dirs['abs_work_dir'],
                                     error_level=FATAL)
 
         with self.opened(os.path.realpath(source)) as (fh, err):
             package_requirements = json.load(fh)
@@ -413,17 +424,17 @@ 2. running via buildbot and running the 
                 self.fatal("There was an error reading test package requirements from %s "
                            "requirements: `%s` - error: `%s`" % (source,
                                                                  package_requirements or 'None',
                                                                  err or 'No error'))
         self.info("Using the following test package requirements:\n%s" %
                   pprint.pformat(package_requirements))
         return package_requirements
 
-    def _download_test_packages(self, suite_categories, extract_dirs):
+    def _download_test_packages(self, suite_categories, target_unzip_dirs):
         # Some platforms define more suite categories/names than others.
         # This is a difference in the convention of the configs more than
         # to how these tests are run, so we pave over these differences here.
         aliases = {
             'robocop': 'mochitest',
             'mochitest-chrome': 'mochitest',
             'mochitest-media': 'mochitest',
             'mochitest-plain-clipboard': 'mochitest',
@@ -449,31 +460,31 @@ 2. running via buildbot and running the 
                 # If we don't harness specific requirements, assume the common zip
                 # has everything we need to run tests for this suite.
                 target_packages = package_requirements['common']
 
             self.info("Downloading packages: %s for test suite category: %s" %
                       (target_packages, category))
             for file_name in target_packages:
                 target_dir = test_install_dir
-                unpack_dirs = extract_dirs
+                unzip_dirs = target_unzip_dirs
                 if "jsshell-" in file_name or file_name == "target.jsshell.zip":
                     self.info("Special-casing the jsshell zip file")
-                    unpack_dirs = None
+                    unzip_dirs = None
                     target_dir = dirs['abs_test_bin_dir']
                 url = self.query_build_dir_url(file_name)
-                self.download_unpack(url, target_dir,
-                                     extract_dirs=unpack_dirs)
+                self.download_unzip(url, target_dir,
+                                     target_unzip_dirs=unzip_dirs)
 
-    def _download_test_zip(self, extract_dirs=None):
+    def _download_test_zip(self, target_unzip_dirs=None):
         dirs = self.query_abs_dirs()
         test_install_dir = dirs.get('abs_test_install_dir',
                                     os.path.join(dirs['abs_work_dir'], 'tests'))
-        self.download_unpack(self.test_url, test_install_dir,
-                             extract_dirs=extract_dirs)
+        self.download_unzip(self.test_url, test_install_dir,
+                             target_unzip_dirs=target_unzip_dirs)
 
     def structured_output(self, suite_category):
         """Defines whether structured logging is in use in this configuration. This
         may need to be replaced with data from a different config at the resolution
         of bug 1070041 and related bugs.
         """
         return ('structured_suites' in self.config and
                 suite_category in self.config['structured_suites'])
@@ -510,19 +521,19 @@ 2. running via buildbot and running the 
         if self.config.get('download_symbols') == 'ondemand':
             self.symbols_path = self.symbols_url
             return
         if not self.symbols_path:
             self.symbols_path = os.path.join(dirs['abs_work_dir'], 'symbols')
 
         self.set_buildbot_property("symbols_url", self.symbols_url,
                                    write_to_file=True)
-        self.download_unpack(self.symbols_url, self.symbols_path)
+        self.download_unzip(self.symbols_url, self.symbols_path)
 
-    def download_and_extract(self, extract_dirs=None, suite_categories=None):
+    def download_and_extract(self, target_unzip_dirs=None, suite_categories=None):
         """
         download and extract test zip / download installer
         """
         # Swap plain http for https when we're downloading from ftp
         # See bug 957502 and friends
         from_ = "http://ftp.mozilla.org"
         to_ = "https://ftp-ssl.mozilla.org"
         for attr in 'symbols_url', 'installer_url', 'test_packages_url', 'test_url':
@@ -535,27 +546,27 @@ 2. running via buildbot and running the 
         if 'test_url' in self.config:
             # A user has specified a test_url directly, any test_packages_url will
             # be ignored.
             if self.test_packages_url:
                 self.error('Test data will be downloaded from "%s", the specified test '
                            ' package data at "%s" will be ignored.' %
                            (self.config.get('test_url'), self.test_packages_url))
 
-            self._download_test_zip(extract_dirs)
+            self._download_test_zip(target_unzip_dirs)
         else:
             if not self.test_packages_url:
                 # The caller intends to download harness specific packages, but doesn't know
                 # where the packages manifest is located. This is the case when the
                 # test package manifest isn't set as a buildbot property, which is true
                 # for some self-serve jobs and platforms using parse_make_upload.
                 self.test_packages_url = self.query_prefixed_build_dir_url('.test_packages.json')
 
             suite_categories = suite_categories or ['common']
-            self._download_test_packages(suite_categories, extract_dirs)
+            self._download_test_packages(suite_categories, target_unzip_dirs)
 
         self._download_installer()
         if self.config.get('download_symbols'):
             self._download_and_extract_symbols()
 
     # create_virtualenv is in VirtualenvMixin.
 
     def preflight_install(self):
--- a/testing/mozharness/mozharness/mozilla/testing/unittest.py
+++ b/testing/mozharness/mozharness/mozilla/testing/unittest.py
@@ -230,17 +230,17 @@ class EmulatorMixin(object):
             unzip_cmd = [unzip, '-q', os.path.join(dirs['abs_work_dir'], "emulator.zip")]
             self.run_command(unzip_cmd, cwd=dirs['abs_emulator_dir'], halt_on_failure=True,
                              fatal_exit_code=3)
 
     def install_emulator(self):
         dirs = self.query_abs_dirs()
         self.mkdir_p(dirs['abs_emulator_dir'])
         if self.config.get('emulator_url'):
-            self.download_unpack(self.config['emulator_url'], dirs['abs_emulator_dir'])
+            self.download_unzip(self.config['emulator_url'], dirs['abs_emulator_dir'])
         elif self.config.get('emulator_manifest'):
             manifest_path = self.create_tooltool_manifest(self.config['emulator_manifest'])
             do_unzip = True
             if 'unpack' in self.config['emulator_manifest']:
                 do_unzip = False
             self.install_emulator_from_tooltool(manifest_path, do_unzip)
         elif self.buildbot_config:
             props = self.buildbot_config.get('properties')
--- a/testing/mozharness/scripts/b2g_emulator_unittest.py
+++ b/testing/mozharness/scripts/b2g_emulator_unittest.py
@@ -206,17 +206,18 @@ class B2GEmulatorTest(TestingMixin, VCSM
 
         self.mkdir_p(dirs['abs_emulator_dir'])
         tar = self.query_exe('tar', return_type='list')
         self.run_command(tar + ['zxf', self.installer_path],
                          cwd=dirs['abs_emulator_dir'],
                          error_list=TarErrorList,
                          halt_on_failure=True, fatal_exit_code=3)
 
-        self.download_unpack(self.config['xre_url'], dirs['abs_xre_dir'])
+        self.download_unzip(self.config['xre_url'],
+                             dirs['abs_xre_dir'])
 
         if self.config.get('busybox_url'):
             self.download_file(self.config['busybox_url'],
                                file_name='busybox',
                                parent_dir=dirs['abs_work_dir'])
             self.busybox_path = os.path.join(dirs['abs_work_dir'], 'busybox')
 
     @PreScriptAction('create-virtualenv')
--- a/testing/mozharness/scripts/desktop_unittest.py
+++ b/testing/mozharness/scripts/desktop_unittest.py
@@ -474,30 +474,30 @@ class DesktopUnittest(TestingMixin, Merc
 
     def download_and_extract(self):
         """
         download and extract test zip / download installer
         optimizes which subfolders to extract from tests zip
         """
         c = self.config
 
-        extract_dirs = None
+        target_unzip_dirs = None
         if c['specific_tests_zip_dirs']:
-            extract_dirs = list(c['minimum_tests_zip_dirs'])
+            target_unzip_dirs = list(c['minimum_tests_zip_dirs'])
             for category in c['specific_tests_zip_dirs'].keys():
                 if c['run_all_suites'] or self._query_specified_suites(category) \
                         or 'run-tests' not in self.actions:
-                    extract_dirs.extend(c['specific_tests_zip_dirs'][category])
+                    target_unzip_dirs.extend(c['specific_tests_zip_dirs'][category])
 
         if c.get('run_all_suites'):
             target_categories = SUITE_CATEGORIES
         else:
             target_categories = [cat for cat in SUITE_CATEGORIES
                                  if self._query_specified_suites(cat) is not None]
-        super(DesktopUnittest, self).download_and_extract(extract_dirs=extract_dirs,
+        super(DesktopUnittest, self).download_and_extract(target_unzip_dirs=target_unzip_dirs,
                                                           suite_categories=target_categories)
 
     def stage_files(self):
         for category in SUITE_CATEGORIES:
             suites = self._query_specified_suites(category)
             stage = getattr(self, '_stage_{}'.format(category), None)
             if suites and stage:
                 stage(suites)
--- a/testing/mozharness/scripts/web_platform_tests.py
+++ b/testing/mozharness/scripts/web_platform_tests.py
@@ -161,22 +161,22 @@ class WebPlatformTest(TestingMixin, Merc
                                       str_format_values=str_format_values))
         cmd.extend(self.query_tests_args(try_tests,
                                          str_format_values=str_format_values))
 
         return cmd
 
     def download_and_extract(self):
         super(WebPlatformTest, self).download_and_extract(
-            extract_dirs=["bin/*",
-                          "config/*",
-                          "mozbase/*",
-                          "marionette/*",
-                          "tools/wptserve/*",
-                          "web-platform/*"],
+            target_unzip_dirs=["bin/*",
+                               "config/*",
+                               "mozbase/*",
+                               "marionette/*",
+                               "tools/wptserve/*",
+                               "web-platform/*"],
             suite_categories=["web-platform"])
 
     def run_tests(self):
         dirs = self.query_abs_dirs()
         cmd = self._query_cmd()
 
         parser = StructuredOutputParser(config=self.config,
                                         log_obj=self.log_obj,
deleted file mode 100644
index c34000ebe229e790837d7f582e4397c3dbd96080..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
literal 0
Hc$@<O00001
deleted file mode 100644
index 969e6de4447ff5a99c1a355108a643899e8ace17..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
literal 0
Hc$@<O00001
deleted file mode 100644
index 7ddfe68015d5a5c27c1464540949ecc3fad06c55..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
literal 0
Hc$@<O00001
deleted file mode 100644
index 118be7a48e2a7292f0a99a0d3a0d3f36910cd464..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
literal 0
Hc$@<O00001
deleted file mode 100644
index 20bdc5acdf11e3c466c5b59090d1aaa52b721d31..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
literal 0
Hc$@<O00001
deleted file mode 100755
--- a/testing/mozharness/test/helper_files/archives/reference/bin/script.sh
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/bin/bash
-
-echo Hello world!
deleted file mode 100644
--- a/testing/mozharness/test/helper_files/archives/reference/lorem.txt
+++ /dev/null
@@ -1,1 +0,0 @@
-Lorem ipsum dolor sit amet.
deleted file mode 100755
--- a/testing/mozharness/test/helper_files/create_archives.sh
+++ /dev/null
@@ -1,11 +0,0 @@
-#!/bin/bash
-# Script to auto-generate the different archive types under the archives directory.
-
-cd archives
-
-rm archive.*
-
-tar cf archive.tar -C reference .
-gzip -fk archive.tar >archive.tar.gz
-bzip2 -fk archive.tar >archive.tar.bz2
-cd reference && zip ../archive.zip -r * && cd ..
--- a/testing/mozharness/test/test_base_script.py
+++ b/testing/mozharness/test/test_base_script.py
@@ -1,14 +1,12 @@
 import gc
 import mock
 import os
 import re
-import shutil
-import tempfile
 import types
 import unittest
 PYWIN32 = False
 if os.name == 'nt':
     try:
         import win32file
         PYWIN32 = True
     except:
@@ -16,37 +14,32 @@ if os.name == 'nt':
 
 
 import mozharness.base.errors as errors
 import mozharness.base.log as log
 from mozharness.base.log import DEBUG, INFO, WARNING, ERROR, CRITICAL, FATAL, IGNORE
 import mozharness.base.script as script
 from mozharness.base.config import parse_config_file
 
-
-here = os.path.dirname(os.path.abspath(__file__))
-
 test_string = '''foo
 bar
 baz'''
 
 
 class CleanupObj(script.ScriptMixin, log.LogMixin):
     def __init__(self):
         super(CleanupObj, self).__init__()
         self.log_obj = None
         self.config = {'log_level': ERROR}
 
 
-def cleanup(files=None):
-    files = files or []
-    files.extend(('test_logs', 'test_dir', 'tmpfile_stdout', 'tmpfile_stderr'))
+def cleanup():
     gc.collect()
     c = CleanupObj()
-    for f in files:
+    for f in ('test_logs', 'test_dir', 'tmpfile_stdout', 'tmpfile_stderr'):
         c.rmtree(f)
 
 
 def get_debug_script_obj():
     s = script.BaseScript(config={'log_type': 'multi',
                                   'log_level': DEBUG},
                           initial_config_file='test/test.json')
     return s
@@ -58,23 +51,22 @@ def _post_fatal(self, **kwargs):
     fh.close()
 
 
 # TestScript {{{1
 class TestScript(unittest.TestCase):
     def setUp(self):
         cleanup()
         self.s = None
-        self.tmpdir = tempfile.mkdtemp(suffix='.mozharness')
 
     def tearDown(self):
         # Close the logfile handles, or windows can't remove the logs
         if hasattr(self, 's') and isinstance(self.s, object):
             del(self.s)
-        cleanup([self.tmpdir])
+        cleanup()
 
     # test _dump_config_hierarchy() when --dump-config-hierarchy is passed
     def test_dump_config_hierarchy_valid_files_len(self):
         try:
             self.s = script.BaseScript(
                 initial_config_file='test/test.json',
                 option_args=['--cfg', 'test/test_override.py,test/test_override2.py'],
                 config={'dump_config_hierarchy': True}
@@ -254,48 +246,16 @@ class TestScript(unittest.TestCase):
                 'regex': re.compile(',$'), 'level': IGNORE,
             }, {
                 'substr': ']$', 'level': WARNING,
             }])
         error_logsize = os.path.getsize("test_logs/test_error.log")
         self.assertTrue(error_logsize > 0,
                         msg="error list not working properly")
 
-    def test_unpack(self):
-        self.s = get_debug_script_obj()
-
-        archives_path = os.path.join(here, 'helper_files', 'archives')
-
-        # Test basic decompression
-        for archive in ('archive.tar', 'archive.tar.bz2', 'archive.tar.gz', 'archive.zip'):
-            self.s.unpack(os.path.join(archives_path, archive), self.tmpdir)
-            self.assertIn('script.sh', os.listdir(os.path.join(self.tmpdir, 'bin')))
-            self.assertIn('lorem.txt', os.listdir(self.tmpdir))
-            shutil.rmtree(self.tmpdir)
-
-        # Test permissions for extracted entries from zip archive
-        self.s.unpack(os.path.join(archives_path, 'archive.zip'), self.tmpdir)
-        file_stats = os.stat(os.path.join(self.tmpdir, 'bin', 'script.sh'))
-        orig_fstats = os.stat(os.path.join(archives_path, 'reference', 'bin', 'script.sh'))
-        self.assertEqual(file_stats.st_mode, orig_fstats.st_mode)
-        shutil.rmtree(self.tmpdir)
-
-        # Test extract specific dirs only
-        self.s.unpack(os.path.join(archives_path, 'archive.zip'), self.tmpdir,
-                      extract_dirs=['bin/*'])
-        self.assertIn('bin', os.listdir(self.tmpdir))
-        self.assertNotIn('lorem.txt', os.listdir(self.tmpdir))
-        shutil.rmtree(self.tmpdir)
-
-        # Test for invalid filenames (Windows only)
-        if PYWIN32:
-            with self.assertRaises(IOError):
-                self.s.unpack(os.path.join(archives_path, 'archive_invalid_filename.zip'),
-                              self.tmpdir)
-
 
 # TestHelperFunctions {{{1
 class TestHelperFunctions(unittest.TestCase):
     temp_file = "test_dir/mozilla"
 
     def setUp(self):
         cleanup()
         self.s = None