1import os 2import sys 3import argparse 4import re 5 6 7class Checks(object): 8 class CheckError(Exception): 9 pass 10 11 def __init__(self, filename, prefix): 12 self.checks = [] 13 self.lines = [] 14 self.check_no_output = False 15 self.filename = filename 16 self.prefix = prefix 17 18 def readStdin(self): 19 self.lines = [l.rstrip("\r\n") for l in sys.stdin.readlines()] 20 21 def readChecks(self): 22 with open(self.filename) as f: 23 for line in f: 24 match = re.search("{}: NO_OUTPUT".format(self.prefix), line) 25 if match is not None: 26 self.check_no_output = True 27 return 28 match = re.search( 29 "{}: num_threads=([0-9]+) (.*)$".format(self.prefix), line 30 ) 31 if match is not None: 32 num_threads = int(match.group(1)) 33 for i in range(num_threads): 34 self.checks.append(match.group(2)) 35 continue 36 37 def check(self): 38 # If no checks at all, then nothing to do 39 if len(self.checks) == 0 and not self.check_no_output: 40 print("Nothing to check for") 41 return 42 # Check if we are expecting no output 43 if self.check_no_output: 44 if len(self.lines) == 0: 45 return 46 else: 47 raise Checks.CheckError( 48 "{}: Output was found when expecting none.".format(self.prefix) 49 ) 50 # Run through each check line and see if it exists in the output 51 # If it does, then delete the line from output and look for the 52 # next check line. 53 # If you don't find the line then raise Checks.CheckError 54 # If there are extra lines of output then raise Checks.CheckError 55 for c in self.checks: 56 found = False 57 index = -1 58 for idx, line in enumerate(self.lines): 59 if re.search(c, line) is not None: 60 found = True 61 index = idx 62 break 63 if not found: 64 raise Checks.CheckError("{}: Did not find: {}".format(self.prefix, c)) 65 else: 66 del self.lines[index] 67 if len(self.lines) != 0: 68 raise Checks.CheckError( 69 "{}: Extra output: {}".format(self.prefix, self.lines) 70 ) 71 72 73# Setup argument parsing 74parser = argparse.ArgumentParser( 75 description="""This script checks output of 76 a program against "CHECK" lines in filename""" 77) 78parser.add_argument("filename", default=None, help="filename to check against") 79parser.add_argument( 80 "-c", 81 "--check-prefix", 82 dest="prefix", 83 default="CHECK", 84 help="check prefix token default: %(default)s", 85) 86command_args = parser.parse_args() 87# Do the checking 88checks = Checks(command_args.filename, command_args.prefix) 89checks.readStdin() 90checks.readChecks() 91checks.check() 92