Package epyunit :: Module SubprocUnit
[hide private]
[frames] | no frames]

Source Code for Module epyunit.SubprocUnit

   1  # -*- coding: utf-8 -*- 
   2  """Basic classes and functions for unittests. 
   3  """ 
   4  from __future__ import absolute_import 
   5   
   6  __author__ = 'Arno-Can Uestuensoez' 
   7  __license__ = "Artistic-License-2.0 + Forced-Fairplay-Constraints" 
   8  __copyright__ = "Copyright (C) 2010-2016 Arno-Can Uestuensoez @Ingenieurbuero Arno-Can Uestuensoez" 
   9  __version__ = '0.2.2' 
  10  __uuid__='9de52399-7752-4633-9fdc-66c87a9200b8' 
  11   
  12  __docformat__ = "restructuredtext en" 
  13   
  14  import sys,re 
  15  from types import NoneType,FunctionType 
  16   
  17  version = '{0}.{1}'.format(*sys.version_info[:2]) 
  18  if not version in ('2.6', '2.7',): # pragma: no cover 
  19      raise Exception("Requires Python-2.6.* or higher") 
  20   
  21  from epyunit.SystemCalls import SystemCalls 
  22   
  23  _parentrepr = re.compile(ur'[{](.*[^}])}') 
  24  """ 
  25  static precompiled 're' for parent '__repr__'. 
  26  """ 
  27   
  28  # 
  29  # enums for priority type  
  30  # 
  31  _P_OK = 0  
  32  """hasSuccess""" 
  33   
  34  _P_NOK = 1 
  35  """hasFailure""" 
  36   
  37  _P_WEIGHT = 3 
  38  """simple counter compare, bigger wins: (resultok, resultnok), else default""" 
  39   
  40  _P_CUSTOM = 4 
  41  """callback for custom function""" 
  42   
  43  _prioenums = {_P_OK:'_P_OK',_P_NOK:'_P_NOK',_P_WEIGHT:'_P_WEIGHT',_P_CUSTOM:'_P_CUSTOM', } 
  44   
  45  # 
  46  # enums for exit type  
  47  # 
  48  _E_IGN = 4 
  49  """ 
  50  exittype: ignore 
  51  """ 
  52   
  53  _E_OK = 8 
  54  """ 
  55  exittype: OK 
  56  """ 
  57   
  58  _E_NOK = 16 
  59  """ 
  60  exittype: NOK 
  61  """ 
  62   
  63  _E_VAL = 32 
  64  """ 
  65  exittype: value 
  66  """ 
  67  _exitenums = {4:'_E_IGN', 8:'_E_OK', 16:'_E_NOK',32:'_E_VAL', } 
  68   
  69   
