Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 13 additions & 38 deletions pollbot/tasks/bouncer.py
Original file line number Diff line number Diff line change
@@ -1,58 +1,33 @@
import os.path


from pyquery import PyQuery as pq
from pollbot.exceptions import TaskError
from pollbot.utils import (build_version_id, Channel, get_version_channel,
get_version_from_filename)
from . import get_session, heartbeat_factory, build_task_response


async def bouncer(product, version):
"""Fetch bedrock download page to grab the bouncer download link and then make sure
it redirects to the expected version."""
"""Make sure bouncer redirects to the expected version (or a later one)."""
channel = get_version_channel(product, version)
channel_value = channel.value

if channel is Channel.ESR:
bedrock_url = "https://www.mozilla.org/en-US/{}/organizations/all/".format(product)
elif channel is Channel.RELEASE:
bedrock_url = 'https://www.mozilla.org/en-US/{}/all/'.format(product)
if product == 'devedition':
channel_value = "DEVEDITION"
if channel == Channel.RELEASE:
product_channel = 'firefox'
else:
bedrock_url = 'https://www.mozilla.org/fr/{}/channel/desktop/'.format(product)
if product == 'devedition':
bedrock_url = 'https://www.mozilla.org/en-US/firefox/developer/'
channel_value = "DEVEDITION"
product_channel = 'firefox-{}'.format(channel_value.lower())
url = 'https://download.mozilla.org?product={}-latest-ssl&os=linux64&lang=en-US'.format(
product_channel)

async with get_session() as session:
async with session.get(bedrock_url) as resp:
if resp.status != 200:
msg = 'Download page not available ({})'.format(resp.status)
raise TaskError(msg, url=bedrock_url)
body = await resp.text()
d = pq(body)

if product == 'devedition':
link_path = "#intro-download > .download-list > .os_linux64 > a"
elif channel is Channel.NIGHTLY:
link_path = "#desktop-nightly-download > .download-list > .os_linux64 > a"
elif channel in (Channel.BETA, Channel.AURORA):
link_path = "#desktop-beta-download > .download-list > .os_linux64 > a"
else: # channel in (Channel.RELEASE, Channel.ESR):
link_path = "#fr > .linux64 > a"

url = d(link_path).attr('href')

if url is not None:
async with session.get(url, allow_redirects=False) as resp:
if resp.status == 302:
url = resp.headers['Location']
else:
msg = 'Bouncer is down ({}).'.format(resp.status)
raise TaskError(msg, url=url)
async with session.get(url, allow_redirects=False) as resp:
if resp.status == 302:
url = resp.headers['Location']
else:
msg = 'No links found.'.format(resp.status)
raise TaskError(msg, url=bedrock_url)
msg = 'Bouncer is down ({}).'.format(resp.status)
raise TaskError(msg, url=url)

filename = os.path.basename(url)
last_release = get_version_from_filename(filename)
Expand Down
92 changes: 9 additions & 83 deletions tests/test_tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -720,38 +720,16 @@ async def test_devedition_version_tasks_returns_missing_for_other_channels(self)
assert received["message"] == "No devedition and beta check for 'release' releases"

async def test_bouncer_tasks_returns_error_if_error(self):
url = 'https://www.mozilla.org/en-US/firefox/all/'
url = 'https://download.mozilla.org/?product=firefox-latest-ssl&os=linux64&lang=en-US'
self.mocked.get(url, status=404)

with pytest.raises(TaskError) as excinfo:
await bouncer('firefox', '54.0')
assert str(excinfo.value) == 'Download page not available (404)'

async def test_bouncer_tasks_returns_error_if_not_link_found(self):
url = 'https://www.mozilla.org/en-US/firefox/all/'
self.mocked.get(url, status=200, body='''
<html></html>''')

with pytest.raises(TaskError) as excinfo:
await bouncer('firefox', '54.0')
assert str(excinfo.value) == 'No links found.'
assert str(excinfo.value.url) == 'https://www.mozilla.org/en-US/firefox/all/'
assert str(excinfo.value) == 'Bouncer is down (404).'

async def test_bouncer_tasks_returns_true_if_version_matches_for_nightly(self):
url = 'https://www.mozilla.org/fr/firefox/channel/desktop/'
self.mocked.get(url, status=200, body='''
<html>
<div id="desktop-nightly-download">
<ul class="download-list">
<li class="os_linux64">
<a class="download-link"
href="https://download.mozilla.org/?product=firefox-nightly-latest-l10n-ssl&os=linux64"
>Téléchargement</a>
</li>
</ul>
</div>
</html>''')
url = 'https://download.mozilla.org/?product=firefox-nightly-latest-l10n-ssl&os=linux64'
url = 'https://download.mozilla.org/?product=firefox-nightly-latest-ssl' + \
'&os=linux64&lang=en-US'
self.mocked.get(url, status=302, headers={
"Location": "https://download-installer.cdn.mozilla.net/pub/firefox/nightly"
"/latest-mozilla-central-l10n/firefox-57.0a1.en-US.linux-x86_64.tar.bz2"})
Expand All @@ -760,20 +738,7 @@ async def test_bouncer_tasks_returns_true_if_version_matches_for_nightly(self):
assert received["status"] == Status.EXISTS.value

