/
gramine-test
executable file
·134 lines (109 loc) · 4.68 KB
/
gramine-test
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
#!/usr/bin/python3
# SPDX-License-Identifier: LGPL-3.0-or-later
# Copyright (C) 2021 Intel Corporation
# Paweł Marczewski <pawel@invisiblethingslab.com>
import os
import subprocess
import sys
import click
from graminelibos import util_tests, _CONFIG_SGX_ENABLED
def change_dir(_ctx, _param, value):
if value:
os.chdir(value)
@click.group(help='Helper program for running Gramine tests.')
@click.option('--sgx/--no-sgx', default=(os.environ.get('SGX') == '1'),
help='Enable SGX mode (you can also set SGX=1 before running)')
@click.option('--conf-file-name', '-n', type=click.Path(exists=True, dir_okay=False),
default='tests.toml', help='Configuration file name to use')
@click.option('--directory', '-C', callback=change_dir, expose_value=False, is_eager=True,
metavar='dir', type=click.Path(file_okay=False),
help='Change directory before running')
@click.pass_context
def main(ctx, sgx, conf_file_name):
if sgx and not _CONFIG_SGX_ENABLED:
raise click.ClickException('This version of Gramine is built without SGX')
ctx.obj = {
'sgx': sgx,
'conf_file_name': conf_file_name,
}
@main.command(help='Rebuild the build.ninja file. Used internally by Ninja.')
@click.pass_context
def regenerate(ctx):
util_tests.gen_build_file(ctx.obj['conf_file_name'])
@main.command(help='Rebuild manifests. This rebuilds either all manifests, or the specified ones.')
@click.pass_context
@click.option('--force/--no-force', '-f', help='Force rebuild')
@click.option('--verbose/--quiet', '-v/-q', help='Show all command lines while building')
@click.argument('names', type=str, nargs=-1)
def build(ctx, force, verbose, names):
sgx = ctx.obj['sgx']
names = [strip_suffix(name) for name in names]
rebuild(sgx, ctx.obj['conf_file_name'], *names, force=force, verbose=verbose)
@main.command(help='Remove all generated files.')
@click.pass_context
def clean(ctx):
util_tests.gen_build_file(ctx.obj['conf_file_name'])
try:
util_tests.run_ninja(['-t', 'clean', '-g'])
except subprocess.CalledProcessError as e:
sys.exit(e.returncode)
for name in ['.ninja_deps', '.ninja_log']:
if os.path.exists(name):
print(f'deleting {name}')
os.unlink(name)
@main.command(
help='Run Gramine on a test program, rebuilding the manifest first. '
'Arguments will be passed to the test program.',
context_settings={'ignore_unknown_options': True},
)
@click.option('--force/--no-force', '-f', help='Force rebuild')
@click.option('--verbose/--quiet', '-v/-q',
help='Show all command lines while building')
@click.argument('name', type=str)
@click.argument('args', nargs=-1, type=click.UNPROCESSED)
@click.pass_context
def run(ctx, force, verbose, name, args):
sgx = ctx.obj['sgx']
name = strip_suffix(name)
rebuild(sgx, ctx.obj['conf_file_name'], name, force=force, verbose=verbose)
util_tests.exec_gramine(sgx, name, args)
# NOTE: We do not accept the `-v/-q` short options in the below command, because Pytest accepts the
# same options. We could instruct the user to run `gramine-test pytest -- -v` as a workaround, but
# that would make `gramine-test` harder to use.
@main.command(
help='Run Pytest, rebuilding all manifests first. Arguments will be passed to Pytest.',
context_settings={'ignore_unknown_options': True},
)
@click.option('--force/--no-force', '-f', help='Force rebuild')
@click.option('--verbose/--quiet', help='Show all command lines while building')
@click.argument('args', nargs=-1, type=click.UNPROCESSED)
@click.pass_context
def pytest(ctx, force, verbose, args):
sgx = ctx.obj['sgx']
rebuild(sgx, ctx.obj['conf_file_name'], force=force, verbose=verbose)
util_tests.exec_pytest(sgx, args)
def strip_suffix(name):
'''
Retrieve manifest name without suffix. Allows the user to pass *.manifest or *.manifest.template
files (e.g. using tab-completion).
'''
for suffix in ('.manifest.template', '.manifest'):
if name.endswith(suffix):
return name[:-len(suffix)]
return name
def rebuild(sgx, conf_file_name, *names, force=False, verbose=False):
util_tests.gen_build_file(conf_file_name)
verbosity = ['-v'] if verbose else []
host = 'sgx' if sgx else 'direct'
if names:
targets = [f'{host}-{name}' for name in names]
else:
targets = [host]
try:
if force:
util_tests.run_ninja(verbosity + ['-t', 'clean'] + targets)
util_tests.run_ninja(verbosity + targets)
except subprocess.CalledProcessError as e:
sys.exit(e.returncode)
if __name__ == '__main__':
main() # pylint: disable=no-value-for-parameter