| Left: | ||
| Right: |
| LEFT | RIGHT |
|---|---|
| 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 os | 5 import os |
| 6 import shutil | 6 import shutil |
| 7 import json | 7 import json |
| 8 import re | 8 import re |
| 9 from struct import unpack | |
| 9 | 10 |
| 10 import pytest | 11 import pytest |
| 11 | 12 from Crypto.Hash import SHA |
| 12 from buildtools import packager | 13 from Crypto.PublicKey import RSA |
| 13 from buildtools.tests.tools import DirContent | 14 from Crypto.Signature import PKCS1_v1_5 |
|
Vasily Kuznetsov
2017/09/11 12:50:07
These imports also can be combined.
tlucas
2017/09/12 11:32:10
Acknowledged.
tlucas
2017/09/13 13:43:24
Done.
| |
| 14 from buildtools.tests.tools import ZipContent | 15 |
| 15 from buildtools.tests.tools import copy_metadata | 16 |
| 16 from buildtools.tests.tools import run_webext_build | 17 from buildtools import packager, packagerChrome |
| 17 from buildtools.tests.tools import assert_all_locales_present | 18 from buildtools.tests.tools import (DirContent, ZipContent, copy_metadata, |
| 18 from buildtools.tests.tools import assert_manifest_content | 19 run_webext_build, assert_manifest_content, |
| 19 from buildtools.tests.tools import locale_files | 20 assert_all_locales_present, locale_files) |
| 20 from buildtools.tests.conftest import ALL_LANGUAGES | 21 from buildtools.tests.conftest import ALL_LANGUAGES |
| 21 | 22 |
| 22 | 23 |
| 23 LOCALES_MODULE = { | 24 LOCALES_MODULE = { |
| 24 'test.Foobar': { | 25 'test.Foobar': { |
| 25 'message': 'Ensuring dict-copy from modules for $domain$', | 26 'message': 'Ensuring dict-copy from modules for $domain$', |
| 26 'description': 'test description', | 27 'description': 'test description', |
| 27 'placeholders': {'content': '$1', 'example': 'www.adblockplus.org'} | 28 'placeholders': {'content': '$1', 'example': 'www.adblockplus.org'} |
| 28 } | 29 } |
| 29 } | 30 } |
| (...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 140 filenames = set(package.namelist()) | 141 filenames = set(package.namelist()) |
| 141 | 142 |
| 142 assert 'bar.json' in filenames | 143 assert 'bar.json' in filenames |
| 143 assert 'manifest.json' in filenames | 144 assert 'manifest.json' in filenames |
| 144 assert 'lib/foo.js' in filenames | 145 assert 'lib/foo.js' in filenames |
| 145 assert 'foo/logo_50.png' in filenames | 146 assert 'foo/logo_50.png' in filenames |
| 146 assert 'icons/logo_150.png' in filenames | 147 assert 'icons/logo_150.png' in filenames |
| 147 | 148 |
| 148 | 149 |
| 149 def assert_chrome_signature(filename, keyfile): | 150 def assert_chrome_signature(filename, keyfile): |
| 150 from struct import unpack | |
|
Vasily Kuznetsov
2017/09/11 12:50:07
Is there any specific reason to have these imports
tlucas
2017/09/12 11:32:11
Not at all - merely a result of a speedy adjustmen
tlucas
2017/09/13 13:43:25
Done.
| |
| 151 from Crypto.Hash import SHA | |
| 152 from Crypto.PublicKey import RSA | |
| 153 from Crypto.Signature import PKCS1_v1_5 | |
| 154 | |
| 155 with open(filename, 'r') as fp: | 151 with open(filename, 'r') as fp: |
| 156 content = fp.read() | 152 content = fp.read() |
| 157 | 153 |
| 158 _, _, l_pubkey, l_signature = unpack('<4sIII', content[:16]) | 154 _, _, l_pubkey, l_signature = unpack('<4sIII', content[:16]) |
| 159 signature = content[16 + l_pubkey: 16 + l_pubkey + l_signature] | 155 signature = content[16 + l_pubkey: 16 + l_pubkey + l_signature] |
| 160 | 156 |
| 161 digest = SHA.new() | 157 digest = SHA.new() |
| 162 with open(keyfile, 'r') as fp: | 158 with open(keyfile, 'r') as fp: |
| 163 rsa_key = RSA.importKey(fp.read()) | 159 rsa_key = RSA.importKey(fp.read()) |
| 164 | 160 |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 176 | 172 |
| 177 manifest = package.read('manifest.json') | 173 manifest = package.read('manifest.json') |
| 178 | 174 |
| 179 # Chrome Web Store requires descriptive translations to be present in | 175 # Chrome Web Store requires descriptive translations to be present in |
| 180 # every language. | 176 # every language. |
| 181 for match in re.finditer(r'__MSG_(\S+)__', manifest): | 177 for match in re.finditer(r'__MSG_(\S+)__', manifest): |
| 182 name = match.group(1) | 178 name = match.group(1) |
| 183 | 179 |
| 184 for other in translations[1:]: | 180 for other in translations[1:]: |
| 185 assert translations[0][name]['message'] == other[name]['message'] | 181 assert translations[0][name]['message'] == other[name]['message'] |
| 186 | |
| 187 | |
| 188 @pytest.mark.usefixtures( | |
| 189 'all_lang_locales', | |
| 190 'gecko_import', | |
| 191 'locale_modules', | |
| 192 'icons', | |
| 193 'lib_files', | |
| 194 'chrome_metadata', | |
| 195 ) | |
| 196 @pytest.mark.parametrize('dev_build_release', ['build', 'devenv', 'release']) | |
| 197 def test_build_chrome(dev_build_release, keyfile, tmpdir, srcdir, capsys): | |
| 198 from buildtools import packagerChrome | |
| 199 release = dev_build_release == 'release' | |
| 200 devenv = dev_build_release == 'devenv' | |
| 201 | |
| 202 run_webext_build('chrome', dev_build_release, srcdir, packagerChrome, | |
| 203 keyfile if release else None) | |
| 204 | |
| 205 # The makeIcons() in packagerChrome.py should warn about non-square | |
| 206 # icons via stderr. | |
| 207 out, err = capsys.readouterr() | |
| 208 assert 'icon should be square' in err | |
| 209 | |
| 210 if devenv: | |
| 211 content_class = DirContent | |
| 212 out_file_path = os.path.join(str(srcdir), 'devenv.chrome') | |
| 213 else: | |
| 214 content_class = ZipContent | |
| 215 out_file = 'adblockpluschrome-1.2.3' | |
| 216 if not release: | |
| 217 out_file += '.0' | |
| 218 | |
| 219 if release: | |
| 220 out_file += '.crx' | |
| 221 else: | |
| 222 out_file += '.zip' | |
| 223 | |
| 224 out_file_path = os.path.abspath(os.path.join( | |
| 225 os.path.dirname(__file__), os.pardir, out_file)) | |
| 226 | |
| 227 assert os.path.exists(out_file_path) | |
| 228 | |
| 229 if release: | |
| 230 assert_chrome_signature(out_file_path, keyfile) | |
| 231 | |
| 232 with content_class(out_file_path) as package: | |
| 233 assert_base_files(package) | |
| 234 assert_devenv_scripts(package, devenv) | |
| 235 assert_all_locales_present(package, '_locales') | |
| 236 assert_locale_upfix(package) | |
| 237 assert_gecko_locale_conversion(package) | |
| 238 assert_convert_js(package) | |
| 239 expected = os.path.join( | |
| 240 os.path.dirname(__file__), | |
| 241 'expecteddata', | |
| 242 'manifest_chrome_{}.json'.format(dev_build_release), | |
| 243 ) | |
| 244 assert_manifest_content(package.read('manifest.json'), expected) | |
| 245 | 182 |
| 246 | 183 |
| 247 @pytest.mark.usefixtures( | 184 @pytest.mark.usefixtures( |
| 248 'all_lang_locales', | 185 'all_lang_locales', |
| 249 'locale_modules', | 186 'locale_modules', |
| 250 'gecko_import', | 187 'gecko_import', |
| 251 'icons', | 188 'icons', |
| 252 'lib_files', | 189 'lib_files', |
| 190 'chrome_metadata', | |
| 253 'gecko_webext_metadata', | 191 'gecko_webext_metadata', |
| 254 ) | 192 ) |
| 255 @pytest.mark.parametrize('dev_build_release', ['build', 'devenv', 'release']) | 193 @pytest.mark.parametrize('platform', ['chrome', 'gecko-webext']) |
| 256 def test_build_gecko_webext(dev_build_release, tmpdir, srcdir, capsys): | 194 @pytest.mark.parametrize('dev_build_release,buildnum', [ |
|
Vasily Kuznetsov
2017/09/11 12:50:07
This test seems very similar to the previous one a
tlucas
2017/09/12 11:32:11
I agree - will do (also i fear the complexity of t
tlucas
2017/09/13 13:43:25
Done.
| |
| 257 from buildtools import packagerChrome | 195 ('build', None), |
| 196 ('build', '1337'), | |
| 197 ('devenv', None), | |
| 198 pytest.param('devenv', '1337', marks=pytest.mark.xfail), | |
| 199 ('release', None), | |
| 200 ('release', '1337'), | |
| 201 ]) | |
| 202 def test_build_webext(platform, dev_build_release, keyfile, tmpdir, srcdir, | |
| 203 buildnum, capsys): | |
| 258 release = dev_build_release == 'release' | 204 release = dev_build_release == 'release' |
| 259 devenv = dev_build_release == 'devenv' | 205 devenv = dev_build_release == 'devenv' |
| 260 | 206 |
| 261 run_webext_build('gecko-webext', dev_build_release, srcdir, packagerChrome) | 207 if platform == 'chrome' and release: |
| 208 key = keyfile | |
| 209 else: | |
| 210 key = None | |
| 211 | |
| 212 filenames = { | |
| 213 'gecko-webext': 'adblockplusfirefox-1.2.3{}.{}', | |
| 214 'chrome': 'adblockpluschrome-1.2.3{}.{}' | |
| 215 } | |
| 216 | |
| 217 extensions = { | |
| 218 'gecko-webext': { | |
| 219 True: 'xpi', | |
| 220 False: 'xpi', | |
| 221 }, | |
| 222 'chrome': { | |
| 223 True: 'crx', | |
| 224 False: 'zip', | |
| 225 }, | |
| 226 } | |
| 227 | |
| 228 expected_manifest = os.path.join( | |
| 229 os.path.dirname(__file__), | |
| 230 'expecteddata', | |
| 231 'manifest_{}_{}_{}.json'.format(platform, dev_build_release, buildnum), | |
| 232 ) | |
| 233 | |
| 234 run_webext_build(platform, dev_build_release, srcdir, packagerChrome, | |
| 235 buildnum=buildnum, keyfile=key) | |
| 262 | 236 |
| 263 # The makeIcons() in packagerChrome.py should warn about non-square | 237 # The makeIcons() in packagerChrome.py should warn about non-square |
| 264 # icons via stderr. | 238 # icons via stderr. |
| 265 out, err = capsys.readouterr() | 239 out, err = capsys.readouterr() |
| 266 assert 'icon should be square' in err | 240 assert 'icon should be square' in err |
| 267 | 241 |
| 268 if devenv: | 242 if devenv: |
| 269 content_class = DirContent | 243 content_class = DirContent |
| 270 out_file_path = os.path.join(str(srcdir), 'devenv.gecko-webext') | 244 out_file_path = os.path.join(str(srcdir), 'devenv.' + platform) |
| 271 else: | 245 else: |
| 272 content_class = ZipContent | 246 content_class = ZipContent |
| 273 out_file = 'adblockplusfirefox-1.2.3{}.xpi'.format( | 247 |
| 274 '.0' if not release else '' | 248 if release: |
| 275 ) | 249 add_version = '' |
| 250 else: | |
| 251 add_version = '.' + (buildnum or '0') | |
| 252 extension = extensions[platform][release] | |
| 253 | |
| 254 out_file = filenames[platform].format(add_version, extension) | |
| 276 | 255 |
| 277 out_file_path = os.path.abspath(os.path.join( | 256 out_file_path = os.path.abspath(os.path.join( |
| 278 os.path.dirname(__file__), os.pardir, out_file)) | 257 os.path.dirname(__file__), os.pardir, out_file)) |
| 279 | |
| 280 assert os.path.exists(out_file_path) | 258 assert os.path.exists(out_file_path) |
| 281 | 259 |
| 260 if release and platform == 'chrome': | |
| 261 assert_chrome_signature(out_file_path, keyfile) | |
| 262 | |
| 282 with content_class(out_file_path) as package: | 263 with content_class(out_file_path) as package: |
| 264 assert_manifest_content( | |
| 265 package.read('manifest.json'), expected_manifest | |
| 266 ) | |
| 283 assert_base_files(package) | 267 assert_base_files(package) |
| 284 assert_devenv_scripts(package, devenv) | 268 assert_devenv_scripts(package, devenv) |
| 285 assert_all_locales_present(package, '_locales') | 269 assert_all_locales_present(package, '_locales') |
| 286 assert_gecko_locale_conversion(package) | 270 assert_gecko_locale_conversion(package) |
| 287 assert_convert_js(package, True) | 271 assert_convert_js(package, platform == 'gecko-webext') |
| 288 | 272 |
| 289 expected = os.path.join( | 273 if platform == 'chrome': |
| 290 os.path.dirname(__file__), | 274 assert_locale_upfix(package) |
| 291 'expecteddata', | |
| 292 'manifest_gecko-webext_{}.json'.format(dev_build_release), | |
| 293 ) | |
| 294 assert_manifest_content(package.read('manifest.json'), expected) | |
| LEFT | RIGHT |