Skip to content

Commit 71c8f08

Browse files
authored
vs2019 support for tfs2019 (#9800)
* Added VS 2019 support * Added 2019 to drop down list * regenerated auto generated files
1 parent 07a7c6c commit 71c8f08

File tree

6 files changed

+100
-42
lines changed

6 files changed

+100
-42
lines changed

Tasks/VsTestV2/Strings/resources.resjson/en-US/resources.resjson

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232
"loc.input.help.uiTests": "To run UI tests, ensure that the agent is set to run in interactive mode. Setting up an agent to run interactively must be done before queueing the build / release. Checking this box does <b>not</b> configure the agent in interactive mode automatically. This option in the task is to only serve as a reminder to configure agent appropriately to avoid failures. <br><br> Hosted Windows agents from the VS 2015 and 2017 pools can be used to run UI tests.<br> [More information](https://aka.ms/uitestmoreinfo).",
3333
"loc.input.label.vstestLocationMethod": "Select test platform using",
3434
"loc.input.label.vsTestVersion": "Test platform version",
35-
"loc.input.help.vsTestVersion": "The version of Visual Studio test to use. If latest is specified it chooses Visual Studio 2017 or Visual Studio 2015 depending on what is installed. Visual Studio 2013 is not supported. To run tests without needing Visual Studio on the agent, use the ‘Installed by tools installer’ option. Be sure to include the ‘Visual Studio Test Platform Installer’ task to acquire the test platform from nuget.",
35+
"loc.input.help.vsTestVersion": "The version of Visual Studio test to use. If latest is specified it chooses the latest among Visual Studio 2019, 2017 or 2015 depending on what is installed. Visual Studio 2013 is not supported. To run tests without needing Visual Studio on the agent, use the ‘Installed by tools installer’ option. Be sure to include the ‘Visual Studio Test Platform Installer’ task to acquire the test platform from nuget.",
3636
"loc.input.label.vstestLocation": "Path to vstest.console.exe",
3737
"loc.input.help.vstestLocation": "Optionally supply the path to VSTest.",
3838
"loc.input.label.runSettingsFile": "Settings file",

Tasks/VsTestV2/inputparser.ts

Lines changed: 60 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
import * as path from 'path';
22
import * as tl from 'vsts-task-lib/task';
3+
import * as tr from 'vsts-task-lib/toolrunner';
34
import * as utils from './helpers';
45
import * as constants from './constants';
56
import * as ci from './cieventlogger';
67
import { AreaCodes, DistributionTypes } from './constants';
78
import * as idc from './inputdatacontract';
8-
import * as versionfinder from './versionfinder';
99
import * as Q from "q";
1010
import * as isUncPath from 'is-unc-path';
1111
const regedit = require('regedit');
@@ -65,7 +65,6 @@ export function parseInputsForNonDistributedTestRun() : idc.InputDataContract {
6565
inputDataContract.EnableSingleAgentAPIFlow = utils.Helper.stringToBool(tl.getVariable('Hydra.EnableApiFlow'));
6666
inputDataContract.SourcesDirectory = tl.getVariable('Build.SourcesDirectory');
6767

68-
6968
logWarningForWER(tl.getBoolInput('uiTests'));
7069

7170
return inputDataContract;
@@ -158,8 +157,8 @@ function getTargetBinariesSettings(inputDataContract : idc.InputDataContract) :
158157
function getTestReportingSettings(inputDataContract : idc.InputDataContract) : idc.InputDataContract {
159158
inputDataContract.TestReportingSettings = <idc.TestReportingSettings>{};
160159
inputDataContract.TestReportingSettings.TestRunTitle = tl.getInput('testRunTitle');
161-
inputDataContract.TestReportingSettings.TestRunSystem = "VSTS - vstest";
162-
160+
inputDataContract.TestReportingSettings.TestRunSystem = 'VSTS - vstest';
161+
163162
if (utils.Helper.isNullEmptyOrUndefined(inputDataContract.TestReportingSettings.TestRunTitle)) {
164163

165164
let definitionName = tl.getVariable('BUILD_DEFINITIONNAME');
@@ -209,7 +208,7 @@ function getTestPlatformSettings(inputDataContract : idc.InputDataContract) : id
209208

210209
ci.publishEvent({ subFeature: 'ToolsInstallerInstallationSuccessful' });
211210

212-
} else if ((vsTestVersion !== '15.0') && (vsTestVersion !== '14.0')
211+
} else if ((vsTestVersion !== '16.0') && (vsTestVersion !== '15.0') && (vsTestVersion !== '14.0')
213212
&& (vsTestVersion.toLowerCase() !== 'latest')) {
214213
throw new Error(tl.loc('vstestVersionInvalid', vsTestVersion));
215214
} else if (vsTestLocationMethod === utils.Constants.vsTestVersionString && vsTestVersion === '12.0') {
@@ -360,7 +359,7 @@ function getExecutionSettings(inputDataContract : idc.InputDataContract) : idc.I
360359

361360
inputDataContract.ExecutionSettings.CodeCoverageEnabled = tl.getBoolInput('codeCoverageEnabled');
362361
console.log(tl.loc('codeCoverageInput', inputDataContract.ExecutionSettings.CodeCoverageEnabled));
363-
362+
364363
inputDataContract = getDiagnosticsSettings(inputDataContract);
365364
console.log(tl.loc('diagnosticsInput', inputDataContract.ExecutionSettings.DiagnosticsSettings.Enabled));
366365

@@ -372,12 +371,10 @@ function getExecutionSettings(inputDataContract : idc.InputDataContract) : idc.I
372371

373372
function getDiagnosticsSettings(inputDataContract : idc.InputDataContract) : idc.InputDataContract {
374373
inputDataContract.ExecutionSettings.DiagnosticsSettings = <idc.DiagnosticsSettings>{};
375-
if(enableDiagnosticsSettings)
376-
{
374+
if (enableDiagnosticsSettings) {
377375
inputDataContract.ExecutionSettings.DiagnosticsSettings.Enabled = tl.getBoolInput('diagnosticsEnabled');
378376
inputDataContract.ExecutionSettings.DiagnosticsSettings.DumpCollectionType = tl.getInput('collectDumpOn').toLowerCase();
379-
}
380-
else {
377+
} else {
381378
inputDataContract.ExecutionSettings.DiagnosticsSettings.Enabled = false;
382379
}
383380
return inputDataContract;
@@ -404,8 +401,8 @@ function getTiaSettings(inputDataContract : idc.InputDataContract) : idc.InputDa
404401

405402
// This option gives the user ability to add Fully Qualified name filters for test impact. Does not work with XUnit
406403
inputDataContract.ExecutionSettings.TiaSettings.UseTestCaseFilterInResponseFile = utils.Helper.stringToBool(tl.getVariable('tia.useTestCaseFilterInResponseFile'));
407-
408-
// A legacy switch to disable test impact from build variables
404+
405+
// A legacy switch to disable test impact from build variables
409406
inputDataContract.ExecutionSettings.TiaSettings.Enabled = !utils.Helper.stringToBool(tl.getVariable('DisableTestImpactAnalysis'));
410407

411408
const buildReason = tl.getVariable('Build.Reason');
@@ -423,7 +420,7 @@ function getTiaSettings(inputDataContract : idc.InputDataContract) : idc.InputDa
423420
}
424421

425422
function getRerunSettings(inputDataContract : idc.InputDataContract) : idc.InputDataContract {
426-
// Rerun settings
423+
427424
if (tl.getBoolInput('rerunFailedTests') === false) {
428425
return inputDataContract;
429426
}
@@ -459,6 +456,7 @@ function getRerunSettings(inputDataContract : idc.InputDataContract) : idc.Input
459456
} else {
460457
tl.warning(tl.loc('invalidRerunMaxAttempts'));
461458
}
459+
462460
return inputDataContract;
463461
}
464462

@@ -490,35 +488,70 @@ function getTIALevel(fileLevel: string) {
490488
}
491489

492490
function getTestPlatformPath(inputDataContract : idc.InputDataContract) {
493-
let vsTestVersion = tl.getInput('vsTestVersion');
491+
const vsTestVersion = tl.getInput('vsTestVersion');
492+
494493
if (vsTestVersion.toLowerCase() === 'latest') {
495-
// latest
496-
tl.debug('Searching for latest Visual Studio');
497-
const vstestconsole15Path = versionfinder.getVSTestConsole15Path();
498-
if (vstestconsole15Path) {
499-
vsTestVersion = '15.0';
500-
return vstestconsole15Path;
494+
tl.debug('Searching for latest Visual Studio.');
495+
496+
let vstestconsolePath = getVSTestConsolePath('16.0', '17.0');
497+
if (vstestconsolePath) {
498+
return path.join(vstestconsolePath, 'Common7', 'IDE', 'Extensions', 'TestPlatform');
499+
}
500+
501+
vstestconsolePath = getVSTestConsolePath('15.0', '16.0');
502+
if (vstestconsolePath) {
503+
return path.join(vstestconsolePath, 'Common7', 'IDE', 'CommonExtensions', 'Microsoft', 'TestWindow');
501504
}
502505

503506
// fallback
504-
tl.debug('Unable to find an instance of Visual Studio 2017..');
507+
tl.debug('Unable to find an instance of Visual Studio 2017 or higher.');
505508
tl.debug('Searching for Visual Studio 2015..');
506-
vsTestVersion = '14.0';
507-
return versionfinder.getVSTestLocation(14);
509+
return getVSTestLocation(14);
508510
}
509511

510512
const vsVersion: number = parseFloat(vsTestVersion);
511513

514+
if (vsVersion === 16.0) {
515+
const vstestconsolePath = getVSTestConsolePath('15.0', '17.0');
516+
if (vstestconsolePath) {
517+
return path.join(vstestconsolePath, 'Common7', 'IDE', 'Extensions', 'TestPlatform');
518+
}
519+
throw (new Error(tl.loc('VstestNotFound', utils.Helper.getVSVersion(vsVersion))));
520+
}
521+
512522
if (vsVersion === 15.0) {
513-
const vstestconsole15Path = versionfinder.getVSTestConsole15Path();
514-
if (vstestconsole15Path) {
515-
return vstestconsole15Path;
523+
const vstestconsolePath = getVSTestConsolePath('15.0', '16.0');
524+
if (vstestconsolePath) {
525+
return path.join(vstestconsolePath, 'Common7', 'IDE', 'CommonExtensions', 'Microsoft', 'TestWindow');
516526
}
517527
throw (new Error(tl.loc('VstestNotFound', utils.Helper.getVSVersion(vsVersion))));
518528
}
519529

520530
tl.debug('Searching for Visual Studio ' + vsVersion.toString());
521-
return versionfinder.getVSTestLocation(vsVersion);
531+
return getVSTestLocation(vsVersion);
532+
}
533+
534+
function getVSTestConsolePath(versionLowerLimit : string, versionUpperLimit : string): string {
535+
const vswhereTool = tl.tool(path.join(__dirname, 'vswhere.exe'));
536+
537+
vswhereTool.line(`-version [${versionLowerLimit},${versionUpperLimit}) -latest -products * -requires Microsoft.VisualStudio.PackageGroup.TestTools.Core -property installationPath`);
538+
let vsPath = vswhereTool.execSync({ silent: true } as tr.IExecSyncOptions).stdout;
539+
vsPath = utils.Helper.trimString(vsPath);
540+
tl.debug('Visual Studio 15.0 or higher installed path: ' + vsPath);
541+
542+
if (!utils.Helper.isNullOrWhitespace(vsPath)) {
543+
return vsPath;
544+
}
545+
546+
return null;
547+
}
548+
549+
export function getVSTestLocation(vsVersion: number): string {
550+
const vsCommon: string = tl.getVariable('VS' + vsVersion + '0COMNTools');
551+
if (!vsCommon) {
552+
throw (new Error(tl.loc('VstestNotFound', utils.Helper.getVSVersion(vsVersion))));
553+
}
554+
return path.join(vsCommon, '..\\IDE\\CommonExtensions\\Microsoft\\TestWindow');
522555
}
523556

524557
async function logWarningForWER(runUITests: boolean) {

Tasks/VsTestV2/task.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
"version": {
1818
"Major": 2,
1919
"Minor": 143,
20-
"Patch": 8
20+
"Patch": 9
2121
},
2222
"demands": [
2323
"vstest"
@@ -201,11 +201,12 @@
201201
"label": "Test platform version",
202202
"defaultValue": "latest",
203203
"required": false,
204-
"helpMarkDown": "The version of Visual Studio test to use. If latest is specified it chooses Visual Studio 2017 or Visual Studio 2015 depending on what is installed. Visual Studio 2013 is not supported. To run tests without needing Visual Studio on the agent, use the ‘Installed by tools installer’ option. Be sure to include the ‘Visual Studio Test Platform Installer’ task to acquire the test platform from nuget.",
204+
"helpMarkDown": "The version of Visual Studio test to use. If latest is specified it chooses the latest among Visual Studio 2019, 2017 or 2015 depending on what is installed. Visual Studio 2013 is not supported. To run tests without needing Visual Studio on the agent, use the ‘Installed by tools installer’ option. Be sure to include the ‘Visual Studio Test Platform Installer’ task to acquire the test platform from nuget.",
205205
"visibleRule": "vstestLocationMethod = version",
206206
"groupName": "executionOptions",
207207
"options": {
208208
"latest": "Latest",
209+
"16.0": "Visual Studio 2019",
209210
"15.0": "Visual Studio 2017",
210211
"14.0": "Visual Studio 2015",
211212
"toolsInstaller": "Installed by Tools Installer"

Tasks/VsTestV2/task.loc.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
"version": {
1818
"Major": 2,
1919
"Minor": 143,
20-
"Patch": 8
20+
"Patch": 9
2121
},
2222
"demands": [
2323
"vstest"
@@ -206,6 +206,7 @@
206206
"groupName": "executionOptions",
207207
"options": {
208208
"latest": "Latest",
209+
"16.0": "Visual Studio 2019",
209210
"15.0": "Visual Studio 2017",
210211
"14.0": "Visual Studio 2015",
211212
"toolsInstaller": "Installed by Tools Installer"
@@ -618,4 +619,4 @@
618619
"diagnosticsInput": "ms-resource:loc.messages.diagnosticsInput",
619620
"UncPathNotSupported": "ms-resource:loc.messages.UncPathNotSupported"
620621
}
621-
}
622+
}

Tasks/VsTestV2/taskinputparser.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,7 @@ function initTestConfigurations(testConfiguration: models.TestConfigurations) {
165165
testConfiguration.vsTestLocation = testConfiguration.toolsInstallerConfig.vsTestConsolePathFromPackageLocation;
166166

167167
testConfiguration.toolsInstallerConfig.isToolsInstallerInUse = true;
168-
} else if ((testConfiguration.vsTestVersion !== '15.0') && (testConfiguration.vsTestVersion !== '14.0')
168+
} else if ((testConfiguration.vsTestVersion !== '16.0') && (testConfiguration.vsTestVersion !== '15.0') && (testConfiguration.vsTestVersion !== '14.0')
169169
&& (testConfiguration.vsTestVersion.toLowerCase() !== 'latest')) {
170170
throw new Error(tl.loc('vstestVersionInvalid', testConfiguration.vsTestVersion));
171171
}

Tasks/VsTestV2/versionfinder.ts

Lines changed: 32 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,13 @@ const regedit = require('regedit');
1111

1212
export function getVsTestRunnerDetails(testConfig: models.TestConfigurations) {
1313
const vstestexeLocation = locateVSTestConsole(testConfig);
14+
15+
// Temporary hack for 16.0. All this code will be removed once we migrate to the Hydra flow
16+
if (testConfig.vsTestVersion === '16.0') {
17+
testConfig.vsTestVersionDetails = new version.VSTestVersion(vstestexeLocation, 16, 0, 0);
18+
return;
19+
}
20+
1421
const vstestLocationEscaped = vstestexeLocation.replace(/\\/g, '\\\\');
1522
const wmicTool = tl.tool('wmic');
1623
const wmicArgs = ['datafile', 'where', 'name=\''.concat(vstestLocationEscaped, '\''), 'get', 'Version', '/Value'];
@@ -84,10 +91,17 @@ function locateTestWindow(testConfig: models.TestConfigurations): string {
8491
if (testConfig.vsTestVersion.toLowerCase() === 'latest') {
8592
// latest
8693
tl.debug('Searching for latest Visual Studio');
87-
const vstestconsole15Path = getVSTestConsole15Path();
88-
if (vstestconsole15Path) {
94+
95+
let vstestconsolePath = getVSTestConsolePath('16.0', '17.0');
96+
if (vstestconsolePath) {
97+
testConfig.vsTestVersion = "16.0";
98+
return path.join(vstestconsolePath, 'Common7', 'IDE', 'Extensions', 'TestPlatform');
99+
}
100+
101+
vstestconsolePath = getVSTestConsolePath('15.0', '16.0');
102+
if (vstestconsolePath) {
89103
testConfig.vsTestVersion = "15.0";
90-
return vstestconsole15Path;
104+
return path.join(vstestconsolePath, 'Common7', 'IDE', 'CommonExtensions', 'Microsoft', 'TestWindow');
91105
}
92106

93107
// fallback
@@ -99,10 +113,18 @@ function locateTestWindow(testConfig: models.TestConfigurations): string {
99113

100114
const vsVersion: number = parseFloat(testConfig.vsTestVersion);
101115

116+
if (vsVersion === 16.0) {
117+
const vstestconsolePath = getVSTestConsolePath('16.0', '17.0');
118+
if (vstestconsolePath) {
119+
return path.join(vstestconsolePath, 'Common7', 'IDE', 'Extensions', 'TestPlatform');
120+
}
121+
throw (new Error(tl.loc('VstestNotFound', utils.Helper.getVSVersion(vsVersion))));
122+
}
123+
102124
if (vsVersion === 15.0) {
103-
const vstestconsole15Path = getVSTestConsole15Path();
104-
if (vstestconsole15Path) {
105-
return vstestconsole15Path;
125+
const vstestconsolePath = getVSTestConsolePath('15.0', '16.0');
126+
if (vstestconsolePath) {
127+
return path.join(vstestconsolePath, 'Common7', 'IDE', 'CommonExtensions', 'Microsoft', 'TestWindow');
106128
}
107129
throw (new Error(tl.loc('VstestNotFound', utils.Helper.getVSVersion(vsVersion))));
108130
}
@@ -111,14 +133,15 @@ function locateTestWindow(testConfig: models.TestConfigurations): string {
111133
return getVSTestLocation(vsVersion);
112134
}
113135

114-
export function getVSTestConsole15Path(): string {
136+
export function getVSTestConsolePath(versionLowerLimit : string, versionUpperLimit : string): string {
115137
const vswhereTool = tl.tool(path.join(__dirname, 'vswhere.exe'));
116-
vswhereTool.line('-version [15.0,16.0) -latest -products * -requires Microsoft.VisualStudio.PackageGroup.TestTools.Core -property installationPath');
138+
139+
vswhereTool.line(`-version [${versionLowerLimit},${versionUpperLimit}) -latest -products * -requires Microsoft.VisualStudio.PackageGroup.TestTools.Core -property installationPath`);
117140
let vsPath = vswhereTool.execSync({ silent: true } as tr.IExecSyncOptions).stdout;
118141
vsPath = utils.Helper.trimString(vsPath);
119142
tl.debug('Visual Studio 15.0 or higher installed path: ' + vsPath);
120143
if (!utils.Helper.isNullOrWhitespace(vsPath)) {
121-
return path.join(vsPath, 'Common7', 'IDE', 'CommonExtensions', 'Microsoft', 'TestWindow');
144+
return vsPath;
122145
}
123146
return null;
124147
}

0 commit comments

Comments
 (0)