Skip to content

Commit 1a973f3

Browse files
lidizhengcrwilcox
andauthored
fix: patch emulator channel to be created accordingly (#288)
Co-authored-by: Christopher Wilcox <[email protected]>
1 parent a007675 commit 1a973f3

File tree

2 files changed

+26
-12
lines changed

2 files changed

+26
-12
lines changed

google/cloud/firestore_v1/base_client.py

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ def _firestore_api_helper(self, transport, client_class, client_module) -> Any:
148148
# We need this in order to set appropriate keepalive options.
149149

150150
if self._emulator_host is not None:
151-
channel = self._emulator_channel()
151+
channel = self._emulator_channel(transport)
152152
else:
153153
channel = transport.create_channel(
154154
self._target,
@@ -165,25 +165,30 @@ def _firestore_api_helper(self, transport, client_class, client_module) -> Any:
165165

166166
return self._firestore_api_internal
167167

168-
def _emulator_channel(self):
168+
def _emulator_channel(self, transport):
169169
"""
170170
Creates a channel using self._credentials in a similar way to grpc.secure_channel but
171171
using grpc.local_channel_credentials() rather than grpc.ssh_channel_credentials() to allow easy connection
172172
to a local firestore emulator. This allows local testing of firestore rules if the credentials have been
173173
created from a signed custom token.
174174
175-
:return: grcp.Channel
175+
:return: grpc.Channel or grpc.aio.Channel
176176
"""
177-
return grpc._channel.Channel(
178-
self._emulator_host,
179-
(),
180-
self._local_composite_credentials()._credentials,
181-
None,
182-
)
177+
# TODO: Implement a special credentials type for emulator and use
178+
# "transport.create_channel" to create gRPC channels once google-auth
179+
# extends it's allowed credentials types.
180+
if "GrpcAsyncIOTransport" in str(transport.__name__):
181+
return grpc.aio.secure_channel(
182+
self._emulator_host, self._local_composite_credentials()
183+
)
184+
else:
185+
return grpc.secure_channel(
186+
self._emulator_host, self._local_composite_credentials()
187+
)
183188

184189
def _local_composite_credentials(self):
185190
"""
186-
Ceates the credentials for the local emulator channel
191+
Creates the credentials for the local emulator channel
187192
:return: grpc.ChannelCredentials
188193
"""
189194
credentials = google.auth.credentials.with_scopes_if_required(

tests/unit/v1/test_base_client.py

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,13 @@ def test__rpc_metadata_property_with_emulator(self):
138138
)
139139

140140
def test_emulator_channel(self):
141+
from google.cloud.firestore_v1.services.firestore.transports.grpc import (
142+
FirestoreGrpcTransport,
143+
)
144+
from google.cloud.firestore_v1.services.firestore.transports.grpc_asyncio import (
145+
FirestoreGrpcAsyncIOTransport,
146+
)
147+
141148
emulator_host = "localhost:8081"
142149
with mock.patch("os.getenv") as getenv:
143150
getenv.return_value = emulator_host
@@ -149,8 +156,10 @@ def test_emulator_channel(self):
149156
)
150157

151158
# checks that a channel is created
152-
channel = client._emulator_channel()
153-
self.assertTrue(isinstance(channel, grpc._channel.Channel))
159+
channel = client._emulator_channel(FirestoreGrpcTransport)
160+
self.assertTrue(isinstance(channel, grpc.Channel))
161+
channel = client._emulator_channel(FirestoreGrpcAsyncIOTransport)
162+
self.assertTrue(isinstance(channel, grpc.aio.Channel))
154163
# checks that the credentials are composite ones using a local channel from grpc
155164
composite_credentials = client._local_composite_credentials()
156165
self.assertTrue(isinstance(composite_credentials, grpc.ChannelCredentials))

0 commit comments

Comments
 (0)