HttpStress: Add Stress Pipelines (dotnet/corefx#41833)
authorEirik Tsarpalis <eirik.tsarpalis@gmail.com>
Thu, 24 Oct 2019 23:02:30 +0000 (00:02 +0100)
committerGitHub <noreply@github.com>
Thu, 24 Oct 2019 23:02:30 +0000 (00:02 +0100)
Commit migrated from https://github.com/dotnet/corefx/commit/f41ba828c76126a871d986cb5b7e9c44ddf6f3d7

eng/pipelines/libraries/stress/http-linux.yml [new file with mode: 0644]
eng/pipelines/libraries/stress/http-windows.yml [new file with mode: 0644]
src/libraries/System.Net.Http/tests/StressTests/HttpStress/Dockerfile [new file with mode: 0644]
src/libraries/System.Net.Http/tests/StressTests/HttpStress/Readme.md
src/libraries/System.Net.Http/tests/StressTests/HttpStress/StressServer.cs
src/libraries/System.Net.Http/tests/StressTests/HttpStress/corefx.Dockerfile [new file with mode: 0644]
src/libraries/System.Net.Http/tests/StressTests/HttpStress/load-corefx-testhost.ps1
src/libraries/System.Net.Http/tests/StressTests/HttpStress/load-corefx-testhost.sh

diff --git a/eng/pipelines/libraries/stress/http-linux.yml b/eng/pipelines/libraries/stress/http-linux.yml
new file mode 100644 (file)
index 0000000..e1936fd
--- /dev/null
@@ -0,0 +1,28 @@
+trigger: none
+
+pool:
+  name: Hosted Ubuntu 1604
+
+variables:
+  httpStressProject: src/System.Net.Http/tests/StressTests/HttpStress
+  sdkBaseImage: sdk-corefx-current
+  httpStressImage: httpstress
+
+steps:
+- checkout: self
+  clean: true
+  fetchDepth: 0
+  lfs: false
+
+- bash: |
+    docker build -t $(sdkBaseImage) -f $(Build.SourcesDirectory)/$(HttpStressProject)/corefx.Dockerfile .
+  displayName: Build Corefx
+
+- bash: |
+    cd '$(Build.SourcesDirectory)/$(HttpStressProject)'
+    docker build -t $(httpStressImage) --build-arg SDK_BASE_IMAGE=$(sdkBaseImage) .
+  displayName: Build HttpStress
+
+- bash: |
+    docker run --rm -e HTTPSTRESS_ARGS='$(HTTPSTRESS_ARGS)' $(httpStressImage)
+  displayName: Run HttpStress
diff --git a/eng/pipelines/libraries/stress/http-windows.yml b/eng/pipelines/libraries/stress/http-windows.yml
new file mode 100644 (file)
index 0000000..a18de65
--- /dev/null
@@ -0,0 +1,34 @@
+trigger: none
+
+pool:
+  name: Hosted VS2017
+
+variables:
+  httpStressProject: src/System.Net.Http/tests/StressTests/HttpStress/
+
+steps:
+- checkout: self
+  clean: true
+  fetchDepth: 0
+  lfs: false
+
+- powershell: |
+    .\build.cmd -ci -c $(BUILD_CONFIGURATION)
+  displayName: Build Corefx
+
+- powershell: |
+    cd '$(Build.SourcesDirectory)/$(HttpStressProject)'
+    # Load testhost sdk in environment
+    . .\load-corefx-testhost.ps1 -c $(BUILD_CONFIGURATION) -b
+    # Run the stress suite
+    dotnet run -c $(BUILD_CONFIGURATION) -- $(HTTPSTRESS_ARGS)
+  displayName: Run HttpStress
+
+- task: PublishBuildArtifacts@1
+  displayName: Publish Logs
+  inputs:
+    PathtoPublish: '$(Build.SourcesDirectory)/artifacts/log/$(BUILD_CONFIGURATION)'
+    PublishLocation: Container
+    ArtifactName: 'httpstress_$(Agent.Os)_$(Agent.JobName)'
+  continueOnError: true
+  condition: always()
diff --git a/src/libraries/System.Net.Http/tests/StressTests/HttpStress/Dockerfile b/src/libraries/System.Net.Http/tests/StressTests/HttpStress/Dockerfile
new file mode 100644 (file)
index 0000000..8f6571a
--- /dev/null
@@ -0,0 +1,8 @@
+ARG SDK_BASE_IMAGE=mcr.microsoft.com/dotnet/core/sdk:3.0.100-buster
+FROM $SDK_BASE_IMAGE
+
+WORKDIR /app
+COPY . .
+
+ENV HTTPSTRESS_ARGS='-maxExecutionTime 30 -displayInterval 60'
+CMD dotnet run -c Release -- $HTTPSTRESS_ARGS
index 92ef65d..94d9f7a 100644 (file)
@@ -30,13 +30,9 @@ PS> .\build.sh -c Release
 # Load the testhost sdk in the current environment, must match build configuration
 PS> . .\src\System.Net.Http\tests\StressTests\HttpStress\load-corefx-testhost.ps1 -c Release
 # run the stress suite with the new bits
-PS> cd .\src\System.Net.Http\tests\StressTests\HttpStress ; dotnet run --runtime win10-x64 
+PS> cd .\src\System.Net.Http\tests\StressTests\HttpStress ; dotnet run -c Release -- <stress args>
 ```
 
-Note that the `--runtime` argument is necessary because `testhost` 
-does not bundle the required aspnetcore runtime dependencies.
-This will force the sdk to install the relevant native bits from nuget.
-
 Equivalently using bash on linux:
 
 ```bash
@@ -45,5 +41,5 @@ $ ./build.sh -c Release
 # Load the testhost sdk in the current environment, must match build configuration
 $ source src/System.Net.Http/tests/StressTests/HttpStress/load-corefx-testhost.sh -c Release
 # run the stress suite with the new bits
-$ cd src/System.Net.Http/tests/StressTests/HttpStress && dotnet run -r linux-x64 
+$ cd src/System.Net.Http/tests/StressTests/HttpStress && dotnet run -- <stress args>
 ```
\ No newline at end of file
index 6acec37..f81a71e 100644 (file)
@@ -289,7 +289,7 @@ namespace HttpStress
 
         private void SetUpJustInTimeLogging()
         {
-            if (_eventListener == null)
+            if (_eventListener == null && !Console.IsInputRedirected)
             {
                 // If no command-line requested logging, enable the user to press 'L' to enable logging to the console
                 // during execution, so that it can be done just-in-time when something goes awry.
diff --git a/src/libraries/System.Net.Http/tests/StressTests/HttpStress/corefx.Dockerfile b/src/libraries/System.Net.Http/tests/StressTests/HttpStress/corefx.Dockerfile
new file mode 100644 (file)
index 0000000..be62e71
--- /dev/null
@@ -0,0 +1,28 @@
+# Builds a dotnet sdk base image which contains corefx bits compiled from source
+ARG BUILD_BASE_IMAGE=mcr.microsoft.com/dotnet-buildtools/prereqs:rhel7_prereqs_2
+ARG SDK_BASE_IMAGE=mcr.microsoft.com/dotnet/core/sdk:3.0.100-buster
+
+FROM $BUILD_BASE_IMAGE as corefxbuild
+
+WORKDIR /repo
+COPY . .
+
+ARG CONFIG=Release
+RUN ./build.sh -c $CONFIG
+
+FROM $SDK_BASE_IMAGE as target
+
+ARG TESTHOST_LOCATION=/repo/artifacts/bin/testhost
+ARG TFM=netcoreapp
+ARG OS=Linux
+ARG ARCH=x64
+ARG CONFIG=Release
+
+ARG COREFX_SHARED_FRAMEWORK_NAME=Microsoft.NETCore.App
+ARG SOURCE_COREFX_VERSION=5.0.0
+ARG TARGET_SHARED_FRAMEWORK=/usr/share/dotnet/shared
+ARG TARGET_COREFX_VERSION=3.0.0
+
+COPY --from=corefxbuild \
+    $TESTHOST_LOCATION/$TFM-$OS-$CONFIG-$ARCH/shared/$COREFX_SHARED_FRAMEWORK_NAME/$SOURCE_COREFX_VERSION/* \
+    $TARGET_SHARED_FRAMEWORK/$COREFX_SHARED_FRAMEWORK_NAME/$TARGET_COREFX_VERSION/
index e6c7826..dfb3fa4 100644 (file)
@@ -10,7 +10,8 @@ Param(
   [string][Alias('f')]$framework = "netcoreapp",
   [string][Alias('c')]$configuration = "Debug",
   [string][Alias('a')]$arch = "x64",
-  [string][Alias('o')]$os = ""
+  [string][Alias('o')]$os = "",
+  [switch][Alias('b')]$copyAspNetBits
 )
 
 # script needs to be sourced, detect if running standalone
@@ -47,6 +48,73 @@ if ($os -eq "")
     $os=$(Find-Os)
 }
 
+# the corefx testhost does not bundle AspNetCore runtime bits;
+# fix up by copying from the bootstrap sdk 
+function Copy-Aspnetcore-Bits([string] $testhost_path)
+{
+
+    function find-bootstrap-sdk()
+    {
+        if (test-path -PathType container "$COREFX_ROOT_DIR/.dotnet")
+        {
+            "$COREFX_ROOT_DIR/.dotnet"
+        }
+        else
+        {
+            $dotnet_path = $(which dotnet)
+
+            # follow any symlinks if unix
+            if (which readlink)
+            {
+                $dotnet_path = $(readlink -f $dotnet_path)
+            }
+
+            $(dirname $dotnet_path)
+        }
+    }
+
+    $netfx_bits_folder="Microsoft.NETCore.App"
+    $aspnet_bits_folder="Microsoft.AspNetCore.App"
+
+    if (!(test-path -PathType container "$testhost_path/shared/$aspnet_bits_folder"))
+    {
+        $bootstrap_sdk=$(find-bootstrap-sdk)
+
+        function get-most-recent-version($path)
+        {
+            (Get-ChildItem -Directory "$path" `
+            | Select-Object -ExpandProperty Fullname `
+            | Split-Path -Leaf `
+            | ForEach-Object{[System.Version]$_} `
+            | Sort-Object -Descending `
+            | Select-Object -First 1).ToString()
+        }
+        
+        $netfx_runtime_version=$(get-most-recent-version "$testhost_path/shared/$netfx_bits_folder")
+        $aspnet_runtime_version=$(get-most-recent-version "$bootstrap_sdk/shared/$aspnet_bits_folder")
+
+        # copy the bits
+        mkdir -p "$testhost_path/shared/$aspnet_bits_folder/" > $null
+        copy-item -R "$bootstrap_sdk/shared/$aspnet_bits_folder/$aspnet_runtime_version" "$testhost_path/shared/$aspnet_bits_folder/$netfx_runtime_version"
+        if (!$?)
+        {
+            write-host "failed to copy aspnetcore bits"
+            return
+        }
+
+        $aspNetRuntimeConfig="$testhost_path/shared/$aspnet_bits_folder/$netfx_runtime_version/$aspnet_bits_folder.runtimeconfig.json"
+        if (test-path -PathType leaf "$aspNetRuntimeConfig")
+        {
+            # point aspnetcore runtimeconfig.json to current netfx version
+            # would prefer jq here but missing in many distros by default
+            $updated_content = $(get-content "$aspNetRuntimeConfig") -replace '"version"\s*:\s*"[^"]*"', "`"version`":`"$netfx_runtime_version`""
+            write-output $updated_content | Out-File -FilePath "$aspNetRuntimeConfig" -Encoding utf8
+        }
+
+        write-host "Copied Microsoft.AspNetCore.App runtime bits from $bootstrap_sdk"
+    }
+}
+
 function Set-Sdk-Environment()
 {
     $candidate_path=$([IO.Path]::Combine($COREFX_ROOT_DIR, 'artifacts', 'bin', 'testhost', "$FRAMEWORK-$OS-$CONFIGURATION-$ARCH"))
@@ -56,13 +124,18 @@ function Set-Sdk-Environment()
         write-output "Could not locate testhost sdk path $candidate_path" 
         return
     }
-    elseif (!$(test-path -PathType leaf $([IO.Path]::Combine($candidate_path, "dotnet"))) -and 
-            !$(test-path -PathType leaf $([IO.Path]::Combine($candidate_path, "dotnet.exe"))))
+    elseif (!$(test-path -PathType leaf "$candidate_path/dotnet") -and 
+            !$(test-path -PathType leaf "$candidate_path/dotnet.exe"))
     {
         write-output "Could not find dotnet executable in testhost sdk path $candidate_path"
         return
     }
 
+    if($copyAspNetBits)
+    {
+        Copy-Aspnetcore-Bits $candidate_path
+    }
+
     $pathSeparator=if($os -eq "Windows_NT") { ";" } else { ":" }
     
     $env:DOTNET_ROOT=$candidate_path
@@ -72,4 +145,5 @@ function Set-Sdk-Environment()
     $env:DOTNET_ROLL_FORWARD_ON_NO_CANDIDATE_FX=2
 }
 
+
 Set-Sdk-Environment
index e91fc26..ed06450 100644 (file)
@@ -14,7 +14,7 @@ fi
 
 # find corefx root, assuming script lives in the git repo
 SOURCE_DIR="$(cd -P "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
-COREFX_ROOT_DIR=$(git -C "$SOURCE_DIR" rev-parse --show-toplevel)
+COREFX_ROOT_DIR=$(cd -P "$SOURCE_DIR" && git rev-parse --show-toplevel)
 
 usage()
 {
@@ -23,6 +23,7 @@ usage()
     echo "    -c <config>   Build configuration: defaults to Debug"
     echo "    -a <arch>     Build architecture: defaults to netcoreapp"
     echo "    -o <os>       Operating system"
+    echo "    -b            Copy AspNetCore bits from bootstrap SDK"
 }
 
 detect_os()
