blob: 926f9f5d0f89393453d2b8a6d53166477ac4356a [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",
36 "cover",
37 "pytype",
Tres Seaver0023ee12021-10-13 17:54:33 -040038 "mypy",
Tres Seaver1db493c2021-08-30 13:45:35 -040039 "lint",
40 "lint_setup_py",
41 "blacken",
42 "docs",
43]
Lidi Zhenga82f2892020-05-26 17:30:51 -070044
Tres Seaverfbf447c2021-06-16 13:45:41 -040045
Lidi Zhenga82f2892020-05-26 17:30:51 -070046def _greater_or_equal_than_36(version_string):
Tres Seaverfdbed0f2020-12-10 15:19:02 -050047 tokens = version_string.split(".")
Lidi Zhenga82f2892020-05-26 17:30:51 -070048 for i, token in enumerate(tokens):
49 try:
50 tokens[i] = int(token)
51 except ValueError:
52 pass
53 return tokens >= [3, 6]
54
Jon Wayne Parrott77fb0f22017-10-18 12:52:35 -070055
Tres Seaverfbf447c2021-06-16 13:45:41 -040056@nox.session(python=DEFAULT_PYTHON_VERSION)
57def lint(session):
58 """Run linters.
59
60 Returns a failure if the linters find linting errors or sufficiently
61 serious code quality issues.
62 """
63 session.install("flake8", "flake8-import-order", BLACK_VERSION)
64 session.install(".")
65 session.run(
66 "black", "--check", *BLACK_EXCLUDES, *BLACK_PATHS,
67 )
68 session.run("flake8", "google", "tests")
69
70
71@nox.session(python=DEFAULT_PYTHON_VERSION)
72def blacken(session):
73 """Run black.
74
75 Format code to uniform standard.
76 """
77 session.install(BLACK_VERSION)
78 session.run("black", *BLACK_EXCLUDES, *BLACK_PATHS)
79
80
Danny Hermesfd1d18f2017-11-01 21:47:55 -070081def default(session):
82 """Default unit test session.
Jon Wayne Parrott77fb0f22017-10-18 12:52:35 -070083
Danny Hermesfd1d18f2017-11-01 21:47:55 -070084 This is intended to be run **without** an interpreter set, so
85 that the current ``python`` (on the ``PATH``) or the version of
86 Python corresponding to the ``nox`` binary the ``PATH`` can
87 run the tests.
88 """
Bu Sun Kimc5fee892021-01-13 14:46:03 -070089 constraints_path = str(
90 CURRENT_DIRECTORY / "testing" / f"constraints-{session.python}.txt"
91 )
92
Jon Wayne Parrott77fb0f22017-10-18 12:52:35 -070093 # Install all test dependencies, then install this package in-place.
Tres Seaverffa528e2021-08-12 17:42:46 -040094 session.install("mock", "pytest", "pytest-cov")
95 session.install("-e", ".[grpc]", "-c", constraints_path)
Jon Wayne Parrott77fb0f22017-10-18 12:52:35 -070096
Lidi Zhenga82f2892020-05-26 17:30:51 -070097 pytest_args = [
98 "python",
99 "-m",
Christopher Wilcox6f4070d2018-11-29 11:02:52 -0800100 "py.test",
101 "--quiet",
102 "--cov=google.api_core",
103 "--cov=tests.unit",
104 "--cov-append",
105 "--cov-config=.coveragerc",
106 "--cov-report=",
Tres Seaver0c2c5562020-02-25 13:59:11 -0500107 "--cov-fail-under=0",
Christopher Wilcox6f4070d2018-11-29 11:02:52 -0800108 os.path.join("tests", "unit"),
Lidi Zhenga82f2892020-05-26 17:30:51 -0700109 ]
110 pytest_args.extend(session.posargs)
111
Bu Sun Kimff6ef1b2021-08-03 11:47:13 -0600112 # Inject AsyncIO content and proto-plus, if version >= 3.6.
113 # proto-plus is needed for a field mask test in test_protobuf_helpers.py
Lidi Zhenga82f2892020-05-26 17:30:51 -0700114 if _greater_or_equal_than_36(session.python):
Bu Sun Kimff6ef1b2021-08-03 11:47:13 -0600115 session.install("asyncmock", "pytest-asyncio", "proto-plus")
Lidi Zhenga82f2892020-05-26 17:30:51 -0700116
117 pytest_args.append("--cov=tests.asyncio")
118 pytest_args.append(os.path.join("tests", "asyncio"))
119 session.run(*pytest_args)
120 else:
121 # Run py.test against the unit tests.
122 session.run(*pytest_args)
Jon Wayne Parrott77fb0f22017-10-18 12:52:35 -0700123
124
Tres Seavera422a5d2021-10-05 16:54:45 -0400125@nox.session(python=["3.6", "3.7", "3.8", "3.9", "3.10"])
Bu Sun Kim9f45e3c2018-10-10 11:04:44 -0700126def unit(session):
Danny Hermesfd1d18f2017-11-01 21:47:55 -0700127 """Run the unit test suite."""
Danny Hermesfd1d18f2017-11-01 21:47:55 -0700128 default(session)
129
130
Tres Seavera30f0042021-08-03 13:59:25 -0400131@nox.session(python=["3.6", "3.7", "3.8", "3.9"])
Bu Sun Kim9f45e3c2018-10-10 11:04:44 -0700132def unit_grpc_gcp(session):
Weiran Fang0a5c85c2018-07-27 11:30:48 -0700133 """Run the unit test suite with grpcio-gcp installed."""
Bu Sun Kimc5fee892021-01-13 14:46:03 -0700134 constraints_path = str(
135 CURRENT_DIRECTORY / "testing" / f"constraints-{session.python}.txt"
136 )
Weiran Fang0a5c85c2018-07-27 11:30:48 -0700137 # Install grpcio-gcp
Tres Seaverffa528e2021-08-12 17:42:46 -0400138 session.install("-e", ".[grpcgcp]", "-c", constraints_path)
Weiran Fang0a5c85c2018-07-27 11:30:48 -0700139
140 default(session)
141
142
Christopher Wilcox6f4070d2018-11-29 11:02:52 -0800143@nox.session(python="3.6")
Jon Wayne Parrott77fb0f22017-10-18 12:52:35 -0700144def lint_setup_py(session):
145 """Verify that setup.py is valid (including RST check)."""
Jon Wayne Parrott77fb0f22017-10-18 12:52:35 -0700146
Christopher Wilcox6f4070d2018-11-29 11:02:52 -0800147 session.install("docutils", "Pygments")
148 session.run("python", "setup.py", "check", "--restructuredtext", "--strict")
Jon Wayne Parrott77fb0f22017-10-18 12:52:35 -0700149
150
Rebecca Chen0fce6372018-09-27 10:45:58 -0700151# No 3.7 because pytype supports up to 3.6 only.
Christopher Wilcox6f4070d2018-11-29 11:02:52 -0800152@nox.session(python="3.6")
Rebecca Chen0fce6372018-09-27 10:45:58 -0700153def pytype(session):
Christopher Wilcox6f4070d2018-11-29 11:02:52 -0800154 """Run type-checking."""
Tres Seaverffa528e2021-08-12 17:42:46 -0400155 session.install(".[grpc, grpcgcp]", "pytype >= 2019.3.21")
Christopher Wilcox6f4070d2018-11-29 11:02:52 -0800156 session.run("pytype")
Rebecca Chen0fce6372018-09-27 10:45:58 -0700157
158
Tres Seaver0023ee12021-10-13 17:54:33 -0400159@nox.session(python=DEFAULT_PYTHON_VERSION)
160def mypy(session):
161 """Run type-checking."""
162 session.install(".[grpc, grpcgcp]", "mypy")
163 session.install("types-setuptools", "types-requests", "types-mock")
164 session.run("mypy", "google", "tests")
165
166
Christopher Wilcox6f4070d2018-11-29 11:02:52 -0800167@nox.session(python="3.6")
Jon Wayne Parrott77fb0f22017-10-18 12:52:35 -0700168def cover(session):
169 """Run the final coverage report.
170
171 This outputs the coverage report aggregating coverage from the unit
172 test runs (not system test runs), and then erases coverage data.
173 """
Christopher Wilcox6f4070d2018-11-29 11:02:52 -0800174 session.install("coverage", "pytest-cov")
175 session.run("coverage", "report", "--show-missing", "--fail-under=100")
176 session.run("coverage", "erase")
Bu Sun Kimbee4b072019-06-25 12:44:16 -0700177
178
Dan Lee877fabc2021-07-07 11:40:46 -0400179@nox.session(python="3.8")
Bu Sun Kimbee4b072019-06-25 12:44:16 -0700180def docs(session):
181 """Build the docs for this library."""
182
Tres Seaverffa528e2021-08-12 17:42:46 -0400183 session.install("-e", ".[grpc, grpcgcp]")
Dan Lee877fabc2021-07-07 11:40:46 -0400184 session.install("sphinx==4.0.1", "alabaster", "recommonmark")
Bu Sun Kimbee4b072019-06-25 12:44:16 -0700185
186 shutil.rmtree(os.path.join("docs", "_build"), ignore_errors=True)
187 session.run(
188 "sphinx-build",
189 "-W", # warnings as errors
190 "-T", # show full traceback on exception
191 "-N", # no colors
192 "-b",
193 "html",
194 "-d",
195 os.path.join("docs", "_build", "doctrees", ""),
196 os.path.join("docs", ""),
197 os.path.join("docs", "_build", "html", ""),
Tres Seaver0c2c5562020-02-25 13:59:11 -0500198 )
Tres Seaveraaffc892020-12-02 14:31:03 -0500199
200
Dan Lee877fabc2021-07-07 11:40:46 -0400201@nox.session(python="3.8")
Tres Seaveraaffc892020-12-02 14:31:03 -0500202def docfx(session):
203 """Build the docfx yaml files for this library."""
204
205 session.install("-e", ".")
Dan Lee877fabc2021-07-07 11:40:46 -0400206 session.install(
207 "sphinx==4.0.1", "alabaster", "recommonmark", "gcp-sphinx-docfx-yaml"
208 )
Tres Seaveraaffc892020-12-02 14:31:03 -0500209
210 shutil.rmtree(os.path.join("docs", "_build"), ignore_errors=True)
211 session.run(
212 "sphinx-build",
213 "-T", # show full traceback on exception
214 "-N", # no colors
215 "-D",
216 (
217 "extensions=sphinx.ext.autodoc,"
218 "sphinx.ext.autosummary,"
219 "docfx_yaml.extension,"
220 "sphinx.ext.intersphinx,"
221 "sphinx.ext.coverage,"
222 "sphinx.ext.napoleon,"
223 "sphinx.ext.todo,"
224 "sphinx.ext.viewcode,"
225 "recommonmark"
226 ),
227 "-b",
228 "html",
229 "-d",
230 os.path.join("docs", "_build", "doctrees", ""),
231 os.path.join("docs", ""),
232 os.path.join("docs", "_build", "html", ""),
233 )