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
Labels
Merge Requests
141
Merge Requests
141
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
Jobs
Commits
Open sidebar
nexedi
erp5
Commits
a9c8f164
Commit
a9c8f164
authored
Jun 17, 2013
by
Benjamin Blanc
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Fix bug(s) and add a scalability unit test
parent
4d50b6ca
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
128 additions
and
41 deletions
+128
-41
erp5/tests/testERP5TestNode.py
erp5/tests/testERP5TestNode.py
+94
-15
erp5/util/testnode/ScalabilityTestRunner.py
erp5/util/testnode/ScalabilityTestRunner.py
+14
-13
erp5/util/testnode/testnode.py
erp5/util/testnode/testnode.py
+19
-6
erp5/util/testnode/testnodeUtils.py
erp5/util/testnode/testnodeUtils.py
+1
-7
No files found.
erp5/tests/testERP5TestNode.py
View file @
a9c8f164
...
...
@@ -475,9 +475,9 @@ branch = foo
def
patch_getSlaposAccountCertificate
(
self
,
*
args
,
**
kw
):
return
"Certificate"
def
patch_generateConfiguration
(
self
,
*
args
,
**
kw
):
return
'
{"configuration_list": [], "involved_nodes_computer_guid"
\
: [], "error_message": "No error.", "launcher_nodes_computer_guid":
{}
,
\
"launchable":
false, "randomized_path" : "azertyuiop"}'
return
json
.
dumps
(
{
"configuration_list"
:
[],
"involved_nodes_computer_guid"
\
:
[],
"error_message"
:
"No error."
,
"launcher_nodes_computer_guid"
:
[]
,
\
"launchable"
:
False
,
"randomized_path"
:
"azertyuiop"
})
def
patch_isMasterTestnode
(
self
,
*
args
,
**
kw
):
return
(
grade
==
'master'
)
test_self
=
self
...
...
@@ -490,7 +490,10 @@ branch = foo
config_list
=
[]
# Sclalability slave testnode is not directly in charge of testsuites
if
my_test_type
==
'ScalabilityTest'
and
grade
==
'slave'
:
return
[]
if
counter
==
5
:
raise
StopIteration
counter
+=
1
return
json
.
dumps
([])
def
_checkExistingTestSuite
(
reference_set
):
test_self
.
assertEquals
(
set
(
reference_set
),
...
...
@@ -564,12 +567,7 @@ branch = foo
SlapOSControler
.
initializeSlapOSControler
=
doNothing
# Inside test_node a runner is created using new UnitTestRunner methods
test_node
.
run
()
# Doesn't have to install sofwtare themself
if
my_test_type
==
'ScalabilityTest'
and
grade
==
'slave'
:
self
.
assertEquals
(
0
,
counter
)
else
:
self
.
assertEquals
(
5
,
counter
)
self
.
assertEquals
(
5
,
counter
)
time
.
sleep
=
original_sleep
# Restore old class methods
if
my_test_type
==
"ScalabilityTest"
:
...
...
@@ -632,11 +630,11 @@ branch = foo
def
patch_getSlaposAccountCertificate
(
self
,
*
args
,
**
kw
):
return
"Certificate"
def
patch_generateConfiguration
(
self
,
*
args
,
**
kw
):
return
'
{"configuration_list": [], "involved_nodes_computer_guid"
\
: [], "error_message": "No error.", "launcher_nodes_computer_guid":
{}
,
\
"launchable":
false, "randomized_path" : "azertyuiop"}'
return
json
.
dumps
(
{
"configuration_list"
:
[],
"involved_nodes_computer_guid"
\
:
[],
"error_message"
:
"No error."
,
"launcher_nodes_computer_guid"
:
[]
,
\
"launchable"
:
False
,
"randomized_path"
:
"azertyuiop"
})
def
patch_isMasterTestnode
(
self
,
*
args
,
**
kw
):
return
(
grade
==
'master'
)
return
grade
==
'master'
test_self
=
self
test_result_path_root
=
os
.
path
.
join
(
test_self
.
_temp_dir
,
'test/results'
)
os
.
makedirs
(
test_result_path_root
)
...
...
@@ -854,4 +852,85 @@ branch = foo
def
test_scalability_18_resetSoftwareAfterManyBuildFailures
(
self
,
my_test_type
=
'ScalabilityTest'
):
# TODO : write own scalability test
pass
#TODO : add more test for scalability case
def
test_zzzz_scalability_19_xxxx
(
self
):
def
patch_createTestResult
(
self
,
revision
,
test_name_list
,
node_title
,
allow_restart
=
False
,
test_title
=
None
,
project_title
=
None
):
test_result_path
=
os
.
path
.
join
(
test_result_path_root
,
test_title
)
result
=
TestResultProxy
(
self
.
_proxy
,
self
.
_retry_time
,
self
.
_logger
,
test_result_path
,
node_title
,
revision
)
return
result
global
startTestSuiteDone
startTestSuiteDone
=
False
def
patch_startTestSuite
(
self
,
test_node_title
):
config_list
=
[]
global
startTestSuiteDone
if
not
startTestSuiteDone
:
startTestSuiteDone
=
True
config_list
.
append
(
test_self
.
getTestSuiteData
(
reference
=
'foo'
)[
0
])
config_list
.
append
(
test_self
.
getTestSuiteData
(
reference
=
'bar'
)[
0
])
else
:
raise
StopIteration
return
json
.
dumps
(
config_list
)
def
patch_isMasterTestnode
(
self
,
*
args
,
**
kw
):
return
True
def
patch_generateConfiguration
(
self
,
*
args
,
**
kw
):
return
json
.
dumps
({
"configuration_list"
:
[{
"ok"
:
"ok"
}],
"involved_nodes_computer_guid"
\
:
[
"COMP1"
,
"COMP2"
,
"COMP3"
],
"error_message"
:
"No error."
,
"launcher_nodes_computer_guid"
:
[
"COMP1"
],
\
"launchable"
:
False
,
"randomized_path"
:
"azertyuiop"
})
def
doNothing
(
self
,
*
args
,
**
kw
):
pass
def
patch_getSlaposAccountKey
(
self
,
*
args
,
**
kw
):
return
"key"
def
patch_getSlaposAccountCertificate
(
self
,
*
args
,
**
kw
):
return
"Certificate"
def
patch_getTestType
(
self
,
*
args
,
**
kw
):
return
"ScalabilityTest"
test_self
=
self
test_result_path_root
=
os
.
path
.
join
(
test_self
.
_temp_dir
,
'test/results'
)
os
.
makedirs
(
test_result_path_root
)
self
.
generateTestRepositoryList
()
# Select the good runner to modify
RunnerClass
=
self
.
returnGoodClassRunner
(
'ScalabilityTest'
)
# Patch methods
original_sleep
=
time
.
sleep
original_getSlaposAccountKey
=
TaskDistributor
.
getSlaposAccountKey
original_getSlaposAccountCertificate
=
TaskDistributor
.
getSlaposAccountCertificate
original_generateConfiguration
=
TaskDistributor
.
generateConfiguration
original_isMasterTestnode
=
TaskDistributor
.
isMasterTestnode
original_startTestSuite
=
TaskDistributor
.
startTestSuite
original_subscribeNode
=
TaskDistributor
.
subscribeNode
original_getTestType
=
TaskDistributor
.
getTestType
original_createTestResult
=
TaskDistributionTool
.
createTestResult
original_prepareSlapOS
=
RunnerClass
.
_prepareSlapOS
original_runTestSuite
=
RunnerClass
.
runTestSuite
original_supply
=
SlapOSControler
.
supply
#
time
.
sleep
=
doNothing
TaskDistributor
.
getSlaposAccountKey
=
patch_getSlaposAccountKey
TaskDistributor
.
getSlaposAccountCertificate
=
patch_getSlaposAccountCertificate
TaskDistributor
.
generateConfiguration
=
patch_generateConfiguration
TaskDistributor
.
isMasterTestnode
=
patch_isMasterTestnode
TaskDistributor
.
startTestSuite
=
patch_startTestSuite
TaskDistributor
.
subscribeNode
=
doNothing
TaskDistributor
.
getTestType
=
patch_getTestType
TaskDistributionTool
.
createTestResult
=
patch_createTestResult
RunnerClass
.
_prepareSlapOS
=
doNothing
RunnerClass
.
runTestSuite
=
doNothing
SlapOSControler
.
supply
=
doNothing
# Run
test_node
=
self
.
getTestNode
()
test_node
.
run
()
# Restore methods
TaskDistributor
.
getSlaposAccountKey
=
original_getSlaposAccountKey
TaskDistributor
.
getSlaposAccountCertificate
=
original_getSlaposAccountCertificate
TaskDistributor
.
generateConfiguration
=
original_generateConfiguration
TaskDistributor
.
isMasterTestnode
=
original_isMasterTestnode
TaskDistributor
.
startTestSuite
=
original_startTestSuite
TaskDistributionTool
.
createTestResult
=
original_createTestResult
TaskDistributionTool
.
subscribeNode
=
original_subscribeNode
TaskDistributionTool
.
getTestType
=
original_getTestType
RunnerClass
.
_prepareSlapOS
=
original_prepareSlapOS
RunnerClass
.
runTestSuite
=
original_runTestSuite
SlapOSControler
.
supply
=
original_supply
time
.
sleep
=
original_sleep
erp5/util/testnode/ScalabilityTestRunner.py
View file @
a9c8f164
...
...
@@ -49,17 +49,18 @@ import signal
class
ScalabilityTestRunner
():
def
__init__
(
self
,
testnode
):
self
.
testnode
=
testnode
self
.
log
=
self
.
testnode
.
log
self
.
slapos_controler
=
SlapOSControler
.
SlapOSControler
(
self
.
testnode
.
working_directory
,
self
.
testnode
.
config
,
self
.
testnode
.
log
)
self
.
log
)
# Create the slapos account configuration file and dir
key
=
self
.
testnode
.
test_suite_portal
.
getSlaposAccountKey
()
certificate
=
self
.
testnode
.
test_suite_portal
.
getSlaposAccountCertificate
()
self
.
slapos_controler
.
createSlaposConfigurationFileAccount
(
key
,
certificate
,
self
.
testnode
.
config
)
self
.
remaining_software_installation_dict
=
{}
# Protection to prevent installation of softwares after checking
...
...
@@ -72,7 +73,7 @@ class ScalabilityTestRunner():
"""
A proxy to supply : Install a software on a specific node
"""
self
.
testnode
.
log
(
"testnode, supply : %s %s"
,
software_path
,
computer_guid
)
self
.
log
(
"testnode, supply : %s %s"
,
software_path
,
computer_guid
)
if
self
.
authorize_supply
:
self
.
remaining_software_installation_dict
[
computer_guid
]
=
software_path
self
.
slapos_controler
.
supply
(
software_path
,
computer_guid
)
...
...
@@ -94,7 +95,7 @@ class ScalabilityTestRunner():
# Dummy slapos answering
def
_getSignal
(
self
,
signal
,
frame
):
self
.
testnode
.
log
(
"Dummy SlapOS Master answer received."
)
self
.
log
(
"Dummy SlapOS Master answer received."
)
self
.
last_slapos_answer
.
append
(
True
)
def
_prepareDummySlapOSAnswer
(
self
):
print
"Dummy slapOS answer enabled, send signal to %s (=PID) to simu
\
...
...
@@ -155,21 +156,21 @@ late a SlapOS (positive) answer." %(str(os.getpid()),)
# Avoid the test if it is not launchable
if
not
self
.
launchable
:
self
.
testnode
.
log
(
"Test suite %s is not actually launchable with
\
self
.
log
(
"Test suite %s is not actually launchable with
\
the current cluster configuration."
%
(
node_test_suite
.
test_suite_title
,))
self
.
testnode
.
log
(
"ERP5 Master indicates : %s"
%
(
self
.
error_message
,))
self
.
log
(
"ERP5 Master indicates : %s"
%
(
self
.
error_message
,))
# error : wich code to return ?
return
{
'status_code'
:
1
}
# create an obfuscated link to the testsuite directory
self
.
testnode
.
log
(
"self.testnode.config['software_directory']
\
self
.
log
(
"self.testnode.config['software_directory']
\
: %s"
%
(
self
.
testnode
.
config
[
'software_directory'
]))
self
.
testnode
.
log
(
"self.randomized_path
\
self
.
log
(
"self.randomized_path
\
: %s"
%
(
self
.
randomized_path
))
path_to_suite
=
os
.
path
.
join
(
self
.
testnode
.
config
[
'working_directory'
],
node_test_suite
.
reference
)
self
.
testnode
.
log
(
"path_to_suite
\
self
.
log
(
"path_to_suite
\
: %s"
%
(
path_to_suite
))
self
.
ofuscated_link_path
=
os
.
path
.
join
(
self
.
testnode
.
config
[
'software_directory'
],
...
...
@@ -181,7 +182,7 @@ late a SlapOS (positive) answer." %(str(os.getpid()),)
except
:
raise
ValueError
(
"testnode, Unable to create symbolic link to the testsuite."
)
self
.
testnode
.
log
(
"Sym link : %s %s"
%
(
path_to_suite
,
self
.
ofuscated_link_path
))
self
.
log
(
"Sym link : %s %s"
%
(
path_to_suite
,
self
.
ofuscated_link_path
))
involved_nodes_computer_guid
=
test_configuration
[
'involved_nodes_computer_guid'
]
...
...
@@ -192,7 +193,7 @@ late a SlapOS (positive) answer." %(str(os.getpid()),)
self
.
reachable_profile
=
os
.
path
.
join
(
"https://"
,
"["
+
self
.
testnode
.
config
[
'httpd_ip'
]
+
"]"
+
":"
+
self
.
testnode
.
config
[
'httpd_software_access_port'
],
self
.
randomized_path
,
"software.cfg"
)
self
.
testnode
.
log
(
"Software reachable profile path is : %s "
self
.
log
(
"Software reachable profile path is : %s "
%
(
self
.
reachable_profile
,))
software_path_list
.
append
(
self
.
reachable_profile
)
# Ask for softwares installation
...
...
@@ -206,7 +207,7 @@ late a SlapOS (positive) answer." %(str(os.getpid()),)
# Waiting until all softwares are installed
while
(
self
.
remainSoftwareToInstall
()
and
(
max_time
>
(
time
.
time
()
-
start_time
))):
self
.
testnode
.
log
(
"Master testnode is waiting
\
self
.
log
(
"Master testnode is waiting
\
for the end of all software installation (for %ss)."
,
str
(
int
(
time
.
time
()
-
start_time
)))
time
.
sleep
(
interval_time
)
...
...
@@ -215,7 +216,7 @@ late a SlapOS (positive) answer." %(str(os.getpid()),)
self
.
_comeBackFromDummySlapOS
()
if
self
.
remainSoftwareToInstall
()
:
return
{
'status_code'
:
1
}
self
.
testnode
.
log
(
"Softwares installed"
)
self
.
log
(
"Softwares installed"
)
return
{
'status_code'
:
0
}
def
_cleanUpNodesInformation
(
self
):
...
...
erp5/util/testnode/testnode.py
View file @
a9c8f164
...
...
@@ -38,6 +38,9 @@ import logging
import
string
import
random
import
testnodeUtils
import
traceback
from
ProcessManager
import
SubprocessError
,
ProcessManager
,
CancellationError
from
subprocess
import
CalledProcessError
from
Updater
import
Updater
...
...
@@ -298,7 +301,6 @@ branch = %(branch)s
test_node_slapos
=
SlapOSInstance
()
test_node_slapos
.
edit
(
working_directory
=
self
.
config
[
'slapos_directory'
])
## /BLOCK OK
try
:
while
True
:
try
:
...
...
@@ -310,9 +312,10 @@ branch = %(branch)s
portal_url
=
config
[
'test_suite_master_url'
]
portal
=
taskdistribution
.
TaskDistributionTool
(
portal_url
,
logger
=
DummyLogger
(
log
))
self
.
test_suite_portal
=
taskdistribution
.
TaskDistributor
(
portal_url
,
logger
=
DummyLogger
(
log
))
self
.
test_suite_portal
.
subscribeNode
(
config
[
'test_node_title'
],
config
[
'computer_id'
])
self
.
test_suite_portal
.
subscribeNode
(
config
[
'test_node_title'
],
config
[
'computer_id'
])
test_suite_json
=
self
.
test_suite_portal
.
startTestSuite
(
config
[
'test_node_title'
])
test_suite_data
=
testnodeUtils
.
deunicodeData
(
json
.
loads
(
test_suite_json
))
log
(
"Got following test suite data from master : %r"
%
\
(
test_suite_data
,))
...
...
@@ -337,8 +340,11 @@ from the distributor.")
# master testnode gets test_suites, slaves get nothing
runner
.
prepareSlapOSForTestNode
(
test_node_slapos
)
# Clean-up test suites
self
.
checkOldTestSuite
(
test_suite_data
)
self
.
checkOldTestSuite
(
test_suite_data
)
for
test_suite
in
test_suite_data
:
remote_test_result_needs_cleanup
=
False
node_test_suite
=
self
.
getNodeTestSuite
(
...
...
@@ -360,13 +366,15 @@ from the distributor.")
node_test_suite
.
project_title
)
remote_test_result_needs_cleanup
=
True
log
(
"testnode, test_result : %r"
%
(
test_result
,
))
if
test_result
is
not
None
:
self
.
registerSuiteLog
(
test_result
,
node_test_suite
)
self
.
checkRevision
(
test_result
,
node_test_suite
)
# Now prepare the installation of SlapOS and create instance
status_dict
=
runner
.
prepareSlapOSForTestSuite
(
node_test_suite
)
# Give some time so computer partitions may start
# as partitions can be of any kind we have and likely will never have
# a reliable way to check if they are up or not ...
...
...
@@ -396,6 +404,9 @@ from the distributor.")
node_test_suite
.
retry
=
True
continue
except
:
log
(
"Errror"
)
ex_type
,
ex
,
tb
=
sys
.
exc_info
()
traceback
.
print_tb
(
tb
)
log
(
"erp5testnode exception"
,
exc_info
=
sys
.
exc_info
())
raise
now
=
time
.
time
()
...
...
@@ -407,6 +418,8 @@ from the distributor.")
except
:
log
(
"Exception in error handling"
,
exc_info
=
sys
.
exc_info
())
finally
:
if
'tb'
in
locals
():
del
tb
# Nice way to kill *everything* generated by run process -- process
# groups working only in POSIX compilant systems
# Exceptions are swallowed during cleanup phase
...
...
erp5/util/testnode/testnodeUtils.py
View file @
a9c8f164
...
...
@@ -4,13 +4,7 @@ import shutil
import
string
def
deunicodeData
(
data
):
if
isinstance
(
data
,
int
):
new_data
=
data
elif
isinstance
(
data
,
str
):
new_data
=
data
elif
isinstance
(
data
,
bool
):
new_data
=
data
elif
isinstance
(
data
,
list
):
if
isinstance
(
data
,
list
):
new_data
=
[]
for
sub_data
in
data
:
new_data
.
append
(
deunicodeData
(
sub_data
))
...
...
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