Skip to content

rewrite should respect settings.testing.cwd #21539

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

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
Original file line number Diff line number Diff line change
Expand Up @@ -55,12 +55,13 @@ export class PytestTestDiscoveryAdapter implements ITestDiscoveryAdapter {
const uuid = this.testServer.createUUID(uri.fsPath);
const settings = this.configSettings.getSettings(uri);
const { pytestArgs } = settings.testing;
const cwd = settings.testing.cwd && settings.testing.cwd.length > 0 ? settings.testing.cwd : uri.fsPath;

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

const spawnOptions: SpawnOptions = {
cwd: uri.fsPath,
cwd,
throwOnStdErr: true,
extraVariables: {
PYTHONPATH: pythonPathCommand,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,12 +84,13 @@ export class PytestTestExecutionAdapter implements ITestExecutionAdapter {
this.configSettings.isTestExecution();
const settings = this.configSettings.getSettings(uri);
const { pytestArgs } = settings.testing;
const cwd = settings.testing.cwd && settings.testing.cwd.length > 0 ? settings.testing.cwd : uri.fsPath;

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

const spawnOptions: SpawnOptions = {
cwd: uri.fsPath,
cwd,
throwOnStdErr: true,
extraVariables: {
PYTHONPATH: pythonPathCommand,
Expand Down Expand Up @@ -131,7 +132,7 @@ export class PytestTestExecutionAdapter implements ITestExecutionAdapter {
const pytestPort = this.testServer.getPort().toString();
const pytestUUID = uuid.toString();
const launchOptions: LaunchOptions = {
cwd: uri.fsPath,
cwd,
args: testArgs,
token: spawnOptions.token,
testProvider: PYTEST_PROVIDER,
Expand All @@ -156,7 +157,7 @@ export class PytestTestExecutionAdapter implements ITestExecutionAdapter {
return Promise.reject(ex);
}

const executionPayload: ExecutionTestPayload = { cwd: uri.fsPath, status: 'success', error: '' };
const executionPayload: ExecutionTestPayload = { cwd, status: 'success', error: '' };
return executionPayload;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,6 @@ import {
* Wrapper class for unittest test discovery. This is where we call `runTestCommand`.
*/
export class UnittestTestDiscoveryAdapter implements ITestDiscoveryAdapter {
private cwd: string | undefined;

constructor(
public testServer: ITestServer,
public configSettings: IConfigurationService,
Expand All @@ -31,16 +29,16 @@ export class UnittestTestDiscoveryAdapter implements ITestDiscoveryAdapter {
public async discoverTests(uri: Uri): Promise<DiscoveredTestPayload> {
const settings = this.configSettings.getSettings(uri);
const { unittestArgs } = settings.testing;
const cwd = settings.testing.cwd && settings.testing.cwd.length > 0 ? settings.testing.cwd : uri.fsPath;

const command = buildDiscoveryCommand(unittestArgs);

this.cwd = uri.fsPath;
const uuid = this.testServer.createUUID(uri.fsPath);

const options: TestCommandOptions = {
workspaceFolder: uri,
command,
cwd: this.cwd,
cwd,
uuid,
outChannel: this.outputChannel,
};
Expand All @@ -57,7 +55,7 @@ export class UnittestTestDiscoveryAdapter implements ITestDiscoveryAdapter {
// placeholder until after the rewrite is adopted
// TODO: remove after adoption.
const discoveryPayload: DiscoveredTestPayload = {
cwd: uri.fsPath,
cwd,
status: 'success',
};
return discoveryPayload;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,6 @@ import { startTestIdServer } from '../common/utils';
*/

export class UnittestTestExecutionAdapter implements ITestExecutionAdapter {
private cwd: string | undefined;

constructor(
public testServer: ITestServer,
public configSettings: IConfigurationService,
Expand Down Expand Up @@ -62,15 +60,15 @@ export class UnittestTestExecutionAdapter implements ITestExecutionAdapter {
debugBool?: boolean,
): Promise<ExecutionTestPayload> {
const settings = this.configSettings.getSettings(uri);
const { cwd, unittestArgs } = settings.testing;
const { unittestArgs } = settings.testing;
const cwd = settings.testing.cwd && settings.testing.cwd.length > 0 ? settings.testing.cwd : uri.fsPath;

const command = buildExecutionCommand(unittestArgs);
this.cwd = cwd || uri.fsPath;

const options: TestCommandOptions = {
workspaceFolder: uri,
command,
cwd: this.cwd,
cwd,
uuid,
debugBool,
testIds,
Expand All @@ -87,7 +85,7 @@ export class UnittestTestExecutionAdapter implements ITestExecutionAdapter {
});
// placeholder until after the rewrite is adopted
// TODO: remove after adoption.
const executionPayload: ExecutionTestPayload = { cwd: uri.fsPath, status: 'success', error: '' };
const executionPayload: ExecutionTestPayload = { cwd, status: 'success', error: '' };
return executionPayload;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -105,9 +105,10 @@ suite('pytest test discovery adapter', () => {
});
test('Test discovery correctly pulls pytest args from config service settings', async () => {
// set up a config service with different pytest args
const expectedPathNew = path.join('other', 'path');
const configServiceNew: IConfigurationService = ({
getSettings: () => ({
testing: { pytestArgs: ['.', 'abc', 'xyz'] },
testing: { pytestArgs: ['.', 'abc', 'xyz'], cwd: expectedPathNew },
}),
} as unknown) as IConfigurationService;

Expand All @@ -120,7 +121,7 @@ suite('pytest test discovery adapter', () => {
expectedArgs,
typeMoq.It.is<SpawnOptions>((options) => {
assert.deepEqual(options.extraVariables, expectedExtraVariables);
assert.equal(options.cwd, expectedPath);
assert.equal(options.cwd, expectedPathNew);
assert.equal(options.throwOnStdErr, true);
return true;
}),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,55 @@ suite('pytest test execution adapter', () => {
typeMoq.Times.once(),
);
});
test('pytest execution respects settings.testing.cwd when present', async () => {
const newCwd = path.join('new', 'path');
configService = ({
getSettings: () => ({
testing: { pytestArgs: ['.'], cwd: newCwd },
}),
isTestExecution: () => false,
} as unknown) as IConfigurationService;
const uri = Uri.file(myTestPath);
const uuid = 'uuid123';
testServer
.setup((t) => t.onDiscoveryDataReceived(typeMoq.It.isAny(), typeMoq.It.isAny()))
.returns(() => ({
dispose: () => {
/* no-body */
},
}));
testServer.setup((t) => t.createUUID(typeMoq.It.isAny())).returns(() => uuid);
const outputChannel = typeMoq.Mock.ofType<ITestOutputChannel>();
const testRun = typeMoq.Mock.ofType<TestRun>();
adapter = new PytestTestExecutionAdapter(testServer.object, configService, outputChannel.object);
await adapter.runTests(uri, [], false, testRun.object, execFactory.object);

const pathToPythonFiles = path.join(EXTENSION_ROOT_DIR, 'pythonFiles');
const pathToPythonScript = path.join(pathToPythonFiles, 'vscode_pytest', 'run_pytest_script.py');
const expectedArgs = [pathToPythonScript, '--rootdir', myTestPath];
const expectedExtraVariables = {
PYTHONPATH: pathToPythonFiles,
TEST_UUID: 'uuid123',
TEST_PORT: '12345',
};

execService.verify(
(x) =>
x.exec(
expectedArgs,
typeMoq.It.is<SpawnOptions>((options) => {
assert.equal(options.extraVariables?.PYTHONPATH, expectedExtraVariables.PYTHONPATH);
assert.equal(options.extraVariables?.TEST_UUID, expectedExtraVariables.TEST_UUID);
assert.equal(options.extraVariables?.TEST_PORT, expectedExtraVariables.TEST_PORT);
assert.equal(options.extraVariables?.RUN_TEST_IDS_PORT, '54321');
assert.equal(options.cwd, newCwd);
assert.equal(options.throwOnStdErr, true);
return true;
}),
),
typeMoq.Times.once(),
);
});
test('Debug launched correctly for pytest', async () => {
const uri = Uri.file(myTestPath);
const uuid = 'uuid123';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,4 +54,41 @@ suite('Unittest test discovery adapter', () => {
uuid: '123456789',
});
});
test('DiscoverTests should respect settings.testings.cwd when present', async () => {
let options: TestCommandOptions | undefined;
stubConfigSettings = ({
getSettings: () => ({
testing: { unittestArgs: ['-v', '-s', '.', '-p', 'test*'], cwd: '/foo' },
}),
} as unknown) as IConfigurationService;

const stubTestServer = ({
sendCommand(opt: TestCommandOptions): Promise<void> {
delete opt.outChannel;
options = opt;
return Promise.resolve();
},
onDiscoveryDataReceived: () => {
// no body
},
createUUID: () => '123456789',
} as unknown) as ITestServer;

const uri = Uri.file('/foo/bar');
const newCwd = '/foo';
const script = path.join(EXTENSION_ROOT_DIR, 'pythonFiles', 'unittestadapter', 'discovery.py');

const adapter = new UnittestTestDiscoveryAdapter(stubTestServer, stubConfigSettings, outputChannel.object);
adapter.discoverTests(uri);

assert.deepStrictEqual(options, {
workspaceFolder: uri,
cwd: newCwd,
command: {
script,
args: ['--udiscovery', '-v', '-s', '.', '-p', 'test*'],
},
uuid: '123456789',
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -62,4 +62,43 @@ suite('Unittest test execution adapter', () => {
assert.deepStrictEqual(options, expectedOptions);
});
});
test('runTests should respect settings.testing.cwd when present', async () => {
stubConfigSettings = ({
getSettings: () => ({
testing: { unittestArgs: ['-v', '-s', '.', '-p', 'test*'], cwd: '/foo' },
}),
} as unknown) as IConfigurationService;
let options: TestCommandOptions | undefined;

const stubTestServer = ({
sendCommand(opt: TestCommandOptions, runTestIdPort?: string): Promise<void> {
delete opt.outChannel;
options = opt;
assert(runTestIdPort !== undefined);
return Promise.resolve();
},
onRunDataReceived: () => {
// no body
},
createUUID: () => '123456789',
} as unknown) as ITestServer;

const newCwd = '/foo';
const uri = Uri.file('/foo/bar');
const script = path.join(EXTENSION_ROOT_DIR, 'pythonFiles', 'unittestadapter', 'execution.py');

const adapter = new UnittestTestExecutionAdapter(stubTestServer, stubConfigSettings, outputChannel.object);
const testIds = ['test1id', 'test2id'];
adapter.runTests(uri, testIds, false).then(() => {
const expectedOptions: TestCommandOptions = {
workspaceFolder: uri,
command: { script, args: ['--udiscovery', '-v', '-s', '.', '-p', 'test*'] },
cwd: newCwd,
uuid: '123456789',
debugBool: false,
testIds,
};
assert.deepStrictEqual(options, expectedOptions);
});
});
});