@@ -2,34 +2,72 @@ import * as SentryNode from '@sentry/node';
22import * as AWS from 'aws-sdk' ;
33import * as nock from 'nock' ;
44
5- import { AWSServices } from '../src/awsservices' ;
5+ import { awsServicesIntegration } from '../src/awsservices' ;
66
7- describe ( 'AWSServices' , ( ) => {
8- beforeAll ( ( ) => {
9- new AWSServices ( ) . setupOnce ( ) ;
7+ const mockSpanEnd = jest . fn ( ) ;
8+ const mockStartInactiveSpan = jest . fn ( spanArgs => ( { ...spanArgs } ) ) ;
9+
10+ jest . mock ( '@sentry/node' , ( ) => {
11+ return {
12+ ...jest . requireActual ( '@sentry/node' ) ,
13+ startInactiveSpan : ( ctx : unknown ) => {
14+ mockStartInactiveSpan ( ctx ) ;
15+ return { end : mockSpanEnd } ;
16+ } ,
17+ } ;
18+ } ) ;
19+
20+ describe ( 'awsServicesIntegration' , ( ) => {
21+ const mockClient = new SentryNode . NodeClient ( {
22+ tracesSampleRate : 1.0 ,
23+ integrations : [ ] ,
24+ dsn : 'https://withAWSServices@domain/123' ,
25+ transport : ( ) => SentryNode . createTransport ( { recordDroppedEvent : ( ) => undefined } , _ => Promise . resolve ( { } ) ) ,
26+ stackParser : ( ) => [ ] ,
1027 } ) ;
11- afterEach ( ( ) => {
12- // @ts -expect-error see "Why @ts-expect-error" note
13- SentryNode . resetMocks ( ) ;
28+
29+ const integration = awsServicesIntegration ( ) ;
30+ mockClient . addIntegration ( integration ) ;
31+
32+ const mockClientWithoutIntegration = new SentryNode . NodeClient ( {
33+ tracesSampleRate : 1.0 ,
34+ integrations : [ ] ,
35+ dsn : 'https://withoutAWSServices@domain/123' ,
36+ transport : ( ) => SentryNode . createTransport ( { recordDroppedEvent : ( ) => undefined } , _ => Promise . resolve ( { } ) ) ,
37+ stackParser : ( ) => [ ] ,
1438 } ) ;
39+
1540 afterAll ( ( ) => {
1641 nock . restore ( ) ;
1742 } ) ;
1843
44+ beforeEach ( ( ) => {
45+ SentryNode . setCurrentClient ( mockClient ) ;
46+ mockSpanEnd . mockClear ( ) ;
47+ mockStartInactiveSpan . mockClear ( ) ;
48+ } ) ;
49+
1950 describe ( 'S3 tracing' , ( ) => {
2051 const s3 = new AWS . S3 ( { accessKeyId : '-' , secretAccessKey : '-' } ) ;
2152
2253 test ( 'getObject' , async ( ) => {
2354 nock ( 'https://foo.s3.amazonaws.com' ) . get ( '/bar' ) . reply ( 200 , 'contents' ) ;
2455 const data = await s3 . getObject ( { Bucket : 'foo' , Key : 'bar' } ) . promise ( ) ;
2556 expect ( data . Body ?. toString ( 'utf-8' ) ) . toEqual ( 'contents' ) ;
26- expect ( SentryNode . startInactiveSpan ) . toBeCalledWith ( {
57+ expect ( mockStartInactiveSpan ) . toBeCalledWith ( {
2758 op : 'http.client' ,
2859 origin : 'auto.http.serverless' ,
2960 name : 'aws.s3.getObject foo' ,
3061 } ) ;
31- // @ts -expect-error see "Why @ts-expect-error" note
32- expect ( SentryNode . fakeSpan . end ) . toBeCalled ( ) ;
62+
63+ expect ( mockSpanEnd ) . toHaveBeenCalledTimes ( 1 ) ;
64+ } ) ;
65+
66+ test ( 'getObject with integration-less client' , async ( ) => {
67+ SentryNode . setCurrentClient ( mockClientWithoutIntegration ) ;
68+ nock ( 'https://foo.s3.amazonaws.com' ) . get ( '/bar' ) . reply ( 200 , 'contents' ) ;
69+ await s3 . getObject ( { Bucket : 'foo' , Key : 'bar' } ) . promise ( ) ;
70+ expect ( mockStartInactiveSpan ) . not . toBeCalled ( ) ;
3371 } ) ;
3472
3573 test ( 'getObject with callback' , done => {
@@ -40,12 +78,22 @@ describe('AWSServices', () => {
4078 expect ( data . Body ?. toString ( 'utf-8' ) ) . toEqual ( 'contents' ) ;
4179 done ( ) ;
4280 } ) ;
43- expect ( SentryNode . startInactiveSpan ) . toBeCalledWith ( {
81+ expect ( mockStartInactiveSpan ) . toBeCalledWith ( {
4482 op : 'http.client' ,
4583 origin : 'auto.http.serverless' ,
4684 name : 'aws.s3.getObject foo' ,
4785 } ) ;
4886 } ) ;
87+
88+ test ( 'getObject with callback with integration-less client' , done => {
89+ SentryNode . setCurrentClient ( mockClientWithoutIntegration ) ;
90+ expect . assertions ( 1 ) ;
91+ nock ( 'https://foo.s3.amazonaws.com' ) . get ( '/bar' ) . reply ( 200 , 'contents' ) ;
92+ s3 . getObject ( { Bucket : 'foo' , Key : 'bar' } , ( ) => {
93+ done ( ) ;
94+ } ) ;
95+ expect ( mockStartInactiveSpan ) . not . toBeCalled ( ) ;
96+ } ) ;
4997 } ) ;
5098
5199 describe ( 'Lambda' , ( ) => {
@@ -55,11 +103,19 @@ describe('AWSServices', () => {
55103 nock ( 'https://lambda.eu-north-1.amazonaws.com' ) . post ( '/2015-03-31/functions/foo/invocations' ) . reply ( 201 , 'reply' ) ;
56104 const data = await lambda . invoke ( { FunctionName : 'foo' } ) . promise ( ) ;
57105 expect ( data . Payload ?. toString ( 'utf-8' ) ) . toEqual ( 'reply' ) ;
58- expect ( SentryNode . startInactiveSpan ) . toBeCalledWith ( {
106+ expect ( mockStartInactiveSpan ) . toBeCalledWith ( {
59107 op : 'http.client' ,
60108 origin : 'auto.http.serverless' ,
61109 name : 'aws.lambda.invoke foo' ,
62110 } ) ;
111+ expect ( mockSpanEnd ) . toHaveBeenCalledTimes ( 1 ) ;
112+ } ) ;
113+
114+ test ( 'invoke with integration-less client' , async ( ) => {
115+ SentryNode . setCurrentClient ( mockClientWithoutIntegration ) ;
116+ nock ( 'https://lambda.eu-north-1.amazonaws.com' ) . post ( '/2015-03-31/functions/foo/invocations' ) . reply ( 201 , 'reply' ) ;
117+ await lambda . invoke ( { FunctionName : 'foo' } ) . promise ( ) ;
118+ expect ( mockStartInactiveSpan ) . not . toBeCalled ( ) ;
63119 } ) ;
64120 } ) ;
65121} ) ;
0 commit comments