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

[tests] Add support for running EndToEnd tests on helix with the aspire workload #2534

Merged
merged 49 commits into from
Mar 7, 2024

Conversation

radical
Copy link
Member

@radical radical commented Feb 29, 2024

Problem:

  1. We want to run some EndToEnd tests on CI, which can dotnet run an aspire project,
    and allow individual tests to interact with the services.
    This requires:

    • Ability to build, and run an aspire project - IOW, a sdk with the aspire workload installed.
    • docker
  2. Also, allow using TestProject.* in tests/testproject, in two modes:

    • in-tree test run which directly reference aspire projects, and repo targets
    • out-of-tree test runs which uses a SDK+workload based on local build output

Solution:

SDK+workload

  • SDK with version from global.json is installed into artifacts/bin/dotnet-{none,latest}
    • The aspire workload is installed into the sdk using the nuget packages in artifacts/packages with a version like 8.0.0-{dev,ci}
  • this also allows running tests that do dotnet new aspire-starter; dotnet run same as a user
  • this utilizes an internal nuget from dotnet/runtime

TestProject

  • This can switch between the two test run modes using the msbuild property $(TestsRunningOutsideRepo)
    • when running in-tree the test project directly references hosting targets, and aspire projects via ProjectReference
    • when running out-of-tree the ProjectReferences and imports are replaced with PackageReferences to the Aspire nugets
  • Default is to run in-tree

Helix

TL;dr or How do I use this?

Steps to prepare for out-of-tree runs

  1. .\build.cmd -pack - to build all the nugets
  2. dotnet build tests/Aspire.EndToEnd.Tests/Aspire.EndToEnd.csproj /t:InstallWorkloadUsingArtifacts /p:Configuration=<config>
    • this will install the sdk, and the aspire workload using the nugets from artifacts/packages
  • at this point the sdk is usable outside the repo too. Note: you need to add artifacts/packages/$(Configuration)/Shipping as a nuget source so the locally built packages can be picked up.

Using it from VS

  • No difference when running the EndToEnd tests in in-tree mode
  • For switching to out-of-tree add <TestsRunningOutsideRepo>true</TestsRunningOutsideRepo> to tests/Aspire.EndToEnd.Tests/Directory.props before any imports.
    • tests cannot be run at this point as they will fail complaining about artifacts/bin/dotnet-latest being missing
    • Install the sdk+workload following the steps above
    • Run/debug the tests normally now, and they will be using the sdk
    • Also note that in this case the testproject is run from the bindir for Aspire.EndToEnd.Tests, so a path like artifacts/bin/Aspire.EndToEnd.Tests/Debug/net8.0/testassets/testproject/

Using it from command line

  • No difference when running the EndToEnd tests in in-tree mode
  • Install the sdk+workload following the steps above
  • When running the tests you can either:
    • set <TestsRunningOutsideRepo>true</TestsRunningOutsideRepo> to tests/Aspire.EndToEnd.Tests/Directory.props before any imports
    • or set the environment variable TestsRunningOutsideRepo=true

Other details

  • tests/Shared/WorkloadTesting - has sources essentially from dotnet/runtime's Wasm.Build.Tests
  • TestProject supports skipping individual resources like --skip-resources oracledatabase,cosmos
  • .runsettings with 15min timeout
  • xunit.runner.json - to get diagnostic messages
  • The core infrastructure is not specific for Aspire.EndToEnd.Tests, and will get used by other test projects in the future
Microsoft Reviewers: Open in CodeFlow

- add a xunit.runner.json, .runsettings
- update tests to skip resources as needed
- update test fixture to work with sdk+workload for testing
- reference workload.testing nuget from dotnet/runtime
- Extra some workload properties needed to a Workload.props, used in
  more than once place now

- Microsoft.NET.Sdk.Aspire: set `PackageType=''` to the manifest nuget is not
  `dotnetplatform`, and can be installed directly by the workload
  testing tasks.
@dotnet-issue-labeler dotnet-issue-labeler bot added the area-integrations Issues pertaining to Aspire Integrations packages label Feb 29, 2024
@radical radical requested review from eerhardt and joperezr February 29, 2024 04:08
@radical
Copy link
Member Author

radical commented Feb 29, 2024

  • Questions:
    • should a forced container cleanup be done at the end?
    • nuget-cache - Is it OK to expect the dev to manually delete aspire packages from the cache?
      • PR uses a new nuget-cache path for every run, which is slow on slow connections, but good on fast ones
    • Microsoft.NET.Sdk.Aspire: set PackageType='' to the manifest nuget is notdotnetplatform, and can be installed directly by the workload testing tasks. Check that nothing else is affected, and this is an acceptable change.

TODO:

  • nuget.helix.config - Use the root nuget.config and insert the built-nugets source

@joperezr
Copy link
Member

joperezr commented Mar 1, 2024

Talked offline with @radical, marking as ready for review as this is ready for feedback.

