[Tizen] Add RunTests.sh to each test dir and replace new runtest.sh with old one...
authorGleb Balykov <g.balykov@samsung.com>
Thu, 22 Aug 2019 16:24:38 +0000 (19:24 +0300)
committerKonstantin Baladurin <k.baladurin@samsung.com>
Wed, 25 Sep 2019 15:04:17 +0000 (18:04 +0300)
RunTests.sh [new file with mode: 0755]
packaging/corefx.spec
run-test.sh [new file with mode: 0755]

diff --git a/RunTests.sh b/RunTests.sh
new file mode 100755 (executable)
index 0000000..18fc34a
--- /dev/null
@@ -0,0 +1,164 @@
+#!/usr/bin/env bash
+
+export RUNTIME_PATH=${1%/}
+export EXECUTION_DIR=$(dirname "$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 -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
+}
+
+if [ "$RUNTIME_PATH" == "" ]
+then
+echo error: RUNTIME_PATH is not defined.  Usage: $0 RUNTIME_PATH
+exit -1
+fi
+
+# ========================= 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 +"%T") ===============  To repro directly: ===================================================== 
+echo pushd $EXECUTION_DIR
+echo "$RUNTIME_PATH/dotnet xunit.console.dll TEST_NAME_DLL -xml testResults.xml -nologo -notrait category=nonnetcoreapptests -notrait category=nonlinuxtests -notrait category=failing -notrait category=Outerloop"
+
+echo popd
+echo ===========================================================================================================
+pushd $EXECUTION_DIR
+$RUNTIME_PATH/dotnet xunit.console.dll TEST_NAME_DLL -xml testResults.xml -nologo -notrait category=nonnetcoreapptests -notrait category=nonlinuxtests -notrait category=failing -notrait category=Outerloop
+
+test_exitcode=$?
+popd
+echo ----- end $(date +"%T") ----- 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
+
index ea86191..d204c99 100755 (executable)
@@ -296,6 +296,15 @@ done
 
 rm -rf ./artifacts/bin/tests/artifacts
 
+for TEST in `find ./artifacts/bin/tests/ -type d -name "*.Tests"`
+do
+    TEST_NAME=$(echo ${TEST} | sed 's/.*\///')
+    TEST_DIR=$(find ${TEST} -name ${TEST_NAME}.dll)
+    TEST_DIR=$(echo ${TEST_DIR} | sed -r 's/(.+)\/.+/\1/')
+    sed "s/TEST_NAME_DLL/${TEST_NAME}.dll/" RunTests.sh > ${TEST_DIR}/RunTests.sh
+    chmod +x ${TEST_DIR}/RunTests.sh
+done
+
 cp ./artifacts/bin/tests/ %{buildroot}/opt/usr/%{tcdir} --parents -rf
 cp ./artifacts/bin/testhost %{buildroot}/opt/usr/%{tcdir} --parents -rf
 cp ./eng/run-test.sh %{buildroot}/opt/usr/%{tcdir}/
