Hides validator tracebacks from JSON result (bug 626899)
This commit is contained in:
Родитель
ee736d56ab
Коммит
75bf5f3602
|
@ -5,6 +5,8 @@ import shutil
|
|||
import sys
|
||||
import traceback
|
||||
|
||||
from django.conf import settings
|
||||
|
||||
import mock
|
||||
from nose.plugins.attrib import attr
|
||||
from nose.tools import eq_
|
||||
|
@ -182,6 +184,7 @@ class TestValidateFile(BaseUploadTest):
|
|||
doc = pq(r.content)
|
||||
assert doc('time').text()
|
||||
|
||||
@mock.patch.object(settings, 'EXPOSE_VALIDATOR_TRACEBACKS', False)
|
||||
@mock.patch('devhub.tasks.run_validator')
|
||||
def test_validator_errors(self, v):
|
||||
v.side_effect = ValueError('catastrophic failure in amo-validator')
|
||||
|
@ -191,9 +194,8 @@ class TestValidateFile(BaseUploadTest):
|
|||
eq_(r.status_code, 200)
|
||||
data = json.loads(r.content)
|
||||
eq_(data['validation'], '')
|
||||
assert data['error'].endswith(
|
||||
"ValueError: catastrophic failure in amo-validator\n"), (
|
||||
'Unexpected error: ...%s' % data['error'][-50:-1])
|
||||
eq_(data['error'].strip(),
|
||||
'ValueError: catastrophic failure in amo-validator')
|
||||
|
||||
@mock.patch('devhub.tasks.run_validator')
|
||||
def test_validator_sets_binary_flag(self, v):
|
||||
|
@ -253,6 +255,18 @@ class TestValidateFile(BaseUploadTest):
|
|||
doc = pq(data['validation']['messages'][0]['description'][0])
|
||||
eq_(doc('a').text(), 'https://bugzilla.mozilla.org/')
|
||||
|
||||
@mock.patch.object(settings, 'EXPOSE_VALIDATOR_TRACEBACKS', False)
|
||||
@mock.patch('devhub.tasks.run_validator')
|
||||
def test_hide_validation_traceback(self, run_validator):
|
||||
run_validator.side_effect = RuntimeError('simulated task error')
|
||||
r = self.client.post(reverse('devhub.json_file_validation',
|
||||
args=[self.addon.slug, self.file.id]),
|
||||
follow=True)
|
||||
eq_(r.status_code, 200)
|
||||
data = json.loads(r.content)
|
||||
eq_(data['validation'], '')
|
||||
eq_(data['error'], 'RuntimeError: simulated task error')
|
||||
|
||||
|
||||
class TestCompatibilityResults(test_utils.TestCase):
|
||||
fixtures = ['base/users', 'devhub/addon-compat-results']
|
||||
|
@ -266,6 +280,13 @@ class TestCompatibilityResults(test_utils.TestCase):
|
|||
file__version__addon=self.addon)
|
||||
self.job = self.result.validation_job
|
||||
|
||||
def validate(self, expected_status=200):
|
||||
r = self.client.post(reverse('devhub.json_validation_result',
|
||||
args=[self.addon.slug, self.result.id]),
|
||||
follow=True)
|
||||
eq_(r.status_code, expected_status)
|
||||
return json.loads(r.content)
|
||||
|
||||
def test_login_protected(self):
|
||||
self.client.logout()
|
||||
r = self.client.get(reverse('devhub.validation_result',
|
||||
|
@ -303,11 +324,7 @@ class TestCompatibilityResults(test_utils.TestCase):
|
|||
'https://developer.mozilla.org/en/Firefox_4_for_developers')
|
||||
|
||||
def test_validation_success(self):
|
||||
r = self.client.post(reverse('devhub.json_validation_result',
|
||||
args=[self.addon.slug, self.result.id]),
|
||||
follow=True)
|
||||
eq_(r.status_code, 200)
|
||||
data = json.loads(r.content)
|
||||
data = self.validate()
|
||||
eq_(data['validation']['messages'][3]['for_appversions'],
|
||||
{'{ec8030f7-c20a-464f-9b0e-13a3a9e97384}': ['4.0b3']})
|
||||
|
||||
|
@ -319,16 +336,24 @@ class TestCompatibilityResults(test_utils.TestCase):
|
|||
assert doc('time').text()
|
||||
eq_(doc('table tr td:eq(1)').text(), 'Firefox 4.0.*')
|
||||
|
||||
@mock.patch.object(settings, 'EXPOSE_VALIDATOR_TRACEBACKS', True)
|
||||
def test_validation_error(self):
|
||||
try:
|
||||
raise RuntimeError('simulated task error')
|
||||
except:
|
||||
error = ''.join(traceback.format_exception(*sys.exc_info()))
|
||||
self.result.update(validation='', task_error=error)
|
||||
r = self.client.post(reverse('devhub.json_validation_result',
|
||||
args=[self.addon.slug, self.result.id]),
|
||||
follow=True)
|
||||
eq_(r.status_code, 200)
|
||||
data = json.loads(r.content)
|
||||
data = self.validate()
|
||||
eq_(data['validation'], '')
|
||||
eq_(data['error'], error)
|
||||
|
||||
@mock.patch.object(settings, 'EXPOSE_VALIDATOR_TRACEBACKS', False)
|
||||
def test_hide_validation_traceback(self):
|
||||
try:
|
||||
raise RuntimeError('simulated task error')
|
||||
except:
|
||||
error = ''.join(traceback.format_exception(*sys.exc_info()))
|
||||
self.result.update(validation='', task_error=error)
|
||||
data = self.validate()
|
||||
eq_(data['validation'], '')
|
||||
eq_(data['error'], 'RuntimeError: simulated task error')
|
||||
|
|
|
@ -531,14 +531,21 @@ def escape_all(v):
|
|||
return v
|
||||
|
||||
|
||||
def prepare_validation_results(validation):
|
||||
for msg in validation['messages']:
|
||||
if msg['tier'] == 0:
|
||||
# We can't display a message if it's on tier 0.
|
||||
# Should get fixed soon in bug 617481
|
||||
msg['tier'] = 1
|
||||
for k, v in msg.items():
|
||||
msg[k] = escape_all(v)
|
||||
def make_validation_result(data):
|
||||
"""Safe wrapper around JSON dict containing a validation result."""
|
||||
if not settings.EXPOSE_VALIDATOR_TRACEBACKS:
|
||||
if data['error']:
|
||||
# Just expose the message, not the traceback
|
||||
data['error'] = data['error'].strip().split('\n')[-1].strip()
|
||||
if data['validation']:
|
||||
for msg in data['validation']['messages']:
|
||||
if msg['tier'] == 0:
|
||||
# We can't display a message if it's on tier 0.
|
||||
# Should get fixed soon in bug 617481
|
||||
msg['tier'] = 1
|
||||
for k, v in msg.items():
|
||||
msg[k] = escape_all(v)
|
||||
return data
|
||||
|
||||
|
||||
@dev_required(allow_editors=True)
|
||||
|
@ -589,19 +596,15 @@ def json_file_validation(request, addon_id, addon, file_id):
|
|||
v_result = tasks.file_validator(file.id)
|
||||
except Exception, exc:
|
||||
log.error('file_validator(%s): %s' % (file.id, exc))
|
||||
return {
|
||||
'validation': '',
|
||||
'error': "\n".join(
|
||||
traceback.format_exception(*sys.exc_info())),
|
||||
}
|
||||
error = "\n".join(traceback.format_exception(*sys.exc_info()))
|
||||
return make_validation_result({'validation': '',
|
||||
'error': error})
|
||||
else:
|
||||
v_result = file.validation
|
||||
validation = json.loads(v_result.validation)
|
||||
prepare_validation_results(validation)
|
||||
|
||||
r = dict(validation=validation,
|
||||
error=None)
|
||||
return r
|
||||
return make_validation_result(dict(validation=validation,
|
||||
error=None))
|
||||
|
||||
|
||||
@json_view
|
||||
|
@ -612,11 +615,11 @@ def json_validation_result(request, addon_id, addon, result_id):
|
|||
qs = ValidationResult.objects.exclude(completed=None)
|
||||
result = get_object_or_404(qs, pk=result_id)
|
||||
if result.task_error:
|
||||
return {'validation': '', 'error': result.task_error}
|
||||
return make_validation_result({'validation': '',
|
||||
'error': result.task_error})
|
||||
else:
|
||||
validation = json.loads(result.validation)
|
||||
prepare_validation_results(validation)
|
||||
return dict(validation=validation, error=None)
|
||||
return make_validation_result(dict(validation=validation, error=None))
|
||||
|
||||
|
||||
@json_view
|
||||
|
@ -633,7 +636,6 @@ def json_upload_detail(upload):
|
|||
plat_exclude = []
|
||||
|
||||
if validation:
|
||||
prepare_validation_results(validation)
|
||||
if validation['errors'] == 0:
|
||||
try:
|
||||
apps = parse_addon(upload.path).get('apps', [])
|
||||
|
@ -655,11 +657,11 @@ def json_upload_detail(upload):
|
|||
# right here to avoid confusion about platform selection.
|
||||
log.error("XPI parsing error, ignored: %s" % exc)
|
||||
|
||||
r = dict(upload=upload.uuid, validation=validation,
|
||||
error=upload.task_error, url=url,
|
||||
full_report_url=full_report_url,
|
||||
platforms_to_exclude=plat_exclude)
|
||||
return r
|
||||
return make_validation_result(dict(upload=upload.uuid,
|
||||
validation=validation,
|
||||
error=upload.task_error, url=url,
|
||||
full_report_url=full_report_url,
|
||||
platforms_to_exclude=plat_exclude))
|
||||
|
||||
|
||||
def upload_detail(request, uuid, format='html'):
|
||||
|
|
|
@ -928,6 +928,9 @@ QUNIT_TEST_DIRECTORY = os.path.join(MEDIA_ROOT, 'js', 'zamboni', 'tests')
|
|||
SPIDERMONKEY = None
|
||||
VALIDATE_ADDONS = True
|
||||
|
||||
# When True include full tracebacks in JSON. This is useful for QA on preview.
|
||||
EXPOSE_VALIDATOR_TRACEBACKS = False
|
||||
|
||||
# Feature flags
|
||||
SEARCH_EXCLUDE_PERSONAS = True
|
||||
UNLINK_SITE_STATS = True
|
||||
|
|
Загрузка…
Ссылка в новой задаче