ConfigurationProcessorTelemetryTests.cs (10827B)
1 // ----------------------------------------------------------------------------- 2 // <copyright file="ConfigurationProcessorTelemetryTests.cs" company="Microsoft Corporation"> 3 // Copyright (c) Microsoft Corporation. Licensed under the MIT License. 4 // </copyright> 5 // ----------------------------------------------------------------------------- 6 7 namespace Microsoft.Management.Configuration.UnitTests.Tests 8 { 9 using System; 10 using System.Collections; 11 using System.Collections.Generic; 12 using System.IO; 13 using System.Linq; 14 using System.Runtime.InteropServices; 15 using System.Threading; 16 using Microsoft.Management.Configuration.UnitTests.Fixtures; 17 using Microsoft.Management.Configuration.UnitTests.Helpers; 18 using Microsoft.VisualBasic; 19 using Microsoft.VisualStudio.TestPlatform.ObjectModel; 20 using Xunit; 21 using Xunit.Abstractions; 22 using static System.Collections.Specialized.BitVector32; 23 24 /// <summary> 25 /// Unit tests for running test on the processor. 26 /// </summary> 27 [Collection("UnitTestCollection")] 28 [InProc] 29 public class ConfigurationProcessorTelemetryTests : ConfigurationProcessorTestBase 30 { 31 /// <summary> 32 /// Initializes a new instance of the <see cref="ConfigurationProcessorTelemetryTests"/> class. 33 /// </summary> 34 /// <param name="fixture">Unit test fixture.</param> 35 /// <param name="log">Log helper.</param> 36 public ConfigurationProcessorTelemetryTests(UnitTestFixture fixture, ITestOutputHelper log) 37 : base(fixture, log) 38 { 39 } 40 41 /// <summary> 42 /// No event is generated if the unit succeeds. 43 /// </summary> 44 [Fact] 45 public void Telemetry_NoUnitEventOnSuccess() 46 { 47 TelemetryTestObjects testObjects = new TelemetryTestObjects(getFails: false); 48 testObjects.Processor = this.CreateConfigurationProcessorWithDiagnostics(testObjects.Factory); 49 testObjects.CreateDetails(); 50 51 GetConfigurationUnitSettingsResult result = testObjects.Processor.GetUnitSettings(testObjects.Unit); 52 53 Assert.Single(this.EventSink.Events); 54 Assert.Equal(TelemetryEvent.ConfigUnitRunName, this.EventSink.Events[0].Name); 55 } 56 57 /// <summary> 58 /// No event is generated if the details have not been retrieved. 59 /// </summary> 60 [Fact] 61 public void Telemetry_NoUnitEventIfNoDetails() 62 { 63 TelemetryTestObjects testObjects = new TelemetryTestObjects(); 64 testObjects.Processor = this.CreateConfigurationProcessorWithDiagnostics(testObjects.Factory); 65 66 GetConfigurationUnitSettingsResult result = testObjects.Processor.GetUnitSettings(testObjects.Unit); 67 68 Assert.Empty(this.EventSink.Events); 69 } 70 71 /// <summary> 72 /// No event is generated if the module is not public. 73 /// </summary> 74 [Fact] 75 public void Telemetry_NoUnitEventIfNotPublic() 76 { 77 TelemetryTestObjects testObjects = new TelemetryTestObjects(); 78 testObjects.Processor = this.CreateConfigurationProcessorWithDiagnostics(testObjects.Factory); 79 testObjects.CreateDetails(isPublic: false); 80 81 GetConfigurationUnitSettingsResult result = testObjects.Processor.GetUnitSettings(testObjects.Unit); 82 83 Assert.Empty(this.EventSink.Events); 84 } 85 86 /// <summary> 87 /// The activity set by the caller is the value in the event. 88 /// </summary> 89 [Fact] 90 public void Telemetry_ActivityID() 91 { 92 TelemetryTestObjects testObjects = new TelemetryTestObjects(); 93 testObjects.Processor = this.CreateConfigurationProcessorWithDiagnostics(testObjects.Factory); 94 testObjects.CreateDetails(); 95 96 Guid activity = Guid.NewGuid(); 97 testObjects.Processor.ActivityIdentifier = activity; 98 99 GetConfigurationUnitSettingsResult result = testObjects.Processor.GetUnitSettings(testObjects.Unit); 100 101 Assert.Single(this.EventSink.Events); 102 Assert.Equal(TelemetryEvent.ConfigUnitRunName, this.EventSink.Events[0].Name); 103 Assert.Equal(activity, this.EventSink.Events[0].ActivityID); 104 } 105 106 /// <summary> 107 /// Disabling telemetry causes no event to be produced. 108 /// </summary> 109 /// <param name="state">The state of telemetry.</param> 110 [Theory] 111 [InlineData(true)] 112 [InlineData(false)] 113 public void Telemetry_EnableState(bool state) 114 { 115 TelemetryTestObjects testObjects = new TelemetryTestObjects(); 116 testObjects.Processor = this.CreateConfigurationProcessorWithDiagnostics(testObjects.Factory); 117 testObjects.CreateDetails(); 118 119 testObjects.Processor.GenerateTelemetryEvents = state; 120 121 GetConfigurationUnitSettingsResult result = testObjects.Processor.GetUnitSettings(testObjects.Unit); 122 123 if (state) 124 { 125 Assert.Single(this.EventSink.Events); 126 Assert.Equal(TelemetryEvent.ConfigUnitRunName, this.EventSink.Events[0].Name); 127 } 128 else 129 { 130 Assert.Empty(this.EventSink.Events); 131 } 132 } 133 134 /// <summary> 135 /// The caller set by the caller is the value in the event. 136 /// </summary> 137 [Fact] 138 public void Telemetry_Caller() 139 { 140 TelemetryTestObjects testObjects = new TelemetryTestObjects(); 141 testObjects.Processor = this.CreateConfigurationProcessorWithDiagnostics(testObjects.Factory); 142 testObjects.CreateDetails(); 143 144 string caller = "TheTests"; 145 testObjects.Processor.Caller = caller; 146 147 GetConfigurationUnitSettingsResult result = testObjects.Processor.GetUnitSettings(testObjects.Unit); 148 149 Assert.Single(this.EventSink.Events); 150 Assert.Equal(TelemetryEvent.ConfigUnitRunName, this.EventSink.Events[0].Name); 151 Assert.Equal(caller, this.EventSink.Events[0].Caller); 152 } 153 154 /// <summary> 155 /// Verifies all of the telemetry fields that come from executing a specific unit. 156 /// </summary> 157 [Fact] 158 public void Telemetry_UnitFields() 159 { 160 #pragma warning disable CS8602 // Dereference of a possibly null reference. 161 TelemetryTestObjects testObjects = new TelemetryTestObjects(); 162 testObjects.Processor = this.CreateConfigurationProcessorWithDiagnostics(testObjects.Factory); 163 testObjects.CreateDetails(); 164 165 testObjects.Unit.Type = "TestUnitName"; 166 testObjects.UnitDetails.ModuleName = "TestModuleName"; 167 168 string setting1 = "setting1"; 169 string setting2 = "setting2"; 170 171 testObjects.Unit.Settings.Add(setting1, 0); 172 testObjects.Unit.Settings.Add(setting2, 0); 173 174 GetConfigurationUnitSettingsResult result = testObjects.Processor.GetUnitSettings(testObjects.Unit); 175 176 Assert.Single(this.EventSink.Events); 177 TelemetryEvent runEvent = this.EventSink.Events[0]; 178 Assert.Equal(TelemetryEvent.ConfigUnitRunName, runEvent.Name); 179 Assert.NotEqual(string.Empty, runEvent.CodeVersion); 180 Assert.NotEqual(Guid.Empty, runEvent.ActivityID); 181 Assert.Equal(string.Empty, runEvent.Caller); 182 Assert.Equal(Guid.Empty, Guid.Parse(runEvent.Properties[TelemetryEvent.SetID])); 183 Assert.NotEqual(Guid.Empty, Guid.Parse(runEvent.Properties[TelemetryEvent.UnitID])); 184 Assert.Equal(testObjects.Unit.Type, runEvent.Properties[TelemetryEvent.UnitName]); 185 Assert.Equal(testObjects.UnitDetails.ModuleName, runEvent.Properties[TelemetryEvent.ModuleName]); 186 Assert.Equal(((int)testObjects.Unit.Intent).ToString(), runEvent.Properties[TelemetryEvent.UnitIntent]); 187 Assert.Equal(((int)ConfigurationUnitIntent.Inform).ToString(), runEvent.Properties[TelemetryEvent.RunIntent]); 188 Assert.NotEqual(string.Empty, runEvent.Properties[TelemetryEvent.Action]); 189 Assert.Equal(testObjects.GetResult.ResultInformation.ResultCode.HResult.ToString(), runEvent.Properties[TelemetryEvent.Result]); 190 Assert.Equal(((int)testObjects.GetResult.ResultInformation.ResultSource).ToString(), runEvent.Properties[TelemetryEvent.FailurePoint]); 191 Assert.Equal(setting1 + "|" + setting2, runEvent.Properties[TelemetryEvent.SettingsProvided]); 192 #pragma warning restore CS8602 // Dereference of a possibly null reference. 193 } 194 195 private class TelemetryTestObjects 196 { 197 public TelemetryTestObjects(bool getFails = true) 198 { 199 this.Unit = new ConfigurationUnit { Intent = ConfigurationUnitIntent.Apply }; 200 201 this.Factory = new TestConfigurationProcessorFactory(); 202 this.Factory.NullProcessor = new TestConfigurationSetProcessor(null); 203 204 this.UnitProcessor = this.Factory.NullProcessor.CreateTestProcessor(this.Unit); 205 206 if (getFails) 207 { 208 var getResult = new GetSettingsResultInstance(this.Unit); 209 getResult.InternalResult.ResultCode = new NullReferenceException(); 210 getResult.InternalResult.ResultSource = ConfigurationUnitResultSource.UnitProcessing; 211 this.GetResult = getResult; 212 this.UnitProcessor.GetSettingsDelegate = () => this.GetResult; 213 } 214 } 215 216 public ConfigurationUnit Unit { get; set; } 217 218 public TestConfigurationProcessorFactory Factory { get; set; } 219 220 public TestConfigurationUnitProcessor UnitProcessor { get; set; } 221 222 public IGetSettingsResult? GetResult { get; set; } 223 224 public TestConfigurationUnitProcessorDetails? UnitDetails { get; set; } 225 226 public ConfigurationProcessor? Processor { get; set; } 227 228 public void CreateDetails(bool isPublic = true) 229 { 230 #pragma warning disable CS8602 // Dereference of a possibly null reference. 231 this.UnitDetails = this.Factory.NullProcessor.CreateUnitDetails(this.Unit, ConfigurationUnitDetailFlags.ReadOnly); 232 #pragma warning restore CS8602 // Dereference of a possibly null reference. 233 this.UnitDetails.IsPublic = isPublic; 234 235 this.Processor?.GetUnitDetails(this.Unit, ConfigurationUnitDetailFlags.ReadOnly); 236 } 237 } 238 } 239 }