14 """Provides distutils command classes for the gRPC Python setup process."""
16 from distutils
import errors
as _errors
26 from setuptools.command
import build_ext
27 from setuptools.command
import build_py
28 from setuptools.command
import easy_install
29 from setuptools.command
import install
30 from setuptools.command
import test
32 PYTHON_STEM = os.path.dirname(os.path.abspath(__file__))
33 GRPC_STEM = os.path.abspath(PYTHON_STEM +
'../../../../')
34 GRPC_PROTO_STEM = os.path.join(GRPC_STEM,
'src',
'proto')
35 PROTO_STEM = os.path.join(PYTHON_STEM,
'src',
'proto')
36 PYTHON_PROTO_TOP_LEVEL = os.path.join(PYTHON_STEM,
'src')
45 description =
'gather proto dependencies'
58 shutil.rmtree(PROTO_STEM)
59 except Exception
as error:
62 shutil.copytree(GRPC_PROTO_STEM, PROTO_STEM)
63 for root, _, _
in os.walk(PYTHON_PROTO_TOP_LEVEL):
64 path = os.path.join(root,
'__init__.py')
68 class BuildPy(build_py.build_py):
69 """Custom project build command."""
73 self.run_command(
'build_package_protos')
74 except CommandError
as error:
75 sys.stderr.write(
'warning: %s\n' % error.message)
76 build_py.build_py.run(self)
80 """Command to run tests without fetching or building anything."""
82 description =
'run tests without fetching or building anything.'
93 self._add_eggs_to_path()
97 loader.loadTestsFromNames([
'tests'])
99 result = runner.run(loader.suite)
100 if not result.wasSuccessful():
101 sys.exit(
'Test failure')
104 """Fetch install and test requirements"""
105 self.distribution.fetch_build_eggs(self.distribution.install_requires)
106 self.distribution.fetch_build_eggs(self.distribution.tests_require)
110 """Command to run tests for Python 3+ features.
112 This does not include asyncio tests, which are housed in a separate
116 description =
'run tests for py3+ features'
126 self._add_eggs_to_path()
129 loader.loadTestsFromNames([
'tests_py3_only'])
131 result = runner.run(loader.suite)
132 if not result.wasSuccessful():
133 sys.exit(
'Test failure')
136 self.distribution.fetch_build_eggs(self.distribution.install_requires)
137 self.distribution.fetch_build_eggs(self.distribution.tests_require)
141 """Command to run aio tests without fetching or building anything."""
143 description =
'run aio tests without fetching or building anything.'
153 self._add_eggs_to_path()
157 loader.loadTestsFromNames([
'tests_aio'])
162 result = runner.run(loader.suite)
163 if not result.wasSuccessful():
164 sys.exit(
'Test failure')
167 """Fetch install and test requirements"""
168 self.distribution.fetch_build_eggs(self.distribution.install_requires)
169 self.distribution.fetch_build_eggs(self.distribution.tests_require)
173 """Command to run tests w/gevent."""
177 'fork._fork_interop_test.ForkInteropTest',
180 'unit._cython._no_messages_server_completion_queue_per_call_test.Test.test_rpcs',
181 'unit._cython._no_messages_single_server_completion_queue_test.Test.test_rpcs',
182 'unit._compression_test',
184 'unit._cython._channel_test.ChannelTest.test_multiple_channels_lonely_connectivity',
187 'testing._client_test.ClientTest.test_infinite_request_stream_real_time',
189 'unit._session_cache_test.SSLSessionCacheTest.testSSLSessionCacheLRU',
191 'unit._server_ssl_cert_config_test',
193 'protoc_plugin._python_plugin_test.PythonPluginTest',
194 'protoc_plugin._python_plugin_test.SimpleStubsPluginTest',
196 'protoc_plugin.beta_python_plugin_test',
197 'unit.beta._beta_features_test',
200 'unit._auth_context_test.AuthContextTest.testSessionResumption',
202 'unit._channel_ready_future_test.ChannelReadyFutureTest.test_immediately_connectable_channel_connectivity',
203 "unit._cython._channel_test.ChannelTest.test_single_channel_lonely_connectivity",
204 'unit._exit_test.ExitTest.test_in_flight_unary_unary_call',
205 'unit._exit_test.ExitTest.test_in_flight_unary_stream_call',
206 'unit._exit_test.ExitTest.test_in_flight_stream_unary_call',
207 'unit._exit_test.ExitTest.test_in_flight_stream_stream_call',
208 'unit._exit_test.ExitTest.test_in_flight_partial_unary_stream_call',
209 'unit._exit_test.ExitTest.test_in_flight_partial_stream_unary_call',
210 'unit._exit_test.ExitTest.test_in_flight_partial_stream_stream_call',
212 'unit._signal_handling_test.SignalHandlingTest',
213 'unit._metadata_flags_test',
214 'health_check._health_servicer_test.HealthServicerTest.test_cancelled_watch_removed_from_watch_list',
216 'channelz._channelz_servicer_test.ChannelzServicerTest.test_many_subchannels',
217 'channelz._channelz_servicer_test.ChannelzServicerTest.test_many_subchannels_and_sockets',
218 'channelz._channelz_servicer_test.ChannelzServicerTest.test_streaming_rpc',
220 'unit._cython._channel_test.ChannelTest.test_negative_deadline_connectivity',
222 'unit._local_credentials_test.LocalCredentialsTest',
225 'unit._contextvars_propagation_test',
226 'testing._time_test.StrictRealTimeTest',
228 BANNED_WINDOWS_TESTS = (
230 'unit._dns_resolver_test.DNSResolverTest.test_connect_loopback',
232 'unit._server_test.ServerTest.test_failed_port_binding_exception',
234 BANNED_MACOS_TESTS = (
236 'unit._dynamic_stubs_test.DynamicStubTest',)
237 description =
'run tests with gevent. Assumes grpc/gevent are installed'
240 def initialize_options(self):
243 def finalize_options(self):
249 from gevent
import monkey
252 threadpool = gevent.hub.get_hub().threadpool
259 threadpool.maxsize = 1024
271 loader.loadTestsFromNames([
'tests',
'tests_gevent'])
273 if sys.platform ==
'win32':
274 runner.skip_tests(self.BANNED_TESTS + self.BANNED_WINDOWS_TESTS)
275 elif sys.platform ==
'darwin':
276 runner.skip_tests(self.BANNED_TESTS + self.BANNED_MACOS_TESTS)
278 runner.skip_tests(self.BANNED_TESTS)
279 result = gevent.spawn(runner.run, loader.suite)
281 if not result.value.wasSuccessful():
282 sys.exit(
'Test failure')
287 description =
'run interop test client/server'
289 (
'args=',
None,
'pass-thru arguments for the client/server'),
290 (
'client',
None,
'flag indicating to run the client'),
291 (
'server',
None,
'flag indicating to run the server'),
292 (
'use-asyncio',
None,
'flag indicating to run the asyncio stack')
303 raise _errors.DistutilsOptionError(
304 'you may only specify one of client or server')
307 if self.distribution.install_requires:
308 self.distribution.fetch_build_eggs(
309 self.distribution.install_requires)
310 if self.distribution.tests_require:
311 self.distribution.fetch_build_eggs(self.distribution.tests_require)
325 asyncio.get_event_loop().run_until_complete(
server.serve())
336 client.test_interoperability()
341 description =
'run fork test client'
342 user_options = [(
'args=',
'a',
'pass-thru arguments for the client')]
352 if self.distribution.install_requires:
353 self.distribution.fetch_build_eggs(
354 self.distribution.install_requires)
355 if self.distribution.tests_require:
356 self.distribution.fetch_build_eggs(self.distribution.tests_require)
360 sys.argv[1:] = self.args.
split()