fix: propagate initialization errors and reduce request metrics

This commit is contained in:
whyour
2026-08-17 08:55:53 +08:00
parent afe9b5702b
commit f71fd5ebd6
4 changed files with 193 additions and 53 deletions
+73
View File
@@ -0,0 +1,73 @@
const assert = require('node:assert/strict');
const test = require('node:test');
const { monitoringMiddleware } = require('../../back/middlewares/monitoring');
const { metricsService } = require('../../back/services/metrics');
function createResponse() {
return {
statusCode: 200,
ended: false,
end() {
this.ended = true;
},
};
}
test('health probes bypass request metric retention with or without base URL', () => {
const before = metricsService.getMetrics('http_request', {
path: '/api/health',
}).count;
let nextCalled = false;
for (const path of ['/api/health', '/ql/api/health']) {
const response = createResponse();
monitoringMiddleware({ method: 'GET', path }, response, () => {
nextCalled = true;
});
response.end();
assert.equal(response.ended, true);
}
const after = metricsService.getMetrics('http_request', {
path: '/api/health',
}).count;
assert.equal(nextCalled, true);
assert.equal(after, before);
});
test('non-health requests keep bounded service metrics', () => {
const path = '/api/monitoring-test';
const before = metricsService.getMetrics('http_request', { path }).count;
const response = createResponse();
monitoringMiddleware(
{ method: 'GET', path, platform: 'desktop' },
response,
() => {},
);
response.end();
const after = metricsService.getMetrics('http_request', { path }).count;
assert.equal(response.ended, true);
assert.equal(after, before + 1);
});
test('ordinary request metrics are sampled instead of retained per request', () => {
const path = '/api/monitoring-sampling-test';
const before = metricsService.getMetrics('http_request', { path }).count;
for (let index = 0; index < 30; index += 1) {
const response = createResponse();
monitoringMiddleware(
{ method: 'GET', path, platform: 'desktop' },
response,
() => {},
);
response.end();
}
const recorded =
metricsService.getMetrics('http_request', { path }).count - before;
assert.ok(recorded >= 2 && recorded <= 3);
});
+99
View File
@@ -0,0 +1,99 @@
const assert = require('node:assert/strict');
const test = require('node:test');
const express = require('express');
const { Container } = require('typedi');
test('initialization returns the username and password validation result', async (t) => {
const originalGet = Container.get;
const userServicePath = require.resolve('../../back/services/user');
const originalUserService = require.cache[userServicePath];
const i18nPath = require.resolve('../../back/shared/i18n');
const originalI18n = require.cache[i18nPath];
const utilPath = require.resolve('../../back/config/util');
const originalUtil = require.cache[utilPath];
const authPath = require.resolve('../../back/shared/auth');
const originalAuth = require.cache[authPath];
require.cache[userServicePath] = {
id: userServicePath,
filename: userServicePath,
loaded: true,
exports: { __esModule: true, default: class UserService {} },
children: [],
paths: [],
};
require.cache[utilPath] = {
id: utilPath,
filename: utilPath,
loaded: true,
exports: { getToken: () => '', isDemoEnv: () => false },
children: [],
paths: [],
};
require.cache[authPath] = {
id: authPath,
filename: authPath,
loaded: true,
exports: { isDefaultAuthInfo: () => false },
children: [],
paths: [],
};
require.cache[i18nPath] = {
id: i18nPath,
filename: i18nPath,
loaded: true,
exports: { t: (message) => message },
children: [],
paths: [],
};
Container.get = () => ({
updateUsernameAndPassword: async () => ({
code: 400,
message: 'password rejected',
}),
});
t.after(() => {
Container.get = originalGet;
if (originalUserService) {
require.cache[userServicePath] = originalUserService;
} else {
delete require.cache[userServicePath];
}
if (originalI18n) {
require.cache[i18nPath] = originalI18n;
} else {
delete require.cache[i18nPath];
}
if (originalUtil) {
require.cache[utilPath] = originalUtil;
} else {
delete require.cache[utilPath];
}
if (originalAuth) {
require.cache[authPath] = originalAuth;
} else {
delete require.cache[authPath];
}
});
const app = express.Router();
require('../../back/api/user').default(app);
const userRouter = app.stack.find((layer) => layer.name === 'router').handle;
const initRoute = userRouter.stack.find(
(layer) => layer.route?.path === '/init',
);
const handler = initRoute.route.stack.at(-1).handle;
let responseBody;
await handler(
{ body: { username: 'admin', password: 'admin' } },
{ send: (body) => (responseBody = body) },
(error) => {
throw error;
},
);
assert.deepEqual(responseBody, {
code: 400,
message: 'password rejected',
});
});