forked from robotframework/robotframework
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathrun.py
executable file
·159 lines (133 loc) · 5.64 KB
/
run.py
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
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
#!/usr/bin/env python3
"""A script for running Robot Framework's own acceptance tests.
Usage: atest/run.py [-I name] [-S] [-R] [options] [data]
`data` is path (or paths) of the file or directory under the `atest/robot`
folder to execute. If `data` is not given, all tests except for tests tagged
with `no-ci` are executed.
Available `options` are in general normal Robot Framework options, but there
are some exceptions listed below.
By default, the same Python interpreter that is used for running this script is
also used for running tests. That can be changed by using the `--interpreter`
(`-I`) option. It can be the name of the interpreter like `pypy3` or a path to
the selected interpreter like `/usr/bin/python39`. If the interpreter itself
needs arguments, the interpreter and its arguments need to be quoted like
`"py -3.12"`.
To enable schema validation for all suites, use the `--schema-validation`
(`-S`) option. This is the same as setting the `ATEST_VALIDATE_OUTPUT`
environment variable to `TRUE`.
Use `--rerun-failed (`-R`)` to re-execute failed tests from the previous run.
The output directory is set based on the interpreter version and operating
system by default. It can be changed using the normal `--outputdir` option.
Examples:
$ atest/run.py
$ atest/run.py --exclude no-ci atest/robot/standard_libraries
$ atest/run.py --interpreter pypy3
$ atest/run.py --rerun-failed
The results of the test execution are written into an interpreter specific
directory under the `atest/results` directory. Temporary outputs created
during the execution are created under the system temporary directory.
"""
import argparse
import os
import shutil
import signal
import subprocess
import sys
import tempfile
from pathlib import Path
from interpreter import Interpreter
CURDIR = Path(__file__).parent
LATEST = str(CURDIR / 'results/{interpreter.output_name}-latest.xml')
ARGUMENTS = '''
--doc Robot Framework acceptance tests
--metadata interpreter:{interpreter}
--variable-file {variable_file};{interpreter.path};{interpreter.name};{interpreter.version}
--pythonpath {pythonpath}
--output-dir {output_dir}
--splitlog
--console dotted
--console-width 100
--suite-stat-level 3
--log NONE
--report NONE
'''.strip()
def atests(interpreter, arguments, output_dir=None, schema_validation=False):
output_dir, temp_dir = _get_directories(interpreter, output_dir)
arguments = list(_get_arguments(interpreter, output_dir)) + list(arguments)
rc = _run(arguments, temp_dir, interpreter, schema_validation)
if rc < 251:
_rebot(rc, output_dir, interpreter)
return rc
def _get_directories(interpreter, output_dir=None):
name = interpreter.output_name
if output_dir:
output_dir = Path(output_dir)
else:
output_dir = CURDIR / 'results' / name
temp_dir = Path(tempfile.gettempdir()) / 'robotatest' / name
if output_dir.exists():
shutil.rmtree(output_dir)
if temp_dir.exists():
shutil.rmtree(temp_dir)
os.makedirs(temp_dir)
return output_dir, temp_dir
def _get_arguments(interpreter, output_dir):
arguments = ARGUMENTS.format(interpreter=interpreter,
variable_file=CURDIR / 'interpreter.py',
pythonpath=CURDIR / 'resources',
output_dir=output_dir)
for line in arguments.splitlines():
yield from line.split(' ', 1)
for exclude in interpreter.excludes:
yield '--exclude'
yield exclude
def _run(args, tempdir, interpreter, schema_validation):
command = [str(c) for c in
[sys.executable, CURDIR.parent / 'src/robot/run.py'] + args]
environ = dict(os.environ,
TEMPDIR=str(tempdir),
PYTHONCASEOK='True',
PYTHONIOENCODING='',
PYTHONWARNDEFAULTENCODING='True')
if schema_validation:
environ['ATEST_VALIDATE_OUTPUT'] = 'TRUE'
print(f"{interpreter}\n{interpreter.underline}\n")
print(f"Running command:\n{' '.join(command)}\n")
sys.stdout.flush()
signal.signal(signal.SIGINT, signal.SIG_IGN)
return subprocess.call(command, env=environ)
def _rebot(rc, output_dir, interpreter):
output = output_dir / 'output.xml'
if rc == 0:
print('All tests passed, not generating log or report.')
else:
command = [sys.executable, str(CURDIR.parent / 'src/robot/rebot.py'),
'--output-dir', str(output_dir), str(output)]
subprocess.call(command)
latest = Path(LATEST.format(interpreter=interpreter))
latest.unlink(missing_ok=True)
shutil.copy(output, latest)
if __name__ == '__main__':
parser = argparse.ArgumentParser(add_help=False)
parser.add_argument('-I', '--interpreter', default=sys.executable)
parser.add_argument('-S', '--schema-validation', action='store_true')
parser.add_argument('-R', '--rerun-failed', action='store_true')
parser.add_argument('-d', '--outputdir')
parser.add_argument('-h', '--help', action='store_true')
options, robot_args = parser.parse_known_args()
try:
interpreter = Interpreter(options.interpreter)
except ValueError as err:
sys.exit(str(err))
if options.rerun_failed:
robot_args[:0] = ['--rerun-failed', LATEST.format(interpreter=interpreter)]
last = Path(robot_args[-1]) if robot_args else None
source_given = last and (last.is_dir() or last.is_file() and last.suffix == '.robot')
if not source_given:
robot_args += ['--exclude', 'no-ci', CURDIR / 'robot']
if options.help:
print(__doc__)
rc = 251
else:
rc = atests(interpreter, robot_args, options.outputdir, options.schema_validation)
sys.exit(rc)