Пример #1
0
def test_firefox_version_ensures_it_does_not_have_multiple_type(
        monkeypatch, version_string):
    # Let's make sure the sanity checks detect a broken regular expression
    monkeypatch.setattr(mozilla_version.gecko, '_VALID_ENOUGH_VERSION_PATTERN',
                        _SUPER_PERMISSIVE_PATTERN)

    with pytest.raises(TooManyTypesError):
        FirefoxVersion.parse(version_string)
Пример #2
0
def test_firefox_version_ensures_it_does_not_have_multiple_type(
        monkeypatch, version_string):
    # Let's make sure the sanity checks detect a broken regular expression
    original_pattern = FirefoxVersion._VALID_ENOUGH_VERSION_PATTERN
    FirefoxVersion._VALID_ENOUGH_VERSION_PATTERN = _SUPER_PERMISSIVE_PATTERN

    with pytest.raises(TooManyTypesError):
        FirefoxVersion.parse(version_string)

    FirefoxVersion._VALID_ENOUGH_VERSION_PATTERN = original_pattern
Пример #3
0
def good_version(release):
    '''Can the version be parsed by mozilla_version

    Some ancient versions cannot be parsed by the mozilla_version module. This
    function helps to skip the versions that are not supported.
    Example versions that cannot be parsed:
    1.1, 1.1b1, 2.0.0.1
    '''
    try:
        FirefoxVersion.parse(release['version'])
        return True
    except ValueError:
        return False
Пример #4
0
def _generate_beetmover_template_args_maven(task, release_props):
    tmpl_args = {
        "artifact_id": task["payload"]["artifact_id"],
        "template_key": "maven_{}".format(release_props["appName"])
    }

    # Geckoview follows the FirefoxVersion pattern
    if release_props.get("appName") == "geckoview":
        payload_version = FirefoxVersion.parse(task["payload"]["version"])
        # Change version number to major.minor.buildId because that's what the build task produces
        version = [
            payload_version.major_number, payload_version.minor_number,
            release_props["buildid"]
        ]
    else:
        payload_version = MavenVersion.parse(task["payload"]["version"])
        version = [
            payload_version.major_number, payload_version.minor_number,
            payload_version.patch_number
        ]

    if any(number is None for number in version):
        raise TaskVerificationError(
            "At least one digit is undefined. Got: {}".format(version))
    tmpl_args["version"] = ".".join(str(n) for n in version)

    # XXX: some appservices maven.zip files have a different structure,
    # encompassing only `pom` and `jar` files. We toggle that behavior in the
    # mapping by using this flag
    tmpl_args["is_jar"] = task["payload"].get("is_jar")

    return tmpl_args
def _generate_beetmover_template_args_maven(task, release_props):
    tmpl_args = {
        'artifact_id': task['payload']['artifact_id'],
        'template_key': 'maven_{}'.format(release_props['appName']),
    }

    # FIXME: this is a temporarily solution while we sanitize the payload
    # under https://github.com/mozilla-releng/beetmoverscript/issues/196
    if 'SNAPSHOT' in task['payload']['version']:
        payload_version = MavenVersion.parse(task['payload']['version'])
    else:
        payload_version = FirefoxVersion.parse(task['payload']['version'])
    # Change version number to major.minor.buildId because that's what the build task produces
    version = [
        payload_version.major_number, payload_version.minor_number,
        release_props.get('buildid', payload_version.patch_number)
    ]
    if any(number is None for number in version):
        raise TaskVerificationError(
            'At least one digit is undefined. Got: {}'.format(version))
    tmpl_args['version'] = '.'.join(str(n) for n in version)

    if isinstance(payload_version,
                  MavenVersion) and payload_version.is_snapshot:
        tmpl_args['snapshot_version'] = payload_version
        tmpl_args['date_timestamp'] = "{{date_timestamp}}"
        tmpl_args['clock_timestamp'] = "{{clock_timestamp}}"
        tmpl_args['build_number'] = "{{build_number}}"

    return tmpl_args
