Skip to content

Commit b4fcb37

Browse files
add probe unit tests
1 parent 043f9df commit b4fcb37

File tree

2 files changed

+173
-1
lines changed

2 files changed

+173
-1
lines changed
Lines changed: 173 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,173 @@
1+
import { CoreModule } from '@module/CoreModule.js';
2+
import { container, ContainerImplementation, ProbeModule } from '@powersync/lib-services-framework';
3+
import { modules, system, utils } from '@powersync/service-core';
4+
import { constants } from 'fs';
5+
import fs from 'fs/promises';
6+
import path from 'path';
7+
import { describe, expect, it } from 'vitest';
8+
9+
type TestContainerOptions = {
10+
yamlConfig: string;
11+
mode: system.ServiceContextMode;
12+
};
13+
14+
const createTestContainer = async (options: TestContainerOptions) => {
15+
// Initialize framework components
16+
container.registerDefaults();
17+
18+
const moduleManager = new modules.ModuleManager();
19+
moduleManager.register([new CoreModule()]);
20+
21+
const collectedConfig = await new utils.CompoundConfigCollector().collectConfig({
22+
config_base64: Buffer.from(options.yamlConfig).toString('base64')
23+
});
24+
25+
const serviceContext = new system.ServiceContextContainer({
26+
configuration: collectedConfig,
27+
mode: options.mode
28+
});
29+
30+
await moduleManager.initialize(serviceContext);
31+
32+
return {
33+
[Symbol.asyncDispose]: async () => {
34+
await serviceContext.lifeCycleEngine.stop();
35+
},
36+
serviceContext
37+
};
38+
};
39+
40+
describe('Probes', () => {
41+
it('should expose HTTP probes in API mode in legacy mode', async () => {
42+
await using context = await createTestContainer({
43+
yamlConfig: /* yaml */ `
44+
# Test config
45+
telemetry:
46+
disable_telemetry_sharing: true
47+
storage:
48+
type: memory
49+
`,
50+
mode: system.ServiceContextMode.API
51+
});
52+
53+
const { serviceContext } = context;
54+
55+
// The router engine should have been configured with probe routes
56+
const testRoute = serviceContext.routerEngine.routes.api_routes.find((r) => r.path == '/probes/startup');
57+
expect(testRoute).exist;
58+
});
59+
60+
it('should not expose routes in sync mode in legacy mode', async () => {
61+
await using context = await createTestContainer({
62+
yamlConfig: /* yaml */ `
63+
# Test config
64+
telemetry:
65+
disable_telemetry_sharing: true
66+
storage:
67+
type: memory
68+
`,
69+
mode: system.ServiceContextMode.SYNC
70+
});
71+
72+
const {
73+
serviceContext: { routerEngine }
74+
} = context;
75+
76+
// The router engine should have been configured with probe routes
77+
expect(routerEngine.routes.api_routes).empty;
78+
expect(routerEngine.routes.stream_routes).empty;
79+
expect(routerEngine.routes.socket_routes).empty;
80+
});
81+
82+
it('should not expose API routes in sync mode with HTTP probes enabled', async () => {
83+
await using context = await createTestContainer({
84+
yamlConfig: /* yaml */ `
85+
# Test config
86+
telemetry:
87+
disable_telemetry_sharing: true
88+
storage:
89+
type: memory
90+
healthcheck:
91+
probes:
92+
http: true
93+
`,
94+
mode: system.ServiceContextMode.SYNC
95+
});
96+
97+
const {
98+
serviceContext: { routerEngine }
99+
} = context;
100+
101+
// The router engine should have been configured with probe routes
102+
expect(routerEngine.routes.stream_routes).empty;
103+
expect(routerEngine.routes.socket_routes).empty;
104+
expect(routerEngine.routes.api_routes.map((r) => r.path)).deep.equal([
105+
'/probes/startup',
106+
'/probes/liveness',
107+
'/probes/readiness'
108+
]); // Only the HTTP probes
109+
});
110+
111+
it('should use filesystem probes in legacy mode', async () => {
112+
await using context = await createTestContainer({
113+
yamlConfig: /* yaml */ `
114+
# Test config
115+
telemetry:
116+
disable_telemetry_sharing: true
117+
storage:
118+
type: memory
119+
`,
120+
mode: system.ServiceContextMode.API
121+
});
122+
123+
const { serviceContext } = context;
124+
125+
// This should be a filesystem probe
126+
const probes = serviceContext.get<ProbeModule>(ContainerImplementation.PROBES);
127+
128+
const aliveProbePath = path.join(process.cwd(), '.probes', 'poll');
129+
130+
await fs.unlink(aliveProbePath).catch(() => {});
131+
132+
await probes.touch();
133+
134+
const exists = await fs
135+
.access(aliveProbePath, constants.F_OK)
136+
.then(() => true)
137+
.catch(() => false);
138+
expect(exists).to.be.true;
139+
});
140+
141+
it('should not use filesystem probes if not enabled', async () => {
142+
await using context = await createTestContainer({
143+
yamlConfig: /* yaml */ `
144+
# Test config
145+
telemetry:
146+
disable_telemetry_sharing: true
147+
storage:
148+
type: memory
149+
healthcheck:
150+
probes:
151+
http: true
152+
`,
153+
mode: system.ServiceContextMode.API
154+
});
155+
156+
const { serviceContext } = context;
157+
158+
// This should be a filesystem probe
159+
const probes = serviceContext.get<ProbeModule>(ContainerImplementation.PROBES);
160+
161+
const aliveProbePath = path.join(process.cwd(), '.probes', 'poll');
162+
163+
await fs.unlink(aliveProbePath).catch(() => {});
164+
165+
await probes.touch();
166+
167+
const exists = await fs
168+
.access(aliveProbePath, constants.F_OK)
169+
.then(() => true)
170+
.catch(() => false);
171+
expect(exists).to.be.false;
172+
});
173+
});

modules/module-core/vitest.config.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import { defineConfig } from 'vitest/config';
44
export default defineConfig({
55
plugins: [tsconfigPaths()],
66
test: {
7-
setupFiles: './test/src/setup.ts',
87
poolOptions: {
98
threads: {
109
singleThread: true

0 commit comments

Comments
 (0)