Skip to content

Commit 771bc7a

Browse files
authored
Merge pull request #1952 from tseaver/logging-fix_gax_system_tests
Fix GAX logging system tests
2 parents e7b9a28 + 6ffe88d commit 771bc7a

File tree

3 files changed

+199
-43
lines changed

3 files changed

+199
-43
lines changed

gcloud/logging/_gax.py

Lines changed: 55 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,8 @@ def list_sinks(self, project, page_size=0, page_token=None):
154154
with another call (pass that value as ``page_token``).
155155
"""
156156
options = _build_paging_options(page_token)
157-
page_iter = self._gax_api.list_sinks(project, page_size, options)
157+
path = 'projects/%s' % (project,)
158+
page_iter = self._gax_api.list_sinks(path, page_size, options)
158159
sinks = [_log_sink_pb_to_mapping(log_sink_pb)
159160
for log_sink_pb in page_iter.next()]
160161
token = page_iter.page_token or None
@@ -289,7 +290,8 @@ def list_metrics(self, project, page_size=0, page_token=None):
289290
with another call (pass that value as ``page_token``).
290291
"""
291292
options = _build_paging_options(page_token)
292-
page_iter = self._gax_api.list_log_metrics(project, page_size, options)
293+
path = 'projects/%s' % (project,)
294+
page_iter = self._gax_api.list_log_metrics(path, page_size, options)
293295
metrics = [_log_metric_pb_to_mapping(log_metric_pb)
294296
for log_metric_pb in page_iter.next()]
295297
token = page_iter.page_token or None
@@ -416,6 +418,41 @@ def _pb_timestamp_to_rfc3339(timestamp_pb):
416418
return _datetime_to_rfc3339(timestamp)
417419

418420

