Skip to content

Commit

Permalink
Add error reporting system test (#3348)
Browse files Browse the repository at this point in the history
  • Loading branch information
waprin authored and dhermes committed May 4, 2017
1 parent 520637c commit 336a9f2
Show file tree
Hide file tree
Showing 2 changed files with 145 additions and 0 deletions.
22 changes: 22 additions & 0 deletions error_reporting/nox.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,28 @@ def lint_setup_py(session):
'python', 'setup.py', 'check', '--restructuredtext', '--strict')


@nox.session
@nox.parametrize('python_version', ['2.7', '3.6'])
def system_tests(session, python_version):
"""Run the system test suite."""

# Sanity check: Only run system tests if the environment variable is set.
if not os.environ.get('GOOGLE_APPLICATION_CREDENTIALS', ''):
return

# Run the system tests against latest Python 2 and Python 3 only.
session.interpreter = 'python{}'.format(python_version)

# Install all test dependencies, then install this package into the
# virtualenv's dist-packages.
session.install('mock', 'pytest', *LOCAL_DEPS)
session.install('../test_utils/')
session.install('.')

# Run py.test against the system tests.
session.run('py.test', '-vvv', 'tests/system.py')


@nox.session
def cover(session):
"""Run the final coverage report.
Expand Down
123 changes: 123 additions & 0 deletions error_reporting/tests/system.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
# 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.
wrapped_get_count = RetryResult(is_one)(_get_error_count)

error_count = wrapped_get_count(class_name, Config.CLIENT)
self.assertEqual(error_count, 1)

0 comments on commit 336a9f2

Please sign in to comment.