From 4878293baabcf0eab116b3530c0a037b500a90b1 Mon Sep 17 00:00:00 2001 From: Aaron Abbott Date: Wed, 24 Jun 2020 16:41:42 +0000 Subject: [PATCH 1/2] uncomment stackdriver tests --- .../tests/test_stackdriver_exporter.py | 1738 +++++------ .../tests/test_stackdriver_stats.py | 2780 ++++++++--------- 2 files changed, 2259 insertions(+), 2259 deletions(-) diff --git a/contrib/opencensus-ext-stackdriver/tests/test_stackdriver_exporter.py b/contrib/opencensus-ext-stackdriver/tests/test_stackdriver_exporter.py index 16b50447e..5325a6910 100644 --- a/contrib/opencensus-ext-stackdriver/tests/test_stackdriver_exporter.py +++ b/contrib/opencensus-ext-stackdriver/tests/test_stackdriver_exporter.py @@ -1,869 +1,869 @@ -# # Copyright 2017, OpenCensus 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. - -# import unittest - -# import mock - -# from opencensus.common.version import __version__ -# from opencensus.ext.stackdriver import trace_exporter -# from opencensus.trace import span_context -# from opencensus.trace import span_data as span_data_module - - -# class _Client(object): -# def __init__(self, project=None): -# if project is None: -# project = 'PROJECT' - -# self.project = project - - -# class TestStackdriverExporter(unittest.TestCase): -# def test_constructor_default(self): -# patch = mock.patch( -# 'opencensus.ext.stackdriver.trace_exporter.Client', -# new=_Client) - -# with patch: -# exporter = trace_exporter.StackdriverExporter() - -# project_id = 'PROJECT' -# self.assertEqual(exporter.project_id, project_id) - -# def test_constructor_explicit(self): -# client = mock.Mock() -# project_id = 'PROJECT' -# client.project = project_id -# transport = mock.Mock() - -# exporter = trace_exporter.StackdriverExporter( -# client=client, project_id=project_id, transport=transport) - -# self.assertIs(exporter.client, client) -# self.assertEqual(exporter.project_id, project_id) - -# def test_export(self): -# client = mock.Mock() -# project_id = 'PROJECT' -# client.project = project_id -# exporter = trace_exporter.StackdriverExporter( -# client=client, project_id=project_id, transport=MockTransport) -# exporter.export({}) - -# self.assertTrue(exporter.transport.export_called) - -# @mock.patch('opencensus.ext.stackdriver.trace_exporter.' -# 'monitored_resource.get_instance', -# return_value=None) -# def test_emit(self, mr_mock): -# trace_id = '6e0c63257de34c92bf9efcd03927272e' -# span_datas = [ -# span_data_module.SpanData( -# name='span', -# context=span_context.SpanContext(trace_id=trace_id), -# span_id='1111', -# parent_span_id=None, -# attributes=None, -# start_time=None, -# end_time=None, -# child_span_count=None, -# stack_trace=None, -# annotations=None, -# message_events=None, -# links=None, -# status=None, -# same_process_as_parent_span=None, -# span_kind=0, -# ) -# ] - -# stackdriver_spans = { -# 'spans': [{ -# 'status': -# None, -# 'childSpanCount': -# None, -# 'links': -# None, -# 'startTime': -# None, -# 'spanId': -# '1111', -# 'attributes': { -# 'attributeMap': { -# 'g.co/agent': { -# 'string_value': { -# 'truncated_byte_count': -# 0, -# 'value': -# 'opencensus-python [{}]'.format(__version__) -# } -# } -# } -# }, -# 'stackTrace': -# None, -# 'displayName': { -# 'truncated_byte_count': 0, -# 'value': 'span' -# }, -# 'name': -# 'projects/PROJECT/traces/{}/spans/1111'.format(trace_id), -# 'timeEvents': -# None, -# 'endTime': -# None, -# 'sameProcessAsParentSpan': -# None -# }] -# } - -# client = mock.Mock() -# project_id = 'PROJECT' -# client.project = project_id - -# exporter = trace_exporter.StackdriverExporter( -# client=client, project_id=project_id) - -# exporter.emit(span_datas) - -# name = 'projects/{}'.format(project_id) - -# client.batch_write_spans.assert_called_with(name, stackdriver_spans) -# self.assertTrue(client.batch_write_spans.called) - -# @mock.patch('opencensus.ext.stackdriver.trace_exporter.' -# 'monitored_resource.get_instance', -# return_value=None) -# def test_translate_to_stackdriver(self, mr_mock): -# project_id = 'PROJECT' -# trace_id = '6e0c63257de34c92bf9efcd03927272e' -# span_name = 'test span' -# span_id = '6e0c63257de34c92' -# attributes = { -# 'attributeMap': { -# 'key': { -# 'string_value': { -# 'truncated_byte_count': 0, -# 'value': 'value' -# } -# }, -# 'key_double': { -# 'double_value': { -# 'value': 123.45 -# } -# }, -# 'http.host': { -# 'string_value': { -# 'truncated_byte_count': 0, -# 'value': 'host' -# } -# } -# } -# } -# parent_span_id = '6e0c63257de34c93' -# start_time = 'test start time' -# end_time = 'test end time' -# trace = { -# 'spans': [{ -# 'displayName': { -# 'value': span_name, -# 'truncated_byte_count': 0 -# }, -# 'spanId': -# span_id, -# 'startTime': -# start_time, -# 'endTime': -# end_time, -# 'parentSpanId': -# parent_span_id, -# 'attributes': -# attributes, -# 'someRandomKey': -# 'this should not be included in result', -# 'childSpanCount': -# 0 -# }], -# 'traceId': -# trace_id -# } - -# client = mock.Mock() -# client.project = project_id -# exporter = trace_exporter.StackdriverExporter( -# client=client, project_id=project_id) - -# spans = list(exporter.translate_to_stackdriver(trace)) - -# expected_traces = [{ -# 'name': 'projects/{}/traces/{}/spans/{}'.format( -# project_id, trace_id, span_id), -# 'displayName': { -# 'value': span_name, -# 'truncated_byte_count': 0 -# }, -# 'attributes': { -# 'attributeMap': { -# 'g.co/agent': { -# 'string_value': { -# 'truncated_byte_count': 0, -# 'value': -# 'opencensus-python [{}]'.format(__version__) -# } -# }, -# 'key': { -# 'string_value': { -# 'truncated_byte_count': 0, -# 'value': 'value' -# } -# }, -# 'key_double': { -# 'double_value': { -# 'value': 123.45 -# } -# }, -# '/http/host': { -# 'string_value': { -# 'truncated_byte_count': 0, -# 'value': 'host' -# } -# } -# } -# }, -# 'spanId': str(span_id), -# 'startTime': start_time, -# 'endTime': end_time, -# 'parentSpanId': str(parent_span_id), -# 'status': None, -# 'links': None, -# 'stackTrace': None, -# 'timeEvents': None, -# 'childSpanCount': 0, -# 'sameProcessAsParentSpan': None -# }] - -# self.assertEqual(spans, expected_traces) - -# def test_translate_common_attributes_to_stackdriver_no_map(self): -# project_id = 'PROJECT' -# client = mock.Mock() -# client.project = project_id -# exporter = trace_exporter.StackdriverExporter( -# client=client, project_id=project_id) - -# attributes = {'outer key': 'some value'} -# expected_attributes = {'outer key': 'some value'} - -# exporter.map_attributes(attributes) -# self.assertEqual(attributes, expected_attributes) - -# def test_translate_common_attributes_to_stackdriver_none(self): -# project_id = 'PROJECT' -# client = mock.Mock() -# client.project = project_id -# exporter = trace_exporter.StackdriverExporter( -# client=client, project_id=project_id) - -# # does not throw -# self.assertIsNone(exporter.map_attributes(None)) - -# def test_translate_common_attributes_to_stackdriver(self): -# project_id = 'PROJECT' -# client = mock.Mock() -# client.project = project_id -# exporter = trace_exporter.StackdriverExporter( -# client=client, project_id=project_id) - -# attributes = { -# 'outer key': 'some value', -# 'attributeMap': { -# 'key': { -# 'string_value': { -# 'truncated_byte_count': 0, -# 'value': 'value' -# } -# }, -# 'component': { -# 'string_value': { -# 'truncated_byte_count': 0, -# 'value': 'http' -# } -# }, -# 'error.message': { -# 'string_value': { -# 'truncated_byte_count': 0, -# 'value': 'error message' -# } -# }, -# 'error.name': { -# 'string_value': { -# 'truncated_byte_count': 0, -# 'value': 'error name' -# } -# }, -# 'http.host': { -# 'string_value': { -# 'truncated_byte_count': 0, -# 'value': 'host' -# } -# }, -# 'http.method': { -# 'string_value': { -# 'truncated_byte_count': 0, -# 'value': 'GET' -# } -# }, -# 'http.status_code': { -# 'int_value': { -# 'value': 200 -# } -# }, -# 'http.url': { -# 'string_value': { -# 'truncated_byte_count': 0, -# 'value': 'http://host:port/path?query' -# } -# }, -# 'http.user_agent': { -# 'string_value': { -# 'truncated_byte_count': 0, -# 'value': 'some user agent' -# } -# }, -# 'http.client_city': { -# 'string_value': { -# 'truncated_byte_count': 0, -# 'value': 'Redmond' -# } -# }, -# 'http.client_country': { -# 'string_value': { -# 'truncated_byte_count': 0, -# 'value': 'USA' -# } -# }, -# 'http.client_protocol': { -# 'string_value': { -# 'truncated_byte_count': 0, -# 'value': 'HTTP 1.1' -# } -# }, -# 'http.client_region': { -# 'string_value': { -# 'truncated_byte_count': 0, -# 'value': 'WA' -# } -# }, -# 'http.request_size': { -# 'int_value': { -# 'value': 100 -# } -# }, -# 'http.response_size': { -# 'int_value': { -# 'value': 10 -# } -# }, -# 'pid': { -# 'int_value': { -# 'value': 123456789 -# } -# }, -# 'tid': { -# 'int_value': { -# 'value': 987654321 -# } -# }, -# 'stacktrace': { -# 'string_value': { -# 'truncated_byte_count': 0, -# 'value': 'at unknown' -# } -# }, -# 'grpc.host_port': { -# 'string_value': { -# 'truncated_byte_count': 0, -# 'value': 'localhost:50051' -# } -# }, -# 'grpc.method': { -# 'string_value': { -# 'truncated_byte_count': 0, -# 'value': 'post' -# } -# } -# } -# } - -# expected_attributes = { -# 'outer key': 'some value', -# 'attributeMap': { -# 'key': { -# 'string_value': { -# 'truncated_byte_count': 0, -# 'value': 'value' -# } -# }, -# '/component': { -# 'string_value': { -# 'truncated_byte_count': 0, -# 'value': 'http' -# } -# }, -# '/error/message': { -# 'string_value': { -# 'truncated_byte_count': 0, -# 'value': 'error message' -# } -# }, -# '/error/name': { -# 'string_value': { -# 'truncated_byte_count': 0, -# 'value': 'error name' -# } -# }, -# '/http/host': { -# 'string_value': { -# 'truncated_byte_count': 0, -# 'value': 'host' -# } -# }, -# '/http/method': { -# 'string_value': { -# 'truncated_byte_count': 0, -# 'value': 'GET' -# } -# }, -# '/http/status_code': { -# 'string_value': { -# 'truncated_byte_count': 0, -# 'value': '200' -# } -# }, -# '/http/url': { -# 'string_value': { -# 'truncated_byte_count': 0, -# 'value': 'http://host:port/path?query' -# } -# }, -# '/http/user_agent': { -# 'string_value': { -# 'truncated_byte_count': 0, -# 'value': 'some user agent' -# } -# }, -# '/http/client_city': { -# 'string_value': { -# 'truncated_byte_count': 0, -# 'value': 'Redmond' -# } -# }, -# '/http/client_country': { -# 'string_value': { -# 'truncated_byte_count': 0, -# 'value': 'USA' -# } -# }, -# '/http/client_protocol': { -# 'string_value': { -# 'truncated_byte_count': 0, -# 'value': 'HTTP 1.1' -# } -# }, -# '/http/client_region': { -# 'string_value': { -# 'truncated_byte_count': 0, -# 'value': 'WA' -# } -# }, -# '/http/request/size': { -# 'int_value': { -# 'value': 100 -# } -# }, -# '/http/response/size': { -# 'int_value': { -# 'value': 10 -# } -# }, -# '/pid': { -# 'int_value': { -# 'value': 123456789 -# } -# }, -# '/tid': { -# 'int_value': { -# 'value': 987654321 -# } -# }, -# '/stacktrace': { -# 'string_value': { -# 'truncated_byte_count': 0, -# 'value': 'at unknown' -# } -# }, -# '/grpc/host_port': { -# 'string_value': { -# 'truncated_byte_count': 0, -# 'value': 'localhost:50051' -# } -# }, -# '/grpc/method': { -# 'string_value': { -# 'truncated_byte_count': 0, -# 'value': 'post' -# } -# } -# } -# } - -# exporter.map_attributes(attributes) -# self.assertEqual(attributes, expected_attributes) - -# def test_translate_common_attributes_status_code(self): -# project_id = 'PROJECT' -# client = mock.Mock() -# client.project = project_id -# exporter = trace_exporter.StackdriverExporter( -# client=client, project_id=project_id) - -# attributes = { -# 'outer key': 'some value', -# 'attributeMap': { -# 'http.status_code': { -# 'int_value': 200 -# } -# } -# } - -# expected_attributes = { -# 'outer key': 'some value', -# 'attributeMap': { -# '/http/status_code': { -# 'string_value': { -# 'truncated_byte_count': 0, -# 'value': '200' -# } -# } -# } -# } - -# exporter.map_attributes(attributes) -# self.assertEqual(attributes, expected_attributes) - - -# class Test_set_attributes_gae(unittest.TestCase): -# @mock.patch('opencensus.ext.stackdriver.trace_exporter.' -# 'monitored_resource.get_instance', -# return_value=None) -# def test_set_attributes_gae(self, mr_mock): -# import os - -# trace = {'spans': [{'attributes': {}}]} - -# expected = { -# 'attributes': { -# 'attributeMap': { -# 'g.co/gae/app/module': { -# 'string_value': { -# 'truncated_byte_count': 0, -# 'value': 'service' -# } -# }, -# 'g.co/gae/app/instance': { -# 'string_value': { -# 'truncated_byte_count': 0, -# 'value': 'flex' -# } -# }, -# 'g.co/gae/app/version': { -# 'string_value': { -# 'truncated_byte_count': 0, -# 'value': 'version' -# } -# }, -# 'g.co/gae/app/project': { -# 'string_value': { -# 'truncated_byte_count': 0, -# 'value': 'project' -# } -# }, -# 'g.co/agent': { -# 'string_value': { -# 'truncated_byte_count': 0, -# 'value': -# 'opencensus-python [{}]'.format(__version__) -# } -# }, -# } -# } -# } - -# with mock.patch.dict( -# os.environ, { -# trace_exporter._APPENGINE_FLEXIBLE_ENV_VM: 'vm', -# trace_exporter._APPENGINE_FLEXIBLE_ENV_FLEX: 'flex', -# 'GOOGLE_CLOUD_PROJECT': 'project', -# 'GAE_SERVICE': 'service', -# 'GAE_VERSION': 'version' -# }): -# self.assertTrue(trace_exporter.is_gae_environment()) -# trace_exporter.set_attributes(trace) - -# span = trace.get('spans')[0] -# self.assertEqual(span, expected) - - -# class TestMonitoredResourceAttributes(unittest.TestCase): -# @mock.patch('opencensus.ext.stackdriver.trace_exporter.' -# 'monitored_resource.get_instance') -# def test_monitored_resource_attributes_gke(self, gmr_mock): -# import os - -# trace = {'spans': [{'attributes': {}}]} - -# expected = { -# 'attributes': { -# 'attributeMap': { -# 'g.co/gae/app/module': { -# 'string_value': { -# 'truncated_byte_count': 0, -# 'value': 'service' -# } -# }, -# 'g.co/gae/app/instance': { -# 'string_value': { -# 'truncated_byte_count': 0, -# 'value': 'flex' -# } -# }, -# 'g.co/gae/app/version': { -# 'string_value': { -# 'truncated_byte_count': 0, -# 'value': 'version' -# } -# }, -# 'g.co/gae/app/project': { -# 'string_value': { -# 'truncated_byte_count': 0, -# 'value': 'project' -# } -# }, -# 'g.co/agent': { -# 'string_value': { -# 'truncated_byte_count': 0, -# 'value': -# 'opencensus-python [{}]'.format(__version__) -# } -# }, -# 'g.co/r/k8s_container/project_id': { -# 'string_value': { -# 'truncated_byte_count': 0, -# 'value': 'my_project' -# } -# }, -# 'g.co/r/k8s_container/location': { -# 'string_value': { -# 'truncated_byte_count': 0, -# 'value': 'zone1' -# } -# }, -# 'g.co/r/k8s_container/namespace_name': { -# 'string_value': { -# 'truncated_byte_count': 0, -# 'value': 'namespace' -# } -# }, -# 'g.co/r/k8s_container/pod_name': { -# 'string_value': { -# 'truncated_byte_count': 0, -# 'value': 'pod' -# } -# }, -# 'g.co/r/k8s_container/cluster_name': { -# 'string_value': { -# 'truncated_byte_count': 0, -# 'value': 'cluster' -# } -# }, -# 'g.co/r/k8s_container/container_name': { -# 'string_value': { -# 'truncated_byte_count': 0, -# 'value': 'c1' -# } -# }, -# } -# } -# } - -# mock_resource = mock.Mock() -# mock_resource.get_type.return_value = 'k8s_container' -# mock_resource.get_labels.return_value = { -# 'k8s.io/pod/name': 'pod', -# 'k8s.io/cluster/name': 'cluster', -# 'k8s.io/namespace/name': 'namespace', -# 'k8s.io/container/name': 'c1', -# 'project_id': 'my_project', -# 'zone': 'zone1' -# } -# gmr_mock.return_value = mock_resource -# with mock.patch.dict( -# os.environ, { -# trace_exporter._APPENGINE_FLEXIBLE_ENV_VM: 'vm', -# trace_exporter._APPENGINE_FLEXIBLE_ENV_FLEX: 'flex', -# 'GOOGLE_CLOUD_PROJECT': 'project', -# 'GAE_SERVICE': 'service', -# 'GAE_VERSION': 'version' -# }): -# self.assertTrue(trace_exporter.is_gae_environment()) -# trace_exporter.set_attributes(trace) - -# span = trace.get('spans')[0] -# self.assertEqual(span, expected) - -# @mock.patch('opencensus.ext.stackdriver.trace_exporter.' -# 'monitored_resource.get_instance') -# def test_monitored_resource_attributes_gce(self, gmr_mock): -# trace = {'spans': [{'attributes': {}}]} - -# expected = { -# 'attributes': { -# 'attributeMap': { -# 'g.co/agent': { -# 'string_value': { -# 'truncated_byte_count': 0, -# 'value': -# 'opencensus-python [{}]'.format(__version__) -# } -# }, -# 'g.co/r/gce_instance/project_id': { -# 'string_value': { -# 'truncated_byte_count': 0, -# 'value': 'my_project' -# } -# }, -# 'g.co/r/gce_instance/instance_id': { -# 'string_value': { -# 'truncated_byte_count': 0, -# 'value': '12345' -# } -# }, -# 'g.co/r/gce_instance/zone': { -# 'string_value': { -# 'truncated_byte_count': 0, -# 'value': 'zone1' -# } -# }, -# } -# } -# } - -# mock_resource = mock.Mock() -# mock_resource.get_type.return_value = 'gce_instance' -# mock_resource.get_labels.return_value = { -# 'project_id': 'my_project', -# 'instance_id': '12345', -# 'zone': 'zone1' -# } -# gmr_mock.return_value = mock_resource -# trace_exporter.set_attributes(trace) -# span = trace.get('spans')[0] -# self.assertEqual(span, expected) - -# @mock.patch('opencensus.ext.stackdriver.trace_exporter.' -# 'monitored_resource.get_instance') -# def test_monitored_resource_attributes_aws(self, amr_mock): -# trace = {'spans': [{'attributes': {}}]} - -# expected = { -# 'attributes': { -# 'attributeMap': { -# 'g.co/agent': { -# 'string_value': { -# 'truncated_byte_count': 0, -# 'value': -# 'opencensus-python [{}]'.format(__version__) -# } -# }, -# 'g.co/r/aws_ec2_instance/aws_account': { -# 'string_value': { -# 'truncated_byte_count': 0, -# 'value': '123456789012' -# } -# }, -# 'g.co/r/aws_ec2_instance/region': { -# 'string_value': { -# 'truncated_byte_count': 0, -# 'value': 'aws:us-west-2' -# } -# }, -# } -# } -# } - -# mock_resource = mock.Mock() -# mock_resource.get_type.return_value = 'aws_ec2_instance' -# mock_resource.get_labels.return_value = { -# 'aws_account': '123456789012', -# 'region': 'us-west-2' -# } -# amr_mock.return_value = mock_resource - -# trace_exporter.set_attributes(trace) -# span = trace.get('spans')[0] -# self.assertEqual(span, expected) - -# @mock.patch('opencensus.ext.stackdriver.trace_exporter.' -# 'monitored_resource.get_instance') -# def test_monitored_resource_attributes_None(self, mr_mock): -# trace = {'spans': [{'attributes': {}}]} - -# expected = { -# 'attributes': { -# 'attributeMap': { -# 'g.co/agent': { -# 'string_value': { -# 'truncated_byte_count': 0, -# 'value': -# 'opencensus-python [{}]'.format(__version__) -# } -# } -# } -# } -# } - -# mr_mock.return_value = None -# trace_exporter.set_attributes(trace) -# span = trace.get('spans')[0] -# self.assertEqual(span, expected) - -# mock_resource = mock.Mock() -# mock_resource.get_type.return_value = mock.Mock() -# mock_resource.get_labels.return_value = mock.Mock() -# mr_mock.return_value = mock_resource - -# trace_exporter.set_attributes(trace) -# span = trace.get('spans')[0] -# self.assertEqual(span, expected) - - -# class MockTransport(object): -# def __init__(self, exporter=None): -# self.export_called = False -# self.exporter = exporter - -# def export(self, trace): -# self.export_called = True +# Copyright 2017, OpenCensus 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. + +import unittest + +import mock + +from opencensus.common.version import __version__ +from opencensus.ext.stackdriver import trace_exporter +from opencensus.trace import span_context +from opencensus.trace import span_data as span_data_module + + +class _Client(object): + def __init__(self, project=None): + if project is None: + project = 'PROJECT' + + self.project = project + + +class TestStackdriverExporter(unittest.TestCase): + def test_constructor_default(self): + patch = mock.patch( + 'opencensus.ext.stackdriver.trace_exporter.Client', + new=_Client) + + with patch: + exporter = trace_exporter.StackdriverExporter() + + project_id = 'PROJECT' + self.assertEqual(exporter.project_id, project_id) + + def test_constructor_explicit(self): + client = mock.Mock() + project_id = 'PROJECT' + client.project = project_id + transport = mock.Mock() + + exporter = trace_exporter.StackdriverExporter( + client=client, project_id=project_id, transport=transport) + + self.assertIs(exporter.client, client) + self.assertEqual(exporter.project_id, project_id) + + def test_export(self): + client = mock.Mock() + project_id = 'PROJECT' + client.project = project_id + exporter = trace_exporter.StackdriverExporter( + client=client, project_id=project_id, transport=MockTransport) + exporter.export({}) + + self.assertTrue(exporter.transport.export_called) + + @mock.patch('opencensus.ext.stackdriver.trace_exporter.' + 'monitored_resource.get_instance', + return_value=None) + def test_emit(self, mr_mock): + trace_id = '6e0c63257de34c92bf9efcd03927272e' + span_datas = [ + span_data_module.SpanData( + name='span', + context=span_context.SpanContext(trace_id=trace_id), + span_id='1111', + parent_span_id=None, + attributes=None, + start_time=None, + end_time=None, + child_span_count=None, + stack_trace=None, + annotations=None, + message_events=None, + links=None, + status=None, + same_process_as_parent_span=None, + span_kind=0, + ) + ] + + stackdriver_spans = { + 'spans': [{ + 'status': + None, + 'childSpanCount': + None, + 'links': + None, + 'startTime': + None, + 'spanId': + '1111', + 'attributes': { + 'attributeMap': { + 'g.co/agent': { + 'string_value': { + 'truncated_byte_count': + 0, + 'value': + 'opencensus-python [{}]'.format(__version__) + } + } + } + }, + 'stackTrace': + None, + 'displayName': { + 'truncated_byte_count': 0, + 'value': 'span' + }, + 'name': + 'projects/PROJECT/traces/{}/spans/1111'.format(trace_id), + 'timeEvents': + None, + 'endTime': + None, + 'sameProcessAsParentSpan': + None + }] + } + + client = mock.Mock() + project_id = 'PROJECT' + client.project = project_id + + exporter = trace_exporter.StackdriverExporter( + client=client, project_id=project_id) + + exporter.emit(span_datas) + + name = 'projects/{}'.format(project_id) + + client.batch_write_spans.assert_called_with(name, stackdriver_spans) + self.assertTrue(client.batch_write_spans.called) + + @mock.patch('opencensus.ext.stackdriver.trace_exporter.' + 'monitored_resource.get_instance', + return_value=None) + def test_translate_to_stackdriver(self, mr_mock): + project_id = 'PROJECT' + trace_id = '6e0c63257de34c92bf9efcd03927272e' + span_name = 'test span' + span_id = '6e0c63257de34c92' + attributes = { + 'attributeMap': { + 'key': { + 'string_value': { + 'truncated_byte_count': 0, + 'value': 'value' + } + }, + 'key_double': { + 'double_value': { + 'value': 123.45 + } + }, + 'http.host': { + 'string_value': { + 'truncated_byte_count': 0, + 'value': 'host' + } + } + } + } + parent_span_id = '6e0c63257de34c93' + start_time = 'test start time' + end_time = 'test end time' + trace = { + 'spans': [{ + 'displayName': { + 'value': span_name, + 'truncated_byte_count': 0 + }, + 'spanId': + span_id, + 'startTime': + start_time, + 'endTime': + end_time, + 'parentSpanId': + parent_span_id, + 'attributes': + attributes, + 'someRandomKey': + 'this should not be included in result', + 'childSpanCount': + 0 + }], + 'traceId': + trace_id + } + + client = mock.Mock() + client.project = project_id + exporter = trace_exporter.StackdriverExporter( + client=client, project_id=project_id) + + spans = list(exporter.translate_to_stackdriver(trace)) + + expected_traces = [{ + 'name': 'projects/{}/traces/{}/spans/{}'.format( + project_id, trace_id, span_id), + 'displayName': { + 'value': span_name, + 'truncated_byte_count': 0 + }, + 'attributes': { + 'attributeMap': { + 'g.co/agent': { + 'string_value': { + 'truncated_byte_count': 0, + 'value': + 'opencensus-python [{}]'.format(__version__) + } + }, + 'key': { + 'string_value': { + 'truncated_byte_count': 0, + 'value': 'value' + } + }, + 'key_double': { + 'double_value': { + 'value': 123.45 + } + }, + '/http/host': { + 'string_value': { + 'truncated_byte_count': 0, + 'value': 'host' + } + } + } + }, + 'spanId': str(span_id), + 'startTime': start_time, + 'endTime': end_time, + 'parentSpanId': str(parent_span_id), + 'status': None, + 'links': None, + 'stackTrace': None, + 'timeEvents': None, + 'childSpanCount': 0, + 'sameProcessAsParentSpan': None + }] + + self.assertEqual(spans, expected_traces) + + def test_translate_common_attributes_to_stackdriver_no_map(self): + project_id = 'PROJECT' + client = mock.Mock() + client.project = project_id + exporter = trace_exporter.StackdriverExporter( + client=client, project_id=project_id) + + attributes = {'outer key': 'some value'} + expected_attributes = {'outer key': 'some value'} + + exporter.map_attributes(attributes) + self.assertEqual(attributes, expected_attributes) + + def test_translate_common_attributes_to_stackdriver_none(self): + project_id = 'PROJECT' + client = mock.Mock() + client.project = project_id + exporter = trace_exporter.StackdriverExporter( + client=client, project_id=project_id) + + # does not throw + self.assertIsNone(exporter.map_attributes(None)) + + def test_translate_common_attributes_to_stackdriver(self): + project_id = 'PROJECT' + client = mock.Mock() + client.project = project_id + exporter = trace_exporter.StackdriverExporter( + client=client, project_id=project_id) + + attributes = { + 'outer key': 'some value', + 'attributeMap': { + 'key': { + 'string_value': { + 'truncated_byte_count': 0, + 'value': 'value' + } + }, + 'component': { + 'string_value': { + 'truncated_byte_count': 0, + 'value': 'http' + } + }, + 'error.message': { + 'string_value': { + 'truncated_byte_count': 0, + 'value': 'error message' + } + }, + 'error.name': { + 'string_value': { + 'truncated_byte_count': 0, + 'value': 'error name' + } + }, + 'http.host': { + 'string_value': { + 'truncated_byte_count': 0, + 'value': 'host' + } + }, + 'http.method': { + 'string_value': { + 'truncated_byte_count': 0, + 'value': 'GET' + } + }, + 'http.status_code': { + 'int_value': { + 'value': 200 + } + }, + 'http.url': { + 'string_value': { + 'truncated_byte_count': 0, + 'value': 'http://host:port/path?query' + } + }, + 'http.user_agent': { + 'string_value': { + 'truncated_byte_count': 0, + 'value': 'some user agent' + } + }, + 'http.client_city': { + 'string_value': { + 'truncated_byte_count': 0, + 'value': 'Redmond' + } + }, + 'http.client_country': { + 'string_value': { + 'truncated_byte_count': 0, + 'value': 'USA' + } + }, + 'http.client_protocol': { + 'string_value': { + 'truncated_byte_count': 0, + 'value': 'HTTP 1.1' + } + }, + 'http.client_region': { + 'string_value': { + 'truncated_byte_count': 0, + 'value': 'WA' + } + }, + 'http.request_size': { + 'int_value': { + 'value': 100 + } + }, + 'http.response_size': { + 'int_value': { + 'value': 10 + } + }, + 'pid': { + 'int_value': { + 'value': 123456789 + } + }, + 'tid': { + 'int_value': { + 'value': 987654321 + } + }, + 'stacktrace': { + 'string_value': { + 'truncated_byte_count': 0, + 'value': 'at unknown' + } + }, + 'grpc.host_port': { + 'string_value': { + 'truncated_byte_count': 0, + 'value': 'localhost:50051' + } + }, + 'grpc.method': { + 'string_value': { + 'truncated_byte_count': 0, + 'value': 'post' + } + } + } + } + + expected_attributes = { + 'outer key': 'some value', + 'attributeMap': { + 'key': { + 'string_value': { + 'truncated_byte_count': 0, + 'value': 'value' + } + }, + '/component': { + 'string_value': { + 'truncated_byte_count': 0, + 'value': 'http' + } + }, + '/error/message': { + 'string_value': { + 'truncated_byte_count': 0, + 'value': 'error message' + } + }, + '/error/name': { + 'string_value': { + 'truncated_byte_count': 0, + 'value': 'error name' + } + }, + '/http/host': { + 'string_value': { + 'truncated_byte_count': 0, + 'value': 'host' + } + }, + '/http/method': { + 'string_value': { + 'truncated_byte_count': 0, + 'value': 'GET' + } + }, + '/http/status_code': { + 'string_value': { + 'truncated_byte_count': 0, + 'value': '200' + } + }, + '/http/url': { + 'string_value': { + 'truncated_byte_count': 0, + 'value': 'http://host:port/path?query' + } + }, + '/http/user_agent': { + 'string_value': { + 'truncated_byte_count': 0, + 'value': 'some user agent' + } + }, + '/http/client_city': { + 'string_value': { + 'truncated_byte_count': 0, + 'value': 'Redmond' + } + }, + '/http/client_country': { + 'string_value': { + 'truncated_byte_count': 0, + 'value': 'USA' + } + }, + '/http/client_protocol': { + 'string_value': { + 'truncated_byte_count': 0, + 'value': 'HTTP 1.1' + } + }, + '/http/client_region': { + 'string_value': { + 'truncated_byte_count': 0, + 'value': 'WA' + } + }, + '/http/request/size': { + 'int_value': { + 'value': 100 + } + }, + '/http/response/size': { + 'int_value': { + 'value': 10 + } + }, + '/pid': { + 'int_value': { + 'value': 123456789 + } + }, + '/tid': { + 'int_value': { + 'value': 987654321 + } + }, + '/stacktrace': { + 'string_value': { + 'truncated_byte_count': 0, + 'value': 'at unknown' + } + }, + '/grpc/host_port': { + 'string_value': { + 'truncated_byte_count': 0, + 'value': 'localhost:50051' + } + }, + '/grpc/method': { + 'string_value': { + 'truncated_byte_count': 0, + 'value': 'post' + } + } + } + } + + exporter.map_attributes(attributes) + self.assertEqual(attributes, expected_attributes) + + def test_translate_common_attributes_status_code(self): + project_id = 'PROJECT' + client = mock.Mock() + client.project = project_id + exporter = trace_exporter.StackdriverExporter( + client=client, project_id=project_id) + + attributes = { + 'outer key': 'some value', + 'attributeMap': { + 'http.status_code': { + 'int_value': 200 + } + } + } + + expected_attributes = { + 'outer key': 'some value', + 'attributeMap': { + '/http/status_code': { + 'string_value': { + 'truncated_byte_count': 0, + 'value': '200' + } + } + } + } + + exporter.map_attributes(attributes) + self.assertEqual(attributes, expected_attributes) + + +class Test_set_attributes_gae(unittest.TestCase): + @mock.patch('opencensus.ext.stackdriver.trace_exporter.' + 'monitored_resource.get_instance', + return_value=None) + def test_set_attributes_gae(self, mr_mock): + import os + + trace = {'spans': [{'attributes': {}}]} + + expected = { + 'attributes': { + 'attributeMap': { + 'g.co/gae/app/module': { + 'string_value': { + 'truncated_byte_count': 0, + 'value': 'service' + } + }, + 'g.co/gae/app/instance': { + 'string_value': { + 'truncated_byte_count': 0, + 'value': 'flex' + } + }, + 'g.co/gae/app/version': { + 'string_value': { + 'truncated_byte_count': 0, + 'value': 'version' + } + }, + 'g.co/gae/app/project': { + 'string_value': { + 'truncated_byte_count': 0, + 'value': 'project' + } + }, + 'g.co/agent': { + 'string_value': { + 'truncated_byte_count': 0, + 'value': + 'opencensus-python [{}]'.format(__version__) + } + }, + } + } + } + + with mock.patch.dict( + os.environ, { + trace_exporter._APPENGINE_FLEXIBLE_ENV_VM: 'vm', + trace_exporter._APPENGINE_FLEXIBLE_ENV_FLEX: 'flex', + 'GOOGLE_CLOUD_PROJECT': 'project', + 'GAE_SERVICE': 'service', + 'GAE_VERSION': 'version' + }): + self.assertTrue(trace_exporter.is_gae_environment()) + trace_exporter.set_attributes(trace) + + span = trace.get('spans')[0] + self.assertEqual(span, expected) + + +class TestMonitoredResourceAttributes(unittest.TestCase): + @mock.patch('opencensus.ext.stackdriver.trace_exporter.' + 'monitored_resource.get_instance') + def test_monitored_resource_attributes_gke(self, gmr_mock): + import os + + trace = {'spans': [{'attributes': {}}]} + + expected = { + 'attributes': { + 'attributeMap': { + 'g.co/gae/app/module': { + 'string_value': { + 'truncated_byte_count': 0, + 'value': 'service' + } + }, + 'g.co/gae/app/instance': { + 'string_value': { + 'truncated_byte_count': 0, + 'value': 'flex' + } + }, + 'g.co/gae/app/version': { + 'string_value': { + 'truncated_byte_count': 0, + 'value': 'version' + } + }, + 'g.co/gae/app/project': { + 'string_value': { + 'truncated_byte_count': 0, + 'value': 'project' + } + }, + 'g.co/agent': { + 'string_value': { + 'truncated_byte_count': 0, + 'value': + 'opencensus-python [{}]'.format(__version__) + } + }, + 'g.co/r/k8s_container/project_id': { + 'string_value': { + 'truncated_byte_count': 0, + 'value': 'my_project' + } + }, + 'g.co/r/k8s_container/location': { + 'string_value': { + 'truncated_byte_count': 0, + 'value': 'zone1' + } + }, + 'g.co/r/k8s_container/namespace_name': { + 'string_value': { + 'truncated_byte_count': 0, + 'value': 'namespace' + } + }, + 'g.co/r/k8s_container/pod_name': { + 'string_value': { + 'truncated_byte_count': 0, + 'value': 'pod' + } + }, + 'g.co/r/k8s_container/cluster_name': { + 'string_value': { + 'truncated_byte_count': 0, + 'value': 'cluster' + } + }, + 'g.co/r/k8s_container/container_name': { + 'string_value': { + 'truncated_byte_count': 0, + 'value': 'c1' + } + }, + } + } + } + + mock_resource = mock.Mock() + mock_resource.get_type.return_value = 'k8s_container' + mock_resource.get_labels.return_value = { + 'k8s.io/pod/name': 'pod', + 'k8s.io/cluster/name': 'cluster', + 'k8s.io/namespace/name': 'namespace', + 'k8s.io/container/name': 'c1', + 'project_id': 'my_project', + 'zone': 'zone1' + } + gmr_mock.return_value = mock_resource + with mock.patch.dict( + os.environ, { + trace_exporter._APPENGINE_FLEXIBLE_ENV_VM: 'vm', + trace_exporter._APPENGINE_FLEXIBLE_ENV_FLEX: 'flex', + 'GOOGLE_CLOUD_PROJECT': 'project', + 'GAE_SERVICE': 'service', + 'GAE_VERSION': 'version' + }): + self.assertTrue(trace_exporter.is_gae_environment()) + trace_exporter.set_attributes(trace) + + span = trace.get('spans')[0] + self.assertEqual(span, expected) + + @mock.patch('opencensus.ext.stackdriver.trace_exporter.' + 'monitored_resource.get_instance') + def test_monitored_resource_attributes_gce(self, gmr_mock): + trace = {'spans': [{'attributes': {}}]} + + expected = { + 'attributes': { + 'attributeMap': { + 'g.co/agent': { + 'string_value': { + 'truncated_byte_count': 0, + 'value': + 'opencensus-python [{}]'.format(__version__) + } + }, + 'g.co/r/gce_instance/project_id': { + 'string_value': { + 'truncated_byte_count': 0, + 'value': 'my_project' + } + }, + 'g.co/r/gce_instance/instance_id': { + 'string_value': { + 'truncated_byte_count': 0, + 'value': '12345' + } + }, + 'g.co/r/gce_instance/zone': { + 'string_value': { + 'truncated_byte_count': 0, + 'value': 'zone1' + } + }, + } + } + } + + mock_resource = mock.Mock() + mock_resource.get_type.return_value = 'gce_instance' + mock_resource.get_labels.return_value = { + 'project_id': 'my_project', + 'instance_id': '12345', + 'zone': 'zone1' + } + gmr_mock.return_value = mock_resource + trace_exporter.set_attributes(trace) + span = trace.get('spans')[0] + self.assertEqual(span, expected) + + @mock.patch('opencensus.ext.stackdriver.trace_exporter.' + 'monitored_resource.get_instance') + def test_monitored_resource_attributes_aws(self, amr_mock): + trace = {'spans': [{'attributes': {}}]} + + expected = { + 'attributes': { + 'attributeMap': { + 'g.co/agent': { + 'string_value': { + 'truncated_byte_count': 0, + 'value': + 'opencensus-python [{}]'.format(__version__) + } + }, + 'g.co/r/aws_ec2_instance/aws_account': { + 'string_value': { + 'truncated_byte_count': 0, + 'value': '123456789012' + } + }, + 'g.co/r/aws_ec2_instance/region': { + 'string_value': { + 'truncated_byte_count': 0, + 'value': 'aws:us-west-2' + } + }, + } + } + } + + mock_resource = mock.Mock() + mock_resource.get_type.return_value = 'aws_ec2_instance' + mock_resource.get_labels.return_value = { + 'aws_account': '123456789012', + 'region': 'us-west-2' + } + amr_mock.return_value = mock_resource + + trace_exporter.set_attributes(trace) + span = trace.get('spans')[0] + self.assertEqual(span, expected) + + @mock.patch('opencensus.ext.stackdriver.trace_exporter.' + 'monitored_resource.get_instance') + def test_monitored_resource_attributes_None(self, mr_mock): + trace = {'spans': [{'attributes': {}}]} + + expected = { + 'attributes': { + 'attributeMap': { + 'g.co/agent': { + 'string_value': { + 'truncated_byte_count': 0, + 'value': + 'opencensus-python [{}]'.format(__version__) + } + } + } + } + } + + mr_mock.return_value = None + trace_exporter.set_attributes(trace) + span = trace.get('spans')[0] + self.assertEqual(span, expected) + + mock_resource = mock.Mock() + mock_resource.get_type.return_value = mock.Mock() + mock_resource.get_labels.return_value = mock.Mock() + mr_mock.return_value = mock_resource + + trace_exporter.set_attributes(trace) + span = trace.get('spans')[0] + self.assertEqual(span, expected) + + +class MockTransport(object): + def __init__(self, exporter=None): + self.export_called = False + self.exporter = exporter + + def export(self, trace): + self.export_called = True diff --git a/contrib/opencensus-ext-stackdriver/tests/test_stackdriver_stats.py b/contrib/opencensus-ext-stackdriver/tests/test_stackdriver_stats.py index db9eb66e1..7c82fc592 100644 --- a/contrib/opencensus-ext-stackdriver/tests/test_stackdriver_stats.py +++ b/contrib/opencensus-ext-stackdriver/tests/test_stackdriver_stats.py @@ -1,1391 +1,1391 @@ # flake8: noqa -# # Copyright 2018, OpenCensus 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. - -# import unittest -# from datetime import datetime - -# import google.auth -# import mock -# from google.cloud import monitoring_v3 - -# from opencensus.common import utils -# from opencensus.common.version import __version__ -# from opencensus.ext.stackdriver import stats_exporter as stackdriver -# from opencensus.metrics import label_key, label_value -# from opencensus.metrics import transport as transport_module -# from opencensus.metrics.export import ( -# metric, -# metric_descriptor, -# point, -# time_series, -# value, -# ) -# from opencensus.stats import aggregation as aggregation_module -# from opencensus.stats import aggregation_data as aggregation_data_module -# from opencensus.stats import execution_context -# from opencensus.stats import measure as measure_module -# from opencensus.stats import metric_utils -# from opencensus.stats import stats as stats_module -# from opencensus.stats import view as view_module -# from opencensus.stats import view_data as view_data_module -# from opencensus.tags import tag_key as tag_key_module -# from opencensus.tags import tag_map as tag_map_module -# from opencensus.tags import tag_value as tag_value_module - -# MiB = 1 << 20 -# FRONTEND_KEY = tag_key_module.TagKey("my.org/keys/frontend") -# FRONTEND_KEY_FLOAT = tag_key_module.TagKey("my.org/keys/frontend-FLOAT") -# FRONTEND_KEY_INT = tag_key_module.TagKey("my.org/keys/frontend-INT") -# FRONTEND_KEY_STR = tag_key_module.TagKey("my.org/keys/frontend-STR") - -# FRONTEND_KEY_CLEAN = "my_org_keys_frontend" -# FRONTEND_KEY_FLOAT_CLEAN = "my_org_keys_frontend_FLOAT" -# FRONTEND_KEY_INT_CLEAN = "my_org_keys_frontend_INT" -# FRONTEND_KEY_STR_CLEAN = "my_org_keys_frontend_STR" - -# VIDEO_SIZE_MEASURE = measure_module.MeasureFloat( -# "my.org/measure/video_size_test2", "size of processed videos", "By") -# VIDEO_SIZE_MEASURE_2 = measure_module.MeasureFloat( -# "my.org/measure/video_size_test_2", "size of processed videos", "By") - -# VIDEO_SIZE_MEASURE_FLOAT = measure_module.MeasureFloat( -# "my.org/measure/video_size_test-float", "size of processed videos-float", -# "By") - -# VIDEO_SIZE_VIEW_NAME = "my.org/views/video_size_test2" -# VIDEO_SIZE_DISTRIBUTION = aggregation_module.DistributionAggregation( -# [16.0 * MiB, 256.0 * MiB]) -# VIDEO_SIZE_VIEW = view_module.View( -# VIDEO_SIZE_VIEW_NAME, "processed video size over time", [FRONTEND_KEY], -# VIDEO_SIZE_MEASURE, VIDEO_SIZE_DISTRIBUTION) - -# TEST_TIME = datetime(2018, 12, 25, 1, 2, 3, 4) -# TEST_TIME_STR = utils.to_iso_str(TEST_TIME) - - -# class _Client(object): -# def __init__(self, client_info=None): -# self.client_info = client_info - - -# class TestOptions(unittest.TestCase): -# def test_options_blank(self): -# options = stackdriver.Options() - -# self.assertEqual(options.project_id, "") -# self.assertEqual(options.resource, "") - -# def test_options_parameters(self): -# options = stackdriver.Options( -# project_id="project-id", metric_prefix="sample") -# self.assertEqual(options.project_id, "project-id") -# self.assertEqual(options.metric_prefix, "sample") - -# def test_default_monitoring_labels(self): -# options = stackdriver.Options(default_monitoring_labels={ -# label_key.LabelKey('lk_key', 'lk_desc'): -# label_value.LabelValue('lk_value') -# }) - -# self.assertEqual(len(options.default_monitoring_labels), 1) -# [[lk, lv]] = options.default_monitoring_labels.items() -# self.assertEqual(lk.key, 'lk_key') -# self.assertEqual(lk.description, 'lk_desc') -# self.assertEqual(lv.value, 'lk_value') - -# def test_default_monitoring_labels_blank(self): -# with mock.patch('opencensus.ext.stackdriver.stats_exporter' -# '.get_task_value') as mock_gtv: -# options = stackdriver.Options() - -# mock_gtv.assert_called() - -# self.assertEqual(len(options.default_monitoring_labels), 1) -# [[lk, lv]] = options.default_monitoring_labels.items() -# self.assertEqual(lk.key, stackdriver.OPENCENSUS_TASK) -# self.assertEqual(lk.description, -# stackdriver.OPENCENSUS_TASK_DESCRIPTION) -# self.assertEqual(lv.value, mock_gtv()) - -# def test_bad_default_monitoring_labels(self): -# with self.assertRaises(AttributeError): -# stackdriver.Options( -# default_monitoring_labels=[ -# 'not a dict' -# ]) - -# with self.assertRaises(TypeError): -# stackdriver.Options( -# default_monitoring_labels={ -# 'bad key': -# label_value.LabelValue('clk_value') -# }) - -# with self.assertRaises(TypeError): -# stackdriver.Options( -# default_monitoring_labels={ -# label_key.LabelKey('clk_key', 'clk_desc'): -# 'bad value' -# }) - - -# class TestStackdriverStatsExporter(unittest.TestCase): -# def test_constructor(self): -# exporter = stackdriver.StackdriverStatsExporter() - -# self.assertIsNone(exporter.client) - -# def test_constructor_param(self): -# exporter = stackdriver.StackdriverStatsExporter( -# options=stackdriver.Options(project_id=1)) -# self.assertEqual(exporter.options.project_id, 1) - -# def test_null_options(self): -# # Check that we don't suppress auth errors -# auth_error = google.auth.exceptions.DefaultCredentialsError -# mock_auth_error = mock.Mock() -# mock_auth_error.side_effect = auth_error -# with mock.patch('opencensus.ext.stackdriver.stats_exporter' -# '.google.auth.default', mock_auth_error): -# with self.assertRaises(auth_error): -# stackdriver.new_stats_exporter() - -# # Check that we get the default credentials' project ID -# mock_auth_ok = mock.Mock() -# mock_auth_ok.return_value = (None, 123) -# with mock.patch('opencensus.ext.stackdriver.stats_exporter' -# '.google.auth.default', mock_auth_ok): -# sdse = stackdriver.new_stats_exporter() -# self.assertEqual(sdse.options.project_id, 123) - -# # Check that we raise if auth works but the project is empty -# mock_auth_no_project = mock.Mock() -# mock_auth_no_project.return_value = (None, '') -# with mock.patch('opencensus.ext.stackdriver.stats_exporter' -# '.google.auth.default', mock_auth_no_project): -# with self.assertRaises(ValueError): -# stackdriver.new_stats_exporter() - -# def test_blank_project(self): -# self.assertRaises(ValueError, stackdriver.new_stats_exporter, -# stackdriver.Options(project_id="")) - -# def test_not_blank_project(self): -# patch_client = mock.patch( -# ('opencensus.ext.stackdriver.stats_exporter' -# '.monitoring_v3.MetricServiceClient'), _Client) - -# with patch_client: -# exporter_created = stackdriver.new_stats_exporter( -# stackdriver.Options(project_id=1)) - -# self.assertIsInstance(exporter_created, -# stackdriver.StackdriverStatsExporter) - -# def test_get_user_agent_slug(self): -# self.assertIn(__version__, stackdriver.get_user_agent_slug()) - -# def test_client_info_user_agent(self): -# """Check that the monitoring client sets a user agent. - -# The user agent should include the library version. Note that this -# assumes MetricServiceClient calls ClientInfo.to_user_agent to attach -# the user agent as metadata to metric service API calls. -# """ -# patch_client = mock.patch( -# 'opencensus.ext.stackdriver.stats_exporter.monitoring_v3' -# '.MetricServiceClient', _Client) - -# with patch_client: -# exporter = stackdriver.new_stats_exporter( -# stackdriver.Options(project_id=1)) - -# self.assertIn(stackdriver.get_user_agent_slug(), -# exporter.client.client_info.to_user_agent()) - -# def test_sanitize(self): -# # empty -# result = stackdriver.sanitize_label("") -# self.assertEqual(result, "") - -# # all invalid -# result = stackdriver.sanitize_label("/*^#$") -# self.assertEqual(result, "key_") - -# # all valid -# result = stackdriver.sanitize_label("abc") -# self.assertEqual(result, "abc") - -# # mixed -# result = stackdriver.sanitize_label("a.b/c") -# self.assertEqual(result, "a_b_c") - -# # starts with '_' -# result = stackdriver.sanitize_label("_abc") -# self.assertEqual(result, "key_abc") - -# # starts with digit -# result = stackdriver.sanitize_label("0abc") -# self.assertEqual(result, "key_0abc") - -# # too long -# result = stackdriver.sanitize_label("0123456789" * 10) -# self.assertEqual(len(result), 100) -# self.assertEqual(result, "key_" + "0123456789" * 9 + "012345") - -# def test_get_task_value(self): -# task_value = stackdriver.get_task_value() -# self.assertNotEqual(task_value, "") - -# def test_namespaced_views(self): -# view_name = "view-1" -# expected_view_name_namespaced = ( -# "custom.googleapis.com/opencensus/{}".format(view_name)) -# view_name_namespaced = stackdriver.namespaced_view_name(view_name, "") -# self.assertEqual(expected_view_name_namespaced, view_name_namespaced) - -# expected_view_name_namespaced = "kubernetes.io/myorg/%s" % view_name -# view_name_namespaced = stackdriver.namespaced_view_name( -# view_name, "kubernetes.io/myorg") -# self.assertEqual(expected_view_name_namespaced, view_name_namespaced) - -# def test_stackdriver_register_exporter(self): -# stats = stats_module.stats -# view_manager = stats.view_manager - -# exporter = mock.Mock() -# if len(view_manager.measure_to_view_map.exporters) > 0: -# view_manager.unregister_exporter( -# view_manager.measure_to_view_map.exporters[0]) -# view_manager.register_exporter(exporter) - -# registered_exporters = len(view_manager.measure_to_view_map.exporters) - -# self.assertEqual(registered_exporters, 1) - -# @mock.patch('os.getpid', return_value=12345) -# @mock.patch( -# 'platform.uname', -# return_value=('system', 'node', 'release', 'version', 'machine', -# 'processor')) -# def test_get_task_value_with_hostname(self, mock_uname, mock_pid): -# self.assertEqual(stackdriver.get_task_value(), "py-12345@node") - -# @mock.patch('os.getpid', return_value=12345) -# @mock.patch( -# 'platform.uname', -# return_value=('system', '', 'release', 'version', 'machine', -# 'processor')) -# def test_get_task_value_without_hostname(self, mock_uname, mock_pid): -# self.assertEqual(stackdriver.get_task_value(), "py-12345@localhost") - -# def test_default_default_monitoring_labels(self): -# """Check that metrics include OC task label by default.""" -# exporter = stackdriver.StackdriverStatsExporter( -# options=stackdriver.Options(project_id='project_id'), -# client=mock.Mock()) - -# lv = label_value.LabelValue('val') -# val = value.ValueLong(value=123) -# dt = datetime(2019, 3, 20, 21, 34, 0, 537954) -# pp = point.Point(value=val, timestamp=dt) -# ts = [ -# time_series.TimeSeries(label_values=[lv], points=[pp], -# start_timestamp=utils.to_iso_str(dt)) -# ] - -# desc = metric_descriptor.MetricDescriptor( -# name='name', -# description='description', -# unit='unit', -# type_=metric_descriptor.MetricDescriptorType.GAUGE_INT64, -# label_keys=[label_key.LabelKey('key', 'description')] -# ) -# mm = metric.Metric(descriptor=desc, time_series=ts) - -# sd_md = exporter.get_metric_descriptor(desc) -# self.assertEqual(len(sd_md.labels), 2) -# sd_descriptors = {ld.key: ld.description for ld in sd_md.labels} -# self.assertIn('key', sd_descriptors) -# self.assertEqual(sd_descriptors['key'], 'description') -# self.assertIn(stackdriver.OPENCENSUS_TASK, sd_descriptors) -# self.assertEqual( -# sd_descriptors[stackdriver.OPENCENSUS_TASK], -# stackdriver.OPENCENSUS_TASK_DESCRIPTION -# ) - -# sd_ts_list = exporter.create_time_series_list(mm) -# self.assertEqual(len(sd_ts_list), 1) -# [sd_ts] = sd_ts_list -# self.assertIn('key', sd_ts.metric.labels) -# self.assertEqual(sd_ts.metric.labels['key'], 'val') -# self.assertIn(stackdriver.OPENCENSUS_TASK, sd_ts.metric.labels) - -# def test_empty_default_monitoring_labels(self): -# """Check that it's possible to remove the default OC task label.""" -# exporter = stackdriver.StackdriverStatsExporter( -# options=stackdriver.Options( -# project_id='project_id', -# default_monitoring_labels={}), -# client=mock.Mock()) - -# lv = label_value.LabelValue('val') -# val = value.ValueLong(value=123) -# dt = datetime(2019, 3, 20, 21, 34, 0, 537954) -# pp = point.Point(value=val, timestamp=dt) -# ts = [ -# time_series.TimeSeries(label_values=[lv], points=[pp], -# start_timestamp=utils.to_iso_str(dt)) -# ] - -# desc = metric_descriptor.MetricDescriptor( -# name='name', -# description='description', -# unit='unit', -# type_=metric_descriptor.MetricDescriptorType.GAUGE_INT64, -# label_keys=[label_key.LabelKey('key', 'description')] -# ) -# mm = metric.Metric(descriptor=desc, time_series=ts) - -# sd_md = exporter.get_metric_descriptor(desc) -# self.assertEqual(len(sd_md.labels), 1) -# [sd_label] = sd_md.labels -# self.assertEqual(sd_label.key, 'key') -# self.assertEqual(sd_label.description, 'description') - -# sd_ts_list = exporter.create_time_series_list(mm) -# self.assertEqual(len(sd_ts_list), 1) -# [sd_ts] = sd_ts_list -# self.assertIn('key', sd_ts.metric.labels) -# self.assertEqual(sd_ts.metric.labels['key'], 'val') -# self.assertNotIn(stackdriver.OPENCENSUS_TASK, sd_ts.metric.labels) - -# def test_custom_default_monitoring_labels(self): -# """Check that custom labels are exported and included in descriptor.""" -# exporter = stackdriver.StackdriverStatsExporter( -# options=stackdriver.Options( -# project_id='project_id', -# default_monitoring_labels={ -# label_key.LabelKey('clk_key', 'clk_desc'): -# label_value.LabelValue('clk_value') -# }), -# client=mock.Mock()) - -# lv = label_value.LabelValue('val') -# val = value.ValueLong(value=123) -# dt = datetime(2019, 3, 20, 21, 34, 0, 537954) -# pp = point.Point(value=val, timestamp=dt) -# ts = [ -# time_series.TimeSeries(label_values=[lv], points=[pp], -# start_timestamp=utils.to_iso_str(dt)) -# ] - -# desc = metric_descriptor.MetricDescriptor( -# name='name', -# description='description', -# unit='unit', -# type_=metric_descriptor.MetricDescriptorType.GAUGE_INT64, -# label_keys=[label_key.LabelKey('key', 'description')] -# ) -# mm = metric.Metric(descriptor=desc, time_series=ts) - -# sd_md = exporter.get_metric_descriptor(desc) -# self.assertEqual(len(sd_md.labels), 2) -# sd_descriptors = {ld.key: ld.description for ld in sd_md.labels} -# self.assertIn('key', sd_descriptors) -# self.assertEqual(sd_descriptors['key'], 'description') -# self.assertIn('clk_key', sd_descriptors) -# self.assertEqual(sd_descriptors['clk_key'], 'clk_desc') - -# sd_ts_list = exporter.create_time_series_list(mm) -# self.assertEqual(len(sd_ts_list), 1) -# [sd_ts] = sd_ts_list -# self.assertIn('key', sd_ts.metric.labels) -# self.assertEqual(sd_ts.metric.labels['key'], 'val') -# self.assertIn('clk_key', sd_ts.metric.labels) -# self.assertEqual(sd_ts.metric.labels['clk_key'], 'clk_value') - -# def test_get_metric_descriptor(self): -# exporter = stackdriver.StackdriverStatsExporter( -# options=stackdriver.Options( -# project_id='project_id'), -# client=mock.Mock()) - -# oc_md = metric_descriptor.MetricDescriptor( -# name='name', -# description='description', -# unit='unit', -# type_=metric_descriptor.MetricDescriptorType.GAUGE_INT64, -# label_keys=[label_key.LabelKey('ck', 'cd')] -# ) - -# sd_md = exporter.get_metric_descriptor(oc_md) -# self.assertEqual( -# sd_md.metric_kind, -# monitoring_v3.enums.MetricDescriptor.MetricKind.GAUGE) -# self.assertEqual( -# sd_md.value_type, -# monitoring_v3.enums.MetricDescriptor.ValueType.INT64) - -# self.assertIsInstance(sd_md, monitoring_v3.types.MetricDescriptor) -# exporter.client.create_metric_descriptor.assert_not_called() - -# def test_get_metric_descriptor_bad_type(self): -# exporter = stackdriver.StackdriverStatsExporter( -# options=stackdriver.Options(project_id='project_id'), -# client=mock.Mock()) - -# bad_type_oc_md = metric_descriptor.MetricDescriptor( -# name='name', -# description='description', -# unit='unit', -# # Need a valid type to create the descriptor -# type_=metric_descriptor.MetricDescriptorType.GAUGE_INT64, -# label_keys=[label_key.LabelKey('key', 'description')] -# ) -# bad_type_oc_md._type = 100 - -# with self.assertRaises(TypeError): -# exporter.get_metric_descriptor(bad_type_oc_md) - -# def test_get_metric_descriptor_custom_prefix(self): - -# exporter = stackdriver.StackdriverStatsExporter( -# options=stackdriver.Options( -# metric_prefix='metric_prefix', -# project_id='project_id'), -# client=mock.Mock()) - -# oc_md = metric_descriptor.MetricDescriptor( -# name='name', -# description='description', -# unit='unit', -# type_=metric_descriptor.MetricDescriptorType.GAUGE_INT64, -# label_keys=[label_key.LabelKey('ck', 'cd')] -# ) - -# sd_md = exporter.get_metric_descriptor(oc_md) -# self.assertIn('metric_prefix', sd_md.type) -# self.assertIn('metric_prefix', sd_md.name) - -# def test_register_metric_descriptor(self): -# exporter = stackdriver.StackdriverStatsExporter( -# options=stackdriver.Options( -# metric_prefix='metric_prefix', -# project_id='project_id'), -# client=mock.Mock()) - -# oc_md = metric_descriptor.MetricDescriptor( -# name='name', -# description='description', -# unit='unit', -# type_=metric_descriptor.MetricDescriptorType.GAUGE_INT64, -# label_keys=[label_key.LabelKey('key', 'description')] -# ) - -# exporter.register_metric_descriptor(oc_md) -# self.assertEqual( -# exporter.client.create_metric_descriptor.call_count, -# 1 -# ) -# exporter.register_metric_descriptor(oc_md) -# self.assertEqual( -# exporter.client.create_metric_descriptor.call_count, -# 1 -# ) - -# def test_export_metrics(self): -# lv = label_value.LabelValue('val') -# val = value.ValueLong(value=123) -# dt = datetime(2019, 3, 20, 21, 34, 0, 537954) -# pp = point.Point(value=val, timestamp=dt) - -# ts = [ -# time_series.TimeSeries(label_values=[lv], points=[pp], -# start_timestamp=utils.to_iso_str(dt)) -# ] - -# desc = metric_descriptor.MetricDescriptor( -# name='name', -# description='description', -# unit='unit', -# type_=metric_descriptor.MetricDescriptorType.GAUGE_INT64, -# label_keys=[label_key.LabelKey('key', 'description')] -# ) - -# mm = metric.Metric(descriptor=desc, time_series=ts) - -# exporter = stackdriver.StackdriverStatsExporter(client=mock.Mock()) -# exporter.export_metrics([mm]) - -# self.assertEqual(exporter.client.create_time_series.call_count, 1) -# sd_args = exporter.client.create_time_series.call_args[0][1] -# self.assertEqual(len(sd_args), 1) -# [sd_arg] = exporter.client.create_time_series.call_args[0][1] -# self.assertEqual(sd_arg.points[0].value.int64_value, 123) - - -# class MockPeriodicMetricTask(object): -# """Testing mock of metrics.transport.PeriodicMetricTask. - -# Simulate calling export asynchronously from another thread synchronously -# from this one. -# """ -# def __init__(self, interval=None, function=None, args=None, kwargs=None): -# self.function = function -# self.logger = mock.Mock() -# self.start = mock.Mock() -# self.run = mock.Mock() - -# def step(self): -# try: -# self.function() -# except transport_module.TransportError as ex: -# self.logger.exception(ex) -# self.cancel() -# except Exception: -# self.logger.exception("Error handling metric export") - - -# class MockGetExporterThread(object): -# """Intercept calls to get_exporter_thread. - -# To get a reference to the running PeriodicMetricTask created by -# get_exporter_thread. -# """ -# def __init__(self): -# self.transport = None - -# def __enter__(self): -# original_func = transport_module.get_exporter_thread - -# def get_exporter_thread(*aa, **kw): -# self.transport = original_func(*aa, **kw) - -# mock_get = mock.Mock() -# mock_get.side_effect = get_exporter_thread -# self.patcher = mock.patch( -# ('opencensus.ext.stackdriver.stats_exporter' -# '.transport.get_exporter_thread'), -# mock_get) -# self.patcher.start() -# return self - -# def __exit__(self, type, value, traceback): -# self.patcher.stop() - - -# @mock.patch('opencensus.ext.stackdriver.stats_exporter' -# '.monitoring_v3.MetricServiceClient') -# @mock.patch('opencensus.ext.stackdriver.stats_exporter' -# '.stats.stats') -# class TestAsyncStatsExport(unittest.TestCase): -# """Check that metrics are exported using the exporter thread.""" - -# def setUp(self): -# patcher = mock.patch( -# 'opencensus.metrics.transport.PeriodicMetricTask', -# MockPeriodicMetricTask) -# patcher.start() -# self.addCleanup(patcher.stop) - -# def test_export_empty(self, mock_stats, mock_client): -# """Check that we don't attempt to export empty metric sets.""" - -# mock_stats.get_metrics.return_value = [] - -# with MockGetExporterThread() as mget: -# exporter = stackdriver.new_stats_exporter( -# stackdriver.Options(project_id=1)) -# mget.transport.step() - -# exporter.client.create_metric_descriptor.assert_not_called() -# exporter.client.create_time_series.assert_not_called() - -# def test_export_single_metric(self, mock_stats, mock_client): -# """Check that we can export a set of a single metric.""" - -# lv = label_value.LabelValue('val') -# val = value.ValueLong(value=123) -# dt = datetime(2019, 3, 20, 21, 34, 0, 537954) -# pp = point.Point(value=val, timestamp=dt) - -# ts = [ -# time_series.TimeSeries(label_values=[lv], points=[pp], -# start_timestamp=utils.to_iso_str(dt)) -# ] - -# desc = metric_descriptor.MetricDescriptor( -# name='name2', -# description='description2', -# unit='unit2', -# type_=metric_descriptor.MetricDescriptorType.GAUGE_INT64, -# label_keys=[label_key.LabelKey('key', 'description')] -# ) - -# mm = metric.Metric(descriptor=desc, time_series=ts) -# mock_stats.get_metrics.return_value = [mm] - -# with MockGetExporterThread() as mget: -# exporter = stackdriver.new_stats_exporter( -# stackdriver.Options(project_id=1)) -# mget.transport.step() - -# exporter.client.create_metric_descriptor.assert_called() -# self.assertEqual( -# exporter.client.create_metric_descriptor.call_count, -# 1) -# md_call_arg =\ -# exporter.client.create_metric_descriptor.call_args[0][1] -# self.assertEqual( -# md_call_arg.metric_kind, -# monitoring_v3.enums.MetricDescriptor.MetricKind.GAUGE -# ) -# self.assertEqual( -# md_call_arg.value_type, -# monitoring_v3.enums.MetricDescriptor.ValueType.INT64 -# ) - -# exporter.client.create_time_series.assert_called() -# self.assertEqual( -# exporter.client.create_time_series.call_count, -# 1) -# ts_call_arg = exporter.client.create_time_series.call_args[0][1] -# self.assertEqual(len(ts_call_arg), 1) -# self.assertEqual(len(ts_call_arg[0].points), 1) -# self.assertEqual(ts_call_arg[0].points[0].value.int64_value, 123) - - -# class TestCreateTimeseries(unittest.TestCase): - -# def setUp(self): -# patcher = mock.patch( -# 'opencensus.ext.stackdriver.stats_exporter.stats.stats', -# stats_module._Stats()) -# patcher.start() -# self.addCleanup(patcher.stop) - -# def check_labels(self, -# actual_labels, -# expected_labels, -# include_opencensus=False): -# actual_labels = dict(actual_labels) -# if include_opencensus: -# opencensus_tag = actual_labels.pop(stackdriver.OPENCENSUS_TASK) -# self.assertIsNotNone(opencensus_tag) -# self.assertIn("py-", opencensus_tag) -# self.assertDictEqual(actual_labels, expected_labels) - -# @mock.patch('opencensus.ext.stackdriver.stats_exporter.' -# 'monitored_resource.get_instance', -# return_value=None) -# def test_create_batched_time_series(self, monitor_resource_mock): -# client = mock.Mock() -# v_data = view_data_module.ViewData( -# view=VIDEO_SIZE_VIEW, -# start_time=TEST_TIME_STR, -# end_time=TEST_TIME_STR) -# v_data.record(context=tag_map_module.TagMap(), value=2, timestamp=None) -# view_data = [v_data] - -# option = stackdriver.Options(project_id="project-test") -# exporter = stackdriver.StackdriverStatsExporter( -# options=option, client=client) - -# view_data = [metric_utils.view_data_to_metric(view_data[0], TEST_TIME)] - -# time_series_batches = exporter.create_batched_time_series(view_data, 1) - -# self.assertEqual(len(time_series_batches), 1) -# [time_series_batch] = time_series_batches -# self.assertEqual(len(time_series_batch), 1) -# [time_series] = time_series_batch -# self.assertEqual( -# time_series.metric.type, -# 'custom.googleapis.com/opencensus/' + VIDEO_SIZE_VIEW_NAME) -# self.check_labels( -# time_series.metric.labels, {}, include_opencensus=True) - -# @mock.patch('opencensus.ext.stackdriver.stats_exporter.' -# 'monitored_resource.get_instance', -# return_value=None) -# def test_create_batched_time_series_with_many(self, monitor_resource_mock): -# client = mock.Mock() - -# # First view with 3 -# view_name1 = "view-name1" -# view1 = view_module.View(view_name1, "test description", ['test'], -# VIDEO_SIZE_MEASURE, -# aggregation_module.LastValueAggregation()) -# v_data1 = view_data_module.ViewData( -# view=view1, start_time=TEST_TIME_STR, end_time=TEST_TIME_STR) -# v_data1.record(context=tag_map_module.TagMap({'test': '1'}), value=7, -# timestamp=None) -# v_data1.record(context=tag_map_module.TagMap({'test': '2'}), value=5, -# timestamp=None) -# v_data1.record(context=tag_map_module.TagMap({'test': '3'}), value=3, -# timestamp=None) - -# # Second view with 2 -# view_name2 = "view-name2" -# view2 = view_module.View(view_name2, "test description", ['test'], -# VIDEO_SIZE_MEASURE, -# aggregation_module.LastValueAggregation()) -# v_data2 = view_data_module.ViewData( -# view=view2, start_time=TEST_TIME_STR, end_time=TEST_TIME_STR) -# v_data2.record(context=tag_map_module.TagMap({'test': '1'}), value=7, -# timestamp=None) -# v_data2.record(context=tag_map_module.TagMap({'test': '2'}), value=5, -# timestamp=None) - -# view_data = [v_data1, v_data2] -# view_data = [metric_utils.view_data_to_metric(vd, TEST_TIME) -# for vd in view_data] - -# option = stackdriver.Options(project_id="project-test") -# exporter = stackdriver.StackdriverStatsExporter( -# options=option, client=client) - -# time_series_batches = exporter.create_batched_time_series(view_data, 2) - -# self.assertEqual(len(time_series_batches), 3) -# [tsb1, tsb2, tsb3] = time_series_batches -# self.assertEqual(len(tsb1), 2) -# self.assertEqual(len(tsb2), 2) -# self.assertEqual(len(tsb3), 1) - -# def setup_create_timeseries_test(self): -# client = mock.Mock() -# execution_context.clear() - -# option = stackdriver.Options( -# project_id="project-test", resource="global") -# exporter = stackdriver.StackdriverStatsExporter( -# options=option, client=client) - -# stats = stats_module.stats -# view_manager = stats.view_manager -# stats_recorder = stats.stats_recorder - -# if len(view_manager.measure_to_view_map.exporters) > 0: -# view_manager.unregister_exporter( -# view_manager.measure_to_view_map.exporters[0]) - -# view_manager.register_exporter(exporter) -# return view_manager, stats_recorder, exporter - -# @mock.patch('opencensus.ext.stackdriver.stats_exporter.' -# 'monitored_resource.get_instance', -# return_value=None) -# def test_create_timeseries(self, monitor_resource_mock): -# view_manager, stats_recorder, exporter = \ -# self.setup_create_timeseries_test() - -# view_manager.register_view(VIDEO_SIZE_VIEW) - -# tag_value = tag_value_module.TagValue("1200") -# tag_map = tag_map_module.TagMap() -# tag_map.insert(FRONTEND_KEY, tag_value) - -# measure_map = stats_recorder.new_measurement_map() -# measure_map.measure_int_put(VIDEO_SIZE_MEASURE, 25 * MiB) -# measure_map.record(tag_map) - -# v_data = measure_map.measure_to_view_map.get_view( -# VIDEO_SIZE_VIEW_NAME, None) - -# v_data = metric_utils.view_data_to_metric(v_data, TEST_TIME) - -# time_series_list = exporter.create_time_series_list(v_data) - -# self.assertEqual(len(time_series_list), 1) -# time_series = time_series_list[0] -# self.assertEqual(time_series.resource.type, "global") -# self.assertEqual( -# time_series_list[0].metric.type, -# "custom.googleapis.com/opencensus/my.org/views/video_size_test2") -# self.check_labels( -# time_series.metric.labels, {FRONTEND_KEY_CLEAN: "1200"}, -# include_opencensus=True) -# self.assertIsNotNone(time_series.resource) - -# self.assertEqual(len(time_series.points), 1) -# value = time_series.points[0].value -# self.assertEqual(value.distribution_value.count, 1) - -# time_series_list = exporter.create_time_series_list(v_data) - -# self.assertEqual(len(time_series_list), 1) -# time_series = time_series_list[0] -# self.check_labels( -# time_series.metric.labels, {FRONTEND_KEY_CLEAN: "1200"}, -# include_opencensus=True) -# self.assertIsNotNone(time_series.resource) - -# self.assertEqual(len(time_series.points), 1) -# value = time_series.points[0].value -# self.assertEqual(value.distribution_value.count, 1) - -# @mock.patch('opencensus.ext.stackdriver.stats_exporter.' -# 'monitored_resource.get_instance') -# def test_create_timeseries_with_resource(self, monitor_resource_mock): - -# client = mock.Mock() -# execution_context.clear() - -# option = stackdriver.Options(project_id="project-test", resource="") -# exporter = stackdriver.StackdriverStatsExporter( -# options=option, client=client) - -# stats = stats_module.stats -# view_manager = stats.view_manager -# stats_recorder = stats.stats_recorder - -# if len(view_manager.measure_to_view_map.exporters) > 0: -# view_manager.unregister_exporter( -# view_manager.measure_to_view_map.exporters[0]) - -# view_manager.register_exporter(exporter) -# view_manager.register_view(VIDEO_SIZE_VIEW) - -# tag_value = tag_value_module.TagValue("1200") -# tag_map = tag_map_module.TagMap() -# tag_map.insert(FRONTEND_KEY, tag_value) - -# measure_map = stats_recorder.new_measurement_map() -# measure_map.measure_int_put(VIDEO_SIZE_MEASURE, 25 * MiB) -# measure_map.record(tag_map) - -# v_data = measure_map.measure_to_view_map.get_view( -# VIDEO_SIZE_VIEW_NAME, None) - -# v_data = metric_utils.view_data_to_metric(v_data, TEST_TIME) - -# # check for gce_instance monitored resource -# mocked_labels = { -# 'instance_id': 'my-instance', -# 'project_id': 'my-project', -# 'zone': 'us-east1', -# 'k8s.io/pod/name': 'localhost', -# 'k8s.io/namespace/name': 'namespace', -# } - -# mock_resource = mock.Mock() -# mock_resource.get_type.return_value = 'gce_instance' -# mock_resource.get_labels.return_value = mocked_labels -# monitor_resource_mock.return_value = mock_resource - -# time_series_list = exporter.create_time_series_list(v_data) -# self.assertEqual(len(time_series_list), 1) -# time_series = time_series_list[0] -# self.assertEqual(time_series.resource.type, "gce_instance") -# self.check_labels( -# time_series.resource.labels, { -# 'instance_id': 'my-instance', -# 'project_id': 'my-project', -# 'zone': 'us-east1', -# }) -# self.assertEqual( -# time_series.metric.type, -# "custom.googleapis.com/opencensus/my.org/views/video_size_test2") -# self.assertIsNotNone(time_series) - -# time_series_list = exporter.create_time_series_list(v_data) -# self.assertEqual(len(time_series_list), 1) -# time_series = time_series_list[0] - -# self.assertEqual( -# time_series.metric.type, -# "custom.googleapis.com/opencensus/my.org/views/video_size_test2") - -# # check for k8s_container monitored resource -# mocked_labels = { -# 'instance_id': 'my-instance', -# 'project_id': 'my-project', -# 'zone': 'us-east1', -# 'k8s.io/pod/name': 'localhost', -# 'k8s.io/cluster/name': 'cluster', -# 'k8s.io/namespace/name': 'namespace', -# } - -# mock_resource = mock.Mock() -# mock_resource.get_type.return_value = 'k8s_container' -# mock_resource.get_labels.return_value = mocked_labels -# monitor_resource_mock.return_value = mock_resource - -# time_series_list = exporter.create_time_series_list(v_data) -# self.assertEqual(len(time_series_list), 1) -# time_series = time_series_list[0] -# self.assertEqual(time_series.resource.type, "k8s_container") -# self.check_labels( -# time_series.resource.labels, { -# 'project_id': 'my-project', -# 'location': 'us-east1', -# 'cluster_name': 'cluster', -# 'pod_name': 'localhost', -# 'namespace_name': 'namespace', -# }) -# self.assertEqual( -# time_series.metric.type, -# "custom.googleapis.com/opencensus/my.org/views/video_size_test2") -# self.assertIsNotNone(time_series) - -# # check for aws_ec2_instance monitored resource -# mocked_labels = { -# 'instance_id': 'my-instance', -# 'aws_account': 'my-project', -# 'region': 'us-east1', -# } - -# mock_resource = mock.Mock() -# mock_resource.get_type.return_value = 'aws_ec2_instance' -# mock_resource.get_labels.return_value = mocked_labels -# monitor_resource_mock.return_value = mock_resource - -# time_series_list = exporter.create_time_series_list(v_data) -# self.assertEqual(len(time_series_list), 1) -# time_series = time_series_list[0] -# self.assertEqual(time_series.resource.type, "aws_ec2_instance") -# self.check_labels( -# time_series.resource.labels, { -# 'instance_id': 'my-instance', -# 'aws_account': 'my-project', -# 'region': 'aws:us-east1', -# }) -# self.assertEqual( -# time_series.metric.type, -# "custom.googleapis.com/opencensus/my.org/views/video_size_test2") -# self.assertIsNotNone(time_series) - -# # check for out of box monitored resource -# mock_resource = mock.Mock() -# mock_resource.get_type.return_value = '' -# mock_resource.get_labels.return_value = mock.Mock() -# monitor_resource_mock.return_value = mock_resource - -# time_series_list = exporter.create_time_series_list(v_data) -# self.assertEqual(len(time_series_list), 1) -# time_series = time_series_list[0] -# self.assertEqual(time_series.resource.type, 'global') -# self.check_labels(time_series.resource.labels, {}) -# self.assertEqual( -# time_series.metric.type, -# "custom.googleapis.com/opencensus/my.org/views/video_size_test2") -# self.assertIsNotNone(time_series) - -# @mock.patch('opencensus.ext.stackdriver.stats_exporter.' -# 'monitored_resource.get_instance', -# return_value=None) -# def test_create_timeseries_str_tagvalue(self, monitor_resource_mock): -# view_manager, stats_recorder, exporter = \ -# self.setup_create_timeseries_test() - -# agg_1 = aggregation_module.LastValueAggregation(value=2) -# view_name1 = "view-name1" -# new_view1 = view_module.View( -# view_name1, "processed video size over time", [FRONTEND_KEY_INT], -# VIDEO_SIZE_MEASURE_2, agg_1) - -# view_manager.register_view(new_view1) - -# tag_value_int = tag_value_module.TagValue("Abc") -# tag_map = tag_map_module.TagMap() -# tag_map.insert(FRONTEND_KEY_INT, tag_value_int) - -# measure_map = stats_recorder.new_measurement_map() -# measure_map.measure_int_put(VIDEO_SIZE_MEASURE_2, 25 * MiB) -# measure_map.record(tag_map) - -# v_data = measure_map.measure_to_view_map.get_view(view_name1, None) - -# v_data = metric_utils.view_data_to_metric(v_data, TEST_TIME) - -# time_series_list = exporter.create_time_series_list(v_data) -# self.assertEqual(len(time_series_list), 1) -# time_series = time_series_list[0] - -# self.check_labels( -# time_series.metric.labels, {FRONTEND_KEY_INT_CLEAN: "Abc"}, -# include_opencensus=True) -# self.assertIsNotNone(time_series.resource) - -# self.assertEqual(len(time_series.points), 1) -# expected_value = monitoring_v3.types.TypedValue() -# # TODO: #565 -# expected_value.double_value = 25.0 * MiB -# self.assertEqual(time_series.points[0].value, expected_value) - -# @mock.patch('opencensus.ext.stackdriver.stats_exporter.' -# 'monitored_resource.get_instance', -# return_value=None) -# def test_create_timeseries_str_tagvalue_count_aggregtation( -# self, monitor_resource_mock): -# view_manager, stats_recorder, exporter = \ -# self.setup_create_timeseries_test() - -# agg_1 = aggregation_module.CountAggregation(count=2) -# view_name1 = "view-name1" -# new_view1 = view_module.View( -# view_name1, "processed video size over time", [FRONTEND_KEY_INT], -# VIDEO_SIZE_MEASURE_2, agg_1) - -# view_manager.register_view(new_view1) - -# tag_value_int = tag_value_module.TagValue("Abc") -# tag_map = tag_map_module.TagMap() -# tag_map.insert(FRONTEND_KEY_INT, tag_value_int) - -# measure_map = stats_recorder.new_measurement_map() -# measure_map.measure_int_put(VIDEO_SIZE_MEASURE_2, 25 * MiB) -# measure_map.record(tag_map) - -# v_data = measure_map.measure_to_view_map.get_view(view_name1, None) - -# v_data = metric_utils.view_data_to_metric(v_data, TEST_TIME) - -# time_series_list = exporter.create_time_series_list(v_data) -# self.assertEqual(len(time_series_list), 1) -# time_series = time_series_list[0] -# self.check_labels( -# time_series.metric.labels, {FRONTEND_KEY_INT_CLEAN: "Abc"}, -# include_opencensus=True) -# self.assertIsNotNone(time_series.resource) - -# self.assertEqual(len(time_series.points), 1) -# expected_value = monitoring_v3.types.TypedValue() -# expected_value.int64_value = 3 -# self.assertEqual(time_series.points[0].value, expected_value) - -# @mock.patch('opencensus.ext.stackdriver.stats_exporter.' -# 'monitored_resource.get_instance', -# return_value=None) -# def test_create_timeseries_last_value_float_tagvalue( -# self, monitor_resource_mock): -# view_manager, stats_recorder, exporter = \ -# self.setup_create_timeseries_test() - -# agg_2 = aggregation_module.LastValueAggregation(value=2.2 * MiB) -# view_name2 = "view-name2" -# new_view2 = view_module.View( -# view_name2, "processed video size over time", [FRONTEND_KEY_FLOAT], -# VIDEO_SIZE_MEASURE_FLOAT, agg_2) - -# view_manager.register_view(new_view2) - -# tag_value_float = tag_value_module.TagValue("Abc") -# tag_map = tag_map_module.TagMap() -# tag_map.insert(FRONTEND_KEY_FLOAT, tag_value_float) - -# measure_map = stats_recorder.new_measurement_map() -# measure_map.measure_float_put(VIDEO_SIZE_MEASURE_FLOAT, 25.7 * MiB) -# measure_map.record(tag_map) - -# v_data = measure_map.measure_to_view_map.get_view(view_name2, None) - -# v_data = metric_utils.view_data_to_metric(v_data, TEST_TIME) - -# time_series_list = exporter.create_time_series_list(v_data) -# self.assertEqual(len(time_series_list), 1) -# time_series = time_series_list[0] -# self.check_labels( -# time_series.metric.labels, {FRONTEND_KEY_FLOAT_CLEAN: "Abc"}, -# include_opencensus=True) -# self.assertIsNotNone(time_series.resource) - -# self.assertEqual(len(time_series.points), 1) -# expected_value = monitoring_v3.types.TypedValue() -# expected_value.double_value = 25.7 * MiB -# self.assertEqual(time_series.points[0].value, expected_value) - -# @mock.patch('opencensus.ext.stackdriver.stats_exporter.' -# 'monitored_resource.get_instance', -# return_value=None) -# def test_create_timeseries_float_tagvalue(self, monitor_resource_mock): -# client = mock.Mock() - -# option = stackdriver.Options( -# project_id="project-test", resource="global") -# exporter = stackdriver.StackdriverStatsExporter( -# options=option, client=client) - -# stats = stats_module.stats -# view_manager = stats.view_manager -# stats_recorder = stats.stats_recorder - -# if len(view_manager.measure_to_view_map.exporters) > 0: -# view_manager.unregister_exporter( -# view_manager.measure_to_view_map.exporters[0]) - -# view_manager.register_exporter(exporter) - -# agg_3 = aggregation_module.SumAggregation(sum=2.2) -# view_name3 = "view-name3" -# new_view3 = view_module.View( -# view_name3, "processed video size over time", [FRONTEND_KEY_FLOAT], -# VIDEO_SIZE_MEASURE_FLOAT, agg_3) - -# view_manager.register_view(new_view3) - -# tag_value_float = tag_value_module.TagValue("1200") -# tag_map = tag_map_module.TagMap() -# tag_map.insert(FRONTEND_KEY_FLOAT, tag_value_float) - -# measure_map = stats_recorder.new_measurement_map() -# measure_map.measure_float_put(VIDEO_SIZE_MEASURE_FLOAT, 25 * MiB) -# measure_map.record(tag_map) - -# v_data = measure_map.measure_to_view_map.get_view(view_name3, None) - -# v_data = metric_utils.view_data_to_metric(v_data, TEST_TIME) - -# time_series_list = exporter.create_time_series_list(v_data) -# self.assertEqual(len(time_series_list), 1) -# [time_series] = time_series_list -# self.assertEqual(time_series.metric.type, -# "custom.googleapis.com/opencensus/view-name3") -# self.check_labels( -# time_series.metric.labels, {FRONTEND_KEY_FLOAT_CLEAN: "1200"}, -# include_opencensus=True) -# self.assertIsNotNone(time_series.resource) - -# self.assertEqual(len(time_series.points), 1) -# expected_value = monitoring_v3.types.TypedValue() -# expected_value.double_value = 2.2 + 25 * MiB -# self.assertEqual(time_series.points[0].value, expected_value) - -# @mock.patch('opencensus.ext.stackdriver.stats_exporter.' -# 'monitored_resource.get_instance', -# return_value=None) -# def test_create_timeseries_multiple_tag_values(self, -# monitoring_resoure_mock): -# view_manager, stats_recorder, exporter = \ -# self.setup_create_timeseries_test() - -# view_manager.register_view(VIDEO_SIZE_VIEW) - -# measure_map = stats_recorder.new_measurement_map() - -# # Add first point with one tag value -# tag_map = tag_map_module.TagMap() -# tag_map.insert(FRONTEND_KEY, tag_value_module.TagValue("1200")) -# measure_map.measure_int_put(VIDEO_SIZE_MEASURE, 25 * MiB) -# measure_map.record(tag_map) - -# # Add second point with different tag value -# tag_map = tag_map_module.TagMap() -# tag_map.insert(FRONTEND_KEY, tag_value_module.TagValue("1400")) -# measure_map.measure_int_put(VIDEO_SIZE_MEASURE, 12 * MiB) -# measure_map.record(tag_map) - -# v_data = measure_map.measure_to_view_map.get_view( -# VIDEO_SIZE_VIEW_NAME, None) - -# v_data = metric_utils.view_data_to_metric(v_data, TEST_TIME) - -# time_series_list = exporter.create_time_series_list(v_data) - -# self.assertEqual(len(time_series_list), 2) -# ts_by_frontend = { -# ts.metric.labels.get(FRONTEND_KEY_CLEAN): ts -# for ts in time_series_list -# } -# self.assertEqual(set(ts_by_frontend.keys()), {"1200", "1400"}) -# ts1 = ts_by_frontend["1200"] -# ts2 = ts_by_frontend["1400"] - -# # Verify first time series -# self.assertEqual(ts1.resource.type, "global") -# self.assertEqual( -# ts1.metric.type, -# "custom.googleapis.com/opencensus/my.org/views/video_size_test2") -# self.assertIsNotNone(ts1.resource) - -# self.assertEqual(len(ts1.points), 1) -# value1 = ts1.points[0].value -# self.assertEqual(value1.distribution_value.count, 1) - -# # Verify second time series -# self.assertEqual(ts2.resource.type, "global") -# self.assertEqual( -# ts2.metric.type, -# "custom.googleapis.com/opencensus/my.org/views/video_size_test2") -# self.assertIsNotNone(ts2.resource) - -# self.assertEqual(len(ts2.points), 1) -# value2 = ts2.points[0].value -# self.assertEqual(value2.distribution_value.count, 1) - -# @mock.patch('opencensus.ext.stackdriver.stats_exporter.' -# 'monitored_resource.get_instance', -# return_value=None) -# def test_create_timeseries_disjoint_tags(self, monitoring_resoure_mock): -# view_manager, stats_recorder, exporter = \ -# self.setup_create_timeseries_test() - -# # Register view with two tags -# view_name = "view-name" -# view = view_module.View(view_name, "test description", -# [FRONTEND_KEY, FRONTEND_KEY_FLOAT], -# VIDEO_SIZE_MEASURE, -# aggregation_module.SumAggregation()) - -# view_manager.register_view(view) - -# # Add point with one tag in common and one different tag -# measure_map = stats_recorder.new_measurement_map() -# tag_map = tag_map_module.TagMap() -# tag_map.insert(FRONTEND_KEY, tag_value_module.TagValue("1200")) -# tag_map.insert(FRONTEND_KEY_STR, tag_value_module.TagValue("1800")) -# measure_map.measure_int_put(VIDEO_SIZE_MEASURE, 25 * MiB) -# measure_map.record(tag_map) - -# v_data = measure_map.measure_to_view_map.get_view(view_name, None) - -# v_data = metric_utils.view_data_to_metric(v_data, TEST_TIME) - -# time_series_list = exporter.create_time_series_list(v_data) - -# self.assertEqual(len(time_series_list), 1) -# [time_series] = time_series_list - -# # Verify first time series -# self.assertEqual(time_series.resource.type, "global") -# self.assertEqual(time_series.metric.type, -# "custom.googleapis.com/opencensus/" + view_name) -# self.check_labels( -# time_series.metric.labels, {FRONTEND_KEY_CLEAN: "1200"}, -# include_opencensus=True) -# self.assertIsNotNone(time_series.resource) - -# self.assertEqual(len(time_series.points), 1) -# expected_value = monitoring_v3.types.TypedValue() -# # TODO: #565 -# expected_value.double_value = 25.0 * MiB -# self.assertEqual(time_series.points[0].value, expected_value) - -# def test_create_timeseries_from_distribution(self): -# """Check for explicit 0-bound bucket for SD export.""" -# agg = aggregation_module.DistributionAggregation() - -# view = view_module.View( -# name="example.org/test_view", -# description="example.org/test_view", -# columns=['tag_key'], -# measure=mock.Mock(), -# aggregation=agg, -# ) - -# v_data = view_data_module.ViewData( -# view=view, -# start_time=TEST_TIME_STR, -# end_time=TEST_TIME_STR, -# ) - -# # Aggregation over (10 * range(10)) for buckets [2, 4, 6, 8] -# dad = aggregation_data_module.DistributionAggregationData( -# mean_data=4.5, -# count_data=100, -# sum_of_sqd_deviations=825, -# counts_per_bucket=[20, 20, 20, 20, 20], -# bounds=[2, 4, 6, 8], -# exemplars={mock.Mock() for ii in range(5)} -# ) -# v_data._tag_value_aggregation_data_map = {('tag_value',): dad} - -# v_data = metric_utils.view_data_to_metric(v_data, TEST_TIME) - -# exporter = stackdriver.StackdriverStatsExporter() -# time_series_list = exporter.create_time_series_list(v_data) -# self.assertEqual(len(time_series_list), 1) -# [time_series] = time_series_list - -# self.check_labels( -# time_series.metric.labels, {'tag_key': 'tag_value'}, -# include_opencensus=True) -# self.assertEqual(len(time_series.points), 1) -# [point] = time_series.points -# dv = point.value.distribution_value -# self.assertEqual(100, dv.count) -# self.assertEqual(825.0, dv.sum_of_squared_deviation) -# self.assertEqual([0, 20, 20, 20, 20, 20], dv.bucket_counts) -# self.assertEqual([0, 2, 4, 6, 8], -# dv.bucket_options.explicit_buckets.bounds) - -# def test_create_timeseries_multiple_tags(self): -# """Check that exporter creates timeseries for multiple tag values. - -# create_time_series_list should return a time series for each set of -# values in the tag value aggregation map. -# """ -# agg = aggregation_module.CountAggregation() - -# view = view_module.View( -# name="example.org/test_view", -# description="example.org/test_view", -# columns=[tag_key_module.TagKey('color'), -# tag_key_module.TagKey('shape')], -# measure=mock.Mock(), -# aggregation=agg, -# ) - -# v_data = view_data_module.ViewData( -# view=view, -# start_time=TEST_TIME_STR, -# end_time=TEST_TIME_STR, -# ) - -# rs_count = aggregation_data_module.CountAggregationData(10) -# bc_count = aggregation_data_module.CountAggregationData(20) -# v_data._tag_value_aggregation_data_map = { -# ('red', 'square'): rs_count, -# ('blue', 'circle'): bc_count, -# } - -# v_data = metric_utils.view_data_to_metric(v_data, TEST_TIME) - -# exporter = stackdriver.StackdriverStatsExporter() -# time_series_list = exporter.create_time_series_list(v_data) - -# self.assertEqual(len(time_series_list), 2) -# self.assertEqual(len(time_series_list[0].points), 1) -# self.assertEqual(len(time_series_list[1].points), 1) - -# ts_by_color = {ts.metric.labels.get('color'): ts -# for ts in time_series_list} -# rs_ts = ts_by_color['red'] -# bc_ts = ts_by_color['blue'] -# self.assertEqual(rs_ts.metric.labels.get('shape'), 'square') -# self.assertEqual(bc_ts.metric.labels.get('shape'), 'circle') -# self.assertEqual(rs_ts.points[0].value.int64_value, 10) -# self.assertEqual(bc_ts.points[0].value.int64_value, 20) - -# def test_create_timeseries_invalid_aggregation(self): -# v_data = mock.Mock(spec=view_data_module.ViewData) -# v_data.view.name = "example.org/base_view" -# v_data.view.columns = [tag_key_module.TagKey('base_key')] -# v_data.start_time = TEST_TIME_STR -# v_data.end_time = TEST_TIME_STR - -# base_data = None -# v_data.tag_value_aggregation_data_map = { -# (None,): base_data, -# } - -# exporter = stackdriver.StackdriverStatsExporter( -# options=mock.Mock(), -# client=mock.Mock(), -# ) -# self.assertRaises(TypeError, exporter.create_time_series_list, v_data, -# "", "") +# Copyright 2018, OpenCensus 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. + +import unittest +from datetime import datetime + +import google.auth +import mock +from google.cloud import monitoring_v3 + +from opencensus.common import utils +from opencensus.common.version import __version__ +from opencensus.ext.stackdriver import stats_exporter as stackdriver +from opencensus.metrics import label_key, label_value +from opencensus.metrics import transport as transport_module +from opencensus.metrics.export import ( + metric, + metric_descriptor, + point, + time_series, + value, +) +from opencensus.stats import aggregation as aggregation_module +from opencensus.stats import aggregation_data as aggregation_data_module +from opencensus.stats import execution_context +from opencensus.stats import measure as measure_module +from opencensus.stats import metric_utils +from opencensus.stats import stats as stats_module +from opencensus.stats import view as view_module +from opencensus.stats import view_data as view_data_module +from opencensus.tags import tag_key as tag_key_module +from opencensus.tags import tag_map as tag_map_module +from opencensus.tags import tag_value as tag_value_module + +MiB = 1 << 20 +FRONTEND_KEY = tag_key_module.TagKey("my.org/keys/frontend") +FRONTEND_KEY_FLOAT = tag_key_module.TagKey("my.org/keys/frontend-FLOAT") +FRONTEND_KEY_INT = tag_key_module.TagKey("my.org/keys/frontend-INT") +FRONTEND_KEY_STR = tag_key_module.TagKey("my.org/keys/frontend-STR") + +FRONTEND_KEY_CLEAN = "my_org_keys_frontend" +FRONTEND_KEY_FLOAT_CLEAN = "my_org_keys_frontend_FLOAT" +FRONTEND_KEY_INT_CLEAN = "my_org_keys_frontend_INT" +FRONTEND_KEY_STR_CLEAN = "my_org_keys_frontend_STR" + +VIDEO_SIZE_MEASURE = measure_module.MeasureFloat( + "my.org/measure/video_size_test2", "size of processed videos", "By") +VIDEO_SIZE_MEASURE_2 = measure_module.MeasureFloat( + "my.org/measure/video_size_test_2", "size of processed videos", "By") + +VIDEO_SIZE_MEASURE_FLOAT = measure_module.MeasureFloat( + "my.org/measure/video_size_test-float", "size of processed videos-float", + "By") + +VIDEO_SIZE_VIEW_NAME = "my.org/views/video_size_test2" +VIDEO_SIZE_DISTRIBUTION = aggregation_module.DistributionAggregation( + [16.0 * MiB, 256.0 * MiB]) +VIDEO_SIZE_VIEW = view_module.View( + VIDEO_SIZE_VIEW_NAME, "processed video size over time", [FRONTEND_KEY], + VIDEO_SIZE_MEASURE, VIDEO_SIZE_DISTRIBUTION) + +TEST_TIME = datetime(2018, 12, 25, 1, 2, 3, 4) +TEST_TIME_STR = utils.to_iso_str(TEST_TIME) + + +class _Client(object): + def __init__(self, client_info=None): + self.client_info = client_info + + +class TestOptions(unittest.TestCase): + def test_options_blank(self): + options = stackdriver.Options() + + self.assertEqual(options.project_id, "") + self.assertEqual(options.resource, "") + + def test_options_parameters(self): + options = stackdriver.Options( + project_id="project-id", metric_prefix="sample") + self.assertEqual(options.project_id, "project-id") + self.assertEqual(options.metric_prefix, "sample") + + def test_default_monitoring_labels(self): + options = stackdriver.Options(default_monitoring_labels={ + label_key.LabelKey('lk_key', 'lk_desc'): + label_value.LabelValue('lk_value') + }) + + self.assertEqual(len(options.default_monitoring_labels), 1) + [[lk, lv]] = options.default_monitoring_labels.items() + self.assertEqual(lk.key, 'lk_key') + self.assertEqual(lk.description, 'lk_desc') + self.assertEqual(lv.value, 'lk_value') + + def test_default_monitoring_labels_blank(self): + with mock.patch('opencensus.ext.stackdriver.stats_exporter' + '.get_task_value') as mock_gtv: + options = stackdriver.Options() + + mock_gtv.assert_called() + + self.assertEqual(len(options.default_monitoring_labels), 1) + [[lk, lv]] = options.default_monitoring_labels.items() + self.assertEqual(lk.key, stackdriver.OPENCENSUS_TASK) + self.assertEqual(lk.description, + stackdriver.OPENCENSUS_TASK_DESCRIPTION) + self.assertEqual(lv.value, mock_gtv()) + + def test_bad_default_monitoring_labels(self): + with self.assertRaises(AttributeError): + stackdriver.Options( + default_monitoring_labels=[ + 'not a dict' + ]) + + with self.assertRaises(TypeError): + stackdriver.Options( + default_monitoring_labels={ + 'bad key': + label_value.LabelValue('clk_value') + }) + + with self.assertRaises(TypeError): + stackdriver.Options( + default_monitoring_labels={ + label_key.LabelKey('clk_key', 'clk_desc'): + 'bad value' + }) + + +class TestStackdriverStatsExporter(unittest.TestCase): + def test_constructor(self): + exporter = stackdriver.StackdriverStatsExporter() + + self.assertIsNone(exporter.client) + + def test_constructor_param(self): + exporter = stackdriver.StackdriverStatsExporter( + options=stackdriver.Options(project_id=1)) + self.assertEqual(exporter.options.project_id, 1) + + def test_null_options(self): + # Check that we don't suppress auth errors + auth_error = google.auth.exceptions.DefaultCredentialsError + mock_auth_error = mock.Mock() + mock_auth_error.side_effect = auth_error + with mock.patch('opencensus.ext.stackdriver.stats_exporter' + '.google.auth.default', mock_auth_error): + with self.assertRaises(auth_error): + stackdriver.new_stats_exporter() + + # Check that we get the default credentials' project ID + mock_auth_ok = mock.Mock() + mock_auth_ok.return_value = (None, 123) + with mock.patch('opencensus.ext.stackdriver.stats_exporter' + '.google.auth.default', mock_auth_ok): + sdse = stackdriver.new_stats_exporter() + self.assertEqual(sdse.options.project_id, 123) + + # Check that we raise if auth works but the project is empty + mock_auth_no_project = mock.Mock() + mock_auth_no_project.return_value = (None, '') + with mock.patch('opencensus.ext.stackdriver.stats_exporter' + '.google.auth.default', mock_auth_no_project): + with self.assertRaises(ValueError): + stackdriver.new_stats_exporter() + + def test_blank_project(self): + self.assertRaises(ValueError, stackdriver.new_stats_exporter, + stackdriver.Options(project_id="")) + + def test_not_blank_project(self): + patch_client = mock.patch( + ('opencensus.ext.stackdriver.stats_exporter' + '.monitoring_v3.MetricServiceClient'), _Client) + + with patch_client: + exporter_created = stackdriver.new_stats_exporter( + stackdriver.Options(project_id=1)) + + self.assertIsInstance(exporter_created, + stackdriver.StackdriverStatsExporter) + + def test_get_user_agent_slug(self): + self.assertIn(__version__, stackdriver.get_user_agent_slug()) + + def test_client_info_user_agent(self): + """Check that the monitoring client sets a user agent. + + The user agent should include the library version. Note that this + assumes MetricServiceClient calls ClientInfo.to_user_agent to attach + the user agent as metadata to metric service API calls. + """ + patch_client = mock.patch( + 'opencensus.ext.stackdriver.stats_exporter.monitoring_v3' + '.MetricServiceClient', _Client) + + with patch_client: + exporter = stackdriver.new_stats_exporter( + stackdriver.Options(project_id=1)) + + self.assertIn(stackdriver.get_user_agent_slug(), + exporter.client.client_info.to_user_agent()) + + def test_sanitize(self): + # empty + result = stackdriver.sanitize_label("") + self.assertEqual(result, "") + + # all invalid + result = stackdriver.sanitize_label("/*^#$") + self.assertEqual(result, "key_") + + # all valid + result = stackdriver.sanitize_label("abc") + self.assertEqual(result, "abc") + + # mixed + result = stackdriver.sanitize_label("a.b/c") + self.assertEqual(result, "a_b_c") + + # starts with '_' + result = stackdriver.sanitize_label("_abc") + self.assertEqual(result, "key_abc") + + # starts with digit + result = stackdriver.sanitize_label("0abc") + self.assertEqual(result, "key_0abc") + + # too long + result = stackdriver.sanitize_label("0123456789" * 10) + self.assertEqual(len(result), 100) + self.assertEqual(result, "key_" + "0123456789" * 9 + "012345") + + def test_get_task_value(self): + task_value = stackdriver.get_task_value() + self.assertNotEqual(task_value, "") + + def test_namespaced_views(self): + view_name = "view-1" + expected_view_name_namespaced = ( + "custom.googleapis.com/opencensus/{}".format(view_name)) + view_name_namespaced = stackdriver.namespaced_view_name(view_name, "") + self.assertEqual(expected_view_name_namespaced, view_name_namespaced) + + expected_view_name_namespaced = "kubernetes.io/myorg/%s" % view_name + view_name_namespaced = stackdriver.namespaced_view_name( + view_name, "kubernetes.io/myorg") + self.assertEqual(expected_view_name_namespaced, view_name_namespaced) + + def test_stackdriver_register_exporter(self): + stats = stats_module.stats + view_manager = stats.view_manager + + exporter = mock.Mock() + if len(view_manager.measure_to_view_map.exporters) > 0: + view_manager.unregister_exporter( + view_manager.measure_to_view_map.exporters[0]) + view_manager.register_exporter(exporter) + + registered_exporters = len(view_manager.measure_to_view_map.exporters) + + self.assertEqual(registered_exporters, 1) + + @mock.patch('os.getpid', return_value=12345) + @mock.patch( + 'platform.uname', + return_value=('system', 'node', 'release', 'version', 'machine', + 'processor')) + def test_get_task_value_with_hostname(self, mock_uname, mock_pid): + self.assertEqual(stackdriver.get_task_value(), "py-12345@node") + + @mock.patch('os.getpid', return_value=12345) + @mock.patch( + 'platform.uname', + return_value=('system', '', 'release', 'version', 'machine', + 'processor')) + def test_get_task_value_without_hostname(self, mock_uname, mock_pid): + self.assertEqual(stackdriver.get_task_value(), "py-12345@localhost") + + def test_default_default_monitoring_labels(self): + """Check that metrics include OC task label by default.""" + exporter = stackdriver.StackdriverStatsExporter( + options=stackdriver.Options(project_id='project_id'), + client=mock.Mock()) + + lv = label_value.LabelValue('val') + val = value.ValueLong(value=123) + dt = datetime(2019, 3, 20, 21, 34, 0, 537954) + pp = point.Point(value=val, timestamp=dt) + ts = [ + time_series.TimeSeries(label_values=[lv], points=[pp], + start_timestamp=utils.to_iso_str(dt)) + ] + + desc = metric_descriptor.MetricDescriptor( + name='name', + description='description', + unit='unit', + type_=metric_descriptor.MetricDescriptorType.GAUGE_INT64, + label_keys=[label_key.LabelKey('key', 'description')] + ) + mm = metric.Metric(descriptor=desc, time_series=ts) + + sd_md = exporter.get_metric_descriptor(desc) + self.assertEqual(len(sd_md.labels), 2) + sd_descriptors = {ld.key: ld.description for ld in sd_md.labels} + self.assertIn('key', sd_descriptors) + self.assertEqual(sd_descriptors['key'], 'description') + self.assertIn(stackdriver.OPENCENSUS_TASK, sd_descriptors) + self.assertEqual( + sd_descriptors[stackdriver.OPENCENSUS_TASK], + stackdriver.OPENCENSUS_TASK_DESCRIPTION + ) + + sd_ts_list = exporter.create_time_series_list(mm) + self.assertEqual(len(sd_ts_list), 1) + [sd_ts] = sd_ts_list + self.assertIn('key', sd_ts.metric.labels) + self.assertEqual(sd_ts.metric.labels['key'], 'val') + self.assertIn(stackdriver.OPENCENSUS_TASK, sd_ts.metric.labels) + + def test_empty_default_monitoring_labels(self): + """Check that it's possible to remove the default OC task label.""" + exporter = stackdriver.StackdriverStatsExporter( + options=stackdriver.Options( + project_id='project_id', + default_monitoring_labels={}), + client=mock.Mock()) + + lv = label_value.LabelValue('val') + val = value.ValueLong(value=123) + dt = datetime(2019, 3, 20, 21, 34, 0, 537954) + pp = point.Point(value=val, timestamp=dt) + ts = [ + time_series.TimeSeries(label_values=[lv], points=[pp], + start_timestamp=utils.to_iso_str(dt)) + ] + + desc = metric_descriptor.MetricDescriptor( + name='name', + description='description', + unit='unit', + type_=metric_descriptor.MetricDescriptorType.GAUGE_INT64, + label_keys=[label_key.LabelKey('key', 'description')] + ) + mm = metric.Metric(descriptor=desc, time_series=ts) + + sd_md = exporter.get_metric_descriptor(desc) + self.assertEqual(len(sd_md.labels), 1) + [sd_label] = sd_md.labels + self.assertEqual(sd_label.key, 'key') + self.assertEqual(sd_label.description, 'description') + + sd_ts_list = exporter.create_time_series_list(mm) + self.assertEqual(len(sd_ts_list), 1) + [sd_ts] = sd_ts_list + self.assertIn('key', sd_ts.metric.labels) + self.assertEqual(sd_ts.metric.labels['key'], 'val') + self.assertNotIn(stackdriver.OPENCENSUS_TASK, sd_ts.metric.labels) + + def test_custom_default_monitoring_labels(self): + """Check that custom labels are exported and included in descriptor.""" + exporter = stackdriver.StackdriverStatsExporter( + options=stackdriver.Options( + project_id='project_id', + default_monitoring_labels={ + label_key.LabelKey('clk_key', 'clk_desc'): + label_value.LabelValue('clk_value') + }), + client=mock.Mock()) + + lv = label_value.LabelValue('val') + val = value.ValueLong(value=123) + dt = datetime(2019, 3, 20, 21, 34, 0, 537954) + pp = point.Point(value=val, timestamp=dt) + ts = [ + time_series.TimeSeries(label_values=[lv], points=[pp], + start_timestamp=utils.to_iso_str(dt)) + ] + + desc = metric_descriptor.MetricDescriptor( + name='name', + description='description', + unit='unit', + type_=metric_descriptor.MetricDescriptorType.GAUGE_INT64, + label_keys=[label_key.LabelKey('key', 'description')] + ) + mm = metric.Metric(descriptor=desc, time_series=ts) + + sd_md = exporter.get_metric_descriptor(desc) + self.assertEqual(len(sd_md.labels), 2) + sd_descriptors = {ld.key: ld.description for ld in sd_md.labels} + self.assertIn('key', sd_descriptors) + self.assertEqual(sd_descriptors['key'], 'description') + self.assertIn('clk_key', sd_descriptors) + self.assertEqual(sd_descriptors['clk_key'], 'clk_desc') + + sd_ts_list = exporter.create_time_series_list(mm) + self.assertEqual(len(sd_ts_list), 1) + [sd_ts] = sd_ts_list + self.assertIn('key', sd_ts.metric.labels) + self.assertEqual(sd_ts.metric.labels['key'], 'val') + self.assertIn('clk_key', sd_ts.metric.labels) + self.assertEqual(sd_ts.metric.labels['clk_key'], 'clk_value') + + def test_get_metric_descriptor(self): + exporter = stackdriver.StackdriverStatsExporter( + options=stackdriver.Options( + project_id='project_id'), + client=mock.Mock()) + + oc_md = metric_descriptor.MetricDescriptor( + name='name', + description='description', + unit='unit', + type_=metric_descriptor.MetricDescriptorType.GAUGE_INT64, + label_keys=[label_key.LabelKey('ck', 'cd')] + ) + + sd_md = exporter.get_metric_descriptor(oc_md) + self.assertEqual( + sd_md.metric_kind, + monitoring_v3.enums.MetricDescriptor.MetricKind.GAUGE) + self.assertEqual( + sd_md.value_type, + monitoring_v3.enums.MetricDescriptor.ValueType.INT64) + + self.assertIsInstance(sd_md, monitoring_v3.types.MetricDescriptor) + exporter.client.create_metric_descriptor.assert_not_called() + + def test_get_metric_descriptor_bad_type(self): + exporter = stackdriver.StackdriverStatsExporter( + options=stackdriver.Options(project_id='project_id'), + client=mock.Mock()) + + bad_type_oc_md = metric_descriptor.MetricDescriptor( + name='name', + description='description', + unit='unit', + # Need a valid type to create the descriptor + type_=metric_descriptor.MetricDescriptorType.GAUGE_INT64, + label_keys=[label_key.LabelKey('key', 'description')] + ) + bad_type_oc_md._type = 100 + + with self.assertRaises(TypeError): + exporter.get_metric_descriptor(bad_type_oc_md) + + def test_get_metric_descriptor_custom_prefix(self): + + exporter = stackdriver.StackdriverStatsExporter( + options=stackdriver.Options( + metric_prefix='metric_prefix', + project_id='project_id'), + client=mock.Mock()) + + oc_md = metric_descriptor.MetricDescriptor( + name='name', + description='description', + unit='unit', + type_=metric_descriptor.MetricDescriptorType.GAUGE_INT64, + label_keys=[label_key.LabelKey('ck', 'cd')] + ) + + sd_md = exporter.get_metric_descriptor(oc_md) + self.assertIn('metric_prefix', sd_md.type) + self.assertIn('metric_prefix', sd_md.name) + + def test_register_metric_descriptor(self): + exporter = stackdriver.StackdriverStatsExporter( + options=stackdriver.Options( + metric_prefix='metric_prefix', + project_id='project_id'), + client=mock.Mock()) + + oc_md = metric_descriptor.MetricDescriptor( + name='name', + description='description', + unit='unit', + type_=metric_descriptor.MetricDescriptorType.GAUGE_INT64, + label_keys=[label_key.LabelKey('key', 'description')] + ) + + exporter.register_metric_descriptor(oc_md) + self.assertEqual( + exporter.client.create_metric_descriptor.call_count, + 1 + ) + exporter.register_metric_descriptor(oc_md) + self.assertEqual( + exporter.client.create_metric_descriptor.call_count, + 1 + ) + + def test_export_metrics(self): + lv = label_value.LabelValue('val') + val = value.ValueLong(value=123) + dt = datetime(2019, 3, 20, 21, 34, 0, 537954) + pp = point.Point(value=val, timestamp=dt) + + ts = [ + time_series.TimeSeries(label_values=[lv], points=[pp], + start_timestamp=utils.to_iso_str(dt)) + ] + + desc = metric_descriptor.MetricDescriptor( + name='name', + description='description', + unit='unit', + type_=metric_descriptor.MetricDescriptorType.GAUGE_INT64, + label_keys=[label_key.LabelKey('key', 'description')] + ) + + mm = metric.Metric(descriptor=desc, time_series=ts) + + exporter = stackdriver.StackdriverStatsExporter(client=mock.Mock()) + exporter.export_metrics([mm]) + + self.assertEqual(exporter.client.create_time_series.call_count, 1) + sd_args = exporter.client.create_time_series.call_args[0][1] + self.assertEqual(len(sd_args), 1) + [sd_arg] = exporter.client.create_time_series.call_args[0][1] + self.assertEqual(sd_arg.points[0].value.int64_value, 123) + + +class MockPeriodicMetricTask(object): + """Testing mock of metrics.transport.PeriodicMetricTask. + + Simulate calling export asynchronously from another thread synchronously + from this one. + """ + def __init__(self, interval=None, function=None, args=None, kwargs=None): + self.function = function + self.logger = mock.Mock() + self.start = mock.Mock() + self.run = mock.Mock() + + def step(self): + try: + self.function() + except transport_module.TransportError as ex: + self.logger.exception(ex) + self.cancel() + except Exception: + self.logger.exception("Error handling metric export") + + +class MockGetExporterThread(object): + """Intercept calls to get_exporter_thread. + + To get a reference to the running PeriodicMetricTask created by + get_exporter_thread. + """ + def __init__(self): + self.transport = None + + def __enter__(self): + original_func = transport_module.get_exporter_thread + + def get_exporter_thread(*aa, **kw): + self.transport = original_func(*aa, **kw) + + mock_get = mock.Mock() + mock_get.side_effect = get_exporter_thread + self.patcher = mock.patch( + ('opencensus.ext.stackdriver.stats_exporter' + '.transport.get_exporter_thread'), + mock_get) + self.patcher.start() + return self + + def __exit__(self, type, value, traceback): + self.patcher.stop() + + +@mock.patch('opencensus.ext.stackdriver.stats_exporter' + '.monitoring_v3.MetricServiceClient') +@mock.patch('opencensus.ext.stackdriver.stats_exporter' + '.stats.stats') +class TestAsyncStatsExport(unittest.TestCase): + """Check that metrics are exported using the exporter thread.""" + + def setUp(self): + patcher = mock.patch( + 'opencensus.metrics.transport.PeriodicMetricTask', + MockPeriodicMetricTask) + patcher.start() + self.addCleanup(patcher.stop) + + def test_export_empty(self, mock_stats, mock_client): + """Check that we don't attempt to export empty metric sets.""" + + mock_stats.get_metrics.return_value = [] + + with MockGetExporterThread() as mget: + exporter = stackdriver.new_stats_exporter( + stackdriver.Options(project_id=1)) + mget.transport.step() + + exporter.client.create_metric_descriptor.assert_not_called() + exporter.client.create_time_series.assert_not_called() + + def test_export_single_metric(self, mock_stats, mock_client): + """Check that we can export a set of a single metric.""" + + lv = label_value.LabelValue('val') + val = value.ValueLong(value=123) + dt = datetime(2019, 3, 20, 21, 34, 0, 537954) + pp = point.Point(value=val, timestamp=dt) + + ts = [ + time_series.TimeSeries(label_values=[lv], points=[pp], + start_timestamp=utils.to_iso_str(dt)) + ] + + desc = metric_descriptor.MetricDescriptor( + name='name2', + description='description2', + unit='unit2', + type_=metric_descriptor.MetricDescriptorType.GAUGE_INT64, + label_keys=[label_key.LabelKey('key', 'description')] + ) + + mm = metric.Metric(descriptor=desc, time_series=ts) + mock_stats.get_metrics.return_value = [mm] + + with MockGetExporterThread() as mget: + exporter = stackdriver.new_stats_exporter( + stackdriver.Options(project_id=1)) + mget.transport.step() + + exporter.client.create_metric_descriptor.assert_called() + self.assertEqual( + exporter.client.create_metric_descriptor.call_count, + 1) + md_call_arg =\ + exporter.client.create_metric_descriptor.call_args[0][1] + self.assertEqual( + md_call_arg.metric_kind, + monitoring_v3.enums.MetricDescriptor.MetricKind.GAUGE + ) + self.assertEqual( + md_call_arg.value_type, + monitoring_v3.enums.MetricDescriptor.ValueType.INT64 + ) + + exporter.client.create_time_series.assert_called() + self.assertEqual( + exporter.client.create_time_series.call_count, + 1) + ts_call_arg = exporter.client.create_time_series.call_args[0][1] + self.assertEqual(len(ts_call_arg), 1) + self.assertEqual(len(ts_call_arg[0].points), 1) + self.assertEqual(ts_call_arg[0].points[0].value.int64_value, 123) + + +class TestCreateTimeseries(unittest.TestCase): + + def setUp(self): + patcher = mock.patch( + 'opencensus.ext.stackdriver.stats_exporter.stats.stats', + stats_module._Stats()) + patcher.start() + self.addCleanup(patcher.stop) + + def check_labels(self, + actual_labels, + expected_labels, + include_opencensus=False): + actual_labels = dict(actual_labels) + if include_opencensus: + opencensus_tag = actual_labels.pop(stackdriver.OPENCENSUS_TASK) + self.assertIsNotNone(opencensus_tag) + self.assertIn("py-", opencensus_tag) + self.assertDictEqual(actual_labels, expected_labels) + + @mock.patch('opencensus.ext.stackdriver.stats_exporter.' + 'monitored_resource.get_instance', + return_value=None) + def test_create_batched_time_series(self, monitor_resource_mock): + client = mock.Mock() + v_data = view_data_module.ViewData( + view=VIDEO_SIZE_VIEW, + start_time=TEST_TIME_STR, + end_time=TEST_TIME_STR) + v_data.record(context=tag_map_module.TagMap(), value=2, timestamp=None) + view_data = [v_data] + + option = stackdriver.Options(project_id="project-test") + exporter = stackdriver.StackdriverStatsExporter( + options=option, client=client) + + view_data = [metric_utils.view_data_to_metric(view_data[0], TEST_TIME)] + + time_series_batches = exporter.create_batched_time_series(view_data, 1) + + self.assertEqual(len(time_series_batches), 1) + [time_series_batch] = time_series_batches + self.assertEqual(len(time_series_batch), 1) + [time_series] = time_series_batch + self.assertEqual( + time_series.metric.type, + 'custom.googleapis.com/opencensus/' + VIDEO_SIZE_VIEW_NAME) + self.check_labels( + time_series.metric.labels, {}, include_opencensus=True) + + @mock.patch('opencensus.ext.stackdriver.stats_exporter.' + 'monitored_resource.get_instance', + return_value=None) + def test_create_batched_time_series_with_many(self, monitor_resource_mock): + client = mock.Mock() + + # First view with 3 + view_name1 = "view-name1" + view1 = view_module.View(view_name1, "test description", ['test'], + VIDEO_SIZE_MEASURE, + aggregation_module.LastValueAggregation()) + v_data1 = view_data_module.ViewData( + view=view1, start_time=TEST_TIME_STR, end_time=TEST_TIME_STR) + v_data1.record(context=tag_map_module.TagMap({'test': '1'}), value=7, + timestamp=None) + v_data1.record(context=tag_map_module.TagMap({'test': '2'}), value=5, + timestamp=None) + v_data1.record(context=tag_map_module.TagMap({'test': '3'}), value=3, + timestamp=None) + + # Second view with 2 + view_name2 = "view-name2" + view2 = view_module.View(view_name2, "test description", ['test'], + VIDEO_SIZE_MEASURE, + aggregation_module.LastValueAggregation()) + v_data2 = view_data_module.ViewData( + view=view2, start_time=TEST_TIME_STR, end_time=TEST_TIME_STR) + v_data2.record(context=tag_map_module.TagMap({'test': '1'}), value=7, + timestamp=None) + v_data2.record(context=tag_map_module.TagMap({'test': '2'}), value=5, + timestamp=None) + + view_data = [v_data1, v_data2] + view_data = [metric_utils.view_data_to_metric(vd, TEST_TIME) + for vd in view_data] + + option = stackdriver.Options(project_id="project-test") + exporter = stackdriver.StackdriverStatsExporter( + options=option, client=client) + + time_series_batches = exporter.create_batched_time_series(view_data, 2) + + self.assertEqual(len(time_series_batches), 3) + [tsb1, tsb2, tsb3] = time_series_batches + self.assertEqual(len(tsb1), 2) + self.assertEqual(len(tsb2), 2) + self.assertEqual(len(tsb3), 1) + + def setup_create_timeseries_test(self): + client = mock.Mock() + execution_context.clear() + + option = stackdriver.Options( + project_id="project-test", resource="global") + exporter = stackdriver.StackdriverStatsExporter( + options=option, client=client) + + stats = stats_module.stats + view_manager = stats.view_manager + stats_recorder = stats.stats_recorder + + if len(view_manager.measure_to_view_map.exporters) > 0: + view_manager.unregister_exporter( + view_manager.measure_to_view_map.exporters[0]) + + view_manager.register_exporter(exporter) + return view_manager, stats_recorder, exporter + + @mock.patch('opencensus.ext.stackdriver.stats_exporter.' + 'monitored_resource.get_instance', + return_value=None) + def test_create_timeseries(self, monitor_resource_mock): + view_manager, stats_recorder, exporter = \ + self.setup_create_timeseries_test() + + view_manager.register_view(VIDEO_SIZE_VIEW) + + tag_value = tag_value_module.TagValue("1200") + tag_map = tag_map_module.TagMap() + tag_map.insert(FRONTEND_KEY, tag_value) + + measure_map = stats_recorder.new_measurement_map() + measure_map.measure_int_put(VIDEO_SIZE_MEASURE, 25 * MiB) + measure_map.record(tag_map) + + v_data = measure_map.measure_to_view_map.get_view( + VIDEO_SIZE_VIEW_NAME, None) + + v_data = metric_utils.view_data_to_metric(v_data, TEST_TIME) + + time_series_list = exporter.create_time_series_list(v_data) + + self.assertEqual(len(time_series_list), 1) + time_series = time_series_list[0] + self.assertEqual(time_series.resource.type, "global") + self.assertEqual( + time_series_list[0].metric.type, + "custom.googleapis.com/opencensus/my.org/views/video_size_test2") + self.check_labels( + time_series.metric.labels, {FRONTEND_KEY_CLEAN: "1200"}, + include_opencensus=True) + self.assertIsNotNone(time_series.resource) + + self.assertEqual(len(time_series.points), 1) + value = time_series.points[0].value + self.assertEqual(value.distribution_value.count, 1) + + time_series_list = exporter.create_time_series_list(v_data) + + self.assertEqual(len(time_series_list), 1) + time_series = time_series_list[0] + self.check_labels( + time_series.metric.labels, {FRONTEND_KEY_CLEAN: "1200"}, + include_opencensus=True) + self.assertIsNotNone(time_series.resource) + + self.assertEqual(len(time_series.points), 1) + value = time_series.points[0].value + self.assertEqual(value.distribution_value.count, 1) + + @mock.patch('opencensus.ext.stackdriver.stats_exporter.' + 'monitored_resource.get_instance') + def test_create_timeseries_with_resource(self, monitor_resource_mock): + + client = mock.Mock() + execution_context.clear() + + option = stackdriver.Options(project_id="project-test", resource="") + exporter = stackdriver.StackdriverStatsExporter( + options=option, client=client) + + stats = stats_module.stats + view_manager = stats.view_manager + stats_recorder = stats.stats_recorder + + if len(view_manager.measure_to_view_map.exporters) > 0: + view_manager.unregister_exporter( + view_manager.measure_to_view_map.exporters[0]) + + view_manager.register_exporter(exporter) + view_manager.register_view(VIDEO_SIZE_VIEW) + + tag_value = tag_value_module.TagValue("1200") + tag_map = tag_map_module.TagMap() + tag_map.insert(FRONTEND_KEY, tag_value) + + measure_map = stats_recorder.new_measurement_map() + measure_map.measure_int_put(VIDEO_SIZE_MEASURE, 25 * MiB) + measure_map.record(tag_map) + + v_data = measure_map.measure_to_view_map.get_view( + VIDEO_SIZE_VIEW_NAME, None) + + v_data = metric_utils.view_data_to_metric(v_data, TEST_TIME) + + # check for gce_instance monitored resource + mocked_labels = { + 'instance_id': 'my-instance', + 'project_id': 'my-project', + 'zone': 'us-east1', + 'k8s.io/pod/name': 'localhost', + 'k8s.io/namespace/name': 'namespace', + } + + mock_resource = mock.Mock() + mock_resource.get_type.return_value = 'gce_instance' + mock_resource.get_labels.return_value = mocked_labels + monitor_resource_mock.return_value = mock_resource + + time_series_list = exporter.create_time_series_list(v_data) + self.assertEqual(len(time_series_list), 1) + time_series = time_series_list[0] + self.assertEqual(time_series.resource.type, "gce_instance") + self.check_labels( + time_series.resource.labels, { + 'instance_id': 'my-instance', + 'project_id': 'my-project', + 'zone': 'us-east1', + }) + self.assertEqual( + time_series.metric.type, + "custom.googleapis.com/opencensus/my.org/views/video_size_test2") + self.assertIsNotNone(time_series) + + time_series_list = exporter.create_time_series_list(v_data) + self.assertEqual(len(time_series_list), 1) + time_series = time_series_list[0] + + self.assertEqual( + time_series.metric.type, + "custom.googleapis.com/opencensus/my.org/views/video_size_test2") + + # check for k8s_container monitored resource + mocked_labels = { + 'instance_id': 'my-instance', + 'project_id': 'my-project', + 'zone': 'us-east1', + 'k8s.io/pod/name': 'localhost', + 'k8s.io/cluster/name': 'cluster', + 'k8s.io/namespace/name': 'namespace', + } + + mock_resource = mock.Mock() + mock_resource.get_type.return_value = 'k8s_container' + mock_resource.get_labels.return_value = mocked_labels + monitor_resource_mock.return_value = mock_resource + + time_series_list = exporter.create_time_series_list(v_data) + self.assertEqual(len(time_series_list), 1) + time_series = time_series_list[0] + self.assertEqual(time_series.resource.type, "k8s_container") + self.check_labels( + time_series.resource.labels, { + 'project_id': 'my-project', + 'location': 'us-east1', + 'cluster_name': 'cluster', + 'pod_name': 'localhost', + 'namespace_name': 'namespace', + }) + self.assertEqual( + time_series.metric.type, + "custom.googleapis.com/opencensus/my.org/views/video_size_test2") + self.assertIsNotNone(time_series) + + # check for aws_ec2_instance monitored resource + mocked_labels = { + 'instance_id': 'my-instance', + 'aws_account': 'my-project', + 'region': 'us-east1', + } + + mock_resource = mock.Mock() + mock_resource.get_type.return_value = 'aws_ec2_instance' + mock_resource.get_labels.return_value = mocked_labels + monitor_resource_mock.return_value = mock_resource + + time_series_list = exporter.create_time_series_list(v_data) + self.assertEqual(len(time_series_list), 1) + time_series = time_series_list[0] + self.assertEqual(time_series.resource.type, "aws_ec2_instance") + self.check_labels( + time_series.resource.labels, { + 'instance_id': 'my-instance', + 'aws_account': 'my-project', + 'region': 'aws:us-east1', + }) + self.assertEqual( + time_series.metric.type, + "custom.googleapis.com/opencensus/my.org/views/video_size_test2") + self.assertIsNotNone(time_series) + + # check for out of box monitored resource + mock_resource = mock.Mock() + mock_resource.get_type.return_value = '' + mock_resource.get_labels.return_value = mock.Mock() + monitor_resource_mock.return_value = mock_resource + + time_series_list = exporter.create_time_series_list(v_data) + self.assertEqual(len(time_series_list), 1) + time_series = time_series_list[0] + self.assertEqual(time_series.resource.type, 'global') + self.check_labels(time_series.resource.labels, {}) + self.assertEqual( + time_series.metric.type, + "custom.googleapis.com/opencensus/my.org/views/video_size_test2") + self.assertIsNotNone(time_series) + + @mock.patch('opencensus.ext.stackdriver.stats_exporter.' + 'monitored_resource.get_instance', + return_value=None) + def test_create_timeseries_str_tagvalue(self, monitor_resource_mock): + view_manager, stats_recorder, exporter = \ + self.setup_create_timeseries_test() + + agg_1 = aggregation_module.LastValueAggregation(value=2) + view_name1 = "view-name1" + new_view1 = view_module.View( + view_name1, "processed video size over time", [FRONTEND_KEY_INT], + VIDEO_SIZE_MEASURE_2, agg_1) + + view_manager.register_view(new_view1) + + tag_value_int = tag_value_module.TagValue("Abc") + tag_map = tag_map_module.TagMap() + tag_map.insert(FRONTEND_KEY_INT, tag_value_int) + + measure_map = stats_recorder.new_measurement_map() + measure_map.measure_int_put(VIDEO_SIZE_MEASURE_2, 25 * MiB) + measure_map.record(tag_map) + + v_data = measure_map.measure_to_view_map.get_view(view_name1, None) + + v_data = metric_utils.view_data_to_metric(v_data, TEST_TIME) + + time_series_list = exporter.create_time_series_list(v_data) + self.assertEqual(len(time_series_list), 1) + time_series = time_series_list[0] + + self.check_labels( + time_series.metric.labels, {FRONTEND_KEY_INT_CLEAN: "Abc"}, + include_opencensus=True) + self.assertIsNotNone(time_series.resource) + + self.assertEqual(len(time_series.points), 1) + expected_value = monitoring_v3.types.TypedValue() + # TODO: #565 + expected_value.double_value = 25.0 * MiB + self.assertEqual(time_series.points[0].value, expected_value) + + @mock.patch('opencensus.ext.stackdriver.stats_exporter.' + 'monitored_resource.get_instance', + return_value=None) + def test_create_timeseries_str_tagvalue_count_aggregtation( + self, monitor_resource_mock): + view_manager, stats_recorder, exporter = \ + self.setup_create_timeseries_test() + + agg_1 = aggregation_module.CountAggregation(count=2) + view_name1 = "view-name1" + new_view1 = view_module.View( + view_name1, "processed video size over time", [FRONTEND_KEY_INT], + VIDEO_SIZE_MEASURE_2, agg_1) + + view_manager.register_view(new_view1) + + tag_value_int = tag_value_module.TagValue("Abc") + tag_map = tag_map_module.TagMap() + tag_map.insert(FRONTEND_KEY_INT, tag_value_int) + + measure_map = stats_recorder.new_measurement_map() + measure_map.measure_int_put(VIDEO_SIZE_MEASURE_2, 25 * MiB) + measure_map.record(tag_map) + + v_data = measure_map.measure_to_view_map.get_view(view_name1, None) + + v_data = metric_utils.view_data_to_metric(v_data, TEST_TIME) + + time_series_list = exporter.create_time_series_list(v_data) + self.assertEqual(len(time_series_list), 1) + time_series = time_series_list[0] + self.check_labels( + time_series.metric.labels, {FRONTEND_KEY_INT_CLEAN: "Abc"}, + include_opencensus=True) + self.assertIsNotNone(time_series.resource) + + self.assertEqual(len(time_series.points), 1) + expected_value = monitoring_v3.types.TypedValue() + expected_value.int64_value = 3 + self.assertEqual(time_series.points[0].value, expected_value) + + @mock.patch('opencensus.ext.stackdriver.stats_exporter.' + 'monitored_resource.get_instance', + return_value=None) + def test_create_timeseries_last_value_float_tagvalue( + self, monitor_resource_mock): + view_manager, stats_recorder, exporter = \ + self.setup_create_timeseries_test() + + agg_2 = aggregation_module.LastValueAggregation(value=2.2 * MiB) + view_name2 = "view-name2" + new_view2 = view_module.View( + view_name2, "processed video size over time", [FRONTEND_KEY_FLOAT], + VIDEO_SIZE_MEASURE_FLOAT, agg_2) + + view_manager.register_view(new_view2) + + tag_value_float = tag_value_module.TagValue("Abc") + tag_map = tag_map_module.TagMap() + tag_map.insert(FRONTEND_KEY_FLOAT, tag_value_float) + + measure_map = stats_recorder.new_measurement_map() + measure_map.measure_float_put(VIDEO_SIZE_MEASURE_FLOAT, 25.7 * MiB) + measure_map.record(tag_map) + + v_data = measure_map.measure_to_view_map.get_view(view_name2, None) + + v_data = metric_utils.view_data_to_metric(v_data, TEST_TIME) + + time_series_list = exporter.create_time_series_list(v_data) + self.assertEqual(len(time_series_list), 1) + time_series = time_series_list[0] + self.check_labels( + time_series.metric.labels, {FRONTEND_KEY_FLOAT_CLEAN: "Abc"}, + include_opencensus=True) + self.assertIsNotNone(time_series.resource) + + self.assertEqual(len(time_series.points), 1) + expected_value = monitoring_v3.types.TypedValue() + expected_value.double_value = 25.7 * MiB + self.assertEqual(time_series.points[0].value, expected_value) + + @mock.patch('opencensus.ext.stackdriver.stats_exporter.' + 'monitored_resource.get_instance', + return_value=None) + def test_create_timeseries_float_tagvalue(self, monitor_resource_mock): + client = mock.Mock() + + option = stackdriver.Options( + project_id="project-test", resource="global") + exporter = stackdriver.StackdriverStatsExporter( + options=option, client=client) + + stats = stats_module.stats + view_manager = stats.view_manager + stats_recorder = stats.stats_recorder + + if len(view_manager.measure_to_view_map.exporters) > 0: + view_manager.unregister_exporter( + view_manager.measure_to_view_map.exporters[0]) + + view_manager.register_exporter(exporter) + + agg_3 = aggregation_module.SumAggregation(sum=2.2) + view_name3 = "view-name3" + new_view3 = view_module.View( + view_name3, "processed video size over time", [FRONTEND_KEY_FLOAT], + VIDEO_SIZE_MEASURE_FLOAT, agg_3) + + view_manager.register_view(new_view3) + + tag_value_float = tag_value_module.TagValue("1200") + tag_map = tag_map_module.TagMap() + tag_map.insert(FRONTEND_KEY_FLOAT, tag_value_float) + + measure_map = stats_recorder.new_measurement_map() + measure_map.measure_float_put(VIDEO_SIZE_MEASURE_FLOAT, 25 * MiB) + measure_map.record(tag_map) + + v_data = measure_map.measure_to_view_map.get_view(view_name3, None) + + v_data = metric_utils.view_data_to_metric(v_data, TEST_TIME) + + time_series_list = exporter.create_time_series_list(v_data) + self.assertEqual(len(time_series_list), 1) + [time_series] = time_series_list + self.assertEqual(time_series.metric.type, + "custom.googleapis.com/opencensus/view-name3") + self.check_labels( + time_series.metric.labels, {FRONTEND_KEY_FLOAT_CLEAN: "1200"}, + include_opencensus=True) + self.assertIsNotNone(time_series.resource) + + self.assertEqual(len(time_series.points), 1) + expected_value = monitoring_v3.types.TypedValue() + expected_value.double_value = 2.2 + 25 * MiB + self.assertEqual(time_series.points[0].value, expected_value) + + @mock.patch('opencensus.ext.stackdriver.stats_exporter.' + 'monitored_resource.get_instance', + return_value=None) + def test_create_timeseries_multiple_tag_values(self, + monitoring_resoure_mock): + view_manager, stats_recorder, exporter = \ + self.setup_create_timeseries_test() + + view_manager.register_view(VIDEO_SIZE_VIEW) + + measure_map = stats_recorder.new_measurement_map() + + # Add first point with one tag value + tag_map = tag_map_module.TagMap() + tag_map.insert(FRONTEND_KEY, tag_value_module.TagValue("1200")) + measure_map.measure_int_put(VIDEO_SIZE_MEASURE, 25 * MiB) + measure_map.record(tag_map) + + # Add second point with different tag value + tag_map = tag_map_module.TagMap() + tag_map.insert(FRONTEND_KEY, tag_value_module.TagValue("1400")) + measure_map.measure_int_put(VIDEO_SIZE_MEASURE, 12 * MiB) + measure_map.record(tag_map) + + v_data = measure_map.measure_to_view_map.get_view( + VIDEO_SIZE_VIEW_NAME, None) + + v_data = metric_utils.view_data_to_metric(v_data, TEST_TIME) + + time_series_list = exporter.create_time_series_list(v_data) + + self.assertEqual(len(time_series_list), 2) + ts_by_frontend = { + ts.metric.labels.get(FRONTEND_KEY_CLEAN): ts + for ts in time_series_list + } + self.assertEqual(set(ts_by_frontend.keys()), {"1200", "1400"}) + ts1 = ts_by_frontend["1200"] + ts2 = ts_by_frontend["1400"] + + # Verify first time series + self.assertEqual(ts1.resource.type, "global") + self.assertEqual( + ts1.metric.type, + "custom.googleapis.com/opencensus/my.org/views/video_size_test2") + self.assertIsNotNone(ts1.resource) + + self.assertEqual(len(ts1.points), 1) + value1 = ts1.points[0].value + self.assertEqual(value1.distribution_value.count, 1) + + # Verify second time series + self.assertEqual(ts2.resource.type, "global") + self.assertEqual( + ts2.metric.type, + "custom.googleapis.com/opencensus/my.org/views/video_size_test2") + self.assertIsNotNone(ts2.resource) + + self.assertEqual(len(ts2.points), 1) + value2 = ts2.points[0].value + self.assertEqual(value2.distribution_value.count, 1) + + @mock.patch('opencensus.ext.stackdriver.stats_exporter.' + 'monitored_resource.get_instance', + return_value=None) + def test_create_timeseries_disjoint_tags(self, monitoring_resoure_mock): + view_manager, stats_recorder, exporter = \ + self.setup_create_timeseries_test() + + # Register view with two tags + view_name = "view-name" + view = view_module.View(view_name, "test description", + [FRONTEND_KEY, FRONTEND_KEY_FLOAT], + VIDEO_SIZE_MEASURE, + aggregation_module.SumAggregation()) + + view_manager.register_view(view) + + # Add point with one tag in common and one different tag + measure_map = stats_recorder.new_measurement_map() + tag_map = tag_map_module.TagMap() + tag_map.insert(FRONTEND_KEY, tag_value_module.TagValue("1200")) + tag_map.insert(FRONTEND_KEY_STR, tag_value_module.TagValue("1800")) + measure_map.measure_int_put(VIDEO_SIZE_MEASURE, 25 * MiB) + measure_map.record(tag_map) + + v_data = measure_map.measure_to_view_map.get_view(view_name, None) + + v_data = metric_utils.view_data_to_metric(v_data, TEST_TIME) + + time_series_list = exporter.create_time_series_list(v_data) + + self.assertEqual(len(time_series_list), 1) + [time_series] = time_series_list + + # Verify first time series + self.assertEqual(time_series.resource.type, "global") + self.assertEqual(time_series.metric.type, + "custom.googleapis.com/opencensus/" + view_name) + self.check_labels( + time_series.metric.labels, {FRONTEND_KEY_CLEAN: "1200"}, + include_opencensus=True) + self.assertIsNotNone(time_series.resource) + + self.assertEqual(len(time_series.points), 1) + expected_value = monitoring_v3.types.TypedValue() + # TODO: #565 + expected_value.double_value = 25.0 * MiB + self.assertEqual(time_series.points[0].value, expected_value) + + def test_create_timeseries_from_distribution(self): + """Check for explicit 0-bound bucket for SD export.""" + agg = aggregation_module.DistributionAggregation() + + view = view_module.View( + name="example.org/test_view", + description="example.org/test_view", + columns=['tag_key'], + measure=mock.Mock(), + aggregation=agg, + ) + + v_data = view_data_module.ViewData( + view=view, + start_time=TEST_TIME_STR, + end_time=TEST_TIME_STR, + ) + + # Aggregation over (10 * range(10)) for buckets [2, 4, 6, 8] + dad = aggregation_data_module.DistributionAggregationData( + mean_data=4.5, + count_data=100, + sum_of_sqd_deviations=825, + counts_per_bucket=[20, 20, 20, 20, 20], + bounds=[2, 4, 6, 8], + exemplars={mock.Mock() for ii in range(5)} + ) + v_data._tag_value_aggregation_data_map = {('tag_value',): dad} + + v_data = metric_utils.view_data_to_metric(v_data, TEST_TIME) + + exporter = stackdriver.StackdriverStatsExporter() + time_series_list = exporter.create_time_series_list(v_data) + self.assertEqual(len(time_series_list), 1) + [time_series] = time_series_list + + self.check_labels( + time_series.metric.labels, {'tag_key': 'tag_value'}, + include_opencensus=True) + self.assertEqual(len(time_series.points), 1) + [point] = time_series.points + dv = point.value.distribution_value + self.assertEqual(100, dv.count) + self.assertEqual(825.0, dv.sum_of_squared_deviation) + self.assertEqual([0, 20, 20, 20, 20, 20], dv.bucket_counts) + self.assertEqual([0, 2, 4, 6, 8], + dv.bucket_options.explicit_buckets.bounds) + + def test_create_timeseries_multiple_tags(self): + """Check that exporter creates timeseries for multiple tag values. + + create_time_series_list should return a time series for each set of + values in the tag value aggregation map. + """ + agg = aggregation_module.CountAggregation() + + view = view_module.View( + name="example.org/test_view", + description="example.org/test_view", + columns=[tag_key_module.TagKey('color'), + tag_key_module.TagKey('shape')], + measure=mock.Mock(), + aggregation=agg, + ) + + v_data = view_data_module.ViewData( + view=view, + start_time=TEST_TIME_STR, + end_time=TEST_TIME_STR, + ) + + rs_count = aggregation_data_module.CountAggregationData(10) + bc_count = aggregation_data_module.CountAggregationData(20) + v_data._tag_value_aggregation_data_map = { + ('red', 'square'): rs_count, + ('blue', 'circle'): bc_count, + } + + v_data = metric_utils.view_data_to_metric(v_data, TEST_TIME) + + exporter = stackdriver.StackdriverStatsExporter() + time_series_list = exporter.create_time_series_list(v_data) + + self.assertEqual(len(time_series_list), 2) + self.assertEqual(len(time_series_list[0].points), 1) + self.assertEqual(len(time_series_list[1].points), 1) + + ts_by_color = {ts.metric.labels.get('color'): ts + for ts in time_series_list} + rs_ts = ts_by_color['red'] + bc_ts = ts_by_color['blue'] + self.assertEqual(rs_ts.metric.labels.get('shape'), 'square') + self.assertEqual(bc_ts.metric.labels.get('shape'), 'circle') + self.assertEqual(rs_ts.points[0].value.int64_value, 10) + self.assertEqual(bc_ts.points[0].value.int64_value, 20) + + def test_create_timeseries_invalid_aggregation(self): + v_data = mock.Mock(spec=view_data_module.ViewData) + v_data.view.name = "example.org/base_view" + v_data.view.columns = [tag_key_module.TagKey('base_key')] + v_data.start_time = TEST_TIME_STR + v_data.end_time = TEST_TIME_STR + + base_data = None + v_data.tag_value_aggregation_data_map = { + (None,): base_data, + } + + exporter = stackdriver.StackdriverStatsExporter( + options=mock.Mock(), + client=mock.Mock(), + ) + self.assertRaises(TypeError, exporter.create_time_series_list, v_data, + "", "") From f9ae95c800fd61c31337bf1bb9545c91457891a1 Mon Sep 17 00:00:00 2001 From: Aaron Abbott Date: Wed, 24 Jun 2020 17:38:22 +0000 Subject: [PATCH 2/2] pin rsa library at < 4.1 for python 3.4 support --- contrib/opencensus-ext-stackdriver/setup.py | 1 + .../tests/test_stackdriver_exporter.py | 2 +- .../opencensus-ext-stackdriver/tests/test_stackdriver_stats.py | 1 - 3 files changed, 2 insertions(+), 2 deletions(-) diff --git a/contrib/opencensus-ext-stackdriver/setup.py b/contrib/opencensus-ext-stackdriver/setup.py index 7c4c8c926..f87f47ab8 100644 --- a/contrib/opencensus-ext-stackdriver/setup.py +++ b/contrib/opencensus-ext-stackdriver/setup.py @@ -41,6 +41,7 @@ install_requires=[ 'google-cloud-monitoring >= 0.30.0, < 1.0.0', 'google-cloud-trace >= 0.20.0, < 1.0.0', + 'rsa <= 4.0; python_version<="3.4"', 'opencensus >= 0.8.dev0, < 1.0.0', ], extras_require={}, diff --git a/contrib/opencensus-ext-stackdriver/tests/test_stackdriver_exporter.py b/contrib/opencensus-ext-stackdriver/tests/test_stackdriver_exporter.py index 5325a6910..c48e21681 100644 --- a/contrib/opencensus-ext-stackdriver/tests/test_stackdriver_exporter.py +++ b/contrib/opencensus-ext-stackdriver/tests/test_stackdriver_exporter.py @@ -257,7 +257,7 @@ def test_translate_to_stackdriver(self, mr_mock): self.assertEqual(spans, expected_traces) - def test_translate_common_attributes_to_stackdriver_no_map(self): + def test_translate_common_attributes_to_stackdriver_no_attribute_map(self): project_id = 'PROJECT' client = mock.Mock() client.project = project_id diff --git a/contrib/opencensus-ext-stackdriver/tests/test_stackdriver_stats.py b/contrib/opencensus-ext-stackdriver/tests/test_stackdriver_stats.py index 7c82fc592..fd3b517c6 100644 --- a/contrib/opencensus-ext-stackdriver/tests/test_stackdriver_stats.py +++ b/contrib/opencensus-ext-stackdriver/tests/test_stackdriver_stats.py @@ -1,4 +1,3 @@ -# flake8: noqa # Copyright 2018, OpenCensus Authors # # Licensed under the Apache License, Version 2.0 (the "License");