Skip to content

Commit

Permalink
Fix bad plugin EndBuild exception handling during graph builds
Browse files Browse the repository at this point in the history
  • Loading branch information
cdmihai committed Feb 3, 2021
1 parent aaea331 commit 7b9afd9
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 17 deletions.
68 changes: 58 additions & 10 deletions src/Build.UnitTests/ProjectCache/ProjectCacheTests.cs
Expand Up @@ -818,16 +818,7 @@ public void EngineShouldHandleExceptionsFromCachePlugin(ExceptionLocations excep
</Target>
</Project>".Cleanup());

foreach (var enumValue in Enum.GetValues(typeof(ExceptionLocations)))
{
var typedValue = (ExceptionLocations) enumValue;
if (exceptionLocations.HasFlag(typedValue))
{
var exceptionLocation = typedValue.ToString();
_env.SetEnvironmentVariable(exceptionLocation, "1");
_output.WriteLine($"Set exception location: {exceptionLocation}");
}
}
SetEnvironmentForExceptionLocations(exceptionLocations);

using var buildSession = new Helpers.BuildManagerSession(
_env,
Expand Down Expand Up @@ -880,5 +871,62 @@ public void EngineShouldHandleExceptionsFromCachePlugin(ExceptionLocations excep
logger.FullLog.ShouldContain($"{AssemblyMockCache}: EndBuildAsync");
}
}

[Fact]
public void EndBuildShouldGetCalledOnceWhenItThrowsExceptionsFromGraphBuilds()
{
_env.DoNotLaunchDebugger();

var project = _env.CreateFile(
"1.proj",
@$"
<Project>
<ItemGroup>
<{ItemTypeNames.ProjectCachePlugin} Include=`{SamplePluginAssemblyPath.Value}` />
</ItemGroup>
<Target Name=`Build`>
<Message Text=`Hello EngineShouldHandleExceptionsFromCachePlugin` Importance=`High` />
</Target>
</Project>".Cleanup());

SetEnvironmentForExceptionLocations(ExceptionLocations.EndBuildAsync);

using var buildSession = new Helpers.BuildManagerSession(
_env,
new BuildParameters
{
UseSynchronousLogging = true
});

var logger = buildSession.Logger;

GraphBuildResult? buildResult = null;
Should.NotThrow(
() =>
{
buildResult = buildSession.BuildGraph(new ProjectGraph(project.Path));
});

buildResult!.OverallResult.ShouldBe(BuildResultCode.Failure);
buildResult.Exception.Message.ShouldContain("Cache plugin exception from EndBuildAsync");

buildSession.Dispose();

Regex.Matches(logger.FullLog, $"{nameof(AssemblyMockCache)}: EndBuildAsync").Count.ShouldBe(1);
}

private void SetEnvironmentForExceptionLocations(ExceptionLocations exceptionLocations)
{
foreach (var enumValue in Enum.GetValues(typeof(ExceptionLocations)))
{
var typedValue = (ExceptionLocations) enumValue;
if (exceptionLocations.HasFlag(typedValue))
{
var exceptionLocation = typedValue.ToString();
_env.SetEnvironmentVariable(exceptionLocation, "1");
_output.WriteLine($"Set exception location: {exceptionLocation}");
}
}
}
}
}
10 changes: 8 additions & 2 deletions src/Build/BackEnd/BuildManager/BuildManager.cs
Expand Up @@ -1943,8 +1943,14 @@ public void Dispose()

lock (_buildManager._syncLock)
{
_buildManager._projectCacheService?.Result.ShutDown().GetAwaiter().GetResult();
_buildManager._projectCacheService = null;
try
{
_buildManager._projectCacheService?.Result.ShutDown().GetAwaiter().GetResult();
}
finally
{
_buildManager._projectCacheService = null;
}
}
}
}
Expand Down
10 changes: 5 additions & 5 deletions src/Shared/UnitTests/ObjectModelHelpers.cs
Expand Up @@ -1950,6 +1950,11 @@ public GraphBuildResult BuildGraphSubmission(GraphBuildRequestData requestData)
return _buildManager.BuildRequest(requestData);
}

public GraphBuildResult BuildGraph(ProjectGraph graph, string[] entryTargets = null)
{
return _buildManager.BuildRequest(new GraphBuildRequestData(graph, entryTargets ?? new string[0]));
}

public void Dispose()
{
if (_disposed)
Expand All @@ -1962,11 +1967,6 @@ public void Dispose()
_buildManager.EndBuild();
_buildManager.Dispose();
}

public GraphBuildResult BuildGraph(ProjectGraph graph, string[] entryTargets = null)
{
return _buildManager.BuildRequest(new GraphBuildRequestData(graph, entryTargets ?? new string[0]));
}
}

internal class LoggingFileSystem : MSBuildFileSystemBase
Expand Down

0 comments on commit 7b9afd9

Please sign in to comment.