Пример #6
0
def is_partner_enabled(product, version, min_version=60):
    if product == "firefox":
        firefox_version = FirefoxVersion.parse(version)
        return firefox_version.major_number >= min_version and any(
            (firefox_version.is_beta and firefox_version.beta_number >= 8,
             firefox_version.is_release, firefox_version.is_esr))

    return False
Пример #7
0
def is_eme_free_enabled(product, version):
    if product == "firefox":
        firefox_version = FirefoxVersion.parse(version)
        return any(
            (firefox_version.is_beta
             and firefox_version.beta_number >= 8, firefox_version.is_release))

    return False
Пример #8
0
def check_versions_are_successive(current_version, payload_version, product):
    """Function to check if the provided version in the payload and the existing
    one in bouncer are successive as valid versions."""
    def _successive_sanity(current_identifier, candidate_identifier):
        if current_identifier == candidate_identifier:
            err_msg = (
                "Identifiers for {} and {} can't be equal at this point "
                "in the code".format(payload_version, current_version))
            raise ScriptWorkerTaskException(err_msg)
        elif current_identifier > candidate_identifier:
            err_msg = ("In-tree version {} can't be less than current bouncer "
                       "counterpart".format(payload_version, current_version))
            raise ScriptWorkerTaskException(err_msg)
        elif (candidate_identifier - current_identifier) > 1:
            err_msg = (
                "In-tree version {} can't be greater than current bouncer "
                "by more than 1 digit".format(payload_version,
                                              current_version))
            raise ScriptWorkerTaskException(err_msg)

    # XXX: for Firefox central nightlies we need to handle the major number
    # while for Fennec nightlies on ESR we need to handle minor_number
    if product == "firefox":
        current_bouncer_version = FirefoxVersion.parse(current_version)
        candidate_version = FirefoxVersion.parse(payload_version)

        _successive_sanity(current_bouncer_version.major_number,
                           candidate_version.major_number)
    elif product == "fennec":
        # XXX: this will fail for the next ESR cut, on 75, since that will be a
        # major_number bump, but also a minor_number. But cutting ESR releases
        # can vary over time (could be 7 releases or 8 like ESR8, etc);
        # It's unrecommended to hardcode those variable window times here
        # in order to ensure the check; So for now we leave this code smell here.
        # Real fix is to centralize this operation and implement it in mozilla-version directly
        current_bouncer_version = FennecVersion.parse(current_version)
        candidate_version = FennecVersion.parse(payload_version)

        _successive_sanity(current_bouncer_version.minor_number,
                           candidate_version.minor_number)
    else:
        err_msg = "Unknown product {} in the payload".format(product)
        raise ScriptWorkerTaskException(err_msg)

    log.info("Versions are successive. All good")
Пример #9
0
def test_firefox_version_supports_released_edge_cases(version_string):
    assert str(FirefoxVersion.parse(version_string)) == version_string
    for Class in (DeveditionVersion, FennecVersion, ThunderbirdVersion):
        if Class == FennecVersion and version_string in ('33.1', '33.1build1',
                                                         '33.1build2'):
            # These edge cases also exist in Fennec
            continue
        with pytest.raises(PatternNotMatchedError):
            Class.parse(version_string)
Пример #10
0
def list_releases(product=None, branch=None, version=None, build_number=None,
                  status=['scheduled']):
    session = current_app.db.session
    releases = session.query(Release)
    if product:
        releases = releases.filter(Release.product == product)
    if branch:
        releases = releases.filter(Release.branch == branch)
    if version:
        releases = releases.filter(Release.version == version)
        if build_number:
            releases = releases.filter(Release.build_number == build_number)
    elif build_number:
        raise BadRequest(description='Filtering by build_number without version'
                         ' is not supported.')
    releases = releases.filter(Release.status.in_(status))
    releases = [r.json for r in releases.all()]
    # filter out not parsable releases, like 1.1, 1.1b1, etc
    releases = filter(good_version, releases)
    return sorted(releases, key=lambda r: FirefoxVersion.parse(r['version']))
