Skip to content

Commit

Permalink
bring back support for python2.7
Browse files Browse the repository at this point in the history
  • Loading branch information
cnnradams committed Jul 15, 2020
1 parent 2a07883 commit 70a9012
Show file tree
Hide file tree
Showing 10 changed files with 200 additions and 184 deletions.
2 changes: 1 addition & 1 deletion google/cloud/spanner_v1/_opentelemetry_tracing.py
@@ -1,4 +1,4 @@
# Copyright 2016 Google LLC All rights reserved.
# Copyright 2020 Google LLC All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
Expand Down
6 changes: 4 additions & 2 deletions google/cloud/spanner_v1/session.py
Expand Up @@ -139,9 +139,11 @@ def exists(self):
with trace_call("CloudSpanner.GetSession", self) as span:
try:
api.get_session(self.name, metadata=metadata)
span.set_attribute("session_found", True)
if span:
span.set_attribute("session_found", True)
except NotFound:
span.set_attribute("session_found", False)
if span:
span.set_attribute("session_found", False)
return False

return True
Expand Down
22 changes: 12 additions & 10 deletions noxfile.py
Expand Up @@ -67,10 +67,11 @@ def default(session):
# Install all test dependencies, then install this package in-place.
session.install("mock", "pytest", "pytest-cov")

# Install opentelemetry dependencies
session.install(
"opentelemetry-api", "opentelemetry-sdk", "opentelemetry-instrumentation"
)
# Install opentelemetry dependencies if python3+
if session.python != "2.7":
session.install(
"opentelemetry-api", "opentelemetry-sdk", "opentelemetry-instrumentation"
)

session.install("-e", ".")

Expand All @@ -89,13 +90,13 @@ def default(session):
)


@nox.session(python=["3.5", "3.6", "3.7", "3.8"])
@nox.session(python=["2.7", "3.5", "3.6", "3.7", "3.8"])
def unit(session):
"""Run the unit test suite."""
default(session)


@nox.session(python="3.7")
@nox.session(python=["2.7", "3.7"])
def system(session):
"""Run the system test suite."""
system_test_path = os.path.join("tests", "system.py")
Expand All @@ -121,10 +122,11 @@ def system(session):
# virtualenv's dist-packages.
session.install("mock", "pytest")

# Install opentelemetry dependencies
session.install(
"opentelemetry-api", "opentelemetry-sdk", "opentelemetry-instrumentation"
)
# Install opentelemetry dependencies if not 2.7
if session.python != "2.7":
session.install(
"opentelemetry-api", "opentelemetry-sdk", "opentelemetry-instrumentation"
)

session.install("-e", ".")
session.install("-e", "test_utils/")
Expand Down
54 changes: 33 additions & 21 deletions tests/_helpers.py
@@ -1,35 +1,47 @@
import unittest
from opentelemetry import trace as trace_api
from opentelemetry.trace.status import StatusCanonicalCode
from unittest import mock

from opentelemetry.sdk.trace import TracerProvider, export
from opentelemetry.sdk.trace.export.in_memory_span_exporter import InMemorySpanExporter
try:
from opentelemetry import trace as trace_api
from opentelemetry.trace.status import StatusCanonicalCode

from opentelemetry.sdk.trace import TracerProvider, export
from opentelemetry.sdk.trace.export.in_memory_span_exporter import InMemorySpanExporter

HAS_OPENTELEMETRY_INSTALLED = True
except ImportError:
HAS_OPENTELEMETRY_INSTALLED = False

StatusCanonicalCode = mock.Mock()

class OpenTelemetryBase(unittest.TestCase):
def setUp(self):
self.original_tracer_provider = trace_api.get_tracer_provider()
self.tracer_provider = TracerProvider()
self.memory_exporter = InMemorySpanExporter()
span_processor = export.SimpleExportSpanProcessor(self.memory_exporter)
self.tracer_provider.add_span_processor(span_processor)
trace_api.set_tracer_provider(self.tracer_provider)
if HAS_OPENTELEMETRY_INSTALLED:
self.original_tracer_provider = trace_api.get_tracer_provider()
self.tracer_provider = TracerProvider()
self.memory_exporter = InMemorySpanExporter()
span_processor = export.SimpleExportSpanProcessor(self.memory_exporter)
self.tracer_provider.add_span_processor(span_processor)
trace_api.set_tracer_provider(self.tracer_provider)

def tearDown(self):
trace_api.set_tracer_provider(self.original_tracer_provider)
if HAS_OPENTELEMETRY_INSTALLED:
trace_api.set_tracer_provider(self.original_tracer_provider)

def assertNoSpans(self):
span_list = self.memory_exporter.get_finished_spans()
self.assertEqual(len(span_list), 0)
if HAS_OPENTELEMETRY_INSTALLED:
span_list = self.memory_exporter.get_finished_spans()
self.assertEqual(len(span_list), 0)