421+
def _value_pb_to_value(value_pb):
422+
"""Helper for :func:`_log_entry_pb_to_mapping`."""
423+
kind = value_pb.WhichOneof('kind')
424+
425+
if kind is None:
426+
result = None
427+
428+
elif kind == 'string_value':
429+
result = value_pb.string_value
430+
431+
elif kind == 'bool_value':
432+
result = value_pb.bool_value
433+
434+
elif kind == 'number_value':
435+
result = value_pb.number_value
436+
437+
elif kind == 'list_value':
438+
result = [_value_pb_to_value(element)
439+
for element in value_pb.list_value.values]
440+
441+
elif kind == 'struct_value':
442+
result = _struct_pb_to_mapping(value_pb.struct_value)
443+
444+
else:
445+
raise ValueError('Value protobuf had unknown kind: %s' % (kind,))
446+
447+
return result
448+
449+
450+
def _struct_pb_to_mapping(struct_pb):
451+
"""Helper for :func:`_log_entry_pb_to_mapping`."""
452+
return dict([(key, _value_pb_to_value(struct_pb.fields[key]))
453+
for key in struct_pb.fields])
454+
455+
419456
def _log_entry_pb_to_mapping(entry_pb):
420457
"""Helper for :meth:`list_entries`, et aliae
421458
@@ -426,27 +463,32 @@ def _log_entry_pb_to_mapping(entry_pb):
426463
mapping = {
427464
'logName': entry_pb.log_name,
428465
'resource': _mon_resource_pb_to_mapping(entry_pb.resource),
429-
'severity': entry_pb.severity,
466+
'severity': LogSeverity.Name(entry_pb.severity),
430467
'insertId': entry_pb.insert_id,
431468
'timestamp': _pb_timestamp_to_rfc3339(entry_pb.timestamp),
432469
'labels': entry_pb.labels,
433-
'textPayload': entry_pb.text_payload,
434-
'jsonPayload': entry_pb.json_payload,
435-
'protoPayload': entry_pb.proto_payload,
436470
}
471+
if entry_pb.HasField('text_payload'):
472+
mapping['textPayload'] = entry_pb.text_payload
473+
474+
if entry_pb.HasField('json_payload'):
475+
mapping['jsonPayload'] = _struct_pb_to_mapping(entry_pb.json_payload)
476+
477+
if entry_pb.HasField('proto_payload'):
478+
mapping['protoPayload'] = entry_pb.proto_payload
437479

438480
if entry_pb.http_request:
439481
request = entry_pb.http_request
440482
mapping['httpRequest'] = {
441-
'request_method': request.request_method,
442-
'request_url': request.request_url,
483+
'requestMethod': request.request_method,
484+
'requestUrl': request.request_url,
443485
'status': request.status,
444486
'referer': request.referer,
445-
'user_agent': request.user_agent,
446-
'cache_hit': request.cache_hit,
447-
'request_size': request.request_size,
448-
'response_size': request.response_size,
449-
'remote_ip': request.remote_ip,
487+
'userAgent': request.user_agent,
488+
'cacheHit': request.cache_hit,
489+
'requestSize': request.request_size,
490+
'responseSize': request.response_size,
491+
'remoteIp': request.remote_ip,
450492
}
451493

452494
if entry_pb.operation:

gcloud/logging/test__gax.py

Lines changed: 96 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -78,13 +78,16 @@ def test_list_entries_no_paging(self):
7878
self.assertTrue(options.page_token is INITIAL_PAGE)
7979

8080
def test_list_entries_with_paging(self):
81+
from google.protobuf.struct_pb2 import Value
8182
from gcloud._testing import _GAXPageIterator
8283
SIZE = 23
8384
TOKEN = 'TOKEN'
8485
NEW_TOKEN = 'NEW_TOKEN'
8586
PAYLOAD = {'message': 'MESSAGE', 'weather': 'sunny'}
87+
struct_pb = _StructPB(dict([(key, Value(string_value=value))
88+
for key, value in PAYLOAD.items()]))
8689
response = _GAXPageIterator(
87-
[_LogEntryPB(self.LOG_NAME, json_payload=PAYLOAD)], NEW_TOKEN)
90+
[_LogEntryPB(self.LOG_NAME, json_payload=struct_pb)], NEW_TOKEN)
8891
gax_api = _GAXLoggingAPI(_list_log_entries_response=response)
8992
api = self._makeOne(gax_api)
9093

@@ -109,6 +112,7 @@ def test_list_entries_with_paging(self):
109112

110113
def test_list_entries_with_extra_properties(self):
111114
from datetime import datetime
115+
from google.logging.type.log_severity_pb2 import WARNING
112116
from gcloud._testing import _GAXPageIterator
113117
from gcloud._helpers import UTC
114118
from gcloud._helpers import _datetime_to_rfc3339
@@ -126,7 +130,7 @@ def test_list_entries_with_extra_properties(self):
126130
request = _HTTPRequestPB()
127131
operation = _LogEntryOperationPB()
128132
EXTRAS = {
129-
'severity': SEVERITY,
133+
'severity': WARNING,
130134
'labels': LABELS,
131135
'insert_id': IID,
132136
'http_request': request,
@@ -154,15 +158,15 @@ def test_list_entries_with_extra_properties(self):
154158
self.assertEqual(entry['insertId'], IID)
155159
self.assertEqual(entry['timestamp'], _datetime_to_rfc3339(NOW))
156160
EXPECTED_REQUEST = {
157-
'request_method': request.request_method,
158-
'request_url': request.request_url,
161+
'requestMethod': request.request_method,
162+
'requestUrl': request.request_url,
159163
'status': request.status,
160-
'request_size': request.request_size,
161-
'response_size': request.response_size,
164+
'requestSize': request.request_size,
165+
'responseSize': request.response_size,
162166
'referer': request.referer,
163-
'user_agent': request.user_agent,
164-
'remote_ip': request.remote_ip,
165-
'cache_hit': request.cache_hit,
167+
'userAgent': request.user_agent,
168+
'remoteIp': request.remote_ip,
169+
'cacheHit': request.cache_hit,
166170
}
167171
self.assertEqual(entry['httpRequest'], EXPECTED_REQUEST)
168172
EXPECTED_OPERATION = {
@@ -439,7 +443,7 @@ def test_list_sinks_no_paging(self):
439443
self.assertEqual(token, TOKEN)
440444

441445
project, page_size, options = gax_api._list_sinks_called_with
442-
self.assertEqual(project, self.PROJECT)
446+
self.assertEqual(project, self.PROJECT_PATH)
443447
self.assertEqual(page_size, 0)
444448
self.assertEqual(options.page_token, INITIAL_PAGE)
445449

@@ -465,7 +469,7 @@ def test_list_sinks_w_paging(self):
465469
self.assertEqual(token, None)
466470

467471
project, page_size, options = gax_api._list_sinks_called_with
468-
self.assertEqual(project, self.PROJECT)
472+
self.assertEqual(project, self.PROJECT_PATH)
469473
self.assertEqual(page_size, PAGE_SIZE)
470474
self.assertEqual(options.page_token, TOKEN)
471475

@@ -643,7 +647,7 @@ def test_list_metrics_no_paging(self):
643647
self.assertEqual(token, TOKEN)
644648

645649
project, page_size, options = gax_api._list_log_metrics_called_with
646-
self.assertEqual(project, self.PROJECT)
650+
self.assertEqual(project, self.PROJECT_PATH)
647651
self.assertEqual(page_size, 0)
648652
self.assertEqual(options.page_token, INITIAL_PAGE)
649653

@@ -669,7 +673,7 @@ def test_list_metrics_w_paging(self):
669673
self.assertEqual(token, None)
670674

671675
project, page_size, options = gax_api._list_log_metrics_called_with
672-
self.assertEqual(project, self.PROJECT)
676+
self.assertEqual(project, self.PROJECT_PATH)
673677
self.assertEqual(page_size, PAGE_SIZE)
674678
self.assertEqual(options.page_token, TOKEN)
675679

@@ -811,6 +815,75 @@ def test_metric_delete_hit(self):
811815
self.assertEqual(options, None)
812816

813817

818+
@unittest2.skipUnless(_HAVE_GAX, 'No gax-python')
819+
class Test_value_pb_to_value(_Base, unittest2.TestCase):
820+
821+
def _callFUT(self, value_pb):
822+
from gcloud.logging._gax import _value_pb_to_value
823+
return _value_pb_to_value(value_pb)
824+
825+
def test_w_null_values(self):
826+
from google.protobuf.struct_pb2 import Value
827+
value_pb = Value()
828+
self.assertEqual(self._callFUT(value_pb), None)
829+
value_pb = Value(null_value=None)
830+
self.assertEqual(self._callFUT(value_pb), None)
831+
832+
def test_w_string_value(self):
833+
from google.protobuf.struct_pb2 import Value
834+
STRING = 'STRING'
835+
value_pb = Value(string_value=STRING)
836+
self.assertEqual(self._callFUT(value_pb), STRING)
837+
838+
def test_w_bool_values(self):
839+
from google.protobuf.struct_pb2 import Value
840+
true_value_pb = Value(bool_value=True)
841+
self.assertTrue(self._callFUT(true_value_pb) is True)
842+
false_value_pb = Value(bool_value=False)
843+
self.assertTrue(self._callFUT(false_value_pb) is False)
844+
845+
def test_w_number_values(self):
846+
from google.protobuf.struct_pb2 import Value
847+
ANSWER = 42
848+
PI = 3.1415926
849+
int_value_pb = Value(number_value=ANSWER)
850+
self.assertEqual(self._callFUT(int_value_pb), ANSWER)
851+
float_value_pb = Value(number_value=PI)
852+
self.assertEqual(self._callFUT(float_value_pb), PI)
853+
854+
def test_w_list_value(self):
855+
from google.protobuf.struct_pb2 import Value
856+
STRING = 'STRING'
857+
PI = 3.1415926
858+
value_pb = Value()
859+
value_pb.list_value.values.add(string_value=STRING)
860+
value_pb.list_value.values.add(bool_value=True)
861+
value_pb.list_value.values.add(number_value=PI)
862+
self.assertEqual(self._callFUT(value_pb), [STRING, True, PI])
863+
864+
def test_w_struct_value(self):
865+
from google.protobuf.struct_pb2 import Value
866+
STRING = 'STRING'
867+
PI = 3.1415926
868+
value_pb = Value()
869+
value_pb.struct_value.fields['string'].string_value = STRING
870+
value_pb.struct_value.fields['bool'].bool_value = True
871+
value_pb.struct_value.fields['number'].number_value = PI
872+
self.assertEqual(self._callFUT(value_pb),
873+
{'string': STRING, 'bool': True, 'number': PI})
874+
875+
def test_w_unknown_kind(self):
876+
877+
class _Value(object):
878+
879+
def WhichOneof(self, name):
880+
assert name == 'kind'
881+
return 'UNKNOWN'
882+
883+
with self.assertRaises(ValueError):
884+
self._callFUT(_Value())
885+
886+
814887
class _GAXBaseAPI(object):
815888

816889
_random_gax_error = False
@@ -974,9 +1047,15 @@ def __init__(self, type_='global', **labels):
9741047
self.labels = labels
9751048

9761049

1050+
class _StructPB(object):
1051+
1052+
def __init__(self, fields):
1053+
self.fields = fields
1054+
1055+
9771056
class _LogEntryPB(object):
9781057

979-
severity = 'DEFAULT'
1058+
severity = 0
9801059
http_request = operation = insert_id = None
9811060
text_payload = json_payload = proto_payload = None
9821061

@@ -987,6 +1066,9 @@ def __init__(self, log_name, **kw):
9871066
self.labels = kw.pop('labels', {})
9881067
self.__dict__.update(kw)
9891068

1069+
def HasField(self, field_name):
1070+
return getattr(self, field_name, None) is not None
1071+
9901072
@staticmethod
9911073
def _make_timestamp():
9921074
from datetime import datetime

0 commit comments

Comments
 (0)