Skip to content

🐛 handle failure to detect conda environment #829

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 3 commits into from
Feb 21, 2018
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
2 changes: 1 addition & 1 deletion src/client/common/logger.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ const PREFIX = 'Python Extension: ';
export class Logger implements ILogger {
public logError(message: string, ex?: Error) {
if (ex) {
console.error(`${PREFIX}${message}`, error);
console.error(`${PREFIX}${message}`, ex);
} else {
console.error(`${PREFIX}${message}`);
}
Expand Down
6 changes: 3 additions & 3 deletions src/client/interpreter/locators/services/condaService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ export class CondaService implements ICondaService {
const homeDir = this.platform.isWindows ? process.env.USERPROFILE : (process.env.HOME || process.env.HOMEPATH);
return homeDir ? path.join(homeDir, '.conda', 'environments.txt') : undefined;
}
constructor( @inject(IServiceContainer) private serviceContainer: IServiceContainer,
constructor(@inject(IServiceContainer) private serviceContainer: IServiceContainer,
@inject(IInterpreterLocatorService) @named(WINDOWS_REGISTRY_SERVICE) @optional() private registryLookupForConda?: IInterpreterLocatorService) {
this.processService = this.serviceContainer.get<IProcessService>(IProcessService);
this.platform = this.serviceContainer.get<IPlatformService>(IPlatformService);
Expand Down Expand Up @@ -106,10 +106,10 @@ export class CondaService implements ICondaService {
const fs = this.serviceContainer.get<IFileSystem>(IFileSystem);

// From the list of conda environments find this dir.
let matchingEnvs = environments!.filter(item => fs.arePathsSame(item.path, interpreterPathToMatch));
let matchingEnvs = Array.isArray(environments) ? environments.filter(item => fs.arePathsSame(item.path, interpreterPathToMatch)) : [];
if (matchingEnvs.length === 0) {
environments = await this.getCondaEnvironments(true);
matchingEnvs = environments!.filter(item => fs.arePathsSame(item.path, interpreterPathToMatch));
matchingEnvs = Array.isArray(environments) ? environments.filter(item => fs.arePathsSame(item.path, interpreterPathToMatch)) : [];
}

if (matchingEnvs.length > 0) {
Expand Down
21 changes: 13 additions & 8 deletions src/test/debugger/misc.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,13 @@ const EXPERIMENTAL_DEBUG_ADAPTER = path.join(__dirname, '..', '..', 'client', 'd
});
teardown(async () => {
// Wait for a second before starting another test (sometimes, sockets take a while to get closed).
await new Promise(resolve => setTimeout(resolve, 1000));
await sleep(1000);
try {
// tslint:disable-next-line:no-empty
await debugClient.stop().catch(() => { });
// tslint:disable-next-line:no-empty
} catch (ex) { }
await sleep(1000);
});

function buildLauncArgs(pythonFile: string, stopOnEntry: boolean = false): LaunchRequestArguments {
Expand Down Expand Up @@ -131,15 +132,19 @@ const EXPERIMENTAL_DEBUG_ADAPTER = path.join(__dirname, '..', '..', 'client', 'd
]);
});
test('Ensure threadid is int32', async () => {
const launchArgs = buildLauncArgs('sample2.py', false);
const breakpointLocation = { path: path.join(debugFilesPath, 'sample2.py'), column: 0, line: 5 };
await debugClient.hitBreakpoint(launchArgs, breakpointLocation);
if (debuggerType !== 'python') {
return this.skip();
}
const threadIdPromise = debugClient.waitForEvent('thread');

const threads = await debugClient.threadsRequest();
expect(threads).to.be.not.equal(undefined, 'no threads response');
expect(threads.body.threads).to.be.lengthOf(1);
await Promise.all([
debugClient.configurationSequence(),
debugClient.launch(buildLauncArgs('simplePrint.py', true)),
debugClient.waitForEvent('initialized'),
debugClient.waitForEvent('stopped')
]);

const threadId = threads.body.threads[0].id;
const threadId = ((await threadIdPromise) as ThreadEvent).body.threadId;
expect(threadId).to.be.lessThan(MAX_SIGNED_INT32 + 1, 'ThreadId is not an integer');
await Promise.all([
debugClient.continueRequest({ threadId }),
Expand Down
29 changes: 29 additions & 0 deletions src/test/interpreters/condaService.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -514,4 +514,33 @@ suite('Interpreters Conda Service', () => {
assert.equal(isAvailable, false);
});

async function testFailureOfGettingCondaEnvironments(isWindows: boolean, isOsx: boolean, isLinux: boolean, pythonPath: string) {
platformService.setup(p => p.isLinux).returns(() => isLinux);
platformService.setup(p => p.isWindows).returns(() => isWindows);
platformService.setup(p => p.isMac).returns(() => isOsx);

const stateFactory = TypeMoq.Mock.ofType<IPersistentStateFactory>();
serviceContainer.setup(c => c.get(TypeMoq.It.isValue(IPersistentStateFactory))).returns(() => stateFactory.object);
const state = new MockState({ data: undefined });
stateFactory.setup(s => s.createGlobalPersistentState(TypeMoq.It.isValue('CONDA_ENVIRONMENTS'), TypeMoq.It.isValue(undefined))).returns(() => state);
processService.setup(p => p.exec(TypeMoq.It.isValue('conda'), TypeMoq.It.isValue(['--version']), TypeMoq.It.isAny())).returns(() => Promise.resolve({ stdout: 'some value' }));
processService.setup(p => p.exec(TypeMoq.It.isValue('conda'), TypeMoq.It.isValue(['env', 'list']), TypeMoq.It.isAny())).returns(() => Promise.reject(new Error('Failed')));
const condaEnv = await condaService.getCondaEnvironment(pythonPath);
expect(condaEnv).to.be.equal(undefined, 'Conda should be undefined');
}
test('Fails to identify an environment as a conda env (windows)', async () => {
const pythonPath = path.join('c', 'users', 'xyz', '.conda', 'envs', 'one', 'python.exe');
fileSystem.setup(f => f.directoryExistsAsync(TypeMoq.It.isValue(path.join(path.dirname(pythonPath), 'conda-meta')))).returns(() => Promise.resolve(true));
await testFailureOfGettingCondaEnvironments(true, false, false, pythonPath);
});
test('Fails to identify an environment as a conda env (linux)', async () => {
const pythonPath = path.join('c', 'users', 'xyz', '.conda', 'envs', 'one', 'python');
fileSystem.setup(f => f.directoryExistsAsync(TypeMoq.It.isValue(path.join(path.dirname(pythonPath), 'conda-meta')))).returns(() => Promise.resolve(true));
await testFailureOfGettingCondaEnvironments(false, false, true, pythonPath);
});
test('Fails to identify an environment as a conda env (osx)', async () => {
const pythonPath = path.join('c', 'users', 'xyz', '.conda', 'envs', 'one', 'python');
fileSystem.setup(f => f.directoryExistsAsync(TypeMoq.It.isValue(path.join(path.dirname(pythonPath), 'conda-meta')))).returns(() => Promise.resolve(true));
await testFailureOfGettingCondaEnvironments(false, true, false, pythonPath);
});
});