def assertSpanAttributes(
self, name, status=StatusCanonicalCode.OK, attributes=None, span=None
):
if not span:
span_list = self.memory_exporter.get_finished_spans()
self.assertEqual(len(span_list), 1)
span = span_list[0]
print(status, attributes, span.status, span.attributes)
self.assertEqual(span.name, name)
self.assertEqual(span.status.canonical_code, status)
self.assertEqual(span.attributes, attributes)
if HAS_OPENTELEMETRY_INSTALLED:
if not span:
span_list = self.memory_exporter.get_finished_spans()
self.assertEqual(len(span_list), 1)
span = span_list[0]

self.assertEqual(span.name, name)
self.assertEqual(span.status.canonical_code, status)
self.assertEqual(span.attributes, attributes)
6 changes: 4 additions & 2 deletions tests/system/test_system.py
Expand Up @@ -1332,8 +1332,10 @@ def test_transaction_batch_update_wo_statements(self):
transaction.batch_update([])

def test_transaction_batch_update_w_parent_span(self):
import sys
from opentelemetry import trace
try:
from opentelemetry import trace
except ImportError:
return

tracer = trace.get_tracer(__name__)

Expand Down
216 changes: 104 additions & 112 deletions tests/unit/test__opentelemetry_tracing.py
Expand Up @@ -3,27 +3,18 @@
import unittest
import sys

from opentelemetry import trace as trace_api
from opentelemetry.trace.status import StatusCanonicalCode
from opentelemetry.sdk.trace import TracerProvider, export
from opentelemetry.sdk.trace.export.in_memory_span_exporter import InMemorySpanExporter
try:
from opentelemetry import trace as trace_api
from opentelemetry.trace.status import StatusCanonicalCode
from opentelemetry.sdk.trace import TracerProvider, export
from opentelemetry.sdk.trace.export.in_memory_span_exporter import InMemorySpanExporter
except ImportError:
pass

from google.api_core.exceptions import GoogleAPICallError
from google.cloud.spanner_v1 import _opentelemetry_tracing


class OpenTelemetryBase(unittest.TestCase):
def setUp(self):
self.original_tracer_provider = trace_api.get_tracer_provider()
self.tracer_provider = TracerProvider()
self.memory_exporter = InMemorySpanExporter()
span_processor = export.SimpleExportSpanProcessor(self.memory_exporter)
self.tracer_provider.add_span_processor(span_processor)
trace_api.set_tracer_provider(self.tracer_provider)

def tearDown(self):
trace_api.set_tracer_provider(self.original_tracer_provider)

from tests._helpers import OpenTelemetryBase, HAS_OPENTELEMETRY_INSTALLED

def _make_rpc_error(error_cls, trailing_metadata=None):
import grpc
Expand All @@ -38,102 +29,103 @@ def _make_session():

return mock.Mock(autospec=Session, instance=True)

# Skip all of these tests if we don't have OpenTelemetry
if HAS_OPENTELEMETRY_INSTALLED:
class TestNoTracing(unittest.TestCase):
def setUp(self):
self._temp_opentelemetry = sys.modules["opentelemetry"]

sys.modules["opentelemetry"] = None
importlib.reload(_opentelemetry_tracing)

def tearDown(self):
sys.modules["opentelemetry"] = self._temp_opentelemetry
importlib.reload(_opentelemetry_tracing)

def test_no_trace_call(self):
with _opentelemetry_tracing.trace_call("Test", _make_session()) as no_span:
self.assertIsNone(no_span)


class TestTracing(OpenTelemetryBase):
def test_trace_call(self):
extra_attributes = {
"attribute1": "value1",
# Since our database is mocked, we have to override the db.instance parameter so it is a string
"db.instance": "database_name",
}

expected_attributes = {
"db.type": "spanner",
"db.url": "spanner.googleapis.com:443",
"net.host.name": "spanner.googleapis.com:443",
}
expected_attributes.update(extra_attributes)

class TestNoTracing(unittest.TestCase):
def setUp(self):
self._temp_opentelemetry = sys.modules["opentelemetry"]

sys.modules["opentelemetry"] = None
importlib.reload(_opentelemetry_tracing)

def tearDown(self):
sys.modules["opentelemetry"] = self._temp_opentelemetry
importlib.reload(_opentelemetry_tracing)

def test_no_trace_call(self):
with _opentelemetry_tracing.trace_call("Test", _make_session()) as no_span:
self.assertIsNone(no_span)


class TestTracing(OpenTelemetryBase):
def test_trace_call(self):
extra_attributes = {
"attribute1": "value1",
# Since our database is mocked, we have to override the db.instance parameter so it is a string
"db.instance": "database_name",
}

expected_attributes = {
"db.type": "spanner",
"db.url": "spanner.googleapis.com:443",
"net.host.name": "spanner.googleapis.com:443",
}
expected_attributes.update(extra_attributes)

with _opentelemetry_tracing.trace_call(
"CloudSpanner.Test", _make_session(), extra_attributes
) as span:
span.set_attribute("after_setup_attribute", 1)

expected_attributes["after_setup_attribute"] = 1

