Skip to content

Commit a9bcc27

Browse files
authored
Add 'client_info' support to Client. (#7903)
1 parent d613b57 commit a9bcc27

File tree

6 files changed

+126
-49
lines changed

6 files changed

+126
-49
lines changed

error_reporting/google/cloud/error_reporting/_gapic.py

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,15 +14,10 @@
1414

1515
"""GAX wrapper for Error Reporting API requests."""
1616

17-
from google.api_core.gapic_v1 import client_info
18-
19-
from google.cloud.error_reporting import __version__
2017
from google.cloud.errorreporting_v1beta1.gapic import report_errors_service_client
2118
from google.cloud.errorreporting_v1beta1.proto import report_errors_service_pb2
2219
from google.protobuf.json_format import ParseDict
2320

24-
_CLIENT_INFO = client_info.ClientInfo(client_library_version=__version__)
25-
2621

2722
def make_report_error_api(client):
2823
"""Create an instance of the gapic Logging API.
@@ -33,10 +28,10 @@ def make_report_error_api(client):
3328
:rtype: :class:_ErrorReportingGapicApi
3429
:returns: An Error Reporting API instance.
3530
"""
36-
gax_client = report_errors_service_client.ReportErrorsServiceClient(
37-
credentials=client._credentials, client_info=_CLIENT_INFO
31+
gapic_api = report_errors_service_client.ReportErrorsServiceClient(
32+
credentials=client._credentials, client_info=client._client_info
3833
)
39-
return _ErrorReportingGapicApi(gax_client, client.project)
34+
return _ErrorReportingGapicApi(gapic_api, client.project)
4035

4136

4237
class _ErrorReportingGapicApi(object):

error_reporting/google/cloud/error_reporting/_logging.py

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,11 +45,20 @@ class _ErrorReportingLoggingAPI(object):
4545
``credentials`` for the current object.
4646
This parameter should be considered private, and could
4747
change in the future.
48+
49+
:type client_info:
50+
:class:`google.api_core.client_info.ClientInfo` or
51+
:class:`google.api_core.gapic_v1.client_info.ClientInfo`
52+
:param client_info:
53+
The client info used to send a user-agent string along with API
54+
requests. If ``None``, then default info will be used. Generally,
55+
you only need to set this if you're developing your own library
56+
or partner tool.
4857
"""
4958

50-
def __init__(self, project, credentials=None, _http=None):
59+
def __init__(self, project, credentials=None, _http=None, client_info=None):
5160
self.logging_client = google.cloud.logging.client.Client(
52-
project, credentials, _http=_http
61+
project, credentials, _http=_http, client_info=client_info
5362
)
5463

5564
def report_error_event(self, error_report):

error_reporting/google/cloud/error_reporting/client.py

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,21 +17,27 @@
1717
import os
1818
import traceback
1919

20+
import six
21+
2022
try:
2123
from google.cloud.error_reporting._gapic import make_report_error_api
22-
23-
_HAVE_GRPC = True
2424
except ImportError: # pragma: NO COVER
25+
from google.api_core import ciient_info # noqa
26+
2527
_HAVE_GRPC = False
28+
else:
29+
from google.api_core.gapic_v1 import client_info
30+
31+
_HAVE_GRPC = True
2632

2733
from google.cloud.client import ClientWithProject
34+
from google.cloud.error_reporting import __version__
2835
from google.cloud.error_reporting._logging import _ErrorReportingLoggingAPI
2936
from google.cloud.environment_vars import DISABLE_GRPC
3037

31-
import six
32-
3338
_DISABLE_GRPC = os.getenv(DISABLE_GRPC, False)
3439
_USE_GRPC = _HAVE_GRPC and not _DISABLE_GRPC
40+
_CLIENT_INFO = client_info.ClientInfo(client_library_version=__version__)
3541

3642

3743
class HTTPContext(object):
@@ -128,6 +134,15 @@ class Client(ClientWithProject):
128134
This parameter should be considered private, and could
129135
change in the future.
130136
137+
:type client_info:
138+
:class:`google.api_core.client_info.ClientInfo` or
139+
:class:`google.api_core.gapic_v1.client_info.ClientInfo`
140+
:param client_info:
141+
The client info used to send a user-agent string along with API
142+
requests. If ``None``, then default info will be used. Generally,
143+
you only need to set this if you're developing your own library
144+
or partner tool.
145+
131146
:raises: :class:`ValueError` if the project is neither passed in nor
132147
set in the environment.
133148
"""
@@ -142,6 +157,7 @@ def __init__(
142157
_http=None,
143158
service=None,
144159
version=None,
160+
client_info=_CLIENT_INFO,
145161
_use_grpc=None,
146162
):
147163
super(Client, self).__init__(
@@ -151,6 +167,8 @@ def __init__(
151167

152168
self.service = service if service else self.DEFAULT_SERVICE
153169
self.version = version
170+
self._client_info = client_info
171+
154172
if _use_grpc is None:
155173
self._use_grpc = _USE_GRPC
156174
else:
@@ -177,7 +195,7 @@ def report_errors_api(self):
177195
self._report_errors_api = make_report_error_api(self)
178196
else:
179197
self._report_errors_api = _ErrorReportingLoggingAPI(
180-
self.project, self._credentials, self._http
198+
self.project, self._credentials, self._http, self._client_info
181199
)
182200
return self._report_errors_api
183201

error_reporting/tests/unit/test__gapic.py

Lines changed: 16 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -18,37 +18,31 @@
1818

1919

2020
class Test_make_report_error_api(unittest.TestCase):
21-
def test_make_report_error_api(self):
22-
from google.cloud.errorreporting_v1beta1.gapic import (
23-
report_errors_service_client,
24-
)
25-
21+
@staticmethod
22+
def _call_fut(client):
2623
from google.cloud.error_reporting._gapic import make_report_error_api
2724

28-
client = mock.Mock(
29-
_credentials=mock.sentinel.credentials,
30-
project="prahj-ekt",
31-
spec=["project", "_credentials"],
32-
)
25+
return make_report_error_api(client)
3326

34-
# Mock out the constructor for the GAPIC client.
35-
ServiceClient = report_errors_service_client.ReportErrorsServiceClient
36-
with mock.patch.object(ServiceClient, "__init__") as resc:
37-
resc.return_value = None
27+
def test_make_report_error_api(self):
28+
client = mock.Mock(spec=["project", "_credentials", "_client_info"])
3829

39-
# Call the function being tested.
40-
report_error_client = make_report_error_api(client)
30+
# Call the function being tested.
31+
patch = mock.patch(
32+
"google.cloud.errorreporting_v1beta1."
33+
"gapic.report_errors_service_client.ReportErrorsServiceClient"
34+
)
4135

42-
# Assert that the arguments to the GAPIC constructor appear
43-
# to be correct.
44-
resc.assert_called_once()
45-
_, _, kwargs = resc.mock_calls[0]
46-
self.assertEqual(kwargs["credentials"], mock.sentinel.credentials)
47-
self.assertIsNotNone(kwargs["client_info"])
36+
with patch as patched:
37+
report_error_client = self._call_fut(client)
4838

4939
# Assert that the final error client has the project in
5040
# the expected location.
5141
self.assertIs(report_error_client._project, client.project)
42+
self.assertIs(report_error_client._gapic_api, patched.return_value)
43+
patched.assert_called_once_with(
44+
credentials=client._credentials, client_info=client._client_info
45+
)
5246

5347

5448
class Test_ErrorReportingGapicApi(unittest.TestCase):

error_reporting/tests/unit/test__logging.py

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -27,26 +27,41 @@ class Test_ErrorReportingLoggingAPI(unittest.TestCase):
2727

2828
PROJECT = "PROJECT"
2929

30-
def _make_one(self, project, credentials):
30+
def _make_one(self, project, credentials, **kw):
3131
from google.cloud.error_reporting._logging import _ErrorReportingLoggingAPI
3232

33-
return _ErrorReportingLoggingAPI(project, credentials)
33+
return _ErrorReportingLoggingAPI(project, credentials, **kw)
3434

35-
def test_constructor(self):
35+
@mock.patch("google.cloud.logging.client.Client")
36+
def test_ctor_defaults(self, mocked_cls):
3637
credentials = _make_credentials()
38+
3739
logging_api = self._make_one(self.PROJECT, credentials)
3840

39-
self.assertEqual(
40-
logging_api.logging_client._connection.credentials, credentials
41+
self.assertIs(logging_api.logging_client, mocked_cls.return_value)
42+
mocked_cls.assert_called_once_with(
43+
self.PROJECT, credentials, _http=None, client_info=None
44+
)
45+
46+
@mock.patch("google.cloud.logging.client.Client")
47+
def test_ctor_explicit(self, mocked_cls):
48+
credentials = _make_credentials()
49+
http = mock.Mock()
50+
client_info = mock.Mock()
51+
52+
logging_api = self._make_one(
53+
self.PROJECT, credentials, _http=http, client_info=client_info
54+
)
55+
56+
self.assertIs(logging_api.logging_client, mocked_cls.return_value)
57+
mocked_cls.assert_called_once_with(
58+
self.PROJECT, credentials, _http=http, client_info=client_info
4159
)
42-
self.assertEqual(logging_api.logging_client.project, self.PROJECT)
4360

4461
@mock.patch("google.cloud.logging.client.Client")
4562
def test_report_error_event(self, mocked_cls):
4663
credentials = _make_credentials()
4764
logging_api = self._make_one(self.PROJECT, credentials)
48-
mocked_cls.assert_called_once_with(self.PROJECT, credentials, _http=None)
49-
self.assertIs(logging_api.logging_client, mocked_cls.return_value)
5065

5166
logger = mock.Mock(spec=["log_struct"])
5267
logging_api.logging_client.logger.return_value = logger

error_reporting/tests/unit/test_client.py

Lines changed: 50 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -53,26 +53,72 @@ def _get_report_payload(self, error_api):
5353
return positional[0]
5454

5555
@mock.patch("google.cloud.client._determine_default_project")
56-
def test_ctor_default(self, default_mock):
56+
def test_ctor_defaults(self, default_mock):
57+
from google.api_core.client_info import ClientInfo
58+
5759
credentials = _make_credentials()
5860
default_mock.return_value = "foo"
5961
client = self._make_one(credentials=credentials)
6062
self.assertEqual(client.service, client.DEFAULT_SERVICE)
6163
self.assertEqual(client.version, None)
64+
self.assertIsInstance(client._client_info, ClientInfo)
6265
default_mock.assert_called_once_with(None)
6366

64-
def test_ctor_params(self):
67+
def test_ctor_explicit(self):
6568
credentials = _make_credentials()
69+
client_info = mock.Mock()
6670
client = self._make_one(
6771
project=self.PROJECT,
6872
credentials=credentials,
6973
service=self.SERVICE,
7074
version=self.VERSION,
75+
client_info=client_info,
7176
)
7277
self.assertEqual(client.service, self.SERVICE)
7378
self.assertEqual(client.version, self.VERSION)
79+
self.assertIs(client._client_info, client_info)
80+
81+
def test_report_errors_api_already(self):
82+
credentials = _make_credentials()
83+
client = self._make_one(project=self.PROJECT, credentials=credentials)
84+
client._report_errors_api = already = mock.Mock()
85+
self.assertIs(client.report_errors_api, already)
86+
87+
def test_report_errors_api_wo_grpc(self):
88+
credentials = _make_credentials()
89+
client_info = mock.Mock()
90+
http = mock.Mock()
91+
client = self._make_one(
92+
project=self.PROJECT,
93+
credentials=credentials,
94+
client_info=client_info,
95+
_http=http,
96+
_use_grpc=False,
97+
)
98+
patch = mock.patch(
99+
"google.cloud.error_reporting.client._ErrorReportingLoggingAPI"
100+
)
101+
102+
with patch as patched:
103+
api = client.report_errors_api
104+
105+
self.assertIs(api, patched.return_value)
106+
patched.assert_called_once_with(self.PROJECT, credentials, http, client_info)
107+
108+
def test_report_errors_api_w_grpc(self):
109+
credentials = _make_credentials()
110+
client = self._make_one(
111+
project=self.PROJECT, credentials=credentials, _use_grpc=True
112+
)
113+
patch = mock.patch("google.cloud.error_reporting.client.make_report_error_api")
114+
115+
with patch as patched:
116+
api = client.report_errors_api
117+
118+
self.assertIs(api, patched.return_value)
119+
patched.assert_called_once_with(client)
74120

75-
def test_report_exception_with_gax(self):
121+
def test_report_exception_with_grpc(self):
76122
credentials = _make_credentials()
77123
client = self._make_one(project=self.PROJECT, credentials=credentials)
78124

@@ -89,7 +135,7 @@ def test_report_exception_with_gax(self):
89135
self.assertIn("test_report", payload["message"])
90136
self.assertIn("test_client.py", payload["message"])
91137

92-
def test_report_exception_wo_gax(self):
138+
def test_report_exception_wo_grpc(self):
93139
credentials = _make_credentials()
94140
client = self._make_one(
95141
project=self.PROJECT, credentials=credentials, _use_grpc=False

0 commit comments

Comments
 (0)