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