Skip to content

Commit 2e9cc6c

Browse files
committed
Update
1 parent 2b9fa71 commit 2e9cc6c

File tree

3 files changed

+122
-102
lines changed

3 files changed

+122
-102
lines changed
File renamed without changes.
Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
"use strict";
2+
3+
const cds = require("@sap/cds");
4+
5+
const redis = require("redis");
6+
require("../mocks/redis");
7+
jest.mock("redis", () => require("../mocks/redis"));
8+
9+
const { test } = cds.test(__dirname + "/../..");
10+
11+
const { RedisClient } = require("../../src/redis-client");
12+
13+
process.env.PORT = 0; // Random
14+
15+
describe("Redis Client (Sentinel)", () => {
16+
beforeEach(async () => {
17+
await test.data.reset();
18+
await RedisClient.closeAllClients();
19+
});
20+
21+
describe("Sentinel Mode", () => {
22+
23+
it("creates Sentinel client when sentinel_nodes configured", async () => {
24+
cds.env.requires.redis = {
25+
credentials: {
26+
sentinel_nodes: [
27+
{ hostname: "sentinel1.example.com", port: 26379 },
28+
{ hostname: "sentinel2.example.com", port: 26379 },
29+
],
30+
uri: "redis://:secret@sentinel1.example.com:26379#mymaster",
31+
password: "secret",
32+
tls: true,
33+
},
34+
};
35+
36+
const redisClient = RedisClient.create("sentinel-test");
37+
const client = await redisClient.createMainClientAndConnect();
38+
39+
expect(client).toBeDefined();
40+
expect(redis.createSentinel).toHaveBeenCalledWith({
41+
name: "mymaster",
42+
sentinelRootNodes: [
43+
{ host: "sentinel1.example.com", port: 26379 },
44+
{ host: "sentinel2.example.com", port: 26379 },
45+
],
46+
nodeClientOptions: expect.objectContaining({
47+
password: "secret",
48+
socket: expect.objectContaining({ tls: true }),
49+
}),
50+
sentinelClientOptions: expect.objectContaining({
51+
password: "secret",
52+
}),
53+
passthroughClientErrorEvents: true,
54+
});
55+
expect(redisClient.isSentinel).toBe(true);
56+
expect(redisClient.isCluster).toBe(false);
57+
await redisClient.closeMainClient();
58+
});
59+
60+
it("prefers master_name field over URI fragment", async () => {
61+
cds.env.requires.redis = {
62+
credentials: {
63+
sentinel_nodes: [{ host: "sentinel.local", port: 26379 }],
64+
master_name: "explicit-master",
65+
uri: "redis://sentinel.local#uri-master",
66+
},
67+
};
68+
69+
const redisClient = RedisClient.create("master-name-test");
70+
await redisClient.createMainClientAndConnect();
71+
72+
expect(redis.createSentinel).toHaveBeenCalledWith(expect.objectContaining({ name: "explicit-master" }));
73+
});
74+
75+
it("uses default port 26379 when not specified", async () => {
76+
cds.env.requires.redis = {
77+
credentials: {
78+
sentinel_nodes: [{ hostname: "sentinel.local" }],
79+
master_name: "mymaster",
80+
},
81+
};
82+
83+
const redisClient = RedisClient.create("default-port-test");
84+
await redisClient.createMainClientAndConnect();
85+
86+
expect(redis.createSentinel).toHaveBeenCalledWith(
87+
expect.objectContaining({
88+
sentinelRootNodes: [{ host: "sentinel.local", port: 26379 }],
89+
}),
90+
);
91+
});
92+
93+
it("returns undefined if master name not found", async () => {
94+
cds.env.requires.redis = {
95+
credentials: {
96+
sentinel_nodes: [{ hostname: "sentinel.local" }],
97+
},
98+
};
99+
100+
const redisClient = RedisClient.create("no-master-test");
101+
const client = await redisClient.createMainClientAndConnect();
102+
expect(client).toBeUndefined();
103+
});
104+
105+
it("prioritizes sentinel over cluster mode", async () => {
106+
cds.env.requires.redis = {
107+
credentials: {
108+
sentinel_nodes: [{ hostname: "sentinel.local" }],
109+
master_name: "mymaster",
110+
cluster_mode: true,
111+
},
112+
};
113+
114+
const redisClient = RedisClient.create("priority-test");
115+
await redisClient.createMainClientAndConnect();
116+
117+
expect(redis.createSentinel).toHaveBeenCalled();
118+
expect(redis.createCluster).not.toHaveBeenCalled();
119+
expect(redisClient.isSentinel).toBe(true);
120+
});
121+
});
122+
});

