-
Notifications
You must be signed in to change notification settings - Fork 134
Expand file tree
/
Copy pathpkg_test.py
More file actions
153 lines (118 loc) · 4.15 KB
/
pkg_test.py
File metadata and controls
153 lines (118 loc) · 4.15 KB
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
import subprocess as sp
import tempfile
import tarfile
import os
import shlex
import logging
from . import utils
from conda_build.metadata import MetaData
logger = logging.getLogger(__name__)
def get_tests(path):
"Extract tests from a built package"
tmp = tempfile.mkdtemp()
t = tarfile.open(path)
t.extractall(tmp)
input_dir = os.path.join(tmp, 'info', 'recipe')
tests = []
recipe_meta = MetaData(input_dir)
tests_commands = recipe_meta.get_value('test/commands')
tests_imports = recipe_meta.get_value('test/imports')
requirements = recipe_meta.get_value('requirements/run')
if tests_imports or tests_commands:
if tests_commands:
tests.append(' && '.join(tests_commands))
if tests_imports and 'python' in requirements:
tests.append(
' && '.join('python -c "import %s"' % imp
for imp in tests_imports)
)
elif tests_imports and (
'perl' in requirements or 'perl-threaded' in requirements
):
tests.append(
' && '.join('''perl -e "use %s;"''' % imp
for imp in tests_imports)
)
tests = ' && '.join(tests)
tests = tests.replace('$R ', 'Rscript ')
# this is specific to involucro, the way how we build our containers
tests = tests.replace('$PREFIX', '/usr/local/')
tests = tests.replace('${PREFIX}', '/usr/local/')
return tests
def get_image_name(path):
"""
Returns name of generated docker image.
Parameters
----------
path : str
Path to .tar.by2 package build by conda-build
"""
assert path.endswith('.tar.bz2')
pkg = os.path.basename(path).replace('.tar.bz2', '')
toks = pkg.split('-')
build_string = toks[-1]
version = toks[-2]
name = '-'.join(toks[:-2])
spec = '%s=%s--%s' % (name, version, build_string)
return spec
def test_package(
path,
name_override=None,
channels=["conda-forge", "defaults"],
mulled_args="",
base_image=None
):
"""
Tests a built package in a minimal docker container.
Parameters
----------
path : str
Path to a .tar.bz2 package built by conda-build
name_override : str
Passed as the --name-override argument to mulled-build
channels : None | str | list
The local channel of the provided package will be added automatically;
`channels` are channels to use in addition to the local channel.
mulled_args : str
Mechanism for passing arguments to the mulled-build command. They will
be split with shlex.split and passed to the mulled-build command. E.g.,
mulled_args="--dry-run --involucro-path /opt/involucro"
base_image : None | str
Specify custom base image. Busybox is used in the default case.
"""
assert path.endswith('.tar.bz2'), "Unrecognized path {0}".format(path)
# assert os.path.exists(path), '{0} does not exist'.format(path)
conda_bld_dir = os.path.abspath(os.path.dirname(os.path.dirname(path)))
sp.check_call([utils.bin_for('conda'), 'index', os.path.dirname(path)])
spec = get_image_name(path)
extra_channels = ['file://{0}'.format(conda_bld_dir)]
if channels is None:
channels = []
if isinstance(channels, str):
channels = [channels]
extra_channels.extend(channels)
channel_args = ['--extra-channels', ','.join(extra_channels)]
tests = get_tests(path)
logger.debug('Tests to run: %s', tests)
target = 'biocontainers'
if os.environ.get('QUAY_TARGET') is not None:
target = os.environ.get('QUAY_TARGET')
cmd = [
'mulled-build',
'build-and-test',
spec,
'-n', target,
'--test', tests
]
if name_override:
cmd += ['--name-override', name_override]
cmd += channel_args
cmd += shlex.split(mulled_args)
logger.debug('mulled-build command: %s' % cmd)
env = os.environ.copy()
if base_image is not None:
env["DEST_BASE_IMAGE"] = base_image
with tempfile.TemporaryDirectory() as d:
with utils.Progress():
p = utils.run(cmd, env=env, cwd=d)
return p