70 -class SProcUnitRulesException(Exception):
71 """Application error of unittest rules. 72 """ 73 pass
74
75 -class SubprocessUnitException(Exception):
76 """Failure of subprocess call. 77 """ 78 pass
79
80 -class SProcUnitRules(object):
81 """ 82 The 'epyunit.SubprocUnit.SProcUnitRules' defines the expected data, and 83 the minimal degree of expectation. Therefore a set of parameters 84 constitute a basic rule set, which matches the provided reference data 85 on the actual response data. 86 """ 87 88 rules_default = { 89 # default when ambiguous 90 'default': True, 91 92 # re flags 93 'cflags': 0, 94 'multiline': 0, 95 'ignorecase': 0, 96 'unicode': 0, 97 'dotall': 0, 98 'debug': 0, 99 100 # priorities 101 'priotype': _P_NOK, 102 103 # required result counters 104 'result': 0, 105 'resultok': 0, 106 'resultnok': 0, 107 108 # exit value match 109 'exitign': False, 110 'exittype': _E_OK, 111 'exitval': 0, 112 113 # stderr match 114 'stderrchk': False, 115 'stderrnok': [], 116 'stderrok': [], 117 118 # stdout match 119 'stdoutchk': False, 120 'stdoutnok': [], 121 'stdoutok': [], 122 123 '_exitcond': False, 124 '_exitret': 0, 125 126 } 127 """The default rules for OK operations.""" 128
129 - def __init__(self,**kargs):
130 """Initializes the ruleset and operational parameters. 131 132 For parameters refer to called **setrules** and **setkargs**. 133 """ 134 # 135 # the re pattern 136 # 137 138 #: list of 're' patterns indicating error on STDERR 139 self.stderrnok = [] 140 141 self.stderrok = [] 142 """list of 're' patterns indicating success on STDERR""" 143 144 self.stdoutnok = [] #: list of 're' patterns indicating success on STDOUT 145 self.stdoutok = [] #: list of 're' patterns indicating success on STDOUT 146 147 # 148 # the actual matched strings 149 # 150 self.stderrnok_matched = []; #: list of actually matched failure strings on STDERR 151 self.stderrok_matched = []; #: list of actually matched success strings on STDERR 152 self.stdoutnok_matched = []; """list of actually matched failure strings on STDOUT""" 153 self.stdoutok_matched = []; """list of actually matched success strings on STDOUT""" 154 155 self.reset() 156 157 _args = kargs.copy() 158 self.setkargs(**_args) 159 if not _args.get('default'): # for initial default 160 self.setrules(**{'default':True}) 161 self.setrules(**_args)
162
163 - def reset(self):
164 """A completely empty initial in-place default set for current variables. 165 """ 166 # default for ambiguity 167 self.default = self.rules_default['default'] 168 169 # re flags 170 self.cflags = self.rules_default['cflags'] 171 self.multiline = self.rules_default['multiline'] 172 self.ignorecase = self.rules_default['ignorecase'] 173 self.unicode = self.rules_default['unicode'] 174 self.dotall = self.rules_default['dotall'] 175 self.debug = self.rules_default['debug'] 176 177 # priorities 178 self.priotype = self.rules_default['priotype'] 179 180 # required results 181 self.result_cnt = 0 182 self.resultok_cnt = 0 183 self.resultnok_cnt = 0 184 self.result = self.rules_default['result'] 185 self.resultok = self.rules_default['resultok'] 186 self.resultnok = self.rules_default['resultnok'] 187 188 # exit value match 189 self.exitign = self.rules_default['exitign'] 190 self.exittype = self.rules_default['exittype'] 191 self.exitval = self.rules_default['exitval'] 192 193 # stderr match pattern 194 self.stderrchk = self.rules_default['stderrchk'] 195 lx=len(self.stderrnok) 196 for x in range(lx): #@UnusedVariable 197 self.stderrnok.pop() 198 self.stderrnok.extend(self.rules_default['stderrnok']) 199 200 lx=len(self.stderrok) 201 for x in range(lx): #@UnusedVariable 202 self.stderrok.pop() 203 self.stderrok.extend(self.rules_default['stderrok']) 204 205 # stderr matched strings 206 lx=len(self.stderrnok_matched) 207 for x in range(lx): #@UnusedVariable 208 self.stderrnok_matched.pop() 209 self.stderrnok_cnt = 0 210 211 lx=len(self.stderrok_matched) 212 for x in range(lx): #@UnusedVariable 213 self.stderrok_matched.pop() 214 self.stderrok_cnt = 0 215 216 217 # stdout match pattern 218 self.stdoutchk = self.rules_default['stdoutchk'] 219 lx=len(self.stdoutnok) 220 for x in range(lx): #@UnusedVariable 221 self.stdoutnok.pop() 222 self.stdoutnok.extend(self.rules_default['stdoutnok']) 223 224 lx=len(self.stdoutok) 225 for x in range(lx): #@UnusedVariable 226 self.stdoutok.pop() 227 self.stdoutok.extend(self.rules_default['stdoutok']) 228 229 # stdout matched strings 230 lx=len(self.stdoutnok_matched) 231 for x in range(lx): #@UnusedVariable 232 self.stdoutnok_matched.pop() 233 self.stdoutnok_cnt = 0 234 235 lx=len(self.stdoutok_matched) 236 for x in range(lx): #@UnusedVariable 237 self.stdoutok_matched.pop() 238 self.stdoutok_cnt = 0 239 240 self._exitcond = self.rules_default['_exitcond'] 241 self._exitret = self.rules_default['_exitret'] 242 243 pass
244
245 - def setkargs(self,**kargs):
246 """Sets supported parameters. 247 248 Applicable for the initial call of self.__init__(), 249 and later modification. 250 251 Tolerates unknown keyword parameters, pops own. 252 253 Args: 254 **kargs: Parameter specific for the operation, 255 256 debug: Sets debug for rule application. 257 258 verbose: Sets verbose for rule application. 259 260 Returns: 261 When successful returns 'True', else returns either 'False', 262 or raises an exception. 263 264 Raises: 265 passed through exceptions: 266 267 """ 268 _ret = True 269 for k,v in kargs.iteritems(): 270 if k=='debug': 271 self.debug=v 272 elif k=='verbose': 273 self.verbose=v 274 return _ret
275
276 - def setrules(self,**predef):
277 """Initialize and reset parameters and previous results. 278 279 Args: 280 **kargs: 281 282 setdefault: Sets the predefined default dictionary, 283 see 'rules_default'. 284 285 debug: 286 287 True: see *re.DEBUG*, when set 288 289 False: default:=unset 290 291 dotall: 292 293 True: see *re.DOTALL*, when set 294 295 False: default:=unset 296 297 exitign: 298 299 True: Ignores exit at all. 300 301 False: Does not ignore exit value. 302 303 exittype: 304 305 False|'nok': Success when exit is not 0. 306 307 True|'ok': Success when exit is 0. 308 309 'value': Success when exit is equal <exit-value>. 310 311 exitval=<exit-value>: A specific exit value indicating 312 success. 313 314 ignorecase: 315 316 True: see *re.IGNORECASE*, when set 317 318 False: default:=unset 319 320 multiline: 321 322 True: see *re.MULTILINE*, when set 323 324 False: default:=unset 325 326 priotype: 327 328 False|'nok': One failure state sets the whole case 329 to failure. This is the default. 330 331 True|'ok': One success state sets the whole case 332 to success. 333 334 weight: Choose larger values of counters. 335 336 <customcallback>: Custom callback with signature: 337 338 customcallback(self,ret) 339 340 self: Current instance. 341 342 ret: Data provided to apply. 343 344 reset: A reset dictionary, see 'rules_reset'. 345 346 result: Required sum of all matches for success, 347 else failure. 348 349 resultnok: Required sum of NOK matches for failure, 350 else success. 351 352 resultok: Required sum of OK matches for success, 353 else failure. 354 355 stderrnok: List of regular expressions for match on 356 STDERR, indicating failure. 357 358 Could contain app-cached precompiled 're'. 359 360 stderrok: List of regular expressions for match on 361 STDERR, indicating success. 362 363 Could contain app-cached precompiled 're'. 364 365 stdoutnok: List of regular expressions for match on 366 STDOUT, indicating failure. 367 368 Could contain app-cached precompiled 're'. 369 370 stdoutok: List of regular expressions for match on 371 STDOUT, indicating success. 372 373 Could contain app-cached precompiled 're'. 374 375 unicode: 376 377 True: see *re.UNICODE*, when set 378 379 False: default:=unset 380 381 Returns: 382 When successful returns 'True', else returns either 'False', 383 or raises an exception. 384 385 Raises: 386 passed through exceptions: 387 388 """ 389 _ret = True 390 _cnt = 0 391 392 for k,v in predef.iteritems(): 393 394 if k=='setdefault': # set predefined default rule set 395 # superposes reference values, reset changes in place 396 self.stderrnok = self.rules_default['stderrnok'] 397 self.stderrok = self.rules_default['stderrok'] 398 self.stdoutnok = self.rules_default['stdoutnok'] 399 self.stdoutok = self.rules_default['stdoutok'] 400 self.reset() 401 _cnt += 1 402 403 elif k=='reset': # set predefined reset rule set 404 self.reset() 405 406 # 407 # string match attributes 408 # 409 elif k=='multiline': 410 self.cflags &= re.MULTILINE 411 412 elif k=='ignorecase': 413 self.cflags &= re.IGNORECASE 414 415 elif k=='unicode': 416 self.cflags &= re.UNICODE 417 418 elif k=='dotall': 419 self.cflags &= re.DOTALL 420 421 elif k=='debug': 422 self.cflags &= re.DEBUG 423 424 # 425 # weight of types 426 # 427 elif k=='priotype': # weight priority type,current 2 values 428 if v in (True,) : 429 self.priotype = _P_OK 430 elif v in (False,): 431 self.priotype = _P_NOK 432 elif v.lower() in ('ok',) : 433 self.priotype = _P_OK 434 elif type(v) in (FunctionType,) : 435 self.priotype = _P_CUSTOM 436 self._pcustom = v 437 else: 438 self.priotype = _P_NOK 439 440 441 # 442 # required number of matches - first matching counter dominates 443 # 444 elif k=='result': # sum of result counter 445 self.result = v 446 447 elif k=='resultok': # required number of OK for success 448 self.resultok = v 449 450 elif k=='resultnok': # required number of NOK for success 451 self.resultnok = v 452 453 # 454 # mactch on: exit 455 # 456 elif k=='exitign': 457 if v: 458 self.exittype = _E_IGN 459 else: 460 if self.exittype == _E_IGN: 461 self.exittype = self.rules_default['exittype'] 462 self.exitign = v 463 _cnt += 1 464 elif k=='exittype': 465 if v in (True,) : 466 self.exittype = _E_OK 467 elif v in (False,) : 468 self.exittype = _E_NOK 469 elif v.lower() in ('ok',) : 470 self.exittype = _E_OK 471 elif v.lower() in ('value','val',) : 472 self.exittype = _E_VAL 473 else: 474 self.exittype = _E_NOK 475 _cnt += 1 476 elif k=='exitval': 477 self.exittype = _E_VAL 478 self.exitval = int(v) 479 _cnt += 1 480 481 # 482 # mactch on: STDERR 483 # 484 elif k=='stderrnok': 485 self.stderrchk = True 486 if not type(v) is list: 487 _v = [v] 488 else: 489 _v = v 490 for _ci in _v: 491 if _ci and type(_ci) in (str, unicode,): 492 _ci = re.compile(_ci,self.cflags) 493 if _ci: 494 self.stderrnok.append(_ci) 495 _cnt += 1 496 497 elif k=='stderrok': 498 self.stderrchk = True 499 if not type(v) is list: 500 _v = [v] 501 else: 502 _v = v 503 for _ci in _v: 504 if _ci and type(_ci) in (str, unicode,): 505 _ci = re.compile(_ci,self.cflags) 506 if _ci: 507 self.stderrok.append(_ci) 508 _cnt += 1 509 510 # 511 # mactch on: STDOUT 512 # 513 elif k=='stdoutnok': 514 self.stdoutchk = True 515 if not type(v) is list: 516 _v = [v] 517 else: 518 _v = v 519 for _ci in _v: 520 if _ci and type(_ci) in (str, unicode,): 521 _ci = re.compile(_ci,self.cflags) 522 if _ci: 523 self.stdoutnok.append(_ci) 524 _cnt += 1 525 526 elif k=='stdoutok': 527 self.stdoutchk = True 528 if not type(v) is list: 529 _v = [v] 530 else: 531 _v = v 532 for _ci in _v: 533 if _ci and type(_ci) in (str, unicode,): 534 _ci = re.compile(_ci,self.cflags) 535 if _ci: 536 self.stdoutok.append(_ci) 537 _cnt += 1 538 539 if not _cnt: 540 return False 541 return _ret
542
543 - def apply(self,ret):
544 """Apply rules on the input ret and weight the result. 545 546 The provided match patterns and values are matched onto the input, and the 547 number of matches is counted. 548 549 The number of required matches of sub-patterns has to be defined within the 550 regexpr, e.g. by:: 551 552 'abv{4}[^v]+' 553 554 this matches on:: 555 556 abvvvv 557 558 Args: 559 ret: Tuple received from 'SystemCalls'. 560 561 Returns: 562 When successful returns 'True', else returns either 'False', 563 or raises an exception. 564 565 Raises: 566 passed through exceptions: 567 568 """ 569 _result = self.default 570 571 572 #----------------------------- 573 # *** filter and count *** 574 #----------------------------- 575 576 # 577 # filter string patterns on STDERR 578 # 579 if self.stderrchk: # patterns for STDERR are provided 580 for _r in self.stderrok: 581 _mx = ret[2] 582 if type(_mx) == list: 583 _mx = '\n'.join(_mx) 584 _m = _r.search(_mx,self.cflags) 585 if type(_m) is NoneType: 586 continue 587 self.stderrok_matched.append(_mx) 588 self.stderrok_cnt += 1 589 self.resultok_cnt += 1 590 for _r in self.stderrnok: 591 _mx = ret[2] 592 if type(_mx) == list: 593 _mx = '\n'.join(_mx) 594 _m = _r.search(_mx,self.cflags) 595 if type(_m) is NoneType: 596 continue 597 self.stderrnok_matched.append(_mx) 598 self.stderrnok_cnt += 1 599 self.resultnok_cnt += 1 600 601 # 602 # filter string patterns on STDOUT 603 # 604 if self.stdoutchk: # patterns for STDOUT are provided 605 for _r in self.stdoutok: 606 _mx = ret[1] 607 if type(_mx) == list: 608 _mx = '\n'.join(_mx) 609 _m = _r.search(_mx,self.cflags) 610 if type(_m) is NoneType: 611 continue 612 self.stdoutok_matched.append(_mx) 613 self.stdoutok_cnt += 1 614 self.resultok_cnt += 1 615 for _r in self.stdoutnok: 616 _mx = ret[1] 617 if type(_mx) == list: 618 _mx = '\n'.join(_mx) 619 _m = _r.search(_mx,self.cflags) 620 if type(_m) is NoneType: 621 continue 622 self.stdoutnok_matched.append(_mx) 623 self.stdoutnok_cnt += 1 624 self.resultnok_cnt += 1 625 626 # sumup 627 self.result_cnt = self.resultok_cnt + self.resultnok_cnt 628 629 630 # 631 # filter exit 632 # 633 # check exit value - store condition for later correlation with priorities 634 # True: the requested exit value is matched 635 # False: did not match the requested exit value 636 # 637 self._exitcond = True 638 self._exitret = ret[0] 639 if self.exittype == _E_IGN: # ignore exit values 640 pass # exitconf == True 641 elif self.exittype == _E_OK: # check whether current exit is OK 642 self._exitcond = ret[0] == 0 643 elif self.exittype == _E_NOK: # check whether current exit is NOK 644 self._exitcond = ret[0] > 0 645 elif self.exittype == _E_VAL: # check whether present is predefined value 646 self._exitcond = self.exitval == ret[0] 647 648 649 #---------------------------------- 650 # *** priotype and countres *** 651 #---------------------------------- 652 653 # 654 # interpret the presence of specific partial results into overall resulting test status 655 # 656 657 # 658 # any failure dominates 659 # 660 if self.priotype == _P_NOK: # ignore OK, when at least one NOK defined/failure occured 661 if self.resultnok_cnt and self.resultnok_cnt >= self.resultnok: # threshold for expected failures 662 _result = False 663 elif self.resultok_cnt and self.resultok_cnt < self.resultok: # threshold for required success 664 _result = False 665 elif self.exitign: # no more failure criteria expected 666 if self.stderrok and self.stderrok_cnt == 0 or self.stdoutok and self.stdoutok_cnt == 0: 667 _result = False # no provided success criteria matched, thus define as failure 668 else: 669 _result = True # no failure criteria was provided, thus define as success 670 else: 671 _result = self._exitcond 672 673 674 # 675 # any success dominates 676 # 677 elif self.priotype == _P_OK: # ignore NOK, when at least one OK defined 678 if self.resultok_cnt and self.resultok_cnt >= self.resultok: # OK counter threshold match 679 _result = True 680 elif self.resultnok_cnt and self.resultnok_cnt < self.resultnok: # any is NOK 681 _result = True 682 elif self.exitign: # no more success criteria expected 683 if self.stderrok and self.stderrok_cnt or self.stdoutok and self.stdoutok_cnt: 684 _result = True 685 elif self.stderrnok and self.stderrnok_cnt == 0 or self.stdoutnok and not self.stdoutnok_cnt == 0: 686 _result = True 687 else: 688 _result = False 689 690 # if self.stderrnok and self.stderrnok_cnt or self.stdoutnok and self.stdoutnok_cnt: 691 # _result = False # no provided failure criteria matched, thus define as success 692 # else: 693 # _result = True # no failure criteria was provided, thus define as failure 694 else: 695 _result = self._exitcond 696 697 # 698 # weight the success and failures 699 # 700 elif self.priotype == _P_WEIGHT: # weight counters 701 _r = self._exitcond # default 702 703 # prep weight, required in any case 704 if self.resultok and self.resultnok: # both, weight 705 if self.resultok > self.resultok_cnt or self.resultnok > self.resultnok_cnt: 706 _r = False 707 else: 708 _r = self.resultok > self.resultnok 709 710 elif self.resultok: # ok only 711 _r = self.resultok > self.resultok_cnt 712 713 elif self.resultnok: # failure only 714 _r = self.resultnok > self.resultnok_cnt 715 716 717 if self.exitign: # weight counters only 718 return _r 719 720 return _r and self._exitcond # consider in addition exit value with priority 721 722 # 723 # custom callback 724 # 725 elif self.priotype == _P_CUSTOM: # weight counters 726 return self._pcustom(self,ret) 727 728 return _result
729
730 - def states(self):
731 """State values of current applied unittest. 732 733 The applied parameters are available by 'repr()'. 734 735 Args: 736 ret: Tuple received from 'SystemCalls'. 737 738 Returns: 739 Returns the state of the last 'apply' operation. 740 this is the result of the 'filter' and 'countres' 741 described in the manual by the syntax-tree:: 742 743 r = { 744 '_exitcond' = self._exitcond, # resulting after applied self.exittype 745 'exit' = self._exitret, # see _exitcond 746 'stderrnok' = self.stderrnok_matched, 747 'stderrok' = self.stderrok_matched, 748 'stdoutnok' = self.stdoutnok_matched, 749 'stdoutok' = self.stdoutok_matched, 750 751 'result' = self.result_cnt, 752 'resultnok' = self.resultnok_cnt, 753 'resultok' = self.resultok_cnt, 754 } 755 756 757 Raises: 758 passed through exceptions: 759 760 761 """ 762 _r = {} 763 _r['_exitcond'] = self._exitcond 764 _r['exit'] = self._exitret 765 766 _r['stderrnok'] = self.stderrnok_matched 767 _r['stderrok'] = self.stderrok_matched 768 _r['stdoutnok'] = self.stdoutnok_matched 769 _r['stdoutok'] = self.stdoutok_matched 770 771 _r['result'] = self.result_cnt 772 _r['resultnok'] = self.resultnok_cnt 773 _r['resultok'] = self.resultok_cnt 774 775 return _r
776
777 - def __str__(self):
778 """Prints current rule set. 779 """ 780 def _eenum(t): 781 _e = _exitenums.get(t) 782 if _e: return _e+"("+str(t)+")" 783 return str(t)
784 785 def _penum(t): 786 _e = _prioenums.get(t) 787 if _e: return _e+"("+str(t)+")" 788 return str(t)
789 790 ret = "" 791 ret += "\ndefault = "+str(self.default) 792 ret += "\nexitign = "+str(self.exitign) 793 ret += "\nexittype = "+str(_eenum(self.exittype)) 794 ret += "\nexitval = "+str(self.exitval) 795 ret += "\npriotype = "+str(_penum(self.priotype)) 796 ret += "\nresult = "+str(self.result) 797 ret += "\nresultok = "+str(self.resultok) 798 ret += "\nresultnok = "+str(self.resultnok) 799 ret += "\nstderrchk = "+str(self.stderrchk) 800 ret += "\nstderrok = "+str(self._re_pattern(self.stderrok)) 801 ret += "\nstderrnok = "+str(self._re_pattern(self.stderrnok)) 802 ret += "\nstdoutchk = "+str(self.stdoutchk) 803 ret += "\nstdoutok = "+str(self._re_pattern(self.stdoutok)) 804 ret += "\nstdoutnok = "+str(self._re_pattern(self.stdoutnok)) 805 return ret 806
807 - def _re_pattern(self,pat):
808 return [str(xi.pattern) for xi in pat]
809
810 - def __repr__(self):
811 """Represents current rule set. 812 """ 813 ret = "{" 814 ret += "'default': "+str(self.default) 815 ret += ", 'cflags': "+str(self.cflags) 816 ret += ", 'multiline': "+str(self.multiline) 817 ret += ", 'ignorecase': "+str(self.ignorecase) 818 ret += ", 'unicode': "+str(self.unicode) 819 ret += ", 'dotall': "+str(self.dotall) 820 ret += ", 'debug': "+str(self.debug) 821 ret += ", 'priotype': "+str(self.priotype) 822 ret += ", 'result': "+str(self.result) 823 ret += ", 'resultok': "+str(self.resultok) 824 ret += ", 'resultnok': "+str(self.resultnok) 825 ret += ", 'exitign': "+str(self.exitign) 826 ret += ", 'exittype': "+str(self.exittype) 827 ret += ", 'exitval': "+str(self.exitval) 828 ret += ", 'stderrchk': "+str(self.stderrchk) 829 ret += ", 'stderrnok': "+str(self.stderrnok) 830 ret += ", 'stderrok': "+str(self.stderrok) 831 ret += ", 'stdoutchk': "+str(self.stdoutchk) 832 ret += ", 'stdoutnok': "+str(self.stdoutnok) 833 ret += ", 'stdoutok': "+str(self.stdoutok) 834 ret += "}" 835 return ret
836
837 -class SubprocessUnit(SystemCalls):
838 """Wraps and checks results from execution of subprocesses by objects of class 'SProcUnitRules'. 839 840 """
841 - def __init__(self,**kargs):
842 """Prepares the caller interface for subprocess unit tests. 843 844 Args: 845 **kargs: Parameter specific for the operation, 846 passed through to **setkargs**. 847 848 Returns: 849 When successful returns 'True'. 850 851 Raises: 852 passed through exceptions: 853 854 """ 855 self.rules = None 856 857 super(SubprocessUnit,self).__init__(**kargs)
858 859 # kargs['noparent'] = True 860 # self.setkargs(**kargs) 861 # kargs.pop('noparent') 862
863 - def apply(self,res=None):
864 """Applies the linked rule set onto the res-data. 865 866 Args: 867 res: Result data to be filtered by a filter of type 868 'epyunit.SProcUnitRules'. 869 870 Returns: 871 When a rule set is present and could be applied successful 872 returns 'True', else either 'False', or raises an exception. 873 874 Raises: 875 passed through exceptions: 876 877 """ 878 if self.rules: 879 return self.rules.apply(res) 880 return False
881
882 - def displayit(self,ret,**kargs):
883 """Displays result list ret in selected format. 884 885 Args: 886 ret: Data to be displayed. 887 888 **kargs: 889 890 outtarget: The target of display: 891 892 str: return as formatted string 893 894 stdout: print to sys.stdout 895 896 stderr: print to sys.stderr 897 898 out: Output for display, valid: 899 900 csv : CSV with sparse records 901 902 pass : pass through STDOUT and STDERR from subprocess 903 904 repr : Python 'repr()' 905 906 str : Python 'str()' 907 908 xml : XML 909 910 default:=self.out 911 912 Returns: 913 When successful returns 914 915 outtarget=='str': returns a printable formatted string 916 917 outtarget in ('stdout', 'stderr',): 918 919 'True': for success 920 921 'False': for failure 922 923 Raises: 924 passed through exceptions: 925 926 """ 927 928 return super(SubprocessUnit,self).displayit(ret,**kargs)
929
930 - def setkargs(self,**kargs):
931 """Sets provided parameters for the subprocess call context. 932 933 Applicable for the initial call of self.__init__(), 934 and later modification. Called for each start of 935 a subprocess in order to update optional the specific 936 call context modification. 937 938 Calls the parent method by default, could be supressed 939 by option for the update of current objects class only. 940 941 Args: 942 **kargs: Parameters specific for the operations. 943 944 noparent: Suppress call of parent class. 945 946 rules: Sets the rules object to be used. 947 948 Returns: 949 When successful returns 'True', else returns either 'False', or 950 raises an exception. 951 952 Raises: 953 passed through exceptions: 954 955 """ 956 _ret = True 957 _args = kargs.copy() 958 _noparent = _args.get('noparent',False) 959 for k,v in kargs.iteritems(): 960 if k=='rules': 961 self.rules = v 962 _args.pop(k) 963 elif k=='noparent': 964 pass 965 966 if not _noparent: 967 _ret = super(SubprocessUnit,self).setkargs(**_args) 968 969 if not self.rules: 970 self.rules = SProcUnitRules(**kargs) 971 if not self.rules: 972 raise SubprocessUnitException("Failed to set rule set.") 973 974 return _ret
975 976 #FIXME: 977
978 - def setruleset(self,ruleset):
979 """Assigns the ruleset object as current. 980 981 Args: 982 ruleset: The ruleset to be applied as unittest. 983 Replaces any previous. 984 985 Returns: 986 Returns the previous value of ruleset. 987 If input is not an instance of 'SProcUnitRules' 988 returns 'None'. 989 990 Raises: 991 passed through exceptions: 992 993 """ 994 if not isinstance(ruleset,SProcUnitRules): 995 return None 996 _o = self.rules 997 self.rules = ruleset 998 return _o
999
1000 - def getruleset(self):
1001 """Returns the current ruleset. 1002 1003 Args: 1004 **kargs: Parameters passed transparently to 1005 created SProcUnitRules instance. 1006 1007 noparent: Suppress call of parent class. 1008 1009 Returns: 1010 Returns the current rules. 1011 1012 Raises: 1013 passed through exceptions: 1014 1015 """ 1016 return self.rules
1017
1018 - def get_proceed(self,s=None):
1019 """Verifies valid proceed type. 1020 1021 Args: 1022 s: Requested type for validation. 1023 1024 Returns: 1025 Supported types. 1026 1027 Raises: 1028 passed through exceptions: 1029 1030 """ 1031 if s is NoneType: 1032 return 'subprocunits' 1033 if s in ('subprocunits',): 1034 return s 1035 else: 1036 return super(SubprocessUnit,self).get_proceed(s)
1037
1038 - def __str__(self):
1039 """Prints the current unit parameters including parent. 1040 """ 1041 ret = super(SubprocessUnit,self).__str__() 1042 ret += "\n" 1043 ret += "\nSubprocessUnit.rules = "+str(self.rules.__class__.__name__) 1044 return ret
1045
1046 - def __repr__(self):
1047 """Prints the current representation of unit parameters including parent and ruleset. 1048 """ 1049 ret = super(SubprocessUnit,self).__repr__() 1050 ret = "{" + _parentrepr.sub(ur'\1', ret) 1051 ret += ", 'rules': "+self.rules.__class__.__name__ 1052 # ret += ", 'rules': "+str(self.rules.__name__) 1053 ret += "}" 1054 return ret
1055