Consolidate NCL stress testing infrastructure (#700)
authorEirik Tsarpalis <eirik.tsarpalis@gmail.com>
Thu, 12 Dec 2019 17:05:22 +0000 (19:05 +0200)
committerGitHub <noreply@github.com>
Thu, 12 Dec 2019 17:05:22 +0000 (19:05 +0200)
18 files changed:
eng/docker/Readme.md [new file with mode: 0644]
eng/docker/build-docker-sdk.ps1 [new file with mode: 0755]
eng/docker/libraries-sdk.linux.Dockerfile [moved from src/libraries/System.Net.Http/tests/StressTests/HttpStress/corefx.Dockerfile with 84% similarity]
eng/docker/libraries-sdk.windows.Dockerfile [moved from src/libraries/System.Net.Http/tests/StressTests/HttpStress/corefx.windows.Dockerfile with 86% similarity]
eng/pipelines/libraries/stress/http-linux.yml [deleted file]
eng/pipelines/libraries/stress/http-windows.yml [deleted file]
eng/pipelines/libraries/stress/http.yml [new file with mode: 0644]
eng/pipelines/libraries/stress/ssl-linux.yml [deleted file]
eng/pipelines/libraries/stress/ssl-windows.yml [deleted file]
eng/pipelines/libraries/stress/ssl.yml [new file with mode: 0644]
src/libraries/System.Net.Http/tests/StressTests/HttpStress/Readme.md
src/libraries/System.Net.Http/tests/StressTests/HttpStress/docker-compose.yml
src/libraries/System.Net.Http/tests/StressTests/HttpStress/load-corefx-testhost.ps1 [deleted file]
src/libraries/System.Net.Http/tests/StressTests/HttpStress/load-corefx-testhost.sh [deleted file]
src/libraries/System.Net.Http/tests/StressTests/HttpStress/run-docker-compose.ps1 [new file with mode: 0755]
src/libraries/System.Net.Security/tests/StressTests/SslStress/Readme.md
src/libraries/System.Net.Security/tests/StressTests/SslStress/docker-compose.yml
src/libraries/System.Net.Security/tests/StressTests/SslStress/run-docker-compose.ps1 [new file with mode: 0755]

diff --git a/eng/docker/Readme.md b/eng/docker/Readme.md
new file mode 100644 (file)
index 0000000..1e3cb2c
--- /dev/null
@@ -0,0 +1,30 @@
+# Docker Build Infrastructure
+
+Provides reusable docker build infrastructure for the dotnet/runtime repo.
+
+## libraries-sdk Dockerfiles
+
+The `libraries-sdk` Dockerfiles can be used to build dotnet sdk docker images
+that contain the current libraries built from source. 
+These images can be used to build dockerized dotnet services that target the current libraries.
+Currently, debian and windows nanoserver sdk's are supported.
+
+### Building the images
+
+To build the linux image locally
+
+```powershell
+PS> .\build-docker-sdk.ps1 -t dotnet-linux-sdk-current
+```
+
+and for Windows:
+
+```powershell
+PS> .\build-socker-sdk.ps1 -w -t dotnet-nanoserver-sdk-current
+```
+
+To use Debug builds:
+
+```powershell
+PS> .\build-docker-sdk.ps1 -c Debug -t dotnet-sdk-current
+```
diff --git a/eng/docker/build-docker-sdk.ps1 b/eng/docker/build-docker-sdk.ps1
new file mode 100755 (executable)
index 0000000..599c533
--- /dev/null
@@ -0,0 +1,35 @@
+#!/usr/bin/env pwsh
+# Builds libraries and produces a dotnet sdk docker image
+# that contains the current bits in its shared framework folder.
+
+[CmdletBinding(PositionalBinding=$false)]
+Param(
+  [string][Alias('t')]$imageName = "dotnet-sdk-libs-current",
+  [string][Alias('c')]$configuration = "Release",
+  [switch][Alias('w')]$buildWindowsContainers
+)
+
+$REPO_ROOT_DIR=$(git -C "$PSScriptRoot" rev-parse --show-toplevel)
+
+if ($buildWindowsContainers)
+{
+  # Due to size concerns, we don't currently do docker builds on windows.
+  # Build on the host machine, then simply copy artifacts to the target docker image.
+  # This should result in significantly lower build times, for now.
+  & "$REPO_ROOT_DIR/libraries.cmd" -ci -c $configuration
+  
+  # Dockerize the build artifacts
+  docker build --tag $imageName `
+      --build-arg CONFIGURATION=$configuration `
+      --build-arg TESTHOST_LOCATION=. `
+      --file "$PSScriptRoot/libraries-sdk.windows.Dockerfile" `
+      "$REPO_ROOT_DIR/artifacts/bin/testhost"
+}
+else 
+{
+  # Docker build libraries and copy to dotnet sdk image
+  docker build --tag $imageName `
+      --build-arg CONFIGURATION=$configuration `
+      --file "$PSScriptRoot/libraries-sdk.linux.Dockerfile" `
+      $REPO_ROOT_DIR
+}
@@ -1,5 +1,5 @@
-# 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
+# Builds and copies library artifacts into target dotnet sdk image
+ARG BUILD_BASE_IMAGE=mcr.microsoft.com/dotnet-buildtools/prereqs:centos-7-f39df28-20191023143754
 ARG SDK_BASE_IMAGE=mcr.microsoft.com/dotnet/core/sdk:3.0.100-buster
 
 FROM $BUILD_BASE_IMAGE as corefxbuild
@@ -9,7 +9,7 @@ COPY . .
 
 ARG CONFIGURATION=Release
 ARG BUILD_SCRIPT_NAME=libraries
-RUN ./$BUILD_SCRIPT_NAME.sh -c $CONFIGURATION
+RUN ./libraries.sh -c $CONFIGURATION
 
 FROM $SDK_BASE_IMAGE as target
 
@@ -1,8 +1,6 @@
 # escape=`
+# Simple Dockerfile which copies library build artifacts into target dotnet sdk image
 ARG SDK_BASE_IMAGE=mcr.microsoft.com/dotnet/core/sdk:3.0.100-nanoserver-1809
-
-# Simple Dockerfile which copies testhost shared framework artifacts into a target dotnet sdk image
-
 FROM $SDK_BASE_IMAGE as target
 
 ARG TESTHOST_LOCATION=".\\artifacts\\bin\\testhost"
diff --git a/eng/pipelines/libraries/stress/http-linux.yml b/eng/pipelines/libraries/stress/http-linux.yml
deleted file mode 100644 (file)
index fc55c8f..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-trigger: none
-
-pr:
-  branches:
-    include:
-    - "*"
-
-schedules:
-- cron: "0 13 * * *" # 1PM UTC => 5 AM PST
-  displayName: HttpStress nightly run
-  branches:
-    include:
-    - master
-
-pool:
-  name: Hosted Ubuntu 1604
-
-variables:
-  - template: ../variables.yml
-  - name: httpStressProject
-    value: $(sourcesRoot)/System.Net.Http/tests/StressTests/HttpStress/
-  - name: sdkBaseImage
-    value: sdk-corefx-current
-  - name: httpStressImage
-    value: httpstress
-
-steps:
-- checkout: self
-  clean: true
-  fetchDepth: 1
-  lfs: false
-
-- bash: |
-    docker build -t $(sdkBaseImage) --build-arg CONFIGURATION=$(BUILD_CONFIGURATION) --build-arg BUILD_SCRIPT_NAME=$(buildScriptFileName) -f $(HttpStressProject)corefx.Dockerfile .
-  displayName: Build Libraries
-
-- bash: |
-    cd '$(HttpStressProject)'
-    docker build -t $(httpStressImage) --build-arg SDK_BASE_IMAGE=$(sdkBaseImage) --build-arg CONFIGURATION=$(BUILD_CONFIGURATION) .
-  displayName: Build HttpStress
-
-- bash: |
-    cd '$(HttpStressProject)'
-    docker-compose up --abort-on-container-exit --no-color
-  displayName: Run HttpStress
-  env:
-    HTTPSTRESS_IMAGE: $(httpStressImage)
diff --git a/eng/pipelines/libraries/stress/http-windows.yml b/eng/pipelines/libraries/stress/http-windows.yml
deleted file mode 100644 (file)
index 41a5513..0000000
+++ /dev/null
@@ -1,62 +0,0 @@
-trigger: none
-
-pr:
-  branches:
-    include:
-    - "*"
-
-schedules:
-- cron: "0 13 * * *" # 1PM UTC => 5 AM PST
-  displayName: HttpStress nightly run
-  branches:
-    include:
-    - master
-
-pool:
-  vmImage: 'windows-latest'
-
-variables:
-  - template: ../variables.yml
-  - name: httpStressProject
-    value: $(sourcesRoot)/System.Net.Http/tests/StressTests/HttpStress/
-  - name: sdkBaseImage
-    value: sdk-corefx-current
-  - name: httpStressImage
-    value: httpstress
-
-steps:
-- checkout: self
-  clean: true
-  fetchDepth: 1
-  lfs: false
-
-- powershell: |
-    .\libraries.cmd -ci -c $(BUILD_CONFIGURATION)
-    docker build -t $(sdkBaseImage) `
-        --build-arg CONFIGURATION=$(BUILD_CONFIGURATION) `
-        --build-arg TESTHOST_LOCATION=. `
-        -f src/libraries/System.Net.Http/tests/StressTests/HttpStress/corefx.windows.Dockerfile `
-        artifacts/bin/testhost
-
-  displayName: Build Libraries
-
-- powershell: |
-    cd '$(HttpStressProject)'
-    docker build -t $(httpStressImage) --build-arg SDK_BASE_IMAGE=$(sdkBaseImage) --build-arg CONFIGURATION=$(BUILD_CONFIGURATION) -f windows.Dockerfile .
-  displayName: Build HttpStress
-
-- powershell: |
-    cd '$(HttpStressProject)'
-    docker-compose up --abort-on-container-exit --no-color
-  displayName: Run HttpStress
-  env:
-    HTTPSTRESS_IMAGE: $(httpStressImage)
-
-- 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/eng/pipelines/libraries/stress/http.yml b/eng/pipelines/libraries/stress/http.yml
new file mode 100644 (file)
index 0000000..c4916c5
--- /dev/null
@@ -0,0 +1,72 @@
+trigger: none
+
+pr:
+  branches:
+    include:
+    - "*"
+
+schedules:
+- cron: "0 13 * * *" # 1PM UTC => 5 AM PST
+  displayName: HttpStress nightly run
+  branches:
+    include:
+    - master
+
+variables:
+  - template: ../variables.yml
+  - name: dockerfilesFolder
+    value: $(Build.SourcesDirectory)/eng/docker
+  - name: httpStressProject
+    value: $(sourcesRoot)/System.Net.Http/tests/StressTests/HttpStress
+  - name: sdkBaseImage
+    value: dotnet-sdk-libraries-current
+
+
+jobs:
+
+- job: linux
+  displayName: Docker Linux
+  pool:
+    name: Hosted Ubuntu 1604
+
+  steps:
+  - checkout: self
+    clean: true
+    fetchDepth: 5
+  
+  - bash: |
+      $(dockerfilesFolder)/build-docker-sdk.ps1 -t $(sdkBaseImage) -c $(BUILD_CONFIGURATION)
+    displayName: Build Libraries
+  
+  - bash: |
+      $(httpStressProject)/run-docker-compose.ps1 -o -c $(BUILD_CONFIGURATION) -t $(sdkBaseImage)
+    displayName: Build HttpStress
+  
+  - bash: |
+      cd '$(httpStressProject)'
+      docker-compose up --abort-on-container-exit --no-color
+    displayName: Run HttpStress
+
+- job: windows
+  displayName: Docker Nano Server
+  pool:
+    vmImage: 'windows-latest'
+
+  steps:
+  - checkout: self
+    clean: true
+    fetchDepth: 1
+    lfs: false
+  
+  - pwsh: |
+      $(dockerfilesFolder)/build-docker-sdk.ps1 -w -t $(sdkBaseImage) -c $(BUILD_CONFIGURATION)
+    displayName: Build Libraries
+  
+  - pwsh: |
+      $(httpStressProject)/run-docker-compose.ps1 -w -o -c $(BUILD_CONFIGURATION) -t $(sdkBaseImage)
+    displayName: Build HttpStress
+  
+  - pwsh: |
+      cd '$(httpStressProject)'
+      docker-compose up --abort-on-container-exit --no-color
+    displayName: Run HttpStress
diff --git a/eng/pipelines/libraries/stress/ssl-linux.yml b/eng/pipelines/libraries/stress/ssl-linux.yml
deleted file mode 100644 (file)
index a06e6fc..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-trigger: none
-
-pr:
-  branches:
-    include:
-    - "*"
-
-schedules:
-- cron: "0 13 * * *" # 1PM UTC => 5 AM PST
-  displayName: SslStress nightly run
-  branches:
-    include:
-    - master
-
-pool:
-  name: Hosted Ubuntu 1604
-
-variables:
-  - template: ../variables.yml
-  - name: sslStressProject
-    value: $(sourcesRoot)/System.Net.Security/tests/StressTests/SslStress/
-    # Avoid duplication by referencing corefx build infrastructure hosted in HttpStress
-    # TODO move to eng/ folder.
-  - name: httpStressProject
-    value: $(sourcesRoot)/System.Net.Http/tests/StressTests/HttpStress/
-  - name: sdkBaseImage
-    value: sdk-corefx-current
-  - name: sslStressImage
-    value: sslstress
-
-steps:
-- checkout: self
-  clean: true
-  fetchDepth: 1
-  lfs: false
-
-- bash: |
-    docker build -t $(sdkBaseImage) --build-arg CONFIGURATION=$(BUILD_CONFIGURATION) --build-arg BUILD_SCRIPT_NAME=$(buildScriptFileName) -f $(httpStressProject)corefx.Dockerfile .
-  displayName: Build Libraries
-
-- bash: |
-    # we need to include the entire src/libraries folder in the build context due to Common/ dependencies
-    docker build -t $(sslStressImage) --build-arg SDK_BASE_IMAGE=$(sdkBaseImage) --build-arg CONFIGURATION=$(BUILD_CONFIGURATION) -f $(sslStressProject)/Dockerfile src/libraries
-  displayName: Build SslStress
-
-- bash: |
-    cd '$(sslStressProject)'
-    docker-compose up --abort-on-container-exit --no-color
-  displayName: Run SslStress
-  env:
-    HTTPSTRESS_IMAGE: $(sslStressImage)
diff --git a/eng/pipelines/libraries/stress/ssl-windows.yml b/eng/pipelines/libraries/stress/ssl-windows.yml
deleted file mode 100644 (file)
index a97d99b..0000000
+++ /dev/null
@@ -1,66 +0,0 @@
-trigger: none
-
-pr:
-  branches:
-    include:
-    - "*"
-
-schedules:
-- cron: "0 13 * * *" # 1PM UTC => 5 AM PST
-  displayName: SslStress nightly run
-  branches:
-    include:
-    - master
-
-pool:
-  vmImage: 'windows-latest'
-
-variables:
-  - template: ../variables.yml
-  - name: sslStressProject
-    value: $(sourcesRoot)/System.Net.Security/tests/StressTests/SslStress/
-    # Avoid duplication by referencing corefx build infrastructure hosted in HttpStress
-    # TODO move to eng/ folder.
-  - name: httpStressProject
-    value: $(sourcesRoot)/System.Net.Http/tests/StressTests/HttpStress/
-  - name: sdkBaseImage
-    value: sdk-corefx-current
-  - name: sslStressImage
-    value: sslstress
-
-steps:
-- checkout: self
-  clean: true
-  fetchDepth: 1
-  lfs: false
-
-- powershell: |
-    .\libraries.cmd -ci -c $(BUILD_CONFIGURATION)
-    docker build -t $(sdkBaseImage) `
-        --build-arg CONFIGURATION=$(BUILD_CONFIGURATION) `
-        --build-arg TESTHOST_LOCATION=. `
-        -f src/libraries/System.Net.Http/tests/StressTests/HttpStress/corefx.windows.Dockerfile `
-        artifacts/bin/testhost
-
-  displayName: Build Libraries
-
-- powershell: |
-    # we need to include the entire src/libraries folder in the build context due to Common/ dependencies
-    docker build -t $(sslStressImage) --build-arg SDK_BASE_IMAGE=$(sdkBaseImage) --build-arg CONFIGURATION=$(BUILD_CONFIGURATION) -f $(sslStressProject)/windows.Dockerfile src/libraries
-  displayName: Build SslStress
-
-- powershell: |
-    cd '$(sslStressProject)'
-    docker-compose up --abort-on-container-exit --no-color
-  displayName: Run SslStress
-  env:
-    SSLTRESS_IMAGE: $(sslStressImage)
-
-- task: PublishBuildArtifacts@1
-  displayName: Publish Logs
-  inputs:
-    PathtoPublish: '$(Build.SourcesDirectory)/artifacts/log/$(BUILD_CONFIGURATION)'
-    PublishLocation: Container
-    ArtifactName: 'sslstress_$(Agent.Os)_$(Agent.JobName)'
-  continueOnError: true
-  condition: always()
diff --git a/eng/pipelines/libraries/stress/ssl.yml b/eng/pipelines/libraries/stress/ssl.yml
new file mode 100644 (file)
index 0000000..2eac354
--- /dev/null
@@ -0,0 +1,72 @@
+trigger: none
+
+pr:
+  branches:
+    include:
+    - "*"
+
+schedules:
+- cron: "0 13 * * *" # 1PM UTC => 5 AM PST
+  displayName: SslStress nightly run
+  branches:
+    include:
+    - master
+
+variables:
+  - template: ../variables.yml
+  - name: dockerfilesFolder
+    value: $(Build.SourcesDirectory)/eng/docker
+  - name: sslStressProject
+    value: $(sourcesRoot)/System.Net.Security/tests/StressTests/SslStress
+  - name: sdkBaseImage
+    value: dotnet-sdk-libraries-current
+
+
+jobs:
+
+- job: linux
+  displayName: Docker Linux
+  pool:
+    name: Hosted Ubuntu 1604
+
+  steps:
+  - checkout: self
+    clean: true
+    fetchDepth: 5
+
+  - bash: |
+      $(dockerfilesFolder)/build-docker-sdk.ps1 -t $(sdkBaseImage) -c $(BUILD_CONFIGURATION)
+    displayName: Build Libraries
+
+  - bash: |
+      $(sslStressProject)/run-docker-compose.ps1 -o -c $(BUILD_CONFIGURATION) -t $(sdkBaseImage)
+    displayName: Build SslStress
+
+  - bash: |
+      cd '$(sslStressProject)'
+      docker-compose up --abort-on-container-exit --no-color
+    displayName: Run SslStress
+
+- job: windows
+  displayName: Docker Nano Server
+  pool:
+    vmImage: 'windows-latest'
+
+  steps:
+  - checkout: self
+    clean: true
+    fetchDepth: 1
+    lfs: false
+
+  - pwsh: |
+      $(dockerfilesFolder)/build-docker-sdk.ps1 -w -t $(sdkBaseImage) -c $(BUILD_CONFIGURATION)
+    displayName: Build Libraries
+  
+  - pwsh: |
+      $(sslStressProject)/run-docker-compose.ps1 -w -o -c $(BUILD_CONFIGURATION) -t $(sdkBaseImage)
+    displayName: Build SslStress
+  
+  - pwsh: |
+      cd '$(sslStressProject)'
+      docker-compose up --abort-on-container-exit --no-color
+    displayName: Run SslStress 
index f5ce264..b54efae 100644 (file)
@@ -1,6 +1,6 @@
 ## HttpStress
 
-Provides stress testing scenaria for System.Net.HttpClient, with emphasis on the HTTP/2 implementation of SocketsHttpHandler.
+Provides stress testing scenaria for System.Net.Http.HttpClient, with emphasis on the HTTP/2 implementation of SocketsHttpHandler.
 
 ### Running the suite locally
 
@@ -18,82 +18,39 @@ $ dotnet run -- -help
 
 ### Running with local runtime builds
 
-Note that the stress suite will test the sdk build available in the available,
+Note that the stress suite will test the sdk available in the environment,
 that is to say it will not necessarily test the implementation of the local runtime repo.
 To achieve this, you will need to point your environment to the [`testhost` build](https://github.com/dotnet/runtime/blob/master/docs/coreclr/building/testing-with-corefx.md).
 
-Using powershell on windows:
+### Running using docker-compose
 
-```powershell
-# Build runtime libraries from source
-PS> .\libraries.sh -c Release
-# Load the testhost sdk in the current environment, must match build configuration
-PS> . .\src\libraries\System.Net.Http\tests\StressTests\HttpStress\load-corefx-testhost.ps1 -c Release
-# run the stress suite with the new bits
-PS> cd .\src\libraries\System.Net.Http\tests\StressTests\HttpStress ; dotnet run -c Release -- <stress args>
-```
-
-Equivalently using bash on linux:
-
-```bash
-# Build runtime libraries from source
-$ ./libraries.sh -c Release
-# Load the testhost sdk in the current environment, must match build configuration
-$ source src/libraries/System.Net.Http/tests/StressTests/HttpStress/load-corefx-testhost.sh -c Release
-# run the stress suite with the new bits
-$ cd src/libraries/System.Net.Http/tests/StressTests/HttpStress && dotnet run -- <stress args>
-```
+The prefered way of running the stress suite is using docker-compose,
+which can be used to target both linux and windows containers.
+Docker and compose-compose are required for this step (both included in [docker for windows](https://docs.docker.com/docker-for-windows/)).
 
-### Running with docker
+#### Using Linux containers
 
-To run the stress suite in docker:
+From the stress folder on powershell:
 
-```bash
-$ cd src/libraries/System.Net.Http/tests/StressTests/HttpStress
-$ docker build -t httpstress .
-$ docker run --rm httpstress
+```powershell
+PS> .\run-docker-compose.ps1 -b
 ```
 
-This will build the stress suite using the `mcr.microsoft.com/dotnet/core/sdk` base image,
-however that can be overriden using the `SDK_BASE_IMAGE` build argument:
+This will build libraries and stress suite to a linux docker image and initialize a stress run using docker-compose.
 
-```bash
-$ docker build -t httpstress \
-    --build-arg SDK_BASE_IMAGE=my-sdk-3.1.100-preview1 \
-    .
-```
+#### Using Windows containers
 
-This should work with any base image with a dotnet sdk supporting `netcoreapp3.0`.
+Before we get started, please see 
+[docker documentation](https://docs.docker.com/docker-for-windows/#switch-between-windows-and-linux-containers) 
+on how windows containers can be enabled on your machine.
+Once ready, simply run:
 
-#### Using runtime bits
-
-To containerize httpstress using current runtime source code, from the root of the runtime repo do:
-```bash
-$ docker build -t sdk-corefx-current \
-    --build-arg BUILD_CONFIGURATION=Debug \
-    -f src/libraries/System.Net.Http/tests/StressTests/HttpStress/corefx.Dockerfile \
-    .
-```
-Then as before build the stress suite using the image we just built as our base image:
-```bash
-$ cd src/libraries/System.Net.Http/tests/StressTests/HttpStress/
-$ docker build -t httpstress \
-    --build-arg SDK_BASE_IMAGE=sdk-corefx-current \
-    .
+```powershell
+PS> .\run-docker-compose.ps1 -b -w
 ```
 
-### Orchestrating with docker-compose
+For more details on how the `run-docker-compose.ps1` script can be used:
 
-Once the httpstress image has been built successfully, 
-it is possible to orchestrate stress runs with client and server deployed to separate containers
-using docker-compose. 
-To do this, from the stress folder simply run
-```bash
-$ docker-compose up
-```
-Parameters of the stress run can be tuned by setting environment variables:
-```bash
-$ export HTTPSTRESS_CLIENT_ARGS='-maxExecutionTime 20'
-$ export HTTPSTRESS_SERVER_ARGS='-aspnetlog'
-$ docker-compose up
+```powershell
+Get-Help .\run-docker-compose.ps1
 ```
index f64eb30..e0e17c1 100644 (file)
@@ -1,13 +1,19 @@
 version: '3'
 services:
   client:
-    image: ${HTTPSTRESS_IMAGE:-httpstress}
+    build:
+      context: .
+      dockerfile: ${DOCKERFILE:-Dockerfile}
+    image: httpstress
     links:
       - server
     environment:
       - HTTPSTRESS_ARGS=-runMode client -serverUri https://server:5001 ${HTTPSTRESS_CLIENT_ARGS}
   server:
-    image: ${HTTPSTRESS_IMAGE:-httpstress}
+    build:
+      context: .
+      dockerfile: ${DOCKERFILE:-Dockerfile}
+    image: httpstress
     ports:
       - "5001:5001"
     environment:
diff --git a/src/libraries/System.Net.Http/tests/StressTests/HttpStress/load-corefx-testhost.ps1 b/src/libraries/System.Net.Http/tests/StressTests/HttpStress/load-corefx-testhost.ps1
deleted file mode 100644 (file)
index 16e8057..0000000
+++ /dev/null
@@ -1,152 +0,0 @@
-# Licensed to the .NET Foundation under one or more agreements.
-# The .NET Foundation licenses this file to you under the MIT license.
-# See the LICENSE file in the project root for more information.
-
-# Helper script used for pointing the current powershell environment 
-# to the testhost sdk built by the corefx build script.
-
-[CmdletBinding(PositionalBinding=$false)]
-Param(
-  [string][Alias('f')]$framework = "netcoreapp",
-  [string][Alias('c')]$configuration = "Debug",
-  [string][Alias('a')]$arch = "x64",
-  [string][Alias('o')]$os = "",
-  [switch][Alias('b')]$copyAspNetBits
-)
-
-# script needs to be sourced, detect if running standalone
-if ($MyInvocation.InvocationName -ne ".")
-{
-    write-output "Script must be sourced"
-    write-output "USAGE: . $($MyInvocation.InvocationName) <args>"
-    exit
-}
-
-# find corefx root, assuming script lives in the git repo
-$SOURCE_DIR="$(split-path -Parent $MyInvocation.MyCommand.Definition)"
-$COREFX_ROOT_DIR=$(git -C "$SOURCE_DIR" rev-parse --show-toplevel)
-
-function Find-Os()
-{
-    if (!$(test-path variable:IsWindows) -or $IsWindows)
-    {
-        return "Windows_NT"
-    } 
-    else
-    {
-        switch -Wildcard ($(uname -s))
-        {
-            "Linux*" { return "Linux" }
-            "Darwin*" { return "MacOS" }
-            "*" { return "Unix" }
-        }
-    }
-}
-
-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 = $(get-command dotnet).Source
-
-            try
-            {
-                # follow any symlinks if unix
-                $dotnet_path = $(readlink -f $dotnet_path)
-            }
-            catch [System.Management.Automation.CommandNotFoundException]
-            {
-
-            }
-
-            split-path -Path $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"))
-
-    if (!$(test-path -PathType container $candidate_path))
-    {
-        write-output "Could not locate testhost sdk path $candidate_path" 
-        return
-    }
-    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
-    $env:DOTNET_CLI_HOME=$candidate_path
-    $env:PATH=($candidate_path + $pathSeparator + $env:PATH)
-    $env:DOTNET_MULTILEVEL_LOOKUP=0
-    $env:DOTNET_ROLL_FORWARD_ON_NO_CANDIDATE_FX=2
-}
-
-
-Set-Sdk-Environment
diff --git a/src/libraries/System.Net.Http/tests/StressTests/HttpStress/load-corefx-testhost.sh b/src/libraries/System.Net.Http/tests/StressTests/HttpStress/load-corefx-testhost.sh
deleted file mode 100644 (file)
index ed06450..0000000
+++ /dev/null
@@ -1,134 +0,0 @@
-# Licensed to the .NET Foundation under one or more agreements.
-# The .NET Foundation licenses this file to you under the MIT license.
-# See the LICENSE file in the project root for more information.
-
-# Helper script used for pointing the current bash environment 
-# to the testhost sdk built by the corefx build script.
-
-# script needs to be sourced, detect if running standalone
-if [[ $0 = $_ ]]; then
-    echo "Script needs to be sourced"
-    echo "USAGE: . $0 <args>"
-    exit 1
-fi
-
-# find corefx root, assuming script lives in the git repo
-SOURCE_DIR="$(cd -P "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
-COREFX_ROOT_DIR=$(cd -P "$SOURCE_DIR" && git rev-parse --show-toplevel)
-
-usage()
-{
-    echo "Usage:"
-    echo "    -f <moniker>  Target framework: defaults to netcoreapp"
-    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()
-{
-    case $(uname -s) in
-        Linux*)     echo Linux;;
-        Darwin*)    echo MacOS;;
-        CYGWIN*)    echo Windows_NT;;
-        MINGW*)     echo Windows_NT;;
-        *)          echo Unix;;
-    esac
-}
-
-# parse command line args
-OS=$(detect_os)
-ARCH=x64
-FRAMEWORK=netcoreapp
-CONFIGURATION=Debug
-COPY_ASPNETCORE_BITS="false"
-
-OPTIND=1
-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"
-
-    if [ ! -d $candidate_path ]; then
-        echo "Could not locate testhost sdk path $candidate_path" 
-        return 1
-    elif [ ! -f $candidate_path/dotnet -a ! -f $candidate_path/dotnet.exe ]; then
-        echo "Could not find dotnet executable in testhost sdk path $candidate_path"
-        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
-    export DOTNET_ROLL_FORWARD_ON_NO_CANDIDATE_FX=2
-
-    if which cygpath > /dev/null 2>&1; then
-        # cygwin & mingw compat: PATH values must be unix style
-        export PATH=$(cygpath -u $candidate_path):$PATH
-    else
-        export PATH=$candidate_path:$PATH
-    fi
-}
-
-apply_to_environment
diff --git a/src/libraries/System.Net.Http/tests/StressTests/HttpStress/run-docker-compose.ps1 b/src/libraries/System.Net.Http/tests/StressTests/HttpStress/run-docker-compose.ps1
new file mode 100755 (executable)
index 0000000..81dd794
--- /dev/null
@@ -0,0 +1,54 @@
+#!/usr/bin/env pwsh
+# Runs the stress test using docker-compose
+
+[CmdletBinding(PositionalBinding=$false)]
+Param(
+    [string][Alias('c')]$configuration = "Release", # Build configuration for libraries and stress suite
+    [switch][Alias('w')]$useWindowsContainers, # Use windows containers, if available
+    [switch][Alias('b')]$buildCurrentLibraries, # Drives the stress test using libraries built from current source
+    [switch][Alias('o')]$buildOnly, # Build, but do not run the stress app
+    [string][Alias('t')]$sdkImageName, # Name of the sdk image name, if built from source.
+    [string]$clientStressArgs = "",
+    [string]$serverStressArgs = ""
+)
+
+$REPO_ROOT_DIR = $(git -C "$PSScriptRoot" rev-parse --show-toplevel)
+$COMPOSE_FILE = "$PSScriptRoot/docker-compose.yml"
+
+# Build runtime libraries and place in a docker image
+
+if ($buildCurrentLibraries)
+{
+    $LIBRARIES_BUILD_ARGS = " -t $sdkImageName -c $configuration"
+    if($useWindowsContainers)
+    {
+        $LIBRARIES_BUILD_ARGS += " -w"
+    }
+
+    Invoke-Expression "& $REPO_ROOT_DIR/eng/docker/build-docker-sdk.ps1 $LIBRARIES_BUILD_ARGS"
+
+    if (!$?) { exit 1 }
+}
+
+# Dockerize the stress app using docker-compose
+
+$BUILD_ARGS = ""
+if (![string]::IsNullOrEmpty($sdkImageName))
+{
+    $BUILD_ARGS += " --build-arg SDK_BASE_IMAGE=$sdkImageName"
+}
+if ($useWindowsContainers)
+{
+    $env:DOCKERFILE="windows.Dockerfile"
+}
+
+docker-compose --file "$COMPOSE_FILE" build $BUILD_ARGS.Split()
+
+# Run the stress app
+
+if (!$buildOnly)
+{
+    $env:SSLSTRESS_CLIENT_ARGS = $clientStressArgs
+    $env:SSLSTRESS_SERVER_ARGS = $serverStressArgs
+    docker-compose --file "$COMPOSE_FILE" up --abort-on-container-exit
+}
index 8193c18..04a0278 100644 (file)
@@ -1,3 +1,56 @@
 ## SslStress
 
-Stress testing suite for SslStream
+Provides stress testing scenaria for System.Net.Security.SslStream.
+
+### Running the suite locally
+
+Using the command line,
+
+```bash
+$ dotnet run -- <stress suite args>
+```
+
+To get the full list of available parameters:
+
+```bash
+$ dotnet run -- -help
+```
+
+### Running with local runtime builds
+
+Note that the stress suite will test the sdk available in the environment,
+that is to say it will not necessarily test the implementation of the local runtime repo.
+To achieve this, you will need to point your environment to the [`testhost` build](https://github.com/dotnet/runtime/blob/master/docs/coreclr/building/testing-with-corefx.md).
+
+### Running using docker-compose
+
+The prefered way of running the stress suite is using docker-compose,
+which can be used to target both linux and windows containers.
+Docker and compose-compose are required for this step (both included in [docker for windows](https://docs.docker.com/docker-for-windows/)).
+
+#### Using Linux containers
+
+From the stress folder on powershell:
+
+```powershell
+PS> .\run-docker-compose.ps1 -b
+```
+
+This will build the libraries and stress suite to a linux docker image and initialize a stress run using docker-compose.
+
+#### Using Windows containers
+
+Before we get started, please see 
+[docker documentation](https://docs.docker.com/docker-for-windows/#switch-between-windows-and-linux-containers) 
+on how windows containers can be enabled on your machine.
+Once ready, simply run:
+
+```powershell
+PS> .\run-docker-compose.ps1 -b -w
+```
+
+For more details on how the `run-docker-compose.ps1` script can be used:
+
+```powershell
+Get-Help .\run-docker-compose.ps1
+```
index ddf9b8c..0433022 100644 (file)
@@ -1,13 +1,17 @@
 version: '3'
 services:
   client:
-    image: ${SSLSTRESS_IMAGE:-sslstress}
+    build:
+      context: ../../../../ # ~> src/libraries
+      dockerfile: ./System.Net.Security/tests/StressTests/SslStress//${DOCKERFILE:-Dockerfile}
     links:
       - server
     environment:
       - SSLSTRESS_ARGS=--mode client --server-endpoint server:5001 ${SSLSTRESS_CLIENT_ARGS}
   server:
-    image: ${SSLSTRESS_IMAGE:-sslstress}
+    build:
+      context: ../../../../ # ~> src/libraries
+      dockerfile: ./System.Net.Security/tests/StressTests/SslStress/${DOCKERFILE:-Dockerfile}
     ports:
       - "5001:5001"
     environment:
diff --git a/src/libraries/System.Net.Security/tests/StressTests/SslStress/run-docker-compose.ps1 b/src/libraries/System.Net.Security/tests/StressTests/SslStress/run-docker-compose.ps1
new file mode 100755 (executable)
index 0000000..81dd794
--- /dev/null
@@ -0,0 +1,54 @@
+#!/usr/bin/env pwsh
+# Runs the stress test using docker-compose
+
+[CmdletBinding(PositionalBinding=$false)]
+Param(
+    [string][Alias('c')]$configuration = "Release", # Build configuration for libraries and stress suite
+    [switch][Alias('w')]$useWindowsContainers, # Use windows containers, if available
+    [switch][Alias('b')]$buildCurrentLibraries, # Drives the stress test using libraries built from current source
+    [switch][Alias('o')]$buildOnly, # Build, but do not run the stress app
+    [string][Alias('t')]$sdkImageName, # Name of the sdk image name, if built from source.
+    [string]$clientStressArgs = "",
+    [string]$serverStressArgs = ""
+)
+
+$REPO_ROOT_DIR = $(git -C "$PSScriptRoot" rev-parse --show-toplevel)
+$COMPOSE_FILE = "$PSScriptRoot/docker-compose.yml"
+
+# Build runtime libraries and place in a docker image
+
+if ($buildCurrentLibraries)
+{
+    $LIBRARIES_BUILD_ARGS = " -t $sdkImageName -c $configuration"
+    if($useWindowsContainers)
+    {
+        $LIBRARIES_BUILD_ARGS += " -w"
+    }
+
+    Invoke-Expression "& $REPO_ROOT_DIR/eng/docker/build-docker-sdk.ps1 $LIBRARIES_BUILD_ARGS"
+
+    if (!$?) { exit 1 }
+}
+
+# Dockerize the stress app using docker-compose
+
+$BUILD_ARGS = ""
+if (![string]::IsNullOrEmpty($sdkImageName))
+{
+    $BUILD_ARGS += " --build-arg SDK_BASE_IMAGE=$sdkImageName"
+}
+if ($useWindowsContainers)
+{
+    $env:DOCKERFILE="windows.Dockerfile"
+}
+
+docker-compose --file "$COMPOSE_FILE" build $BUILD_ARGS.Split()
+
+# Run the stress app
+
+if (!$buildOnly)
+{
+    $env:SSLSTRESS_CLIENT_ARGS = $clientStressArgs
+    $env:SSLSTRESS_SERVER_ARGS = $serverStressArgs
+    docker-compose --file "$COMPOSE_FILE" up --abort-on-container-exit
+}