span_list = self.memory_exporter.get_finished_spans()
self.assertEqual(len(span_list), 1)
span = span_list[0]
self.assertEqual(span.kind, trace_api.SpanKind.CLIENT)
self.assertEqual(span.attributes, expected_attributes)
self.assertEqual(span.name, "CloudSpanner.Test")
self.assertEqual(
span.status.canonical_code, trace_api.status.StatusCanonicalCode.OK
)

def test_trace_error(self):
extra_attributes = {"db.instance": "database_name"}

expected_attributes = {
"db.type": "spanner",
"db.url": "spanner.googleapis.com:443",
"net.host.name": "spanner.googleapis.com:443",
}
expected_attributes.update(extra_attributes)

with self.assertRaises(GoogleAPICallError):
with _opentelemetry_tracing.trace_call(
"CloudSpanner.Test", _make_session(), extra_attributes
) as span:
from google.api_core.exceptions import InvalidArgument

raise _make_rpc_error(InvalidArgument)

span_list = self.memory_exporter.get_finished_spans()
self.assertEqual(len(span_list), 1)
span = span_list[0]
self.assertEqual(span.kind, trace_api.SpanKind.CLIENT)
self.assertEqual(span.attributes, expected_attributes)
self.assertEqual(span.name, "CloudSpanner.Test")
self.assertEqual(
span.status.canonical_code, StatusCanonicalCode.INVALID_ARGUMENT
)

def test_trace_grpc_error(self):
extra_attributes = {"db.instance": "database_name"}

expected_attributes = {
"db.type": "spanner",
"db.url": "spanner.googleapis.com:443",
"net.host.name": "spanner.googleapis.com:443",
}
expected_attributes.update(extra_attributes)

with self.assertRaises(GoogleAPICallError):
with _opentelemetry_tracing.trace_call(
"CloudSpanner.Test", _make_session(), extra_attributes
) as span:
from google.api_core.exceptions import DataLoss

raise _make_rpc_error(DataLoss)

span_list = self.memory_exporter.get_finished_spans()
self.assertEqual(len(span_list), 1)
span = span_list[0]
self.assertEqual(span.status.canonical_code, StatusCanonicalCode.DATA_LOSS)
span.set_attribute("after_setup_attribute", 1)

expected_attributes["after_setup_attribute"] = 1

span_list = self.memory_exporter.get_finished_spans()
self.assertEqual(len(span_list), 1)
span = span_list[0]
self.assertEqual(span.kind, trace_api.SpanKind.CLIENT)
self.assertEqual(span.attributes, expected_attributes)
self.assertEqual(span.name, "CloudSpanner.Test")
self.assertEqual(
span.status.canonical_code, trace_api.status.StatusCanonicalCode.OK
)

def test_trace_error(self):
extra_attributes = {"db.instance": "database_name"}

expected_attributes = {
"db.type": "spanner",
"db.url": "spanner.googleapis.com:443",
"net.host.name": "spanner.googleapis.com:443",
}
expected_attributes.update(extra_attributes)

with self.assertRaises(GoogleAPICallError):
with _opentelemetry_tracing.trace_call(
"CloudSpanner.Test", _make_session(), extra_attributes
) as span:
from google.api_core.exceptions import InvalidArgument

raise _make_rpc_error(InvalidArgument)

span_list = self.memory_exporter.get_finished_spans()
self.assertEqual(len(span_list), 1)
span = span_list[0]
self.assertEqual(span.kind, trace_api.SpanKind.CLIENT)
self.assertEqual(span.attributes, expected_attributes)
self.assertEqual(span.name, "CloudSpanner.Test")
self.assertEqual(
span.status.canonical_code, StatusCanonicalCode.INVALID_ARGUMENT
)

def test_trace_grpc_error(self):
extra_attributes = {"db.instance": "database_name"}

expected_attributes = {
"db.type": "spanner",
"db.url": "spanner.googleapis.com:443",
"net.host.name": "spanner.googleapis.com:443",
}
expected_attributes.update(extra_attributes)

with self.assertRaises(GoogleAPICallError):
with _opentelemetry_tracing.trace_call(
"CloudSpanner.Test", _make_session(), extra_attributes
) as span:
from google.api_core.exceptions import DataLoss

raise _make_rpc_error(DataLoss)

span_list = self.memory_exporter.get_finished_spans()
self.assertEqual(len(span_list), 1)
span = span_list[0]
self.assertEqual(span.status.canonical_code, StatusCanonicalCode.DATA_LOSS)
3 changes: 1 addition & 2 deletions tests/unit/test_batch.py
Expand Up @@ -14,8 +14,7 @@


import unittest
from tests._helpers import OpenTelemetryBase
from opentelemetry.trace.status import StatusCanonicalCode
from tests._helpers import OpenTelemetryBase, StatusCanonicalCode

TABLE_NAME = "citizens"
COLUMNS = ["email", "first_name", "last_name", "age"]
Expand Down

0 comments on commit 70a9012

Please sign in to comment.