From cb83d3be59f810fc3d7089293da2b80c0f444a41 Mon Sep 17 00:00:00 2001 From: Kartik Raj Date: Thu, 6 Dec 2018 15:50:58 -0800 Subject: [PATCH] Added virtual environment system tests --- build/ci/templates/virtual_env_tests.yml | 77 ++++++++++++---- build/ci/vscode-python-pr-validation.yaml | 2 +- package.json | 3 +- src/test/ciConstants.ts | 1 + src/test/common.ts | 2 +- src/test/virtualEnvTest.ts | 19 ++++ src/testVirtualEnv/terminalActivation.test.ts | 87 +++++++++++++++++++ 7 files changed, 171 insertions(+), 20 deletions(-) create mode 100644 src/test/virtualEnvTest.ts create mode 100644 src/testVirtualEnv/terminalActivation.test.ts diff --git a/build/ci/templates/virtual_env_tests.yml b/build/ci/templates/virtual_env_tests.yml index 22b4bc91ca79..7096ae83ccc9 100644 --- a/build/ci/templates/virtual_env_tests.yml +++ b/build/ci/templates/virtual_env_tests.yml @@ -12,7 +12,8 @@ parameters: AzureStorageAccountName: 'vscodepythonci' AzureStorageContainerName: 'vscode-python-ci' EnvironmentExecutableFolder: 'Scripts' - DIRECTORY_FOR_VIRTUAL_ENVS: './envPaths.json' + ENV_PATHS_LOCATION: './src/testVirtualEnv/envPaths.json' + TestSuiteName: 'testVirtualEnv' jobs: - job: ${{ parameters.name }} @@ -35,7 +36,8 @@ jobs: azureStorageContainerName: ${{ parameters.AzureStorageContainerName }} plaform: ${{ parameters.Platform }} environmentExecutableFolder: ${{ parameters.EnvironmentExecutableFolder }} - DIRECTORY_FOR_VIRTUAL_ENVS: ${{ parameters.DIRECTORY_FOR_VIRTUAL_ENVS }} + ENV_PATHS_LOCATION: ${{ parameters.ENV_PATHS_LOCATION }} + TestSuiteName: ${{ parameters.TestSuiteName }} steps: - bash: echo REQUESTED VARIABLE VALUES @@ -85,6 +87,10 @@ jobs: cleanDestinationFolder: false + - task: NodeTool@0 + displayName: 'Use Node $(NodeVersion)' + inputs: + versionSpec: '$(NodeVersion)' - task: UsePythonVersion@0 displayName: 'Use Python 3.7' @@ -99,13 +105,13 @@ jobs: import os.path key = sys.argv[1] - if os.path.isfile('$(DIRECTORY_FOR_VIRTUAL_ENVS)'): - with open('$(DIRECTORY_FOR_VIRTUAL_ENVS)', 'r') as read_file: + if os.path.isfile('$(ENV_PATHS_LOCATION)'): + with open('$(ENV_PATHS_LOCATION)', 'r') as read_file: data = json.load(read_file) else: - with open('$(DIRECTORY_FOR_VIRTUAL_ENVS)', 'w+') as read_file: + with open('$(ENV_PATHS_LOCATION)', 'w+') as read_file: data = {} - with open('$(DIRECTORY_FOR_VIRTUAL_ENVS)', 'w') as outfile: + with open('$(ENV_PATHS_LOCATION)', 'w') as outfile: data[key] = sys.executable json.dump(data, outfile, sort_keys=True, indent=4)" > addEnvPath.py @@ -117,7 +123,7 @@ jobs: pipenv run python addEnvPath.py pipenv - cat $(DIRECTORY_FOR_VIRTUAL_ENVS) + cat $(ENV_PATHS_LOCATION) displayName: 'Create pipenv environment' @@ -127,7 +133,7 @@ jobs: .venv/$(environmentExecutableFolder)/python addEnvPath.py venv - cat $(DIRECTORY_FOR_VIRTUAL_ENVS) + cat $(ENV_PATHS_LOCATION) displayName: 'Create venv environment' @@ -139,23 +145,60 @@ jobs: .virtualenv/$(environmentExecutableFolder)/python addEnvPath.py virtualenv - cat $(DIRECTORY_FOR_VIRTUAL_ENVS) + cat $(ENV_PATHS_LOCATION) displayName: 'Create virtualenv environment' - - task: CondaEnvironment@1 - displayName: 'Create conda environment ' + - task: Npm@1 + displayName: 'update npm' inputs: - packageSpecs: 'python=3.7' + command: custom + verbose: true - - bash: | - python addEnvPath.py conda + customCommand: 'install -g npm@$(npmVersion)' + + + - task: Npm@1 + displayName: 'npm ci' + inputs: + command: custom + + verbose: true + + customCommand: ci + + + - task: CmdLine@1 + displayName: 'pip upgrade pip' + inputs: + filename: python - source deactivate + arguments: '-m pip install --upgrade pip' - cat $(DIRECTORY_FOR_VIRTUAL_ENVS) - displayName: 'Save conda environment executable' + - task: CmdLine@1 + displayName: 'pip install requirements' + inputs: + filename: python + + arguments: '-m pip install --upgrade -r ./build/test-requirements.txt' + + + - task: CmdLine@1 + displayName: 'pip install ptvsd' + inputs: + filename: python + + arguments: '-m pip --disable-pip-version-check install -t ./pythonFiles/lib/python --no-cache-dir --implementation py --no-deps --upgrade -r requirements.txt' + + + - task: Npm@1 + displayName: 'run $(TestSuiteName)' + inputs: + command: custom + + verbose: true + customCommand: 'run $(TestSuiteName)' diff --git a/build/ci/vscode-python-pr-validation.yaml b/build/ci/vscode-python-pr-validation.yaml index e8dfefb30aae..1a2b948b479d 100644 --- a/build/ci/vscode-python-pr-validation.yaml +++ b/build/ci/vscode-python-pr-validation.yaml @@ -29,7 +29,7 @@ jobs: AzureStorageAccountName: 'vscodepythonci' AzureStorageContainerName: 'vscode-python-ci' EnvironmentExecutableFolder: 'Scripts' - DIRECTORY_FOR_VIRTUAL_ENVS: './envPaths.json' + ENV_PATHS_LOCATION: './src/testVirtualEnv/envPaths.json' - job: 'System_Test_macOS' diff --git a/package.json b/package.json index cc2fa5603754..0975a0ff4767 100644 --- a/package.json +++ b/package.json @@ -1845,7 +1845,7 @@ "compile-webviews": "gulp compile-webviews", "compile-webviews-verbose": "npx webpack --config webpack.datascience-ui.config.js", "postinstall": "node ./node_modules/vscode/bin/install", - "test": "node ./out/test/standardTest.js && node ./out/test/multiRootTest.js", + "test": "node ./out/test/standardTest.js && node ./out/test/multiRootTest.js && node ./out/test/virtualEnvTest.js", "test:unittests": "node ./out/test/unittests.js", "test:functional": "node ./out/test/functionalTests.js", "testDebugger": "node ./out/test/debuggerTest.js", @@ -1853,6 +1853,7 @@ "testMultiWorkspace": "node ./out/test/multiRootTest.js", "testPerformance": "node ./out/test/performanceTest.js", "testSmoke": "node ./out/test/smokeTest.js", + "testVirtualEnv": "node ./out/test/virtualEnvTest.js", "lint-staged": "node gulpfile.js", "lint": "tslint src/**/*.ts -t verbose", "clean": "gulp clean", diff --git a/src/test/ciConstants.ts b/src/test/ciConstants.ts index e1fc989e5fd8..edec8d30d000 100644 --- a/src/test/ciConstants.ts +++ b/src/test/ciConstants.ts @@ -7,6 +7,7 @@ // Constants that pertain to CI processes/tests only. No dependencies on vscode! // +export const ENV_PATHS_LOCATION = process.env.ENV_PATHS_LOCATION; export const IS_APPVEYOR = process.env.APPVEYOR === 'true'; export const IS_TRAVIS = process.env.TRAVIS === 'true'; export const IS_VSTS = process.env.TF_BUILD !== undefined; diff --git a/src/test/common.ts b/src/test/common.ts index e1e9e30150df..4182c712aaa9 100644 --- a/src/test/common.ts +++ b/src/test/common.ts @@ -35,7 +35,7 @@ export type PythonSettingKeys = 'workspaceSymbols.enabled' | 'pythonPath' | 'unitTest.nosetestArgs' | 'unitTest.pyTestArgs' | 'unitTest.unittestArgs' | 'formatting.provider' | 'sortImports.args' | 'unitTest.nosetestsEnabled' | 'unitTest.pyTestEnabled' | 'unitTest.unittestEnabled' | - 'envFile' | 'jediEnabled' | 'linting.ignorePatterns'; + 'envFile' | 'jediEnabled' | 'linting.ignorePatterns' | 'terminal.activateEnvironment'; async function disposePythonSettings() { if (!IS_SMOKE_TEST) { diff --git a/src/test/virtualEnvTest.ts b/src/test/virtualEnvTest.ts new file mode 100644 index 000000000000..7d257fed4a4b --- /dev/null +++ b/src/test/virtualEnvTest.ts @@ -0,0 +1,19 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +'use strict'; + +// tslint:disable:no-console no-require-imports no-var-requires + +import * as path from 'path'; + +process.env.CODE_TESTS_WORKSPACE = process.env.CODE_TESTS_WORKSPACE ? process.env.CODE_TESTS_WORKSPACE : path.join(__dirname, '..', '..', 'src', 'testVirtualEnv'); +process.env.IS_CI_SERVER_TEST_DEBUGGER = ''; +process.env.VSC_PYTHON_CI_TEST = '1'; + +function start() { + console.log('*'.repeat(100)); + console.log('Start Virtual Environment tests'); + require('../../node_modules/vscode/bin/test'); +} +start(); diff --git a/src/testVirtualEnv/terminalActivation.test.ts b/src/testVirtualEnv/terminalActivation.test.ts new file mode 100644 index 000000000000..5f0797623e77 --- /dev/null +++ b/src/testVirtualEnv/terminalActivation.test.ts @@ -0,0 +1,87 @@ +'use strict'; +// tslint:disable:max-func-body-length no-invalid-this no-any + +import { expect } from 'chai'; +import * as fs from 'fs-extra'; +import * as path from 'path'; +import * as vscode from 'vscode'; +import { ENV_PATHS_LOCATION } from '../test/ciConstants'; +import { PYTHON_PATH, setPythonPathInWorkspaceRoot, updateSetting, waitForCondition } from '../test/common'; +import { EXTENSION_ROOT_DIR_FOR_TESTS } from '../test/constants'; +import { sleep } from '../test/core'; +import { initialize, initializeTest } from '../test/initialize'; + +suite('Activation of Environments in Terminal', () => { + const file = path.join(EXTENSION_ROOT_DIR_FOR_TESTS, 'src', 'testMultiRootWkspc', 'smokeTests', 'testExecInTerminal.py'); + const outputFile = path.join(EXTENSION_ROOT_DIR_FOR_TESTS, 'src', 'testMultiRootWkspc', 'smokeTests', 'testExecInTerminal.log'); + const envPathsLocation = ENV_PATHS_LOCATION !== undefined ? + ENV_PATHS_LOCATION : path.join(EXTENSION_ROOT_DIR_FOR_TESTS, 'src', 'testVirtualEnv', 'envPaths.json'); + const envPaths = fs.readJsonSync(envPathsLocation); + suiteSetup(initialize); + setup(async () => { + await initializeTest(); + await cleanUp(); + }); + teardown(cleanUp); + suiteTeardown(revertSettings); + async function revertSettings() { + await updateSetting('terminal.activateEnvironment', false , vscode.workspace.workspaceFolders[0].uri, vscode.ConfigurationTarget.WorkspaceFolder); + } + async function cleanUp() { + if (await fs.pathExists(outputFile)) { + await fs.unlink(outputFile); + } + } + test('Should not activate', async () => { + await updateSetting('terminal.activateEnvironment', false, vscode.workspace.workspaceFolders[0].uri, vscode.ConfigurationTarget.WorkspaceFolder); + const terminal = vscode.window.createTerminal(); + terminal.sendText(`python ${file}`, true); + await waitForCondition(() => fs.pathExists(outputFile), 5_000, '\'testExecInTerminal.log\' file not created'); + const content = await fs.readFile(outputFile, 'utf-8'); + expect(content).to.not.equal(PYTHON_PATH); + }); + test('Should activate with venv', async () => { + await updateSetting('terminal.activateEnvironment', true, vscode.workspace.workspaceFolders[0].uri, vscode.ConfigurationTarget.WorkspaceFolder); + await setPythonPathInWorkspaceRoot(envPaths['venv']); + const terminal = vscode.window.createTerminal(); + await sleep(5000); + terminal.sendText(`python ${file}`, true); + await waitForCondition(() => fs.pathExists(outputFile), 5_000, '\'testExecInTerminal.log\' file not created'); + const content = await fs.readFile(outputFile, 'utf-8'); + + expect(content).to.equal(envPaths['venv']); + }); + test('Should activate with pipenv', async () => { + await updateSetting('terminal.activateEnvironment', true, vscode.workspace.workspaceFolders[0].uri, vscode.ConfigurationTarget.WorkspaceFolder); + await setPythonPathInWorkspaceRoot(envPaths['pipenv']); + const terminal = vscode.window.createTerminal(); + await sleep(5000); + terminal.sendText(`python ${file}`, true); + await waitForCondition(() => fs.pathExists(outputFile), 5_000, '\'testExecInTerminal.log\' file not created'); + const content = await fs.readFile(outputFile, 'utf-8'); + + expect(content).to.equal(envPaths['pipenv']); + }); + test('Should activate with virtualenv', async () => { + await updateSetting('terminal.activateEnvironment', true, vscode.workspace.workspaceFolders[0].uri, vscode.ConfigurationTarget.WorkspaceFolder); + await setPythonPathInWorkspaceRoot(envPaths['virtualenv']); + const terminal = vscode.window.createTerminal(); + await sleep(5000); + terminal.sendText(`python ${file}`, true); + await waitForCondition(() => fs.pathExists(outputFile), 5_000, '\'testExecInTerminal.log\' file not created'); + const content = await fs.readFile(outputFile, 'utf-8'); + + expect(content).to.equal(envPaths['virtualenv']); + }); + test('Should activate with conda', async () => { + await updateSetting('terminal.activateEnvironment', true, vscode.workspace.workspaceFolders[0].uri, vscode.ConfigurationTarget.WorkspaceFolder); + await setPythonPathInWorkspaceRoot(envPaths['conda']); + const terminal = vscode.window.createTerminal(); + await sleep(5000); + terminal.sendText(`python ${file}`, true); + await waitForCondition(() => fs.pathExists(outputFile), 5_000, '\'testExecInTerminal.log\' file not created'); + const content = await fs.readFile(outputFile, 'utf-8'); + + expect(content).to.equal(envPaths['conda']); + }); +});