Skip to content

Commit 32f5336

Browse files
andreamattcursoragent
authored andcommitted
cassandra: complete instruments_any conversion
Co-authored-by: Cursor <cursoragent@cursor.com>
1 parent 6694c2d commit 32f5336

3 files changed

Lines changed: 121 additions & 4 deletions

File tree

instrumentation/opentelemetry-instrumentation-cassandra/pyproject.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,8 @@ dependencies = [
3232
]
3333

3434
[project.optional-dependencies]
35-
instruments = [
35+
instruments = []
36+
instruments-any = [
3637
"cassandra-driver ~= 3.25",
3738
"scylla-driver ~= 3.25",
3839
]

instrumentation/opentelemetry-instrumentation-cassandra/src/opentelemetry/instrumentation/cassandra/__init__.py

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,13 +37,18 @@
3737
---
3838
"""
3939

40+
from importlib.metadata import PackageNotFoundError, distribution
4041
from typing import Collection
4142

4243
import cassandra.cluster
4344
from wrapt import wrap_function_wrapper
4445

4546
from opentelemetry import trace
46-
from opentelemetry.instrumentation.cassandra.package import _instruments
47+
from opentelemetry.instrumentation.cassandra.package import (
48+
_instruments_any,
49+
_instruments_cassandra_driver,
50+
_instruments_scylla_driver,
51+
)
4752
from opentelemetry.instrumentation.cassandra.version import __version__
4853
from opentelemetry.instrumentation.instrumentor import BaseInstrumentor
4954
from opentelemetry.instrumentation.utils import unwrap
@@ -96,7 +101,20 @@ def _traced_execute_async(func, instance, args, kwargs):
96101

97102
class CassandraInstrumentor(BaseInstrumentor):
98103
def instrumentation_dependencies(self) -> Collection[str]:
99-
return _instruments
104+
# Determine if cassandra-driver or scylla-driver is installed
105+
try:
106+
distribution("cassandra-driver")
107+
return (_instruments_cassandra_driver,)
108+
except PackageNotFoundError:
109+
pass
110+
111+
try:
112+
distribution("scylla-driver")
113+
return (_instruments_scylla_driver,)
114+
except PackageNotFoundError:
115+
pass
116+
117+
return _instruments_any
100118

101119
def _instrument(self, **kwargs):
102120
_instrument(

instrumentation/opentelemetry-instrumentation-cassandra/tests/test_cassandra_integration.py

Lines changed: 99 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,20 @@
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
1414

15-
from unittest import mock
15+
from importlib.metadata import PackageNotFoundError
16+
from unittest import TestCase, mock
17+
from unittest.mock import call, patch
1618

1719
import cassandra.cluster
1820
from wrapt import BoundFunctionWrapper
1921

2022
import opentelemetry.instrumentation.cassandra
2123
from opentelemetry import trace as trace_api
2224
from opentelemetry.instrumentation.cassandra import CassandraInstrumentor
25+
from opentelemetry.instrumentation.cassandra.package import (
26+
_instruments_cassandra_driver,
27+
_instruments_scylla_driver,
28+
)
2329
from opentelemetry.sdk import resources
2430
from opentelemetry.test.test_base import TestBase
2531
from opentelemetry.trace import SpanKind
@@ -137,3 +143,95 @@ def test_instrument_connection_no_op_tracer_provider(
137143

138144
spans_list = self.memory_exporter.get_finished_spans()
139145
self.assertEqual(len(spans_list), 0)
146+
147+
148+
class TestCassandraInstrumentationDependencies(TestCase):
149+
@patch("opentelemetry.instrumentation.cassandra.distribution")
150+
def test_instrumentation_dependencies_cassandra_driver_installed(
151+
self, mock_distribution
152+
) -> None:
153+
instrumentation = CassandraInstrumentor()
154+
155+
def _distribution(name):
156+
if name == "cassandra-driver":
157+
return None
158+
raise PackageNotFoundError
159+
160+
mock_distribution.side_effect = _distribution
161+
package_to_instrument = instrumentation.instrumentation_dependencies()
162+
self.assertEqual(mock_distribution.call_count, 1)
163+
self.assertEqual(
164+
mock_distribution.mock_calls,
165+
[
166+
call("cassandra-driver"),
167+
],
168+
)
169+
self.assertEqual(
170+
package_to_instrument, (_instruments_cassandra_driver,)
171+
)
172+
173+
@patch("opentelemetry.instrumentation.cassandra.distribution")
174+
def test_instrumentation_dependencies_scylla_driver_installed(
175+
self, mock_distribution
176+
) -> None:
177+
instrumentation = CassandraInstrumentor()
178+
179+
def _distribution(name):
180+
if name == "scylla-driver":
181+
return None
182+
raise PackageNotFoundError
183+
184+
mock_distribution.side_effect = _distribution
185+
package_to_instrument = instrumentation.instrumentation_dependencies()
186+
self.assertEqual(mock_distribution.call_count, 2)
187+
self.assertEqual(
188+
mock_distribution.mock_calls,
189+
[
190+
call("cassandra-driver"),
191+
call("scylla-driver"),
192+
],
193+
)
194+
self.assertEqual(package_to_instrument, (_instruments_scylla_driver,))
195+
196+
@patch("opentelemetry.instrumentation.cassandra.distribution")
197+
def test_instrumentation_dependencies_both_installed(
198+
self, mock_distribution
199+
) -> None:
200+
instrumentation = CassandraInstrumentor()
201+
202+
def _distribution(name):
203+
return None
204+
205+
mock_distribution.side_effect = _distribution
206+
package_to_instrument = instrumentation.instrumentation_dependencies()
207+
self.assertEqual(mock_distribution.call_count, 1)
208+
self.assertEqual(
209+
mock_distribution.mock_calls, [call("cassandra-driver")]
210+
)
211+
self.assertEqual(
212+
package_to_instrument, (_instruments_cassandra_driver,)
213+
)
214+
215+
@patch("opentelemetry.instrumentation.cassandra.distribution")
216+
def test_instrumentation_dependencies_none_installed(
217+
self, mock_distribution
218+
) -> None:
219+
instrumentation = CassandraInstrumentor()
220+
221+
def _distribution(name):
222+
raise PackageNotFoundError
223+
224+
mock_distribution.side_effect = _distribution
225+
package_to_instrument = instrumentation.instrumentation_dependencies()
226+
self.assertEqual(mock_distribution.call_count, 2)
227+
self.assertEqual(
228+
mock_distribution.mock_calls,
229+
[
230+
call("cassandra-driver"),
231+
call("scylla-driver"),
232+
],
233+
)
234+
self.assertEqual(
235+
package_to_instrument,
236+
(_instruments_cassandra_driver, _instruments_scylla_driver),
237+
)

0 commit comments

Comments
 (0)