mirror of
https://github.com/hyperdxio/hyperdx
synced 2026-04-21 13:37:15 +00:00
Clean Up Integration Test Console Output (#1566)
- Also fix issue where integration tests were making actual network requests - this also slightly speeds up tests - Fixes issues where there were JS errors thrown during tests due to incorrect mocks, causing confusion when adding/fixing other tests Before (note: too much content to even see all tests) https://github.com/user-attachments/assets/346bb57d-aa64-4a62-b666-3cf47fcc2a6c After: https://github.com/user-attachments/assets/f6379a93-2d1d-4f12-a467-02d874f98de6 Fixes HDX-3165
This commit is contained in:
parent
e9eb84eb1d
commit
e767d79e02
13 changed files with 125 additions and 69 deletions
|
|
@ -8,3 +8,5 @@ MONGO_URI=mongodb://localhost:29999/hyperdx-test
|
|||
NODE_ENV=test
|
||||
PORT=9000
|
||||
OPAMP_PORT=4320
|
||||
# Default to only logging warnings/errors. Adjust if you need more verbosity
|
||||
HYPERDX_LOG_LEVEL=warn
|
||||
|
|
@ -1,2 +1,21 @@
|
|||
// @eslint-disable @typescript-eslint/no-var-requires
|
||||
jest.retryTimes(1, { logErrorsBeforeRetry: true });
|
||||
|
||||
global.console = {
|
||||
...console,
|
||||
// Turn off console.debug logs in tests (useful since we log db queries aggressively)
|
||||
debug: jest.fn(),
|
||||
};
|
||||
|
||||
// Mock alert notification functions to prevent HTTP calls during tests
|
||||
jest.mock('@/utils/slack', () => ({
|
||||
...jest.requireActual('@/utils/slack'),
|
||||
postMessageToWebhook: jest.fn().mockResolvedValue(null),
|
||||
}));
|
||||
|
||||
// Mock global fetch for generic webhook calls
|
||||
global.fetch = jest.fn().mockResolvedValue({
|
||||
ok: true,
|
||||
text: jest.fn().mockResolvedValue(''),
|
||||
json: jest.fn().mockResolvedValue({}),
|
||||
} as any);
|
||||
|
|
|
|||
|
|
@ -73,7 +73,7 @@
|
|||
"supertest": "^6.3.1",
|
||||
"swagger-jsdoc": "^6.2.8",
|
||||
"swagger-ui-express": "^5.0.1",
|
||||
"ts-jest": "^28.0.5",
|
||||
"ts-jest": "^29.4.5",
|
||||
"ts-node": "^10.8.1",
|
||||
"tsc-alias": "^1.8.8",
|
||||
"tsconfig-paths": "^4.2.0",
|
||||
|
|
|
|||
|
|
@ -54,7 +54,9 @@ if (!config.IS_LOCAL_APP_MODE) {
|
|||
app.use(passport.session());
|
||||
}
|
||||
|
||||
app.use(expressLogger);
|
||||
if (!config.IS_CI) {
|
||||
app.use(expressLogger);
|
||||
}
|
||||
// Allows timing data from frontend package
|
||||
// see: https://github.com/expressjs/cors/issues/102
|
||||
app.use(function (req, res, next) {
|
||||
|
|
|
|||
|
|
@ -108,7 +108,6 @@ describe('renderChartConfig', () => {
|
|||
});
|
||||
|
||||
afterEach(async () => {
|
||||
console.log('running db cleanup code');
|
||||
await server.clearDBs();
|
||||
jest.clearAllMocks();
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
import _ from 'lodash';
|
||||
import { ObjectId } from 'mongodb';
|
||||
import mongoose from 'mongoose';
|
||||
|
||||
import { getLoggedInAgent, getServer } from '@/fixtures';
|
||||
|
|
@ -60,7 +61,7 @@ Object {
|
|||
team: team.id,
|
||||
kind: 'log',
|
||||
name: 'My New Source',
|
||||
connection: 'local',
|
||||
connection: new ObjectId().toString(),
|
||||
from: {
|
||||
databaseName: 'system',
|
||||
tableName: 'query_log',
|
||||
|
|
|
|||
|
|
@ -231,6 +231,11 @@ describe('External API Alerts', () => {
|
|||
});
|
||||
|
||||
it('should handle validation errors when creating alerts', async () => {
|
||||
// Spy on console.error to suppress error output in tests
|
||||
const consoleErrorSpy = jest
|
||||
.spyOn(console, 'error')
|
||||
.mockImplementation(() => {});
|
||||
|
||||
// Missing required fields
|
||||
const invalidInput = {
|
||||
name: 'Invalid Alert',
|
||||
|
|
@ -243,6 +248,9 @@ describe('External API Alerts', () => {
|
|||
.expect(500);
|
||||
|
||||
expect(response.body).toHaveProperty('message');
|
||||
|
||||
// Restore console.error
|
||||
consoleErrorSpy.mockRestore();
|
||||
});
|
||||
|
||||
it('should create multiple alerts for different tiles', async () => {
|
||||
|
|
|
|||
|
|
@ -414,6 +414,11 @@ describe('External API v2 Charts', () => {
|
|||
});
|
||||
|
||||
it('should handle lucene query errors gracefully', async () => {
|
||||
// Spy on console.error to suppress expected error output
|
||||
const consoleErrorSpy = jest
|
||||
.spyOn(console, 'error')
|
||||
.mockImplementation(() => {});
|
||||
|
||||
const payload = createSeriesRequestPayload(logSource.id.toString(), {
|
||||
series: [{ aggFn: 'count', where: '(invalid query', groupBy: [] }],
|
||||
});
|
||||
|
|
@ -421,9 +426,17 @@ describe('External API v2 Charts', () => {
|
|||
.send(payload)
|
||||
.expect(500);
|
||||
expect(response.body).toHaveProperty('error');
|
||||
|
||||
// Restore console.error
|
||||
consoleErrorSpy.mockRestore();
|
||||
});
|
||||
|
||||
it('should handle sql query errors gracefully', async () => {
|
||||
// Spy on console.error to suppress expected error output
|
||||
const consoleErrorSpy = jest
|
||||
.spyOn(console, 'error')
|
||||
.mockImplementation(() => {});
|
||||
|
||||
const payload = createSeriesRequestPayload(logSource.id.toString(), {
|
||||
series: [
|
||||
{
|
||||
|
|
@ -438,6 +451,9 @@ describe('External API v2 Charts', () => {
|
|||
.send(payload)
|
||||
.expect(500);
|
||||
expect(response.body).toHaveProperty('error');
|
||||
|
||||
// Restore console.error
|
||||
consoleErrorSpy.mockRestore();
|
||||
});
|
||||
|
||||
it('should return data grouped by a single field', async () => {
|
||||
|
|
|
|||
|
|
@ -123,6 +123,37 @@ describe('checkAlerts', () => {
|
|||
});
|
||||
|
||||
describe('Alert Templates', () => {
|
||||
// Create a mock metadata object with the necessary methods
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
|
||||
const mockMetadata = {
|
||||
getColumn: jest.fn().mockImplementation(({ column }) => {
|
||||
// Provide basic column definitions for common columns to avoid warnings
|
||||
const columnMap = {
|
||||
Timestamp: { name: 'Timestamp', type: 'DateTime' },
|
||||
Body: { name: 'Body', type: 'String' },
|
||||
SeverityText: { name: 'SeverityText', type: 'String' },
|
||||
ServiceName: { name: 'ServiceName', type: 'String' },
|
||||
};
|
||||
return Promise.resolve(columnMap[column]);
|
||||
}),
|
||||
getColumns: jest.fn().mockResolvedValue([]),
|
||||
getMapKeys: jest.fn().mockResolvedValue([]),
|
||||
getMapValues: jest.fn().mockResolvedValue([]),
|
||||
getAllFields: jest.fn().mockResolvedValue([]),
|
||||
getTableMetadata: jest.fn().mockResolvedValue({}),
|
||||
getClickHouseSettings: jest.fn().mockReturnValue({}),
|
||||
setClickHouseSettings: jest.fn(),
|
||||
} as any;
|
||||
|
||||
// Create a mock clickhouse client
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
|
||||
const mockClickhouseClient = {
|
||||
query: jest.fn().mockResolvedValue({
|
||||
json: jest.fn().mockResolvedValue({ data: [] }),
|
||||
text: jest.fn().mockResolvedValue(''),
|
||||
}),
|
||||
} as any;
|
||||
|
||||
const defaultSearchView: AlertMessageTemplateDefaultView = {
|
||||
alert: {
|
||||
thresholdType: AlertThresholdType.ABOVE,
|
||||
|
|
@ -525,8 +556,8 @@ describe('checkAlerts', () => {
|
|||
|
||||
await renderAlertTemplate({
|
||||
alertProvider,
|
||||
clickhouseClient: {} as any,
|
||||
metadata: {} as any,
|
||||
clickhouseClient: mockClickhouseClient,
|
||||
metadata: mockMetadata,
|
||||
state: AlertState.ALERT,
|
||||
template: 'Custom body @webhook-My_Web', // partial name should work
|
||||
view: {
|
||||
|
|
@ -560,8 +591,8 @@ describe('checkAlerts', () => {
|
|||
|
||||
await renderAlertTemplate({
|
||||
alertProvider,
|
||||
clickhouseClient: {} as any,
|
||||
metadata: {} as any,
|
||||
clickhouseClient: mockClickhouseClient,
|
||||
metadata: mockMetadata,
|
||||
state: AlertState.ALERT,
|
||||
template: 'Custom body @webhook-My_Web', // partial name should work
|
||||
view: {
|
||||
|
|
@ -617,8 +648,8 @@ describe('checkAlerts', () => {
|
|||
|
||||
await renderAlertTemplate({
|
||||
alertProvider,
|
||||
clickhouseClient: {} as any,
|
||||
metadata: {} as any,
|
||||
clickhouseClient: mockClickhouseClient,
|
||||
metadata: mockMetadata,
|
||||
state: AlertState.ALERT,
|
||||
template: 'Custom body @webhook-{{attributes.webhookName}}', // partial name should work
|
||||
view: {
|
||||
|
|
@ -687,8 +718,8 @@ describe('checkAlerts', () => {
|
|||
|
||||
await renderAlertTemplate({
|
||||
alertProvider,
|
||||
clickhouseClient: {} as any,
|
||||
metadata: {} as any,
|
||||
clickhouseClient: mockClickhouseClient,
|
||||
metadata: mockMetadata,
|
||||
state: AlertState.ALERT,
|
||||
template: `
|
||||
{{#is_match "attributes.k8s.pod.name" "otel-collector-123"}}
|
||||
|
|
@ -725,8 +756,8 @@ describe('checkAlerts', () => {
|
|||
// @webhook should not be called
|
||||
await renderAlertTemplate({
|
||||
alertProvider,
|
||||
clickhouseClient: {} as any,
|
||||
metadata: {} as any,
|
||||
clickhouseClient: mockClickhouseClient,
|
||||
metadata: mockMetadata,
|
||||
state: AlertState.ALERT,
|
||||
template:
|
||||
'{{#is_match "attributes.host" "web"}} @webhook-My_Web {{/is_match}}', // partial name should work
|
||||
|
|
@ -818,8 +849,8 @@ describe('checkAlerts', () => {
|
|||
|
||||
await renderAlertTemplate({
|
||||
alertProvider,
|
||||
clickhouseClient: {} as any,
|
||||
metadata: {} as any,
|
||||
clickhouseClient: mockClickhouseClient,
|
||||
metadata: mockMetadata,
|
||||
state: AlertState.OK, // Resolved state
|
||||
template: '@webhook-My_Webhook',
|
||||
view: {
|
||||
|
|
|
|||
|
|
@ -18,6 +18,16 @@ const MOCK_SAVED_SEARCH: any = {
|
|||
id: 'fake-saved-search-id',
|
||||
};
|
||||
|
||||
// Mock logger to suppress error output in tests for this file
|
||||
jest.mock('@/utils/logger', () => ({
|
||||
__esModule: true,
|
||||
default: {
|
||||
debug: jest.fn(),
|
||||
info: jest.fn(),
|
||||
warn: jest.fn(),
|
||||
error: jest.fn(),
|
||||
},
|
||||
}));
|
||||
describe('DefaultAlertProvider', () => {
|
||||
let provider: AlertProvider;
|
||||
const server = getServer();
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@
|
|||
"@/*": ["./*"]
|
||||
},
|
||||
"outDir": "build",
|
||||
"isolatedModules": true,
|
||||
"skipLibCheck": true,
|
||||
"sourceMap": true,
|
||||
"strict": true,
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@
|
|||
"nodemon": "^2.0.20",
|
||||
"rimraf": "^4.4.1",
|
||||
"supertest": "^6.3.1",
|
||||
"ts-jest": "^28.0.5",
|
||||
"ts-jest": "^29.4.5",
|
||||
"ts-node": "^10.8.1",
|
||||
"tsc-alias": "^1.8.8",
|
||||
"tsconfig-paths": "^4.2.0",
|
||||
|
|
|
|||
71
yarn.lock
71
yarn.lock
|
|
@ -4298,7 +4298,7 @@ __metadata:
|
|||
supertest: "npm:^6.3.1"
|
||||
swagger-jsdoc: "npm:^6.2.8"
|
||||
swagger-ui-express: "npm:^5.0.1"
|
||||
ts-jest: "npm:^28.0.5"
|
||||
ts-jest: "npm:^29.4.5"
|
||||
ts-node: "npm:^10.8.1"
|
||||
tsc-alias: "npm:^1.8.8"
|
||||
tsconfig-paths: "npm:^4.2.0"
|
||||
|
|
@ -4483,7 +4483,7 @@ __metadata:
|
|||
sqlstring: "npm:^2.3.3"
|
||||
store2: "npm:^2.14.4"
|
||||
supertest: "npm:^6.3.1"
|
||||
ts-jest: "npm:^28.0.5"
|
||||
ts-jest: "npm:^29.4.5"
|
||||
ts-node: "npm:^10.8.1"
|
||||
tsc-alias: "npm:^1.8.8"
|
||||
tsconfig-paths: "npm:^4.2.0"
|
||||
|
|
@ -11592,7 +11592,7 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"bs-logger@npm:0.x, bs-logger@npm:^0.2.6":
|
||||
"bs-logger@npm:^0.2.6":
|
||||
version: 0.2.6
|
||||
resolution: "bs-logger@npm:0.2.6"
|
||||
dependencies:
|
||||
|
|
@ -18711,7 +18711,7 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"jest-util@npm:^28.0.0, jest-util@npm:^28.1.3":
|
||||
"jest-util@npm:^28.1.3":
|
||||
version: 28.1.3
|
||||
resolution: "jest-util@npm:28.1.3"
|
||||
dependencies:
|
||||
|
|
@ -19085,7 +19085,7 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"json5@npm:^2.1.2, json5@npm:^2.2.1, json5@npm:^2.2.2, json5@npm:^2.2.3":
|
||||
"json5@npm:^2.1.2, json5@npm:^2.2.2, json5@npm:^2.2.3":
|
||||
version: 2.2.3
|
||||
resolution: "json5@npm:2.2.3"
|
||||
bin:
|
||||
|
|
@ -19534,7 +19534,7 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"lodash.memoize@npm:4.x, lodash.memoize@npm:^4.1.2":
|
||||
"lodash.memoize@npm:^4.1.2":
|
||||
version: 4.1.2
|
||||
resolution: "lodash.memoize@npm:4.1.2"
|
||||
checksum: 10c0/c8713e51eccc650422716a14cece1809cfe34bc5ab5e242b7f8b4e2241c2483697b971a604252807689b9dd69bfe3a98852e19a5b89d506b000b4187a1285df8
|
||||
|
|
@ -19759,7 +19759,7 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"make-error@npm:1.x, make-error@npm:^1.1.1, make-error@npm:^1.3.6":
|
||||
"make-error@npm:^1.1.1, make-error@npm:^1.3.6":
|
||||
version: 1.3.6
|
||||
resolution: "make-error@npm:1.3.6"
|
||||
checksum: 10c0/171e458d86854c6b3fc46610cfacf0b45149ba043782558c6875d9f42f222124384ad0b468c92e996d815a8a2003817a710c0a160e49c1c394626f76fa45396f
|
||||
|
|
@ -25215,17 +25215,6 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"semver@npm:7.x, semver@npm:^7.3.5, semver@npm:^7.3.7, semver@npm:^7.3.8, semver@npm:^7.5.2":
|
||||
version: 7.5.2
|
||||
resolution: "semver@npm:7.5.2"
|
||||
dependencies:
|
||||
lru-cache: "npm:^6.0.0"
|
||||
bin:
|
||||
semver: bin/semver.js
|
||||
checksum: 10c0/d151207ab762a8067f6302076edc04e5b8da2362eb9e3f21c2567ceadfd415064936d215b4aae7791da118c230649d29089be979ffa49c5b56a6bcf82147efdd
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"semver@npm:^6.0.0, semver@npm:^6.3.0, semver@npm:^6.3.1":
|
||||
version: 6.3.1
|
||||
resolution: "semver@npm:6.3.1"
|
||||
|
|
@ -25246,6 +25235,17 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"semver@npm:^7.3.5, semver@npm:^7.3.7, semver@npm:^7.3.8, semver@npm:^7.5.2":
|
||||
version: 7.5.2
|
||||
resolution: "semver@npm:7.5.2"
|
||||
dependencies:
|
||||
lru-cache: "npm:^6.0.0"
|
||||
bin:
|
||||
semver: bin/semver.js
|
||||
checksum: 10c0/d151207ab762a8067f6302076edc04e5b8da2362eb9e3f21c2567ceadfd415064936d215b4aae7791da118c230649d29089be979ffa49c5b56a6bcf82147efdd
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"semver@npm:^7.6.0, semver@npm:^7.6.2":
|
||||
version: 7.6.2
|
||||
resolution: "semver@npm:7.6.2"
|
||||
|
|
@ -27186,39 +27186,6 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"ts-jest@npm:^28.0.5":
|
||||
version: 28.0.8
|
||||
resolution: "ts-jest@npm:28.0.8"
|
||||
dependencies:
|
||||
bs-logger: "npm:0.x"
|
||||
fast-json-stable-stringify: "npm:2.x"
|
||||
jest-util: "npm:^28.0.0"
|
||||
json5: "npm:^2.2.1"
|
||||
lodash.memoize: "npm:4.x"
|
||||
make-error: "npm:1.x"
|
||||
semver: "npm:7.x"
|
||||
yargs-parser: "npm:^21.0.1"
|
||||
peerDependencies:
|
||||
"@babel/core": ">=7.0.0-beta.0 <8"
|
||||
"@jest/types": ^28.0.0
|
||||
babel-jest: ^28.0.0
|
||||
jest: ^28.0.0
|
||||
typescript: ">=4.3"
|
||||
peerDependenciesMeta:
|
||||
"@babel/core":
|
||||
optional: true
|
||||
"@jest/types":
|
||||
optional: true
|
||||
babel-jest:
|
||||
optional: true
|
||||
esbuild:
|
||||
optional: true
|
||||
bin:
|
||||
ts-jest: cli.js
|
||||
checksum: 10c0/4f6d7c8dbf6deaf56f4490ae819071077e8ed30c1a3c87c7d2e21b3103e6d12aaa53d2776cb5c947bac3f3a05cd9f8dea2aedc4c6550c14fbf639c1368a0fbc9
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"ts-jest@npm:^29.4.5":
|
||||
version: 29.4.5
|
||||
resolution: "ts-jest@npm:29.4.5"
|
||||
|
|
@ -28978,7 +28945,7 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"yargs-parser@npm:21.1.1, yargs-parser@npm:^21.0.1, yargs-parser@npm:^21.1.1":
|
||||
"yargs-parser@npm:21.1.1, yargs-parser@npm:^21.1.1":
|
||||
version: 21.1.1
|
||||
resolution: "yargs-parser@npm:21.1.1"
|
||||
checksum: 10c0/f84b5e48169479d2f402239c59f084cfd1c3acc197a05c59b98bab067452e6b3ea46d4dd8ba2985ba7b3d32a343d77df0debd6b343e5dae3da2aab2cdf5886b2
|
||||
|
|
|
|||
Loading…
Reference in a new issue