Пример #11
0
def _generate_beetmover_template_args_maven(task, release_props):
    tmpl_args = {
        'artifact_id': task['payload']['artifact_id'],
        'template_key': 'maven_{}'.format(release_props['appName']),
    }

    # Geckoview follows the FirefoxVersion pattern
    if release_props.get('appName') == 'geckoview':
        payload_version = FirefoxVersion.parse(task['payload']['version'])
        # Change version number to major.minor.buildId because that's what the build task produces
        version = [
            payload_version.major_number,
            payload_version.minor_number,
            release_props['buildid'],
        ]
    else:
        payload_version = MavenVersion.parse(task['payload']['version'])
        version = [
            payload_version.major_number,
            payload_version.minor_number,
            payload_version.patch_number,
        ]

    if any(number is None for number in version):
        raise TaskVerificationError(
            'At least one digit is undefined. Got: {}'.format(version))
    tmpl_args['version'] = '.'.join(str(n) for n in version)

    # XXX: some appservices maven.zip files have a different structure,
    # encompassing only `pom` and `jar` files. We toggle that behavior in the
    # mapping by using this flag
    tmpl_args['is_jar'] = task['payload'].get('is_jar')

    if isinstance(payload_version,
                  MavenVersion) and payload_version.is_snapshot:
        tmpl_args['snapshot_version'] = payload_version
        tmpl_args['date_timestamp'] = "{{date_timestamp}}"
        tmpl_args['clock_timestamp'] = "{{clock_timestamp}}"
        tmpl_args['build_number'] = "{{build_number}}"

    return tmpl_args
Пример #12
0
def get_maven_version(context):
    """Extract and validate a valid Maven version"""
    version = context.task["payload"]["version"]
    release_props = context.release_props
    # TODO The following 'if' should be removed once GeckoView >= 84 is in mozilla-release.
    # This is a temporary solution to maintain compatibility while the 'version' field in
    # GeckoView's payload transitions from FirefoxVersion format to MavenVersion.
    if release_props.get("appName") == "geckoview":
        app_version = FirefoxVersion.parse(release_props["appVersion"])
        if int(app_version.major_number) < 84:
            # Change version number to major.minor.buildId because that's what the build task produces
            version = "{}.{}.{}".format(app_version.major_number,
                                        app_version.minor_number,
                                        release_props["buildid"])

    # Check that version is a valid maven version
    try:
        MavenVersion.parse(version)
    except (ValueError, PatternNotMatchedError) as e:
        raise ScriptWorkerTaskException(
            f"Version defined in the payload does not match the pattern of a MavenVersion. Got: {version}"
        ) from e

    return version
Пример #13
0
def test_firefox_version_implements_str_operator(version_string,
                                                 expected_output):
    assert str(FirefoxVersion.parse(version_string)) == expected_output
Пример #14
0
def test_firefox_version_implements_remaining_comparision_operators():
    assert FirefoxVersion.parse('32.0') <= FirefoxVersion.parse('32.0')
    assert FirefoxVersion.parse('32.0') <= FirefoxVersion.parse('33.0')

    assert FirefoxVersion.parse('33.0') >= FirefoxVersion.parse('32.0')
    assert FirefoxVersion.parse('33.0') >= FirefoxVersion.parse('33.0')

    assert FirefoxVersion.parse('33.0') > FirefoxVersion.parse('32.0')
    assert not FirefoxVersion.parse('33.0') > FirefoxVersion.parse('33.0')

    assert not FirefoxVersion.parse('32.0') < FirefoxVersion.parse('32.0')

    assert FirefoxVersion.parse('33.0') != FirefoxVersion.parse('32.0')
Пример #15
0
def test_firefox_version_raises_eq_operator(wrong_type):
    with pytest.raises(ValueError):
        assert FirefoxVersion.parse('32.0') == wrong_type
    # AttributeError is raised by LooseVersion and StrictVersion
    with pytest.raises((ValueError, AttributeError)):
        assert wrong_type == FirefoxVersion.parse('32.0')
Пример #16
0
def test_firefox_version_implements_eq_operator(equivalent_version_string):
    assert FirefoxVersion.parse('32.0') == FirefoxVersion.parse(
        equivalent_version_string)
    # raw strings are also converted
    assert FirefoxVersion.parse('32.0') == equivalent_version_string
