0001-workflows-only-log-condition-errors-as-functional-er.patch
tests/test_form_pages.py | ||
---|---|---|
4492 | 4492 |
assert LoggedError.count() == 1 |
4493 | 4493 | |
4494 | 4494 |
error = LoggedError.get_on_index( |
4495 |
'34-12-None-None-zerodivisionerror-integer-division-or-modulo-by-zero', 'tech_id') |
|
4495 |
'34-12-just_submitted-_jump-failed-to-evaluate-condition-10-python-integer-division-or-modulo-by-zero-zerodivisionerror', |
|
4496 |
'tech_id') |
|
4496 | 4497 |
assert error.occurences_count == 2 |
4497 | 4498 | |
4498 | 4499 |
assert len(LoggedError.get_ids_with_indexed_value('formdef_id', '34')) == 1 |
tests/test_workflows.py | ||
---|---|---|
19 | 19 |
from wcs import sessions |
20 | 20 |
from wcs.fields import (StringField, DateField, MapField, FileField, ItemField, |
21 | 21 |
ItemsField, CommentField) |
22 |
from wcs.logged_errors import LoggedError |
|
22 | 23 |
from wcs.roles import Role |
23 | 24 |
from wcs.workflows import (Workflow, WorkflowStatusItem, |
24 | 25 |
SendmailWorkflowStatusItem, SendSMSWorkflowStatusItem, |
... | ... | |
258 | 259 |
'value': 'utils.time_delta(utils.time.localtime(), "2015-01-04").days > 0'} |
259 | 260 |
assert item.must_jump(formdata) is True |
260 | 261 | |
261 | ||
262 | 262 |
def test_jump_count_condition(pub): |
263 | 263 |
FormDef.wipe() |
264 | 264 |
formdef = FormDef() |
... | ... | |
278 | 278 |
item.condition = {'type': 'python', 'value': 'form_objects.count < 2'} |
279 | 279 |
assert item.must_jump(formdata) is False |
280 | 280 | |
281 |
def test_jump_bad_python_condition(pub): |
|
282 |
FormDef.wipe() |
|
283 |
formdef = FormDef() |
|
284 |
formdef.name = 'foobar' |
|
285 |
formdef.store() |
|
286 |
pub.substitutions.feed(formdef) |
|
287 |
formdef.data_class().wipe() |
|
288 |
formdata = formdef.data_class()() |
|
289 |
item = JumpWorkflowStatusItem() |
|
290 | ||
291 |
LoggedError.wipe() |
|
292 |
item.condition = {'type': 'python', 'value': 'form_var_foobar == 0'} |
|
293 |
assert item.must_jump(formdata) is False |
|
294 |
assert LoggedError.count() == 1 |
|
295 |
logged_error = LoggedError.select()[0] |
|
296 |
assert logged_error.summary.startswith('Failed to evaluate condition') |
|
297 |
assert 'form_var_foobar == 0' in logged_error.summary |
|
298 |
assert "name 'form_var_foobar' is not defined" in logged_error.summary |
|
299 | ||
300 |
LoggedError.wipe() |
|
301 |
item.condition = {'type': 'python', 'value': '~ invalid ~'} |
|
302 |
assert item.must_jump(formdata) is False |
|
303 |
assert LoggedError.count() == 1 |
|
304 |
logged_error = LoggedError.select()[0] |
|
305 |
assert logged_error.summary.startswith('Failed to evaluate condition') |
|
306 |
assert '~ invalid ~' in logged_error.summary |
|
307 |
assert 'unexpected EOF while parsing' in logged_error.summary |
|
308 | ||
281 | 309 |
def test_jump_django_conditions(pub): |
282 | 310 |
FormDef.wipe() |
283 | 311 |
formdef = FormDef() |
... | ... | |
289 | 317 |
pub.substitutions.feed(formdata) |
290 | 318 |
item = JumpWorkflowStatusItem() |
291 | 319 | |
320 |
LoggedError.wipe() |
|
292 | 321 |
item.condition = {'type': 'django', 'value': '1 < 2'} |
293 | 322 |
assert item.must_jump(formdata) is True |
294 | 323 | |
... | ... | |
301 | 330 |
item.condition = {'type': 'django', 'value': 'form_var_foo|first|upper == "X"'} |
302 | 331 |
assert item.must_jump(formdata) is False |
303 | 332 | |
333 |
assert LoggedError.count() == 0 |
|
334 | ||
304 | 335 |
item.condition = {'type': 'django', 'value': '~ invalid ~'} |
305 | 336 |
assert item.must_jump(formdata) is False |
337 |
assert LoggedError.count() == 1 |
|
338 |
logged_error = LoggedError.select()[0] |
|
339 |
assert logged_error.summary.startswith('Failed to evaluate condition') |
|
340 |
assert '~ invalid ~' in logged_error.summary |
|
341 |
assert "Could not parse the remainder: '~' from '~'" in logged_error.summary |
|
306 | 342 | |
307 | 343 |
def test_check_auth(pub): |
308 | 344 |
user = pub.user_class(name='foo') |
... | ... | |
3504 | 3540 |
choice.condition = {'type': 'python', 'value': 'form_name == "baz"'} |
3505 | 3541 |
workflow.store() |
3506 | 3542 |
assert len(FormDef.get(formdef.id).data_class().get_actionable_ids([role.id])) == 2 |
3543 | ||
3544 |
# bad condition |
|
3545 |
LoggedError.wipe() |
|
3546 |
choice.condition = {'type': 'python', 'value': 'foobar == barfoo'} |
|
3547 |
workflow.store() |
|
3548 |
assert len(FormDef.get(formdef.id).data_class().get_actionable_ids([role.id])) == 0 |
|
3549 |
assert LoggedError.count() == 1 |
|
3550 |
logged_error = LoggedError.select()[0] |
|
3551 |
assert logged_error.occurences_count > 1 # should be 2... == 12 with pickle, 4 with sql |
|
3552 |
assert logged_error.summary.startswith('Failed to evaluate condition') |
|
3553 |
assert 'foobar == barfoo' in logged_error.summary |
|
3554 |
assert "name 'foobar' is not defined" in logged_error.summary |
wcs/conditions.py | ||
---|---|---|
30 | 30 |
record_errors = True |
31 | 31 |
log_errors = False |
32 | 32 | |
33 |
def __init__(self, condition, context=None):
|
|
33 |
def __init__(self, condition, context={}):
|
|
34 | 34 |
if not condition: |
35 | 35 |
condition = {} |
36 | 36 |
self.type = condition.get('type') |
... | ... | |
53 | 53 |
if self.log_errors: |
54 | 54 |
get_logger().warn('failed to evaluate %r (%r)', self, e) |
55 | 55 |
if self.record_errors: |
56 |
get_publisher().notify_of_exception(sys.exc_info()) |
|
56 |
from wcs.logged_errors import LoggedError |
|
57 |
message = '%s (%s)' % (e, e.__class__.__name__) |
|
58 |
summary = _('Failed to evaluate condition "%(value)s" (%(type)s): %(message)s') % { |
|
59 |
'value': self.value, |
|
60 |
'type': self.type, |
|
61 |
'message': message, |
|
62 |
} |
|
63 |
LoggedError.record(summary, |
|
64 |
formdata=self.context.get('formdata'), |
|
65 |
status_item=self.context.get('status_item')) |
|
57 | 66 |
raise RuntimeError() |
58 | 67 | |
59 | 68 |
def evaluate_python(self, local_variables): |
wcs/logged_errors.py | ||
---|---|---|
74 | 74 | |
75 | 75 |
if status_item: |
76 | 76 |
error.status_item_id = status_item.id |
77 |
if status_item.parent:
|
|
77 |
if getattr(status_item, 'parent', None):
|
|
78 | 78 |
error.status_id = status_item.parent.id |
79 | 79 |
if status: |
80 | 80 |
error.status_id = status.id |
wcs/wf/jump.py | ||
---|---|---|
218 | 218 |
must_jump = True |
219 | 219 | |
220 | 220 |
if self.condition: |
221 |
context = {'formdata': formdata, 'status_item': self} |
|
221 | 222 |
try: |
222 |
must_jump = Condition(self.condition).evaluate() |
|
223 |
must_jump = Condition(self.condition, context).evaluate()
|
|
223 | 224 |
except RuntimeError: |
224 | 225 |
must_jump = False |
225 | 226 |
wcs/workflows.py | ||
---|---|---|
1583 | 1583 |
return False |
1584 | 1584 | |
1585 | 1585 |
def check_condition(self, formdata): |
1586 |
context = {'formdata': formdata, 'status_item': self} |
|
1586 | 1587 |
try: |
1587 |
return Condition(self.condition).evaluate() |
|
1588 |
return Condition(self.condition, context).evaluate()
|
|
1588 | 1589 |
except RuntimeError: |
1589 | 1590 |
return False |
1590 | 1591 | |
1591 |
- |