Skip to content

Commit ef32ac2

Browse files
committed
testing logging
1 parent 145ccc8 commit ef32ac2

File tree

2 files changed

+47
-2
lines changed

2 files changed

+47
-2
lines changed

src/client/pythonEnvironments/base/locators/common/nativePythonFinder.ts

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,16 @@ class NativePythonFinderImpl extends DisposableBase implements NativePythonFinde
114114

115115
private readonly suppressErrorNotification: IPersistentStorage<boolean>;
116116

117+
/**
118+
* Tracks whether the internal JSON-RPC connection has been closed.
119+
* This can happen independently of the finder being disposed.
120+
*/
121+
private _connectionClosed = false;
122+
123+
public get isConnectionClosed(): boolean {
124+
return this._connectionClosed;
125+
}
126+
117127
constructor(private readonly cacheDirectory?: Uri, private readonly context?: IExtensionContext) {
118128
super();
119129
this.suppressErrorNotification = this.context
@@ -135,14 +145,21 @@ class NativePythonFinderImpl extends DisposableBase implements NativePythonFinde
135145
}
136146

137147
async *refresh(options?: NativePythonEnvironmentKind | Uri[]): AsyncIterable<NativeEnvInfo> {
148+
this.outputChannel.info(
149+
`refresh() called: firstRefreshResults=${!!this.firstRefreshResults}, connectionClosed=${
150+
this._connectionClosed
151+
}, isDisposed=${this.isDisposed}`,
152+
);
138153
if (this.firstRefreshResults) {
139154
// If this is the first time we are refreshing,
140155
// Then get the results from the first refresh.
141156
// Those would have started earlier and cached in memory.
157+
this.outputChannel.info('Using firstRefreshResults');
142158
const results = this.firstRefreshResults();
143159
this.firstRefreshResults = undefined;
144160
yield* results;
145161
} else {
162+
this.outputChannel.info('Calling doRefresh');
146163
const result = this.doRefresh(options);
147164
let completed = false;
148165
void result.completed.finally(() => {
@@ -298,6 +315,8 @@ class NativePythonFinderImpl extends DisposableBase implements NativePythonFinde
298315
sendNativeTelemetry(data, this.initialRefreshMetrics),
299316
),
300317
connection.onClose(() => {
318+
this.outputChannel.info('JSON-RPC connection closed, marking connection as closed');
319+
this._connectionClosed = true;
301320
disposables.forEach((d) => d.dispose());
302321
}),
303322
);
@@ -535,7 +554,15 @@ export function getNativePythonFinder(context?: IExtensionContext): NativePython
535554
}
536555

537556
function isFinderDisposed(finder: NativePythonFinder): boolean {
538-
return 'isDisposed' in finder && Boolean((finder as { isDisposed?: boolean }).isDisposed);
557+
const finderImpl = finder as { isDisposed?: boolean; isConnectionClosed?: boolean };
558+
const disposed = Boolean(finderImpl.isDisposed);
559+
const connectionClosed = Boolean(finderImpl.isConnectionClosed);
560+
if (disposed || connectionClosed) {
561+
traceError(
562+
`[NativePythonFinder] Finder needs recreation: isDisposed=${disposed}, isConnectionClosed=${connectionClosed}`,
563+
);
564+
}
565+
return disposed || connectionClosed;
539566
}
540567

541568
export function getCacheDirectory(context: IExtensionContext): Uri {
@@ -546,3 +573,14 @@ export async function clearCacheDirectory(context: IExtensionContext): Promise<v
546573
const cacheDirectory = getCacheDirectory(context);
547574
await fs.emptyDir(cacheDirectory.fsPath).catch(noop);
548575
}
576+
577+
/**
578+
* Clears the singleton finder instance. For testing purposes only.
579+
* @internal
580+
*/
581+
export function clearNativePythonFinder(): void {
582+
if (_finder) {
583+
_finder.dispose();
584+
_finder = undefined;
585+
}
586+
}

src/test/pythonEnvironments/nativePythonFinder.unit.test.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import * as sinon from 'sinon';
66
import * as typemoq from 'typemoq';
77
import { WorkspaceConfiguration } from 'vscode';
88
import {
9+
clearNativePythonFinder,
910
getNativePythonFinder,
1011
isNativeEnvInfo,
1112
NativeEnvInfo,
@@ -23,6 +24,9 @@ suite('Native Python Finder', () => {
2324
let getWorkspaceFolderPathsStub: sinon.SinonStub;
2425

2526
setup(() => {
27+
// Clear singleton before each test to ensure fresh state
28+
clearNativePythonFinder();
29+
2630
createLogOutputChannelStub = sinon.stub(windowsApis, 'createLogOutputChannel');
2731
createLogOutputChannelStub.returns(new MockOutputChannel('locator'));
2832

@@ -41,11 +45,14 @@ suite('Native Python Finder', () => {
4145
});
4246

4347
teardown(() => {
48+
// Clean up finder before restoring stubs to avoid issues with mock references
49+
clearNativePythonFinder();
4450
sinon.restore();
4551
});
4652

4753
suiteTeardown(() => {
48-
finder.dispose();
54+
// Final cleanup (finder may already be disposed by teardown)
55+
clearNativePythonFinder();
4956
});
5057

5158
test('Refresh should return python environments', async () => {

0 commit comments

Comments
 (0)