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
alecs_myu
erp5
Commits
c8d33446
Commit
c8d33446
authored
Aug 24, 2017
by
Roque
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
All my changes since beginning. Includes tasks: 1 to 4 (done) and 5 (current).
parent
646852df
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
666 additions
and
246 deletions
+666
-246
erp5/util/testnode/ScalabilityTestRunner.py
erp5/util/testnode/ScalabilityTestRunner.py
+128
-31
erp5/util/testnode/SlapOSControler.py
erp5/util/testnode/SlapOSControler.py
+16
-5
erp5/util/testnode/SlapOSMasterCommunicator.py
erp5/util/testnode/SlapOSMasterCommunicator.py
+513
-207
erp5/util/testnode/testnode.py
erp5/util/testnode/testnode.py
+9
-3
No files found.
erp5/util/testnode/ScalabilityTestRunner.py
View file @
c8d33446
...
...
@@ -24,9 +24,6 @@
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
##############################################################################
############## ROQUE VERSION #################################################
import
datetime
import
os
import
subprocess
...
...
@@ -49,6 +46,10 @@ from erp5.util import taskdistribution
# for dummy slapos answer
import
signal
import
slapos.slap
# max time to instance changing state: 2 hour
MAX_INSTANCE_TIME
=
60
*
60
*
2
# max time to register instance to slapOSMaster: 5 minutes
...
...
@@ -68,7 +69,6 @@ class ScalabilityTestRunner():
# Create the slapos account configuration file and dir
key
=
self
.
testnode
.
test_suite_portal
.
getSlaposAccountKey
()
certificate
=
self
.
testnode
.
test_suite_portal
.
getSlaposAccountCertificate
()
# Get Slapos Master Url
self
.
slapos_url
=
''
try
:
...
...
@@ -85,7 +85,7 @@ class ScalabilityTestRunner():
self
.
log
(
"SlapOS Master hateoas url is: %s"
%
self
.
slapos_api_rest_url
)
self
.
key_path
,
self
.
cert_path
,
config_path
=
self
.
slapos_controler
.
createSlaposConfigurationFileAccount
(
key
,
certificate
,
self
.
slapos_url
,
self
.
testnode
.
config
)
key
,
certificate
,
self
.
slapos_url
,
self
.
testnode
.
config
,
self
.
slapos_api_rest_url
)
self
.
slapos_communicator
=
None
# Dict containing used to store which SR is not yet correctly installed.
# looks like: {'comp_id1':'SR_urlA', 'comp_id2':'SR_urlA',..}
...
...
@@ -106,7 +106,9 @@ class ScalabilityTestRunner():
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
)
#self.slapos_controler.supply(software_path, computer_guid)
#self.slapos_communicator._supply("available")
# Here make a request via slapos controler ?
return
{
'status_code'
:
0
}
else
:
...
...
@@ -150,9 +152,21 @@ class ScalabilityTestRunner():
test_result
,
test_suite
)
self
.
log
(
"testnode, request : %s"
,
instance_title
)
config
=
json
.
dumps
(
config
)
self
.
slapos_controler
.
request
(
instance_title
,
software_path
,
"test"
,
{
"_"
:
config
},
self
.
launcher_nodes_computer_guid
[
0
])
#request_kw = {"_" : config}
request
=
{
"_"
:
config
}
request_kw
=
{
"partition_parameter_kw"
:
request
}
#self.log("config from softConf, tResult & tSuite: " + str(config))
#self.log("request_kw: " + str(request_kw))
self
.
log
(
"Computer : "
+
str
(
self
.
launcher_nodes_computer_guid
[
0
]))
#self.slapos_controler.request(instance_title, software_path,
# "test", {"_" : config},
# self.launcher_nodes_computer_guid[0])
self
.
slapos_communicator
.
setName
(
instance_title
)
self
.
slapos_communicator
.
setRequestParameters
(
request_kw
)
# ROQUE: request commented because it's failing. Instance manually requested.
#self.slapos_communicator._request("started")
# ROQUE: harcoded state (that should happens in the ._request )
self
.
slapos_communicator
.
forceSetState
(
'started'
)
self
.
authorize_request
=
False
return
{
'status_code'
:
0
}
else
:
...
...
@@ -224,9 +238,11 @@ late a SlapOS (positive) answer." %(str(os.getpid()),str(os.getpid()),))
"""
Wait for 'max_time' an instance specific state
"""
max_time
=
20
self
.
log
(
"Wait for instance state: %s"
%
state
)
start_time
=
time
.
time
()
while
(
not
self
.
slapos_communicator
.
isHostingSubscriptionReady
(
instance_title
,
state
)
#while (not self.slapos_communicator.isHostingSubscriptionReady(instance_title, state)
while
(
not
self
.
slapos_communicator
.
_getInstanceState
()
==
state
and
(
max_time
>
(
time
.
time
()
-
start_time
))):
self
.
log
(
"Instance(s) not in %s state yet."
%
state
)
time
.
sleep
(
15
)
...
...
@@ -243,13 +259,17 @@ late a SlapOS (positive) answer." %(str(os.getpid()),str(os.getpid()),))
raise
ValueError
(
error_message
)
self
.
log
(
"Instance correctly '%s' after %s seconds."
%
(
state
,
str
(
time
.
time
()
-
start_time
)))
def
_waitInstanceCreation
(
self
,
instance_title
,
max_time
=
MAX_CREATION_INSTANCE_TIME
):
def
_waitInstanceCreation
(
self
,
instance_title
,
hateoas
,
max_time
=
MAX_CREATION_INSTANCE_TIME
):
"""
Wait for 'max_time' the instance creation
"""
self
.
log
(
"Wait
for instance creation
"
)
self
.
log
(
"Wait
ing for instance creation...
"
)
start_time
=
time
.
time
()
while
(
not
self
.
slapos_communicator
.
isRegisteredHostingSubscription
(
instance_title
)
\
#while ( not self.slapos_communicator.isRegisteredHostingSubscription(instance_title) \
self
.
log
(
"Instance title: "
+
str
(
instance_title
))
#self.log("List of Hosting subscriptions : ")
#self.log(str(hateoas.getHostingSubscriptionDict()))
while
(
not
instance_title
in
hateoas
.
getHostingSubscriptionDict
()
\
and
(
max_time
>
(
time
.
time
()
-
start_time
))
):
time
.
sleep
(
5
)
if
(
time
.
time
()
-
start_time
)
>
max_time
:
...
...
@@ -260,18 +280,52 @@ late a SlapOS (positive) answer." %(str(os.getpid()),str(os.getpid()),))
"""
Install testsuite softwares
"""
self
.
log
(
'
prepareSlapOSForTestSuite
'
)
self
.
log
(
'
Preparing SlapOS for Test Suite...
'
)
# Define how many time this method can take
max_time
=
3600
*
10
*
1.0
# 10 hours
interval_time
=
60
start_time
=
time
.
time
()
# Create a communicator with slapos
self
.
log
(
"creating SlapOs Master communicator..."
)
self
.
slapos_communicator
=
SlapOSMasterCommunicator
.
SlapOSMasterCommunicator
(
self
.
cert_path
,
self
.
key_path
,
self
.
log
,
self
.
slapos_api_rest_url
)
#self.log("CERT: " + str(self.cert_path))
#self.log("KEY: " + str(self.key_path))
#self.log("API URL: " + str(self.slapos_api_rest_url))
#self.log("MASTER URL: " + str(self.slapos_url))
### NEW ! Creating Slapos master communicator ###
slap
=
slapos
.
slap
.
slap
()
retry
=
0
while
True
:
if
retry
>
100
:
break
# wait until _hateoas_navigator is loaded.
slap
.
initializeConnection
(
self
.
slapos_url
,
self
.
key_path
,
self
.
cert_path
,
timeout
=
120
,
slapgrid_rest_uri
=
self
.
slapos_api_rest_url
)
if
getattr
(
slap
,
'_hateoas_navigator'
,
None
)
is
None
:
retry
+=
1
self
.
log
(
"Fail to load _hateoas_navigator waiting a bit and retry."
)
time
.
sleep
(
30
)
else
:
break
if
getattr
(
slap
,
'_hateoas_navigator'
,
None
)
is
None
:
raise
ValueError
(
"Fail to load _hateoas_navigator"
)
hateoas
=
getattr
(
slap
,
'_hateoas_navigator'
,
None
)
#self.log("_hateoas_navigator object ")
#self.log(".getHostingSubscriptionDict()")
#self.log(hateoas.getHostingSubscriptionDict())
#self.log("_hateoasGetInformation()")
#self.log(hateoas._hateoasGetInformation("nxdcloud-onlinenet-scalabilitynode-001-ERP5SCALABILITY"))
#self.log("getHostingSubscriptionRootSoftwareInstanceInformation(node)")
#self.log(hateoas.getHostingSubscriptionRootSoftwareInstanceInformation("nxdcloud-onlinenet-scalabilitynode-001-ERP5SCALABILITY"))
#self.log(".getRelatedInstanceInformation(node)")
#self.log(hateoas.getRelatedInstanceInformation("nxdcloud-onlinenet-scalabilitynode-001-ERP5SCALABILITY"))
supply
=
slap
.
registerSupply
()
order
=
slap
.
registerOpenOrder
()
### //NEW ! ###
# Only master testnode must order software installation
if
self
.
testnode
.
test_suite_portal
.
isMasterTestnode
(
self
.
testnode
.
config
[
'test_node_title'
]):
...
...
@@ -340,7 +394,9 @@ late a SlapOS (positive) answer." %(str(os.getpid()),str(os.getpid()),))
# Ask for SR installation
for
computer_guid
in
self
.
involved_nodes_computer_guid
:
self
.
_prepareSlapOS
(
self
.
reachable_profile
,
computer_guid
)
self
.
slapos_communicator
=
SlapOSMasterCommunicator
.
SoftwareReleaseTester
(
"NAME"
,
self
.
log
,
slap
,
supply
,
order
,
self
.
reachable_profile
,
computer_guid
=
computer_guid
)
# ROQUE: "_prepareSlapOS" is commented because the instance request is not working (manually created for dev purposes)
#self._prepareSlapOS(self.reachable_profile, computer_guid)
# From the line below we would not supply any more softwares
self
.
authorize_supply
=
False
# TODO : remove the line below wich simulate an answer from slapos master
...
...
@@ -362,14 +418,49 @@ late a SlapOS (positive) answer." %(str(os.getpid()),str(os.getpid()),))
# Launch instance
self
.
instance_title
=
self
.
_generateInstanceTitle
(
node_test_suite
.
test_suite_title
)
try
:
# ROQUE: the instance title is harcoded because the instance request is not working (this one was manually created)
self
.
instance_title
=
"nxdcloud-onlinenet-scalabilitynode-001-TESTINSTANCE"
self
.
_createInstance
(
self
.
reachable_profile
,
configuration_list
[
0
],
self
.
instance_title
,
node_test_suite
.
test_result
,
node_test_suite
.
test_suite
)
self
.
log
(
"Scalability instance requested."
)
except
:
self
.
log
(
"Unable to launch instance"
)
raise
ValueError
(
"Unable to launch instance"
)
self
.
log
(
"Waiting for instance creation.."
)
self
.
_waitInstanceCreation
(
self
.
instance_title
)
self
.
_waitInstanceCreation
(
self
.
instance_title
,
hateoas
)
computer
=
self
.
slapos_communicator
.
_hateoas_getComputer
(
"COMP-2732"
)
#self.log("COMPUTER: " + str(computer))
#software_installation_list = self.slapos_communicator.getSoftwareInstallationList()
#self.log("software_installation_list: ")
#self.log(str(software_installation_list))
getSoftwareInstallationNews
=
self
.
slapos_communicator
.
getSoftwareInstallationNews
()
self
.
log
(
"Software installation news: "
)
self
.
log
(
str
(
getSoftwareInstallationNews
))
#getInstanceUrlList = self.slapos_communicator.getInstanceUrlList()
#self.log("getInstanceUrlList")
#self.log(str(getInstanceUrlList))
# ROQUE: for debugging purposes
instance_url
=
'https://api.vifib.com/software_instance_module/20170822-1568166F/ERP5Document_getHateoas'
self
.
log
(
"getNewsFromInstance(url)"
)
self
.
log
(
str
(
self
.
slapos_communicator
.
getNewsFromInstance
(
instance_url
)))
self
.
log
(
"getInformationFromInstance(url)"
)
self
.
log
(
str
(
self
.
slapos_communicator
.
getInformationFromInstance
(
instance_url
)))
# ROQUE: get info contains the software release url
#getInfo = self.slapos_communicator.getInfo()
#self.log("getInfo: ")
#self.log(str(getInfo))
# "No message"
#getFormatedLastMessage = self.slapos_communicator.getFormatedLastMessage()
#self.log("getFormatedLastMessage: ")
#self.log(str(getFormatedLastMessage))
getSoftwareState
=
self
.
slapos_communicator
.
_getSoftwareState
()
self
.
log
(
"Software state: "
+
str
(
getSoftwareState
))
getInstanceState
=
self
.
slapos_communicator
.
_getInstanceState
()
self
.
log
(
"Instance state: "
+
str
(
getInstanceState
))
return
{
'status_code'
:
0
}
return
{
'status_code'
:
1
}
...
...
@@ -380,17 +471,21 @@ late a SlapOS (positive) answer." %(str(os.getpid()),str(os.getpid()),))
configuration_list
=
node_test_suite
.
configuration_list
test_list
=
range
(
0
,
len
(
configuration_list
))
# create test_result
self
.
log
(
"Creating Test Result..."
)
test_result_proxy
=
self
.
testnode
.
portal
.
createTestResult
(
node_test_suite
.
revision
,
test_list
,
self
.
testnode
.
config
[
'test_node_title'
],
True
,
node_test_suite
.
test_suite_title
,
node_test_suite
.
project_title
)
self
.
log
(
"Test Result created."
)
count
=
0
error_message
=
None
# Each cluster configuration are tested
self
.
log
(
"FOR CONFIG IN CONFIG_LIST:"
)
for
configuration
in
configuration_list
:
self
.
log
(
"configuration n: "
+
str
(
count
))
self
.
log
(
str
(
configuration
))
# First configuration doesn't need XML configuration update.
if
count
>
0
:
...
...
@@ -400,19 +495,21 @@ late a SlapOS (positive) answer." %(str(os.getpid()),str(os.getpid()),))
# Update instance XML configuration
self
.
_updateInstanceXML
(
configuration
,
self
.
instance_title
,
node_test_suite
.
test_result
,
node_test_suite
.
test_suite
)
self
.
_waitInstance
(
self
.
instance_title
,
'started'
)
self
.
_waitInstance
(
self
.
instance_title
,
SlapOSMasterCommunicator
.
INSTANCE_STATE_STARTED
)
# Start instance
self
.
slapos_controler
.
startInstance
(
self
.
instance_title
)
# XXX: Dirty hack used to force haproxy to restart in time
# with all zope informations.
self
.
_waitInstance
(
self
.
instance_title
,
'started'
)
self
.
slapos_controler
.
stopInstance
(
self
.
instance_title
)
self
.
_waitInstance
(
self
.
instance_title
,
'stopped'
)
self
.
slapos_controler
.
startInstance
(
self
.
instance_title
)
self
.
_waitInstance
(
self
.
instance_title
,
SlapOSMasterCommunicator
.
INSTANCE_STATE_STARTED
)
#self.slapos_controler.stopInstance(self.instance_title)
self
.
slapos_communicator
.
_request
(
'stopped'
)
self
.
_waitInstance
(
self
.
instance_title
,
SlapOSMasterCommunicator
.
INSTANCE_STATE_STOPPED
)
self
.
slapos_communicator
.
_request
(
'started'
)
#self.slapos_controler.startInstance(self.instance_title)
##########################################################
self
.
_waitInstance
(
self
.
instance_title
,
'started'
)
self
.
_waitInstance
(
self
.
instance_title
,
SlapOSMasterCommunicator
.
INSTANCE_STATE_STARTED
)
# Start only the current test
exclude_list
=
[
x
for
x
in
test_list
if
x
!=
test_list
[
count
]]
...
...
erp5/util/testnode/SlapOSControler.py
View file @
c8d33446
...
...
@@ -37,6 +37,8 @@ import argparse
import
json
from
slapos
import
client
from
ConfigParser
import
ConfigParser
MAX_PARTIONS
=
10
MAX_SR_RETRIES
=
3
...
...
@@ -78,7 +80,7 @@ class SlapOSControler(object):
#TODO: implement a method to get all instance related the slapOS account
# and deleting all old instances (based on creation date or name etc...)
def
createSlaposConfigurationFileAccount
(
self
,
key
,
certificate
,
slapos_url
,
config
):
def
createSlaposConfigurationFileAccount
(
self
,
key
,
certificate
,
slapos_url
,
config
,
slapos_rest_url
):
# Create "slapos_account" directory in the "slapos_directory"
slapos_account_directory
=
os
.
path
.
join
(
config
[
'slapos_directory'
],
"slapos_account"
)
createFolder
(
slapos_account_directory
)
...
...
@@ -86,9 +88,10 @@ class SlapOSControler(object):
slapos_account_key_path
=
os
.
path
.
join
(
slapos_account_directory
,
"key"
)
slapos_account_certificate_path
=
os
.
path
.
join
(
slapos_account_directory
,
"certificate"
)
configuration_file_path
=
os
.
path
.
join
(
slapos_account_directory
,
"slapos.cfg"
)
configuration_file_value
=
"[slapos]
\
n
master_url = %s
\
n
\
configuration_file_value
=
"[slapos]
\
n
master_url = %s
\
n
master_rest_url = %s
\
n
\
[slapconsole]
\
n
cert_file = %s
\
n
key_file = %s"
%
(
slapos_url
,
slapos_rest_url
,
slapos_account_certificate_path
,
slapos_account_key_path
)
createFile
(
slapos_account_key_path
,
"w"
,
key
)
...
...
@@ -109,11 +112,19 @@ class SlapOSControler(object):
parser
.
add_argument
(
"software_url"
)
parser
.
add_argument
(
"node"
)
if
os
.
path
.
exists
(
self
.
configuration_file_path
):
self
.
log
(
"configuration_file_path: "
+
str
(
self
.
configuration_file_path
))
args
=
parser
.
parse_args
([
self
.
configuration_file_path
,
software_url
,
computer_id
])
config
=
client
.
Config
()
config
.
setConfig
(
args
,
args
.
configuration_file
)
self
.
log
(
"parsed args: "
+
str
(
args
))
#config = client.Config()
#config.setConfig(args, args.configuration_file)
self
.
log
(
"Creating clientConfig..."
)
configp
=
ConfigParser
()
configp
.
read
(
self
.
configuration_file_path
)
config
=
client
.
ClientConfig
(
args
,
configp
)
try
:
local
=
client
.
init
(
config
)
self
.
log
(
"config instantiated. Calling client.init(config)..."
)
local
=
client
.
init
(
config
,
self
.
log
)
self
.
log
(
"local instantiated with client.init!"
)
local
[
'supply'
](
software_url
,
computer_guid
=
computer_id
,
state
=
state
)
self
.
log
(
'SlapOSControler : supply %s %s %s'
%
(
software_url
,
computer_id
,
state
))
except
:
...
...
erp5/util/testnode/SlapOSMasterCommunicator.py
View file @
c8d33446
import
datetime
import
json
import
httplib
import
urlparse
import
sys
import
traceback
import
time
#import feedparser
from
uritemplate
import
expand
TIMEOUT
=
30
import
slapos.slap
from
slapos.slap
import
SoftwareProductCollection
from
slapos.slap.slap
import
ConnectionError
from
requests.exceptions
import
HTTPError
from
erp5.util.taskdistribution
import
SAFE_RPC_EXCEPTION_LIST
SOFTWARE_PRODUCT_NAMESPACE
=
"product."
SOFTWARE_STATE_UNKNOWN
=
"SOFTWARE_STATE_UNKNOWN"
SOFTWARE_STATE_INSTALLING
=
"SOFTWARE_STATE_INSTALLING"
SOFTWARE_STATE_INSTALLED
=
"SOFTWARE_STATE_INSTALLED"
SOFTWARE_STATE_DESTROYING
=
"SOFTWARE_STATE_DESTROYING"
INSTANCE_STATE_UNKNOWN
=
"INSTANCE_STATE_UNKNOWN"
INSTANCE_STATE_STARTING
=
"INSTANCE_STATE_STARTING"
INSTANCE_STATE_STARTED
=
"INSTANCE_STATE_STARTED"
INSTANCE_STATE_STARTED_WITH_ERROR
=
"INSTANCE_STATE_STARTED_WITH_ERROR"
INSTANCE_STATE_STOPPING
=
"INSTANCE_STATE_STOPPING"
INSTANCE_STATE_STOPPED
=
"INSTANCE_STATE_STOPPED"
INSTANCE_STATE_DESTROYING
=
"INSTANCE_STATE_DESTROYING"
TESTER_STATE_INITIAL
=
"TESTER_STATE_INITIAL"
TESTER_STATE_NOTHING
=
"TESTER_STATE_NOTHING"
TESTER_STATE_SOFTWARE_INSTALLED
=
"TESTER_STATE_SOFTWARE_INSTALLED"
TESTER_STATE_INSTANCE_INSTALLED
=
"TESTER_STATE_INSTANCE_INSTALLED"
TESTER_STATE_INSTANCE_STARTED
=
"TESTER_STATE_INSTANCE_STARTED"
TESTER_STATE_INSTANCE_UNINSTALLED
=
"TESTER_STATE_INSTANCE_UNINSTALLED"
# Simple decorator to prevent raise due small
# network failures.
def
retryOnNetworkFailure
(
func
):
def
wrapper
(
*
args
,
**
kwargs
):
retry_time
=
64
while
True
:
try
:
return
func
(
*
args
,
**
kwargs
)
except
SAFE_RPC_EXCEPTION_LIST
,
e
:
print
'Network failure: %s , %s'
%
(
sys
.
exc_info
(),
e
)
except
HTTPError
,
e
:
print
'Network failure: %s , %s'
%
(
sys
.
exc_info
(),
e
)
except
ConnectionError
,
e
:
print
'Network failure: %s , %s'
%
(
sys
.
exc_info
(),
e
)
except
slapos
.
slap
.
ConnectionError
,
e
:
print
'Network failure: %s , %s'
%
(
sys
.
exc_info
(),
e
)
print
'Retry method %s in %i seconds'
%
(
func
,
retry_time
)
time
.
sleep
(
retry_time
)
retry_time
=
min
(
retry_time
*
1.5
,
640
)
wrapper
.
__name__
=
func
.
__name__
wrapper
.
__doc__
=
func
.
__doc__
return
wrapper
# TODO: News-> look list to get last news... (and not the first of the list)
class
SlapOSMasterCommunicator
(
object
):
"""
Communication with slapos Master using Hateoas.
collection: collection of data (hosting_subscription, instance, software_release...)
hosting_subscription: result of a request
instance(s): instance(s) related to an hosting_subscription
usage: ex:
# Try to reuse same communicator, because initilization step may takes a lot of time
# due to listing of all instances (alive or not) related to the specified slapOS account.
communicator = SlapOSMasterCommunicator()
def
__init__
(
self
,
slap
,
slap_supply
,
slap_order
,
url
,
logger
):
self
.
_logger
=
logger
self
.
slap
=
slap
self
.
slap_order
=
slap_order
self
.
slap_supply
=
slap_supply
self
.
hateoas_navigator
=
self
.
slap
.
_hateoas_navigator
self
.
hosting_subscription_url
=
None
# Print news related to 'TestScalability_21423104630420' all instances
instance_link_list = communicator._getRelatedInstanceLink('TestScalability_21423104630420')
for instance_link in instance_link_list:
news = communicator.getNewsFromInstanceLink(instance_link)
print news['news']
"""
def
__init__
(
self
,
certificate_path
,
key_path
,
log
,
url
):
# Create connection
api_scheme
,
api_netloc
,
api_path
,
api_query
,
api_fragment
=
urlparse
.
urlsplit
(
url
)
self
.
log
=
log
self
.
certificate_path
=
certificate_path
self
.
key_path
=
key_path
self
.
url
=
url
self
.
log
(
"Getting connection to "
+
str
(
self
.
url
))
self
.
connection
=
self
.
_getConnection
(
self
.
certificate_path
,
self
.
key_path
,
self
.
url
)
self
.
log
(
"Connection done."
)
# Get master
master_link
=
{
'href'
:
api_path
,
'type'
:
"application/vnd.slapos.org.hal+json; class=slapos.org.master"
}
self
.
log
(
"Getting master with href: "
+
str
(
api_path
))
#master = self._curl(master_link)
#self.person_link = master['_links']['http://slapos.org/reg/me']
self
.
person_link
=
{
"href"
:
"urn:jio:get:person_module/20170705-995F2E"
}
self
.
log
(
"Getting person with curl to harcoded link."
)
# Get person related to specified key/certificate provided
person
=
self
.
_curl
(
self
.
person_link
)
self
.
log
(
"person: "
str
(
person
))
self
.
personnal_collection_link
=
person
[
'_links'
][
'http://slapos.org/reg/hosting_subscription'
]
self
.
log
(
"personal collection link : "
+
str
(
self
.
personnal_collection_link
))
# Get collection (of hosting subscriptions)
self
.
log
(
"Getting collection with curl"
)
collection
=
self
.
_curl
(
self
.
personnal_collection_link
)
self
.
log
(
"collection: "
+
str
(
collection
))
# XXX: This part may be extremly long (because here no hosting subscriptions
# has been visited)
self
.
hosting_subcriptions_dict
=
{}
self
.
visited_hosting_subcriptions_link_list
=
[]
self
.
log
(
"SlapOSMasterCommunicator will read all hosting subscriptions entries, "
"it may take several time..."
)
self
.
_update_hosting_subscription_informations
()
#self.computer_guid = computer_guid
#self.name = name
if
url
is
not
None
and
\
url
.
startswith
(
SOFTWARE_PRODUCT_NAMESPACE
):
product
=
SoftwareProductCollection
(
self
.
_logger
,
self
.
slap
)
try
:
url
=
product
.
__getattr__
(
url
[
len
(
SOFTWARE_PRODUCT_NAMESPACE
):])
except
AttributeError
as
e
:
self
.
_logger
.
warning
(
'Error on get software release : %s '
%
e
.
message
)
self
.
url
=
url
def
setName
(
self
,
name
):
self
.
name
=
name
def
setRequestParameters
(
self
,
request_kw
):
if
isinstance
(
request_kw
,
str
)
or
\
isinstance
(
request_kw
,
unicode
):
self
.
request_kw
=
json
.
loads
(
request_kw
)
else
:
self
.
request_kw
=
request_kw
#self._logger("request parameters set: " + str(self.request_kw))
@
retryOnNetworkFailure
def
_supply
(
self
,
state
):
if
self
.
computer_guid
is
None
:
self
.
_logger
.
log
(
'Nothing to supply for %s.'
%
(
self
.
name
))
return
None
self
.
_logger
(
"From SlapOSMasterCommunicator"
)
self
.
_logger
(
'Supply %s@%s: %s'
,
self
.
url
,
self
.
computer_guid
,
state
)
return
self
.
slap_supply
.
supply
(
self
.
url
,
self
.
computer_guid
)
#return self.slap_supply.supply(self.url, self.computer_guid, state)
@
retryOnNetworkFailure
def
_request
(
self
,
state
):
self
.
_logger
.
info
(
'Request %s@%s: %s'
,
self
.
url
,
self
.
name
,
state
)
self
.
latest_state
=
state
return
self
.
slap_order
.
request
(
software_release
=
self
.
url
,
partition_reference
=
self
.
name
,
state
=
state
,
**
self
.
request_kw
)
@
retryOnNetworkFailure
def
_hateoas_getComputer
(
self
,
reference
):
root_document
=
self
.
hateoas_navigator
.
getRootDocument
()
search_url
=
root_document
[
"_links"
][
'raw_search'
][
'href'
]
getter_link
=
expand
(
search_url
,
{
"query"
:
"reference:%s AND portal_type:Computer"
%
reference
,
"select_list"
:
[
"relative_url"
],
"limit"
:
1
})
result
=
self
.
hateoas_navigator
.
GET
(
getter_link
)
content_list
=
json
.
loads
(
result
)[
'_embedded'
][
'contents'
]
if
len
(
content_list
)
==
0
:
raise
Exception
(
'No Computer found.'
)
computer_relative_url
=
content_list
[
0
][
"relative_url"
]
def
_getConnection
(
self
,
certificate_path
,
key_path
,
url
):
api_scheme
,
api_netloc
,
api_path
,
api_query
,
api_fragment
=
urlparse
.
urlsplit
(
url
)
#self.log("HTTPS Connection with: api_scheme=%s, api_netloc=%s, api_path=%s, api_query=%s, api_fragment=%s" %(api_scheme, api_netloc, api_path, api_query, api_fragment))
self
.
log
(
"_getConnection method - api_netloc: "
+
str
(
api_netloc
))
return
httplib
.
HTTPSConnection
(
api_netloc
,
key_file
=
key_path
,
cert_file
=
certificate_path
,
timeout
=
TIMEOUT
)
getter_url
=
self
.
hateoas_navigator
.
getDocumentAndHateoas
(
computer_relative_url
)
def
_curl
(
self
,
link
):
"""
'link' must look like : {'href':url,'type':content_type}
"""
# Set timeout
import
socket
socket
.
setdefaulttimeout
(
1.0
*
TIMEOUT
)
return
json
.
loads
(
self
.
hateoas_navigator
.
GET
(
getter_url
))
api_scheme
,
api_netloc
,
api_path
,
api_query
,
api_fragment
=
urlparse
.
urlsplit
(
link
[
'href'
])
max_retry
=
10
# Try to use existing conection
try
:
self
.
log
(
"Curl to link: "
+
str
(
link
))
self
.
log
(
"GET to api "
+
str
(
api_path
))
self
.
connection
.
request
(
method
=
'GET'
,
url
=
api_path
,
body
=
""
)
self
.
log
(
"Request done. Getting response..."
)
response
=
self
.
connection
.
getresponse
()
self
.
log
(
"REPONSE.read: "
+
str
(
response
.
read
()))
return
json
.
loads
(
response
.
read
())
# Create and use new connection
except
:
self
.
log
(
"Request or response fail! Entering the while-try"
)
retry
=
0
# (re)Try several time to use new connection
while
retry
<
max_retry
:
try
:
self
.
log
(
"Retry number: "
+
str
(
retry
))
self
.
log
(
"entering _getConnection() to "
+
str
(
self
.
url
))
self
.
connection
=
self
.
_getConnection
(
self
.
certificate_path
,
self
.
key_path
,
self
.
url
)
self
.
log
(
"_getConnection DONE. Getting response..."
)
self
.
connection
.
request
(
method
=
'GET'
,
url
=
api_path
,
headers
=
{
'Accept'
:
link
[
'type'
]},
body
=
""
)
response
=
self
.
connection
.
getresponse
()
self
.
log
(
"REPONSE.read: "
+
str
(
response
.
read
()))
return
json
.
loads
(
response
.
read
())
except
Exception
,
e
:
self
.
log
(
"SlapOSMasterCommunicator: Connection failed.."
)
self
.
log
(
"EXCEPTION MESSAGE: "
+
str
(
e
))
retry
+=
1
time
.
sleep
(
10
)
self
.
log
(
"SlapOSMasterCommunicator: All connection attempts failed after %d try.."
%
max_retry
)
raise
ValueError
(
"SlapOSMasterCommunicator: Impossible to use connection"
)
@
retryOnNetworkFailure
def
getSoftwareInstallationList
(
self
):
# XXX Move me to slap.py API
computer
=
self
.
_hateoas_getComputer
(
self
.
computer_guid
)
# Not a list ?
action
=
computer
[
'_links'
][
'action_object_slap'
]
if
action
.
get
(
'title'
)
==
'getHateoasSoftwareInstallationList'
:
getter_link
=
action
[
'href'
]
else
:
raise
Exception
(
'No Link found found.'
)
result
=
self
.
hateoas_navigator
.
GET
(
getter_link
)
return
json
.
loads
(
result
)[
'_links'
][
'content'
]
@
retryOnNetworkFailure
def
getSoftwareInstallationNews
(
self
):
getter_link
=
None
for
si
in
self
.
getSoftwareInstallationList
():
if
si
[
"title"
]
==
self
.
url
:
getter_link
=
si
[
"href"
]
break
# We could not find the document, so it is probably too soon.
if
getter_link
is
None
:
return
""
result
=
self
.
hateoas_navigator
.
GET
(
getter_link
)
action_object_slap_list
=
json
.
loads
(
result
)[
'_links'
][
'action_object_slap'
]
for
action
in
action_object_slap_list
:
if
action
.
get
(
'title'
)
==
'getHateoasNews'
:
getter_link
=
action
[
'href'
]
break
else
:
raise
Exception
(
'getHateoasNews not found.'
)
result
=
self
.
hateoas_navigator
.
GET
(
getter_link
)
if
len
(
json
.
loads
(
result
)[
'news'
])
>
0
:
return
json
.
loads
(
result
)[
'news'
][
0
][
"text"
]
return
""
@
retryOnNetworkFailure
def
getInstanceUrlList
(
self
):
if
self
.
hosting_subscription_url
is
None
:
hosting_subscription_dict
=
self
.
hateoas_navigator
.
_hateoas_getHostingSubscriptionDict
()
for
hs
in
hosting_subscription_dict
:
if
hs
[
'title'
]
==
self
.
name
:
self
.
hosting_subscription_url
=
hs
[
'href'
]
break
if
self
.
hosting_subscription_url
is
None
:
return
None
return
self
.
hateoas_navigator
.
getHateoasInstanceList
(
self
.
hosting_subscription_url
)
@
retryOnNetworkFailure
def
getNewsFromInstance
(
self
,
url
):
result
=
self
.
hateoas_navigator
.
GET
(
url
)
result
=
json
.
loads
(
result
)
if
result
[
'_links'
].
get
(
'action_object_slap'
,
None
)
is
None
:
return
None
object_link
=
self
.
hateoas_navigator
.
hateoasGetLinkFromLinks
(
result
[
'_links'
][
'action_object_slap'
],
'getHateoasNews'
)
result
=
self
.
hateoas_navigator
.
GET
(
object_link
)
return
json
.
loads
(
result
)[
'news'
]
@
retryOnNetworkFailure
def
getInformationFromInstance
(
self
,
url
):
result
=
self
.
hateoas_navigator
.
GET
(
url
)
result
=
json
.
loads
(
result
)
if
result
[
'_links'
].
get
(
'action_object_slap'
,
None
)
is
None
:
print
result
[
'links'
]
return
None
object_link
=
self
.
hateoas_navigator
.
hateoasGetLinkFromLinks
(
result
[
'_links'
][
'action_object_slap'
],
'getHateoasInformation'
)
result
=
self
.
hateoas_navigator
.
GET
(
object_link
)
return
json
.
loads
(
result
)
class
SoftwareReleaseTester
(
SlapOSMasterCommunicator
):
deadline
=
None
latest_state
=
None
def
__init__
(
self
,
name
,
logger
,
slap
,
slap_order
,
slap_supply
,
url
,
# software release url
computer_guid
=
None
,
# computer for supply if desired
request_kw
=
None
,
# instance parameters, if instantiation
# testing is desired
software_timeout
=
3600
,
instance_timeout
=
3600
,
):
super
(
SoftwareReleaseTester
,
self
).
__init__
(
slap
,
slap_supply
,
slap_order
,
url
,
logger
)
self
.
name
=
name
self
.
computer_guid
=
computer_guid
if
isinstance
(
request_kw
,
str
)
or
\
isinstance
(
request_kw
,
unicode
):
self
.
request_kw
=
json
.
loads
(
request_kw
)
else
:
self
.
request_kw
=
request_kw
self
.
message_history
=
[]
self
.
state
=
TESTER_STATE_INITIAL
self
.
transition_dict
=
{
# step function
# delay
# next_state
# software_state
# instance_state
TESTER_STATE_INITIAL
:
(
lambda
t
:
None
,
None
,
TESTER_STATE_NOTHING
,
None
,
None
,
),
TESTER_STATE_NOTHING
:
(
lambda
t
:
t
.
_supply
(
"available"
),
int
(
software_timeout
),
request_kw
is
None
and
TESTER_STATE_INSTANCE_UNINSTALLED
or
\
TESTER_STATE_SOFTWARE_INSTALLED
,
SOFTWARE_STATE_INSTALLED
,
None
,
),
TESTER_STATE_SOFTWARE_INSTALLED
:
(
lambda
t
:
t
.
_request
(
"started"
),
int
(
instance_timeout
),
TESTER_STATE_INSTANCE_STARTED
,
None
,
INSTANCE_STATE_STARTED
,
),
TESTER_STATE_INSTANCE_STARTED
:
(
lambda
t
:
t
.
_request
(
"destroyed"
),
int
(
1200
),
TESTER_STATE_INSTANCE_UNINSTALLED
,
None
,
INSTANCE_STATE_STOPPED
,
),
TESTER_STATE_INSTANCE_UNINSTALLED
:
(
lambda
t
:
t
.
_supply
(
"destroyed"
),
int
(
1200
),
None
,
None
,
None
,
),
}
def
__repr__
(
self
):
deadline
=
self
.
deadline
if
deadline
is
not
None
:
deadline
-=
time
.
time
()
deadline
=
'+%is'
%
(
deadline
,
)
return
'<%s(state=%s, deadline=%s) at %x>'
%
(
self
.
__class__
.
__name__
,
self
.
state
,
deadline
,
id
(
self
))
# ROQUE: this method is a hack. This set must occur during request.
def
forceSetState
(
self
,
state
):
self
.
latest_state
=
state
def
getInfo
(
self
):
info
=
""
info
+=
"Software Release URL: %s
\
n
"
%
(
self
.
url
)
if
self
.
computer_guid
is
not
None
:
info
+=
"Supply requested on: %s
\
n
"
%
(
self
.
computer_guid
)
info
+=
"Instance Requested (Parameters): %s
\
n
"
%
self
.
request_kw
return
info
def
getFormatedLastMessage
(
self
):
if
len
(
self
.
message_history
)
==
0
:
return
"No message"
summary
=
"Summary about the test. Instance List and Status:
\
n
"
message
=
"Last information about the tester:
\
n
"
if
self
.
message_history
[
-
1
]
is
not
None
:
message_list
=
self
.
message_history
[
-
1
]
for
entry
in
message_list
:
summary
+=
"%s %s -> %s
\
n
"
%
(
entry
[
'title'
],
entry
[
"slave"
]
and
"(slave)"
or
""
,
entry
[
'state'
])
for
prop
in
entry
:
if
prop
!=
"information"
:
message
+=
"%s = %s
\
n
"
%
(
prop
,
json
.
dumps
(
entry
[
prop
],
indent
=
2
))
message
+=
"=== connection_dict ===
\
n
%s
\
n
"
%
(
json
.
dumps
(
entry
[
"information"
][
"connection_dict"
],
indent
=
2
))
message
+=
"
\
n
"
message
+=
"=== parameter_dict ===
\
n
%s
\
n
"
%
(
json
.
dumps
(
entry
[
"information"
][
"parameter_dict"
],
indent
=
2
))
message
+=
"
\
n
"
message
+=
"="
*
79
message
+=
"
\
n
\
n
\
n
"
return
summary
+
message
def
_getSoftwareState
(
self
):
if
self
.
computer_guid
is
None
:
return
SOFTWARE_STATE_INSTALLED
message
=
self
.
getSoftwareInstallationNews
()
if
message
.
startswith
(
"#error no data found"
):
return
SOFTWARE_STATE_UNKNOWN
if
message
.
startswith
(
'#access software release'
):
return
SOFTWARE_STATE_INSTALLED
if
message
.
startswith
(
'#error'
):
return
SOFTWARE_STATE_INSTALLING
return
SOFTWARE_STATE_UNKNOWN
@
retryOnNetworkFailure
def
getRSSEntryFromMonitoring
(
self
,
base_url
):
if
base_url
is
None
:
return
{}
feed_url
=
base_url
+
'/monitor-public/rssfeed.html'
d
=
feedparser
.
parse
(
feed_url
)
if
len
(
d
.
entries
)
>
0
:
return
{
"date"
:
d
.
entries
[
0
].
published
,
"message"
:
d
.
entries
[
0
].
description
,
"title"
:
d
.
entries
[
0
].
title
}
def
_update_hosting_subscription_informations
(
self
):
"""
Add all not already visited hosting_subcription
# Visit all hosting subscriptions and fill a dict containing all
# new hosting subscriptions. ( like: {hs1_title:hs1_link, hs2_title:hs2_link, ..} )
# and a list of visited hosting_subsciption ( like: [hs1_link, hs2_link, ..] )
"""
collection
=
self
.
_curl
(
self
.
personnal_collection_link
)
# For each hosting_subcription present in the collection
for
hosting_subscription_link
in
collection
[
'_links'
][
'item'
]:
if
hosting_subscription_link
not
in
self
.
visited_hosting_subcriptions_link_list
:
hosting_subscription
=
self
.
_curl
(
hosting_subscription_link
)
self
.
hosting_subcriptions_dict
.
update
({
hosting_subscription
[
'title'
]:
hosting_subscription_link
})
self
.
visited_hosting_subcriptions_link_list
.
append
(
hosting_subscription_link
)
def
_getRelatedInstanceLink
(
self
,
hosting_subscription_title
):
"""
Return a list of all related instance_url from an hosting_subscription_title
"""
# Update informations
self
.
_update_hosting_subscription_informations
()
# Get specified hosting_subscription
hosting_subscription_link
=
self
.
hosting_subcriptions_dict
[
hosting_subscription_title
]
hosting_subscription
=
self
.
_curl
(
hosting_subscription_link
)
assert
(
hosting_subscription_title
==
hosting_subscription
[
'title'
])
# Get instance collection related to this hosting_subscription
instance_collection_link
=
hosting_subscription
[
'_links'
][
'http://slapos.org/reg/instance'
]
instance_collection
=
self
.
_curl
(
instance_collection_link
)
related_instance_link_list
=
[]
# For each instance present in the collection
for
instance
in
instance_collection
[
'_links'
][
'item'
]:
related_instance_link_list
.
append
(
instance
)
return
related_instance_link_list
def
getNewsFromInstanceLink
(
self
,
instance_link
):
instance
=
self
.
_curl
(
instance_link
)
news_link
=
instance
[
'_links'
][
'http://slapos.org/reg/news'
]
return
self
.
_curl
(
news_link
)
def
isHostingSubsciptionStatusEqualTo
(
self
,
hosting_subscription_title
,
excepted_news_text
):
"""
Return True if all related instance state are equal to status,
or False if not or if there is are no related instances.
"""
related_instance_link_list
=
_getRelatedInstanceLink
(
hosting_subscription_title
)
# For each instance present in the collection
for
instance_link
in
related_instance_link_list
:
news
=
self
.
getNewsFromInstanceLink
(
instance_link
)
if
excepted_news_text
!=
news
[
'news'
][
0
][
'text'
]:
return
False
return
len
(
related_instance_link_list
)
>
0
def
isInstanceReady
(
self
,
instance_link
,
status
):
"""
Return True if instance status and instance news text ~looks corresponding.
( use the matching of 'correctly' and 'Instance' and status )
"""
# XXX: SlapOS Master doesn't store any "news" about slave instances. Assume true.
if
self
.
_curl
(
instance_link
)[
'slave'
]:
return
True
text
=
self
.
getNewsFromInstanceLink
(
instance_link
)[
'news'
][
0
][
'text'
]
return
(
'Instance'
in
text
)
and
(
'correctly'
in
text
)
and
(
status
in
text
)
# check if provided 'status' = status
def
isHostingSubscriptionReady
(
self
,
hosting_subscription_title
,
status
):
"""
Return True if all instance status and instance news text ~looks corresponding.
( use the matching of 'correctly' and 'Instance' and status ).
"""
instance_link_list
=
self
.
_getRelatedInstanceLink
(
hosting_subscription_title
)
for
instance_link
in
instance_link_list
:
if
not
self
.
isInstanceReady
(
instance_link
,
status
):
return
False
return
len
(
instance_link_list
)
>
0
return
{}
@
retryOnNetworkFailure
def
_getInstanceState
(
self
):
latest_state
=
self
.
latest_state
self
.
_logger
(
'latest_state = %r'
,
latest_state
)
if
latest_state
is
None
:
return
INSTANCE_STATE_UNKNOWN
message_list
=
[]
try
:
for
instance
in
self
.
getInstanceUrlList
():
news
=
self
.
getNewsFromInstance
(
instance
[
"href"
])
information
=
self
.
getInformationFromInstance
(
instance
[
"href"
])
state
=
INSTANCE_STATE_UNKNOWN
monitor_information_dict
=
{}
info_created_at
=
"-1"
is_slave
=
information
[
'slave'
]
if
is_slave
:
self
.
_logger
.
debug
(
'Instance is slave'
)
if
(
information
[
"connection_dict"
])
>
0
:
state
=
INSTANCE_STATE_STARTED
else
:
# not slave
instance_state
=
news
[
0
]
if
instance_state
.
get
(
'created_at'
,
'-1'
)
!=
"-1"
:
# the following does NOT take TZ into account
created_at
=
datetime
.
datetime
.
strptime
(
instance_state
[
'created_at'
],
'%a, %d %b %Y %H:%M:%S %Z'
)
gmt_now
=
datetime
.
datetime
(
*
time
.
gmtime
()[:
6
])
info_created_at
=
'%s (%d)'
%
(
instance_state
[
'created_at'
],
(
gmt_now
-
created_at
).
seconds
)
if
instance_state
[
'text'
].
startswith
(
'#access'
):
state
=
INSTANCE_STATE_STARTED
if
instance_state
[
'text'
].
startswith
(
'#access Instance correctly stopped'
):
state
=
INSTANCE_STATE_STOPPED
if
instance_state
[
'text'
].
startswith
(
'#error'
):
state
=
INSTANCE_STATE_STARTED_WITH_ERROR
if
state
==
INSTANCE_STATE_STARTED_WITH_ERROR
:
# search for monitor url
monitor_v6_url
=
information
[
"connection_dict"
].
get
(
"monitor_v6_url"
)
try
:
monitor_information_dict
=
self
.
getRSSEntryFromMonitoring
(
monitor_v6_url
)
self
.
_logger
(
"[DEBUG] monitor information dictionary: "
)
self
.
_logger
(
str
(
monitor_information_dict
))
except
Exception
:
self
.
_logger
.
exception
(
'Unable to download promises for: %s'
%
(
instance
[
"title"
]))
self
.
_logger
.
info
(
traceback
.
format_exc
())
monitor_information_dict
=
{
"message"
:
"Unable to download"
}
self
.
_logger
(
'Instance state: %s -> %s'
%
(
instance
[
'title'
],
state
))
self
.
_logger
(
'Instance Created at: %s -> %s'
%
(
instance
[
'title'
],
info_created_at
))
message_list
.
append
({
'title'
:
instance
[
"title"
],
'slave'
:
is_slave
,
'news'
:
news
[
0
],
'information'
:
information
,
'monitor'
:
monitor_information_dict
,
'state'
:
state
})
except
slapos
.
slap
.
ServerError
:
self
.
_logger
.
exception
(
'Got an error requesting partition for '
'its state'
)
return
INSTANCE_STATE_UNKNOWN
started
=
0
stopped
=
0
self
.
message_history
.
append
(
message_list
)
for
instance
in
message_list
:
if
not
instance
[
'slave'
]
and
\
instance
[
'state'
]
in
(
INSTANCE_STATE_UNKNOWN
,
INSTANCE_STATE_STARTED_WITH_ERROR
):
return
instance
[
'state'
]
elif
not
instance
[
'slave'
]
and
instance
[
'state'
]
==
INSTANCE_STATE_STARTED
:
started
=
1
elif
not
instance
[
'slave'
]
and
instance
[
'state'
]
==
INSTANCE_STATE_STOPPED
:
stopped
=
1
if
instance
[
'slave'
]
and
instance
[
'state'
]
==
INSTANCE_STATE_UNKNOWN
:
return
instance
[
'state'
]
if
started
and
stopped
:
return
INSTANCE_STATE_UNKNOWN
def
isRegisteredHostingSubscription
(
self
,
hosting_subscription_title
):
"""
Return True if the specified hosting_subscription is present on SlapOSMaster
"""
self
.
_update_hosting_subscription_informations
()
if
self
.
hosting_subcriptions_dict
.
get
(
hosting_subscription_title
):
return
True
return
False
if
started
:
return
INSTANCE_STATE_STARTED
def
getHostingSubscriptionDict
(
self
):
if
stopped
:
return
INSTANCE_STATE_STOPPED
@
retryOnNetworkFailure
def
teardown
(
self
):
"""
Return the dict of hosting subcription
.
Interrupt a running test sequence, putting it in idle state
.
"""
return
self
.
hosting_subcriptions_dict
self
.
_logger
.
info
(
'Invoking TearDown for %s@%s'
%
(
self
.
url
,
self
.
name
))
if
self
.
request_kw
is
not
None
:
self
.
_request
(
'destroyed'
)
if
self
.
computer_guid
is
not
None
:
self
.
_supply
(
'destroyed'
)
self
.
state
=
TESTER_STATE_INSTANCE_UNINSTALLED
def
getHostingSubscriptionInformationDict
(
self
,
title
):
def
tic
(
self
,
now
):
"""
Return a dict with informations about Hosting subscription
Check for missed deadlines (-> test failure), conditions for moving to
next state, and actually moving to next state (executing its payload).
"""
related_instance_link_list
=
self
.
_getRelatedInstanceLink
(
title
)
related_instance_link
=
None
# Get root instance
for
link
in
related_instance_link_list
:
instance
=
self
.
_curl
(
link
)
if
title
==
instance
[
'title'
]:
related_instance_link
=
link
break
# Return information dict
if
related_instance_link
:
related_instance
=
self
.
_curl
(
related_instance_link
)
return
{
'title'
:
related_instance
[
'title'
],
'status'
:
related_instance
[
'status'
],
'software_url'
:
related_instance
[
'_links'
][
'http://slapos.org/reg/release'
],
'software_type'
:
related_instance
[
'software_type'
],
'computer_guid'
:
related_instance
[
'sla'
][
'computer_guid'
]
}
else
:
return
None
self
.
_logger
.
debug
(
'TIC'
)
deadline
=
self
.
deadline
if
deadline
<
now
and
deadline
is
not
None
:
raise
TestTimeout
(
self
.
state
)
_
,
_
,
next_state
,
software_state
,
instance_state
=
self
.
transition_dict
[
self
.
state
]
if
(
software_state
is
None
or
software_state
==
self
.
_getSoftwareState
())
and
(
instance_state
is
None
or
instance_state
==
self
.
_getInstanceState
()):
self
.
_logger
.
debug
(
'Going to state %s (%r)'
,
next_state
,
instance_state
)
if
next_state
is
None
:
return
None
self
.
state
=
next_state
stepfunc
,
delay
,
_
,
_
,
_
=
self
.
transition_dict
[
next_state
]
self
.
deadline
=
now
+
delay
stepfunc
(
self
)
return
self
.
deadline
erp5/util/testnode/testnode.py
View file @
c8d33446
...
...
@@ -65,6 +65,7 @@ class TestNode(object):
max_temp_time
=
MAX_TEMP_TIME
):
self
.
testnode_log
=
log
self
.
log
=
log
self
.
log
(
"Config parameter in TestNode.init(): "
+
str
(
config
))
self
.
config
=
config
or
{}
self
.
process_manager
=
ProcessManager
(
log
)
self
.
working_directory
=
config
[
'working_directory'
]
...
...
@@ -405,9 +406,14 @@ shared = true
node_test_suite
.
edit
(
test_result
=
test_result
)
# get cluster configuration for this test suite, this is needed to
# know slapos parameters to user for creating instances
node_test_suite
.
edit
(
cluster_configuration
=
Utils
.
deunicodeData
(
json
.
loads
(
self
.
test_suite_portal
.
generateConfiguration
(
node_test_suite
.
test_suite_title
))[
'configuration_list'
][
0
]))
log
(
"Getting configuration from test suite "
+
str
(
node_test_suite
.
test_suite_title
))
generated_config
=
self
.
test_suite_portal
.
generateConfiguration
(
node_test_suite
.
test_suite_title
)
log
(
"Generated configuration: "
+
str
(
generated_config
))
jsonData
=
json
.
loads
(
generated_config
)
cluster_configuration
=
Utils
.
deunicodeData
(
jsonData
[
'configuration_list'
][
0
])
node_test_suite
.
edit
(
cluster_configuration
=
cluster_configuration
)
# Now prepare the installation of SlapOS and create instance
status_dict
=
runner
.
prepareSlapOSForTestSuite
(
node_test_suite
)
# Give some time so computer partitions may start
...
...
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