Skip to content

Commit c1f2cd6

Browse files
committed
added redis cluster test
1 parent 65e2c64 commit c1f2cd6

File tree

1 file changed

+125
-0
lines changed
  • instrumentation/opentelemetry-instrumentation-redis/tests

1 file changed

+125
-0
lines changed

instrumentation/opentelemetry-instrumentation-redis/tests/test_redis.py

Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,69 @@
2828
from opentelemetry.test.test_base import TestBase
2929
from opentelemetry.trace import SpanKind
3030

31+
default_cluster_slots = [
32+
[0, 8191, ["1.1.1.1", 6380, "node_0"], ["1.1.1.1", 6383, "node_3"]],
33+
[8192, 16383, ["1.1.1.1", 6381, "node_1"], ["1.1.1.1", 6382, "node_2"]],
34+
]
35+
36+
37+
def get_mocked_redis_cluster_client(
38+
func=None, cluster_slots_raise_error=False, *args, **kwargs
39+
):
40+
"""
41+
Return a stable RedisCluster object that have deterministic
42+
nodes and slots setup to remove the problem of different IP addresses
43+
on different installations and machines.
44+
"""
45+
cluster_slots = kwargs.pop("cluster_slots", default_cluster_slots)
46+
coverage_res = kwargs.pop("coverage_result", "yes")
47+
cluster_enabled = kwargs.pop("cluster_enabled", True)
48+
with mock.patch.object(
49+
redis.Redis, "execute_command"
50+
) as execute_command_mock:
51+
52+
def execute_command(*_args, **_kwargs):
53+
if _args[0] == "CLUSTER SLOTS":
54+
if cluster_slots_raise_error:
55+
raise redis.exceptions.ResponseError()
56+
else:
57+
mock_cluster_slots = cluster_slots
58+
return mock_cluster_slots
59+
elif _args[0] == "COMMAND":
60+
return {"get": [], "set": []}
61+
elif _args[0] == "INFO":
62+
return {"cluster_enabled": cluster_enabled}
63+
elif (
64+
len(_args) > 1 and _args[1] == "cluster-require-full-coverage"
65+
):
66+
return {"cluster-require-full-coverage": coverage_res}
67+
elif func is not None:
68+
return func(*args, **kwargs)
69+
else:
70+
return execute_command_mock(*_args, **_kwargs)
71+
72+
execute_command_mock.side_effect = execute_command
73+
74+
with mock.patch.object(
75+
redis._parsers.CommandsParser, "initialize", autospec=True
76+
) as cmd_parser_initialize:
77+
78+
def cmd_init_mock(self, r):
79+
self.commands = {
80+
"get": {
81+
"name": "get",
82+
"arity": 2,
83+
"flags": ["readonly", "fast"],
84+
"first_key_pos": 1,
85+
"last_key_pos": 1,
86+
"step_count": 1,
87+
}
88+
}
89+
90+
cmd_parser_initialize.side_effect = cmd_init_mock
91+
92+
return redis.RedisCluster(*args, **kwargs)
93+
3194

3295
class TestRedis(TestBase):
3396
def setUp(self):
@@ -311,3 +374,65 @@ def test_attributes_unix_socket(self):
311374
span.attributes[SpanAttributes.NET_TRANSPORT],
312375
NetTransportValues.OTHER.value,
313376
)
377+
378+
def test_attributes_redis_cluster(self):
379+
with mock.patch.object(redis.RedisCluster, "from_url") as from_url:
380+
381+
def from_url_mocked(_url, **_kwargs):
382+
return get_mocked_redis_cluster_client(url=_url, **_kwargs)
383+
384+
from_url.side_effect = from_url_mocked
385+
redis_client = redis.RedisCluster.from_url(
386+
"redis://foo:bar@1.1.1.1:6380/0"
387+
)
388+
389+
with mock.patch.object(
390+
redis._parsers.CommandsParser, "initialize", autospec=True
391+
) as cmd_parser_initialize:
392+
393+
def cmd_init_mock(self, r):
394+
self.commands = {
395+
"get": {
396+
"name": "get",
397+
"arity": 2,
398+
"flags": ["readonly", "fast"],
399+
"first_key_pos": 1,
400+
"last_key_pos": 1,
401+
"step_count": 1,
402+
},
403+
"set": {
404+
"name": "set",
405+
"arity": -3,
406+
"flags": ["write", "denyoom"],
407+
"first_key_pos": 1,
408+
"last_key_pos": 1,
409+
"step_count": 1,
410+
},
411+
}
412+
413+
cmd_parser_initialize.side_effect = cmd_init_mock
414+
with mock.patch.object(
415+
redis.connection.ConnectionPool, "get_connection"
416+
) as get_connection:
417+
get_connection.return_value = mock.MagicMock()
418+
redis_client.set("key", "value")
419+
420+
spans = self.memory_exporter.get_finished_spans()
421+
self.assertEqual(len(spans), 1)
422+
423+
span = spans[0]
424+
self.assertEqual(
425+
span.attributes[SpanAttributes.DB_SYSTEM],
426+
DbSystemValues.REDIS.value,
427+
)
428+
self.assertEqual(
429+
span.attributes[SpanAttributes.DB_REDIS_DATABASE_INDEX], 0
430+
)
431+
self.assertEqual(
432+
span.attributes[SpanAttributes.NET_PEER_NAME], "1.1.1.1"
433+
)
434+
self.assertEqual(span.attributes[SpanAttributes.NET_PEER_PORT], 6380)
435+
self.assertEqual(
436+
span.attributes[SpanAttributes.NET_TRANSPORT],
437+
NetTransportValues.IP_TCP.value,
438+
)

0 commit comments

Comments
 (0)