test.py 2.17 KB
Newer Older
Maxime Perrotin's avatar
Maxime Perrotin committed
1
#!/usr/bin/env python3
dbarbera's avatar
dbarbera committed
2
3
4
import subprocess
import sys
import time
Maxime Perrotin's avatar
Maxime Perrotin committed
5
import signal
6
7
import os
from functools import partial
8
from multiprocessing import cpu_count
Maxime Perrotin's avatar
Maxime Perrotin committed
9
from concurrent import futures
10
11
12
13


def colorMe(result, msg):
    if sys.stdout.isatty():
Maxime Perrotin's avatar
Maxime Perrotin committed
14
        code = "1" if result else "2"
15
16
        msg = chr(27) + "[3" + code + "m" + msg + chr(27) + "[0m"
    return msg
dbarbera's avatar
dbarbera committed
17
18

def main():
19
    ''' Run the test cases in parallel on all available CPUs '''
dbarbera's avatar
dbarbera committed
20
21
    start = time.time()
    results = []
dbarbera's avatar
dbarbera committed
22
23
24
    rule = sys.argv[1]
    paths = sys.argv[2:]

25
    with futures.ProcessPoolExecutor(max_workers=cpu_count()) as executor:
Maxime Perrotin's avatar
Maxime Perrotin committed
26
27
28
        for result in executor.map(partial(make, rule), paths):
            print("%40s: %s" % (result[3], colorMe(result[0],
                               '[OK]' if result[0]==0 else '[FAILED]')))
29
            results.append(result)
Maxime Perrotin's avatar
Maxime Perrotin committed
30
        executor.map(partial(make, 'clean'), paths)
dbarbera's avatar
dbarbera committed
31
32
33
    sys.stdout.write('\n')

    elapsed = time.time() - start
34
    return summarize(results, elapsed)
dbarbera's avatar
dbarbera committed
35
36


37
def make(rule, path):
38
    ''' Call a Makefile with the required rule (e.g. test-ada or clean) '''
dbarbera's avatar
dbarbera committed
39
40
41
42
43
44
45
46
47
48
49
    proc = subprocess.Popen(
        ['make', '-C', path, rule],
        stdout=subprocess.PIPE,
        stderr=subprocess.PIPE
    )
    stdout, stderr = proc.communicate()
    errcode = proc.wait()
    return (errcode, stdout, stderr, path, rule)


def summarize(results, elapsed):
50
    ''' At the end display the errors of project that failed '''
dbarbera's avatar
dbarbera committed
51
52
53
54
55
    failed = 0
    for errcode, stdout, stderr, path, rule in results:
        if errcode == 0:
            continue
        failed += 1
Maxime Perrotin's avatar
Maxime Perrotin committed
56
57
        print("=" * 80)
        print("ERROR: %s %s" % (path, rule))
dbarbera's avatar
dbarbera committed
58
        if stdout:
Maxime Perrotin's avatar
Maxime Perrotin committed
59
            print("-- stdout " + "-" * 70)
60
            print(stdout.decode())
dbarbera's avatar
dbarbera committed
61
        if stderr:
Maxime Perrotin's avatar
Maxime Perrotin committed
62
            print("-- stderr " + "-" * 70)
63
            print(stderr.decode())
Maxime Perrotin's avatar
Maxime Perrotin committed
64
65
66
            print("-" * 80)
    print("Finished in %.3fs" % elapsed)
    print("%s tests, %s errors" % (len(results), failed))
dbarbera's avatar
dbarbera committed
67
68
69
70
71

    return 0 if not failed else 1


if __name__ == '__main__':
Maxime Perrotin's avatar
Maxime Perrotin committed
72
73
    # Catch Ctrl-C to stop the app from the console
    signal.signal(signal.SIGINT, signal.SIG_DFL)
74
75
76
77
    ret = main()
    sys.stdout.write('\033[0m\n')
    sys.stdout.flush()
    sys.exit(ret)