Skip to content

Commit 4893ccd

Browse files
committed
add missing redis integration tests
1 parent f6217f3 commit 4893ccd

File tree

2 files changed

+112
-0
lines changed

2 files changed

+112
-0
lines changed

test-integration/e2e-redis.test.js

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
"use strict";
2+
3+
const { promisify } = require("util");
4+
5+
const cds = require("@sap/cds");
6+
7+
const CHANNELS = {};
8+
9+
const mockRedisClientInstance = {
10+
createMainClientAndConnect: require("../test/mocks/redisMock").createMainClientAndConnect,
11+
subscribeChannel: jest.fn().mockImplementation((...args) => {
12+
const [, channel, cb] = args;
13+
CHANNELS[channel] = cb;
14+
}),
15+
publishMessage: jest.fn().mockImplementation((...args) => {
16+
const [, channel, data] = args;
17+
setTimeout(() => {
18+
const cb = CHANNELS[channel];
19+
if (!cb) {
20+
throw new Error("missing channel subscribe!");
21+
}
22+
cb(data);
23+
}, 1);
24+
}),
25+
connectionCheck: jest.fn(),
26+
isCluster: false,
27+
beforeCloseHandler: null,
28+
};
29+
30+
jest.mock("@cap-js-community/common", () => ({
31+
RedisClient: {
32+
create: jest.fn().mockReturnValue(mockRedisClientInstance),
33+
},
34+
}));
35+
36+
const eventQueue = require("../src");
37+
const { EventProcessingStatus } = require("../src");
38+
const periodicEvents = require("../src/periodicEvents");
39+
const path = require("path");
40+
const { Logger: mockLogger } = require("../test/mocks/logger");
41+
const { checkAndInsertPeriodicEvents } = require("../src/periodicEvents");
42+
const runner = require("../src/runner/runner");
43+
44+
cds.test(__dirname + "/_env");
45+
46+
const basePath = path.join(__dirname, "..", "test", "asset", "outboxProject");
47+
cds.env.requires.StandardService = {
48+
impl: path.join(basePath, "srv/service/standard-service.js"),
49+
outbox: {
50+
kind: "persistent-outbox",
51+
events: {
52+
mainPeriodic: {
53+
interval: 20 * 60,
54+
},
55+
},
56+
},
57+
};
58+
59+
let loggerMock;
60+
61+
describe("end-to-end", () => {
62+
beforeAll(async () => {
63+
loggerMock = mockLogger();
64+
jest.spyOn(periodicEvents, "checkAndInsertPeriodicEvents").mockResolvedValue();
65+
eventQueue.config.initialized = false;
66+
await eventQueue.initialize({
67+
useAsCAPOutbox: true,
68+
processEventsAfterPublish: true,
69+
isEventQueueActive: true,
70+
});
71+
eventQueue.config.redisEnabled = true;
72+
cds.emit("connect", await cds.connect.to("db"));
73+
});
74+
75+
beforeEach(async () => {
76+
await DELETE.from("sap.eventqueue.Lock");
77+
await DELETE.from("sap.eventqueue.Event");
78+
await DELETE.from("cds.outbox.Messages");
79+
jest.clearAllMocks();
80+
});
81+
82+
it("insert entry: redis broadcast + process", async () => {
83+
const srv = await cds.connect.to("StandardService");
84+
await srv.emit("main");
85+
await waitAtLeastOneEntryIsDone();
86+
expect(loggerMock.callsLengths().error).toEqual(0);
87+
});
88+
89+
it("checkAndInsertPeriodicEvents should insert new events and runner should broadcast + process events", async () => {
90+
await cds.tx((tx) => checkAndInsertPeriodicEvents(tx.context));
91+
await runner.__._singleTenantRedis();
92+
await waitAtLeastOneEntryIsDone();
93+
expect(loggerMock.callsLengths().error).toEqual(0);
94+
});
95+
});
96+
97+
const waitAtLeastOneEntryIsDone = async () => {
98+
let startTime = Date.now();
99+
while (true) {
100+
const row = await cds.tx({}, (tx2) => tx2.run(SELECT.one.from("sap.eventqueue.Event").where({ status: 2 })));
101+
if (row?.status === EventProcessingStatus.Done) {
102+
break;
103+
}
104+
if (Date.now() - startTime > 180 * 1000) {
105+
throw new Error("entry not completed");
106+
}
107+
await promisify(setTimeout)(50);
108+
}
109+
return false;
110+
};

test/mocks/redisMock.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ const _createMainClientAndConnect = async () => ({
1818
});
1919

2020
module.exports = {
21+
attachRedisUnsubscribeHandler: () => {},
22+
subscribeRedisChannel: () => {},
2123
createClientAndConnect: _createMainClientAndConnect,
2224
createMainClientAndConnect: _createMainClientAndConnect,
2325
closeSubscribeClient: () => {},

0 commit comments

Comments
 (0)