Skip to content

Commit 75744f4

Browse files
committed
test: add redis 5 integration test
1 parent 0f7e6f6 commit 75744f4

4 files changed

Lines changed: 172 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://public@dsn.ingest.sentry.io/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: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
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('should create spans for redis v5 commands via diagnostics_channel', { timeout: 60_000 }, async () => {
10+
const EXPECTED_CONNECT = {
11+
transaction: 'redis-connect',
12+
};
13+
14+
const EXPECTED_TRANSACTION = {
15+
transaction: 'Test Span Redis 5 DC',
16+
spans: expect.arrayContaining([
17+
// non-cache SET: span name stays redis-SET, cacheResponseHook runs but returns early
18+
expect.objectContaining({
19+
description: 'redis-SET',
20+
op: 'db.redis',
21+
origin: 'auto.db.otel.redis',
22+
data: expect.objectContaining({
23+
'sentry.op': 'db.redis',
24+
'sentry.origin': 'auto.db.otel.redis',
25+
'db.system': 'redis',
26+
'db.statement': 'SET dc-test-key [1 other arguments]',
27+
}),
28+
}),
29+
// cache SET: span name updated to key by cacheResponseHook
30+
expect.objectContaining({
31+
description: 'dc-cache:test-key',
32+
op: 'cache.put',
33+
origin: 'auto.db.otel.redis',
34+
data: expect.objectContaining({
35+
'sentry.origin': 'auto.db.otel.redis',
36+
'db.statement': 'SET dc-cache:test-key [1 other arguments]',
37+
'cache.key': ['dc-cache:test-key'],
38+
'cache.item_size': 2,
39+
}),
40+
}),
41+
// cache SET with EX option: redis v5 sends SET key value EX 10 as the command
42+
expect.objectContaining({
43+
description: 'dc-cache:test-key-ex',
44+
op: 'cache.put',
45+
origin: 'auto.db.otel.redis',
46+
data: expect.objectContaining({
47+
'sentry.origin': 'auto.db.otel.redis',
48+
'db.statement': 'SET dc-cache:test-key-ex [3 other arguments]',
49+
'cache.key': ['dc-cache:test-key-ex'],
50+
'cache.item_size': 2,
51+
}),
52+
}),
53+
// non-cache GET: span name stays redis-GET
54+
expect.objectContaining({
55+
description: 'redis-GET',
56+
op: 'db.redis',
57+
origin: 'auto.db.otel.redis',
58+
data: expect.objectContaining({
59+
'sentry.op': 'db.redis',
60+
'sentry.origin': 'auto.db.otel.redis',
61+
'db.system': 'redis',
62+
'db.statement': 'GET dc-test-key',
63+
}),
64+
}),
65+
// cache GET (hit)
66+
expect.objectContaining({
67+
description: 'dc-cache:test-key',
68+
op: 'cache.get',
69+
origin: 'auto.db.otel.redis',
70+
data: expect.objectContaining({
71+
'sentry.origin': 'auto.db.otel.redis',
72+
'db.statement': 'GET dc-cache:test-key',
73+
'cache.hit': true,
74+
'cache.key': ['dc-cache:test-key'],
75+
'cache.item_size': 10,
76+
}),
77+
}),
78+
// cache GET (miss)
79+
expect.objectContaining({
80+
description: 'dc-cache:unavailable-data',
81+
op: 'cache.get',
82+
origin: 'auto.db.otel.redis',
83+
data: expect.objectContaining({
84+
'sentry.origin': 'auto.db.otel.redis',
85+
'db.statement': 'GET dc-cache:unavailable-data',
86+
'cache.hit': false,
87+
'cache.key': ['dc-cache:unavailable-data'],
88+
}),
89+
}),
90+
// MGET: mixed cache/non-cache keys, span name is all keys joined
91+
expect.objectContaining({
92+
description: 'dc-test-key, dc-cache:test-key, dc-cache:unavailable-data',
93+
op: 'cache.get',
94+
origin: 'auto.db.otel.redis',
95+
data: expect.objectContaining({
96+
'sentry.origin': 'auto.db.otel.redis',
97+
'db.statement': 'MGET [3 other arguments]',
98+
'cache.hit': true,
99+
'cache.key': ['dc-test-key', 'dc-cache:test-key', 'dc-cache:unavailable-data'],
100+
}),
101+
}),
102+
]),
103+
};
104+
105+
await createRunner(__dirname, 'scenario-redis-5.js')
106+
.withDockerCompose({ workingDirectory: [__dirname] })
107+
.expect({ transaction: EXPECTED_CONNECT })
108+
.expect({ transaction: EXPECTED_TRANSACTION })
109+
.start()
110+
.completed();
111+
});
112+
});

0 commit comments

Comments
 (0)