Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

tests(e2e): Refactor nestjs e2e applications into multiple smaller test applications #12948

Merged
merged 8 commits into from
Jul 18, 2024

Conversation

nicohrubec
Copy link
Contributor

@nicohrubec nicohrubec commented Jul 17, 2024

Refactor of the existing nestjs test applications. Before we had one sample application testing everything nest-related. This PR splits them up into three applications to make it more readable and easier to understand what is being tested. It also allows for iterating a bit quicker in local development.

No new functionality was added. Will add more tests in a follow-up.

The three new services are:

  • nestjs-basic: Simple nestjs application with no submodules and tests for basic functionality of the SDK like error monitoring and span instrumentation.
  • nestjs-with-submodules: NestJS application that is bit more complex including a submodule (and potentially multiple in the future) to have a more realistic setup for more advanced testing.
  • nestjs-distributed-tracing: Includes tests for trace propagation with multiple services.

@nicohrubec nicohrubec requested a review from lforst July 17, 2024 14:07
@nicohrubec nicohrubec marked this pull request as ready for review July 17, 2024 14:21
import * as Sentry from '@sentry/nestjs';
import { AppModule } from './app.module';

const app1Port = 3030;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
const app1Port = 3030;
const PORT = 3030;

const { httpAdapter } = app.get(HttpAdapterHost);
Sentry.setupNestErrorHandler(app, new BaseExceptionFilter(httpAdapter));

await app.listen(app1Port);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
await app.listen(app1Port);
await app.listen(PORT);

Comment on lines 49 to 64
@Injectable()
export class AppService2 {
externalAllowed(headers: Record<string, string>) {
return {
headers,
route: 'external-allowed',
};
}

externalDisallowed(headers: Record<string, string>) {
return {
headers,
route: 'external-disallowed',
};
}
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

m: would generally move each service into its own file and use more descriptive names instead of AppService1 AppService2 etc.

Copy link
Member

@Lms24 Lms24 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1st pass review: Would you mind adding the purpose of the three new apps to the PR description? Just a brief description of what they do or how they differ from each other would be great for future and external readers :)

import * as Sentry from '@sentry/nestjs';
import { AppModule } from './app.module';

const app1Port = 3030;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
const app1Port = 3030;
const PORT = 3030;

const { httpAdapter } = app1.get(HttpAdapterHost);
Sentry.setupNestErrorHandler(app1, new BaseExceptionFilter(httpAdapter));

await app1.listen(app1Port);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
await app1.listen(app1Port);
await app1.listen(PORT);

Copy link
Member

@chargome chargome left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good! I would just try to prevent naming services etc. with numerical suffixes.

@nicohrubec
Copy link
Contributor Author

@Lms24 Sure good idea, updated the PR description :)

Copy link
Member

@Lms24 Lms24 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for adding the explanation! Looks good to me (once all feedback is addressed)

