Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Overload methods testing rewrite #21082

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
1374370
hel
Apr 7, 2023
9f67fbe
Merge branch 'microsoft:main' into main
eleanorjboyd Apr 11, 2023
69c100a
Merge pull request #7 from eleanorjboyd/fix-main
eleanorjboyd Apr 17, 2023
6403d20
Attempt to fix pre-release build (#21071)
Apr 17, 2023
a1f5041
Use new logging API for python extension logger and LS logger (#21062)
karthiknadig Apr 17, 2023
3217420
Direct users to the Jupyter extension when using Run in Interactive w…
Apr 18, 2023
540658b
Add quick pick hover support to explain conda environment lacking a P…
Apr 18, 2023
b377503
Python test execution simple (#21053)
eleanorjboyd Apr 18, 2023
8223362
Add black to `extensions.json` (#20912)
cpinamtz Apr 18, 2023
b19126e
Merge pull request #7 from eleanorjboyd/fix-main
eleanorjboyd Apr 17, 2023
72d210f
Merge pull request #7 from eleanorjboyd/fix-main
eleanorjboyd Apr 17, 2023
7dbe187
Merge pull request #7 from eleanorjboyd/fix-main
eleanorjboyd Apr 17, 2023
1bf0450
Merge pull request #7 from eleanorjboyd/fix-main
eleanorjboyd Apr 17, 2023
c95b095
Merge pull request #7 from eleanorjboyd/fix-main
eleanorjboyd Apr 17, 2023
7e5f2b4
Merge pull request #7 from eleanorjboyd/fix-main
eleanorjboyd Apr 17, 2023
b9466cc
Merge pull request #7 from eleanorjboyd/fix-main
eleanorjboyd Apr 17, 2023
bf3ad2c
Merge pull request #8 from eleanorjboyd/new-main
eleanorjboyd Apr 19, 2023
c3c6550
uncommenting and overloading
eleanorjboyd Apr 18, 2023
5a84606
fix comments
eleanorjboyd Apr 18, 2023
ab689f6
add env var for testing
eleanorjboyd Apr 20, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 10 additions & 10 deletions src/client/testing/testController/common/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ import {
Uri,
WorkspaceFolder,
} from 'vscode';
// ** import { IPythonExecutionFactory } from '../../../common/process/types';
import { TestDiscoveryOptions } from '../../common/types';
import { IPythonExecutionFactory } from '../../../common/process/types';

export type TestRunInstanceOptions = TestRunOptions & {
exclude?: readonly TestItem[];
Expand Down Expand Up @@ -179,21 +179,21 @@ export interface ITestServer {
}

export interface ITestDiscoveryAdapter {
// ** Uncomment second line and comment out first line to use the new discovery method.
// ** first line old method signature, second line new method signature
discoverTests(uri: Uri): Promise<DiscoveredTestPayload>;
// discoverTests(uri: Uri, executionFactory: IPythonExecutionFactory): Promise<DiscoveredTestPayload>;
discoverTests(uri: Uri, executionFactory: IPythonExecutionFactory): Promise<DiscoveredTestPayload>;
}

// interface for execution/runner adapter
export interface ITestExecutionAdapter {
// ** Uncomment second line and comment out first line to use the new execution method.
// ** first line old method signature, second line new method signature
runTests(uri: Uri, testIds: string[], debugBool?: boolean): Promise<ExecutionTestPayload>;
// runTests(
// uri: Uri,
// testIds: string[],
// debugBool?: boolean,
// executionFactory?: IPythonExecutionFactory,
// ): Promise<ExecutionTestPayload>;
runTests(
uri: Uri,
testIds: string[],
debugBool?: boolean,
executionFactory?: IPythonExecutionFactory,
): Promise<ExecutionTestPayload>;
}

// Same types as in pythonFiles/unittestadapter/utils.py
Expand Down
116 changes: 62 additions & 54 deletions src/client/testing/testController/controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -241,39 +241,46 @@ export class PythonTestController implements ITestController, IExtensionSingleAc
if (uri) {
const settings = this.configSettings.getSettings(uri);
traceVerbose(`Testing: Refreshing test data for ${uri.fsPath}`);
const rewriteTestingEnabled = process.env.ENABLE_PYTHON_TESTING_REWRITE;
if (settings.testing.pytestEnabled) {
// Ensure we send test telemetry if it gets disabled again
this.sendTestDisabledTelemetry = true;
// ** uncomment ~231 - 241 to NEW new test discovery mechanism
// const workspace = this.workspaceService.getWorkspaceFolder(uri);
// traceVerbose(`Discover tests for workspace name: ${workspace?.name} - uri: ${uri.fsPath}`);
// const testAdapter =
// this.testAdapters.get(uri) || (this.testAdapters.values().next().value as WorkspaceTestAdapter);
// testAdapter.discoverTests(
// this.testController,
// this.refreshCancellation.token,
// this.testAdapters.size > 1,
// this.workspaceService.workspaceFile?.fsPath,
// this.pythonExecFactory,
// );
// uncomment ~243 to use OLD test discovery mechanism
await this.pytest.refreshTestData(this.testController, uri, this.refreshCancellation.token);
if (rewriteTestingEnabled) {
// ** rewriteTestingEnabled set to true to use NEW test discovery mechanism
const workspace = this.workspaceService.getWorkspaceFolder(uri);
traceVerbose(`Discover tests for workspace name: ${workspace?.name} - uri: ${uri.fsPath}`);
const testAdapter =
this.testAdapters.get(uri) || (this.testAdapters.values().next().value as WorkspaceTestAdapter);
testAdapter.discoverTests(
this.testController,
this.refreshCancellation.token,
this.testAdapters.size > 1,
this.workspaceService.workspaceFile?.fsPath,
this.pythonExecFactory,
);
} else {
// else use OLD test discovery mechanism
await this.pytest.refreshTestData(this.testController, uri, this.refreshCancellation.token);
}
} else if (settings.testing.unittestEnabled) {
// ** Ensure we send test telemetry if it gets disabled again
this.sendTestDisabledTelemetry = true;
// uncomment ~248 - 258 to NEW new test discovery mechanism
// const workspace = this.workspaceService.getWorkspaceFolder(uri);
// traceVerbose(`Discover tests for workspace name: ${workspace?.name} - uri: ${uri.fsPath}`);
// const testAdapter =
// this.testAdapters.get(uri) || (this.testAdapters.values().next().value as WorkspaceTestAdapter);
// testAdapter.discoverTests(
// this.testController,
// this.refreshCancellation.token,
// this.testAdapters.size > 1,
// this.workspaceService.workspaceFile?.fsPath,
// );
// uncomment ~260 to use OLD test discovery mechanism
await this.unittest.refreshTestData(this.testController, uri, this.refreshCancellation.token);
if (rewriteTestingEnabled) {
// ** rewriteTestingEnabled set to true to use NEW test discovery mechanism
const workspace = this.workspaceService.getWorkspaceFolder(uri);
traceVerbose(`Discover tests for workspace name: ${workspace?.name} - uri: ${uri.fsPath}`);
const testAdapter =
this.testAdapters.get(uri) || (this.testAdapters.values().next().value as WorkspaceTestAdapter);
testAdapter.discoverTests(
this.testController,
this.refreshCancellation.token,
this.testAdapters.size > 1,
this.workspaceService.workspaceFile?.fsPath,
);
} else {
// else use OLD test discovery mechanism
await this.unittest.refreshTestData(this.testController, uri, this.refreshCancellation.token);
}
} else {
if (this.sendTestDisabledTelemetry) {
this.sendTestDisabledTelemetry = false;
Expand Down Expand Up @@ -384,25 +391,26 @@ export class PythonTestController implements ITestController, IExtensionSingleAc

const settings = this.configSettings.getSettings(workspace.uri);
if (testItems.length > 0) {
const rewriteTestingEnabled = process.env.ENABLE_PYTHON_TESTING_REWRITE;
if (settings.testing.pytestEnabled) {
sendTelemetryEvent(EventName.UNITTEST_RUN, undefined, {
tool: 'pytest',
debugging: request.profile?.kind === TestRunProfileKind.Debug,
});
// ** new execution runner/adapter
// const testAdapter =
// this.testAdapters.get(workspace.uri) ||
// (this.testAdapters.values().next().value as WorkspaceTestAdapter);
// return testAdapter.executeTests(
// this.testController,
// runInstance,
// testItems,
// token,
// request.profile?.kind === TestRunProfileKind.Debug,
// this.pythonExecFactory,
// );

// below is old way of running pytest execution
// ** rewriteTestingEnabled set to true to use NEW test discovery mechanism
if (rewriteTestingEnabled) {
const testAdapter =
this.testAdapters.get(workspace.uri) ||
(this.testAdapters.values().next().value as WorkspaceTestAdapter);
return testAdapter.executeTests(
this.testController,
runInstance,
testItems,
token,
request.profile?.kind === TestRunProfileKind.Debug,
this.pythonExecFactory,
);
}
return this.pytest.runTests(
{
includes: testItems,
Expand All @@ -415,23 +423,23 @@ export class PythonTestController implements ITestController, IExtensionSingleAc
);
}
if (settings.testing.unittestEnabled) {
// potentially squeeze in the new execution way here?
sendTelemetryEvent(EventName.UNITTEST_RUN, undefined, {
tool: 'unittest',
debugging: request.profile?.kind === TestRunProfileKind.Debug,
});
// new execution runner/adapter
// const testAdapter =
// this.testAdapters.get(workspace.uri) ||
// (this.testAdapters.values().next().value as WorkspaceTestAdapter);
// return testAdapter.executeTests(
// this.testController,
// runInstance,
// testItems,
// token,
// request.profile?.kind === TestRunProfileKind.Debug,
// );

// ** rewriteTestingEnabled set to true to use NEW test discovery mechanism
if (rewriteTestingEnabled) {
const testAdapter =
this.testAdapters.get(workspace.uri) ||
(this.testAdapters.values().next().value as WorkspaceTestAdapter);
return testAdapter.executeTests(
this.testController,
runInstance,
testItems,
token,
request.profile?.kind === TestRunProfileKind.Debug,
);
}
// below is old way of running unittest execution
return this.unittest.runTests(
{
Expand Down
19 changes: 9 additions & 10 deletions src/client/testing/testController/pytest/pytestDiscoveryAdapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,20 +37,19 @@ export class PytestTestDiscoveryAdapter implements ITestDiscoveryAdapter {
}
}

// ** Old version of discover tests.
discoverTests(uri: Uri): Promise<DiscoveredTestPayload> {
discoverTests(uri: Uri, executionFactory?: IPythonExecutionFactory): Promise<DiscoveredTestPayload> {
if (executionFactory !== undefined) {
// ** new version of discover tests.
const settings = this.configSettings.getSettings(uri);
const { pytestArgs } = settings.testing;
traceVerbose(pytestArgs);
return this.runPytestDiscovery(uri, executionFactory);
}
// if executionFactory is undefined, we are using the old method signature of discover tests.
traceVerbose(uri);
this.deferred = createDeferred<DiscoveredTestPayload>();
return this.deferred.promise;
}
// Uncomment this version of the function discoverTests to use the new discovery method.
// public async discoverTests(uri: Uri, executionFactory: IPythonExecutionFactory): Promise<DiscoveredTestPayload> {
// const settings = this.configSettings.getSettings(uri);
// const { pytestArgs } = settings.testing;
// traceVerbose(pytestArgs);

// return this.runPytestDiscovery(uri, executionFactory);
// }

async runPytestDiscovery(uri: Uri, executionFactory: IPythonExecutionFactory): Promise<DiscoveredTestPayload> {
const deferred = createDeferred<DiscoveredTestPayload>();
Expand Down
117 changes: 61 additions & 56 deletions src/client/testing/testController/pytest/pytestExecutionAdapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,17 @@
// Licensed under the MIT License.

import { Uri } from 'vscode';
import path from 'path';
import { IConfigurationService, ITestOutputChannel } from '../../../common/types';
import { createDeferred, Deferred } from '../../../common/utils/async';
import { traceVerbose } from '../../../logging';
import { DataReceivedEvent, ExecutionTestPayload, ITestExecutionAdapter, ITestServer } from '../common/types';
import {
ExecutionFactoryCreateWithEnvironmentOptions,
IPythonExecutionFactory,
SpawnOptions,
} from '../../../common/process/types';
import { EXTENSION_ROOT_DIR } from '../../../constants';

/**
* Wrapper Class for pytest test execution. This is where we call `runTestCommand`?
Expand All @@ -32,70 +39,68 @@ export class PytestTestExecutionAdapter implements ITestExecutionAdapter {
}
}

// ** Old version of discover tests.
async runTests(uri: Uri, testIds: string[], debugBool?: boolean): Promise<ExecutionTestPayload> {
async runTests(
uri: Uri,
testIds: string[],
debugBool?: boolean,
executionFactory?: IPythonExecutionFactory,
): Promise<ExecutionTestPayload> {
traceVerbose(uri, testIds, debugBool);
// TODO:Remove this line after enabling runs
if (executionFactory !== undefined) {
// ** new version of run tests.
return this.runTestsNew(uri, testIds, debugBool, executionFactory);
}
// if executionFactory is undefined, we are using the old method signature of run tests.
this.outputChannel.appendLine('Running tests.');
this.deferred = createDeferred<ExecutionTestPayload>();
return this.deferred.promise;
}
}

// public async runTests(
// uri: Uri,
// testIds: string[],
// debugBool?: boolean,
// executionFactory?: IPythonExecutionFactory,
// ): Promise<ExecutionTestPayload> {
// const deferred = createDeferred<ExecutionTestPayload>();
// const relativePathToPytest = 'pythonFiles';
// const fullPluginPath = path.join(EXTENSION_ROOT_DIR, relativePathToPytest);
// this.configSettings.isTestExecution();
// const uuid = this.testServer.createUUID(uri.fsPath);
// this.promiseMap.set(uuid, deferred);
// const settings = this.configSettings.getSettings(uri);
// const { pytestArgs } = settings.testing;

// const pythonPathParts: string[] = process.env.PYTHONPATH?.split(path.delimiter) ?? [];
// const pythonPathCommand = [fullPluginPath, ...pythonPathParts].join(path.delimiter);

// const spawnOptions: SpawnOptions = {
// cwd: uri.fsPath,
// throwOnStdErr: true,
// extraVariables: {
// PYTHONPATH: pythonPathCommand,
// TEST_UUID: uuid.toString(),
// TEST_PORT: this.testServer.getPort().toString(),
// },
// outputChannel: this.outputChannel,
// };
private async runTestsNew(
uri: Uri,
testIds: string[],
debugBool?: boolean,
executionFactory?: IPythonExecutionFactory,
): Promise<ExecutionTestPayload> {
const deferred = createDeferred<ExecutionTestPayload>();
const relativePathToPytest = 'pythonFiles';
const fullPluginPath = path.join(EXTENSION_ROOT_DIR, relativePathToPytest);
this.configSettings.isTestExecution();
const uuid = this.testServer.createUUID(uri.fsPath);
this.promiseMap.set(uuid, deferred);
const settings = this.configSettings.getSettings(uri);
const { pytestArgs } = settings.testing;

// // Create the Python environment in which to execute the command.
// const creationOptions: ExecutionFactoryCreateWithEnvironmentOptions = {
// allowEnvironmentFetchExceptions: false,
// resource: uri,
// };
// // need to check what will happen in the exec service is NOT defined and is null
// const execService = await executionFactory?.createActivatedEnvironment(creationOptions);
const pythonPathParts: string[] = process.env.PYTHONPATH?.split(path.delimiter) ?? [];
const pythonPathCommand = [fullPluginPath, ...pythonPathParts].join(path.delimiter);

// const testIdsString = testIds.join(' ');
// console.debug('what to do with debug bool?', debugBool);
// try {
// execService?.exec(['-m', 'pytest', '-p', 'vscode_pytest', testIdsString].concat(pytestArgs), spawnOptions);
// } catch (ex) {
// console.error(ex);
// }
const spawnOptions: SpawnOptions = {
cwd: uri.fsPath,
throwOnStdErr: true,
extraVariables: {
PYTHONPATH: pythonPathCommand,
TEST_UUID: uuid.toString(),
TEST_PORT: this.testServer.getPort().toString(),
},
outputChannel: this.outputChannel,
};

// return deferred.promise;
// }
// }
// Create the Python environment in which to execute the command.
const creationOptions: ExecutionFactoryCreateWithEnvironmentOptions = {
allowEnvironmentFetchExceptions: false,
resource: uri,
};
// need to check what will happen in the exec service is NOT defined and is null
const execService = await executionFactory?.createActivatedEnvironment(creationOptions);

// function buildExecutionCommand(args: string[]): TestExecutionCommand {
// const executionScript = path.join(EXTENSION_ROOT_DIR, 'pythonFiles', 'unittestadapter', 'execution.py');
const testIdsString = testIds.join(' ');
console.debug('what to do with debug bool?', debugBool);
try {
execService?.exec(['-m', 'pytest', '-p', 'vscode_pytest', testIdsString].concat(pytestArgs), spawnOptions);
} catch (ex) {
console.error(ex);
}

// return {
// script: executionScript,
// args: ['--udiscovery', ...args],
// };
// }
return deferred.promise;
}
}
Loading