Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code

Delta Between Two Patch Sets: tests/test_packagerWebExt.py

Issue 29501558: Issue 5383 - Add tests for the Chrome and Firefox packagers (Closed)
Left Patch Set: Addressing comments, handling Edge devenv Created Oct. 18, 2017, 11:19 a.m.
Right Patch Set: Addressing Vasily's comments Created Oct. 22, 2017, 11:11 a.m.
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
Left: Side by side diff | Download
Right: Side by side diff | Download
« no previous file with change/comment | « tests/test_packagerEdge.py ('k') | tox.ini » ('j') | no next file with change/comment »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
LEFTRIGHT
1 # This Source Code Form is subject to the terms of the Mozilla Public 1 # This Source Code Form is subject to the terms of the Mozilla Public
2 # License, v. 2.0. If a copy of the MPL was not distributed with this 2 # License, v. 2.0. If a copy of the MPL was not distributed with this
3 # file, You can obtain one at http://mozilla.org/MPL/2.0/. 3 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
4 4
5 import difflib
6 import json
5 import os 7 import os
8 import re
6 import shutil 9 import shutil
7 import zipfile 10 import zipfile
8 import json 11 from xml.etree import ElementTree
9 import re
10 from struct import unpack 12 from struct import unpack
11 import difflib
12 13
13 import pytest 14 import pytest
15 from Crypto.Signature import PKCS1_v1_5
16 from Crypto.PublicKey import RSA
14 from Crypto.Hash import SHA 17 from Crypto.Hash import SHA
15 from Crypto.PublicKey import RSA
16 from Crypto.Signature import PKCS1_v1_5
17 from xml.etree import ElementTree
18 18
19 from buildtools import packager 19 from buildtools import packager
20 from buildtools.packagerChrome import defaultLocale 20 from buildtools.packagerChrome import defaultLocale
21 from buildtools.build import processArgs 21 from buildtools.build import processArgs
22 22
23 LOCALES_MODULE = { 23 LOCALES_MODULE = {
24 'test.Foobar': { 24 'test.Foobar': {
25 'message': 'Ensuring dict-copy from modules for $domain$', 25 'message': 'Ensuring dict-copy from modules for $domain$',
26 'description': 'test description', 26 'description': 'test description',
27 'placeholders': {'content': '$1', 'example': 'www.adblockplus.org'} 27 'placeholders': {'content': '$1', 'example': 'www.adblockplus.org'}
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
119 return content 119 return content
120 120
121 121
122 def copy_metadata(filename, tmpdir): 122 def copy_metadata(filename, tmpdir):
123 """Copy the used metadata to the used temporary directory.""" 123 """Copy the used metadata to the used temporary directory."""
124 path = os.path.join(os.path.dirname(__file__), filename) 124 path = os.path.join(os.path.dirname(__file__), filename)
125 destination = str(tmpdir.join(filename)) 125 destination = str(tmpdir.join(filename))
126 shutil.copy(path, destination) 126 shutil.copy(path, destination)
127 127
128 128
129 def run_webext_build(ext_type, build_opt, srcdir, buildnum=None, keyfile=None): 129 def run_webext_build(ext_type, build_opt, srcdir, keyfile=None):
130 """Run a build process.""" 130 """Run a build process."""
131 if build_opt == 'build': 131 cmd_mapping = {
132 build_args = ['build'] 132 'devenv': ['devenv'],
133 elif build_opt == 'release': 133 'development_build': ['build', '-b', '1337'],
134 build_args = ['build', '-r'] 134 'release_build': ['build', '-r'],
135 else: 135 }
136 build_args = ['devenv'] 136
137 137 args = ['build.py', '-t', ext_type] + cmd_mapping[build_opt]
138 args = ['build.py', '-t', ext_type] + build_args
139 138
140 if keyfile: 139 if keyfile:
141 args += ['-k', keyfile] 140 args += ['-k', keyfile]
142 if buildnum:
143 args += ['-b', buildnum]
144 141
145 processArgs(str(srcdir), args) 142 processArgs(str(srcdir), args)
146 143
147 144
148 def locale_files(languages, rootfolder, srcdir): 145 def locale_files(languages, rootfolder, srcdir):
149 """Generate example locales. 146 """Generate example locales.
150 147
151 languages: tuple, list or set of languages to include 148 languages: tuple, list or set of languages to include
152 rootdir: folder-name to create the locale-folders in 149 rootdir: folder-name to create the locale-folders in
153 """ 150 """
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
237 234
238 tmpdir.mkdir('lib').join('b.js').write(files['lib/b.js']) 235 tmpdir.mkdir('lib').join('b.js').write(files['lib/b.js'])
239 ext_dir = tmpdir.mkdir('ext') 236 ext_dir = tmpdir.mkdir('ext')
240 ext_dir.join('a.js').write(files['ext/a.js']) 237 ext_dir.join('a.js').write(files['ext/a.js'])
241 ext_dir.join('c.js').write(files['ext/c.js']) 238 ext_dir.join('c.js').write(files['ext/c.js'])
242 239
243 return files 240 return files
244 241
245 242
246 def comparable_xml(xml): 243 def comparable_xml(xml):
247 """Create a nonambiguous representation of a given XML tree.""" 244 """Create a nonambiguous representation of a given XML tree.
245
246 Note that this function is not safe against ambiguous tags
247 containing differently distributed children, e.g.:
248
249 '<a><b><c/></b><b><d/></b></a>'
250 vs.
251 '<a><b/><b><c/><d/></b></a>'
252
253 This is irrelevant for comparing the XML used by the tests of this
254 module.
255 """
248 def get_leafs_string(tree): 256 def get_leafs_string(tree):
249 """Recursively build a string representing all xml leaf-nodes.""" 257 """Recursively build a string representing all xml leaf-nodes."""
250 root_str = '{}|{}|{}'.format(tree.tag, tree.tail, tree.text).strip() 258 root_str = '{}|{}|{}'.format(tree.tag, tree.tail, tree.text).strip()
251 result = [] 259 result = []
252 260
253 if len(tree) > 0: 261 if len(tree) > 0:
254 for subtree in tree: 262 for subtree in tree:
255 for leaf in get_leafs_string(subtree): 263 for leaf in get_leafs_string(subtree):
256 result.append('{}__{}'.format(root_str, leaf)) 264 result.append('{}__{}'.format(root_str, leaf))
257 for k, v in tree.attrib.items(): 265 for k, v in tree.attrib.items():
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
318 assert '../ext/common.js' in quint_index 326 assert '../ext/common.js' in quint_index
319 assert '../ext/background.js' in quint_index 327 assert '../ext/background.js' in quint_index
320 328
321 assert set(manifest['background']['scripts']) == set( 329 assert set(manifest['background']['scripts']) == set(
322 scripts + ['devenvPoller__.js'] 330 scripts + ['devenvPoller__.js']
323 ) 331 )
324 else: 332 else:
325 assert set(manifest['background']['scripts']) == set(scripts) 333 assert set(manifest['background']['scripts']) == set(scripts)
326 334
327 335
328 def assert_base_files(package, platform): 336 def assert_base_files(package, platform, prefix):
329 filenames = set(package.namelist()) 337 filenames = set(package.namelist())
330 338
331 if platform in {'chrome', 'gecko'}: 339 if platform == 'edge':
Sebastian Noack 2017/10/19 05:37:54 While, the files checked in the else-clause are ex
tlucas 2017/10/20 12:05:19 No, changed it.
332 assert 'bar.json' in filenames
333 assert 'manifest.json' in filenames
334 assert 'lib/foo.js' in filenames
335 assert 'foo/logo_50.png' in filenames
336 assert 'icons/logo_150.png' in filenames
337 else:
338 assert 'AppxManifest.xml' in filenames 340 assert 'AppxManifest.xml' in filenames
339 assert 'AppxBlockMap.xml' in filenames 341 assert 'AppxBlockMap.xml' in filenames
340 assert '[Content_Types].xml' in filenames 342 assert '[Content_Types].xml' in filenames
341 343
342 assert 'Extension/bar.json' in filenames
343 assert 'Extension/lib/foo.js' in filenames
344
345 assert package.read('Assets/logo_44.png') == '44' 344 assert package.read('Assets/logo_44.png') == '44'
346 assert package.read('Extension/icons/abp-44.png') == '44' 345 assert package.read('Extension/icons/abp-44.png') == '44'
346
347 assert os.path.join(prefix, 'bar.json') in filenames
348 assert os.path.join(prefix, 'manifest.json') in filenames
349 assert os.path.join(prefix, 'lib/foo.js') in filenames
350 assert os.path.join(prefix, 'foo/logo_50.png') in filenames
351 assert os.path.join(prefix, 'icons/logo_150.png') in filenames
347 352
348 353
349 def assert_chrome_signature(filename, keyfile): 354 def assert_chrome_signature(filename, keyfile):
350 with open(filename, 'r') as fp: 355 with open(filename, 'r') as fp:
351 content = fp.read() 356 content = fp.read()
352 357
353 _, _, l_pubkey, l_signature = unpack('<4sIII', content[:16]) 358 _, _, l_pubkey, l_signature = unpack('<4sIII', content[:16])
354 signature = content[16 + l_pubkey: 16 + l_pubkey + l_signature] 359 signature = content[16 + l_pubkey: 16 + l_pubkey + l_signature]
355 360
356 digest = SHA.new() 361 digest = SHA.new()
(...skipping 25 matching lines...) Expand all
382 387
383 @pytest.mark.usefixtures( 388 @pytest.mark.usefixtures(
384 'all_lang_locales', 389 'all_lang_locales',
385 'locale_modules', 390 'locale_modules',
386 'icons', 391 'icons',
387 'lib_files', 392 'lib_files',
388 'chrome_metadata', 393 'chrome_metadata',
389 'gecko_webext_metadata', 394 'gecko_webext_metadata',
390 'edge_metadata', 395 'edge_metadata',
391 ) 396 )
392 @pytest.mark.parametrize('platform,command,buildnum', [ 397 @pytest.mark.parametrize('platform,command', [
393 ('chrome', 'build', '1337'), 398 ('chrome', 'development_build'),
394 ('chrome', 'devenv', None), 399 ('chrome', 'devenv'),
395 ('chrome', 'release', None), 400 ('chrome', 'release_build'),
396 ('gecko', 'build', '1337'), 401 ('gecko', 'development_build'),
397 ('gecko', 'devenv', None), 402 ('gecko', 'devenv'),
398 ('gecko', 'release', None), 403 ('gecko', 'release_build'),
399 ('edge', 'build', '1337'), 404 ('edge', 'development_build'),
400 ('edge', 'devenv', None), 405 ('edge', 'devenv'),
401 ('edge', 'release', None), 406 ('edge', 'release_build'),
402 ]) 407 ])
403 def test_build_webext(platform, command, keyfile, tmpdir, srcdir, 408 def test_build_webext(platform, command, keyfile, tmpdir, srcdir, capsys):
404 buildnum, capsys): 409 release = command == 'release_build'
405 release = command == 'release'
406 devenv = command == 'devenv' 410 devenv = command == 'devenv'
407 411
408 if platform == 'chrome' and release: 412 if platform == 'chrome' and release:
409 key = keyfile 413 key = keyfile
410 else: 414 else:
411 key = None 415 key = None
412 416
413 manifests = { 417 manifests = {
414 'gecko': [('', 'manifest', 'json')], 418 'gecko': [('', 'manifest', 'json')],
415 'chrome': [('', 'manifest', 'json')], 419 'chrome': [('', 'manifest', 'json')],
416 'edge': [('', 'AppxManifest', 'xml'), 420 'edge': [('', 'AppxManifest', 'xml'),
417 ('Extension', 'manifest', 'json')], 421 ('Extension', 'manifest', 'json')],
418 } 422 }
419 423
420 filenames = { 424 filenames = {
421 'gecko': 'adblockplusfirefox-1.2.3{}.xpi', 425 'gecko': 'adblockplusfirefox-1.2.3{}.xpi',
422 'chrome': 'adblockpluschrome-1.2.3{{}}.{}'.format( 426 'chrome': 'adblockpluschrome-1.2.3{{}}.{}'.format(
423 {True: 'crx', False: 'zip'}[release] 427 {True: 'crx', False: 'zip'}[release]
424 ), 428 ),
425 'edge': 'adblockplusedge-1.2.3{}.appx', 429 'edge': 'adblockplusedge-1.2.3{}.appx',
426 } 430 }
427 431
428 if platform == 'edge': 432 if platform == 'edge':
429 prefix = 'Extension' 433 prefix = 'Extension'
430 else: 434 else:
431 prefix = '' 435 prefix = ''
432 436
433 run_webext_build(platform, command, srcdir, buildnum=buildnum, 437 run_webext_build(platform, command, srcdir, keyfile=key)
434 keyfile=key)
435 438
436 # The makeIcons() in packagerChrome.py should warn about non-square 439 # The makeIcons() in packagerChrome.py should warn about non-square
437 # icons via stderr. 440 # icons via stderr.
438 out, err = capsys.readouterr() 441 out, err = capsys.readouterr()
439 assert 'icon should be square' in err 442 assert 'icon should be square' in err
440 443
441 if devenv: 444 if devenv:
442 content_class = DirContent 445 content_class = DirContent
443 out_file_path = os.path.join(str(srcdir), 'devenv.' + platform) 446 out_file_path = os.path.join(str(srcdir), 'devenv.' + platform)
444 else: 447 else:
445 content_class = ZipContent 448 content_class = ZipContent
446 449
447 if release: 450 if release:
448 add_version = '' 451 add_version = ''
449 else: 452 else:
450 add_version = '.' + buildnum 453 add_version = '.1337'
451 454
452 out_file = filenames[platform].format(add_version) 455 out_file = filenames[platform].format(add_version)
453 456
454 out_file_path = os.path.abspath(os.path.join( 457 out_file_path = os.path.abspath(os.path.join(
455 os.path.dirname(__file__), os.pardir, out_file)) 458 os.path.dirname(__file__), os.pardir, out_file))
456 assert os.path.exists(out_file_path) 459 assert os.path.exists(out_file_path)
457 460
458 if release and platform == 'chrome': 461 if release and platform == 'chrome':
459 assert_chrome_signature(out_file_path, keyfile) 462 assert_chrome_signature(out_file_path, keyfile)
460 463
461 with content_class(out_file_path) as package: 464 with content_class(out_file_path) as package:
462 assert_base_files(package, platform) 465 assert_base_files(package, platform, prefix)
463 assert_all_locales_present(package, prefix) 466 assert_all_locales_present(package, prefix)
464 assert_webpack_bundle(package, prefix, platform == 'gecko') 467 assert_webpack_bundle(package, prefix, platform == 'gecko')
465 468
466 if platform == 'chrome': 469 if platform == 'chrome':
467 assert_locale_upfix(package) 470 assert_locale_upfix(package)
468 471
469 assert_devenv_scripts(package, prefix, devenv) 472 assert_devenv_scripts(package, prefix, devenv)
470 473
471 for folder, name, ext in manifests[platform]: 474 for folder, name, ext in manifests[platform]:
472 filename = '{{}}_{}_{}.{{}}'.format(platform, command) 475 filename = '{{}}_{}_{}.{{}}'.format(platform, command)
473 expected = os.path.join( 476 expected = os.path.join(
474 os.path.dirname(__file__), 477 os.path.dirname(__file__),
475 'expecteddata', 478 'expecteddata',
476 filename.format(name, ext), 479 filename.format(name, ext),
477 ) 480 )
478 481
479 assert_manifest_content( 482 assert_manifest_content(
480 package.read(os.path.join(folder, '{}.{}'.format(name, ext))), 483 package.read(os.path.join(folder, '{}.{}'.format(name, ext))),
481 expected, 484 expected,
482 ) 485 )
LEFTRIGHT

Powered by Google App Engine
This is Rietveld