commit | author | age
|
9c75c0
|
1 |
# |
NJ |
2 |
# CDDL HEADER START |
|
3 |
# |
|
4 |
# The contents of this file are subject to the terms of the |
|
5 |
# Common Development and Distribution License (the "License"). |
|
6 |
# You may not use this file except in compliance with the License. |
|
7 |
# |
|
8 |
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE |
|
9 |
# or http://www.opensolaris.org/os/licensing. |
|
10 |
# See the License for the specific language governing permissions |
|
11 |
# and limitations under the License. |
|
12 |
# |
|
13 |
# When distributing Covered Code, include this CDDL HEADER in each |
|
14 |
# file and include the License file at usr/src/OPENSOLARIS.LICENSE. |
|
15 |
# If applicable, add the following below this CDDL HEADER, with the |
|
16 |
# fields enclosed by brackets "[]" replaced with your own identifying |
|
17 |
# information: Portions Copyright [yyyy] [name of copyright owner] |
|
18 |
# |
|
19 |
# CDDL HEADER END |
|
20 |
# |
8beffa
|
21 |
# Copyright (c) 2010, 2016, Oracle and/or its affiliates. All rights reserved. |
9c75c0
|
22 |
# |
NJ |
23 |
|
7c8106
|
24 |
# |
MT |
25 |
# The Python build infrastructure in setup.py.mk and pyproject.mk files uses |
|
26 |
# several Python projects to work properly. Since we cannot use these projects |
|
27 |
# until they are actually built and installed we need to bootstrap. |
|
28 |
# |
|
29 |
# We do have several sequential bootstrap checkpoints during the process: |
|
30 |
# |
|
31 |
# (0) Nothing works yet. |
|
32 |
# |
|
33 |
# Just core Python runtime is available (with no additional projects). |
|
34 |
# While here almost nothing works. We cannot do following tasks with |
|
35 |
# regular Python projects: |
|
36 |
# - detect their requirements, |
|
37 |
# - build and publish them, |
|
38 |
# - test them. |
|
39 |
# |
|
40 |
# (1) The bootstrapper is ready. |
|
41 |
# |
|
42 |
# The bootstrapper is special tool that requires just core Python with no |
|
43 |
# dependency on other Python projects and it is able to build and publish |
|
44 |
# itself and other Python projects. |
|
45 |
# |
|
46 |
# For projects using the 'setup.py' build style we do not need any |
|
47 |
# special bootstrapper because such projects are built using their own |
|
48 |
# 'setup.py' script. The only issue with the 'setup.py' build style |
|
49 |
# projects is that their 'setup.py' script usually depends on some other |
|
50 |
# projects (typically setuptools) to get successfully built. |
|
51 |
# |
|
52 |
# For 'pyproject'-style projects we use pyproject_installer as the |
|
53 |
# bootstrapper. |
|
54 |
# |
|
55 |
# To achieve this checkpoint we just need to build pyproject_installer |
|
56 |
# using pyproject_installer without detecting its requirements (they are |
6b1855
|
57 |
# none anyway) and without testing it (since no testing infrastructure is |
7c8106
|
58 |
# ready yet). |
MT |
59 |
# |
|
60 |
# (2) The python-requires script works. |
|
61 |
# |
|
62 |
# Once the python-requires script works we can start to detect runtime |
|
63 |
# dependencie of other Python projects automatically. |
|
64 |
# |
|
65 |
# To achieve this checkpoint we need to build the packaging project |
|
66 |
# (directly needed by the python-requires script) and all projects |
|
67 |
# required by packaging. During this all projects' dependencies needs to |
|
68 |
# be manually evaluated to make sure they are correct. |
|
69 |
# |
|
70 |
# (3) The build infrastructure is fully working. |
|
71 |
# |
|
72 |
# Once we are here we can build any Python project, but we cannot test it |
|
73 |
# yet. |
|
74 |
# |
|
75 |
# For projects using the 'setup.py' build style we do not need any |
|
76 |
# special build infrastructure. See checkpoint (1) above for detialed |
|
77 |
# discussion about 'setup.py' build style projects. |
|
78 |
# |
|
79 |
# For 'pyproject'-style projects we need to build both 'build' and |
|
80 |
# 'installer' projects and all projects they depends on. |
|
81 |
# |
|
82 |
# (4) The testing infrastructure is fully working. |
|
83 |
# |
|
84 |
# Once we are here we can finally use all features of the Python build |
|
85 |
# framework. Including testing. |
|
86 |
# |
|
87 |
# To achieve this we need to build tox, tox-current-env, and pytest |
|
88 |
# projects together with their dependencies. |
|
89 |
# |
|
90 |
# All projects needed to achieve checkpoints (1), (2), and (3) should set |
|
91 |
# PYTHON_BOOTSTRAP to 'yes' in their Makefile to make sure the regular build |
|
92 |
# infrastructure is not used for them and special set of build rules is applied |
|
93 |
# instead. |
|
94 |
# |
|
95 |
# All projects needed to go from checkpoint (3) to checkpoint (4) should set |
|
96 |
# PYTHON_TEST_BOOTSTRAP to 'yes' in their Makefile to let the build |
|
97 |
# infrastructure know that testing for such projects might not work properly. |
|
98 |
# |
|
99 |
# The PYTHON_BOOTSTRAP set to 'yes' implies PYTHON_TEST_BOOTSTRAP set to 'yes' |
|
100 |
# too. |
|
101 |
# |
|
102 |
ifeq ($(strip $(PYTHON_BOOTSTRAP)),yes) |
|
103 |
PYTHON_TEST_BOOTSTRAP = yes |
|
104 |
endif |
6b1855
|
105 |
|
MT |
106 |
# |
|
107 |
# Lists of Python projects needed to achieve particular bootstrap checkpoint. |
2172bd
|
108 |
# Indentation shows project dependencies (e.g. packaging requires flit_core). |
6b1855
|
109 |
# |
MT |
110 |
PYTHON_BOOTSTRAP_CHECKPOINT_1 += pyproject_installer |
|
111 |
# |
|
112 |
PYTHON_BOOTSTRAP_CHECKPOINT_2 += $(PYTHON_BOOTSTRAP_CHECKPOINT_1) |
|
113 |
PYTHON_BOOTSTRAP_CHECKPOINT_2 += packaging |
2172bd
|
114 |
PYTHON_BOOTSTRAP_CHECKPOINT_2 += flit_core |
7c8106
|
115 |
|
792915
|
116 |
# Particular python runtime is always required (at least to run setup.py) |
MT |
117 |
PYTHON_REQUIRED_PACKAGES += runtime/python |
|
118 |
|
668bcb
|
119 |
define python-rule |
AL |
120 |
$(BUILD_DIR)/%-$(1)/.built: PYTHON_VERSION=$(1) |
|
121 |
$(BUILD_DIR)/%-$(1)/.installed: PYTHON_VERSION=$(1) |
|
122 |
$(BUILD_DIR)/%-$(1)/.tested: PYTHON_VERSION=$(1) |
|
123 |
$(BUILD_DIR)/%-$(1)/.tested-and-compared: PYTHON_VERSION=$(1) |
|
124 |
endef |
|
125 |
|
|
126 |
$(foreach pyver, $(PYTHON_VERSIONS), $(eval $(call python-rule,$(pyver)))) |
|
127 |
|
74300c
|
128 |
$(BUILD_DIR)/$(MACH32)-%/.built: BITS=32 |
NJ |
129 |
$(BUILD_DIR)/$(MACH64)-%/.built: BITS=64 |
|
130 |
$(BUILD_DIR)/$(MACH32)-%/.installed: BITS=32 |
|
131 |
$(BUILD_DIR)/$(MACH64)-%/.installed: BITS=64 |
8d70f8
|
132 |
$(BUILD_DIR)/$(MACH32)-%/.tested: BITS=32 |
RB |
133 |
$(BUILD_DIR)/$(MACH64)-%/.tested: BITS=64 |
|
134 |
$(BUILD_DIR)/$(MACH32)-%/.tested-and-compared: BITS=32 |
|
135 |
$(BUILD_DIR)/$(MACH64)-%/.tested-and-compared: BITS=64 |
224ba0
|
136 |
|
44f1c2
|
137 |
PYTHON_32_VERSIONS = $(filter-out $(PYTHON_64_ONLY_VERSIONS), $(PYTHON_VERSIONS)) |
AP |
138 |
|
|
139 |
BUILD_32 = $(PYTHON_32_VERSIONS:%=$(BUILD_DIR)/$(MACH32)-%/.built) |
74300c
|
140 |
BUILD_64 = $(PYTHON_VERSIONS:%=$(BUILD_DIR)/$(MACH64)-%/.built) |
ad2fa3
|
141 |
BUILD_NO_ARCH = $(PYTHON_VERSIONS:%=$(BUILD_DIR)/$(MACH)-%/.built) |
224ba0
|
142 |
|
668bcb
|
143 |
ifeq ($(filter-out $(PYTHON_64_ONLY_VERSIONS), $(PYTHON_VERSION)),) |
44f1c2
|
144 |
BUILD_32_and_64 = $(BUILD_64) |
AP |
145 |
endif |
|
146 |
|
|
147 |
INSTALL_32 = $(PYTHON_32_VERSIONS:%=$(BUILD_DIR)/$(MACH32)-%/.installed) |
74300c
|
148 |
INSTALL_64 = $(PYTHON_VERSIONS:%=$(BUILD_DIR)/$(MACH64)-%/.installed) |
ad2fa3
|
149 |
INSTALL_NO_ARCH = $(PYTHON_VERSIONS:%=$(BUILD_DIR)/$(MACH)-%/.installed) |
9c75c0
|
150 |
|
35a012
|
151 |
PYTHON_ENV = CC="$(CC)" |
NJ |
152 |
PYTHON_ENV += CFLAGS="$(CFLAGS)" |
0d76b8
|
153 |
PYTHON_ENV += CXX="$(CXX)" |
MT |
154 |
PYTHON_ENV += CXXFLAGS="$(CXXFLAGS)" |
fd5873
|
155 |
PYTHON_ENV += LDFLAGS="$(LDFLAGS)" |
ba2ab2
|
156 |
PYTHON_ENV += PKG_CONFIG_PATH="$(PKG_CONFIG_PATH)" |
ad2fa3
|
157 |
|
NJ |
158 |
COMPONENT_BUILD_ENV += $(PYTHON_ENV) |
|
159 |
COMPONENT_INSTALL_ENV += $(PYTHON_ENV) |
|
160 |
COMPONENT_TEST_ENV += $(PYTHON_ENV) |
fa74c0
|
161 |
|
ea207c
|
162 |
# Set CARGO_HOME to make sure projects built using rust (for example via |
MT |
163 |
# setuptools-rust) do not pollute user's home directory with cargo bits. |
|
164 |
COMPONENT_BUILD_ENV += CARGO_HOME=$(@D)/.cargo |
|
165 |
|
6aefa3
|
166 |
# Make sure the default Python version is installed last and so is the |
MT |
167 |
# canonical version. This is needed for components that keep PYTHON_VERSIONS |
|
168 |
# set to more than single value, but deliver unversioned binaries in usr/bin or |
|
169 |
# other overlapping files. |
|
170 |
define python-order-rule |
|
171 |
$(BUILD_DIR)/%-$(PYTHON_VERSION)/.installed: $(BUILD_DIR)/%-$(1)/.installed |
|
172 |
endef |
|
173 |
$(foreach pyver,$(filter-out $(PYTHON_VERSION),$(PYTHON_VERSIONS)),$(eval $(call python-order-rule,$(pyver)))) |
|
174 |
|
381aab
|
175 |
# We need to copy the source dir to avoid its modification by install target |
MT |
176 |
# where egg-info is re-generated |
|
177 |
CLONEY_ARGS = CLONEY_MODE="copy" |
a7216a
|
178 |
|
115d4d
|
179 |
COMPONENT_BUILD_CMD = $(PYTHON) setup.py --no-user-cfg build $(COMPONENT_BUILD_SETUP_PY_ARGS) |
7589de
|
180 |
|
9c75c0
|
181 |
# build the configured source |
381aab
|
182 |
$(BUILD_DIR)/%/.built: $(SOURCE_DIR)/.prep |
9c75c0
|
183 |
$(RM) -r $(@D) ; $(MKDIR) $(@D) |
381aab
|
184 |
$(ENV) $(CLONEY_ARGS) $(CLONEY) $(SOURCE_DIR) $(@D) |
9c75c0
|
185 |
$(COMPONENT_PRE_BUILD_ACTION) |
b3a428
|
186 |
(cd $(@D)$(COMPONENT_SUBDIR:%=/%) ; $(ENV) $(COMPONENT_BUILD_ENV) \ |
7589de
|
187 |
$(COMPONENT_BUILD_CMD) $(COMPONENT_BUILD_ARGS)) |
9c75c0
|
188 |
$(COMPONENT_POST_BUILD_ACTION) |
NJ |
189 |
$(TOUCH) $@ |
|
190 |
|
7589de
|
191 |
|
MT |
192 |
COMPONENT_INSTALL_CMD = $(PYTHON) setup.py --no-user-cfg install |
ff17eb
|
193 |
|
e83e52
|
194 |
COMPONENT_INSTALL_ARGS += --root $(PROTO_DIR) |
NJ |
195 |
COMPONENT_INSTALL_ARGS += --install-lib=$(PYTHON_LIB) |
fa74c0
|
196 |
COMPONENT_INSTALL_ARGS += --install-data=$(PYTHON_DATA) |
381aab
|
197 |
COMPONENT_INSTALL_ARGS += --skip-build |
6aefa3
|
198 |
COMPONENT_INSTALL_ARGS += --force |
e83e52
|
199 |
|
9c75c0
|
200 |
# install the built source into a prototype area |
381aab
|
201 |
$(BUILD_DIR)/%/.installed: $(BUILD_DIR)/%/.built |
9c75c0
|
202 |
$(COMPONENT_PRE_INSTALL_ACTION) |
b3a428
|
203 |
(cd $(@D)$(COMPONENT_SUBDIR:%=/%) ; $(ENV) $(COMPONENT_INSTALL_ENV) \ |
7589de
|
204 |
$(COMPONENT_INSTALL_CMD) $(COMPONENT_INSTALL_ARGS)) |
9c75c0
|
205 |
$(COMPONENT_POST_INSTALL_ACTION) |
NJ |
206 |
$(TOUCH) $@ |
e83e52
|
207 |
|
e537d3
|
208 |
ifeq ($(strip $(SINGLE_PYTHON_VERSION)),no) |
053684
|
209 |
# Rename binaries in /usr/bin to contain version number |
MT |
210 |
COMPONENT_POST_INSTALL_ACTION += \ |
|
211 |
for f in $(PROTOUSRBINDIR)/* ; do \ |
9b979e
|
212 |
[ -f $$f ] || continue ; \ |
053684
|
213 |
for v in $(PYTHON_VERSIONS) ; do \ |
9b979e
|
214 |
[ "$$f" == "$${f%%$$v}" ] || continue 2 ; \ |
053684
|
215 |
done ; \ |
MT |
216 |
$(MV) $$f $$f-$(PYTHON_VERSION) ; \ |
|
217 |
done ; |
e537d3
|
218 |
endif |
053684
|
219 |
|
dfab6b
|
220 |
# Remove any previous dependency files |
MT |
221 |
COMPONENT_POST_INSTALL_ACTION += $(RM) $(@D)/.depend-runtime $(@D)/.depend-test ; |
06c6b6
|
222 |
|
17a961
|
223 |
# Define Python version specific filenames for tests. |
30eb16
|
224 |
ifeq ($(strip $(USE_COMMON_TEST_MASTER)),no) |
17a961
|
225 |
COMPONENT_TEST_MASTER = $(COMPONENT_TEST_RESULTS_DIR)/results-$(PYTHON_VERSION).master |
30eb16
|
226 |
endif |
5d7921
|
227 |
COMPONENT_TEST_BUILD_DIR = $(BUILD_DIR)/test-$(PYTHON_VERSION) |
17a961
|
228 |
COMPONENT_TEST_OUTPUT = $(COMPONENT_TEST_BUILD_DIR)/test-$(PYTHON_VERSION)-results |
MT |
229 |
COMPONENT_TEST_DIFFS = $(COMPONENT_TEST_BUILD_DIR)/test-$(PYTHON_VERSION)-diffs |
|
230 |
COMPONENT_TEST_SNAPSHOT = $(COMPONENT_TEST_BUILD_DIR)/results-$(PYTHON_VERSION).snapshot |
|
231 |
COMPONENT_TEST_TRANSFORM_CMD = $(COMPONENT_TEST_BUILD_DIR)/transform-$(PYTHON_VERSION)-results |
8d70f8
|
232 |
|
34664f
|
233 |
# Generic transforms for Python test results. |
MT |
234 |
# See below for test style specific transforms. |
|
235 |
COMPONENT_TEST_TRANSFORMS += "-e 's|$(PYTHON_DIR)|\$$(PYTHON_DIR)|g'" |
848948
|
236 |
|
dcf6a8
|
237 |
# Testing depends on install target because we want to test installed modules |
MT |
238 |
COMPONENT_TEST_DEP += $(BUILD_DIR)/%/.installed |
|
239 |
# Point Python to the proto area so it is able to find installed modules there |
|
240 |
COMPONENT_TEST_ENV += PYTHONPATH=$(PROTO_DIR)/$(PYTHON_LIB) |
9b979e
|
241 |
# Make sure testing is able to find own installed executables (if any) |
MT |
242 |
COMPONENT_TEST_ENV += PATH=$(PROTOUSRBINDIR):$(PATH) |
59c102
|
243 |
|
8d70f8
|
244 |
# determine the type of tests we want to run. |
RB |
245 |
ifeq ($(strip $(wildcard $(COMPONENT_TEST_RESULTS_DIR)/results-*.master)),) |
44f1c2
|
246 |
TEST_32 = $(PYTHON_32_VERSIONS:%=$(BUILD_DIR)/$(MACH32)-%/.tested) |
8d70f8
|
247 |
TEST_64 = $(PYTHON_VERSIONS:%=$(BUILD_DIR)/$(MACH64)-%/.tested) |
RB |
248 |
TEST_NO_ARCH = $(PYTHON_VERSIONS:%=$(BUILD_DIR)/$(MACH)-%/.tested) |
|
249 |
else |
44f1c2
|
250 |
TEST_32 = $(PYTHON_32_VERSIONS:%=$(BUILD_DIR)/$(MACH32)-%/.tested-and-compared) |
8d70f8
|
251 |
TEST_64 = $(PYTHON_VERSIONS:%=$(BUILD_DIR)/$(MACH64)-%/.tested-and-compared) |
RB |
252 |
TEST_NO_ARCH = $(PYTHON_VERSIONS:%=$(BUILD_DIR)/$(MACH)-%/.tested-and-compared) |
|
253 |
endif |
|
254 |
|
381aab
|
255 |
# |
792915
|
256 |
# Testing in the Python world is complex. Python projects usually do not |
MT |
257 |
# support Makefile with common 'check' or 'test' target to get built bits |
|
258 |
# tested. |
381aab
|
259 |
# |
792915
|
260 |
# De facto standard way to test Python projects these days is tox which is |
MT |
261 |
# designed and used primarily for release testing; to make sure the released |
|
262 |
# python project runs on all supported Python versions, platforms, etc. tox |
|
263 |
# does so using virtualenv and creates isolated test environments where the |
|
264 |
# tested package together with all its dependencies is automatically installed |
|
265 |
# (using pip) and tested. This is great for Python projects developers but it |
|
266 |
# is hardly usable for operating system distributions like OpenIndiana. |
381aab
|
267 |
# |
792915
|
268 |
# We do not need such release testing. Instead we need something closer to |
MT |
269 |
# integration testing: we need to test the built component in our real |
|
270 |
# environment without automatic installation of any dependencies using pip. In |
|
271 |
# addition, we need to run tests only for Python versions we actually support |
|
272 |
# and the component is built for. |
381aab
|
273 |
# |
792915
|
274 |
# To achieve that we do few things. First, to avoid isolated environments |
MT |
275 |
# (virtualenv) we run tox with the tox-current-env plugin. Second, to test |
|
276 |
# only Python versions we are interested in we use -e option for tox to select |
|
277 |
# single Python version only. Since we run separate test target per Python |
|
278 |
# version this will make sure we test all needed Python versions. |
|
279 |
# |
25e842
|
280 |
# The tox tool itself uses some other tools under the hood to run tests, for |
MT |
281 |
# example pytest. Some projects could even support pytest testing directly |
|
282 |
# without support for tox. For such projects we offer separate "pytest"-style |
|
283 |
# testing. |
|
284 |
# |
|
285 |
# For projects that do not support testing using neither tox nor pytest we |
855acc
|
286 |
# offer either unittest or (deprecated) "setup.py test" testing too. |
25e842
|
287 |
# |
MT |
288 |
# The TEST_STYLE variable is used to select (or force) particular test style |
|
289 |
# for Python projects. Valid values are: |
|
290 |
# |
|
291 |
# tox - "tox"-style testing |
|
292 |
# pytest - "pytest"-style testing |
855acc
|
293 |
# unittest - "unittest"-style testing |
25e842
|
294 |
# setup.py - "setup.py test"-style testing |
7c8106
|
295 |
# none - no testing is supported (or desired) at all |
792915
|
296 |
# |
MT |
297 |
|
|
298 |
TEST_STYLE ?= tox |
|
299 |
ifeq ($(strip $(TEST_STYLE)),tox) |
9b979e
|
300 |
# tox needs PATH environment variable - see https://github.com/tox-dev/tox/issues/2538 |
MT |
301 |
# We already added it to the test environment - see above |
3db057
|
302 |
COMPONENT_TEST_ENV += PYTEST_ADDOPTS="$(PYTEST_ADDOPTS)" |
dd736d
|
303 |
COMPONENT_TEST_ENV += NOSE_VERBOSE=2 |
792915
|
304 |
COMPONENT_TEST_CMD = $(TOX) |
81789e
|
305 |
COMPONENT_TEST_ARGS = --current-env --no-provision |
e7d6fe
|
306 |
COMPONENT_TEST_ARGS += --recreate |
b621ca
|
307 |
COMPONENT_TEST_ARGS += $(TOX_TESTENV) |
46ab01
|
308 |
COMPONENT_TEST_TARGETS = $(if $(strip $(TOX_POSARGS)),-- $(TOX_POSARGS)) |
b621ca
|
309 |
|
ccec59
|
310 |
TOX_TESTENV = -e py$(subst .,,$(PYTHON_VERSION)) |
792915
|
311 |
|
83badd
|
312 |
# Make sure following tools are called indirectly to properly support tox-current-env |
573ee5
|
313 |
TOX_CALL_INDIRECTLY += py.test |
051a62
|
314 |
TOX_CALL_INDIRECTLY += pytest |
MT |
315 |
TOX_CALL_INDIRECTLY += coverage |
1eb2df
|
316 |
TOX_CALL_INDIRECTLY += zope-testrunner |
MT |
317 |
TOX_CALL_INDIRECTLY.zope-testrunner = zope.testrunner |
|
318 |
TOX_CALL_INDIRECTLY += sphinx-build |
|
319 |
TOX_CALL_INDIRECTLY.sphinx-build = sphinx.cmd.build |
dd736d
|
320 |
TOX_CALL_INDIRECTLY += nosetests |
MT |
321 |
TOX_CALL_INDIRECTLY.nosetests = nose |
1eb2df
|
322 |
$(foreach indirectly, $(TOX_CALL_INDIRECTLY), $(eval TOX_CALL_INDIRECTLY.$(indirectly) ?= $(indirectly))) |
MT |
323 |
COMPONENT_PRE_TEST_ACTION += COMPONENT_TEST_DIR=$(COMPONENT_TEST_DIR) ; |
950890
|
324 |
COMPONENT_PRE_TEST_ACTION += \ |
1eb2df
|
325 |
$(foreach indirectly, $(TOX_CALL_INDIRECTLY), \ |
MT |
326 |
[ -f $$COMPONENT_TEST_DIR/tox.ini ] && \ |
a67d39
|
327 |
$(GSED) -i -e '/^commands *=/,/^$$/{ \ |
MT |
328 |
s/^\(\(commands *=\)\{0,1\}[ \t]*\)'$(indirectly)'\([ \t]\{1,\}.*\)\{0,1\}$$/\1python -m '$(TOX_CALL_INDIRECTLY.$(indirectly))'\3/ \ |
|
329 |
}' $$COMPONENT_TEST_DIR/tox.ini ; \ |
1eb2df
|
330 |
) |
MT |
331 |
COMPONENT_PRE_TEST_ACTION += true ; |
ae4a72
|
332 |
|
792915
|
333 |
# Normalize tox test results. |
ccec59
|
334 |
COMPONENT_TEST_TRANSFORMS += "-e 's/py$(subst .,,$(PYTHON_VERSION))/py\$$(PYV)/g'" # normalize PYV |
34664f
|
335 |
COMPONENT_TEST_TRANSFORMS += "-e '/^py\$$(PYV) installed:/d'" # depends on set of installed packages |
MT |
336 |
COMPONENT_TEST_TRANSFORMS += "-e '/PYTHONHASHSEED/d'" # this is random |
792915
|
337 |
|
a3f365
|
338 |
# Normalize zope.testrunner test results |
8937be
|
339 |
COMPONENT_TEST_TRANSFORMS += \ |
MT |
340 |
"-e 's/ in \([0-9]\{1,\} minutes \)\{0,1\}[0-9]\{1,\}\.[0-9]\{3\} seconds//'" # timing |
a3f365
|
341 |
|
5cfe42
|
342 |
# Remove timing for tox 4 test results |
MT |
343 |
COMPONENT_TEST_TRANSFORMS += "-e 's/^\( py\$$(PYV): OK\) (.* seconds)$$/\1/'" |
|
344 |
COMPONENT_TEST_TRANSFORMS += "-e 's/^\( congratulations :)\) (.* seconds)$$/\1/'" |
|
345 |
|
22f684
|
346 |
# Remove useless lines from the "coverage combine" output |
e91f55
|
347 |
COMPONENT_TEST_TRANSFORMS += "-e '/^Combined data file .*\.coverage/d'" |
MT |
348 |
COMPONENT_TEST_TRANSFORMS += "-e '/^Skipping duplicate data .*\.coverage/d'" |
22f684
|
349 |
|
f86079
|
350 |
# sort list of Sphinx doctest results |
MT |
351 |
COMPONENT_TEST_TRANSFORMS += \ |
|
352 |
"| ( \ |
|
353 |
$(GSED) -u -e '/^running tests\.\.\.$$/q' ; \ |
|
354 |
$(GSED) -u -e '/^Doctest summary/Q' \ |
|
355 |
| $(NAWK) '/^$$/{\$$0=\"\\\\n\"}1' ORS='|' \ |
|
356 |
| $(GNU_GREP) -v '^|$$' \ |
a99182
|
357 |
| $(SORT) \ |
f86079
|
358 |
| tr -d '\\\\n' | tr '|' '\\\\n' \ |
MT |
359 |
| $(NAWK) '{print}END{if(NR>0)printf(\"\\\\nDoctest summary\\\\n\")}' ; \ |
|
360 |
$(CAT) \ |
|
361 |
) | $(COMPONENT_TEST_TRANSFORMER)" |
|
362 |
|
792915
|
363 |
# tox package together with the tox-current-env plugin is needed |
b1d234
|
364 |
USERLAND_TEST_REQUIRED_PACKAGES += library/python/tox |
MT |
365 |
USERLAND_TEST_REQUIRED_PACKAGES += library/python/tox-current-env |
06c6b6
|
366 |
|
MT |
367 |
# Generate raw lists of test dependencies per Python version |
1eea40
|
368 |
# Please note we set PATH below four times for $(COMPONENT_TEST_CMD) (aka tox) |
MT |
369 |
# to workaround https://github.com/tox-dev/tox/issues/2538 |
06c6b6
|
370 |
COMPONENT_POST_INSTALL_ACTION += \ |
b1d234
|
371 |
if [ -x "$(COMPONENT_TEST_CMD)" ] ; then \ |
b3a428
|
372 |
cd $(@D)$(COMPONENT_SUBDIR:%=/%) ; \ |
b1d234
|
373 |
echo "Testing dependencies:" ; \ |
b621ca
|
374 |
PATH=$(PATH) $(COMPONENT_TEST_CMD) -qq --no-provision --print-deps-to=- $(TOX_TESTENV) || exit 1 ; \ |
b1d234
|
375 |
echo "Testing extras:" ; \ |
b621ca
|
376 |
PATH=$(PATH) $(COMPONENT_TEST_CMD) -qq --no-provision --print-extras-to=- $(TOX_TESTENV) || exit 1 ; \ |
MT |
377 |
( PATH=$(PATH) $(COMPONENT_TEST_CMD) -qq --no-provision --print-deps-to=- $(TOX_TESTENV) \ |
b1d234
|
378 |
| $(WS_TOOLS)/python-resolve-deps \ |
MT |
379 |
PYTHONPATH=$(PROTO_DIR)/$(PYTHON_DIR)/site-packages:$(PROTO_DIR)/$(PYTHON_LIB) \ |
|
380 |
$(PYTHON) $(WS_TOOLS)/python-requires $(COMPONENT_NAME) \ |
|
381 |
| $(PYTHON) $(WS_TOOLS)/python-requires - ; \ |
b621ca
|
382 |
for e in $$(PATH=$(PATH) $(COMPONENT_TEST_CMD) -qq --no-provision --print-extras-to=- $(TOX_TESTENV)) ; do \ |
7416d1
|
383 |
PYTHONPATH=$(PROTO_DIR)/$(PYTHON_DIR)/site-packages:$(PROTO_DIR)/$(PYTHON_LIB) \ |
b1d234
|
384 |
$(PYTHON) $(WS_TOOLS)/python-requires $(COMPONENT_NAME) $$e ; \ |
dfab6b
|
385 |
done ) | $(GSED) -e '/^tox\(-current-env\)\?$$/d' >> $(@D)/.depend-test ; \ |
b1d234
|
386 |
fi ; |
25e842
|
387 |
else ifeq ($(strip $(TEST_STYLE)),pytest) |
MT |
388 |
COMPONENT_TEST_CMD = $(PYTHON) -m pytest |
3db057
|
389 |
COMPONENT_TEST_ARGS = $(PYTEST_ADDOPTS) |
25e842
|
390 |
COMPONENT_TEST_TARGETS = |
3db057
|
391 |
|
b1d234
|
392 |
USERLAND_TEST_REQUIRED_PACKAGES += library/python/pytest |
855acc
|
393 |
else ifeq ($(strip $(TEST_STYLE)),unittest) |
MT |
394 |
COMPONENT_TEST_CMD = $(PYTHON) -m unittest |
|
395 |
COMPONENT_TEST_ARGS = |
|
396 |
COMPONENT_TEST_ARGS += --verbose |
|
397 |
COMPONENT_TEST_TARGETS = |
25e842
|
398 |
else ifeq ($(strip $(TEST_STYLE)),setup.py) |
MT |
399 |
# Old and deprecated "setup.py test"-style testing |
792915
|
400 |
COMPONENT_TEST_CMD = $(PYTHON) setup.py |
MT |
401 |
COMPONENT_TEST_ARGS = --no-user-cfg |
|
402 |
COMPONENT_TEST_TARGETS = test |
25e842
|
403 |
else ifeq ($(strip $(TEST_STYLE)),none) |
MT |
404 |
TEST_TARGET = $(NO_TESTS) |
792915
|
405 |
endif |
381aab
|
406 |
|
3db057
|
407 |
# Run pytest verbose to get separate line per test in results output |
MT |
408 |
PYTEST_ADDOPTS += --verbose |
|
409 |
|
808d8a
|
410 |
# Force pytest to not use colored output so the results normalization is unaffected |
MT |
411 |
PYTEST_ADDOPTS += --color=no |
|
412 |
|
ed465b
|
413 |
# Avoid loading of unexpected pytest plugins. |
40cc3a
|
414 |
define disable-pytest-plugin |
ed465b
|
415 |
PYTEST_ADDOPTS += $$(if $$(filter library/python/$(2)-$$(subst .,,$$(PYTHON_VERSION)), $$(REQUIRED_PACKAGES) $$(TEST_REQUIRED_PACKAGES) $$(COMPONENT_FMRI)-$$(subst .,,$$(PYTHON_VERSION))),,-p 'no:$(1)') |
40cc3a
|
416 |
endef |
ed465b
|
417 |
$(eval $(call disable-pytest-plugin,anyio,anyio)) |
1595bc
|
418 |
$(eval $(call disable-pytest-plugin,asyncio,pytest-asyncio)) # adds line to test report header |
MT |
419 |
$(eval $(call disable-pytest-plugin,benchmark,pytest-benchmark)) # adds line to test report header; adds benchmark report |
0f943a
|
420 |
$(eval $(call disable-pytest-plugin,black,pytest-black)) # runs extra test(s) |
ed465b
|
421 |
$(eval $(call disable-pytest-plugin,check,pytest-check)) |
0f943a
|
422 |
$(eval $(call disable-pytest-plugin,checkdocs,pytest-checkdocs)) # runs extra test(s) |
ed465b
|
423 |
$(eval $(call disable-pytest-plugin,console-scripts,pytest-console-scripts)) |
40cc3a
|
424 |
$(eval $(call disable-pytest-plugin,cov,pytest-cov)) |
ed465b
|
425 |
$(eval $(call disable-pytest-plugin,custom_exit_code,pytest-custom-exit-code)) |
3380cb
|
426 |
$(eval $(call disable-pytest-plugin,enabler,pytest-enabler)) |
ed465b
|
427 |
$(eval $(call disable-pytest-plugin,env,pytest-env)) |
MT |
428 |
$(eval $(call disable-pytest-plugin,faker,faker)) |
|
429 |
$(eval $(call disable-pytest-plugin,flake8,pytest-flake8)) |
40cc3a
|
430 |
$(eval $(call disable-pytest-plugin,flaky,flaky)) |
ed465b
|
431 |
$(eval $(call disable-pytest-plugin,freezer,pytest-freezer)) |
MT |
432 |
$(eval $(call disable-pytest-plugin,helpers_namespace,pytest-helpers-namespace)) |
1595bc
|
433 |
$(eval $(call disable-pytest-plugin,hypothesispytest,hypothesis)) # adds line to test report header |
ed465b
|
434 |
$(eval $(call disable-pytest-plugin,jaraco.test.http,jaraco-test)) |
MT |
435 |
$(eval $(call disable-pytest-plugin,kgb,kgb)) |
140fab
|
436 |
$(eval $(call disable-pytest-plugin,metadata,pytest-metadata)) # adds line to test report header |
0f943a
|
437 |
$(eval $(call disable-pytest-plugin,mypy,pytest-mypy)) # runs extra test(s) |
MT |
438 |
$(eval $(call disable-pytest-plugin,perf,pytest-perf)) # https://github.com/jaraco/pytest-perf/issues/9 |
e7470e
|
439 |
$(eval $(call disable-pytest-plugin,pytest home,pytest-home)) |
ed465b
|
440 |
$(eval $(call disable-pytest-plugin,pytest-datadir,pytest-datadir)) |
a38a08
|
441 |
$(eval $(call disable-pytest-plugin,pytest-mypy-plugins,pytest-mypy-plugins)) # could cause tests to fail |
ed465b
|
442 |
$(eval $(call disable-pytest-plugin,pytest-teamcity,teamcity-messages)) |
MT |
443 |
$(eval $(call disable-pytest-plugin,pytest_expect,pytest-expect)) |
|
444 |
$(eval $(call disable-pytest-plugin,pytest_fakefs,pyfakefs)) |
|
445 |
$(eval $(call disable-pytest-plugin,pytest_forked,pytest-forked)) |
|
446 |
$(eval $(call disable-pytest-plugin,pytest_httpserver,pytest-httpserver)) |
|
447 |
$(eval $(call disable-pytest-plugin,pytest_ignore_flaky,pytest-ignore-flaky)) |
818557
|
448 |
$(eval $(call disable-pytest-plugin,pytest_lazyfixture,pytest-lazy-fixtures)) |
ed465b
|
449 |
$(eval $(call disable-pytest-plugin,pytest_mock,pytest-mock)) |
0f943a
|
450 |
$(eval $(call disable-pytest-plugin,randomly,pytest-randomly)) # reorders tests |
ed465b
|
451 |
$(eval $(call disable-pytest-plugin,regressions,pytest-regressions)) |
95dfd1
|
452 |
$(eval $(call disable-pytest-plugin,relaxed,pytest-relaxed)) # runs extra test(s); produces different test report |
40cc3a
|
453 |
$(eval $(call disable-pytest-plugin,reporter,pytest-reporter)) # https://github.com/christiansandberg/pytest-reporter/issues/8 |
ed465b
|
454 |
$(eval $(call disable-pytest-plugin,rerunfailures,pytest-rerunfailures)) |
af147f
|
455 |
$(eval $(call disable-pytest-plugin,salt-factories,pytest-salt-factories)) # requires salt |
MT |
456 |
$(eval $(call disable-pytest-plugin,salt-factories-event-listener,pytest-salt-factories)) # requires salt |
|
457 |
$(eval $(call disable-pytest-plugin,salt-factories-factories,pytest-salt-factories)) # requires salt |
|
458 |
$(eval $(call disable-pytest-plugin,salt-factories-loader-mock,pytest-salt-factories)) # requires salt |
|
459 |
$(eval $(call disable-pytest-plugin,salt-factories-log-server,pytest-salt-factories)) # requires salt |
|
460 |
$(eval $(call disable-pytest-plugin,salt-factories-markers,pytest-salt-factories)) # requires salt |
|
461 |
$(eval $(call disable-pytest-plugin,salt-factories-sysinfo,pytest-salt-factories)) # requires salt |
|
462 |
$(eval $(call disable-pytest-plugin,salt-factories-sysstats,pytest-salt-factories)) # requires salt |
ed465b
|
463 |
$(eval $(call disable-pytest-plugin,shell-utilities,pytest-shell-utilities)) |
MT |
464 |
$(eval $(call disable-pytest-plugin,skip-markers,pytest-skip-markers)) |
|
465 |
$(eval $(call disable-pytest-plugin,socket,pytest-socket)) |
|
466 |
$(eval $(call disable-pytest-plugin,subprocess,pytest-subprocess)) |
|
467 |
$(eval $(call disable-pytest-plugin,subtests,pytest-subtests)) |
ccfa9a
|
468 |
$(eval $(call disable-pytest-plugin,system-statistics,pytest-system-statistics)) |
1a8beb
|
469 |
$(eval $(call disable-pytest-plugin,tempdir,pytest-tempdir)) # adds line to test report header |
ed465b
|
470 |
$(eval $(call disable-pytest-plugin,time_machine,time-machine)) |
MT |
471 |
$(eval $(call disable-pytest-plugin,timeout,pytest-timeout)) |
|
472 |
$(eval $(call disable-pytest-plugin,travis-fold,pytest-travis-fold)) |
|
473 |
$(eval $(call disable-pytest-plugin,typeguard,typeguard)) |
|
474 |
$(eval $(call disable-pytest-plugin,unittest_mock,backports-unittest-mock)) |
|
475 |
$(eval $(call disable-pytest-plugin,xdist,pytest-xdist)) |
|
476 |
$(eval $(call disable-pytest-plugin,xdist.looponfail,pytest-xdist)) |
af147f
|
477 |
$(eval $(call disable-pytest-plugin,xprocess,pytest-xprocess)) # adds a reminder line to test output |
7d6724
|
478 |
|
18da4f
|
479 |
# By default we are not interested in full list of test failures so exit on |
MT |
480 |
# first failure to save time. This could be easily overridden from environment |
|
481 |
# if needed (for example to debug test failures) or in per-component Makefile. |
|
482 |
PYTEST_FASTFAIL = -x |
|
483 |
PYTEST_ADDOPTS += $(PYTEST_FASTFAIL) |
|
484 |
|
45ab77
|
485 |
# By default we are not interested to see the default long tracebacks. |
MT |
486 |
# Detailed tracebacks are shown either for failures or xfails. We aim to see |
|
487 |
# testing passed so there should be no failures. Since xfails are expected |
|
488 |
# failures we are not interested in detailed tracebacks here at all since they |
|
489 |
# could contain random data, like pointers, temporary file names, etc. |
|
490 |
PYTEST_TRACEBACK = --tb=line |
|
491 |
PYTEST_ADDOPTS += $(PYTEST_TRACEBACK) |
|
492 |
|
ae8210
|
493 |
# Normalize pytest test results. The pytest framework could be used either |
MT |
494 |
# directly or via tox or setup.py so add these transforms for all test styles |
|
495 |
# unconditionally. |
34664f
|
496 |
COMPONENT_TEST_TRANSFORMS += \ |
MT |
497 |
"-e 's/^\(platform sunos5 -- Python \)$(shell echo $(PYTHON_VERSION) | $(GSED) -e 's/\./\\./g')\.[0-9]\{1,\}.*\( -- .*\)/\1\$$(PYTHON_VERSION).X\2/'" |
ae8210
|
498 |
COMPONENT_TEST_TRANSFORMS += "-e '/^Using --randomly-seed=[0-9]\{1,\}$$/d'" # this is random |
MT |
499 |
COMPONENT_TEST_TRANSFORMS += "-e '/^plugins: /d'" # order of listed plugins could vary |
c44dc0
|
500 |
COMPONENT_TEST_TRANSFORMS += "-e '/^-\{1,\} coverage: /,/^$$/d'" # remove coverage report |
27b18a
|
501 |
# sort list of pytest unit tests and drop percentage |
MT |
502 |
COMPONENT_TEST_TRANSFORMS += \ |
08f372
|
503 |
"| ( \ |
MT |
504 |
$(GSED) -u -e '/^=\{1,\} test session starts /q' ; \ |
|
505 |
$(GSED) -u -e '/^$$/q' ; \ |
a99182
|
506 |
$(GSED) -u -e 's/ *\[...%\]$$//' -e '/^$$/Q' | $(SORT) | $(NAWK) '{print}END{if(NR>0)printf(\"\\\\n\")}' ; \ |
08f372
|
507 |
$(CAT) \ |
MT |
508 |
) | $(COMPONENT_TEST_TRANSFORMER)" |
6dfcfa
|
509 |
COMPONENT_TEST_TRANSFORMS += \ |
b4e51a
|
510 |
"-e 's/^=\{1,\} \(.*\) in [0-9]\{1,\}\.[0-9]\{1,\}s \(([^)]*) \)\?=\{1,\}$$/======== \1 ========/'" # remove timing |
a033e0
|
511 |
# Remove slowest durations report for projects that run pytest with --durations option |
2f67f4
|
512 |
COMPONENT_TEST_TRANSFORMS += "-e '/^=\{1,\} slowest [0-9 ]*durations =\{1,\}$$/,/^=/{/^=/!d}'" |
0abb3a
|
513 |
# Remove short test summary info for projects that run pytest with -r option |
MT |
514 |
COMPONENT_TEST_TRANSFORMS += "-e '/^=\{1,\} short test summary info =\{1,\}$$/,/^=/{/^=/!d}'" |
ae8210
|
515 |
|
3d923b
|
516 |
# Normalize test results produced by pytest-benchmark |
MT |
517 |
COMPONENT_TEST_TRANSFORMS += \ |
|
518 |
$(if $(filter library/python/pytest-benchmark-$(subst .,,$(PYTHON_VERSION)), $(REQUIRED_PACKAGES) $(TEST_REQUIRED_PACKAGES)),"| ( \ |
|
519 |
$(GSED) -e '/^-\{1,\} benchmark/,/^=/{/^=/!d}' \ |
|
520 |
) | $(COMPONENT_TEST_TRANSFORMER) -e ''") |
|
521 |
|
d381c2
|
522 |
# Normalize test results produced by pytest-xdist |
MT |
523 |
COMPONENT_TEST_TRANSFORMS += \ |
|
524 |
$(if $(filter library/python/pytest-xdist-$(subst .,,$(PYTHON_VERSION)), $(REQUIRED_PACKAGES) $(TEST_REQUIRED_PACKAGES)),"| ( \ |
|
525 |
$(GSED) -u \ |
|
526 |
-e '/^created: .* workers$$/d' \ |
|
527 |
-e 's/^[0-9]\{1,\}\( workers \[[0-9]\{1,\} items\]\)$$/X\1/' \ |
|
528 |
-e '/^scheduling tests via /q' ; \ |
|
529 |
$(GSED) -u -e '/^$$/q' ; \ |
|
530 |
$(GSED) -u -n -e '/^\[gw/p' -e '/^$$/Q' | ( $(GSED) \ |
|
531 |
-e 's/^\[gw[0-9]\{1,\}\] \[...%\] //' \ |
|
532 |
-e 's/ *$$//' \ |
|
533 |
-e 's/\([^ ]\{1,\}\) \(.*\)$$/\2 \1/' \ |
|
534 |
| $(SORT) | $(NAWK) '{print}END{if(NR>0)printf(\"\\\\n\")}' ; \ |
|
535 |
) ; \ |
|
536 |
$(CAT) \ |
|
537 |
) | $(COMPONENT_TEST_TRANSFORMER) -e ''") |
|
538 |
|
b50750
|
539 |
# Normalize stestr test results |
MT |
540 |
USE_STESTR = $(filter library/python/stestr-$(subst .,,$(PYTHON_VERSION)), $(REQUIRED_PACKAGES) $(TEST_REQUIRED_PACKAGES)) |
|
541 |
COMPONENT_TEST_TRANSFORMS += \ |
|
542 |
$(if $(strip $(USE_STESTR)),"| ( \ |
|
543 |
$(GSED) -e '0,/^{[0-9]\{1,\}}/{//i\'\$$'\\\n{0}\\\n}' \ |
|
544 |
-e 's/^\(Ran: [0-9]\{1,\} tests\{0,1\}\) in .*\$$/\1/' \ |
|
545 |
-e '/^Sum of execute time for each test/d' \ |
|
546 |
-e '/^ - Worker /d' \ |
|
547 |
) | ( \ |
|
548 |
$(GSED) -u -e '/^{0}\$$/Q' ; \ |
|
549 |
$(GSED) -u -e 's/^{[0-9]\{1,\}} //' \ |
|
550 |
-e 's/\[[.0-9]\{1,\}s\] \.\.\./.../' \ |
|
551 |
-e '/^\$$/Q' | $(SORT) | $(GSED) -e '\$$a\'\$$'\\\n\\\n' ; \ |
|
552 |
$(CAT) \ |
|
553 |
) | $(COMPONENT_TEST_TRANSFORMER) -e ''") |
|
554 |
|
ce8823
|
555 |
# Normalize setup.py test results. The setup.py testing could be used either |
MT |
556 |
# directly or via tox so add these transforms for all test styles |
|
557 |
# unconditionally. |
|
558 |
COMPONENT_TEST_TRANSFORMS += "-e '/SetuptoolsDeprecationWarning:/,+1d'" # depends on Python version and is useless |
9f6a07
|
559 |
COMPONENT_TEST_TRANSFORMS += "-e 's/^\(Ran [0-9]\{1,\} tests\{0,1\}\) in .*$$/\1/'" # delete timing from test results |
b3a428
|
560 |
|
MT |
561 |
COMPONENT_TEST_DIR = $(@D)$(COMPONENT_SUBDIR:%=/%) |
ce8823
|
562 |
|
59c102
|
563 |
# test the built source |
8d70f8
|
564 |
$(BUILD_DIR)/%/.tested-and-compared: $(COMPONENT_TEST_DEP) |
237543
|
565 |
$(RM) -rf $(COMPONENT_TEST_BUILD_DIR) |
AP |
566 |
$(MKDIR) $(COMPONENT_TEST_BUILD_DIR) |
59c102
|
567 |
$(COMPONENT_PRE_TEST_ACTION) |
8d70f8
|
568 |
-(cd $(COMPONENT_TEST_DIR) ; \ |
381aab
|
569 |
$(COMPONENT_TEST_ENV_CMD) $(COMPONENT_TEST_ENV) \ |
792915
|
570 |
$(COMPONENT_TEST_CMD) \ |
MT |
571 |
$(COMPONENT_TEST_ARGS) $(COMPONENT_TEST_TARGETS)) \ |
8d70f8
|
572 |
&> $(COMPONENT_TEST_OUTPUT) |
59c102
|
573 |
$(COMPONENT_POST_TEST_ACTION) |
8d70f8
|
574 |
$(COMPONENT_TEST_CREATE_TRANSFORMS) |
RB |
575 |
$(COMPONENT_TEST_PERFORM_TRANSFORM) |
|
576 |
$(COMPONENT_TEST_COMPARE) |
|
577 |
$(COMPONENT_TEST_CLEANUP) |
|
578 |
$(TOUCH) $@ |
|
579 |
|
89aae0
|
580 |
$(BUILD_DIR)/%/.tested: SHELLOPTS=pipefail |
8d70f8
|
581 |
$(BUILD_DIR)/%/.tested: $(COMPONENT_TEST_DEP) |
89aae0
|
582 |
$(RM) -rf $(COMPONENT_TEST_BUILD_DIR) |
MT |
583 |
$(MKDIR) $(COMPONENT_TEST_BUILD_DIR) |
8d70f8
|
584 |
$(COMPONENT_PRE_TEST_ACTION) |
RB |
585 |
(cd $(COMPONENT_TEST_DIR) ; \ |
381aab
|
586 |
$(COMPONENT_TEST_ENV_CMD) $(COMPONENT_TEST_ENV) \ |
792915
|
587 |
$(COMPONENT_TEST_CMD) \ |
89aae0
|
588 |
$(COMPONENT_TEST_ARGS) $(COMPONENT_TEST_TARGETS)) \ |
MT |
589 |
|& $(TEE) $(COMPONENT_TEST_OUTPUT) |
8d70f8
|
590 |
$(COMPONENT_POST_TEST_ACTION) |
89aae0
|
591 |
$(COMPONENT_TEST_CREATE_TRANSFORMS) |
MT |
592 |
$(COMPONENT_TEST_PERFORM_TRANSFORM) |
8d70f8
|
593 |
$(COMPONENT_TEST_CLEANUP) |
59c102
|
594 |
$(TOUCH) $@ |
7999b2
|
595 |
|
9b979e
|
596 |
ifeq ($(strip $(SINGLE_PYTHON_VERSION)),no) |
MT |
597 |
# Temporarily create symlinks for renamed binaries |
|
598 |
COMPONENT_PRE_TEST_ACTION += \ |
|
599 |
for f in $(PROTOUSRBINDIR)/*-$(PYTHON_VERSION) ; do \ |
|
600 |
[ -f $$f ] || continue ; \ |
0c5dad
|
601 |
[ -L $${f%%-$(PYTHON_VERSION)} ] && $(RM) $${f%%-$(PYTHON_VERSION)} ; \ |
9b979e
|
602 |
[ -e $${f%%-$(PYTHON_VERSION)} ] && continue ; \ |
MT |
603 |
$(SYMLINK) $$(basename $$f) $${f%%-$(PYTHON_VERSION)} ; \ |
|
604 |
done ; |
|
605 |
|
|
606 |
# Cleanup of temporary symlinks |
|
607 |
COMPONENT_POST_TEST_ACTION += \ |
|
608 |
for f in $(PROTOUSRBINDIR)/*-$(PYTHON_VERSION) ; do \ |
|
609 |
[ -f $$f ] || continue ; \ |
|
610 |
[ ! -L $${f%%-$(PYTHON_VERSION)} ] || $(RM) $${f%%-$(PYTHON_VERSION)} ; \ |
|
611 |
done ; |
|
612 |
endif |
|
613 |
|
053684
|
614 |
|
e537d3
|
615 |
ifeq ($(strip $(SINGLE_PYTHON_VERSION)),no) |
053684
|
616 |
# We need to add -$(PYV) to package fmri |
MT |
617 |
GENERATE_EXTRA_CMD += | \ |
e537d3
|
618 |
$(GSED) -e 's/^\(set name=pkg.fmri [^@]*\)\(.*\)$$/\1-$$(PYV)\2/' |
MT |
619 |
endif |
053684
|
620 |
|
095208
|
621 |
# Add runtime dependencies from project metadata to generated manifest |
MT |
622 |
GENERATE_EXTRA_DEPS += $(BUILD_DIR)/META.depend-runtime.res |
|
623 |
GENERATE_EXTRA_CMD += | \ |
|
624 |
$(CAT) - <( \ |
|
625 |
echo "" ; \ |
82fd1e
|
626 |
echo "\# python modules are unusable without python runtime binary" ; \ |
MT |
627 |
echo "depend type=require fmri=__TBD pkg.debug.depend.file=python\$$(PYVER) \\" ; \ |
|
628 |
echo " pkg.debug.depend.path=usr/bin" ; \ |
|
629 |
echo "" ; \ |
095208
|
630 |
echo "\# Automatically generated dependencies based on distribution metadata" ; \ |
MT |
631 |
$(CAT) $(BUILD_DIR)/META.depend-runtime.res \ |
|
632 |
) |
|
633 |
|
|
634 |
# Add runtime dependencies from project metadata to REQUIRED_PACKAGES |
|
635 |
REQUIRED_PACKAGES_RESOLVED += $(BUILD_DIR)/META.depend-runtime.res |
|
636 |
|
|
637 |
|
|
638 |
# Generate raw lists of runtime dependencies per Python version |
|
639 |
COMPONENT_POST_INSTALL_ACTION += \ |
06c6b6
|
640 |
PYTHONPATH=$(PROTO_DIR)/$(PYTHON_DIR)/site-packages:$(PROTO_DIR)/$(PYTHON_LIB) \ |
dfab6b
|
641 |
$(PYTHON) $(WS_TOOLS)/python-requires $(COMPONENT_NAME) >> $(@D)/.depend-runtime ; |
095208
|
642 |
|
MT |
643 |
# Convert raw per version lists of runtime dependencies to single resolved |
06c6b6
|
644 |
# runtime dependency list. The dependency on META.depend-test.required here is |
MT |
645 |
# purely to get the file created as a side effect of this target. |
|
646 |
$(BUILD_DIR)/META.depend-runtime.res: $(INSTALL_$(MK_BITS)) $(BUILD_DIR)/META.depend-test.required |
a99182
|
647 |
$(CAT) $(INSTALL_$(MK_BITS):%.installed=%.depend-runtime) | $(SORT) -u \ |
095208
|
648 |
| $(GSED) -e 's/.*/depend type=require fmri=pkg:\/library\/python\/&-$$(PYV)/' > $@ |
MT |
649 |
|
dfab6b
|
650 |
# Generate raw lists of test dependencies per Python version |
MT |
651 |
COMPONENT_POST_INSTALL_ACTION += \ |
b3a428
|
652 |
cd $(@D)$(COMPONENT_SUBDIR:%=/%) ; \ |
9d43f1
|
653 |
( for f in $(TEST_REQUIREMENTS) ; do \ |
ace7a9
|
654 |
$(CAT) $$f | $(DOS2UNIX) -ascii ; \ |
9d43f1
|
655 |
done ; \ |
MT |
656 |
for e in $(TEST_REQUIREMENTS_EXTRAS) ; do \ |
|
657 |
PYTHONPATH=$(PROTO_DIR)/$(PYTHON_DIR)/site-packages:$(PROTO_DIR)/$(PYTHON_LIB) \ |
|
658 |
$(PYTHON) $(WS_TOOLS)/python-requires $(COMPONENT_NAME) $$e ; \ |
|
659 |
done ) | $(WS_TOOLS)/python-resolve-deps \ |
dfab6b
|
660 |
PYTHONPATH=$(PROTO_DIR)/$(PYTHON_DIR)/site-packages:$(PROTO_DIR)/$(PYTHON_LIB) \ |
MT |
661 |
$(PYTHON) $(WS_TOOLS)/python-requires $(COMPONENT_NAME) \ |
|
662 |
| $(PYTHON) $(WS_TOOLS)/python-requires - >> $(@D)/.depend-test ; |
|
663 |
|
06c6b6
|
664 |
# Convert raw per version lists of test dependencies to single list of |
d2a1ce
|
665 |
# TEST_REQUIRED_PACKAGES entries. Some Python projects lists their own project |
MT |
666 |
# as a test dependency so filter this out here too. |
06c6b6
|
667 |
$(BUILD_DIR)/META.depend-test.required: $(INSTALL_$(MK_BITS)) |
a99182
|
668 |
$(CAT) $(INSTALL_$(MK_BITS):%.installed=%.depend-test) | $(SORT) -u \ |
d2a1ce
|
669 |
| $(GSED) -e 's/.*/TEST_REQUIRED_PACKAGES.python += library\/python\/&/' \ |
4325c8
|
670 |
| ( $(GNU_GREP) -v ' $(COMPONENT_FMRI)$$' || true ) \ |
d2a1ce
|
671 |
> $@ |
06c6b6
|
672 |
|
MT |
673 |
# Add META.depend-test.required to the generated list of REQUIRED_PACKAGES |
|
674 |
REQUIRED_PACKAGES_TRANSFORM += -e '$$r $(BUILD_DIR)/META.depend-test.required' |
|
675 |
|
c49523
|
676 |
# The python-requires script requires packaging to provide useful output but |
6b1855
|
677 |
# packaging might be unavailable during bootstrap until we reach bootstrap |
MT |
678 |
# checkpoint 2. So require it conditionally. |
|
679 |
ifeq ($(filter $(strip $(COMPONENT_NAME)),$(PYTHON_BOOTSTRAP_CHECKPOINT_2)),) |
eb37ff
|
680 |
USERLAND_REQUIRED_PACKAGES.python += library/python/packaging |
c49523
|
681 |
endif |
MT |
682 |
|
053684
|
683 |
|
35a012
|
684 |
clean:: |
NJ |
685 |
$(RM) -r $(SOURCE_DIR) $(BUILD_DIR) |
6005c4
|
686 |
|
c437ed
|
687 |
# Make it easy to construct a URL for a pypi source download. |
8beffa
|
688 |
pypi_url_multi = pypi:///$(COMPONENT_NAME_$(1))==$(COMPONENT_VERSION_$(1)) |
DD |
689 |
pypi_url_single = pypi:///$(COMPONENT_NAME)==$(COMPONENT_VERSION) |
|
690 |
pypi_url = $(if $(COMPONENT_NAME_$(1)),$(pypi_url_multi),$(pypi_url_single)) |