Skip to content

Commit fdbf2b6

Browse files
committed
test: add redis 5 e2e test
1 parent 0f7e6f6 commit fdbf2b6

4 files changed

Lines changed: 176 additions & 0 deletions

File tree

dev-packages/node-integration-tests/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@
8080
"prisma": "6.15.0",
8181
"proxy": "^2.1.1",
8282
"redis-4": "npm:redis@^4.6.14",
83+
"redis-5": "npm:redis@^5.12.0",
8384
"reflect-metadata": "0.2.1",
8485
"rxjs": "^7.8.2",
8586
"tedious": "^19.2.1",
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
version: '3.9'
2+
3+
services:
4+
db:
5+
image: redis:latest
6+
restart: always
7+
container_name: integration-tests-redis-dc
8+
ports:
9+
- '6379:6379'
10+
healthcheck:
11+
test: ['CMD-SHELL', 'redis-cli ping | grep -q PONG']
12+
interval: 2s
13+
timeout: 3s
14+
retries: 30
15+
start_period: 5s
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
const { loggingTransport } = require('@sentry-internal/node-integration-tests');
2+
const Sentry = require('@sentry/node');
3+
4+
Sentry.init({
5+
dsn: 'https://[email protected]/1337',
6+
release: '1.0',
7+
tracesSampleRate: 1.0,
8+
transport: loggingTransport,
9+
integrations: [Sentry.redisIntegration({ cachePrefixes: ['dc-cache:'] })],
10+
});
11+
12+
// Stop the process from exiting before the transaction is sent
13+
setInterval(() => {}, 1000);
14+
15+
const { createClient } = require('redis-5');
16+
17+
async function run() {
18+
const redisClient = await createClient({ socket: { host: '127.0.0.1', port: 6379 } }).connect();
19+
20+
await Sentry.startSpan(
21+
{
22+
name: 'Test Span Redis 5 DC',
23+
op: 'test-span-redis-5-dc',
24+
},
25+
async () => {
26+
try {
27+
await redisClient.set('dc-test-key', 'test-value');
28+
await redisClient.set('dc-cache:test-key', 'test-value');
29+
30+
await redisClient.set('dc-cache:test-key-ex', 'test-value', { EX: 10 });
31+
32+
await redisClient.get('dc-test-key');
33+
await redisClient.get('dc-cache:test-key');
34+
await redisClient.get('dc-cache:unavailable-data');
35+
36+
await redisClient.mGet(['dc-test-key', 'dc-cache:test-key', 'dc-cache:unavailable-data']);
37+
} finally {
38+
await redisClient.disconnect();
39+
}
40+
},
41+
);
42+
}
43+
44+
run();
Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
import { afterAll, describe, expect, test } from 'vitest';
2+
import { cleanupChildProcesses, createRunner } from '../../../utils/runner';
3+
4+
describe('redis v5 diagnostics_channel auto instrumentation', () => {
5+
afterAll(() => {
6+
cleanupChildProcesses();
7+
});
8+
9+
test(
10+
'should create spans for redis v5 commands via diagnostics_channel',
11+
{ timeout: 60_000 },
12+
async () => {
13+
const EXPECTED_CONNECT = {
14+
transaction: 'redis-connect',
15+
};
16+
17+
const EXPECTED_TRANSACTION = {
18+
transaction: 'Test Span Redis 5 DC',
19+
spans: expect.arrayContaining([
20+
// non-cache SET: span name stays redis-SET, cacheResponseHook runs but returns early
21+
expect.objectContaining({
22+
description: 'redis-SET',
23+
op: 'db.redis',
24+
origin: 'auto.db.otel.redis',
25+
data: expect.objectContaining({
26+
'sentry.op': 'db.redis',
27+
'sentry.origin': 'auto.db.otel.redis',
28+
'db.system': 'redis',
29+
'db.statement': 'SET dc-test-key [1 other arguments]',
30+
}),
31+
}),
32+
// cache SET: span name updated to key by cacheResponseHook
33+
expect.objectContaining({
34+
description: 'dc-cache:test-key',
35+
op: 'cache.put',
36+
origin: 'auto.db.otel.redis',
37+
data: expect.objectContaining({
38+
'sentry.origin': 'auto.db.otel.redis',
39+
'db.statement': 'SET dc-cache:test-key [1 other arguments]',
40+
'cache.key': ['dc-cache:test-key'],
41+
'cache.item_size': 2,
42+
}),
43+
}),
44+
// cache SET with EX option: redis v5 sends SET key value EX 10 as the command
45+
expect.objectContaining({
46+
description: 'dc-cache:test-key-ex',
47+
op: 'cache.put',
48+
origin: 'auto.db.otel.redis',
49+
data: expect.objectContaining({
50+
'sentry.origin': 'auto.db.otel.redis',
51+
'db.statement': 'SET dc-cache:test-key-ex [3 other arguments]',
52+
'cache.key': ['dc-cache:test-key-ex'],
53+
'cache.item_size': 2,
54+
}),
55+
}),
56+
// non-cache GET: span name stays redis-GET
57+
expect.objectContaining({
58+
description: 'redis-GET',
59+
op: 'db.redis',
60+
origin: 'auto.db.otel.redis',
61+
data: expect.objectContaining({
62+
'sentry.op': 'db.redis',
63+
'sentry.origin': 'auto.db.otel.redis',
64+
'db.system': 'redis',
65+
'db.statement': 'GET dc-test-key',
66+
}),
67+
}),
68+
// cache GET (hit)
69+
expect.objectContaining({
70+
description: 'dc-cache:test-key',
71+
op: 'cache.get',
72+
origin: 'auto.db.otel.redis',
73+
data: expect.objectContaining({
74+
'sentry.origin': 'auto.db.otel.redis',
75+
'db.statement': 'GET dc-cache:test-key',
76+
'cache.hit': true,
77+
'cache.key': ['dc-cache:test-key'],
78+
'cache.item_size': 10,
79+
}),
80+
}),
81+
// cache GET (miss)
82+
expect.objectContaining({
83+
description: 'dc-cache:unavailable-data',
84+
op: 'cache.get',
85+
origin: 'auto.db.otel.redis',
86+
data: expect.objectContaining({
87+
'sentry.origin': 'auto.db.otel.redis',
88+
'db.statement': 'GET dc-cache:unavailable-data',
89+
'cache.hit': false,
90+
'cache.key': ['dc-cache:unavailable-data'],
91+
}),
92+
}),
93+
// MGET: mixed cache/non-cache keys, span name is all keys joined
94+
expect.objectContaining({
95+
description: 'dc-test-key, dc-cache:test-key, dc-cache:unavailable-data',
96+
op: 'cache.get',
97+
origin: 'auto.db.otel.redis',
98+
data: expect.objectContaining({
99+
'sentry.origin': 'auto.db.otel.redis',
100+
'db.statement': 'MGET [3 other arguments]',
101+
'cache.hit': true,
102+
'cache.key': ['dc-test-key', 'dc-cache:test-key', 'dc-cache:unavailable-data'],
103+
}),
104+
}),
105+
]),
106+
};
107+
108+
await createRunner(__dirname, 'scenario-redis-5.js')
109+
.withDockerCompose({ workingDirectory: [__dirname] })
110+
.expect({ transaction: EXPECTED_CONNECT })
111+
.expect({ transaction: EXPECTED_TRANSACTION })
112+
.start()
113+
.completed();
114+
},
115+
);
116+
});

0 commit comments

Comments
 (0)