11import { getSDKSource } from '@sentry/core' ;
22import { initWithoutDefaultIntegrations } from '@sentry/node' ;
3- import { describe , expect , test , vi } from 'vitest' ;
3+ import { beforeEach , describe , expect , test , vi } from 'vitest' ;
44import type { AwsServerlessOptions } from '../src/init' ;
55import { init } from '../src/init' ;
66
@@ -18,6 +18,12 @@ const mockGetSDKSource = vi.mocked(getSDKSource);
1818const mockInitWithoutDefaultIntegrations = vi . mocked ( initWithoutDefaultIntegrations ) ;
1919
2020describe ( 'init' , ( ) => {
21+ beforeEach ( ( ) => {
22+ // Clean up environment variables between tests
23+ delete process . env . http_proxy ;
24+ delete process . env . no_proxy ;
25+ } ) ;
26+
2127 describe ( 'Lambda extension setup' , ( ) => {
2228 test ( 'should preserve user-provided tunnel option when Lambda extension is enabled' , ( ) => {
2329 mockGetSDKSource . mockReturnValue ( 'aws-lambda-layer' ) ;
@@ -128,4 +134,256 @@ describe('init', () => {
128134 ) ;
129135 } ) ;
130136 } ) ;
137+
138+ describe ( 'proxy environment variables and layer extension' , ( ) => {
139+ test ( 'should enable useLayerExtension when no proxy env vars are set' , ( ) => {
140+ mockGetSDKSource . mockReturnValue ( 'aws-lambda-layer' ) ;
141+ const options : AwsServerlessOptions = { } ;
142+
143+ init ( options ) ;
144+
145+ expect ( mockInitWithoutDefaultIntegrations ) . toHaveBeenCalledWith (
146+ expect . objectContaining ( {
147+ useLayerExtension : true ,
148+ tunnel : 'http://localhost:9000/envelope' ,
149+ } ) ,
150+ ) ;
151+ } ) ;
152+
153+ test ( 'should disable useLayerExtension when http_proxy is set' , ( ) => {
154+ process . env . http_proxy = 'http://proxy.example.com:8080' ;
155+ mockGetSDKSource . mockReturnValue ( 'aws-lambda-layer' ) ;
156+ const options : AwsServerlessOptions = { } ;
157+
158+ init ( options ) ;
159+
160+ expect ( mockInitWithoutDefaultIntegrations ) . toHaveBeenCalledWith (
161+ expect . objectContaining ( {
162+ useLayerExtension : false ,
163+ } ) ,
164+ ) ;
165+ expect ( mockInitWithoutDefaultIntegrations ) . toHaveBeenCalledWith (
166+ expect . not . objectContaining ( {
167+ tunnel : expect . any ( String ) ,
168+ } ) ,
169+ ) ;
170+ } ) ;
171+
172+ describe ( 'no_proxy patterns' , ( ) => {
173+ test ( 'should enable useLayerExtension when no_proxy=* (wildcard)' , ( ) => {
174+ process . env . http_proxy = 'http://proxy.example.com:8080' ;
175+ process . env . no_proxy = '*' ;
176+ mockGetSDKSource . mockReturnValue ( 'aws-lambda-layer' ) ;
177+ const options : AwsServerlessOptions = { } ;
178+
179+ init ( options ) ;
180+
181+ expect ( mockInitWithoutDefaultIntegrations ) . toHaveBeenCalledWith (
182+ expect . objectContaining ( {
183+ useLayerExtension : true ,
184+ tunnel : 'http://localhost:9000/envelope' ,
185+ } ) ,
186+ ) ;
187+ } ) ;
188+
189+ test ( 'should enable useLayerExtension when no_proxy contains localhost' , ( ) => {
190+ process . env . http_proxy = 'http://proxy.example.com:8080' ;
191+ process . env . no_proxy = 'localhost' ;
192+ mockGetSDKSource . mockReturnValue ( 'aws-lambda-layer' ) ;
193+ const options : AwsServerlessOptions = { } ;
194+
195+ init ( options ) ;
196+
197+ expect ( mockInitWithoutDefaultIntegrations ) . toHaveBeenCalledWith (
198+ expect . objectContaining ( {
199+ useLayerExtension : true ,
200+ tunnel : 'http://localhost:9000/envelope' ,
201+ } ) ,
202+ ) ;
203+ } ) ;
204+
205+ test ( 'should enable useLayerExtension when no_proxy contains 127.0.0.1' , ( ) => {
206+ process . env . http_proxy = 'http://proxy.example.com:8080' ;
207+ process . env . no_proxy = '127.0.0.1' ;
208+ mockGetSDKSource . mockReturnValue ( 'aws-lambda-layer' ) ;
209+ const options : AwsServerlessOptions = { } ;
210+
211+ init ( options ) ;
212+
213+ expect ( mockInitWithoutDefaultIntegrations ) . toHaveBeenCalledWith (
214+ expect . objectContaining ( {
215+ useLayerExtension : true ,
216+ tunnel : 'http://localhost:9000/envelope' ,
217+ } ) ,
218+ ) ;
219+ } ) ;
220+
221+ test ( 'should enable useLayerExtension when no_proxy contains ::1' , ( ) => {
222+ process . env . http_proxy = 'http://proxy.example.com:8080' ;
223+ process . env . no_proxy = '::1' ;
224+ mockGetSDKSource . mockReturnValue ( 'aws-lambda-layer' ) ;
225+ const options : AwsServerlessOptions = { } ;
226+
227+ init ( options ) ;
228+
229+ expect ( mockInitWithoutDefaultIntegrations ) . toHaveBeenCalledWith (
230+ expect . objectContaining ( {
231+ useLayerExtension : true ,
232+ tunnel : 'http://localhost:9000/envelope' ,
233+ } ) ,
234+ ) ;
235+ } ) ;
236+
237+ test ( 'should enable useLayerExtension when no_proxy contains localhost in a comma-separated list' , ( ) => {
238+ process . env . http_proxy = 'http://proxy.example.com:8080' ;
239+ process . env . no_proxy = 'example.com,localhost,other.com' ;
240+ mockGetSDKSource . mockReturnValue ( 'aws-lambda-layer' ) ;
241+ const options : AwsServerlessOptions = { } ;
242+
243+ init ( options ) ;
244+
245+ expect ( mockInitWithoutDefaultIntegrations ) . toHaveBeenCalledWith (
246+ expect . objectContaining ( {
247+ useLayerExtension : true ,
248+ tunnel : 'http://localhost:9000/envelope' ,
249+ } ) ,
250+ ) ;
251+ } ) ;
252+
253+ test ( 'should disable useLayerExtension when no_proxy does not contain localhost patterns' , ( ) => {
254+ process . env . http_proxy = 'http://proxy.example.com:8080' ;
255+ process . env . no_proxy = 'example.com,other.com' ;
256+ mockGetSDKSource . mockReturnValue ( 'aws-lambda-layer' ) ;
257+ const options : AwsServerlessOptions = { } ;
258+
259+ init ( options ) ;
260+
261+ expect ( mockInitWithoutDefaultIntegrations ) . toHaveBeenCalledWith (
262+ expect . objectContaining ( {
263+ useLayerExtension : false ,
264+ } ) ,
265+ ) ;
266+ expect ( mockInitWithoutDefaultIntegrations ) . toHaveBeenCalledWith (
267+ expect . not . objectContaining ( {
268+ tunnel : expect . any ( String ) ,
269+ } ) ,
270+ ) ;
271+ } ) ;
272+
273+ test ( 'should disable useLayerExtension when no_proxy contains host (no longer supported)' , ( ) => {
274+ process . env . http_proxy = 'http://proxy.example.com:8080' ;
275+ process . env . no_proxy = 'host' ;
276+ mockGetSDKSource . mockReturnValue ( 'aws-lambda-layer' ) ;
277+ const options : AwsServerlessOptions = { } ;
278+
279+ init ( options ) ;
280+
281+ expect ( mockInitWithoutDefaultIntegrations ) . toHaveBeenCalledWith (
282+ expect . objectContaining ( {
283+ useLayerExtension : false ,
284+ } ) ,
285+ ) ;
286+ expect ( mockInitWithoutDefaultIntegrations ) . toHaveBeenCalledWith (
287+ expect . not . objectContaining ( {
288+ tunnel : expect . any ( String ) ,
289+ } ) ,
290+ ) ;
291+ } ) ;
292+
293+ test ( 'should handle case-insensitive no_proxy values' , ( ) => {
294+ process . env . http_proxy = 'http://proxy.example.com:8080' ;
295+ process . env . no_proxy = 'LOCALHOST' ;
296+ mockGetSDKSource . mockReturnValue ( 'aws-lambda-layer' ) ;
297+ const options : AwsServerlessOptions = { } ;
298+
299+ init ( options ) ;
300+
301+ expect ( mockInitWithoutDefaultIntegrations ) . toHaveBeenCalledWith (
302+ expect . objectContaining ( {
303+ useLayerExtension : true ,
304+ tunnel : 'http://localhost:9000/envelope' ,
305+ } ) ,
306+ ) ;
307+ } ) ;
308+
309+ test ( 'should handle whitespace in no_proxy values' , ( ) => {
310+ process . env . http_proxy = 'http://proxy.example.com:8080' ;
311+ process . env . no_proxy = ' localhost , example.com ' ;
312+ mockGetSDKSource . mockReturnValue ( 'aws-lambda-layer' ) ;
313+ const options : AwsServerlessOptions = { } ;
314+
315+ init ( options ) ;
316+
317+ expect ( mockInitWithoutDefaultIntegrations ) . toHaveBeenCalledWith (
318+ expect . objectContaining ( {
319+ useLayerExtension : true ,
320+ tunnel : 'http://localhost:9000/envelope' ,
321+ } ) ,
322+ ) ;
323+ } ) ;
324+ } ) ;
325+
326+ test ( 'should respect explicit useLayerExtension=false even with no proxy interference' , ( ) => {
327+ mockGetSDKSource . mockReturnValue ( 'aws-lambda-layer' ) ;
328+ const options : AwsServerlessOptions = {
329+ useLayerExtension : false ,
330+ } ;
331+
332+ init ( options ) ;
333+
334+ expect ( mockInitWithoutDefaultIntegrations ) . toHaveBeenCalledWith (
335+ expect . objectContaining ( {
336+ useLayerExtension : false ,
337+ } ) ,
338+ ) ;
339+ expect ( mockInitWithoutDefaultIntegrations ) . toHaveBeenCalledWith (
340+ expect . not . objectContaining ( {
341+ tunnel : expect . any ( String ) ,
342+ } ) ,
343+ ) ;
344+ } ) ;
345+
346+ test ( 'should respect explicit useLayerExtension=false even with proxy that would interfere' , ( ) => {
347+ process . env . http_proxy = 'http://proxy.example.com:8080' ;
348+ mockGetSDKSource . mockReturnValue ( 'aws-lambda-layer' ) ;
349+ const options : AwsServerlessOptions = {
350+ useLayerExtension : false ,
351+ } ;
352+
353+ init ( options ) ;
354+
355+ expect ( mockInitWithoutDefaultIntegrations ) . toHaveBeenCalledWith (
356+ expect . objectContaining ( {
357+ useLayerExtension : false ,
358+ } ) ,
359+ ) ;
360+ expect ( mockInitWithoutDefaultIntegrations ) . toHaveBeenCalledWith (
361+ expect . not . objectContaining ( {
362+ tunnel : expect . any ( String ) ,
363+ } ) ,
364+ ) ;
365+ } ) ;
366+
367+ test ( 'should respect explicit useLayerExtension=false even when no_proxy would enable it' , ( ) => {
368+ process . env . http_proxy = 'http://proxy.example.com:8080' ;
369+ process . env . no_proxy = 'localhost' ;
370+ mockGetSDKSource . mockReturnValue ( 'aws-lambda-layer' ) ;
371+ const options : AwsServerlessOptions = {
372+ useLayerExtension : false ,
373+ } ;
374+
375+ init ( options ) ;
376+
377+ expect ( mockInitWithoutDefaultIntegrations ) . toHaveBeenCalledWith (
378+ expect . objectContaining ( {
379+ useLayerExtension : false ,
380+ } ) ,
381+ ) ;
382+ expect ( mockInitWithoutDefaultIntegrations ) . toHaveBeenCalledWith (
383+ expect . not . objectContaining ( {
384+ tunnel : expect . any ( String ) ,
385+ } ) ,
386+ ) ;
387+ } ) ;
388+ } ) ;
131389} ) ;
0 commit comments