Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
erp5
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Richard
erp5
Commits
0474c88f
Commit
0474c88f
authored
Jul 09, 2018
by
Vincent Pelletier
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ProcessingNodeTestCase: Do not retry failed activities.
Including activities which would be allowed to retry later.
parent
2cddee38
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
78 additions
and
38 deletions
+78
-38
product/ERP5Type/tests/ProcessingNodeTestCase.py
product/ERP5Type/tests/ProcessingNodeTestCase.py
+78
-38
No files found.
product/ERP5Type/tests/ProcessingNodeTestCase.py
View file @
0474c88f
...
@@ -3,6 +3,11 @@ import base64, errno, os, select, socket, sys, time
...
@@ -3,6 +3,11 @@ import base64, errno, os, select, socket, sys, time
from
threading
import
Thread
from
threading
import
Thread
from
UserDict
import
IterableUserDict
from
UserDict
import
IterableUserDict
import
Lifetime
import
Lifetime
from
AccessControl.SecurityManagement
import
(
newSecurityManager
,
setSecurityManager
,
getSecurityManager
,
)
import
transaction
import
transaction
from
Testing
import
ZopeTestCase
from
Testing
import
ZopeTestCase
from
ZODB.POSException
import
ConflictError
from
ZODB.POSException
import
ConflictError
...
@@ -10,7 +15,7 @@ from zLOG import LOG, ERROR
...
@@ -10,7 +15,7 @@ from zLOG import LOG, ERROR
from
Products.CMFActivity.Activity.Queue
import
VALIDATION_ERROR_DELAY
from
Products.CMFActivity.Activity.Queue
import
VALIDATION_ERROR_DELAY
from
Products.ERP5Type.tests.utils
import
addUserToDeveloperRole
from
Products.ERP5Type.tests.utils
import
addUserToDeveloperRole
from
Products.ERP5Type.tests.utils
import
createZServer
from
Products.ERP5Type.tests.utils
import
createZServer
from
Products.CMFActivity.ActivityTool
import
getCurrentNode
from
Products.CMFActivity.ActivityTool
import
getCurrentNode
,
Message
class
DictPersistentWrapper
(
IterableUserDict
,
object
):
class
DictPersistentWrapper
(
IterableUserDict
,
object
):
...
@@ -31,6 +36,20 @@ class DictPersistentWrapper(IterableUserDict, object):
...
@@ -31,6 +36,20 @@ class DictPersistentWrapper(IterableUserDict, object):
self
.
data
=
dict
self
.
data
=
dict
self
.
_persistent_object
=
persistent_object
self
.
_persistent_object
=
persistent_object
class
ActivityFailed
(
RuntimeError
):
def
__init__
(
self
,
activity_list
,
last_error
):
self
.
activity_list
=
activity_list
self
.
last_error
=
last_error
super
(
ActivityFailed
,
self
).
__init__
()
def
__str__
(
self
):
return
'tic is looping forever. These messages are pending: %r
\
n
%s'
%
(
[
(
'/'
.
join
(
m
.
object_path
),
m
.
method_id
,
m
.
processing_node
,
m
.
retry
)
for
m
in
self
.
activity_list
],
self
.
last_error
,
)
def
patchActivityTool
():
def
patchActivityTool
():
"""Redefine several methods of ActivityTool for unit tests
"""Redefine several methods of ActivityTool for unit tests
...
@@ -186,6 +205,16 @@ class ProcessingNodeTestCase(ZopeTestCase.TestCase):
...
@@ -186,6 +205,16 @@ class ProcessingNodeTestCase(ZopeTestCase.TestCase):
transaction
.
commit
()
transaction
.
commit
()
self
.
_close
()
self
.
_close
()
def
_getLastError
(
self
):
error_log
=
self
.
portal
.
error_log
.
_getLog
()
if
len
(
error_log
):
return
(
'Last error message:
\
n
'
'%(type)s
\
n
'
'%(value)s
\
n
'
'%(tb_text)s'
%
error_log
[
-
1
]
)
def
assertNoPendingMessage
(
self
):
def
assertNoPendingMessage
(
self
):
"""Get the last error message from error_log"""
"""Get the last error message from error_log"""
message_list
=
self
.
portal
.
portal_activities
.
getMessageList
()
message_list
=
self
.
portal
.
portal_activities
.
getMessageList
()
...
@@ -193,11 +222,9 @@ class ProcessingNodeTestCase(ZopeTestCase.TestCase):
...
@@ -193,11 +222,9 @@ class ProcessingNodeTestCase(ZopeTestCase.TestCase):
error_message
=
'These messages are pending: %r'
%
[
error_message
=
'These messages are pending: %r'
%
[
(
'/'
.
join
(
m
.
object_path
),
m
.
method_id
,
m
.
processing_node
,
m
.
retry
)
(
'/'
.
join
(
m
.
object_path
),
m
.
method_id
,
m
.
processing_node
,
m
.
retry
)
for
m
in
message_list
]
for
m
in
message_list
]
error_log
=
self
.
portal
.
error_log
.
_getLog
()
last_error
=
self
.
_getLastError
()
if
len
(
error_log
):
if
last_error
:
error_message
+=
'
\
n
Last error message:'
\
error_message
+=
'
\
n
'
+
last_error
'
\
n
%(type)s
\
n
%(value)s
\
n
%(tb_text)s'
\
%
error_log
[
-
1
]
self
.
fail
(
error_message
)
self
.
fail
(
error_message
)
def
abort
(
self
):
def
abort
(
self
):
...
@@ -213,45 +240,58 @@ class ProcessingNodeTestCase(ZopeTestCase.TestCase):
...
@@ -213,45 +240,58 @@ class ProcessingNodeTestCase(ZopeTestCase.TestCase):
transaction
.
commit
()
transaction
.
commit
()
# Some tests like testDeferredStyle require that we use self.getPortal()
# Some tests like testDeferredStyle require that we use self.getPortal()
# instead of self.portal in order to setup current skin.
# instead of self.portal in order to setup current skin.
portal_activities
=
self
.
getPortal
().
portal_activities
portal
=
self
.
getPortal
()
portal_activities
=
portal
.
portal_activities
if
verbose
:
if
verbose
:
ZopeTestCase
.
_print
(
'Executing pending activities ...'
)
ZopeTestCase
.
_print
(
'Executing pending activities ...'
)
old_message_count
=
0
start
=
time
.
time
()
start
=
time
.
time
()
count
=
1000
getMessageList
=
portal_activities
.
getMessageList
getMessageList
=
portal_activities
.
getMessageList
message_list
=
getMessageList
()
pre_failed_uid_set
=
{
message_count
=
len
(
message_list
)
x
.
uid
while
message_count
and
not
stop_condition
(
message_list
):
for
x
in
getMessageList
()
if
verbose
and
old_message_count
!=
message_count
:
if
x
.
processing_node
<
-
1
ZopeTestCase
.
_print
(
' %i'
%
message_count
)
}
old_message_count
=
message_count
portal
.
changeSkin
(
None
)
portal_activities
.
process_timer
(
None
,
None
)
old_sm
=
getSecurityManager
()
if
Lifetime
.
_shutdown_phase
:
old_Message_load
=
Message
.
load
# XXX CMFActivity contains bare excepts
def
Message_load
(
s
,
**
kw
):
raise
KeyboardInterrupt
"""
message_list
=
getMessageList
()
Prevent activity retries, as activities must succeed from the first try
message_count
=
len
(
message_list
)
in a unit test environment.
# This prevents an infinite loop.
This is to catch missing activity dependencies which only work because
count
-=
1
activities are being retried until they eventually succeed.
if
not
count
or
message_count
and
all
(
x
.
processing_node
==
-
2
"""
for
x
in
message_list
):
kw
[
'max_retry'
]
=
0
# We're about to raise RuntimeError, but maybe we've reached
kw
[
'conflict_retry'
]
=
False
# the stop condition, so check just once more:
return
old_Message_load
(
s
,
**
kw
)
if
stop_condition
(
message_list
):
try
:
Message
.
load
=
staticmethod
(
Message_load
)
newSecurityManager
(
None
,
portal
.
portal_catalog
.
getWrappedOwner
())
while
True
:
if
verbose
:
ZopeTestCase
.
_print
(
' %i'
%
len
(
getMessageList
()))
# Put everything in the past - hopefully no activity will have been
# pushed that far in the future.
portal_activities
.
timeShift
(
30
*
VALIDATION_ERROR_DELAY
)
portal_activities
.
distribute
()
portal_activities
.
tic
()
self
.
commit
()
message_list
=
getMessageList
()
if
not
message_list
or
stop_condition
(
message_list
):
break
break
error_message
=
'tic is looping forever. '
failed_message_set
=
[
try
:
x
self
.
assertNoPendingMessage
()
for
x
in
message_list
except
AssertionError
,
e
:
if
x
.
processing_node
<
-
1
error_message
+=
str
(
e
)
]
raise
RuntimeError
(
error_message
)
if
failed_message_set
:
# This give some time between messages
raise
ActivityFailed
(
failed_message_set
,
self
.
_getLastError
())
if
count
%
10
==
0
:
finally
:
portal_activities
.
timeShift
(
3
*
VALIDATION_ERROR_DELAY
)
Message
.
load
=
staticmethod
(
old_Message_load
)
setSecurityManager
(
old_sm
)
if
verbose
:
if
verbose
:
ZopeTestCase
.
_print
(
' done (%.3fs)
\
n
'
%
(
time
.
time
()
-
start
))
ZopeTestCase
.
_print
(
' done (%.3fs)
\
n
'
%
(
time
.
time
()
-
start
))
self
.
abor
t
()
self
.
commi
t
()
def
afterSetUp
(
self
):
def
afterSetUp
(
self
):
"""Initialize a node that will only process activities"""
"""Initialize a node that will only process activities"""
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment