Commit 2b4a5b6b authored by Benjamin Blanc's avatar Benjamin Blanc

testnode: SlapOSMasterCommunicator: Correct bugs and accelerate connections.

parent b03d9784
......@@ -502,6 +502,8 @@ revision = %(revision2)s
return (grade == 'master')
def patch_isHostingSubscriptionCorrectly(self, *args, **kw):
return True
def patch_isRegisteredHostingSubscription(self, *args, **kw):
return True
test_self = self
test_result_path_root = os.path.join(test_self._temp_dir,'test/results')
os.makedirs(test_result_path_root)
......@@ -568,6 +570,7 @@ revision = %(revision2)s
original_isMasterTestnode = TaskDistributor.isMasterTestnode
original_updateInstanceXML = RunnerClass._updateInstanceXML
original_isHostingSubscriptionCorrectly = SlapOSMasterCommunicator.isHostingSubscriptionCorrectly
original_isRegisteredHostingSubscription = SlapOSMasterCommunicator.isRegisteredHostingSubscription
original_SlapOSMasterCommunicator__init__ = SlapOSMasterCommunicator.__init__
TaskDistributor.getSlaposAccountKey = patch_getSlaposAccountKey
TaskDistributor.getSlaposAccountCertificate = patch_getSlaposAccountCertificate
......@@ -575,6 +578,7 @@ revision = %(revision2)s
TaskDistributor.isMasterTestnode = patch_isMasterTestnode
RunnerClass._updateInstanceXML = doNothing
SlapOSMasterCommunicator.isHostingSubscriptionCorrectly = patch_isHostingSubscriptionCorrectly
SlapOSMasterCommunicator.isRegisteredHostingSubscription = patch_isRegisteredHostingSubscription
SlapOSMasterCommunicator.__init__ = doNothing
original_startTestSuite = TaskDistributor.startTestSuite
original_subscribeNode = TaskDistributor.subscribeNode
......@@ -605,6 +609,7 @@ revision = %(revision2)s
TaskDistributor.isMasterTestnode = original_isMasterTestnode
RunnerClass._updateInstanceXML = original_updateInstanceXML
SlapOSMasterCommunicator.isHostingSubscriptionCorrectly = original_isHostingSubscriptionCorrectly
SlapOSMasterCommunicator.isRegisteredHostingSubscription = original_isRegisteredHostingSubscription
SlapOSMasterCommunicator.__init__ = original_SlapOSMasterCommunicator__init__
TaskDistributor.startTestSuite = original_startTestSuite
TaskDistributionTool.createTestResult = original_createTestResult
......@@ -668,6 +673,8 @@ revision = %(revision2)s
return grade == 'master'
def patch_isHostingSubscriptionCorrectly(self, *args, **kw):
return True
def patch_isRegisteredHostingSubscription(self, *args, **kw):
return True
test_self = self
test_result_path_root = os.path.join(test_self._temp_dir,'test/results')
os.makedirs(test_result_path_root)
......@@ -722,6 +729,7 @@ revision = %(revision2)s
original_request = SlapOSControler.request
original_updateInstanceXML = RunnerClass._updateInstanceXML
original_isHostingSubscriptionCorrectly = SlapOSMasterCommunicator.isHostingSubscriptionCorrectly
original_isRegisteredHostingSubscription = SlapOSMasterCommunicator.isRegisteredHostingSubscription
original_SlapOSMasterCommunicator__init__ = SlapOSMasterCommunicator.__init__
TaskDistributor.getSlaposAccountKey = patch_getSlaposAccountKey
TaskDistributor.getSlaposAccountCertificate = patch_getSlaposAccountCertificate
......@@ -731,6 +739,7 @@ revision = %(revision2)s
SlapOSControler.request = doNothing
RunnerClass._updateInstanceXML = doNothing
SlapOSMasterCommunicator.isHostingSubscriptionCorrectly = patch_isHostingSubscriptionCorrectly
SlapOSMasterCommunicator.isRegisteredHostingSubscription = patch_isRegisteredHostingSubscription
SlapOSMasterCommunicator.__init__ = doNothing
original_startTestSuite = TaskDistributor.startTestSuite
original_subscribeNode = TaskDistributor.subscribeNode
......@@ -761,6 +770,7 @@ revision = %(revision2)s
SlapOSControler.request = original_request
SlapOSControler.updateInstanceXML = original_updateInstanceXML
SlapOSMasterCommunicator.isHostingSubscriptionCorrectly = original_isHostingSubscriptionCorrectly
SlapOSMasterCommunicator.isRegisteredHostingSubscription = original_isRegisteredHostingSubscription
SlapOSMasterCommunicator.__init__ = original_SlapOSMasterCommunicator__init__
TaskDistributor.startTestSuite = original_startTestSuite
TaskDistributionTool.createTestResult = original_createTestResult
......@@ -938,6 +948,8 @@ revision = %(revision2)s
return "ScalabilityTest"
def patch_isHostingSubscriptionCorrectly(self, *args, **kw):
return True
def patch_isRegisteredHostingSubscription(self, *args, **kw):
return True
test_self = self
test_result_path_root = os.path.join(test_self._temp_dir,'test/results')
os.makedirs(test_result_path_root)
......@@ -960,6 +972,7 @@ revision = %(revision2)s
original_request = SlapOSControler.request
original_updateInstanceXML = SlapOSControler.updateInstanceXML
original_isHostingSubscriptionCorrectly = SlapOSMasterCommunicator.isHostingSubscriptionCorrectly
original_isRegisteredHostingSubscription = SlapOSMasterCommunicator.isRegisteredHostingSubscription
original_SlapOSMasterCommunicator__init__ = SlapOSMasterCommunicator.__init__
#
......@@ -978,6 +991,7 @@ revision = %(revision2)s
SlapOSControler.request = doNothing
SlapOSControler.updateInstanceXML = doNothing
SlapOSMasterCommunicator.isHostingSubscriptionCorrectly = patch_isHostingSubscriptionCorrectly
SlapOSMasterCommunicator.isRegisteredHostingSubscription = patch_isRegisteredHostingSubscription
SlapOSMasterCommunicator.__init__ = doNothing
# Run
test_node = self.getTestNode()
......@@ -997,5 +1011,6 @@ revision = %(revision2)s
SlapOSControler.request = original_request
SlapOSControler.updateInstanceXML = original_updateInstanceXML
SlapOSMasterCommunicator.isHostingSubscriptionCorrectly = original_isHostingSubscriptionCorrectly
SlapOSMasterCommunicator.isRegisteredHostingSubscription = original_isRegisteredHostingSubscription
SlapOSMasterCommunicator.__init__ = original_SlapOSMasterCommunicator__init__
time.sleep =original_sleep
......@@ -47,6 +47,7 @@ from erp5.util import taskdistribution
import signal
MAX_INSTANCE_TIME = 60*60 # 1 hour
MAX_CREATION_INSTANCE_TIME = 60*5 # 5 minutes
class ScalabilityTestRunner():
def __init__(self, testnode):
......@@ -176,14 +177,7 @@ late a SlapOS (positive) answer." %(str(os.getpid()),str(os.getpid()),))
# TODO : implement -> communication with SlapOS master
# this simulate a SlapOS answer
return self.simulateSlapOSAnswer()
def isInstanceReady(self, instance_title, state):
"""
Return true if the specified instance is ready.
This method should communicates with SlapOS Master.
"""
return self.slapos_communicator.isHostingSubscriptionCorrectly(instance_title, state)
def remainSoftwareToInstall(self):
"""
Return True if it remains softwares to install, otherwise return False
......@@ -207,16 +201,31 @@ late a SlapOS (positive) answer." %(str(os.getpid()),str(os.getpid()),))
self.slapos_controler.updateInstanceXML(instance_title, {"_" : config})
return {'status_code' : 0}
# Used to simulate slapOS answer
def _waitInstance(self, instance_title, state):
def _waitInstance(self, instance_title, state, max_time=MAX_INSTANCE_TIME):
"""
Wait for 'max_time' an instance specific state
"""
self.log("Wait for instance state: %s" %state)
#TODO: add a time limit
max_time = MAX_INSTANCE_TIME
start_time = 0
while (not self.isInstanceReady(instance_title, state)
start_time = time.time()
while (not self.slapos_communicator.isHostingSubscriptionCorrectly(instance_title, state)
and (max_time > (time.time()-start_time))):
time.sleep(15)
if (time.time()-start_time) > max_time:
raise ErrorValue("Instance '%s' not '%s' after %s seconds" %(title, state))
self.log("Instance correctly '%s' after %s seconds." %(state, str(time.time()-start_time)))
def _waitInstanceCreation(self, title, max_time=MAX_CREATION_INSTANCE_TIME):
"""
Wait for 'max_time' the instance creation
"""
self.log("Wait for instance creation")
start_time = time.time()
while ( not self.slapos_communicator.isRegisteredHostingSubscription(title) \
and (max_time > (time.time()-start_time)) ):
time.sleep(5)
if (time.time()-start_time) > max_time:
raise ErrorValue("Instance '%s' not found after %s seconds" %(title, max_time))
self.log("Instance found on slapOSMaster")
def prepareSlapOSForTestSuite(self, node_test_suite):
"""
......@@ -303,9 +312,9 @@ late a SlapOS (positive) answer." %(str(os.getpid()),str(os.getpid()),))
self.instance_title = self._generateInstancetitle(node_test_suite.test_suite_title)
self._createInstance(self.reachable_profile, configuration_list[0],
self.instance_title, node_test_suite.test_result, node_test_suite.test_suite)
self.log("Waiting for instance creation..")
self._waitInstance(self.instance_title, 'started')
self.log("Scalability instance requested")
self.log("Waiting for instance creation..")
self._waitInstanceCreation(self.instance_title)
""" except:
self.log("Unable to launch instance")
raise ValueError("Unable to launch instance")
......@@ -330,17 +339,15 @@ late a SlapOS (positive) answer." %(str(os.getpid()),str(os.getpid()),))
count = 0
for configuration in configuration_list:
# Stop instance
self.log("Instance state: %s", self.slapos_controler.getInstanceState(self.instance_title))
self.slapos_controler.stopInstance(self.instance_title)
self._waitInstance(self.instance_title, 'stopped')
# Update instance XML configuration
self.log("Instance state: %s", self.slapos_controler.getInstanceState(self.instance_title))
self._updateInstanceXML(configuration, self.instance_title,
if count > 0:
self.slapos_controler.stopInstance(self.instance_title)
self._waitInstance(self.instance_title, 'stopped')
# 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')
# Start instance
self.log("Instance state: %s", self.slapos_controler.getInstanceState(self.instance_title))
self.slapos_controler.startInstance(self.instance_title)
self._waitInstance(self.instance_title, 'started')
# Start instance
self.slapos_controler.startInstance(self.instance_title)
self._waitInstance(self.instance_title, 'started')
# Start only the current test
......@@ -387,9 +394,7 @@ late a SlapOS (positive) answer." %(str(os.getpid()),str(os.getpid()),))
error = ValueError("Test case is in an undeterminated state")
break;
self.slapos_controler.destroyInstance(self.instance_title)
if error:
test_result_proxy.fail()
......
......@@ -136,13 +136,6 @@ class SlapOSControler(object):
except:
raise ValueError("Instance '%s' not exist" %self.instance_config[reference])
def getInstanceState(self, reference):
try:
return self.instance_config[reference]['partition'].getState()
except:
raise ValueError("Impossible to get the instance state, instance "
"'%s' may not exist" %self.instance_config[reference])
def request(self, reference, software_url, software_type=None,
software_configuration=None, computer_guid=None, state='started'):
"""
......
import json
import httplib
import urlparse
import time
# TODO: News-> look list to get last news... (and not the first of the list)
......@@ -25,15 +26,16 @@ class SlapOSMasterCommunicator(object):
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.log("HTTPS Connection with: %s, cert=%s, key=%s" %(api_netloc,key_path,certificate_path))
self.connection = httplib.HTTPSConnection(api_netloc, key_file=key_path, cert_file=certificate_path)
self.certificate_path = certificate_path
self.key_path = key_path
self.url = url
self.connection = self._getConnection(self.certificate_path, self.key_path, self.url)
# Get master
master_link = {'href':api_path,'type':"application/vnd.slapos.org.hal+json; class=slapos.org.master"}
master = self._curl(master_link)
......@@ -50,6 +52,11 @@ class SlapOSMasterCommunicator(object):
self.log("SlapOSMasterCommunicator will read all hosting subscriptions entries, "
"it may take several time...")
self._update_hosting_subscription_informations()
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: %s, cert=%s, key=%s" %(api_netloc,key_path,certificate_path))
return httplib.HTTPSConnection(api_netloc, key_file=key_path, cert_file=certificate_path)
def _curl(self, link):
"""
......@@ -57,13 +64,18 @@ class SlapOSMasterCommunicator(object):
"""
self.log("_curl with: url:%s content_type:%s" %(link['href'], link['type']))
api_scheme, api_netloc, api_path, api_query, api_fragment = urlparse.urlsplit(link['href'])
self.connection.request(
method='GET',
url=api_path,
headers={'Accept': link['type']},
body=""
)
response = self.connection.getresponse()
# Try to use existing conection
try:
self.connection.request(method='GET', url=api_path, headers={'Accept': link['type']}, body="")
response = self.connection.getresponse()
except:
try:
# Try to update and use the connection
self.connection = self._getConnection(self.certificate_path, self.key_path, self.url)
self.connection.request(method='GET', url=api_path, headers={'Accept': link['type']}, body="")
response = self.connection.getresponse()
except:
raise ValueError("Impossible to use connection")
return json.loads(response.read())
def _update_hosting_subscription_informations(self):
......@@ -77,8 +89,8 @@ class SlapOSMasterCommunicator(object):
# 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:
title = self._curl(hosting_subscription_link)['title']
self.hosting_subcriptions_dict.update({title:hosting_subscription_link})
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):
......@@ -160,8 +172,16 @@ class SlapOSMasterCommunicator(object):
"""
instance_link_list = self._getRelatedInstanceLink(hosting_subscription_title)
for instance_link in instance_link_list:
if not communicator.isInstanceCorrectly(instance_link, status):
if not self.isInstanceCorrectly(instance_link, status):
return False
return len(instance_link_list) > 0
\ No newline at end of file
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
\ No newline at end of file
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment