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