testing/mozbase/mozprofile/tests/test_addons.py

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     1 #!/usr/bin/env python
     3 # This Source Code Form is subject to the terms of the Mozilla Public
     4 # License, v. 2.0. If a copy of the MPL was not distributed with this file,
     5 # You can obtain one at http://mozilla.org/MPL/2.0/.
     7 import os
     8 import shutil
     9 import tempfile
    10 import unittest
    11 import urllib2
    13 from manifestparser import ManifestParser
    14 import mozfile
    15 import mozhttpd
    16 import mozlog
    17 import mozprofile
    19 from addon_stubs import generate_addon, generate_manifest
    22 here = os.path.dirname(os.path.abspath(__file__))
    25 class TestAddonsManager(unittest.TestCase):
    26     """ Class to test mozprofile.addons.AddonManager """
    28     def setUp(self):
    29         self.logger = mozlog.getLogger('mozprofile.addons')
    30         self.logger.setLevel(mozlog.ERROR)
    32         self.profile = mozprofile.profile.Profile()
    33         self.am = self.profile.addon_manager
    35         self.profile_path = self.profile.profile
    36         self.tmpdir = tempfile.mkdtemp()
    38     def tearDown(self):
    39         mozfile.rmtree(self.tmpdir)
    41         self.am = None
    42         self.profile = None
    44         # Bug 934484
    45         # Sometimes the profile folder gets recreated at the end and will be left
    46         # behind. So we should ensure that we clean it up correctly.
    47         mozfile.rmtree(self.profile_path)
    49     def test_install_addons_multiple_same_source(self):
    50         # Generate installer stubs for all possible types of addons
    51         addon_xpi = generate_addon('test-addon-1@mozilla.org',
    52                                    path=self.tmpdir)
    53         addon_folder = generate_addon('test-addon-1@mozilla.org',
    54                                       path=self.tmpdir,
    55                                       xpi=False)
    57         # The same folder should not be installed twice
    58         self.am.install_addons([addon_folder, addon_folder])
    59         self.assertEqual(self.am.installed_addons, [addon_folder])
    60         self.am.clean()
    62         # The same XPI file should not be installed twice
    63         self.am.install_addons([addon_xpi, addon_xpi])
    64         self.assertEqual(self.am.installed_addons, [addon_xpi])
    65         self.am.clean()
    67         # Even if it is the same id the add-on should be installed twice, if
    68         # specified via XPI and folder
    69         self.am.install_addons([addon_folder, addon_xpi])
    70         self.assertEqual(len(self.am.installed_addons), 2)
    71         self.assertIn(addon_folder, self.am.installed_addons)
    72         self.assertIn(addon_xpi, self.am.installed_addons)
    73         self.am.clean()
    75     def test_download(self):
    76         server = mozhttpd.MozHttpd(docroot=os.path.join(here, 'addons'))
    77         server.start()
    79         # Download a valid add-on without a class instance to the general
    80         # tmp folder and clean-up
    81         try:
    82             addon = server.get_url() + 'empty.xpi'
    83             xpi_file = mozprofile.addons.AddonManager.download(addon)
    84             self.assertTrue(os.path.isfile(xpi_file))
    85             self.assertIn('test-empty@quality.mozilla.org.xpi',
    86                           os.path.basename(xpi_file))
    87             self.assertNotIn(self.tmpdir, os.path.dirname(xpi_file))
    88         finally:
    89             # Given that the file is stored outside of the created tmp dir
    90             # we have to ensure to explicitely remove it
    91             if os.path.isfile(xpi_file):
    92                 os.remove(xpi_file)
    94         # Download an valid add-on to a special folder
    95         addon = server.get_url() + 'empty.xpi'
    96         xpi_file = self.am.download(addon, self.tmpdir)
    97         self.assertTrue(os.path.isfile(xpi_file))
    98         self.assertIn('test-empty@quality.mozilla.org.xpi',
    99                       os.path.basename(xpi_file))
   100         self.assertIn(self.tmpdir, os.path.dirname(xpi_file))
   101         self.assertEqual(self.am.downloaded_addons, [])
   102         os.remove(xpi_file)
   104         # Download an invalid add-on to a special folder
   105         addon = server.get_url() + 'invalid.xpi'
   106         self.assertRaises(mozprofile.addons.AddonFormatError,
   107                           self.am.download, addon, self.tmpdir)
   108         self.assertEqual(os.listdir(self.tmpdir), [])
   110         # Download from an invalid URL
   111         addon = server.get_url() + 'not_existent.xpi'
   112         self.assertRaises(urllib2.HTTPError,
   113                           self.am.download, addon, self.tmpdir)
   114         self.assertEqual(os.listdir(self.tmpdir), [])
   116         # Download from an invalid URL
   117         addon = 'not_existent.xpi'
   118         self.assertRaises(ValueError,
   119                           self.am.download, addon, self.tmpdir)
   120         self.assertEqual(os.listdir(self.tmpdir), [])
   122         server.stop()
   124     def test_install_from_path_xpi(self):
   125         addons_to_install = []
   126         addons_installed = []
   128         # Generate installer stubs and install them
   129         for ext in ['test-addon-1@mozilla.org', 'test-addon-2@mozilla.org']:
   130             temp_addon = generate_addon(ext, path=self.tmpdir)
   131             addons_to_install.append(self.am.addon_details(temp_addon)['id'])
   132             self.am.install_from_path(temp_addon)
   134         # Generate a list of addons installed in the profile
   135         addons_installed = [unicode(x[:-len('.xpi')]) for x in os.listdir(os.path.join(
   136                             self.profile.profile, 'extensions', 'staged'))]
   137         self.assertEqual(addons_to_install.sort(), addons_installed.sort())
   139     def test_install_from_path_folder(self):
   140         # Generate installer stubs for all possible types of addons
   141         addons = []
   142         addons.append(generate_addon('test-addon-1@mozilla.org',
   143                                      path=self.tmpdir))
   144         addons.append(generate_addon('test-addon-2@mozilla.org',
   145                                      path=self.tmpdir,
   146                                      xpi=False))
   147         addons.append(generate_addon('test-addon-3@mozilla.org',
   148                                      path=self.tmpdir,
   149                                      name='addon-3'))
   150         addons.append(generate_addon('test-addon-4@mozilla.org',
   151                                      path=self.tmpdir,
   152                                      name='addon-4',
   153                                      xpi=False))
   154         addons.sort()
   156         self.am.install_from_path(self.tmpdir)
   158         self.assertEqual(self.am.installed_addons, addons)
   160     def test_install_from_path_unpack(self):
   161         # Generate installer stubs for all possible types of addons
   162         addon_xpi = generate_addon('test-addon-unpack@mozilla.org',
   163                                    path=self.tmpdir)
   164         addon_folder = generate_addon('test-addon-unpack@mozilla.org',
   165                                       path=self.tmpdir,
   166                                       xpi=False)
   167         addon_no_unpack = generate_addon('test-addon-1@mozilla.org',
   168                                          path=self.tmpdir)
   170         # Test unpack flag for add-on as XPI
   171         self.am.install_from_path(addon_xpi)
   172         self.assertEqual(self.am.installed_addons, [addon_xpi])
   173         self.am.clean()
   175         # Test unpack flag for add-on as folder
   176         self.am.install_from_path(addon_folder)
   177         self.assertEqual(self.am.installed_addons, [addon_folder])
   178         self.am.clean()
   180         # Test forcing unpack an add-on
   181         self.am.install_from_path(addon_no_unpack, unpack=True)
   182         self.assertEqual(self.am.installed_addons, [addon_no_unpack])
   183         self.am.clean()
   185     def test_install_from_path_url(self):
   186         server = mozhttpd.MozHttpd(docroot=os.path.join(here, 'addons'))
   187         server.start()
   189         addon = server.get_url() + 'empty.xpi'
   190         self.am.install_from_path(addon)
   192         server.stop()
   194         self.assertEqual(len(self.am.downloaded_addons), 1)
   195         self.assertTrue(os.path.isfile(self.am.downloaded_addons[0]))
   196         self.assertIn('test-empty@quality.mozilla.org.xpi',
   197                       os.path.basename(self.am.downloaded_addons[0]))
   199     def test_install_from_path_after_reset(self):
   200         # Installing the same add-on after a reset should not cause a failure
   201         addon = generate_addon('test-addon-1@mozilla.org',
   202                                path=self.tmpdir, xpi=False)
   204         # We cannot use self.am because profile.reset() creates a new instance
   205         self.profile.addon_manager.install_from_path(addon)
   207         self.profile.reset()
   209         self.profile.addon_manager.install_from_path(addon)
   210         self.assertEqual(self.profile.addon_manager.installed_addons, [addon])
   212     def test_install_from_path_backup(self):
   213         staged_path = os.path.join(self.profile_path, 'extensions', 'staged')
   215         # Generate installer stubs for all possible types of addons
   216         addon_xpi = generate_addon('test-addon-1@mozilla.org',
   217                                    path=self.tmpdir)
   218         addon_folder = generate_addon('test-addon-1@mozilla.org',
   219                                       path=self.tmpdir,
   220                                       xpi=False)
   221         addon_name = generate_addon('test-addon-1@mozilla.org',
   222                                     path=self.tmpdir,
   223                                     name='test-addon-1-dupe@mozilla.org')
   225         # Test backup of xpi files
   226         self.am.install_from_path(addon_xpi)
   227         self.assertIsNone(self.am.backup_dir)
   229         self.am.install_from_path(addon_xpi)
   230         self.assertIsNotNone(self.am.backup_dir)
   231         self.assertEqual(os.listdir(self.am.backup_dir),
   232                          ['test-addon-1@mozilla.org.xpi'])
   234         self.am.clean()
   235         self.assertEqual(os.listdir(staged_path),
   236                          ['test-addon-1@mozilla.org.xpi'])
   237         self.am.clean()
   239         # Test backup of folders
   240         self.am.install_from_path(addon_folder)
   241         self.assertIsNone(self.am.backup_dir)
   243         self.am.install_from_path(addon_folder)
   244         self.assertIsNotNone(self.am.backup_dir)
   245         self.assertEqual(os.listdir(self.am.backup_dir),
   246                          ['test-addon-1@mozilla.org'])
   248         self.am.clean()
   249         self.assertEqual(os.listdir(staged_path),
   250                          ['test-addon-1@mozilla.org'])
   251         self.am.clean()
   253         # Test backup of xpi files with another file name
   254         self.am.install_from_path(addon_name)
   255         self.assertIsNone(self.am.backup_dir)
   257         self.am.install_from_path(addon_xpi)
   258         self.assertIsNotNone(self.am.backup_dir)
   259         self.assertEqual(os.listdir(self.am.backup_dir),
   260                          ['test-addon-1@mozilla.org.xpi'])
   262         self.am.clean()
   263         self.assertEqual(os.listdir(staged_path),
   264                          ['test-addon-1@mozilla.org.xpi'])
   265         self.am.clean()
   267     def test_install_from_path_invalid_addons(self):
   268         # Generate installer stubs for all possible types of addons
   269         addons = []
   270         addons.append(generate_addon('test-addon-invalid-no-manifest@mozilla.org',
   271                       path=self.tmpdir,
   272                       xpi=False))
   273         addons.append(generate_addon('test-addon-invalid-no-id@mozilla.org',
   274                       path=self.tmpdir))
   276         self.am.install_from_path(self.tmpdir)
   278         self.assertEqual(self.am.installed_addons, [])
   280     @unittest.skip("Feature not implemented as part of AddonManger")
   281     def test_install_from_path_error(self):
   282         """ Check install_from_path raises an error with an invalid addon"""
   284         temp_addon = generate_addon('test-addon-invalid-version@mozilla.org')
   285         # This should raise an error here
   286         self.am.install_from_path(temp_addon)
   288     def test_install_from_manifest(self):
   289         temp_manifest = generate_manifest(['test-addon-1@mozilla.org',
   290                                            'test-addon-2@mozilla.org'])
   291         m = ManifestParser()
   292         m.read(temp_manifest)
   293         addons = m.get()
   295         # Obtain details of addons to install from the manifest
   296         addons_to_install = [self.am.addon_details(x['path']).get('id') for x in addons]
   298         self.am.install_from_manifest(temp_manifest)
   299         # Generate a list of addons installed in the profile
   300         addons_installed = [unicode(x[:-len('.xpi')]) for x in os.listdir(os.path.join(
   301                             self.profile.profile, 'extensions', 'staged'))]
   302         self.assertEqual(addons_installed.sort(), addons_to_install.sort())
   304         # Cleanup the temporary addon and manifest directories
   305         mozfile.rmtree(os.path.dirname(temp_manifest))
   307     def test_addon_details(self):
   308         # Generate installer stubs for a valid and invalid add-on manifest
   309         valid_addon = generate_addon('test-addon-1@mozilla.org',
   310                                      path=self.tmpdir)
   311         invalid_addon = generate_addon('test-addon-invalid-not-wellformed@mozilla.org',
   312                                        path=self.tmpdir)
   314         # Check valid add-on
   315         details = self.am.addon_details(valid_addon)
   316         self.assertEqual(details['id'], 'test-addon-1@mozilla.org')
   317         self.assertEqual(details['name'], 'Test Add-on 1')
   318         self.assertEqual(details['unpack'], False)
   319         self.assertEqual(details['version'], '0.1')
   321         # Check invalid add-on
   322         self.assertRaises(mozprofile.addons.AddonFormatError,
   323                           self.am.addon_details, invalid_addon)
   325         # Check invalid path
   326         self.assertRaises(IOError,
   327                           self.am.addon_details, '')
   329         # Check invalid add-on format
   330         addon_path = os.path.join(os.path.join(here, 'files'), 'not_an_addon.txt')
   331         self.assertRaises(mozprofile.addons.AddonFormatError,
   332                           self.am.addon_details, addon_path)
   334     @unittest.skip("Bug 900154")
   335     def test_clean_addons(self):
   336         addon_one = generate_addon('test-addon-1@mozilla.org')
   337         addon_two = generate_addon('test-addon-2@mozilla.org')
   339         self.am.install_addons(addon_one)
   340         installed_addons = [unicode(x[:-len('.xpi')]) for x in os.listdir(os.path.join(
   341                             self.profile.profile, 'extensions', 'staged'))]
   343         # Create a new profile based on an existing profile
   344         # Install an extra addon in the new profile
   345         # Cleanup addons
   346         duplicate_profile = mozprofile.profile.Profile(profile=self.profile.profile,
   347                                                        addons=addon_two)
   348         duplicate_profile.addon_manager.clean()
   350         addons_after_cleanup = [unicode(x[:-len('.xpi')]) for x in os.listdir(os.path.join(
   351                                 duplicate_profile.profile, 'extensions', 'staged'))]
   352         # New addons installed should be removed by clean_addons()
   353         self.assertEqual(installed_addons, addons_after_cleanup)
   355     def test_noclean(self):
   356         """test `restore=True/False` functionality"""
   358         server = mozhttpd.MozHttpd(docroot=os.path.join(here, 'addons'))
   359         server.start()
   361         profile = tempfile.mkdtemp()
   362         tmpdir = tempfile.mkdtemp()
   364         try:
   365             # empty initially
   366             self.assertFalse(bool(os.listdir(profile)))
   368             # make an addon
   369             addons = []
   370             addons.append(generate_addon('test-addon-1@mozilla.org',
   371                                          path=tmpdir))
   372             addons.append(server.get_url() + 'empty.xpi')
   374             # install it with a restore=True AddonManager
   375             am = mozprofile.addons.AddonManager(profile, restore=True)
   377             for addon in addons:
   378                 am.install_from_path(addon)
   380             # now its there
   381             self.assertEqual(os.listdir(profile), ['extensions'])
   382             staging_folder = os.path.join(profile, 'extensions', 'staged')
   383             self.assertTrue(os.path.exists(staging_folder))
   384             self.assertEqual(len(os.listdir(staging_folder)), 2)
   386             # del addons; now its gone though the directory tree exists
   387             downloaded_addons = am.downloaded_addons
   388             del am
   390             self.assertEqual(os.listdir(profile), ['extensions'])
   391             self.assertTrue(os.path.exists(staging_folder))
   392             self.assertEqual(os.listdir(staging_folder), [])
   394             for addon in downloaded_addons:
   395                 self.assertFalse(os.path.isfile(addon))
   397         finally:
   398             mozfile.rmtree(tmpdir)
   399             mozfile.rmtree(profile)
   401     def test_remove_addon(self):
   402         addons = []
   403         addons.append(generate_addon('test-addon-1@mozilla.org',
   404                                      path=self.tmpdir))
   405         addons.append(generate_addon('test-addon-2@mozilla.org',
   406                                      path=self.tmpdir))
   408         self.am.install_from_path(self.tmpdir)
   410         extensions_path = os.path.join(self.profile_path, 'extensions')
   411         staging_path = os.path.join(extensions_path, 'staged')
   413         # Fake a run by virtually installing one of the staged add-ons
   414         shutil.move(os.path.join(staging_path, 'test-addon-1@mozilla.org.xpi'),
   415                     extensions_path)
   417         for addon in self.am._addons:
   418             self.am.remove_addon(addon)
   420         self.assertEqual(os.listdir(staging_path), [])
   421         self.assertEqual(os.listdir(extensions_path), ['staged'])
   424 if __name__ == '__main__':
   425     unittest.main()

mercurial