Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Build HttpStress and SslStress with live-built runtime using current TFM #61689

Merged
merged 20 commits into from
Nov 30, 2021

Conversation

antonfirsov
Copy link
Member

@antonfirsov antonfirsov commented Nov 16, 2021

As noted in #60769 (comment), the assumption that the live-built runtime of version (X+1).0 can be a drop-in replacement in an SDK of version X.0 is sometimes wrong, and it currently breaks our stress builds.

This PR changes both local (non-containerized) and containerized stress builds to build against the live-built runtime with the help of targetingpacks.targets.

Some tricky parts:

  • The docker builds no longer replace the shared dotnet runtime. Instead, we copy the live built runtime dll-s and ref dlls under /live-runtime-artifacts and reference that location from properties required by targetingpacks.targets
  • We also copy testhost to /live-runtime-artifacts. Tests are being executed by:
    TESTHOSTDIR/dotnet exec STRESSBINDIR/HttpStress.dll <args> .
  • Since I wanted to avoid using the entire repository as the container context, targetingpacks.targets also goes to /live-runtime-artifacts
  • HttpStress needs compatible (7.0) Microsoft.AspNetCore.App bits. These are acquired by getting the latest daily SDK build with dotnet-install.sh/ps1
  • To support local, non-containerized test execution helper scripts build-local.ps1/sh have been implemented. In case of HttpStress these scripts need to grab the daily SDK just like container scripts.
  • Visual Studio experience is now broken for HttpStress, but it can be "fixed" by temporary local hacks if necessary. We may open a tracking issue to fix this.

Fixes #60769.

/cc @ManickaP @safern

@ghost
Copy link

ghost commented Nov 16, 2021

Tagging subscribers to this area: @dotnet/ncl
See info in area-owners.md if you want to be subscribed.

Issue Details

As noted in #60769 (comment), the assumption that the live-built runtime of version (X+1).0 can be a drop-in replacement in an SDK of version X.0 is sometimes wrong, and it currently breaks our stress tests.

This PR changes both local (non-containerized) and containerized stress builds to build against the live-built runtime with the help of targetingpacks.targets.

Some tricky parts:

  • The docker builds no longer replace the shared dotnet runtime. Instead, we copy the live built runtime dll-s and ref dlls under /live-runtime-artifacts and reference that location from properties required by targetingpacks.targets
  • We also copy testhost to /live-runtime-artifacts. Tests being executed by TESTHOSTDIR/dotnet exec STRESSBINDIR/HttpStress.dll <args> then.
  • Since I wanted to avoid using the entire repository as the container context, targetingpacks.targets also goes to /live-runtime-artifacts
  • HttpStress needs compatible (7.0) Microsoft.AspNetCore.App bits. These are acquired by getting the latest daily SDK build with dotnet-install.sh/ps1
  • This mechanism replaces the outdated privateAspNetCore stuff implemented in Run stress tests on private Asp.Net Core package #33860
  • To support local, non-containerized test execution helper scripts build-local.ps1/sh have been implemented. In case of HttpStress these scripts need to grab the daily SDK just like container scripts.
  • Visual Studio experience is now broken for HttpStress, but it can be "fixed" by temporary local hacks if necessary

Fixes #60769.

Author: antonfirsov
Assignees: -
Labels:

area-System.Net

Milestone: -

