def test_skip_blacklisted_file(): """Ensure blacklisted files are skipped for processing.""" package_data = open('tests/resources/libraryblacklist/errors.xpi') package = XPIManager(package_data, mode='r', name='errors.xpi') err = ErrorBundle() test_content.test_packed_packages(err, package) print err.print_summary() assert err.notices assert not err.failed()
def test_mismatched_module_version(): """ Tests that add-ons using modules from a version of the SDK other than the version they claim. """ xpi = XPIManager( "tests/resources/jetpack/jetpack-1.8-pretending-1.8.1.xpi") err = _do_test(xpi) assert err.failed() assert any(w["id"][2] == "mismatched_version" for w in err.warnings)
def test_validate_libs_in_compat_mode(): xpi = 'tests/resources/libraryblacklist/addon_with_mootools.xpi' with open(xpi) as data: package = XPIManager(data, mode='r', name='addon_with_mootools.xpi') appversions = { FIREFOX_GUID: version_range('firefox', '39.0a1', '39.*') } err = ErrorBundle(for_appversions=appversions) test_content.test_packed_packages(err, package) assert err.get_resource('scripts'), ( 'expected mootools scripts to be marked for proessing') assert err.get_resource('scripts')[0]['scripts'] == set( ['content/mootools.js'])
def test_outdated_sdkversion(): """ Tests that add-ons using a version other than the latest release are warned against, but module hashes are still recognized. """ xpi = XPIManager("tests/resources/jetpack/jetpack-1.8-outdated.xpi") err = _do_test(xpi, allow_old_sdk=False) assert err.failed() # Make sure we don't have any version mismatch warnings eq_(len(err.warnings), 1) eq_(err.warnings[0]["id"][2], "outdated_version")
def test_package(err, file_, name, expectation=PACKAGE_ANY, for_appversions=None): 'Begins tests for the package.' # Load up a new instance of an XPI. try: package = XPIManager(file_, mode='r', name=name) has_package_json = 'package.json' in package has_manifest_json = 'manifest.json' in package has_install_rdf = 'install.rdf' in package # install.rdf? | package.json? | manifest.json? | error | use-file # Yes | No | No | No | install.rdf # Yes | Yes | No | No | install.rdf # Yes | No | Yes | No | install.rdf # No | No | Yes | No | manifest.json # No | No | No | Yes | install.rdf # No | Yes | No | No | package.json # No | No | Yes | Yes | install.rdf if has_package_json: _load_package_json(err, package, expectation) if has_manifest_json: _load_manifest_json(err, package, expectation) if has_install_rdf: _load_install_rdf(err, package, expectation) except IOError: # Die on this one because the file won't open. err.error(('main', 'test_package', 'unopenable'), 'The XPI could not be opened.') return except (BadZipfile, zlib_error): # Die if the zip file is corrupt. err.error(('submain', '_load_install_rdf', 'badzipfile'), error='Corrupt ZIP file', description='We were unable to decompress the zip file.') return if package.extension in assumed_extensions: assumed_type = assumed_extensions[package.extension] # Is the user expecting a different package type? if expectation not in (PACKAGE_ANY, assumed_type): err.error(('main', 'test_package', 'unexpected_type'), 'Unexpected package type (found theme)') test_inner_package(err, package, for_appversions)
def _run_test(filename, expectation, should_fail=True): name = "tests/resources/submain/%s" % filename pack = open(name) xpi = XPIManager(pack, mode="r", name=name) err = ErrorBundle(None, True) submain._load_install_rdf(err, xpi, expectation) if should_fail: assert err.failed() else: assert not err.failed() assert err.get_resource("install_rdf") return err
def _do_test(path, test, failure=True, require_install=False, set_type=0, listed=False, xpi_mode='r'): package_data = open(path, 'rb') package = XPIManager(package_data, mode=xpi_mode, name=path) err = ErrorBundle() if listed: err.save_resource('listed', True) # Populate in the dependencies. if set_type: err.detected_type = set_type # Conduit test requires type if require_install: if 'install.rdf' in package: err.save_resource('has_install_rdf', True) rdf_data = package.read('install.rdf') install_rdf = RDFParser(err, rdf_data) err.save_resource('install_rdf', install_rdf) elif 'manifest.json' in package: err.save_resource('has_manifest_json', True) manifest_data = package.read('manifest.json') manifest_json = ManifestJsonParser(err, manifest_data) err.save_resource('install_rdf', manifest_json) populate_chrome_manifest(err, package) test(err, package) print err.print_summary(verbose=True) if failure: assert err.failed() else: assert not err.failed() return err
def _test_type(file_, expectation, failure=False): 'Tests a file against the expectations' err = ErrorBundle(None, True) package = XPIManager(open(file_), mode='r', name=file_) contents = package.package_contents() # We need to have an install.rdf. assert 'install.rdf' in contents # Load up the install.rdf into an RDFParser install_file = package.read('install.rdf') install_rdf = RDFParser(err, install_file) results = typedetection.detect_type(err, install_rdf, package) assert results == expectation if not failure: assert not err.failed() else: assert err.failed() return err
def test_blacklisted_files(): """ Tests the validator's ability to hash each individual file and (based on this information) determine whether the addon passes or fails the validation process. """ package_data = open('tests/resources/libraryblacklist/blocked.xpi') package = XPIManager(package_data, mode='r', name='blocked.xpi') err = ErrorBundle() test_content.test_packed_packages(err, package) print err.print_summary() assert err.notices assert not err.failed() assert err.metadata.get('identified_files') == { 'test.js': { 'path': 'This file is a false script to facilitate ' 'testing of library blacklisting.' } }
def test_comparer(): 'Tests the function that compares two packages.' ref = XPIManager('tests/resources/l10n/langpack/reference.jar') ref.locale_name = 'en-US' extra_ref = XPIManager('tests/resources/l10n/langpack/extra_files_ref.jar') pass_ = XPIManager('tests/resources/l10n/langpack/pass.jar') pass_.locale_name = 'en-US' mfile = XPIManager('tests/resources/l10n/langpack/missing_file.jar') mfile.locale_name = 'en-US' extra = XPIManager('tests/resources/l10n/langpack/extra_files.jar') extra.locale_name = 'en-US' mfileent = XPIManager( 'tests/resources/l10n/langpack/missing_file_entities.jar') mfileent.locale_name = 'en-US' ment = XPIManager('tests/resources/l10n/langpack/missing_entities.jar') ment.locale_name = 'en-US' assert _compare_packs(ref, pass_) == 3 assert _compare_packs(extra_ref, pass_) == 3 assert _compare_packs(ref, extra) == 3 assert _compare_packs(ref, mfile) == 4 assert _compare_packs(ref, mfileent) == 3 assert _compare_packs(ref, ref) > 3
def test_valid_name(): 'Test that the manager can retrieve the correct file name.' z = XPIManager(get_path('xpi/install_rdf_only.xpi')) contents = z.package_contents() assert 'install.rdf' in contents
def __init__(self, filename, project=None, release=None, name=None): """ Fills in a list of locales from the chrome.manifest file. """ Bundle.__init__(self, project, release) self.xpi = XPIManager(filename, name=name) # here we will store managers for jarfiles self.jarfiles = {} chrome = ChromeManifest(self.xpi.read("chrome.manifest"), "manifest") locales = list(chrome.get_triples("locale")) if not locales: return None # read the list for locale in locales: code, location = locale["object"].split() # finding out the language of the locale try: lang = self._get_lang(code) except Language.DoesNotExist: self.log("Locale %s SKIPPED" % code, "font-weight:bold") continue # Locales can be bundled in JARs jarred = location.startswith("jar:") if jarred: # We just care about the JAR path location = location[4:] split_location = location.split("!", 2) # Ignore malformed JAR URIs. if len(split_location) < 2: continue jarname, location = split_location # missing file mentioned if jarname not in self.xpi: continue # may be we have already read this one if jarname in self.jarfiles: package = self.jarfiles[jarname] else: jar = StringIO(self.xpi.read(jarname)) package = XPIManager(jar, mode="r", name=jarname) else: package = self.xpi # and now we read files from there location = location.strip('/') result = {} for f in package.package_contents(): f = f.strip("/") if f.startswith(location) and f != location: result[f.split("/")[-1]] = package.read(f) # file with same name in different jars can get overwritten if lang not in self.locales: self.locales[lang] = result else: self.locales[lang].update(result)
def test_package(err, file_, name, expectation=PACKAGE_ANY, for_appversions=None): 'Begins tests for the package.' # Load up a new instance of an XPI. try: package = XPIManager(file_, mode='r', name=name) has_package_json = 'package.json' in package has_manifest_json = 'manifest.json' in package has_install_rdf = 'install.rdf' in package # install.rdf? | package.json? | manifest.json? | error | use-file # Yes | No | No | No | install.rdf # Yes | Yes | No | No | install.rdf # Yes | No | Yes | No | install.rdf # No | No | Yes | No | manifest.json # No | No | No | Yes | install.rdf # No | Yes | No | No | package.json # No | No | Yes | Yes | install.rdf if has_package_json: _load_package_json(err, package, expectation) if has_manifest_json: _load_manifest_json(err, package, expectation) if has_install_rdf: _load_install_rdf(err, package, expectation) except IOError: # Die on this one because the file won't open. err.error(('main', 'test_package', 'unopenable'), 'The XPI could not be opened.') return except (BadZipfile, zlib_error): # Die if the zip file is corrupt. err.error(('submain', '_load_install_rdf', 'badzipfile'), error='Corrupt ZIP file', description='We were unable to decompress the zip file.') return if package.extension in assumed_extensions: assumed_type = assumed_extensions[package.extension] # Is the user expecting a different package type? if expectation not in (PACKAGE_ANY, assumed_type): err.error(('main', 'test_package', 'unexpected_type'), 'Unexpected package type (found theme)') if (err.get_resource('has_manifest_json') and not err.get_resource('has_package_json') and not err.get_resource('has_install_rdf')): # It's a WebExtension. Those are not supported by amo-validator, we # should be using the linter instead. Only reason we could be using # amo validator with a WebExtension is if a developer tried to use # the compatibilty checker with a WebExtension, so add a relevant error # message. format_args = {'link': MDN_DOC % 'Mozilla/Add-ons/WebExtensions'} err.error( ('submain', 'test_inner_package', 'webextension'), 'This tool only works with legacy add-ons. See {link} for more ' 'information about WebExtension APIs.'.format(**format_args)) else: test_inner_package(err, package, for_appversions)
def _process_file(err, xpi_package, name, file_data, name_lower, pollutable=False): """Process a single file's content tests.""" extension = os.path.splitext(name_lower)[1] # If that item is a container file, unzip it and scan it. if extension == '.jar': # This is either a subpackage or a nested theme. is_subpackage = not err.get_resource('is_multipackage') # Unpack the package and load it up. package = StringIO(file_data) try: sub_xpi = XPIManager(package, mode='r', name=name, subpackage=is_subpackage) except BadZipfile: err.error(('testcases_content', 'test_packed_packages', 'jar_subpackage_corrupt'), 'Subpackage corrupt.', 'The subpackage appears to be corrupt, and could not ' 'be opened.', name) return # Let the error bunder know we're in a sub-package. err.push_state(name) err.detected_type = (PACKAGE_SUBPACKAGE if is_subpackage else PACKAGE_THEME) err.set_tier(1) supported_versions = (err.supported_versions.copy() if err.supported_versions else err.supported_versions) if is_subpackage: testendpoint_validator.test_inner_package(err, sub_xpi) else: testendpoint_validator.test_package(err, package, name) err.pop_state() err.set_tier(2) err.supported_versions = supported_versions elif extension == '.xpi': # It's not a subpackage, it's a nested extension. These are # found in multi-extension packages. # Unpack! package = StringIO(file_data) err.push_state(name_lower) err.set_tier(1) # There are no expected types for packages within a multi- # item package. testendpoint_validator.test_package(err, package, name) err.pop_state() err.set_tier(2) # Reset to the current tier else: if not file_data: return # Convert the file data to unicode. file_data = unicodehelper.decode(file_data) if extension in ('.js', '.jsm'): testendpoint_js.test_js_file(err, name, file_data, pollutable=pollutable) elif extension == '.css': testendpoint_css.test_css_file(err, name, file_data) run_regex_tests(file_data, err, filename=name)
def test_lp_xpi(err, xpi_package): "Tests a language pack for L10n completeness" # Don't even both with the test(s) if there's no chrome.manifest. if "chrome.manifest" not in xpi_package: return None locales = _get_locales(err) # Get the reference packages. references = [] support_references = err.get_resource("supports") if not support_references: references.append("firefox") err.info(("testcases_l10ncompleteness", "test_lp_xpi", "missing_app_support"), "Supported app missing in localization completeness.", "While testing in localization comleteness, a list of " "supported applications for the language pack was not found. " "This is likely because there are no listed " "<em:targetApplication> elements in the install.rdf file.") else: for support in support_references: ref_xpi = XPIManager( os.path.join(os.path.dirname(__file__), "langpacks/%s.xpi" % support)) ref_xpi.app_name = support reference_locales = _get_locales(None, ref_xpi) references.append((ref_xpi, reference_locales)) # Iterate each supported reference package for (ref_xpi, ref_locales) in references: # Iterate each locale in each supported reference package ref_pack = _get_locale_manager(err, ref_xpi, { "path": "en-US.jar", "jarred": True }, no_cache=True) for ref_locale_name in ref_locales: ref_locale = ref_locales[ref_locale_name] ref_predicate = ref_locale["predicate"] corresp_locales = [ locales[name] for name in locales if locales[name]["predicate"] == ref_predicate ] # If we found no matching locale, then it's missing from the pack if not corresp_locales: err.warning( ("testcases_l10ncompleteness", "test_lp_xpi", "find_corresponding_locale"), "Could not find corresponding locale", [ "A locale was found in the reference package, " "however it was not found in the target package.", "Missing locale: %s" % ref_predicate ], filename="chrome.manifest") continue target_locale = corresp_locales[0] target_pack = _get_locale_manager(err, xpi_package, target_locale) if target_pack is None: continue results = _compare_packages(reference=ref_pack, target=target_pack, ref_base=ref_locale["target"], locale_base=target_locale["target"]) # Report the findings after each supported app's locale _aggregate_results(err, results, target_locale) # Clear the cache at the end of the test LOCALE_CACHE = {}
def test_open(): """Test that the manager will open the package.""" z = XPIManager(get_path('xpi/install_rdf_only.xpi')) assert z is not None
def test_lp_xpi(err, xpi_package): 'Tests a language pack for L10n completeness' # Don't even both with the test(s) if there's no chrome.manifest. if 'chrome.manifest' not in xpi_package: return None locales = _get_locales(err) # Get the reference packages. references = [] support_references = err.get_resource('supports') if not support_references: references.append('firefox') err.info(('testcases_l10ncompleteness', 'test_lp_xpi', 'missing_app_support'), 'Supported app missing in localization completeness.', 'While testing in localization comleteness, a list of ' 'supported applications for the language pack was not found. ' 'This is likely because there are no listed ' '<em:targetApplication> elements in the install.rdf file.') else: for support in support_references: ref_xpi = XPIManager( os.path.join(os.path.dirname(__file__), 'langpacks/%s.xpi' % support)) ref_xpi.app_name = support reference_locales = _get_locales(None, ref_xpi) references.append((ref_xpi, reference_locales)) # Iterate each supported reference package for (ref_xpi, ref_locales) in references: # Iterate each locale in each supported reference package ref_pack = _get_locale_manager(err, ref_xpi, { 'path': 'en-US.jar', 'jarred': True }, no_cache=True) for ref_locale_name in ref_locales: ref_locale = ref_locales[ref_locale_name] ref_predicate = ref_locale['predicate'] corresp_locales = [ locales[name] for name in locales if locales[name]['predicate'] == ref_predicate ] # If we found no matching locale, then it's missing from the pack if not corresp_locales: err.warning( ('testcases_l10ncompleteness', 'test_lp_xpi', 'find_corresponding_locale'), 'Could not find corresponding locale', [ 'A locale was found in the reference package, ' 'however it was not found in the target package.', 'Missing locale: %s' % ref_predicate ], filename='chrome.manifest') continue target_locale = corresp_locales[0] target_pack = _get_locale_manager(err, xpi_package, target_locale) if target_pack is None: continue results = _compare_packages(reference=ref_pack, target=target_pack, ref_base=ref_locale['target'], locale_base=target_locale['target']) # Report the findings after each supported app's locale _aggregate_results(err, results, target_locale) # Clear the cache at the end of the test LOCALE_CACHE.clear()
def test_read_file(): """Test that a file can be read from the package.""" z = XPIManager(get_path('xpi/install_rdf_only.xpi')) assert z.read('install.rdf') is not None
def _process_file(err, xpi_package, name, file_data, name_lower, pollutable=False): """Process a single file's content tests.""" # If that item is a container file, unzip it and scan it. if name_lower.endswith(".jar"): # This is either a subpackage or a nested theme. is_subpackage = not err.get_resource("is_multipackage") # Unpack the package and load it up. package = StringIO(file_data) try: sub_xpi = XPIManager(package, mode="r", name=name, subpackage=is_subpackage) except Exception: err.error(("testcases_content", "test_packed_packages", "jar_subpackage_corrupt"), "Subpackage corrupt.", "The subpackage could not be opened due to issues " "with corruption. Ensure that the file is valid.", name) return None # Let the error bunder know we're in a sub-package. err.push_state(name) err.detected_type = (PACKAGE_SUBPACKAGE if is_subpackage else PACKAGE_THEME) err.set_tier(1) supported_versions = (err.supported_versions.copy() if err.supported_versions else err.supported_versions) if is_subpackage: testendpoint_validator.test_inner_package(err, sub_xpi) else: testendpoint_validator.test_package(err, package, name) err.pop_state() err.set_tier(2) err.supported_versions = supported_versions elif name_lower.endswith(".xpi"): # It's not a subpackage, it's a nested extension. These are # found in multi-extension packages. # Unpack! package = StringIO(file_data) err.push_state(name_lower) err.set_tier(1) # There are no expected types for packages within a multi- # item package. testendpoint_validator.test_package(err, package, name) err.pop_state() err.set_tier(2) # Reset to the current tier elif name_lower.endswith((".css", ".js", ".jsm")): if not file_data: return None # Convert the file data to unicode file_data = unicodehelper.decode(file_data) is_js = False if name_lower.endswith(".css"): testendpoint_css.test_css_file(err, name, file_data) elif name_lower.endswith((".js", ".jsm")): is_js = True testendpoint_js.test_js_file(err, name, file_data, pollutable=pollutable) run_regex_tests(file_data, err, name, is_js=is_js) return True return False