Hides validator tracebacks from JSON result (bug 626899)

This commit is contained in:
Kumar McMillan 2011-06-21 17:19:51 -05:00
Родитель ee736d56ab
Коммит 75bf5f3602
3 изменённых файлов: 69 добавлений и 39 удалений

Просмотреть файл

@ -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