test.py 2.5 KB
Newer Older
Maxime Perrotin's avatar
Maxime Perrotin committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#!/usr/bin/env python3
import subprocess
import sys
import time
import signal
import os
from functools       import partial
from multiprocessing import cpu_count
from concurrent      import futures


def colorMe(result, msg):
    if sys.stdout.isatty():
        code = "1" if result else "2"
        msg = chr(27) + "[3" + code + "m" + msg + chr(27) + "[0m"
    return msg

def main():
    ''' Run the test cases in parallel on all available CPUs '''
    start = time.time()
    results = []
    rule = sys.argv[1]
    paths = sys.argv[2:]

    with futures.ProcessPoolExecutor(max_workers=cpu_count()) as executor:
        for result in executor.map(partial(make, rule), paths):
27
            print("%40s: %s" % (result[3].replace("/", ""), colorMe(result[0],
Maxime Perrotin's avatar
Maxime Perrotin committed
28
                               '[OK]' if result[0]==0 else '[FAILED]')))
29
            sys.stdout.flush()
Maxime Perrotin's avatar
Maxime Perrotin committed
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
            results.append(result)
        executor.map(partial(make, 'clean'), paths)
    sys.stdout.write('\n')

    elapsed = time.time() - start
    return summarize(results, elapsed)


def make(rule, path):
    ''' Call a Makefile with the required rule (e.g. build or clean) '''
    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):
    ''' At the end display the errors of project that failed '''
    failed = 0
Maxime Perrotin's avatar
Maxime Perrotin committed
53
54
55
    with open("/tmp/kazoo.err", "w") as f:
        f.write("kazoo test report")
        f.write("-----------------")
Maxime Perrotin's avatar
Maxime Perrotin committed
56
57
58
59
    for errcode, stdout, stderr, path, rule in results:
        if errcode == 0:
            continue
        failed += 1
Maxime Perrotin's avatar
Maxime Perrotin committed
60
61
62
63
64
65
66
67
68
69
        with open("/tmp/kazoo.err", 'a') as f:
            f.write("=" * 80)
            f.write("ERROR: %s %s" % (path, rule))
            if stdout:
                f.write("-- stdout " + "-" * 70)
                f.write(stdout.decode())
            if stderr:
                f.write("-- stderr " + "-" * 70)
                f.write(stderr.decode())
                f.write("-" * 80)
Maxime Perrotin's avatar
Maxime Perrotin committed
70
    print("Finished in %.3fs" % elapsed)
Maxime Perrotin's avatar
Maxime Perrotin committed
71
72
    if failed:
        print("Test report in /tmp/kazoo.err")
Maxime Perrotin's avatar
Maxime Perrotin committed
73
74
75
76
77
78
79
80
81
82
83
    print("%s tests, %s errors" % (len(results), failed))
    return 0 if not failed else 1


if __name__ == '__main__':
    # Catch Ctrl-C to stop the app from the console
    signal.signal(signal.SIGINT, signal.SIG_DFL)
    ret = main()
    sys.stdout.write('\033[0m\n')
    sys.stdout.flush()
    sys.exit(ret)