restrict jetpack upgrader to builder SDK versions (bug 684412)
This commit is contained in:
Родитель
c7648d918e
Коммит
cc56382dcd
|
@ -1,5 +1,7 @@
|
|||
import json
|
||||
import os
|
||||
import re
|
||||
import urllib2
|
||||
|
||||
from django import forms
|
||||
from django.conf import settings
|
||||
|
@ -7,6 +9,7 @@ from django.forms import ModelForm
|
|||
from django.forms.models import modelformset_factory
|
||||
from django.template import Context, Template, TemplateSyntaxError
|
||||
|
||||
import commonware.log
|
||||
import happyforms
|
||||
from piston.models import Consumer
|
||||
from product_details import product_details
|
||||
|
@ -21,6 +24,8 @@ from bandwagon.models import Collection, FeaturedCollection, MonthlyPick
|
|||
from files.models import File
|
||||
from zadmin.models import ValidationJob
|
||||
|
||||
log = commonware.log.getLogger('z.zadmin')
|
||||
|
||||
|
||||
class BulkValidationForm(happyforms.ModelForm):
|
||||
application = forms.ChoiceField(
|
||||
|
@ -199,3 +204,32 @@ class FileStatusForm(ModelForm):
|
|||
|
||||
FileFormSet = modelformset_factory(File, form=FileStatusForm,
|
||||
formset=BaseModelFormSet, extra=0)
|
||||
|
||||
|
||||
class JetpackUpgradeForm(happyforms.Form):
|
||||
minver = forms.CharField()
|
||||
maxver = forms.CharField()
|
||||
|
||||
def __init__(self, *args, **kw):
|
||||
super(JetpackUpgradeForm, self).__init__(*args, **kw)
|
||||
fields = self.fields
|
||||
url = settings.BUILDER_VERSIONS_URL
|
||||
try:
|
||||
page = urllib2.urlopen(url)
|
||||
choices = [('', '')] + [(v, v) for v in json.loads(page.read())]
|
||||
fields['minver'] = fields['maxver'] = forms.ChoiceField()
|
||||
fields['minver'].choices = fields['maxver'].choices = choices
|
||||
except urllib2.URLError, e:
|
||||
log.error('Could not open %r: %s' % (url, e))
|
||||
except ValueError, e:
|
||||
log.error('Could not parse %r: %s' % (url, e))
|
||||
if not ('minver' in self.data or 'maxver' in self.data):
|
||||
fields['minver'].required = fields['maxver'].required = False
|
||||
|
||||
def clean(self):
|
||||
if not self.errors:
|
||||
minver = self.cleaned_data.get('minver')
|
||||
maxver = self.cleaned_data.get('maxver')
|
||||
if minver and maxver and minver >= maxver:
|
||||
raise forms.ValidationError('Invalid version range.')
|
||||
return self.cleaned_data
|
||||
|
|
|
@ -15,17 +15,15 @@
|
|||
{% set repack_status = upgrader.files() %}
|
||||
|
||||
{% block content %}
|
||||
{% include "messages.html" %}
|
||||
<h2>Jetpack</h2>
|
||||
<p>Jetpacks built with SDK versions <b>{{ minver }} – {{ maxver }}</b> will be upgraded.</p>
|
||||
<p>Should it be something different?</p>
|
||||
<form method="post" action="">
|
||||
{{ csrf() }}
|
||||
<input name="minver" value="{{ minver }}">
|
||||
to
|
||||
<input name="maxver" value="{{ maxver }}">
|
||||
{{ form.minver }} to {{ form.maxver }}
|
||||
<button>Hit it.</button>
|
||||
</form>
|
||||
<p>Make sure builder.amo knows about the max version! And ask someone to fix <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=658375">bug 658375</a>.</p>
|
||||
|
||||
<h3>Jetpack Files ({{ jetpacks|length }})</h3>
|
||||
<p>These are all the jetpack files we know about. Disabled files and add-ons are excluded.</p>
|
||||
|
|
|
@ -16,7 +16,7 @@ from pyquery import PyQuery as pq
|
|||
|
||||
import amo
|
||||
import amo.tests
|
||||
from amo.tests import (formset, initial, close_to_now,
|
||||
from amo.tests import (formset, initial, close_to_now, assert_required,
|
||||
assert_no_validation_errors)
|
||||
from amo.urlresolvers import reverse
|
||||
from addons.models import Addon
|
||||
|
@ -1325,3 +1325,106 @@ class TestAddonManagement(amo.tests.TestCase):
|
|||
assert file.size, 'File size should not be zero'
|
||||
assert file.hash, 'File hash should not be empty'
|
||||
|
||||
|
||||
class TestJetpack(amo.tests.TestCase):
|
||||
fixtures = ['base/users']
|
||||
|
||||
def setUp(self):
|
||||
self.url = reverse('zadmin.jetpack')
|
||||
self.client.login(username='admin@mozilla.com', password='password')
|
||||
|
||||
self.versions = '["1.0", "1.1", "1.2", "1.2.1"]'
|
||||
self.patcher = mock.patch('devhub.tasks.urllib2.urlopen')
|
||||
self.urlopen_mock = self.patcher.start()
|
||||
self.urlopen_mock.return_value = self.urlopener(self.versions)
|
||||
self.addCleanup(self.patcher.stop)
|
||||
|
||||
def urlopener(self, content):
|
||||
m = mock.Mock()
|
||||
m.read.return_value = content
|
||||
return m
|
||||
|
||||
def test_no_builder_versions(self):
|
||||
self.urlopen_mock.return_value = self.urlopener('xxx')
|
||||
r = self.client.get(self.url)
|
||||
eq_(r.status_code, 200)
|
||||
doc = pq(r.content)
|
||||
for field in ('minver', 'maxver'):
|
||||
eq_(doc('input[name=%s]' % field).length, 1)
|
||||
|
||||
def test_get_builder_versions(self):
|
||||
r = self.client.get(self.url)
|
||||
eq_(r.status_code, 200)
|
||||
doc = pq(r.content)
|
||||
for field in ('minver', 'maxver'):
|
||||
eq_(doc('select[name=%s]' % field).length, 1)
|
||||
options = doc('select[name=%s] option' % field)
|
||||
versions = [''] + json.loads(self.versions)
|
||||
for option, version in zip(options, versions):
|
||||
eq_(pq(option).attr('value'), version)
|
||||
|
||||
def test_change_range_optional(self):
|
||||
r = self.client.post(self.url)
|
||||
self.assertRedirects(r, self.url)
|
||||
|
||||
def test_change_range_max_required(self):
|
||||
r = self.client.post(self.url, {'minver': '1.0'})
|
||||
eq_(r.status_code, 200)
|
||||
assert_required(r.context['form'].errors['maxver'][0])
|
||||
|
||||
def test_change_range_min_required(self):
|
||||
r = self.client.post(self.url, {'maxver': '1.1'})
|
||||
eq_(r.status_code, 200)
|
||||
assert_required(r.context['form'].errors['minver'][0])
|
||||
|
||||
def test_change_range_bad(self):
|
||||
r = self.client.post(self.url, {'minver': '1.1', 'maxver': '1.0'})
|
||||
eq_(r.status_code, 200)
|
||||
eq_(r.context['form'].non_field_errors(), ['Invalid version range.'])
|
||||
|
||||
def test_change_range_unknown(self):
|
||||
r = self.client.post(self.url, {'minver': '9.0', 'maxver': '99.0'})
|
||||
eq_(r.status_code, 200)
|
||||
self.assertFormError(r, 'form', 'minver',
|
||||
'Select a valid choice. 9.0 is not one of the available choices.')
|
||||
self.assertFormError(r, 'form', 'maxver',
|
||||
'Select a valid choice. 99.0 is not one of the available choices.')
|
||||
|
||||
def set_range(self, min_, max_):
|
||||
r = self.client.post(self.url, {'minver': min_, 'maxver': max_})
|
||||
self.assertRedirects(r, self.url)
|
||||
|
||||
r = self.client.get(self.url)
|
||||
eq_(r.status_code, 200)
|
||||
minver, maxver = r.context['upgrader'].jetpack_versions()
|
||||
eq_(minver, min_)
|
||||
eq_(maxver, max_)
|
||||
eq_(r.context['upgrader'].version(), None)
|
||||
eq_(pq(r.content)('input[name=upgrade]').length, 1)
|
||||
|
||||
def test_change_range_success(self):
|
||||
self.set_range('1.0', '1.1')
|
||||
|
||||
def test_upgrade(self):
|
||||
self.set_range('1.2', '1.2.1')
|
||||
|
||||
r = self.client.post(self.url, {'upgrade': True})
|
||||
self.assertRedirects(r, self.url)
|
||||
|
||||
r = self.client.get(self.url)
|
||||
eq_(r.status_code, 200)
|
||||
eq_(r.context['upgrader'].version(), '1.2.1')
|
||||
eq_(pq(r.content)('input[name=cancel]').length, 1)
|
||||
|
||||
def test_cancel(self):
|
||||
self.set_range('1.2', '1.2.1')
|
||||
|
||||
r = self.client.post(self.url, {'upgrade': True})
|
||||
self.assertRedirects(r, self.url)
|
||||
|
||||
r = self.client.post(self.url, {'cancel': True})
|
||||
self.assertRedirects(r, self.url)
|
||||
|
||||
r = self.client.get(self.url)
|
||||
eq_(r.status_code, 200)
|
||||
eq_(r.context['upgrader'].version(), None)
|
||||
|
|
|
@ -47,7 +47,7 @@ from versions.models import Version
|
|||
from . import tasks
|
||||
from .forms import (BulkValidationForm, FeaturedCollectionFormSet, NotifyForm,
|
||||
OAuthConsumerForm, MonthlyPickFormSet, AddonStatusForm,
|
||||
FileFormSet)
|
||||
FileFormSet, JetpackUpgradeForm)
|
||||
from .models import ValidationJob, EmailPreviewTopic, ValidationJobTally
|
||||
|
||||
log = commonware.log.getLogger('z.zadmin')
|
||||
|
@ -329,22 +329,26 @@ def validation_tally_csv(request, job_id):
|
|||
def jetpack(request):
|
||||
upgrader = files.utils.JetpackUpgrader()
|
||||
minver, maxver = upgrader.jetpack_versions()
|
||||
form = JetpackUpgradeForm(request.POST)
|
||||
if request.method == 'POST':
|
||||
if 'minver' in request.POST:
|
||||
upgrader.jetpack_versions(request.POST['minver'],
|
||||
request.POST['maxver'])
|
||||
elif 'upgrade' in request.POST:
|
||||
if upgrader.version(maxver):
|
||||
start_upgrade(minver, maxver)
|
||||
elif 'cancel' in request.POST:
|
||||
upgrader.cancel()
|
||||
return redirect('zadmin.jetpack')
|
||||
if form.is_valid():
|
||||
if 'minver' in request.POST:
|
||||
data = form.cleaned_data
|
||||
upgrader.jetpack_versions(data['minver'], data['maxver'])
|
||||
elif 'upgrade' in request.POST:
|
||||
if upgrader.version(maxver):
|
||||
start_upgrade(minver, maxver)
|
||||
elif 'cancel' in request.POST:
|
||||
upgrader.cancel()
|
||||
return redirect('zadmin.jetpack')
|
||||
else:
|
||||
messages.error(request, form.errors.as_text())
|
||||
|
||||
jetpacks = files.utils.find_jetpacks(minver, maxver)
|
||||
groups = sorted_groupby(jetpacks, 'jetpack_version')
|
||||
by_version = dict((version, len(list(files))) for version, files in groups)
|
||||
return jingo.render(request, 'zadmin/jetpack.html',
|
||||
dict(jetpacks=jetpacks, upgrader=upgrader,
|
||||
dict(form=form, jetpacks=jetpacks, upgrader=upgrader,
|
||||
by_version=by_version))
|
||||
|
||||
|
||||
|
|
|
@ -1198,7 +1198,8 @@ VALID_LOGIN_REDIRECTS = {
|
|||
BUILDER_SECRET_KEY = 'love will tear us apart'
|
||||
# The builder URL we hit to upgrade jetpacks.
|
||||
BUILDER_UPGRADE_URL = 'https://addons.mozilla.org/services/builder'
|
||||
|
||||
BUILDER_VERSIONS_URL = ('https://builder.addons.mozilla.org/repackage/'
|
||||
'sdk-versions/')
|
||||
|
||||
## Elastic Search
|
||||
ES_HOSTS = ['127.0.0.1:9200']
|
||||
|
|
Загрузка…
Ссылка в новой задаче