@@ -41,19 +42,61 @@ OS=$(detect_os)
 ARCH=x64
 FRAMEWORK=netcoreapp
 CONFIGURATION=Debug
+COPY_ASPNETCORE_BITS="false"
 
 OPTIND=1
-while getopts "hf:c:a:o:" opt; do
+while getopts "hf:c:a:o:b" opt; do
     case $opt in
         f) FRAMEWORK=$OPTARG ;;
         c) CONFIGURATION=$OPTARG ;;
         a) ARCH=$OPTARG ;;
         o) OS=$OPTARG ;;
+        b) COPY_ASPNETCORE_BITS="true" ;;
         h) usage ; return 0 ;;
         *) usage ; return 1 ;;
     esac
 done
 
+# the corefx testhost does not bundle AspNetCore runtime bits;
+# fix up by copying from the bootstrap sdk 
+copy_aspnetcore_bits()
+{
+    testhost_path=$1
+
+    find_bootstrap_sdk()
+    {
+        if [ -d "$COREFX_ROOT_DIR/.dotnet" ]; then
+            echo $COREFX_ROOT_DIR/.dotnet
+        else
+            echo $(dirname "$(readlink -f "$(which dotnet)")")
+        fi
+    }
+
+    netfx_bits_folder="Microsoft.NETCore.App"
+    aspnet_bits_folder="Microsoft.AspNetCore.App"
+
+    if [ ! -d "$testhost_path/shared/$aspnet_bits_folder" ]; then
+
+        bootstrap_sdk=$(find_bootstrap_sdk)
+        netfx_runtime_version=$(ls "$testhost_path/shared/$netfx_bits_folder" | sort -V | tail -n1)
+        aspnet_runtime_version=$(ls "$bootstrap_sdk/shared/$aspnet_bits_folder" | sort -V | tail -n1)
+
+        # copy the bits
+        mkdir -p "$testhost_path/shared/$aspnet_bits_folder/"
+        cp -R "$bootstrap_sdk/shared/$aspnet_bits_folder/$aspnet_runtime_version" "$testhost_path/shared/$aspnet_bits_folder/$netfx_runtime_version"
+        [ $? -ne 0 ] && return 1
+
+        aspNetRuntimeConfig="$testhost_path/shared/$aspnet_bits_folder/$netfx_runtime_version/$aspnet_bits_folder.runtimeconfig.json"
+        if [ -f "$aspNetRuntimeConfig" ]; then
+            # point aspnetcore runtimeconfig.json to current netfx version
+            # would prefer jq here but missing in many distros by default
+            sed -i 's/"version"\s*:\s*"[^"]*"/"version":"'$netfx_runtime_version'"/g' "$aspNetRuntimeConfig"
+        fi
+
+        echo "Copied Microsoft.AspNetCore.App runtime bits from $bootstrap_sdk"
+    fi
+}
+
 apply_to_environment()
 {
     candidate_path="$COREFX_ROOT_DIR/artifacts/bin/testhost/$FRAMEWORK-$OS-$CONFIGURATION-$ARCH"
@@ -66,6 +109,15 @@ apply_to_environment()
         return 1
     fi
 
+    if [ $COPY_ASPNETCORE_BITS = "true" ]; then
+        copy_aspnetcore_bits $candidate_path
+    
+        if [ $? -ne 0 ]; then
+            echo "failed to copy aspnetcore bits"
+            return 1
+        fi
+    fi
+
     export DOTNET_ROOT=$candidate_path
     export DOTNET_CLI_HOME=$candidate_path
     export DOTNET_MULTILEVEL_LOOKUP=0