Skip to content

Commit

Permalink
Add IVT for UnitTestingHostReloadService (#54366)
Browse files Browse the repository at this point in the history
Co-authored-by: David Wengier <david.wengier@microsoft.com>
  • Loading branch information
vritant24 and davidwengier committed Jun 25, 2021
1 parent ee996f2 commit 2384855
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3682,7 +3682,7 @@ public async Task UnitTestingHotReloadServiceTest()

var hotReload = new UnitTestingHotReloadService(workspace.Services);

await hotReload.StartSessionAsync(solution, CancellationToken.None);
await hotReload.StartSessionAsync(solution, ImmutableArray.Create("Baseline", "AddDefinitionToExistingType", "NewTypeDefinition"), CancellationToken.None);

var sessionId = hotReload.GetTestAccessor().SessionId;
var session = encService.GetTestAccessor().GetDebuggingSession(sessionId);
Expand All @@ -3694,13 +3694,13 @@ public async Task UnitTestingHotReloadServiceTest()

solution = solution.WithDocumentText(documentIdA, SourceText.From(source2, Encoding.UTF8));

var result = await hotReload.EmitSolutionUpdateAsync(solution, CancellationToken.None);
var result = await hotReload.EmitSolutionUpdateAsync(solution, true, CancellationToken.None);
Assert.Empty(result.diagnostics);
Assert.Equal(1, result.updates.Length);

solution = solution.WithDocumentText(documentIdA, SourceText.From(source3, Encoding.UTF8));

result = await hotReload.EmitSolutionUpdateAsync(solution, CancellationToken.None);
result = await hotReload.EmitSolutionUpdateAsync(solution, true, CancellationToken.None);
AssertEx.Equal(
new[] { "ENC0020: " + string.Format(FeaturesResources.Renaming_0_will_prevent_the_debug_session_from_continuing, FeaturesResources.method) },
result.diagnostics.Select(d => $"{d.Id}: {d.GetMessage()}"));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,17 +19,21 @@ internal sealed class UnitTestingHotReloadService
{
private sealed class DebuggerService : IManagedEditAndContinueDebuggerService
{
public static readonly DebuggerService Instance = new();
private readonly ImmutableArray<string> _capabilities;

public DebuggerService(ImmutableArray<string> capabilities)
{
_capabilities = capabilities;
}

public Task<ImmutableArray<ManagedActiveStatementDebugInfo>> GetActiveStatementsAsync(CancellationToken cancellationToken)
=> Task.FromResult(ImmutableArray<ManagedActiveStatementDebugInfo>.Empty);

public Task<ManagedEditAndContinueAvailability> GetAvailabilityAsync(Guid module, CancellationToken cancellationToken)
=> Task.FromResult(new ManagedEditAndContinueAvailability(ManagedEditAndContinueAvailabilityStatus.Available));

// TODO: get capabilities from the runtime
public Task<ImmutableArray<string>> GetCapabilitiesAsync(CancellationToken cancellationToken)
=> Task.FromResult(ImmutableArray.Create("Baseline", "AddDefinitionToExistingType", "NewTypeDefinition"));
=> Task.FromResult(_capabilities);

public Task PrepareModuleForUpdateAsync(Guid module, CancellationToken cancellationToken)
=> Task.CompletedTask;
Expand Down Expand Up @@ -64,24 +68,27 @@ public UnitTestingHotReloadService(HostWorkspaceServices services)
/// Starts the watcher.
/// </summary>
/// <param name="solution">Solution that represents sources that match the built binaries on disk.</param>
/// <param name="capabilities">Array of capabilities retrieved from the runtime to dictate supported rude edits.</param>
/// <param name="cancellationToken">Cancellation token.</param>
public async Task StartSessionAsync(Solution solution, CancellationToken cancellationToken)
public async Task StartSessionAsync(Solution solution, ImmutableArray<string> capabilities, CancellationToken cancellationToken)
{
var newSessionId = await _encService.StartDebuggingSessionAsync(solution, DebuggerService.Instance, captureMatchingDocuments: true, reportDiagnostics: false, cancellationToken).ConfigureAwait(false);
var newSessionId = await _encService.StartDebuggingSessionAsync(solution, new DebuggerService(capabilities), captureMatchingDocuments: true, reportDiagnostics: false, cancellationToken).ConfigureAwait(false);
Contract.ThrowIfFalse(_sessionId == default, "Session already started");
_sessionId = newSessionId;
}

/// <summary>
/// Emits updates for all projects that differ between the given <paramref name="solution"/> snapshot and the one given to the previous successful call or
/// the one passed to <see cref="StartSessionAsync(Solution, CancellationToken)"/> for the first invocation.
/// Emits updates for all projects that differ between the given <paramref name="solution"/> snapshot and the one given to the previous successful call
/// where <paramref name="commitUpdates"/> was `true` or the one passed to <see cref="StartSessionAsync(Solution, ImmutableArray{string}, CancellationToken)"/>
/// for the first invocation.
/// </summary>
/// <param name="solution">Solution snapshot.</param>
/// <param name="commitUpdates">commits changes if true, discards if false</param>
/// <param name="cancellationToken">Cancellation token.</param>
/// <returns>
/// Updates (one for each changed project) and Rude Edit diagnostics. Does not include syntax or semantic diagnostics.
/// </returns>
public async Task<(ImmutableArray<Update> updates, ImmutableArray<Diagnostic> diagnostics)> EmitSolutionUpdateAsync(Solution solution, CancellationToken cancellationToken)
public async Task<(ImmutableArray<Update> updates, ImmutableArray<Diagnostic> diagnostics)> EmitSolutionUpdateAsync(Solution solution, bool commitUpdates, CancellationToken cancellationToken)
{
var sessionId = _sessionId;
Contract.ThrowIfFalse(sessionId != default, "Session has not started");
Expand All @@ -90,7 +97,14 @@ public async Task StartSessionAsync(Solution solution, CancellationToken cancell

if (results.ModuleUpdates.Status == ManagedModuleUpdateStatus.Ready)
{
_encService.CommitSolutionUpdate(sessionId, out _);
if (commitUpdates)
{
_encService.CommitSolutionUpdate(sessionId, out _);
}
else
{
_encService.DiscardSolutionUpdate(sessionId);
}
}

var updates = results.ModuleUpdates.Updates.SelectAsArray(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
<RestrictedInternalsVisibleTo Include="Microsoft.CodeAnalysis.LiveUnitTesting.Orchestrator" Partner="UnitTesting" Key="$(UnitTestingKey)" />
<RestrictedInternalsVisibleTo Include="Microsoft.CodeAnalysis.UnitTesting.SourceBasedTestDiscovery" Partner="UnitTesting" Key="$(UnitTestingKey)" />
<RestrictedInternalsVisibleTo Include="Microsoft.CodeAnalysis.UnitTesting.SourceBasedTestDiscovery.Core" Partner="UnitTesting" Key="$(UnitTestingKey)" />
<RestrictedInternalsVisibleTo Include="Microsoft.VisualStudio.TestWindow.Core" Partner="UnitTesting" Key="$(UnitTestingKey)" />
<InternalsVisibleTo Include="Microsoft.CodeAnalysis.VisualBasic.EditorFeatures" />
<InternalsVisibleTo Include="Microsoft.CodeAnalysis.VisualBasic.Features" />
<InternalsVisibleTo Include="Roslyn.Hosting.Diagnostics" />
Expand Down

0 comments on commit 2384855

Please sign in to comment.