Skip to content

Commit 979ffe6

Browse files
authored
Add file watching behind experiment (#14920)
* Add file watching behind experiment * Update tests * Fix windows store watcher tests
1 parent de8e5f2 commit 979ffe6

File tree

3 files changed

+31
-9
lines changed

3 files changed

+31
-9
lines changed

src/client/pythonEnvironments/base/locators/lowLevel/fsWatchingLocator.ts

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
// Copyright (c) Microsoft Corporation. All rights reserved.
22
// Licensed under the MIT License.
33

4+
import { DiscoveryVariants } from '../../../../common/experiments/groups';
45
import { FileChangeType } from '../../../../common/platform/fileSystemWatcher';
56
import { sleep } from '../../../../common/utils/async';
7+
import { inExperiment } from '../../../common/externalDependencies';
68
import { watchLocationForPythonBinaries } from '../../../common/pythonBinariesWatcher';
79
import { PythonEnvKind } from '../../info';
810
import { LazyResourceBasedLocator } from '../common/resourceBasedLocator';
@@ -38,12 +40,14 @@ export abstract class FSWatchingLocator extends LazyResourceBasedLocator {
3840
}
3941

4042
protected async initWatchers(): Promise<void> {
41-
// Start the FS watchers.
42-
let roots = await this.getRoots();
43-
if (typeof roots === 'string') {
44-
roots = [roots];
43+
if (await inExperiment(DiscoveryVariants.discoverWithFileWatching)) {
44+
// Start the FS watchers.
45+
let roots = await this.getRoots();
46+
if (typeof roots === 'string') {
47+
roots = [roots];
48+
}
49+
roots.forEach((root) => this.startWatcher(root));
4550
}
46-
roots.forEach((root) => this.startWatcher(root));
4751
}
4852

4953
private startWatcher(root: string): void {

src/test/pythonEnvironments/discovery/locators/watcherTestUtils.ts

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
import { assert } from 'chai';
55
import * as fs from 'fs-extra';
66
import * as path from 'path';
7+
import * as sinon from 'sinon';
8+
import { DiscoveryVariants } from '../../../../client/common/experiments/groups';
79
import { traceWarning } from '../../../../client/common/logger';
810
import { FileChangeType } from '../../../../client/common/platform/fileSystemWatcher';
911
import { createDeferred, Deferred, sleep } from '../../../../client/common/utils/async';
@@ -14,7 +16,7 @@ import { ILocator } from '../../../../client/pythonEnvironments/base/locator';
1416
import { getEnvs } from '../../../../client/pythonEnvironments/base/locatorUtils';
1517
import { PythonEnvsChangedEvent } from '../../../../client/pythonEnvironments/base/watcher';
1618
import { getInterpreterPathFromDir } from '../../../../client/pythonEnvironments/common/commonUtils';
17-
import { arePathsSame } from '../../../../client/pythonEnvironments/common/externalDependencies';
19+
import * as externalDeps from '../../../../client/pythonEnvironments/common/externalDependencies';
1820
import { deleteFiles, PYTHON_PATH } from '../../../common';
1921
import { TEST_TIMEOUT } from '../../../constants';
2022
import { run } from './envTestUtils';
@@ -121,6 +123,7 @@ export function testLocatorWatcher(
121123
},
122124
): void {
123125
let locator: ILocator & IDisposable;
126+
let inExperimentStub: sinon.SinonStub;
124127
const venvs = new Venvs(root);
125128

126129
async function waitForChangeToBeDetected(deferred: Deferred<void>) {
@@ -133,11 +136,16 @@ export function testLocatorWatcher(
133136

134137
async function isLocated(executable: string): Promise<boolean> {
135138
const items = await getEnvs(locator.iterEnvs());
136-
return items.some((item) => arePathsSame(item.executable.filename, executable));
139+
return items.some((item) => externalDeps.arePathsSame(item.executable.filename, executable));
137140
}
138141

139142
suiteSetup(() => venvs.cleanUp());
140143

144+
setup(() => {
145+
inExperimentStub = sinon.stub(externalDeps, 'inExperiment');
146+
inExperimentStub.withArgs(DiscoveryVariants.discoverWithFileWatching).resolves(true);
147+
});
148+
141149
async function setupLocator(onChanged: (e: PythonEnvsChangedEvent) => Promise<void>) {
142150
locator = options?.arg ? await createLocatorFactoryFunc(options.arg) : await createLocatorFactoryFunc();
143151
await getEnvs(locator.iterEnvs()); // Force the FS watcher to start.
@@ -149,6 +157,7 @@ export function testLocatorWatcher(
149157
teardown(async () => {
150158
await venvs.cleanUp();
151159
locator.dispose();
160+
inExperimentStub.restore();
152161
});
153162

154163
test('Detect a new environment', async () => {

src/test/pythonEnvironments/discovery/locators/windowsStoreLocator.test.ts

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,15 @@
44
import { assert } from 'chai';
55
import * as fs from 'fs-extra';
66
import * as path from 'path';
7+
import * as sinon from 'sinon';
8+
import { DiscoveryVariants } from '../../../../client/common/experiments/groups';
79
import { traceWarning } from '../../../../client/common/logger';
810
import { FileChangeType } from '../../../../client/common/platform/fileSystemWatcher';
911
import { createDeferred, Deferred, sleep } from '../../../../client/common/utils/async';
1012
import { PythonEnvKind } from '../../../../client/pythonEnvironments/base/info';
1113
import { getEnvs } from '../../../../client/pythonEnvironments/base/locatorUtils';
1214
import { PythonEnvsChangedEvent } from '../../../../client/pythonEnvironments/base/watcher';
13-
import { arePathsSame } from '../../../../client/pythonEnvironments/common/externalDependencies';
15+
import * as externalDeps from '../../../../client/pythonEnvironments/common/externalDependencies';
1416
import { WindowsStoreLocator } from '../../../../client/pythonEnvironments/discovery/locators/services/windowsStoreLocator';
1517
import { TEST_TIMEOUT } from '../../../constants';
1618
import { TEST_LAYOUT_ROOT } from '../../common/commonTestConstants';
@@ -54,6 +56,7 @@ class WindowsStoreEnvs {
5456
}
5557

5658
suite('Windows Store Locator', async () => {
59+
let inExperimentStub: sinon.SinonStub;
5760
const testLocalAppData = path.join(TEST_LAYOUT_ROOT, 'storeApps');
5861
const testStoreAppRoot = path.join(testLocalAppData, 'Microsoft', 'WindowsApps');
5962
const windowsStoreEnvs = new WindowsStoreEnvs(testStoreAppRoot);
@@ -74,14 +77,19 @@ suite('Windows Store Locator', async () => {
7477

7578
async function isLocated(executable: string): Promise<boolean> {
7679
const items = await getEnvs(locator.iterEnvs());
77-
return items.some((item) => arePathsSame(item.executable.filename, executable));
80+
return items.some((item) => externalDeps.arePathsSame(item.executable.filename, executable));
7881
}
7982

8083
suiteSetup(async () => {
8184
process.env.LOCALAPPDATA = testLocalAppData;
8285
await windowsStoreEnvs.cleanUp();
8386
});
8487

88+
setup(() => {
89+
inExperimentStub = sinon.stub(externalDeps, 'inExperiment');
90+
inExperimentStub.withArgs(DiscoveryVariants.discoverWithFileWatching).resolves(true);
91+
});
92+
8593
async function setupLocator(onChanged: (e: PythonEnvsChangedEvent) => Promise<void>) {
8694
locator = new WindowsStoreLocator();
8795
await getEnvs(locator.iterEnvs()); // Force the watchers to start.
@@ -91,6 +99,7 @@ suite('Windows Store Locator', async () => {
9199
}
92100

93101
teardown(async () => {
102+
inExperimentStub.restore();
94103
await windowsStoreEnvs.cleanUp();
95104
await locator.dispose();
96105
});

0 commit comments

Comments
 (0)