Skip to content

Commit 0c2c470

Browse files
committed
Update pymemcache instrumentation to support pymemcache version >= 1.3.5
1 parent d1f3d51 commit 0c2c470

File tree

6 files changed

+69
-20
lines changed

6 files changed

+69
-20
lines changed

CHANGELOG.md

+5
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
6161
- `opentelemetry-instrumentation-kafka-python` Fix topic extraction
6262
([#949](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/949))
6363

64+
### Changed
65+
66+
- `opentelemetry-instrumentation-pymemcache` should run against newer versions of pymemcache.
67+
([#935](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/935))
68+
6469
## [1.9.1-0.28b1](https://github.com/open-telemetry/opentelemetry-python/releases/tag/v1.9.1-0.28b1) - 2022-01-29
6570

6671
### Fixed

instrumentation/README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
| [opentelemetry-instrumentation-mysql](./opentelemetry-instrumentation-mysql) | mysql-connector-python ~= 8.0 |
2424
| [opentelemetry-instrumentation-pika](./opentelemetry-instrumentation-pika) | pika >= 0.12.0 |
2525
| [opentelemetry-instrumentation-psycopg2](./opentelemetry-instrumentation-psycopg2) | psycopg2 >= 2.7.3.1 |
26-
| [opentelemetry-instrumentation-pymemcache](./opentelemetry-instrumentation-pymemcache) | pymemcache ~= 1.3 |
26+
| [opentelemetry-instrumentation-pymemcache](./opentelemetry-instrumentation-pymemcache) | pymemcache >= 1.3.5, < 4 |
2727
| [opentelemetry-instrumentation-pymongo](./opentelemetry-instrumentation-pymongo) | pymongo >= 3.1, < 5.0 |
2828
| [opentelemetry-instrumentation-pymysql](./opentelemetry-instrumentation-pymysql) | PyMySQL < 2 |
2929
| [opentelemetry-instrumentation-pyramid](./opentelemetry-instrumentation-pyramid) | pyramid >= 1.7 |

instrumentation/opentelemetry-instrumentation-pymemcache/src/opentelemetry/instrumentation/pymemcache/package.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,4 @@
1313
# limitations under the License.
1414

1515

16-
_instruments = ("pymemcache ~= 1.3",)
16+
_instruments = ("pymemcache >= 1.3.5, < 4",)

instrumentation/opentelemetry-instrumentation-pymemcache/tests/test_pymemcache.py

+53-13
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
from unittest import mock
1515

1616
import pymemcache
17+
from packaging import version as get_package_version
18+
from pymemcache import __version__ as pymemcache_package_version
1719
from pymemcache.exceptions import (
1820
MemcacheClientError,
1921
MemcacheIllegalInputError,
@@ -33,6 +35,22 @@
3335
TEST_HOST = "localhost"
3436
TEST_PORT = 117711
3537

38+
pymemcache_version = get_package_version.parse(pymemcache_package_version)
39+
40+
# In pymemcache versions greater than 2, set_multi, set_many and delete_multi
41+
# now use a batched call
42+
# https://github.com/pinterest/pymemcache/blob/master/ChangeLog.rst#new-in-version-200 # noqa
43+
pymemcache_version_lt_2 = pymemcache_version < get_package_version.parse(
44+
"2.0.0"
45+
)
46+
47+
# In pymemcache versions greater than 3.4.1, the stats command no
48+
# longer sends trailing whitespace in the command
49+
# https://github.com/pinterest/pymemcache/blob/master/ChangeLog.rst#new-in-version-342 # noqa
50+
pymemcache_version_gt_341 = pymemcache_version > get_package_version.parse(
51+
"3.4.1"
52+
)
53+
3654

3755
class PymemcacheClientTestCase(
3856
TestBase
@@ -126,11 +144,16 @@ def test_set_multi_success(self):
126144
client = self.make_client([b"STORED\r\n"])
127145
# Alias for set_many, a convienance function that calls set for every key
128146
result = client.set_multi({b"key": b"value"}, noreply=False)
129-
self.assertTrue(result)
130-
131147
spans = self.memory_exporter.get_finished_spans()
132148

133-
self.check_spans(spans, 2, ["set key", "set_multi key"])
149+
# In pymemcache versions greater than 2, set_multi now uses a batched call
150+
# https://github.com/pinterest/pymemcache/blob/master/ChangeLog.rst#new-in-version-200 # noqa
151+
if pymemcache_version_lt_2:
152+
self.assertTrue(result)
153+
self.check_spans(spans, 2, ["set key", "set_multi key"])
154+
else:
155+
assert len(result) == 0
156+
self.check_spans(spans, 1, ["set_multi key"])
134157

135158
def test_delete_not_found(self):
136159
client = self.make_client([b"NOT_FOUND\r\n"])
@@ -191,19 +214,30 @@ def test_delete_many_found(self):
191214

192215
spans = self.memory_exporter.get_finished_spans()
193216

194-
self.check_spans(
195-
spans, 3, ["add key", "delete key", "delete_many key"]
196-
)
217+
# In pymemcache versions greater than 2, delete_many now uses a batched call
218+
# https://github.com/pinterest/pymemcache/blob/master/ChangeLog.rst#new-in-version-200 # noqa
219+
if pymemcache_version_lt_2:
220+
self.check_spans(
221+
spans, 3, ["add key", "delete key", "delete_many key"]
222+
)
223+
else:
224+
self.check_spans(spans, 2, ["add key", "delete_many key"])
197225

198226
def test_set_many_success(self):
199227
client = self.make_client([b"STORED\r\n"])
200228
# a convienance function that calls set for every key
201229
result = client.set_many({b"key": b"value"}, noreply=False)
202-
self.assertTrue(result)
203230

204231
spans = self.memory_exporter.get_finished_spans()
205232

206-
self.check_spans(spans, 2, ["set key", "set_many key"])
233+
# In pymemcache versions greater than 2, set_many now uses a batched call
234+
# https://github.com/pinterest/pymemcache/blob/master/ChangeLog.rst#new-in-version-200 # noqa
235+
if pymemcache_version_lt_2:
236+
self.assertTrue(result)
237+
self.check_spans(spans, 2, ["set key", "set_many key"])
238+
else:
239+
assert len(result) == 0
240+
self.check_spans(spans, 1, ["set_many key"])
207241

208242
def test_set_get(self):
209243
client = self.make_client(
@@ -243,7 +277,7 @@ def test_prepend_stored(self):
243277

244278
def test_cas_stored(self):
245279
client = self.make_client([b"STORED\r\n"])
246-
result = client.cas(b"key", b"value", b"cas", noreply=False)
280+
result = client.cas(b"key", b"value", b"1", noreply=False)
247281
self.assertTrue(result)
248282

249283
spans = self.memory_exporter.get_finished_spans()
@@ -252,7 +286,7 @@ def test_cas_stored(self):
252286

253287
def test_cas_exists(self):
254288
client = self.make_client([b"EXISTS\r\n"])
255-
result = client.cas(b"key", b"value", b"cas", noreply=False)
289+
result = client.cas(b"key", b"value", b"1", noreply=False)
256290
assert result is False
257291

258292
spans = self.memory_exporter.get_finished_spans()
@@ -261,7 +295,7 @@ def test_cas_exists(self):
261295

262296
def test_cas_not_found(self):
263297
client = self.make_client([b"NOT_FOUND\r\n"])
264-
result = client.cas(b"key", b"value", b"cas", noreply=False)
298+
result = client.cas(b"key", b"value", b"1", noreply=False)
265299
assert result is None
266300

267301
spans = self.memory_exporter.get_finished_spans()
@@ -445,7 +479,14 @@ def test_version_success(self):
445479
def test_stats(self):
446480
client = self.make_client([b"STAT fake_stats 1\r\n", b"END\r\n"])
447481
result = client.stats()
448-
assert client.sock.send_bufs == [b"stats \r\n"]
482+
483+
# In pymemcache versions greater than 3.4.1, the stats command no
484+
# longer sends trailing whitespace in the command
485+
# https://github.com/pinterest/pymemcache/blob/master/ChangeLog.rst#new-in-version-342 # noqa
486+
if pymemcache_version_gt_341:
487+
assert client.sock.send_bufs == [b"stats\r\n"]
488+
else:
489+
assert client.sock.send_bufs == [b"stats \r\n"]
449490
assert result == {b"fake_stats": 1}
450491

451492
spans = self.memory_exporter.get_finished_spans()
@@ -544,5 +585,4 @@ def test_delete_many_found(self):
544585
self.assertTrue(result)
545586

546587
spans = self.memory_exporter.get_finished_spans()
547-
548588
self.check_spans(spans, 2, ["add key", "delete key"])

opentelemetry-instrumentation/src/opentelemetry/instrumentation/bootstrap_gen.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@
9393
"instrumentation": "opentelemetry-instrumentation-psycopg2==0.29b0",
9494
},
9595
"pymemcache": {
96-
"library": "pymemcache ~= 1.3",
96+
"library": "pymemcache >= 1.3.5, < 4",
9797
"instrumentation": "opentelemetry-instrumentation-pymemcache==0.29b0",
9898
},
9999
"pymongo": {

tox.ini

+8-4
Original file line numberDiff line numberDiff line change
@@ -111,8 +111,8 @@ envlist =
111111
; ext-psycopg2 intentionally excluded from pypy3
112112

113113
; opentelemetry-instrumentation-pymemcache
114-
py3{6,7,8,9,10}-test-instrumentation-pymemcache
115-
pypy3-test-instrumentation-pymemcache
114+
py3{6,7,8,9,10}-test-instrumentation-pymemcache{135,200,300,342}
115+
pypy3-test-instrumentation-pymemcache{135,200,300,342}
116116

117117
; opentelemetry-instrumentation-pymongo
118118
py3{6,7,8,9,10}-test-instrumentation-pymongo
@@ -222,6 +222,10 @@ deps =
222222
sqlalchemy14: sqlalchemy~=1.4
223223
pika0: pika>=0.12.0,<1.0.0
224224
pika1: pika>=1.0.0
225+
pymemcache135: pymemcache ==1.3.5
226+
pymemcache200: pymemcache >2.0.0,<3.0.0
227+
pymemcache300: pymemcache >3.0.0,<3.4.2
228+
pymemcache342: pymemcache ==3.4.2
225229
httpx18: httpx>=0.18.0,<0.19.0
226230
httpx18: respx~=0.17.0
227231
httpx21: httpx>=0.19.0
@@ -262,7 +266,7 @@ changedir =
262266
test-instrumentation-mysql: instrumentation/opentelemetry-instrumentation-mysql/tests
263267
test-instrumentation-pika{0,1}: instrumentation/opentelemetry-instrumentation-pika/tests
264268
test-instrumentation-psycopg2: instrumentation/opentelemetry-instrumentation-psycopg2/tests
265-
test-instrumentation-pymemcache: instrumentation/opentelemetry-instrumentation-pymemcache/tests
269+
test-instrumentation-pymemcache{135,200,300,342}: instrumentation/opentelemetry-instrumentation-pymemcache/tests
266270
test-instrumentation-pymongo: instrumentation/opentelemetry-instrumentation-pymongo/tests
267271
test-instrumentation-pymysql: instrumentation/opentelemetry-instrumentation-pymysql/tests
268272
test-instrumentation-pyramid: instrumentation/opentelemetry-instrumentation-pyramid/tests
@@ -332,7 +336,7 @@ commands_pre =
332336

333337
mysql: pip install {toxinidir}/instrumentation/opentelemetry-instrumentation-dbapi {toxinidir}/instrumentation/opentelemetry-instrumentation-mysql[test]
334338

335-
pymemcache: pip install {toxinidir}/instrumentation/opentelemetry-instrumentation-pymemcache[test]
339+
pymemcache{135,200,300,342}: pip install {toxinidir}/instrumentation/opentelemetry-instrumentation-pymemcache[test]
336340

337341
pymongo: pip install {toxinidir}/instrumentation/opentelemetry-instrumentation-pymongo[test]
338342

0 commit comments

Comments
 (0)