Comment on lines +2 to +3
"compilerOptions": {
"module": "commonjs",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

out of scope for this PR but idea for once #12920 is ready: In one of these apps we could set "moduleResolution": "Node16" to ensure our "workaround" from yesterday works in both, default and sub-path-export-compatible TS configs.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sounds good, noted!

@nicohrubec
Copy link
Contributor Author

@chargome I just copied what was there before, but definitely agree about the naming. I split up the two services into separate files and renamed them to TraceInitiator and TraceReceiver, should be more clear

Copy link
Contributor

size-limit report 📦

Path Size
@sentry/browser 22.3 KB (0%)
@sentry/browser (incl. Tracing) 33.72 KB (+0.09% 🔺)
@sentry/browser (incl. Tracing, Replay) 69.81 KB (+0.04% 🔺)
@sentry/browser (incl. Tracing, Replay) - with treeshaking flags 63.11 KB (+0.04% 🔺)
@sentry/browser (incl. Tracing, Replay with Canvas) 74.2 KB (+0.04% 🔺)
@sentry/browser (incl. Tracing, Replay, Feedback) 86.52 KB (+0.04% 🔺)
@sentry/browser (incl. Tracing, Replay, Feedback, metrics) 88.39 KB (+0.04% 🔺)
@sentry/browser (incl. metrics) 26.62 KB (+0.11% 🔺)
@sentry/browser (incl. Feedback) 38.98 KB (0%)
@sentry/browser (incl. sendFeedback) 26.93 KB (0%)
@sentry/browser (incl. FeedbackAsync) 31.54 KB (0%)
@sentry/react 25.06 KB (0%)
@sentry/react (incl. Tracing) 36.79 KB (+0.09% 🔺)
@sentry/vue 26.44 KB (+0.13% 🔺)
@sentry/vue (incl. Tracing) 35.6 KB (+0.07% 🔺)
@sentry/svelte 22.44 KB (0%)
CDN Bundle 23.52 KB (0%)
CDN Bundle (incl. Tracing) 35.5 KB (+0.09% 🔺)
CDN Bundle (incl. Tracing, Replay) 69.91 KB (+0.05% 🔺)
CDN Bundle (incl. Tracing, Replay, Feedback) 75.17 KB (+0.05% 🔺)
CDN Bundle - uncompressed 69 KB (0%)
CDN Bundle (incl. Tracing) - uncompressed 105.1 KB (+0.16% 🔺)
CDN Bundle (incl. Tracing, Replay) - uncompressed 216.88 KB (+0.08% 🔺)
CDN Bundle (incl. Tracing, Replay, Feedback) - uncompressed 229.6 KB (+0.07% 🔺)
@sentry/nextjs (client) 36.64 KB (+0.07% 🔺)
@sentry/sveltekit (client) 34.37 KB (+0.08% 🔺)
@sentry/node 111.28 KB (0%)
@sentry/node - without tracing 88.73 KB (+0.01% 🔺)
@sentry/aws-serverless 97.87 KB (0%)

@nicohrubec nicohrubec self-assigned this Jul 18, 2024
@nicohrubec nicohrubec merged commit d629991 into develop Jul 18, 2024
123 checks passed
@nicohrubec nicohrubec deleted the nh/improve-nest-tests branch July 18, 2024 10:04
nicohrubec added a commit that referenced this pull request Jul 23, 2024
- Adds a new nest root module that can be used to setup the Nest SDK as
a replacement for the existing setup (with a function). Instead of
calling `setupNestErrorHandler` in the main.ts file, users can now add
`SentryModule.forRoot()` (feedback about the name is definitely welcome)
as an import in their main app module. This approach is much more native
to nest than what we used so far. This root module is introduced in the
setup.ts file.
- This root module is exported with a submodule export
`@sentry/nestjs/setup`, because the SDK now depends on nestjs directly
and without this the nest instrumentation does not work anymore, since
nest gets imported before Sentry.init gets called, which disables the
otel nest instrumentation.
- Judging from the e2e tests it seems that this new approach also
resolves some issues the previous implementation had, specifically [this
issue](#12351)
seems to be resolved. The e2e test that was in place, just documented
the current (wrong) behavior. So I updated the test to reflect the new
(correct) behavior.
- I updated all the test applications to use the new approach but kept a
copy of the nestjs-basic and nestjs-distributed-tracing with the old
setup (now named node-nestjs-basic and node-nestjs-distributed-tracing
respectively) so we can still verify that the old setup (which a lot of
people use) still keeps working going forward.
- Updated/New tests in this PR: 
    - Sends unexpected exception to Sentry if thrown in Submodule
- Does not send expected exception to Sentry if thrown in Submodule and
caught by a global exception filter
- Does not send expected exception to Sentry if thrown in Submodule and
caught by a local exception filter
- Sends expected exception to Sentry if thrown from submodule registered
before Sentry
- To accomodate the new tests I added several submodules in the
nestjs-with-submodules test-application. These are overall similarly but
have important distinctions:
- example-module-local-filter: Submodule with a local filter registered
using `@UseFilters` on the controller.
- example-module-global-filter: Submodule with a global filter
registered using APP_FILTER in the submodule definition.
- example-module-global-filter-wrong-registration-order: Also has a
global filter set with APP_FILTER, but is registered in the root module
as first submodule, even before the SentryIntegration is initialized.
This case does not work properly in the new setup (Sentry should be set
first), so this module is used for tests documenting this behavior.
- Also set "moduleResolution": "Node16" in the nestjs-basic sample app
to ensure our submodule-export workaround works in both, default and
sub-path-export-compatible TS configs as was suggested
[here](#12948 (comment)).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants