blob: db37c5617819a92f865141ee17fff7e953fbf50c [file] [log] [blame]
Luke Sneeringeracb6e3e2017-10-31 08:57:09 -07001# Copyright 2016 Google LLC
Jon Wayne Parrott77fb0f22017-10-18 12:52:35 -07002#
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7# http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
14
15from __future__ import absolute_import
16import os
Bu Sun Kimc5fee892021-01-13 14:46:03 -070017import pathlib
Bu Sun Kimbee4b072019-06-25 12:44:16 -070018import shutil
Jon Wayne Parrott77fb0f22017-10-18 12:52:35 -070019
Rebecca Chen0fce6372018-09-27 10:45:58 -070020# https://github.com/google/importlab/issues/25
21import nox # pytype: disable=import-error
Jon Wayne Parrott77fb0f22017-10-18 12:52:35 -070022
Tres Seaverfbf447c2021-06-16 13:45:41 -040023
24BLACK_VERSION = "black==19.10b0"
25BLACK_PATHS = ["docs", "google", "tests", "noxfile.py", "setup.py"]
26# Black and flake8 clash on the syntax for ignoring flake8's F401 in this file.
27BLACK_EXCLUDES = ["--exclude", "^/google/api_core/operations_v1/__init__.py"]
28
29DEFAULT_PYTHON_VERSION = "3.7"
Bu Sun Kimc5fee892021-01-13 14:46:03 -070030CURRENT_DIRECTORY = pathlib.Path(__file__).parent.absolute()
Lidi Zhenga82f2892020-05-26 17:30:51 -070031
Tres Seaver1db493c2021-08-30 13:45:35 -040032# 'docfx' is excluded since it only needs to run in 'docs-presubmit'
33nox.options.sessions = [
34 "unit",
35 "unit_grpc_gcp",
Tres Seaver09cf2852021-10-19 12:58:59 -040036 "unit_wo_grpc",
Tres Seaver1db493c2021-08-30 13:45:35 -040037 "cover",
38 "pytype",
Tres Seaver0023ee12021-10-13 17:54:33 -040039 "mypy",
Tres Seaver1db493c2021-08-30 13:45:35 -040040 "lint",
41 "lint_setup_py",
42 "blacken",
43 "docs",
44]
Lidi Zhenga82f2892020-05-26 17:30:51 -070045
Tres Seaverfbf447c2021-06-16 13:45:41 -040046
Lidi Zhenga82f2892020-05-26 17:30:51 -070047def _greater_or_equal_than_36(version_string):
Tres Seaverfdbed0f2020-12-10 15:19:02 -050048 tokens = version_string.split(".")
Lidi Zhenga82f2892020-05-26 17:30:51 -070049 for i, token in enumerate(tokens):
50 try:
51 tokens[i] = int(token)
52 except ValueError:
53 pass
54 return tokens >= [3, 6]
55
Jon Wayne Parrott77fb0f22017-10-18 12:52:35 -070056
Tres Seaverfbf447c2021-06-16 13:45:41 -040057@nox.session(python=DEFAULT_PYTHON_VERSION)
58def lint(session):
59 """Run linters.
60
61 Returns a failure if the linters find linting errors or sufficiently
62 serious code quality issues.
63 """
64 session.install("flake8", "flake8-import-order", BLACK_VERSION)
65 session.install(".")
66 session.run(
67 "black", "--check", *BLACK_EXCLUDES, *BLACK_PATHS,
68 )
69 session.run("flake8", "google", "tests")
70
71
72@nox.session(python=DEFAULT_PYTHON_VERSION)
73def blacken(session):
74 """Run black.
75
76 Format code to uniform standard.
77 """
78 session.install(BLACK_VERSION)
79 session.run("black", *BLACK_EXCLUDES, *BLACK_PATHS)
80
81
Tres Seaver09cf2852021-10-19 12:58:59 -040082def default(session, install_grpc=True):
Danny Hermesfd1d18f2017-11-01 21:47:55 -070083 """Default unit test session.
Jon Wayne Parrott77fb0f22017-10-18 12:52:35 -070084
Danny Hermesfd1d18f2017-11-01 21:47:55 -070085 This is intended to be run **without** an interpreter set, so
86 that the current ``python`` (on the ``PATH``) or the version of
87 Python corresponding to the ``nox`` binary the ``PATH`` can
88 run the tests.
89 """
Bu Sun Kimc5fee892021-01-13 14:46:03 -070090 constraints_path = str(
91 CURRENT_DIRECTORY / "testing" / f"constraints-{session.python}.txt"
92 )
93
Jon Wayne Parrott77fb0f22017-10-18 12:52:35 -070094 # Install all test dependencies, then install this package in-place.
Tres Seaverffa528e2021-08-12 17:42:46 -040095 session.install("mock", "pytest", "pytest-cov")
Tres Seaver09cf2852021-10-19 12:58:59 -040096 if install_grpc:
97 session.install("-e", ".[grpc]", "-c", constraints_path)
98 else:
99 session.install("-e", ".", "-c", constraints_path)
Jon Wayne Parrott77fb0f22017-10-18 12:52:35 -0700100
Lidi Zhenga82f2892020-05-26 17:30:51 -0700101 pytest_args = [
102 "python",
103 "-m",
Christopher Wilcox6f4070d2018-11-29 11:02:52 -0800104 "py.test",
105 "--quiet",
106 "--cov=google.api_core",
107 "--cov=tests.unit",
108 "--cov-append",
109 "--cov-config=.coveragerc",
110 "--cov-report=",
Tres Seaver0c2c5562020-02-25 13:59:11 -0500111 "--cov-fail-under=0",
Christopher Wilcox6f4070d2018-11-29 11:02:52 -0800112 os.path.join("tests", "unit"),
Lidi Zhenga82f2892020-05-26 17:30:51 -0700113 ]
114 pytest_args.extend(session.posargs)
115
Bu Sun Kimff6ef1b2021-08-03 11:47:13 -0600116 # Inject AsyncIO content and proto-plus, if version >= 3.6.
117 # proto-plus is needed for a field mask test in test_protobuf_helpers.py
Lidi Zhenga82f2892020-05-26 17:30:51 -0700118 if _greater_or_equal_than_36(session.python):
Bu Sun Kimff6ef1b2021-08-03 11:47:13 -0600119 session.install("asyncmock", "pytest-asyncio", "proto-plus")
Lidi Zhenga82f2892020-05-26 17:30:51 -0700120
121 pytest_args.append("--cov=tests.asyncio")
122 pytest_args.append(os.path.join("tests", "asyncio"))
123 session.run(*pytest_args)
124 else:
125 # Run py.test against the unit tests.
126 session.run(*pytest_args)
Jon Wayne Parrott77fb0f22017-10-18 12:52:35 -0700127
128
Tres Seavera422a5d2021-10-05 16:54:45 -0400129@nox.session(python=["3.6", "3.7", "3.8", "3.9", "3.10"])
Bu Sun Kim9f45e3c2018-10-10 11:04:44 -0700130def unit(session):
Danny Hermesfd1d18f2017-11-01 21:47:55 -0700131 """Run the unit test suite."""
Danny Hermesfd1d18f2017-11-01 21:47:55 -0700132 default(session)
133
134
Tres Seavera30f0042021-08-03 13:59:25 -0400135@nox.session(python=["3.6", "3.7", "3.8", "3.9"])
Bu Sun Kim9f45e3c2018-10-10 11:04:44 -0700136def unit_grpc_gcp(session):
Weiran Fang0a5c85c2018-07-27 11:30:48 -0700137 """Run the unit test suite with grpcio-gcp installed."""
Bu Sun Kimc5fee892021-01-13 14:46:03 -0700138 constraints_path = str(
139 CURRENT_DIRECTORY / "testing" / f"constraints-{session.python}.txt"
140 )
Weiran Fang0a5c85c2018-07-27 11:30:48 -0700141 # Install grpcio-gcp
Tres Seaverffa528e2021-08-12 17:42:46 -0400142 session.install("-e", ".[grpcgcp]", "-c", constraints_path)
Weiran Fang0a5c85c2018-07-27 11:30:48 -0700143
144 default(session)
145
146
Tres Seaver09cf2852021-10-19 12:58:59 -0400147@nox.session(python=["3.6", "3.10"])
148def unit_wo_grpc(session):
149 """Run the unit test suite w/o grpcio installed"""
150 default(session, install_grpc=False)
151
152
Christopher Wilcox6f4070d2018-11-29 11:02:52 -0800153@nox.session(python="3.6")
Jon Wayne Parrott77fb0f22017-10-18 12:52:35 -0700154def lint_setup_py(session):
155 """Verify that setup.py is valid (including RST check)."""
Jon Wayne Parrott77fb0f22017-10-18 12:52:35 -0700156
Christopher Wilcox6f4070d2018-11-29 11:02:52 -0800157 session.install("docutils", "Pygments")
158 session.run("python", "setup.py", "check", "--restructuredtext", "--strict")
Jon Wayne Parrott77fb0f22017-10-18 12:52:35 -0700159
160
Rebecca Chen0fce6372018-09-27 10:45:58 -0700161# No 3.7 because pytype supports up to 3.6 only.
Christopher Wilcox6f4070d2018-11-29 11:02:52 -0800162@nox.session(python="3.6")
Rebecca Chen0fce6372018-09-27 10:45:58 -0700163def pytype(session):
Christopher Wilcox6f4070d2018-11-29 11:02:52 -0800164 """Run type-checking."""
Tres Seaverffa528e2021-08-12 17:42:46 -0400165 session.install(".[grpc, grpcgcp]", "pytype >= 2019.3.21")
Christopher Wilcox6f4070d2018-11-29 11:02:52 -0800166 session.run("pytype")
Rebecca Chen0fce6372018-09-27 10:45:58 -0700167
168
Tres Seaver0023ee12021-10-13 17:54:33 -0400169@nox.session(python=DEFAULT_PYTHON_VERSION)
170def mypy(session):
171 """Run type-checking."""
172 session.install(".[grpc, grpcgcp]", "mypy")
Tres Seaverbc0abe42021-11-18 14:58:20 -0500173 session.install(
174 "types-setuptools", "types-requests", "types-protobuf", "types-mock"
175 )
Tres Seaver0023ee12021-10-13 17:54:33 -0400176 session.run("mypy", "google", "tests")
177
178
Christopher Wilcox6f4070d2018-11-29 11:02:52 -0800179@nox.session(python="3.6")
Jon Wayne Parrott77fb0f22017-10-18 12:52:35 -0700180def cover(session):
181 """Run the final coverage report.
182
183 This outputs the coverage report aggregating coverage from the unit
184 test runs (not system test runs), and then erases coverage data.
185 """
Christopher Wilcox6f4070d2018-11-29 11:02:52 -0800186 session.install("coverage", "pytest-cov")
187 session.run("coverage", "report", "--show-missing", "--fail-under=100")
188 session.run("coverage", "erase")
Bu Sun Kimbee4b072019-06-25 12:44:16 -0700189
190
Dan Lee877fabc2021-07-07 11:40:46 -0400191@nox.session(python="3.8")
Bu Sun Kimbee4b072019-06-25 12:44:16 -0700192def docs(session):
193 """Build the docs for this library."""
194
Tres Seaverffa528e2021-08-12 17:42:46 -0400195 session.install("-e", ".[grpc, grpcgcp]")
Dan Lee877fabc2021-07-07 11:40:46 -0400196 session.install("sphinx==4.0.1", "alabaster", "recommonmark")
Bu Sun Kimbee4b072019-06-25 12:44:16 -0700197
198 shutil.rmtree(os.path.join("docs", "_build"), ignore_errors=True)
199 session.run(
200 "sphinx-build",
201 "-W", # warnings as errors
202 "-T", # show full traceback on exception
203 "-N", # no colors
204 "-b",
205 "html",
206 "-d",
207 os.path.join("docs", "_build", "doctrees", ""),
208 os.path.join("docs", ""),
209 os.path.join("docs", "_build", "html", ""),
Tres Seaver0c2c5562020-02-25 13:59:11 -0500210 )
Tres Seaveraaffc892020-12-02 14:31:03 -0500211
212
Dan Lee877fabc2021-07-07 11:40:46 -0400213@nox.session(python="3.8")
Tres Seaveraaffc892020-12-02 14:31:03 -0500214def docfx(session):
215 """Build the docfx yaml files for this library."""
216
217 session.install("-e", ".")
Dan Lee877fabc2021-07-07 11:40:46 -0400218 session.install(
219 "sphinx==4.0.1", "alabaster", "recommonmark", "gcp-sphinx-docfx-yaml"
220 )
Tres Seaveraaffc892020-12-02 14:31:03 -0500221
222 shutil.rmtree(os.path.join("docs", "_build"), ignore_errors=True)
223 session.run(
224 "sphinx-build",
225 "-T", # show full traceback on exception
226 "-N", # no colors
227 "-D",
228 (
229 "extensions=sphinx.ext.autodoc,"
230 "sphinx.ext.autosummary,"
231 "docfx_yaml.extension,"
232 "sphinx.ext.intersphinx,"
233 "sphinx.ext.coverage,"
234 "sphinx.ext.napoleon,"
235 "sphinx.ext.todo,"
236 "sphinx.ext.viewcode,"
237 "recommonmark"
238 ),
239 "-b",
240 "html",
241 "-d",
242 os.path.join("docs", "_build", "doctrees", ""),
243 os.path.join("docs", ""),
244 os.path.join("docs", "_build", "html", ""),
245 )