@@ -6,7 +6,7 @@ import { IExtensionContext } from '../../extension/common/types';
66import { registerNoConfigDebug as registerNoConfigDebug } from '../../extension/noConfigDebugInit' ;
77import * as TypeMoq from 'typemoq' ;
88import * as sinon from 'sinon' ;
9- import { DebugConfiguration , DebugSessionOptions , RelativePattern , Uri , env , workspace } from 'vscode' ;
9+ import { DebugConfiguration , DebugSessionOptions , env , RelativePattern , Uri , workspace } from 'vscode' ;
1010import * as utils from '../../extension/utils' ;
1111import { assert } from 'console' ;
1212import * as fs from 'fs' ;
@@ -22,9 +22,7 @@ suite('setup for no-config debug scenario', function () {
2222 let DEBUGPY_ADAPTER_ENDPOINTS = 'DEBUGPY_ADAPTER_ENDPOINTS' ;
2323 let BUNDLED_DEBUGPY_PATH = 'BUNDLED_DEBUGPY_PATH' ;
2424 let workspaceUriStub : sinon . SinonStub ;
25- let sessionIdStub : sinon . SinonStub ;
26- let stableWorkspaceHash : string ;
27- let workspacePath : string ;
25+ let windowHash : string ;
2826
2927 const testDataDir = path . join ( __dirname , 'testData' ) ;
3028 const testFilePath = path . join ( testDataDir , 'debuggerAdapterEndpoint.txt' ) ;
@@ -37,28 +35,25 @@ suite('setup for no-config debug scenario', function () {
3735 noConfigScriptsDir = path . join ( context . object . extensionPath , 'bundled/scripts/noConfigScripts' ) ;
3836 bundledDebugPath = path . join ( context . object . extensionPath , 'bundled/libs/debugpy' ) ;
3937
40- sessionIdStub = sinon . stub ( env , 'sessionId' ) . value ( 'test-session' ) ;
41- workspacePath = os . tmpdir ( ) ;
42-
4338 // Stub crypto.randomBytes with proper typing
4439 let randomBytesStub = sinon . stub ( crypto , 'randomBytes' ) ;
4540 // Provide a valid Buffer object
4641 randomBytesStub . callsFake ( ( _size : number ) => Buffer . from ( '1234567899' , 'hex' ) ) ;
4742
48- workspaceUriStub = sinon . stub ( workspace , 'workspaceFolders' ) . value ( [ { uri : Uri . parse ( workspacePath ) } ] ) ;
43+ workspaceUriStub = sinon . stub ( workspace , 'workspaceFolders' ) . value ( [ { uri : Uri . parse ( os . tmpdir ( ) ) } ] ) ;
4944
50- const hash = crypto . createHash ( 'sha256' ) ;
51- hash . update ( workspacePath . toString ( ) ) ;
52- hash . update ( 'test-session' ) ;
53- stableWorkspaceHash = hash . digest ( 'hex' ) . slice ( 0 , 16 ) ;
45+ // Stub env.sessionId to get a stable window hash
46+ sinon . stub ( env , 'sessionId' ) . value ( 'test-session-id' ) ;
47+ const hashObj = crypto . createHash ( 'sha256' ) ;
48+ hashObj . update ( 'test-session-id' ) ;
49+ windowHash = hashObj . digest ( 'hex' ) . substring ( 0 , 16 ) ;
5450 } catch ( error ) {
5551 console . error ( 'Error in setup:' , error ) ;
5652 }
5753 } ) ;
5854 teardown ( ( ) => {
5955 sinon . restore ( ) ;
6056 workspaceUriStub . restore ( ) ;
61- sessionIdStub . restore ( ) ;
6257 } ) ;
6358
6459 test ( 'should add environment variables for DEBUGPY_ADAPTER_ENDPOINTS, BUNDLED_DEBUGPY_PATH, and PATH' , async ( ) => {
@@ -71,14 +66,8 @@ suite('setup for no-config debug scenario', function () {
7166 . setup ( ( x ) => x . replace ( TypeMoq . It . isAny ( ) , TypeMoq . It . isAny ( ) ) )
7267 . callback ( ( key , value ) => {
7368 if ( key === DEBUGPY_ADAPTER_ENDPOINTS ) {
74- assert (
75- value ===
76- path . join (
77- context . object . extensionPath ,
78- '.noConfigDebugAdapterEndpoints' ,
79- stableWorkspaceHash ,
80- ) ,
81- ) ;
69+ assert ( value . includes ( 'endpoint-' ) ) ;
70+ assert ( value . includes ( windowHash ) ) ;
8271 } else if ( key === BUNDLED_DEBUGPY_PATH ) {
8372 assert ( value === bundledDebugPath ) ;
8473 } else if ( key === 'PYDEVD_DISABLE_FILE_VALIDATION' ) {
@@ -213,8 +202,8 @@ suite('setup for no-config debug scenario', function () {
213202 // Assert
214203 sinon . assert . calledOnce ( createFileSystemWatcherFunct ) ;
215204 const expectedPattern = new RelativePattern (
216- path . join ( os . tmpdir ( ) , '.noConfigDebugAdapterEndpoints' , stableWorkspaceHash ) ,
217- '**/*.txt' ,
205+ path . join ( os . tmpdir ( ) , '.noConfigDebugAdapterEndpoints' ) ,
206+ `endpoint- ${ windowHash } -*` ,
218207 ) ;
219208 sinon . assert . calledWith ( createFileSystemWatcherFunct , expectedPattern ) ;
220209 } ) ;
@@ -280,27 +269,25 @@ suite('setup for no-config debug scenario', function () {
280269 sinon . assert . calledWith ( debugStub , undefined , expectedConfig , optionsExpected ) ;
281270 } ) ;
282271
283- test ( 'should clear existing endpoint files when debuggerAdapterEndpointFolder exists' , async ( ) => {
272+ test ( 'should clean up existing endpoint files for this window hash when debuggerAdapterEndpointFolder exists' , async ( ) => {
284273 // Arrange
285274 const environmentVariableCollectionMock = TypeMoq . Mock . ofType < any > ( ) ;
286275 context . setup ( ( c ) => c . environmentVariableCollection ) . returns ( ( ) => environmentVariableCollectionMock . object ) ;
287276
288- const endpointFolderPath = path . join ( os . tmpdir ( ) , '.noConfigDebugAdapterEndpoints' , stableWorkspaceHash ) ;
289- const fsExistsSyncStub = sinon . stub ( fs , 'existsSync' ) . callsFake ( ( p ) => p === endpointFolderPath ) ;
290- const fakeDirent = { isFile : ( ) => true , name : Buffer . from ( 'old.txt' ) } as unknown as fs . Dirent < Buffer > ;
291- const fsReaddirSyncStub = sinon . stub ( fs , 'readdirSync' ) . callsFake ( ( dirPath : fs . PathLike , options ?: any ) => {
292- assert ( dirPath === endpointFolderPath ) ;
293- assert ( options ?. withFileTypes === true ) ;
294- return [ fakeDirent ] as unknown as fs . Dirent < Buffer > [ ] ;
295- } ) ;
277+ const fsExistsSyncStub = sinon . stub ( fs , 'existsSync' ) . returns ( true ) ;
278+ const fsReaddirSyncStub = sinon . stub ( fs , 'readdirSync' ) . returns ( [
279+ { name : `endpoint-${ windowHash } -abc123.txt` , isFile : ( ) => true } ,
280+ { name : `endpoint-otherhash-def456.txt` , isFile : ( ) => true } ,
281+ { name : 'somedir' , isFile : ( ) => false } ,
282+ ] as any ) ;
296283 const fsUnlinkSyncStub = sinon . stub ( fs , 'unlinkSync' ) ;
297284
298285 // Act
299286 await registerNoConfigDebug ( context . object . environmentVariableCollection , context . object . extensionPath ) ;
300287
301- // Assert
302- sinon . assert . calledWith ( fsExistsSyncStub , endpointFolderPath ) ;
303- sinon . assert . calledWith ( fsUnlinkSyncStub , path . join ( endpointFolderPath , 'old.txt' ) ) ;
288+ // Assert - only files matching this window hash should be deleted
289+ sinon . assert . called ( fsReaddirSyncStub ) ;
290+ sinon . assert . calledOnce ( fsUnlinkSyncStub ) ;
304291
305292 // Cleanup
306293 fsExistsSyncStub . restore ( ) ;
0 commit comments