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
20if sys.version_info.major >= 3:
21 unicode = str
22
23import xml.etree.cElementTree as etree
24# ----------------------------------------------------------------------------------------------}}}-
25
26# -- local imports -----------------------------------------------------------------------------{{{-
27import mevis
28import PackageSorter
29
30from . import IPC
31from . import Config
32from . import Utils
33from .LogHandler import LogHandler
34from TestSupport.TestHelper import TestHelper
35
36from .TestCaseGeneric import GenericTestCase
37from .TestCaseFunctional import FunctionalTestCase
38import TestSupport
39
40from . import CodeCoverage
41from .CodeTestSupport import getCodeTest, getCodeTestsByPackage, CodeTestTestCase
42
43# ----------------------------------------------------------------------------------------------}}}-
44
45# Determine if the Standard 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.stopped = False
53 self.__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.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.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.send(etree.tostring(resultNode), 5):
73 mevis.MLAB.logError("Couldn't send status")
75
76# -- class Slave -------------------------------------------------------------------------------{{{-
77
79class Slave :
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 = context
105 self.__com = IPC.ComSlave() if not offline else None
106
107 self.__testCaseListener = None
108 self.__agendaTestCase = None
109 self.__isInsideTestCaseManager = False
110
111 # The current configuration
113
114 # Create result directory if not available.
115 resultDir = self._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 = self._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, resultDir=self._config.getResultDir())
130 # --------------------------------------------------------------------------------------------}}}-
131
132 def setIsInsideTestCaseManager(self, isInsideTestCaseManager):
133 self.__isInsideTestCaseManager = isInsideTestCaseManager
134
135 def setTestCaseListener(self, listener):
136 self.__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(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 = testCase
176 # --------------------------------------------------------------------------------------------}}}-
177
178 # -- def getTestCase -------------------------------------------------------------------------{{{-
179
182 def getTestCase ( self ):
183 return self.__testCase
184 # --------------------------------------------------------------------------------------------}}}-
185
186 # -- def unloadTestCase -------------------------------------------------------------------------{{{-
187
188 def unloadTestCase ( self ):
189 self.__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,
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,
226 testCaseNode=testCaseNode)
227 except CodeCoverage.CoverageException as e:
228 bullseyeCoverage = None
229 mevis.MLAB.logError(e)
230
231 self.__testCase = self.loadTestCase(testCaseNode)
232
233 # Run the test case only if it loaded correctly.
234 if self.__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)
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()
256 self.__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 = { 'Packages': { 'Tested': [], 'Available': [] },
300 'TestGroups': [],
301 'TestSuites': [],
302 'Modules': [] }
303
304 # Consolidate the information on the packages available.
305 self.__verifyPackages(testCfg)
306
307 # Get information on the test groups selected.
308 for testGroupNode in testCfg.findall('TestGroups/TestGroup'):
309 self.__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(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(testCfg)
343 self.__buildModuleInfo(infoNode.find("Modules"))
344 break
345
346 resultNode.set('errorCode', 'Ok')
347 resultNode.append(testRunNode)
348 resultNode.append(testCfg)
349
350 self.__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(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['Packages']['Tested']:
388 availTestCaseList.extend(mevis.MLABTestCaseDatabase.allTestCasesForPackage(package))
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(testCaseName)
405 # Verify test groups if necessary.
406 if not self.__verifyTestGroups(infoDict, self.__testCfg['TestGroups']):
407 mevis.MLAB.logError("TestCase %s not in tested groups (%s)." % (testCaseName, ", ".join(self.__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(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(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
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(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(iPkgNode)
526 ignoredPackageIDs = set()
527 for ignoredPackage in iPkgNode:
528 ignoredPackageIDs.add(ignoredPackage.get('name'))
529
530 self.__verifyPackageListNode(tPkgNode, ignoredPackageIDs)
531 self.__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['Packages']['Tested'] = list(tPkgSet)
545 self.__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['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['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['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 = False
684 elif command == 'DoTest':
685 testCaseNode = requestNode.find('TestCase')
686 if self.__com and testCaseNode.get("requestProgress") == "1":
688
689 self.__doTest(testCaseNode, resultNode)
690
691 if self.__com and testCaseNode.get("requestProgress") == "1":
692 self.setTestCaseListener(None)
693
694 elif command == 'SetPackageList': self.__setPackageList(requestNode.find('Packages'), resultNode)
695 elif command == 'BuildTestAgenda': self.__buildTestAgenda(requestNode.find('Configuration'), resultNode)
696 elif command == 'BuildTestCaseAgenda': self.__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 = 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.connect()
714 self.__running = True
715 while self.__running:
716 request = self.__com.recv(20)
717 if request in ('', None):
718 mevis.MLAB.logError(self.__com.getLastErrorWithMessage()[1])
719 break
720
721 requestNode = etree.fromstring(request)
722 resultNode = self.runCommand(requestNode)
723
724 if not self.__com.send(etree.tostring(resultNode), 5):
725 mevis.MLAB.logError("Couldn't send result to request %s" % (request))
726 self.__running = False
727 self.__com.disconnect()
728 # --------------------------------------------------------------------------------------------}}}-
729# ----------------------------------------------------------------------------------------------}}}-
The connection's slave.
Definition IPC.py:310
The class controlling a MeVisLab slave instance.
Definition Slave.py:79
__loadTestCase(self, testCaseName, testCaseType, moduleName=None)
Definition Slave.py:157
__init__(self, cfgFile, context, offline=False)
The default constructor.
Definition Slave.py:103
setAgendaTestCase(self, testCase)
Set the test case that is used for building the agenda/function list.
Definition Slave.py:174
__verifyTestCaseList(self, testCfg, testRunNode)
Definition Slave.py:384
__buildTestAgenda(self, testCfg, resultNode)
Definition Slave.py:289
__doTest(self, testCaseNode, resultNode)
Definition Slave.py:200
__verifyPackages(self, testCfg)
Definition Slave.py:514
__setPackageList(self, xmlNode, resultNode)
Definition Slave.py:658
__loadAndVerifyTestCase(self, testCaseName, testResultNode, packagesToTest, modulesToTest)
Definition Slave.py:420
runCommand(self, requestNode)
Run a command given via the requestNode.
Definition Slave.py:671
getTestCase(self)
Returns the test case that has been run.
Definition Slave.py:182
__verifyTestGroups(self, infoDict, testGroupList)
Definition Slave.py:488
loadTestCase(self, testCaseNode)
Load the given test case.
Definition Slave.py:144
setTestCaseListener(self, listener)
Definition Slave.py:135
run(self)
The main method which handles all the request from the master.
Definition Slave.py:712
__verifyPackageListNode(self, packageListNode, ignoredPackageIDs=[])
Definition Slave.py:556
__getTestCaseInfo(self, testCaseName)
Definition Slave.py:437
__buildTestCaseAgenda(self, requestNode, resultNode)
Definition Slave.py:354
unloadTestCase(self)
Clears the loaded test case.
Definition Slave.py:188
__collectModulesToTest(self, testCfg)
Definition Slave.py:601
__buildModuleInfo(self, modulesInfoNode)
Definition Slave.py:645
setIsInsideTestCaseManager(self, isInsideTestCaseManager)
Definition Slave.py:132
__verifyTestCase(self, testCaseName, testResultNode, packagesToTest, modulesToTest)
Definition Slave.py:450
startTestCaseFunction(self, testType, testCase, testFunction)
Definition Slave.py:55
endTestCaseFunction(self, status, duration)
Definition Slave.py:69
Implementation of the TestCase superclass for functional test cases.
The implementation of the TestCase superclass for generic testing.
clearEncodingCache()
Definition Base.py:39