{
// For some reason, System.Security.Cryptography.Encoding.dll fails to resolve when being loaded on-demand by AspNetCore.
// Enforce early-loading to workaround this issue.
_ = new Oid();
Copy link
Member Author

@antonfirsov antonfirsov Nov 16, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here is the error I get by removing this line:
https://dev.azure.com/dnceng/public/_build/results?buildId=1459792&view=logs&j=0da5d1d9-276d-5173-c4c4-9d4d4ed14fdb&t=6c56d998-158d-5232-283c-5140104799fc

I'm open to ideas or recommendations that can help getting rid of this hack, but I would like to avoid spending time root-causing the issue.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@wfurt any ideas? Should we file this as a separate issue? Or is this related to all the targeting pack magic around?

@antonfirsov

This comment has been minimized.

@antonfirsov

This comment has been minimized.

@dotnet dotnet deleted a comment from azure-pipelines bot Nov 19, 2021
@dotnet dotnet deleted a comment from azure-pipelines bot Nov 19, 2021
@dotnet dotnet deleted a comment from azure-pipelines bot Nov 19, 2021
@dotnet dotnet deleted a comment from azure-pipelines bot Nov 19, 2021
@dotnet dotnet deleted a comment from azure-pipelines bot Nov 19, 2021
@dotnet dotnet deleted a comment from azure-pipelines bot Nov 19, 2021
@dotnet dotnet deleted a comment from azure-pipelines bot Nov 19, 2021
@dotnet dotnet deleted a comment from azure-pipelines bot Nov 19, 2021
@antonfirsov
Copy link
Member Author

/azp run runtime-libraries stress-http

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@antonfirsov
Copy link
Member Author

I followed PS convention (Copy-Item, Write-Host etc), but you are right that all dotnet/runtime scripts are named in lowercase do-something.ps1 style, so I will rename.

@antonfirsov
Copy link
Member Author

/azp run runtime-libraries stress-http

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@antonfirsov
Copy link
Member Author

/azp run runtime-libraries stress-ssl

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@dotnet dotnet deleted a comment from azure-pipelines bot Nov 23, 2021
@@ -57,6 +57,7 @@ jobs:
export HTTPSTRESS_CLIENT_ARGS="$HTTPSTRESS_CLIENT_ARGS -http 3.0"
export HTTPSTRESS_SERVER_ARGS="$HTTPSTRESS_SERVER_ARGS -http 3.0"
docker-compose up --abort-on-container-exit --no-color
timeoutInMinutes: 35 # In case the HTTP/3.0 run hangs, we timeout shortly after the expected 30 minute run
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we know what happened? I see only blank screen (no output from the run)? Either way, we shouldn't hold this PR on it and investigate it separately.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It stopped logging after this line, then that log disappeared for some reason after the whole job becoming cancelled. Unfortunately I wasn't able to reproduce this behavior locally.

I would be surprised if this is caused by my changes, we haven't seen working stress runs on the CI for a while.

@ManickaP
Copy link
Member

I can build the HttpStress project, but I cannot run it:

It was not possible to find any compatible framework version
The framework 'Microsoft.NETCore.App', version '7.0.0' (x64) was not found.
...

I have 7.0.0-alpha.1.21567.1 installed globally. I vaguely remember being able to do that with 6.0...

@antonfirsov
Copy link
Member Author

antonfirsov commented Nov 23, 2021

Copy link
Member

@ManickaP ManickaP left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Proper first pass through the change (it's big 😄)
I haven't gotten to fully test this yet though.

eng/docker/build-docker-sdk.ps1 Outdated Show resolved Hide resolved
eng/docker/build-docker-sdk.ps1 Outdated Show resolved Hide resolved
eng/docker/build-docker-sdk.ps1 Outdated Show resolved Hide resolved
eng/docker/libraries-sdk.linux.Dockerfile Show resolved Hide resolved
eng/docker/libraries-sdk.linux.Dockerfile Show resolved Hide resolved
{
// For some reason, System.Security.Cryptography.Encoding.dll fails to resolve when being loaded on-demand by AspNetCore.
// Enforce early-loading to workaround this issue.
_ = new Oid();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@wfurt any ideas? Should we file this as a separate issue? Or is this related to all the targeting pack magic around?

@@ -0,0 +1,44 @@
#!/usr/bin/env bash
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this script same (or very similar) as the one in HttpStress? Should we somehow share it (in eng dir potentially)?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

HttpStress doesn't need Microsoft.AspNetCore.App so in that case it's much simpler. There is a lot of duplication including msbuild stuff and scripts, but moving these bits to a shared location would make things only harder to maintain. It's already pretty hard to track what lives in /eng/docker vs individual stress projects.

If we had a 3rd stress project that would make these bits worth to dedupe.

Comment on lines +15 to +16
stress_configuration=${1,,} # Lowercase all characters in $1
stress_configuration=${stress_configuration^} # Uppercase first character
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this really matter, I've been using lower-case interchangeably.

As a result, the whole if-else could be reduced to stress_configuration="${1:-Release}"

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sometimes the scripts refer to filesystem locations based on the configuration variable values:

testhost_root=$repo_root/artifacts/bin/testhost/net$version-Linux-$libraries_configuration-x64

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I learned the hard way it does matter in certain scenarios 🤣.
However, I was thinking how to make this more convenient to use, e.g.: testhost_root=$(ls -t -d $repo_root/artifacts/bin/testhost/net$version-Linux-*-x64 | head -n 1) which picks the most recent testhost dir if you do not specify which one you want to use.

So the script would work nicely without providing any argument with either release or debug testhost builds.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

BTW, this is just a suggestion for possible future improvement. I certainly won't hold the PR on this.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For now I just made it fail with a verbose message if you build it with the wrong config.

@ManickaP
Copy link
Member

ManickaP commented Nov 23, 2021

In case of local, did you use build-local.sh

No, I used to be able to build and run against globally installed SDK/runtime, which I've used extensively. Note that my connection is not so great to pull SDKs all the time, I usually install them globally once for all clones I have.

@antonfirsov
Copy link
Member Author

antonfirsov commented Nov 23, 2021

No, I used to be able to build and run against globally installed SDK/runtime, which I've used extensively. Note that my connection is not so great to pull SDKs all the time, I usually install them globally once for all clones I have.

After this PR, you really need the testhost to run the stress project. I don't know if there is a reliable way to hack the global dotnet host & runtime SDK to make dotnet run work with the live-built bits.

Note that my script does dotnet-install only the first time after cloning the repo just like build.sh in the root. If you really prefer to grab your globally installed Microsoft.AspNetCore.App, you need to copy it to testhost manually. If your main concern against the buildscript is the bandwidth usage, maybe we should expose a parameter aspnetlocation, so you can do:

./build-local.sh -aspnetlocation "/usr/share/dotnet/shared/Microsoft.AspNetCore.App/7.0.0-alpha.1.21567.1"

Copy link
Member

@ManickaP ManickaP left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!
The script for running stress with your local bits is very convenient, I like it a lot!

@antonfirsov
Copy link
Member Author

/azp run runtime-libraries stress-http

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@antonfirsov
Copy link
Member Author

/azp run runtime-libraries stress-ssl

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@antonfirsov antonfirsov merged commit 85642f8 into dotnet:main Nov 30, 2021
agocke added a commit that referenced this pull request Dec 1, 2021
@ghost ghost locked as resolved and limited conversation to collaborators Dec 30, 2021
@karelz karelz added this to the 7.0.0 milestone Jan 11, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

HttpStress and SslStress builds are broken
5 participants