aboutsummaryrefslogtreecommitdiffstats
path: root/runtest-junitxml.py
blob: 380891dde7c157b15d2d28ce1f0387b890b750b8 (plain)
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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
#!/usr/bin/python

# Alternative executor for m3ua tests suite by Michael Tuexen's nplab
# (C) 2017 by Harald Welte <laforge@gnumonks.org>

from optparse import OptionParser
import os, sys, signal, time
from subprocess import Popen, PIPE
from junit_xml import TestSuite, TestCase

PROTO='m3ua'
GUILE='/usr/bin/guile'
COMMAND_SKEL="""
    (load-from-path "%s/.guile")
    (let ((test-name "%s"))
      (if (defined? (string->symbol test-name))
          (exit ((eval-string test-name)
                 tester-addr tester-port sut-addr sut-port))
          (exit 254)))
          """;

TEST='%s-test' % PROTO

def status2tc(testcase, exitstatus, time_passed=0, stdout=None, stderr=None):
    tc = TestCase(testcase, TEST, time_passed, stdout, stderr)
    if exitstatus == 0:
        return tc
    elif exitstatus == 1:
        tc.add_failure_info('FAILED')
    elif exitstatus == 2:
        tc.add_error_info('UNKNOWN')
    elif exitstatus == 252:
        tc.add_error_info('TIMEOUT')
    elif exitstatus == 253:
        tc.add_skipped_info('NON-APPLICABLE')
    elif exitstatus == 254:
        tc.add_error_info('NON-EXISTENT')
    elif exitstatus == 255:
        tc.add_error_info("COULDN'T START GUILE")
    else:
        tc.add_error_info("BUG")
    return tc

def signal_handler(signum, frame):
    raise IOError("Timeout!")

def start_testcase(directory, testcase, timeout=0):
    cmd = COMMAND_SKEL % (directory, testcase)
    signal.signal(signal.SIGALRM, signal_handler)
    signal.alarm(timeout)
    before = time.time()
    my_env = os.environ
    my_env["GUILE_WARN_DEPRECATED"] = "no"
    my_env["GUILE_AUTO_COMPILE"] = "0"
    p = Popen([GUILE, '-L', directory, '-c', cmd], env=my_env, stdout=PIPE, stderr=PIPE)
    try:
        (tc_stdout, tc_stderr) = p.communicate()
        returncode = p.returncode
    except IOError:
        tc_stdout = tc_stderr = None
        returncode = 252
    signal.alarm(0)
    after = time.time()
    return status2tc(testcase, returncode, after-before, tc_stdout, tc_stderr)

def parse_options():
    parser = OptionParser(usage="usage: %prog [options] test-case-list.txt")
    parser.add_option('-d', '--directory', dest='directory', metavar='DIR',
                    help='Directory where to look for .guile file',
                    default=os.environ['HOME'])
    parser.add_option('-t', '--timeout', dest='timeout', metavar='TOUT',
                    help='Timeout for individual test case in sconds',
                    default=60, type='int')
    parser.add_option('-s', '--sleep', dest='sleep', metavar='SLEEP',
                    help='Sleep for given amount of time in between tests',
                    default=0, type='float')

    (options, args) = parser.parse_args()

    if len(args) < 1:
        parser.error('You must specify a test list file name')

    return options, args



(options, args) = parse_options()

with open(args[0]) as f:
    cases = f.read().splitlines()

tcs = []

for c in cases:
    res = start_testcase(options.directory, c, timeout=options.timeout)
    tcs.append(res)
    time.sleep(options.sleep)

ts = TestSuite(TEST, tcs)
print(TestSuite.to_xml_string([ts]))