test/redis-client/redis-client.test.js

Lines changed: 0 additions & 102 deletions
Original file line numberDiff line numberDiff line change
@@ -123,106 +123,4 @@ describe("Redis Client", () => {
123123
const result = await redisClient.publishMessage({}, "test", "message");
124124
expect(result).toBeUndefined();
125125
});
126-
127-
describe("Sentinel Mode", () => {
128-
129-
it.skip("creates Sentinel client when sentinel_nodes configured", async () => {
130-
cds.env.requires.redis = {
131-
credentials: {
132-
sentinel_nodes: [
133-
{ hostname: "sentinel1.example.com", port: 26379 },
134-
{ hostname: "sentinel2.example.com", port: 26379 },
135-
],
136-
uri: "redis://:secret@sentinel1.example.com:26379#mymaster",
137-
password: "secret",
138-
tls: true,
139-
},
140-
};
141-
142-
const redisClient = RedisClient.create("sentinel-test");
143-
const client = await redisClient.createMainClientAndConnect();
144-
145-
expect(client).toBeDefined();
146-
expect(redis.createSentinel).toHaveBeenCalledWith({
147-
name: "mymaster",
148-
sentinelRootNodes: [
149-
{ host: "sentinel1.example.com", port: 26379 },
150-
{ host: "sentinel2.example.com", port: 26379 },
151-
],
152-
nodeClientOptions: expect.objectContaining({
153-
password: "secret",
154-
socket: expect.objectContaining({ tls: true }),
155-
}),
156-
sentinelClientOptions: expect.objectContaining({
157-
password: "secret",
158-
}),
159-
passthroughClientErrorEvents: true,
160-
});
161-
expect(redisClient.isSentinel).toBe(true);
162-
expect(redisClient.isCluster).toBe(false);
163-
await redisClient.closeMainClient();
164-
});
165-
166-
it("prefers master_name field over URI fragment", async () => {
167-
cds.env.requires.redis = {
168-
credentials: {
169-
sentinel_nodes: [{ host: "sentinel.local", port: 26379 }],
170-
master_name: "explicit-master",
171-
uri: "redis://sentinel.local#uri-master",
172-
},
173-
};
174-
175-
const redisClient = RedisClient.create("master-name-test");
176-
await redisClient.createMainClientAndConnect();
177-
178-
expect(redis.createSentinel).toHaveBeenCalledWith(expect.objectContaining({ name: "explicit-master" }));
179-
});
180-
181-
it.skip("uses default port 26379 when not specified", async () => {
182-
cds.env.requires.redis = {
183-
credentials: {
184-
sentinel_nodes: [{ hostname: "sentinel.local" }],
185-
master_name: "mymaster",
186-
},
187-
};
188-
189-
const redisClient = RedisClient.create("default-port-test");
190-
await redisClient.createMainClientAndConnect();
191-
192-
expect(redis.createSentinel).toHaveBeenCalledWith(
193-
expect.objectContaining({
194-
sentinelRootNodes: [{ host: "sentinel.local", port: 26379 }],
195-
}),
196-
);
197-
});
198-
199-
it.skip("returns undefined if master name not found", async () => {
200-
cds.env.requires.redis = {
201-
credentials: {
202-
sentinel_nodes: [{ hostname: "sentinel.local" }],
203-
},
204-
};
205-
206-
const redisClient = RedisClient.create("no-master-test");
207-
const client = await redisClient.createMainClientAndConnect();
208-
expect(client).toBeUndefined();
209-
});
210-
211-
it.skip("prioritizes sentinel over cluster mode", async () => {
212-
cds.env.requires.redis = {
213-
credentials: {
214-
sentinel_nodes: [{ hostname: "sentinel.local" }],
215-
master_name: "mymaster",
216-
cluster_mode: true,
217-
},
218-
};
219-
220-
const redisClient = RedisClient.create("priority-test");
221-
await redisClient.createMainClientAndConnect();
222-
223-
expect(redis.createSentinel).toHaveBeenCalled();
224-
expect(redis.createCluster).not.toHaveBeenCalled();
225-
expect(redisClient.isSentinel).toBe(true);
226-
});
227-
});
228126
});

0 commit comments

Comments
 (0)