TestCenter Reference
Slave.py
Go to the documentation of this file.
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
13
14# -- system imports ----------------------------------------------------------------------------{{{-
15import os
16import re
17import traceback
18
19import sys
20
21if sys.version_info.major >= 3:
22 unicode = str
23
24import xml.etree.cElementTree as etree
25
26# ----------------------------------------------------------------------------------------------}}}-
27
28# -- local imports -----------------------------------------------------------------------------{{{-
29import mevis
30import PackageSorter
31
32from . import IPC
33from . import Config
34from . import Utils
35from .LogHandler import LogHandler
36from TestSupport.TestHelper import TestHelper
37
38from .TestCaseGeneric import GenericTestCase
39from .TestCaseFunctional import FunctionalTestCase
40import TestSupport
41
42from . import CodeCoverage
43from .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.stopped = False
58 self.__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.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.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.send(etree.tostring(resultNode), 5):
78 mevis.MLAB.logError("Couldn't send status")
80
81
82# -- class Slave -------------------------------------------------------------------------------{{{-
83
85class 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 = context
111 self.__com = IPC.ComSlave() if not offline else None
112
113 self.__testCaseListener = None
114 self.__agendaTestCase = None
115 self.__isInsideTestCaseManager = False
116
117 # The current configuration
119
120 # Create result directory if not available.
121 resultDir = self._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 = self._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, resultDir=self._config.getResultDir())
136
137 # --------------------------------------------------------------------------------------------}}}-
138
139 def setIsInsideTestCaseManager(self, isInsideTestCaseManager):
140 self.__isInsideTestCaseManager = isInsideTestCaseManager
141
142 def setTestCaseListener(self, listener):
143 self.__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(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 = testCase
185
186 # --------------------------------------------------------------------------------------------}}}-
187
188 # -- def getTestCase -------------------------------------------------------------------------{{{-
189
192 def getTestCase(self):
193 return self.__testCase
194
195 # --------------------------------------------------------------------------------------------}}}-
196
197 # -- def unloadTestCase -------------------------------------------------------------------------{{{-
198
199 def unloadTestCase(self):
200 self.__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, 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, testCaseNode=testCaseNode)
235 except CodeCoverage.CoverageException as e:
236 bullseyeCoverage = None
237 mevis.MLAB.logError(e)
238
239 self.__testCase = self.loadTestCase(testCaseNode)
240
241 # Run the test case only if it loaded correctly.
242 if self.__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)
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()
264 self.__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 = {
312 "Packages": {"Tested": [], "Available": []},
313 "TestGroups": [],
314 "TestSuites": [],
315 "Modules": [],
316 }
317
318 # Consolidate the information on the packages available.
319 self.__verifyPackages(testCfg)
320
321 # Get information on the test groups selected.
322 for testGroupNode in testCfg.findall("TestGroups/TestGroup"):
323 self.__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(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(testCfg)
357 self.__buildModuleInfo(infoNode.find("Modules"))
358 break
359
360 resultNode.set("errorCode", "Ok")
361 resultNode.append(testRunNode)
362 resultNode.append(testCfg)
363
364 self.__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(
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["Packages"]["Tested"]:
406 availTestCaseList.extend(mevis.MLABTestCaseDatabase.allTestCasesForPackage(package))
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(testCaseName)
423 # Verify test groups if necessary.
424 if not self.__verifyTestGroups(infoDict, self.__testCfg["TestGroups"]):
425 mevis.MLAB.logError(
426 "TestCase %s not in tested groups (%s)."
427 % (testCaseName, ", ".join(self.__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(
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(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
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(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(iPkgNode)
560 ignoredPackageIDs = set()
561 for ignoredPackage in iPkgNode:
562 ignoredPackageIDs.add(ignoredPackage.get("name"))
563
564 self.__verifyPackageListNode(tPkgNode, ignoredPackageIDs)
565 self.__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["Packages"]["Tested"] = list(tPkgSet)
579 self.__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["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["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["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 = False
723 elif command == "DoTest":
724 testCaseNode = requestNode.find("TestCase")
725 if self.__com and testCaseNode.get("requestProgress") == "1":
727
728 self.__doTest(testCaseNode, resultNode)
729
730 if self.__com and testCaseNode.get("requestProgress") == "1":
731 self.setTestCaseListener(None)
732
733 elif command == "SetPackageList":
734 self.__setPackageList(requestNode.find("Packages"), resultNode)
735 elif command == "BuildTestAgenda":
736 self.__buildTestAgenda(requestNode.find("Configuration"), resultNode)
737 elif command == "BuildTestCaseAgenda":
738 self.__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 = 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.connect()
757 self.__running = True
758 TestHelper.getInstance().runTestInSecureMode()
759 while self.__running:
760 request = self.__com.recv(20)
761 if request in ("", None):
762 mevis.MLAB.logError(self.__com.getLastErrorWithMessage()[1])
763 break
764
765 requestNode = etree.fromstring(request)
766 resultNode = self.runCommand(requestNode)
767
768 if not self.__com.send(etree.tostring(resultNode), 5):
769 mevis.MLAB.logError("Couldn't send result to request %s" % (request))
770 self.__running = False
771 TestHelper.getInstance().runTestInCurrentMlabInstance()
772 self.__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
__loadTestCase(self, testCaseName, testCaseType, moduleName=None)
Definition Slave.py:165
__init__(self, cfgFile, context, offline=False)
The default constructor.
Definition Slave.py:109
setAgendaTestCase(self, testCase)
Set the test case that is used for building the agenda/function list.
Definition Slave.py:183
__verifyTestCaseList(self, testCfg, testRunNode)
Definition Slave.py:402
__buildTestAgenda(self, testCfg, resultNode)
Definition Slave.py:297
__doTest(self, testCaseNode, resultNode)
Definition Slave.py:210
__verifyPackages(self, testCfg)
Definition Slave.py:548
__setPackageList(self, xmlNode, resultNode)
Definition Slave.py:696
__loadAndVerifyTestCase(self, testCaseName, testResultNode, packagesToTest, modulesToTest)
Definition Slave.py:442
runCommand(self, requestNode)
Run a command given via the requestNode.
Definition Slave.py:710
getTestCase(self)
Returns the test case that has been run.
Definition Slave.py:192
__verifyTestGroups(self, infoDict, testGroupList)
Definition Slave.py:521
loadTestCase(self, testCaseNode)
Load the given test case.
Definition Slave.py:151
setTestCaseListener(self, listener)
Definition Slave.py:142
run(self)
The main method which handles all the request from the master.
Definition Slave.py:755
__verifyPackageListNode(self, packageListNode, ignoredPackageIDs=[])
Definition Slave.py:591
__getTestCaseInfo(self, testCaseName)
Definition Slave.py:462
__buildTestCaseAgenda(self, requestNode, resultNode)
Definition Slave.py:369
unloadTestCase(self)
Clears the loaded test case.
Definition Slave.py:199
__collectModulesToTest(self, testCfg)
Definition Slave.py:637
__buildModuleInfo(self, modulesInfoNode)
Definition Slave.py:682
setIsInsideTestCaseManager(self, isInsideTestCaseManager)
Definition Slave.py:139
__verifyTestCase(self, testCaseName, testResultNode, packagesToTest, modulesToTest)
Definition Slave.py:475
startTestCaseFunction(self, testType, testCase, testFunction)
Definition Slave.py:60
endTestCaseFunction(self, status, duration)
Definition Slave.py:74
Implementation of the TestCase superclass for functional test cases.
The implementation of the TestCase superclass for generic testing.
clearEncodingCache()
Definition Base.py:48