예제 #1
0
    def random_aus_test(self, background_rate, force=None, fallback=False):
        mapping = 'b'
        with mock.patch('auslib.db.Rules.getRulesMatchingQuery') as m:
            fallback = fallback and 'fallback'  # convert True to string
            m.return_value = [dict(backgroundRate=background_rate, priority=1, mapping=mapping, update_type='minor',
                                   fallbackMapping=fallback)]

            results = list(ENTIRE_RANGE)
            resultsLength = len(results)

            def se(*args, **kwargs):
                return results.pop()

            aus = AUS()
            aus.rand = mock.Mock(side_effect=se)
            served_mapping = 0
            served_fallback = 0
            tested = 0
            while len(results) > 0:
                updateQuery = dict(
                    channel='foo', force=force, buildTarget='a', buildID='0',
                    locale='a', version='1.0', product='bar'
                )
                r, _ = aus.evaluateRules(updateQuery)
                tested += 1
                if r and r['name'] == mapping:
                    served_mapping += 1
                elif fallback and r['name'] == fallback:
                    served_fallback += 1
                # bail out if we're not asking for any randint's
                if resultsLength == len(results):
                    break
            return (served_mapping, served_fallback, tested)
예제 #2
0
    def random_aus_test(self, background_rate, force=None, fallback=False):
        mapping = "b"
        with mock.patch("auslib.db.Rules.getRulesMatchingQuery") as m:
            fallback = fallback and "fallback"  # convert True to string
            m.return_value = [dict(backgroundRate=background_rate, priority=1, mapping=mapping, update_type="minor", fallbackMapping=fallback)]

            results = list(ENTIRE_RANGE)
            resultsLength = len(results)

            def se(*args, **kwargs):
                return results.pop()

            aus = AUS()
            aus.rand = mock.Mock(side_effect=se)
            served_mapping = 0
            served_fallback = 0
            tested = 0
            while len(results) > 0:
                updateQuery = dict(channel="foo", force=force, buildTarget="a", buildID="0", locale="a", version="1.0", product="bar")
                r, _ = aus.evaluateRules(updateQuery)
                tested += 1
                if r and r["name"] == mapping:
                    served_mapping += 1
                elif fallback and r["name"] == fallback:
                    served_fallback += 1
                # bail out if we're not asking for any randint's
                if resultsLength == len(results):
                    break
            return (served_mapping, served_fallback, tested)
예제 #3
0
def RandomAUSTest(AUS, backgroundRate, force, mapping):
    with mock.patch('auslib.db.Rules.getRulesMatchingQuery') as m:
        m.return_value = [
            dict(backgroundRate=backgroundRate,
                 priority=1,
                 mapping=mapping,
                 update_type='minor',
                 whitelist=None)
        ]

        results = AUS.rand.getRange()
        resultsLength = len(results)

        def se(*args, **kwargs):
            return results.pop()

        with mock.patch('auslib.AUS.AUSRandom.getInt') as m2:
            m2.side_effect = se
            served = 0
            tested = 0
            while len(results) > 0:
                updateQuery = dict(channel='foo',
                                   force=force,
                                   buildTarget='a',
                                   buildID='0',
                                   locale='a',
                                   version='1.0')
                r, _ = AUS.evaluateRules(updateQuery)
                tested += 1
                if r:
                    served += 1
                # bail out if we're not asking for any randint's
                if resultsLength == len(results):
                    break
            return (served, tested)
예제 #4
0
파일: test_AUS.py 프로젝트: aksareen/balrog
def RandomAUSTestWithFallback(AUS, backgroundRate, force, mapping):
    with mock.patch('auslib.db.Rules.getRulesMatchingQuery') as m:
        m.return_value = [dict(backgroundRate=backgroundRate, priority=1, mapping=mapping, update_type='minor',
                               fallbackMapping='fallback')]

        results = AUS.rand.getRange()
        resultsLength = len(results)

        def se(*args, **kwargs):
            return results.pop()
        with mock.patch('auslib.AUS.AUSRandom.getInt') as m2:
            m2.side_effect = se
            served_mapping = 0
            served_fallback = 0
            tested = 0
            while len(results) > 0:
                updateQuery = dict(
                    channel='foo', force=force, buildTarget='a', buildID='0',
                    locale='a', version='1.0',
                )
                r, _ = AUS.evaluateRules(updateQuery)
                tested += 1
                if r['name'] == mapping:
                    served_mapping += 1
                elif r['name'] == "fallback":
                    served_fallback += 1
                # bail out if we're not asking for any randint's
                if resultsLength == len(results):
                    break
            return (served_mapping, served_fallback, tested)
예제 #5
0
 def setUp(self):
     self.AUS = AUS()
     dbo.setDb('sqlite:///:memory:')
     dbo.create()
     dbo.releases.t.insert().execute(
         name='b',
         product='b',
         data_version=1,
         data=
         '{"name": "b", "extv": "1.0", "schema_version": 1, "platforms": {"a": {"buildID": "1", "locales": {"a": {}}}}}'
     )
예제 #6
0
from functools import wraps

from auslib.AUS import AUS
from auslib.global_state import dbo


def with_transaction(f):
    @wraps(f)
    def wrapper(*args, **kwargs):
        with dbo.begin() as transaction:
            return f(*args, transaction=transaction, **kwargs)

    return wrapper


AUS = AUS()
예제 #7
0
파일: client.py 프로젝트: aksareen/balrog
def get_update_blob(**url):
    query = getQueryFromURL(url)
    LOG.debug("Got query: %s", query)
    release, update_type = AUS.evaluateRules(query)

    # passing {},None returns empty xml
    if release:
        response_products = release.getResponseProducts()
        response_blobs = []
        response_blob_names = release.getResponseBlobs()
        if response_products:
            # if we have a SuperBlob of gmp, we process the response products and
            # concatenate their inner XMLs
            for product in response_products:
                product_query = query.copy()
                product_query["product"] = product
                response_release, response_update_type = AUS.evaluateRules(product_query)
                if not response_release:
                    continue

                response_blobs.append({'product_query': product_query,
                                       'response_release': response_release,
                                       'response_update_type': response_update_type})
        elif response_blob_names:
            for blob_name in response_blob_names:
                # if we have a SuperBlob of systemaddons, we process the response products and
                # concatenate their inner XMLs
                product_query = query.copy()
                product = dbo.releases.getReleases(name=blob_name, limit=1)[0]['product']
                product_query["product"] = product
                response_release = dbo.releases.getReleaseBlob(name=blob_name)
                if not response_release:
                    LOG.warning("No release found with name: %s", blob_name)
                    continue

                response_blobs.append({'product_query': product_query,
                                       'response_release': response_release,
                                       'response_update_type': update_type})
        else:
            response_blobs.append({'product_query': query,
                                   'response_release': release,
                                   'response_update_type': update_type})

        # getHeaderXML() returns outermost header for an update which
        # is same for all release type
        xml = release.getHeaderXML()
        # we assume that all blobs will have similar ones. We might want to
        # verify that all of them are indeed the same in the future.

        # Appending Header
        # In case of superblob Extracting Header form parent release
        xml.append(release.getInnerHeaderXML(query,
                                             update_type,
                                             app.config["WHITELISTED_DOMAINS"],
                                             app.config["SPECIAL_FORCE_HOSTS"]))
        for response_blob in response_blobs:
            xml.extend(response_blob['response_release']
                       .getInnerXML(response_blob['product_query'],
                                    response_blob['response_update_type'],
                                    app.config["WHITELISTED_DOMAINS"],
                                    app.config["SPECIAL_FORCE_HOSTS"]))
        # Appending Footer
        # In case of superblob Extracting Header form parent release
        xml.append(release.getInnerFooterXML(query,
                                             update_type,
                                             app.config["WHITELISTED_DOMAINS"],
                                             app.config["SPECIAL_FORCE_HOSTS"]))
        xml.append(release.getFooterXML())
        # ensure valid xml by using the right entity for ampersand
        xml = re.sub('&(?!amp;)', '&', '\n'.join(xml))
    else:
        xml = ['<?xml version="1.0"?>']
        xml.append('<updates>')
        xml.append('</updates>')
        xml = "\n".join(xml)
    LOG.debug("Sending XML: %s", xml)
    response = make_response(xml)
    response.headers["Cache-Control"] = app.cacheControl
    response.mimetype = "text/xml"
    return response
예제 #8
0
def get_update_blob(transaction, **url):
    url['queryVersion'] = extract_query_version(request.url)
    # Underlying code depends on osVersion being set. Since this route only
    # exists to support ancient queries, and all newer versions have osVersion
    # in them it's easier to set this here than make the all of the underlying
    # code support queries without it.
    if url['queryVersion'] == 1:
        url['osVersion'] = ''
    # Bug 1517743 - two Firefox nightlies can't parse update.xml when it contains the usual newlines or indentations
    squash_response = False

    query = getQueryFromURL(url)
    LOG.debug("Got query: %s", query)
    release, update_type = AUS.evaluateRules(query, transaction=transaction)

    # passing {},None returns empty xml
    if release:
        response_products = release.getResponseProducts()
        response_blobs = []
        response_blob_names = release.getResponseBlobs()
        if response_products:
            # if we have a SuperBlob of gmp, we process the response products and
            # concatenate their inner XMLs
            for product in response_products:
                product_query = query.copy()
                product_query["product"] = product
                response_release, response_update_type = AUS.evaluateRules(
                    product_query, transaction=transaction)
                if not response_release:
                    continue

                response_blobs.append({
                    'product_query':
                    product_query,
                    'response_release':
                    response_release,
                    'response_update_type':
                    response_update_type
                })
        elif response_blob_names:
            for blob_name in response_blob_names:
                # if we have a SuperBlob of systemaddons, we process the response products and
                # concatenate their inner XMLs
                product_query = query.copy()
                product = dbo.releases.getReleases(
                    name=blob_name, limit=1,
                    transaction=transaction)[0]['product']
                product_query["product"] = product
                response_release = dbo.releases.getReleaseBlob(
                    name=blob_name, transaction=transaction)
                if not response_release:
                    LOG.warning("No release found with name: %s", blob_name)
                    continue

                response_blobs.append({
                    'product_query': product_query,
                    'response_release': response_release,
                    'response_update_type': update_type
                })
        else:
            response_blobs.append({
                'product_query': query,
                'response_release': release,
                'response_update_type': update_type
            })
            # Bug 1517743 - we want a cheap test because this will be run on each request
            if release[
                    'name'] == 'Firefox-mozilla-central-nightly-latest' and query[
                        'buildID'] in ('20190103220533', '20190104093221'):
                squash_response = True
                LOG.debug('Busted nightly detected, will squash xml response')

        # getHeaderXML() returns outermost header for an update which
        # is same for all release type
        xml = release.getHeaderXML()
        # we assume that all blobs will have similar ones. We might want to
        # verify that all of them are indeed the same in the future.

        # Appending Header
        # In case of superblob Extracting Header form parent release
        xml.append(
            release.getInnerHeaderXML(query, update_type,
                                      app.config["WHITELISTED_DOMAINS"],
                                      app.config["SPECIAL_FORCE_HOSTS"]))
        for response_blob in response_blobs:
            xml.extend(response_blob['response_release'].getInnerXML(
                response_blob['product_query'],
                response_blob['response_update_type'],
                app.config["WHITELISTED_DOMAINS"],
                app.config["SPECIAL_FORCE_HOSTS"]))
        # Appending Footer
        # In case of superblob Extracting Header form parent release
        xml.append(
            release.getInnerFooterXML(query, update_type,
                                      app.config["WHITELISTED_DOMAINS"],
                                      app.config["SPECIAL_FORCE_HOSTS"]))
        xml.append(release.getFooterXML())
        # ensure valid xml by using the right entity for ampersand
        xml = re.sub('&(?!amp;)', '&amp;', '\n'.join(xml))
    else:
        xml = ['<?xml version="1.0"?>']
        xml.append('<updates>')
        xml.append('</updates>')
        xml = "\n".join(xml)

    # Bug 1517743 - remove newlines and 4 space indents
    if squash_response:
        xml = xml.replace('\n', '').replace('    ', '')

    LOG.debug("Sending XML: %s", xml)
    response = make_response(xml)
    response.headers["Cache-Control"] = app.cacheControl
    response.mimetype = "text/xml"
    return response
예제 #9
0
def get_update_blob(**url):
    url['queryVersion'] = extract_query_version(request.url)
    # Underlying code depends on osVersion being set. Since this route only
    # exists to support ancient queries, and all newer versions have osVersion
    # in them it's easier to set this here than make the all of the underlying
    # code support queries without it.
    if url['queryVersion'] == 1:
        url['osVersion'] = ''

    query = getQueryFromURL(url)
    LOG.debug("Got query: %s", query)
    release, update_type = AUS.evaluateRules(query)

    # passing {},None returns empty xml
    if release:
        response_products = release.getResponseProducts()
        response_blobs = []
        response_blob_names = release.getResponseBlobs()
        if response_products:
            # if we have a SuperBlob of gmp, we process the response products and
            # concatenate their inner XMLs
            for product in response_products:
                product_query = query.copy()
                product_query["product"] = product
                response_release, response_update_type = AUS.evaluateRules(
                    product_query)
                if not response_release:
                    continue

                response_blobs.append({
                    'product_query':
                    product_query,
                    'response_release':
                    response_release,
                    'response_update_type':
                    response_update_type
                })
        elif response_blob_names:
            for blob_name in response_blob_names:
                # if we have a SuperBlob of systemaddons, we process the response products and
                # concatenate their inner XMLs
                product_query = query.copy()
                product = dbo.releases.getReleases(name=blob_name,
                                                   limit=1)[0]['product']
                product_query["product"] = product
                response_release = dbo.releases.getReleaseBlob(name=blob_name)
                if not response_release:
                    LOG.warning("No release found with name: %s", blob_name)
                    continue

                response_blobs.append({
                    'product_query': product_query,
                    'response_release': response_release,
                    'response_update_type': update_type
                })
        else:
            response_blobs.append({
                'product_query': query,
                'response_release': release,
                'response_update_type': update_type
            })

        # getHeaderXML() returns outermost header for an update which
        # is same for all release type
        xml = release.getHeaderXML()
        # we assume that all blobs will have similar ones. We might want to
        # verify that all of them are indeed the same in the future.

        # Appending Header
        # In case of superblob Extracting Header form parent release
        xml.append(
            release.getInnerHeaderXML(query, update_type,
                                      app.config["WHITELISTED_DOMAINS"],
                                      app.config["SPECIAL_FORCE_HOSTS"]))
        for response_blob in response_blobs:
            xml.extend(response_blob['response_release'].getInnerXML(
                response_blob['product_query'],
                response_blob['response_update_type'],
                app.config["WHITELISTED_DOMAINS"],
                app.config["SPECIAL_FORCE_HOSTS"]))
        # Appending Footer
        # In case of superblob Extracting Header form parent release
        xml.append(
            release.getInnerFooterXML(query, update_type,
                                      app.config["WHITELISTED_DOMAINS"],
                                      app.config["SPECIAL_FORCE_HOSTS"]))
        xml.append(release.getFooterXML())
        # ensure valid xml by using the right entity for ampersand
        xml = re.sub('&(?!amp;)', '&amp;', '\n'.join(xml))
    else:
        xml = ['<?xml version="1.0"?>']
        xml.append('<updates>')
        xml.append('</updates>')
        xml = "\n".join(xml)
    LOG.debug("Sending XML: %s", xml)
    response = make_response(xml)
    response.headers["Cache-Control"] = app.cacheControl
    response.mimetype = "text/xml"
    return response
