Skip to content

Conversation

@novacole
Copy link

@novacole novacole commented Jan 3, 2024

Adds test execution caching when used with Microsoft.Build.RunVSTest microsoft/MSBuildSdks#473.
If a test project is a cache hit, test execution will be skipped and a message indicating that the test was skipped is logged.

Usage:
MSBuild /restore /graph /m /nr:false /reportfileaccesses /t:"Build;Test" /p:UseMSBuildTestInfrastructure="true"

Sample output
image


if (!nodeContext.TargetNames.SetEquals(buildRequest.TargetNames))
bool isBuildAndTestRequest = IsBuildAndTestRequest(buildRequest);
if (!nodeContext.TargetNames.SetEquals(buildRequest.TargetNames) && !isBuildAndTestRequest)
Copy link
Member

Choose a reason for hiding this comment

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

If the target names don't align, this seems like a correctness issue

Copy link
Author

@novacole novacole Jan 4, 2024

Choose a reason for hiding this comment

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

The targets don't align, MSBuildCache seems to ignore the Test target. That is, it is not included in nodeContext.TargetNames but it is in buildRequest.TargetNames

Copy link
Author

@novacole novacole Jan 4, 2024

Choose a reason for hiding this comment

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

reference: dotnet/msbuild#9569

await FinishNodeAsync(logger, nodeContext, pathSet, nodeBuildResult);
// In the case of a build-and-test request, we want to cache the build results but and the test execution (i.e, only execute tests on cache misses).
_ = bool.TryParse(projectInstance.GetPropertyValue("IsTestProject"), out bool isTestProject);
if (isBuildAndTestRequest && isTestProject)
Copy link
Member

Choose a reason for hiding this comment

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

if (isBuildAndTestRequest
  && bool.TryParse(projectInstance.GetPropertyValue("IsTestProject"), out bool isTestProject)
  && isTestProject)

if (isBuildAndTestRequest && isTestProject)
{
// this property can be read by downstream tasks, such as a Test Target, to determine if the test execution should be skipped
_ = projectInstance.SetProperty("SkipExecution", "true");
Copy link
Member

Choose a reason for hiding this comment

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

This seems dangerous for the cache plugin to mutate the project instance. I'm actually not even sure it even works in practice considering this is happening in the scheduler node and not the worker node.

Copy link
Author

Choose a reason for hiding this comment

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

This works from my testing.

Copy link
Author

Choose a reason for hiding this comment

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

Also, this is a property of the runvstest task/sdk not the test project

/// <returns>A bool value representing whether the build request is a build and test request.</returns>
private static bool IsBuildAndTestRequest(BuildRequestData buildRequest)
{
if (buildRequest == null)
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 can be null

return false;
}
// Check if the build request includes both "Build" and "Test" targets
bool isBuildAndTestRequest = buildRequest.TargetNames.Contains("Build") && buildRequest.TargetNames.Contains("Test");
Copy link
Member

Choose a reason for hiding this comment

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

This should be case-insensitive

@dfederm
Copy link
Member

dfederm commented Jan 3, 2024

I don't think I understand why the Test target is called out specifically, especially since the Build target isn't called out specifically today.

@novacole novacole closed this Jan 5, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants