#!/usr/bin/env python # lint_ignore=E501 # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this file, # You can obtain one at http://mozilla.org/MPL/2.0/. """ bouncer_check.py
A script to check HTTP statuses of Bouncer products to be shipped. """
class BouncerCheck(BaseScript):
config_options = [
[
["--version"],
{ "dest": "version", "help": "Version of release, eg: 39.0b5",
},
],
[
["--product-field"],
{ "dest": "product_field", "help": "Version field of release from product details, eg: LATEST_FIREFOX_VERSION", # NOQA: E501
},
],
[
["--products-url"],
{ "dest": "products_url", "help": "The URL of the current Firefox product versions", "type": str, "default": "https://product-details.mozilla.org/1.0/firefox_versions.json",
},
],
[
["--previous-version"],
{ "dest": "prev_versions", "action": "extend", "help": "Previous version(s)",
},
],
[
["--locale"],
{ "dest": "locales", # Intentionally limited for several reasons: # 1) faster to check # 2) do not need to deal with situation when a new locale # introduced and we do not have partials for it yet # 3) it mimics the old Sentry behaviour that worked for ages # 4) no need to handle ja-JP-mac "default": ["en-US", "de", "it", "zh-TW"], "action": "append", "help": "List of locales to check.",
},
],
[
["-j", "--parallelization"],
{ "dest": "parallelization", "default": 20, "type": int, "help": "Number of HTTP sessions running in parallel",
},
],
]
final_url = urlparse(r.url) if final_url.scheme != "https":
self.error("FAIL: URL scheme is not https: {}".format(r.url))
self.return_code = EXIT_STATUS_DICT[TBPL_FAILURE]
if final_url.netloc notin self.config["cdn_urls"]:
self.error("FAIL: host not in allowed locations: {}".format(r.url))
self.return_code = EXIT_STATUS_DICT[TBPL_FAILURE]
try:
retry(do_check_url, sleeptime=3, max_sleeptime=10, attempts=3) except HTTPError: # The error was already logged above.
self.return_code = EXIT_STATUS_DICT[TBPL_FAILURE] return
def get_urls(self): for product in self.config["products"].values():
product_name = product["product-name"] % {"version": self.config["version"]} for bouncer_platform in product["platforms"]: for locale in self.config["locales"]:
url = BOUNCER_URL_PATTERN.format(
bouncer_prefix=self.config["bouncer_prefix"],
product=product_name,
os=bouncer_platform,
lang=locale,
) yield url
for product in self.config.get("partials", {}).values(): for prev_version in self.config.get("prev_versions", []):
product_name = product["product-name"] % { "version": self.config["version"], "prev_version": prev_version,
} for bouncer_platform in product["platforms"]: for locale in self.config["locales"]:
url = BOUNCER_URL_PATTERN.format(
bouncer_prefix=self.config["bouncer_prefix"],
product=product_name,
os=bouncer_platform,
lang=locale,
) yield url
def check_bouncer(self): import concurrent.futures as futures
with futures.ThreadPoolExecutor(self.config["parallelization"]) as e:
fs = [] for url in self.get_urls():
fs.append(e.submit(self.check_url, session, url)) for f in futures.as_completed(fs):
f.result()
if __name__ == "__main__":
BouncerCheck().run_and_exit()
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.13 Sekunden
(vorverarbeitet am 2026-06-05)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.