@joperezr joperezr marked this pull request as ready for review March 1, 2024 00:22
</packageSources>
<packageSourceMapping>
<!-- used for installing test workloads for resolving aspire workload manifest -->
<packageSource key="nuget-local">
Copy link
Member

Choose a reason for hiding this comment

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

Where is this package source defined?

Copy link
Member Author

Choose a reason for hiding this comment

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

https://github.com/dotnet/runtime/blob/f135699310bccfa83b3b441d2f4f1571fe8df480/src/tasks/WorkloadBuildTasks/InstallWorkloadFromArtifacts.cs#L262

I agree that it does seem odd that you can't directly see what this links up to in the repo. I can have the package source name be passed to the task, which would be in aspire repo.

Copy link
Member

Choose a reason for hiding this comment

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

Does this throw a warning at all on the initial restore before the task has a chance to replace the source? Did we also consider manually passing in -s <path> to a manual invocation of restore instead of having this in the config?

Copy link
Member Author

Choose a reason for hiding this comment

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

No warnings. Wouldn't -s path only add a package source but not the mapping, and because of that restoring from the source would fail. That is what I hit when I removed this mapping.

Copy link
Member Author

Choose a reason for hiding this comment

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

Once dotnet/runtime#99277 is merged this entry can be removed, and it would be added at build time.

Directory.Packages.props Outdated Show resolved Hide resolved
tests/nuget.helix.config Outdated Show resolved Hide resolved
<HelixPreCommand Condition="'$(OS)' == 'Windows_NT'" Include="set SDK_FOR_WORKLOAD_TESTING_PATH=%HELIX_CORRELATION_PAYLOAD%\%SDK_DIR_NAME%" />
<HelixPreCommand Condition="'$(OS)' != 'Windows_NT'" Include="export SDK_FOR_WORKLOAD_TESTING_PATH=$HELIX_CORRELATION_PAYLOAD/$SDK_DIR_NAME" />

<HelixPreCommand Condition="'$(OS)' == 'Windows_NT'" Include="set TestsRunningOutOfTree=true" />
Copy link
Member

Choose a reason for hiding this comment

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

I'm not sure how much I like the term "running out of tree". I think there are 2 things about it I don't like:

  1. I think I'd rather use the term "repo" than "tree".
  2. "Running out of" actually makes it sound like that's where the tests are from. Like the phrase "fighting out of the blue corner".

Possible suggestions:

  • TestingOutsideOfSourceRepo
  • TestsNotInRepo
  • TestsNotContainedInRepo

I think at a minimum change OutOf to OutsideOf and I'll be OK with the name. TestsRunningOutsideOfTree

tests/Aspire.EndToEnd.Tests/ProjectInfo.cs Outdated Show resolved Hide resolved
Comment on lines +6 to +8
<!-- no docker support on helix/windows yet -->
<RunTestsOnHelix Condition="'$(OS)' != 'Windows_NT'">true</RunTestsOnHelix>
<SkipTests Condition="'$(OS)' == 'Windows_NT'">true</SkipTests>
Copy link
Member

Choose a reason for hiding this comment

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

Can we just say RunTestsOnHelix=true all the time, and then do these checks inside the tests? Similar to how I did it in RabbitMQ in #2345. It just feels cleaner that way.

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes we can do it like that also. The reason for "also" is that if we don't have any tests that would get run, then not skipping the whole thing would mean:

  1. installing sdk+workload - extra step on CI
  2. sending this work item to helix with the big payload (sdk) for nothing to run, which dnceng kinda frowns upon.

I think we can add the attributes also, and for the specific case (windows) where nothing can run, we skip in the project file too. Thoughts?

Copy link
Member

Choose a reason for hiding this comment

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

How long until we are able to run these tests on Windows?


<BuiltNuGetsDir>$(ArtifactsShippingPackagesDir)</BuiltNuGetsDir>
<PackageVersionForWorkloadManifests>$(PackageVersion)</PackageVersionForWorkloadManifests>
<DefineConstants Condition="'$(TestsRunningOutOfTree)' == 'true'">TESTS_RUNNING_OUT_OF_TREE;$(DefineConstants)</DefineConstants>
Copy link
Member

Choose a reason for hiding this comment

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

Can we get this from an env var when the test runs so we don't have to have an #if in the code?

Copy link
Member Author

Choose a reason for hiding this comment

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

I had to add this just for the VS run, so you need to set only one property in one file to have the tests switch.
Using env var works perfectly well when running from command line, but I don't know what the workflow can be for setting it in case of VS. Open to suggestions.

Comment on lines 53 to 55
-t:InstallWorkloadUsingArtifacts
-bl:${{ parameters.repoLogPath }}/WorkloadInstallForTesting.binlog
$(Build.SourcesDirectory)/tests/Aspire.EndToEnd.Tests/Aspire.EndToEnd.Tests.csproj
Copy link
Member

Choose a reason for hiding this comment

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

