Skip to content

Commit

Permalink
Cherry-picking the changes from 2.2.7 (#958)
Browse files Browse the repository at this point in the history
* Allow opting-out of ITestDataSource test discovery.
* Fixed missing strong-name and Authenticode signatures (#956)
* Updated signature verification to include DLLs
  • Loading branch information
Haplois committed Sep 3, 2021
1 parent bcd14b2 commit 3bb2cef
Show file tree
Hide file tree
Showing 16 changed files with 283 additions and 62 deletions.
5 changes: 4 additions & 1 deletion scripts/Build.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,10 @@ function Invoke-MSBuild([string]$solution, $buildTarget = $Target, $hasVsixExten
"-m")

Write-Log " $buildTarget`: $solution..."
& "$msbuild" $argument;
& {
$PSNativeCommandArgumentPassing = 'Legacy'
& "$msbuild" $argument;
}

if ($lastExitCode -ne 0) {
throw "Build failed with an exit code of '$lastExitCode'."
Expand Down
21 changes: 21 additions & 0 deletions scripts/build/TestFx.Sign.props
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0">
<PropertyGroup>
<RepoRoot Condition=" '$(RepoRoot)' == '' ">$([MSBuild]::NormalizeDirectory('$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildProjectDirectory), 'LICENSE'))'))</RepoRoot>
<NuGetPackageRoot Condition=" '$(NuGetPackageRoot)' == '' ">$(RepoRoot)packages</NuGetPackageRoot>
<BuildConfiguration Condition=" '$(BuildConfiguration)' == '' ">Release</BuildConfiguration>

<TestFxSigningPropsImported>true</TestFxSigningPropsImported>
</PropertyGroup>

<PropertyGroup>
<AssemblyOriginatorKeyFile>$(MSBuildThisFileDirectory)key.snk</AssemblyOriginatorKeyFile>
<SignAssembly>true</SignAssembly>
<SignType Condition=" '$(SignType)' == '' ">Test</SignType>
<PublicSign Condition=" '$(IsLocalizedBuild)' == '' or '$(IsLocalizedBuild)' != 'true'">true</PublicSign>

<!-- Temporarily turning on Delay signing for Localized builds because publickey = true is not passed on to the assembler to create resource assmblies.-->
<DelaySign Condition=" '$(IsLocalizedBuild)' == 'true' ">true</DelaySign>
<OutputPath Condition=" '$(OutputPath)' == '' ">$(RepoRoot)artifacts\$(Configuration)\$(MSBuildProjectName)\</OutputPath>
</PropertyGroup>
</Project>
35 changes: 35 additions & 0 deletions scripts/build/TestFx.Sign.targets
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<?xml version="1.0" encoding="utf-8"?>
<Project>
<PropertyGroup>
<TestFxSigningTargetsImported>true</TestFxSigningTargetsImported>
</PropertyGroup>

<ItemGroup>
<None Include="$(MSBuildThisFileDirectory)key.snk">
<!-- Do not have this show up in Solution Explorer in VS -->
<InProject>false</InProject>
</None>
</ItemGroup>

<!-- Signing and Localization. -->
<ItemGroup Condition=" '$(IsTest)' == '' or '$(IsTest)' == 'false' ">
<FilesToSign Include="$(OutDir)\$(AssemblyName).dll" Condition=" '$(IsVsixProj)' == '' or '$(IsVsixProj)' != 'true' ">
<Authenticode>Microsoft400</Authenticode>
<StrongName>StrongName</StrongName>
</FilesToSign>

<SignFilesDependsOn Include="GatherLocalizedOutputsForSigning">
<!-- Do not have this show up in Solution Explorer in VS -->
<InProject>false</InProject>
</SignFilesDependsOn>
</ItemGroup>

<Target Name="GatherLocalizedOutputsForSigning" DependsOnTargets="TestFxLocalization">
<ItemGroup>
<FilesToSign Include="$(OutDir)\**\$(AssemblyName).resources.dll">
<Authenticode>Microsoft400</Authenticode>
<StrongName>StrongName</StrongName>
</FilesToSign>
</ItemGroup>
</Target>
</Project>
7 changes: 1 addition & 6 deletions scripts/build/TestFx.props
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,14 @@
</PropertyGroup>

<Import Project="$(RepoRoot)eng\Versions.props" />
<Import Project="$(RepoRoot)scripts\build\TestFx.Sign.props" Condition=" '$(TestFxSigningPropsImported)' != 'true' " />

<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<DefaultLanguage>en-US</DefaultLanguage>
<FileAlignment>512</FileAlignment>
<GenerateLCE>true</GenerateLCE>
<AssemblyOriginatorKeyFile>$(MSBuildThisFileDirectory)key.snk</AssemblyOriginatorKeyFile>
<SignAssembly>true</SignAssembly>
<PublicSign Condition=" '$(IsLocalizedBuild)' == '' or '$(IsLocalizedBuild)' != 'true'">true</PublicSign>
<!-- Temporarily turning on Delay signing for Localized builds because publickey = true is not passed on to the assembler to create resource assmblies.-->
<DelaySign Condition=" '$(IsLocalizedBuild)' == 'true' ">true</DelaySign>
<OutputPath Condition=" '$(OutputPath)' == '' ">$(RepoRoot)artifacts\$(Configuration)\$(MSBuildProjectName)\</OutputPath>
<IntermediatePath Condition=" '$(IntermediatePath)' == '' ">$(RepoRoot)artifacts\$(Configuration)\$(MSBuildProjectName)\obj\</IntermediatePath>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
</PropertyGroup>
Expand Down
30 changes: 1 addition & 29 deletions scripts/build/TestFx.targets
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,7 @@
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<!-- Import localization specific Targets if enabled. -->
<Import Project="$(MSBuildThisFileDirectory)TestFx.Loc.props" Condition=" ('$(IsTest)' == '' or '$(IsTest)' == 'false') and '$(IsLocalizationEnabled)' == 'true' "/>

<ItemGroup>
<None Include="$(MSBuildThisFileDirectory)key.snk">
<!-- Do not have this show up in Solution Explorer in VS -->
<InProject>false</InProject>
</None>
</ItemGroup>
<Import Project="$(RepoRoot)scripts\build\TestFx.Sign.targets" Condition=" '$(TestFxSigningTargetsImported)' != 'true' " />

<!-- StyleCop settings. -->
<ItemGroup Condition=" '$(ShouldEnableStyleCop)' != 'false' and '$(IsVsixProj)' != 'true'">
Expand All @@ -21,28 +15,6 @@
<Analyzer Include="$(NuGetPackageRoot)\StyleCop.Analyzers\$(StyleCopAnalyzersVersion)\analyzers\dotnet\cs\StyleCop.Analyzers.dll" />
</ItemGroup>

<!-- Signing and Localization. -->
<ItemGroup Condition=" '$(IsTest)' == '' or '$(IsTest)' == 'false' ">
<FilesToSign Include="$(OutDir)\$(AssemblyName).dll" Condition=" '$(IsVsixProj)' == '' or '$(IsVsixProj)' != 'true' ">
<Authenticode>Microsoft400</Authenticode>
<StrongName>StrongName</StrongName>
</FilesToSign>

<SignFilesDependsOn Include="GatherLocalizedOutputsForSigning">
<!-- Do not have this show up in Solution Explorer in VS -->
<InProject>false</InProject>
</SignFilesDependsOn>
</ItemGroup>

<Target Name="GatherLocalizedOutputsForSigning" DependsOnTargets="TestFxLocalization">
<ItemGroup>
<FilesToSign Include="$(OutDir)\**\$(AssemblyName).resources.dll">
<Authenticode>Microsoft400</Authenticode>
<StrongName>StrongName</StrongName>
</FilesToSign>
</ItemGroup>
</Target>

<!-- Generate AssemblyInfo.cs -->
<PropertyGroup>
<TFBuildNumber Condition=" '$(TFBuildNumber)' == '' ">0.1</TFBuildNumber>
Expand Down
9 changes: 9 additions & 0 deletions scripts/common.lib.ps1
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT license. See LICENSE file in the project root for full license information.

Add-Type -AssemblyName System.IO.Compression.FileSystem

# Common utilities for building solution and running tests

$TF_ROOT_DIR = (Get-Item (Split-Path $MyInvocation.MyCommand.Path)).Parent.FullName
Expand Down Expand Up @@ -294,4 +296,11 @@ function Install-DotNetCli {
}
catch {}
Write-Log "Install-DotNetCli: Complete."
}

function Unzip
{
param([string]$zipfile, [string]$outpath)

[System.IO.Compression.ZipFile]::ExtractToDirectory($zipfile, $outpath)
}
143 changes: 125 additions & 18 deletions scripts/verify-sign.ps1
Original file line number Diff line number Diff line change
@@ -1,56 +1,163 @@
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT license. See LICENSE file in the project root for full license information.

# Build script for Test Platform.

[CmdletBinding()]
Param(
[Parameter(Mandatory=$false)]
[ValidateSet("Debug", "Release")]
[Alias("c")]
[System.String] $Configuration = "Debug"
[string] $Configuration = "Debug",
[string] $ArtifactsDirectory = "",
[switch] $Force
)

. $PSScriptRoot\common.lib.ps1

#
# Variables
#
$rootDirectory = (Get-Item (Split-Path $MyInvocation.MyCommand.Path)).Parent.FullName
if(-not [string]::IsNullOrWhiteSpace($ArtifactsDirectory)) {
$TF_OUT_DIR = $ArtifactsDirectory
}

#
# Signing configuration
#
Write-Verbose "Setup build configuration."
$TPB_Configuration = $Configuration

function Verify-NugetPackages
$TF_Configuration = $Configuration
$TF_AssembliesPattern = @("Microsoft.VisualStudio.TestPlatform.*.dll", "Microsoft.TestPlatform.*.dll")
$script:ErrorCount = 0

function Test-Assembly ([string] $Path)
{
Write-Log "Verify-NugetPackages: Start"
$signature = Get-AuthenticodeSignature -FilePath $Path

$nugetInstallPath = Locate-NuGet
if ($signature.Status -eq "Valid") {
if ($signature.SignerCertificate.Subject -eq "CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US") {
Write-Debug "Valid ($($signature.SignerCertificate.Thumbprint)): $Path"
}
elseif ($signature.SignerCertificate.Subject -eq "CN=Microsoft 3rd Party Application Component, O=Microsoft Corporation, L=Redmond, S=Washington, C=US") {
Write-Debug "Valid ($($signature.SignerCertificate.Thumbprint)): $Path [3rd Party]"
}
else {
# For legacy components
# CN=Microsoft Corporation, OU=AOC, O=Microsoft Corporation, L=Redmond, S=Washington, C=US
if ($signature.SignerCertificate.Thumbprint -eq "49D59D86505D82942A076388693F4FB7B21254EE") {
Write-Debug "Valid ($($signature.SignerCertificate.Thumbprint)): $Path [Legacy Prod Signed]"
}
else {
Write-FailLog "Invalid ($($signature.SignerCertificate.Thumbprint)). File: $Path. [$($signature.SignerCertificate.Subject)]"
}
}
}
else {
Write-FailLog "Not signed. File: $Path."
}
}

function Test-Assemblies ([string] $Path)
{
foreach ($pattern in $TF_AssembliesPattern) {
Get-ChildItem -Recurse -Include $pattern $Path | Where-Object { (!$_.PSIsContainer) } | ForEach-Object {
Test-Assembly $_.FullName
}
}
}

function Test-NugetPackage ([string] $Path) {
$packageFolder = [System.IO.Path]::GetDirectoryName($Path)
$fileName = [System.IO.Path]::GetFileNameWithoutExtension($Path)
$out = Join-Path $packageFolder $fileName

try {
Write-ToCI "Verifing assemblies in $Path" -type "group"
Write-Debug "Extracting..."
if (Test-Path $out) {
if (-not $Force) {
Write-FailLog "Folder already exists: $out"
return
}

Remove-Item $out -Recurse -Force
}

Unzip $Path $out

Test-Assemblies $out
} finally {
if (Test-Path $out) {
Remove-Item $out -Recurse -Force
}
Write-ToCI -type "endgroup"
}
}

Write-Log "Using nuget.exe installed at $nugetInstallPath"
function Test-NugetPackages
{
Write-Debug "Test-NugetPackages"

$nugetInstallPath = Locate-NuGet
Write-Debug "Using nuget.exe installed at $nugetInstallPath"

$artifactsDirectory = Join-Path $rootDirectory "artifacts"
$artifactsConfigDirectory = Join-Path $artifactsDirectory $TPB_Configuration
$artifactsConfigDirectory = Join-Path $TF_OUT_DIR $TF_Configuration
$packagesDirectory = Join-Path $artifactsConfigDirectory "MSTestPackages"

Get-ChildItem -Filter *.nupkg $packagesDirectory | ForEach-Object {
& $nugetInstallPath verify -signature -CertificateFingerprint "3F9001EA83C560D712C24CF213C3D312CB3BFF51EE89435D3430BD06B5D0EECE;AA12DA22A49BCE7D5C1AE64CC1F3D892F150DA76140F210ABD2CBFFCA2C18A27;" $_.FullName
try {
Write-ToCI "Verifing $($_.FullName)" -type "group"
& $nugetInstallPath verify -signature -CertificateFingerprint "3F9001EA83C560D712C24CF213C3D312CB3BFF51EE89435D3430BD06B5D0EECE;AA12DA22A49BCE7D5C1AE64CC1F3D892F150DA76140F210ABD2CBFFCA2C18A27;" $_.FullName
Test-NugetPackage -path $_.FullName
} finally {
Write-ToCI -type "endgroup"
}
}

Write-Log "Verify-NugetPackages: Complete"
Write-Debug "Test-NugetPackages: Complete"
}

function Write-Log ([string] $message)
function Write-FailLog ([string] $message)
{
$script:ErrorCount = $script:ErrorCount + 1
Write-ToCI -message $message -type "error"
}

function Write-Debug ([string] $message)
{
Write-ToCI -message $message -type "debug"
}

function Write-ToCI ([string] $message, [string]$type, [switch]$vso)
{
$currentColor = $Host.UI.RawUI.ForegroundColor
$Host.UI.RawUI.ForegroundColor = "Green"
if ($message)

if($type -eq "error") {
$Host.UI.RawUI.ForegroundColor = "Red"
}

if ($message -or $vso -or $type)
{
Write-Output "... $message"
$prefix = ""
if ($vso) {
$prefix = "vso"
}

Write-Output "##$prefix[$type]$message"
}
$Host.UI.RawUI.ForegroundColor = $currentColor
}

Verify-NugetPackages
try {
Write-ToCI "Variables used: " -type "group"
Get-ChildItem variable:TF_*
Write-Output ""
Write-Output ""
} finally {
Write-ToCI -type "endgroup"
}

Test-NugetPackages

if ($script:ErrorCount -gt 0) {
Write-ToCI -message "Verification failed, $($script:ErrorCount) errors found!" -type "task.logissue" -vso
}
12 changes: 8 additions & 4 deletions src/Adapter/MSTest.CoreAdapter/Discovery/AssemblyEnumerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ internal ICollection<UnitTestElement> EnumerateAssembly(string assemblyFileName,
var types = this.GetTypes(assembly, assemblyFileName, warningMessages);

var discoverInternals = assembly.GetCustomAttribute<UTF.DiscoverInternalsAttribute>() != null;
var testDataSourceDiscovery = assembly.GetCustomAttribute<UTF.TestDataSourceDiscoveryAttribute>()?.DiscoveryOption ?? UTF.TestDataSourceDiscoveryOption.DuringDiscovery;

foreach (var type in types)
{
Expand All @@ -110,7 +111,7 @@ internal ICollection<UnitTestElement> EnumerateAssembly(string assemblyFileName,
continue;
}

var testsInType = this.DiscoverTestsInType(assemblyFileName, runSettingsXml, assembly, type, warningMessages, discoverInternals);
var testsInType = this.DiscoverTestsInType(assemblyFileName, runSettingsXml, assembly, type, warningMessages, discoverInternals, testDataSourceDiscovery);
tests.AddRange(testsInType);
}

Expand Down Expand Up @@ -206,7 +207,7 @@ internal virtual TypeEnumerator GetTypeEnumerator(Type type, string assemblyFile
return new TypeEnumerator(type, assemblyFileName, ReflectHelper, typeValidator, testMethodValidator);
}

private IEnumerable<UnitTestElement> DiscoverTestsInType(string assemblyFileName, string runSettingsXml, Assembly assembly, Type type, List<string> warningMessages, bool discoverInternals = false)
private IEnumerable<UnitTestElement> DiscoverTestsInType(string assemblyFileName, string runSettingsXml, Assembly assembly, Type type, List<string> warningMessages, bool discoverInternals = false, UTF.TestDataSourceDiscoveryOption discoveryOption = UTF.TestDataSourceDiscoveryOption.DuringExecution)
{
var sourceLevelParameters = PlatformServiceProvider.Instance.SettingsProvider.GetProperties(assemblyFileName);
sourceLevelParameters = RunSettingsUtilities.GetTestRunParameters(runSettingsXml)?.ConcatWithOverwrites(sourceLevelParameters)
Expand All @@ -231,9 +232,12 @@ private IEnumerable<UnitTestElement> DiscoverTestsInType(string assemblyFileName
{
foreach (var test in unitTestCases)
{
if (this.DynamicDataAttached(sourceLevelParameters, assembly, test, tests))
if (discoveryOption == UTF.TestDataSourceDiscoveryOption.DuringDiscovery)
{
continue;
if (this.DynamicDataAttached(sourceLevelParameters, assembly, test, tests))
{
continue;
}
}

tests.Add(test);
Expand Down
Loading

0 comments on commit 3bb2cef

Please sign in to comment.