# Copyright 2017 Google Inc. # # 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 functools import operator import unittest from google.cloud import error_reporting from google.cloud.gapic.errorreporting.v1beta1 import ( error_stats_service_client) from google.cloud.proto.devtools.clouderrorreporting.v1beta1 import ( error_stats_service_pb2) from google.protobuf.duration_pb2 import Duration from test_utils.retry import RetryResult from test_utils.system import unique_resource_id ERROR_MSG = 'Stackdriver Error Reporting System Test' def setUpModule(): Config.CLIENT = error_reporting.Client() class Config(object): """Run-time configuration to be modified at set-up. This is a mutable stand-in to allow test set-up to modify global state. """ CLIENT = None def _list_groups(client): """List Error Groups from the last 60 seconds. This class provides a wrapper around making calls to the GAX API. It's used by the system tests to find the appropriate error group to verify the error was successfully reported. :type client: :class:`~google.cloud.error_reporting.client.Client` :param client: The client containing a project and credentials. :rtype: :class:`~google.gax.ResourceIterator` :returns: Iterable of :class:`~.error_stats_service_pb2.ErrorGroupStats`. """ gax_api = error_stats_service_client.ErrorStatsServiceClient( credentials=client._credentials) project_name = gax_api.project_path(client.project) time_range = error_stats_service_pb2.QueryTimeRange() time_range.period = error_stats_service_pb2.QueryTimeRange.PERIOD_1_HOUR duration = Duration(seconds=60 * 60) return gax_api.list_group_stats( project_name, time_range, timed_count_duration=duration) def _simulate_exception(class_name, client): """Simulates an exception to verify it was reported. :type class_name: str :param class_name: The name of a custom error class to create (and raise). :type client: :class:`~google.cloud.error_reporting.client.Client` :param client: The client that will report the exception. """ custom_exc = type(class_name, (RuntimeError,), {}) try: raise custom_exc(ERROR_MSG) except RuntimeError: client.report_exception() def _get_error_count(class_name, client): """Counts the number of errors in the group of the test exception. :type class_name: str :param class_name: The name of a custom error class used. :type client: :class:`~google.cloud.error_reporting.client.Client` :param client: The client containing a project and credentials. :rtype: int :returns: Group count for errors that match ``class_name``. If no match is found, returns :data:`None`. """ groups = _list_groups(client) for group in groups: if class_name in group.representative.message: return group.count class TestErrorReporting(unittest.TestCase): def test_report_exception(self): # Get a class name unique to this test case. class_name = 'RuntimeError' + unique_resource_id('_') # Simulate an error: group won't exist until we report # first exception. _simulate_exception(class_name, Config.CLIENT) is_one = functools.partial(operator.eq, 1) is_one.__name__ = 'is_one' # partial() has no name. retry = RetryResult(is_one, max_tries=6) wrapped_get_count = retry(_get_error_count) error_count = wrapped_get_count(class_name, Config.CLIENT) self.assertEqual(error_count, 1)