| import os | |
| import sys | |
| import argparse | |
| import re | |
| class Checks(object): | |
| class CheckError(Exception): | |
| pass | |
| def __init__(self, filename, prefix): | |
| self.checks = [] | |
| self.lines = [] | |
| self.check_no_output = False | |
| self.filename = filename | |
| self.prefix = prefix | |
| def readStdin(self): | |
| self.lines = [l.rstrip("\r\n") for l in sys.stdin.readlines()] | |
| def readChecks(self): | |
| with open(self.filename) as f: | |
| for line in f: | |
| match = re.search("{}: NO_OUTPUT".format(self.prefix), line) | |
| if match is not None: | |
| self.check_no_output = True | |
| return | |
| match = re.search( | |
| "{}: num_threads=([0-9]+) (.*)$".format(self.prefix), line | |
| ) | |
| if match is not None: | |
| num_threads = int(match.group(1)) | |
| for i in range(num_threads): | |
| self.checks.append(match.group(2)) | |
| continue | |
| def check(self): | |
| # If no checks at all, then nothing to do | |
| if len(self.checks) == 0 and not self.check_no_output: | |
| print("Nothing to check for") | |
| return | |
| # Check if we are expecting no output | |
| if self.check_no_output: | |
| if len(self.lines) == 0: | |
| return | |
| else: | |
| raise Checks.CheckError( | |
| "{}: Output was found when expecting none.".format(self.prefix) | |
| ) | |
| # Run through each check line and see if it exists in the output | |
| # If it does, then delete the line from output and look for the | |
| # next check line. | |
| # If you don't find the line then raise Checks.CheckError | |
| # If there are extra lines of output then raise Checks.CheckError | |
| for c in self.checks: | |
| found = False | |
| index = -1 | |
| for idx, line in enumerate(self.lines): | |
| if re.search(c, line) is not None: | |
| found = True | |
| index = idx | |
| break | |
| if not found: | |
| raise Checks.CheckError("{}: Did not find: {}".format(self.prefix, c)) | |
| else: | |
| del self.lines[index] | |
| if len(self.lines) != 0: | |
| raise Checks.CheckError( | |
| "{}: Extra output: {}".format(self.prefix, self.lines) | |
| ) | |
| # Setup argument parsing | |
| parser = argparse.ArgumentParser( | |
| description="""This script checks output of | |
| a program against "CHECK" lines in filename""" | |
| ) | |
| parser.add_argument("filename", default=None, help="filename to check against") | |
| parser.add_argument( | |
| "-c", | |
| "--check-prefix", | |
| dest="prefix", | |
| default="CHECK", | |
| help="check prefix token default: %(default)s", | |
| ) | |
| command_args = parser.parse_args() | |
| # Do the checking | |
| checks = Checks(command_args.filename, command_args.prefix) | |
| checks.readStdin() | |
| checks.readChecks() | |
| checks.check() |