diff --git a/src/EditorFeatures/CSharpTest/Workspaces/WorkspaceTests.cs b/src/EditorFeatures/CSharpTest/Workspaces/WorkspaceTests.cs index 4e4c96a53dab1..cf4a26490a9f3 100644 --- a/src/EditorFeatures/CSharpTest/Workspaces/WorkspaceTests.cs +++ b/src/EditorFeatures/CSharpTest/Workspaces/WorkspaceTests.cs @@ -37,7 +37,7 @@ private static TestWorkspace CreateWorkspace(string workspaceKind = null, bool d composition = composition.AddParts(typeof(TestOptionsServiceWithSharedGlobalOptionsServiceFactory)); } - return new TestWorkspace(exportProvider: null, composition, workspaceKind, disablePartialSolutions); + return new TestWorkspace(exportProvider: null, composition, workspaceKind, disablePartialSolutions: disablePartialSolutions); } private static async Task WaitForWorkspaceOperationsToComplete(TestWorkspace workspace) diff --git a/src/EditorFeatures/Test/EditAndContinue/EditAndContinueWorkspaceServiceTests.cs b/src/EditorFeatures/Test/EditAndContinue/EditAndContinueWorkspaceServiceTests.cs index e8a1d51b2d973..750c618bda064 100644 --- a/src/EditorFeatures/Test/EditAndContinue/EditAndContinueWorkspaceServiceTests.cs +++ b/src/EditorFeatures/Test/EditAndContinue/EditAndContinueWorkspaceServiceTests.cs @@ -40,6 +40,8 @@ namespace Microsoft.CodeAnalysis.EditAndContinue.UnitTests public sealed partial class EditAndContinueWorkspaceServiceTests : TestBase { private static readonly TestComposition s_composition = FeaturesTestCompositions.Features; + private static readonly Guid s_solutionTelemetryId = Guid.Parse("00000000-AAAA-AAAA-AAAA-000000000000"); + private static readonly Guid s_defaultProjectTelemetryId = Guid.Parse("00000000-AAAA-AAAA-AAAA-111111111111"); private static readonly ActiveStatementSpanProvider s_noActiveSpans = (_, _, _) => new(ImmutableArray.Empty); @@ -65,7 +67,7 @@ public EditAndContinueWorkspaceServiceTests() private TestWorkspace CreateWorkspace(out Solution solution, out EditAndContinueWorkspaceService service, Type[] additionalParts = null) { - var workspace = new TestWorkspace(composition: s_composition.AddParts(additionalParts)); + var workspace = new TestWorkspace(composition: s_composition.AddParts(additionalParts), solutionTelemetryId: s_solutionTelemetryId); solution = workspace.CurrentSolution; service = GetEditAndContinueService(workspace); return workspace; @@ -92,8 +94,10 @@ private static Solution AddDefaultTestProject( string additionalFileText = null, (string key, string value)[] analyzerConfig = null) { + var projectId = ProjectId.CreateNewId(); + var project = solution. - AddProject("proj", "proj", LanguageNames.CSharp). + AddProject(ProjectInfo.Create(projectId, VersionStamp.Create(), "proj", "proj", LanguageNames.CSharp).WithTelemetryId(s_defaultProjectTelemetryId)).GetProject(projectId). WithMetadataReferences(TargetFrameworkUtil.GetReferences(DefaultTargetFramework)); solution = project.Solution; @@ -619,7 +623,7 @@ public async Task DifferentDocumentWithSameContent() AssertEx.Equal(new[] { - "Debugging_EncSession: SessionId=1|SessionCount=0|EmptySessionCount=0|HotReloadSessionCount=0|EmptyHotReloadSessionCount=1" + "Debugging_EncSession: SolutionSessionId={00000000-AAAA-AAAA-AAAA-000000000000}|SessionId=1|SessionCount=0|EmptySessionCount=0|HotReloadSessionCount=0|EmptyHotReloadSessionCount=1" }, _telemetryLog); } @@ -689,7 +693,7 @@ public async Task DesignTimeOnlyDocument() AssertEx.Equal(new[] { - "Debugging_EncSession: SessionId=1|SessionCount=0|EmptySessionCount=0|HotReloadSessionCount=0|EmptyHotReloadSessionCount=1" + "Debugging_EncSession: SolutionSessionId={00000000-AAAA-AAAA-AAAA-000000000000}|SessionId=1|SessionCount=0|EmptySessionCount=0|HotReloadSessionCount=0|EmptyHotReloadSessionCount=1" }, _telemetryLog); } @@ -859,8 +863,8 @@ public async Task ErrorReadingModuleFile(bool breakMode) { AssertEx.Equal(new[] { - "Debugging_EncSession: SessionId=1|SessionCount=1|EmptySessionCount=0|HotReloadSessionCount=0|EmptyHotReloadSessionCount=2", - "Debugging_EncSession_EditSession: SessionId=1|EditSessionId=2|HadCompilationErrors=False|HadRudeEdits=False|HadValidChanges=True|HadValidInsignificantChanges=False|RudeEditsCount=0|EmitDeltaErrorIdCount=1|InBreakState=True|Capabilities=31", + "Debugging_EncSession: SolutionSessionId={00000000-AAAA-AAAA-AAAA-000000000000}|SessionId=1|SessionCount=1|EmptySessionCount=0|HotReloadSessionCount=0|EmptyHotReloadSessionCount=2", + "Debugging_EncSession_EditSession: SessionId=1|EditSessionId=2|HadCompilationErrors=False|HadRudeEdits=False|HadValidChanges=True|HadValidInsignificantChanges=False|RudeEditsCount=0|EmitDeltaErrorIdCount=1|InBreakState=True|Capabilities=31|ProjectsWithAppliedChanges=", "Debugging_EncSession_EditSession_EmitDeltaErrorId: SessionId=1|EditSessionId=2|ErrorId=ENC1001" }, _telemetryLog); } @@ -868,8 +872,8 @@ public async Task ErrorReadingModuleFile(bool breakMode) { AssertEx.Equal(new[] { - "Debugging_EncSession: SessionId=1|SessionCount=0|EmptySessionCount=0|HotReloadSessionCount=1|EmptyHotReloadSessionCount=0", - "Debugging_EncSession_EditSession: SessionId=1|EditSessionId=2|HadCompilationErrors=False|HadRudeEdits=False|HadValidChanges=True|HadValidInsignificantChanges=False|RudeEditsCount=0|EmitDeltaErrorIdCount=1|InBreakState=False|Capabilities=31", + "Debugging_EncSession: SolutionSessionId={00000000-AAAA-AAAA-AAAA-000000000000}|SessionId=1|SessionCount=0|EmptySessionCount=0|HotReloadSessionCount=1|EmptyHotReloadSessionCount=0", + "Debugging_EncSession_EditSession: SessionId=1|EditSessionId=2|HadCompilationErrors=False|HadRudeEdits=False|HadValidChanges=True|HadValidInsignificantChanges=False|RudeEditsCount=0|EmitDeltaErrorIdCount=1|InBreakState=False|Capabilities=31|ProjectsWithAppliedChanges=", "Debugging_EncSession_EditSession_EmitDeltaErrorId: SessionId=1|EditSessionId=2|ErrorId=ENC1001" }, _telemetryLog); } @@ -926,7 +930,7 @@ public async Task ErrorReadingPdbFile() AssertEx.Equal(new[] { - "Debugging_EncSession: SessionId=1|SessionCount=0|EmptySessionCount=1|HotReloadSessionCount=0|EmptyHotReloadSessionCount=1" + "Debugging_EncSession: SolutionSessionId={00000000-AAAA-AAAA-AAAA-000000000000}|SessionId=1|SessionCount=0|EmptySessionCount=1|HotReloadSessionCount=0|EmptyHotReloadSessionCount=1" }, _telemetryLog); } @@ -985,8 +989,8 @@ public async Task ErrorReadingSourceFile() AssertEx.Equal(new[] { - "Debugging_EncSession: SessionId=1|SessionCount=1|EmptySessionCount=0|HotReloadSessionCount=0|EmptyHotReloadSessionCount=1", - "Debugging_EncSession_EditSession: SessionId=1|EditSessionId=2|HadCompilationErrors=False|HadRudeEdits=False|HadValidChanges=True|HadValidInsignificantChanges=False|RudeEditsCount=0|EmitDeltaErrorIdCount=0|InBreakState=True|Capabilities=31" + "Debugging_EncSession: SolutionSessionId={00000000-AAAA-AAAA-AAAA-000000000000}|SessionId=1|SessionCount=1|EmptySessionCount=0|HotReloadSessionCount=0|EmptyHotReloadSessionCount=1", + "Debugging_EncSession_EditSession: SessionId=1|EditSessionId=2|HadCompilationErrors=False|HadRudeEdits=False|HadValidChanges=True|HadValidInsignificantChanges=False|RudeEditsCount=0|EmitDeltaErrorIdCount=0|InBreakState=True|Capabilities=31|ProjectsWithAppliedChanges=" }, _telemetryLog); } @@ -1046,16 +1050,16 @@ public async Task FileAdded(bool breakMode) { AssertEx.Equal(new[] { - "Debugging_EncSession: SessionId=1|SessionCount=1|EmptySessionCount=0|HotReloadSessionCount=0|EmptyHotReloadSessionCount=2", - "Debugging_EncSession_EditSession: SessionId=1|EditSessionId=2|HadCompilationErrors=False|HadRudeEdits=False|HadValidChanges=True|HadValidInsignificantChanges=False|RudeEditsCount=0|EmitDeltaErrorIdCount=0|InBreakState=True|Capabilities=31" + "Debugging_EncSession: SolutionSessionId={00000000-AAAA-AAAA-AAAA-000000000000}|SessionId=1|SessionCount=1|EmptySessionCount=0|HotReloadSessionCount=0|EmptyHotReloadSessionCount=2", + "Debugging_EncSession_EditSession: SessionId=1|EditSessionId=2|HadCompilationErrors=False|HadRudeEdits=False|HadValidChanges=True|HadValidInsignificantChanges=False|RudeEditsCount=0|EmitDeltaErrorIdCount=0|InBreakState=True|Capabilities=31|ProjectsWithAppliedChanges=" }, _telemetryLog); } else { AssertEx.Equal(new[] { - "Debugging_EncSession: SessionId=1|SessionCount=0|EmptySessionCount=0|HotReloadSessionCount=1|EmptyHotReloadSessionCount=0", - "Debugging_EncSession_EditSession: SessionId=1|EditSessionId=2|HadCompilationErrors=False|HadRudeEdits=False|HadValidChanges=True|HadValidInsignificantChanges=False|RudeEditsCount=0|EmitDeltaErrorIdCount=0|InBreakState=False|Capabilities=31" + "Debugging_EncSession: SolutionSessionId={00000000-AAAA-AAAA-AAAA-000000000000}|SessionId=1|SessionCount=0|EmptySessionCount=0|HotReloadSessionCount=1|EmptyHotReloadSessionCount=0", + "Debugging_EncSession_EditSession: SessionId=1|EditSessionId=2|HadCompilationErrors=False|HadRudeEdits=False|HadValidChanges=True|HadValidInsignificantChanges=False|RudeEditsCount=0|EmitDeltaErrorIdCount=0|InBreakState=False|Capabilities=31|ProjectsWithAppliedChanges=" }, _telemetryLog); } } @@ -1121,8 +1125,8 @@ void M() AssertEx.Equal(new[] { - "Debugging_EncSession: SessionId=1|SessionCount=1|EmptySessionCount=0|HotReloadSessionCount=0|EmptyHotReloadSessionCount=1", - "Debugging_EncSession_EditSession: SessionId=1|EditSessionId=2|HadCompilationErrors=False|HadRudeEdits=False|HadValidChanges=True|HadValidInsignificantChanges=False|RudeEditsCount=0|EmitDeltaErrorIdCount=1|InBreakState=True|Capabilities=31", + "Debugging_EncSession: SolutionSessionId={00000000-AAAA-AAAA-AAAA-000000000000}|SessionId=1|SessionCount=1|EmptySessionCount=0|HotReloadSessionCount=0|EmptyHotReloadSessionCount=1", + "Debugging_EncSession_EditSession: SessionId=1|EditSessionId=2|HadCompilationErrors=False|HadRudeEdits=False|HadValidChanges=True|HadValidInsignificantChanges=False|RudeEditsCount=0|EmitDeltaErrorIdCount=1|InBreakState=True|Capabilities=31|ProjectsWithAppliedChanges=", "Debugging_EncSession_EditSession_EmitDeltaErrorId: SessionId=1|EditSessionId=2|ErrorId=ENC2016" }, _telemetryLog); } @@ -1221,8 +1225,8 @@ public async Task RudeEdits(bool breakMode) { AssertEx.Equal(new[] { - "Debugging_EncSession: SessionId=1|SessionCount=1|EmptySessionCount=0|HotReloadSessionCount=0|EmptyHotReloadSessionCount=2", - "Debugging_EncSession_EditSession: SessionId=1|EditSessionId=2|HadCompilationErrors=False|HadRudeEdits=True|HadValidChanges=False|HadValidInsignificantChanges=False|RudeEditsCount=1|EmitDeltaErrorIdCount=0|InBreakState=True|Capabilities=31", + "Debugging_EncSession: SolutionSessionId={00000000-AAAA-AAAA-AAAA-000000000000}|SessionId=1|SessionCount=1|EmptySessionCount=0|HotReloadSessionCount=0|EmptyHotReloadSessionCount=2", + "Debugging_EncSession_EditSession: SessionId=1|EditSessionId=2|HadCompilationErrors=False|HadRudeEdits=True|HadValidChanges=False|HadValidInsignificantChanges=False|RudeEditsCount=1|EmitDeltaErrorIdCount=0|InBreakState=True|Capabilities=31|ProjectsWithAppliedChanges=", "Debugging_EncSession_EditSession_RudeEdit: SessionId=1|EditSessionId=2|RudeEditKind=20|RudeEditSyntaxKind=8875|RudeEditBlocking=True" }, _telemetryLog); } @@ -1230,8 +1234,8 @@ public async Task RudeEdits(bool breakMode) { AssertEx.Equal(new[] { - "Debugging_EncSession: SessionId=1|SessionCount=0|EmptySessionCount=0|HotReloadSessionCount=1|EmptyHotReloadSessionCount=0", - "Debugging_EncSession_EditSession: SessionId=1|EditSessionId=2|HadCompilationErrors=False|HadRudeEdits=True|HadValidChanges=False|HadValidInsignificantChanges=False|RudeEditsCount=1|EmitDeltaErrorIdCount=0|InBreakState=False|Capabilities=31", + "Debugging_EncSession: SolutionSessionId={00000000-AAAA-AAAA-AAAA-000000000000}|SessionId=1|SessionCount=0|EmptySessionCount=0|HotReloadSessionCount=1|EmptyHotReloadSessionCount=0", + "Debugging_EncSession_EditSession: SessionId=1|EditSessionId=2|HadCompilationErrors=False|HadRudeEdits=True|HadValidChanges=False|HadValidInsignificantChanges=False|RudeEditsCount=1|EmitDeltaErrorIdCount=0|InBreakState=False|Capabilities=31|ProjectsWithAppliedChanges=", "Debugging_EncSession_EditSession_RudeEdit: SessionId=1|EditSessionId=2|RudeEditKind=20|RudeEditSyntaxKind=8875|RudeEditBlocking=True" }, _telemetryLog); } @@ -1365,8 +1369,8 @@ public async Task RudeEdits_DocumentOutOfSync(bool breakMode) { AssertEx.Equal(new[] { - "Debugging_EncSession: SessionId=1|SessionCount=1|EmptySessionCount=0|HotReloadSessionCount=0|EmptyHotReloadSessionCount=2", - "Debugging_EncSession_EditSession: SessionId=1|EditSessionId=2|HadCompilationErrors=False|HadRudeEdits=True|HadValidChanges=False|HadValidInsignificantChanges=False|RudeEditsCount=1|EmitDeltaErrorIdCount=0|InBreakState=True|Capabilities=31", + "Debugging_EncSession: SolutionSessionId={00000000-AAAA-AAAA-AAAA-000000000000}|SessionId=1|SessionCount=1|EmptySessionCount=0|HotReloadSessionCount=0|EmptyHotReloadSessionCount=2", + "Debugging_EncSession_EditSession: SessionId=1|EditSessionId=2|HadCompilationErrors=False|HadRudeEdits=True|HadValidChanges=False|HadValidInsignificantChanges=False|RudeEditsCount=1|EmitDeltaErrorIdCount=0|InBreakState=True|Capabilities=31|ProjectsWithAppliedChanges=", "Debugging_EncSession_EditSession_RudeEdit: SessionId=1|EditSessionId=2|RudeEditKind=20|RudeEditSyntaxKind=8875|RudeEditBlocking=True" }, _telemetryLog); } @@ -1374,8 +1378,8 @@ public async Task RudeEdits_DocumentOutOfSync(bool breakMode) { AssertEx.Equal(new[] { - "Debugging_EncSession: SessionId=1|SessionCount=0|EmptySessionCount=0|HotReloadSessionCount=1|EmptyHotReloadSessionCount=0", - "Debugging_EncSession_EditSession: SessionId=1|EditSessionId=2|HadCompilationErrors=False|HadRudeEdits=True|HadValidChanges=False|HadValidInsignificantChanges=False|RudeEditsCount=1|EmitDeltaErrorIdCount=0|InBreakState=False|Capabilities=31", + "Debugging_EncSession: SolutionSessionId={00000000-AAAA-AAAA-AAAA-000000000000}|SessionId=1|SessionCount=0|EmptySessionCount=0|HotReloadSessionCount=1|EmptyHotReloadSessionCount=0", + "Debugging_EncSession_EditSession: SessionId=1|EditSessionId=2|HadCompilationErrors=False|HadRudeEdits=True|HadValidChanges=False|HadValidInsignificantChanges=False|RudeEditsCount=1|EmitDeltaErrorIdCount=0|InBreakState=False|Capabilities=31|ProjectsWithAppliedChanges=", "Debugging_EncSession_EditSession_RudeEdit: SessionId=1|EditSessionId=2|RudeEditKind=20|RudeEditSyntaxKind=8875|RudeEditBlocking=True" }, _telemetryLog); } @@ -1525,8 +1529,8 @@ public async Task SyntaxError() AssertEx.Equal(new[] { - "Debugging_EncSession: SessionId=1|SessionCount=1|EmptySessionCount=0|HotReloadSessionCount=0|EmptyHotReloadSessionCount=1", - "Debugging_EncSession_EditSession: SessionId=1|EditSessionId=2|HadCompilationErrors=True|HadRudeEdits=False|HadValidChanges=False|HadValidInsignificantChanges=False|RudeEditsCount=0|EmitDeltaErrorIdCount=0|InBreakState=True|Capabilities=31" + "Debugging_EncSession: SolutionSessionId={00000000-AAAA-AAAA-AAAA-000000000000}|SessionId=1|SessionCount=1|EmptySessionCount=0|HotReloadSessionCount=0|EmptyHotReloadSessionCount=1", + "Debugging_EncSession_EditSession: SessionId=1|EditSessionId=2|HadCompilationErrors=True|HadRudeEdits=False|HadValidChanges=False|HadValidInsignificantChanges=False|RudeEditsCount=0|EmitDeltaErrorIdCount=0|InBreakState=True|Capabilities=31|ProjectsWithAppliedChanges=" }, _telemetryLog); } @@ -1572,8 +1576,8 @@ public async Task SemanticError() AssertEx.Equal(new[] { - "Debugging_EncSession: SessionId=1|SessionCount=1|EmptySessionCount=0|HotReloadSessionCount=0|EmptyHotReloadSessionCount=1", - "Debugging_EncSession_EditSession: SessionId=1|EditSessionId=2|HadCompilationErrors=False|HadRudeEdits=False|HadValidChanges=True|HadValidInsignificantChanges=False|RudeEditsCount=0|EmitDeltaErrorIdCount=1|InBreakState=True|Capabilities=31", + "Debugging_EncSession: SolutionSessionId={00000000-AAAA-AAAA-AAAA-000000000000}|SessionId=1|SessionCount=1|EmptySessionCount=0|HotReloadSessionCount=0|EmptyHotReloadSessionCount=1", + "Debugging_EncSession_EditSession: SessionId=1|EditSessionId=2|HadCompilationErrors=False|HadRudeEdits=False|HadValidChanges=True|HadValidInsignificantChanges=False|RudeEditsCount=0|EmitDeltaErrorIdCount=1|InBreakState=True|Capabilities=31|ProjectsWithAppliedChanges=", "Debugging_EncSession_EditSession_EmitDeltaErrorId: SessionId=1|EditSessionId=2|ErrorId=CS0266" }, _telemetryLog); } @@ -1932,8 +1936,8 @@ public async Task ValidSignificantChange_EmitError() AssertEx.Equal(new[] { - "Debugging_EncSession: SessionId=1|SessionCount=1|EmptySessionCount=0|HotReloadSessionCount=0|EmptyHotReloadSessionCount=1", - "Debugging_EncSession_EditSession: SessionId=1|EditSessionId=2|HadCompilationErrors=False|HadRudeEdits=False|HadValidChanges=True|HadValidInsignificantChanges=False|RudeEditsCount=0|EmitDeltaErrorIdCount=1|InBreakState=True|Capabilities=31", + "Debugging_EncSession: SolutionSessionId={00000000-AAAA-AAAA-AAAA-000000000000}|SessionId=1|SessionCount=1|EmptySessionCount=0|HotReloadSessionCount=0|EmptyHotReloadSessionCount=1", + "Debugging_EncSession_EditSession: SessionId=1|EditSessionId=2|HadCompilationErrors=False|HadRudeEdits=False|HadValidChanges=True|HadValidInsignificantChanges=False|RudeEditsCount=0|EmitDeltaErrorIdCount=1|InBreakState=True|Capabilities=31|ProjectsWithAppliedChanges=", "Debugging_EncSession_EditSession_EmitDeltaErrorId: SessionId=1|EditSessionId=2|ErrorId=CS8055" }, _telemetryLog); } @@ -2343,16 +2347,16 @@ void ValidateDelta(ManagedModuleUpdate delta) { AssertEx.Equal(new[] { - $"Debugging_EncSession: SessionId=1|SessionCount=1|EmptySessionCount=0|HotReloadSessionCount=0|EmptyHotReloadSessionCount={(commitUpdate ? 3 : 2)}", - "Debugging_EncSession_EditSession: SessionId=1|EditSessionId=2|HadCompilationErrors=False|HadRudeEdits=False|HadValidChanges=True|HadValidInsignificantChanges=False|RudeEditsCount=0|EmitDeltaErrorIdCount=0|InBreakState=True|Capabilities=31", + $"Debugging_EncSession: SolutionSessionId={{00000000-AAAA-AAAA-AAAA-000000000000}}|SessionId=1|SessionCount=1|EmptySessionCount=0|HotReloadSessionCount=0|EmptyHotReloadSessionCount={(commitUpdate ? 3 : 2)}", + $"Debugging_EncSession_EditSession: SessionId=1|EditSessionId=2|HadCompilationErrors=False|HadRudeEdits=False|HadValidChanges=True|HadValidInsignificantChanges=False|RudeEditsCount=0|EmitDeltaErrorIdCount=0|InBreakState=True|Capabilities=31|ProjectsWithAppliedChanges={(commitUpdate ? "{00000000-AAAA-AAAA-AAAA-111111111111}" : "")}", }, _telemetryLog); } else { AssertEx.Equal(new[] { - $"Debugging_EncSession: SessionId=1|SessionCount=0|EmptySessionCount=0|HotReloadSessionCount=1|EmptyHotReloadSessionCount={(commitUpdate ? 1 : 0)}", - "Debugging_EncSession_EditSession: SessionId=1|EditSessionId=2|HadCompilationErrors=False|HadRudeEdits=False|HadValidChanges=True|HadValidInsignificantChanges=False|RudeEditsCount=0|EmitDeltaErrorIdCount=0|InBreakState=False|Capabilities=31" + $"Debugging_EncSession: SolutionSessionId={{00000000-AAAA-AAAA-AAAA-000000000000}}|SessionId=1|SessionCount=0|EmptySessionCount=0|HotReloadSessionCount=1|EmptyHotReloadSessionCount={(commitUpdate ? 1 : 0)}", + $"Debugging_EncSession_EditSession: SessionId=1|EditSessionId=2|HadCompilationErrors=False|HadRudeEdits=False|HadValidChanges=True|HadValidInsignificantChanges=False|RudeEditsCount=0|EmitDeltaErrorIdCount=0|InBreakState=False|Capabilities=31|ProjectsWithAppliedChanges={(commitUpdate ? "{00000000-AAAA-AAAA-AAAA-111111111111}" : "")}" }, _telemetryLog); } } @@ -3033,8 +3037,8 @@ public async Task ValidSignificantChange_BaselineCreationFailed_AssemblyReadErro AssertEx.Equal(new[] { - "Debugging_EncSession: SessionId=1|SessionCount=1|EmptySessionCount=0|HotReloadSessionCount=0|EmptyHotReloadSessionCount=1", - "Debugging_EncSession_EditSession: SessionId=1|EditSessionId=2|HadCompilationErrors=False|HadRudeEdits=False|HadValidChanges=True|HadValidInsignificantChanges=False|RudeEditsCount=0|EmitDeltaErrorIdCount=1|InBreakState=True|Capabilities=31", + "Debugging_EncSession: SolutionSessionId={00000000-AAAA-AAAA-AAAA-000000000000}|SessionId=1|SessionCount=1|EmptySessionCount=0|HotReloadSessionCount=0|EmptyHotReloadSessionCount=1", + "Debugging_EncSession_EditSession: SessionId=1|EditSessionId=2|HadCompilationErrors=False|HadRudeEdits=False|HadValidChanges=True|HadValidInsignificantChanges=False|RudeEditsCount=0|EmitDeltaErrorIdCount=1|InBreakState=True|Capabilities=31|ProjectsWithAppliedChanges=", "Debugging_EncSession_EditSession_EmitDeltaErrorId: SessionId=1|EditSessionId=2|ErrorId=ENC1001" }, _telemetryLog); } diff --git a/src/EditorFeatures/TestUtilities/Workspaces/TestWorkspace.cs b/src/EditorFeatures/TestUtilities/Workspaces/TestWorkspace.cs index cb70f6b50ac27..859dbdc2efca9 100644 --- a/src/EditorFeatures/TestUtilities/Workspaces/TestWorkspace.cs +++ b/src/EditorFeatures/TestUtilities/Workspaces/TestWorkspace.cs @@ -55,11 +55,19 @@ public partial class TestWorkspace : Workspace private readonly Dictionary _createdTextBuffers = new(); private readonly string _workspaceKind; - public TestWorkspace(ExportProvider? exportProvider = null, TestComposition? composition = null, string? workspaceKind = WorkspaceKind.Host, bool disablePartialSolutions = true, bool ignoreUnchangeableDocumentsWhenApplyingChanges = true) + public TestWorkspace( + ExportProvider? exportProvider = null, + TestComposition? composition = null, + string? workspaceKind = WorkspaceKind.Host, + Guid solutionTelemetryId = default, + bool disablePartialSolutions = true, + bool ignoreUnchangeableDocumentsWhenApplyingChanges = true) : base(GetHostServices(exportProvider, composition), workspaceKind ?? WorkspaceKind.Host) { Contract.ThrowIfTrue(exportProvider != null && composition != null); + SetCurrentSolution(CreateSolution(SolutionInfo.Create(SolutionId.CreateNewId(), VersionStamp.Create()).WithTelemetryId(solutionTelemetryId))); + this.TestHookPartialSolutionsDisabled = disablePartialSolutions; this.ExportProvider = exportProvider ?? GetComposition(composition).ExportProviderFactory.CreateExportProvider(); _workspaceKind = workspaceKind ?? WorkspaceKind.Host; diff --git a/src/Features/Core/Portable/EditAndContinue/DebuggingSession.cs b/src/Features/Core/Portable/EditAndContinue/DebuggingSession.cs index 9ae6dff713e63..0f8d1b99de78d 100644 --- a/src/Features/Core/Portable/EditAndContinue/DebuggingSession.cs +++ b/src/Features/Core/Portable/EditAndContinue/DebuggingSession.cs @@ -83,7 +83,7 @@ internal sealed class DebuggingSession : IDisposable /// internal readonly bool ReportDiagnostics; - private readonly DebuggingSessionTelemetry _telemetry = new(); + private readonly DebuggingSessionTelemetry _telemetry; private readonly EditSessionTelemetry _editSessionTelemetry = new(); private PendingSolutionUpdate? _pendingUpdate; @@ -105,6 +105,7 @@ internal DebuggingSession( { _compilationOutputsProvider = compilationOutputsProvider; _reportTelemetry = ReportTelemetry; + _telemetry = new DebuggingSessionTelemetry(solution.State.SolutionAttributes.TelemetryId); Id = id; DebuggerService = debuggerService; @@ -582,6 +583,8 @@ from region in moduleRegions.Regions LastCommittedSolution.CommitSolution(pendingUpdate.Solution); + _editSessionTelemetry.LogCommitted(); + // Restart edit session with no active statements (switching to run mode). RestartEditSession(newNonRemappableRegions, inBreakState: false, out documentsToReanalyze); } diff --git a/src/Features/Core/Portable/EditAndContinue/DebuggingSessionTelemetry.cs b/src/Features/Core/Portable/EditAndContinue/DebuggingSessionTelemetry.cs index dae3a50de4885..8fb01e4a3ee1b 100644 --- a/src/Features/Core/Portable/EditAndContinue/DebuggingSessionTelemetry.cs +++ b/src/Features/Core/Portable/EditAndContinue/DebuggingSessionTelemetry.cs @@ -5,6 +5,7 @@ using System; using System.Collections.Generic; using System.Collections.Immutable; +using System.Linq; using Microsoft.CodeAnalysis.Internal.Log; namespace Microsoft.CodeAnalysis.EditAndContinue @@ -13,12 +14,14 @@ internal sealed class DebuggingSessionTelemetry { internal readonly struct Data { + public readonly Guid SolutionSessionId; public readonly ImmutableArray EditSessionData; public readonly int EmptyEditSessionCount; public readonly int EmptyHotReloadEditSessionCount; public Data(DebuggingSessionTelemetry telemetry) { + SolutionSessionId = telemetry._solutionSessionId; EditSessionData = telemetry._editSessionData.ToImmutableArray(); EmptyEditSessionCount = telemetry._emptyEditSessionCount; EmptyHotReloadEditSessionCount = telemetry._emptyHotReloadEditSessionCount; @@ -27,10 +30,16 @@ public Data(DebuggingSessionTelemetry telemetry) private readonly object _guard = new(); + private readonly Guid _solutionSessionId; private readonly List _editSessionData = new(); private int _emptyEditSessionCount; private int _emptyHotReloadEditSessionCount; + public DebuggingSessionTelemetry(Guid solutionSessionId) + { + _solutionSessionId = solutionSessionId; + } + public Data GetDataAndClear() { lock (_guard) @@ -82,6 +91,7 @@ public static void Log(Data data, Action log, Func log(FunctionId.Debugging_EncSession, KeyValueLogMessage.Create(map => { + map["SolutionSessionId"] = data.SolutionSessionId.ToString("B").ToUpperInvariant(); map[SessionId] = debugSessionId; map["SessionCount"] = data.EditSessionData.Count(session => session.InBreakState); map["EmptySessionCount"] = data.EmptyEditSessionCount; @@ -100,13 +110,24 @@ public static void Log(Data data, Action log, Func map["HadCompilationErrors"] = editSessionData.HadCompilationErrors; map["HadRudeEdits"] = editSessionData.HadRudeEdits; + + // Changes made to source code during the edit session were valid - they were significant and no rude edits were reported. + // The changes still might fail to emit (see EmitDeltaErrorIdCount). map["HadValidChanges"] = editSessionData.HadValidChanges; map["HadValidInsignificantChanges"] = editSessionData.HadValidInsignificantChanges; map["RudeEditsCount"] = editSessionData.RudeEdits.Length; + + // Number of emit errors. map["EmitDeltaErrorIdCount"] = editSessionData.EmitErrorIds.Length; + + // False for Hot Reload session, true or missing for EnC session (missing in older data that did not have this property). map["InBreakState"] = editSessionData.InBreakState; + map["Capabilities"] = (int)editSessionData.Capabilities; + + // Ids of all projects whose binaries were successfully updated during the session. + map["ProjectsWithAppliedChanges"] = editSessionData.Committed ? string.Join(",", editSessionData.ProjectsWithValidDelta.Select(id => id.ToString("B").ToUpperInvariant())) : ""; })); foreach (var errorId in editSessionData.EmitErrorIds) diff --git a/src/Features/Core/Portable/EditAndContinue/EditSession.cs b/src/Features/Core/Portable/EditAndContinue/EditSession.cs index e302e319298a7..65017b18e2428 100644 --- a/src/Features/Core/Portable/EditAndContinue/EditSession.cs +++ b/src/Features/Core/Portable/EditAndContinue/EditSession.cs @@ -742,7 +742,7 @@ public async ValueTask EmitSolutionUpdateAsync(Solution solution // Bail before analyzing documents as the analysis needs to read the PDB which will likely fail if we can't even read the MVID. diagnostics.Add((newProject.Id, ImmutableArray.Create(mvidReadError))); - Telemetry.LogProjectAnalysisSummary(ProjectAnalysisSummary.ValidChanges, ImmutableArray.Create(mvidReadError.Descriptor.Id), InBreakState); + Telemetry.LogProjectAnalysisSummary(ProjectAnalysisSummary.ValidChanges, newProject.State.ProjectInfo.Attributes.TelemetryId, ImmutableArray.Create(mvidReadError.Descriptor.Id), InBreakState); isBlocked = true; continue; } @@ -813,7 +813,7 @@ public async ValueTask EmitSolutionUpdateAsync(Solution solution if (isModuleEncBlocked || projectSummary != ProjectAnalysisSummary.ValidChanges) { - Telemetry.LogProjectAnalysisSummary(projectSummary, moduleDiagnostics.NullToEmpty().SelectAsArray(d => d.Descriptor.Id), InBreakState); + Telemetry.LogProjectAnalysisSummary(projectSummary, newProject.State.ProjectInfo.Attributes.TelemetryId, moduleDiagnostics.NullToEmpty().SelectAsArray(d => d.Descriptor.Id), InBreakState); continue; } @@ -824,7 +824,7 @@ public async ValueTask EmitSolutionUpdateAsync(Solution solution // Report diagnosics even when the module is never going to be loaded (e.g. in multi-targeting scenario, where only one framework being debugged). // This is consistent with reporting compilation errors - the IDE reports them for all TFMs regardless of what framework the app is running on. diagnostics.Add((newProject.Id, createBaselineDiagnostics)); - Telemetry.LogProjectAnalysisSummary(projectSummary, createBaselineDiagnostics, InBreakState); + Telemetry.LogProjectAnalysisSummary(projectSummary, newProject.State.ProjectInfo.Attributes.TelemetryId, createBaselineDiagnostics, InBreakState); isBlocked = true; continue; } @@ -927,7 +927,7 @@ public async ValueTask EmitSolutionUpdateAsync(Solution solution diagnostics.Add((newProject.Id, emitResult.Diagnostics)); } - Telemetry.LogProjectAnalysisSummary(projectSummary, emitResult.Diagnostics, InBreakState); + Telemetry.LogProjectAnalysisSummary(projectSummary, newProject.State.ProjectInfo.Attributes.TelemetryId, emitResult.Diagnostics, InBreakState); } // log capabilities for edit sessions with changes or reported errors: diff --git a/src/Features/Core/Portable/EditAndContinue/EditSessionTelemetry.cs b/src/Features/Core/Portable/EditAndContinue/EditSessionTelemetry.cs index d297bb4177826..6e45247f98e17 100644 --- a/src/Features/Core/Portable/EditAndContinue/EditSessionTelemetry.cs +++ b/src/Features/Core/Portable/EditAndContinue/EditSessionTelemetry.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +using System; using System.Collections.Generic; using System.Collections.Immutable; using System.Diagnostics; @@ -16,6 +17,7 @@ internal readonly struct Data { public readonly ImmutableArray<(ushort EditKind, ushort SyntaxKind)> RudeEdits; public readonly ImmutableArray EmitErrorIds; + public readonly ImmutableArray ProjectsWithValidDelta; public readonly EditAndContinueCapabilities Capabilities; public readonly bool HadCompilationErrors; public readonly bool HadRudeEdits; @@ -23,11 +25,13 @@ internal readonly struct Data public readonly bool HadValidInsignificantChanges; public readonly bool InBreakState; public readonly bool IsEmpty; + public readonly bool Committed; public Data(EditSessionTelemetry telemetry) { RudeEdits = telemetry._rudeEdits.AsImmutable(); EmitErrorIds = telemetry._emitErrorIds.AsImmutable(); + ProjectsWithValidDelta = telemetry._projectsWithValidDelta.AsImmutable(); HadCompilationErrors = telemetry._hadCompilationErrors; HadRudeEdits = telemetry._hadRudeEdits; HadValidChanges = telemetry._hadValidChanges; @@ -35,6 +39,7 @@ public Data(EditSessionTelemetry telemetry) InBreakState = telemetry._inBreakState; Capabilities = telemetry._capabilities; IsEmpty = telemetry.IsEmpty; + Committed = telemetry._committed; } } @@ -42,12 +47,14 @@ public Data(EditSessionTelemetry telemetry) private readonly HashSet<(ushort, ushort)> _rudeEdits = new(); private readonly HashSet _emitErrorIds = new(); + private readonly HashSet _projectsWithValidDelta = new(); private bool _hadCompilationErrors; private bool _hadRudeEdits; private bool _hadValidChanges; private bool _hadValidInsignificantChanges; private bool _inBreakState; + private bool _committed; private EditAndContinueCapabilities _capabilities; @@ -58,19 +65,21 @@ public Data GetDataAndClear() var data = new Data(this); _rudeEdits.Clear(); _emitErrorIds.Clear(); + _projectsWithValidDelta.Clear(); _hadCompilationErrors = false; _hadRudeEdits = false; _hadValidChanges = false; _hadValidInsignificantChanges = false; _inBreakState = false; _capabilities = EditAndContinueCapabilities.None; + _committed = false; return data; } } public bool IsEmpty => !(_hadCompilationErrors || _hadRudeEdits || _hadValidChanges || _hadValidInsignificantChanges); - public void LogProjectAnalysisSummary(ProjectAnalysisSummary summary, ImmutableArray errorsIds, bool inBreakState) + public void LogProjectAnalysisSummary(ProjectAnalysisSummary summary, Guid projectTelemetryId, ImmutableArray errorsIds, bool inBreakState) { lock (_guard) { @@ -92,6 +101,12 @@ public void LogProjectAnalysisSummary(ProjectAnalysisSummary summary, ImmutableA case ProjectAnalysisSummary.ValidChanges: _hadValidChanges = true; + + if (errorsIds.IsEmpty) + { + _projectsWithValidDelta.Add(projectTelemetryId); + } + break; case ProjectAnalysisSummary.ValidInsignificantChanges: @@ -104,8 +119,8 @@ public void LogProjectAnalysisSummary(ProjectAnalysisSummary summary, ImmutableA } } - public void LogProjectAnalysisSummary(ProjectAnalysisSummary summary, ImmutableArray emitDiagnostics, bool inBreakState) - => LogProjectAnalysisSummary(summary, emitDiagnostics.SelectAsArray(d => d.Severity == DiagnosticSeverity.Error, d => d.Id), inBreakState); + public void LogProjectAnalysisSummary(ProjectAnalysisSummary summary, Guid projectTelemetryId, ImmutableArray emitDiagnostics, bool inBreakState) + => LogProjectAnalysisSummary(summary, projectTelemetryId, emitDiagnostics.SelectAsArray(d => d.Severity == DiagnosticSeverity.Error, d => d.Id), inBreakState); public void LogRudeEditDiagnostics(ImmutableArray diagnostics) { @@ -126,5 +141,8 @@ public void LogRuntimeCapabilities(EditAndContinueCapabilities capabilities) _capabilities = capabilities; } } + + internal void LogCommitted() + => _committed = true; } }