Is it weird to pick the EndToEnd tests to have this "InstallWorkloadUsingArtifacts" target? It seems like something that should be coming from an "infrastructure" project. Not one of the test projects.

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes, I was thinking of fixing it in a follow up though. But I can try to do it here too.

Copy link
Member Author

Choose a reason for hiding this comment

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

I'll keep this for a follow up PR, unless you think it should be done here itsefl


public class TestProgram : IDisposable
{
private TestProgram(string[] args, Assembly assembly, bool includeIntegrationServices, bool includeNodeApp, bool disableDashboard)
{
if (args.Contains("--disable-dashboard"))
IList<TestResourceNames> resourcesToSkip = [];
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 actually need this resourcesToSkip? If we just skipped the cosmos and oracle tests, wouldn't that be enough? Yes it would still spin up those containers during the tests, but nothing would try to connect to them.

I don't really like all these if conditions everywhere. It really clutters up the code.

Copy link
Member Author

@radical radical Mar 1, 2024

Choose a reason for hiding this comment

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

We have one test that health checks on the whole thing, and that would continue to fail.

I don't really like all these if conditions everywhere. It really clutters up the code.

agree!

tests/Aspire.EndToEnd.Tests/IntegrationServicesFixture.cs Outdated Show resolved Hide resolved
eng/Version.Details.xml Outdated Show resolved Hide resolved
eng/Versions.props Outdated Show resolved Hide resolved
@@ -10,8 +10,6 @@
<VSTemp>$(WorkloadIntermediateOutputPath)VS/</VSTemp>
<WorkloadOutputPath>$(ArtifactsBinDir)workloads/</WorkloadOutputPath>
<WorkloadOutputPath Condition="'$(workloadArtifactsPath)' != ''">$(workloadArtifactsPath)/</WorkloadOutputPath>
<PackageSource>$(ArtifactsShippingPackagesDir)</PackageSource>
<PackageSource Condition="'$(workloadPackagesPath)' != ''">$(workloadPackagesPath)/</PackageSource>
Copy link
Member

Choose a reason for hiding this comment

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

Does this mean that this cannot get overriden any longer? cc: @danegsta in case he is aware if we depend 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.

Where does $(workloadPackagesPath) get set? I didn't find any reference to it in the repo.

Copy link
Member

Choose a reason for hiding this comment

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

Should be fine as long as the workload still builds correctly

eng/dcppack/dcppack.csproj Outdated Show resolved Hide resolved
@radical
Copy link
Member Author

radical commented Mar 6, 2024

@eerhardt I tried to add oracledb back, but it failed because the test timeout was 5minutes. I think we continue with that in a follow up PR, so reverting that change.

@@ -26,7 +26,7 @@

<Target Name="Build" />

<Target Name="BeforeBuild" BeforeTargets="Build">
<Target Name="BeforeBuild" BeforeTargets="_GetPackageFiles">
Copy link
Member

Choose a reason for hiding this comment

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

Why do we need this change? In general, it's best to avoid depending on "private" tragets (Targets that start with an underscore)

Copy link
Member Author

Choose a reason for hiding this comment

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

I wanted to limit this target to only when we are generating a nuget.

Is this target needed only for generating the zip file? Is the zip file used for the dashboard docker image?

Copy link
Member

Choose a reason for hiding this comment

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

This target mainly accomplishes two things:

  • Adds the right content to the each of the dashboard packs (which actually may no longer be needed now that we have the dashboard as a tool) cc: @danegsta
  • Zips up the published output as that will be uploaded as a blob so that it can then be used to build the docker image for the dashboard.

Copy link
Member Author

Choose a reason for hiding this comment

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

Reverted.

eng/dcppack/dcppack.csproj Outdated Show resolved Hide resolved
@@ -21,6 +21,7 @@ parameters:
steps:
- script: ${{ parameters.buildScript }}
-restore -build
-pack
Copy link
Member

Choose a reason for hiding this comment

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

We are already running pack as a separate step (check line 98 in this file). Can we either change the ordering so that happens before the steps that run the tests, or alternatively just remove that whole step if it is no longer needed?

Copy link
Member Author

Choose a reason for hiding this comment

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

Good point. This pack could conflict with the subsequent pack, since that one is signed. I will investigate this in a separate PR. And it will really be needed only when we have this running on windows again.
For now, I will add -pack only for linux, where the separate pack step is not defined at all.

Copy link
Member

@joperezr joperezr left a comment

Choose a reason for hiding this comment

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

Added a few comments/suggestions but the rest LGTM.

@radical
Copy link
Member Author

radical commented Mar 7, 2024

Follow-up work is being tracked in #2687 .

@radical radical merged commit ea3e182 into dotnet:main Mar 7, 2024
8 checks passed
@radical radical deleted the e2e-testing-helix branch March 7, 2024 05:14
@github-actions github-actions bot locked and limited conversation to collaborators Apr 20, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-integrations Issues pertaining to Aspire Integrations packages
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants