Skip to content

Commit 993985f

Browse files
tseaverparthea
andauthored
chore(python): refactor unit / system test dependency install (#1294)
* chore(python): refactor unit / system test dependency install Closes #1185. * chore: use editable installs for local deps * chore: don't install deps using '-e' * chore: deprecate 'unit_test_external_dependencies' * fix: install standard + main unit test deps together FBO pip resolver. Co-authored-by: Anthonios Partheniou <[email protected]>
1 parent f087181 commit 993985f

File tree

2 files changed

+169
-64
lines changed

2 files changed

+169
-64
lines changed

synthtool/gcp/templates/python_library/noxfile.py.j2

Lines changed: 108 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -20,16 +20,62 @@ from __future__ import absolute_import
2020
import os
2121
import pathlib
2222
import shutil
23+
import warnings
2324

2425
import nox
2526

26-
2727
BLACK_VERSION = "black==22.3.0"
2828
BLACK_PATHS = ["docs", "google", "tests", "noxfile.py", "setup.py"]
2929

3030
DEFAULT_PYTHON_VERSION="{{ default_python_version }}"
31-
SYSTEM_TEST_PYTHON_VERSIONS=[{% for v in system_test_python_versions %}"{{v}}"{% if not loop.last %},{% endif %}{% endfor %}]
32-
UNIT_TEST_PYTHON_VERSIONS=[{% for v in unit_test_python_versions %}"{{v}}"{% if not loop.last %},{% endif %}{% endfor %}]
31+
32+
UNIT_TEST_PYTHON_VERSIONS=[{% for v in unit_test_python_versions %}"{{v}}"{% if not loop.last %}, {% endif %}{% endfor %}]
33+
UNIT_TEST_STANDARD_DEPENDENCIES = [
34+
"mock",
35+
"asyncmock",
36+
"pytest",
37+
"pytest-cov",
38+
"pytest-asyncio",
39+
]
40+
UNIT_TEST_EXTERNAL_DEPENDENCIES = [{% for v in unit_test_external_dependencies %}
41+
"{{v}}",{% endfor %}
42+
]
43+
UNIT_TEST_LOCAL_DEPENDENCIES = [{% for v in unit_test_local_dependencies %}
44+
"{{v}}",{% endfor %}
45+
]
46+
UNIT_TEST_DEPENDENCIES = [{% for v in unit_test_dependencies %}
47+
"{{v}}",{% endfor %}
48+
]
49+
UNIT_TEST_EXTRAS = [{% for v in unit_test_extras %}
50+
"{{v}}",{% endfor %}
51+
]
52+
UNIT_TEST_EXTRAS_BY_PYTHON = {{ '{' }}{% if unit_test_extras_by_python %}{% for python_version, extras in unit_test_extras_by_python.items() %}
53+
"{{python_version}}": [{% for v in extras %}
54+
"{{v}}",{% endfor %}
55+
],{% endfor %}{% endif %}
56+
}
57+
58+
SYSTEM_TEST_PYTHON_VERSIONS=[{% for v in system_test_python_versions %}"{{v}}"{% if not loop.last %}, {% endif %}{% endfor %}]
59+
SYSTEM_TEST_STANDARD_DEPENDENCIES = [
60+
"mock", "pytest", "google-cloud-testutils",
61+
]
62+
SYSTEM_TEST_EXTERNAL_DEPENDENCIES = [{% for v in system_test_external_dependencies %}
63+
"{{v}}",{% endfor %}
64+
]
65+
SYSTEM_TEST_LOCAL_DEPENDENCIES = [{% for v in system_test_local_dependencies %}
66+
"{{v}}",{% endfor %}
67+
]
68+
SYSTEM_TEST_DEPENDENCIES = [{% for v in system_test_dependencies %}
69+
"{{v}}",{% endfor %}
70+
]
71+
SYSTEM_TEST_EXTRAS = [{% for v in system_test_extras %}
72+
"{{v}}",{% endfor %}
73+
]
74+
SYSTEM_TEST_EXTRAS_BY_PYTHON = {{ '{' }}{% if system_test_extras_by_python %}{% for python_version, extras in system_test_extras_by_python.items() %}
75+
"{{python_version}}": [{% for v in extras %}
76+
"{{v}}",{% endfor %}
77+
],{% endfor %}{% endif %}
78+
}
3379

3480
CURRENT_DIRECTORY = pathlib.Path(__file__).parent.absolute()
3581

@@ -81,31 +127,41 @@ def lint_setup_py(session):
81127
session.run("python", "setup.py", "check", "--restructuredtext", "--strict")
82128

83129

130+
def install_unittest_dependencies(session, *constraints):
131+
standard_deps = UNIT_TEST_STANDARD_DEPENDENCIES + UNIT_TEST_DEPENDENCIES
132+
session.install(*standard_deps, *constraints)
133+
134+
if UNIT_TEST_EXTERNAL_DEPENDENCIES:
135+
warnings.warn(
136+
"'unit_test_external_dependencies' is deprecated. Instead, please "
137+
"use 'unit_test_dependencies' or 'unit_test_local_dependencies'.",
138+
DeprecationWarning,
139+
)
140+
session.install(*UNIT_TEST_EXTERNAL_DEPENDENCIES, *constraints)
141+
142+
if UNIT_TEST_LOCAL_DEPENDENCIES:
143+
session.install(*UNIT_TEST_LOCAL_DEPENDENCIES, *constraints)
144+
145+
if UNIT_TEST_EXTRAS_BY_PYTHON:
146+
extras = UNIT_TEST_EXTRAS_BY_PYTHON.get(session.python, [])
147+
elif UNIT_TEST_EXTRAS:
148+
extras = UNIT_TEST_EXTRAS
149+
else:
150+
extras = []
151+
152+
if extras:
153+
session.install("-e", f".[{','.join(extras)}]", *constraints)
154+
else:
155+
session.install("-e", ".", *constraints)
156+
157+
84158
def default(session):
85159
# Install all test dependencies, then install this package in-place.
86160

87161
constraints_path = str(
88162
CURRENT_DIRECTORY / "testing" / f"constraints-{session.python}.txt"
89163
)
90-
session.install("mock", "asyncmock", "pytest", "pytest-cov", "pytest-asyncio", "-c", constraints_path)
91-
{% for d in unit_test_external_dependencies -%}
92-
session.install("{{d}}", "-c", constraints_path)
93-
{% endfor %}
94-
{% for dependency in unit_test_local_dependencies %}session.install("-e", "{{dependency}}", "-c", constraints_path)
95-
{% endfor %}
96-
{% for dependency in unit_test_dependencies %}session.install("-e", "{{dependency}}", "-c", constraints_path){% endfor %}
97-
{%- if unit_test_extras_by_python %}
98-
{% for extras_python in unit_test_extras_by_python %}
99-
{%- if not loop.first %}el{% endif %}if session.python == "{{extras_python}}":
100-
extras = "[{{",".join(unit_test_extras_by_python[extras_python])}}]"
101-
{% endfor %}else:
102-
extras = "{%- if unit_test_extras %}[{{",".join(unit_test_extras)}}]{% endif %}"
103-
session.install("-e", f".{extras}", "-c", constraints_path)
104-
{% elif unit_test_extras %}
105-
session.install("-e", ".[{{",".join(unit_test_extras)}}]", "-c", constraints_path)
106-
{% else %}
107-
session.install("-e", ".", "-c", constraints_path)
108-
{% endif %}
164+
install_unittest_dependencies(session, "-c", constraints_path)
109165

110166
# Run py.test against the unit tests.
111167
session.run(
@@ -128,6 +184,35 @@ def unit(session):
128184
default(session)
129185

130186

187+
def install_systemtest_dependencies(session, *constraints):
188+
189+
# Use pre-release gRPC for system tests.
190+
session.install("--pre", "grpcio")
191+
192+
session.install(*SYSTEM_TEST_STANDARD_DEPENDENCIES, *constraints)
193+
194+
if SYSTEM_TEST_EXTERNAL_DEPENDENCIES:
195+
session.install(*SYSTEM_TEST_EXTERNAL_DEPENDENCIES, *constraints)
196+
197+
if SYSTEM_TEST_LOCAL_DEPENDENCIES:
198+
session.install("-e", *SYSTEM_TEST_LOCAL_DEPENDENCIES, *constraints)
199+
200+
if SYSTEM_TEST_DEPENDENCIES:
201+
session.install("-e", *SYSTEM_TEST_DEPENDENCIES, *constraints)
202+
203+
if SYSTEM_TEST_EXTRAS_BY_PYTHON:
204+
extras = SYSTEM_TEST_EXTRAS_BY_PYTHON.get(session.python, [])
205+
elif SYSTEM_TEST_EXTRAS:
206+
extras = SYSTEM_TEST_EXTRAS
207+
else:
208+
extras = []
209+
210+
if extras:
211+
session.install("-e", f".[{','.join(extras)}]", *constraints)
212+
else:
213+
session.install("-e", ".", *constraints)
214+
215+
131216
@nox.session(python=SYSTEM_TEST_PYTHON_VERSIONS)
132217
def system(session):
133218
"""Run the system test suite."""
@@ -150,29 +235,7 @@ def system(session):
150235
if not system_test_exists and not system_test_folder_exists:
151236
session.skip("System tests were not found")
152237

153-
# Use pre-release gRPC for system tests.
154-
session.install("--pre", "grpcio")
155-
156-
# Install all test dependencies, then install this package into the
157-
# virtualenv's dist-packages.
158-
session.install("mock", "pytest", "google-cloud-testutils"{% for d in system_test_external_dependencies %}, "{{d}}"{% endfor %}, "-c", constraints_path)
159-
160-
{%- if system_test_local_dependencies %}
161-
{% for dependency in system_test_local_dependencies %}session.install("-e", "{{dependency}}", "-c", constraints_path)
162-
{% endfor %}
163-
{%- endif %}
164-
{%- if system_test_extras_by_python %}
165-
{% for extras_python in system_test_extras_by_python %}
166-
{%- if not loop.first %}el{% endif %}if session.python == "{{extras_python}}":
167-
extras = "[{{",".join(system_test_extras_by_python[extras_python])}}]"
168-
{% endfor %}else:
169-
extras = "{%- if system_test_extras %}[{{",".join(system_test_extras)}}]{% endif %}"
170-
session.install("-e", f".{extras}", "-c", constraints_path)
171-
{% elif system_test_extras %}
172-
session.install("-e", ".[{{",".join(system_test_extras)}}]", "-c", constraints_path)
173-
{% else %}
174-
session.install("-e", ".", "-c", constraints_path)
175-
{% endif %}
238+
install_systemtest_dependencies(session, "-c", constraints_path)
176239

177240
# Run py.test against the system tests.
178241
if system_test_exists:

tests/test_python_library.py

Lines changed: 61 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -30,43 +30,67 @@
3030
@pytest.mark.parametrize(
3131
["template_kwargs", "expected_text"],
3232
[
33-
({}, ["import nox", 'session.install("-e", ".", "-c", constraints_path)']),
33+
({}, ["import nox", 'session.install("-e", ".", *constraints)']),
3434
(
3535
{"unit_test_local_dependencies": ["../testutils", "../unitutils"]},
3636
[
37-
'session.install("-e", "../testutils", "-c", constraints_path)',
38-
'session.install("-e", "../unitutils", "-c", constraints_path)',
37+
"""\
38+
UNIT_TEST_LOCAL_DEPENDENCIES = [
39+
"../testutils",
40+
"../unitutils",
41+
]""",
3942
],
4043
),
4144
(
4245
{"system_test_local_dependencies": ["../testutils", "../sysutils"]},
4346
[
44-
'session.install("-e", "../testutils", "-c", constraints_path)',
45-
'session.install("-e", "../sysutils", "-c", constraints_path)',
47+
"""\
48+
SYSTEM_TEST_LOCAL_DEPENDENCIES = [
49+
"../testutils",
50+
"../sysutils",
51+
]""",
4652
],
4753
),
4854
(
4955
{"unit_test_extras": ["abc", "def"]},
50-
['session.install("-e", ".[abc,def]", "-c", constraints_path)'],
56+
[
57+
"""\
58+
UNIT_TEST_EXTRAS = [
59+
"abc",
60+
"def",
61+
]""",
62+
],
5163
),
5264
(
5365
{"system_test_extras": ["abc", "def"]},
54-
['session.install("-e", ".[abc,def]", "-c", constraints_path)'],
66+
"""\
67+
SYSTEM_TEST_EXTRAS = [
68+
"abc",
69+
"def",
70+
]""",
5571
),
5672
(
5773
{"unit_test_extras_by_python": {"3.8": ["abc", "def"]}},
5874
[
59-
'if session.python == "3.8":\n extras = "[abc,def]"',
60-
'else:\n extras = ""',
61-
'session.install("-e", f".{extras}", "-c", constraints_path)',
75+
"""\
76+
UNIT_TEST_EXTRAS_BY_PYTHON = {
77+
"3.8": [
78+
"abc",
79+
"def",
80+
],
81+
}""",
6282
],
6383
),
6484
(
6585
{"system_test_extras_by_python": {"3.8": ["abc", "def"]}},
6686
[
67-
'if session.python == "3.8":\n extras = "[abc,def]"',
68-
'else:\n extras = ""',
69-
'session.install("-e", f".{extras}", "-c", constraints_path)',
87+
"""\
88+
SYSTEM_TEST_EXTRAS_BY_PYTHON = {
89+
"3.8": [
90+
"abc",
91+
"def",
92+
],
93+
}""",
7094
],
7195
),
7296
(
@@ -75,9 +99,18 @@
7599
"unit_test_extras_by_python": {"3.8": ["abc", "def"]},
76100
},
77101
[
78-
'if session.python == "3.8":\n extras = "[abc,def]"',
79-
'else:\n extras = "[tuv,wxyz]"',
80-
'session.install("-e", f".{extras}", "-c", constraints_path)',
102+
"""\
103+
UNIT_TEST_EXTRAS = [
104+
"tuv",
105+
"wxyz",
106+
]""",
107+
"""\
108+
UNIT_TEST_EXTRAS_BY_PYTHON = {
109+
"3.8": [
110+
"abc",
111+
"def",
112+
],
113+
}""",
81114
],
82115
),
83116
(
@@ -86,9 +119,18 @@
86119
"system_test_extras_by_python": {"3.8": ["abc", "def"]},
87120
},
88121
[
89-
'if session.python == "3.8":\n extras = "[abc,def]"',
90-
'else:\n extras = "[tuv,wxyz]"',
91-
'session.install("-e", f".{extras}", "-c", constraints_path)',
122+
"""\
123+
SYSTEM_TEST_EXTRAS = [
124+
"tuv",
125+
"wxyz",
126+
]""",
127+
"""\
128+
SYSTEM_TEST_EXTRAS_BY_PYTHON = {
129+
"3.8": [
130+
"abc",
131+
"def",
132+
],
133+
}""",
92134
],
93135
),
94136
],

0 commit comments

Comments
 (0)