@@ -16,10 +16,12 @@ import {
1616const execAsync = promisify ( exec ) ;
1717const resourcesPath = path . resolve ( __dirname , 'resources' ) ;
1818const TEST_TIMEOUT = Number ( process . env . TEST_TIMEOUT ?? '999999' ) ;
19+
1920const UV_STABILIZING_ENV = {
20- UV_CONCURRENT_BUILDS : '1' ,
21- UV_CONCURRENT_INSTALLS : '1' ,
22- UV_CONCURRENT_DOWNLOADS : '8' ,
21+ // Spurious open file count errors have occurred. These mitigations should not be required. WIP
22+ // UV_CONCURRENT_BUILDS: '1',
23+ // UV_CONCURRENT_INSTALLS: '1',
24+ // UV_CONCURRENT_DOWNLOADS: '1',
2325} ;
2426
2527/**
@@ -101,8 +103,8 @@ test('Create a function from basic_app', async () => {
101103 template . findResources ( 'AWS::Lambda::Function' ) ,
102104 ) ;
103105 expect ( functions ) . toHaveLength ( 1 ) ;
104- const contents = await getFunctionAssetContents ( functions [ 0 ] , app ) ;
105- expect ( contents ) . toContain ( 'handler.py' ) ;
106+ const asset = await getFunctionAssetContents ( functions [ 0 ] , app ) ;
107+ expect ( asset . rootEntries ) . toContain ( 'handler.py' ) ;
106108} ) ;
107109
108110test ( 'Create a function from basic_app with no .py index extension' , async ( ) => {
@@ -182,11 +184,16 @@ test(
182184 template . findResources ( 'AWS::Lambda::Function' ) ,
183185 ) ;
184186 expect ( functions ) . toHaveLength ( 1 ) ;
185- const contents = await getFunctionAssetContents ( functions [ 0 ] , app ) ;
186- for ( const entry of [ 'common' , 'pydantic' , 'httpx' , 'app_handler.py' ] ) {
187- expect ( contents ) . toContain ( entry ) ;
188- }
189- expect ( contents ) . not . toContain ( '_editable_impl_common.pth' ) ;
187+ const asset = await getFunctionAssetContents ( functions [ 0 ] , app ) ;
188+
189+ expect ( asset . rootEntries ) . toEqual (
190+ expect . arrayContaining ( [ 'app' , 'common' , 'httpx' , 'pydantic' ] ) ,
191+ ) ;
192+ expect ( asset . files ) . toEqual (
193+ expect . arrayContaining ( [ 'app/__init__.py' , 'app/app_handler.py' ] ) ,
194+ ) ;
195+ expect ( asset . files ) . toContain ( 'common/__init__.py' ) ;
196+ expect ( asset . files ) . not . toContain ( '_editable_impl_common.pth' ) ;
190197 } ,
191198 TEST_TIMEOUT ,
192199) ;
@@ -220,8 +227,8 @@ test(
220227 ) ;
221228
222229 expect ( functions ) . toHaveLength ( 1 ) ;
223- const contents = await getFunctionAssetContents ( functions [ 0 ] , app ) ;
224- expect ( contents ) . toContain ( 'handler.py' ) ;
230+ const asset = await getFunctionAssetContents ( functions [ 0 ] , app ) ;
231+ expect ( asset . rootEntries ) . toContain ( 'handler.py' ) ;
225232 } ,
226233 TEST_TIMEOUT ,
227234) ;
@@ -281,6 +288,27 @@ test('Reject non-python runtimes', async () => {
281288async function getFunctionAssetContents ( functionResource : any , app : App ) {
282289 const assetRelPath = functionResource . Metadata [ 'uv-python-lambda:asset-path' ] ;
283290 const assetPath = path . join ( app . outdir , assetRelPath ) ;
284- const contents = await fs . readdir ( assetPath ) ;
285- return contents ;
291+ const rootEntries = await fs . readdir ( assetPath ) ;
292+ const files : string [ ] = [ ] ;
293+
294+ async function walk ( currentPath : string , relativePath = '' ) : Promise < void > {
295+ const entries = await fs . readdir ( currentPath , { withFileTypes : true } ) ;
296+
297+ for ( const entry of entries ) {
298+ const nextRelativePath = relativePath
299+ ? path . posix . join ( relativePath , entry . name )
300+ : entry . name ;
301+ const nextPath = path . join ( currentPath , entry . name ) ;
302+
303+ if ( entry . isDirectory ( ) ) {
304+ await walk ( nextPath , nextRelativePath ) ;
305+ } else {
306+ files . push ( nextRelativePath ) ;
307+ }
308+ }
309+ }
310+
311+ await walk ( assetPath ) ;
312+
313+ return { rootEntries, files } ;
286314}
0 commit comments