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.

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

mercurial