aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/python
diff options
context:
space:
mode:
Diffstat (limited to 'src/python')
-rw-r--r--src/python/.gitignore1
-rw-r--r--src/python/grpcio/commands.py6
-rw-r--r--src/python/grpcio/grpc/_channel.py10
-rw-r--r--src/python/grpcio/grpc/_common.py2
-rw-r--r--src/python/grpcio/grpc/_cython/_cygrpc/arguments.pxd.pxi4
-rw-r--r--src/python/grpcio/grpc/_cython/_cygrpc/arguments.pyx.pxi4
-rw-r--r--src/python/grpcio/grpc/_cython/_cygrpc/grpc_string.pyx.pxi2
-rw-r--r--src/python/grpcio/grpc/_cython/_cygrpc/server.pyx.pxi2
-rw-r--r--src/python/grpcio/grpc/_plugin_wrapping.py2
-rw-r--r--src/python/grpcio/grpc/_server.py1
-rw-r--r--src/python/grpcio/grpc/framework/foundation/callable_util.py2
-rw-r--r--src/python/grpcio/grpc/framework/foundation/logging_pool.py2
-rw-r--r--src/python/grpcio/grpc/framework/foundation/stream_util.py2
-rw-r--r--src/python/grpcio/grpc_core_dependencies.py17
-rw-r--r--src/python/grpcio_tests/commands.py2
-rw-r--r--src/python/grpcio_tests/tests/interop/server.py2
-rw-r--r--src/python/grpcio_tests/tests/tests.json1
-rw-r--r--src/python/grpcio_tests/tests/unit/BUILD.bazel1
-rw-r--r--src/python/grpcio_tests/tests/unit/_api_test.py2
-rw-r--r--src/python/grpcio_tests/tests/unit/_auth_context_test.py2
-rw-r--r--src/python/grpcio_tests/tests/unit/_auth_test.py2
-rw-r--r--src/python/grpcio_tests/tests/unit/_channel_args_test.py18
-rw-r--r--src/python/grpcio_tests/tests/unit/_channel_close_test.py2
-rw-r--r--src/python/grpcio_tests/tests/unit/_channel_connectivity_test.py2
-rw-r--r--src/python/grpcio_tests/tests/unit/_channel_ready_future_test.py2
-rw-r--r--src/python/grpcio_tests/tests/unit/_compression_test.py2
-rw-r--r--src/python/grpcio_tests/tests/unit/_credentials_test.py2
-rw-r--r--src/python/grpcio_tests/tests/unit/_empty_message_test.py2
-rw-r--r--src/python/grpcio_tests/tests/unit/_exit_scenarios.py2
-rw-r--r--src/python/grpcio_tests/tests/unit/_exit_test.py2
-rw-r--r--src/python/grpcio_tests/tests/unit/_interceptor_test.py2
-rw-r--r--src/python/grpcio_tests/tests/unit/_invalid_metadata_test.py2
-rw-r--r--src/python/grpcio_tests/tests/unit/_invocation_defects_test.py2
-rw-r--r--src/python/grpcio_tests/tests/unit/_logging_test.py73
-rw-r--r--src/python/grpcio_tests/tests/unit/_metadata_code_details_test.py2
-rw-r--r--src/python/grpcio_tests/tests/unit/_metadata_test.py2
-rw-r--r--src/python/grpcio_tests/tests/unit/_reconnect_test.py2
-rw-r--r--src/python/grpcio_tests/tests/unit/_resource_exhausted_test.py2
-rw-r--r--src/python/grpcio_tests/tests/unit/_rpc_test.py2
-rw-r--r--src/python/grpcio_tests/tests/unit/_server_ssl_cert_config_test.py2
-rw-r--r--src/python/grpcio_tests/tests/unit/_server_test.py2
-rw-r--r--src/python/grpcio_tests/tests/unit/_session_cache_test.py2
42 files changed, 178 insertions, 20 deletions
diff --git a/src/python/.gitignore b/src/python/.gitignore
index 7b520579a0..41813129bd 100644
--- a/src/python/.gitignore
+++ b/src/python/.gitignore
@@ -1,3 +1,4 @@
gens/
*_pb2.py
*_pb2_grpc.py
+*.egg-info/
diff --git a/src/python/grpcio/commands.py b/src/python/grpcio/commands.py
index 0a3097111f..3cb0eb179e 100644
--- a/src/python/grpcio/commands.py
+++ b/src/python/grpcio/commands.py
@@ -274,8 +274,14 @@ class BuildExt(build_ext.build_ext):
extra_defines = [
'EXTRA_DEFINES="GRPC_POSIX_FORK_ALLOW_PTHREAD_ATFORK=1"'
]
+ # Ensure the BoringSSL are built instead of using system provided
+ # libraries. It prevents dependency issues while distributing to
+ # Mac users who use MacPorts to manage their libraries. #17002
+ mod_env = dict(os.environ)
+ mod_env['REQUIRE_CUSTOM_LIBRARIES_opt'] = '1'
make_process = subprocess.Popen(
['make'] + extra_defines + targets,
+ env=mod_env,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
make_out, make_err = make_process.communicate()
diff --git a/src/python/grpcio/grpc/_channel.py b/src/python/grpcio/grpc/_channel.py
index 3494c9b15a..734eac3801 100644
--- a/src/python/grpcio/grpc/_channel.py
+++ b/src/python/grpcio/grpc/_channel.py
@@ -24,8 +24,8 @@ from grpc import _grpcio_metadata
from grpc._cython import cygrpc
from grpc.framework.foundation import callable_util
-logging.basicConfig()
_LOGGER = logging.getLogger(__name__)
+_LOGGER.addHandler(logging.NullHandler())
_USER_AGENT = 'grpc-python/{}'.format(_grpcio_metadata.__version__)
@@ -980,5 +980,9 @@ class Channel(grpc.Channel):
# for as long as they are in use and to close them after using them,
# then deletion of this grpc._channel.Channel instance can be made to
# effect closure of the underlying cygrpc.Channel instance.
- cygrpc.fork_unregister_channel(self)
- _moot(self._connectivity_state)
+ if cygrpc is not None: # Globals may have already been collected.
+ cygrpc.fork_unregister_channel(self)
+ # This prevent the failed-at-initializing object removal from failing.
+ # Though the __init__ failed, the removal will still trigger __del__.
+ if _moot is not None and hasattr(self, "_connectivity_state"):
+ _moot(self._connectivity_state)
diff --git a/src/python/grpcio/grpc/_common.py b/src/python/grpcio/grpc/_common.py
index 3805c7e82a..d35f4566bd 100644
--- a/src/python/grpcio/grpc/_common.py
+++ b/src/python/grpcio/grpc/_common.py
@@ -20,8 +20,8 @@ import six
import grpc
from grpc._cython import cygrpc
-logging.basicConfig()
_LOGGER = logging.getLogger(__name__)
+_LOGGER.addHandler(logging.NullHandler())
CYGRPC_CONNECTIVITY_STATE_TO_CHANNEL_CONNECTIVITY = {
cygrpc.ConnectivityState.idle:
diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/arguments.pxd.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/arguments.pxd.pxi
index 6cb1bc0c05..e0e068e452 100644
--- a/src/python/grpcio/grpc/_cython/_cygrpc/arguments.pxd.pxi
+++ b/src/python/grpcio/grpc/_cython/_cygrpc/arguments.pxd.pxi
@@ -32,7 +32,7 @@ cdef class _ArgumentProcessor:
cdef grpc_arg c_argument
- cdef void c(self, argument, grpc_arg_pointer_vtable *vtable, references)
+ cdef void c(self, argument, grpc_arg_pointer_vtable *vtable, references) except *
cdef class _ArgumentsProcessor:
@@ -42,5 +42,5 @@ cdef class _ArgumentsProcessor:
cdef readonly list _references
cdef grpc_channel_args _c_arguments
- cdef grpc_channel_args *c(self, grpc_arg_pointer_vtable *vtable)
+ cdef grpc_channel_args *c(self, grpc_arg_pointer_vtable *vtable) except *
cdef un_c(self)
diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/arguments.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/arguments.pyx.pxi
index 2239e26b32..b7a4277ff6 100644
--- a/src/python/grpcio/grpc/_cython/_cygrpc/arguments.pyx.pxi
+++ b/src/python/grpcio/grpc/_cython/_cygrpc/arguments.pyx.pxi
@@ -52,7 +52,7 @@ cdef grpc_arg _unwrap_grpc_arg(tuple wrapped_arg):
cdef class _ArgumentProcessor:
- cdef void c(self, argument, grpc_arg_pointer_vtable *vtable, references):
+ cdef void c(self, argument, grpc_arg_pointer_vtable *vtable, references) except *:
key, value = argument
cdef bytes encoded_key = _encode(key)
if encoded_key is not key:
@@ -89,7 +89,7 @@ cdef class _ArgumentsProcessor:
self._argument_processors = []
self._references = []
- cdef grpc_channel_args *c(self, grpc_arg_pointer_vtable *vtable):
+ cdef grpc_channel_args *c(self, grpc_arg_pointer_vtable *vtable) except *:
self._c_arguments.arguments_length = len(self._arguments)
if self._c_arguments.arguments_length == 0:
return NULL
diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/grpc_string.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/grpc_string.pyx.pxi
index 334e561baa..fa356d913e 100644
--- a/src/python/grpcio/grpc/_cython/_cygrpc/grpc_string.pyx.pxi
+++ b/src/python/grpcio/grpc/_cython/_cygrpc/grpc_string.pyx.pxi
@@ -14,8 +14,8 @@
import logging
-logging.basicConfig()
_LOGGER = logging.getLogger(__name__)
+_LOGGER.addHandler(logging.NullHandler())
# This function will ascii encode unicode string inputs if neccesary.
# In Python3, unicode strings are the default str type.
diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/server.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/server.pyx.pxi
index 5779437b92..f9d1e863ca 100644
--- a/src/python/grpcio/grpc/_cython/_cygrpc/server.pyx.pxi
+++ b/src/python/grpcio/grpc/_cython/_cygrpc/server.pyx.pxi
@@ -18,8 +18,8 @@ import logging
import time
import grpc
-logging.basicConfig()
_LOGGER = logging.getLogger(__name__)
+_LOGGER.addHandler(logging.NullHandler())
cdef class Server:
diff --git a/src/python/grpcio/grpc/_plugin_wrapping.py b/src/python/grpcio/grpc/_plugin_wrapping.py
index 88ab4d8371..53af2ff913 100644
--- a/src/python/grpcio/grpc/_plugin_wrapping.py
+++ b/src/python/grpcio/grpc/_plugin_wrapping.py
@@ -20,8 +20,8 @@ import grpc
from grpc import _common
from grpc._cython import cygrpc
-logging.basicConfig()
_LOGGER = logging.getLogger(__name__)
+_LOGGER.addHandler(logging.NullHandler())
class _AuthMetadataContext(
diff --git a/src/python/grpcio/grpc/_server.py b/src/python/grpcio/grpc/_server.py
index daa000a6e1..7276a7fd90 100644
--- a/src/python/grpcio/grpc/_server.py
+++ b/src/python/grpcio/grpc/_server.py
@@ -27,7 +27,6 @@ from grpc import _interceptor
from grpc._cython import cygrpc
from grpc.framework.foundation import callable_util
-logging.basicConfig()
_LOGGER = logging.getLogger(__name__)
_SHUTDOWN_TAG = 'shutdown'
diff --git a/src/python/grpcio/grpc/framework/foundation/callable_util.py b/src/python/grpcio/grpc/framework/foundation/callable_util.py
index fb8d5f7c1e..36066e19df 100644
--- a/src/python/grpcio/grpc/framework/foundation/callable_util.py
+++ b/src/python/grpcio/grpc/framework/foundation/callable_util.py
@@ -21,8 +21,8 @@ import logging
import six
-logging.basicConfig()
_LOGGER = logging.getLogger(__name__)
+_LOGGER.addHandler(logging.NullHandler())
class Outcome(six.with_metaclass(abc.ABCMeta)):
diff --git a/src/python/grpcio/grpc/framework/foundation/logging_pool.py b/src/python/grpcio/grpc/framework/foundation/logging_pool.py
index 7702d1785f..dfb8dbdc30 100644
--- a/src/python/grpcio/grpc/framework/foundation/logging_pool.py
+++ b/src/python/grpcio/grpc/framework/foundation/logging_pool.py
@@ -17,8 +17,8 @@ import logging
from concurrent import futures
-logging.basicConfig()
_LOGGER = logging.getLogger(__name__)
+_LOGGER.addHandler(logging.NullHandler())
def _wrap(behavior):
diff --git a/src/python/grpcio/grpc/framework/foundation/stream_util.py b/src/python/grpcio/grpc/framework/foundation/stream_util.py
index 9184f95873..e03130cced 100644
--- a/src/python/grpcio/grpc/framework/foundation/stream_util.py
+++ b/src/python/grpcio/grpc/framework/foundation/stream_util.py
@@ -19,8 +19,8 @@ import threading
from grpc.framework.foundation import stream
_NO_VALUE = object()
-logging.basicConfig()
_LOGGER = logging.getLogger(__name__)
+_LOGGER.addHandler(logging.NullHandler())
class TransformingConsumer(stream.Consumer):
diff --git a/src/python/grpcio/grpc_core_dependencies.py b/src/python/grpcio/grpc_core_dependencies.py
index 932621a38d..7d9ce0cf28 100644
--- a/src/python/grpcio/grpc_core_dependencies.py
+++ b/src/python/grpcio/grpc_core_dependencies.py
@@ -208,6 +208,7 @@ CORE_SOURCE_FILES = [
'src/core/lib/transport/timeout_encoding.cc',
'src/core/lib/transport/transport.cc',
'src/core/lib/transport/transport_op_string.cc',
+ 'src/core/lib/uri/uri_parser.cc',
'src/core/lib/debug/trace.cc',
'src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.cc',
'src/core/ext/transport/chttp2/transport/bin_decoder.cc',
@@ -254,11 +255,14 @@ CORE_SOURCE_FILES = [
'src/core/lib/security/credentials/oauth2/oauth2_credentials.cc',
'src/core/lib/security/credentials/plugin/plugin_credentials.cc',
'src/core/lib/security/credentials/ssl/ssl_credentials.cc',
- 'src/core/lib/security/security_connector/alts_security_connector.cc',
+ 'src/core/lib/security/security_connector/alts/alts_security_connector.cc',
+ 'src/core/lib/security/security_connector/fake/fake_security_connector.cc',
'src/core/lib/security/security_connector/load_system_roots_fallback.cc',
'src/core/lib/security/security_connector/load_system_roots_linux.cc',
- 'src/core/lib/security/security_connector/local_security_connector.cc',
+ 'src/core/lib/security/security_connector/local/local_security_connector.cc',
'src/core/lib/security/security_connector/security_connector.cc',
+ 'src/core/lib/security/security_connector/ssl/ssl_security_connector.cc',
+ 'src/core/lib/security/security_connector/ssl_utils.cc',
'src/core/lib/security/transport/client_auth_filter.cc',
'src/core/lib/security/transport/secure_endpoint.cc',
'src/core/lib/security/transport/security_handshaker.cc',
@@ -313,6 +317,7 @@ CORE_SOURCE_FILES = [
'src/core/ext/filters/client_channel/client_channel_factory.cc',
'src/core/ext/filters/client_channel/client_channel_plugin.cc',
'src/core/ext/filters/client_channel/connector.cc',
+ 'src/core/ext/filters/client_channel/health/health_check_client.cc',
'src/core/ext/filters/client_channel/http_connect_handshaker.cc',
'src/core/ext/filters/client_channel/http_proxy.cc',
'src/core/ext/filters/client_channel/lb_policy.cc',
@@ -327,8 +332,8 @@ CORE_SOURCE_FILES = [
'src/core/ext/filters/client_channel/retry_throttle.cc',
'src/core/ext/filters/client_channel/subchannel.cc',
'src/core/ext/filters/client_channel/subchannel_index.cc',
- 'src/core/ext/filters/client_channel/uri_parser.cc',
'src/core/ext/filters/deadline/deadline_filter.cc',
+ 'src/core/ext/filters/client_channel/health/health.pb.c',
'src/core/tsi/alts_transport_security.cc',
'src/core/tsi/fake_transport_security.cc',
'src/core/tsi/local_transport_security.cc',
@@ -348,10 +353,14 @@ CORE_SOURCE_FILES = [
'src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel_secure.cc',
'src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.cc',
'src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.cc',
+ 'src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc',
'src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/duration.pb.c',
'src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/timestamp.pb.c',
'src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c',
- 'src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc',
+ 'src/core/ext/filters/client_channel/lb_policy/xds/xds.cc',
+ 'src/core/ext/filters/client_channel/lb_policy/xds/xds_channel_secure.cc',
+ 'src/core/ext/filters/client_channel/lb_policy/xds/xds_client_stats.cc',
+ 'src/core/ext/filters/client_channel/lb_policy/xds/xds_load_balancer_api.cc',
'src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc',
'src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc',
'src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc',
diff --git a/src/python/grpcio_tests/commands.py b/src/python/grpcio_tests/commands.py
index 0dfbf3180b..6931d93ef0 100644
--- a/src/python/grpcio_tests/commands.py
+++ b/src/python/grpcio_tests/commands.py
@@ -116,6 +116,8 @@ class TestGevent(setuptools.Command):
# eventually succeed, but need to dig into performance issues.
'unit._cython._no_messages_server_completion_queue_per_call_test.Test.test_rpcs',
'unit._cython._no_messages_single_server_completion_queue_test.Test.test_rpcs',
+ # TODO(https://github.com/grpc/grpc/issues/16890) enable this test
+ 'unit._cython._channel_test.ChannelTest.test_multiple_channels_lonely_connectivity',
# I have no idea why this doesn't work in gevent, but it shouldn't even be
# using the c-core
'testing._client_test.ClientTest.test_infinite_request_stream_real_time',
diff --git a/src/python/grpcio_tests/tests/interop/server.py b/src/python/grpcio_tests/tests/interop/server.py
index 768cdaf468..72f88a1c98 100644
--- a/src/python/grpcio_tests/tests/interop/server.py
+++ b/src/python/grpcio_tests/tests/interop/server.py
@@ -25,8 +25,8 @@ from tests.interop import methods
from tests.interop import resources
from tests.unit import test_common
-logging.basicConfig()
_ONE_DAY_IN_SECONDS = 60 * 60 * 24
+logging.basicConfig()
_LOGGER = logging.getLogger(__name__)
diff --git a/src/python/grpcio_tests/tests/tests.json b/src/python/grpcio_tests/tests/tests.json
index 76d5d22d57..5505369867 100644
--- a/src/python/grpcio_tests/tests/tests.json
+++ b/src/python/grpcio_tests/tests/tests.json
@@ -46,6 +46,7 @@
"unit._interceptor_test.InterceptorTest",
"unit._invalid_metadata_test.InvalidMetadataTest",
"unit._invocation_defects_test.InvocationDefectsTest",
+ "unit._logging_test.LoggingTest",
"unit._metadata_code_details_test.MetadataCodeDetailsTest",
"unit._metadata_test.MetadataTest",
"unit._reconnect_test.ReconnectTest",
diff --git a/src/python/grpcio_tests/tests/unit/BUILD.bazel b/src/python/grpcio_tests/tests/unit/BUILD.bazel
index dcd6d9fbb2..de33b81e32 100644
--- a/src/python/grpcio_tests/tests/unit/BUILD.bazel
+++ b/src/python/grpcio_tests/tests/unit/BUILD.bazel
@@ -17,6 +17,7 @@ GRPCIO_TESTS_UNIT = [
"_interceptor_test.py",
"_invalid_metadata_test.py",
"_invocation_defects_test.py",
+ "_logging_test.py",
"_metadata_code_details_test.py",
"_metadata_test.py",
# TODO: Issue 16336
diff --git a/src/python/grpcio_tests/tests/unit/_api_test.py b/src/python/grpcio_tests/tests/unit/_api_test.py
index f6245be77d..38072861a4 100644
--- a/src/python/grpcio_tests/tests/unit/_api_test.py
+++ b/src/python/grpcio_tests/tests/unit/_api_test.py
@@ -14,6 +14,7 @@
"""Test of gRPC Python's application-layer API."""
import unittest
+import logging
import six
@@ -102,4 +103,5 @@ class ChannelTest(unittest.TestCase):
if __name__ == '__main__':
+ logging.basicConfig()
unittest.main(verbosity=2)
diff --git a/src/python/grpcio_tests/tests/unit/_auth_context_test.py b/src/python/grpcio_tests/tests/unit/_auth_context_test.py
index d174051070..b1b5bbdcab 100644
--- a/src/python/grpcio_tests/tests/unit/_auth_context_test.py
+++ b/src/python/grpcio_tests/tests/unit/_auth_context_test.py
@@ -15,6 +15,7 @@
import pickle
import unittest
+import logging
import grpc
from grpc import _channel
@@ -187,4 +188,5 @@ class AuthContextTest(unittest.TestCase):
if __name__ == '__main__':
+ logging.basicConfig()
unittest.main(verbosity=2)
diff --git a/src/python/grpcio_tests/tests/unit/_auth_test.py b/src/python/grpcio_tests/tests/unit/_auth_test.py
index e2cb938936..d9df2add4f 100644
--- a/src/python/grpcio_tests/tests/unit/_auth_test.py
+++ b/src/python/grpcio_tests/tests/unit/_auth_test.py
@@ -16,6 +16,7 @@
import collections
import threading
import unittest
+import logging
from grpc import _auth
@@ -77,4 +78,5 @@ class AccessTokenAuthMetadataPluginTest(unittest.TestCase):
if __name__ == '__main__':
+ logging.basicConfig()
unittest.main(verbosity=2)
diff --git a/src/python/grpcio_tests/tests/unit/_channel_args_test.py b/src/python/grpcio_tests/tests/unit/_channel_args_test.py
index 869c2f4d2f..228c0e4c16 100644
--- a/src/python/grpcio_tests/tests/unit/_channel_args_test.py
+++ b/src/python/grpcio_tests/tests/unit/_channel_args_test.py
@@ -15,6 +15,7 @@
from concurrent import futures
import unittest
+import logging
import grpc
@@ -33,6 +34,14 @@ TEST_CHANNEL_ARGS = (
('arg6', TestPointerWrapper()),
)
+INVALID_TEST_CHANNEL_ARGS = [
+ {
+ 'foo': 'bar'
+ },
+ (('key',),),
+ 'str',
+]
+
class ChannelArgsTest(unittest.TestCase):
@@ -44,6 +53,15 @@ class ChannelArgsTest(unittest.TestCase):
futures.ThreadPoolExecutor(max_workers=1),
options=TEST_CHANNEL_ARGS)
+ def test_invalid_client_args(self):
+ for invalid_arg in INVALID_TEST_CHANNEL_ARGS:
+ self.assertRaises(
+ ValueError,
+ grpc.insecure_channel,
+ 'localhost:8080',
+ options=invalid_arg)
+
if __name__ == '__main__':
+ logging.basicConfig()
unittest.main(verbosity=2)
diff --git a/src/python/grpcio_tests/tests/unit/_channel_close_test.py b/src/python/grpcio_tests/tests/unit/_channel_close_test.py
index af3a9ee1ee..82fa165710 100644
--- a/src/python/grpcio_tests/tests/unit/_channel_close_test.py
+++ b/src/python/grpcio_tests/tests/unit/_channel_close_test.py
@@ -13,6 +13,7 @@
# limitations under the License.
"""Tests server and client side compression."""
+import logging
import threading
import time
import unittest
@@ -182,4 +183,5 @@ class ChannelCloseTest(unittest.TestCase):
if __name__ == '__main__':
+ logging.basicConfig()
unittest.main(verbosity=2)
diff --git a/src/python/grpcio_tests/tests/unit/_channel_connectivity_test.py b/src/python/grpcio_tests/tests/unit/_channel_connectivity_test.py
index f9eb0011dc..727fb7d65f 100644
--- a/src/python/grpcio_tests/tests/unit/_channel_connectivity_test.py
+++ b/src/python/grpcio_tests/tests/unit/_channel_connectivity_test.py
@@ -13,6 +13,7 @@
# limitations under the License.
"""Tests of grpc._channel.Channel connectivity."""
+import logging
import threading
import time
import unittest
@@ -142,4 +143,5 @@ class ChannelConnectivityTest(unittest.TestCase):
if __name__ == '__main__':
+ logging.basicConfig()
unittest.main(verbosity=2)
diff --git a/src/python/grpcio_tests/tests/unit/_channel_ready_future_test.py b/src/python/grpcio_tests/tests/unit/_channel_ready_future_test.py
index 30b486079c..345460ef40 100644
--- a/src/python/grpcio_tests/tests/unit/_channel_ready_future_test.py
+++ b/src/python/grpcio_tests/tests/unit/_channel_ready_future_test.py
@@ -15,6 +15,7 @@
import threading
import unittest
+import logging
import grpc
from tests.unit.framework.common import test_constants
@@ -85,4 +86,5 @@ class ChannelReadyFutureTest(unittest.TestCase):
if __name__ == '__main__':
+ logging.basicConfig()
unittest.main(verbosity=2)
diff --git a/src/python/grpcio_tests/tests/unit/_compression_test.py b/src/python/grpcio_tests/tests/unit/_compression_test.py
index 0b11f03adf..876d8e827e 100644
--- a/src/python/grpcio_tests/tests/unit/_compression_test.py
+++ b/src/python/grpcio_tests/tests/unit/_compression_test.py
@@ -15,6 +15,7 @@
import unittest
+import logging
import grpc
from grpc import _grpcio_metadata
@@ -117,4 +118,5 @@ class CompressionTest(unittest.TestCase):
if __name__ == '__main__':
+ logging.basicConfig()
unittest.main(verbosity=2)
diff --git a/src/python/grpcio_tests/tests/unit/_credentials_test.py b/src/python/grpcio_tests/tests/unit/_credentials_test.py
index f487fe66a2..be7378ecbc 100644
--- a/src/python/grpcio_tests/tests/unit/_credentials_test.py
+++ b/src/python/grpcio_tests/tests/unit/_credentials_test.py
@@ -14,6 +14,7 @@
"""Tests of credentials."""
import unittest
+import logging
import grpc
@@ -54,4 +55,5 @@ class CredentialsTest(unittest.TestCase):
if __name__ == '__main__':
+ logging.basicConfig()
unittest.main(verbosity=2)
diff --git a/src/python/grpcio_tests/tests/unit/_empty_message_test.py b/src/python/grpcio_tests/tests/unit/_empty_message_test.py
index c55ef61c13..3e8393b53c 100644
--- a/src/python/grpcio_tests/tests/unit/_empty_message_test.py
+++ b/src/python/grpcio_tests/tests/unit/_empty_message_test.py
@@ -13,6 +13,7 @@
# limitations under the License.
import unittest
+import logging
import grpc
@@ -118,4 +119,5 @@ class EmptyMessageTest(unittest.TestCase):
if __name__ == '__main__':
+ logging.basicConfig()
unittest.main(verbosity=2)
diff --git a/src/python/grpcio_tests/tests/unit/_exit_scenarios.py b/src/python/grpcio_tests/tests/unit/_exit_scenarios.py
index 0a0239a63d..f489db12cb 100644
--- a/src/python/grpcio_tests/tests/unit/_exit_scenarios.py
+++ b/src/python/grpcio_tests/tests/unit/_exit_scenarios.py
@@ -16,6 +16,7 @@
import argparse
import threading
import time
+import logging
import grpc
@@ -161,6 +162,7 @@ def infinite_request_iterator():
if __name__ == '__main__':
+ logging.basicConfig()
parser = argparse.ArgumentParser()
parser.add_argument('scenario', type=str)
parser.add_argument(
diff --git a/src/python/grpcio_tests/tests/unit/_exit_test.py b/src/python/grpcio_tests/tests/unit/_exit_test.py
index f40f3ae07c..5226537579 100644
--- a/src/python/grpcio_tests/tests/unit/_exit_test.py
+++ b/src/python/grpcio_tests/tests/unit/_exit_test.py
@@ -26,6 +26,7 @@ import sys
import threading
import time
import unittest
+import logging
from tests.unit import _exit_scenarios
@@ -187,4 +188,5 @@ class ExitTest(unittest.TestCase):
if __name__ == '__main__':
+ logging.basicConfig()
unittest.main(verbosity=2)
diff --git a/src/python/grpcio_tests/tests/unit/_interceptor_test.py b/src/python/grpcio_tests/tests/unit/_interceptor_test.py
index 3d547b71cd..99db0ac58b 100644
--- a/src/python/grpcio_tests/tests/unit/_interceptor_test.py
+++ b/src/python/grpcio_tests/tests/unit/_interceptor_test.py
@@ -17,6 +17,7 @@ import collections
import itertools
import threading
import unittest
+import logging
from concurrent import futures
import grpc
@@ -598,4 +599,5 @@ class InterceptorTest(unittest.TestCase):
if __name__ == '__main__':
+ logging.basicConfig()
unittest.main(verbosity=2)
diff --git a/src/python/grpcio_tests/tests/unit/_invalid_metadata_test.py b/src/python/grpcio_tests/tests/unit/_invalid_metadata_test.py
index f153089a24..9771764635 100644
--- a/src/python/grpcio_tests/tests/unit/_invalid_metadata_test.py
+++ b/src/python/grpcio_tests/tests/unit/_invalid_metadata_test.py
@@ -14,6 +14,7 @@
"""Test of RPCs made against gRPC Python's application-layer API."""
import unittest
+import logging
import grpc
@@ -131,4 +132,5 @@ class InvalidMetadataTest(unittest.TestCase):
if __name__ == '__main__':
+ logging.basicConfig()
unittest.main(verbosity=2)
diff --git a/src/python/grpcio_tests/tests/unit/_invocation_defects_test.py b/src/python/grpcio_tests/tests/unit/_invocation_defects_test.py
index 93a5fdf9ff..00949e2236 100644
--- a/src/python/grpcio_tests/tests/unit/_invocation_defects_test.py
+++ b/src/python/grpcio_tests/tests/unit/_invocation_defects_test.py
@@ -15,6 +15,7 @@
import itertools
import threading
import unittest
+import logging
import grpc
@@ -271,4 +272,5 @@ class InvocationDefectsTest(unittest.TestCase):
if __name__ == '__main__':
+ logging.basicConfig()
unittest.main(verbosity=2)
diff --git a/src/python/grpcio_tests/tests/unit/_logging_test.py b/src/python/grpcio_tests/tests/unit/_logging_test.py
new file mode 100644
index 0000000000..80b1f1b3c1
--- /dev/null
+++ b/src/python/grpcio_tests/tests/unit/_logging_test.py
@@ -0,0 +1,73 @@
+# Copyright 2018 gRPC authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+"""Test of gRPC Python's interaction with the python logging module"""
+
+import unittest
+import six
+from six.moves import reload_module
+import logging
+import grpc
+import functools
+import sys
+
+
+def patch_stderr(f):
+
+ @functools.wraps(f)
+ def _impl(*args, **kwargs):
+ old_stderr = sys.stderr
+ sys.stderr = six.StringIO()
+ try:
+ f(*args, **kwargs)
+ finally:
+ sys.stderr = old_stderr
+
+ return _impl
+
+
+def isolated_logging(f):
+
+ @functools.wraps(f)
+ def _impl(*args, **kwargs):
+ reload_module(logging)
+ reload_module(grpc)
+ try:
+ f(*args, **kwargs)
+ finally:
+ reload_module(logging)
+
+ return _impl
+
+
+class LoggingTest(unittest.TestCase):
+
+ @isolated_logging
+ def test_logger_not_occupied(self):
+ self.assertEqual(0, len(logging.getLogger().handlers))
+
+ @patch_stderr
+ @isolated_logging
+ def test_handler_found(self):
+ self.assertEqual(0, len(sys.stderr.getvalue()))
+
+ @isolated_logging
+ def test_can_configure_logger(self):
+ intended_stream = six.StringIO()
+ logging.basicConfig(stream=intended_stream)
+ self.assertEqual(1, len(logging.getLogger().handlers))
+ self.assertIs(logging.getLogger().handlers[0].stream, intended_stream)
+
+
+if __name__ == '__main__':
+ unittest.main(verbosity=2)
diff --git a/src/python/grpcio_tests/tests/unit/_metadata_code_details_test.py b/src/python/grpcio_tests/tests/unit/_metadata_code_details_test.py
index ca10bd4dab..0dafab827a 100644
--- a/src/python/grpcio_tests/tests/unit/_metadata_code_details_test.py
+++ b/src/python/grpcio_tests/tests/unit/_metadata_code_details_test.py
@@ -15,6 +15,7 @@
import threading
import unittest
+import logging
import grpc
@@ -656,4 +657,5 @@ class MetadataCodeDetailsTest(unittest.TestCase):
if __name__ == '__main__':
+ logging.basicConfig()
unittest.main(verbosity=2)
diff --git a/src/python/grpcio_tests/tests/unit/_metadata_test.py b/src/python/grpcio_tests/tests/unit/_metadata_test.py
index 5908421011..777ab683e3 100644
--- a/src/python/grpcio_tests/tests/unit/_metadata_test.py
+++ b/src/python/grpcio_tests/tests/unit/_metadata_test.py
@@ -15,6 +15,7 @@
import unittest
import weakref
+import logging
import grpc
from grpc import _channel
@@ -237,4 +238,5 @@ class MetadataTest(unittest.TestCase):
if __name__ == '__main__':
+ logging.basicConfig()
unittest.main(verbosity=2)
diff --git a/src/python/grpcio_tests/tests/unit/_reconnect_test.py b/src/python/grpcio_tests/tests/unit/_reconnect_test.py
index a708d8d862..f6d4fcbd0a 100644
--- a/src/python/grpcio_tests/tests/unit/_reconnect_test.py
+++ b/src/python/grpcio_tests/tests/unit/_reconnect_test.py
@@ -15,6 +15,7 @@
import socket
import time
+import logging
import unittest
import grpc
@@ -100,4 +101,5 @@ class ReconnectTest(unittest.TestCase):
if __name__ == '__main__':
+ logging.basicConfig()
unittest.main(verbosity=2)
diff --git a/src/python/grpcio_tests/tests/unit/_resource_exhausted_test.py b/src/python/grpcio_tests/tests/unit/_resource_exhausted_test.py
index df4b129018..4fead8fcd5 100644
--- a/src/python/grpcio_tests/tests/unit/_resource_exhausted_test.py
+++ b/src/python/grpcio_tests/tests/unit/_resource_exhausted_test.py
@@ -15,6 +15,7 @@
import threading
import unittest
+import logging
import grpc
from grpc import _channel
@@ -253,4 +254,5 @@ class ResourceExhaustedTest(unittest.TestCase):
if __name__ == '__main__':
+ logging.basicConfig()
unittest.main(verbosity=2)
diff --git a/src/python/grpcio_tests/tests/unit/_rpc_test.py b/src/python/grpcio_tests/tests/unit/_rpc_test.py
index 34e7831a98..a768d6c7c1 100644
--- a/src/python/grpcio_tests/tests/unit/_rpc_test.py
+++ b/src/python/grpcio_tests/tests/unit/_rpc_test.py
@@ -16,6 +16,7 @@
import itertools
import threading
import unittest
+import logging
from concurrent import futures
import grpc
@@ -846,4 +847,5 @@ class RPCTest(unittest.TestCase):
if __name__ == '__main__':
+ logging.basicConfig()
unittest.main(verbosity=2)
diff --git a/src/python/grpcio_tests/tests/unit/_server_ssl_cert_config_test.py b/src/python/grpcio_tests/tests/unit/_server_ssl_cert_config_test.py
index 0d78034b7b..e733a59a5b 100644
--- a/src/python/grpcio_tests/tests/unit/_server_ssl_cert_config_test.py
+++ b/src/python/grpcio_tests/tests/unit/_server_ssl_cert_config_test.py
@@ -35,6 +35,7 @@ import os
import six
import threading
import unittest
+import logging
from concurrent import futures
@@ -518,4 +519,5 @@ class ServerSSLCertReloadTestCertConfigReuse(_ServerSSLCertReloadTest):
if __name__ == '__main__':
+ logging.basicConfig()
unittest.main(verbosity=2)
diff --git a/src/python/grpcio_tests/tests/unit/_server_test.py b/src/python/grpcio_tests/tests/unit/_server_test.py
index acf4a17921..2c8205f365 100644
--- a/src/python/grpcio_tests/tests/unit/_server_test.py
+++ b/src/python/grpcio_tests/tests/unit/_server_test.py
@@ -14,6 +14,7 @@
from concurrent import futures
import unittest
+import logging
import grpc
@@ -49,4 +50,5 @@ class ServerTest(unittest.TestCase):
if __name__ == '__main__':
+ logging.basicConfig()
unittest.main(verbosity=2)
diff --git a/src/python/grpcio_tests/tests/unit/_session_cache_test.py b/src/python/grpcio_tests/tests/unit/_session_cache_test.py
index b4e4670fa7..9223a6da03 100644
--- a/src/python/grpcio_tests/tests/unit/_session_cache_test.py
+++ b/src/python/grpcio_tests/tests/unit/_session_cache_test.py
@@ -15,6 +15,7 @@
import pickle
import unittest
+import logging
import grpc
from grpc import _channel
@@ -142,4 +143,5 @@ class SSLSessionCacheTest(unittest.TestCase):
if __name__ == '__main__':
+ logging.basicConfig()
unittest.main(verbosity=2)