예제 #10
0
def get_update_blob(transaction, **url):
    url["queryVersion"] = extract_query_version(request.url)
    # Underlying code depends on osVersion being set. Since this route only
    # exists to support ancient queries, and all newer versions have osVersion
    # in them it's easier to set this here than make the all of the underlying
    # code support queries without it.
    if url["queryVersion"] == 1:
        url["osVersion"] = ""
    # Bug 1517743 - two Firefox nightlies can't parse update.xml when it contains the usual newlines or indentations
    squash_response = False

    query = getQueryFromURL(url)
    LOG.debug("Got query: %s", query)
    release, update_type = AUS.evaluateRules(query, transaction=transaction)

    # passing {},None returns empty xml
    if release:
        response_products = release.getResponseProducts()
        response_blobs = []
        response_blob_names = release.getResponseBlobs()
        if response_products:
            # if we have a SuperBlob of gmp, we process the response products and
            # concatenate their inner XMLs
            for product in response_products:
                product_query = query.copy()
                product_query["product"] = product
                response_release, response_update_type = AUS.evaluateRules(product_query, transaction=transaction)
                if not response_release:
                    continue

                response_blobs.append({"product_query": product_query, "response_release": response_release, "response_update_type": response_update_type})
        elif response_blob_names:
            for blob_name in response_blob_names:
                # if we have a SuperBlob of systemaddons, we process the response products and
                # concatenate their inner XMLs
                product_query = query.copy()
                product = dbo.releases.getReleases(name=blob_name, limit=1, transaction=transaction)[0]["product"]
                product_query["product"] = product
                response_release = dbo.releases.getReleaseBlob(name=blob_name, transaction=transaction)
                if not response_release:
                    LOG.warning("No release found with name: %s", blob_name)
                    continue

                response_blobs.append({"product_query": product_query, "response_release": response_release, "response_update_type": update_type})
        else:
            response_blobs.append({"product_query": query, "response_release": release, "response_update_type": update_type})
            # Bug 1517743 - we want a cheap test because this will be run on each request
            if release["name"] == "Firefox-mozilla-central-nightly-latest" and query["buildID"] in ("20190103220533", "20190104093221"):
                squash_response = True
                LOG.debug("Busted nightly detected, will squash xml response")

        # getHeaderXML() returns outermost header for an update which
        # is same for all release type
        xml = release.getHeaderXML()
        # we assume that all blobs will have similar ones. We might want to
        # verify that all of them are indeed the same in the future.

        # Appending Header
        # In case of superblob Extracting Header form parent release
        xml.append(release.getInnerHeaderXML(query, update_type, app.config["WHITELISTED_DOMAINS"], app.config["SPECIAL_FORCE_HOSTS"]))
        for response_blob in response_blobs:
            xml.extend(
                response_blob["response_release"].getInnerXML(
                    response_blob["product_query"], response_blob["response_update_type"], app.config["WHITELISTED_DOMAINS"], app.config["SPECIAL_FORCE_HOSTS"]
                )
            )
        # Appending Footer
        # In case of superblob Extracting Header form parent release
        xml.append(release.getInnerFooterXML(query, update_type, app.config["WHITELISTED_DOMAINS"], app.config["SPECIAL_FORCE_HOSTS"]))
        xml.append(release.getFooterXML())
        # ensure valid xml by using the right entity for ampersand
        xml = re.sub("&(?!amp;)", "&amp;", "\n".join(xml))
    else:
        xml = ['<?xml version="1.0"?>']
        xml.append("<updates>")
        xml.append("</updates>")
        xml = "\n".join(xml)

    # Bug 1517743 - remove newlines and 4 space indents
    if squash_response:
        xml = xml.replace("\n", "").replace("    ", "")

    LOG.debug("Sending XML: %s", xml)
    response = make_response(xml)
    response.headers["Cache-Control"] = app.cacheControl
    response.mimetype = "text/xml"
    return response