diff --git a/run-test.sh b/run-test.sh
new file mode 100755 (executable)
index 0000000..c549870
--- /dev/null
@@ -0,0 +1,439 @@
+#!/usr/bin/env bash
+
+wait_on_pids()
+{
+  # Wait on the last processes
+  for job in $1
+  do
+    wait $job
+    if [ "$?" -ne 0 ]
+    then
+      TestsFailed=$(($TestsFailed+1))
+    fi
+  done
+}
+
+usage()
+{
+    echo "Runs .NET CoreFX tests on FreeBSD, Linux, NetBSD or OSX"
+    echo "usage: run-test [options]"
+    echo
+    echo "Input sources:"
+    echo "    --runtime <location>              Location of root of the binaries directory"
+    echo "                                      containing the FreeBSD, Linux, NetBSD or OSX runtime"
+    echo "                                      default: <repo_root>/bin/testhost/netcoreapp-<OS>-<ConfigurationGroup>-<Arch>"
+    echo "    --corefx-tests <location>         Location of the root binaries location containing"
+    echo "                                      the tests to run"
+    echo "                                      default: <repo_root>/bin"
+    echo
+    echo "Flavor/OS/Architecture options:"
+    echo "    --configurationGroup <config>     ConfigurationGroup to run (Debug/Release)"
+    echo "                                      default: Debug"
+    echo "    --os <os>                         OS to run (FreeBSD, Linux, NetBSD or OSX)"
+    echo "                                      default: detect current OS"
+    echo "    --arch <Architecture>             Architecture to run (x64, arm, armel, x86, arm64)"
+    echo "                                      default: detect current architecture"
+    echo
+    echo "Execution options:"
+    echo "    --sequential                      Run tests sequentially (default is to run in parallel)."
+    echo "    --restrict-proj <regex>           Run test projects that match regex"
+    echo "                                      default: .* (all projects)"
+    echo "    --useServerGC                     Enable Server GC for this test run"
+    echo "    --test-dir <path>                 Run tests only in the specified directory. Path is relative to the directory"
+    echo "                                      specified by --corefx-tests"
+    echo "    --test-dir-file <path>            Run tests only in the directories specified by the file at <path>. Paths are"
+    echo "                                      listed one line, relative to the directory specified by --corefx-tests"
+    echo "    --test-exclude-file <path>        Do not run tests in the directories specified by the file at <path>. Paths are"
+    echo "                                      listed one line, relative to the directory specified by --corefx-tests"
+    echo "    --timeout <time>                  Specify a per-test timeout value (using 'timeout' tool syntax; default is 10 minutes (10m))"
+    echo
+    echo "Runtime Code Coverage options:"
+    echo "    --coreclr-coverage                Optional argument to get coreclr code coverage reports"
+    echo "    --coreclr-objs <location>         Location of root of the object directory"
+    echo "                                      containing the FreeBSD, Linux, NetBSD or OSX coreclr build"
+    echo "                                      default: <repo_root>/bin/obj/<OS>.x64.<ConfigurationGroup"
+    echo "    --coreclr-src <location>          Location of root of the directory"
+    echo "                                      containing the coreclr source files"
+    echo
+    exit 1
+}
+
+# Handle Ctrl-C.
+function handle_ctrl_c {
+  local errorSource='handle_ctrl_c'
+
+  echo ""
+  echo "Cancelling test execution."
+  exit $TestsFailed
+}
+
+# Register the Ctrl-C handler
+trap handle_ctrl_c INT
+
+ProjectRoot="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
+# Location parameters
+# OS/ConfigurationGroup defaults
+ConfigurationGroup="Debug"
+OSName=$(uname -s)
+case $OSName in
+    Darwin)
+        OS=OSX
+        ;;
+
+    FreeBSD)
+        OS=FreeBSD
+        ;;
+
+    Linux)
+        OS=Linux
+        ;;
+
+    NetBSD)
+        OS=NetBSD
+        ;;
+
+    *)
+        echo "Unsupported OS $OSName detected, configuring as if for Linux"
+        OS=Linux
+        ;;
+esac
+
+# Use uname to determine what the CPU is.
+CPUName=$(uname -p)
+# Some Linux platforms report unknown for platform, but the arch for machine.
+if [ "$CPUName" == "unknown" ]; then
+    CPUName=$(uname -m)
+fi
+
+case $CPUName in
+    i686)
+        echo "Unsupported CPU $CPUName detected, test might not succeed!"
+        __Arch=x86
+        ;;
+
+    x86_64)
+        __Arch=x64
+        ;;
+
+    armv7l)
+        __Arch=armel
+        ;;
+
+    aarch64)
+        __Arch=arm64
+        ;;
+    amd64)
+        __Arch=x64
+        ;;
+    *)
+        echo "Unknown CPU $CPUName detected, configuring as if for x64"
+        __Arch=x64
+        ;;
+esac
+
+# Misc defaults
+TestSelection=".*"
+TestsFailed=0
+
+ensure_binaries_are_present()
+{
+  if [ ! -d $Runtime ]
+  then
+    echo "error: Coreclr $OS binaries not found at $Runtime"
+    exit 1
+  fi
+}
+
+# $1 is the path of list file
+read_array()
+{
+  local theArray=()
+
+  while IFS='' read -r line || [ -n "$line" ]; do
+    theArray[${#theArray[@]}]=$line
+  done < "$1"
+  echo ${theArray[@]}
+}
+
+run_selected_tests()
+{
+  local selectedTests=()
+
+  if [ -n "$TestDirFile" ]; then
+    selectedTests=($(read_array "$TestDirFile"))
+  fi
+
+  if [ -n "$TestDir" ]; then
+    selectedTests[${#selectedTests[@]}]="$TestDir"
+  fi
+
+  run_all_tests ${selectedTests[@]/#/$CoreFxTests/}
+}
+
+# $1 is the name of the platform folder (e.g Unix.AnyCPU.Debug)
+run_all_tests()
+{
+  for testFolder in $@
+  do
+     run_test $testFolder &
+     pids="$pids $!"
+     numberOfProcesses=$(($numberOfProcesses+1))
+     if [ "$numberOfProcesses" -ge $maxProcesses ]; then
+       wait_on_pids "$pids"
+       numberOfProcesses=0
+       pids=""
+     fi
+  done
+
+  # Wait on the last processes
+  wait_on_pids "$pids"
+  pids=""
+}
+
+# $1 is the path to the test folder
+run_test()
+{
+  testProject=`basename $1`
+
+  # Check for project restrictions
+
+  if [[ ! $testProject =~ $TestSelection ]]; then
+    echo "Skipping $testProject"
+    exit 0
+  fi
+
+  if [ -n "$TestExcludeFile" ]; then
+    if grep -q $testProject "$TestExcludeFile" ; then
+      echo "Excluding $testProject"
+      exit 0
+    fi
+  fi
+
+  dirName="$1/netcoreapp-$OS-$ConfigurationGroup-$__Arch"
+  if [ ! -d "$dirName" ]; then
+    echo "Nothing to test in $testProject"
+    return
+  fi
+
+  if [ ! -e "$dirName/RunTests.sh" ]; then
+      echo "Cannot find $dirName/RunTests.sh"
+      return
+  fi
+
+  pushd $dirName > /dev/null
+
+  echo
+  echo "Running tests in $dirName"
+  echo "${TimeoutTool}./RunTests.sh $Runtime"
+  echo
+  ${TimeoutTool}./RunTests.sh "$Runtime"
+  exitCode=$?
+
+  if [ $exitCode -ne 0 ]
+  then
+      echo "error: One or more tests failed while running tests from '$fileNameWithoutExtension'.  Exit code $exitCode."
+  fi
+
+  popd > /dev/null
+  exit $exitCode
+}
+
+coreclr_code_coverage()
+{
+  if [ ! "$OS" == "FreeBSD" ] && [ ! "$OS" == "Linux" ] && [ ! "$OS" == "NetBSD" ] && [ ! "$OS" == "OSX" ]
+  then
+      echo "error: Code Coverage not supported on $OS"
+      exit 1
+  fi
+
+  if [ "$CoreClrSrc" == "" ]
+    then
+      echo "error: Coreclr source files are required to generate code coverage reports"
+      echo "Coreclr source files root path can be passed using '--coreclr-src' argument"
+      exit 1
+  fi
+
+  local coverageDir="$ProjectRoot/artifacts/bin/Coverage"
+  local toolsDir="$coverageDir/tools"
+  local reportsDir="$coverageDir/reports"
+  local packageName="unix-code-coverage-tools.1.0.0.nupkg"
+  rm -rf $coverageDir
+  mkdir -p $coverageDir
+  mkdir -p $toolsDir
+  mkdir -p $reportsDir
+  pushd $toolsDir > /dev/null
+
+  echo "Pulling down code coverage tools"
+
+  which curl > /dev/null 2> /dev/null
+  if [ $? -ne 0 ]; then
+    wget -q -O $packageName https://www.myget.org/F/dotnet-buildtools/api/v2/package/unix-code-coverage-tools/1.0.0
+  else
+    curl -sSL -o $packageName https://www.myget.org/F/dotnet-buildtools/api/v2/package/unix-code-coverage-tools/1.0.0
+  fi
+
+  echo "Unzipping to $toolsDir"
+  unzip -q -o $packageName
+
+  # Invoke gcovr
+  chmod a+rwx ./gcovr
+  chmod a+rwx ./$OS/llvm-cov
+
+  echo
+  echo "Generating coreclr code coverage reports at $reportsDir/coreclr.html"
+  echo "./gcovr $CoreClrObjs --gcov-executable=$toolsDir/$OS/llvm-cov -r $CoreClrSrc --html --html-details -o $reportsDir/coreclr.html"
+  echo
+  ./gcovr $CoreClrObjs --gcov-executable=$toolsDir/$OS/llvm-cov -r $CoreClrSrc --html --html-details -o $reportsDir/coreclr.html
+  exitCode=$?
+  popd > /dev/null
+  exit $exitCode
+}
+
+# Parse arguments
+
+RunTestSequential=0
+((serverGC = 0))
+TimeoutTime=20m
+
+while [[ $# > 0 ]]
+do
+    opt="$1"
+    case $opt in
+        -h|--help)
+        usage
+        ;;
+        --runtime)
+        Runtime=$2
+        ;;
+        --corefx-tests)
+        CoreFxTests=$2
+        ;;
+        --restrict-proj)
+        TestSelection=$2
+        ;;
+        --configurationGroup)
+        ConfigurationGroup=$2
+        ;;
+        --os)
+        OS=$2
+        ;;
+        --arch)
+        __Arch=$2
+        ;;
+        --coreclr-coverage)
+        CoreClrCoverage=ON
+        ;;
+        --coreclr-objs)
+        CoreClrObjs=$2
+        ;;
+        --coreclr-src)
+        CoreClrSrc=$2
+        ;;
+        --sequential)
+        RunTestSequential=1
+        ;;
+        --useServerGC)
+        ((serverGC = 1))
+        ;;
+        --test-dir)
+        TestDir=$2
+        ;;
+        --test-dir-file)
+        TestDirFile=$2
+        ;;
+        --test-exclude-file)
+        TestExcludeFile=$2
+        ;;
+        --timeout)
+        TimeoutTime=$2
+        ;;
+        --outerloop)
+        OuterLoop=""
+        ;;
+        --IgnoreForCI)
+        IgnoreForCI="-notrait category=IgnoreForCI"
+        ;;
+        *)
+        ;;
+    esac
+    shift
+done
+
+# Compute paths to the binaries if they haven't already been computed
+
+if [ "$Runtime" == "" ]
+then
+    Runtime="$ProjectRoot/artifacts/bin/testhost/netcoreapp-$OS-$ConfigurationGroup-$__Arch"
+fi
+
+if [ "$CoreFxTests" == "" ]
+then
+    CoreFxTests="$ProjectRoot/artifacts/bin"
+fi
+
+# Check parameters up front for valid values:
+
+if [ ! "$ConfigurationGroup" == "Debug" ] && [ ! "$ConfigurationGroup" == "Release" ]
+then
+    echo "error: ConfigurationGroup should be Debug or Release"
+    exit 1
+fi
+
+if [ ! "$OS" == "FreeBSD" ] && [ ! "$OS" == "Linux" ] && [ ! "$OS" == "NetBSD" ] && [ ! "$OS" == "OSX" ]
+then
+    echo "error: OS should be FreeBSD, Linux, NetBSD or OSX"
+    exit 1
+fi
+
+export CORECLR_SERVER_GC="$serverGC"
+export PAL_OUTPUTDEBUGSTRING="1"
+
+if [ "$LANG" == "" ]
+then
+    export LANG="en_US.UTF-8"
+fi
+
+# Is the 'timeout' tool available?
+TimeoutTool=
+if hash timeout 2>/dev/null ; then
+  TimeoutTool="timeout --kill-after=30s $TimeoutTime "
+fi
+
+ensure_binaries_are_present
+
+# Walk the directory tree rooted at src bin/tests/$OS.AnyCPU.$ConfigurationGroup/
+
+TestsFailed=0
+numberOfProcesses=0
+
+if [ $RunTestSequential -eq 1 ]
+then
+    maxProcesses=1;
+else
+    if [ `uname` = "NetBSD" ] || [ `uname` = "FreeBSD" ]; then
+      maxProcesses=$(($(getconf NPROCESSORS_ONLN)+1))
+    else
+      maxProcesses=$(($(getconf _NPROCESSORS_ONLN)+1))
+    fi
+fi
+
+if [ -n "$TestDirFile" ] || [ -n "$TestDir" ]
+then
+    run_selected_tests
+else
+    run_all_tests "$CoreFxTests/tests/"*.Tests
+fi
+
+if [ "$CoreClrCoverage" == "ON" ]
+then
+    coreclr_code_coverage
+fi
+
+if [ "$TestsFailed" -gt 0 ]
+then
+    echo "$TestsFailed test(s) failed"
+else
+    echo "All tests passed."
+fi
+
+exit $TestsFailed