TestCenter Reference
Slave.py
Go to the documentation of this file.
1 #
2 # Copyright 2007, MeVis Medical Solutions AG
3 #
4 # The user may use this file in accordance with the license agreement provided with
5 # the Software or, alternatively, in accordance with the terms contained in a
6 # written agreement between the user and MeVis Medical Solutions AG.
7 #
8 # For further information use the contact form at https://www.mevislab.de/contact
9 #
10 
11 
13 
14 # -- system imports ----------------------------------------------------------------------------{{{-
15 import os
16 import re
17 import traceback
18 
19 import sys
20 if sys.version_info.major >= 3:
21  unicode = str
22 
23 import xml.etree.cElementTree as etree
24 # ----------------------------------------------------------------------------------------------}}}-
25 
26 # -- local imports -----------------------------------------------------------------------------{{{-
27 import mevis
28 import PackageSorter
29 
30 from . import IPC
31 from . import Config
32 from . import Utils
33 from .LogHandler import LogHandler
34 from TestSupport.TestHelper import TestHelper
35 
36 from .TestCaseGeneric import GenericTestCase
37 from .TestCaseFunctional import FunctionalTestCase
38 import TestSupport
39 
40 from . import CodeCoverage
41 from .CodeTestSupport import getCodeTest, getCodeTestsByPackage, CodeTestTestCase
42 
43 # ----------------------------------------------------------------------------------------------}}}-
44 
45 # Determine if the Public SDK FME modules are available:
46 _isPublicSDK = bool(mevis.MLABPackageManager.packagesByGroup('FMEstable') and mevis.MLABPackageManager.packagesByGroup('FMEwork'))
47 
48 # ----------------------------------------------------------------------------------------------}}}-
50 
51  def __init__(self, com):
52  self.stoppedstopped = False
53  self.__com__com = com
54 
55  def startTestCaseFunction(self, testType, testCase, testFunction):
56  resultNode = etree.Element("Progress")
57  resultNode.set("testType", testType)
58  resultNode.set("testCase", testCase)
59  resultNode.set("testFunction", testFunction)
60  if not self.__com__com.send(etree.tostring(resultNode), 5):
61  mevis.MLAB.logError("Couldn't send progress")
63  # receive the result, if it is "0", we are supposed to stop,
64  # otherwise we can continue
65  result = self.__com__com.recv(5)
66  if result=="0":
68 
69  def endTestCaseFunction(self, status, duration):
70  resultNode = etree.Element("Status")
71  resultNode.set("status", str(status))
72  if not self.__com__com.send(etree.tostring(resultNode), 5):
73  mevis.MLAB.logError("Couldn't send status")
75 
76 # -- class Slave -------------------------------------------------------------------------------{{{-
77 
79 class Slave (object):
80  # -- member variables ------------------------------------------------------------------------{{{-
81 
82  __ctx = None
83 
84  __com = None
85 
86 
87  __testCase = None
88 
89 
90  __running = None
91 
92 
93  __testCfg = None
94  # --------------------------------------------------------------------------------------------}}}-
95 
96  # -- def __init__ ----------------------------------------------------------------------------{{{-
97 
103  def __init__ (self, cfgFile, context, offline=False):
104  self.__ctx__ctx = context
105  self.__com__com = IPC.ComSlave() if not offline else None
106 
107  self.__testCaseListener__testCaseListener = None
108  self.__agendaTestCase__agendaTestCase = None
109  self.__isInsideTestCaseManager__isInsideTestCaseManager = False
110 
111  # The current configuration
112  self._config_config = Config.Configuration(cfgFile)
113 
114  # Create result directory if not available.
115  resultDir = self._config_config.getResultDir()
116  if not os.path.isdir(resultDir):
117  os.makedirs(resultDir)
118 
119  # Set new logfile to use. This is required as there could be multiple
120  # MeVisLab instances writing to the same logfile what would make crash
121  # handling impossible.
122  self.__logfile__logfile = self._config_config.getSlaveLogFilePath()
123 
124  # Load test cases if not done already.
125  if not mevis.MLABTestCaseDatabase.areTestCasesLoaded():
126  mevis.MLABTestCaseDatabase.loadTestCases()
127 
128  # Initialize the test helper singleton.
129  TestHelper.getInstance(context=self.__ctx__ctx, resultDir=self._config_config.getResultDir())
130  # --------------------------------------------------------------------------------------------}}}-
131 
132  def setIsInsideTestCaseManager(self, isInsideTestCaseManager):
133  self.__isInsideTestCaseManager__isInsideTestCaseManager = isInsideTestCaseManager
134 
135  def setTestCaseListener(self, listener):
136  self.__testCaseListener__testCaseListener = listener
137 
138  # -- def loadTestCase ------------------------------------------------------------------------{{{-
139 
144  def loadTestCase (self, testCaseNode):
145  testType = testCaseNode.get('type')
146  moduleName = testCaseNode.get('module') if testType == "GenericTestCase" else None
147  return self.__loadTestCase__loadTestCase(testCaseNode.get('name'), testType, moduleName)
148  # --------------------------------------------------------------------------------------------}}}-
149 
150  # -- def __loadTestCase ----------------------------------------------------------------------{{{-
151 
157  def __loadTestCase (self, testCaseName, testCaseType, moduleName=None):
158  # Create test case depending on the type.
159  if testCaseType == 'GenericTestCase':
160  testCase = GenericTestCase(testCaseName, moduleName)
161  elif testCaseType == 'FunctionalTestCase':
162  testCase = FunctionalTestCase(testCaseName)
163  elif testCaseType == 'CodeTestTestCase':
164  testCase = CodeTestTestCase(testCaseName)
165  else:
166  raise Exception('Unsupported test case type %s' % testCaseType)
167  return testCase
168  # --------------------------------------------------------------------------------------------}}}-
169 
170  # -- def setAgendaTestCase -------------------------------------------------------------------------{{{-
171 
174  def setAgendaTestCase (self, testCase):
175  self.__agendaTestCase__agendaTestCase = testCase
176  # --------------------------------------------------------------------------------------------}}}-
177 
178  # -- def getTestCase -------------------------------------------------------------------------{{{-
179 
182  def getTestCase ( self ):
183  return self.__testCase__testCase
184  # --------------------------------------------------------------------------------------------}}}-
185 
186  # -- def unloadTestCase -------------------------------------------------------------------------{{{-
187 
188  def unloadTestCase ( self ):
189  self.__testCase__testCase = None
190  # --------------------------------------------------------------------------------------------}}}-
191 
192  # -- def __doTest ----------------------------------------------------------------------------{{{-
193 
197 
198  def __doTest (self,
199  testCaseNode,
200  resultNode):
201 
202  try:
203  maxErrorMessagesPerTestFunction = int(testCaseNode.get("maxErrorMessagesPerTestFunction"))
204  except:
205  maxErrorMessagesPerTestFunction = 10000
206  try:
207  maxInfoMessagesPerTestFunction = int(testCaseNode.get("maxInfoMessagesPerTestFunction"))
208  except:
209  maxInfoMessagesPerTestFunction = 10000
210 
211  # clear encoding cache for each test to prevent it from containing outdated encoding data
213 
214  #start coverage right in front of loading, since some code parts are only
215  #traversed during the loading phase of a test case. Those
216  #are mainly function definitions etc.
217  try:
218  pythonCoverage = CodeCoverage.PythonCoverage(config=self._config_config,
219  testCaseNode=testCaseNode)
220  except CodeCoverage.CoverageException as e:
221  pythonCoverage = None
222  mevis.MLAB.logError(e)
223 
224  try:
225  bullseyeCoverage = CodeCoverage.BullseyeCoverage(config=self._config_config,
226  testCaseNode=testCaseNode)
227  except CodeCoverage.CoverageException as e:
228  bullseyeCoverage = None
229  mevis.MLAB.logError(e)
230 
231  self.__testCase__testCase = self.loadTestCaseloadTestCase(testCaseNode)
232 
233  # Run the test case only if it loaded correctly.
234  if self.__testCase__testCase:
235  # Do NOT run test, when status is TEST_STATUS_DO_NOT_TEST_MODULE. Only relevant for GenericTests
236  if not testCaseNode.get("status") == Utils.TEST_STATUS_DO_NOT_TEST_MODULE:
237  if pythonCoverage and pythonCoverage.isRunning():
238  #store the target file in a subNode so the HTML creation process knows there
239  #were coverage results for this test.
240  resultNode.set('pythonCoverage', pythonCoverage.getCoverageBinaryFilePath())
241 
242  if bullseyeCoverage and bullseyeCoverage.isRunning():
243  #store the target file in a subNode so the HTML creation process knows there
244  #were coverage results for this test.
245  resultNode.set('bullseyeCoverage', bullseyeCoverage.getCoverageBinaryFilePath())
246 
247  logHandler = LogHandler(self.__logfile__logfile)
248  logHandler.setErrorLimit(maxErrorMessagesPerTestFunction)
249  logHandler.setInfoLimit(maxInfoMessagesPerTestFunction)
250  TestHelper.getInstance().setLogHandler(logHandler)
251 
252  mevis.MLAB.priv().connect("loggingMessage(const QString&)", logHandler.appendMessage)
253  mevis.MLAB.priv().aboutToLogMessage.connect(logHandler.aboutToLogMessage)
254  mevis.MLAB.priv().startLogCollect()
255  self.__testCase__testCase.setTestCaseListener(self.__testCaseListener__testCaseListener)
256  self.__testCase__testCase.run(testCaseNode)
257 
258  mevis.MLAB.priv().stopLogCollect()
259  mevis.MLAB.priv().disconnect("loggingMessage(const QString&)", logHandler.appendMessage)
260  mevis.MLAB.priv().aboutToLogMessage.disconnect(logHandler.aboutToLogMessage)
261 
262  TestHelper.getInstance().unsetLogHandler()
263  logHandler.close()
264 
265  resultNode.set('errorCode', 'Ok')
266  # Append results to the resultNode.
267  resultNode.append(testCaseNode)
268  else:
269  resultNode.set('errorCode', 'TestCaseError')
270  etree.SubElement(resultNode, 'Error').text = "Unknown test case (%s)." % (testCaseNode.get('name'))
271 
272  if pythonCoverage:
273  pythonCoverage.stop()
274 
275  if bullseyeCoverage:
276  try:
277  bullseyeCoverage.stop()
278  except CodeCoverage.CoverageException as e:
279  mevis.MLAB.logError(e)
280 
281  # --------------------------------------------------------------------------------------------}}}-
282 
283  # -- def __buildTestAgenda -------------------------------------------------------------------{{{-
284 
289  def __buildTestAgenda (self, testCfg, resultNode):
290 
291  def ___addPackageInfoNode( rootNode ):
292  packageInfoNode = etree.SubElement( rootNode, 'PackageSortingInReport')
293  packageInfoNode.set( 'PackagesByNumberOfDependencies', ",".join( PackageSorter.byNumberOfDependencies.packages ) )
294  packageInfoNode.set( 'PackageGroupsByNumberOfDependencies', ",".join( PackageSorter.byNumberOfDependencies.packageGroups ) )
295 
296  testRunNode = etree.Element('TestRun')
297 
298  # An internal data structure with easier access than the XML structure.
299  self.__testCfg__testCfg = { 'Packages': { 'Tested': [], 'Available': [] },
300  'TestGroups': [],
301  'TestSuites': [],
302  'Modules': [] }
303 
304  # Consolidate the information on the packages available.
305  self.__verifyPackages__verifyPackages(testCfg)
306 
307  # Get information on the test groups selected.
308  for testGroupNode in testCfg.findall('TestGroups/TestGroup'):
309  self.__testCfg__testCfg['TestGroups'].append(testGroupNode.get('name'))
310 
311  # Add the test cases from given test suites to the TestCases node
312  for testSuiteNode in testCfg.findall('TestSuites/TestSuite'):
313  testSuite = testSuiteNode.get('name')
314  testCaseNames = mevis.MLABTestCaseDatabase.allTestCaseSuites().get(testSuite, {}).get("testCases", [])
315  testCasesNode = testCfg.find('TestCases')
316  for name in testCaseNames:
317  etree.SubElement(testCasesNode, 'TestCase', {'name': name})
318 
319  # Set system information.
320  testRunNode.set('platform', mevis.MLAB.systemId())
321  testRunNode.set('compiler', mevis.MLAB.compilerInfo())
322  # Set build information.
323  testRunNode.set('builddate', mevis.MLAB.dateOfBuildJob().date().toString("yyyy-MM-dd"))
324  testRunNode.set('version', mevis.MLAB.priv().variable('Version', False))
325 
326  # Create nodes to store information on the test run.
327  infoNode = etree.SubElement(testRunNode, 'Information')
328  testResultNode = etree.SubElement(testRunNode, 'Results')
329  etree.SubElement(infoNode, 'TestCases')
330  etree.SubElement(infoNode, 'Modules')
331  ___addPackageInfoNode( infoNode )
332 
333  # Consolidate the information on the test cases that should be executed.
334  self.__verifyTestCaseList__verifyTestCaseList(testCfg, testRunNode)
335 
336  # If no generic test cases are used then don't build information list for
337  # modules (this causes major performance on windows machines when storing
338  # the resulting xml).
339  for testCaseNode in infoNode.findall("./TestCases/TestCase"):
340  if testCaseNode.get("type") == "GenericTestCase":
341  # extend the XML structure and hook in all modules to test
342  self.__collectModulesToTest__collectModulesToTest(testCfg)
343  self.__buildModuleInfo__buildModuleInfo(infoNode.find("Modules"))
344  break
345 
346  resultNode.set('errorCode', 'Ok')
347  resultNode.append(testRunNode)
348  resultNode.append(testCfg)
349 
350  self.__testCfg__testCfg = None
351  # --------------------------------------------------------------------------------------------}}}-
352 
353  # -- def __buildTestCaseAgenda ---------------------------------------------------------------{{{-
354  def __buildTestCaseAgenda(self, requestNode, resultNode):
355  try:
356  parameterNode = requestNode.find('Parameters')
357  packagesToTest = parameterNode.get('packages', '').split(',')
358  modulesToTest = parameterNode.get('modules', '').split(',')
359  testCaseName = parameterNode.find('TestCase').get('name')
360  testResultsNode = etree.SubElement(resultNode, 'Results')
361  testCaseAgenda, status = self.__loadAndVerifyTestCase__loadAndVerifyTestCase(testCaseName, testResultsNode, packagesToTest, modulesToTest)
362  testCase = testResultsNode.find('TestCase')
363  # Remove TestFunctions for GenericTests with status TEST_STATUS_DO_NOT_TEST_MODULE.
364  if testCase is not None and testCase.get('status',"") == str(Utils.TEST_STATUS_DO_NOT_TEST_MODULE):
365  functionListNode = testCaseAgenda.find('TestFunctions')
366  functionNodes = functionListNode.findall('Function')
367  for functionNode in functionNodes:
368  functionListNode.remove(functionNode)
369  assert(testCaseAgenda)
370  resultNode.append(testCaseAgenda)
371  if status != 'Ok':
372  etree.SubElement(resultNode, 'Error').text = 'Failed to load the test case'
373  resultNode.set('errorCode', status)
374  except:
375  resultNode.set('errorCode', 'Failed')
376  etree.SubElement(resultNode, 'Error').text = traceback.format_exc()
377  # --------------------------------------------------------------------------------------------}}}-
378 
379  # -- def __verifyTestCaseList ----------------------------------------------------------------{{{-
380 
384  def __verifyTestCaseList (self, testCfg, testRunNode):
385  # Get list of all available test cases.
386  availTestCaseList = []
387  for package in self.__testCfg__testCfg['Packages']['Tested']:
388  availTestCaseList.extend(mevis.MLABTestCaseDatabase.allTestCasesForPackage(package))
389  if self.__isInsideTestCaseManager__isInsideTestCaseManager:
390  availTestCaseList.extend(getCodeTestsByPackage().get(package,{}).keys())
391 
392  # If no test cases were given use list of available ones.
393  testCaseListNode = testCfg.find('TestCases')
394  if len(testCaseListNode.findall('TestCase')) == 0:
395  for testCaseName in availTestCaseList:
396  etree.SubElement(testCaseListNode, 'TestCase', name=testCaseName)
397 
398  # Get the node to append information to.
399  testInfoNode = testRunNode.find('Information/TestCases')
400 
401  for testCaseNode in testCfg.findall('TestCases/TestCase'):
402  testCaseName = testCaseNode.get('name')
403  if testCaseName in availTestCaseList:
404  infoDict = self.__getTestCaseInfo__getTestCaseInfo(testCaseName)
405  # Verify test groups if necessary.
406  if not self.__verifyTestGroups__verifyTestGroups(infoDict, self.__testCfg__testCfg['TestGroups']):
407  mevis.MLAB.logError("TestCase %s not in tested groups (%s)." % (testCaseName, ", ".join(self.__testCfg__testCfg['TestGroups'])))
408  testCaseNode.set('isNotInTestGroups', str(True))
409  else:
410  testCaseNode.set('type', infoDict['type'])
411  testInfoNode.append(testCaseNode)
412  testCaseNode.set('status', str(Utils.TEST_STATUS_OK))
413  else:
414  mevis.MLAB.logError("test case not found %s %s" %( testCaseName, availTestCaseList))
415  testCaseNode.set('status', str(Utils.TEST_STATUS_ERROR))
416  # --------------------------------------------------------------------------------------------}}}-
417 
418  # -- def __verifyTestCase --------------------------------------------------------------------{{{-
419 
420  def __loadAndVerifyTestCase(self, testCaseName, testResultNode, packagesToTest, modulesToTest):
421  resolvedPackagesToTest = []
422  for package in packagesToTest:
423  pGroup, pName = package.split('/')
424  if pGroup == "*" and pName == "*":
425  for package in mevis.MLABPackageManager.packages():
426  resolvedPackagesToTest.append(package.packageIdentifier())
427  elif pName == "*":
428  for package in mevis.MLABPackageManager.packages():
429  if package.packageGroup() == pGroup:
430  resolvedPackagesToTest.append(package.packageIdentifier())
431  else:
432  resolvedPackagesToTest.append(package)
433  testCaseNode, status = self.__verifyTestCase__verifyTestCase(testCaseName, testResultNode, resolvedPackagesToTest, modulesToTest)
434  return testCaseNode, status
435  # --------------------------------------------------------------------------------------------}}}-
436 
437  def __getTestCaseInfo(self, testCaseName):
438  infoDict = mevis.MLABTestCaseDatabase.testCaseInfo(testCaseName)
439  if not infoDict:
440  codeTest = getCodeTest(testCaseName)
441  if codeTest != None:
442  infoDict = codeTest.getInfoDict()
443  return infoDict
444 
445  # -- def __verifyTestCase --------------------------------------------------------------------{{{-
446 
450  def __verifyTestCase (self, testCaseName, testResultNode, packagesToTest, modulesToTest):
451  infoDict = self.__getTestCaseInfo__getTestCaseInfo(testCaseName)
452 
453  # Try to load the test case.
454  testType = infoDict['type']
455 
456  # if agenda test case is set from outside, use it
457  testCase = self.__agendaTestCase__agendaTestCase
458  if not testCase:
459  mevis.MLAB.log("Trying to load test case %s" % testCaseName)
460  # no test case set, try loading it instead
461  testCase = self.__loadTestCase__loadTestCase(testCaseName, testType)
462  mevis.MLAB.log("Loading complete")
463 
464  if testCase == None:
465  return None, 'Failed'
466 
467  # Add basic information for the actual testing.
468  if testType == 'GenericTestCase':
469  modulesToTest, modulesNotToTest = testCase.getModulesToTest(modulesToTest, packagesToTest)
470  for moduleName in modulesToTest:
471  etree.SubElement(testResultNode, "TestCase", name=testCaseName, type=testType, module=moduleName)
472  for moduleName in modulesNotToTest:
473  etree.SubElement(testResultNode, "TestCase", name=testCaseName, type=testType, module=moduleName, status=str(Utils.TEST_STATUS_DO_NOT_TEST_MODULE))
474  else:
475  etree.SubElement(testResultNode, 'TestCase', name=testCaseName, type=testType)
476 
477  return testCase.getTestCaseNode(), 'Ok'
478  # --------------------------------------------------------------------------------------------}}}-
479 
480  # -- def __verifyTestGroups ------------------------------------------------------------------{{{-
481 
488  def __verifyTestGroups (self, infoDict, testGroupList):
489  testCaseGroupList = infoDict['testGroups'].lower() if 'testGroups' in infoDict else ""
490  testCaseGroupList = testCaseGroupList.split()
491 
492  if 'disabled' in testCaseGroupList or ('needspublicsdk' in testCaseGroupList and not _isPublicSDK):
493  return False
494  testGroupList = [tg.lower() for tg in testGroupList]
495  if testGroupList:
496  if 'automatic' in testGroupList:
497  if 'manual' in testCaseGroupList:
498  return False
499  return True
500  for testGroup in testGroupList:
501  if testGroup in testCaseGroupList:
502  return True
503  return False
504  return True
505  # --------------------------------------------------------------------------------------------}}}-
506 
507  # -- def __verifyPackages --------------------------------------------------------------------{{{-
508 
514  def __verifyPackages (self, testCfg):
515  packageRoot = testCfg.find('Packages')
516 
517  # First go over list and substitute wildcards and verify all given
518  # packages.
519  tPkgNode = packageRoot.find('Tested')
520  aPkgNode = packageRoot.find('Available')
521  iPkgNode = packageRoot.find('Ignored')
522  # if no ignored package is given,
523  # then self.__verifyPackageListNode() would ignore all packages
524  if len(iPkgNode) > 0:
525  self.__verifyPackageListNode__verifyPackageListNode(iPkgNode)
526  ignoredPackageIDs = set()
527  for ignoredPackage in iPkgNode:
528  ignoredPackageIDs.add(ignoredPackage.get('name'))
529 
530  self.__verifyPackageListNode__verifyPackageListNode(tPkgNode, ignoredPackageIDs)
531  self.__verifyPackageListNode__verifyPackageListNode(aPkgNode, ignoredPackageIDs)
532  # Get list of verified packages.
533  tPkgSet = set()
534  for packageNode in tPkgNode.findall('Package'):
535  if packageNode.get('status') in ('Ok', 'Added'):
536  tPkgSet.add(packageNode.get('name'))
537 
538  aPkgSet = set()
539  for packageNode in aPkgNode.findall('Package'):
540  if packageNode.get('status') in ('Ok', 'Added'):
541  aPkgSet.add(packageNode.get('name'))
542 
543  # Save lists of packages sets for usage on slave side.
544  self.__testCfg__testCfg['Packages']['Tested'] = list(tPkgSet)
545  self.__testCfg__testCfg['Packages']['Available'] = list(tPkgSet.union(aPkgSet))
546 
547  # Add all available packages for usage on master side.
548  for item in tPkgSet.difference(aPkgSet):
549  etree.SubElement(aPkgNode, 'Package', name=item, status='Ok')
550  # --------------------------------------------------------------------------------------------}}}-
551 
552  # -- def __verifyPackageListNode -------------------------------------------------------------{{{-
553 
556  def __verifyPackageListNode (self, packageListNode, ignoredPackageIDs=[]):
557  # If no packages are given add everything!
558  if len(packageListNode) == 0:
559  etree.SubElement(packageListNode, "Package", name="*/*")
560 
561  for packageNode in packageListNode:
562  packageID = packageNode.get('name')
563  try:
564  pGroup, pName = packageID.split("/")
565  except:
566  packageNode.set('status', 'Invalid')
567  continue
568 
569  # Substitute the wildcards.
570  if pGroup == "*":
571  if pName == "*":
572  for package in mevis.MLABPackageManager.packages():
573  packageID = package.packageIdentifier()
574  if not packageID in ignoredPackageIDs:
575  etree.SubElement(packageListNode, "Package", name=packageID, status='Added')
576  # Remove node as the wildcard has been executed.
577  packageNode.set('status', 'Substituted')
578  else:
579  packageNode.set('status', 'Failed')
580  elif pName == "*":
581  packageNode.set('status', 'Substituted')
582  for package in mevis.MLABPackageManager.packagesByGroup(pGroup):
583  packageID = package.packageIdentifier()
584  if not packageID in ignoredPackageIDs:
585  etree.SubElement(packageListNode, "Package", name=packageID, status='Added')
586  else:
587  # If the given package exists add it to the package set otherwise
588  # remove the XML node.
589  if mevis.MLABPackageManager.packageByIdentifier(packageID):
590  packageNode.set('status', 'Ok')
591  else:
592  packageNode.set('status', 'Failed')
593  # --------------------------------------------------------------------------------------------}}}-
594 
595  # -- def __collectModulesToTest ---------------------------------------------------------------------{{{-
596 
601  def __collectModulesToTest (self, testCfg):
602  modulesNode = testCfg.find('Modules')
603 
604  # Build up a dictionary with all specified filters.
605  filterDict = {}
606  for filterNode in modulesNode.findall('Filter'):
607  key, valueList = filterNode.text.split(":")
608  filterDict[key] = []
609  for value in valueList.split(","):
610  filterDict[key].append(value)
611 
612  # Build up a list with all modules to be be taken into account.
613  availableModuleList = []
614  for packageName in self.__testCfg__testCfg['Packages']['Tested']:
615  availableModuleList.extend(mevis.MLAB.allModulesForPackageIdentifier(packageName))
616 
617  # If the user did not specify a list of modules use all available.
618  if len(modulesNode.findall('Module')) == 0:
619  for moduleName in availableModuleList:
620  etree.SubElement(modulesNode, "Module", name=moduleName)
621 
622  # Find all modules to test.
623  for moduleNode in modulesNode.findall('Module'):
624  moduleName = moduleNode.get('name')
625  moduleInfo = mevis.MLAB.moduleInfo(moduleName)
626 
627  if moduleInfo and moduleName in availableModuleList:
628  useModule = True
629  # Does module pass filters?
630  for f in filterDict:
631  if not f in moduleInfo or not [x for x in filterDict[f] if re.search(x, moduleInfo[f])]:
632  useModule = False
633  break
634  if useModule:
635  self.__testCfg__testCfg['Modules'].append(moduleName)
636  moduleNode.set('status', str(Utils.TEST_STATUS_OK))
637  else:
638  moduleNode.set('isModuleFiltered', str(True))
639  else:
640  modulesNode.set('status', str(Utils.TEST_STATUS_ERROR))
641  # --------------------------------------------------------------------------------------------}}}-
642 
643  # -- def __buildModuleInfo -------------------------------------------------------------------{{{-
644  # @param modulesInfoNode XML node taking the module information.
645  def __buildModuleInfo (self, modulesInfoNode):
646  for moduleName in self.__testCfg__testCfg['Modules']:
647  moduleInfo = mevis.MLAB.moduleInfo(moduleName)
648  newModuleNode = etree.SubElement(modulesInfoNode, 'Module', name=moduleName)
649  for key in moduleInfo:
650  value = moduleInfo[key]
651  etree.SubElement(newModuleNode, key, type=value.__class__.__name__).text = unicode(value)
652  # --------------------------------------------------------------------------------------------}}}-
653 
654  # -- def __setPackageList --------------------------------------------------------------------{{{-
655 
658  def __setPackageList (self, xmlNode, resultNode):
659  packageList = []
660  for item in xmlNode.findall('Package'):
661  packageList.append(item.get('name'))
662  TestHelper.getInstance().setPackageList(packageList)
663  resultNode.set('errorCode', 'Ok')
664  # --------------------------------------------------------------------------------------------}}}-
665 
666  # -- def runCommand --------------------------------------------------------------------------{{{-
667 
671  def runCommand(self, requestNode):
672  resultNode = etree.Element('Result')
673  if not TestHelper.getInstance().getGlobalContext():
674  command = 'Quit'
675  mevis.MLAB.logWarning("Test case manager has been closed - aborting test execution")
676  else:
677  command = requestNode.get('type')
678  mevis.MLAB.log("Running command '%s'" % command)
679 
680  try:
681  if command == 'Quit':
682  resultNode.set('errorCode', 'Ok')
683  self.__running__running = False
684  elif command == 'DoTest':
685  testCaseNode = requestNode.find('TestCase')
686  if self.__com__com and testCaseNode.get("requestProgress") == "1":
687  self.setTestCaseListenersetTestCaseListener(TestCaseRemoteListener(self.__com__com))
688 
689  self.__doTest__doTest(testCaseNode, resultNode)
690 
691  if self.__com__com and testCaseNode.get("requestProgress") == "1":
692  self.setTestCaseListenersetTestCaseListener(None)
693 
694  elif command == 'SetPackageList': self.__setPackageList__setPackageList(requestNode.find('Packages'), resultNode)
695  elif command == 'BuildTestAgenda': self.__buildTestAgenda__buildTestAgenda(requestNode.find('Configuration'), resultNode)
696  elif command == 'BuildTestCaseAgenda': self.__buildTestCaseAgenda__buildTestCaseAgenda(requestNode, resultNode)
697  else:
698  raise Exception('Unknown command: %s' % (command))
699  except:
700  resultNode.set('errorCode', 'Exception')
701  etree.SubElement(resultNode, 'Error').text = traceback.format_exc()
702  mevis.MLAB.log(traceback.format_exc())
703  self.__running__running = False
704 
705  content = etree.tostring(resultNode).decode()
706  mevis.MLAB.log("Result content: %s%s" % (content[:150], " [...]" if len(content)>150 else ""))
707  return resultNode
708  # --------------------------------------------------------------------------------------------}}}-
709 
710  # -- def run ---------------------------------------------------------------------------------{{{-
711 
712  def run (self):
713  self.__com__com.connect()
714  self.__running__running = True
715  while self.__running__running:
716  request = self.__com__com.recv(20)
717  if request in ('', None):
718  mevis.MLAB.logError(self.__com__com.getLastErrorWithMessage()[1])
719  break
720 
721  requestNode = etree.fromstring(request)
722  resultNode = self.runCommandrunCommand(requestNode)
723 
724  if not self.__com__com.send(etree.tostring(resultNode), 5):
725  mevis.MLAB.logError("Couldn't send result to request %s" % (request))
726  self.__running__running = False
727  self.__com__com.disconnect()
728  # --------------------------------------------------------------------------------------------}}}-
729 # ----------------------------------------------------------------------------------------------}}}-
The connection's slave.
Definition: IPC.py:310
The class controlling a MeVisLab slave instance.
Definition: Slave.py:79
def __verifyTestCaseList(self, testCfg, testRunNode)
Definition: Slave.py:384
def __buildTestCaseAgenda(self, requestNode, resultNode)
Definition: Slave.py:354
def __setPackageList(self, xmlNode, resultNode)
Definition: Slave.py:658
def setAgendaTestCase(self, testCase)
Set the test case that is used for building the agenda/function list.
Definition: Slave.py:174
def runCommand(self, requestNode)
Run a command given via the requestNode.
Definition: Slave.py:671
def __collectModulesToTest(self, testCfg)
Definition: Slave.py:601
def __doTest(self, testCaseNode, resultNode)
Definition: Slave.py:200
def getTestCase(self)
Returns the test case that has been run.
Definition: Slave.py:182
def __verifyPackageListNode(self, packageListNode, ignoredPackageIDs=[])
Definition: Slave.py:556
def setTestCaseListener(self, listener)
Definition: Slave.py:135
def __verifyTestCase(self, testCaseName, testResultNode, packagesToTest, modulesToTest)
Definition: Slave.py:450
def __init__(self, cfgFile, context, offline=False)
The default constructor.
Definition: Slave.py:103
def setIsInsideTestCaseManager(self, isInsideTestCaseManager)
Definition: Slave.py:132
def unloadTestCase(self)
Clears the loaded test case.
Definition: Slave.py:188
def __getTestCaseInfo(self, testCaseName)
Definition: Slave.py:437
def __loadAndVerifyTestCase(self, testCaseName, testResultNode, packagesToTest, modulesToTest)
Definition: Slave.py:420
def __loadTestCase(self, testCaseName, testCaseType, moduleName=None)
Definition: Slave.py:157
def __buildTestAgenda(self, testCfg, resultNode)
Definition: Slave.py:289
def loadTestCase(self, testCaseNode)
Load the given test case.
Definition: Slave.py:144
def __buildModuleInfo(self, modulesInfoNode)
Definition: Slave.py:645
def run(self)
The main method which handles all the request from the master.
Definition: Slave.py:712
def __verifyPackages(self, testCfg)
Definition: Slave.py:514
def __verifyTestGroups(self, infoDict, testGroupList)
Definition: Slave.py:488
def endTestCaseFunction(self, status, duration)
Definition: Slave.py:69
def startTestCaseFunction(self, testType, testCase, testFunction)
Definition: Slave.py:55
Implementation of the TestCase superclass for functional test cases.
The implementation of the TestCase superclass for generic testing.
def clearEncodingCache()
Definition: Base.py:42