From 97959787fea8274ebd8646069f8b8977a58ac5d8 Mon Sep 17 00:00:00 2001 From: Gleb Balykov Date: Mon, 12 Apr 2021 23:13:24 +0300 Subject: [PATCH] [Tizen] Add support for gbs build for i586, x86_64, armv7l, armv7hl, aarch64 (including tests) --- RunTests.sh | 54 ++ eng/build.sh | 6 + packaging/coreclr-rpmlintrc | 2 + packaging/coreclr.manifest | 5 + packaging/coreclr.spec | 689 ++++++++++++++ runtest_clr.sh | 1006 ++++++++++++++++++++ runtest_fx.sh | 387 ++++++++ src/tests/Common/CLRTest.CrossGen.targets | 268 ++---- .../TieredCompilation/BasicTestWithMcj.csproj | 2 +- src/tests/build.proj | 2 +- .../readytorun/coreroot_determinism/Program.cs | 5 +- .../determinism/crossgen2determinism.csproj | 4 +- .../readytorun/multifolder/multifolder.csproj | 4 +- src/tests/readytorun/tests/mainv1.csproj | 6 +- src/tests/readytorun/tests/mainv2.csproj | 6 +- 15 files changed, 2231 insertions(+), 215 deletions(-) create mode 100644 RunTests.sh create mode 100644 packaging/coreclr-rpmlintrc create mode 100644 packaging/coreclr.manifest create mode 100755 packaging/coreclr.spec create mode 100755 runtest_clr.sh create mode 100755 runtest_fx.sh diff --git a/RunTests.sh b/RunTests.sh new file mode 100644 index 0000000..da93618 --- /dev/null +++ b/RunTests.sh @@ -0,0 +1,54 @@ +#!/usr/bin/env bash + +coreOverlayDir=$1 +outerloop=$2 +outxml=$3 +tmpDir=$4 + +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]="SIGBUS 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." + +if [ "$coreOverlayDir" == "" ] || [ "$outerloop" == "" ] || [ "$outxml" == "" ] || [ "$tmpDir" == "" ] +then + echo "Usage: $0 coreOverlayDir outerloop outxml tmpdir" + exit -1 +fi + +ulimit -c unlimited + +outerloopCmd="" + +if [ "$outerloop" == "on" ] +then + outerloopCmd="-trait category=OuterLoop" +else + outerloopCmd="-notrait category=OuterLoop" +fi + +cmd="$coreOverlayDir/corerun xunit.console.dll TEST_NAME_DLL -xml $outxml -nologo -notrait category=nonnetcoreapptests -notrait category=nonlinuxtests -notrait category=failing $outerloopCmd" + +echo Start time TEST_NAME_DLL: $(date +"%T") +echo "TMPDIR=$tmpDir $cmd" +echo "================" + +TMPDIR=$tmpDir $cmd +test_exitcode=$? + +echo "================" +echo End time TEST_NAME_DLL: $(date +"%T") + +if [ "${exitcode_list[$test_exitcode]}" != "" ]; then + echo exit code $test_exitcode means ${exitcode_list[$test_exitcode]} +fi + +exit $test_exitcode diff --git a/eng/build.sh b/eng/build.sh index 8836bde..65a7830 100755 --- a/eng/build.sh +++ b/eng/build.sh @@ -79,6 +79,7 @@ usage() echo " --keepnativesymbols Optional argument: set to true to keep native symbols/debuginfo in generated binaries." echo " --ninja Optional argument: set to true to use Ninja instead of Make to run the native build." echo " --pgoinstrument Optional argument: build PGO-instrumented runtime" + echo " --nopgooptimize Optional argument: build without PGO optimization" echo "" echo "Command line arguments starting with '/p:' are passed through to MSBuild." @@ -450,6 +451,11 @@ while [[ $# > 0 ]]; do shift 1 ;; + -nopgooptimize) + arguments="$arguments /p:NoPgoOptimize=true" + shift 1 + ;; + *) extraargs="$extraargs $1" shift 1 diff --git a/packaging/coreclr-rpmlintrc b/packaging/coreclr-rpmlintrc new file mode 100644 index 0000000..edcdd8e --- /dev/null +++ b/packaging/coreclr-rpmlintrc @@ -0,0 +1,2 @@ +# This package should install an ELF binary in the /usr/share hierarchy. +addFilter("E: arch-dependent-file-in-usr-share") diff --git a/packaging/coreclr.manifest b/packaging/coreclr.manifest new file mode 100644 index 0000000..017d22d --- /dev/null +++ b/packaging/coreclr.manifest @@ -0,0 +1,5 @@ + + + + + diff --git a/packaging/coreclr.spec b/packaging/coreclr.spec new file mode 100755 index 0000000..d7f5e44 --- /dev/null +++ b/packaging/coreclr.spec @@ -0,0 +1,689 @@ +%{!?dotnet_buildtype: %define dotnet_buildtype Release} +%{!?skiptests: %define skiptests 1} + +%define dotnet_buildtype_clr %{dotnet_buildtype} +%define dotnet_buildtype_fx %{dotnet_buildtype} + +%if "%{?dotnet_buildtype}" == "Checked" + %define dotnet_buildtype_fx Debug +%endif + +%define _binaries_in_noarch_packages_terminate_build 0 +%define _unpackaged_files_terminate_build 0 + +%define skipmscorlib 0 +%define skipmanaged 0 +%define skipmanagedtools 0 + +%ifarch %{ix86} +%define skipmanagedtools 1 +%endif + +%ifarch %{arm} aarch64 %{ix86} x86_64 +%else +%define skiptests 1 +%endif + +%define pgo_instrument 0 +%define pgo_optimize 0 + +%define dotnet_version 6.0.0 + +Name: coreclr +Version: 6.0.0 +Release: 0 +Summary: Microsoft .NET Runtime with Microsoft .NET foundation class libraries (CoreCLR and CoreFX) +Group: Development/Languages +License: MIT +URL: http://github.com/dotnet/runtime +Source0: %{name}-%{version}.tar.gz +Source1: %{name}.manifest + +BuildRequires: python +BuildRequires: python-xml +# libcoreclr.so +BuildRequires: pkgconfig(libunwind) +BuildRequires: pkgconfig(uuid) +# System.Globalization.Native.so +BuildRequires: libicu-devel +BuildRequires: tizen-release +# System.Net.Security.Native.so +# System.Net.Http.Native.so +BuildRequires: krb5-devel +BuildRequires: libcurl-devel +# No matter what tizen-release package you use in any profile +AutoReq: 0 +Requires: glibc +Requires: libgcc +Requires: libstdc++ +Requires: libunwind +Requires: libuuid + +# Accelerate python, clang +%ifarch armv7l +BuildRequires: python-accel-armv7l-cross-arm +BuildRequires: clang-accel-armv7l-cross-arm +%endif + +%ifarch armv7hl +BuildRequires: python-accel-armv7hl-cross-arm +BuildRequires: clang-accel-armv7hl-cross-arm +%endif + +%ifarch aarch64 +BuildRequires: python-accel-aarch64-cross-aarch64 +BuildRequires: clang-accel-aarch64-cross-aarch64 +%endif + +BuildRequires: cmake +BuildRequires: llvm >= 3.8 +BuildRequires: llvm-devel >= 3.8 +BuildRequires: clang >= 3.8 +BuildRequires: clang-devel >= 3.8 +BuildRequires: lldb >= 3.8 +BuildRequires: lldb-devel >= 3.8 +BuildRequires: gettext-tools +BuildRequires: libopenssl1.1-devel +# C include headers +BuildRequires: libstdc++-devel +BuildRequires: pkgconfig(lttng-ust) + +BuildRequires: libatomic +BuildRequires: gcc-devel-static + +%if 0%{skipmscorlib} && 0%{skipmanaged} && 0%{skipmanagedtools} +%else +%ifarch %{arm} aarch64 +BuildRequires: patchelf +%endif +%ifarch %{ix86} +BuildRequires: patchelf +BuildRequires: glibc-64bit +BuildRequires: libgcc-64bit +BuildRequires: libstdc++-64bit +BuildRequires: libunwind-64bit +BuildRequires: libuuid-64bit +BuildRequires: zlib-64bit +BuildRequires: libopenssl11-64bit +%endif +%endif + +%if 0%{pgo_instrument} || 0%{pgo_optimize} +BuildRequires: binutils-gold +BuildRequires: compiler-rt +%endif + +%description +The CoreCLR repo contains the complete runtime implementation for .NET Core. It includes RyuJIT, the .NET GC, native interop and many other components. It is cross-platform, with multiple OS and CPU ports in progress. The .NET Core foundational libraries, called CoreFX. It includes classes for collections, file systems, console, XML, async and many others. + +%package -n coreclr-test +Summary: Dotnet Core Unit Test +Requires: coreclr + +%description -n coreclr-test +Unit Test objs + +%package -n coreclr-devel +Summary: Dotnet Core Development package +Requires: coreclr + +%description -n coreclr-devel +Headers and static libraries + +%package -n mscorlib +Summary: Core Library for MS .NET +Requires: coreclr + +%description -n mscorlib +The System.Private.CoreLib.dll for .NET Core Runtime (coreclr) + +%package -n corefx-native +Summary: Core foundational native libraries +Requires: coreclr +Requires: mscorlib + +%description -n corefx-native +The native part (.so) of dotnet core foundational libraries + +%package -n corefx-managed +Summary: Core foundational managed libraries +Requires: coreclr +Requires: mscorlib +Requires: corefx-native +BuildArch: noarch +AutoReqProv: no + +%description -n corefx-managed +The managed part (.dll) of dotnet core foundational class libraries + +%package -n corefx-managed-devel +Summary: Core foundational managed libraries for debugging (.pdb) +Requires: corefx-managed +BuildArch: noarch +AutoReqProv: no + +%description -n corefx-managed-devel +The managed debugging files (.pdb) of dotnet core fundational class libraries + +%package -n corefx-managed-ref +Summary: Core foundational managed class libraries for developer +BuildArch: noarch +AutoReqProv: no + +%description -n corefx-managed-ref +The managed part (.dll) of dotnet core foundational class libraries for developer + +%ifarch x86_64 +%package -n corefx-test +Summary: Dotnet Libraries Unit Test +Requires: corefx-native +Requires: corefx-managed +BuildArch: noarch +AutoReqProv: no + +%description -n corefx-test +Unit Test objs +%endif + +%package -n corefx-test-native +Summary: Dotnet Libraries Unit Test, native part +Requires: corefx-native +Requires: corefx-managed + +%description -n corefx-test-native +Unit Test objs, native part + +%prep +%setup -q -n %{name}-%{version} +cp %{SOURCE1} . + +%if 0%{skipmscorlib} && 0%{skipmanaged} && 0%{skipmanagedtools} +%else +%ifarch %{arm} aarch64 +# Detect interpreter name from cross-gcc +LD_INTERPRETER=$(patchelf --print-interpreter /emul/usr/bin/gcc) +LD_RPATH=$(patchelf --print-rpath /emul/usr/bin/gcc) +for file in $( find ./.dotnet ./.packages -name "dotnet" -type f -o -name "ilasm" -type f) +do + patchelf --set-interpreter ${LD_INTERPRETER} ${file} + patchelf --set-rpath ${LD_RPATH}:%{_builddir}/%{name}-%{version}/libicu-57.1/ ${file} +done +for file in $( find ./.dotnet ./.packages ./libicu-57.1 -iname "*.so" -or -iname "*.so.*" ) +do + patchelf --set-rpath ${LD_RPATH}:%{_builddir}/%{name}-%{version}/libicu-57.1/ ${file} +done +%endif + +%ifarch %{ix86} +for file in $( find ./.dotnet ./.packages ./libicu-57.1 -iname "*.so" -or -iname "*.so.*" ) +do + patchelf --set-rpath %{_builddir}/%{name}-%{version}/libicu-57.1/ ${file} +done +%endif +%endif + +%build +# disable asan build when global forced asan build +%{?asan: +export ASAN_OPTIONS=use_sigaltstack=false:`cat /ASAN_OPTIONS` +/usr/bin/gcc-unforce-options +export LD_LIBRARY_PATH=`pwd`/libicu-57.1 +export CPPFLAGS+=" -DHAS_ADDRESS_SANITIZER " +} + +BASE_FLAGS=" --target=%{_host} " + + + +%ifarch x86_64 +# Even though build architectur is x86_64, it will be running on arm board. +# So we need to pass the arch argument as arm. +%define _barch %{?cross:%{cross}}%{!?cross:x64} +%endif + +%ifarch aarch64 +%define _barch arm64 +%endif + +%ifarch %{ix86} +%define _barch x86 +export CLANG_NO_LIBDIR_SUFFIX=1 +BASE_FLAGS="$(echo $BASE_FLAGS | sed -e 's/--target=i686/--target=i586/')" +BASE_FLAGS="$BASE_FLAGS -mstackrealign" +%endif + +%ifarch armv7l +%define _barch armel +export CLANG_NO_LIBDIR_SUFFIX=1 +%endif + +%ifarch armv7hl +%define _barch arm +export CLANG_NO_LIBDIR_SUFFIX=1 +%endif + +%ifarch %{arm} +%define _tarch arm +%endif +%ifarch aarch64 +%define _tarch arm64 +%endif +%ifarch %{ix86} +%define _tarch x86 +%endif +%ifarch x86_64 +%define _tarch x64 +%endif + +%define _reldir_clr artifacts/bin/coreclr/Linux.%{_barch}.%{dotnet_buildtype_clr} +%define _reldir_fx_native artifacts/bin/native/net6.0-Linux-%{dotnet_buildtype_fx}-%{_barch} +%define _reldir_fx_managed artifacts/bin/microsoft.netcore.app.runtime.linux-%{_barch}/%{dotnet_buildtype_fx}/runtimes/linux-%{_barch}/lib/net6.0/ +%define _reldir_fx_withoob artifacts/bin/runtime/net6.0-Linux-%{dotnet_buildtype_fx}-%{_barch} + +export CFLAGS="${BASE_FLAGS}" +export CXXFLAGS="${BASE_FLAGS}" +export ASMFLAGS="${BASE_FLAGS}" + +%ifarch %{arm} +%if %{dotnet_buildtype} == "Release" +export CXXFLAGS+="-fstack-protector-strong -D_FORTIFY_SOURCE=2" +%else +export CXXFLAGS+="-fstack-protector-strong" +%endif +%endif + +%if 0%{pgo_instrument} +%define _pgo_flags --pgoinstrument +%else +%if 0%{pgo_optimize} +# pgo optimization is enabled by default +%define _pgo_flags "" +%else +%define _pgo_flags --nopgooptimize +%endif +%endif + +%define _source_version_flags /p:EnableSourceLink=false /p:DisableSourceLink=true /p:EnableSourceControlManagerQueries=false /p:EmbedUntrackedSources=false +%define _build_args --keepnativesymbols true --arch %{_barch} --runtimeConfiguration %{dotnet_buildtype_clr} --librariesConfiguration %{dotnet_buildtype_fx} %{_source_version_flags} +%define _build_args_release --keepnativesymbols true --arch %{_barch} --runtimeConfiguration Release --librariesConfiguration Release %{_source_version_flags} + +export NUGET_PACKAGES=%{_builddir}/%{name}-%{version}/.packages/ +export LD_LIBRARY_PATH=%{_builddir}/%{name}-%{version}/libicu-57.1/ + +# Build native CoreCLR and native CoreFX +./build.sh --portablebuild false %{_build_args} --subset clr.runtime+clr.jit+clr.iltools+libs.native --cmakeargs -DFEATURE_IBCLOGGER=true --cmakeargs -DFEATURE_ENABLE_NO_ADDRESS_SPACE_RANDOMIZATION=true --cmakeargs -DCLR_ADDITIONAL_LINKER_FLAGS=-Wl,-z,relro %{_pgo_flags} + +%if 0%{skipmscorlib} +%else +# Build mscorlib (System.Private.CoreLib.dll) +./build.sh --portablebuild false %{_build_args} --subset clr.corelib +%endif + +%if 0%{skipmanaged} +%else +# Build managed CoreFX +./build.sh %{_build_args} --subset libs.ref+libs.src+libs.packages + +%if 0%{skipmanagedtools} +%else +# Build managed tools +./build.sh %{_build_args} --subset clr.tools +%endif + +%ifarch x86_64 +# Build CoreFX managed tests, which are reused for all arches +./build.sh %{_build_args} --subset libs.pretest+libs.tests --testscope all /p:DisableImplicitFSharpCoreReference=true +%endif +%endif + +%if 0%{skiptests} +%else +# Build CoreCLR tests + +%if %{dotnet_buildtype} != "Release" +# Build Release CoreCLR & CoreFX (these are required for some tests) + +# Build native CoreCLR and native CoreFX +./build.sh --portablebuild false %{_build_args_release} --subset clr.runtime+clr.jit+clr.iltools+libs.native --cmakeargs -DFEATURE_IBCLOGGER=true --cmakeargs -DFEATURE_ENABLE_NO_ADDRESS_SPACE_RANDOMIZATION=true --cmakeargs -DCLR_ADDITIONAL_LINKER_FLAGS=-Wl,-z,relro %{_pgo_flags} + +# Build mscorlib (System.Private.CoreLib.dll) +./build.sh --portablebuild false %{_build_args_release} --subset clr.corelib + +# Build managed CoreFX +./build.sh %{_build_args_release} --subset libs.ref+libs.src+libs.packages /p:UseSharedCompilation=false +%endif + +# Build native part of tests as non-portable (i.e. for Tizen) +./src/tests/build.sh -%{dotnet_buildtype_clr} portablebuild=false -%{_barch} -priority1 skipgenerateversion skipmanaged skipgeneratelayout skiprestorepackages /p:__SkipPackageRestore=true + +# Build managed part of tests +./src/tests/build.sh -%{dotnet_buildtype_clr} -%{_barch} -priority1 skipgenerateversion copynativeonly skiprestorepackages /p:__SkipPackageRestore=true +./src/tests/build.sh -%{dotnet_buildtype_clr} -%{_barch} -priority1 skipgenerateversion skipnative skipgeneratelayout skiptestwrappers /p:DisableImplicitFSharpCoreReference=true +./src/tests/build.sh -%{dotnet_buildtype_clr} -%{_barch} -priority1 skipgenerateversion generatelayoutonly skiprestorepackages /p:__SkipPackageRestore=true +%endif + +%install +# .NET Core Runtime dir +%define dotnetdir dotnet +%define netshareddir %{dotnetdir}/shared +%define netcoreappdir %{netshareddir}/Microsoft.NETCore.App/%{dotnet_version} +mkdir -p %{buildroot}%{_datadir}/%{netcoreappdir} + +# Test dirs +%define clrtestdir /opt/usr/coreclr-tc +%define fxtestdir /opt/usr/corefx-tc +mkdir -p %{buildroot}/%{clrtestdir} +mkdir -p %{buildroot}/%{fxtestdir} +mkdir -p %{buildroot}/%{fxtestdir}/coreroot + +# .NET Tizen Runtime dir +%define dotnettizendir dotnet.tizen +%define dotnetfwdir %{dotnettizendir}/framework +mkdir -p %{buildroot}%{_datadir}/%{dotnettizendir} +mkdir -p %{buildroot}%{_datadir}/%{dotnetfwdir} +ln -sf %{_datadir}/%{netcoreappdir} %{buildroot}%{_datadir}/%{dotnettizendir}/netcoreapp + +# symlink to .NET version for compatibility +ln -sf %{dotnet_version} %{buildroot}%{_datadir}/%{netshareddir}/Microsoft.NETCore.App/2.0.0 +ln -sf %{dotnet_version} %{buildroot}%{_datadir}/%{netshareddir}/Microsoft.NETCore.App/2.1.0 +ln -sf %{dotnet_version} %{buildroot}%{_datadir}/%{netshareddir}/Microsoft.NETCore.App/2.1.1 +ln -sf %{dotnet_version} %{buildroot}%{_datadir}/%{netshareddir}/Microsoft.NETCore.App/2.1.4 +ln -sf %{dotnet_version} %{buildroot}%{_datadir}/%{netshareddir}/Microsoft.NETCore.App/3.0.0 +ln -sf %{dotnet_version} %{buildroot}%{_datadir}/%{netshareddir}/Microsoft.NETCore.App/3.1.3 + +# CoreCLR native +cp %{_reldir_clr}/corerun %{buildroot}%{_datadir}/%{netcoreappdir} +cp %{_reldir_clr}/libclrjit.so %{buildroot}%{_datadir}/%{netcoreappdir} +cp %{_reldir_clr}/libclrgc.so %{buildroot}%{_datadir}/%{netcoreappdir} +cp %{_reldir_clr}/libcoreclr.so %{buildroot}%{_datadir}/%{netcoreappdir} +cp %{_reldir_clr}/libdbgshim.so %{buildroot}%{_datadir}/%{netcoreappdir} +cp %{_reldir_clr}/libmscordaccore.so %{buildroot}%{_datadir}/%{netcoreappdir} +cp %{_reldir_clr}/libmscordbi.so %{buildroot}%{_datadir}/%{netcoreappdir} +cp %{_reldir_clr}/libcoreclrtraceptprovider.so %{buildroot}%{_datadir}/%{netcoreappdir} +cp %{_reldir_clr}/libjitinterface_%{_tarch}.so %{buildroot}%{_datadir}/%{netcoreappdir} +cp %{_reldir_clr}/ilasm %{buildroot}%{_datadir}/%{netcoreappdir} +cp %{_reldir_clr}/ildasm %{buildroot}%{_datadir}/%{netcoreappdir} + +# CoreFX native +cp %{_reldir_fx_native}/libSystem.Globalization.Native.so %{buildroot}%{_datadir}/%{netcoreappdir} +cp %{_reldir_fx_native}/libSystem.IO.Compression.Native.so %{buildroot}%{_datadir}/%{netcoreappdir} +cp %{_reldir_fx_native}/libSystem.Native.so %{buildroot}%{_datadir}/%{netcoreappdir} +cp %{_reldir_fx_native}/libSystem.Net.Security.Native.so %{buildroot}%{_datadir}/%{netcoreappdir} +cp %{_reldir_fx_native}/libSystem.Security.Cryptography.Native.OpenSsl.so %{buildroot}%{_datadir}/%{netcoreappdir} + +# CoreFX native test +cp %{_reldir_fx_native}/libSystem.IO.Ports.Native.so %{buildroot}/%{fxtestdir}/coreroot + +# .NET Core Headers and static libraries +mkdir -p %{buildroot}%{_datadir}/%{netcoreappdir}/src/pal/src/ +mkdir -p %{buildroot}%{_datadir}/%{netcoreappdir}/src/debug/ +mkdir -p %{buildroot}%{_datadir}/%{netcoreappdir}/src/dlls/ +mkdir -p %{buildroot}%{_datadir}/%{netcoreappdir}/src/coreclr/hosts/ +cp -rf src/coreclr/inc %{buildroot}%{_datadir}/%{netcoreappdir}/src/ +cp -rf src/coreclr/pal/inc %{buildroot}%{_datadir}/%{netcoreappdir}/src/pal/ +cp -rf src/coreclr/pal/prebuilt %{buildroot}%{_datadir}/%{netcoreappdir}/src/pal/ +cp -rf src/coreclr/debug/inc %{buildroot}%{_datadir}/%{netcoreappdir}/src/debug/ +cp -rf src/coreclr/debug/shim %{buildroot}%{_datadir}/%{netcoreappdir}/src/debug/ +cp -rf src/coreclr/dlls/dbgshim %{buildroot}%{_datadir}/%{netcoreappdir}/src/dlls/ +cp -rf src/coreclr/hosts/inc %{buildroot}%{_datadir}/%{netcoreappdir}/src/coreclr/hosts/ +cp -rf src/coreclr/pal/src/include %{buildroot}%{_datadir}/%{netcoreappdir}/src/pal/src +cp -rf %{_reldir_clr}/lib %{buildroot}%{_datadir}/%{netcoreappdir} + +# System.Private.CoreLib.dll +%if 0%{skipmscorlib} +%else +cp %{_reldir_clr}/IL/System.Private.CoreLib.dll %{buildroot}%{_datadir}/%{netcoreappdir} +cp %{_reldir_clr}/IL/System.Private.CoreLib.pdb %{buildroot}%{_datadir}/%{netcoreappdir} +%endif + +# Managed tools and managed CoreFX +%if 0%{skipmanaged} +%else + +%if 0%{skipmanagedtools} +%else +cp %{_reldir_clr}/createdump %{buildroot}%{_datadir}/%{netcoreappdir} + +# Managed crossgen2 +mkdir -p %{buildroot}%{_datadir}/%{netcoreappdir}/crossgen2 +cp %{_reldir_clr}/crossgen2/crossgen2.dll %{buildroot}%{_datadir}/%{netcoreappdir}/crossgen2 +cp %{_reldir_clr}/crossgen2/ILCompiler.Diagnostics.dll %{buildroot}%{_datadir}/%{netcoreappdir}/crossgen2 +cp %{_reldir_clr}/crossgen2/ILCompiler.ReadyToRun.dll %{buildroot}%{_datadir}/%{netcoreappdir}/crossgen2 +cp %{_reldir_clr}/crossgen2/ILCompiler.TypeSystem.ReadyToRun.dll %{buildroot}%{_datadir}/%{netcoreappdir}/crossgen2 +cp %{_reldir_clr}/crossgen2/ILCompiler.DependencyAnalysisFramework.dll %{buildroot}%{_datadir}/%{netcoreappdir}/crossgen2 +cp %{_reldir_clr}/crossgen2/Microsoft.DiaSymReader.dll %{buildroot}%{_datadir}/%{netcoreappdir}/crossgen2 + +cp %{_reldir_clr}/libjitinterface_%{_tarch}.so %{buildroot}%{_datadir}/%{netcoreappdir}/crossgen2 +%endif + +# Managed CoreFX +cp %{_reldir_fx_managed}/*.dll %{buildroot}%{_datadir}/%{netcoreappdir} +cp %{_reldir_fx_managed}/*.pdb %{buildroot}%{_datadir}/%{netcoreappdir} + +# Copy files for test rpm +%ifarch x86_64 + +mkdir artifacts/corefx_tests +mkdir artifacts/corefx_tests/tests +mkdir artifacts/corefx_tests/coreroot + +for test_dir in `find ./artifacts/bin -type d -name "*.Tests"`; do + test=$(basename $test_dir) + mkdir artifacts/corefx_tests/tests/$test + + for FILE in `find $test_dir \( -name "*dll" -or -name "*.json" -or -name "*.resources" -or -name "*.pdb" -or -name "*.xml" -or -name "*.exe" -or -name "*.cs" -or -name "*.docx" \)` + do + cp $FILE artifacts/corefx_tests/tests/$test/ + done + + for DIR in `find $test_dir -type d \( -name "*TestFiles" -or -name "*TestData" -or -name "*NetworkFiles" -or -name "*Utils" -or -name "*Mono" -or -name "*TestFeeds" -or -name "*bitmaps" \)` + do + cp -r $DIR artifacts/corefx_tests/tests/$test/ + done +done + +for test in System.Runtime.Loader.Tests System.Resources.ResourceManager.Tests System.IO.Packaging.Tests; do + test_dir=$(find ./artifacts/bin -type d -name $test) + file_dir=$(find $test_dir -name $test.dll) + file_dir=$(dirname $file_dir) + cp -r $file_dir/* artifacts/corefx_tests/tests/$test/ +done + +for test_dir in `find artifacts/corefx_tests/tests/ -type d -name "*.Tests"`; do + test=$(basename $test_dir) + sed "s/TEST_NAME_DLL/${test}.dll/" RunTests.sh > ${test_dir}/RunTests.sh + chmod +x ${test_dir}/RunTests.sh +done + +for test_dir in `find artifacts/corefx_tests/tests/ -type d -name "Invariant.Tests"`; do + file=$(find ${test_dir} -name RunTests.sh) + cp $file $file.bak + sed "s/\$RUNTIME_PATH\/corerun xunit.console.dll/CORECLR_GLOBAL_INVARIANT=1 \$RUNTIME_PATH\/corerun xunit.console.dll/g" $file > $file.bak + mv $file.bak $file + chmod +x $file +done + +# This is a workaround for missing xunit.console.dll for ILCompiler tests (which are technically not corefx tests, but for now are placed in corefx-tests rpm). +# For corefx tests xunit is set up (and copied to test dir) in ./eng/testing/xunit/xunit.console.targets. +# ILCompiler tests do not use this set up approach, so explicitly perform copy step (see CopyRunnerToOutputDirectory target in ./eng/testing/xunit/xunit.console.targets for details). +cp ./.packages/microsoft.dotnet.xunitconsolerunner/*/tools/netcoreapp3.1/* artifacts/corefx_tests/tests/ILCompiler.TypeSystem.ReadyToRun.Tests/ + +cp %{_reldir_fx_withoob}/*.dll artifacts/corefx_tests/coreroot/ + +mv artifacts/corefx_tests/tests %{buildroot}/%{fxtestdir}/ +mv artifacts/corefx_tests/coreroot/* %{buildroot}/%{fxtestdir}/coreroot/ +cp runtest_fx.sh %{buildroot}/%{fxtestdir}/runtest.sh +chmod +x %{buildroot}/%{fxtestdir}/runtest.sh + +%endif + +%endif + +# coreclr-test +%if 0%{skiptests} +%else +cp runtest_clr.sh %{buildroot}/%{clrtestdir}/runtest.sh +chmod +x %{buildroot}/%{clrtestdir}/runtest.sh +cp unsupportedCrossgenLibs.%{_barch}.txt %{buildroot}/%{clrtestdir}/unsupportedCrossgenLibs.txt | true +cp unsupportedCrossgenTests.%{_barch}.txt %{buildroot}/%{clrtestdir}/unsupportedCrossgenTests.txt | true +cp unsupportedTests.%{_barch}.txt %{buildroot}/%{clrtestdir}/unsupportedTests.txt | true + +%define _tcreldir artifacts/tests/coreclr/Linux.%{_barch}.%{dotnet_buildtype_clr} +cp -r %{_tcreldir}/* %{buildroot}/%{clrtestdir} +find %{buildroot}/%{clrtestdir} -name "*.pdb" -exec rm {} \; +find %{buildroot}/%{clrtestdir} -name "*.cmd" -exec rm {} \; +rm -rf %{buildroot}/%{clrtestdir}/Tests/Core_Root/in +rm -rf %{buildroot}/%{clrtestdir}/Tests/Core_Root/sharedFramework +rm -rf %{buildroot}/%{clrtestdir}/Tests/Core_Root/PDB +rm -rf %{buildroot}/%{clrtestdir}/Tests/Core_Root/x64 +rm -rf %{buildroot}/%{clrtestdir}/Tests/Core_Root/gcinfo +rm -rf %{buildroot}/%{clrtestdir}/Tests/Core_Root/inc +rm -rf %{buildroot}/%{clrtestdir}/Tests/Core_Root/lib +rm -rf %{buildroot}/%{clrtestdir}/Tests/Core_Root/IL +rm -rf %{buildroot}/%{clrtestdir}/Tests/Core_Root/crossgen2 + +%ifarch %{arm} aarch64 +rm -rf %{buildroot}/%{clrtestdir}/Tests/Core_Root/R2RDump/Microsoft.DiaSymReader.Native.x86.dll +rm -rf %{buildroot}/%{clrtestdir}/Tests/Core_Root/R2RDump/Microsoft.DiaSymReader.Native.amd64.dll +%endif + +rm -rf %{buildroot}/%{clrtestdir}/Tests/Core_Root/ILCompiler.*.dll +rm -rf %{buildroot}/%{clrtestdir}/build/ +rm %{buildroot}/%{clrtestdir}/Tests/Core_Root/{superpmi,SOS_README.md,mcs,*.a,*.so,ilasm,ildasm} +#rm %{buildroot}/%{clrtestdir}/Tests/Core_Root/api-ms-win-core-debug-l1-1-0.dll +#rm %{buildroot}/%{clrtestdir}/Tests/Core_Root/api-ms-win-core-debug-l1-1-1.dll + +cp %{buildroot}/%{clrtestdir}/bin/*.so %{buildroot}/%{clrtestdir}/Tests/Core_Root +mv %{buildroot}/%{clrtestdir}/Tests/Core_Root %{buildroot}/%{clrtestdir}/coreroot +%endif + +# test native +mkdir -p %{buildroot}/%{clrtestdir}/bin +cp %{_reldir_clr}/superpmi %{buildroot}/%{clrtestdir}/bin +cp %{_reldir_clr}/mcs %{buildroot}/%{clrtestdir}/bin +cp %{_reldir_clr}/libsuperpmi-shim-collector.so %{buildroot}/%{clrtestdir}/bin +cp %{_reldir_clr}/libsuperpmi-shim-counter.so %{buildroot}/%{clrtestdir}/bin +cp %{_reldir_clr}/libsuperpmi-shim-simple.so %{buildroot}/%{clrtestdir}/bin + +### +### Copy nupkg to nuget directory +### +mkdir -p %{buildroot}/nuget +cp ./nuget/*.nupkg %{buildroot}/nuget + +# coreclr rpm +%files +%manifest %{name}.manifest +%dir %{_datadir}/%{dotnetdir} +%dir %{_datadir}/%{netcoreappdir} +%dir %{_datadir}/%{dotnettizendir} +%{_datadir}/%{netcoreappdir}/corerun +%{_datadir}/%{netcoreappdir}/libclrjit.so +%{_datadir}/%{netcoreappdir}/libclrgc.so +%{_datadir}/%{netcoreappdir}/libcoreclr.so +%{_datadir}/%{netcoreappdir}/libdbgshim.so +%{_datadir}/%{netcoreappdir}/libmscordaccore.so +%{_datadir}/%{netcoreappdir}/libmscordbi.so +%{_datadir}/%{netcoreappdir}/libcoreclrtraceptprovider.so +%{_datadir}/%{netcoreappdir}/libjitinterface_%{_tarch}.so +%{_datadir}/%{dotnettizendir}/netcoreapp +%{_datadir}/%{netcoreappdir}/ilasm +%{_datadir}/%{netcoreappdir}/ildasm + +%if 0%{skipmanaged} +%else + +%if 0%{skipmanagedtools} +%else +%{_datadir}/%{netcoreappdir}/createdump + +%dir %{_datadir}/%{netcoreappdir}/crossgen2 +%{_datadir}/%{netcoreappdir}/crossgen2/crossgen2.dll +%{_datadir}/%{netcoreappdir}/crossgen2/ILCompiler.Diagnostics.dll +%{_datadir}/%{netcoreappdir}/crossgen2/ILCompiler.ReadyToRun.dll +%{_datadir}/%{netcoreappdir}/crossgen2/ILCompiler.TypeSystem.ReadyToRun.dll +%{_datadir}/%{netcoreappdir}/crossgen2/ILCompiler.DependencyAnalysisFramework.dll +%{_datadir}/%{netcoreappdir}/crossgen2/Microsoft.DiaSymReader.dll + +%{_datadir}/%{netcoreappdir}/crossgen2/libjitinterface_%{_tarch}.so +%endif + +%endif + +# symlink to .NET version for compatibility +%{_datadir}/%{netshareddir}/Microsoft.NETCore.App/2.0.0 +%{_datadir}/%{netshareddir}/Microsoft.NETCore.App/2.1.0 +%{_datadir}/%{netshareddir}/Microsoft.NETCore.App/2.1.1 +%{_datadir}/%{netshareddir}/Microsoft.NETCore.App/2.1.4 +%{_datadir}/%{netshareddir}/Microsoft.NETCore.App/3.0.0 +%{_datadir}/%{netshareddir}/Microsoft.NETCore.App/3.1.3 + +%files -n coreclr-test +%manifest %{name}.manifest +%dir %{clrtestdir} +%{clrtestdir}/* + +%files -n coreclr-devel +%manifest %{name}.manifest +%dir %{_datadir}/%{netcoreappdir}/lib +%dir %{_datadir}/%{netcoreappdir}/src +%dir %{_datadir}/%{netcoreappdir} +%{_datadir}/%{netcoreappdir}/lib/* +%{_datadir}/%{netcoreappdir}/src/* +%{_datadir}/%{netcoreappdir}/System.Private.CoreLib.pdb + +%if 0%{skipmscorlib} +%else +%files -n mscorlib +%manifest %{name}.manifest +%{_datadir}/%{netcoreappdir}/System.Private.CoreLib.dll +%endif + +%files -n corefx-native +%manifest %{name}.manifest +%{_datadir}/%{netcoreappdir}/libSystem.Globalization.Native.so +%{_datadir}/%{netcoreappdir}/libSystem.IO.Compression.Native.so +%{_datadir}/%{netcoreappdir}/libSystem.Native.so +%{_datadir}/%{netcoreappdir}/libSystem.Net.Security.Native.so +%{_datadir}/%{netcoreappdir}/libSystem.Security.Cryptography.Native.OpenSsl.so + +%files -n corefx-test-native +%manifest %{name}.manifest +%{fxtestdir}/coreroot/libSystem.IO.Ports.Native.so + +%if 0%{skipmanaged} +%else + +%files -n corefx-managed +%manifest %{name}.manifest +%{_datadir}/%{netcoreappdir}/*.dll +%exclude %{_datadir}/%{netcoreappdir}/System.Private.CoreLib.dll + +%files -n corefx-managed-devel +%manifest %{name}.manifest +%{_datadir}/%{netcoreappdir}/*.pdb +%exclude %{_datadir}/%{netcoreappdir}/System.Private.CoreLib.pdb + +%ifarch x86_64 +%files -n corefx-test +%manifest %{name}.manifest +%{fxtestdir}/tests +%{fxtestdir}/coreroot/*.dll +%{fxtestdir}/runtest.sh +%endif + +%endif + +%files -n corefx-managed-ref +%manifest %{name}.manifest +/nuget/*.nupkg + +%if 0%{skipmscorlib} +%else +%post -n mscorlib +rm -f %{_datadir}/%{netcoreappdir}/*.Backup +%endif + +%post -p /sbin/ldconfig + +%postun -p /sbin/ldconfig diff --git a/runtest_clr.sh b/runtest_clr.sh new file mode 100755 index 0000000..56b53f2 --- /dev/null +++ b/runtest_clr.sh @@ -0,0 +1,1006 @@ +#!/usr/bin/env bash + +function print_usage { + echo '' + echo 'CoreCLR test runner script.' + echo 'Script uses next files if they exist:' + echo ' unsupportedTests.txt' + echo ' unsupportedCrossgenLibs.txt' + echo ' unsupportedCrossgenTests.txt' + echo '' + echo 'Typical Tizen command:' + echo ' coreclr/tests/runtest.sh' + echo ' --arch=armel' + echo ' --testRootDir="/opt/usr/coreclr-tc"' + echo ' --coreOverlayDir="/opt/usr/coreclr-tc/coreroot"' + echo ' --netcoreDir="/usr/share/dotnet.tizen/netcoreapp"' + echo ' --copy-netcore-to-coreroot' + echo ' --xunitOutputPath="/opt/usr/coreclr-tc/results/coreclrtests.xml"' + echo ' --testsPassOutputPath="/opt/usr/coreclr-tc/results/coreclrtests.pass.txt"' + echo ' --testsSkipOutputPath="/opt/usr/coreclr-tc/results/coreclrtests.skip.txt"' + echo ' --testsFailOutputPath="/opt/usr/coreclr-tc/results/coreclrtests.fail.txt"' + echo ' --libsCrossgenPassOutputPath="/opt/usr/coreclr-tc/results/crossgenlibs.pass.txt"' + echo ' --libsCrossgenSkipOutputPath="/opt/usr/coreclr-tc/results/crossgenlibs.skip.txt"' + echo ' --libsCrossgenFailOutputPath="/opt/usr/coreclr-tc/results/crossgenlibs.fail.txt"' + echo ' --crossgen2options="--jitpath /opt/usr/coreclr-tc/coreroot/libclrjit.so --targetarch armel --parallelism 4 -O"' + echo '' + echo 'Required arguments:' + echo ' --arch= : Target arch (for TW targets "armel" should be passed instead of "arm64", for TM use "armel"; allowed values: "arm", "armel", "arm64", "x64", "x86").' + echo ' --testRootDir= : Root directory of the test build (default: /opt/usr/coreclr-tc).' + echo ' --coreOverlayDir= : Directory containing CLR and FX (default: /opt/usr/coreclr-tc/coreroot).' + echo '' + echo 'Optional arguments:' + echo ' --netcoreDir= : Netcore (CLR and FX) system dir (default: /usr/share/dotnet.tizen/netcoreapp).' + echo ' --copy-netcore-to-coreroot : Copy netcore (CLR and FX) from netcore system dir to coreroot.' + echo ' --testDir= : Run tests only in the specified directory. The path is relative to the directory' + echo ' specified by --testRootDir. Multiple of this switch may be specified.' + echo ' --testDirFile= : Run tests only in the directories specified by the file at . Paths are listed' + echo ' one line, relative to the directory specified by --testRootDir.' + echo ' --num-procs= : Run N test processes at the same time (default is 1).' + echo ' -v, --verbose : Show output from each test.' + echo ' -h, --help : Show usage information.' + echo ' --xunitOutputPath= : Create xUnit XML report at the specifed path (default: /coreclrtests.xml)' + echo ' --testsPassOutputPath= : Create pass report at the specifed path (default: /coreclrtests.pass.txt)' + echo ' --testsSkipOutputPath= : Create skip report at the specifed path (default: /coreclrtests.skip.txt)' + echo ' --testsFailOutputPath= : Create fail report at the specifed path (default: /coreclrtests.fail.txt)' + echo ' --test-env : Script to set environment variables for tests.' + echo '' + echo 'Optional arguments with "export COMPlus_..." meaning:' + echo ' --jitstress= : Runs the tests with COMPlus_JitStress=n' + echo ' --jitstressregs= : Runs the tests with COMPlus_JitStressRegs=n' + echo ' --gcstresslevel= : Runs the tests with COMPlus_GCStress=n' + echo '' + echo 'MulticoreJit:' + echo ' --mcj : Runs the tests with COMPlus_MultiCoreJitProfile= COMPlus_MultiCoreJitMinNumCpus=1 (each test is launched 2 times: first launch to gather profile, second launch to use profile)' + echo ' --mcj-no-profile-gather : Runs the tests with COMPlus_MultiCoreJitNoProfileGather=1 on the second mcj launch' + echo '' + echo 'Crossgen:' + echo ' --crossgen-libs : Precompiles system libs.' + echo ' --crossgen-tests : Precompiles tests.' + echo ' --crossgenoptions : Options passed to crossgen.' + echo ' --allow-crossgen-fails : Allow crossgen to ignore compilation fails.' + echo ' --crossgen-lib= : Precompile only specified lib. The path is absolute.' + echo ' --libsCrossgenPassOutputPath= : Create crossgen pass report at the specifed path (default: /crossgenlibs.pass.txt)' + echo ' --libsCrossgenSkipOutputPath= : Create crossgen skip report at the specifed path (default: /crossgenlibs.skip.txt)' + echo ' --libsCrossgenFailOutputPath= : Create crossgen fail report at the specifed path (default: /crossgenlibs.fail.txt)' + echo '' + echo 'Temporary:' + echo ' --crossgen2options : Options passed to crossgen2 (default: --jitpath /opt/usr/coreclr-tc/coreroot/libclrjit.so --targetarch armel)' + echo ' --crossgen2-libs : Use crossgen2 for compilation of system libs.' + echo ' --crossgen2-tests : Use crossgen2 for compilation of tests.' + echo ' --crossgen-spc-first : Crossgen System.Private.CoreLib.dll before other dlls.' +} + +function print_results { + echo "" + echo "=======================" + echo " Test Results" + echo "=======================" + echo "# Overlay : $coreOverlayDir" + echo "# Tests Discovered : $countTotalTests" + echo "# Passed : $countPassedTests" + echo "# Failed : $countFailedTests" + echo "# Skipped : $countSkippedTests" + echo "=======================" +} + +# Initialize counters for bookkeeping. +countTotalTests=0 +countPassedTests=0 +countFailedTests=0 +countSkippedTests=0 + +# Variables for xUnit-style XML output. XML format: https://xunit.github.io/docs/format-xml-v2.html +xunitOutputPath= +xunitTestOutputPath= + +# Variables for text file output. These can be passed back to runtest.sh using the "--playlist" argument +# to rerun specific tests. +testsPassOutputPath= +testsFailOutputPath= +testsSkipOutputPath= +libsCrossgenPassOutputPath= +libsCrossgenFailOutputPath= +libsCrossgenSkipOutputPath= + +function xunit_output_begin { + if [ -z "$xunitOutputPath" ]; then + xunitOutputPath=$testRootDir/coreclrtests.xml + fi + xunitTestOutputPath=${xunitOutputPath}.test + if [ -f "$xunitOutputPath" ]; then + rm -f -r "$xunitOutputPath" + fi + if [ -f "$xunitTestOutputPath" ]; then + rm -f -r "$xunitTestOutputPath" + fi +} + +function xunit_output_add_test { + # + # + # + # + + local scriptFilePath=$1 + local outputFilePath=$2 + local testResult=$3 # Pass, Fail, or Skip + local testScriptExitCode=$4 + local testRunningTime=$5 + + local testPath=${scriptFilePath%.sh} # Remove trailing ".sh" + local testDir=$(dirname "$testPath") + local testName=$(basename "$testPath") + + # Replace '/' with '.' + testPath=$(echo "$testPath" | tr / .) + testDir=$(echo "$testDir" | tr / .) + + local line + + line=" " + line="${line}>"$xunitTestOutputPath" + return + fi + + line="${line}>" + echo "$line" >>"$xunitTestOutputPath" + + line=" " + if [ "$testResult" == "Skip" ]; then + line="${line}" + echo "$line" >>"$xunitTestOutputPath" + else + line="${line}" + echo "$line" >>"$xunitTestOutputPath" + + line=" " + line="${line}" + echo "$line" >>"$xunitTestOutputPath" + line=" " + line="${line}>"$xunitTestOutputPath" + cat "$outputFilePath" >>"$xunitTestOutputPath" + line=" " + line="${line}]]>" + echo "$line" >>"$xunitTestOutputPath" + line=" " + line="${line}" + echo "$line" >>"$xunitTestOutputPath" + + line=" " + line="${line}" + echo "$line" >>"$xunitTestOutputPath" + fi + + line=" " + line="${line}" + echo "$line" >>"$xunitTestOutputPath" +} + +function xunit_output_end { + local errorSource=$1 + local errorMessage=$2 + + local errorCount + if [ -z "$errorSource" ]; then + ((errorCount = 0)) + else + ((errorCount = 1)) + fi + + echo '' >>"$xunitOutputPath" + echo '' >>"$xunitOutputPath" + + local line + + # + line=" " + line="${line}>"$xunitOutputPath" + + # + line=" " + line="${line}>"$xunitOutputPath" + + # ... + if [ -f "$xunitTestOutputPath" ]; then + cat "$xunitTestOutputPath" >>"$xunitOutputPath" + rm -f "$xunitTestOutputPath" + fi + + # + line=" " + line="${line}" + echo "$line" >>"$xunitOutputPath" + + if [ -n "$errorSource" ]; then + # + line=" " + line="${line}" + echo "$line" >>"$xunitOutputPath" + + # + line=" " + line="${line}>"$xunitOutputPath" + + # + line=" " + line="${line}${errorMessage}" + echo "$line" >>"$xunitOutputPath" + + # + line=" " + line="${line}" + echo "$line" >>"$xunitOutputPath" + + # + line=" " + line="${line}" + echo "$line" >>"$xunitOutputPath" + fi + + # + line=" " + line="${line}" + echo "$line" >>"$xunitOutputPath" + + # + echo '' >>"$xunitOutputPath" +} + +function text_file_output_begin { + if [ -z "$testsPassOutputPath" ]; then + testsPassOutputPath=$testRootDir/coreclrtests.pass.txt + fi + if [ -f "$testsPassOutputPath" ]; then + rm -f "$testsPassOutputPath" + fi + if [ -z "$testsFailOutputPath" ]; then + testsFailOutputPath=$testRootDir/coreclrtests.fail.txt + fi + if [ -f "$testsFailOutputPath" ]; then + rm -f "$testsFailOutputPath" + fi + if [ -z "$testsSkipOutputPath" ]; then + testsSkipOutputPath=$testRootDir/coreclrtests.skip.txt + fi + if [ -f "$testsSkipOutputPath" ]; then + rm -f "$testsSkipOutputPath" + fi + + if [ -z "$libsCrossgenPassOutputPath" ]; then + libsCrossgenPassOutputPath=$testRootDir/crossgenlibs.pass.txt + fi + if [ -f "$libsCrossgenPassOutputPath" ]; then + rm -f "$libsCrossgenPassOutputPath" + fi + if [ -z "$libsCrossgenFailOutputPath" ]; then + libsCrossgenFailOutputPath=$testRootDir/crossgenlibs.fail.txt + fi + if [ -f "$libsCrossgenFailOutputPath" ]; then + rm -f "$libsCrossgenFailOutputPath" + fi + if [ -z "$libsCrossgenSkipOutputPath" ]; then + libsCrossgenSkipOutputPath=$testRootDir/crossgenlibs.skip.txt + fi + if [ -f "$libsCrossgenSkipOutputPath" ]; then + rm -f "$libsCrossgenSkipOutputPath" + fi +} + +function text_file_output_add_test { + local scriptFilePath=$1 + local testResult=$2 # Pass, Fail, or Skip + + if [ "$testResult" == "Pass" ]; then + echo "$scriptFilePath" >>"$testsPassOutputPath" + elif [ "$testResult" == "Skip" ]; then + echo "$scriptFilePath" >>"$testsSkipOutputPath" + else + echo "$scriptFilePath" >>"$testsFailOutputPath" + fi +} + +function exit_with_error { + local errorSource=$1 + local errorMessage=$2 + local printUsage=$3 + + if [ -z "$printUsage" ]; then + ((printUsage = 0)) + fi + + echo "$errorMessage" + xunit_output_end "$errorSource" "$errorMessage" + if ((printUsage != 0)); then + print_usage + fi + exit $EXIT_CODE_EXCEPTION +} + +# Handle Ctrl-C. We will stop execution and print the results that +# we gathered so far. +function handle_ctrl_c { + local errorSource='handle_ctrl_c' + + echo "" + echo "*** Stopping... ***" + print_results + exit_with_error "$errorSource" "Test run aborted by Ctrl+C." +} + +# Register the Ctrl-C handler +trap handle_ctrl_c INT + +# Variables for unsupported and failing tests +declare -a unsupportedCrossGenLibs +declare -a unsupportedCrossGenTests +declare -a unsupportedTests + +# Get an array of items by reading the specified file line by line. +function read_array { + local theArray=() + + if [ ! -f "$1" ]; then + return + fi + + # bash in Mac OS X doesn't support 'readarray', so using alternate way instead. + # readarray -t theArray < "$1" + # Any line that starts with '#' is ignored. + while IFS='' read -r line || [ -n "$line" ]; do + if [[ $line != "#"* ]]; then + theArray[${#theArray[@]}]=$line + fi + done < "$1" + echo ${theArray[@]} +} + +function load_unsupported_tests { + # Load the list of tests that are not supported on this platform + unsupportedTests=($(read_array "$(dirname "$0")/unsupportedTests.txt")) + # Load the list of libs that are not supported for crossgen on this platform + unsupportedCrossGenLibs=($(read_array "$(dirname "$0")/unsupportedCrossgenLibs.txt")) + # Load the list of test that are not supported for crossgen on this platform + unsupportedCrossGenTests=($(read_array "$(dirname "$0")/unsupportedCrossgenTests.txt")) +} + +function is_unsupported_crossgen_lib { + for unsupported in "${unsupportedCrossGenLibs[@]}"; do + if [ "$1" == "$unsupported" ]; then + return 0 + fi + done + return 1 +} + +function is_unsupported_test { + for unsupported in "${unsupportedTests[@]}"; do + if [ "$1" == "$unsupported" ]; then + return 0 + fi + done + + if [ $doCrossgenTests == 1 ] || [ $doCrossgen2Tests == 1 ]; then + for unsupported in "${unsupportedCrossGenTests[@]}"; do + if [ "$1" == "$unsupported" ]; then + return 0 + fi + done + fi + + return 1 +} + +function crossgen_file { + local overlayDir=$1 + local dll_path=$2 + local name=$3 + + # ni.dll are created as ni.dll.tmp in order to not interfere + # with crossgen2 at first, then moved to ni.dll all at once at the end + # (logic is similar to https://github.com/dotnet/runtime/pull/57341/) + local tmp_ni_path=$(echo $dll_path | sed 's/.dll$/.ni.dll.tmp/') + + echo "Precompiling $dll_path to $tmp_ni_path" + + if [ $doCrossgenLibs == 1 ]; then + ${overlayDir}/crossgen /in $dll_path /out $tmp_ni_path $CrossGenOptions /p ${overlayDir}:${overlayDir}/crossgen2 &>$dll_path.out + elif [ $doCrossgen2Libs == 1 ]; then + ${overlayDir}/corerun ${overlayDir}/crossgen2/crossgen2.dll $CrossGen2Options -o:$tmp_ni_path $dll_path -r:${overlayDir}/*.dll -r:${overlayDir}/crossgen2/*.dll &>$dll_path.out + fi + + local exitCode=$? + if [[ $exitCode != 0 ]]; then + echo Crossgen fail for $dll_path. + echo "$dll_path" >> "$libsCrossgenFailOutputPath" + + cat $dll_path.out + + if [ $CrossGenAllowFail == 0 ]; then + exit $exitCode + fi + else + echo Crossgen success $dll_path. + echo "$dll_path" >> "$libsCrossgenPassOutputPath" + + if [[ "${name}" == "System.Private.CoreLib.dll" ]]; then + # SPC.ni.dll can be used directly without ni.dll.tmp + # (because SPC doesn't use any dependencies) + mv $dll_path $dll_path.bak + mv $tmp_ni_path $dll_path + fi + fi + + rm $dll_path.out +} + +function precompile_overlay_assemblies { + local overlayDir=$CORE_ROOT + + if [ $doCopyNetcoreToCoreroot == 1 ]; then + echo "Copying netcore ($netcoreDir) to coreroot ($overlayDir)" + cp -r $netcoreDir/* $overlayDir + fi + + echo Cleanup old ni.dll + for file in `find $testRootDir -name "*.ni.*"`; do + rm $file + done + + test -f $overlayDir/System.Private.CoreLib.dll.Backup && mv $overlayDir/System.Private.CoreLib.dll.Backup $overlayDir/System.Private.CoreLib.dll + test -f $overlayDir/System.Private.CoreLib.dll.bak && mv $overlayDir/System.Private.CoreLib.dll.bak $overlayDir/System.Private.CoreLib.dll + + if [ $doCrossgenLibs == 0 ] && [ $doCrossgen2Libs == 0 ]; then + echo Skipping crossgen of libs. + return 0 + else + echo Precompiling libs + fi + + if [ $doCrossgenSPCFirst == 1 ]; then + local dll_path=$overlayDir/System.Private.CoreLib.dll + local name=$(basename $dll_path) + crossgen_file $overlayDir $dll_path $name + fi + + if [ -z "$crossgenLibs" ]; then + # No libs to crossgen were specified, so crossgen everything in the overlay + filesToPrecompile=$(find -L $overlayDir -iname \*.dll -not -iname \*.ni.dll -type f) + else + # Otherwise, compile only specified libs + filesToPrecompile=$(echo "${crossgenLibs[@]}") + fi + + for fileToPrecompile in ${filesToPrecompile} + do + local dll_path=${fileToPrecompile} + local name=$(basename $dll_path) + + if [[ "$name" == "System.Private.CoreLib.dll" && "$doCrossgenSPCFirst" == "1" ]]; then + continue + fi + + if is_unsupported_crossgen_lib "${name}"; then + echo Skipping crossgen for $dll_path. + echo "$dll_path" >> "$libsCrossgenSkipOutputPath" + continue + fi + + crossgen_file $overlayDir $dll_path $name + done + + # Copy ni.dll all at once + for tmp_ni_path in `find $overlayDir -name "*.ni.dll.tmp"`; do + local ni_dll_path=$(echo $tmp_ni_path | sed 's/.ni.dll.tmp$/.ni.dll/') + + echo "Moving $tmp_ni_path to $ni_dll_path" + mv $tmp_ni_path $ni_dll_path + done +} + +function skip_unsupported_test { + # This function runs in a background process. It should not echo anything, and should not use global variables. This + # function is analogous to run_test, and causes the test to be skipped with the message below. + + local scriptFilePath=$1 + local outputFilePath=$2 + + echo "Not supported on this platform or in this mode." >"$outputFilePath" + return 2 # skip the test +} + +function run_test { + # This function runs in a background process. It should not echo anything, and should not use global variables. + + local scriptFilePath=$1 + local outputFilePath=$2 + + # Switch to directory where the script is + cd "$(dirname "$scriptFilePath")" + + local scriptFileName=$(basename "$scriptFilePath") + local outputFileName=$(basename "$outputFilePath") + + echo "" > "$outputFileName" 2>&1 + + if [ $useMulticoreJit == 1 ]; then + export COMPlus_MultiCoreJitProfile="`pwd`/mcj_profile.dat" + export COMPlus_MultiCoreJitMinNumCpus="1" + echo "MULTICOREJIT: 1st launch" >> "$outputFileName" 2>&1 + + "./$scriptFileName" >> "$outputFileName" 2>&1 + local testScriptExitCode=$? + + if [ $testScriptExitCode == 0 ]; then + if [ $useMulticoreJitNoProfileGather == 1 ]; then + export COMPlus_MultiCoreJitNoProfileGather="1" + fi + + echo "" >> "$outputFileName" 2>&1 + echo "MULTICOREJIT: 2nd launch" >> "$outputFileName" 2>&1 + else + return $testScriptExitCode + fi + fi + + if [ $doCrossgenTests == 1 ]; then + export RunCrossGen=1 + fi + + if [ $doCrossgen2Tests == 1 ]; then + export RunCrossGen2=1 + fi + + "./$scriptFileName" >> "$outputFileName" 2>&1 + local testScriptExitCode=$? + + return $testScriptExitCode +} + +# Variables for running tests in the background +((maxProcesses = 1)) # long tests delay process creation, use a few more processors + +((processCount = 0)) +declare -a scriptFilePaths +declare -a outputFilePaths +declare -a processIds +declare -a testStartTimes +waitProcessIndex= +pidNone=0 + +function waitany { + local pid + local exitcode + while true; do + for (( i=0; i<$maxProcesses; i++ )); do + pid=${processIds[$i]} + if [ -z "$pid" ] || [ "$pid" == "$pidNone" ]; then + continue + fi + if ! kill -0 $pid 2>/dev/null; then + wait $pid + exitcode=$? + waitProcessIndex=$i + processIds[$i]=$pidNone + return $exitcode + fi + done + sleep 0.1 + done +} + +function get_available_process_index { + local pid + local i=0 + for (( i=0; i<$maxProcesses; i++ )); do + pid=${processIds[$i]} + if [ -z "$pid" ] || [ "$pid" == "$pidNone" ]; then + break + fi + done + echo $i +} + +function finish_test { + waitany + local testScriptExitCode=$? + local finishedProcessIndex=$waitProcessIndex + ((--processCount)) + + local scriptFilePath=${scriptFilePaths[$finishedProcessIndex]} + local outputFilePath=${outputFilePaths[$finishedProcessIndex]} + local scriptFileName=$(basename "$scriptFilePath") + + local testEndTime= + local testRunningTime= + local header= + + if ((verbose == 1)); then + header=$(printf "[%4d]" $countTotalTests) + fi + + testEndTime=$(date +%s) + testRunningTime=$(( $testEndTime - ${testStartTimes[$finishedProcessIndex]} )) + header=$header$(printf "[%4ds]" $testRunningTime) + + if [ $useMulticoreJit == 1 ]; then + header="$header[mcj]" + fi + + local testResult + case $testScriptExitCode in + 0) + let countPassedTests++ + testResult='Pass' + if ((verbose == 1)); then + echo "PASSED - ${header}${scriptFilePath}" + else + echo " - ${header}${scriptFilePath}" + fi + ;; + 2) + let countSkippedTests++ + testResult='Skip' + echo "SKIPPED - ${header}${scriptFilePath}" + ;; + *) + let countFailedTests++ + testResult='Fail' + echo "FAILED - ${header}${scriptFilePath}" + ;; + esac + let countTotalTests++ + + if ((verbose == 1 || testScriptExitCode != 0)); then + while IFS='' read -r line || [ -n "$line" ]; do + echo " $line" + done <"$outputFilePath" + fi + + xunit_output_add_test "$scriptFilePath" "$outputFilePath" "$testResult" "$testScriptExitCode" "$testRunningTime" + text_file_output_add_test "$scriptFilePath" "$testResult" +} + +function finish_remaining_tests { + # Finish the remaining tests in the order in which they were started + while ((processCount > 0)); do + finish_test + done +} + +function prep_test { + local scriptFilePath=$1 + local scriptFileDir=$(dirname "$scriptFilePath") + + test "$verbose" == 1 && echo "Preparing $scriptFilePath" + + # Add executable file mode bit if needed + chmod +x "$scriptFilePath" + + # remove any Locks + rm -rf $scriptFileDir/lock + + # remove mcj profiles + rm -rf $scriptFileDir/mcj_profile.dat* +} + +function start_test { + local nextProcessIndex=$(get_available_process_index) + local scriptFilePath=$1 + + if ((nextProcessIndex == maxProcesses)); then + finish_test + nextProcessIndex=$(get_available_process_index) + fi + + scriptFilePaths[$nextProcessIndex]=$scriptFilePath + local scriptFileName=$(basename "$scriptFilePath") + local outputFilePath=$(dirname "$scriptFilePath")/${scriptFileName}.out + outputFilePaths[$nextProcessIndex]=$outputFilePath + + testStartTimes[$nextProcessIndex]=$(date +%s) + + test "$verbose" == 1 && echo "Starting $scriptFilePath" + if is_unsupported_test "$scriptFilePath"; then + skip_unsupported_test "$scriptFilePath" "$outputFilePath" & + else + run_test "$scriptFilePath" "$outputFilePath" & + fi + processIds[$nextProcessIndex]=$! + + ((++processCount)) +} + +# Get a list of directories in which to scan for tests by reading the +# specified file line by line. +function set_test_directories { + local errorSource='set_test_directories' + + local listFileName=$1 + + if [ ! -f "$listFileName" ] + then + exit_with_error "$errorSource" "Test directories file not found at $listFileName" + fi + testDirectories=($(read_array "$listFileName")) +} + +function run_tests_in_directory { + local testDir=$1 + local skipScriptsInDir=$2 + + local minDepth="1" + + # Need to skip scripts in testDir since they are not tests + if [[ "$skipScriptsInDir" == "1" ]]; then + minDepth="2" + fi + + # Recursively search through directories for .sh files to prepare them. + # Note: This needs to occur before any test runs as some of the .sh files + # depend on other .sh files + echo "Preparing tests..." + for scriptFilePath in $(find "$testDir" -mindepth ${minDepth} -type f -iname '*.sh' | sort) + do + prep_test "${scriptFilePath:2}" + done + echo "The tests have been prepared" + # Recursively search through directories for .sh files to run. + for scriptFilePath in $(find "$testDir" -mindepth ${minDepth} -type f -iname '*.sh' | sort) + do + start_test "${scriptFilePath:2}" + done +} + +# Exit code constants +readonly EXIT_CODE_SUCCESS=0 # Script ran normally. +readonly EXIT_CODE_EXCEPTION=1 # Script exited because something exceptional happened (e.g. bad arguments, Ctrl-C interrupt). +readonly EXIT_CODE_TEST_FAILURE=2 # Script completed successfully, but one or more tests failed. + +# Argument variables +testRootDir="/opt/usr/coreclr-tc/" +coreOverlayDir="/opt/usr/coreclr-tc/coreroot/" +doCopyNetcoreToCoreroot=0 +netcoreDir="/usr/share/dotnet.tizen/netcoreapp" +testEnv= + +# Handle arguments +verbose=0 +doCrossgenLibs=0 +doCrossgen2Libs=0 +CrossGenAllowFail=0 +doCrossgenTests=0 +doCrossgen2Tests=0 +doCrossgenSPCFirst=0 + +useMulticoreJit=0 +useMulticoreJitNoProfileGather=0 + +crossgenOpts="" +crossgen2Opts="" + +for i in "$@" +do + case $i in + -h|--help) + print_usage + exit $EXIT_CODE_SUCCESS + ;; + -v|--verbose) + verbose=1 + ;; + --arch=*) + ARCH=${i#*=} + ;; + --crossgen-libs) + doCrossgenLibs=1 + ;; + --crossgen2-libs) + doCrossgen2Libs=1 + ;; + --crossgen-tests) + doCrossgenTests=1 + ;; + --crossgen2-tests) + doCrossgen2Tests=1 + ;; + --crossgen-spc-first) + doCrossgenSPCFirst=1 + ;; + --crossgenoptions=*) + crossgenOpts="$crossgenOpts ${i#*=}" + ;; + --crossgen2options=*) + crossgen2Opts="$crossgen2Opts ${i#*=}" + ;; + --allow-crossgen-fails) + CrossGenAllowFail=1 + ;; + --crossgen-lib=*) + crossgenLibs[${#crossgenLibs[@]}]=${i#*=} + ;; + --jitstress=*) + export COMPlus_JitStress=${i#*=} + ;; + --jitstressregs=*) + export COMPlus_JitStressRegs=${i#*=} + ;; + --mcj) + useMulticoreJit=1 + ;; + --mcj-no-profile-gather) + useMulticoreJitNoProfileGather=1 + ;; + --testRootDir=*) + testRootDir=${i#*=} + ;; + --coreOverlayDir=*) + coreOverlayDir=${i#*=} + ;; + --netcoreDir=*) + netcoreDir=${i#*=} + ;; + --copy-netcore-to-coreroot) + doCopyNetcoreToCoreroot=1 + ;; + --testDir=*) + testDirectories[${#testDirectories[@]}]=${i#*=} + ;; + --testDirFile=*) + set_test_directories "${i#*=}" + ;; + --num-procs=*) + ((maxProcesses = ${i#*=})) + ;; + --test-env=*) + testEnv=${i#*=} + ;; + --gcstresslevel=*) + export COMPlus_GCStress=${i#*=} + ;; + --xunitOutputPath=*) + xunitOutputPath=${i#*=} + ;; + --testsPassOutputPath=*) + testsPassOutputPath=${i#*=} + ;; + --testsSkipOutputPath=*) + testsSkipOutputPath=${i#*=} + ;; + --testsFailOutputPath=*) + testsFailOutputPath=${i#*=} + ;; + --libsCrossgenPassOutputPath=*) + libsCrossgenPassOutputPath=${i#*=} + ;; + --libsCrossgenSkipOutputPath=*) + libsCrossgenSkipOutputPath=${i#*=} + ;; + --libsCrossgenFailOutputPath=*) + libsCrossgenFailOutputPath=${i#*=} + ;; + *) + echo "Unknown switch: $i" + print_usage + exit $EXIT_CODE_SUCCESS + ;; + esac +done + +if [ -z "$ARCH" ]; then + echo "--arch is required." + print_usage + exit $EXIT_CODE_EXCEPTION +fi +if [ "$ARCH" != "arm" ] && [ "$ARCH" != "armel" ] && [ "$ARCH" != "arm64" ] && [ "$ARCH" != "x64" ] && [ "$ARCH" != "x86" ]; then + echo "Unsupported value for --arch: $ARCH" + print_usage + exit $EXIT_CODE_EXCEPTION +fi + +if [ -z "$testRootDir" ]; then + echo "--testRootDir is required." + print_usage + exit $EXIT_CODE_EXCEPTION +fi +if [ ! -d "$testRootDir" ]; then + echo "Directory specified by --testRootDir does not exist: $testRootDir" + exit $EXIT_CODE_EXCEPTION +fi + +if [ -z "$coreOverlayDir" ]; then + echo "--coreOverlayDir is required." + print_usage + exit $EXIT_CODE_EXCEPTION +fi +if [ ! -d "$coreOverlayDir" ]; then + echo "Directory specified by --coreOverlayDir does not exist: $coreOverlayDir" + exit $EXIT_CODE_EXCEPTION +fi + +export CORE_ROOT="$coreOverlayDir" + +# Default values for crossgen2 options +if [ "$crossgen2Opts" == "" ]; then + crossgen2Opts="--jitpath $coreOverlayDir/libclrjit.so --targetarch $ARCH" +fi + +export CrossGenOptions="$crossgenOpts" +export CrossGen2Options="$crossgen2Opts" +export CrossGen2OptionsR2RTest="--crossgen2-jitpath $coreOverlayDir/libclrjit.so --target-arch $ARCH" + +echo "! Make sure CLR/FX are copied to $coreOverlayDir !" + +echo "Running on CPU-$ARCH" + +xunit_output_begin +text_file_output_begin +load_unsupported_tests +precompile_overlay_assemblies + +export __TestEnv=$testEnv +cd "$testRootDir" + +time_start=$(date +"%s") +if [ -z "$testDirectories" ] +then + # No test directories were specified, so run everything in the current + # directory and its subdirectories. + run_tests_in_directory "." 1 +else + # Otherwise, run all the tests in each specified test directory. + for testDir in "${testDirectories[@]}" + do + if [ ! -d "$testDir" ]; then + echo "Test directory does not exist: $testDir" + else + run_tests_in_directory "./$testDir" 0 + fi + done +fi + +finish_remaining_tests +print_results + +time_end=$(date +"%s") +time_diff=$(($time_end-$time_start)) +echo "$(($time_diff / 60)) minutes and $(($time_diff % 60)) seconds taken to run CoreCLR tests." + +xunit_output_end + +if ((countFailedTests > 0)); then + exit $EXIT_CODE_TEST_FAILURE +fi + +exit $EXIT_CODE_SUCCESS diff --git a/runtest_fx.sh b/runtest_fx.sh new file mode 100755 index 0000000..c2a677c --- /dev/null +++ b/runtest_fx.sh @@ -0,0 +1,387 @@ +#!/usr/bin/env bash + +function print_usage { + echo '' + echo 'CoreFX test runner script.' + echo '' + echo 'Typical Tizen command:' + echo ' corefx/runtest.sh' + echo ' --testRootDir="/opt/usr/corefx-tc/tests"' + echo ' --coreOverlayDir="/opt/usr/corefx-tc/coreroot"' + echo ' --outerloop=on/off' + echo ' --netcoreDir="/usr/share/dotnet.tizen/netcoreapp"' + echo ' --copy-netcore-to-coreroot' + echo ' --outputDir="/opt/usr/corefx-tc/results"' + echo ' --tmpDir="/opt/usr/corefx-tc/tmp"' + echo '' + echo 'Required arguments:' + echo ' --testRootDir= : Root directory of the test build (default: /opt/usr/corefx-tc/tests).' + echo ' --coreOverlayDir= : Directory containing CLR and FX (default: /opt/usr/corefx-tc/coreroot).' + echo " --outerloop= : OuterLoop category: on/off" + echo '' + echo 'Optional arguments:' + echo ' --netcoreDir= : Netcore (CLR and FX) system dir (default: /usr/share/dotnet.tizen/netcoreapp).' + echo ' --copy-netcore-to-coreroot : Copy netcore (CLR and FX) from netcore system dir to coreroot.' + echo ' --testDir= : Run tests only in the specified directory. The path is relative to the directory' + echo ' specified by --testRootDir. Multiple of this switch may be specified.' + echo ' --testDirFile= : Run tests only in the directories specified by the file at . Paths are listed' + echo ' one line, relative to the directory specified by --testRootDir.' + echo ' --num-procs= : Run N test processes at the same time (default is 1).' + echo ' -h, --help : Show usage information.' + echo ' --outputDir : Dir to save results to (default: /opt/usr/corefx-tc/results).' + echo ' --tmpDir : Local tmp dir (default: /opt/usr/corefx-tc/tmp).' +} + +function print_results { + echo "" + echo "=======================" + echo " Test Results" + echo "=======================" + echo "# Overlay : $coreOverlayDir" + echo "# Tests Discovered : $countTotalTests" + echo "# Passed : $countPassedTests" + echo "# Errored : $countErroredTests" + echo "# Failed : $countFailedTests" + echo "# Skipped : $countSkippedTests" + echo "#" + echo "# Errored dlls : $countErroredDlls" + echo "=======================" +} + +# Initialize counters for bookkeeping. +countTotalTests=0 +countPassedTests=0 +countErroredTests=0 +countFailedTests=0 +countSkippedTests=0 +countErroredDlls=0 + +# Variables for running tests in the background +((maxProcesses = 1)) # long tests delay process creation, use a few more processors + +((processCount = 0)) +declare -a testDirPaths +declare -a processIds +waitProcessIndex= +pidNone=0 + +function waitany { + local pid + local exitcode + while true; do + for (( i=0; i<$maxProcesses; i++ )); do + pid=${processIds[$i]} + if [ -z "$pid" ] || [ "$pid" == "$pidNone" ]; then + continue + fi + if ! kill -0 $pid 2>/dev/null; then + wait $pid + exitcode=$? + waitProcessIndex=$i + processIds[$i]=$pidNone + return $exitcode + fi + done + sleep 0.1 + done +} + +function get_available_process_index { + local pid + local i=0 + for (( i=0; i<$maxProcesses; i++ )); do + pid=${processIds[$i]} + if [ -z "$pid" ] || [ "$pid" == "$pidNone" ]; then + break + fi + done + echo $i +} + +function finish_test { + waitany + local testScriptExitCode=$? + local finishedProcessIndex=$waitProcessIndex + ((--processCount)) + + local dirName=${testDirPaths[$finishedProcessIndex]} + local testProject=`basename $dirName` + local outputFilePath="$testsOutputDir/$testProject/log.out" + + local resultsStr=$(grep "Total:.*Errors:.*Failed:.*Skipped:.*Time:" $outputFilePath) + + if [ "$resultsStr" == "" ]; then + if [ $testScriptExitCode -ne 0 ] + then + echo "$testProject: dll errored, see log $outputFilePath" + countErroredDlls=$(($countErroredDlls+1)) + else + # No appropriate tests were found in dll + echo "$testProject: no tests found, see log $outputFilePath" + fi + else + local curTotal=$(echo $resultsStr | awk '{print $4}' | sed 's/,//') + local curErrored=$(echo $resultsStr | awk '{print $6}' | sed 's/,//') + local curFailed=$(echo $resultsStr | awk '{print $8}' | sed 's/,//') + local curSkipped=$(echo $resultsStr | awk '{print $10}' | sed 's/,//') + local curTime=$(echo $resultsStr | awk '{print $12}' | sed 's/s//') + local curPassed=$(echo $curTotal $curErrored $curFailed $curSkipped | awk '{print $1-$2-$3-$4}') + + countTotalTests=$(echo $countTotalTests $curTotal | awk '{print $1+$2}') + countPassedTests=$(echo $countPassedTests $curPassed | awk '{print $1+$2}') + countErroredTests=$(echo $countErroredTests $curErrored | awk '{print $1+$2}') + countFailedTests=$(echo $countFailedTests $curFailed | awk '{print $1+$2}') + countSkippedTests=$(echo $countSkippedTests $curSkipped | awk '{print $1+$2}') + + if [ $testScriptExitCode -ne 0 ] + then + echo "$testProject: failed, Total:$curTotal Passed:$curPassed Errored:$curErrored Failed:$curFailed Skipped:$curSkipped Time:$curTime, see log $outputFilePath" + else + echo "$testProject: ok, Total:$curTotal Passed:$curPassed Errored:$curErrored Failed:$curFailed Skipped:$curSkipped Time:$curTime, see log $outputFilePath" + fi + fi +} + +function finish_remaining_tests { + # Finish the remaining tests in the order in which they were started + while ((processCount > 0)); do + finish_test + done +} + +function start_test { + local nextProcessIndex=$(get_available_process_index) + local dirName="$1" + local testProject=`basename $dirName` + + if ((nextProcessIndex == maxProcesses)); then + finish_test + nextProcessIndex=$(get_available_process_index) + fi + + testDirPaths[$nextProcessIndex]=$dirName + + run_test "$dirName" & + processIds[$nextProcessIndex]=$! + + ((++processCount)) +} + +# Handle Ctrl-C. +function handle_ctrl_c +{ + echo "" + echo "*** Stopping... ***" + print_results + exit $EXIT_CODE_EXCEPTION +} + +# $1 is the path of list file +function read_array() +{ + local theArray=() + + if [ ! -f "$1" ]; then + return + fi + + # bash in Mac OS X doesn't support 'readarray', so using alternate way instead. + # readarray -t theArray < "$1" + # Any line that starts with '#' is ignored. + while IFS='' read -r line || [ -n "$line" ]; do + if [[ $line != "#"* ]]; then + theArray[${#theArray[@]}]=$line + fi + done < "$1" + echo ${theArray[@]} +} + +# Get a list of directories in which to scan for tests by reading the +# specified file line by line. +function set_test_directories { + local listFileName=$1 + + if [ ! -f "$listFileName" ] + then + echo "Test directories file not found at $listFileName" + exit $EXIT_CODE_EXCEPTION + fi + testDirectories=($(read_array "$listFileName")) +} + +# $1 is the name of the platform folder (e.g Unix.AnyCPU.Debug) +function run_tests() +{ + for testFolder in $@ + do + start_test $testFolder + done +} + +# $1 is the path to the test folder +function run_test() +{ + local dirName="$1" + local testProject=`basename $1` + local outputDir="$testsOutputDir/$testProject" + + mkdir -p $outputDir + + local outputFilePath="$outputDir/log.out" + local outputXmlPath="$outputDir/testResults.xml" + + if [ ! -d "$dirName" ]; then + echo "Nothing to test in $testProject" > $outputFilePath 2>&1 + return $EXIT_CODE_EXCEPTION + fi + + if [ ! -e "$dirName/RunTests.sh" ]; then + echo "Cannot find $dirName/RunTests.sh" > $outputFilePath 2>&1 + return $EXIT_CODE_EXCEPTION + fi + + cd $dirName + + ./RunTests.sh "$coreOverlayDir" "$outerloop" "$outputXmlPath" "$tmpDir" > $outputFilePath 2>&1 + local testScriptExitCode=$? + + return $testScriptExitCode +} + +# Register the Ctrl-C handler +trap handle_ctrl_c INT + +# Exit code constants +readonly EXIT_CODE_SUCCESS=0 # Script ran normally. +readonly EXIT_CODE_EXCEPTION=1 # Script exited because something exceptional happened (e.g. bad arguments, Ctrl-C interrupt). +readonly EXIT_CODE_TEST_FAILURE=2 # Script completed successfully, but one or more tests failed. + +# Argument variables +testRootDir="/opt/usr/corefx-tc/tests" +coreOverlayDir="/opt/usr/corefx-tc/coreroot/" +doCopyNetcoreToCoreroot=0 +netcoreDir="/usr/share/dotnet.tizen/netcoreapp" +outputDir="/opt/usr/corefx-tc/results" +tmpDir="/opt/usr/corefx-tc/tmp" + +for i in "$@" +do + case $i in + -h|--help) + print_usage + exit $EXIT_CODE_SUCCESS + ;; + --testRootDir=*) + testRootDir=${i#*=} + ;; + --coreOverlayDir=*) + coreOverlayDir=${i#*=} + ;; + --outerloop=*) + outerloop=${i#*=} + ;; + --netcoreDir=*) + netcoreDir=${i#*=} + ;; + --copy-netcore-to-coreroot) + doCopyNetcoreToCoreroot=1 + ;; + --testDir=*) + testDirectories[${#testDirectories[@]}]=${i#*=} + ;; + --testDirFile=*) + set_test_directories "${i#*=}" + ;; + --num-procs=*) + ((maxProcesses = ${i#*=})) + ;; + --outputDir=*) + outputDir=${i#*=} + ;; + --tmpDir=*) + tmpDir=${i#*=} + ;; + *) + echo "Unknown switch: $i" + print_usage + exit $EXIT_CODE_SUCCESS + ;; + esac +done + +if [ -z "$testRootDir" ]; then + echo "--testRootDir is required." + print_usage + exit $EXIT_CODE_EXCEPTION +fi +if [ ! -d "$testRootDir" ]; then + echo "Directory specified by --testRootDir does not exist: $testRootDir" + exit $EXIT_CODE_EXCEPTION +fi + +if [ -z "$coreOverlayDir" ]; then + echo "--coreOverlayDir is required." + print_usage + exit $EXIT_CODE_EXCEPTION +fi +if [ ! -d "$coreOverlayDir" ]; then + echo "Directory specified by --coreOverlayDir does not exist: $coreOverlayDir" + exit $EXIT_CODE_EXCEPTION +fi + +if [ -z "$outerloop" ]; then + echo "--outerloop is required." + print_usage + exit $EXIT_CODE_EXCEPTION +fi + +export CORE_ROOT="$coreOverlayDir" + +echo "! Make sure CLR/FX are copied to $coreOverlayDir !" + +export PAL_OUTPUTDEBUGSTRING="1" + +if [ "$LANG" == "" ] +then + export LANG="en_US.UTF-8" +fi + +if [ $doCopyNetcoreToCoreroot == 1 ]; then + echo "Copying netcore ($netcoreDir) to coreroot ($coreOverlayDir)" + cp $netcoreDir/* $coreOverlayDir +fi + +echo "Cleanup old ni.dll" +for file in `find $testRootDir $coreOverlayDir -name "*.ni.*"`; do + rm $file +done + +testsOutputDir="$outputDir/tests" +mkdir -p $testsOutputDir +mkdir -p $tmpDir + +time_start=$(date +"%s") +if [ -z "$testDirectories" ] +then + # No test directories were specified, so run everything + testDirectories=( $(ls "$testRootDir/" | grep .Tests) ) +fi + +for testDir in "${testDirectories[@]}" +do + run_tests "$testRootDir/$testDir" +done + +finish_remaining_tests +print_results + +time_end=$(date +"%s") +time_diff=$(($time_end-$time_start)) +echo "$(($time_diff / 60)) minutes and $(($time_diff % 60)) seconds taken to run CoreFX tests." + +if [ "$countErroredDlls" -gt 0 ] || [ "$countErroredTests" -gt 0 ] || [ "$countFailedTests" -gt 0 ] +then + exit $EXIT_CODE_TEST_FAILURE +fi + +exit $EXIT_CODE_SUCCESS diff --git a/src/tests/Common/CLRTest.CrossGen.targets b/src/tests/Common/CLRTest.CrossGen.targets index 4d3e8ea..6300938 100644 --- a/src/tests/Common/CLRTest.CrossGen.targets +++ b/src/tests/Common/CLRTest.CrossGen.targets @@ -21,9 +21,6 @@ WARNING: When setting properties based on their current state (for example: $(BashScriptSnippetGen);GetCrossgenBashScript $(BatchScriptSnippetGen);GetCrossgenBatchScript - - - true - - > $__ResponseFile - - echo -o:$__OutputFile>>$__ResponseFile - echo -r:$CORE_ROOT/System.*.dll>>$__ResponseFile - echo -r:$CORE_ROOT/Microsoft.*.dll>>$__ResponseFile - echo -r:$CORE_ROOT/mscorlib.dll>>$__ResponseFile - echo --verify-type-and-field-layout>>$__ResponseFile - echo --targetarch:$(TargetArchitecture)>>$__ResponseFile - echo -O>>$__ResponseFile +# CrossGen2 Script +if [ ! -z ${RunCrossGen2+x} ]%3B then + if [ -d IL ]%3B then + echo Inconsistency, IL dir already exists, reinstall tests + exit 1 + fi - echo "Response file: $__ResponseFile" - cat $__ResponseFile + mkdir IL + mv *.dll IL/ - # Suppress some COMPlus variables for the duration of Crossgen2 execution - export -n COMPlus_GCName COMPlus_GCStress COMPlus_HeapVerify COMPlus_ReadyToRun + refs="" + for file in `find $CORE_ROOT -maxdepth 1 -name "*.dll" | grep -v ".ni.dll" | grep -v "xunit" `%3B do + refs="${refs} -r:$file" + done + for file in `find $PWD/IL -name "*.dll"`%3B do + refs="${refs} -r:$file" + done - echo "Running CrossGen2: $__Command" - $__Command - __cg2ExitCode=$? + extraCrossGen2Args="$(CrossGen2TestExtraArguments)" - export COMPlus_GCName COMPlus_GCStress COMPlus_HeapVerify COMPlus_ReadyToRun - } + for file in `find $PWD/IL -name "*.dll"`%3B do + filename=`basename $file` + outfile="$PWD/$filename" - if [ ! -z ${CompositeBuildMode+x} ]%3B then - ExtraCrossGen2Args+=" --composite" - OneFileCrossgen2 "$PWD/composite-r2r.dll" "$PWD/IL-CG2/*.dll" - else - ExtraCrossGen2Args+= -r:$PWD/IL-CG2/*.dll - for dllFile in $PWD/IL-CG2/*.dll - do - echo $dllFile - bareFileName="${dllFile##*/}" - OneFileCrossgen2 "$PWD/$bareFileName" "$dllFile" - if [ $__cg2ExitCode -ne 0 ]; then - break - fi - done - fi + __Command="$CORE_ROOT/corerun $CORE_ROOT/crossgen2/crossgen2.dll $CrossGen2Options $extraCrossGen2Args -o%3A$outfile $file ${refs}" - echo "Crossgen2 compilation finished, exit code $__cg2ExitCode" >> $compilationDoneFlagFile - if [ $__cg2ExitCode -ne 0 ]; then - echo Crossgen2 failed with exitcode: $__cg2ExitCode - ReleaseLock + echo "Running CrossGen2: $__Command" + COMPlus_MultiCoreJitProfile= $__Command + __cg2ExitCode=$? + if [ $__cg2ExitCode -ne 0 ] + then + mv IL/* . + rm -rf IL + echo Crossgen2 failed for $file with exitcode: $__cg2ExitCode exit 1 fi - fi - ReleaseLock - fi - - export COMPlus_ZapRequire=$(ZapRequire) - export COMPlus_ZapRequireList=$(MSBuildProjectName) + done fi ]]> + + + + $(BashCLRTestPreCommands);$(CrossgenBashScript) + $(BashCLRTestPostCommands);$(CrossgenCleanupBashScript) @@ -157,117 +127,11 @@ fi >!__ResponseFile! - echo -o:!__OutputFile!>>!__ResponseFile! - echo --targetarch:$(TargetArchitecture)>>!__ResponseFile! - echo --verify-type-and-field-layout>>!__ResponseFile! - echo --method-layout:random>>!__ResponseFile! - echo -r:!CORE_ROOT!\System.*.dll>>!__ResponseFile! - echo -r:!CORE_ROOT!\Microsoft.*.dll>>!__ResponseFile! - echo -r:!CORE_ROOT!\mscorlib.dll>>!__ResponseFile! - echo -r:!CORE_ROOT!\netstandard.dll>>!__ResponseFile! - echo -O>>!__ResponseFile! - - if not "$(__CreatePdb)" == "" ( - echo --pdb>>!__ResponseFile! - ) - - echo Response file: !__ResponseFile! - type !__ResponseFile! - - REM Suppress some COMPlus variables for the duration of Crossgen2 execution - setlocal - set "COMPlus_GCName=" - set "COMPlus_GCStress=" - set "COMPlus_HeapVerify=" - set "COMPlus_ReadyToRun=" - - echo "!__Command!" - call !__Command! - endlocal - set CrossGen2Status=!ERRORLEVEL! - Exit /b 0 - -:DoneCrossgen2Operations - echo Crossgen2 compilation finished, exit code !CrossGen2Status!>>!compilationDoneFlagFile! - call :ReleaseLock -:DoneCrossgen2OperationsNoRelease - IF NOT !CrossGen2Status!==0 ( - ECHO Crossgen2 failed with exitcode - !CrossGen2Status! - Exit /b 1 - ) - - set COMPlus_ZapRequire=$(ZapRequire) - set COMPlus_ZapRequireList=$(MSBuildProjectName) -) ]]> $(CLRTestBatchPreCommands);$(CrossgenBatchScript) + diff --git a/src/tests/baseservices/TieredCompilation/BasicTestWithMcj.csproj b/src/tests/baseservices/TieredCompilation/BasicTestWithMcj.csproj index 3ef80d9..8964617 100644 --- a/src/tests/baseservices/TieredCompilation/BasicTestWithMcj.csproj +++ b/src/tests/baseservices/TieredCompilation/BasicTestWithMcj.csproj @@ -42,7 +42,7 @@ mkdir r2r # Suppress some COMPlus variables for the duration of Crossgen2 execution export -n COMPlus_GCName COMPlus_GCStress COMPlus_HeapVerify COMPlus_ReadyToRun -"$CORE_ROOT/corerun" $CORE_ROOT/crossgen2/crossgen2.dll --out r2r/$(MSBuildProjectName).dll $(MSBuildProjectName).dll -r $CORE_ROOT/*.dll +"$CORE_ROOT/corerun" $CORE_ROOT/crossgen2/crossgen2.dll $CrossGen2Options --out r2r/$(MSBuildProjectName).dll $(MSBuildProjectName).dll -r $CORE_ROOT/*.dll export COMPlus_GCName COMPlus_GCStress COMPlus_HeapVerify COMPlus_ReadyToRun chmod +x ./RunBasicTestWithMcj.sh diff --git a/src/tests/build.proj b/src/tests/build.proj index e06e245..e71e28f 100644 --- a/src/tests/build.proj +++ b/src/tests/build.proj @@ -45,7 +45,7 @@ <_ConfigurationProperties>/p:TargetOS=$(TargetOS) /p:TargetArchitecture=$(TargetArchitecture) /p:Configuration=$(Configuration) /p:CrossBuild=$(CrossBuild) "$(DotNetTool)" restore $(RestoreProj) $(PackageVersionArg) /p:SetTFMForRestore=true $(_ConfigurationProperties) - "$(DotNetTool)" restore -r $(__DistroRid) $(RestoreProj) $(PackageVersionArg) /p:SetTFMForRestore=true $(_ConfigurationProperties) + "$(DotNetTool)" restore --ignore-failed-sources --source ../../.packages -r $(__DistroRid) $(RestoreProj) $(PackageVersionArg) /p:SetTFMForRestore=true $(_ConfigurationProperties) diff --git a/src/tests/readytorun/coreroot_determinism/Program.cs b/src/tests/readytorun/coreroot_determinism/Program.cs index ea537f2..78aebca 100644 --- a/src/tests/readytorun/coreroot_determinism/Program.cs +++ b/src/tests/readytorun/coreroot_determinism/Program.cs @@ -93,7 +93,10 @@ internal class Program Directory.Delete(outDir, true); } Directory.CreateDirectory(outDir); - ProcessStartInfo processStartInfo = new ProcessStartInfo(coreRunPath, $"{superIlcPath} compile-directory -cr {coreRootPath} -in {compilationInputFolder} --nojit --noexe --large-bubble --release --nocleanup -out {outDir}"); + + string crossgen2OptsR2RTest = Environment.GetEnvironmentVariable("CrossGen2OptionsR2RTest"); + + ProcessStartInfo processStartInfo = new ProcessStartInfo(coreRunPath, $"{superIlcPath} compile-directory -cr {coreRootPath} -in {compilationInputFolder} {crossgen2OptsR2RTest} --nojit --noexe --large-bubble --release --nocleanup -out {outDir}"); var process = Process.Start(processStartInfo); process.WaitForExit(); if (process.ExitCode != 0) diff --git a/src/tests/readytorun/determinism/crossgen2determinism.csproj b/src/tests/readytorun/determinism/crossgen2determinism.csproj index 029cb2a..16fa9c2 100644 --- a/src/tests/readytorun/determinism/crossgen2determinism.csproj +++ b/src/tests/readytorun/determinism/crossgen2determinism.csproj @@ -24,9 +24,9 @@ set CoreRT_DeterminismSeed=2 diff --git a/src/tests/readytorun/multifolder/multifolder.csproj b/src/tests/readytorun/multifolder/multifolder.csproj index 7011612..ea9527e 100644 --- a/src/tests/readytorun/multifolder/multifolder.csproj +++ b/src/tests/readytorun/multifolder/multifolder.csproj @@ -96,9 +96,9 @@ $(BashCLRTestPreCommands) if [ ! -z ${__TestDotNetCmd+x} ] %3B then __Command+=" $__TestDotNetCmd" else - __Command+=" dotnet" + __Command+=" $CORE_ROOT/corerun" fi - __Command+=" $CORE_ROOT/crossgen2/crossgen2.dll" + __Command+=" $CORE_ROOT/crossgen2/crossgen2.dll $CrossGen2Options" __Command+=" @$__ResponseFile" echo Response file: $__ResponseFile diff --git a/src/tests/readytorun/tests/mainv1.csproj b/src/tests/readytorun/tests/mainv1.csproj index 5e51ca9..8f9eb62 100644 --- a/src/tests/readytorun/tests/mainv1.csproj +++ b/src/tests/readytorun/tests/mainv1.csproj @@ -92,7 +92,7 @@ then echo Failed to copy test.dll exit 1 fi -$CORE_ROOT/corerun $CORE_ROOT/crossgen2/crossgen2.dll -r:$CORE_ROOT/*.dll -r:`pwd` -o:test.ni.dll test.dll +$CORE_ROOT/corerun $CORE_ROOT/crossgen2/crossgen2.dll $CrossGen2Options -r:$CORE_ROOT/*.dll -r:`pwd` -o:test.ni.dll test.dll __cgExitCode=$? if [ $__cgExitCode -ne 0 ] @@ -106,7 +106,7 @@ then exit 1 fi -$CORE_ROOT/corerun $CORE_ROOT/crossgen2/crossgen2.dll -r:$CORE_ROOT/*.dll -r:`pwd` -o:fieldgetter.ni.dll fieldgetter.dll +$CORE_ROOT/corerun $CORE_ROOT/crossgen2/crossgen2.dll $CrossGen2Options -r:$CORE_ROOT/*.dll -r:`pwd` -o:fieldgetter.ni.dll fieldgetter.dll __cgExitCode=$? if [ $__cgExitCode -ne 0 ] @@ -120,7 +120,7 @@ then exit 1 fi -$CORE_ROOT/corerun $CORE_ROOT/crossgen2/crossgen2.dll -r:$CORE_ROOT/*.dll -r:`pwd` -o:mainv1.ni.dll mainv1.dll +$CORE_ROOT/corerun $CORE_ROOT/crossgen2/crossgen2.dll $CrossGen2Options -r:$CORE_ROOT/*.dll -r:`pwd` -o:mainv1.ni.dll mainv1.dll __cgExitCode=$? if [ $__cgExitCode -ne 0 ] diff --git a/src/tests/readytorun/tests/mainv2.csproj b/src/tests/readytorun/tests/mainv2.csproj index 3d9794e..f1a6300 100644 --- a/src/tests/readytorun/tests/mainv2.csproj +++ b/src/tests/readytorun/tests/mainv2.csproj @@ -101,7 +101,7 @@ then exit 1 fi -$CORE_ROOT/corerun $CORE_ROOT/crossgen2/crossgen2.dll -r:$CORE_ROOT/*.dll -r:`pwd` -o:mainv2.ni.dll mainv2.dll +$CORE_ROOT/corerun $CORE_ROOT/crossgen2/crossgen2.dll $CrossGen2Options -r:$CORE_ROOT/*.dll -r:`pwd` -o:mainv2.ni.dll mainv2.dll __cgExitCode=$? if [ $__cgExitCode -ne 0 ] @@ -115,7 +115,7 @@ then exit 1 fi -$CORE_ROOT/corerun $CORE_ROOT/crossgen2/crossgen2.dll -r:$CORE_ROOT/*.dll -r:`pwd` -o:fieldgetter.ni.dll fieldgetter.dll +$CORE_ROOT/corerun $CORE_ROOT/crossgen2/crossgen2.dll $CrossGen2Options -r:$CORE_ROOT/*.dll -r:`pwd` -o:fieldgetter.ni.dll fieldgetter.dll __cgExitCode=$? if [ $__cgExitCode -ne 0 ] @@ -141,7 +141,7 @@ then exit 1 fi -$CORE_ROOT/corerun $CORE_ROOT/crossgen2/crossgen2.dll -r:$CORE_ROOT/*.dll -r:`pwd` -o:test.ni.dll test.dll +$CORE_ROOT/corerun $CORE_ROOT/crossgen2/crossgen2.dll $CrossGen2Options -r:$CORE_ROOT/*.dll -r:`pwd` -o:test.ni.dll test.dll __cgExitCode=$? if [ $__cgExitCode -ne 0 ] -- 2.7.4