Skip to content

Commit

Permalink
tests
Browse files Browse the repository at this point in the history
  • Loading branch information
lforst committed Jul 22, 2024
1 parent c5a4770 commit 3f51221
Show file tree
Hide file tree
Showing 11 changed files with 184 additions and 9 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { loggingTransport } from '@sentry-internal/node-integration-tests';
import * as Sentry from '@sentry/node';

// eslint-disable-next-line @typescript-eslint/no-floating-promises
(async () => {
Sentry.init({
dsn: 'https://public@dsn.ingest.sentry.io/1337',
transport: loggingTransport,
beforeSend(event) {
return !event.type ? null : event;
},
});

Sentry.captureException(new Error('this should get dropped by the event processor'));

await Sentry.flush();

Sentry.captureException(new Error('this should get dropped by the event processor'));
Sentry.captureException(new Error('this should get dropped by the event processor'));

// eslint-disable-next-line @typescript-eslint/no-floating-promises
Sentry.flush();
})();
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { cleanupChildProcesses, createRunner } from '../../../../utils/runner';

afterAll(() => {
cleanupChildProcesses();
});

test('should record client report for beforeSend', done => {
createRunner(__dirname, 'scenario.ts')
.expect({
client_report: {
discarded_events: [
{
category: 'error',
quantity: 1,
reason: 'before_send',
},
],
},
})
.expect({
client_report: {
discarded_events: [
{
category: 'error',
quantity: 2,
reason: 'before_send',
},
],
},
})
.start(done);
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { loggingTransport } from '@sentry-internal/node-integration-tests';
import * as Sentry from '@sentry/node';

// eslint-disable-next-line @typescript-eslint/no-floating-promises
(async () => {
Sentry.init({
dsn: 'https://public@dsn.ingest.sentry.io/1337',
transport: loggingTransport,
});

Sentry.addEventProcessor(event => {
return !event.type ? null : event;
});

Sentry.captureException(new Error('this should get dropped by the event processor'));

await Sentry.flush();

Sentry.captureException(new Error('this should get dropped by the event processor'));
Sentry.captureException(new Error('this should get dropped by the event processor'));

// eslint-disable-next-line @typescript-eslint/no-floating-promises
Sentry.flush();
})();
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { cleanupChildProcesses, createRunner } from '../../../../utils/runner';

afterAll(() => {
cleanupChildProcesses();
});

test('should record client report for event processors', done => {
createRunner(__dirname, 'scenario.ts')
.expect({
client_report: {
discarded_events: [
{
category: 'error',
quantity: 1,
reason: 'event_processor',
},
],
},
})
.expect({
client_report: {
discarded_events: [
{
category: 'error',
quantity: 2,
reason: 'event_processor',
},
],
},
})
.start(done);
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { loggingTransport } from '@sentry-internal/node-integration-tests';
import * as Sentry from '@sentry/node';

Sentry.init({
dsn: 'https://public@dsn.ingest.sentry.io/1337',
transport: loggingTransport,
clientReportFlushInterval: 5000,
beforeSend(event) {
return !event.type ? null : event;
},
});

Sentry.captureException(new Error('this should get dropped by before send'));
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { cleanupChildProcesses, createRunner } from '../../../utils/runner';

afterAll(() => {
cleanupChildProcesses();
});

test('should flush client reports automatically after the timeout interval', done => {
createRunner(__dirname, 'scenario.ts')
.expect({
client_report: {
discarded_events: [
{
category: 'error',
quantity: 1,
reason: 'before_send',
},
],
},
})
.start(done);
});
21 changes: 21 additions & 0 deletions dev-packages/node-integration-tests/utils/runner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { spawn, spawnSync } from 'child_process';
import { join } from 'path';
import { SDK_VERSION } from '@sentry/node';
import type {
ClientReport,
Envelope,
EnvelopeItemType,
Event,
Expand Down Expand Up @@ -46,6 +47,12 @@ export function assertSentryCheckIn(actual: SerializedCheckIn, expected: Partial
});
}

export function assertSentryClientReport(actual: ClientReport, expected: Partial<ClientReport>): void {
expect(actual).toMatchObject({
...expected,
});
}

export function assertEnvelopeHeader(actual: Envelope[0], expected: Partial<Envelope[0]>): void {
expect(actual).toEqual({
event_id: expect.any(String),
Expand Down Expand Up @@ -148,6 +155,9 @@ type Expected =
}
| {
check_in: Partial<SerializedCheckIn> | ((event: SerializedCheckIn) => void);
}
| {
client_report: Partial<ClientReport> | ((event: ClientReport) => void);
};

type ExpectedEnvelopeHeader =
Expand Down Expand Up @@ -332,6 +342,17 @@ export function createRunner(...paths: string[]) {

expectCallbackCalled();
}

if ('client_report' in expected) {
const clientReport = item[1] as ClientReport;
if (typeof expected.client_report === 'function') {
expected.client_report(clientReport);
} else {
assertSentryClientReport(clientReport, expected.client_report);
}

expectCallbackCalled();
}
} catch (e) {
complete(e as Error);
}
Expand Down
18 changes: 11 additions & 7 deletions packages/node/src/sdk/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { isMainThread, threadId } from 'worker_threads';
import { DEBUG_BUILD } from '../debug-build';
import type { NodeClientOptions } from '../types';

const CLIENT_REPORT_FLUSH_INTERVAL_MS = 60_000; // 60s was chosen arbitrarily
const DEFAULT_CLIENT_REPORT_FLUSH_INTERVAL_MS = 60_000; // 60s was chosen arbitrarily

/** A client for using Sentry with Node & OpenTelemetry. */
export class NodeClient extends ServerRuntimeClient<NodeClientOptions> {
Expand Down Expand Up @@ -59,7 +59,7 @@ export class NodeClient extends ServerRuntimeClient<NodeClientOptions> {
await spanProcessor.forceFlush();
}

if (this.getOptions().sendClientReports !== false) {
if (this.getOptions().sendClientReports) {
this._flushOutcomes();
}

Expand Down Expand Up @@ -96,15 +96,19 @@ export class NodeClient extends ServerRuntimeClient<NodeClientOptions> {
// Note: We have experimented with using `FinalizationRegisty` to clear the interval when the client is garbage
// collected, but it did not work, because the cleanup function never got called.
public startClientReportTracking(): void {
if (this.getOptions().sendClientReports !== false) {
const clientOptions = this.getOptions();
if (clientOptions.sendClientReports) {
this._clientReportOnExitFlushListener = () => {
this._flushOutcomes();
};

this._clientReportInterval = setInterval(() => {
DEBUG_BUILD && logger.log('Flushing client reports based on interval.');
this._flushOutcomes();
}, CLIENT_REPORT_FLUSH_INTERVAL_MS)
this._clientReportInterval = setInterval(
() => {
DEBUG_BUILD && logger.log('Flushing client reports based on interval.');
this._flushOutcomes();
},
clientOptions.clientReportFlushInterval ?? DEFAULT_CLIENT_REPORT_FLUSH_INTERVAL_MS,
)
// Unref is critical for not preventing the process from exiting because the interval is active.
.unref();

Expand Down
1 change: 1 addition & 0 deletions packages/node/src/sdk/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,7 @@ function getClientOptions(
transport: makeNodeTransport,
dsn: process.env.SENTRY_DSN,
environment: process.env.SENTRY_ENVIRONMENT,
sendClientReports: true,
});

const overwriteOptions = dropUndefinedKeys({
Expand Down
5 changes: 5 additions & 0 deletions packages/node/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,11 @@ export interface BaseNodeOptions {
*/
registerEsmLoaderHooks?: boolean | EsmLoaderHookOptions;

/**
* Configures in which interval client reports will be flushed. Defaults to `60_000` (milliseconds).
*/
clientReportFlushInterval?: number;

/** Callback that is executed when a fatal global error occurs. */
onFatalError?(this: void, error: Error): void;
}
Expand Down
3 changes: 1 addition & 2 deletions packages/types/src/options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,7 @@ export interface ClientOptions<TO extends BaseTransportOptions = BaseTransportOp
autoSessionTracking?: boolean;

/**
* Send SDK Client Reports.
* By default, Client Reports are enabled.
* Send SDK Client Reports. When calling `Sentry.init()`, this option defaults to `true`.
*/
sendClientReports?: boolean;

Expand Down

0 comments on commit 3f51221

Please sign in to comment.