1#!/usr/local/bin/python3.8
2import sys
3import os
4import re
5import argparse
6import sqlite3
7import subprocess
8import wudb
9
10def do_check(acc, wu, programs):
11    result = None
12    if wu["files"] is None:
13        return result
14    for file in wu["files"]:
15        (filename, filepath) = (file["filename"], file["path"])
16        for (progname, pattern) in programs:
17            m = re.match(pattern, filename)
18            if m is None:
19                continue
20            assert m.start() == 0
21            # Check that the whole string matched the pattern,
22            # not just a prefix
23            if not m.end() == len(filename):
24                continue
25            command = progname + " " + filepath
26            print ("Running: " + command)
27            child = subprocess.Popen(command, shell=True,
28                                     stdout = subprocess.PIPE,
29                                     stderr = subprocess.PIPE)
30            (child_stdout, child_stderr) = child.communicate()
31            print ("Return code is " + str (child.returncode))
32            if child.returncode == 0:
33                result = True
34            else:
35                return False
36    return result
37
38if __name__ == "__main__":
39    description = "Run a verification tool on files of received work units"
40    epilog = "For each WU processed, run PROGRAM on those files of the WU whose filenames match REGEX. " + \
41             "The client side filename (as specified in a RESULT line of a WU) is used for the REGEX match. " + \
42             "Multiple programs can be specified; each program is run for any file(s) that match the respective REGEX. " + \
43             "If the exit status of the PROGRAMs is zero for all tested files of a WU, the WU is considered verified ok. " + \
44             "If the exit status is non-zero for any tested file, the WU is considered verified with error. " + \
45             "The database is updated accordingly only if --update is given; otherwise only output to screen (and badidealsfile if specified) happens."
46
47    wudb_name = "wudb"
48    parser = argparse.ArgumentParser(description=description, epilog = epilog)
49    parser.add_argument('-f', '--file', action = 'store',
50                        help = "Does nothing")
51    parser.add_argument('-p', '--program', nargs = 2, required = True,
52                        action = 'append', metavar=('PROGRAM', 'REGEX'),
53                        help = "run PROGRAM on files whose names match REGEX")
54    parser.add_argument('--wudb', action = 'store', default = wudb_name,
55                        metavar = "FILE", help = "use FILE as Workunit DB")
56    parser.add_argument('--badidealsfile', action = 'store',
57                        metavar = "FILE", help = "dump text of failed workunits to FILE")
58    parser.add_argument('-r', '--received', action = 'store_true',
59                        help = 'Process all workunits currently marked as received without error')
60    parser.add_argument('--update', action = 'store_true',
61                        help = 'Update status of processed WUs to verified with/without error according to test result')
62    args = parser.parse_args()
63
64    if "wudb" in args:
65        wudb_name = args.wudb
66
67    acc = wudb.WuAccess(wudb_name)
68
69    if "file" in args:
70        # find wu for this file
71        # do_check(acc, wu)
72        pass
73
74    if args.received:
75        # Test all workunits whose status is RECEIVED_OK
76        received = acc.query(eq={"status": wudb.WuStatus.RECEIVED_OK})
77        badidealsfile = None
78        print ("Found " + str(len(received)) + " workunits")
79        for wu in received:
80            result = do_check(acc, wu, list(args.program))
81            if result is None:
82                print ("Warning: none of the supplied programs matched for workunit "
83                       + wu["wuid"])
84            else:
85                if result == True:
86                    print ("Workunit " + wu["wuid"] + " verified ok")
87                elif result == False:
88                    print ("Workunit " + wu["wuid"] + " verified with error")
89                    if args.badidealsfile:
90                        if badidealsfile is None:
91                            badidealsfile = open(args.badidealsfile, "a")
92                        badidealsfile.write(wu["wu"] + '\n')
93            if args.update:
94                acc.verification(wu["wuid"], result)
95        if not badidealsfile is None:
96            badidealsfile.close()
97