Пример #17
0
def test_firefox_version_implements_lt_operator(previous, next):
    assert FirefoxVersion.parse(previous) < FirefoxVersion.parse(next)
Пример #18
0
    mocker.patch.object(merges, "replace", new=noop_replace)
    mocker.patch.object(merges, "touch_clobber_file", new=sync_noop)

    await merges.apply_rebranding(config, repo_context.repo, merge_config)
    assert called_args[0] == expected


@pytest.mark.asyncio
@pytest.mark.parametrize(
    "version_config,current_version, expected",
    (
        # central-to-beta
        ({
            "filename": "config/milestone.txt",
            "new_suffix": ""
        }, FirefoxVersion.parse("75.0a1"), "75.0"),
        ({
            "filename": "browser/config/version_display.txt",
            "new_suffix": "b1"
        }, FirefoxVersion.parse("75.0a1"), "75.0b1"),
        # beta-to-release
        ({
            "filename": "browser/config/version_display.txt",
            "new_suffix": ""
        }, FirefoxVersion.parse("75.0b9"), "75.0"),
        # bump_central
        ({
            "filename": "config/milestone.txt",
            "version_bump": "major"
        }, FirefoxVersion.parse("75.0a1"), "76.0a1"),
        ({
Пример #19
0
def test_firefox_version_raises_when_invalid_version_is_given(
        version_string, ExpectedErrorType):
    with pytest.raises(ExpectedErrorType):
        FirefoxVersion.parse(version_string)
Пример #20
0
def test_firefox_version_is_of_a_defined_type(version_string, expected_type):
    release = FirefoxVersion.parse(version_string)
    assert getattr(release, 'is_{}'.format(expected_type))
Пример #21
0
 def mocked_get_version(path, repo_path):
     return FirefoxVersion.parse("76.0")
Пример #22
0
    mocker.patch.object(merges, "get_version", new=mocked_get_version)
    mocker.patch.object(merges, "do_bump_version", new=noop_bump_version)
    mocker.patch.object(shutil, "copyfile", new=noop_copyfile)
    mocker.patch.object(merges, "replace", new=noop_replace)
    mocker.patch.object(merges, "touch_clobber_file", new=sync_noop)

    await merges.apply_rebranding(config, repo_context.repo, merge_config)
    assert called_args[0] == expected


@pytest.mark.asyncio
@pytest.mark.parametrize(
    "version_config,current_version, expected",
    (
        # central-to-beta
        ({"filename": "config/milestone.txt", "new_suffix": ""}, FirefoxVersion.parse("75.0a1"), "75.0"),
        ({"filename": "browser/config/version_display.txt", "new_suffix": "b1"}, FirefoxVersion.parse("75.0a1"), "75.0b1"),
        # beta-to-release
        ({"filename": "browser/config/version_display.txt", "new_suffix": ""}, FirefoxVersion.parse("75.0b9"), "75.0"),
        # bump_central
        ({"filename": "config/milestone.txt", "version_bump": "major"}, FirefoxVersion.parse("75.0a1"), "76.0a1"),
        ({"filename": "config/milestone.txt", "version_bump": "major"}, FirefoxVersion.parse("75.0"), "76.0"),
        # bump_esr
        ({"filename": "browser/config/version.txt", "version_bump": "minor"}, FirefoxVersion.parse("68.1.0"), "68.2.0"),
        ({"filename": "browser/config/version_display.txt", "version_bump": "minor"}, FirefoxVersion.parse("68.1.0esr"), "68.2.0esr"),
        ({"filename": "mobile/android/config/version-files/beta/version.txt", "version_bump": "minor"}, FennecVersion.parse("68.1"), "68.2"),
        ({"filename": "mobile/android/config/version-files/beta/version_display.txt", "version_bump": "minor"}, FennecVersion.parse("68.1b9"), "68.2b1"),
        ({"filename": "mobile/android/config/version-files/nightly/version.txt", "version_bump": "minor"}, FennecVersion.parse("68.1a1"), "68.2a1"),
        ({"filename": "mobile/android/config/version-files/release/version.txt", "version_bump": "minor"}, FennecVersion.parse("68.6.1"), "68.7.0"),
    ),
)