############################################################################## # Copyright (c) 2013 Nexedi SA and Contributors. All Rights Reserved. # Sebastien Robin <seb@nexedi.com> # # WARNING: This program as such is intended to be used by professional # programmers who take the whole responsibility of assessing all potential # consequences resulting from its eventual inadequacies and bugs # End users who are looking for a ready-to-use solution with commercial # guarantees and support are strongly advised to contract a Free Software # Service Company # # This program is Free Software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. # ############################################################################## from Products.ERP5.Document.ERP5ProjectUnitTestDistributor import ERP5ProjectUnitTestDistributor import string import erp5.util.taskdistribution from Products.ERP5Type.Log import log from AccessControl import ClassSecurityInfo from Products.ERP5Type import Permissions import json import random from Products.ERP5.Tool.TaskDistributionTool import TaskDistributionTool class ERP5ScalabilityDistributor(ERP5ProjectUnitTestDistributor): security = ClassSecurityInfo() security.declareObjectProtected(Permissions.AccessContentsInformation) security.declareProtected(Permissions.ManagePortal, "optimizeConfiguration") def optimizeConfiguration(self): """ Do master testnode selection and associate testsuites. """ # Get modules portal = self.getPortalObject() test_node_module = self._getTestNodeModule() test_suite_module = self._getTestSuiteModule() # Get lists of test node wich belong to the current distributor all_test_node_list = test_node_module.searchFolder( portal_type="Test Node", specialise_uid=self.getUid()) test_node_list = [ x.getObject() for x in all_test_node_list if x.getValidationState() == 'validated' ] invalid_test_node_list = [ x.getObject() for x in all_test_node_list if x.getValidationState() != 'validated' ] # Set master property to False for all invalid testnode for node in invalid_test_node_list: node.setMaster(False) # Get all valid slave testnodes slave_test_node_list = [ x.getObject() for x in test_node_list if x.getMaster()!=True ] master_test_node_list = [ x.getObject() for x in test_node_list if x.getMaster()==True ] # Set to 'False' slaves for node in slave_test_node_list: node.setMaster(False) # if there is validated testnodes if len(test_node_list) > 0: # Only one testnode must be the master # if there is no or more than 1 master if len(master_test_node_list) != 1: # No master: elect the first testnode as master if len(master_test_node_list) == 0: test_node_list[0].setMaster(True) else: # Too many master: keep as master only the the first of list for node in master_test_node_list[1:]: node.setMaster(False) # Update testnode lists slave_test_node_list = [ x.getObject() for x in test_node_list if x.getMaster()!=True ] master_test_node_list = [ x.getObject() for x in test_node_list if x.getMaster()==True ] # Get test suites and aggregate them to all valid testnode test_suite_list = [ x.getRelativeUrl() for x in test_suite_module.searchFolder( portal_type="Scalability Test Suite", validation_state="validated", specialise_uid=self.getUid())] for test_node in test_node_list: test_node.setAggregateList(test_suite_list) security.declarePublic("getInvolvedNodeList") def getInvolvedNodeList(self): """ getInvolvedNodeList doc """ test_node_module = self._getTestNodeModule() distributor_title = self.getTitle() involved_nodes = [] involved_nodes = involved_nodes + [ x.getObject() for x in test_node_module.searchFolder(validation_state='validated') if ( x.getSpecialiseTitle() == distributor_title ) ] return involved_nodes security.declarePublic("getTestNode") def getTestNode(self,title,batch_mode=0): """ getTestNode doc """ test_node_module = self._getTestNodeModule() portal = self.getPortalObject() tag = "%s_%s" % (self.getRelativeUrl(), title) if portal.portal_activities.countMessageWithTag(tag) == 0: test_node_list = test_node_module.searchFolder(portal_type="Test Node",title=title) assert len(test_node_list) in (0, 1), "Unable to find testnode : %s" % title test_node = None if len(test_node_list) == 1: test_node = test_node_list[0].getObject() if test_node.getValidationState() != 'validated': try: test_node.validate() except e: LOG('Test Node Validate',ERROR,'%s' %e) return test_node return None security.declarePublic("isMasterTestnode") def isMasterTestnode(self,title, batch_mode=0): """ isMasterTestnode : return True if the node given in parameter exists and is a validated master """ test_node_module = self._getTestNodeModule() test_node_master = [ node for node in test_node_module.searchFolder(portal_type="Test Node", title=title, specialise=self.getRelativeUrl(), validation_state="validated") if node.getMaster() == 1 ] if len(test_node_master) == 1: return True else: return False security.declarePublic("getTestType") def getTestType(self, batch_mode=0): """ getTestType : return a string defining the type of tests """ return 'ScalabilityTest' security.declarePublic("startTestSuite") def startTestSuite(self,title, computer_guid='unknown', batch_mode=0): """ startTestSuite : subscribe node + return testsuite list to the master """ config_list = [] super(ERP5ScalabilityDistributor, self).subscribeNode(title=title, computer_guid=computer_guid, batch_mode=batch_mode) test_node = self.getTestNode(title,batch_mode) test_suite_module = self._getTestSuiteModule() test_node_module = self._getTestNodeModule() portal = self.getPortalObject() # If the testnode wich request testsuites is not the master # he does not have to receive any testsuites master_test_node_title_list = [x.getTitle() for x in test_node_module.searchFolder( validatation_state = 'validated') if (x.getMaster() == True) ] if len(master_test_node_title_list) == 1 and title == master_test_node_title_list[0]: return super(ERP5ScalabilityDistributor, self).startTestSuite(title=title, batch_mode=batch_mode, computer_guid=computer_guid) else: if batch_mode: return [] return json.dumps([]) security.declarePublic("generateConfiguration") def generateConfiguration(self, test_suite_title, batch_mode=0): """ generateConfiguration : this is just a proxy to an external method """ generated_configuration = self.ScalabilityTestSuiteUtils_generateConfigurationList(self, test_suite_title) if batch_mode: return generated_configuration return json.dumps(generated_configuration) def getRunningTestCase(self, test_result_path, batch_mode=0): """ getRunningTestCase : return informations about the running test case, if no running test_case, return None """ portal = self.getPortalObject() test_result = portal.restrictedTraverse(test_result_path) test_result_lines = test_result.objectValues(portal_type="Test Result Line", sort_on='int_index') count = 0 for test_result_line in test_result_lines: count += 1 state = test_result_line.getSimulationState() if state == "started": relative_path = test_result_line.getRelativeUrl() title = test_result_line.getTitle() break; else: return None next_test = {"relative_path": relative_path, "title": title, "count" : count, } if batch_mode: return next_test return json.dumps(next_test) security.declarePublic("isTestCaseAlive") def isTestCaseAlive(self, test_result_line_path, batch_mode=0): """ Is a test result line alive or not. """ portal = self.getPortalObject() test_result_line = portal.restrictedTraverse(test_result_line_path) return test_result_line.getSimulationState() == "started"