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
1
Issues
1
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
Roque
erp5
Commits
96c6ea1c
Commit
96c6ea1c
authored
Jan 29, 2025
by
Jérome Perrin
Browse files
Options
Browse Files
Download
Plain Diff
Backport and small fixes for unittest
See merge request
nexedi/erp5!2051
parents
143be498
24638029
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
76 additions
and
68 deletions
+76
-68
product/ERP5Type/Tool/ComponentTool.py
product/ERP5Type/Tool/ComponentTool.py
+1
-0
product/ERP5Type/tests/ERP5TypeLiveTestCase.py
product/ERP5Type/tests/ERP5TypeLiveTestCase.py
+13
-7
product/ERP5Type/tests/ERP5TypeTestCase.py
product/ERP5Type/tests/ERP5TypeTestCase.py
+5
-0
product/ERP5Type/tests/backportUnittest.py
product/ERP5Type/tests/backportUnittest.py
+16
-0
product/ERP5Type/tests/runUnitTest.py
product/ERP5Type/tests/runUnitTest.py
+5
-1
product/ERP5Type/tests/testDynamicClassGeneration.py
product/ERP5Type/tests/testDynamicClassGeneration.py
+36
-60
No files found.
product/ERP5Type/Tool/ComponentTool.py
View file @
96c6ea1c
...
@@ -315,6 +315,7 @@ class Test(ERP5TypeTestCase):
...
@@ -315,6 +315,7 @@ class Test(ERP5TypeTestCase):
except
ImportError
:
except
ImportError
:
import
traceback
import
traceback
traceback
.
print_exc
(
file
=
global_stream
)
traceback
.
print_exc
(
file
=
global_stream
)
traceback
.
print_exc
()
# also print on stderr
global_stream
.
seek
(
0
)
global_stream
.
seek
(
0
)
return
global_stream
.
read
()
return
global_stream
.
read
()
finally
:
finally
:
...
...
product/ERP5Type/tests/ERP5TypeLiveTestCase.py
View file @
96c6ea1c
...
@@ -291,12 +291,18 @@ def runLiveTest(test_list, verbosity=1, stream=None, request_server_url=None, **
...
@@ -291,12 +291,18 @@ def runLiveTest(test_list, verbosity=1, stream=None, request_server_url=None, **
output
=
stream
output
=
stream
if
stream
is
None
:
if
stream
is
None
:
output
=
StringIO
()
output
=
StringIO
()
def
print_and_write
(
data
):
class
StderrIOWrapper
:
sys
.
stderr
.
write
(
data
)
def
__init__
(
self
,
wrapped
):
sys
.
stderr
.
flush
()
self
.
_wrapped_io
=
wrapped
return
output
.
write
(
data
)
def
write
(
self
,
data
):
print_and_write
(
"**Running Live Test:
\
n
"
)
sys
.
stderr
.
write
(
data
)
ZopeTestCase
.
_print
=
print_and_write
return
self
.
_wrapped_io
.
write
(
data
)
def
__getattr__
(
self
,
attr
):
return
getattr
(
self
.
_wrapped_io
,
attr
)
output
=
StderrIOWrapper
(
output
)
output
.
write
(
"**Running Live Test:
\
n
"
)
ZopeTestCase
.
_print
=
output
.
write
with
warnings
.
catch_warnings
():
with
warnings
.
catch_warnings
():
warnings
.
simplefilter
(
kw
[
'warnings'
])
warnings
.
simplefilter
(
kw
[
'warnings'
])
...
@@ -306,6 +312,6 @@ def runLiveTest(test_list, verbosity=1, stream=None, request_server_url=None, **
...
@@ -306,6 +312,6 @@ def runLiveTest(test_list, verbosity=1, stream=None, request_server_url=None, **
from
AccessControl.SecurityManagement
import
getSecurityManager
,
setSecurityManager
from
AccessControl.SecurityManagement
import
getSecurityManager
,
setSecurityManager
sm
=
getSecurityManager
()
sm
=
getSecurityManager
()
try
:
try
:
result
=
TestRunner
(
stream
=
output
,
verbosity
=
verbosity
).
run
(
suite
)
TestRunner
(
stream
=
output
,
verbosity
=
verbosity
).
run
(
suite
)
finally
:
finally
:
setSecurityManager
(
sm
)
setSecurityManager
(
sm
)
product/ERP5Type/tests/ERP5TypeTestCase.py
View file @
96c6ea1c
...
@@ -17,6 +17,7 @@ import string
...
@@ -17,6 +17,7 @@ import string
import
sys
import
sys
import
time
import
time
import
traceback
import
traceback
import
warnings
from
six.moves
import
configparser
from
six.moves
import
configparser
from
contextlib
import
contextmanager
from
contextlib
import
contextmanager
from
io
import
BytesIO
from
io
import
BytesIO
...
@@ -273,6 +274,10 @@ class ERP5TypeTestCaseMixin(ProcessingNodeTestCase, PortalTestCase, functional.F
...
@@ -273,6 +274,10 @@ class ERP5TypeTestCaseMixin(ProcessingNodeTestCase, PortalTestCase, functional.F
def
newPassword
(
self
):
def
newPassword
(
self
):
""" Generate a password """
""" Generate a password """
forced_password
=
os
.
environ
.
get
(
'insecure_erp5_test_password'
)
if
forced_password
:
warnings
.
warn
(
"Using password set from environment variable"
)
return
forced_password
return
''
.
join
(
random
.
SystemRandom
().
sample
(
string
.
ascii_letters
+
string
.
digits
,
20
))
return
''
.
join
(
random
.
SystemRandom
().
sample
(
string
.
ascii_letters
+
string
.
digits
,
20
))
def
login
(
self
,
user_name
=
None
,
quiet
=
0
):
def
login
(
self
,
user_name
=
None
,
quiet
=
0
):
...
...
product/ERP5Type/tests/backportUnittest.py
View file @
96c6ea1c
...
@@ -11,6 +11,8 @@ class SetupSiteError(Exception):
...
@@ -11,6 +11,8 @@ class SetupSiteError(Exception):
def
patch
():
def
patch
():
import
six
import
six
import
contextlib
import
sys
import
traceback
import
traceback
from
unittest
import
TestCase
,
TextTestResult
,
TextTestRunner
from
unittest
import
TestCase
,
TextTestResult
,
TextTestRunner
...
@@ -21,6 +23,20 @@ def patch():
...
@@ -21,6 +23,20 @@ def patch():
TestCase
.
assertRaisesRegex
=
getattr
(
TestCase
,
'assertRaisesRegexp'
)
TestCase
.
assertRaisesRegex
=
getattr
(
TestCase
,
'assertRaisesRegexp'
)
TestCase
.
assertRegex
=
getattr
(
TestCase
,
'assertRegexpMatches'
)
TestCase
.
assertRegex
=
getattr
(
TestCase
,
'assertRegexpMatches'
)
TestCase
.
assertCountEqual
=
TestCase
.
assertItemsEqual
TestCase
.
assertCountEqual
=
TestCase
.
assertItemsEqual
@
contextlib
.
contextmanager
def
subTest
(
self
,
msg
=
''
,
**
params
):
yield
TestCase
.
subTest
=
subTest
if
sys
.
version_info
<
(
3
,
11
):
def
enterContext
(
self
,
cm
):
cls
=
type
(
cm
)
enter
=
cls
.
__enter__
exit
=
cls
.
__exit__
result
=
enter
(
cm
)
self
.
addCleanup
(
exit
,
cm
,
None
,
None
,
None
)
return
result
TestCase
.
enterContext
=
enterContext
TextTestResult_addError
=
six
.
get_unbound_function
(
TextTestResult
.
addError
)
TextTestResult_addError
=
six
.
get_unbound_function
(
TextTestResult
.
addError
)
def
addError
(
self
,
test
,
err
):
def
addError
(
self
,
test
,
err
):
...
...
product/ERP5Type/tests/runUnitTest.py
View file @
96c6ea1c
...
@@ -150,6 +150,7 @@ Options:
...
@@ -150,6 +150,7 @@ Options:
timer service.
timer service.
This option only makes sense with --activity_node=
This option only makes sense with --activity_node=
or when not specifying a test to run.
or when not specifying a test to run.
--insecure_password=PWD Use `PWD` instead of generating random passwords for users.
--zserver=ADDRESS[,...] Make ZServer listen on given IPv4 address.
--zserver=ADDRESS[,...] Make ZServer listen on given IPv4 address.
Addresses can be given in the following syntaxs:
Addresses can be given in the following syntaxs:
- HOST:PORT
- HOST:PORT
...
@@ -798,7 +799,8 @@ def main(argument_list=None):
...
@@ -798,7 +799,8 @@ def main(argument_list=None):
"sys_path="
,
"sys_path="
,
"instance_home="
,
"instance_home="
,
"log_directory="
,
"log_directory="
,
"with_wendelin_core"
"with_wendelin_core"
,
"insecure_password="
,
])
])
except
getopt
.
GetoptError
as
msg
:
except
getopt
.
GetoptError
as
msg
:
usage
(
sys
.
stderr
,
msg
)
usage
(
sys
.
stderr
,
msg
)
...
@@ -919,6 +921,8 @@ def main(argument_list=None):
...
@@ -919,6 +921,8 @@ def main(argument_list=None):
_log_directory
=
os
.
path
.
abspath
(
arg
)
_log_directory
=
os
.
path
.
abspath
(
arg
)
elif
opt
==
"--with_wendelin_core"
:
elif
opt
==
"--with_wendelin_core"
:
os
.
environ
[
"with_wendelin_core"
]
=
"1"
os
.
environ
[
"with_wendelin_core"
]
=
"1"
elif
opt
==
"--insecure_password"
:
os
.
environ
[
"insecure_erp5_test_password"
]
=
arg
setupWarnings
()
setupWarnings
()
...
...
product/ERP5Type/tests/testDynamicClassGeneration.py
View file @
96c6ea1c
...
@@ -3255,17 +3255,9 @@ class Test(ERP5TypeTestCase):
...
@@ -3255,17 +3255,9 @@ class Test(ERP5TypeTestCase):
self.assertNotEqual(os, None)
self.assertNotEqual(os, None)
'''
'''
def
testRunLiveTest
(
self
):
def
_runLiveTest
(
self
,
test_name
):
"""
"""Runs a live test from portal_components
Create a new ZODB Test Component and try to run it as a live tests and
check the expected output
"""
"""
# First try with a test which run successfully
source_code
=
self
.
_getValidSourceCode
()
component
=
self
.
_newComponent
(
'testRunLiveTest'
,
source_code
)
component
.
validate
()
self
.
tic
()
from
Products.ERP5Type.tests.runUnitTest
import
ERP5TypeTestLoader
from
Products.ERP5Type.tests.runUnitTest
import
ERP5TypeTestLoader
ERP5TypeTestLoader_loadTestsFromNames
=
ERP5TypeTestLoader
.
loadTestsFromNames
ERP5TypeTestLoader_loadTestsFromNames
=
ERP5TypeTestLoader
.
loadTestsFromNames
def
loadTestsFromNames
(
self
,
*
args
,
**
kwargs
):
def
loadTestsFromNames
(
self
,
*
args
,
**
kwargs
):
...
@@ -3287,6 +3279,35 @@ class Test(ERP5TypeTestCase):
...
@@ -3287,6 +3279,35 @@ class Test(ERP5TypeTestCase):
return
ret
return
ret
# ERP5TypeLiveTestCase.runLiveTest patches ERP5TypeTestCase bases, thus it
# needs to be restored after calling runLiveTest
base_tuple
=
ERP5TypeTestCase
.
__bases__
ERP5TypeTestLoader
.
loadTestsFromNames
=
loadTestsFromNames
from
six.moves
import
cStringIO
as
StringIO
stderr
=
StringIO
()
_real_stderr
=
sys
.
stderr
sys
.
stderr
=
stderr
try
:
self
.
_component_tool
.
runLiveTest
(
test_name
)
finally
:
ERP5TypeTestCase
.
__bases__
=
base_tuple
ERP5TypeTestLoader
.
loadTestsFromNames
=
ERP5TypeTestLoader_loadTestsFromNames
sys
.
stderr
=
_real_stderr
test_output
=
self
.
_component_tool
.
readTestOutput
()
self
.
assertEqual
(
stderr
.
getvalue
(),
test_output
)
return
test_output
def
testRunLiveTest
(
self
):
"""
Create a new ZODB Test Component and try to run it as a live tests and
check the expected output
"""
# First try with a test which run successfully
source_code
=
self
.
_getValidSourceCode
()
component
=
self
.
_newComponent
(
'testRunLiveTest'
,
source_code
)
component
.
validate
()
self
.
tic
()
self
.
assertEqual
(
component
.
getValidationState
(),
'validated'
)
self
.
assertEqual
(
component
.
getValidationState
(),
'validated'
)
self
.
assertModuleImportable
(
'testRunLiveTest'
)
self
.
assertModuleImportable
(
'testRunLiveTest'
)
self
.
_component_tool
.
reset
(
force
=
True
,
self
.
_component_tool
.
reset
(
force
=
True
,
...
@@ -3295,19 +3316,7 @@ class Test(ERP5TypeTestCase):
...
@@ -3295,19 +3316,7 @@ class Test(ERP5TypeTestCase):
# set a request key, that should not be set from the test request
# set a request key, that should not be set from the test request
self
.
portal
.
REQUEST
.
set
(
'foo'
,
'something from main request'
)
self
.
portal
.
REQUEST
.
set
(
'foo'
,
'something from main request'
)
def
runLiveTest
(
test_name
):
output
=
self
.
_runLiveTest
(
'testRunLiveTest'
)
# ERP5TypeLiveTestCase.runLiveTest patches ERP5TypeTestCase bases, thus it
# needs to be restored after calling runLiveTest
base_tuple
=
ERP5TypeTestCase
.
__bases__
ERP5TypeTestLoader
.
loadTestsFromNames
=
loadTestsFromNames
try
:
self
.
_component_tool
.
runLiveTest
(
test_name
)
finally
:
ERP5TypeTestCase
.
__bases__
=
base_tuple
ERP5TypeTestLoader
.
loadTestsFromNames
=
ERP5TypeTestLoader_loadTestsFromNames
return
self
.
_component_tool
.
readTestOutput
()
output
=
runLiveTest
(
'testRunLiveTest'
)
expected_msg_re
=
re
.
compile
(
'Ran 1 test.*OK'
,
re
.
DOTALL
)
expected_msg_re
=
re
.
compile
(
'Ran 1 test.*OK'
,
re
.
DOTALL
)
self
.
assertRegex
(
output
,
expected_msg_re
)
self
.
assertRegex
(
output
,
expected_msg_re
)
...
@@ -3325,7 +3334,7 @@ class Test(ERP5TypeTestCase):
...
@@ -3325,7 +3334,7 @@ class Test(ERP5TypeTestCase):
self
.
_component_tool
.
reset
(
force
=
True
,
self
.
_component_tool
.
reset
(
force
=
True
,
reset_portal_type_at_transaction_boundary
=
True
)
reset_portal_type_at_transaction_boundary
=
True
)
output
=
runLiveTest
(
'testRunLiveTest'
)
output
=
self
.
_
runLiveTest
(
'testRunLiveTest'
)
expected_msg_re
=
re
.
compile
(
r'Ran 2 tests.*FAILED \
(
failures=1\
)
', re.DOTALL)
expected_msg_re
=
re
.
compile
(
r'Ran 2 tests.*FAILED \
(
failures=1\
)
', re.DOTALL)
self.assertRegex(output, expected_msg_re)
self.assertRegex(output, expected_msg_re)
...
@@ -3350,7 +3359,7 @@ class Test(ERP5TypeTestCase):
...
@@ -3350,7 +3359,7 @@ class Test(ERP5TypeTestCase):
self._component_tool.reset(force=True,
self._component_tool.reset(force=True,
reset_portal_type_at_transaction_boundary=True)
reset_portal_type_at_transaction_boundary=True)
output = runLiveTest('
testRunLiveTest
')
output =
self._
runLiveTest('
testRunLiveTest
')
expected_msg_re = re.compile('
Ran
3
test
.
*
OK
', re.DOTALL)
expected_msg_re = re.compile('
Ran
3
test
.
*
OK
', re.DOTALL)
self.assertRegex(output, expected_msg_re)
self.assertRegex(output, expected_msg_re)
...
@@ -3364,44 +3373,11 @@ break_at_import()
...
@@ -3364,44 +3373,11 @@ break_at_import()
component.validate()
component.validate()
self.tic()
self.tic()
from Products.ERP5Type.tests.runUnitTest import ERP5TypeTestLoader
ERP5TypeTestLoader_loadTestsFromNames = ERP5TypeTestLoader.loadTestsFromNames
def loadTestsFromNames(self, *args, **kwargs):
"""
Monkey patched to simulate a reset right after importing the ZODB Test
Component whose Unit Tests are going to be executed
"""
ret = ERP5TypeTestLoader_loadTestsFromNames(self, *args, **kwargs)
from Products.ERP5.ERP5Site import getSite
getSite().portal_components.reset(force=True)
# Simulate a new REQUEST while the old one has been GC'
ed
import
erp5.component
erp5
.
component
.
ref_manager
.
clear
()
import
gc
gc
.
collect
()
return
ret
self.assertEqual(component.getValidationState(), '
validated
')
self.assertEqual(component.getValidationState(), '
validated
')
self._component_tool.reset(force=True,
self._component_tool.reset(force=True,
reset_portal_type_at_transaction_boundary=True)
reset_portal_type_at_transaction_boundary=True)
def
runLiveTest
(
test_name
):
output = self._runLiveTest('
testRunLiveTestImportError
')
# ERP5TypeLiveTestCase.runLiveTest patches ERP5TypeTestCase bases, thus it
# needs to be restored after calling runLiveTest
base_tuple
=
ERP5TypeTestCase
.
__bases__
ERP5TypeTestLoader
.
loadTestsFromNames
=
loadTestsFromNames
try
:
self
.
_component_tool
.
runLiveTest
(
test_name
)
finally
:
ERP5TypeTestCase
.
__bases__
=
base_tuple
ERP5TypeTestLoader
.
loadTestsFromNames
=
ERP5TypeTestLoader_loadTestsFromNames
return
self
.
_component_tool
.
readTestOutput
()
output
=
runLiveTest
(
'testRunLiveTestImportError'
)
relative_url = '
portal_components
/
test
.
erp5
.
testRunLiveTestImportError
'
relative_url = '
portal_components
/
test
.
erp5
.
testRunLiveTestImportError
'
if six.PY2:
if six.PY2:
module_file = '
<
' + relative_url + '
>
'
module_file = '
<
' + relative_url + '
>
'
...
@@ -3417,7 +3393,7 @@ break_at_import()
...
@@ -3417,7 +3393,7 @@ break_at_import()
%(error_message)s
%(error_message)s
''' % dict(module_file=module_file, error_message=error_message), output)
''' % dict(module_file=module_file, error_message=error_message), output)
output
=
runLiveTest
(
'testDoesNotExist_import_error_because_module_does_not_exist'
)
output =
self._
runLiveTest('
testDoesNotExist_import_error_because_module_does_not_exist
')
if six.PY2:
if six.PY2:
expected_output = "ImportError: No module named testDoesNotExist_import_error_because_module_does_not_exist"
expected_output = "ImportError: No module named testDoesNotExist_import_error_because_module_does_not_exist"
else:
else:
...
...
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