async def test_bouncer_tasks_returns_true_if_version_matches_for_beta(self):
url = 'https://www.mozilla.org/fr/firefox/channel/desktop/'
self.mocked.get(url, status=200, body='''
<html>
<div id="desktop-beta-download">
<ul class="download-list">
<li class="os_linux64">
<a class="download-link"
href="https://download.mozilla.org/?product=firefox-beta-ssl&amp;os=linux64"
>Téléchargement</a>
</li>
</ul>
</div>
</html>''')
url = 'https://download.mozilla.org/?product=firefox-beta-ssl&os=linux64'
url = 'https://download.mozilla.org/?product=firefox-beta-latest-ssl&os=linux64&lang=en-US'
self.mocked.get(url, status=302, headers={
"Location": "https://download-installer.cdn.mozilla.net/pub/firefox/releases"
"/57.0b13/linux-x86_64/en-US/firefox-57.0b13.tar.bz2"})
Expand All @@ -782,20 +747,7 @@ async def test_bouncer_tasks_returns_true_if_version_matches_for_beta(self):
assert received["status"] == Status.EXISTS.value

async def test_bouncer_tasks_returns_true_if_version_matches_for_release(self):
url = 'https://www.mozilla.org/en-US/firefox/all/'
self.mocked.get(url, status=200, body='''
<html>
<table>
<tr id="fr">
<td class="download linux64">
<a href="https://download.mozilla.org/?product=firefox-latest-ssl&amp;os=linux64&amp;lang=fr">
Download
</a>
</td>
</tr>
</table>
</html>''')
url = 'https://download.mozilla.org/?product=firefox-latest-ssl&os=linux64&amp;lang=fr'
url = 'https://download.mozilla.org/?product=firefox-latest-ssl&os=linux64&lang=en-US'
self.mocked.get(url, status=302, headers={
"Location": "https://download-installer.cdn.mozilla.net/pub/firefox/releases"
"/57.0/linux-x86_64/fr/firefox-57.0.tar.bz2"})
Expand All @@ -804,20 +756,7 @@ async def test_bouncer_tasks_returns_true_if_version_matches_for_release(self):
assert received["status"] == Status.EXISTS.value

async def test_bouncer_tasks_returns_true_if_version_matches_for_esr(self):
url = 'https://www.mozilla.org/en-US/firefox/organizations/all/'
self.mocked.get(url, status=200, body='''
<html>
<table>
<tr id="fr">
<td class="download linux64">
<a href="https://download.mozilla.org/?product=firefox-esr-ssl&amp;os=linux64&amp;lang=fr">
Download
</a>
</td>
</tr>
</table>
</html>''')
url = 'https://download.mozilla.org/?product=firefox-esr-ssl&os=linux64&amp;lang=fr'
url = 'https://download.mozilla.org/?product=firefox-esr-latest-ssl&os=linux64&lang=en-US'
self.mocked.get(url, status=302, headers={
"Location": "https://download-installer.cdn.mozilla.net/pub/firefox/releases/"
"52.5.0esr/linux-x86_64/fr/firefox-52.5.0esr.tar.bz2"})
Expand All @@ -826,27 +765,14 @@ async def test_bouncer_tasks_returns_true_if_version_matches_for_esr(self):
assert received["status"] == Status.EXISTS.value

async def test_bouncer_tasks_returns_error_if_bouncer_down(self):
url = 'https://www.mozilla.org/en-US/firefox/organizations/all/'
self.mocked.get(url, status=200, body='''
<html>
<table>
<tr id="fr">
<td class="download linux64">
<a href="https://download.mozilla.org/?product=firefox-esr-ssl&amp;os=linux64&amp;lang=fr">
Download
</a>
</td>
</tr>
</table>
</html>''')
url = 'https://download.mozilla.org/?product=firefox-esr-ssl&os=linux64&amp;lang=fr'
url = 'https://download.mozilla.org?product=firefox-esr-latest-ssl&os=linux64&lang=en-US'
self.mocked.get(url, status=504)

with pytest.raises(TaskError) as excinfo:
await bouncer('firefox', '52.5.0esr')
assert str(excinfo.value) == 'Bouncer is down (504).'
assert str(excinfo.value.url) == (
'https://download.mozilla.org/?product=firefox-esr-ssl&os=linux64&lang=fr')
'https://download.mozilla.org?product=firefox-esr-latest-ssl&os=linux64&lang=en-US')

async def test_failing_heartbeat(self):
# Archive
Expand Down