Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/dotnet/runtime.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorViktor Hofer <viktor.hofer@microsoft.com>2019-11-22 01:13:26 +0300
committerGitHub <noreply@github.com>2019-11-22 01:13:26 +0300
commit1d5de1533ad35b39f776701c4d22b68a3def2dd8 (patch)
tree12b8f6e209302aae8f613a11db66d2ba25e7fb43
parent5e5a0d4eba091621e25ad70f6391961d7a835e9d (diff)
Libraries testing (#178)
* Add Libraries Testing framework package as inline The existing package Microsoft.DotNet.CoreFxTesting lived in Arcade because of no infrastructure being available to compile local tasks in the repository. As the runtime repository now offers that we can inline the testing framework. * Hardcode configuration for installer.tasks * Update ReportGenerator global tool version * Add vstest support * Update binary serialization blobs
-rw-r--r--.config/dotnet-tools.json2
-rw-r--r--.gitignore1
-rw-r--r--Directory.Build.props15
-rw-r--r--NuGet.config1
-rw-r--r--docs/libraries/building/code-coverage.md2
-rw-r--r--docs/libraries/project-docs/developer-guide.md2
-rw-r--r--eng/Build.props3
-rw-r--r--eng/Version.Details.xml4
-rw-r--r--eng/Versions.props6
-rw-r--r--eng/pipelines/libraries/corefx-base.yml2
-rw-r--r--eng/pipelines/libraries/windows.yml2
-rw-r--r--eng/references.targets30
-rw-r--r--eng/testing/RunnerTemplate.Unix.txt200
-rw-r--r--eng/testing/RunnerTemplate.Windows.txt74
-rw-r--r--eng/testing/coverage.props14
-rw-r--r--eng/testing/coverage.targets62
-rw-r--r--eng/testing/launchSettings.json10
-rw-r--r--eng/testing/launchSettings.targets22
-rw-r--r--eng/testing/netfx.exe.config7
-rw-r--r--eng/testing/runtimeConfiguration.targets45
-rw-r--r--eng/testing/tests.props17
-rw-r--r--eng/testing/tests.targets127
-rw-r--r--eng/testing/xunit/vstest.props20
-rw-r--r--eng/testing/xunit/vstest.targets32
-rw-r--r--eng/testing/xunit/xunit.console.props21
-rw-r--r--eng/testing/xunit/xunit.console.targets75
-rw-r--r--eng/testing/xunit/xunit.props18
-rw-r--r--eng/testing/xunit/xunit.runner.json5
-rw-r--r--eng/testing/xunit/xunit.targets31
-rw-r--r--global.json1
-rw-r--r--src/coreclr/tests/scripts/run-corefx-tests.py2
-rw-r--r--src/libraries/Directory.Build.props90
-rw-r--r--src/libraries/Directory.Build.targets16
-rw-r--r--src/libraries/System.Configuration.ConfigurationManager/tests/System.Configuration.ConfigurationManager.Tests.csproj5
-rw-r--r--src/libraries/System.Runtime.Serialization.Formatters/tests/BinaryFormatterTests.cs4
-rw-r--r--src/libraries/pkg/test/testPackages.proj6
-rw-r--r--src/libraries/pretest.proj22
-rw-r--r--src/libraries/restore/runtime/runtime.depproj1
-rw-r--r--src/libraries/tests.proj22
-rw-r--r--tools-local/tasks/installer.tasks/GenerateFileVersionProps.cs35
-rw-r--r--tools-local/tasks/installer.tasks/GenerateRunScript.cs114
-rw-r--r--tools-local/tasks/installer.tasks/GenerateTestSharedFrameworkDepsFile.cs132
-rw-r--r--tools-local/tasks/installer.tasks/installer.tasks.csproj53
43 files changed, 1228 insertions, 125 deletions
diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json
index 8d72881706e..d18a21c3f05 100644
--- a/.config/dotnet-tools.json
+++ b/.config/dotnet-tools.json
@@ -9,7 +9,7 @@
]
},
"dotnet-reportgenerator-globaltool": {
- "version": "4.3.0",
+ "version": "4.3.6",
"commands": [
"reportgenerator"
]
diff --git a/.gitignore b/.gitignore
index f39c9433649..bf23e45830e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -50,6 +50,7 @@ cross/android-rootfs/
#NUNIT
*.VisualState.xml
TestResult.xml
+testResults.xml
# Build Results of an ATL Project
[Dd]ebugPS/
diff --git a/Directory.Build.props b/Directory.Build.props
index c9024609663..d7e46d25026 100644
--- a/Directory.Build.props
+++ b/Directory.Build.props
@@ -11,18 +11,23 @@
<Import Project="Sdk.props" Sdk="Microsoft.DotNet.Arcade.Sdk" Condition="'$(SkipImportArcadeSdkFromRoot)' != 'true'" />
<!-- Common paths -->
- <PropertyGroup>
- <!-- Set these properties early enough for libraries as they import the Arcade SDK not early enough. -->
+
+ <!-- Set these properties early enough for libraries as they import the Arcade SDK not early enough. -->
+ <PropertyGroup Condition="'$(SkipImportArcadeSdkFromRoot)' == 'true'">
<RepoRoot>$(MSBuildThisFileDirectory)</RepoRoot>
<RepositoryEngineeringDir>$([MSBuild]::NormalizeDirectory('$(RepoRoot)', 'eng'))</RepositoryEngineeringDir>
+ <ArtifactsDir>$([MSBuild]::NormalizeDirectory('$(RepoRoot)', 'artifacts'))</ArtifactsDir>
+ <ArtifactsBinDir>$([MSBuild]::NormalizeDirectory('$(ArtifactsDir)', 'bin'))</ArtifactsBinDir>
+ </PropertyGroup>
+ <PropertyGroup>
<RepoToolsLocalDir>$([MSBuild]::NormalizeDirectory('$(RepoRoot)', 'tools-local'))</RepoToolsLocalDir>
<RepoTasksDir>$([MSBuild]::NormalizeDirectory('$(RepoToolsLocalDir)', 'tasks'))</RepoTasksDir>
<!-- Installer specific, required during restore. -->
- <InstallerTasksOutputPath>$([MSBuild]::NormalizeDirectory('$(ArtifactsBinDir)', 'installer.tasks', '$(Configuration)'))</InstallerTasksOutputPath>
- <InstallerTasksAssemblyPath Condition="'$(MSBuildRuntimeType)' == 'Core'">$([MSBuild]::NormalizePath('$(InstallerTasksOutputPath)', 'netstandard2.0', 'installer.tasks.dll'))</InstallerTasksAssemblyPath>
- <InstallerTasksAssemblyPath Condition="'$(MSBuildRuntimeType)' != 'Core'">$([MSBuild]::NormalizePath('$(InstallerTasksOutputPath)', 'net46', 'installer.tasks.dll'))</InstallerTasksAssemblyPath>
+ <InstallerTasksOutputPath>$([MSBuild]::NormalizeDirectory('$(ArtifactsBinDir)', 'installer.tasks'))</InstallerTasksOutputPath>
+ <InstallerTasksAssemblyPath Condition="'$(MSBuildRuntimeType)' == 'Core'">$([MSBuild]::NormalizePath('$(InstallerTasksOutputPath)', 'Debug', 'netstandard2.0', 'installer.tasks.dll'))</InstallerTasksAssemblyPath>
+ <InstallerTasksAssemblyPath Condition="'$(MSBuildRuntimeType)' != 'Core'">$([MSBuild]::NormalizePath('$(InstallerTasksOutputPath)', 'Debug', 'net46', 'installer.tasks.dll'))</InstallerTasksAssemblyPath>
<HostMachineInfoProps>$(ArtifactsObjDir)HostMachineInfo.props</HostMachineInfoProps>
<LibrariesProjectRoot>$([MSBuild]::NormalizeDirectory('$(RepoRoot)', 'src', 'libraries'))</LibrariesProjectRoot>
diff --git a/NuGet.config b/NuGet.config
index 6b6e54b554f..b656e4d9162 100644
--- a/NuGet.config
+++ b/NuGet.config
@@ -12,6 +12,7 @@
-->
<!-- TEST_RESTORE_SOURCES_INSERTION_LINE -->
<add key="nuget.org" value="https://api.nuget.org/v3/index.json" />
+ <add key="dotnet-tools" value="https://dnceng.pkgs.visualstudio.com/public/_packaging/dotnet-tools/nuget/v3/index.json" />
<add key="dotnet-eng" value="https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-eng/nuget/v3/index.json" />
<add key="dotnet5-transport" value="https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet5-transport/nuget/v3/index.json" />
<add key="dotnet-core" value="https://dotnetfeed.blob.core.windows.net/dotnet-core/index.json" />
diff --git a/docs/libraries/building/code-coverage.md b/docs/libraries/building/code-coverage.md
index f612695fcc3..76e7834dcb4 100644
--- a/docs/libraries/building/code-coverage.md
+++ b/docs/libraries/building/code-coverage.md
@@ -45,7 +45,7 @@ The results for this one library will then show up in the aforementioned index.h
And then once the run completes:
- $(TestPath)\report\index.htm
+ $(OutDir)\report\index.htm
**Note:** If you only want to measure the coverage of your local changes (that haven't been pushed to git), run:
diff --git a/docs/libraries/project-docs/developer-guide.md b/docs/libraries/project-docs/developer-guide.md
index 4dd8b73fd4f..8865259d23a 100644
--- a/docs/libraries/project-docs/developer-guide.md
+++ b/docs/libraries/project-docs/developer-guide.md
@@ -423,7 +423,7 @@ cd src\System.Collections.Immutable\tests
dotnet msbuild /t:BuildAndTest /p:Coverage=true
```
-If coverage succeeds, the individual report can be found at `$(TestPath)\report\index.htm`.
+If coverage succeeds, the individual report can be found at `$(OutDir)\report\index.htm`.
Code coverage reports from the continuous integration system are available from the links on the front page of the corefx repo.
diff --git a/eng/Build.props b/eng/Build.props
index 3f3624723e9..e6bf9aa8cd9 100644
--- a/eng/Build.props
+++ b/eng/Build.props
@@ -79,6 +79,7 @@
</ItemGroup>
<MSBuild Projects="@(RepoTaskProjects)"
+ Properties="Configuration=Debug"
Targets="Restore;Build"/>
<WriteLinesToFile File="$(RepoTasksOutputFile)"
@@ -89,7 +90,7 @@
<Target Name="GetRepoTasksSrc">
<PropertyGroup>
<RepoTasksDir>$(RepoTasksDir)</RepoTasksDir>
- <RepoTasksOutputFile>$(ArtifactsObjDir)runtime.tasks\$(Configuration)\build-semaphore.txt</RepoTasksOutputFile>
+ <RepoTasksOutputFile>$(ArtifactsObjDir)runtime.tasks\Debug\build-semaphore.txt</RepoTasksOutputFile>
</PropertyGroup>
<ItemGroup>
diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml
index a0cc6829ede..3e11596f706 100644
--- a/eng/Version.Details.xml
+++ b/eng/Version.Details.xml
@@ -130,5 +130,9 @@
<Uri>https://dev.azure.com/dnceng/internal/_git/dotnet-optimization</Uri>
<Sha>d0bb63d2ec7060714e63ee4082fac48f2e57f3e2</Sha>
</Dependency>
+ <Dependency Name="Microsoft.NET.Test.Sdk" Version="16.4.0">
+ <Uri>https://github.com/Microsoft/vstest</Uri>
+ <Sha>ca987de449d17284f8c9806df36f42276f13962a</Sha>
+ </Dependency>
</ToolsetDependencies>
</Dependencies>
diff --git a/eng/Versions.props b/eng/Versions.props
index c3887007e82..25eac8a7796 100644
--- a/eng/Versions.props
+++ b/eng/Versions.props
@@ -80,12 +80,12 @@
<RefOnlyNugetPackagingVersion>4.9.4</RefOnlyNugetPackagingVersion>
<!-- sni -->
<RuntimeWinX64RuntimeNativeSystemDataSqlClientSniVersion>4.4.0</RuntimeWinX64RuntimeNativeSystemDataSqlClientSniVersion>
- <RuntimeNativeSystemDataSqlClientSniVersion>4.4.0</RuntimeNativeSystemDataSqlClientSniVersion>
<!-- Testing -->
- <MicrosoftNETTestSdkVersion>16.3.0</MicrosoftNETTestSdkVersion>
+ <MicrosoftNETTestSdkVersion>16.4.0</MicrosoftNETTestSdkVersion>
<XUnitVersion>2.4.1</XUnitVersion>
<TraceEventVersion>2.0.5</TraceEventVersion>
- <NewtonsoftJsonVersion>12.0.1</NewtonsoftJsonVersion>
+ <NewtonsoftJsonVersion>12.0.3</NewtonsoftJsonVersion>
+ <XUnitXmlTestLoggerVersion>2.1.26</XUnitXmlTestLoggerVersion>
<!-- Test data -->
<SystemIOCompressionTestDataVersion>1.0.16</SystemIOCompressionTestDataVersion>
<SystemIOPackagingTestDataVersion>1.0.4</SystemIOPackagingTestDataVersion>
diff --git a/eng/pipelines/libraries/corefx-base.yml b/eng/pipelines/libraries/corefx-base.yml
index a8ad96ceb36..aac9dbf5637 100644
--- a/eng/pipelines/libraries/corefx-base.yml
+++ b/eng/pipelines/libraries/corefx-base.yml
@@ -84,7 +84,7 @@ jobs:
- _msbuildCommonParameters: /p:OfficialBuildId=$(Build.BuildNumber)
- ${{ if eq(job.submitToHelix, 'true') }}:
- - _archiveTestsParameter: /p:ArchiveTests=Tests
+ - _archiveTestsParameter: /p:ArchiveTests=true
- ${{ if eq(parameters.isOfficialBuild, 'true') }}:
- group: DotNet-HelixApi-Access
diff --git a/eng/pipelines/libraries/windows.yml b/eng/pipelines/libraries/windows.yml
index 6fd05b3a5c0..c1825eaacad 100644
--- a/eng/pipelines/libraries/windows.yml
+++ b/eng/pipelines/libraries/windows.yml
@@ -134,7 +134,7 @@ stages:
-allconfigurations
-arch $(_architecture)
/p:RuntimeOS=win10
- /p:ArchiveTests=Packages
+ /p:ArchiveTests=true
$(_msbuildCommonParameters)
displayName: Build Packages and Tests
diff --git a/eng/references.targets b/eng/references.targets
index 3f9105695d8..0c104db2bb2 100644
--- a/eng/references.targets
+++ b/eng/references.targets
@@ -17,8 +17,9 @@
<IncludeDefaultReferences Condition="'$(MSBuildProjectExtension)' == '.csproj'">true</IncludeDefaultReferences>
<IncludeDefaultReferences Condition="'$(MSBuildProjectExtension)' == '.vbproj'">true</IncludeDefaultReferences>
</PropertyGroup>
+
<Target Name="SetupDefaultReferences">
- <ItemGroup Condition="'$(IncludeDefaultReferences)' =='true'">
+ <ItemGroup Condition="'$(IncludeDefaultReferences)' == 'true'">
<!-- netstandard is a default reference whenever building for NETStandard or building an implementation assembly -->
<DefaultReference Condition="('$(TargetsNetStandard)' == 'true' or '$(IsReferenceAssembly)' != 'true') and Exists('$(RefPath)netstandard.dll')" Include="netstandard" />
</ItemGroup>
@@ -35,5 +36,32 @@
</ItemGroup>
</Target>
+ <Target Name="AddDefaultTestReferences" BeforeTargets="SetupDefaultReferences" Condition="'$(IsTestProject)' == 'true'">
+ <ItemGroup>
+ <DefaultReferenceExclusions Include="@(ReferenceFromRuntime)"/>
+
+ <!-- Reference everything in the targeting pack directory -->
+ <DefaultReferenceDirs Include="$(RefPath)" />
+ <DefaultReferenceItems Include="%(DefaultReferenceDirs.Identity)/*.dll" />
+
+ <DefaultReferenceExclusions>
+ <RefDir>%(DefaultReferenceDirs.Identity)</RefDir>
+ </DefaultReferenceExclusions>
+ <_defaultReferenceExclusionsFullPath Include="%(DefaultReferenceExclusions.RefDir)%(DefaultReferenceExclusions.Identity).dll" />
+
+ <!-- Ensure conflict resolution can see these references. -->
+ <Reference Include="%(DefaultReferenceItems.FullPath)" Private="false" />
+ </ItemGroup>
+ </Target>
+
+ <Target Name="RemoveConflictResolutionAssetsForTests"
+ AfterTargets="_HandlePackageFileConflicts"
+ DependsOnTargets="AddDefaultTestReferences"
+ Condition="'@(_defaultReferenceExclusionsFullPath)' != ''">
+ <ItemGroup>
+ <Reference Remove="@(_defaultReferenceExclusionsFullPath)" />
+ </ItemGroup>
+ </Target>
+
<Target Name="AddReferencesDynamically" BeforeTargets="PrepareForBuild" />
</Project> \ No newline at end of file
diff --git a/eng/testing/RunnerTemplate.Unix.txt b/eng/testing/RunnerTemplate.Unix.txt
new file mode 100644
index 00000000000..80b496efe82
--- /dev/null
+++ b/eng/testing/RunnerTemplate.Unix.txt
@@ -0,0 +1,200 @@
+#!/usr/bin/env bash
+
+usage()
+{
+ echo "Usage: RunTests.sh {-r|--runtime-path} <runtime-path> [{--rsp-file} <rsp-file>]"
+ echo ""
+ echo "Parameters:"
+ echo "--runtime-path (Mandatory) Testhost containing the test runtime used during test execution (short: -r)"
+ echo "--rsp-file RSP file to pass in additional arguments"
+ echo "--help Print help and exit (short: -h)"
+}
+
+EXECUTION_DIR=$(dirname "$0")
+RUNTIME_PATH=''
+RSP_FILE=''
+
+while [[ $# > 0 ]]; do
+ opt="$(echo "${1}" | awk '{print tolower($0)}')"
+ case "$opt" in
+ --help|-h)
+ usage
+ exit 0
+ ;;
+ --runtime-path|-r)
+ RUNTIME_PATH=$2
+ shift
+ ;;
+ --rsp-file)
+ RSP_FILE=\@$2
+ shift
+ ;;
+ *)
+ echo "Invalid argument: $1"
+ usage
+ exit -1
+ ;;
+ esac
+
+ shift
+done
+
+if [ "$RUNTIME_PATH" == "" ]; then
+ echo "error: -r|--runtime-path argument is required."
+ usage
+ exit -1
+fi
+
+# Don't use a globally installed SDK.
+export DOTNET_MULTILEVEL_LOOKUP=0
+
+exitcode_list[0]="Exited Successfully"
+exitcode_list[130]="SIGINT Ctrl-C occurred. Likely tests timed out."
+exitcode_list[131]="SIGQUIT Ctrl-\ occurred. Core dumped."
+exitcode_list[132]="SIGILL Illegal Instruction. Core dumped. Likely codegen issue."
+exitcode_list[133]="SIGTRAP Breakpoint hit. Core dumped."
+exitcode_list[134]="SIGABRT Abort. Managed or native assert, or runtime check such as heap corruption, caused call to abort(). Core dumped."
+exitcode_list[135]="IGBUS Unaligned memory access. Core dumped."
+exitcode_list[136]="SIGFPE Bad floating point arguments. Core dumped."
+exitcode_list[137]="SIGKILL Killed eg by kill"
+exitcode_list[139]="SIGSEGV Illegal memory access. Deref invalid pointer, overrunning buffer, stack overflow etc. Core dumped."
+exitcode_list[143]="SIGTERM Terminated. Usually before SIGKILL."
+exitcode_list[159]="SIGSYS Bad System Call."
+
+function print_info_from_core_file_using_lldb {
+ local core_file_name=$1
+ local executable_name=$2
+ local plugin_path_name="$RUNTIME_PATH/shared/Microsoft.NETCore.App/9.9.9/libsosplugin.so"
+
+ # check for existence of lldb on the path
+ hash lldb 2>/dev/null || { echo >&2 "lldb was not found. Unable to print core file."; return; }
+
+ # pe, clrstack, and dumpasync are defined in libsosplugin.so
+ if [ ! -f $plugin_path_name ]; then
+ echo $plugin_path_name cannot be found.
+ return
+ fi
+
+ echo ----- start =============== lldb Output =====================================================
+ echo Printing managed exceptions, managed call stacks, and async state machines.
+ lldb -O "settings set target.exec-search-paths $RUNTIME_PATH" -o "plugin load $plugin_path_name" -o "clrthreads -managedexception" -o "pe -nested" -o "clrstack -all -a -f" -o "dumpasync -fields -stacks -roots" -o "quit" --core $core_file_name $executable_name
+ echo ----- end =============== lldb Output =======================================================
+}
+
+function print_info_from_core_file_using_gdb {
+ local core_file_name=$1
+ local executable_name=$2
+
+ # Check for the existence of GDB on the path
+ hash gdb 2>/dev/null || { echo >&2 "GDB was not found. Unable to print core file."; return; }
+
+ echo ----- start =============== GDB Output =====================================================
+ # Open the dump in GDB and print the stack from each thread. We can add more
+ # commands here if desired.
+ echo printing native stack.
+ gdb --batch -ex "thread apply all bt full" -ex "quit" $executable_name $core_file_name
+ echo ----- end =============== GDB Output =======================================================
+}
+
+function print_info_from_core_file {
+ local core_file_name=$1
+ local executable_name=$RUNTIME_PATH/$2
+
+ if ! [ -e $executable_name ]; then
+ echo "Unable to find executable $executable_name"
+ return
+ elif ! [ -e $core_file_name ]; then
+ echo "Unable to find core file $core_file_name"
+ return
+ fi
+ echo "Printing info from core file $core_file_name"
+ print_info_from_core_file_using_gdb $core_file_name $executable_name
+ print_info_from_core_file_using_lldb $core_file_name $executable_name
+}
+
+function copy_core_file_to_temp_location {
+ local core_file_name=$1
+
+ local storage_location="/tmp/coredumps"
+
+ # Create the directory (this shouldn't fail even if it already exists).
+ mkdir -p $storage_location
+
+ local new_location=$storage_location/core.$RANDOM
+
+ echo "Copying core file $core_file_name to $new_location in case you need it."
+ cp $core_file_name $new_location
+}
+
+# ========================= BEGIN Core File Setup ============================
+if [ "$(uname -s)" == "Darwin" ]; then
+ # On OS X, we will enable core dump generation only if there are no core
+ # files already in /cores/ at this point. This is being done to prevent
+ # inadvertently flooding the CI machines with dumps.
+ if [[ ! -d "/cores" || ! "$(ls -A /cores)" ]]; then
+ ulimit -c unlimited
+ fi
+elif [ "$(uname -s)" == "Linux" ]; then
+ # On Linux, we'll enable core file generation unconditionally, and if a dump
+ # is generated, we will print some useful information from it and delete the
+ # dump immediately.
+
+ if [ -e /proc/self/coredump_filter ]; then
+ # Include memory in private and shared file-backed mappings in the dump.
+ # This ensures that we can see disassembly from our shared libraries when
+ # inspecting the contents of the dump. See 'man core' for details.
+ echo -n 0x3F > /proc/self/coredump_filter
+ fi
+
+ ulimit -c unlimited
+fi
+# ========================= END Core File Setup ==============================
+
+# ========================= BEGIN Test Execution =============================
+echo ----- start $(date) =============== To repro directly: =====================================================
+echo pushd $EXECUTION_DIR
+[[RunCommandsEcho]]
+echo popd
+echo ===========================================================================================================
+pushd $EXECUTION_DIR
+[[RunCommands]]
+test_exitcode=$?
+popd
+echo ----- end $(date) ----- exit code $test_exitcode ----------------------------------------------------------
+
+if [ "${exitcode_list[$test_exitcode]}" != "" ]; then
+ echo exit code $test_exitcode means ${exitcode_list[$test_exitcode]}
+fi
+# ========================= END Test Execution ===============================
+
+# ======================= BEGIN Core File Inspection =========================
+pushd $EXECUTION_DIR >/dev/null
+if [[ "$(uname -s)" == "Linux" && $test_exitcode -ne 0 ]]; then
+ echo Looking around for any Linux dump...
+ # Depending on distro/configuration, the core files may either be named "core"
+ # or "core.<PID>" by default. We read /proc/sys/kernel/core_uses_pid to
+ # determine which it is.
+ core_name_uses_pid=0
+ if [ -e /proc/sys/kernel/core_uses_pid ] && [ "1" == $(cat /proc/sys/kernel/core_uses_pid) ]; then
+ core_name_uses_pid=1
+ fi
+
+ if [ $core_name_uses_pid == "1" ]; then
+ # We don't know what the PID of the process was, so let's look at all core
+ # files whose name matches core.NUMBER
+ echo Looking for files matching core.* ...
+ for f in core.*; do
+ [[ $f =~ core.[0-9]+ ]] && print_info_from_core_file "$f" "dotnet" && copy_core_file_to_temp_location "$f" && rm "$f"
+ done
+ elif [ -f core ]; then
+ echo found a dump named core in $EXECUTION_DIR !
+ print_info_from_core_file "core" "dotnet"
+ copy_core_file_to_temp_location "core"
+ rm "core"
+ else
+ echo ... found no dump in $PWD
+ fi
+fi
+popd >/dev/null
+# ======================== END Core File Inspection ==========================
+exit $test_exitcode
diff --git a/eng/testing/RunnerTemplate.Windows.txt b/eng/testing/RunnerTemplate.Windows.txt
new file mode 100644
index 00000000000..6d956f5221e
--- /dev/null
+++ b/eng/testing/RunnerTemplate.Windows.txt
@@ -0,0 +1,74 @@
+@echo off
+setlocal enabledelayedexpansion
+
+set EXECUTION_DIR=%~dp0
+
+:argparser_start
+ if "%~1" == "" goto argparser_end
+ set "argparser_currentarg=%~1"
+ shift
+
+ set "argparser_help_specified_inloop="
+ if /i "%argparser_currentarg%"=="-h" ( set "argparser_help_specified_inloop=1" )
+ if /i "%argparser_currentarg%"=="--help" ( set "argparser_help_specified_inloop=1" )
+ if defined argparser_help_specified_inloop (
+ goto usage
+ )
+
+ set "argparser_runtime_path_specified_inloop="
+ if /i "%argparser_currentarg%"=="-r" ( set "argparser_runtime_path_specified_inloop=1" )
+ if /i "%argparser_currentarg%"=="--runtime-path" ( set "argparser_runtime_path_specified_inloop=1" )
+ if defined argparser_runtime_path_specified_inloop (
+ if "%~1" == "" ( goto argparser_invalid )
+ set "RUNTIME_PATH=%~1"
+ goto argparser_break
+ )
+
+ if /i "%argparser_currentarg%"=="--rsp-file" (
+ if "%~1" == "" ( goto argparser_invalid )
+ set "RSP_FILE=@%~1"
+ goto argparser_break
+ )
+
+:argparser_invalid
+ echo Invalid argument or value: %argparser_currentarg%
+ call :usage
+ exit /b -1
+
+:argparser_break
+ shift
+ goto argparser_start
+
+:argparser_end
+
+if not defined RUNTIME_PATH (
+ echo error: -r|--runtime-path argument is required.
+ call :usage
+ exit /b -1
+)
+
+:: Don't use a globally installed SDK.
+set DOTNET_MULTILEVEL_LOOKUP=0
+
+:: ========================= BEGIN Test Execution =============================
+echo ----- start %DATE% %TIME% =============== To repro directly: =====================================================
+echo pushd %EXECUTION_DIR%
+[[RunCommandsEcho]]
+echo popd
+echo ===========================================================================================================
+pushd %EXECUTION_DIR%
+@echo on
+[[RunCommands]]
+@echo off
+popd
+echo ----- end %DATE% %TIME% ----- exit code %ERRORLEVEL% ----------------------------------------------------------
+exit /b %ERRORLEVEL%
+:: ========================= END Test Execution =================================
+
+:usage
+echo Usage: RunTests.cmd {-r^|--runtime-path} ^<runtime-path^> [{--rsp-file} ^<rsp-file^>]
+echo.
+echo Parameters:
+echo --runtime-path (Mandatory) Testhost containing the test runtime used during test execution (short: -r)"
+echo --rsp-file RSP file to pass in additional arguments
+echo --help Print help and exit (short: -h)
diff --git a/eng/testing/coverage.props b/eng/testing/coverage.props
new file mode 100644
index 00000000000..7af30267a56
--- /dev/null
+++ b/eng/testing/coverage.props
@@ -0,0 +1,14 @@
+<Project>
+ <PropertyGroup>
+ <CoverageOutputPath Condition="'$(CoverageOutputPath)' == ''">coverage.xml</CoverageOutputPath>
+ <CoverageThreshold Condition="$(CoverageThreshold) == ''">0</CoverageThreshold>
+ <CoverageThresholdType Condition="$(CoverageThresholdType) == ''">line,branch,method</CoverageThresholdType>
+ <CoverageFormat Condition="'$(CoverageFormat)' == ''">opencover</CoverageFormat>
+ <CoverageSourceLink Condition="'$(CoverageSourceLink)' == ''">true</CoverageSourceLink>
+ <CoverageVerbosity Condition="'$(CoverageVerbosity)' == ''">normal</CoverageVerbosity>
+
+ <CoverageReportInputPath Condition="'$(CoverageReportInputPath)' == ''">$(CoverageOutputPath)</CoverageReportInputPath>
+ <CoverageReportTypes Condition="'$(CoverageReportTypes)' == ''">Html</CoverageReportTypes>
+ <CoverageReportVerbosity Condition="'$(CoverageReportVerbosity)' == ''">Info</CoverageReportVerbosity>
+ </PropertyGroup>
+</Project>
diff --git a/eng/testing/coverage.targets b/eng/testing/coverage.targets
new file mode 100644
index 00000000000..c2d9059eff3
--- /dev/null
+++ b/eng/testing/coverage.targets
@@ -0,0 +1,62 @@
+<Project InitialTargets="SetupCoverageFilter">
+ <!-- Wrap RunCommand and RunArguments inside code coverage invocation. -->
+ <PropertyGroup>
+ <RunArguments>"$(TargetFileName)" --target "$(RunCommand)" --targetargs "$(RunArguments)" --format "$(CoverageFormat)" --output "$(CoverageOutputPath)" --threshold "$(CoverageThreshold)" --threshold-type "$(CoverageThresholdType)" --verbosity "$(CoverageVerbosity)"</RunArguments>
+ <RunArguments Condition="'$(CoverageSourceLink)' == 'true'">$(RunArguments) --use-source-link</RunArguments>
+ <RunCommand>"$(DotNetTool)" tool run coverlet</RunCommand>
+ </PropertyGroup>
+
+ <!-- Coverage report -->
+ <PropertyGroup>
+ <CoverageReportDir Condition="'$(CoverageReportDir)' == ''">$([MSBuild]::NormalizeDirectory('$(OutDir)', 'report'))</CoverageReportDir>
+ <CoverageReportResultsPath>$([MSBuild]::NormalizePath('$(CoverageReportDir)', 'index.htm'))</CoverageReportResultsPath>
+ <CoverageReportCommandLine>"$(DotNetTool)" tool run reportgenerator "-reports:$(CoverageReportInputPath)" "-targetdir:$(CoverageReportDir.TrimEnd('\/'))" "-reporttypes:$(CoverageReportTypes)" "-verbosity:$(CoverageReportVerbosity)"</CoverageReportCommandLine>
+ </PropertyGroup>
+
+ <!-- Skip generating individual reports if a full report is generated. -->
+ <ItemGroup Condition="'$(TestAllProjects)' != 'true' and '$(SkipCoverageReport)' != 'true'">
+ <PostRunScriptCommands Include="$(CoverageReportCommandLine)" />
+ </ItemGroup>
+
+ <Target Name="SetupCoverageFilter">
+ <PropertyGroup Condition="'@(CoverageExcludeFile)' != ''">
+ <CoverageExcludeByFileFilter>--exclude-by-file @(CoverageExcludeFile -> '"%(Identity)"', ' --exclude-by-file ')</CoverageExcludeByFileFilter>
+ <RunArguments>$(RunArguments) $(CoverageExcludeByFileFilter)</RunArguments>
+ </PropertyGroup>
+
+ <PropertyGroup Condition="'@(CoverageProbePath)' != ''">
+ <IncludeDirectoriesFilter>--include-directory @(CoverageProbePath -> '"$(RunScriptHostDir)%(Identity)"', ' --include-directory ')</IncludeDirectoriesFilter>
+ <RunArguments>$(RunArguments) $(IncludeDirectoriesFilter)</RunArguments>
+ </PropertyGroup>
+
+ <PropertyGroup Condition="'@(CoverageExclude)' != ''">
+ <CoverageExcludeFilter>--exclude @(CoverageExclude -> '"%(Identity)"', ' --exclude ')</CoverageExcludeFilter>
+ <RunArguments>$(RunArguments) $(CoverageExcludeFilter)</RunArguments>
+ </PropertyGroup>
+
+ <!--
+ We need to filter the data to only the assembly being tested. Otherwise we will gather tons of data about other assemblies.
+ If the code being tested is part of the runtime itself, it requires special treatment.
+ -->
+ <PropertyGroup Condition="'$(AssemblyBeingTested)' == ''">
+ <_ProjectDirectoryUnderSourceDir>$(MSBuildProjectDirectory.SubString($(LibrariesProjectRoot.Length)))</_ProjectDirectoryUnderSourceDir>
+ <AssemblyBeingTested>$(_ProjectDirectoryUnderSourceDir.SubString(0, $(_ProjectDirectoryUnderSourceDir.IndexOfAny("\\/"))))</AssemblyBeingTested>
+ </PropertyGroup>
+
+ <!--
+ By default, code coverage data is only gathered for the assembly being tested.
+ CoverageAssemblies can be passed in to the build to gather coverage on additional assemblies.
+ -->
+ <ItemGroup>
+ <_CoverageAssemblies Include="$(AssemblyBeingTested)" />
+ <_CoverageAssemblies Include="System.Private.CoreLib" Condition="'$(TestRuntime)' == 'true'" />
+ <_CoverageAssemblies Include="@(AssembliesBeingTested)" />
+ <_CoverageAssemblies Include="$(CoverageAssemblies)" Condition="'$(CoverageAssemblies)' != ''" />
+ </ItemGroup>
+
+ <PropertyGroup Condition="'$(CoverageType)' != 'all'">
+ <CoverageFilter>--include @(_CoverageAssemblies -> '"[%(Identity)]*"', ' --include ')</CoverageFilter>
+ <RunArguments>$(RunArguments) $(CoverageFilter)</RunArguments>
+ </PropertyGroup>
+ </Target>
+</Project>
diff --git a/eng/testing/launchSettings.json b/eng/testing/launchSettings.json
new file mode 100644
index 00000000000..c215e10ba94
--- /dev/null
+++ b/eng/testing/launchSettings.json
@@ -0,0 +1,10 @@
+{
+ "profiles": {
+ ".NET Core xUnit Console": {
+ "commandName": "Executable",
+ "executablePath": "$(TestHostRootPath)dotnet.exe",
+ "commandLineArgs": "$(RunArguments) -parallel none",
+ "workingDirectory": "$(RunWorkingDirectory)"
+ }
+ }
+}
diff --git a/eng/testing/launchSettings.targets b/eng/testing/launchSettings.targets
new file mode 100644
index 00000000000..6caf9475304
--- /dev/null
+++ b/eng/testing/launchSettings.targets
@@ -0,0 +1,22 @@
+<Project>
+ <!--
+ Generates the launch settings file in case it doesn't exist yet.
+ This supports scenarios when new projects are added or the file was deleted.
+ -->
+ <PropertyGroup>
+ <LaunchSettingsInputFileFullPath Condition="'$(LaunchSettingsInputFileFullPath)' == ''">$(MSBuildThisFileDirectory)launchSettings.json</LaunchSettingsInputFileFullPath>
+ <LaunchSettingsOutputFileFullPath Condition="'$(LaunchSettingsOutputFileFullPath)' == ''">$([MSBuild]::NormalizePath('$(MSBuildProjectDirectory)', '$(AppDesignerFolder)', 'launchSettings.json'))</LaunchSettingsOutputFileFullPath>
+ <PrepareForRunDependsOn Condition="!Exists($(LaunchSettingsOutputFileFullPath))">GenerateLaunchSettingsFile;$(PrepareForRunDependsOn);</PrepareForRunDependsOn>
+ </PropertyGroup>
+
+ <!--
+ Target to generate the launch settings file.
+ Either called by PrepareForRunDependsOn if the file doesn't already exist when building
+ the test assembly or invoked manually from the build.proj when doing a full build.
+ -->
+ <Target Name="GenerateLaunchSettingsFile">
+ <Copy SourceFiles="$(LaunchSettingsInputFileFullPath)"
+ DestinationFiles="$(LaunchSettingsOutputFileFullPath)"
+ SkipUnchangedFiles="true" />
+ </Target>
+</Project> \ No newline at end of file
diff --git a/eng/testing/netfx.exe.config b/eng/testing/netfx.exe.config
new file mode 100644
index 00000000000..ed7d7d08243
--- /dev/null
+++ b/eng/testing/netfx.exe.config
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<configuration>
+ <runtime>
+ <developmentMode developerInstallation="true" />
+ <UseRandomizedStringHashAlgorithm enabled="1" />
+ </runtime>
+</configuration> \ No newline at end of file
diff --git a/eng/testing/runtimeConfiguration.targets b/eng/testing/runtimeConfiguration.targets
new file mode 100644
index 00000000000..6b6c952cb79
--- /dev/null
+++ b/eng/testing/runtimeConfiguration.targets
@@ -0,0 +1,45 @@
+<Project>
+ <PropertyGroup>
+ <!-- Copies the app.config file to the OutDir. -->
+ <TestRuntimeConfigurationFile Condition="'$(TargetsNetFx)' == 'true'">$(MSBuildThisFileDirectory)netfx.exe.config</TestRuntimeConfigurationFile>
+
+ <!-- By default copy the test runtime config file for executable test projects (+ test support projects). -->
+ <GenerateRuntimeConfigurationFiles Condition="'$(IsTestProject)' == 'true' and ('$(IsTestSupportProject)' != 'true' or '$(OutputType.ToLower())' == 'exe')">true</GenerateRuntimeConfigurationFiles>
+ </PropertyGroup>
+
+ <ItemGroup Condition="'$(GenerateRuntimeConfigurationFiles)' == 'true'">
+ <None Include="$(TestRuntimeConfigurationFile)"
+ Condition="Exists('$(TestRuntimeConfigurationFile)')"
+ Link="$(TargetName).exe.config"
+ CopyToOutputDirectory="PreserveNewest"
+ Visible="false" />
+ <!--
+ Include deps.json and runtimeconfig.json in ContentWithTargetPath so they will
+ be copied to the output folder of projects that reference this one.
+ Tracking issue: https://github.com/dotnet/sdk/issues/1675
+ -->
+ <ContentWithTargetPath Include="$(ProjectDepsFilePath)"
+ Condition="'$(TargetsNetCoreApp)' == 'true' and '$(GenerateDependencyFile)' == 'true'"
+ CopyToOutputDirectory="PreserveNewest"
+ TargetPath="$(ProjectDepsFileName)" />
+ <ContentWithTargetPath Include="$(ProjectRuntimeConfigFilePath)"
+ Condition="'$(TargetsNetCoreApp)' == 'true'"
+ CopyToOutputDirectory="PreserveNewest"
+ TargetPath="$(ProjectRuntimeConfigFileName)" />
+ </ItemGroup>
+
+ <!--
+ We disabled implicit framework references but still want to be treated as framework dependent:
+ 1. To have runtimeTargets in the deps file.
+ 2. To populate the framework node in the runtimeconfig's runtimeOptions
+ To do this we manually set the RuntimeFramework.
+ At that point restore and conflict resolution already happened therefore setting the item here has no side effects.
+ -->
+ <Target Name="_SetRuntimeFrameworksForTestAssemblies"
+ Condition="'$(SelfContained)' != 'true'"
+ BeforeTargets="GenerateBuildDependencyFile">
+ <ItemGroup>
+ <RuntimeFramework Include="Microsoft.NETCore.App" Version="$(ProductVersion)" />
+ </ItemGroup>
+ </Target>
+</Project> \ No newline at end of file
diff --git a/eng/testing/tests.props b/eng/testing/tests.props
new file mode 100644
index 00000000000..1dc35ce2949
--- /dev/null
+++ b/eng/testing/tests.props
@@ -0,0 +1,17 @@
+<Project>
+ <PropertyGroup>
+ <TestProjectName Condition="'$(TestProjectName)' == ''">$(MSBuildProjectName)</TestProjectName>
+ <TestFramework Condition="'$(TestFramework)' == ''">xunit</TestFramework>
+ </PropertyGroup>
+
+ <!-- Set env variable to use the local netfx assemblies instead of the ones in the GAC. -->
+ <ItemGroup Condition="'$(TargetsNetFx)' == 'true'">
+ <RunScriptCommands Include="set DEVPATH=%RUNTIME_PATH%" />
+ </ItemGroup>
+
+ <!--
+ Unit/Functional/Integration test support.
+ Supported runners: xunit.
+ -->
+ <Import Project="$(MSBuildThisFileDirectory)xunit\xunit.props" Condition="'$(TestFramework)' == 'xunit'" />
+</Project>
diff --git a/eng/testing/tests.targets b/eng/testing/tests.targets
new file mode 100644
index 00000000000..527f418f9fd
--- /dev/null
+++ b/eng/testing/tests.targets
@@ -0,0 +1,127 @@
+<Project>
+ <PropertyGroup>
+ <TargetOS Condition="'$(TargetOS)' == ''">$(DefaultOSGroup)</TargetOS>
+ <RunWorkingDirectory>$(OutDir)</RunWorkingDirectory>
+
+ <RunScriptInputName Condition="'$(TargetOS)' == 'Windows_NT'">RunnerTemplate.Windows.txt</RunScriptInputName>
+ <RunScriptInputName Condition="'$(TargetOS)' != 'Windows_NT'">RunnerTemplate.Unix.txt</RunScriptInputName>
+ <RunScriptInputPath>$(MSBuildThisFileDirectory)$(RunScriptInputName)</RunScriptInputPath>
+
+ <RunScriptOutputName Condition="'$(TargetOS)' == 'Windows_NT'">RunTests.cmd</RunScriptOutputName>
+ <RunScriptOutputName Condition="'$(TargetOS)' != 'Windows_NT'">RunTests.sh</RunScriptOutputName>
+ <RunScriptOutputPath>$([MSBuild]::NormalizePath('$(OutDir)', '$(RunScriptOutputName)'))</RunScriptOutputPath>
+
+ <RunScriptHostDir Condition="'$(TargetOS)' == 'Windows_NT'">%RUNTIME_PATH%\</RunScriptHostDir>
+ <RunScriptHostDir Condition="'$(TargetOS)' != 'Windows_NT'">$RUNTIME_PATH/</RunScriptHostDir>
+
+ <RunScriptHost Condition="'$(TargetOS)' == 'Windows_NT'">$(RunScriptHostDir)dotnet.exe</RunScriptHost>
+ <RunScriptHost Condition="'$(TargetOS)' != 'Windows_NT'">$(RunScriptHostDir)dotnet</RunScriptHost>
+ </PropertyGroup>
+
+ <!-- Archive test binaries. -->
+ <Target Name="ArchiveTests"
+ Condition="'$(ArchiveTests)' == 'true'"
+ AfterTargets="PrepareForRun"
+ DependsOnTargets="GenerateRunScript">
+ <Error Condition="'$(TestArchiveTestsDir)' == ''" Text="TestArchiveTestsDir property to archive the test folder must be set." />
+
+ <MakeDir Directories="$(TestArchiveTestsDir)" />
+ <ZipDirectory SourceDirectory="$(OutDir)"
+ DestinationFile="$([MSBuild]::NormalizePath('$(TestArchiveTestsDir)', '$(TestProjectName).zip'))"
+ Overwrite="true" />
+ </Target>
+
+ <UsingTask TaskName="GenerateRunScript" AssemblyFile="$(InstallerTasksAssemblyPath)"/>
+ <Target Name="GenerateRunScript">
+ <PropertyGroup>
+ <!-- RSP file support. -->
+ <RunArguments Condition="'$(TargetOS)' == 'Windows_NT'">$(RunArguments) %RSP_FILE%</RunArguments>
+ <RunArguments Condition="'$(TargetOS)' != 'Windows_NT'">$(RunArguments) $RSP_FILE</RunArguments>
+
+ <!-- Escape arguments with user inputs. -->
+ <RunArguments>$([MSBuild]::Escape('$(RunArguments)'))</RunArguments>
+
+ <RunScriptCommand Condition="'$(RunScriptCommand)' == ''">$(RunCommand) $(RunArguments)</RunScriptCommand>
+ </PropertyGroup>
+
+ <!-- Set $(TestDebugger) to eg c:\debuggers\windbg.exe to run tests under a debugger. -->
+ <PropertyGroup Condition="'$(TestDebugger)' != ''">
+ <RunScriptCommand Condition="!$(TestDebugger.Contains('devenv'))">$(TestDebugger) $(RunScriptCommand)</RunScriptCommand>
+ <RunScriptCommand Condition=" $(TestDebugger.Contains('devenv'))">$(TestDebugger) /debugexe $(RunScriptCommand)</RunScriptCommand>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <!--
+ If the PreExecutionTestScript property is set, then it should be set to the full path to a script that will be directly incorporated
+ into the generated runtests script, immediately before the test is run. This can be used to set a number of JIT stress modes,
+ for example. It is intended that this be as late as possible in the generated script, as close as possible to the running of the
+ test. That is why this doesn't appear higher in this file. The idea is that if the included script alters managed code behavior, such as
+ setting various JIT stress modes, we don't want those changes to affect any other managed code invocation (such as test infrastructure
+ written in managed code).
+ -->
+ <RunScriptCommands Condition="'$(PreExecutionTestScript)' != ''" Include="$([System.IO.File]::ReadAllText('$(PreExecutionTestScript)'))" />
+
+ <RunScriptCommands Include="$(RunScriptCommand)" />
+
+ <!-- Do not put anything between this and the GenerateRunScript invocation. -->
+ <RunScriptCommands Include="@(PostRunScriptCommands)" />
+ </ItemGroup>
+
+ <GenerateRunScript RunCommands="@(RunScriptCommands)"
+ TemplatePath="$(RunScriptInputPath)"
+ OutputPath="$(RunScriptOutputPath)" />
+
+ <Exec Condition="'$(TargetOS)' != 'Windows_NT'" Command="chmod +x $(RunScriptOutputPath)" />
+ </Target>
+
+ <Target Name="ValidateTestPlatform">
+ <ItemGroup>
+ <UnsupportedPlatformsItems Include="$(UnsupportedPlatforms)" />
+ </ItemGroup>
+
+ <PropertyGroup>
+ <TestDisabled Condition="'%(UnsupportedPlatformsItems.Identity)' == '$(TargetOS)' or '$(ConfigurationErrorMsg)' != ''">true</TestDisabled>
+ </PropertyGroup>
+
+ <Message Text="ValidateTestPlatform found TargetOS of [$(TargetOS)]." Importance="Low" />
+
+ <Message Condition="'%(UnsupportedPlatformsItems.Identity)' == '$(TargetOS)'"
+ Text="Skipping tests in $(AssemblyName) because it is not supported on $(TargetOS)" />
+
+ <Message Condition="'$(ConfigurationErrorMsg)' != ''"
+ Text="Skipping tests in $(AssemblyName) because there is no configuration compatible with the current BuildConfiguration." />
+ </Target>
+
+ <Target Name="RunTests"
+ Condition="'$(TestDisabled)' != 'true'"
+ DependsOnTargets="ValidateTestPlatform">
+ <Error Condition="!Exists('$(TargetPath)')"
+ Text="Test assembly couldn't be found. Make sure to build the test project first." />
+
+ <PropertyGroup>
+ <RunTestsCommand>"$(RunScriptOutputPath)" --runtime-path "$(TestHostRootPath.TrimEnd('\/'))"</RunTestsCommand>
+ <RunTestsCommand Condition="'$(TestRspFile)' != ''">$(RunTestsCommand) --rsp-file "$(TestRspFile)"</RunTestsCommand>
+ </PropertyGroup>
+
+ <!-- Invoke the run script with the test host as the runtime path. -->
+ <Exec Command="$(RunTestsCommand)"
+ ContinueOnError="true"
+ IgnoreStandardErrorWarningFormat="true">
+ <Output PropertyName="TestRunExitCode" TaskParameter="ExitCode" />
+ </Exec>
+
+ <PropertyGroup>
+ <TestRunErrorMessage>One or more tests failed while running tests from '$(TestProjectName)'.</TestRunErrorMessage>
+ <TestRunErrorMessage Condition="Exists('$(TestResultsPath)')">$(TestRunErrorMessage) Please check $(TestResultsPath) for details!</TestRunErrorMessage>
+ </PropertyGroup>
+
+ <Error Condition="'$(TestRunExitCode)' != '0'" Text="$(TestRunErrorMessage)" />
+ </Target>
+
+ <Import Project="$(MSBuildThisFileDirectory)xunit\xunit.targets" Condition="'$(TestFramework)' == 'xunit'" />
+
+ <!-- Main test targets -->
+ <Target Name="Test" DependsOnTargets="GenerateRunScript;RunTests" />
+ <Target Name="BuildAndTest" DependsOnTargets="Build;Test" />
+ <Target Name="RebuildAndTest" DependsOnTargets="Rebuild;Test" />
+</Project>
diff --git a/eng/testing/xunit/vstest.props b/eng/testing/xunit/vstest.props
new file mode 100644
index 00000000000..bcf5476a827
--- /dev/null
+++ b/eng/testing/xunit/vstest.props
@@ -0,0 +1,20 @@
+<Project>
+ <PropertyGroup>
+ <!-- Microsoft.Net.Test.Sdk brings a lot of satellite assemblies in. -->
+ <SatelliteResourceLanguages>en</SatelliteResourceLanguages>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <PackageReference Include="xunit.runner.visualstudio" Version="$(XUnitVersion)" />
+ <PackageReference Include="XunitXml.TestLogger" Version="$(XUnitXmlTestLoggerVersion)" />
+
+ <PackageReference Include="Microsoft.NET.Test.Sdk" Version="$(MicrosoftNETTestSdkVersion)" />
+ <PackageReference Include="Newtonsoft.Json" Version="$(NewtonsoftJsonVersion)" />
+ </ItemGroup>
+
+ <ItemGroup>
+ <None Include="$(TestRunnerConfigPath)"
+ CopyToOutputDirectory="PreserveNewest"
+ Visible="false" />
+ </ItemGroup>
+</Project>
diff --git a/eng/testing/xunit/vstest.targets b/eng/testing/xunit/vstest.targets
new file mode 100644
index 00000000000..9e1517a2bf6
--- /dev/null
+++ b/eng/testing/xunit/vstest.targets
@@ -0,0 +1,32 @@
+<Project>
+ <PropertyGroup>
+ <RunCommand>"$(RunScriptHost)"</RunCommand>
+ <RunArguments>test $(TargetFileName)</RunArguments>
+
+ <!-- CLI options -->
+ <RunArguments>$(RunArguments) --logger "xunit;LogFilePath=$(TestResultsName)"</RunArguments>
+ <RunArguments>$(RunArguments) --framework $(TargetFramework)</RunArguments>
+ <RunArguments>$(RunArguments) --platform $(ArchGroup)</RunArguments>
+ <RunArguments Condition="'$(TestDisableParallelization)' != 'true'">$(RunArguments) --parallel</RunArguments>
+ <RunArguments Condition="'$(TestBlame)' == 'true'">$(RunArguments) --blame</RunArguments>
+
+ <!-- Categories -->
+ <_testFilter Condition="'$(_withCategories)' != ''">$(_withCategories.Replace(';', '&amp;category='))</_testFilter>
+ <_testFilter Condition="'$(_withoutCategories)' != ''">$(_testFilter)$(_withoutCategories.Replace(';', '&amp;category!='))</_testFilter>
+ <!-- On Windows in bat scripts with delayed expansion enabled we need to escape the bang operator. -->
+ <_testFilter Condition="'$(TargetOS)' == 'Windows_NT'">$(_testFilter.Replace('!=', '^!='))</_testFilter>
+ <_testFilter>$(_testFilter.Trim('&amp;'))</_testFilter>
+ <!-- On Windows in bat scripts with delayed expansion enabled we need to escape the bang operator. -->
+ <_testFilter Condition="'$(TestFilter)' != ''">$(_testFilter)&amp;$(TestFilter.Replace('!=', '^!='))</_testFilter>
+
+ <RunArguments>$(RunArguments) --filter "($(_testFilter))"</RunArguments>
+
+ <!-- User passed in options. -->
+ <RunArguments Condition="'$(XUnitOptions)' != ''">$(RunArguments) $(XUnitOptions)</RunArguments>
+
+ <!-- RunConfiguration settings. -->
+ <RunSettingsOptions Condition="'$(TestDisableParallelization)' == 'true'">$(RunSettingsOptions) RunConfiguration.DisableParallelization=true</RunSettingsOptions>
+ <RunSettingsOptions Condition="'$(TestDisableAppDomain)' == 'true'">$(RunSettingsOptions) RunConfiguration.DisableAppDomain=true</RunSettingsOptions>
+ <RunArguments Condition="'$(RunSettingsOptions)' != ''">$(RunArguments) --(RunSettingsOptions)</RunArguments>
+ </PropertyGroup>
+</Project> \ No newline at end of file
diff --git a/eng/testing/xunit/xunit.console.props b/eng/testing/xunit/xunit.console.props
new file mode 100644
index 00000000000..48a3919fcb6
--- /dev/null
+++ b/eng/testing/xunit/xunit.console.props
@@ -0,0 +1,21 @@
+<Project>
+ <PropertyGroup>
+ <CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <PackageReference Condition="'$(TargetsNetCoreApp)' == 'true'" Include="Microsoft.DotNet.XUnitConsoleRunner" Version="$(MicrosoftDotNetXUnitConsoleRunnerVersion)" />
+ <PackageReference Condition="'$(TargetsNetFx)' == 'true'" Include="xunit.runner.console" Version="$(XUnitVersion)" />
+
+ <!-- Microsoft.Net.Test.Sdk brings a lot of assemblies with it. To reduce helix payload submission size we disable it on CI. -->
+ <PackageReference Condition="'$(ArchiveTest)' != 'true'" Include="Microsoft.NET.Test.Sdk" Version="$(MicrosoftNETTestSdkVersion)" />
+ <PackageReference Condition="'$(ArchiveTest)' != 'true'" Include="xunit.runner.visualstudio" Version="$(XUnitVersion)" />
+ <!--
+ Microsoft.Net.Test.Sdk has a dependency on Newtonsoft.Json v9.0.1. We upgrade the dependency version
+ with the one used in corefx to have a consistent set of dependency versions. Additionally this works
+ around a dupliate type between System.Runtime.Serialization.Formatters and Newtonsoft.Json.
+ -->
+ <PackageReference Condition="'$(ArchiveTest)' != 'true'" Include="Newtonsoft.Json" Version="$(NewtonsoftJsonVersion)" />
+
+ </ItemGroup>
+</Project>
diff --git a/eng/testing/xunit/xunit.console.targets b/eng/testing/xunit/xunit.console.targets
new file mode 100644
index 00000000000..c7f10a9041f
--- /dev/null
+++ b/eng/testing/xunit/xunit.console.targets
@@ -0,0 +1,75 @@
+<Project>
+ <PropertyGroup>
+ <RunArguments>$(TargetFileName)</RunArguments>
+ <RunArguments>$(RunArguments) -xml $(TestResultsName)</RunArguments>
+ <RunArguments>$(RunArguments) -nologo</RunArguments>
+ <RunArguments Condition="'$(ArchiveTest)' == 'true'">$(RunArguments) -nocolor</RunArguments>
+
+ <!-- Add local and global options to the argument stack. -->
+ <RunArguments Condition="'$(TestDisableParallelization)' == 'true'">$(RunArguments) -maxthreads 1</RunArguments>
+ <RunArguments Condition="'$(XUnitMethodName)' != ''">$(RunArguments) -method $(XUnitMethodName)</RunArguments>
+ <RunArguments Condition="'$(XUnitClassName)' != ''">$(RunArguments) -class $(XUnitClassName)</RunArguments>
+ <RunArguments Condition="'$(XUnitShowProgress)' == 'true'">$(RunArguments) -verbose</RunArguments>
+ <RunArguments Condition="'$(TargetsNetFx)' == 'true' and '$(TestDisableAppDomain)' == 'true'">$(RunArguments) -noappdomain</RunArguments>
+
+ <!-- Add to run argument string -->
+ <RunArguments>$(RunArguments)$(_withCategories.Replace(';', ' -trait category='))</RunArguments>
+ <RunArguments>$(RunArguments)$(_withoutCategories.Replace(';', ' -notrait category='))</RunArguments>
+
+ <!-- User passed in options. -->
+ <RunArguments Condition="'$(XUnitOptions)' != ''">$(RunArguments) $(XUnitOptions)</RunArguments>
+ </PropertyGroup>
+
+ <!-- Overwrite the runner config file with the app local one. -->
+ <Target Name="OverwriteDesktopTestRunnerConfigs"
+ Condition="'$(GenerateRuntimeConfigurationFiles)' == 'true' and '$(TargetsNetFx)' == 'true'"
+ AfterTargets="CopyFilesToOutputDirectory">
+
+ <ItemGroup>
+ <_testRunnerConfigSourceFile Include="$(TargetDir)$(TargetName).exe.config" />
+ <_testRunnerConfigDestFile Include="$(TargetDir)$(_testRunnerName).config" />
+ </ItemGroup>
+
+ <Copy SourceFiles="@(_testRunnerConfigSourceFile)"
+ Condition="'@(_testRunnerConfigSourceFile)' != ''"
+ DestinationFiles="@(_testRunnerConfigDestFile)"
+ SkipUnchangedFiles="true" />
+
+ </Target>
+
+ <!-- Setup run commands. -->
+ <PropertyGroup Condition="'$(TargetsNetCoreApp)' == 'true'">
+ <RunCommand>"$(RunScriptHost)"</RunCommand>
+ <_depsFileRunArgument Condition="'$(GenerateDependencyFile)' == 'true'">--depsfile $(AssemblyName).deps.json</_depsFileRunArgument>
+ <RunArguments>exec --runtimeconfig $(AssemblyName).runtimeconfig.json $(_depsFileRunArgument) xunit.console.dll $(RunArguments)</RunArguments>
+ </PropertyGroup>
+
+ <PropertyGroup Condition="'$(TargetsNetFx)' == 'true'">
+ <_testRunnerName>xunit.console.exe</_testRunnerName>
+ <RunCommand>$(_testRunnerName)</RunCommand>
+ </PropertyGroup>
+
+ <!-- ResolveAssemblyReferences is the target that populates ReferenceCopyLocalPaths which is what is copied to output directory. -->
+ <Target Name="CopyRunnerToOutputDirectory" BeforeTargets="ResolveAssemblyReferences">
+ <ItemGroup>
+ <!-- Add the runner configuration file -->
+ <None Include="$(TestRunnerConfigPath)"
+ CopyToOutputDirectory="PreserveNewest"
+ Visible="false" />
+
+ <!-- Copy test runner to output directory -->
+ <None Include="$([System.IO.Path]::GetDirectoryName('$(XunitConsole472Path)'))\*"
+ Exclude="$([System.IO.Path]::GetDirectoryName('$(XunitConsole472Path)'))\xunit.console.*exe.config;$([System.IO.Path]::GetDirectoryName('$(XunitConsole472Path)'))\xunit.console.x86.exe"
+ Condition="'$(TargetsNetFx)' == 'true' and '$(XunitConsole472Path)' != ''"
+ CopyToOutputDirectory="PreserveNewest"
+ Visible="false" />
+
+ <_xunitConsoleNetCoreExclude Condition="'$(GenerateDependencyFile)' != 'true'" Include="$([System.IO.Path]::GetDirectoryName('$(XunitConsoleNetCore21AppPath)'))\xunit.console.deps.json" />
+ <None Include="$([System.IO.Path]::GetDirectoryName('$(XunitConsoleNetCore21AppPath)'))\*"
+ Exclude="@(_xunitConsoleNetCoreExclude)"
+ Condition="'$(TargetsNetCoreApp)' == 'true' and '$(XunitConsoleNetCore21AppPath)' != ''"
+ CopyToOutputDirectory="PreserveNewest"
+ Visible="false" />
+ </ItemGroup>
+ </Target>
+</Project>
diff --git a/eng/testing/xunit/xunit.props b/eng/testing/xunit/xunit.props
new file mode 100644
index 00000000000..2282ba79caa
--- /dev/null
+++ b/eng/testing/xunit/xunit.props
@@ -0,0 +1,18 @@
+<Project>
+ <PropertyGroup>
+ <TestRunner Condition="'$(TestRunner)' == ''">xunit.console</TestRunner>
+ <TestRunnerConfigPath>$(MSBuildThisFileDirectory)xunit.runner.json</TestRunnerConfigPath>
+ <TestResultsName>testResults.xml</TestResultsName>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <PackageReference Condition="'$(IncludeRemoteExecutor)' == 'true'" Include="Microsoft.DotNet.RemoteExecutor" Version="$(MicrosoftDotNetRemoteExecutorVersion)" />
+
+ <!-- Excluding xunit.core/build as it enables deps file generation. -->
+ <PackageReference Include="xunit" Version="$(XUnitVersion)" ExcludeAssets="build" />
+ <PackageReference Include="Microsoft.DotNet.XUnitExtensions" Version="$(MicrosoftDotNetXUnitExtensionsVersion)" />
+ </ItemGroup>
+
+ <Import Project="$(MSBuildThisFileDirectory)xunit.console.props" Condition="'$(TestRunner)' == 'xunit.console'" />
+ <Import Project="$(MSBuildThisFileDirectory)vstest.props" Condition="'$(TestRunner)' == 'vstest'" />
+</Project>
diff --git a/eng/testing/xunit/xunit.runner.json b/eng/testing/xunit/xunit.runner.json
new file mode 100644
index 00000000000..5d2ac0433c9
--- /dev/null
+++ b/eng/testing/xunit/xunit.runner.json
@@ -0,0 +1,5 @@
+{
+ "diagnosticMessages": true,
+ "longRunningTestSeconds": 120,
+ "shadowCopy": false
+} \ No newline at end of file
diff --git a/eng/testing/xunit/xunit.targets b/eng/testing/xunit/xunit.targets
new file mode 100644
index 00000000000..4ddddcce51c
--- /dev/null
+++ b/eng/testing/xunit/xunit.targets
@@ -0,0 +1,31 @@
+<Project>
+ <PropertyGroup>
+ <TargetOSCategory Condition="'$(TargetOS)' == 'Windows_NT'">nonwindowstests</TargetOSCategory>
+ <TargetOSCategory Condition="'$(TargetOS)' == 'Linux'">nonlinuxtests</TargetOSCategory>
+ <TargetOSCategory Condition="'$(TargetOS)' == 'OSX'">nonosxtests</TargetOSCategory>
+ <TargetOSCategory Condition="'$(TargetOS)' == 'FreeBSD'">nonfreebsdtests</TargetOSCategory>
+ <TargetOSCategory Condition="'$(TargetOS)' == 'NetBSD'">nonnetbsdtests</TargetOSCategory>
+
+ <!-- Default and user defined categories -->
+ <_withCategories Condition="'$(WithCategories)' != ''">;$(WithCategories.Trim(';'))</_withCategories>
+ <_withoutCategories Condition="'$(WithoutCategories)' != ''">;$(WithoutCategories.Trim(';'))</_withoutCategories>
+
+ <TestScope Condition="'$(TestScope)' == '' and '$(Outerloop)' == 'true'">all</TestScope>
+ <_withCategories Condition="'$(TestScope)' == 'outerloop'">$(_withCategories);OuterLoop</_withCategories>
+ <_withoutCategories Condition="'$(ArchiveTest)' == 'true'">$(_withoutCategories);IgnoreForCI</_withoutCategories>
+ <_withoutCategories Condition="'$(TestScope)' == '' or '$(TestScope)' == 'innerloop'">$(_withoutCategories);OuterLoop</_withoutCategories>
+ <_withoutCategories Condition="!$(_withCategories.Contains('failing'))">$(_withoutCategories);failing</_withoutCategories>
+
+ <_withoutCategories>$(_withoutCategories);non$(_bc_TargetGroup)tests</_withoutCategories>
+ <_withoutCategories Condition="'$(TargetOSCategory)' != ''">$(_withoutCategories);$(TargetOSCategory)</_withoutCategories>
+ </PropertyGroup>
+
+ <Target Name="ValidateTargetOSCategory"
+ BeforeTargets="GenerateRunScript">
+ <Error Condition="'$(TargetOSCategory)' == ''"
+ Text="TargetOS [$(TargetOS)] is unknown so we don't know how to configure the test run for this project [$(TestProjectName)]" />
+ </Target>
+
+ <Import Project="$(MSBuildThisFileDirectory)xunit.console.targets" Condition="'$(TestRunner)' == 'xunit.console'" />
+ <Import Project="$(MSBuildThisFileDirectory)vstest.targets" Condition="'$(TestRunner)' == 'vstest'" />
+</Project>
diff --git a/global.json b/global.json
index 5cf141c8ca3..bf792d35e80 100644
--- a/global.json
+++ b/global.json
@@ -16,7 +16,6 @@
"Microsoft.DotNet.Build.Tasks.SharedFramework.Sdk": "5.0.0-beta.19567.2",
"Microsoft.DotNet.Helix.Sdk": "5.0.0-beta.19567.2",
"Microsoft.DotNet.Build.Tasks.Configuration": "5.0.0-beta.19567.2",
- "Microsoft.DotNet.CoreFxTesting": "5.0.0-beta.19567.2",
"FIX-85B6-MERGE-9C38-CONFLICT": "1.0.0",
"Microsoft.NET.Sdk.IL": "5.0.0-alpha1.19563.3",
"Microsoft.Build.NoTargets": "1.0.53",
diff --git a/src/coreclr/tests/scripts/run-corefx-tests.py b/src/coreclr/tests/scripts/run-corefx-tests.py
index b34609724d3..1dad96057c1 100644
--- a/src/coreclr/tests/scripts/run-corefx-tests.py
+++ b/src/coreclr/tests/scripts/run-corefx-tests.py
@@ -300,7 +300,7 @@ def main(args):
common_config_args = '-configuration Release -framework netcoreapp -os %s -arch %s' % (clr_os, arch)
build_args = '-build -restore'
- build_test_args = '-buildtests /p:ArchiveTests=Tests'
+ build_test_args = '-buildtests /p:ArchiveTests=true'
if not no_run_tests:
build_test_args += ' -test'
diff --git a/src/libraries/Directory.Build.props b/src/libraries/Directory.Build.props
index 84d0266966a..dd2bcf6b76f 100644
--- a/src/libraries/Directory.Build.props
+++ b/src/libraries/Directory.Build.props
@@ -86,7 +86,19 @@
</PropertyGroup>
<Import Sdk="Microsoft.DotNet.Build.Tasks.Configuration" Project="Sdk.props" />
- <Import Sdk="Microsoft.DotNet.CoreFxTesting" Project="Sdk.props" Condition="'$(DotNetBuildFromSource)' != 'true' and '$(BuildAllConfigurations)' != 'true'" />
+
+ <!-- Define test projects and companions -->
+ <PropertyGroup>
+ <IsTestProject>false</IsTestProject>
+ <IsTestProject Condition="$(MSBuildProjectName.EndsWith('.UnitTests')) or $(MSBuildProjectName.EndsWith('.Tests'))">true</IsTestProject>
+
+ <IsTestSupportProject>false</IsTestSupportProject>
+ <IsTestSupportProject Condition="($(MSBuildProjectFullPath.Contains('\tests\')) OR $(MSBuildProjectFullPath.Contains('/tests/'))) AND '$(IsTestProject)' != 'true'">true</IsTestSupportProject>
+ <IsTestProject Condition="'$(IsTestSupportProject)' == 'true'">true</IsTestProject>
+
+ <!-- Treat test assemblies as non-shipping (do not publish or sign them). -->
+ <IsShipping Condition="'$(IsTestProject)' == 'true'">false</IsShipping>
+ </PropertyGroup>
<PropertyGroup>
<EnableProjectRestore Condition="'$(IsTestProject)' == 'true'">true</EnableProjectRestore>
@@ -304,45 +316,25 @@
<VersionFileForPackages Condition="'$(VersionFileForPackages)' == ''">$(ArtifactsObjDir)version.txt</VersionFileForPackages>
</PropertyGroup>
- <PropertyGroup Condition="'$(BuildAllConfigurations)' != 'true'">
- <!-- We add extra binplacing for the test shared framework until we can get hardlinking with the runtime directory working on all platforms -->
- <BinPlaceTestSharedFramework Condition="'$(_bc_TargetGroup)' == 'netcoreapp'">true</BinPlaceTestSharedFramework>
- <BinPlaceNETFXRuntime Condition="'$(_bc_TargetGroup)' == 'netfx'">true</BinPlaceNETFXRuntime>
-
- <NETCoreAppTestSharedFrameworkPath>$([MSBuild]::NormalizeDirectory('$(TestHostRootPath)', 'shared', 'Microsoft.NETCore.App', '$(ProductVersion)'))</NETCoreAppTestSharedFrameworkPath>
-
- <TestHostRuntimePath Condition="'$(BinPlaceTestSharedFramework)' == 'true'">$(NETCoreAppTestSharedFrameworkPath)</TestHostRuntimePath>
- <TestHostRuntimePath Condition="'$(BinPlaceNETFXRuntime)' == 'true'">$(TestHostRootPath)</TestHostRuntimePath>
-
- <PlatformManifestFile>$(TestHostRuntimePath)PlatformManifest.txt</PlatformManifestFile>
- </PropertyGroup>
-
- <ItemGroup Condition="'$(PlatformManifestFile)' != '' and '$(IsTestProject)' == 'true'">
- <PackageConflictPlatformManifests Include="$(PlatformManifestFile)" />
- </ItemGroup>
-
- <PropertyGroup>
- <!-- F5 and debugging support for netcoreapp and netfx inside VS. -->
- <EnableLaunchSettings Condition="'$(EnableLaunchSettings)' == '' and '$(DotNetBuildFromSource)' != 'true'">true</EnableLaunchSettings>
- </PropertyGroup>
-
- <!-- Test properties for full build. -->
- <PropertyGroup Condition="'$(TestAllProjects)' == 'true'">
- <GenerateFullCoverageReport Condition="'$(GenerateFullCoverageReport)' == ''">true</GenerateFullCoverageReport>
- </PropertyGroup>
-
<Import Project="$(RepositoryEngineeringDir)references.props" />
<!-- Import it at the end of the props file to override the OutputPath for reference assemblies and use common directory props -->
<Import Project="$(RepositoryEngineeringDir)referenceAssemblies.props" />
- <PropertyGroup Condition="'$(IsSourceProject)' == 'true'">
+ <PropertyGroup>
+ <EnableDefaultItems>false</EnableDefaultItems>
+ <EmbedUntrackedSources>true</EmbedUntrackedSources>
+ <DisableImplicitConfigurationDefines>true</DisableImplicitConfigurationDefines>
+
+ <!-- Workaround for https://github.com/microsoft/msbuild/issues/4474 -->
+ <GenerateResourceUsePreserializedResources>false</GenerateResourceUsePreserializedResources>
+
<!-- Set the documentation output file globally. -->
- <DocumentationFile Condition="'$(DocumentationFile)' == ''">$(OutputPath)$(MSBuildProjectName).xml</DocumentationFile>
- </PropertyGroup>
+ <DocumentationFile Condition="'$(IsSourceProject)' == 'true' and '$(DocumentationFile)' == ''">$(OutputPath)$(MSBuildProjectName).xml</DocumentationFile>
+
+ <CodeAnalysisRuleset>$(LibrariesProjectRoot)CodeAnalysis.ruleset</CodeAnalysisRuleset>
+ <EnablePinvokeUWPAnalyzer>false</EnablePinvokeUWPAnalyzer>
- <!-- Additional optimizations -->
- <PropertyGroup>
<!-- Clear the init locals flag on all src projects, except those in VB, where we can't use spans. -->
<ILLinkClearInitLocals Condition="'$(IsSourceProject)' == 'true' and '$(Language)' != 'VB'">true</ILLinkClearInitLocals>
</PropertyGroup>
@@ -356,22 +348,36 @@
<IsShippingPackage Condition="$(MSBuildProjectName.Contains('Private')) and '$(MSBuildProjectExtension)' == '.pkgproj'">false</IsShippingPackage>
</PropertyGroup>
- <PropertyGroup>
- <EnableDefaultItems>false</EnableDefaultItems>
- <EmbedUntrackedSources>true</EmbedUntrackedSources>
- <DisableImplicitConfigurationDefines>true</DisableImplicitConfigurationDefines>
+ <PropertyGroup Condition="'$(BuildAllConfigurations)' != 'true'">
+ <!-- We add extra binplacing for the test shared framework until we can get hardlinking with the runtime directory working on all platforms -->
+ <BinPlaceTestSharedFramework Condition="'$(_bc_TargetGroup)' == 'netcoreapp'">true</BinPlaceTestSharedFramework>
+ <BinPlaceNETFXRuntime Condition="'$(_bc_TargetGroup)' == 'netfx'">true</BinPlaceNETFXRuntime>
- <!-- Workaround for https://github.com/microsoft/msbuild/issues/4474 -->
- <GenerateResourceUsePreserializedResources>false</GenerateResourceUsePreserializedResources>
+ <NETCoreAppTestSharedFrameworkPath>$([MSBuild]::NormalizeDirectory('$(TestHostRootPath)', 'shared', 'Microsoft.NETCore.App', '$(ProductVersion)'))</NETCoreAppTestSharedFrameworkPath>
- <CodeAnalysisRuleset>$(LibrariesProjectRoot)CodeAnalysis.ruleset</CodeAnalysisRuleset>
- <EnablePinvokeUWPAnalyzer>false</EnablePinvokeUWPAnalyzer>
+ <TestHostRuntimePath Condition="'$(BinPlaceTestSharedFramework)' == 'true'">$(NETCoreAppTestSharedFrameworkPath)</TestHostRuntimePath>
+ <TestHostRuntimePath Condition="'$(BinPlaceNETFXRuntime)' == 'true'">$(TestHostRootPath)</TestHostRuntimePath>
+
+ <PlatformManifestFile Condition="'$(BinPlaceTestSharedFramework)' == 'true'">$(TestHostRuntimePath)PlatformManifest.txt</PlatformManifestFile>
</PropertyGroup>
+ <ItemGroup Condition="'$(PlatformManifestFile)' != '' and '$(IsTestProject)' == 'true'">
+ <PackageConflictPlatformManifests Include="$(PlatformManifestFile)" />
+ </ItemGroup>
+
<ItemGroup Condition="'$(IsTestProject)' == 'true' and '$(IsTestSupportProject)' != 'true'">
- <ProjectReference Include="$(CommonTestPath)\CoreFx.Private.TestUtilities\CoreFx.Private.TestUtilities.csproj" />
+ <ProjectReference Include="$(CommonTestPath)CoreFx.Private.TestUtilities\CoreFx.Private.TestUtilities.csproj" />
</ItemGroup>
+ <PropertyGroup Condition="'$(IsTestProject)' == 'true' and '$(IsTestSupportProject)' != 'true'">
+ <EnableTestSupport>true</EnableTestSupport>
+ <EnableCoverageSupport Condition="'$(Coverage)' == 'true' and '$(CoverageSupported)' != 'false'">true</EnableCoverageSupport>
+ <EnableLaunchSettings Condition="'$(DotNetBuildFromSource)' != 'true'">true</EnableLaunchSettings>
+ </PropertyGroup>
+
+ <Import Project="$(RepositoryEngineeringDir)testing\tests.props" Condition="'$(EnableTestSupport)' == 'true'" />
+ <Import Project="$(RepositoryEngineeringDir)testing\coverage.props" Condition="'$(EnableCoverageSupport)' == 'true'" />
+
<!-- Use msbuild path functions as that property is used in bash scripts. -->
<ItemGroup>
<CoverageExcludeFile Include="$([MSBuild]::NormalizePath('$(LibrariesProjectRoot)', 'Common', 'src', 'System', 'SR.*'))" />
diff --git a/src/libraries/Directory.Build.targets b/src/libraries/Directory.Build.targets
index 41789089cd2..08426497067 100644
--- a/src/libraries/Directory.Build.targets
+++ b/src/libraries/Directory.Build.targets
@@ -115,9 +115,12 @@
<Import Project="$(RepositoryEngineeringDir)depProj.targets" Condition="'$(MSBuildProjectExtension)' == '.depproj'" />
<Import Project="$(RepositoryEngineeringDir)references.targets" />
<Import Project="$(RepositoryEngineeringDir)resolveContract.targets" />
+ <Import Project="$(RepositoryEngineeringDir)testing\runtimeConfiguration.targets" />
+ <Import Project="$(RepositoryEngineeringDir)testing\launchSettings.targets" Condition="'$(EnableLaunchSettings)' == 'true'" />
+ <Import Project="$(RepositoryEngineeringDir)testing\tests.targets" Condition="'$(EnableTestSupport)' == 'true'" />
+ <Import Project="$(RepositoryEngineeringDir)testing\coverage.targets" Condition="'$(EnableCoverageSupport)' == 'true'" />
<Import Sdk="Microsoft.DotNet.Build.Tasks.Configuration" Project="Sdk.targets" />
- <Import Sdk="Microsoft.DotNet.CoreFxTesting" Project="Sdk.targets" Condition="'$(DotNetBuildFromSource)' != 'true' and '$(BuildAllConfigurations)' != 'true'" />
<Import Condition="'$(EnableProjectRestore)' != 'true'" Project="$(RepositoryEngineeringDir)restore\repoRestore.targets" />
<Import Project="$(RepositoryEngineeringDir)referenceFromRuntime.targets" />
@@ -178,17 +181,6 @@
</ItemGroup>
</Target>
- <!-- Routing dotnet test to a test project's BuildAndTest target. -->
- <Target Name="VSTest"
- Condition="'$(IsTestProject)' == 'true' and '$(IsTestSupportProject)' != 'true'"
- DependsOnTargets="BuildAndTest" />
-
- <Target Name="ValidateTestProjectConfigurations"
- BeforeTargets="CoreCompile"
- Condition="'$(IsTestProject)' == 'true' and '$(IsTestSupportProject)' != 'true' and '$(TargetsNetStandard)' == 'true'">
- <Error Text="Targeting .NET Standard in a test project isn't supported." />
- </Target>
-
<PropertyGroup>
<!--
Hack workaround to skip the GenerateCompiledExpressionsTempFile target in
diff --git a/src/libraries/System.Configuration.ConfigurationManager/tests/System.Configuration.ConfigurationManager.Tests.csproj b/src/libraries/System.Configuration.ConfigurationManager/tests/System.Configuration.ConfigurationManager.Tests.csproj
index 2a888c9ca66..f0efd58710a 100644
--- a/src/libraries/System.Configuration.ConfigurationManager/tests/System.Configuration.ConfigurationManager.Tests.csproj
+++ b/src/libraries/System.Configuration.ConfigurationManager/tests/System.Configuration.ConfigurationManager.Tests.csproj
@@ -1,12 +1,11 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<!-- XUnit AppDomains BaseDirectory path doesn't contain a trailing slash, which impacts our tests. -->
- <XUnitNoAppdomain>true</XUnitNoAppdomain>
- <XUnitMaxThreads>1</XUnitMaxThreads>
+ <TestDisableAppDomain>true</TestDisableAppDomain>
+ <TestDisableParallelization>true</TestDisableParallelization>
<IncludeRemoteExecutor>true</IncludeRemoteExecutor>
<Configurations>netcoreapp-Debug;netcoreapp-Release;netfx-Debug;netfx-Release</Configurations>
</PropertyGroup>
- <!-- Default configurations to help VS understand the options -->
<ItemGroup>
<Compile Include="$(CommonTestPath)System\IO\TempDirectory.cs">
<Link>Common\System\IO\TempDirectory.cs</Link>
diff --git a/src/libraries/System.Runtime.Serialization.Formatters/tests/BinaryFormatterTests.cs b/src/libraries/System.Runtime.Serialization.Formatters/tests/BinaryFormatterTests.cs
index 5232c1a2764..31ecb267892 100644
--- a/src/libraries/System.Runtime.Serialization.Formatters/tests/BinaryFormatterTests.cs
+++ b/src/libraries/System.Runtime.Serialization.Formatters/tests/BinaryFormatterTests.cs
@@ -159,7 +159,7 @@ namespace System.Runtime.Serialization.Formatters.Tests
// To generate this properly, change AssemblyVersion to a value which is unlikely to happen in production and generate base64(serialized-data)
// For this test 9.98.7.987 is being used
var obj = new SomeType() { SomeField = 7 };
- string serializedObj = @"AAEAAAD/////AQAAAAAAAAAMAgAAAHNTeXN0ZW0uUnVudGltZS5TZXJpYWxpemF0aW9uLkZvcm1hdHRlcnMuVGVzdHMsIFZlcnNpb249OS45OC43Ljk4NywgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj05ZDc3Y2M3YWQzOWI2OGViBQEAAAA2U3lzdGVtLlJ1bnRpbWUuU2VyaWFsaXphdGlvbi5Gb3JtYXR0ZXJzLlRlc3RzLlNvbWVUeXBlAQAAAAlTb21lRmllbGQACAIAAAAHAAAACw==";
+ string serializedObj = @"AAEAAAD/////AQAAAAAAAAAMAgAAAHBTeXN0ZW0uUnVudGltZS5TZXJpYWxpemF0aW9uLkZvcm1hdHRlcnMuVGVzdHMsIFZlcnNpb249NS4wLjAuMCwgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1jYzdiMTNmZmNkMmRkZDUxBQEAAAA2U3lzdGVtLlJ1bnRpbWUuU2VyaWFsaXphdGlvbi5Gb3JtYXR0ZXJzLlRlc3RzLlNvbWVUeXBlAQAAAAlTb21lRmllbGQACAIAAAAHAAAACw==";
var deserialized = (SomeType)BinaryFormatterHelpers.FromBase64String(serializedObj, FormatterAssemblyStyle.Simple);
Assert.Equal(obj, deserialized);
@@ -171,7 +171,7 @@ namespace System.Runtime.Serialization.Formatters.Tests
// To generate this properly, change AssemblyVersion to a value which is unlikely to happen in production and generate base64(serialized-data)
// For this test 9.98.7.987 is being used
var obj = new GenericTypeWithArg<SomeType>() { Test = new SomeType() { SomeField = 9 } };
- string serializedObj = @"AAEAAAD/////AQAAAAAAAAAMAgAAAHNTeXN0ZW0uUnVudGltZS5TZXJpYWxpemF0aW9uLkZvcm1hdHRlcnMuVGVzdHMsIFZlcnNpb249OS45OC43Ljk4NywgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj05ZDc3Y2M3YWQzOWI2OGViBQEAAADxAVN5c3RlbS5SdW50aW1lLlNlcmlhbGl6YXRpb24uRm9ybWF0dGVycy5UZXN0cy5HZW5lcmljVHlwZVdpdGhBcmdgMVtbU3lzdGVtLlJ1bnRpbWUuU2VyaWFsaXphdGlvbi5Gb3JtYXR0ZXJzLlRlc3RzLlNvbWVUeXBlLCBTeXN0ZW0uUnVudGltZS5TZXJpYWxpemF0aW9uLkZvcm1hdHRlcnMuVGVzdHMsIFZlcnNpb249OS45OC43Ljk4NywgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj05ZDc3Y2M3YWQzOWI2OGViXV0BAAAABFRlc3QENlN5c3RlbS5SdW50aW1lLlNlcmlhbGl6YXRpb24uRm9ybWF0dGVycy5UZXN0cy5Tb21lVHlwZQIAAAACAAAACQMAAAAFAwAAADZTeXN0ZW0uUnVudGltZS5TZXJpYWxpemF0aW9uLkZvcm1hdHRlcnMuVGVzdHMuU29tZVR5cGUBAAAACVNvbWVGaWVsZAAIAgAAAAkAAAAL";
+ string serializedObj = @"AAEAAAD/////AQAAAAAAAAAMAgAAAHBTeXN0ZW0uUnVudGltZS5TZXJpYWxpemF0aW9uLkZvcm1hdHRlcnMuVGVzdHMsIFZlcnNpb249NS4wLjAuMCwgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1jYzdiMTNmZmNkMmRkZDUxBQEAAADuAVN5c3RlbS5SdW50aW1lLlNlcmlhbGl6YXRpb24uRm9ybWF0dGVycy5UZXN0cy5HZW5lcmljVHlwZVdpdGhBcmdgMVtbU3lzdGVtLlJ1bnRpbWUuU2VyaWFsaXphdGlvbi5Gb3JtYXR0ZXJzLlRlc3RzLlNvbWVUeXBlLCBTeXN0ZW0uUnVudGltZS5TZXJpYWxpemF0aW9uLkZvcm1hdHRlcnMuVGVzdHMsIFZlcnNpb249NS4wLjAuMCwgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1jYzdiMTNmZmNkMmRkZDUxXV0BAAAABFRlc3QENlN5c3RlbS5SdW50aW1lLlNlcmlhbGl6YXRpb24uRm9ybWF0dGVycy5UZXN0cy5Tb21lVHlwZQIAAAACAAAACQMAAAAFAwAAADZTeXN0ZW0uUnVudGltZS5TZXJpYWxpemF0aW9uLkZvcm1hdHRlcnMuVGVzdHMuU29tZVR5cGUBAAAACVNvbWVGaWVsZAAIAgAAAAkAAAAL";
var deserialized = (GenericTypeWithArg<SomeType>)BinaryFormatterHelpers.FromBase64String(serializedObj, FormatterAssemblyStyle.Simple);
Assert.Equal(obj, deserialized);
diff --git a/src/libraries/pkg/test/testPackages.proj b/src/libraries/pkg/test/testPackages.proj
index fd928d2b352..6db7b5fbb7f 100644
--- a/src/libraries/pkg/test/testPackages.proj
+++ b/src/libraries/pkg/test/testPackages.proj
@@ -155,7 +155,7 @@
<Target Name="ArchiveHelixItems"
DependsOnTargets="GenerateProjects;CopyProducedPackages"
- Condition="'$(ArchiveTests.ToLower())' == 'packages' or '$(ArchiveTests.ToLower())' == 'all'">
+ Condition="'$(ArchiveTests)' == 'true'">
<MakeDir Directories="$(TestArchiveTestsRoot)" />
<ZipDirectory
@@ -173,7 +173,7 @@
<Target Name="RestoreProjects"
DependsOnTargets="GenerateProjects"
- Condition="'$(ArchiveTests.ToLower())' != 'packages' and '$(ArchiveTests.ToLower())' != 'all'">
+ Condition="'$(ArchiveTests)' != 'true'">
<PropertyGroup>
<TestRestoreCommand>$(TestDotNetPath)</TestRestoreCommand>
@@ -191,7 +191,7 @@
<Target Name="BuildProjects"
DependsOnTargets="RestoreProjects"
- Condition="'$(ArchiveTests.ToLower())' != 'packages' and '$(ArchiveTests.ToLower())' != 'all'">
+ Condition="'$(ArchiveTests)' != 'true'">
<PropertyGroup>
<TestBuildCommand>$(TestDotNetPath)</TestBuildCommand>
diff --git a/src/libraries/pretest.proj b/src/libraries/pretest.proj
index 25ed7f64c54..a86dfd053d6 100644
--- a/src/libraries/pretest.proj
+++ b/src/libraries/pretest.proj
@@ -28,6 +28,28 @@
</ItemGroup>
</Target>
+ <UsingTask TaskName="GenerateFileVersionProps" AssemblyFile="$(InstallerTasksAssemblyPath)"/>
+ <Target Name="GenerateFileVersionProps">
+ <GenerateFileVersionProps Files="@(SharedFrameworkRuntimeFiles)"
+ PackageId="Microsoft.NETCore.App"
+ PackageVersion="$(ProductVersion)"
+ PlatformManifestFile="$(PlatformManifestFile)"
+ PreferredPackages="Microsoft.NetCore.App"
+ PermitDllAndExeFilesLackingFileVersion="true" />
+ </Target>
+
+ <!--
+ Shared framework deps file generation.
+ Produces a test shared-framework deps file.
+ To use invoke target directly specifying NETCoreAppTestSharedFrameworkPath property.
+ -->
+ <UsingTask TaskName="GenerateTestSharedFrameworkDepsFile" AssemblyFile="$(InstallerTasksAssemblyPath)"/>
+ <Target Name="GenerateTestSharedFrameworkDepsFile">
+ <GenerateTestSharedFrameworkDepsFile SharedFrameworkDirectory="$(NETCoreAppTestSharedFrameworkPath)"
+ RuntimeGraphFiles="$(RuntimeIdGraphDefinitionFile)"
+ TargetRuntimeIdentifier="$(PackageRID)" />
+ </Target>
+
<!-- Generate launch settings support files to enable VS debugging. -->
<Target Name="GenerateLaunchSettingsFiles" Condition="'$(EnableLaunchSettings)' == 'true'">
<PropertyGroup>
diff --git a/src/libraries/restore/runtime/runtime.depproj b/src/libraries/restore/runtime/runtime.depproj
index 397f7deaa84..bfb02bccfcd 100644
--- a/src/libraries/restore/runtime/runtime.depproj
+++ b/src/libraries/restore/runtime/runtime.depproj
@@ -21,7 +21,6 @@
<PackageReference Include="Microsoft.NETCore.Platforms" Version="$(MicrosoftNETCorePlatformsVersion)" />
<PackageReference Include="transport.Microsoft.NETCore.Runtime.CoreCLR" Version="$(MicrosoftNETCoreRuntimeCoreCLRVersion)" />
<PackageReference Include="Microsoft.NETCore.TestHost" Version="$(MicrosoftNETCoreRuntimeCoreCLRVersion)" />
- <PackageReference Include="runtime.native.System.Data.SqlClient.sni" Version="$(RuntimeNativeSystemDataSqlClientSniVersion)" />
<PackageReference Include="Microsoft.NETCore.DotNetHost" Version="$(MicrosoftNETCoreDotNetHostVersion)" />
<PackageReference Include="Microsoft.NETCore.DotNetHostPolicy" Version="$(MicrosoftNETCoreDotNetHostPolicyVersion)" />
<!-- We do not need apphost.exe and the 3.0 SDK will actually remove it.
diff --git a/src/libraries/tests.proj b/src/libraries/tests.proj
index 67e553b00fe..c65ae3d5841 100644
--- a/src/libraries/tests.proj
+++ b/src/libraries/tests.proj
@@ -1,12 +1,11 @@
<Project InitialTargets="IncludeProjectReferences">
<Import Sdk="Microsoft.NET.Sdk" Project="Sdk.props" />
+ <Import Project="$(RepositoryEngineeringDir)coverage.props" Condition="'$(EnableCoverageSupport)' == 'true'" />
- <PropertyGroup>
- <EnableFullCoverageReportTarget>true</EnableFullCoverageReportTarget>
- <GenerateFullCoverageReport>true</GenerateFullCoverageReport>
+ <PropertyGroup Condition="'$(EnableCoverageSupport)' == 'true'">
<CoverageReportInputPath>$(ArtifactsBinDir)*.Tests/**/coverage.xml</CoverageReportInputPath>
<CoverageReportDir>$(ArtifactsDir)coverage</CoverageReportDir>
- <SerializeProjects Condition="'$(Coverage)' == 'true'">true</SerializeProjects>
+ <SerializeProjects>true</SerializeProjects>
</PropertyGroup>
<ItemGroup Condition="'$(BuildAllConfigurations)' != 'true'">
@@ -25,10 +24,19 @@
</ItemGroup>
</Target>
+ <Target Name="GenerateCoverageReport"
+ Condition="'$(EnableCoverageSupport)' == 'true' and '$(SkipCoverageReport)' != 'true'"
+ AfterTargets="TestAllProjects"
+ Inputs="$(CoverageReportInputPath)"
+ Outputs="$(CoverageReportResultsPath)">
+ <Exec Command="$(CoverageReportCommandLine)" />
+ </Target>
+
+ <Import Project="$(RepositoryEngineeringDir)coverage.targets" Condition="'$(EnableCoverageSupport)' == 'true'" />
<Import Sdk="Microsoft.NET.Sdk" Project="Sdk.targets" />
<Target Name="Build" DependsOnTargets="BuildAllProjects" />
- <Target Name="BuildAllProjects" DependsOnTargets="$(TraversalBuildDependsOn);FilterProjects">
+ <Target Name="BuildAllProjects" DependsOnTargets="FilterProjects">
<MSBuild Targets="Build"
Projects="@(Project)"
Properties="BuildAllProjects=true;BuildConfiguration=$(BuildConfiguration);%(Project.AdditionalProperties)"
@@ -36,7 +44,7 @@
ContinueOnError="ErrorAndStop" />
<!-- Given we ErrorAndContinue we need to propagate the error if the overall task failed -->
- <Error Condition="'$(MSBuildLastTaskResult)'=='false'" />
+ <Error Condition="'$(MSBuildLastTaskResult)' == 'false'" />
</Target>
<Target Name="Test" DependsOnTargets="TestAllProjects" />
@@ -57,7 +65,7 @@
ContinueOnError="ErrorAndContinue" />
<!-- Given we ErrorAndContinue we need to propagate the error if the overall task failed -->
- <Error Condition="'$(MSBuildLastTaskResult)'=='false'" />
+ <Error Condition="'$(MSBuildLastTaskResult)' == 'false'" />
</Target>
</Project>
diff --git a/tools-local/tasks/installer.tasks/GenerateFileVersionProps.cs b/tools-local/tasks/installer.tasks/GenerateFileVersionProps.cs
index a8cfdb81100..9ded17981d4 100644
--- a/tools-local/tasks/installer.tasks/GenerateFileVersionProps.cs
+++ b/tools-local/tasks/installer.tasks/GenerateFileVersionProps.cs
@@ -17,7 +17,6 @@ namespace Microsoft.DotNet.Build.Tasks
private const string PreferredPackagesProperty = "PackageConflictPreferredPackages";
private static readonly Version ZeroVersion = new Version(0, 0, 0, 0);
-
[Required]
public ITaskItem[] Files { get; set; }
@@ -30,7 +29,6 @@ namespace Microsoft.DotNet.Build.Tasks
[Required]
public string PlatformManifestFile { get; set; }
- [Required]
public string PropsFile { get; set; }
[Required]
@@ -121,13 +119,19 @@ namespace Microsoft.DotNet.Build.Tasks
}
}
- var props = ProjectRootElement.Create();
- var itemGroup = props.AddItemGroup();
- // set the platform manifest when the platform is not being published as part of the app
- itemGroup.Condition = "'$(RuntimeIdentifier)' == '' or '$(SelfContained)' != 'true'";
+ bool generatePropsFile = !string.IsNullOrWhiteSpace(PropsFile);
+ ProjectRootElement props = null;
- var manifestFileName = Path.GetFileName(PlatformManifestFile);
- itemGroup.AddItem(PlatformManifestsItem, $"$(MSBuildThisFileDirectory){manifestFileName}");
+ if (generatePropsFile)
+ {
+ props = ProjectRootElement.Create();
+ var itemGroup = props.AddItemGroup();
+ // set the platform manifest when the platform is not being published as part of the app
+ itemGroup.Condition = "'$(RuntimeIdentifier)' == '' or '$(SelfContained)' != 'true'";
+
+ var manifestFileName = Path.GetFileName(PlatformManifestFile);
+ itemGroup.AddItem(PlatformManifestsItem, $"$(MSBuildThisFileDirectory){manifestFileName}");
+ }
Directory.CreateDirectory(Path.GetDirectoryName(PlatformManifestFile));
using (var manifestWriter = File.CreateText(PlatformManifestFile))
@@ -143,13 +147,16 @@ namespace Microsoft.DotNet.Build.Tasks
}
}
- var propertyGroup = props.AddPropertyGroup();
- propertyGroup.AddProperty(PreferredPackagesProperty, PreferredPackages);
+ if (!string.IsNullOrWhiteSpace(PropsFile))
+ {
+ var propertyGroup = props.AddPropertyGroup();
+ propertyGroup.AddProperty(PreferredPackagesProperty, PreferredPackages);
- var versionPropertyName = $"_{PackageId.Replace(".", "_")}_Version";
- propertyGroup.AddProperty(versionPropertyName, PackageVersion);
+ var versionPropertyName = $"_{PackageId.Replace(".", "_")}_Version";
+ propertyGroup.AddProperty(versionPropertyName, PackageVersion);
- props.Save(PropsFile);
+ props.Save(PropsFile);
+ }
return !Log.HasLoggedErrors;
}
@@ -198,4 +205,4 @@ namespace Microsoft.DotNet.Build.Tasks
public ITaskItem File { get; set; }
}
}
-}
+} \ No newline at end of file
diff --git a/tools-local/tasks/installer.tasks/GenerateRunScript.cs b/tools-local/tasks/installer.tasks/GenerateRunScript.cs
new file mode 100644
index 00000000000..0dd240872a7
--- /dev/null
+++ b/tools-local/tasks/installer.tasks/GenerateRunScript.cs
@@ -0,0 +1,114 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using Microsoft.Build.Framework;
+using Microsoft.Build.Utilities;
+using System;
+using System.IO;
+using System.Text;
+
+namespace Microsoft.DotNet.Build.Tasks
+{
+ public class GenerateRunScript : Task
+ {
+ [Required]
+ public string[] RunCommands { get; set; }
+
+ [Required]
+ public string TemplatePath { get; set; }
+
+ [Required]
+ public string OutputPath { get; set; }
+
+ public override bool Execute()
+ {
+ if (RunCommands.Length == 0)
+ {
+ Log.LogError("Please provide at least one test command to execute via the RunCommands property.");
+ return false;
+ }
+
+ if (!File.Exists(TemplatePath))
+ {
+ Log.LogError($"Runner script template {TemplatePath} was not found.");
+ return false;
+ }
+
+ string templateContent = File.ReadAllText(TemplatePath);
+ Directory.CreateDirectory(Path.GetDirectoryName(OutputPath));
+
+ Log.LogMessage($"Run commands = {string.Join(Environment.NewLine, RunCommands)}");
+
+ string extension = Path.GetExtension(Path.GetFileName(OutputPath)).ToLowerInvariant();
+ switch (extension)
+ {
+ case ".sh":
+ case ".cmd":
+ case ".bat":
+ WriteRunScript(templateContent, extension);
+ break;
+ default:
+ Log.LogError($"Generating runner scripts with extension '{extension}' is not supported.");
+ return false;
+ }
+
+ return true;
+ }
+
+ private void WriteRunScript(string templateContent, string extension)
+ {
+ bool isUnix = extension == ".sh";
+ string lineFeed = isUnix ? "\n" : "\r\n";
+
+ var runCommandsBuilder = new StringBuilder();
+ for (int i = 0; i < RunCommands.Length; i++)
+ {
+ runCommandsBuilder.Append(RunCommands[i]);
+ if (i < RunCommands.Length - 1)
+ {
+ runCommandsBuilder.Append(lineFeed);
+ }
+ }
+ templateContent = templateContent.Replace("[[RunCommands]]", runCommandsBuilder.ToString());
+
+ var runCommandEchoesBuilder = new StringBuilder();
+ foreach (string runCommand in RunCommands)
+ {
+ // Escape backtick and question mark characters to avoid running commands instead of echo'ing them.
+ string sanitizedRunCommand = runCommand.Replace("`", "\\`")
+ .Replace("?", "\\")
+ .Replace("\r","")
+ .Replace("\n"," ")
+ .Replace("&", "^&")
+ .Replace(">", "^>");
+
+ if (isUnix)
+ {
+ // Remove parentheses and quotes from echo command before wrapping it in quotes to avoid errors on Linux.
+ sanitizedRunCommand = "\"" + sanitizedRunCommand.Replace("\"", "")
+ .Replace("(", "")
+ .Replace(")", "") + "\"";
+ }
+
+ runCommandEchoesBuilder.Append($"echo {sanitizedRunCommand}{lineFeed}");
+ }
+ templateContent = templateContent.Replace("[[RunCommandsEcho]]", runCommandEchoesBuilder.ToString());
+
+ if (isUnix)
+ {
+ // Just in case any Windows EOLs have made it in by here, clean any up.
+ templateContent = templateContent.Replace("\r\n", "\n");
+ }
+
+ using (StreamWriter sw = new StreamWriter(new FileStream(OutputPath, FileMode.Create)))
+ {
+ sw.NewLine = lineFeed;
+ sw.Write(templateContent);
+ sw.WriteLine();
+ }
+
+ Log.LogMessage($"Wrote {extension} run script to {OutputPath}");
+ }
+ }
+} \ No newline at end of file
diff --git a/tools-local/tasks/installer.tasks/GenerateTestSharedFrameworkDepsFile.cs b/tools-local/tasks/installer.tasks/GenerateTestSharedFrameworkDepsFile.cs
new file mode 100644
index 00000000000..0048a463dc3
--- /dev/null
+++ b/tools-local/tasks/installer.tasks/GenerateTestSharedFrameworkDepsFile.cs
@@ -0,0 +1,132 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using Microsoft.Build.Framework;
+using System;
+using System.IO;
+using System.Linq;
+using System.Reflection.Metadata;
+using System.Reflection.PortableExecutable;
+using Microsoft.Extensions.DependencyModel;
+using System.Collections.Generic;
+using NuGet.RuntimeModel;
+
+namespace Microsoft.DotNet.Build.Tasks
+{
+ public partial class GenerateTestSharedFrameworkDepsFile : BuildTask
+ {
+ // we don't care about these values in the deps file
+ const string rid = "rid";
+ const string tfm = "netcoreapp0.0";
+ const string fullTfm = ".NETCoreApp,Version=v0.0";
+
+ [Required]
+ public string SharedFrameworkDirectory { get; set; }
+
+ [Required]
+ public string[] RuntimeGraphFiles { get; set; }
+
+ [Required]
+ public string TargetRuntimeIdentifier { get; set; }
+
+ public override bool Execute()
+ {
+ var sharedFxDir = new DirectoryInfo(SharedFrameworkDirectory);
+ if (!sharedFxDir.Exists)
+ {
+ Log.LogError($"{nameof(SharedFrameworkDirectory)} '{SharedFrameworkDirectory}' does not exist.");
+ return false;
+ }
+
+ // directory is the version folder, parent is the shared framework name.
+ string sharedFxVersion = sharedFxDir.Name;
+ string sharedFxName = sharedFxDir.Parent.Name;
+
+ var ignoredExtensions = new HashSet<string>(StringComparer.OrdinalIgnoreCase)
+ {
+ ".pdb",
+ ".json",
+ ".config",
+ ".xml"
+ };
+
+ var isAssemblyTofileNames = Directory.EnumerateFiles(SharedFrameworkDirectory)
+ .Where(file => !ignoredExtensions.Contains(Path.GetExtension(file)))
+ .ToLookup(file => IsManagedAssembly(file), file => Path.GetFileName(file));
+
+ var managedFileNames = isAssemblyTofileNames[true];
+ var nativeFileNames = isAssemblyTofileNames[false];
+
+ var runtimeLibraries = new[]
+ {
+ new RuntimeLibrary(
+ type:"package",
+ name: sharedFxName,
+ version: sharedFxVersion,
+ hash: "hash",
+ runtimeAssemblyGroups: new[] { new RuntimeAssetGroup(string.Empty, managedFileNames.Select(f => $"runtimes/{rid}/lib/{tfm}/{f}")) },
+ nativeLibraryGroups: new[] { new RuntimeAssetGroup(string.Empty, nativeFileNames.Select(f => $"runtimes/{rid}/native/{f}")) },
+ resourceAssemblies: Enumerable.Empty<ResourceAssembly>(),
+ dependencies: Enumerable.Empty<Dependency>(),
+ serviceable: true)
+ };
+
+ var targetInfo = new TargetInfo(fullTfm, rid, "runtimeSignature", isPortable: false);
+
+ var runtimeFallbacks = GetRuntimeFallbacks(RuntimeGraphFiles, TargetRuntimeIdentifier);
+
+ var dependencyContext = new DependencyContext(
+ targetInfo,
+ CompilationOptions.Default,
+ Enumerable.Empty<CompilationLibrary>(),
+ runtimeLibraries,
+ runtimeFallbacks);
+
+ using (var depsFileStream = File.Create(Path.Combine(SharedFrameworkDirectory, $"{sharedFxName}.deps.json")))
+ {
+ new DependencyContextWriter().Write(dependencyContext, depsFileStream);
+ }
+
+ return !Log.HasLoggedErrors;
+ }
+
+ private static bool IsManagedAssembly(string file)
+ {
+ bool result = false;
+ try
+ {
+ using (var peReader = new PEReader(File.OpenRead(file)))
+ {
+ result = peReader.HasMetadata && peReader.GetMetadataReader().IsAssembly;
+ }
+ }
+ catch (BadImageFormatException)
+ { }
+
+ return result;
+ }
+
+ private static IEnumerable<RuntimeFallbacks> GetRuntimeFallbacks(string[] runtimeGraphFiles, string runtime)
+ {
+ RuntimeGraph runtimeGraph = RuntimeGraph.Empty;
+
+ foreach (string runtimeGraphFile in runtimeGraphFiles)
+ {
+ runtimeGraph = RuntimeGraph.Merge(runtimeGraph, JsonRuntimeFormat.ReadRuntimeGraph(runtimeGraphFile));
+ }
+
+ foreach (string rid in runtimeGraph.Runtimes.Select(p => p.Key))
+ {
+ IEnumerable<string> ridFallback = runtimeGraph.ExpandRuntime(rid);
+
+ if (ridFallback.Contains(runtime))
+ {
+ // ExpandRuntime return runtime itself as first item so we are skiping it
+ yield return new RuntimeFallbacks(rid, ridFallback.Skip(1));
+ }
+ }
+ }
+
+ }
+}
diff --git a/tools-local/tasks/installer.tasks/installer.tasks.csproj b/tools-local/tasks/installer.tasks/installer.tasks.csproj
index a955c7dc605..0c73fdc843a 100644
--- a/tools-local/tasks/installer.tasks/installer.tasks.csproj
+++ b/tools-local/tasks/installer.tasks/installer.tasks.csproj
@@ -1,14 +1,12 @@
-<Project Sdk="Microsoft.NET.Sdk">
+<Project Sdk="Microsoft.NET.Sdk" TreatAsLocalProperty="Configuration;Debug">
<PropertyGroup>
<TargetFrameworks>netstandard2.0</TargetFrameworks>
<TargetFrameworks Condition="'$(OS)' == 'Windows_NT'">$(TargetFrameworks);net46</TargetFrameworks>
<EnableDefaultCompileItems>false</EnableDefaultCompileItems>
- <!-- Duplicating the assembly path here as CoreClr current overrides the Configuration property. -->
- <InstallerTasksAssemblyPath Condition="'$(MSBuildRuntimeType)' == 'Core'">$(IntermediateOutputPath)netstandard2.0\installer.tasks.dll</InstallerTasksAssemblyPath>
- <InstallerTasksAssemblyPath Condition="'$(MSBuildRuntimeType)' != 'Core'">$(IntermediateOutputPath)net46\installer.tasks.dll</InstallerTasksAssemblyPath>
<!-- Set platform to AnyCPU (not TargetArchitecture) to avoid arch-specific output path. -->
<Platform>AnyCPU</Platform>
+ <Configuration>Debug</Configuration>
</PropertyGroup>
<ItemGroup>
@@ -17,30 +15,37 @@
</ItemGroup>
<ItemGroup>
- <PackageReference Include="NuGet.ProjectModel" Version="$(RefOnlyNugetProjectModelVersion)" />
<PackageReference Include="Microsoft.Extensions.DependencyModel" Version="$(MicrosoftExtensionsDependencyModelVersion)" />
<PackageReference Include="Microsoft.DotNet.PlatformAbstractions" Version="2.1.0" />
+ <PackageReference Include="NuGet.ProjectModel" Version="$(RefOnlyNugetProjectModelVersion)" />
+ <PackageReference Include="NuGet.Packaging" Version="$(RefOnlyNugetPackagingVersion)" />
+ <PackageReference Include="System.Reflection.Metadata" Version="1.7.0" />
</ItemGroup>
- <ItemGroup Condition="'$(TargetFramework)' != 'net46'">
- <PackageReference Include="Microsoft.Build" Version="$(RefOnlyMicrosoftBuildVersion)" />
- <PackageReference Include="Microsoft.Build.Framework" Version="$(RefOnlyMicrosoftBuildFrameworkVersion)" />
- <PackageReference Include="Microsoft.Build.Tasks.Core" Version="$(RefOnlyMicrosoftBuildTasksCoreVersion)" />
- <PackageReference Include="Microsoft.Build.Utilities.Core" Version="$(RefOnlyMicrosoftBuildUtilitiesCoreVersion)" />
-
- <PackageReference Include="System.Diagnostics.FileVersionInfo" Version="4.0.0" />
- </ItemGroup>
-
- <ItemGroup Condition="'$(TargetFramework)' == 'net46'">
- <Compile Include="net46/ProcessSharedFrameworkDeps.net46.cs" />
-
- <Reference Include="Microsoft.Build.Framework" />
- <Reference Include="Microsoft.Build.Tasks.v4.0" />
- <Reference Include="Microsoft.Build.Utilities.v4.0" />
- <Reference Include="Microsoft.Build" />
- <Reference Include="System.IO.Compression.FileSystem" />
- <Reference Include="System.IO.Compression" />
- </ItemGroup>
+ <Choose>
+ <When Condition="'$(TargetFrameworkIdentifier)' == '.NETFramework'">
+ <ItemGroup>
+ <Compile Include="net46/ProcessSharedFrameworkDeps.net46.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <Reference Include="Microsoft.Build.Framework" />
+ <Reference Include="Microsoft.Build.Tasks.v4.0" />
+ <Reference Include="Microsoft.Build.Utilities.v4.0" />
+ <Reference Include="Microsoft.Build" />
+ <Reference Include="System.IO.Compression.FileSystem" />
+ <Reference Include="System.IO.Compression" />
+ </ItemGroup>
+ </When>
+ <Otherwise>
+ <ItemGroup>
+ <PackageReference Include="Microsoft.Build" Version="$(RefOnlyMicrosoftBuildVersion)" />
+ <PackageReference Include="Microsoft.Build.Framework" Version="$(RefOnlyMicrosoftBuildFrameworkVersion)" />
+ <PackageReference Include="Microsoft.Build.Tasks.Core" Version="$(RefOnlyMicrosoftBuildTasksCoreVersion)" />
+ <PackageReference Include="Microsoft.Build.Utilities.Core" Version="$(RefOnlyMicrosoftBuildUtilitiesCoreVersion)" />
+ <PackageReference Include="System.Diagnostics.FileVersionInfo" Version="4.0.0" />
+ </ItemGroup>
+ </Otherwise>
+ </Choose>
<UsingTask TaskName="GetTargetMachineInfo"
AssemblyFile="$(InstallerTasksAssemblyPath)" />