diff --git a/.publicApi/Microsoft.ApplicationInsights.dll/Stable/PublicAPI.Unshipped.txt b/.publicApi/Microsoft.ApplicationInsights.dll/Stable/PublicAPI.Unshipped.txt index 3138568ce7..89aec753af 100644 --- a/.publicApi/Microsoft.ApplicationInsights.dll/Stable/PublicAPI.Unshipped.txt +++ b/.publicApi/Microsoft.ApplicationInsights.dll/Stable/PublicAPI.Unshipped.txt @@ -273,7 +273,7 @@ override Microsoft.ApplicationInsights.DataContracts.RequestTelemetry.Success.ge override Microsoft.ApplicationInsights.DataContracts.RequestTelemetry.Success.set -> void override Microsoft.ApplicationInsights.DataContracts.RequestTelemetry.Timestamp.get -> System.DateTimeOffset override Microsoft.ApplicationInsights.DataContracts.RequestTelemetry.Timestamp.set -> void -override Microsoft.ApplicationInsights.Metrics.MetricIdentifier.Equals(object otherObj) -> bool +override Microsoft.ApplicationInsights.Metrics.MetricIdentifier.Equals(object obj) -> bool override Microsoft.ApplicationInsights.Metrics.MetricIdentifier.GetHashCode() -> int override Microsoft.ApplicationInsights.Metrics.MetricIdentifier.ToString() -> string static Microsoft.ApplicationInsights.Extensibility.TelemetryConfiguration.CreateDefault() -> Microsoft.ApplicationInsights.Extensibility.TelemetryConfiguration diff --git a/BASE/src/Microsoft.ApplicationInsights/DataContracts/ExceptionTelemetry.cs b/BASE/src/Microsoft.ApplicationInsights/DataContracts/ExceptionTelemetry.cs index 4829b05618..b7d6e5f9df 100644 --- a/BASE/src/Microsoft.ApplicationInsights/DataContracts/ExceptionTelemetry.cs +++ b/BASE/src/Microsoft.ApplicationInsights/DataContracts/ExceptionTelemetry.cs @@ -287,7 +287,9 @@ private static Exception ReconstructExceptionFromDetails(IReadOnlyListAn ambient activity that was suppressed to create a root operation and should be restored on dispose. public OperationHolder(TelemetryClient telemetryClient, T telemetry, Activity activity, Activity suppressedActivity) { - if (telemetryClient == null) - { - throw new ArgumentNullException(nameof(telemetryClient)); - } - - if (telemetry == null) - { - throw new ArgumentNullException(nameof(telemetry)); - } - - this.telemetryClient = telemetryClient; - this.Telemetry = telemetry; + this.telemetryClient = telemetryClient ?? throw new ArgumentNullException(nameof(telemetryClient)); + this.Telemetry = telemetry ?? throw new ArgumentNullException(nameof(telemetry)); this.activity = activity; this.suppressedActivity = suppressedActivity; } diff --git a/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Tracing/SelfDiagnosticsConfigParser.cs b/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Tracing/SelfDiagnosticsConfigParser.cs index 92c7dc97fb..a25c4a9b3c 100644 --- a/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Tracing/SelfDiagnosticsConfigParser.cs +++ b/BASE/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Tracing/SelfDiagnosticsConfigParser.cs @@ -74,8 +74,14 @@ public bool TryGetConfiguration(out string logDirectory, out int fileSizeInKB, o this.configBuffer = buffer; } - file.Read(buffer, 0, buffer.Length); - string configJson = Encoding.UTF8.GetString(buffer); + int totalBytesRead = 0; + int bytesRead; + while (totalBytesRead < buffer.Length && (bytesRead = file.Read(buffer, totalBytesRead, buffer.Length - totalBytesRead)) > 0) + { + totalBytesRead += bytesRead; + } + + string configJson = Encoding.UTF8.GetString(buffer, 0, totalBytesRead); if (logDirectory == null && !TryParseLogDirectory(configJson, out logDirectory)) { @@ -102,7 +108,11 @@ public bool TryGetConfiguration(out string logDirectory, out int fileSizeInKB, o return false; } +#if NETCOREAPP + logLevel = Enum.Parse(logLevelString); +#else logLevel = (EventLevel)Enum.Parse(typeof(EventLevel), logLevelString); +#endif return true; } } diff --git a/BASE/src/Microsoft.ApplicationInsights/Extensibility/TelemetryConfiguration.cs b/BASE/src/Microsoft.ApplicationInsights/Extensibility/TelemetryConfiguration.cs index ab04cf2f07..5fdb3a10af 100644 --- a/BASE/src/Microsoft.ApplicationInsights/Extensibility/TelemetryConfiguration.cs +++ b/BASE/src/Microsoft.ApplicationInsights/Extensibility/TelemetryConfiguration.cs @@ -256,11 +256,14 @@ public static TelemetryConfiguration CreateDefault() public void ConfigureOpenTelemetryBuilder(Action configure) { this.ThrowIfBuilt(); - +#if NET6_0_OR_GREATER + ArgumentNullException.ThrowIfNull(configure); +#else if (configure == null) { throw new ArgumentNullException(nameof(configure)); } +#endif // Chain the configurations var previousConfiguration = this.builderConfiguration; @@ -291,11 +294,14 @@ public void Dispose() public void SetAzureTokenCredential(TokenCredential tokenCredential) { this.ThrowIfBuilt(); - +#if NET6_0_OR_GREATER + ArgumentNullException.ThrowIfNull(tokenCredential); +#else if (tokenCredential == null) { throw new ArgumentNullException(nameof(tokenCredential)); } +#endif // Configure the OpenTelemetry builder to pass the credential to Azure Monitor Exporter this.ConfigureOpenTelemetryBuilder(builder => diff --git a/BASE/src/Microsoft.ApplicationInsights/Internal/FeatureMetricEmissionHelper.cs b/BASE/src/Microsoft.ApplicationInsights/Internal/FeatureMetricEmissionHelper.cs index 105c948c2d..67bc6b4f20 100644 --- a/BASE/src/Microsoft.ApplicationInsights/Internal/FeatureMetricEmissionHelper.cs +++ b/BASE/src/Microsoft.ApplicationInsights/Internal/FeatureMetricEmissionHelper.cs @@ -123,7 +123,7 @@ private static Dictionary GetVmMetadata() using (var httpClient = new HttpClient() { Timeout = TimeSpan.FromSeconds(2) }) { httpClient.DefaultRequestHeaders.Add("Metadata", "True"); - var responseString = httpClient.GetStringAsync(StatsbeatConstants.AMSUrl); + var responseString = httpClient.GetStringAsync(new Uri(StatsbeatConstants.AMSUrl)); return JsonSerializer.Deserialize>(responseString.Result); } } @@ -168,7 +168,9 @@ private string GetResourceProvider() if (vmMetadata.TryGetValue("osType", out var osType) && osType is string) { // osType takes precedence over the platform-observed OS. - this.os = (osType as string).ToLower(CultureInfo.InvariantCulture); +#pragma warning disable CA1308 // Normalize strings to uppercase + this.os = (osType as string).ToLowerInvariant(); +#pragma warning restore CA1308 // Normalize strings to uppercase } else { diff --git a/BASE/src/Microsoft.ApplicationInsights/Metrics/MetricIdentifier.cs b/BASE/src/Microsoft.ApplicationInsights/Metrics/MetricIdentifier.cs index 89984d15d6..6cbac391d7 100644 --- a/BASE/src/Microsoft.ApplicationInsights/Metrics/MetricIdentifier.cs +++ b/BASE/src/Microsoft.ApplicationInsights/Metrics/MetricIdentifier.cs @@ -1,6 +1,9 @@ namespace Microsoft.ApplicationInsights.Metrics { using System; +#if NET8_0_OR_GREATER + using System.Buffers; +#endif using System.Collections.Generic; using System.Runtime.CompilerServices; using System.Text; @@ -16,11 +19,20 @@ public sealed class MetricIdentifier : IEquatable private const string NoNamespaceIdentifierStringComponent = ""; +#if NET8_0_OR_GREATER + private static readonly SearchValues InvalidMetricCharsSearchValues = SearchValues.Create( + new char[] + { + '\0', '"', '\'', '(', ')', '[', ']', '{', '}', '<', '>', '=', ',', + '`', '~', '!', '@', '#', '$', '%', '^', '&', '*', '+', '?', + }); +#else private static readonly char[] InvalidMetricChars = new char[] { '\0', '"', '\'', '(', ')', '[', ']', '{', '}', '<', '>', '=', ',', '`', '~', '!', '@', '#', '$', '%', '^', '&', '*', '+', '?', }; +#endif private static string defaultMetricNamespace = String.Empty; @@ -65,7 +77,11 @@ private static void ValidateLiteral(string partValue, string partName, bool allo } } - int pos = partName.IndexOfAny(InvalidMetricChars); +#if NET8_0_OR_GREATER + int pos = partValue.AsSpan().IndexOfAny(InvalidMetricCharsSearchValues); +#else + int pos = partValue.IndexOfAny(InvalidMetricChars); +#endif if (pos >= 0) { throw new ArgumentException(Invariant($"{partName} (\"{partValue}\") contains a disallowed character at position {pos}.")); @@ -501,17 +517,17 @@ public override int GetHashCode() /// Determines whether the specified object is a MetricIdentifier that is equal to this MetricIdentifier based on the /// respective metric namespaces, metric IDs and the number and the names of dimensions. /// - /// Another object. + /// Another object. /// Whether the specified other object is equal to this object based on the respective namespaces, IDs and dimension names. - public override bool Equals(object otherObj) + public override bool Equals(object obj) { - if (otherObj is MetricIdentifier otherMetricIdentifier) + if (obj is MetricIdentifier otherMetricIdentifier) { return this.Equals(otherMetricIdentifier); } else { - return base.Equals(otherObj); + return base.Equals(obj); } } @@ -617,7 +633,11 @@ private static void EnsureDimensionNameValid(ref int dimensionCount, ref string + " they must contain at least 1 printable character."); } +#if NET8_0_OR_GREATER + int pos = dimensionName.AsSpan().IndexOfAny(InvalidMetricCharsSearchValues); +#else int pos = dimensionName.IndexOfAny(InvalidMetricChars); +#endif if (pos >= 0) { throw new ArgumentException(Invariant($"Name for dimension number {thisDimensionNumber} (\"{dimensionName}\")") diff --git a/BASE/src/Microsoft.ApplicationInsights/TelemetryClient.cs b/BASE/src/Microsoft.ApplicationInsights/TelemetryClient.cs index 38e525b835..aa45494a46 100644 --- a/BASE/src/Microsoft.ApplicationInsights/TelemetryClient.cs +++ b/BASE/src/Microsoft.ApplicationInsights/TelemetryClient.cs @@ -473,7 +473,7 @@ public void TrackException(Exception exception, IDictionary prop this.Configuration.FeatureReporter.MarkFeatureInUse(StatsbeatFeatures.TrackException); if (exception == null) { - exception = new Exception(Utils.PopulateRequiredStringValue(null, "message", typeof(ExceptionTelemetry).FullName)); + exception = new InvalidOperationException(Utils.PopulateRequiredStringValue(null, "message", typeof(ExceptionTelemetry).FullName)); } var state = new DictionaryLogState(this.Context, properties, exception.Message); @@ -493,7 +493,7 @@ public void TrackException(ExceptionTelemetry telemetry) // TODO investigate how problem id, custom message, etc should appear in portal if (telemetry == null) { - var exception = new Exception(Utils.PopulateRequiredStringValue(null, "message", typeof(ExceptionTelemetry).FullName)); + var exception = new InvalidOperationException(Utils.PopulateRequiredStringValue(null, "message", typeof(ExceptionTelemetry).FullName)); telemetry = new ExceptionTelemetry(exception); } @@ -697,10 +697,14 @@ public void TrackDependency(DependencyTelemetry telemetry) [EditorBrowsable(EditorBrowsableState.Never)] public void Track(ITelemetry telemetry) { +#if NET6_0_OR_GREATER + ArgumentNullException.ThrowIfNull(telemetry); +#else if (telemetry == null) { throw new ArgumentNullException(nameof(telemetry)); } +#endif switch (telemetry) { @@ -1119,10 +1123,14 @@ public Metric GetMetric( public Metric GetMetric( MetricIdentifier metricIdentifier) { +#if NET6_0_OR_GREATER + ArgumentNullException.ThrowIfNull(metricIdentifier); +#else if (metricIdentifier == null) { throw new ArgumentNullException(nameof(metricIdentifier)); } +#endif // Build dimension names array from MetricIdentifier string[] dimensionNames = null; @@ -1231,10 +1239,14 @@ private static ActivityKind GetActivityKindForDependency(string dependencyType) /// A reconstructed Exception with all diagnostic details. private static Exception ConvertToException(ExceptionTelemetry telemetry) { +#if NET6_0_OR_GREATER + ArgumentNullException.ThrowIfNull(telemetry); +#else if (telemetry == null) { throw new ArgumentNullException(nameof(telemetry)); } +#endif Exception rootException = null; @@ -1252,7 +1264,9 @@ private static Exception ConvertToException(ExceptionTelemetry telemetry) else { // Fallback: create a generic exception with the message +#pragma warning disable CA2201 // Exception reconstruction requires generic Exception type rootException = new Exception(telemetry.Message ?? ""); +#pragma warning restore CA2201 } // Enrich the exception with metadata @@ -1270,7 +1284,9 @@ private static Exception ReconstructExceptionChain(IReadOnlyList"); +#pragma warning restore CA2201 } // Process from innermost (index 0) to outermost (last index) @@ -1287,6 +1303,7 @@ private static Exception ReconstructExceptionChain(IReadOnlyList StartOperation( string parentOperationId = null) where T : OperationTelemetry, new() { +#if NET6_0_OR_GREATER + ArgumentNullException.ThrowIfNull(telemetryClient); +#else if (telemetryClient == null) { throw new ArgumentNullException(nameof(telemetryClient)); } +#endif telemetryClient.Configuration.FeatureReporter.MarkFeatureInUse(Internal.StatsbeatFeatures.StartOperation); @@ -137,6 +141,10 @@ public static IOperationHolder StartOperation( T operationTelemetry) where T : OperationTelemetry { +#if NET6_0_OR_GREATER + ArgumentNullException.ThrowIfNull(telemetryClient); + ArgumentNullException.ThrowIfNull(operationTelemetry); +#else if (telemetryClient == null) { throw new ArgumentNullException(nameof(telemetryClient)); @@ -146,6 +154,7 @@ public static IOperationHolder StartOperation( { throw new ArgumentNullException(nameof(operationTelemetry)); } +#endif if (string.IsNullOrEmpty(operationTelemetry.Name)) { @@ -221,10 +230,14 @@ public static IOperationHolder StartOperation( Activity activity) where T : OperationTelemetry, new() { +#if NET6_0_OR_GREATER + ArgumentNullException.ThrowIfNull(telemetryClient); +#else if (telemetryClient == null) { throw new ArgumentNullException(nameof(telemetryClient)); } +#endif if (activity == null) { @@ -275,10 +288,14 @@ public static void StopOperation( IOperationHolder operation) where T : OperationTelemetry { +#if NET6_0_OR_GREATER + ArgumentNullException.ThrowIfNull(telemetryClient); +#else if (telemetryClient == null) { throw new ArgumentNullException(nameof(telemetryClient)); } +#endif if (operation == null) { diff --git a/NETCORE/src/Microsoft.ApplicationInsights.AspNetCore/JavaScriptSnippet.cs b/NETCORE/src/Microsoft.ApplicationInsights.AspNetCore/JavaScriptSnippet.cs index e2b8ea8f43..939f5a55e6 100644 --- a/NETCORE/src/Microsoft.ApplicationInsights.AspNetCore/JavaScriptSnippet.cs +++ b/NETCORE/src/Microsoft.ApplicationInsights.AspNetCore/JavaScriptSnippet.cs @@ -20,8 +20,10 @@ public class JavaScriptSnippet : IJavaScriptSnippet /// JavaScript snippet. private static readonly string Snippet = Resources.JavaScriptSnippet; +#if !NET6_0_OR_GREATER /// JavaScript authenticated user tracking snippet. private static readonly string AuthSnippet = Resources.JavaScriptAuthSnippet; +#endif /// Http context accessor. private readonly IHttpContextAccessor httpContextAccessor; @@ -47,10 +49,14 @@ public JavaScriptSnippet( IHttpContextAccessor httpContextAccessor = null, JavaScriptEncoder encoder = null) { +#if NET6_0_OR_GREATER + ArgumentNullException.ThrowIfNull(serviceOptions); +#else if (serviceOptions == null) { throw new ArgumentNullException(nameof(serviceOptions)); } +#endif this.telemetryConfiguration = telemetryConfiguration; this.httpContextAccessor = httpContextAccessor; @@ -105,11 +111,19 @@ public string ScriptBody if (identity != null && identity.IsAuthenticated) { string escapedUserName = this.encoder.Encode(identity.Name); +#if NET6_0_OR_GREATER + insertAuthUserContext = string.Create(CultureInfo.InvariantCulture, $"appInsights.setAuthenticatedUserContext(\"{escapedUserName}\");"); +#else insertAuthUserContext = string.Format(CultureInfo.InvariantCulture, AuthSnippet, escapedUserName); +#endif } } +#if NET6_0_OR_GREATER + var snippet = Snippet.Replace("connectionString: \"YOUR_CONNECTION_STRING\"", insertConfig, StringComparison.Ordinal); +#else var snippet = Snippet.Replace("connectionString: \"YOUR_CONNECTION_STRING\"", insertConfig); +#endif // Return snippet return string.Concat(snippet, insertAuthUserContext); } diff --git a/NETCORE/test/FunctionalTests.MVC.Tests/.bowerrc b/NETCORE/test/FunctionalTests.MVC.Tests/.bowerrc deleted file mode 100644 index 6406626abf..0000000000 --- a/NETCORE/test/FunctionalTests.MVC.Tests/.bowerrc +++ /dev/null @@ -1,3 +0,0 @@ -{ - "directory": "wwwroot/lib" -} diff --git a/NETCORE/test/FunctionalTests.MVC.Tests/Controllers/HomeController.cs b/NETCORE/test/FunctionalTests.MVC.Tests/Controllers/HomeController.cs deleted file mode 100644 index 381b779c6a..0000000000 --- a/NETCORE/test/FunctionalTests.MVC.Tests/Controllers/HomeController.cs +++ /dev/null @@ -1,63 +0,0 @@ -using System; -using System.Diagnostics; -using Microsoft.AspNetCore.Mvc; -using Microsoft.ApplicationInsights; -using Microsoft.ApplicationInsights.DataContracts; -using FunctionalTests.MVC.Tests.Models; - -namespace FunctionalTests.MVC.Tests.Controllers -{ - public class HomeController : Controller - { - private TelemetryClient telemetryClient; - - public HomeController(TelemetryClient telemetryClient) - { - this.telemetryClient = telemetryClient; - } - - public IActionResult Index() - { - return View(); - } - - public IActionResult About(int index) - { - ViewBag.Message = "Your application description page # " + index; - - return View(); - } - - public IActionResult Contact() - { - this.telemetryClient.TrackEvent("GetContact"); - this.telemetryClient.TrackMetric("ContactFile", 1); - this.telemetryClient.TrackTrace("Fetched contact details.", SeverityLevel.Information); - ViewData["Message"] = "Your contact page."; - - return View(); - } - - public IActionResult Exception() - { - throw new InvalidOperationException("Do not call the method called Exception"); - } - - public IActionResult Dependency() - { - this.telemetryClient.TrackDependency( - dependencyTypeName: "test", - dependencyName: "MyDependency", - data: "MyCommand", - startTime: DateTimeOffset.Now, - duration: TimeSpan.FromMilliseconds(1), - success: true); - return View(); - } - - public IActionResult Error() - { - return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier }); - } - } -} diff --git a/NETCORE/test/FunctionalTests.MVC.Tests/FunctionalTest/CorrelationMvcTests.cs b/NETCORE/test/FunctionalTests.MVC.Tests/FunctionalTest/CorrelationMvcTests.cs deleted file mode 100644 index d3ef4f519d..0000000000 --- a/NETCORE/test/FunctionalTests.MVC.Tests/FunctionalTest/CorrelationMvcTests.cs +++ /dev/null @@ -1,49 +0,0 @@ -namespace FunctionalTests.MVC.Tests.FunctionalTest -{ - using FunctionalTests.Utils; - using Microsoft.ApplicationInsights.DataContracts; - using System; - using System.Linq; - using System.Net.Http; - using AI; - using Xunit; - using Xunit.Abstractions; - - public class CorrelationMvcTests : TelemetryTestsBase - { - private const string assemblyName = "FunctionalTests.MVC.Tests"; - - public CorrelationMvcTests(ITestOutputHelper output) : base(output) - { - } - - - [Fact] - public void CorrelationInfoIsPropagatedToDependendedService() - { - // TODO: THIS IS A TESTING GAP -//#if NETCOREAPP // Correlation works on .Net core. -// using (var server = new InProcessServer(assemblyName, this.output)) -// { -// using (var httpClient = new HttpClient()) -// { -// var task = httpClient.GetAsync(server.BaseHost + "/"); -// task.Wait(TestTimeoutMs); -// } - -// var actual = server.Execute(() => server.Listener.ReceiveItems(2, TestListenerTimeoutInMs)); -// this.DebugTelemetryItems(actual); - -// var dependencyTelemetry = actual.OfType>().FirstOrDefault(); -// Assert.NotNull(dependencyTelemetry); - -// var requestTelemetry = actual.OfType>().FirstOrDefault(); -// Assert.NotNull(requestTelemetry); - -// Assert.Equal(requestTelemetry.tags["ai.operation.id"], dependencyTelemetry.tags["ai.operation.id"]); -// Assert.Contains(dependencyTelemetry.tags["ai.operation.id"], requestTelemetry.tags["ai.operation.parentId"]); -// } -//#endif - } - } -} diff --git a/NETCORE/test/FunctionalTests.MVC.Tests/FunctionalTest/DependencyTelemetryMvcTests.cs b/NETCORE/test/FunctionalTests.MVC.Tests/FunctionalTest/DependencyTelemetryMvcTests.cs deleted file mode 100644 index 7f107007e3..0000000000 --- a/NETCORE/test/FunctionalTests.MVC.Tests/FunctionalTest/DependencyTelemetryMvcTests.cs +++ /dev/null @@ -1,115 +0,0 @@ -namespace FunctionalTests.MVC.Tests.FunctionalTest -{ - using System; - using System.Linq; - using System.Net.Http; - using System.Reflection; - using System.Text; - - using AI; - using FunctionalTests.Utils; - using Microsoft.ApplicationInsights.DependencyCollector; - using Microsoft.ApplicationInsights.Extensibility; - using Microsoft.Extensions.DependencyInjection; - using Xunit; - using Xunit.Abstractions; - - public class DependencyTelemetryMvcTests : TelemetryTestsBase - { - private readonly string assemblyName; - - public DependencyTelemetryMvcTests(ITestOutputHelper output) : base(output) - { - this.assemblyName = this.GetType().GetTypeInfo().Assembly.GetName().Name; - } - - [Fact] - public void CorrelationInfoIsNotAddedToRequestHeaderIfUserAddDomainToExcludedList() - { - // TODO: THIS IS A TESTING GAP -//#if NETCOREAPP // Correlation is supported on .Net core. -// using (var server = new InProcessServer(assemblyName, this.output)) -// { -// var dependencyCollectorModule = server.ApplicationServices.GetServices().OfType().Single(); -// dependencyCollectorModule.ExcludeComponentCorrelationHttpHeadersOnDomains.Add(server.BaseHost); - -// using (var httpClient = new HttpClient()) -// { -// var task = httpClient.GetAsync(server.BaseHost + "/"); -// task.Wait(TestTimeoutMs); -// } - -// var actual = server.Execute(() => server.Listener.ReceiveItems(TestListenerTimeoutInMs)); -// this.DebugTelemetryItems(actual); - -// try -// { -// var dependencyTelemetry = actual.OfType>().FirstOrDefault(); -// Assert.NotNull(dependencyTelemetry); - -// var requestTelemetry = actual.OfType>().FirstOrDefault(); -// Assert.NotNull(requestTelemetry); - -// Assert.NotEqual(requestTelemetry.tags["ai.operation.id"], dependencyTelemetry.tags["ai.operation.id"]); -// } -// catch (Exception e) -// { -// string data = DebugTelemetryItems(actual); -// throw new Exception(data, e); -// } -// } -//#endif - } - - [Fact] - public void OperationIdOfRequestIsPropagatedToChildDependency() - { - // https://github.com/Microsoft/ApplicationInsights-aspnetcore/issues/340 - // Verify operation of OperationIdTelemetryInitializer - string path = "Home/Dependency"; - InProcessServer server; - - using (server = new InProcessServer(assemblyName, this.output)) - { - this.ExecuteRequest(server.BaseHost + "/" + path); - - var actual = server.Listener.ReceiveItems(TestListenerTimeoutInMs); - this.DebugTelemetryItems(actual); - - var dependencyTelemetry = actual.OfType>() - .First(t => ((TelemetryItem)t).data.baseData.name == "MyDependency"); - Assert.NotNull(dependencyTelemetry); - - var requestTelemetry = actual.OfType>().FirstOrDefault(); - Assert.NotNull(requestTelemetry); - - Assert.Equal(requestTelemetry.tags["ai.operation.id"], dependencyTelemetry.tags["ai.operation.id"]); - } - } - - [Fact] - public void ParentIdOfChildDependencyIsIdOfRequest() - { - // https://github.com/Microsoft/ApplicationInsights-aspnetcore/issues/333 - // Verify operation of OperationCorrelationTelemetryInitializer - string path = "Home/Dependency"; - InProcessServer server; - using (server = new InProcessServer(assemblyName, this.output)) - { - this.ExecuteRequest(server.BaseHost + "/" + path); - - var actual = server.Listener.ReceiveItems(TestListenerTimeoutInMs); - this.DebugTelemetryItems(actual); - - var dependencyTelemetry = actual.OfType>() - .First(t => ((TelemetryItem)t).data.baseData.name == "MyDependency"); - Assert.NotNull(dependencyTelemetry); - - var requestTelemetry = actual.OfType>().FirstOrDefault(); - Assert.NotNull(requestTelemetry); - - Assert.Equal(requestTelemetry.data.baseData.id, dependencyTelemetry.tags["ai.operation.parentId"]); - } - } - } -} diff --git a/NETCORE/test/FunctionalTests.MVC.Tests/FunctionalTest/ExceptionTelemetryMvcTests.cs b/NETCORE/test/FunctionalTests.MVC.Tests/FunctionalTest/ExceptionTelemetryMvcTests.cs deleted file mode 100644 index 12f99d59af..0000000000 --- a/NETCORE/test/FunctionalTests.MVC.Tests/FunctionalTest/ExceptionTelemetryMvcTests.cs +++ /dev/null @@ -1,52 +0,0 @@ -using Xunit; - -[assembly: CollectionBehavior(DisableTestParallelization = true)] -namespace FunctionalTests.MVC.Tests.FunctionalTest -{ - using System; - using System.Reflection; - using FunctionalTests.Utils; - using Microsoft.ApplicationInsights.DataContracts; - using Xunit; - using Xunit.Abstractions; - - public class ExceptionTelemetryMvcTests : TelemetryTestsBase - { - private readonly string assemblyName; - - public ExceptionTelemetryMvcTests(ITestOutputHelper output) : base(output) - { - this.assemblyName = this.GetType().GetTypeInfo().Assembly.GetName().Name; - } - - [Fact] - public void TestBasicRequestPropertiesAfterRequestingControllerThatThrows() - { - using (var server = new InProcessServer(assemblyName, this.output)) - { - const string RequestPath = "/Home/Exception"; - - var expectedRequestTelemetry = new RequestTelemetry(); - expectedRequestTelemetry.Name = "GET Home/Exception"; - expectedRequestTelemetry.ResponseCode = "500"; - expectedRequestTelemetry.Success = false; - expectedRequestTelemetry.Url = new System.Uri(server.BaseHost + RequestPath); - - // the is no response header because of https://github.com/Microsoft/ApplicationInsights-aspnetcore/issues/717 - this.ValidateBasicRequest(server, "/Home/Exception", expectedRequestTelemetry, false); - } - } - - [Fact] - public void TestBasicExceptionPropertiesAfterRequestingControllerThatThrows() - { - using (var server = new InProcessServer(assemblyName, this.output)) - { - var expectedExceptionTelemetry = new ExceptionTelemetry(); - expectedExceptionTelemetry.Exception = new InvalidOperationException(); - - this.ValidateBasicException(server, "/Home/Exception", expectedExceptionTelemetry); - } - } - } -} diff --git a/NETCORE/test/FunctionalTests.MVC.Tests/FunctionalTest/RequestTelemetryMvcTests.cs b/NETCORE/test/FunctionalTests.MVC.Tests/FunctionalTest/RequestTelemetryMvcTests.cs deleted file mode 100644 index a1209588b6..0000000000 --- a/NETCORE/test/FunctionalTests.MVC.Tests/FunctionalTest/RequestTelemetryMvcTests.cs +++ /dev/null @@ -1,53 +0,0 @@ -namespace FunctionalTests.MVC.Tests.FunctionalTest -{ - using System.Collections.Generic; - using System.Linq; - using System.Net.Http; - using System.Reflection; - using AI; - using FunctionalTests.Utils; - using Microsoft.ApplicationInsights.DataContracts; - using Xunit; - using Xunit.Abstractions; - - public class RequestTelemetryMvcTests : TelemetryTestsBase - { - private readonly string assemblyName; - - public RequestTelemetryMvcTests(ITestOutputHelper output) : base(output) - { - this.assemblyName = this.GetType().GetTypeInfo().Assembly.GetName().Name; - } - - [Fact] - public void TestMixedTelemetryItemsReceived() - { - using (var server = new InProcessServer(assemblyName, this.output)) - { - this.ExecuteRequest(server.BaseHost + "/Home/Contact"); - - var telemetries = server.Listener.ReceiveItems(TestListenerTimeoutInMs); - this.DebugTelemetryItems(telemetries); - - // In linux 6 items as it'll always have an Error trace from SDK itself about - // local storage folder. - Assert.InRange(telemetries.Length, 5, 6); - - Assert.Contains(telemetries.OfType>(), - t => ((TelemetryItem)t).data.baseData.name == "GET /Home/Contact"); - - Assert.Contains(telemetries.OfType>(), - t => ((TelemetryItem)t).data.baseData.name == "GET Home/Contact"); - - Assert.Contains(telemetries.OfType>(), - t => ((TelemetryItem)t).data.baseData.name == "GetContact"); - - Assert.Contains(telemetries.OfType>(), - t => ((TelemetryItem)t).data.baseData.metrics[0].name == "ContactFile" && ((TelemetryItem)t).data.baseData.metrics[0].value == 1); - - Assert.Contains(telemetries.OfType>(), - t => ((TelemetryItem)t).data.baseData.message == "Fetched contact details." && ((TelemetryItem)t).data.baseData.severityLevel == AI.SeverityLevel.Information); - } - } - } -} diff --git a/NETCORE/test/FunctionalTests.MVC.Tests/FunctionalTest/TelemetryModuleWorkingMvcTests.cs b/NETCORE/test/FunctionalTests.MVC.Tests/FunctionalTest/TelemetryModuleWorkingMvcTests.cs deleted file mode 100644 index d920597ec1..0000000000 --- a/NETCORE/test/FunctionalTests.MVC.Tests/FunctionalTest/TelemetryModuleWorkingMvcTests.cs +++ /dev/null @@ -1,41 +0,0 @@ -namespace FunctionalTests.MVC.Tests.FunctionalTest -{ - using System.Reflection; - using FunctionalTests.Utils; - using Microsoft.ApplicationInsights.DataContracts; - using Xunit; - using Xunit.Abstractions; - - public class TelemetryModuleWorkingMvcTests : TelemetryTestsBase - { - private readonly string assemblyName; - - public TelemetryModuleWorkingMvcTests(ITestOutputHelper output) : base(output) - { - this.assemblyName = this.GetType().GetTypeInfo().Assembly.GetName().Name; - } - - [Fact] - public void TestBasicDependencyPropertiesAfterRequestingBasicPage() - { - const string RequestPath = "/Home/About/5"; - - using (var server = new InProcessServer(assemblyName, this.output)) - { - DependencyTelemetry expected = new DependencyTelemetry(); - expected.ResultCode = "200"; - expected.Success = true; - expected.Name = "GET " + RequestPath; - expected.Data = server.BaseHost + RequestPath; - - this.ValidateBasicDependency(server, RequestPath, expected); - } - } - - [Fact] - public void TestIfPerformanceCountersAreCollected() - { - ValidatePerformanceCountersAreCollected(assemblyName); - } - } -} diff --git a/NETCORE/test/FunctionalTests.MVC.Tests/FunctionalTests.MVC.Tests.csproj b/NETCORE/test/FunctionalTests.MVC.Tests/FunctionalTests.MVC.Tests.csproj deleted file mode 100644 index 5a2e26e08b..0000000000 --- a/NETCORE/test/FunctionalTests.MVC.Tests/FunctionalTests.MVC.Tests.csproj +++ /dev/null @@ -1,65 +0,0 @@ - - - - - - - $(TargetFrameworks_NetCoreOnly) - - 2.0.0 - true - FunctionalTests.MVC.Tests - FunctionalTests.MVC.Tests - aspnet-MVCFramework45.FunctionalTests-60cfc765-2dc9-454c-bb34-dc379ed92cd0 - true - true - - - - - Always - SettingsSingleFileGenerator - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - - - - - - - - - - - - - - - - - - - - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - - - - - - - - - diff --git a/NETCORE/test/FunctionalTests.MVC.Tests/Models/ErrorViewModel.cs b/NETCORE/test/FunctionalTests.MVC.Tests/Models/ErrorViewModel.cs deleted file mode 100644 index 5a34c1fd32..0000000000 --- a/NETCORE/test/FunctionalTests.MVC.Tests/Models/ErrorViewModel.cs +++ /dev/null @@ -1,11 +0,0 @@ -using System; - -namespace FunctionalTests.MVC.Tests.Models -{ - public class ErrorViewModel - { - public string RequestId { get; set; } - - public bool ShowRequestId => !string.IsNullOrEmpty(RequestId); - } -} \ No newline at end of file diff --git a/NETCORE/test/FunctionalTests.MVC.Tests/Properties/launchSettings.json b/NETCORE/test/FunctionalTests.MVC.Tests/Properties/launchSettings.json deleted file mode 100644 index 8ba517fc11..0000000000 --- a/NETCORE/test/FunctionalTests.MVC.Tests/Properties/launchSettings.json +++ /dev/null @@ -1,27 +0,0 @@ -{ - "iisSettings": { - "windowsAuthentication": false, - "anonymousAuthentication": true, - "iisExpress": { - "applicationUrl": "http://localhost:34244/", - "sslPort": 0 - } - }, - "profiles": { - "IIS Express": { - "commandName": "IISExpress", - "launchBrowser": true, - "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development" - } - }, - "FunctionalTests.MVC.Tests": { - "commandName": "Project", - "launchBrowser": true, - "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development" - }, - "applicationUrl": "http://localhost:34245/" - } - } -} diff --git a/NETCORE/test/FunctionalTests.MVC.Tests/Startup.cs b/NETCORE/test/FunctionalTests.MVC.Tests/Startup.cs deleted file mode 100644 index 5d7db3ca1c..0000000000 --- a/NETCORE/test/FunctionalTests.MVC.Tests/Startup.cs +++ /dev/null @@ -1,64 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; -using Microsoft.AspNetCore.Builder; -using Microsoft.AspNetCore.Hosting; -using Microsoft.Extensions.Configuration; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.ApplicationInsights.Channel; -using FunctionalTests.Utils; -using Microsoft.ApplicationInsights.AspNetCore.Extensions; - -namespace FunctionalTests.MVC.Tests -{ - public class Startup - { - public Startup(IConfiguration configuration) - { - Configuration = configuration; - } - - public IConfiguration Configuration { get; } - - // This method gets called by the runtime. Use this method to add services to the container. - public void ConfigureServices(IServiceCollection services) - { - var endpointAddress = new EndpointAddress(); - services.AddSingleton(endpointAddress); - - ApplicationInsightsServiceOptions applicationInsightsOptions = new ApplicationInsightsServiceOptions(); - applicationInsightsOptions.AddAutoCollectedMetricExtractor = false; - applicationInsightsOptions.DeveloperMode = true; - applicationInsightsOptions.EndpointAddress = endpointAddress.ConnectionString; - applicationInsightsOptions.InstrumentationKey = InProcessServer.IKey; - - services.AddSingleton(typeof(ITelemetryChannel), new InMemoryChannel()); - services.AddApplicationInsightsTelemetry(applicationInsightsOptions); - services.AddMvc(); - } - - // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. - public void Configure(IApplicationBuilder app, IHostingEnvironment env) - { - if (env.IsDevelopment()) - { - app.UseDeveloperExceptionPage(); - //app.UseBrowserLink(); - } - else - { - app.UseExceptionHandler("/Home/Error"); - } - - app.UseStaticFiles(); - - app.UseMvc(routes => - { - routes.MapRoute( - name: "default", - template: "{controller=Home}/{action=Index}/{id?}"); - }); - } - } -} diff --git a/NETCORE/test/FunctionalTests.MVC.Tests/Views/Home/About.cshtml b/NETCORE/test/FunctionalTests.MVC.Tests/Views/Home/About.cshtml deleted file mode 100644 index 3674e37a86..0000000000 --- a/NETCORE/test/FunctionalTests.MVC.Tests/Views/Home/About.cshtml +++ /dev/null @@ -1,7 +0,0 @@ -@{ - ViewData["Title"] = "About"; -} -

@ViewData["Title"]

-

@ViewData["Message"]

- -

Use this area to provide additional information.

diff --git a/NETCORE/test/FunctionalTests.MVC.Tests/Views/Home/Contact.cshtml b/NETCORE/test/FunctionalTests.MVC.Tests/Views/Home/Contact.cshtml deleted file mode 100644 index a11a1867cf..0000000000 --- a/NETCORE/test/FunctionalTests.MVC.Tests/Views/Home/Contact.cshtml +++ /dev/null @@ -1,17 +0,0 @@ -@{ - ViewData["Title"] = "Contact"; -} -

@ViewData["Title"]

-

@ViewData["Message"]

- -
- One Microsoft Way
- Redmond, WA 98052-6399
- P: - 425.555.0100 -
- -
- Support: Support@example.com
- Marketing: Marketing@example.com -
diff --git a/NETCORE/test/FunctionalTests.MVC.Tests/Views/Home/Index.cshtml b/NETCORE/test/FunctionalTests.MVC.Tests/Views/Home/Index.cshtml deleted file mode 100644 index 00afab6a0c..0000000000 --- a/NETCORE/test/FunctionalTests.MVC.Tests/Views/Home/Index.cshtml +++ /dev/null @@ -1,108 +0,0 @@ -@{ - ViewData["Title"] = "Home Page"; -} - - - - diff --git a/NETCORE/test/FunctionalTests.MVC.Tests/Views/Shared/Error.cshtml b/NETCORE/test/FunctionalTests.MVC.Tests/Views/Shared/Error.cshtml deleted file mode 100644 index ec2ea6bd03..0000000000 --- a/NETCORE/test/FunctionalTests.MVC.Tests/Views/Shared/Error.cshtml +++ /dev/null @@ -1,22 +0,0 @@ -@model ErrorViewModel -@{ - ViewData["Title"] = "Error"; -} - -

Error.

-

An error occurred while processing your request.

- -@if (Model.ShowRequestId) -{ -

- Request ID: @Model.RequestId -

-} - -

Development Mode

-

- Swapping to Development environment will display more detailed information about the error that occurred. -

-

- Development environment should not be enabled in deployed applications, as it can result in sensitive information from exceptions being displayed to end users. For local debugging, development environment can be enabled by setting the ASPNETCORE_ENVIRONMENT environment variable to Development, and restarting the application. -

diff --git a/NETCORE/test/FunctionalTests.MVC.Tests/Views/Shared/_Layout.cshtml b/NETCORE/test/FunctionalTests.MVC.Tests/Views/Shared/_Layout.cshtml deleted file mode 100644 index 04c5764c8d..0000000000 --- a/NETCORE/test/FunctionalTests.MVC.Tests/Views/Shared/_Layout.cshtml +++ /dev/null @@ -1,71 +0,0 @@ - - - - - - @ViewData["Title"] - FunctionalTests.MVC.Tests - - - - - - - - - - - - -
- @RenderBody() -
-
-

© 2017 - FunctionalTests.MVC.Tests

-
-
- - - - - - - - - - - - - @RenderSection("Scripts", required: false) - - diff --git a/NETCORE/test/FunctionalTests.MVC.Tests/Views/Shared/_ValidationScriptsPartial.cshtml b/NETCORE/test/FunctionalTests.MVC.Tests/Views/Shared/_ValidationScriptsPartial.cshtml deleted file mode 100644 index a699aafa97..0000000000 --- a/NETCORE/test/FunctionalTests.MVC.Tests/Views/Shared/_ValidationScriptsPartial.cshtml +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - - diff --git a/NETCORE/test/FunctionalTests.MVC.Tests/Views/_ViewImports.cshtml b/NETCORE/test/FunctionalTests.MVC.Tests/Views/_ViewImports.cshtml deleted file mode 100644 index 5f3c7260c4..0000000000 --- a/NETCORE/test/FunctionalTests.MVC.Tests/Views/_ViewImports.cshtml +++ /dev/null @@ -1,3 +0,0 @@ -@using FunctionalTests.MVC.Tests.FunctionalTest -@using FunctionalTests.MVC.Tests.Models -@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers diff --git a/NETCORE/test/FunctionalTests.MVC.Tests/Views/_ViewStart.cshtml b/NETCORE/test/FunctionalTests.MVC.Tests/Views/_ViewStart.cshtml deleted file mode 100644 index a5f10045db..0000000000 --- a/NETCORE/test/FunctionalTests.MVC.Tests/Views/_ViewStart.cshtml +++ /dev/null @@ -1,3 +0,0 @@ -@{ - Layout = "_Layout"; -} diff --git a/NETCORE/test/FunctionalTests.MVC.Tests/appsettings.Development.json b/NETCORE/test/FunctionalTests.MVC.Tests/appsettings.Development.json deleted file mode 100644 index fa8ce71a97..0000000000 --- a/NETCORE/test/FunctionalTests.MVC.Tests/appsettings.Development.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "Logging": { - "IncludeScopes": false, - "LogLevel": { - "Default": "Debug", - "System": "Information", - "Microsoft": "Information" - } - } -} diff --git a/NETCORE/test/FunctionalTests.MVC.Tests/appsettings.json b/NETCORE/test/FunctionalTests.MVC.Tests/appsettings.json deleted file mode 100644 index 5fff67bacc..0000000000 --- a/NETCORE/test/FunctionalTests.MVC.Tests/appsettings.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "Logging": { - "IncludeScopes": false, - "LogLevel": { - "Default": "Warning" - } - } -} diff --git a/NETCORE/test/FunctionalTests.MVC.Tests/bower.json b/NETCORE/test/FunctionalTests.MVC.Tests/bower.json deleted file mode 100644 index b07e3cc5ae..0000000000 --- a/NETCORE/test/FunctionalTests.MVC.Tests/bower.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "name": "asp.net", - "private": true, - "dependencies": { - "bootstrap": "3.3.7", - "jquery": "2.2.0", - "jquery-validation": "1.14.0", - "jquery-validation-unobtrusive": "3.2.6" - } -} diff --git a/NETCORE/test/FunctionalTests.MVC.Tests/bundleconfig.json b/NETCORE/test/FunctionalTests.MVC.Tests/bundleconfig.json deleted file mode 100644 index 6d3f9a57ae..0000000000 --- a/NETCORE/test/FunctionalTests.MVC.Tests/bundleconfig.json +++ /dev/null @@ -1,24 +0,0 @@ -// Configure bundling and minification for the project. -// More info at https://go.microsoft.com/fwlink/?LinkId=808241 -[ - { - "outputFileName": "wwwroot/css/site.min.css", - // An array of relative input file paths. Globbing patterns supported - "inputFiles": [ - "wwwroot/css/site.css" - ] - }, - { - "outputFileName": "wwwroot/js/site.min.js", - "inputFiles": [ - "wwwroot/js/site.js" - ], - // Optionally specify minification options - "minify": { - "enabled": true, - "renameLocals": true - }, - // Optionally generate .map file - "sourceMap": false - } -] diff --git a/NETCORE/test/FunctionalTests.MVC.Tests/xunit.runner.json b/NETCORE/test/FunctionalTests.MVC.Tests/xunit.runner.json deleted file mode 100644 index 78c070e832..0000000000 --- a/NETCORE/test/FunctionalTests.MVC.Tests/xunit.runner.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "shadowCopy": false -} \ No newline at end of file diff --git a/NETCORE/test/FunctionalTests.Utils/FunctionalTests.Utils.csproj b/NETCORE/test/FunctionalTests.Utils/FunctionalTests.Utils.csproj deleted file mode 100644 index d9f831846c..0000000000 --- a/NETCORE/test/FunctionalTests.Utils/FunctionalTests.Utils.csproj +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - $(TargetFrameworks_NetCoreOnly) - - true - FunctionalTests.Utils - FunctionalTests.Utils - - - - - - - - - - - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - - - - - diff --git a/NETCORE/test/FunctionalTests.Utils/HttpListenerObservableBase.cs b/NETCORE/test/FunctionalTests.Utils/HttpListenerObservableBase.cs deleted file mode 100644 index f01fa2061b..0000000000 --- a/NETCORE/test/FunctionalTests.Utils/HttpListenerObservableBase.cs +++ /dev/null @@ -1,97 +0,0 @@ -namespace FunctionalTests.Utils -{ - using System; - using System.Collections.Generic; - using System.Linq; - using System.Net; - using System.Reactive.Linq; - using System.Reactive.Threading.Tasks; - using System.Threading.Tasks; - using Xunit.Abstractions; - - public abstract class HttpListenerObservableBase : IObservable, IDisposable - { - private readonly HttpListener listener; - private IObservable stream; - private ITestOutputHelper output; - - public HttpListenerObservableBase(string url, ITestOutputHelper output) - { - this.output = output; - - this.output.WriteLine(string.Format("{0}: HttpListenerObservableBase Constructor. Url is: {1}", DateTime.Now.ToString("MM/dd/yyyy hh:mm:ss.fff tt"), url)); - this.listener = new HttpListener(); - this.listener.Prefixes.Add(url); - } - - public void Start() - { - OnStart(); - if (this.stream != null) - { - this.output.WriteLine(string.Format("{0}: HttpListenerObservableBase Start. Stream is not null. Stopping", DateTime.Now.ToString("MM/dd/yyyy hh:mm:ss.fff tt"))); - this.Stop(); - this.output.WriteLine(string.Format("{0}: HttpListenerObservableBase Start. Stream is not null. Stop completed", DateTime.Now.ToString("MM/dd/yyyy hh:mm:ss.fff tt"))); - } - - if (!this.listener.IsListening) - { - this.output.WriteLine(string.Format("{0}: HttpListenerObservableBase Start. Listener not already listening. Starting to listen", DateTime.Now.ToString("MM/dd/yyyy hh:mm:ss.fff tt"))); - this.listener.Start(); - this.output.WriteLine(string.Format("{0}: HttpListenerObservableBase Start. Listener not already listening. Started listening", DateTime.Now.ToString("MM/dd/yyyy hh:mm:ss.fff tt"))); - } - - this.stream = this.CreateStream(); - } - - protected virtual void OnStart() - { } - - public void Stop() - { - this.Dispose(); - } - - public IDisposable Subscribe(IObserver observer) - { - if (this.stream == null) - { - throw new InvalidOperationException("Call HttpListenerObservable.Start before subscribing to the stream"); - } - - return this.stream - .Subscribe(observer); - } - - public void Dispose() - { - if (listener != null && listener.IsListening) - { - // listener.Stop() is not required as Close does shutdown the listener. - // Stop() followed by Close() throws error in non-windows. - listener.Close(); - this.stream = null; - } - } - - private IObservable CreateStream() - { - return Observable - .Create - (obs => - Task.Factory.FromAsync( - (a, c) => this.listener.BeginGetContext(a, c), - ar => this.listener.EndGetContext(ar), - null) - .ToObservable() - .SelectMany(this.CreateNewItemsFromContext) - .Subscribe(obs) - ) - .Repeat() - .Publish() - .RefCount(); - } - - protected abstract IEnumerable CreateNewItemsFromContext(HttpListenerContext context); - } -} diff --git a/NETCORE/test/FunctionalTests.Utils/InProcessServer.cs b/NETCORE/test/FunctionalTests.Utils/InProcessServer.cs deleted file mode 100644 index 258d7f55f6..0000000000 --- a/NETCORE/test/FunctionalTests.Utils/InProcessServer.cs +++ /dev/null @@ -1,197 +0,0 @@ -using System.Collections.Generic; -using Microsoft.ApplicationInsights.Extensibility; -using Microsoft.ApplicationInsights.Extensibility.Implementation.ApplicationId; - -namespace FunctionalTests.Utils -{ - using System; - using System.IO; - using System.Net; - using Microsoft.ApplicationInsights.AspNetCore.Extensions; - using Microsoft.ApplicationInsights.Channel; - using Microsoft.AspNetCore.Hosting; - using Microsoft.Extensions.Configuration; - using Microsoft.Extensions.DependencyInjection; - using Xunit.Abstractions; - - public class EndpointAddress - { - private const string httpListenerConnectionString = "http://localhost:{0}/v2/track/"; - private static Random random = new Random(); - - public EndpointAddress() - { - this.ConnectionString = string.Format(httpListenerConnectionString, random.Next(2000, 5000).ToString()); - } - - public string ConnectionString { get; } - } - - // a variant of aspnet/Hosting/test/Microsoft.AspNetCore.Hosting.Tests/HostingEngineTests.cs - public class InProcessServer : IDisposable - { - public const string IKey = "Foo"; - public const string AppId = "AppId"; - private readonly string httpListenerConnectionString; - private readonly ITestOutputHelper output; - - private static Random random = new Random(); - private static object noParallelism = new object(); - - private IWebHost hostingEngine; - private string url; - - private TelemetryHttpListenerObservable listener; - private readonly Action configureApplicationInsights; - - public InProcessServer(string assemblyName, ITestOutputHelper output, - Action configureApplicationInsights = null) - { - this.output = output; - - // localhost instead of machine name, as its not possible to get machine name when running non windows. - var machineName = "localhost"; - this.url = "http://" + machineName + ":" + random.Next(5000, 14000).ToString(); - this.configureApplicationInsights = configureApplicationInsights; - this.httpListenerConnectionString = LauchApplicationAndStartListener(assemblyName); - } - - private string LauchApplicationAndStartListener(string assemblyName) - { - string listenerConnectionString = ""; - bool listenerStarted = false; - int retryCount = 1; - while (retryCount <= 3) - { - output.WriteLine(string.Format("{0}: Attempt {1} to StartApplication", DateTime.Now.ToString("MM/dd/yyyy hh:mm:ss.fff tt"), retryCount)); - listenerConnectionString = StartApplication(assemblyName); - listenerStarted = StartListener(listenerConnectionString); - if(listenerStarted) - { - break; - } - else - { - StopApplication(); - } - retryCount++; - } - - if(!listenerStarted) - { - throw new Exception("Unable to start listener after 3 attempts. Failing. Read logs above for details about the exceptions."); - } - - return listenerConnectionString; - } - - private bool StartListener(string listenerConnectionString) - { - output.WriteLine(string.Format("{0}: Starting listener at: {1}", DateTime.Now.ToString("MM/dd/yyyy hh:mm:ss.fff tt"), this.httpListenerConnectionString)); - - this.listener = new TelemetryHttpListenerObservable(listenerConnectionString, this.output); - try - { - this.listener.Start(); - output.WriteLine(string.Format("{0}: Started listener", DateTime.Now.ToString("MM/dd/yyyy hh:mm:ss.fff tt"))); - } - catch (HttpListenerException ex) - { - output.WriteLine(string.Format("{0}: Error starting listener.ErrorCode {1} Native Code {2}", DateTime.Now.ToString("G"), ex.ErrorCode, ex.NativeErrorCode)); - return false; - } - - return true; - } - - private string StartApplication(string assemblyName) - { - output.WriteLine(string.Format("{0}: Launching application at: {1}", DateTime.Now.ToString("MM/dd/yyyy hh:mm:ss.fff tt"), this.url)); - return this.Start(assemblyName); - } - - private void StopApplication() - { - if (this.hostingEngine != null) - { - this.output.WriteLine(string.Format("{0}:Disposing WebHost starting.....", DateTime.Now.ToString("G"))); - this.hostingEngine.Dispose(); - this.output.WriteLine(string.Format("{0}:Disposing WebHost completed.", DateTime.Now.ToString("G"))); - } - } - - public TelemetryHttpListenerObservable Listener - { - get - { - return this.listener; - } - } - - public string BaseHost - { - get - { - return this.url; - } - } - - public IServiceProvider ApplicationServices { get; private set; } - - private string Start(string assemblyName) - { - var builder = new WebHostBuilder() - .UseContentRoot(Directory.GetCurrentDirectory()) - .UseUrls(this.BaseHost) - .UseKestrel() - .UseStartup(assemblyName) - .UseEnvironment("Production"); - - builder.ConfigureServices(services => - { - services.AddSingleton(provider => - new DictionaryApplicationIdProvider() - { - Defined = new Dictionary {[IKey] = AppId} - }); - - if (this.configureApplicationInsights != null) - { - services.Configure(this.configureApplicationInsights); - } - }); - - this.hostingEngine = builder.Build(); - this.hostingEngine.Start(); - - this.ApplicationServices = this.hostingEngine.Services; - - return ((EndpointAddress)this.hostingEngine.Services.GetService()).ConnectionString; - } - - public void DisposeHost() - { - if (this.hostingEngine != null) - { - this.output.WriteLine(string.Format("{0}:Disposing WebHost starting.....", DateTime.Now.ToString("G"))); - this.hostingEngine.Dispose(); - this.output.WriteLine(string.Format("{0}:Disposing WebHost completed.", DateTime.Now.ToString("G"))); - this.hostingEngine = null; - } - else - { - this.output.WriteLine(string.Format("{0}: Hosting engine is null.", DateTime.Now.ToString("G"))); - } - } - - public void Dispose() - { - DisposeHost(); - if (this.listener != null) - { - output.WriteLine(string.Format("{0}: Stopping listener at: {1}", DateTime.Now.ToString("G"), this.httpListenerConnectionString)); - this.listener.Stop(); - } - } - } -} diff --git a/NETCORE/test/FunctionalTests.Utils/Properties/launchSettings.json b/NETCORE/test/FunctionalTests.Utils/Properties/launchSettings.json deleted file mode 100644 index 454a7722af..0000000000 --- a/NETCORE/test/FunctionalTests.Utils/Properties/launchSettings.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "iisSettings": { - "windowsAuthentication": false, - "anonymousAuthentication": true, - "iisExpress": { - "applicationUrl": "http://localhost:4824/", - "sslPort": 0 - } - }, - "profiles": { - "IIS Express": { - "commandName": "IISExpress", - "launchBrowser": true, - "environmentVariables": { - "ASPNET_ENVIRONMENT": "Development" - } - } - } -} \ No newline at end of file diff --git a/NETCORE/test/FunctionalTests.Utils/TelemetryExtensions.cs b/NETCORE/test/FunctionalTests.Utils/TelemetryExtensions.cs deleted file mode 100644 index 421bba358e..0000000000 --- a/NETCORE/test/FunctionalTests.Utils/TelemetryExtensions.cs +++ /dev/null @@ -1,92 +0,0 @@ -// -------------------------------------------------------------------------------------------------------------------- -// -// Copyright (c) Microsoft Corporation. All rights reserved. -// -// -------------------------------------------------------------------------------------------------------------------- - -namespace FunctionalTests.Utils -{ - using System; - using System.IO; - using System.Linq; - using System.Reactive.Linq; - - using AI; - - public static class TelemetryExtensions - { - public static Envelope[] ReceiveItems( - this TelemetryHttpListenerObservable listener, - int timeOut) - { - if (null == listener) - { - throw new ArgumentNullException("listener"); - } - - var result = listener - .TakeUntil(DateTimeOffset.UtcNow.AddMilliseconds(timeOut)) - .ToEnumerable() - .ToArray(); - - return result; - } - - public static Envelope[] ReceiveItems( - this TelemetryHttpListenerObservable listener, - int count, - int timeOut) - { - if (null == listener) - { - throw new ArgumentNullException("listener"); - } - - var result = listener - .TakeUntil(DateTimeOffset.UtcNow.AddMilliseconds(timeOut)) - .Take(count) - .ToEnumerable() - .ToArray(); - - if (result.Length != count) - { - throw new InvalidDataException("Incorrect number of items. Expected: " + count + " Received: " + result.Length); - } - - return result; - } - - public static Envelope[] ReceiveItemsOfType( - this TelemetryHttpListenerObservable listener, - int timeOut) - { - var result = listener - .Where(item => (item is T)) - .TakeUntil(DateTimeOffset.UtcNow.AddMilliseconds(timeOut)) - .ToEnumerable() - .ToArray(); - - return result; - } - - public static Envelope[] ReceiveItemsOfType( - this TelemetryHttpListenerObservable listener, - int count, - int timeOut) - { - var result = listener - .Where(item => (item is T)) - .TakeUntil(DateTimeOffset.UtcNow.AddMilliseconds(timeOut)) - .Take(count) - .ToEnumerable() - .ToArray(); - - if (result.Length != count) - { - throw new InvalidDataException("Incorrect number of items. Expected: " + count + " Received: " + result.Length); - } - - return result; - } - } -} diff --git a/NETCORE/test/FunctionalTests.Utils/TelemetryHttpListenerObservable.cs b/NETCORE/test/FunctionalTests.Utils/TelemetryHttpListenerObservable.cs deleted file mode 100644 index 22924991c5..0000000000 --- a/NETCORE/test/FunctionalTests.Utils/TelemetryHttpListenerObservable.cs +++ /dev/null @@ -1,62 +0,0 @@ -namespace FunctionalTests.Utils -{ - using System; - using System.Collections.Generic; - using System.Diagnostics; - using System.IO; - using System.IO.Compression; - using System.Net; - using AI; - using FunctionalTests.Utils; - using Xunit.Abstractions; - - public class TelemetryHttpListenerObservable : HttpListenerObservableBase - { - public bool FailureDetected { get; set; } - - public TelemetryHttpListenerObservable(string url, ITestOutputHelper output) : base(url, output) - { - } - - protected override IEnumerable CreateNewItemsFromContext(HttpListenerContext context) - { - try - { - var request = context.Request; - - string content = string.Empty; - - if (!string.IsNullOrWhiteSpace(request.Headers["Content-Encoding"]) && - string.Equals("gzip", request.Headers["Content-Encoding"], - StringComparison.InvariantCultureIgnoreCase)) - { - content = Decompress(request); - } - - Trace.WriteLine("=>"); - Trace.WriteLine("Item received: " + content); - Trace.WriteLine("<="); - - return TelemetryItemFactory.GetTelemetryItems(content); - } - finally - { - context.Response.Close(); - } - } - - /// - /// Decompresses content in gzip and returns decompressed string - /// - /// - /// - private static string Decompress(HttpListenerRequest request) - { - var gzipStream = new GZipStream(request.InputStream, CompressionMode.Decompress); - using (var streamReader = new StreamReader(gzipStream, request.ContentEncoding)) - { - return streamReader.ReadToEnd(); - } - } - } -} diff --git a/NETCORE/test/FunctionalTests.Utils/TelemetryItemFactory.cs b/NETCORE/test/FunctionalTests.Utils/TelemetryItemFactory.cs deleted file mode 100644 index 7659b45daf..0000000000 --- a/NETCORE/test/FunctionalTests.Utils/TelemetryItemFactory.cs +++ /dev/null @@ -1,99 +0,0 @@ -namespace FunctionalTests.Utils -{ - using System; - using System.Collections.Generic; - using System.IO; - using AI; - using Newtonsoft.Json; - using Newtonsoft.Json.Linq; - - internal static class TelemetryItemFactory - { - public static IList GetTelemetryItems(string content) - { - var items = new List(); - - if (string.IsNullOrWhiteSpace(content)) - { - return items; - } - - var newLines = new [] { "\r\n", "\n" }; - - string[] lines = content.Split(newLines, StringSplitOptions.RemoveEmptyEntries); - foreach (string line in lines) - { - JsonReader reader = new JsonTextReader(new StringReader(line)); - reader.DateParseHandling = DateParseHandling.None; - JObject obj = JObject.Load(reader); - var envelope = obj.ToObject(); - - var item = CreateTelemetryItem(envelope, line); - items.Add(item); - } - - return items; - } - - private static Envelope CreateTelemetryItem( - Envelope envelope, - string content) - { - Envelope result; - - TelemetryItemType type; - if (Enum.TryParse(envelope.data.baseType.Replace("Data", ""), out type)) - { - switch (type) - { - case TelemetryItemType.Exception: - { - result = JsonConvert.DeserializeObject>(content); - break; - } - - case TelemetryItemType.Request: - { - result = JsonConvert.DeserializeObject>(content); - break; - } - - case TelemetryItemType.Metric: - { - result = JsonConvert.DeserializeObject>(content); - break; - } - - case TelemetryItemType.RemoteDependency: - { - result = JsonConvert.DeserializeObject>(content); - break; - } - - case TelemetryItemType.Message: - { - result = JsonConvert.DeserializeObject>(content); - break; - } - - case TelemetryItemType.Event: - { - result = JsonConvert.DeserializeObject>(content); - break; - } - - default: - { - throw new InvalidDataException("Unsupported telemetry type"); - } - } - } - else - { - throw new InvalidDataException("Unsupported telemetry type"); - } - - return result; - } - } -} diff --git a/NETCORE/test/FunctionalTests.Utils/TelemetryTestsBase.cs b/NETCORE/test/FunctionalTests.Utils/TelemetryTestsBase.cs deleted file mode 100644 index 9bae62bdb9..0000000000 --- a/NETCORE/test/FunctionalTests.Utils/TelemetryTestsBase.cs +++ /dev/null @@ -1,212 +0,0 @@ -namespace FunctionalTests.Utils -{ - using System; - using System.Diagnostics; - using System.Collections.Generic; - using System.Linq; - using System.Net.Http; - using System.Reflection; - using System.Runtime.CompilerServices; - using System.Text; - using AI; - using Microsoft.ApplicationInsights.DataContracts; - using Microsoft.Extensions.DependencyInjection; - using Xunit; - using Xunit.Abstractions; - using Microsoft.ApplicationInsights.Extensibility; - using Microsoft.ApplicationInsights.Extensibility.PerfCounterCollector; - - public abstract class TelemetryTestsBase - { - public const int TestListenerTimeoutInMs = 10000; - protected readonly ITestOutputHelper output; - - public TelemetryTestsBase(ITestOutputHelper output) - { - this.output = output; - } - - [MethodImpl(MethodImplOptions.NoOptimization)] - public TelemetryItem ValidateBasicRequest(InProcessServer server, string requestPath, RequestTelemetry expected, bool expectRequestContextInResponse = true) - { - return ValidateRequestWithHeaders(server, requestPath, null, expected, expectRequestContextInResponse); - } - - [MethodImpl(MethodImplOptions.NoOptimization)] - public TelemetryItem ValidateRequestWithHeaders(InProcessServer server, string requestPath, Dictionary requestHeaders, RequestTelemetry expected, bool expectRequestContextInResponse = true) - { - // Subtract 50 milliseconds to hack around strange behavior on build server where the RequestTelemetry.Timestamp is somehow sometimes earlier than now by a few milliseconds. - expected.Timestamp = DateTimeOffset.Now.Subtract(TimeSpan.FromMilliseconds(50)); - Stopwatch timer = Stopwatch.StartNew(); - - var response = this.ExecuteRequest(server.BaseHost + requestPath, requestHeaders); - - var actual = server.Listener.ReceiveItemsOfType>(1, TestListenerTimeoutInMs); - timer.Stop(); - - this.DebugTelemetryItems(actual); - this.output.WriteLine("Response headers: " + string.Join(",", response.Headers.Select(kvp => $"{kvp.Key} = {kvp.Value.First()}"))); - - var item = actual.OfType>().FirstOrDefault(); - Assert.NotNull(item); - var data = ((TelemetryItem)item).data.baseData; - - Assert.Equal(expected.ResponseCode, data.responseCode); - Assert.Equal(expected.Name, data.name); - Assert.Equal(expected.Success, data.success); - Assert.Equal(expected.Url, new Uri(data.url)); - Assert.Equal(expectRequestContextInResponse, response.Headers.Contains("Request-Context")); - if (expectRequestContextInResponse) - { - Assert.True(response.Headers.TryGetValues("Request-Context", out var appIds)); - Assert.Equal($"appId={InProcessServer.AppId}", appIds.Single()); - } - - output.WriteLine("actual.Duration: " + data.duration); - output.WriteLine("timer.Elapsed: " + timer.Elapsed); - Assert.True(TimeSpan.Parse(data.duration) < timer.Elapsed.Add(TimeSpan.FromMilliseconds(20)), "duration"); - - return item; - } - - public void ValidateBasicException(InProcessServer server, string requestPath, ExceptionTelemetry expected) - { - this.ExecuteRequest(server.BaseHost + requestPath); - - var actual = server.Listener.ReceiveItemsOfType>(1, TestListenerTimeoutInMs); - this.DebugTelemetryItems(actual); - - var item = actual.OfType>().FirstOrDefault(); - Assert.NotNull(item); - var data = ((TelemetryItem)item).data.baseData; - - Assert.Equal(expected.Exception.GetType().ToString(), data.exceptions[0].typeName); - Assert.NotEmpty(data.exceptions[0].parsedStack); - } - - public (TelemetryItem, TelemetryItem) ValidateBasicDependency(InProcessServer server, string requestPath, DependencyTelemetry expected) - { - var response = this.ExecuteRequest(server.BaseHost + requestPath); - - var actual = server.Listener.ReceiveItems(TestListenerTimeoutInMs); - this.DebugTelemetryItems(actual); - - var dependencyTelemetry = actual.OfType>().FirstOrDefault(); - Assert.NotNull(dependencyTelemetry); - var dependencyData = ((TelemetryItem)dependencyTelemetry).data.baseData; - Assert.Equal(expected.Data, dependencyData.data); - Assert.Equal(expected.ResultCode, dependencyData.resultCode); - Assert.Equal(expected.Success, dependencyData.success); - - var requestTelemetry = actual.OfType>().FirstOrDefault(); - Assert.NotNull(requestTelemetry); - - Assert.Equal(requestTelemetry.tags["ai.operation.id"], dependencyTelemetry.tags["ai.operation.id"]); - Assert.Contains(dependencyTelemetry.data.baseData.id, requestTelemetry.tags["ai.operation.parentId"]); - - return (requestTelemetry, dependencyTelemetry); - } - - public void ValidatePerformanceCountersAreCollected(string assemblyName) - { - using (var server = new InProcessServer(assemblyName, this.output)) - { - // Reconfigure the PerformanceCollectorModule timer. - Type perfModuleType = typeof(PerformanceCollectorModule); - PerformanceCollectorModule perfModule = (PerformanceCollectorModule)server.ApplicationServices.GetServices().FirstOrDefault(m => m.GetType() == perfModuleType); - FieldInfo timerField = perfModuleType.GetField("timer", BindingFlags.NonPublic | BindingFlags.Instance); - var timer = timerField.GetValue(perfModule); - timerField.FieldType.InvokeMember("ScheduleNextTick", BindingFlags.InvokeMethod | BindingFlags.Public | BindingFlags.Instance, null, timer, new object[] { TimeSpan.FromMilliseconds(10) }); - - var actual = server.Listener.ReceiveItems(TestListenerTimeoutInMs); - this.DebugTelemetryItems(actual); - Assert.True(actual.Length > 0); - } - } - - protected HttpResponseMessage ExecuteRequest(string requestPath, Dictionary headers = null) - { - var httpClientHandler = new HttpClientHandler(); - httpClientHandler.UseDefaultCredentials = true; - - using (HttpClient httpClient = new HttpClient(httpClientHandler, true)) - { - this.output.WriteLine($"{DateTime.Now:MM/dd/yyyy hh:mm:ss.fff tt}: Executing request: {requestPath}"); - HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, requestPath); - if (headers != null) - { - foreach (var h in headers) - { - request.Headers.Add(h.Key, h.Value); - } - } - - var task = httpClient.SendAsync(request); - task.Wait(TestListenerTimeoutInMs); - this.output.WriteLine($"{DateTime.Now:MM/dd/yyyy hh:mm:ss.fff tt}: Ended request: {requestPath}"); - - return task.Result; - } - } - - protected void DebugTelemetryItems(Envelope[] telemetries) - { - StringBuilder builder = new StringBuilder(); - foreach (Envelope telemetry in telemetries) - { - TelemetryItem dependency = telemetry as TelemetryItem; - if (dependency != null) - { - var data = ((TelemetryItem)dependency).data.baseData; - builder.AppendLine($"{dependency} - {data.data} - {((TelemetryItem)dependency).time} - {data.duration} - {data.id} - {data.name} - {data.resultCode} - {data.success} - {data.target} - {data.type}"); - } - else - { - TelemetryItem request = telemetry as TelemetryItem; - if (request != null) - { - var data = ((TelemetryItem)request).data.baseData; - builder.AppendLine($"{request} - {data.url} - {((TelemetryItem)request).time} - {data.duration} - {data.id} - {data.name} - {data.success} - {data.responseCode}"); - } - else - { - TelemetryItem exception = telemetry as TelemetryItem; - if (exception != null) - { - var data = ((TelemetryItem)exception).data.baseData; - builder.AppendLine($"{exception} - {data.exceptions[0].message} - {data.exceptions[0].stack} - {data.exceptions[0].typeName} - {data.severityLevel}"); - } - else - { - TelemetryItem message = telemetry as TelemetryItem; - if (message != null) - { - var data = ((TelemetryItem)message).data.baseData; - builder.AppendLine($"{message} - {data.message} - {data.severityLevel}"); - } - else - { - TelemetryItem metric = telemetry as TelemetryItem; - if (metric != null) - { - var data = ((TelemetryItem)metric).data.baseData; - builder.AppendLine($"{metric.ToString()} - {metric.data}- {metric.name} - {data.metrics.Count}"); - foreach (var metricVal in data.metrics) - { - builder.AppendLine($"{metricVal.name} {metricVal.value}"); - } - } - else - { - builder.AppendLine($"{telemetry.ToString()} - {telemetry.time}"); - } - } - } - } - } - } - - this.output.WriteLine(builder.ToString()); - } - } -} \ No newline at end of file diff --git a/NETCORE/test/FunctionalTests.WebApi.Tests/Controllers/DependencyController.cs b/NETCORE/test/FunctionalTests.WebApi.Tests/Controllers/DependencyController.cs deleted file mode 100644 index 4a81170296..0000000000 --- a/NETCORE/test/FunctionalTests.WebApi.Tests/Controllers/DependencyController.cs +++ /dev/null @@ -1,25 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Net.Http; -using System.Threading.Tasks; -using Microsoft.AspNetCore.Mvc; - -namespace FunctionalTests.WebApi.Tests.Controllers -{ - [Route("api/[controller]")] - public class DependencyController : Controller - { - // GET api/values - [HttpGet] - public async Task Get() - { - using (var hc = new HttpClient()) - { - // Microsoft.com will return a redirect to a specific lang version. - // This redirect is not detected in versions older that Net6.0. - await hc.GetAsync("https://www.microsoft.com/en-us/").ContinueWith(t => { }); // ignore all errors - } - } - } -} diff --git a/NETCORE/test/FunctionalTests.WebApi.Tests/Controllers/ExceptionController.cs b/NETCORE/test/FunctionalTests.WebApi.Tests/Controllers/ExceptionController.cs deleted file mode 100644 index 65ab624731..0000000000 --- a/NETCORE/test/FunctionalTests.WebApi.Tests/Controllers/ExceptionController.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System; -using System.Collections.Generic; -using Microsoft.AspNetCore.Mvc; - -namespace FunctionalTests.WebApi.Tests.Controllers -{ - [Route("api/[controller]")] - public class ExceptionController : Controller - { - // GET: api/exception - [HttpGet] - public IEnumerable Get() - { - throw new InvalidOperationException(); - } - } -} diff --git a/NETCORE/test/FunctionalTests.WebApi.Tests/Controllers/ValuesController.cs b/NETCORE/test/FunctionalTests.WebApi.Tests/Controllers/ValuesController.cs deleted file mode 100644 index 1204394e10..0000000000 --- a/NETCORE/test/FunctionalTests.WebApi.Tests/Controllers/ValuesController.cs +++ /dev/null @@ -1,56 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; -using Microsoft.AspNetCore.Mvc; -using Microsoft.Extensions.Logging; - -namespace FunctionalTests.WebApi.Tests.Controllers -{ - [Route("api/[controller]")] - public class ValuesController : Controller - { - ILogger logger; - - public ValuesController(ILogger logger) - { - this.logger = logger; - } - - // GET api/values - [HttpGet] - public IEnumerable Get() - { - return new string[] { "value1", "value2" }; - } - - // GET api/values/5 - [HttpGet("{id}")] - public string Get(int id) - { - logger.LogError("error logged"); - logger.LogWarning("warning logged"); - logger.LogInformation("information logged"); - logger.LogTrace("trace logged"); - return "value"; - } - - // POST api/values - [HttpPost] - public void Post([FromBody]string value) - { - } - - // PUT api/values/5 - [HttpPut("{id}")] - public void Put(int id, [FromBody]string value) - { - } - - // DELETE api/values/5 - [HttpDelete("{id}")] - public void Delete(int id) - { - } - } -} diff --git a/NETCORE/test/FunctionalTests.WebApi.Tests/FunctionalTest/MultipleWebHostsTests.cs b/NETCORE/test/FunctionalTests.WebApi.Tests/FunctionalTest/MultipleWebHostsTests.cs deleted file mode 100644 index 10e8112fcc..0000000000 --- a/NETCORE/test/FunctionalTests.WebApi.Tests/FunctionalTest/MultipleWebHostsTests.cs +++ /dev/null @@ -1,194 +0,0 @@ -using System.Linq; -using System.Reflection; -using System.Runtime.InteropServices; -using AI; -using FunctionalTests.Utils; -using Microsoft.ApplicationInsights; -using Microsoft.ApplicationInsights.Extensibility; -using Microsoft.Extensions.DependencyInjection; - -using Xunit; -using Xunit.Abstractions; - -namespace FunctionalTests.WebApi.Tests.FunctionalTest -{ - public class MultipleWebHostsTests : TelemetryTestsBase - { - private readonly string assemblyName; - private const string requestPath = "/api/dependency"; - - public MultipleWebHostsTests(ITestOutputHelper output) : base(output) - { - this.assemblyName = this.GetType().GetTypeInfo().Assembly.GetName().Name; - } - - [Fact] - public void TwoWebHostsCreatedSequentially() - { - using (var server1 = new InProcessServer(assemblyName, this.output)) - { - this.ExecuteRequest(server1.BaseHost + requestPath); - var telemetry = server1.Listener.ReceiveItems(TestListenerTimeoutInMs); - this.DebugTelemetryItems(telemetry); - - Assert.Single(telemetry.Where(t => t is TelemetryItem)); - Assert.Single(telemetry.Where(IsServiceDependencyCall)); - Assert.DoesNotContain(telemetry, t => t is TelemetryItem); - - var request = telemetry.Single(t => t is TelemetryItem); - Assert.Equal("200", ((TelemetryItem)request).data.baseData.responseCode); - } - - using (var server2 = new InProcessServer(assemblyName, this.output)) - { - this.ExecuteRequest(server2.BaseHost + requestPath); - var telemetry = server2.Listener.ReceiveItems(TestListenerTimeoutInMs); - this.DebugTelemetryItems(telemetry); - - Assert.Single(telemetry.Where(t => t is TelemetryItem)); - Assert.Single(telemetry.Where(IsServiceDependencyCall)); - Assert.DoesNotContain(telemetry, t => t is TelemetryItem); - - var request = telemetry.Single(t => t is TelemetryItem); - Assert.Equal("200", ((TelemetryItem)request).data.baseData.responseCode); - } - } - - [Fact] - public void TwoWebHostsCreatedInParallel() - { - using (var server1 = new InProcessServer(assemblyName, this.output)) - using (var server2 = new InProcessServer(assemblyName, this.output)) - { - this.ExecuteRequest(server1.BaseHost + requestPath); - this.ExecuteRequest(server2.BaseHost + requestPath); - - var telemetry1 = server1.Listener.ReceiveItems(TestListenerTimeoutInMs); - var telemetry2 = server2.Listener.ReceiveItems(TestListenerTimeoutInMs); - - this.output.WriteLine("~~telemetry1~~"); - this.DebugTelemetryItems(telemetry1); - this.output.WriteLine("~~telemetry2~~"); - this.DebugTelemetryItems(telemetry2); - - // we don't know which host reported requests - Assert.True(2 == telemetry1.Count(t => t is TelemetryItem) || - 2 == telemetry2.Count(t => t is TelemetryItem)); - - // we don't know which host reported dependencies - Assert.True(2 == telemetry1.Count(IsServiceDependencyCall) || - 2 == telemetry2.Count(IsServiceDependencyCall)); - - Assert.DoesNotContain(telemetry1, t => t is TelemetryItem); - - var request1 = telemetry1.First(t => t is TelemetryItem); - var request2 = telemetry1.Last(t => t is TelemetryItem); - Assert.Equal("200", ((TelemetryItem)request1).data.baseData.responseCode); - Assert.Equal("200", ((TelemetryItem)request2).data.baseData.responseCode); - } - } - - [Fact] - public void TwoWebHostsOneIsDisposed() - { - using (var server1 = new InProcessServer(assemblyName, this.output)) - { - var config1 = (TelemetryConfiguration) server1.ApplicationServices.GetService(typeof(TelemetryConfiguration)); - this.ExecuteRequest(server1.BaseHost); - - using (var server2 = new InProcessServer(assemblyName, this.output)) - { - var config2 = (TelemetryConfiguration) server2.ApplicationServices.GetService(typeof(TelemetryConfiguration)); - - Assert.NotEqual(config1, config2); - Assert.NotEqual(config1.TelemetryChannel, config2.TelemetryChannel); - - this.ExecuteRequest(server2.BaseHost); - } - - Assert.NotNull(config1.TelemetryChannel); - - this.ExecuteRequest(server1.BaseHost + requestPath); - - var telemetry = server1.Listener.ReceiveItems(TestListenerTimeoutInMs); - this.DebugTelemetryItems(telemetry); - - Assert.NotEmpty(telemetry.Where(t => t is TelemetryItem)); - var request = telemetry.Single(IsValueControllerRequest); - Assert.Equal("200", ((TelemetryItem) request).data.baseData.responseCode); - - Assert.DoesNotContain(telemetry, t => t is TelemetryItem); - Assert.Single(telemetry.Where(IsServiceDependencyCall)); - } - } - - [Fact] - public void ActiveConfigurationIsNotCorruptedAfterWebHostIsDisposed() - { - if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) - { - // https://github.com/dotnet/corefx/issues/25016 - // HttpListener on Linux/MacOS cannot be reused on the same port until connection - // is closed on the OS level. So we run this test on windows only. - return; - } - - // Active config could be used multiple times in the same process before this test - // let's reassign it - -#pragma warning disable CS0618 // Type or member is obsolete - TelemetryConfiguration.Active.Dispose(); -#pragma warning restore CS0618 // Type or member is obsolete - MethodInfo setActive = - typeof(TelemetryConfiguration).GetMethod("set_Active", BindingFlags.Static | BindingFlags.NonPublic); - setActive.Invoke(null, new object[] { TelemetryConfiguration.CreateDefault() }); - -#pragma warning disable CS0618 // Type or member is obsolete - var activeConfig = TelemetryConfiguration.Active; -#pragma warning restore CS0618 // Type or member is obsolete - using (var server = new InProcessServer(assemblyName, this.output, (aiOptions) => aiOptions.EnableActiveTelemetryConfigurationSetup = true)) - { - this.ExecuteRequest(server.BaseHost + requestPath); - - server.DisposeHost(); - Assert.NotNull(activeConfig.TelemetryChannel); - - var telemetryClient = new TelemetryClient(activeConfig); - telemetryClient.TrackTrace("some message after web host is disposed"); - - var message = server.Listener.ReceiveItemsOfType>(1, TestListenerTimeoutInMs); - Assert.Single(message); - - this.output.WriteLine(((TelemetryItem)message.Single()).data.baseData.message); - - Assert.Equal("some message after web host is disposed", ((TelemetryItem)message.Single()).data.baseData.message); - } - } - - private bool IsServiceDependencyCall(Envelope item) - { - if (!(item is TelemetryItem dependency)) - { - return false; - } - - var url = dependency.data.baseData.data; - - // check if it's not tracked call from service to the test and a not call to get appid - return url.Contains("microsoft.com"); - } - - private bool IsValueControllerRequest(Envelope item) - { - if (!(item is TelemetryItem dependency)) - { - return false; - } - - var url = dependency.data.baseData.url; - - // check if it's not tracked call from service to the test and a not call to get appid - return url.Contains(requestPath); - } - } -} diff --git a/NETCORE/test/FunctionalTests.WebApi.Tests/FunctionalTest/RequestCollectionTests.cs b/NETCORE/test/FunctionalTests.WebApi.Tests/FunctionalTest/RequestCollectionTests.cs deleted file mode 100644 index a69c2cec96..0000000000 --- a/NETCORE/test/FunctionalTests.WebApi.Tests/FunctionalTest/RequestCollectionTests.cs +++ /dev/null @@ -1,166 +0,0 @@ -namespace FunctionalTests.WebApi.Tests.FunctionalTest -{ - using System; - using System.Collections.Generic; - using System.Diagnostics; - using Microsoft.AspNetCore.Hosting; - using Microsoft.Extensions.DependencyInjection; - using Microsoft.ApplicationInsights.DataContracts; - using Xunit; - using Xunit.Abstractions; - using System.Reflection; - using global::FunctionalTests.Utils; - - public class RequestCollectionTests : TelemetryTestsBase - { - private readonly string assemblyName; - - public RequestCollectionTests(ITestOutputHelper output) : base (output) - { - this.assemblyName = this.GetType().GetTypeInfo().Assembly.GetName().Name; - } - - [Fact] - public void TestIfPerformanceCountersAreCollected() - { - this.output.WriteLine("Validating perfcounters"); - ValidatePerformanceCountersAreCollected(assemblyName); - } - - [Fact] - public void TestBasicRequestPropertiesAfterRequestingControllerThatThrows() - { - using (var server = new InProcessServer(assemblyName, this.output)) - { - const string RequestPath = "/api/exception"; - - var expectedRequestTelemetry = new RequestTelemetry(); - expectedRequestTelemetry.Name = "GET Exception/Get"; - expectedRequestTelemetry.ResponseCode = "500"; - expectedRequestTelemetry.Success = false; - expectedRequestTelemetry.Url = new System.Uri(server.BaseHost + RequestPath); - - // the is no response header because of https://github.com/Microsoft/ApplicationInsights-aspnetcore/issues/717 - this.ValidateBasicRequest(server, RequestPath, expectedRequestTelemetry, false); - } - } - - [Fact] - public void TestBasicExceptionPropertiesAfterRequestingControllerThatThrows() - { - using (var server = new InProcessServer(assemblyName, this.output)) - { - var expectedExceptionTelemetry = new ExceptionTelemetry(); - expectedExceptionTelemetry.Exception = new InvalidOperationException(); - - this.ValidateBasicException(server, "/api/exception", expectedExceptionTelemetry); - } - } - - [Fact] - public void TestBasicRequestPropertiesAfterRequestingValuesController() - { - using (var server = new InProcessServer(assemblyName, this.output)) - { - const string RequestPath = "/api/values"; - - var expectedRequestTelemetry = new RequestTelemetry(); - expectedRequestTelemetry.Name = "GET Values/Get"; - expectedRequestTelemetry.ResponseCode = "200"; - expectedRequestTelemetry.Success = true; - expectedRequestTelemetry.Url = new System.Uri(server.BaseHost + RequestPath); - - Dictionary requestHeaders = new Dictionary() - { - { "Request-Context", "appId=value"}, - }; - - this.ValidateRequestWithHeaders(server, RequestPath, requestHeaders, expectedRequestTelemetry, expectRequestContextInResponse: true); - } - } - - [Fact] - public void TestBasicRequestPropertiesAfterRequestingNotExistingController() - { - using (var server = new InProcessServer(assemblyName, this.output)) - { - const string RequestPath = "/api/notexistingcontroller"; - - var expectedRequestTelemetry = new RequestTelemetry(); - expectedRequestTelemetry.Name = "GET /api/notexistingcontroller"; - expectedRequestTelemetry.ResponseCode = "404"; - expectedRequestTelemetry.Success = false; - expectedRequestTelemetry.Url = new System.Uri(server.BaseHost + RequestPath); - - Dictionary requestHeaders = new Dictionary() - { - { "Request-Context", "appId=value"}, - }; - - this.ValidateRequestWithHeaders(server, RequestPath, requestHeaders, expectedRequestTelemetry, expectRequestContextInResponse: true); - } - } - - [Fact] - public void TestBasicRequestPropertiesAfterRequestingWebApiShimRoute() - { - using (var server = new InProcessServer(assemblyName, this.output)) - { - const string RequestPath = "/api/values/1"; - - var expectedRequestTelemetry = new RequestTelemetry(); - expectedRequestTelemetry.Name = "GET Values/Get [id]"; - expectedRequestTelemetry.ResponseCode = "200"; - expectedRequestTelemetry.Success = true; - expectedRequestTelemetry.Url = new System.Uri(server.BaseHost + RequestPath); - - Dictionary requestHeaders = new Dictionary() - { - { "Request-Context", "appId=value"}, - }; - - this.ValidateRequestWithHeaders(server, RequestPath, requestHeaders, expectedRequestTelemetry, expectRequestContextInResponse: true); - } - } - - [Fact] - public void TestNoHeadersInjectedInResponseWhenConfiguredAndNoIncomingRequestContext() - { - using (var server = new InProcessServer(assemblyName, this.output, (aiOptions) => aiOptions.RequestCollectionOptions.InjectResponseHeaders = false)) - { - const string RequestPath = "/api/values/1"; - - var expectedRequestTelemetry = new RequestTelemetry(); - expectedRequestTelemetry.Name = "GET Values/Get [id]"; - expectedRequestTelemetry.ResponseCode = "200"; - expectedRequestTelemetry.Success = true; - expectedRequestTelemetry.Url = new System.Uri(server.BaseHost + RequestPath); - - this.ValidateRequestWithHeaders(server, RequestPath, null, expectedRequestTelemetry, false); - } - } - - [Fact] - public void TestNoHeadersInjectedInResponseWhenConfiguredAndWithIncomingRequestContext() - { - using (var server = new InProcessServer(assemblyName, this.output, (aiOptions) => aiOptions.RequestCollectionOptions.InjectResponseHeaders = false)) - { - const string RequestPath = "/api/values/1"; - - var expectedRequestTelemetry = new RequestTelemetry(); - expectedRequestTelemetry.Name = "GET Values/Get [id]"; - expectedRequestTelemetry.ResponseCode = "200"; - expectedRequestTelemetry.Success = true; - expectedRequestTelemetry.Url = new System.Uri(server.BaseHost + RequestPath); - - Dictionary requestHeaders = new Dictionary() - { - { "Request-Context", "appId=value"}, - }; - - this.ValidateRequestWithHeaders(server, RequestPath, requestHeaders, expectedRequestTelemetry, false); - } - } - } -} - diff --git a/NETCORE/test/FunctionalTests.WebApi.Tests/FunctionalTest/RequestCorrelationTests.cs b/NETCORE/test/FunctionalTests.WebApi.Tests/FunctionalTest/RequestCorrelationTests.cs deleted file mode 100644 index 35b1737bef..0000000000 --- a/NETCORE/test/FunctionalTests.WebApi.Tests/FunctionalTest/RequestCorrelationTests.cs +++ /dev/null @@ -1,265 +0,0 @@ -namespace FunctionalTests.WebApi.Tests.FunctionalTest -{ - using System; - using System.Collections.Generic; - using System.Diagnostics; - using Microsoft.AspNetCore.Hosting; - using Microsoft.Extensions.DependencyInjection; - using Microsoft.ApplicationInsights.DataContracts; - using Xunit; - using Xunit.Abstractions; - using System.Linq; - using Microsoft.ApplicationInsights.DependencyCollector; - using System.Text.RegularExpressions; - using Microsoft.ApplicationInsights.AspNetCore.Extensions; - using System.Reflection; - using global::FunctionalTests.Utils; - - public class RequestCorrelationTests : TelemetryTestsBase - { - private readonly string assemblyName; - - public RequestCorrelationTests(ITestOutputHelper output) : base(output) - { - this.assemblyName = this.GetType().GetTypeInfo().Assembly.GetName().Name; - } - - [Fact] - public void TestRequestWithNoCorrelationHeaders() - { - using (var server = new InProcessServer(assemblyName, this.output, (aiOptions) => aiOptions.EnableDependencyTrackingTelemetryModule = false)) - { - const string RequestPath = "/api/values/1"; - - var expectedRequestTelemetry = new RequestTelemetry(); - expectedRequestTelemetry.Name = "GET Values/Get [id]"; - expectedRequestTelemetry.ResponseCode = "200"; - expectedRequestTelemetry.Success = true; - expectedRequestTelemetry.Url = new System.Uri(server.BaseHost + RequestPath); - - Dictionary requestHeaders = new Dictionary() - { - // No Request-ID, No TraceParent - { "Request-Context", "appId=value"}, - }; - - var item = this.ValidateBasicRequest(server, RequestPath, expectedRequestTelemetry); - - Assert.Equal(32, item.tags["ai.operation.id"].Length); - Assert.True(Regex.Match(item.tags["ai.operation.id"], @"[a-z][0-9]").Success); - - Assert.False(item.tags.ContainsKey("ai.operation.parentId")); - } - } - - [Fact] - public void TestRequestWithRequestIdHeader() - { - using (var server = new InProcessServer(assemblyName, this.output, (aiOptions) => aiOptions.EnableDependencyTrackingTelemetryModule = false)) - { - const string RequestPath = "/api/values"; - - var expectedRequestTelemetry = new RequestTelemetry(); - expectedRequestTelemetry.Name = "GET Values/Get"; - expectedRequestTelemetry.ResponseCode = "200"; - expectedRequestTelemetry.Success = true; - expectedRequestTelemetry.Url = new Uri(server.BaseHost + RequestPath); - - var headers = new Dictionary - { - // Request-ID Correlation Header - { "Request-Id", "|8ee8641cbdd8dd280d239fa2121c7e4e.df07da90a5b27d93."}, - { "Request-Context", "appId=value"}, - { "Correlation-Context" , "k1=v1,k2=v2" } - }; - - var actualRequest = this.ValidateRequestWithHeaders(server, RequestPath, headers, expectedRequestTelemetry); - - Assert.Equal("8ee8641cbdd8dd280d239fa2121c7e4e", actualRequest.tags["ai.operation.id"]); - Assert.Equal("|8ee8641cbdd8dd280d239fa2121c7e4e.df07da90a5b27d93.", actualRequest.tags["ai.operation.parentId"]); - Assert.Equal("v1", actualRequest.data.baseData.properties["k1"]); - Assert.Equal("v2", actualRequest.data.baseData.properties["k2"]); - } - } - - [Fact] - public void TestRequestWithNonW3CCompatibleRequestIdHeader() - { - using (var server = new InProcessServer(assemblyName, this.output, (aiOptions) => aiOptions.EnableDependencyTrackingTelemetryModule = false)) - { - const string RequestPath = "/api/values"; - - var expectedRequestTelemetry = new RequestTelemetry(); - expectedRequestTelemetry.Name = "GET Values/Get"; - expectedRequestTelemetry.ResponseCode = "200"; - expectedRequestTelemetry.Success = true; - expectedRequestTelemetry.Url = new Uri(server.BaseHost + RequestPath); - - var headers = new Dictionary - { - // Request-ID Correlation Header - { "Request-Id", "|noncompatible.df07da90a5b27d93."}, - { "Request-Context", "appId=value"}, - { "Correlation-Context" , "k1=v1,k2=v2" } - }; - - var actualRequest = this.ValidateRequestWithHeaders(server, RequestPath, headers, expectedRequestTelemetry); - - Assert.NotEqual("noncompatible", actualRequest.tags["ai.operation.id"]); - Assert.Equal("|noncompatible.df07da90a5b27d93.", actualRequest.tags["ai.operation.parentId"]); - Assert.Equal("noncompatible", actualRequest.data.baseData.properties["ai_legacyRootId"]); - Assert.Equal("v1", actualRequest.data.baseData.properties["k1"]); - Assert.Equal("v2", actualRequest.data.baseData.properties["k2"]); - } - } - - [Fact] - public void TestRequestWithNonW3CCompatibleNonHierrachicalRequestIdHeader() - { - using (var server = new InProcessServer(assemblyName, this.output, (aiOptions) => aiOptions.EnableDependencyTrackingTelemetryModule = false)) - { - const string RequestPath = "/api/values"; - - var expectedRequestTelemetry = new RequestTelemetry(); - expectedRequestTelemetry.Name = "GET Values/Get"; - expectedRequestTelemetry.ResponseCode = "200"; - expectedRequestTelemetry.Success = true; - expectedRequestTelemetry.Url = new Uri(server.BaseHost + RequestPath); - - var headers = new Dictionary - { - // Request-ID Correlation Header - { "Request-Id", "somerandomidnotinanyformat"}, - { "Request-Context", "appId=value"}, - { "Correlation-Context" , "k1=v1,k2=v2" } - }; - - var actualRequest = this.ValidateRequestWithHeaders(server, RequestPath, headers, expectedRequestTelemetry); - - Assert.NotEqual("noncompatible", actualRequest.tags["ai.operation.id"]); - Assert.Equal("somerandomidnotinanyformat", actualRequest.tags["ai.operation.parentId"]); - Assert.Equal("somerandomidnotinanyformat", actualRequest.data.baseData.properties["ai_legacyRootId"]); - Assert.Equal("v1", actualRequest.data.baseData.properties["k1"]); - Assert.Equal("v2", actualRequest.data.baseData.properties["k2"]); - } - } - - [Fact] - public void TestRequestWithTraceParentHeader() - { - using (var server = new InProcessServer(assemblyName, this.output, (aiOptions) => aiOptions.EnableDependencyTrackingTelemetryModule = false)) - { - const string RequestPath = "/api/values"; - - var expectedRequestTelemetry = new RequestTelemetry(); - expectedRequestTelemetry.Name = "GET Values/Get"; - expectedRequestTelemetry.ResponseCode = "200"; - expectedRequestTelemetry.Success = true; - expectedRequestTelemetry.Url = new Uri(server.BaseHost + RequestPath); - - var headers = new Dictionary - { - // TraceParent Correlation Header - ["traceparent"] = "00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01", - ["tracestate"] = "some=state", - ["Correlation-Context"] = "k1=v1,k2=v2" - }; - - var actualRequest = this.ValidateRequestWithHeaders(server, RequestPath, headers, expectedRequestTelemetry); - - Assert.Equal("4bf92f3577b34da6a3ce929d0e0e4736", actualRequest.tags["ai.operation.id"]); - Assert.Equal("00f067aa0ba902b7", actualRequest.tags["ai.operation.parentId"]); - - // Correlation-Context will be read if either Request-Id or TraceParent available. - Assert.True(actualRequest.data.baseData.properties.ContainsKey("k1")); - Assert.True(actualRequest.data.baseData.properties.ContainsKey("k2")); - - // TraceState is simply set to Activity, and not added to Telemetry. - Assert.False(actualRequest.data.baseData.properties.ContainsKey("some")); - } - } - - [Fact] - public void TestRequestWithRequestIdAndTraceParentHeader() - { - using (var server = new InProcessServer(assemblyName, this.output, (aiOptions) => aiOptions.EnableDependencyTrackingTelemetryModule = false)) - { - const string RequestPath = "/api/values"; - - var expectedRequestTelemetry = new RequestTelemetry(); - expectedRequestTelemetry.Name = "GET Values/Get"; - expectedRequestTelemetry.ResponseCode = "200"; - expectedRequestTelemetry.Success = true; - expectedRequestTelemetry.Url = new Uri(server.BaseHost + RequestPath); - - var headers = new Dictionary - { - // Both request id and traceparent - ["Request-Id"] = "|8ee8641cbdd8dd280d239fa2121c7e4e.df07da90a5b27d93.", - ["traceparent"] = "00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01", - ["tracestate"] = "some=state", - ["Correlation-Context"] = "k1=v1,k2=v2" - }; - - var actualRequest = this.ValidateRequestWithHeaders(server, RequestPath, headers, expectedRequestTelemetry); - - Assert.Equal("4bf92f3577b34da6a3ce929d0e0e4736", actualRequest.tags["ai.operation.id"]); - Assert.NotEqual("8ee8641cbdd8dd280d239fa2121c7e4e", actualRequest.tags["ai.operation.id"]); - Assert.Equal("00f067aa0ba902b7", actualRequest.tags["ai.operation.parentId"]); - - // Correlation-Context will be read if either Request-Id or traceparent is present. - Assert.True(actualRequest.data.baseData.properties.ContainsKey("k1")); - Assert.True(actualRequest.data.baseData.properties.ContainsKey("k2")); - - // TraceState is simply set to Activity, and not added to Telemetry. - Assert.False(actualRequest.data.baseData.properties.ContainsKey("some")); - } - } - - [Fact] - public void TestRequestWithRequestIdAndTraceParentHeaderWithW3CDisabled() - { - try - { - // disable w3c - Activity.DefaultIdFormat = ActivityIdFormat.Hierarchical; - Activity.ForceDefaultIdFormat = true; - - using (var server = new InProcessServer(assemblyName, this.output, (aiOptions) => aiOptions.EnableDependencyTrackingTelemetryModule = false)) - { - const string RequestPath = "/api/values"; - - var expectedRequestTelemetry = new RequestTelemetry(); - expectedRequestTelemetry.Name = "GET Values/Get"; - expectedRequestTelemetry.ResponseCode = "200"; - expectedRequestTelemetry.Success = true; - expectedRequestTelemetry.Url = new Uri(server.BaseHost + RequestPath); - - var headers = new Dictionary - { - // Both request id and traceparent - ["Request-Id"] = "|8ee8641cbdd8dd280d239fa2121c7e4e.df07da90a5b27d93.", - ["traceparent"] = "00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01", - ["tracestate"] = "some=state", - ["Correlation-Context"] = "k1=v1,k2=v2" - }; - - var actualRequest = this.ValidateRequestWithHeaders(server, RequestPath, headers, expectedRequestTelemetry); - - Assert.Equal("8ee8641cbdd8dd280d239fa2121c7e4e", actualRequest.tags["ai.operation.id"]); - Assert.NotEqual("4bf92f3577b34da6a3ce929d0e0e4736", actualRequest.tags["ai.operation.id"]); - Assert.Contains("df07da90a5b27d93", actualRequest.tags["ai.operation.parentId"]); - - // Correlation-Context should be read and populated. - Assert.True(actualRequest.data.baseData.properties.ContainsKey("k1")); - Assert.True(actualRequest.data.baseData.properties.ContainsKey("k2")); - } - } - finally - { - Activity.DefaultIdFormat = ActivityIdFormat.W3C; - Activity.ForceDefaultIdFormat = true; - } - } - } -} diff --git a/NETCORE/test/FunctionalTests.WebApi.Tests/FunctionalTest/RequestDependencyCorrelationTests.cs b/NETCORE/test/FunctionalTests.WebApi.Tests/FunctionalTest/RequestDependencyCorrelationTests.cs deleted file mode 100644 index 56a41df330..0000000000 --- a/NETCORE/test/FunctionalTests.WebApi.Tests/FunctionalTest/RequestDependencyCorrelationTests.cs +++ /dev/null @@ -1,76 +0,0 @@ -namespace FunctionalTests.WebApi.Tests.FunctionalTest -{ - using System; - using System.Diagnostics; - using System.Linq; - using Microsoft.ApplicationInsights.AspNetCore; - using Microsoft.ApplicationInsights.DependencyCollector; - using Microsoft.ApplicationInsights.DataContracts; - using Microsoft.Extensions.DependencyInjection; - using Xunit; - using Xunit.Abstractions; - using System.Reflection; - using global::FunctionalTests.Utils; - - public class RequestDependencyCorrelationTests : TelemetryTestsBase, IDisposable - { - private readonly string assemblyName; - - public RequestDependencyCorrelationTests(ITestOutputHelper output) : base (output) - { - this.assemblyName = this.GetType().GetTypeInfo().Assembly.GetName().Name; - } - - public void TestBasicDependencyPropertiesAfterRequestingBasicPage() - { - const string RequestPath = "/api/values"; - - using (var server = new InProcessServer(assemblyName, this.output)) - { - DependencyTelemetry expected = new DependencyTelemetry(); - expected.ResultCode = "200"; - expected.Success = true; - expected.Name = "GET " + RequestPath; - expected.Data = server.BaseHost + RequestPath; - - this.ValidateBasicDependency(server, RequestPath, expected); - } - } - - // We may need to add more tests to cover Request + Dependency Tracking - public void TestDependencyAndRequestWithW3CStandard() - { - const string RequestPath = "/api/values"; - - using (var server = new InProcessServer(assemblyName, this.output)) - { - DependencyTelemetry expected = new DependencyTelemetry - { - ResultCode = "200", - Success = true, - Name = "GET " + RequestPath, - Data = server.BaseHost + RequestPath - }; - - var activity = new Activity("dummy") - .Start(); - - var (request, dependency) = this.ValidateBasicDependency(server, RequestPath, expected); - string expectedTraceId = activity.TraceId.ToHexString(); - string expectedParentSpanId = activity.SpanId.ToHexString(); - - Assert.Equal(expectedTraceId, request.tags["ai.operation.id"]); - Assert.Equal(expectedTraceId, dependency.tags["ai.operation.id"]); - Assert.Equal(expectedParentSpanId, dependency.tags["ai.operation.parentId"]); - } - } - - public void Dispose() - { - while (Activity.Current != null) - { - Activity.Current.Stop(); - } - } - } -} diff --git a/NETCORE/test/FunctionalTests.WebApi.Tests/FunctionalTests.WebApi.Tests.csproj b/NETCORE/test/FunctionalTests.WebApi.Tests/FunctionalTests.WebApi.Tests.csproj deleted file mode 100644 index 76b1866330..0000000000 --- a/NETCORE/test/FunctionalTests.WebApi.Tests/FunctionalTests.WebApi.Tests.csproj +++ /dev/null @@ -1,46 +0,0 @@ - - - - - - $(TargetFrameworks_NetCoreOnly) - - FunctionalTests.WebApi.Tests - FunctionalTests.WebApi.Tests - - - - - SettingsSingleFileGenerator - Always - - - PreserveNewest - - - - - - - - - - - - - - - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - - - - - - - - - diff --git a/NETCORE/test/FunctionalTests.WebApi.Tests/Properties/launchSettings.json b/NETCORE/test/FunctionalTests.WebApi.Tests/Properties/launchSettings.json deleted file mode 100644 index e70e6d2ca3..0000000000 --- a/NETCORE/test/FunctionalTests.WebApi.Tests/Properties/launchSettings.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "iisSettings": { - "windowsAuthentication": false, - "anonymousAuthentication": true, - "iisExpress": { - "applicationUrl": "http://localhost:11955/", - "sslPort": 0 - } - }, - "profiles": { - "IIS Express": { - "commandName": "IISExpress", - "launchBrowser": true, - "launchUrl": "api/values", - "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development" - } - }, - "FunctionalTests.WebApi.Tests": { - "commandName": "Project", - "launchBrowser": true, - "launchUrl": "api/values", - "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development" - }, - "applicationUrl": "http://localhost:11956/" - } - } -} diff --git a/NETCORE/test/FunctionalTests.WebApi.Tests/Startup.cs b/NETCORE/test/FunctionalTests.WebApi.Tests/Startup.cs deleted file mode 100644 index 78eee6b87a..0000000000 --- a/NETCORE/test/FunctionalTests.WebApi.Tests/Startup.cs +++ /dev/null @@ -1,44 +0,0 @@ -using Microsoft.AspNetCore.Builder; -using Microsoft.AspNetCore.Hosting; -using Microsoft.Extensions.Configuration; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.ApplicationInsights.Channel; -using FunctionalTests.Utils; - -namespace FunctionalTests.WebApi.Tests -{ - public class Startup - { - public Startup(IConfiguration configuration) - { - Configuration = configuration; - } - - public IConfiguration Configuration { get; } - - // This method gets called by the runtime. Use this method to add services to the container. - public void ConfigureServices(IServiceCollection services) - { - var endpointAddress = new EndpointAddress(); - services.AddSingleton(endpointAddress); - services.AddSingleton(typeof(ITelemetryChannel), new InMemoryChannel() { EndpointAddress = endpointAddress.ConnectionString, DeveloperMode = true }); - services.AddApplicationInsightsTelemetry(InProcessServer.IKey); - services.AddMvc(); - } - - // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. - public void Configure(IApplicationBuilder app, IHostingEnvironment env) - { - if (env.IsDevelopment()) - { - app.UseDeveloperExceptionPage(); - } - - app.UseMvc(routes => - { - // Add the following route for porting Web API 2 controllers. - routes.MapWebApiRoute("DefaultApi", "api/{controller}/{id?}"); - }); - } - } -} diff --git a/NETCORE/test/FunctionalTests.WebApi.Tests/appsettings.Development.json b/NETCORE/test/FunctionalTests.WebApi.Tests/appsettings.Development.json deleted file mode 100644 index fa8ce71a97..0000000000 --- a/NETCORE/test/FunctionalTests.WebApi.Tests/appsettings.Development.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "Logging": { - "IncludeScopes": false, - "LogLevel": { - "Default": "Debug", - "System": "Information", - "Microsoft": "Information" - } - } -} diff --git a/NETCORE/test/FunctionalTests.WebApi.Tests/appsettings.json b/NETCORE/test/FunctionalTests.WebApi.Tests/appsettings.json deleted file mode 100644 index 26bb0ac7ac..0000000000 --- a/NETCORE/test/FunctionalTests.WebApi.Tests/appsettings.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "Logging": { - "IncludeScopes": false, - "Debug": { - "LogLevel": { - "Default": "Warning" - } - }, - "Console": { - "LogLevel": { - "Default": "Warning" - } - } - } -} diff --git a/NETCORE/test/FunctionalTests.WebApi.Tests/xunit.runner.json b/NETCORE/test/FunctionalTests.WebApi.Tests/xunit.runner.json deleted file mode 100644 index 4d305e95df..0000000000 --- a/NETCORE/test/FunctionalTests.WebApi.Tests/xunit.runner.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "parallelizeAssembly": false, - "parallelizeTestCollections": false, - "shadowCopy": false -} diff --git a/NETCORE/test/Microsoft.ApplicationInsights.AspNetCore.Tests/App.config b/NETCORE/test/Microsoft.ApplicationInsights.AspNetCore.Tests/App.config deleted file mode 100644 index 17f9414bab..0000000000 --- a/NETCORE/test/Microsoft.ApplicationInsights.AspNetCore.Tests/App.config +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/NETCORE/test/Microsoft.ApplicationInsights.AspNetCore.Tests/AspNetCoreMajorVersion.cs b/NETCORE/test/Microsoft.ApplicationInsights.AspNetCore.Tests/AspNetCoreMajorVersion.cs deleted file mode 100644 index 643acbc2c2..0000000000 --- a/NETCORE/test/Microsoft.ApplicationInsights.AspNetCore.Tests/AspNetCoreMajorVersion.cs +++ /dev/null @@ -1,8 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace Microsoft.ApplicationInsights.AspNetCore.Tests -{ - public enum AspNetCoreMajorVersion { One, Two, Three}; -} diff --git a/NETCORE/test/Microsoft.ApplicationInsights.AspNetCore.Tests/EnvironmentHelper.cs b/NETCORE/test/Microsoft.ApplicationInsights.AspNetCore.Tests/EnvironmentHelper.cs deleted file mode 100644 index 911a515362..0000000000 --- a/NETCORE/test/Microsoft.ApplicationInsights.AspNetCore.Tests/EnvironmentHelper.cs +++ /dev/null @@ -1,31 +0,0 @@ -namespace Microsoft.ApplicationInsights.AspNetCore.Tests -{ - using System.IO; - - using Moq; - - using IHostingEnvironment = Microsoft.AspNetCore.Hosting.IHostingEnvironment; - - /// - /// The type was marked Obsolete starting in NetCore3. - /// Here I'm abstracting it's use into a helper method to simplify some of the tests. - /// - public static class EnvironmentHelper - { -#pragma warning disable CS0618 // Type or member is obsolete - /// - /// Get an instance of . - /// is set to "UnitTest". - /// is set to . - /// - /// - public static IHostingEnvironment GetIHostingEnvironment() - { - var mockEnvironment = new Mock(); - mockEnvironment.Setup(x => x.EnvironmentName).Returns("UnitTest"); - mockEnvironment.Setup(x => x.ContentRootPath).Returns(Directory.GetCurrentDirectory()); - return mockEnvironment.Object; - } -#pragma warning restore CS0618 // Type or member is obsolete - } -} diff --git a/NETCORE/test/Microsoft.ApplicationInsights.AspNetCore.Tests/Extensibility/Implementation/Tracing/AspNetEventSourceTests.cs b/NETCORE/test/Microsoft.ApplicationInsights.AspNetCore.Tests/Extensibility/Implementation/Tracing/AspNetEventSourceTests.cs deleted file mode 100644 index 57ae1c8eb0..0000000000 --- a/NETCORE/test/Microsoft.ApplicationInsights.AspNetCore.Tests/Extensibility/Implementation/Tracing/AspNetEventSourceTests.cs +++ /dev/null @@ -1,31 +0,0 @@ -//----------------------------------------------------------------------- -// -// Copyright (c) Microsoft Corporation. All rights reserved. -// -//----------------------------------------------------------------------- -namespace Microsoft.ApplicationInsights.AspNetCore.Tests.Extensibility.Implementation.Tracing -{ - using System; - using System.Diagnostics.Tracing; - using System.Reflection; - using Xunit; - - /// - /// Tests for the AspNetEventSource class. - /// - public class AspNetEventSourceTests - { - /// - /// Tests the event source methods and their attributes. - /// - [Fact] - public void TestThatEventSourceMethodsAreImplementedConsistentlyWithTheirAttributes() - { - Assembly asm = Assembly.Load(new AssemblyName("Microsoft.ApplicationInsights.AspNetCore")); - Type eventSourceType = asm.GetType("Microsoft.ApplicationInsights.AspNetCore.Extensibility.Implementation.Tracing.AspNetCoreEventSource"); - EventSource aspNetCoreEventSource = (EventSource)eventSourceType.GetField("Instance", BindingFlags.Public | BindingFlags.Static).GetValue(null); - - EventSourceTests.MethodsAreImplementedConsistentlyWithTheirAttributes(aspNetCoreEventSource); - } - } -} diff --git a/NETCORE/test/Microsoft.ApplicationInsights.AspNetCore.Tests/Extensibility/Implementation/Tracing/EventSourceTests.cs b/NETCORE/test/Microsoft.ApplicationInsights.AspNetCore.Tests/Extensibility/Implementation/Tracing/EventSourceTests.cs deleted file mode 100644 index 58f6b33fa4..0000000000 --- a/NETCORE/test/Microsoft.ApplicationInsights.AspNetCore.Tests/Extensibility/Implementation/Tracing/EventSourceTests.cs +++ /dev/null @@ -1,200 +0,0 @@ -//----------------------------------------------------------------------- -// -// Copyright (c) Microsoft Corporation. All rights reserved. -// -//----------------------------------------------------------------------- -#define DEBUG -namespace Microsoft.ApplicationInsights.AspNetCore.Tests.Extensibility.Implementation.Tracing -{ - using System; - using System.Collections.Generic; - using System.Diagnostics.Tracing; - using System.Globalization; - using System.Linq; - using System.Reflection; - - /// - /// Event source testing helper methods. - /// - internal static class EventSourceTests - { - /// - /// Tests event source method implementation consistency. - /// - /// The event source instance to test. - public static void MethodsAreImplementedConsistentlyWithTheirAttributes(EventSource eventSource) - { - foreach (MethodInfo publicMethod in GetEventMethods(eventSource)) - { - VerifyMethodImplementation(eventSource, publicMethod); - } - } - - /// - /// Verifies the implementation of an event source method. - /// - /// The event source instance to test. - /// The method to verify. - private static void VerifyMethodImplementation(EventSource eventSource, MethodInfo eventMethod) - { - using (var listener = new TestEventListener()) - { - const long AllKeywords = -1; - listener.EnableEvents(eventSource, EventLevel.Verbose, (EventKeywords)AllKeywords); - try - { - object[] eventArguments = GenerateEventArguments(eventMethod); - eventMethod.Invoke(eventSource, eventArguments); - - EventWrittenEventArgs actualEvent = listener.Messages.First(); - VerifyEventId(eventMethod, actualEvent); - VerifyEventLevel(eventMethod, actualEvent); - VerifyEventMessage(eventMethod, actualEvent, eventArguments); - VerifyEventApplicationName(eventMethod, actualEvent); - } - catch (Exception e) - { - throw new Exception(eventMethod.Name + " is implemented incorrectly: " + e.Message, e); - } - } - } - - /// - /// Generates arguments for an event method. - /// - /// The method to generate arguments for. - /// The generated arguments. - private static object[] GenerateEventArguments(MethodInfo eventMethod) - { - ParameterInfo[] parameters = eventMethod.GetParameters(); - var arguments = new object[parameters.Length]; - for (int i = 0; i < parameters.Length; i++) - { - arguments[i] = GenerateArgument(parameters[i]); - } - - return arguments; - } - - /// - /// Generates an event method argument for the given parameter info instance. - /// - /// The parameter to generate and argument for. - /// The argument value. - private static object GenerateArgument(ParameterInfo parameter) - { - if (parameter.ParameterType == typeof(string)) - { - return "Test String"; - } - - Type parameterType = parameter.ParameterType; - if (parameterType.GetTypeInfo().IsValueType) - { - return Activator.CreateInstance(parameter.ParameterType); - } - - throw new NotSupportedException("Complex types are not suppored"); - } - - /// - /// Verifies that the event Id is correct. - /// - /// The method to validate. - /// An actual event arguments to compare to. - private static void VerifyEventId(MethodInfo eventMethod, EventWrittenEventArgs actualEvent) - { - int expectedEventId = GetEventAttribute(eventMethod).EventId; - AssertEqual(expectedEventId, actualEvent.EventId, "EventId"); - } - - /// - /// Verifies that the event level is correct. - /// - /// The method to validate. - /// An actual event arguments to compare to. - private static void VerifyEventLevel(MethodInfo eventMethod, EventWrittenEventArgs actualEvent) - { - EventLevel expectedLevel = GetEventAttribute(eventMethod).Level; - AssertEqual(expectedLevel, actualEvent.Level, "Level"); - } - - /// - /// Verifies that the event message is correct. - /// - /// The method to validate. - /// An actual event arguments to compare to. - /// The arguments that would be passed to the event method. - private static void VerifyEventMessage(MethodInfo eventMethod, EventWrittenEventArgs actualEvent, object[] eventArguments) - { - string expectedMessage = eventArguments.Length == 0 - ? GetEventAttribute(eventMethod).Message - : string.Format(CultureInfo.InvariantCulture, GetEventAttribute(eventMethod).Message, eventArguments); - string actualMessage = string.Format(CultureInfo.InvariantCulture, actualEvent.Message, actualEvent.Payload.ToArray()); - AssertEqual(expectedMessage, actualMessage, "Message"); - } - - /// - /// Verifies that the application name is correct. - /// - /// The method to validate. - /// An actual event arguments to compare to. - private static void VerifyEventApplicationName(MethodInfo eventMethod, EventWrittenEventArgs actualEvent) - { - string expectedApplicationName; - try - { - expectedApplicationName = System.Reflection.Assembly.GetEntryAssembly().GetName().Name; - } - catch (Exception exp) - { - expectedApplicationName = "Undefined " + exp.Message; - } - - string actualApplicationName = actualEvent.Payload.Last().ToString(); - AssertEqual(expectedApplicationName, actualApplicationName, "Application Name"); - } - - /// - /// Dependency free equality assertion helper. - /// - /// The type of the instances being compared. - /// The expected value. - /// The actual value. - /// Message to show when the values are not equal. - private static void AssertEqual(T expected, T actual, string message) - { - if (!expected.Equals(actual)) - { - string errorMessage = string.Format( - CultureInfo.InvariantCulture, - "{0}. expected: '{1}', actual: '{2}'", - message, - expected, - actual); - throw new Exception(errorMessage); - } - } - - /// - /// Gets the event attribute from a given method. - /// - /// The method being tested. - /// The event attribute on the method. - private static EventAttribute GetEventAttribute(MethodInfo eventMethod) - { - return (EventAttribute)eventMethod.GetCustomAttributes(typeof(EventAttribute), false).Single(); - } - - /// - /// Gets the event methods in an event source. - /// - /// The event source to get the event methods in. - /// The event methods in the specified event source. - private static IEnumerable GetEventMethods(EventSource eventSource) - { - MethodInfo[] methods = eventSource.GetType().GetMethods(); - return methods.Where(m => m.GetCustomAttributes(typeof(EventAttribute), false).Any()); - } - } -} \ No newline at end of file diff --git a/NETCORE/test/Microsoft.ApplicationInsights.AspNetCore.Tests/Extensibility/Implementation/Tracing/TestEventListener.cs b/NETCORE/test/Microsoft.ApplicationInsights.AspNetCore.Tests/Extensibility/Implementation/Tracing/TestEventListener.cs deleted file mode 100644 index 73e8ec3b2d..0000000000 --- a/NETCORE/test/Microsoft.ApplicationInsights.AspNetCore.Tests/Extensibility/Implementation/Tracing/TestEventListener.cs +++ /dev/null @@ -1,90 +0,0 @@ -//----------------------------------------------------------------------- -// -// Copyright (c) Microsoft Corporation. All rights reserved. -// -//----------------------------------------------------------------------- -namespace Microsoft.ApplicationInsights.AspNetCore.Tests.Extensibility.Implementation.Tracing -{ - using System; - using System.Collections.Generic; - using System.Diagnostics.Tracing; - using System.Threading; - - /// - /// Event listener for testing event sources. - /// - internal class TestEventListener : EventListener - { - /// A queue of events that have been logged. - private readonly Queue events; - - /// - /// Lock for event writing tracking. - /// - private readonly AutoResetEvent eventWritten; - - /// - /// Initializes a new instance of the TestEventListener class. - /// - public TestEventListener() - { - this.events = new Queue(); - this.eventWritten = new AutoResetEvent(false); - this.OnOnEventWritten = e => - { - this.events.Enqueue(e); - this.eventWritten.Set(); - }; - } - - /// Gets or sets the handler for event source creation. - public Action OnOnEventSourceCreated { get; set; } - - /// Gets or sets the handler for event source writes. - public Action OnOnEventWritten { get; set; } - - /// Gets the events that have been written. - public IEnumerable Messages - { - get - { - if (this.events.Count == 0) - { - this.eventWritten.WaitOne(TimeSpan.FromSeconds(5)); - } - - while (this.events.Count != 0) - { - yield return this.events.Dequeue(); - } - } - } - - /// - /// Clears all event messages so that testing can assert expected counts. - /// - public void ClearMessages() - { - this.events.Clear(); - } - - /// Handler for event source writes. - /// The event data that was written. - protected override void OnEventWritten(EventWrittenEventArgs eventData) - { - this.OnOnEventWritten(eventData); - } - - /// Handler for event source creation. - /// The event source that was created. - protected override void OnEventSourceCreated(EventSource eventSource) - { - // Check for null because this method is called by the base class constror before we can initialize it - Action callback = this.OnOnEventSourceCreated; - if (callback != null) - { - callback(eventSource); - } - } - } -} diff --git a/NETCORE/test/Microsoft.ApplicationInsights.AspNetCore.Tests/Extensions/ApplicationInsightsAadIntegrationTests.cs b/NETCORE/test/Microsoft.ApplicationInsights.AspNetCore.Tests/Extensions/ApplicationInsightsAadIntegrationTests.cs deleted file mode 100644 index ba6808c6f8..0000000000 --- a/NETCORE/test/Microsoft.ApplicationInsights.AspNetCore.Tests/Extensions/ApplicationInsightsAadIntegrationTests.cs +++ /dev/null @@ -1,121 +0,0 @@ -namespace Microsoft.ApplicationInsights.AspNetCore.Tests.Extensions -{ - using System; - using System.Linq; - using Azure.Core; - using Azure.Monitor.OpenTelemetry.Exporter; - using Microsoft.ApplicationInsights.AspNetCore.Extensions; - using Microsoft.ApplicationInsights.Extensibility; - using Microsoft.AspNetCore.Hosting; - using Microsoft.Extensions.Configuration; - using Microsoft.Extensions.DependencyInjection; - using Microsoft.Extensions.Options; - using Xunit; - - /// - /// Integration tests for Azure Active Directory (AAD) authentication support in AspNetCore. - /// - public class ApplicationInsightsAadIntegrationTests - { - /// - /// Tests that credential flows from ApplicationInsightsServiceOptions to AzureMonitorExporterOptions. - /// - [Fact] - public void AddApplicationInsightsTelemetry_WithCredential_FlowsCredentialToExporter() - { - // Arrange - var services = new ServiceCollection(); - var credential = new MockTokenCredential(); - var connectionString = "InstrumentationKey=test-ikey;IngestionEndpoint=https://test.endpoint.com/"; - - // Act - services.AddApplicationInsightsTelemetry(options => - { - options.ConnectionString = connectionString; - options.Credential = credential; - }); - - var serviceProvider = services.BuildServiceProvider(); - - // Get the configured AzureMonitorExporterOptions - var exporterOptions = serviceProvider.GetService>(); - - // Assert - Assert.NotNull(exporterOptions); - Assert.NotNull(exporterOptions.Value); - Assert.Same(credential, exporterOptions.Value.Credential); - } - - /// - /// Tests that credential is null when not set. - /// - [Fact] - public void AddApplicationInsightsTelemetry_WithoutCredential_HasNullCredentialInExporter() - { - // Arrange - var services = new ServiceCollection(); - var connectionString = "InstrumentationKey=test-ikey;IngestionEndpoint=https://test.endpoint.com/"; - - // Act - services.AddApplicationInsightsTelemetry(options => - { - options.ConnectionString = connectionString; - // No credential set - }); - - var serviceProvider = services.BuildServiceProvider(); - - // Get the configured AzureMonitorExporterOptions - var exporterOptions = serviceProvider.GetService>(); - - // Assert - Assert.NotNull(exporterOptions); - Assert.NotNull(exporterOptions.Value); - Assert.Null(exporterOptions.Value.Credential); - } - - /// - /// Tests that TelemetryClient can be created with credential configured. - /// - [Fact] - public void TelemetryClient_WithCredential_CreatesSuccessfully() - { - // Arrange - var services = new ServiceCollection(); - var credential = new MockTokenCredential(); - var connectionString = "InstrumentationKey=test-ikey;IngestionEndpoint=https://test.endpoint.com/"; - - services.AddApplicationInsightsTelemetry(options => - { - options.ConnectionString = connectionString; - options.Credential = credential; - }); - - var serviceProvider = services.BuildServiceProvider(); - - // Act - var telemetryClient = serviceProvider.GetService(); - - // Assert - Assert.NotNull(telemetryClient); - Assert.NotNull(telemetryClient.TelemetryConfiguration); - } - - /// - /// Mock TokenCredential for testing purposes. - /// - private class MockTokenCredential : TokenCredential - { - public override AccessToken GetToken(TokenRequestContext requestContext, System.Threading.CancellationToken cancellationToken) - { - return new AccessToken("mock-token", DateTimeOffset.UtcNow.AddHours(1)); - } - - public override System.Threading.Tasks.ValueTask GetTokenAsync(TokenRequestContext requestContext, System.Threading.CancellationToken cancellationToken) - { - return new System.Threading.Tasks.ValueTask( - new AccessToken("mock-token", DateTimeOffset.UtcNow.AddHours(1))); - } - } - } -} diff --git a/NETCORE/test/Microsoft.ApplicationInsights.AspNetCore.Tests/Extensions/ApplicationInsightsExtensionsTests/AddApplicationInsightsSettingsTests.cs b/NETCORE/test/Microsoft.ApplicationInsights.AspNetCore.Tests/Extensions/ApplicationInsightsExtensionsTests/AddApplicationInsightsSettingsTests.cs deleted file mode 100644 index 19ccc095a6..0000000000 --- a/NETCORE/test/Microsoft.ApplicationInsights.AspNetCore.Tests/Extensions/ApplicationInsightsExtensionsTests/AddApplicationInsightsSettingsTests.cs +++ /dev/null @@ -1,75 +0,0 @@ -using Xunit; - -namespace Microsoft.Extensions.DependencyInjection.Test -{ - using System; - - using Microsoft.ApplicationInsights; - using Microsoft.ApplicationInsights.Channel; - using Microsoft.ApplicationInsights.DataContracts; - - using Microsoft.Extensions.Configuration; - - public class AddApplicationInsightsSettings : BaseTestClass - { - [Fact] - public static void RegistersTelemetryConfigurationFactoryMethodThatReadsInstrumentationKeyFromSettings() - { - var services = GetServiceCollectionWithContextAccessor(); - services.AddSingleton(new InMemoryChannel()); - var config = new ConfigurationBuilder().AddApplicationInsightsSettings(instrumentationKey: TestInstrumentationKey).Build(); - services.AddApplicationInsightsTelemetry(config); - - IServiceProvider serviceProvider = services.BuildServiceProvider(); - var telemetryConfiguration = serviceProvider.GetTelemetryConfiguration(); - Assert.Equal(TestInstrumentationKey, telemetryConfiguration.InstrumentationKey); - } - - [Fact] - public static void RegistersTelemetryConfigurationFactoryMethodThatReadsDeveloperModeFromSettings() - { - var services = GetServiceCollectionWithContextAccessor(); - services.AddSingleton(new InMemoryChannel()); - var config = new ConfigurationBuilder().AddApplicationInsightsSettings(developerMode: true).Build(); - services.AddApplicationInsightsTelemetry(config); - - IServiceProvider serviceProvider = services.BuildServiceProvider(); - var telemetryConfiguration = serviceProvider.GetTelemetryConfiguration(); - Assert.True(telemetryConfiguration.TelemetryChannel.DeveloperMode); - } - - [Fact] - public static void RegistersTelemetryConfigurationFactoryMethodThatReadsEndpointAddressFromSettings() - { - var services = CreateServicesAndAddApplicationinsightsTelemetry(null, "http://localhost:1234/v2/track/"); - IServiceProvider serviceProvider = services.BuildServiceProvider(); - var telemetryConfiguration = serviceProvider.GetTelemetryConfiguration(); - Assert.Equal("http://localhost:1234/v2/track/", telemetryConfiguration.TelemetryChannel.EndpointAddress); - } - - /// - /// Sanity check to validate that node name and roleinstance are populated - /// - [Fact] - public static void SanityCheckRoleInstance() - { - // ARRANGE - string expected = Environment.MachineName; - var services = GetServiceCollectionWithContextAccessor(); - services.AddApplicationInsightsTelemetry(); - IServiceProvider serviceProvider = services.BuildServiceProvider(); - - // Request TC from DI which would be made with the default TelemetryConfiguration which should - // contain the telemetry initializer capable of populate node name and role instance name. - var tc = serviceProvider.GetRequiredService(); - var mockItem = new EventTelemetry(); - - // ACT - // This is expected to run all TI and populate the node name and role instance. - tc.Initialize(mockItem); - - // VERIFY - Assert.Contains(expected, mockItem.Context.Cloud.RoleInstance, StringComparison.CurrentCultureIgnoreCase); - } - } -} diff --git a/NETCORE/test/Microsoft.ApplicationInsights.AspNetCore.Tests/Extensions/ApplicationInsightsExtensionsTests/AddApplicationInsightsTelemetryTests.cs b/NETCORE/test/Microsoft.ApplicationInsights.AspNetCore.Tests/Extensions/ApplicationInsightsExtensionsTests/AddApplicationInsightsTelemetryTests.cs deleted file mode 100644 index 0720e269da..0000000000 --- a/NETCORE/test/Microsoft.ApplicationInsights.AspNetCore.Tests/Extensions/ApplicationInsightsExtensionsTests/AddApplicationInsightsTelemetryTests.cs +++ /dev/null @@ -1,1609 +0,0 @@ -using Xunit; - -namespace Microsoft.Extensions.DependencyInjection.Test -{ - using System; - using System.Diagnostics; - using System.IO; - using System.Linq; - using System.Reflection; - - using Logging; - - using Microsoft.ApplicationInsights; - using Microsoft.ApplicationInsights.AspNetCore; - using Microsoft.ApplicationInsights.AspNetCore.Extensions; - using Microsoft.ApplicationInsights.AspNetCore.Logging; - using Microsoft.ApplicationInsights.AspNetCore.TelemetryInitializers; - using Microsoft.ApplicationInsights.AspNetCore.Tests; - using Microsoft.ApplicationInsights.AspNetCore.Tests.Helpers; - using Microsoft.ApplicationInsights.Channel; - using Microsoft.ApplicationInsights.DependencyCollector; - using Microsoft.ApplicationInsights.Extensibility; -#if NETCOREAPP - using Microsoft.ApplicationInsights.Extensibility.EventCounterCollector; -#endif - using Microsoft.ApplicationInsights.Extensibility.Implementation; - using Microsoft.ApplicationInsights.Extensibility.Implementation.Tracing; - using Microsoft.ApplicationInsights.Extensibility.PerfCounterCollector; - using Microsoft.ApplicationInsights.Extensibility.PerfCounterCollector.QuickPulse; - using Microsoft.ApplicationInsights.Extensibility.W3C; - using Microsoft.ApplicationInsights.WindowsServer; - using Microsoft.ApplicationInsights.WindowsServer.TelemetryChannel; - using Microsoft.AspNetCore.Hosting; - using Microsoft.Extensions.Configuration; - using Microsoft.Extensions.DependencyInjection.Extensions; - using Microsoft.Extensions.Options; - - public class AddApplicationInsightsTelemetryTests : BaseTestClass - { - [Theory] - [InlineData(true)] - [InlineData(false)] - public static void TelemetryModulesResolvableWhenKeyedServiceRegistered(bool manuallyRegisterDiagnosticsTelemetryModule) - { - // Note: This test verifies a regression doesn't get introduced for: - // https://github.com/microsoft/ApplicationInsights-dotnet/issues/2879 - - var services = new ServiceCollection(); - - services.AddSingleton(); - if (manuallyRegisterDiagnosticsTelemetryModule) - { - services.AddSingleton(); - } - - services.AddKeyedSingleton(typeof(ITestService), serviceKey: new(), implementationType: typeof(TestService)); - services.AddKeyedSingleton(typeof(ITestService), serviceKey: new(), implementationInstance: new TestService()); - services.AddKeyedSingleton(typeof(ITestService), serviceKey: new(), implementationFactory: (sp, key) => new TestService()); - - services.AddApplicationInsightsTelemetry(); - - using var sp = services.BuildServiceProvider(); - - var telemetryModules = sp.GetServices(); - - Assert.Equal(8, telemetryModules.Count()); - - Assert.Single(telemetryModules.Where(m => m.GetType() == typeof(DiagnosticsTelemetryModule))); - } - - [Theory] - [InlineData(typeof(ITelemetryInitializer), typeof(ApplicationInsights.AspNetCore.TelemetryInitializers.DomainNameRoleInstanceTelemetryInitializer), ServiceLifetime.Singleton)] - [InlineData(typeof(ITelemetryInitializer), typeof(AzureAppServiceRoleNameFromHostNameHeaderInitializer), ServiceLifetime.Singleton)] - [InlineData(typeof(ITelemetryInitializer), typeof(ComponentVersionTelemetryInitializer), ServiceLifetime.Singleton)] - [InlineData(typeof(ITelemetryInitializer), typeof(ClientIpHeaderTelemetryInitializer), ServiceLifetime.Singleton)] - [InlineData(typeof(ITelemetryInitializer), typeof(OperationNameTelemetryInitializer), ServiceLifetime.Singleton)] - [InlineData(typeof(ITelemetryInitializer), typeof(SyntheticTelemetryInitializer), ServiceLifetime.Singleton)] - [InlineData(typeof(ITelemetryInitializer), typeof(WebSessionTelemetryInitializer), ServiceLifetime.Singleton)] - [InlineData(typeof(ITelemetryInitializer), typeof(WebUserTelemetryInitializer), ServiceLifetime.Singleton)] - [InlineData(typeof(ITelemetryInitializer), typeof(HttpDependenciesParsingTelemetryInitializer), ServiceLifetime.Singleton)] - [InlineData(typeof(TelemetryConfiguration), null, ServiceLifetime.Singleton)] - [InlineData(typeof(TelemetryClient), typeof(TelemetryClient), ServiceLifetime.Singleton)] - public static void RegistersExpectedServices(Type serviceType, Type implementationType, ServiceLifetime lifecycle) - { - var services = CreateServicesAndAddApplicationinsightsTelemetry(null, null); - ServiceDescriptor service = services.Single(s => s.ServiceType == serviceType && s.ImplementationType == implementationType); - Assert.Equal(lifecycle, service.Lifetime); - } - - [Theory] - [InlineData(typeof(ITelemetryInitializer), typeof(ApplicationInsights.AspNetCore.TelemetryInitializers.DomainNameRoleInstanceTelemetryInitializer), ServiceLifetime.Singleton)] - [InlineData(typeof(ITelemetryInitializer), typeof(AzureAppServiceRoleNameFromHostNameHeaderInitializer), ServiceLifetime.Singleton)] - [InlineData(typeof(ITelemetryInitializer), typeof(ComponentVersionTelemetryInitializer), ServiceLifetime.Singleton)] - [InlineData(typeof(ITelemetryInitializer), typeof(ClientIpHeaderTelemetryInitializer), ServiceLifetime.Singleton)] - [InlineData(typeof(ITelemetryInitializer), typeof(OperationNameTelemetryInitializer), ServiceLifetime.Singleton)] - [InlineData(typeof(ITelemetryInitializer), typeof(SyntheticTelemetryInitializer), ServiceLifetime.Singleton)] - [InlineData(typeof(ITelemetryInitializer), typeof(WebSessionTelemetryInitializer), ServiceLifetime.Singleton)] - [InlineData(typeof(ITelemetryInitializer), typeof(WebUserTelemetryInitializer), ServiceLifetime.Singleton)] - [InlineData(typeof(ITelemetryInitializer), typeof(HttpDependenciesParsingTelemetryInitializer), ServiceLifetime.Singleton)] - [InlineData(typeof(TelemetryConfiguration), null, ServiceLifetime.Singleton)] - [InlineData(typeof(TelemetryClient), typeof(TelemetryClient), ServiceLifetime.Singleton)] - public static void RegistersExpectedServicesOnlyOnce(Type serviceType, Type implementationType, ServiceLifetime lifecycle) - { - var services = GetServiceCollectionWithContextAccessor(); - services.AddApplicationInsightsTelemetry(); - services.AddApplicationInsightsTelemetry(); - ServiceDescriptor service = services.Single(s => s.ServiceType == serviceType && s.ImplementationType == implementationType); - Assert.Equal(lifecycle, service.Lifetime); - } - - [Fact] - public static void DoesNotThrowWithoutInstrumentationKey() - { - var services = CreateServicesAndAddApplicationinsightsTelemetry(null, null); - } - - [Fact] - public static void RegistersTelemetryConfigurationFactoryMethodThatCreatesDefaultInstance() - { - var services = CreateServicesAndAddApplicationinsightsTelemetry(null, null); - - IServiceProvider serviceProvider = services.BuildServiceProvider(); - var telemetryConfiguration = serviceProvider.GetTelemetryConfiguration(); - Assert.Contains(telemetryConfiguration.TelemetryInitializers, t => t is OperationNameTelemetryInitializer); - } - - /// - /// Tests that the instrumentation key configuration can be read from a JSON file by the configuration factory. - /// - /// - /// Calls services.AddApplicationInsightsTelemetry() when the value is true and reads IConfiguration from user application automatically. - /// Else, it invokes services.AddApplicationInsightsTelemetry(configuration) where IConfiguration object is supplied by caller. - /// - [Theory] - [InlineData(false)] - public static void RegistersTelemetryConfigurationFactoryMethodThatReadsInstrumentationKeyFromConfiguration(bool useDefaultConfig) - { - var services = CreateServicesAndAddApplicationinsightsTelemetry(Path.Combine("content", "config-instrumentation-key.json"), null, null, true, useDefaultConfig); - - IServiceProvider serviceProvider = services.BuildServiceProvider(); - var telemetryConfiguration = serviceProvider.GetTelemetryConfiguration(); - if (useDefaultConfig) - { - Assert.Equal(InstrumentationKeyInAppSettings, telemetryConfiguration.InstrumentationKey); - } - else - { - Assert.Equal(TestInstrumentationKey, telemetryConfiguration.InstrumentationKey); - } - } - - /// - /// Tests that the connection string can be read from a JSON file by the configuration factory. - /// - /// - /// Calls services.AddApplicationInsightsTelemetry() when the value is true and reads IConfiguration from user application automatically. - /// Else, it invokes services.AddApplicationInsightsTelemetry(configuration) where IConfiguration object is supplied by caller. - /// - [Theory] - [InlineData(true)] - [InlineData(false)] - [Trait("Trait", "ConnectionString")] - public static void RegistersTelemetryConfigurationFactoryMethodThatReadsConnectionStringFromConfiguration(bool useDefaultConfig) - { - var services = CreateServicesAndAddApplicationinsightsTelemetry(Path.Combine("content", "config-connection-string.json"), null, null, true, useDefaultConfig); - - IServiceProvider serviceProvider = services.BuildServiceProvider(); - var telemetryConfiguration = serviceProvider.GetTelemetryConfiguration(); - Assert.Equal(TestConnectionString, telemetryConfiguration.ConnectionString); - Assert.Equal(TestInstrumentationKey, telemetryConfiguration.InstrumentationKey); - Assert.Equal("http://127.0.0.1/", telemetryConfiguration.EndpointContainer.Ingestion.AbsoluteUri); - } - - /// - /// Tests that the connection string can be read from a JSON file by the configuration factory. - /// This config has both a connection string and an instrumentation key. It is expected to use the ikey from the connection string. - /// - [Fact] - [Trait("Trait", "ConnectionString")] - public static void RegistersTelemetryConfigurationFactoryMethodThatReadsConnectionStringAndInstrumentationKeyFromConfiguration() - { - var services = CreateServicesAndAddApplicationinsightsTelemetry(Path.Combine("content", "config-connection-string-and-instrumentation-key.json"), null); - - IServiceProvider serviceProvider = services.BuildServiceProvider(); - var telemetryConfiguration = serviceProvider.GetTelemetryConfiguration(); - Assert.Equal(TestConnectionString, telemetryConfiguration.ConnectionString); - Assert.Equal(TestInstrumentationKey, telemetryConfiguration.InstrumentationKey); - Assert.Equal("http://127.0.0.1/", telemetryConfiguration.EndpointContainer.Ingestion.AbsoluteUri); - } - - /// - /// Tests that the Active configuration singleton is updated, but another instance of telemetry configuration is created for dependency injection. - /// ASP.NET Core developers should always use Dependency Injection instead of static singleton approach. - /// See Microsoft/ApplicationInsights-dotnet#613 - /// - [Fact] - public static void ConfigurationFactoryMethodUpdatesTheActiveConfigurationSingletonByDefault() - { - var services = CreateServicesAndAddApplicationinsightsTelemetry(Path.Combine("content", "config-instrumentation-key.json"), null, null, true, false); - - IServiceProvider serviceProvider = services.BuildServiceProvider(); - TelemetryConfiguration telemetryConfiguration = serviceProvider.GetTelemetryConfiguration(); - Assert.Equal(TestInstrumentationKey, telemetryConfiguration.InstrumentationKey); - } - - /// - /// We determine if Active telemetry needs to be configured based on the assumptions that 'default' configuration - // created by base SDK has single preset ITelemetryInitializer. If it ever changes, change TelemetryConfigurationOptions.IsActiveConfigured method as well. - /// - [Fact] - public static void DefaultTelemetryConfigurationHasOneTelemetryInitializer() - { - // - var defaultConfig = TelemetryConfiguration.CreateDefault(); - Assert.Equal(1, defaultConfig.TelemetryInitializers.Count); - } - - /// - /// Tests that the developer mode can be read from a JSON file by the configuration factory. - /// - /// - /// Calls services.AddApplicationInsightsTelemetry() when the value is true and reads IConfiguration from user application automatically. - /// Else, it invokes services.AddApplicationInsightsTelemetry(configuration) where IConfiguration object is supplied by caller. - /// - [Theory] - [InlineData(true)] - [InlineData(false)] - public static void RegistersTelemetryConfigurationFactoryMethodThatReadsDeveloperModeFromConfiguration(bool useDefaultConfig) - { - var services = CreateServicesAndAddApplicationinsightsTelemetry(Path.Combine("content", "config-developer-mode.json"), null, null, true, useDefaultConfig); - - IServiceProvider serviceProvider = services.BuildServiceProvider(); - var telemetryConfiguration = serviceProvider.GetTelemetryConfiguration(); - Assert.True(telemetryConfiguration.TelemetryChannel.DeveloperMode); - } - - /// - /// Tests that the endpoint address can be read from a JSON file by the configuration factory. - /// - /// - /// Calls services.AddApplicationInsightsTelemetry() when the value is true and reads IConfiguration from user application automatically. - /// Else, it invokes services.AddApplicationInsightsTelemetry(configuration) where IConfiguration object is supplied by caller. - /// - [Theory] - [InlineData(false)] - public static void RegistersTelemetryConfigurationFactoryMethodThatReadsEndpointAddressFromConfiguration(bool useDefaultConfig) - { - var services = CreateServicesAndAddApplicationinsightsTelemetry(Path.Combine("content", "config-endpoint-address.json"), null, null, true, useDefaultConfig); - - IServiceProvider serviceProvider = services.BuildServiceProvider(); - var telemetryConfiguration = serviceProvider.GetTelemetryConfiguration(); - - if (useDefaultConfig) - { - // Endpoint comes from appSettings - Assert.Equal("http://hosthere/v2/track/", telemetryConfiguration.TelemetryChannel.EndpointAddress); - } - else - { - Assert.Equal("http://localhost:1234/v2/track/", telemetryConfiguration.TelemetryChannel.EndpointAddress); - } - } - - [Fact] - public static void RegistersTelemetryConfigurationFactoryMethodThatReadsInstrumentationKeyFromEnvironment() - { - var services = GetServiceCollectionWithContextAccessor(); - services.AddSingleton(new InMemoryChannel()); - Environment.SetEnvironmentVariable("APPINSIGHTS_INSTRUMENTATIONKEY", TestInstrumentationKey); - var config = new ConfigurationBuilder().AddEnvironmentVariables().Build(); - try - { - services.AddApplicationInsightsTelemetry(config); - - IServiceProvider serviceProvider = services.BuildServiceProvider(); - var telemetryConfiguration = serviceProvider.GetTelemetryConfiguration(); - Assert.Equal(TestInstrumentationKey, telemetryConfiguration.InstrumentationKey); - } - finally - { - Environment.SetEnvironmentVariable("APPINSIGHTS_INSTRUMENTATIONKEY", null); - } - } - - /// - /// Validates that while using services.AddApplicationInsightsTelemetry(); ikey is read from - /// Environment - /// - [Fact] - [Trait("Trait", "ConnectionString")] - public static void AddApplicationInsightsTelemetry_ReadsConnectionString_FromEnvironment() - { - var services = GetServiceCollectionWithContextAccessor(); - Environment.SetEnvironmentVariable(ConnectionStringEnvironmentVariable, TestConnectionString); - try - { - services.AddApplicationInsightsTelemetry(); - IServiceProvider serviceProvider = services.BuildServiceProvider(); - var telemetryConfiguration = serviceProvider.GetTelemetryConfiguration(); - Assert.Equal(TestConnectionString, telemetryConfiguration.ConnectionString); - Assert.Equal(TestInstrumentationKey, telemetryConfiguration.InstrumentationKey); - Assert.Equal("http://127.0.0.1/", telemetryConfiguration.EndpointContainer.Ingestion.AbsoluteUri); - } - finally - { - Environment.SetEnvironmentVariable(ConnectionStringEnvironmentVariable, null); - } - } - - /// - /// Validates that while using services.AddApplicationInsightsTelemetry(); ikey is read from - /// Environment - /// - [Fact] - public static void AddApplicationInsightsTelemetryReadsInstrumentationKeyFromEnvironment() - { - var services = GetServiceCollectionWithContextAccessor(); - Environment.SetEnvironmentVariable("APPINSIGHTS_INSTRUMENTATIONKEY", TestInstrumentationKey); - try - { - services.AddApplicationInsightsTelemetry(); - IServiceProvider serviceProvider = services.BuildServiceProvider(); - var telemetryConfiguration = serviceProvider.GetTelemetryConfiguration(); - Assert.Equal(TestInstrumentationKey, telemetryConfiguration.InstrumentationKey); - } - finally - { - Environment.SetEnvironmentVariable("APPINSIGHTS_INSTRUMENTATIONKEY", null); - } - } - - /// - /// Validates that while using services.AddApplicationInsightsTelemetry(ikey), supplied ikey is - /// used instead of one from Environment - /// - [Fact] - public static void AddApplicationInsightsTelemetryDoesNotReadInstrumentationKeyFromEnvironmentIfSupplied() - { - Environment.SetEnvironmentVariable("APPINSIGHTS_INSTRUMENTATIONKEY", TestInstrumentationKey); - var services = GetServiceCollectionWithContextAccessor(); - string ikeyExpected = Guid.NewGuid().ToString(); - - try - { - services.AddApplicationInsightsTelemetry(ikeyExpected); - IServiceProvider serviceProvider = services.BuildServiceProvider(); - var telemetryConfiguration = serviceProvider.GetTelemetryConfiguration(); - Assert.Equal(ikeyExpected, telemetryConfiguration.InstrumentationKey); - } - finally - { - Environment.SetEnvironmentVariable("APPINSIGHTS_INSTRUMENTATIONKEY", null); - } - } - - /// - /// Validates that while using services.AddApplicationInsightsTelemetry(); reads ikey/other settings from - /// appsettings.json - /// - [Fact] - public static void AddApplicationInsightsTelemetryReadsInstrumentationKeyFromDefaultAppsettingsFile() - { - string ikeyExpected = Guid.NewGuid().ToString(); - string hostExpected = "http://ainewhost/v2/track/"; - string text = File.ReadAllText("appsettings.json"); - string originalText = text; - try - { - text = text.Replace(InstrumentationKeyInAppSettings, ikeyExpected); - text = text.Replace("http://hosthere/v2/track/", hostExpected); - File.WriteAllText("appsettings.json", text); - - var services = GetServiceCollectionWithContextAccessor(); - services.AddApplicationInsightsTelemetry(); - IServiceProvider serviceProvider = services.BuildServiceProvider(); - var telemetryConfiguration = serviceProvider.GetTelemetryConfiguration(); - Assert.Equal(ikeyExpected, telemetryConfiguration.InstrumentationKey); - Assert.Equal(hostExpected, telemetryConfiguration.TelemetryChannel.EndpointAddress); - } - finally - { - File.WriteAllText("appsettings.json", originalText); - } - } - - /// - /// Validates that while using services.AddApplicationInsightsTelemetry(ikey), supplied ikey is - /// used instead of one from appsettings.json - /// - [Fact] - public static void AddApplicationInsightsTelemetryDoesNotReadInstrumentationKeyFromDefaultAppsettingsIfSupplied() - { - string suppliedIKey = "suppliedikey"; - string ikey = Guid.NewGuid().ToString(); - string text = File.ReadAllText("appsettings.json"); - try - { - text = text.Replace(InstrumentationKeyInAppSettings, ikey); - File.WriteAllText("appsettings.json", text); - - var services = GetServiceCollectionWithContextAccessor(); - services.AddApplicationInsightsTelemetry(suppliedIKey); - IServiceProvider serviceProvider = services.BuildServiceProvider(); - var telemetryConfiguration = serviceProvider.GetTelemetryConfiguration(); - Assert.Equal(suppliedIKey, telemetryConfiguration.InstrumentationKey); - } - finally - { - text = text.Replace(ikey, InstrumentationKeyInAppSettings); - File.WriteAllText("appsettings.json", text); - } - } - - /// - /// Validates that while using services.AddApplicationInsightsTelemetry(ApplicationInsightsServiceOptions), supplied ikey is - /// used instead of one from appsettings.json - /// - [Fact] - public static void AddApplicationInsightsTelemetryDoesNotReadInstrumentationKeyFromDefaultAppsettingsIfSuppliedViaOptions() - { - string suppliedIKey = "suppliedikey"; - var options = new ApplicationInsightsServiceOptions() { InstrumentationKey = suppliedIKey }; - string ikey = Guid.NewGuid().ToString(); - string text = File.ReadAllText("appsettings.json"); - try - { - text = text.Replace(InstrumentationKeyInAppSettings, ikey); - File.WriteAllText("appsettings.json", text); - - var services = GetServiceCollectionWithContextAccessor(); - services.AddApplicationInsightsTelemetry(options); - IServiceProvider serviceProvider = services.BuildServiceProvider(); - var telemetryConfiguration = serviceProvider.GetTelemetryConfiguration(); - Assert.Equal(suppliedIKey, telemetryConfiguration.InstrumentationKey); - } - finally - { - text = text.Replace(ikey, InstrumentationKeyInAppSettings); - File.WriteAllText("appsettings.json", text); - } - } - - /// - /// Validates that while using services.AddApplicationInsightsTelemetry(ApplicationInsightsServiceOptions), with null ikey - /// and endpoint, ikey and endpoint from AppSettings.Json is NOT overwritten with the null/empty ones from - /// ApplicationInsightsServiceOptions - /// - [Fact] - public static void AddApplicationInsightsTelemetryDoesNotOverrideEmptyInstrumentationKeyFromAiOptions() - { - // Create new options, which will be default have null ikey and endpoint. - var options = new ApplicationInsightsServiceOptions(); - string ikey = Guid.NewGuid().ToString(); - string text = File.ReadAllText("appsettings.json"); - try - { - text = text.Replace(InstrumentationKeyInAppSettings, ikey); - text = text.Replace("hosthere", "newhost"); - File.WriteAllText("appsettings.json", text); - - var services = GetServiceCollectionWithContextAccessor(); - services.AddApplicationInsightsTelemetry(options); - IServiceProvider serviceProvider = services.BuildServiceProvider(); - var telemetryConfiguration = serviceProvider.GetTelemetryConfiguration(); - Assert.Equal(ikey, telemetryConfiguration.InstrumentationKey); - Assert.Equal("http://newhost/v2/track/", telemetryConfiguration.DefaultTelemetrySink.TelemetryChannel.EndpointAddress); - } - finally - { - text = text.Replace(ikey, InstrumentationKeyInAppSettings); - text = text.Replace("newhost", "hosthere"); - File.WriteAllText("appsettings.json", text); - } - } - - [Fact] - public static void RegistersTelemetryConfigurationFactoryMethodThatReadsDeveloperModeFromEnvironment() - { - var services = GetServiceCollectionWithContextAccessor(); - services.AddSingleton(new InMemoryChannel()); - Environment.SetEnvironmentVariable("APPINSIGHTS_DEVELOPER_MODE", "true"); - var config = new ConfigurationBuilder().AddEnvironmentVariables().Build(); - try - { - services.AddApplicationInsightsTelemetry(config); - - IServiceProvider serviceProvider = services.BuildServiceProvider(); - var telemetryConfiguration = serviceProvider.GetTelemetryConfiguration(); - Assert.True(telemetryConfiguration.TelemetryChannel.DeveloperMode); - } - finally - { - Environment.SetEnvironmentVariable("APPINSIGHTS_DEVELOPER_MODE", null); - } - } - - [Fact] - public static void RegistersTelemetryConfigurationFactoryMethodThatReadsEndpointAddressFromEnvironment() - { - var services = GetServiceCollectionWithContextAccessor(); - services.AddSingleton(new InMemoryChannel()); - Environment.SetEnvironmentVariable("APPINSIGHTS_ENDPOINTADDRESS", "http://localhost:1234/v2/track/"); - var config = new ConfigurationBuilder().AddEnvironmentVariables().Build(); - try - { - services.AddApplicationInsightsTelemetry(config); - - IServiceProvider serviceProvider = services.BuildServiceProvider(); - var telemetryConfiguration = serviceProvider.GetTelemetryConfiguration(); - Assert.Equal("http://localhost:1234/v2/track/", telemetryConfiguration.TelemetryChannel.EndpointAddress); - } - finally - { - Environment.SetEnvironmentVariable("APPINSIGHTS_ENDPOINTADDRESS", null); - } - } - - [Fact] - public static void RegistersTelemetryConfigurationFactoryMethodThatPopulatesItWithTelemetryInitializersFromContainer() - { - var telemetryInitializer = new FakeTelemetryInitializer(); - var services = GetServiceCollectionWithContextAccessor(); - services.AddSingleton(telemetryInitializer); - services.AddSingleton(new InMemoryChannel()); - - services.AddApplicationInsightsTelemetry(new ConfigurationBuilder().Build()); - - IServiceProvider serviceProvider = services.BuildServiceProvider(); - var telemetryConfiguration = serviceProvider.GetTelemetryConfiguration(); - Assert.Contains(telemetryInitializer, telemetryConfiguration.TelemetryInitializers); - } - - [Fact] - public static void RegistersTelemetryConfigurationFactoryMethodThatPopulatesItWithTelemetryChannelFromContainer() - { - var telemetryChannel = new FakeTelemetryChannel(); - var services = GetServiceCollectionWithContextAccessor(); - services.AddSingleton(telemetryChannel); - - services.AddApplicationInsightsTelemetry(new ConfigurationBuilder().Build()); - - IServiceProvider serviceProvider = services.BuildServiceProvider(); - var telemetryConfiguration = serviceProvider.GetTelemetryConfiguration(); - Assert.Same(telemetryChannel, telemetryConfiguration.TelemetryChannel); - } - - [Fact] - public static void DoesNotOverrideDefaultTelemetryChannelIfTelemetryChannelServiceIsNotRegistered() - { - var services = CreateServicesAndAddApplicationinsightsTelemetry(null, null); - IServiceProvider serviceProvider = services.BuildServiceProvider(); - var telemetryConfiguration = serviceProvider.GetTelemetryConfiguration(); - Assert.NotNull(telemetryConfiguration.TelemetryChannel); - } - - [Fact] - public static void RegistersTelemetryClientToGetTelemetryConfigurationFromContainerAndNotGlobalInstance() - { - ITelemetry sentTelemetry = null; - var telemetryChannel = new FakeTelemetryChannel { OnSend = telemetry => sentTelemetry = telemetry }; - var services = CreateServicesAndAddApplicationinsightsTelemetry(null, null); - IServiceProvider serviceProvider = services.BuildServiceProvider(); - var configuration = serviceProvider.GetTelemetryConfiguration(); - configuration.InstrumentationKey = Guid.NewGuid().ToString(); - ITelemetryChannel oldChannel = configuration.TelemetryChannel; - try - { - configuration.TelemetryChannel = telemetryChannel; - - var telemetryClient = serviceProvider.GetRequiredService(); - telemetryClient.TrackEvent("myevent"); - - // We want to check that configuration from container was used but configuration is a private field so we check instrumentation key instead. - Assert.Equal(configuration.InstrumentationKey, sentTelemetry.Context.InstrumentationKey); - } - finally - { - configuration.TelemetryChannel = oldChannel; - } - } - - [Fact] - public static void AddApplicationInsightsTelemetryDoesNotThrowOnNullServiceOptions() - { - var services = CreateServicesAndAddApplicationinsightsTelemetry(null, "http://localhost:1234/v2/track/", null, false); - IServiceProvider serviceProvider = services.BuildServiceProvider(); - var telemetryConfiguration = serviceProvider.GetTelemetryConfiguration(); - } - - [Fact] - public static void AppApplicationInsightsTelemetryFromApplicationInsightsServiceOptionsCopiesAllSettings() - { - ServiceCollection services = GetServiceCollectionWithContextAccessor(); - ApplicationInsightsServiceOptions options = new ApplicationInsightsServiceOptions() - { - ApplicationVersion = "test", - DeveloperMode = true, - EnableAuthenticationTrackingJavaScript = false, - EnableDebugLogger = true, - EnableQuickPulseMetricStream = false, - EndpointAddress = "http://test", - EnableHeartbeat = false, - InstrumentationKey = "test", - ConnectionString = "InstrumentationKey=00000000-0000-0000-0000-000000000000" - }; - services.AddApplicationInsightsTelemetry(options); - ApplicationInsightsServiceOptions servicesOptions = null; - services.Configure((ApplicationInsightsServiceOptions o) => - { - servicesOptions = o; - }); - - IServiceProvider serviceProvider = services.BuildServiceProvider(); - TelemetryConfiguration telemetryConfiguration = serviceProvider.GetTelemetryConfiguration(); - - Type optionsType = typeof(ApplicationInsightsServiceOptions); - PropertyInfo[] properties = optionsType.GetProperties(BindingFlags.Public | BindingFlags.Instance); - Assert.True(properties.Length > 0); - foreach (PropertyInfo property in properties) - { - Assert.Equal(property.GetValue(options).ToString(), property.GetValue(servicesOptions).ToString()); - } - } - - - [Fact] - public static void RegistersTelemetryConfigurationFactoryMethodThatPopulatesItWithModulesFromContainer() - { - var services = CreateServicesAndAddApplicationinsightsTelemetry(null, null, null, false); - IServiceProvider serviceProvider = services.BuildServiceProvider(); - var modules = serviceProvider.GetServices(); - Assert.NotNull(modules); - -#if NETCOREAPP - // Developer Note: Expected modules: - // RequestTrackingTelemetryModule, PerformanceCollectorModule, AppServicesHeartbeatTelemetryModule, AzureInstanceMetadataTelemetryModule, - // QuickPulseTelemetryModule, DiagnosticsTelemetryModule, DependencyTrackingTelemetryModule, EventCollectorCollectionModule - Assert.Equal(8, modules.Count()); -#else - Assert.Equal(7, modules.Count()); -#endif - - var perfCounterModule = modules.OfType().Single(); - Assert.NotNull(perfCounterModule); - -#if NETCOREAPP - var eventCounterModule = modules.OfType().Single(); - Assert.NotNull(eventCounterModule); -#endif - - - var dependencyModuleDescriptor = modules.OfType().Single(); - Assert.NotNull(dependencyModuleDescriptor); - - var reqModuleDescriptor = modules.OfType().Single(); - Assert.NotNull(reqModuleDescriptor); - - var appServiceHeartBeatModuleDescriptor = modules.OfType().Single(); - Assert.NotNull(appServiceHeartBeatModuleDescriptor); - - var azureMetadataHeartBeatModuleDescriptor = modules.OfType().Single(); - Assert.NotNull(azureMetadataHeartBeatModuleDescriptor); - - var quickPulseModuleDescriptor = modules.OfType().Single(); - Assert.NotNull(quickPulseModuleDescriptor); - } - -#if NETCOREAPP - [Fact] - public static void RegistersTelemetryConfigurationFactoryMethodThatPopulatesEventCounterCollectorWithDefaultListOfCounters() - { - //ARRANGE - var services = CreateServicesAndAddApplicationinsightsTelemetry(null, null, null, false); - IServiceProvider serviceProvider = services.BuildServiceProvider(); - var modules = serviceProvider.GetServices(); - - //ACT - - // Requesting TelemetryConfiguration from services trigger constructing the TelemetryConfiguration - // which in turn trigger configuration of all modules. - var telemetryConfiguration = serviceProvider.GetTelemetryConfiguration(); - var eventCounterModule = modules.OfType().Single(); - - // VALIDATE - // By default, no counters are collected. - Assert.Equal(0, eventCounterModule.Counters.Count); - } -#endif - - - [Fact] - public static void RegistersTelemetryConfigurationFactoryMethodThatPopulatesDependencyCollectorWithDefaultValues() - { - //ARRANGE - var services = CreateServicesAndAddApplicationinsightsTelemetry(null, null, null, false); - IServiceProvider serviceProvider = services.BuildServiceProvider(); - var modules = serviceProvider.GetServices(); - - //ACT - - // Requesting TelemetryConfiguration from services trigger constructing the TelemetryConfiguration - // which in turn trigger configuration of all modules. - var telemetryConfiguration = serviceProvider.GetTelemetryConfiguration(); - var dependencyModule = modules.OfType().Single(); - - //VALIDATE - Assert.Equal(4, dependencyModule.ExcludeComponentCorrelationHttpHeadersOnDomains.Count); - Assert.False(dependencyModule.ExcludeComponentCorrelationHttpHeadersOnDomains.Contains("localhost")); - Assert.False(dependencyModule.ExcludeComponentCorrelationHttpHeadersOnDomains.Contains("127.0.0.1")); - } - - /// - /// User could enable or disable LegacyCorrelationHeadersInjection of DependencyCollectorOptions. - /// This configuration can be read from a JSON file by the configuration factory or through code by passing ApplicationInsightsServiceOptions. - /// - /// - /// DefaultConfiguration - calls services.AddApplicationInsightsTelemetry() which reads IConfiguration from user application automatically. - /// SuppliedConfiguration - invokes services.AddApplicationInsightsTelemetry(configuration) where IConfiguration object is supplied by caller. - /// Code - Caller creates an instance of ApplicationInsightsServiceOptions and passes it. This option overrides all configuration being used in JSON file. - /// There is a special case where NULL values in these properties - InstrumentationKey, ConnectionString, EndpointAddress and DeveloperMode are overwritten. We check IConfiguration object to see if these properties have values, if values are present then we override it. - /// - /// Sets the value for property EnableLegacyCorrelationHeadersInjection. - [Theory] - [InlineData("DefaultConfiguration", true)] - [InlineData("DefaultConfiguration", false)] - [InlineData("SuppliedConfiguration", true)] - [InlineData("SuppliedConfiguration", false)] - [InlineData("Code", true)] - [InlineData("Code", false)] - public static void RegistersTelemetryConfigurationFactoryMethodThatPopulatesDependencyCollectorWithCustomValues(string configType, bool isEnable) - { - // Test removed - DependencyCollectionOptions.EnableLegacyCorrelationHeadersInjection property no longer exists - // This functionality has been replaced by OpenTelemetry instrumentation options - } - - [Fact] - public static void RegistersTelemetryConfigurationFactoryMethodThatPopulatesItWithTelemetryProcessorFactoriesFromContainer() - { - var services = GetServiceCollectionWithContextAccessor(); - services.AddApplicationInsightsTelemetryProcessor(); - - services.AddApplicationInsightsTelemetry(new ConfigurationBuilder().Build()); - - IServiceProvider serviceProvider = services.BuildServiceProvider(); - var telemetryConfiguration = serviceProvider.GetTelemetryConfiguration(); - // TP added via AddApplicationInsightsTelemetryProcessor is added to the default sink. - FakeTelemetryProcessor telemetryProcessor = telemetryConfiguration.DefaultTelemetrySink.TelemetryProcessors.OfType().FirstOrDefault(); - Assert.NotNull(telemetryProcessor); - Assert.True(telemetryProcessor.IsInitialized); - } - - [Fact] - public static void AddApplicationInsightsTelemetryProcessorWithNullTelemetryProcessorTypeThrows() - { - var services = GetServiceCollectionWithContextAccessor(); - Assert.Throws(() => services.AddApplicationInsightsTelemetryProcessor(null)); - } - - [Fact] - public static void AddApplicationInsightsTelemetryProcessorWithNonTelemetryProcessorTypeThrows() - { - var services = GetServiceCollectionWithContextAccessor(); - Assert.Throws(() => services.AddApplicationInsightsTelemetryProcessor(typeof(string))); - Assert.Throws(() => services.AddApplicationInsightsTelemetryProcessor(typeof(ITelemetryProcessor))); - } - - [Fact] - public static void AddApplicationInsightsTelemetryProcessorWithImportingConstructor() - { - var services = GetServiceCollectionWithContextAccessor(); - services.AddApplicationInsightsTelemetryProcessor(); - services.AddApplicationInsightsTelemetry(new ConfigurationBuilder().Build()); - IServiceProvider serviceProvider = services.BuildServiceProvider(); - var telemetryConfiguration = serviceProvider.GetTelemetryConfiguration(); - - // TP added via AddApplicationInsightsTelemetryProcessor is added to the default sink. - FakeTelemetryProcessorWithImportingConstructor telemetryProcessor = telemetryConfiguration.DefaultTelemetrySink.TelemetryProcessors.OfType().FirstOrDefault(); - Assert.NotNull(telemetryProcessor); - Assert.Same(serviceProvider.GetService(), telemetryProcessor.HostingEnvironment); - } - - [Fact] - public static void ConfigureApplicationInsightsTelemetryModuleWorks() - { - //ARRANGE - var services = GetServiceCollectionWithContextAccessor(); - services.AddSingleton(); - - //ACT - services.ConfigureTelemetryModule - ((module, o) => module.CustomProperty = "mycustomvalue"); - services.AddApplicationInsightsTelemetry(new ConfigurationBuilder().Build()); - IServiceProvider serviceProvider = services.BuildServiceProvider(); - - // Requesting TelemetryConfiguration from services trigger constructing the TelemetryConfiguration - // which in turn trigger configuration of all modules. - var telemetryConfiguration = serviceProvider.GetTelemetryConfiguration(); - - //VALIDATE - var modules = serviceProvider.GetServices(); - var testTelemetryModule = modules.OfType().Single(); - - //The module should be initialized and configured as instructed. - Assert.NotNull(testTelemetryModule); - Assert.Equal("mycustomvalue", testTelemetryModule.CustomProperty); - Assert.True(testTelemetryModule.IsInitialized); - } - - [Fact] - /// - /// We've added the DiagnosticsTelemetryModule to the default TelemetryModules in AspNetCore DI. - /// During setup, we expect this module to be discovered and set on the other Heartbeat TelemetryModules. - /// - public static void VerifyIfHeartbeatPropertyManagerSetOnOtherModules_Default() - { - //ARRANGE - var services = GetServiceCollectionWithContextAccessor(); - - //ACT - services.AddApplicationInsightsTelemetry(new ConfigurationBuilder().Build()); - IServiceProvider serviceProvider = services.BuildServiceProvider(); - var telemetryConfiguration = serviceProvider.GetTelemetryConfiguration(); - - //VALIDATE - var modules = serviceProvider.GetServices(); - var count = modules.OfType().Count(); - Assert.Equal(1, count); - - var appServicesHeartbeatTelemetryModule = modules.OfType().Single(); - var hpm1 = appServicesHeartbeatTelemetryModule.HeartbeatPropertyManager; - Assert.NotNull(hpm1); - - var azureInstanceMetadataTelemetryModule = modules.OfType().Single(); - var hpm2 = azureInstanceMetadataTelemetryModule.HeartbeatPropertyManager; - Assert.NotNull(hpm2); - - Assert.Same(hpm1, hpm2); - } - - [Fact] - /// - /// A user can configure an instance of DiagnosticsTelemetryModule. - /// During setup, we expect this module to be discovered and set on the other Heartbeat TelemetryModules. - /// - public static void VerifyIfHeartbeatPropertyManagerSetOnOtherModules_UserDefinedInstance() - { - //ARRANGE - var services = GetServiceCollectionWithContextAccessor(); - - // VERIFY THAT A USER CAN SPECIFY THEIR OWN INSTANCE - var testValue = TimeSpan.FromDays(9); - var diagnosticsTelemetryModule = new DiagnosticsTelemetryModule { HeartbeatInterval = testValue }; - services.AddSingleton(diagnosticsTelemetryModule); - - //ACT - services.AddApplicationInsightsTelemetry(new ConfigurationBuilder().Build()); - IServiceProvider serviceProvider = services.BuildServiceProvider(); - var telemetryConfiguration = serviceProvider.GetTelemetryConfiguration(); - - //VALIDATE - var modules = serviceProvider.GetServices(); - var count = modules.OfType().Count(); - Assert.Equal(1, count); - - var appServicesHeartbeatTelemetryModule = modules.OfType().Single(); - var hpm1 = appServicesHeartbeatTelemetryModule.HeartbeatPropertyManager; - Assert.NotNull(hpm1); - Assert.Same(diagnosticsTelemetryModule, hpm1); - Assert.Equal(testValue, hpm1.HeartbeatInterval); - - var azureInstanceMetadataTelemetryModule = modules.OfType().Single(); - var hpm2 = azureInstanceMetadataTelemetryModule.HeartbeatPropertyManager; - Assert.NotNull(hpm2); - Assert.Same(diagnosticsTelemetryModule, hpm2); - Assert.Equal(testValue, hpm2.HeartbeatInterval); - } - - - [Fact] - /// - /// A user can configure an instance of DiagnosticsTelemetryModule. - /// During setup, we expect this module to be discovered and set on the other Heartbeat TelemetryModules. - /// - public static void VerifyIfHeartbeatPropertyManagerSetOnOtherModules_UserDefinedType() - { - //ARRANGE - var services = GetServiceCollectionWithContextAccessor(); - - // VERIFY THAT A USER CAN SPECIFY THEIR OWN TYPE - services.AddSingleton(); - - //act - services.AddApplicationInsightsTelemetry(new ConfigurationBuilder().Build()); - IServiceProvider serviceProvider = services.BuildServiceProvider(); - var telemetryConfiguration = serviceProvider.GetTelemetryConfiguration(); - - //VALIDATE - var modules = serviceProvider.GetServices(); - var count = modules.OfType().Count(); - Assert.Equal(1, count); - - var appServicesHeartbeatTelemetryModule = modules.OfType().Single(); - var hpm1 = appServicesHeartbeatTelemetryModule.HeartbeatPropertyManager; - Assert.NotNull(hpm1); - - var azureInstanceMetadataTelemetryModule = modules.OfType().Single(); - var hpm2 = azureInstanceMetadataTelemetryModule.HeartbeatPropertyManager; - Assert.NotNull(hpm2); - - Assert.Same(hpm1, hpm2); - } - - [Theory] - [InlineData(false, false)] - [InlineData(true, false)] - [InlineData(false, true)] - /// - /// Previously we encouraged users to add the DiagnosticsTelemetryModule manually. - /// Users could have added this either as an INSTANCE or as a TYPE. - /// We don't want to add it a second time so need to confirm that we catch both cases. - /// - public static void TestingAddDiagnosticsTelemetryModule(bool manualAddInstance, bool manualAddType) - { - //ARRANGE - var services = GetServiceCollectionWithContextAccessor(); - - if (manualAddInstance) - { - services.AddSingleton(new DiagnosticsTelemetryModule()); - } - else if (manualAddType) - { - services.AddSingleton(); - } - - //ACT - services.AddApplicationInsightsTelemetry(new ConfigurationBuilder().Build()); - IServiceProvider serviceProvider = services.BuildServiceProvider(); - - //VALIDATE - var modules = serviceProvider.GetServices(); - var count = modules.OfType().Count(); - - Assert.Equal(1, count); - } - - - [Fact] - public static void ConfigureApplicationInsightsTelemetryModuleWorksWithOptions() - { - //ARRANGE - Action serviceOptions = options => options.ApplicationVersion = "123"; - var services = GetServiceCollectionWithContextAccessor(); - services.AddSingleton(); - - //ACT - services.ConfigureTelemetryModule - ((module, o) => module.CustomProperty = o.ApplicationVersion); - services.AddApplicationInsightsTelemetry(serviceOptions); - IServiceProvider serviceProvider = services.BuildServiceProvider(); - - // Requesting TelemetryConfiguration from services trigger constructing the TelemetryConfiguration - // which in turn trigger configuration of all modules. - var telemetryConfiguration = serviceProvider.GetTelemetryConfiguration(); - - //VALIDATE - var modules = serviceProvider.GetServices(); - var testTelemetryModule = modules.OfType().Single(); - - //The module should be initialized and configured as instructed. - Assert.NotNull(testTelemetryModule); - Assert.Equal("123", testTelemetryModule.CustomProperty); - Assert.True(testTelemetryModule.IsInitialized); - } - - [Fact] - public static void ConfigureApplicationInsightsTelemetryModuleWorksWithoutOptions() - { - //ARRANGE - var services = GetServiceCollectionWithContextAccessor(); - services.AddSingleton(); - - //ACT - services.ConfigureTelemetryModule - ((module, o) => module.CustomProperty = "mycustomproperty"); - - services.AddApplicationInsightsTelemetry(); - IServiceProvider serviceProvider = services.BuildServiceProvider(); - - // Requesting TelemetryConfiguration from services trigger constructing the TelemetryConfiguration - // which in turn trigger configuration of all modules. - var telemetryConfiguration = serviceProvider.GetTelemetryConfiguration(); - - //VALIDATE - var modules = serviceProvider.GetServices(); - var testTelemetryModule = modules.OfType().Single(); - - //The module should be initialized and configured as instructed. - Assert.NotNull(testTelemetryModule); - Assert.Equal("mycustomproperty", testTelemetryModule.CustomProperty); - Assert.True(testTelemetryModule.IsInitialized); - } - - [Fact] - public static void ConfigureRequestTrackingTelemetryDefaultOptions() - { - //ARRANGE - var services = GetServiceCollectionWithContextAccessor(); - - //ACT - services.AddApplicationInsightsTelemetry(); - IServiceProvider serviceProvider = services.BuildServiceProvider(); - var telemetryConfiguration = serviceProvider.GetTelemetryConfiguration(); - - //VALIDATE - var requestTrackingModule = (RequestTrackingTelemetryModule)serviceProvider.GetServices().FirstOrDefault(x => x.GetType() - == typeof(RequestTrackingTelemetryModule)); - - Assert.True(requestTrackingModule.CollectionOptions.InjectResponseHeaders); - Assert.False(requestTrackingModule.CollectionOptions.TrackExceptions); - } - - [Fact] - public static void ConfigureApplicationInsightsTelemetryModuleThrowsIfConfigureIsNull() - { - //ARRANGE - var services = GetServiceCollectionWithContextAccessor(); - services.AddSingleton(); - - //ACT and VALIDATE - Assert.Throws(() => services.ConfigureTelemetryModule((Action)null)); - -#pragma warning disable CS0618 // Type or member is obsolete - Assert.Throws(() => services.ConfigureTelemetryModule((Action)null)); -#pragma warning restore CS0618 // Type or member is obsolete - } - - [Fact] - public static void ConfigureApplicationInsightsTelemetryModuleDoesNotThrowIfModuleNotFound() - { - //ARRANGE - var services = GetServiceCollectionWithContextAccessor(); - // Intentionally NOT adding the module - // services.AddSingleton(); - - //ACT - services.ConfigureTelemetryModule - ((module, options) => module.CustomProperty = "mycustomvalue"); - services.AddApplicationInsightsTelemetry(new ConfigurationBuilder().Build()); - IServiceProvider serviceProvider = services.BuildServiceProvider(); - - // Requesting TelemetryConfiguration from services trigger constructing the TelemetryConfiguration - // which in turn trigger configuration of all modules. - var telemetryConfiguration = serviceProvider.GetTelemetryConfiguration(); - - //VALIDATE - var modules = serviceProvider.GetServices(); - var testTelemetryModule = modules.OfType().FirstOrDefault(); - - // No exceptions thrown here. - Assert.Null(testTelemetryModule); - } - - [Fact] - public static void AddsServerTelemetryChannelByDefault() - { - var services = CreateServicesAndAddApplicationinsightsTelemetry(null, "http://localhost:1234/v2/track/", null, false); - IServiceProvider serviceProvider = services.BuildServiceProvider(); - var telemetryConfiguration = serviceProvider.GetTelemetryConfiguration(); - Assert.Equal(typeof(ServerTelemetryChannel), telemetryConfiguration.TelemetryChannel.GetType()); - } - - [Fact] - [Trait("Trait", "ConnectionString")] - public static void AddApplicationInsightsSettings_SetsConnectionString() - { - var services = GetServiceCollectionWithContextAccessor(); - services.AddSingleton(new InMemoryChannel()); - var config = new ConfigurationBuilder().AddApplicationInsightsSettings(connectionString: TestConnectionString).Build(); - services.AddApplicationInsightsTelemetry(config); - - IServiceProvider serviceProvider = services.BuildServiceProvider(); - var telemetryConfiguration = serviceProvider.GetTelemetryConfiguration(); - Assert.Equal(TestConnectionString, telemetryConfiguration.ConnectionString); - Assert.Equal(TestInstrumentationKey, telemetryConfiguration.InstrumentationKey); - Assert.Equal("http://127.0.0.1/", telemetryConfiguration.EndpointContainer.Ingestion.AbsoluteUri); - } - - [Fact] - [Trait("Trait", "Endpoints")] - public static void DoesNotOverWriteExistingChannel() - { - var testEndpoint = "http://localhost:1234/v2/track/"; - - var services = GetServiceCollectionWithContextAccessor(); - services.AddSingleton(); - var config = new ConfigurationBuilder().AddApplicationInsightsSettings(endpointAddress: testEndpoint).Build(); - services.AddApplicationInsightsTelemetry(config); - - IServiceProvider serviceProvider = services.BuildServiceProvider(); - var telemetryConfiguration = serviceProvider.GetTelemetryConfiguration(); - Assert.Equal(typeof(InMemoryChannel), telemetryConfiguration.TelemetryChannel.GetType()); - Assert.Equal(testEndpoint, telemetryConfiguration.TelemetryChannel.EndpointAddress); - } - - [Fact] - public static void FallbacktoDefaultChannelWhenNoChannelFoundInDI() - { - var testEndpoint = "http://localhost:1234/v2/track/"; - - // ARRANGE - var services = GetServiceCollectionWithContextAccessor(); - var config = new ConfigurationBuilder().AddApplicationInsightsSettings(endpointAddress: testEndpoint).Build(); - services.AddApplicationInsightsTelemetry(config); - - // Remove all ITelemetryChannel to simulate scenario where customer remove all channel from DI but forgot to add new one. - // This should not crash application startup, and should fall back to default channel supplied by base sdk. - for (var i = services.Count - 1; i >= 0; i--) - { - var descriptor = services[i]; - if (descriptor.ServiceType == typeof(ITelemetryChannel)) - { - services.RemoveAt(i); - } - } - - // VERIFY that default channel is configured when nothing is present in DI - IServiceProvider serviceProvider = services.BuildServiceProvider(); - var telemetryConfiguration = serviceProvider.GetTelemetryConfiguration(); - Assert.Equal(typeof(InMemoryChannel), telemetryConfiguration.TelemetryChannel.GetType()); - Assert.Equal(testEndpoint, telemetryConfiguration.TelemetryChannel.EndpointAddress); - } - - [Fact] - public static void VerifyNoExceptionWhenAppIdProviderNotFoundInDI() - { - // ARRANGE - var services = GetServiceCollectionWithContextAccessor(); - var config = new ConfigurationBuilder().AddApplicationInsightsSettings(endpointAddress: "http://localhost:1234/v2/track/").Build(); - services.AddApplicationInsightsTelemetry(config); - - for (var i = services.Count - 1; i >= 0; i--) - { - var descriptor = services[i]; - if (descriptor.ServiceType == typeof(IApplicationIdProvider)) - { - services.RemoveAt(i); - } - } - - // ACT - IServiceProvider serviceProvider = services.BuildServiceProvider(); - - - // VERIFY - var requestTrackingModule = serviceProvider.GetServices().FirstOrDefault(x => x.GetType() - == typeof(RequestTrackingTelemetryModule)); - - Assert.NotNull(requestTrackingModule); // this verifies the instance was created without exception - } - - [Fact] - public static void VerifyUserCanOverrideAppIdProvider() - { - var services = GetServiceCollectionWithContextAccessor(); - services.AddSingleton(); // assume user tries to define own implementation - var config = new ConfigurationBuilder().AddApplicationInsightsSettings(endpointAddress: "http://localhost:1234/v2/track/").Build(); - services.AddApplicationInsightsTelemetry(config); - - IServiceProvider serviceProvider = services.BuildServiceProvider(); - var applicationIdProvider = serviceProvider.GetRequiredService(); - - Assert.Equal(typeof(MockApplicationIdProvider), applicationIdProvider.GetType()); - } - - - [Fact] - public static void ValidatesThatOnlyPassThroughProcessorIsAddedToCommonPipeline() - { - var services = CreateServicesAndAddApplicationinsightsTelemetry(null, "http://localhost:1234/v2/track/", null, false); - services.AddSingleton(); - IServiceProvider serviceProvider = services.BuildServiceProvider(); - var telemetryConfiguration = serviceProvider.GetTelemetryConfiguration(); - - // All default TelemetryProcessors are expected to be on the default sink. There should be - // none on the main pipeline except the PassThrough. - - var qpProcessorCount = GetTelemetryProcessorsCountInConfiguration(telemetryConfiguration); - Assert.Equal(0, qpProcessorCount); - - var metricExtractorProcessorCount = GetTelemetryProcessorsCountInConfiguration(telemetryConfiguration); - Assert.Equal(0, metricExtractorProcessorCount); - - var passThroughProcessorCount = telemetryConfiguration.TelemetryProcessors.Count; - Assert.Equal(1, passThroughProcessorCount); - - Assert.Equal("PassThroughProcessor", telemetryConfiguration.TelemetryProcessors[0].GetType().Name); - } - - [Fact] - public static void AddsQuickPulseProcessorToTheConfigurationByDefault() - { - var services = CreateServicesAndAddApplicationinsightsTelemetry(null, "http://localhost:1234/v2/track/", null, false); - services.AddSingleton(); - IServiceProvider serviceProvider = services.BuildServiceProvider(); - var telemetryConfiguration = serviceProvider.GetTelemetryConfiguration(); - var qpProcessorCount = GetTelemetryProcessorsCountInConfigurationDefaultSink(telemetryConfiguration); - Assert.Equal(1, qpProcessorCount); - } - - [Fact] - public static void AddsAutoCollectedMetricsExtractorProcessorToTheConfigurationByDefault() - { - var services = CreateServicesAndAddApplicationinsightsTelemetry(null, "http://localhost:1234/v2/track/", null, false); - services.AddSingleton(); - IServiceProvider serviceProvider = services.BuildServiceProvider(); - var telemetryConfiguration = serviceProvider.GetTelemetryConfiguration(); - var metricExtractorProcessorCount = GetTelemetryProcessorsCountInConfigurationDefaultSink(telemetryConfiguration); - Assert.Equal(1, metricExtractorProcessorCount); - } - - /// - /// User could enable or disable auto collected metrics by setting AddAutoCollectedMetricExtractor. - /// This configuration can be read from a JSON file by the configuration factory or through code by passing ApplicationInsightsServiceOptions. - /// - /// - /// DefaultConfiguration - calls services.AddApplicationInsightsTelemetry() which reads IConfiguration from user application automatically. - /// SuppliedConfiguration - invokes services.AddApplicationInsightsTelemetry(configuration) where IConfiguration object is supplied by caller. - /// Code - Caller creates an instance of ApplicationInsightsServiceOptions and passes it. This option overrides all configuration being used in JSON file. - /// There is a special case where NULL values in these properties - InstrumentationKey, ConnectionString, EndpointAddress and DeveloperMode are overwritten. We check IConfiguration object to see if these properties have values, if values are present then we override it. - /// - /// Sets the value for property AddAutoCollectedMetricExtractor. - [Theory] - [InlineData("DefaultConfiguration", true)] - [InlineData("DefaultConfiguration", false)] - [InlineData("SuppliedConfiguration", true)] - [InlineData("SuppliedConfiguration", false)] - [InlineData("Code", true)] - [InlineData("Code", false)] - public static void DoesNotAddAutoCollectedMetricsExtractorToConfigurationIfExplicitlyControlledThroughParameter(string configType, bool isEnable) - { - // ARRANGE - Action serviceOptions = null; - var filePath = Path.Combine("content", "config-all-settings-" + isEnable.ToString().ToLower() + ".json"); - - if (configType == "Code") - { - serviceOptions = o => { o.AddAutoCollectedMetricExtractor = isEnable; }; - filePath = null; - } - - // ACT - var services = CreateServicesAndAddApplicationinsightsTelemetry(filePath, null, serviceOptions, true, configType == "DefaultConfiguration" ? true : false); - - // VALIDATE - IServiceProvider serviceProvider = services.BuildServiceProvider(); - var telemetryConfiguration = serviceProvider.GetTelemetryConfiguration(); - var metricExtractorProcessorCount = GetTelemetryProcessorsCountInConfigurationDefaultSink(telemetryConfiguration); - Assert.Equal(isEnable ? 1 : 0, metricExtractorProcessorCount); - } - - [Fact] - public static void DoesNotAddQuickPulseProcessorToConfigurationIfExplicitlyControlledThroughParameter() - { - Action serviceOptions = options => options.EnableQuickPulseMetricStream = false; - var services = CreateServicesAndAddApplicationinsightsTelemetry(null, "http://localhost:1234/v2/track/", serviceOptions, false); - IServiceProvider serviceProvider = services.BuildServiceProvider(); - var telemetryConfiguration = serviceProvider.GetTelemetryConfiguration(); - var qpProcessorCount = GetTelemetryProcessorsCountInConfigurationDefaultSink(telemetryConfiguration); - Assert.Equal(0, qpProcessorCount); - } - - /// - /// User could enable or disable AuthenticationTrackingJavaScript by setting EnableAuthenticationTrackingJavaScript. - /// This configuration can be read from a JSON file by the configuration factory or through code by passing ApplicationInsightsServiceOptions. - /// - /// - /// DefaultConfiguration - calls services.AddApplicationInsightsTelemetry() which reads IConfiguration from user application automatically. - /// SuppliedConfiguration - invokes services.AddApplicationInsightsTelemetry(configuration) where IConfiguration object is supplied by caller. - /// Code - Caller creates an instance of ApplicationInsightsServiceOptions and passes it. This option overrides all configuration being used in JSON file. - /// There is a special case where NULL values in these properties - InstrumentationKey, ConnectionString, EndpointAddress and DeveloperMode are overwritten. We check IConfiguration object to see if these properties have values, if values are present then we override it. - /// - /// Sets the value for property EnableAuthenticationTrackingJavaScript. - [Theory] - [InlineData("DefaultConfiguration", true)] - [InlineData("DefaultConfiguration", false)] - [InlineData("SuppliedConfiguration", true)] - [InlineData("SuppliedConfiguration", false)] - [InlineData("Code", true)] - [InlineData("Code", false)] - public static void UserCanEnableAndDisableAuthenticationTrackingJavaScript(string configType, bool isEnable) - { - // ARRANGE - Action serviceOptions = null; - var filePath = Path.Combine("content", "config-all-settings-" + isEnable.ToString().ToLower() + ".json"); - - if (configType == "Code") - { - serviceOptions = o => { o.EnableAuthenticationTrackingJavaScript = isEnable; }; - filePath = null; - } - - // ACT - var services = CreateServicesAndAddApplicationinsightsTelemetry(filePath, null, serviceOptions, true, configType == "DefaultConfiguration" ? true : false); - IServiceProvider serviceProvider = services.BuildServiceProvider(); - - // VALIDATE - // Get telemetry client to trigger TelemetryConfig setup. - var tc = serviceProvider.GetService(); - - Type javaScriptSnippetType = typeof(JavaScriptSnippet); - var javaScriptSnippet = serviceProvider.GetService(); - // Get the JavaScriptSnippet private field value for enableAuthSnippet. - FieldInfo enableAuthSnippetField = javaScriptSnippetType.GetField("enableAuthSnippet", BindingFlags.NonPublic | BindingFlags.Instance); - // JavaScriptSnippet.enableAuthSnippet is set to true when EnableAuthenticationTrackingJavaScript is enabled, else it is set to false. - Assert.Equal(isEnable, (bool)enableAuthSnippetField.GetValue(javaScriptSnippet)); - } - - [Fact] - public static void AddsQuickPulseProcessorToTheConfigurationWithServiceOptions() - { - Action serviceOptions = options => options.EnableQuickPulseMetricStream = true; - var services = CreateServicesAndAddApplicationinsightsTelemetry(null, "http://localhost:1234/v2/track/", serviceOptions, false); - IServiceProvider serviceProvider = services.BuildServiceProvider(); - var telemetryConfiguration = serviceProvider.GetTelemetryConfiguration(); - var qpProcessorCount = GetTelemetryProcessorsCountInConfigurationDefaultSink(telemetryConfiguration); - Assert.Equal(1, qpProcessorCount); - } - - [Fact] - public static void AddsHeartbeatModulesToTheConfigurationByDefault() - { - var services = CreateServicesAndAddApplicationinsightsTelemetry(null, "http://localhost:1234/v2/track/", null, false); - IServiceProvider serviceProvider = services.BuildServiceProvider(); - var telemetryConfiguration = serviceProvider.GetTelemetryConfiguration(); - var modules = serviceProvider.GetServices(); - Assert.NotNull(modules.OfType().Single()); - Assert.NotNull(modules.OfType().Single()); - } - - [Fact] - public static void W3CIsEnabledByDefault() - { - var services = CreateServicesAndAddApplicationinsightsTelemetry(null, "http://localhost:1234/v2/track/"); - IServiceProvider serviceProvider = services.BuildServiceProvider(); - var telemetryConfiguration = serviceProvider.GetTelemetryConfiguration(); - -#pragma warning disable CS0618 // Type or member is obsolete - Assert.DoesNotContain(telemetryConfiguration.TelemetryInitializers, t => t is W3COperationCorrelationTelemetryInitializer); -#pragma warning restore CS0618 // Type or member is obsolete - - var modules = serviceProvider.GetServices().ToList(); - - var requestTracking = modules.OfType().ToList(); - var dependencyTracking = modules.OfType().ToList(); - Assert.Single(requestTracking); - Assert.Single(dependencyTracking); - - Assert.True(Activity.DefaultIdFormat == ActivityIdFormat.W3C); - Assert.True(Activity.ForceDefaultIdFormat); - } - - private static int GetTelemetryProcessorsCountInConfiguration(TelemetryConfiguration telemetryConfiguration) - { - return telemetryConfiguration.TelemetryProcessors.Where(processor => processor.GetType() == typeof(T)).Count(); - } - - private static int GetTelemetryProcessorsCountInConfigurationDefaultSink(TelemetryConfiguration telemetryConfiguration) - { - return telemetryConfiguration.DefaultTelemetrySink.TelemetryProcessors.Where(processor => processor.GetType() == typeof(T)).Count(); - } - - [Fact] - public static void LoggerCallbackIsInvoked() - { - var services = new ServiceCollection(); - services.AddSingleton(); - var serviceProvider = services.BuildServiceProvider(); - - var loggerProvider = new MockLoggingFactory(); - - bool firstLoggerCallback = false; - bool secondLoggerCallback = false; - -#pragma warning disable CS0618 // Type or member is obsolete - loggerProvider.AddApplicationInsights(serviceProvider, (s, level) => true, () => firstLoggerCallback = true); - loggerProvider.AddApplicationInsights(serviceProvider, (s, level) => true, () => secondLoggerCallback = true); -#pragma warning restore CS0618 // Type or member is obsolete - - Assert.True(firstLoggerCallback); - Assert.False(secondLoggerCallback); - } - - [Fact] - public static void NullLoggerCallbackAlowed() - { - var services = new ServiceCollection(); - services.AddSingleton(); - var serviceProvider = services.BuildServiceProvider(); - - var loggerProvider = new MockLoggingFactory(); - -#pragma warning disable CS0618 // Type or member is obsolete - loggerProvider.AddApplicationInsights(serviceProvider, (s, level) => true, null); - loggerProvider.AddApplicationInsights(serviceProvider, (s, level) => true, null); -#pragma warning restore CS0618 // Type or member is obsolete - } - - /// - /// Creates two copies of ApplicationInsightsServiceOptions. First object is created by calling services.AddApplicationInsightsTelemetry() or services.AddApplicationInsightsTelemetry(config). - /// Second object is created directly from configuration file without using any of SDK functionality. - /// Compares ApplicationInsightsServiceOptions object from dependency container and one created directly from configuration. - /// This proves all that SDK read configuration successfully from configuration file. - /// Properties from appSettings.json, appsettings.{env.EnvironmentName}.json and Environmental Variables are read if no IConfiguration is supplied or used in an application. - /// - /// If this is set, read value from appsettings.json, else from passed file. - /// - /// Calls services.AddApplicationInsightsTelemetry() when the value is true and reads IConfiguration from user application automatically. - /// Else, it invokes services.AddApplicationInsightsTelemetry(configuration) where IConfiguration object is supplied by caller. - /// - [Theory] - [InlineData(true, true)] - [InlineData(true, false)] - [InlineData(false, true)] - [InlineData(false, false)] - public static void ReadsSettingsFromDefaultAndSuppliedConfiguration(bool readFromAppSettings, bool useDefaultConfig) - { - // ARRANGE - IConfigurationBuilder configBuilder = null; - var fileName = "config-all-default.json"; - - // ACT - var services = CreateServicesAndAddApplicationinsightsTelemetry( - readFromAppSettings ? null : Path.Combine("content", fileName), - null, null, true, useDefaultConfig); - - // VALIDATE - - // Generate config and don't pass to services - // this is directly generated from config file - // which could be used to validate the data from dependency container - - if (!readFromAppSettings) - { - configBuilder = new ConfigurationBuilder() - .SetBasePath(Directory.GetCurrentDirectory()) - .AddJsonFile(Path.Combine("content", fileName)); - if (useDefaultConfig) - { - configBuilder.AddJsonFile("appsettings.json", false); - } - } - else - { - configBuilder = new ConfigurationBuilder() - .SetBasePath(Directory.GetCurrentDirectory()) - .AddJsonFile("appsettings.json", false); - } - - var config = configBuilder.Build(); - - // Compare ApplicationInsightsServiceOptions from dependency container and configuration - IServiceProvider serviceProvider = services.BuildServiceProvider(); - // ApplicationInsightsServiceOptions from dependency container - var servicesOptions = serviceProvider.GetRequiredService>().Value; - - // Create ApplicationInsightsServiceOptions from configuration for validation. - var aiOptions = new ApplicationInsightsServiceOptions(); - config.GetSection("ApplicationInsights").Bind(aiOptions); - config.GetSection("ApplicationInsights:TelemetryChannel").Bind(aiOptions); - - Type optionsType = typeof(ApplicationInsightsServiceOptions); - PropertyInfo[] properties = optionsType.GetProperties(BindingFlags.Public | BindingFlags.Instance); - Assert.True(properties.Length > 0); - foreach (PropertyInfo property in properties) - { - Assert.Equal(property.GetValue(aiOptions)?.ToString(), property.GetValue(servicesOptions)?.ToString()); - } - } - - [Fact] - public static void ReadsSettingsFromDefaultConfigurationWithEnvOverridingConfig() - { - // Host.CreateDefaultBuilder() in .NET Core 3.0 adds appsetting.json and env variable - // to configuration and is made available for constructor injection. - // this test validates that SDK reads settings from this configuration by default - // and gives priority to the ENV variables than the one from config. - - // ARRANGE - Environment.SetEnvironmentVariable(InstrumentationKeyEnvironmentVariable, TestInstrumentationKey); - Environment.SetEnvironmentVariable(ConnectionStringEnvironmentVariable, TestConnectionString); - Environment.SetEnvironmentVariable(TestEndPointEnvironmentVariable, TestEndPoint); - Environment.SetEnvironmentVariable(DeveloperModeEnvironmentVariable, "true"); - - try - { - var jsonFullPath = Path.Combine(Directory.GetCurrentDirectory(), "content", "config-all-default.json"); - - // This config will have ikey,endpoint from json and env. ENV one is expected to win. - var config = new ConfigurationBuilder().AddJsonFile(jsonFullPath).AddEnvironmentVariables().Build(); - var services = GetServiceCollectionWithContextAccessor(); - - // This line mimics the default behavior by CreateDefaultBuilder - services.AddSingleton(config); - - // ACT - services.AddApplicationInsightsTelemetry(); - - // VALIDATE - IServiceProvider serviceProvider = services.BuildServiceProvider(); - var telemetryConfiguration = serviceProvider.GetRequiredService(); - Assert.Equal(TestInstrumentationKey, telemetryConfiguration.InstrumentationKey); - Assert.Equal(TestConnectionString, telemetryConfiguration.ConnectionString); - Assert.Equal(TestEndPoint, telemetryConfiguration.TelemetryChannel.EndpointAddress); - Assert.True(telemetryConfiguration.TelemetryChannel.DeveloperMode); - } - finally - { - Environment.SetEnvironmentVariable("APPINSIGHTS_INSTRUMENTATIONKEY", null); - Environment.SetEnvironmentVariable("APPLICATIONINSIGHTS_CONNECTION_STRING", null); - Environment.SetEnvironmentVariable("APPINSIGHTS_ENDPOINTADDRESS", null); - Environment.SetEnvironmentVariable("APPINSIGHTS_DEVELOPER_MODE", null); - } - } - - [Fact] - public static void VerifiesIkeyProvidedInAddApplicationInsightsAlwaysWinsOverOtherOptions() - { - // ARRANGE - Environment.SetEnvironmentVariable("APPINSIGHTS_INSTRUMENTATIONKEY", TestInstrumentationKey); - try - { - var jsonFullPath = Path.Combine(Directory.GetCurrentDirectory(), "content", "config-instrumentation-key.json"); - - // This config will have ikey,endpoint from json and env. But the one - // user explicitly provider is expected to win. - var config = new ConfigurationBuilder().AddJsonFile(jsonFullPath).AddEnvironmentVariables().Build(); - var services = GetServiceCollectionWithContextAccessor(); - - // This line mimics the default behavior by CreateDefaultBuilder - services.AddSingleton(config); - - // ACT - services.AddApplicationInsightsTelemetry("userkey"); - - // VALIDATE - IServiceProvider serviceProvider = services.BuildServiceProvider(); - var telemetryConfiguration = serviceProvider.GetRequiredService(); - Assert.Equal("userkey", telemetryConfiguration.InstrumentationKey); - } - finally - { - Environment.SetEnvironmentVariable("APPINSIGHTS_INSTRUMENTATIONKEY", null); - } - } - - [Fact] - public static void VerifiesIkeyProvidedInAppSettingsWinsOverOtherConfigurationOptions() - { - // ARRANGE - var filePath = Path.Combine(Directory.GetCurrentDirectory(), "content", "config-instrumentation-key.json"); - - // ACT - // Calls services.AddApplicationInsightsTelemetry(), which by default reads from appSettings.json - var services = CreateServicesAndAddApplicationinsightsTelemetry(filePath, null, null, true, true); - - // VALIDATE - IServiceProvider serviceProvider = services.BuildServiceProvider(); - var telemetryConfiguration = serviceProvider.GetRequiredService(); - Assert.Equal(InstrumentationKeyInAppSettings, telemetryConfiguration.InstrumentationKey); - } - - [Fact] - public static void ReadsFromAppSettingsIfNoSettingsFoundInDefaultConfiguration() - { - // Host.CreateDefaultBuilder() in .NET Core 3.0 adds appsetting.json and env variable - // to configuration and is made available for constructor injection. - // This test validates that SDK does not throw any error if it cannot find - // application insights configuration in default IConfiguration. - // ARRANGE - var jsonFullPath = Path.Combine(Directory.GetCurrentDirectory(), "content", "sample-appsettings_dontexist.json"); - var config = new ConfigurationBuilder().AddJsonFile(jsonFullPath, true).Build(); - var services = GetServiceCollectionWithContextAccessor(); - // This line mimics the default behavior by CreateDefaultBuilder - services.AddSingleton(config); - - // ACT - services.AddApplicationInsightsTelemetry(); - - // VALIDATE - IServiceProvider serviceProvider = services.BuildServiceProvider(); - var telemetryConfiguration = serviceProvider.GetRequiredService(); - // Create a configuration from appSettings.json for validation. - var appSettingsConfig = new ConfigurationBuilder() - .SetBasePath(Directory.GetCurrentDirectory()) - .AddJsonFile("appsettings.json", false).Build(); - - Assert.Equal(appSettingsConfig["ApplicationInsights:InstrumentationKey"], telemetryConfiguration.InstrumentationKey); - } - - private sealed class TestService : ITestService - { - } - - private interface ITestService - { - } - } -} diff --git a/NETCORE/test/Microsoft.ApplicationInsights.AspNetCore.Tests/Extensions/ApplicationInsightsExtensionsTests/BaseTestClass.cs b/NETCORE/test/Microsoft.ApplicationInsights.AspNetCore.Tests/Extensions/ApplicationInsightsExtensionsTests/BaseTestClass.cs deleted file mode 100644 index cbcf156f88..0000000000 --- a/NETCORE/test/Microsoft.ApplicationInsights.AspNetCore.Tests/Extensions/ApplicationInsightsExtensionsTests/BaseTestClass.cs +++ /dev/null @@ -1,89 +0,0 @@ - -using Xunit; - -[assembly: CollectionBehavior(DisableTestParallelization = true)] // this is an XUnit api setting -namespace Microsoft.Extensions.DependencyInjection.Test -{ - using System; - using System.Diagnostics; - using System.IO; - - using Microsoft.ApplicationInsights.AspNetCore.Extensions; - using Microsoft.ApplicationInsights.AspNetCore.Tests; - using Microsoft.ApplicationInsights.Channel; - using Microsoft.AspNetCore.Hosting; - using Microsoft.AspNetCore.Hosting.Internal; - using Microsoft.Extensions.Configuration; - - public abstract class BaseTestClass - { - internal const string TestInstrumentationKey = "11111111-2222-3333-4444-555555555555"; - internal const string TestConnectionString = "InstrumentationKey=11111111-2222-3333-4444-555555555555;IngestionEndpoint=http://127.0.0.1"; - internal const string InstrumentationKeyInAppSettings = "33333333-2222-3333-4444-555555555555"; - internal const string InstrumentationKeyFromConfig = "ApplicationInsights:InstrumentationKey"; - internal const string InstrumentationKeyEnvironmentVariable = "APPINSIGHTS_INSTRUMENTATIONKEY"; - internal const string ConnectionStringEnvironmentVariable = "APPLICATIONINSIGHTS_CONNECTION_STRING"; - internal const string TestEndPointEnvironmentVariable = "APPINSIGHTS_ENDPOINTADDRESS"; - internal const string DeveloperModeEnvironmentVariable = "APPINSIGHTS_DEVELOPER_MODE"; - internal const string TestEndPoint = "http://127.0.0.1/v2/track"; - - public static ServiceCollection CreateServicesAndAddApplicationinsightsTelemetry(string jsonPath, string channelEndPointAddress, Action serviceOptions = null, bool addChannel = true, bool useDefaultConfig = true) - { - var services = GetServiceCollectionWithContextAccessor(); - if (addChannel) - { - services.AddSingleton(new InMemoryChannel()); - } - - IConfigurationRoot config = null; - - if (jsonPath != null) - { - var jsonFullPath = Path.Combine(Directory.GetCurrentDirectory(), jsonPath); - Console.WriteLine("json:" + jsonFullPath); - Trace.WriteLine("json:" + jsonFullPath); - try - { - config = new ConfigurationBuilder().SetBasePath(Directory.GetCurrentDirectory()).AddJsonFile(jsonFullPath).Build(); - } - catch (Exception) - { - throw new Exception("Unable to build with json:" + jsonFullPath); - } - } - else if (channelEndPointAddress != null) - { - config = new ConfigurationBuilder().AddApplicationInsightsSettings(endpointAddress: channelEndPointAddress).Build(); - } - else - { - config = new ConfigurationBuilder().Build(); - } - - - if (useDefaultConfig) - { - services.AddSingleton(config); - services.AddApplicationInsightsTelemetry(); - } - else - { - services.AddApplicationInsightsTelemetry(config); - } - - if (serviceOptions != null) - { - services.Configure(serviceOptions); - } - return services; - } - - public static ServiceCollection GetServiceCollectionWithContextAccessor() - { - var services = new ServiceCollection(); - services.AddSingleton(EnvironmentHelper.GetIHostingEnvironment()); - services.AddSingleton(new DiagnosticListener("TestListener")); - return services; - } - } -} diff --git a/NETCORE/test/Microsoft.ApplicationInsights.AspNetCore.Tests/Extensions/ApplicationInsightsExtensionsTests/IServiceProviderExtensions.cs b/NETCORE/test/Microsoft.ApplicationInsights.AspNetCore.Tests/Extensions/ApplicationInsightsExtensionsTests/IServiceProviderExtensions.cs deleted file mode 100644 index 3e4f9bd9dc..0000000000 --- a/NETCORE/test/Microsoft.ApplicationInsights.AspNetCore.Tests/Extensions/ApplicationInsightsExtensionsTests/IServiceProviderExtensions.cs +++ /dev/null @@ -1,16 +0,0 @@ -namespace Microsoft.Extensions.DependencyInjection.Test -{ - using System; - - using Microsoft.ApplicationInsights.Extensibility; - - using Microsoft.Extensions.Options; - - internal static class IServiceProviderExtensions - { - public static TelemetryConfiguration GetTelemetryConfiguration(this IServiceProvider serviceProvider) - { - return serviceProvider.GetRequiredService>().Value; - } - } -} \ No newline at end of file diff --git a/NETCORE/test/Microsoft.ApplicationInsights.AspNetCore.Tests/Extensions/ApplicationInsightsExtensionsTests/MockLoggingFactory.cs b/NETCORE/test/Microsoft.ApplicationInsights.AspNetCore.Tests/Extensions/ApplicationInsightsExtensionsTests/MockLoggingFactory.cs deleted file mode 100644 index b5b5486557..0000000000 --- a/NETCORE/test/Microsoft.ApplicationInsights.AspNetCore.Tests/Extensions/ApplicationInsightsExtensionsTests/MockLoggingFactory.cs +++ /dev/null @@ -1,20 +0,0 @@ -namespace Microsoft.Extensions.DependencyInjection.Test -{ - using Logging; - - internal class MockLoggingFactory : ILoggerFactory - { - public void Dispose() - { - } - - public ILogger CreateLogger(string categoryName) - { - return null; - } - - public void AddProvider(ILoggerProvider provider) - { - } - } -} \ No newline at end of file diff --git a/NETCORE/test/Microsoft.ApplicationInsights.AspNetCore.Tests/Extensions/ApplicationInsightsServiceOptionsTests.cs b/NETCORE/test/Microsoft.ApplicationInsights.AspNetCore.Tests/Extensions/ApplicationInsightsServiceOptionsTests.cs deleted file mode 100644 index 36247da9a0..0000000000 --- a/NETCORE/test/Microsoft.ApplicationInsights.AspNetCore.Tests/Extensions/ApplicationInsightsServiceOptionsTests.cs +++ /dev/null @@ -1,418 +0,0 @@ -using System; -using System.Diagnostics; -using System.IO; -using System.Linq; - -using Microsoft.ApplicationInsights.AspNetCore.Extensions; -using Microsoft.ApplicationInsights.Channel; -using Microsoft.ApplicationInsights.DependencyCollector; -using Microsoft.ApplicationInsights.Extensibility; -#if NETCOREAPP -using Microsoft.ApplicationInsights.Extensibility.EventCounterCollector; -#endif -using Microsoft.ApplicationInsights.Extensibility.Implementation.Tracing; -using Microsoft.ApplicationInsights.Extensibility.PerfCounterCollector; -using Microsoft.ApplicationInsights.Extensibility.PerfCounterCollector.QuickPulse; -using Microsoft.ApplicationInsights.WindowsServer; -using Microsoft.AspNetCore.Hosting; -using Microsoft.AspNetCore.Hosting.Internal; -using Microsoft.Extensions.Configuration; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.DependencyInjection.Test; - -using Xunit; - -namespace Microsoft.ApplicationInsights.AspNetCore.Tests.Extensions -{ - /// - /// Test class for . - /// - /// - /// This configuration can be read from a JSON file by the configuration factory or through code by passing ApplicationInsightsServiceOptions. - /// - /// DefaultConfiguration - calls services.AddApplicationInsightsTelemetryWorkerService() which reads IConfiguration from user application automatically. - /// SuppliedConfiguration - invokes services.AddApplicationInsightsTelemetryWorkerService(configuration) where IConfiguration object is supplied by caller. - /// Code - Caller creates an instance of ApplicationInsightsServiceOptions and passes it. This option overrides all configuration being used in JSON file. - /// There is a special case where NULL values in these properties - InstrumentationKey, ConnectionString, EndpointAddress and DeveloperMode are overwritten. We check IConfiguration object to see if these properties have values, if values are present then we override it. - /// - /// Sets the value for property EnableEventCounterCollectionModule. - /// - public class ApplicationInsightsServiceOptionsTests - { - private static IServiceProvider TestShim(string configType, bool isEnabled, Action testConfig, Action servicesConfig = null) - { - // ARRANGE - Action serviceOptions = null; - var filePath = Path.Combine(Directory.GetCurrentDirectory(), "content", "config-all-settings-" + isEnabled.ToString().ToLower() + ".json"); - - if (configType == "Code") - { - filePath = null; - - // This will set the property defined in the test. - serviceOptions = o => { testConfig(o, isEnabled); }; - } - - // ACT - var services = CreateServicesAndAddApplicationinsightsWorker( - jsonPath: filePath, - serviceOptions: serviceOptions, - servicesConfig: servicesConfig, - useDefaultConfig: configType == "DefaultConfiguration" ? true : false); - - IServiceProvider serviceProvider = services.BuildServiceProvider(); - - // Get telemetry client to trigger TelemetryConfig setup. - var tc = serviceProvider.GetService(); - - // Verify that Modules were added to DI. - var modules = serviceProvider.GetServices(); - Assert.NotNull(modules); - - return serviceProvider; - } - - private static ServiceCollection CreateServicesAndAddApplicationinsightsWorker(string jsonPath, Action serviceOptions = null, Action servicesConfig = null, bool useDefaultConfig = true) - { - IConfigurationRoot config; - var services = new ServiceCollection() - .AddSingleton(EnvironmentHelper.GetIHostingEnvironment()) - .AddSingleton(new DiagnosticListener("TestListener")); - - if (jsonPath != null) - { - var jsonFullPath = Path.Combine(Directory.GetCurrentDirectory(), jsonPath); - Console.WriteLine("json:" + jsonFullPath); - try - { - config = new ConfigurationBuilder().SetBasePath(Directory.GetCurrentDirectory()).AddJsonFile(jsonFullPath).Build(); - } - catch (Exception) - { - throw new Exception("Unable to build with json:" + jsonFullPath); - } - } - else - { - var configBuilder = new ConfigurationBuilder() - .AddJsonFile(Path.Combine(Directory.GetCurrentDirectory(), "appsettings.json"), true) - .AddEnvironmentVariables(); - config = configBuilder.Build(); - } - - if (useDefaultConfig) - { - services.AddSingleton(config); - services.AddApplicationInsightsTelemetry(); - } - else - { - services.AddApplicationInsightsTelemetry(config); - } - - servicesConfig?.Invoke(services); - - if (serviceOptions != null) - { - services.Configure(serviceOptions); - } - - return (ServiceCollection)services; - } - - /// - /// User could enable or disable TelemetryConfiguration.Active by setting EnableAppServicesHeartbeatTelemetryModule. - /// - /// /// - /// This SDK previously had a hidden dependency on TelemetryConfiguration.Active. - /// We've removed that, but users may have taken a dependency on the former behavior. - /// This test verifies that users can enable "backwards compat". - /// Enabling this will copy the AspNetCore config to the TC.Active static instance. - /// - [Theory] - - [InlineData("DefaultConfiguration", true)] - [InlineData("DefaultConfiguration", false)] - [InlineData("SuppliedConfiguration", true)] - [InlineData("SuppliedConfiguration", false)] - [InlineData("Code", true)] - [InlineData("Code", false)] - public static void UserCanEnableAndDisableTelemetryConfigurationActive(string configType, bool isEnable) - { -#pragma warning disable CS0618 // Type or member is obsolete - // Dispose .Active to force a new .Active to be created during this test. - TelemetryConfiguration.Active.Dispose(); - - // IMPORTANT: This is the same ikey specified in the config files that will be used for this test. - string testString = "22222222-2222-3333-4444-555555555555"; - var testTelemetryInitializer = new FakeTelemetryInitializer(); - - IServiceProvider serviceProvider = TestShim( - configType: configType, - isEnabled: isEnable, - testConfig: (o, b) => - { - o.EnableActiveTelemetryConfigurationSetup = b; - o.InstrumentationKey = testString; - }, - servicesConfig: (services) => services.AddSingleton(testTelemetryInitializer) - ); - - // TelemetryConfiguration from DI should have custom set InstrumentationKey and TelemetryInitializer - var telemetryConfiguration = serviceProvider.GetTelemetryConfiguration(); - Assert.Equal(testString, telemetryConfiguration.InstrumentationKey); - Assert.Same(testTelemetryInitializer, telemetryConfiguration.TelemetryInitializers.OfType().Single()); - - // TelemetryConfiguration.Active will only have custom set InstrumentationKey if .Active was enabled. - Assert.Equal(testString.Equals(TelemetryConfiguration.Active.InstrumentationKey), isEnable); - - // TelemetryConfiguration.Active will only have custom TelemetryInitializer if .Active was enabled - var activeTelemetryInitializer = TelemetryConfiguration.Active.TelemetryInitializers.OfType().SingleOrDefault(); - if (isEnable) - { - Assert.Same(testTelemetryInitializer, activeTelemetryInitializer); - } - else - { - Assert.Null(activeTelemetryInitializer); - } - -#pragma warning restore CS0618 // Type or member is obsolete - } - - /// - /// User could enable or disable PerformanceCounterCollectionModule by setting EnablePerformanceCounterCollectionModule. - /// - [Theory] - [InlineData("DefaultConfiguration", true)] - [InlineData("DefaultConfiguration", false)] - [InlineData("SuppliedConfiguration", true)] - [InlineData("SuppliedConfiguration", false)] - [InlineData("Code", true)] - [InlineData("Code", false)] - public static void UserCanEnableAndDisablePerfCollectorModule(string configType, bool isEnable) - { - IServiceProvider serviceProvider = TestShim(configType: configType, isEnabled: isEnable, testConfig: (o, b) => o.EnablePerformanceCounterCollectionModule = b); - - var modules = serviceProvider.GetServices(); - var module = modules.OfType().Single(); - Assert.Equal(isEnable, module.IsInitialized); - } - -#if NETCOREAPP - /// - /// User could enable or disable EventCounterCollectionModule by setting EnableEventCounterCollectionModule. - /// - [Theory] - - [InlineData("DefaultConfiguration", true)] - [InlineData("DefaultConfiguration", false)] - [InlineData("SuppliedConfiguration", true)] - [InlineData("SuppliedConfiguration", false)] - - [InlineData("Code", true)] - [InlineData("Code", false)] - public static void UserCanEnableAndDisableEventCounterCollectorModule(string configType, bool isEnable) - { - IServiceProvider serviceProvider = TestShim(configType: configType, isEnabled: isEnable, testConfig: (o, b) => o.EnableEventCounterCollectionModule = b); - - var modules = serviceProvider.GetServices(); - var module = modules.OfType().Single(); - Assert.Equal(isEnable, module.IsInitialized); - } -#endif - - /// - /// User could enable or disable DependencyTrackingTelemetryModule by setting EnableDependencyTrackingTelemetryModule. - /// - [Theory] - [InlineData("DefaultConfiguration", true)] - [InlineData("DefaultConfiguration", false)] - [InlineData("SuppliedConfiguration", true)] - [InlineData("SuppliedConfiguration", false)] - [InlineData("Code", true)] - [InlineData("Code", false)] - public static void UserCanEnableAndDisableDependencyCollectorModule(string configType, bool isEnable) - { - IServiceProvider serviceProvider = TestShim(configType: configType, isEnabled: isEnable, testConfig: (o, b) => o.EnableDependencyTrackingTelemetryModule = b); - - var modules = serviceProvider.GetServices(); - var module = modules.OfType().Single(); - Assert.Equal(isEnable, module.IsInitialized); - } - - /// - /// User could enable or disable QuickPulseCollectorModule by setting EnableQuickPulseMetricStream. - /// - [Theory] - [InlineData("DefaultConfiguration", true)] - [InlineData("DefaultConfiguration", false)] - [InlineData("SuppliedConfiguration", true)] - [InlineData("SuppliedConfiguration", false)] - [InlineData("Code", true)] - [InlineData("Code", false)] - public static void UserCanEnableAndDisableQuickPulseCollectorModule(string configType, bool isEnable) - { - IServiceProvider serviceProvider = TestShim(configType: configType, isEnabled: isEnable, testConfig: (o, b) => o.EnableQuickPulseMetricStream = b); - - var modules = serviceProvider.GetServices(); - var module = modules.OfType().Single(); - Assert.Equal(isEnable, module.IsInitialized); - } - - /// - /// User could enable or disable AzureInstanceMetadataModule by setting EnableAzureInstanceMetadataTelemetryModule. - /// - [Theory] - [InlineData("DefaultConfiguration", true)] - [InlineData("DefaultConfiguration", false)] - [InlineData("SuppliedConfiguration", true)] - [InlineData("SuppliedConfiguration", false)] - [InlineData("Code", true)] - [InlineData("Code", false)] - public static void UserCanEnableAndDisableAzureInstanceMetadataModule(string configType, bool isEnable) - { - IServiceProvider serviceProvider = TestShim(configType: configType, isEnabled: isEnable, testConfig: (o, b) => o.EnableAzureInstanceMetadataTelemetryModule = b); - - var modules = serviceProvider.GetServices(); - var module = modules.OfType().Single(); - Assert.Equal(isEnable, module.IsInitialized); - } - - /// - /// User could enable or disable RequestTrackingTelemetryModule by setting EnableRequestTrackingTelemetryModule. - /// - [Theory] - [InlineData("DefaultConfiguration", true)] - [InlineData("DefaultConfiguration", false)] - [InlineData("SuppliedConfiguration", true)] - [InlineData("SuppliedConfiguration", false)] - [InlineData("Code", true)] - [InlineData("Code", false)] - public static void UserCanEnableAndDisableRequestCounterCollectorModule(string configType, bool isEnable) - { - IServiceProvider serviceProvider = TestShim(configType: configType, isEnabled: isEnable, testConfig: (o, b) => o.EnableRequestTrackingTelemetryModule = b); - - var modules = serviceProvider.GetServices(); - var module = modules.OfType().Single(); - Assert.Equal(isEnable, module.IsInitialized); - } - - /// - /// User could enable or disable AppServiceHeartbeatModule by setting EnableAppServicesHeartbeatTelemetryModule. - /// - [Theory] - [InlineData("DefaultConfiguration", true)] - [InlineData("DefaultConfiguration", false)] - [InlineData("SuppliedConfiguration", true)] - [InlineData("SuppliedConfiguration", false)] - [InlineData("Code", true)] - [InlineData("Code", false)] - public static void UserCanEnableAndDisableAppServiceHeartbeatModule(string configType, bool isEnable) - { - IServiceProvider serviceProvider = TestShim(configType: configType, isEnabled: isEnable, testConfig: (o, b) => o.EnableAppServicesHeartbeatTelemetryModule = b); - - var modules = serviceProvider.GetServices(); - var module = modules.OfType().Single(); - Assert.Equal(isEnable, module.IsInitialized); - } - - /// - /// User could enable or disable by setting . - /// - [Theory] - [InlineData("DefaultConfiguration", true)] - [InlineData("DefaultConfiguration", false)] - [InlineData("SuppliedConfiguration", true)] - [InlineData("SuppliedConfiguration", false)] - [InlineData("Code", true)] - [InlineData("Code", false)] - public static void UserCanEnableAndDisableDiagnosticsTelemetryModule(string configType, bool isEnable) - { - IServiceProvider serviceProvider = TestShim(configType: configType, isEnabled: isEnable, testConfig: (o, b) => o.EnableDiagnosticsTelemetryModule = b); - - var modules = serviceProvider.GetServices(); - var module = modules.OfType().Single(); - Assert.Equal(isEnable, module.IsInitialized); - } - - /// - /// User could enable or disable the Heartbeat feature by setting . - /// - /// - /// Config file tests are not valid in this test because they set ALL settings to either TRUE/FALSE. - /// This test is specifically evaluating what happens when the DiagnosticsTelemetryModule is enabled, but the Heartbeat feature is disabled. - /// - [Theory] - [InlineData("Code", true)] - [InlineData("Code", false)] - public static void UserCanEnableAndDisableHeartbeatFeature(string configType, bool isEnable) - { - IServiceProvider serviceProvider = TestShim(configType: configType, isEnabled: isEnable, - testConfig: (o, b) => { - o.EnableDiagnosticsTelemetryModule = true; - o.EnableHeartbeat = b; - }); - - var modules = serviceProvider.GetServices(); - var module = modules.OfType().Single(); - Assert.True(module.IsInitialized, "module was not initialized"); - Assert.Equal(isEnable, module.IsHeartbeatEnabled); - } - - /// - /// Tests that the Credential property can be set and is properly copied. - /// - [Fact] - public static void CredentialProperty_CanBeSet() - { - // Arrange - var options = new ApplicationInsightsServiceOptions(); - var credential = new MockTokenCredential(); - - // Act - options.Credential = credential; - - // Assert - Assert.NotNull(options.Credential); - Assert.Same(credential, options.Credential); - } - - /// - /// Tests that the Credential property is copied during CopyPropertiesTo. - /// - [Fact] - public static void CredentialProperty_IsCopiedInCopyPropertiesTo() - { - // Arrange - var source = new ApplicationInsightsServiceOptions(); - var target = new ApplicationInsightsServiceOptions(); - var credential = new MockTokenCredential(); - source.Credential = credential; - - // Act - source.CopyPropertiesTo(target); - - // Assert - Assert.NotNull(target.Credential); - Assert.Same(credential, target.Credential); - } - - /// - /// Mock TokenCredential for testing purposes. - /// - private class MockTokenCredential : Azure.Core.TokenCredential - { - public override Azure.Core.AccessToken GetToken(Azure.Core.TokenRequestContext requestContext, System.Threading.CancellationToken cancellationToken) - { - return new Azure.Core.AccessToken("mock-token", DateTimeOffset.UtcNow.AddHours(1)); - } - - public override System.Threading.Tasks.ValueTask GetTokenAsync(Azure.Core.TokenRequestContext requestContext, System.Threading.CancellationToken cancellationToken) - { - return new System.Threading.Tasks.ValueTask( - new Azure.Core.AccessToken("mock-token", DateTimeOffset.UtcNow.AddHours(1))); - } - } - } -} \ No newline at end of file diff --git a/NETCORE/test/Microsoft.ApplicationInsights.AspNetCore.Tests/Extensions/HttpRequestExtensionsTest.cs b/NETCORE/test/Microsoft.ApplicationInsights.AspNetCore.Tests/Extensions/HttpRequestExtensionsTest.cs deleted file mode 100644 index ed51eee536..0000000000 --- a/NETCORE/test/Microsoft.ApplicationInsights.AspNetCore.Tests/Extensions/HttpRequestExtensionsTest.cs +++ /dev/null @@ -1,135 +0,0 @@ -namespace Microsoft.ApplicationInsights.AspNetCore.Tests.Extensions -{ - using Microsoft.ApplicationInsights.AspNetCore.Extensions; - using Microsoft.AspNetCore.Http; - using System; - using System.Globalization; - using Xunit; - - public class HttpRequestExtensionsTest - { - const string ExpectedSchema = "http"; - const string ExpectedHostName = "randomhost"; - const string ExpectedDefaultHostName = "unknown-host"; - const string ExpectedMulltipleHostName = "multiple-host"; - const string ExpectedPath = "/path/path/"; - const string ExpectedPathBase = "/pathbase"; - const string ExpectedQueryString = "?queryType=1"; - - [Fact] - public void TestGetUriThrowsExceptionOnNullRequestObject() - { - Assert.Throws( - () => - { - HttpRequestExtensions.GetUri(null); - }); - } - - [Fact] - public void TestGetUriThrowsExceptionOnRequestObjectSchemeIsEmpty() - { - var request = new DefaultHttpContext().Request; - - var exception = Assert.Throws( - () => - { - HttpRequestExtensions.GetUri(request); - }); - - Assert.True(exception.Message.Contains("Scheme"), "Scheme is not mentioned in the exception"); - } - - [Fact] - public void TestGetUriUsesDefaultHostNameOnRequestObjectHostIsNotSpecified() - { - var request = new DefaultHttpContext().Request; - request.Scheme = ExpectedSchema; - - var uri = HttpRequestExtensions.GetUri(request); - Assert.Equal( - new Uri(string.Format(CultureInfo.InvariantCulture, "{0}://{1}", ExpectedSchema, ExpectedDefaultHostName)), - uri); - } - - [Fact] - public void TestGetUriUsesMultipleHostNameOnRequestWithManyHostsSpecified() - { - var request = new DefaultHttpContext().Request; - request.Scheme = ExpectedSchema; - request.Host = new HostString("host1,host2"); - - var uri = HttpRequestExtensions.GetUri(request); - - Assert.Equal( - new Uri(string.Format(CultureInfo.InvariantCulture, "{0}://{1}", ExpectedSchema, ExpectedMulltipleHostName)), - uri); - } - - [Fact] - public void TestGetUriReturnsCorrectUriIfRequestObjectSchemeAndHostAreSpecified() - { - var request = new DefaultHttpContext().Request; - - request.Scheme = ExpectedSchema; - request.Host = new HostString(ExpectedHostName); - - var uri = HttpRequestExtensions.GetUri(request); - - Assert.Equal( - new Uri(string.Format(CultureInfo.InvariantCulture, "{0}://{1}", ExpectedSchema, ExpectedHostName)), - uri); - } - - [Fact] - public void TestGetUriReturnsCorrectUriIfRequestObjectSchemeAndHostAndPathAreSpecified() - { - var request = new DefaultHttpContext().Request; - - request.Scheme = ExpectedSchema; - request.Host = new HostString(ExpectedHostName); - request.Path = new PathString(ExpectedPath); - - var uri = HttpRequestExtensions.GetUri(request); - - Assert.Equal( - new Uri(string.Format(CultureInfo.InvariantCulture, "{0}://{1}{2}", ExpectedSchema, ExpectedHostName, ExpectedPath)), - uri); - } - - [Fact] - public void TestGetUriReturnsCorrectUriIfRequestObjectSchemeAndHostAndPathAndQueryStringAreSpecified() - { - var request = new DefaultHttpContext().Request; - - request.Scheme = ExpectedSchema; - request.Host = new HostString(ExpectedHostName); - request.Path = new PathString(ExpectedPath); - request.QueryString = new QueryString(ExpectedQueryString); - - var uri = HttpRequestExtensions.GetUri(request); - - Assert.Equal( - new Uri(string.Format(CultureInfo.InvariantCulture, "{0}://{1}{2}{3}", ExpectedSchema, ExpectedHostName, ExpectedPath, ExpectedQueryString)), - uri); - } - - [Fact] - public void TestGetUriReturnsCorrectUriIfRequestObjectSchemeAndHostAndPathBaseAndPathAndQueryStringAreSpecified() - { - var request = new DefaultHttpContext().Request; - - request.Scheme = ExpectedSchema; - request.Host = new HostString(ExpectedHostName); - request.PathBase = new PathString(ExpectedPathBase); - request.Path = new PathString(ExpectedPath); - request.QueryString = new QueryString(ExpectedQueryString); - - var uri = HttpRequestExtensions.GetUri(request); - - Assert.Equal( - new Uri(string.Format(CultureInfo.InvariantCulture, "{0}://{1}{2}{3}{4}", ExpectedSchema, ExpectedHostName, ExpectedPathBase, ExpectedPath, ExpectedQueryString)), - uri); - } - } -} \ No newline at end of file diff --git a/NETCORE/test/Microsoft.ApplicationInsights.AspNetCore.Tests/FakeTelemetryChannel.cs b/NETCORE/test/Microsoft.ApplicationInsights.AspNetCore.Tests/FakeTelemetryChannel.cs deleted file mode 100644 index 08cfcbf904..0000000000 --- a/NETCORE/test/Microsoft.ApplicationInsights.AspNetCore.Tests/FakeTelemetryChannel.cs +++ /dev/null @@ -1,34 +0,0 @@ -namespace Microsoft.ApplicationInsights.AspNetCore.Tests -{ - using System; - using Microsoft.ApplicationInsights.Channel; - - // TODO: Remove FakeTelemetryChannel when we can use a dynamic test isolation framework, like NSubstitute or Moq - internal class FakeTelemetryChannel : ITelemetryChannel - { - public Action OnSend = t => { }; - - public string EndpointAddress - { - get; - set; - } - - public bool? DeveloperMode { get; set; } - - public void Dispose() - { - throw new NotImplementedException(); - } - - public void Flush() - { - throw new NotImplementedException(); - } - - public void Send(ITelemetry item) - { - this.OnSend(item); - } - } -} \ No newline at end of file diff --git a/NETCORE/test/Microsoft.ApplicationInsights.AspNetCore.Tests/FakeTelemetryInitializer.cs b/NETCORE/test/Microsoft.ApplicationInsights.AspNetCore.Tests/FakeTelemetryInitializer.cs deleted file mode 100644 index c9e019a89b..0000000000 --- a/NETCORE/test/Microsoft.ApplicationInsights.AspNetCore.Tests/FakeTelemetryInitializer.cs +++ /dev/null @@ -1,15 +0,0 @@ -namespace Microsoft.ApplicationInsights.AspNetCore.Tests -{ - using System; - using Microsoft.ApplicationInsights.Channel; - using Microsoft.ApplicationInsights.Extensibility; - - // TODO: Remove FakeTelemetryInitializer when we can use a dynamic test isolation framework, like NSubstitute or Moq - internal class FakeTelemetryInitializer : ITelemetryInitializer - { - public void Initialize(ITelemetry telemetry) - { - throw new NotImplementedException(); - } - } -} \ No newline at end of file diff --git a/NETCORE/test/Microsoft.ApplicationInsights.AspNetCore.Tests/FakeTelemetryProcessor.cs b/NETCORE/test/Microsoft.ApplicationInsights.AspNetCore.Tests/FakeTelemetryProcessor.cs deleted file mode 100644 index 5e95b691e7..0000000000 --- a/NETCORE/test/Microsoft.ApplicationInsights.AspNetCore.Tests/FakeTelemetryProcessor.cs +++ /dev/null @@ -1,34 +0,0 @@ -namespace Microsoft.ApplicationInsights.AspNetCore.Tests -{ - using System; - using Microsoft.ApplicationInsights.Channel; - using Microsoft.ApplicationInsights.Extensibility; - - internal class FakeTelemetryProcessor : ITelemetryProcessor, ITelemetryModule - { - private readonly ITelemetryProcessor next; - - public FakeTelemetryProcessor(ITelemetryProcessor next) - { - if (next == null) - { - throw new ArgumentNullException(nameof(next)); - } - - this.next = next; - this.IsInitialized = false; - } - - public bool IsInitialized { get; private set; } - - public void Initialize(TelemetryConfiguration configuration) - { - this.IsInitialized = true; - } - - public void Process(ITelemetry item) - { - this.next.Process(item); - } - } -} diff --git a/NETCORE/test/Microsoft.ApplicationInsights.AspNetCore.Tests/FakeTelemetryProcessorWithImportingConstructor.cs b/NETCORE/test/Microsoft.ApplicationInsights.AspNetCore.Tests/FakeTelemetryProcessorWithImportingConstructor.cs deleted file mode 100644 index 6a514dd99c..0000000000 --- a/NETCORE/test/Microsoft.ApplicationInsights.AspNetCore.Tests/FakeTelemetryProcessorWithImportingConstructor.cs +++ /dev/null @@ -1,30 +0,0 @@ -namespace Microsoft.ApplicationInsights.AspNetCore.Tests -{ - using Microsoft.ApplicationInsights.Channel; - using Microsoft.ApplicationInsights.Extensibility; - using Microsoft.AspNetCore.Hosting; - - internal class FakeTelemetryProcessorWithImportingConstructor : ITelemetryProcessor - { - private readonly ITelemetryProcessor nextProcessor; - - public IHostingEnvironment HostingEnvironment { get; } - - /// - /// Constructs an instance of the telemetry processor. - /// This constructor is designed to be called from a DI framework. - /// - /// The next procesor in the chain. - /// The hosting environment. This parameter will be injected by the DI framework. - public FakeTelemetryProcessorWithImportingConstructor(ITelemetryProcessor next, IHostingEnvironment hostingEnvironment) - { - this.nextProcessor = next; - this.HostingEnvironment = hostingEnvironment; - } - - public void Process(ITelemetry item) - { - nextProcessor.Process(item); - } - } -} diff --git a/NETCORE/test/Microsoft.ApplicationInsights.AspNetCore.Tests/HeadersUtilitiesTest.cs b/NETCORE/test/Microsoft.ApplicationInsights.AspNetCore.Tests/HeadersUtilitiesTest.cs deleted file mode 100644 index fe066f8b91..0000000000 --- a/NETCORE/test/Microsoft.ApplicationInsights.AspNetCore.Tests/HeadersUtilitiesTest.cs +++ /dev/null @@ -1,63 +0,0 @@ -namespace Microsoft.ApplicationInsights.AspNetCore.Tests -{ - using System.Collections.Generic; - using DiagnosticListeners; - using Xunit; - - public class HeadersUtilitiesTest - { - [Fact] - public void ShouldReturnHeaderValueWhenKeyExists() - { - List headers = new List() { - "Key = Value" - }; - - string expectedKey = "Value"; - Assert.Equal(expectedKey, HeadersUtilities.GetHeaderKeyValue(headers, "Key")); - } - - [Fact] - public void ShouldReturnNullWhenKeyNotExists() - { - List headers = new List() { - "Key = Value" - }; - Assert.Null(HeadersUtilities.GetHeaderKeyValue(headers, "Non-Exist-Key")); - } - - [Fact] - public void ShouldReturnHeadersWhenNoHeaderValues() - { - string[] newHeaders = HeadersUtilities.SetHeaderKeyValue(null, "Key", "Value"); - - Assert.NotNull(newHeaders); - Assert.Single(newHeaders); - Assert.Equal("Key=Value", newHeaders[0]); - } - - [Fact] - public void ShouldAppendHeaders() - { - string[] existing = new string[] { "ExistKey=ExistValue" }; - string[] result = HeadersUtilities.SetHeaderKeyValue(existing, "NewKey", "NewValue"); - - Assert.NotNull(result); - Assert.Equal(2, result.Length); - Assert.Equal("ExistKey=ExistValue", result[0]); - Assert.Equal("NewKey=NewValue", result[1]); - } - - [Fact] - public void ShouldUpdateExistingHeader() - { - string[] existing = new string[] { "ExistKey=ExistValue", "NoiseKey=NoiseValue" }; - string[] result = HeadersUtilities.SetHeaderKeyValue(existing, "ExistKey", "NewValue"); - - Assert.NotNull(result); - Assert.Equal(2, result.Length); - Assert.Equal("ExistKey=NewValue", result[0]); - Assert.Equal("NoiseKey=NoiseValue", result[1]); - } - } -} diff --git a/NETCORE/test/Microsoft.ApplicationInsights.AspNetCore.Tests/Helpers/CommonMocks.cs b/NETCORE/test/Microsoft.ApplicationInsights.AspNetCore.Tests/Helpers/CommonMocks.cs deleted file mode 100644 index c291835076..0000000000 --- a/NETCORE/test/Microsoft.ApplicationInsights.AspNetCore.Tests/Helpers/CommonMocks.cs +++ /dev/null @@ -1,44 +0,0 @@ -namespace Microsoft.ApplicationInsights.AspNetCore.Tests.Helpers -{ - using System; - using System.Diagnostics; - using Microsoft.ApplicationInsights.Channel; - using Microsoft.ApplicationInsights.Extensibility; - - public static class CommonMocks - { - public const string InstrumentationKey = "REQUIRED"; - public const string TestApplicationId = nameof(TestApplicationId); - - public static TelemetryClient MockTelemetryClient(Action onSendCallback, bool isW3C = true) - { - if(isW3C) - { - Activity.DefaultIdFormat = ActivityIdFormat.W3C; - } - else - { - Activity.DefaultIdFormat = ActivityIdFormat.Hierarchical; - } - Activity.ForceDefaultIdFormat = true; - - return new TelemetryClient(new TelemetryConfiguration() - { - InstrumentationKey = InstrumentationKey, - TelemetryChannel = new FakeTelemetryChannel { OnSend = onSendCallback }, - }); - } - - public static TelemetryClient MockTelemetryClient(Action onSendCallback, TelemetryConfiguration configuration) - { - configuration.InstrumentationKey = InstrumentationKey; - configuration.TelemetryChannel = new FakeTelemetryChannel {OnSend = onSendCallback}; - return new TelemetryClient(configuration); - } - - internal static IApplicationIdProvider GetMockApplicationIdProvider() - { - return new MockApplicationIdProvider(InstrumentationKey, TestApplicationId); - } - } -} diff --git a/NETCORE/test/Microsoft.ApplicationInsights.AspNetCore.Tests/Helpers/HttpContextAccessorHelper.cs b/NETCORE/test/Microsoft.ApplicationInsights.AspNetCore.Tests/Helpers/HttpContextAccessorHelper.cs deleted file mode 100644 index 0b97475a8b..0000000000 --- a/NETCORE/test/Microsoft.ApplicationInsights.AspNetCore.Tests/Helpers/HttpContextAccessorHelper.cs +++ /dev/null @@ -1,66 +0,0 @@ -namespace Microsoft.ApplicationInsights.AspNetCore.Tests.Helpers -{ - using System; - using Microsoft.ApplicationInsights.AspNetCore.DiagnosticListeners; - using Microsoft.ApplicationInsights.DataContracts; - using Microsoft.AspNetCore.Http; - using Microsoft.AspNetCore.Mvc; - using Microsoft.AspNetCore.Mvc.Infrastructure; - using Microsoft.Extensions.DependencyInjection; - - public static class HttpContextAccessorHelper - { - public static HttpContextAccessor CreateHttpContextAccessor(RequestTelemetry requestTelemetry = null, ActionContext actionContext = null, string httpContextCorrelationId = null) - { - var services = new ServiceCollection(); - - var request = new DefaultHttpContext().Request; - request.Method = "GET"; - request.Path = new PathString("/Test"); - if (httpContextCorrelationId != null) - { - HttpHeadersUtilities.SetRequestContextKeyValue(request.Headers, RequestResponseHeaders.RequestContextSourceKey, httpContextCorrelationId); - } - - var contextAccessor = new HttpContextAccessor { HttpContext = request.HttpContext }; - - services.AddSingleton(contextAccessor); - - if (actionContext != null) - { - var si = new ActionContextAccessor(); - si.ActionContext = actionContext; - services.AddSingleton(si); - } - - if (requestTelemetry != null) - { - request.HttpContext.Features.Set(requestTelemetry); - } - - IServiceProvider serviceProvider = services.BuildServiceProvider(); - contextAccessor.HttpContext.RequestServices = serviceProvider; - - return contextAccessor; - } - - public static HttpContextAccessor CreateHttpContextAccessorWithoutRequest(HttpContext httpContext, RequestTelemetry requestTelemetry = null) - { - var services = new ServiceCollection(); - - var contextAccessor = new HttpContextAccessor { HttpContext = httpContext }; - - services.AddSingleton(contextAccessor); - - if (requestTelemetry != null) - { - services.AddSingleton(requestTelemetry); - } - - IServiceProvider serviceProvider = services.BuildServiceProvider(); - contextAccessor.HttpContext.RequestServices = serviceProvider; - - return contextAccessor; - } - } -} diff --git a/NETCORE/test/Microsoft.ApplicationInsights.AspNetCore.Tests/Helpers/MockApplicationIdProvider.cs b/NETCORE/test/Microsoft.ApplicationInsights.AspNetCore.Tests/Helpers/MockApplicationIdProvider.cs deleted file mode 100644 index fdb26b44d6..0000000000 --- a/NETCORE/test/Microsoft.ApplicationInsights.AspNetCore.Tests/Helpers/MockApplicationIdProvider.cs +++ /dev/null @@ -1,32 +0,0 @@ -using Microsoft.ApplicationInsights.Extensibility; - -namespace Microsoft.ApplicationInsights.AspNetCore.Tests.Helpers -{ - internal class MockApplicationIdProvider : IApplicationIdProvider - { - private readonly string expectedInstrumentationKey; - private readonly string applicationId; - - public MockApplicationIdProvider() - { - } - - public MockApplicationIdProvider(string expectedInstrumentationKey, string applicationId) - { - this.expectedInstrumentationKey = expectedInstrumentationKey; - this.applicationId = applicationId; - } - - public bool TryGetApplicationId(string instrumentationKey, out string applicationId) - { - if (this.expectedInstrumentationKey == instrumentationKey) - { - applicationId = this.applicationId; - return true; - } - - applicationId = null; - return false; - } - } -} diff --git a/NETCORE/test/Microsoft.ApplicationInsights.AspNetCore.Tests/HostingDiagnosticListenerTest.cs b/NETCORE/test/Microsoft.ApplicationInsights.AspNetCore.Tests/HostingDiagnosticListenerTest.cs deleted file mode 100644 index 446d974b8b..0000000000 --- a/NETCORE/test/Microsoft.ApplicationInsights.AspNetCore.Tests/HostingDiagnosticListenerTest.cs +++ /dev/null @@ -1,1333 +0,0 @@ -namespace UnitTests -{ - using System; - using System.Collections.Concurrent; - using System.Collections.Generic; - using System.Diagnostics; - using System.Globalization; - using System.Linq; - using System.Threading.Tasks; - - using Microsoft.ApplicationInsights.AspNetCore.DiagnosticListeners; - using Microsoft.ApplicationInsights.AspNetCore.Implementation; - using Microsoft.ApplicationInsights.AspNetCore.Tests; - using Microsoft.ApplicationInsights.AspNetCore.Tests.Helpers; - using Microsoft.ApplicationInsights.Channel; - using Microsoft.ApplicationInsights.Common; - using Microsoft.ApplicationInsights.DataContracts; - using Microsoft.ApplicationInsights.Extensibility; - using Microsoft.ApplicationInsights.Extensibility.Implementation; - using Microsoft.AspNetCore.Http; - using Microsoft.Extensions.Primitives; - - using Xunit; - using Xunit.Abstractions; - - using AspNetCoreMajorVersion = Microsoft.ApplicationInsights.AspNetCore.Tests.AspNetCoreMajorVersion; - using RequestResponseHeaders = Microsoft.ApplicationInsights.AspNetCore.DiagnosticListeners.RequestResponseHeaders; - - - public class HostingDiagnosticListenerTest : IDisposable - { - private const string HttpRequestScheme = "http"; - private const string ExpectedAppId = "cid-v1:some-app-id"; - private const string ActivityCreatedByHostingDiagnosticListener = "ActivityCreatedByHostingDiagnosticListener"; - - private static readonly HostString HttpRequestHost = new HostString("testHost"); - private static readonly PathString HttpRequestPath = new PathString("/path/path"); - private static readonly QueryString HttpRequestQueryString = new QueryString("?query=1"); - - private readonly ITestOutputHelper output; - - public HostingDiagnosticListenerTest(ITestOutputHelper output) - { - this.output = output; - } - - - private static Uri CreateUri(string scheme, HostString host, PathString? path = null, QueryString? query = null) - { - string uriString = string.Format(CultureInfo.InvariantCulture, "{0}://{1}", scheme, host); - if (path != null) - { - uriString += path.Value; - } - if (query != null) - { - uriString += query.Value; - } - return new Uri(uriString); - } - - private HttpContext CreateContext(string scheme, HostString host, PathString? path = null, QueryString? query = null, string method = null) - { - HttpContext context = new DefaultHttpContext(); - context.Request.Scheme = scheme; - context.Request.Host = host; - - if (path.HasValue) - { - context.Request.Path = path.Value; - } - - if (query.HasValue) - { - context.Request.QueryString = query.Value; - } - - if (!string.IsNullOrEmpty(method)) - { - context.Request.Method = method; - } - - Assert.Null(context.Features.Get()); - - return context; - } - - private ConcurrentQueue sentTelemetry = new ConcurrentQueue(); - - private HostingDiagnosticListener CreateHostingListener(AspNetCoreMajorVersion aspNetCoreMajorVersion, TelemetryConfiguration config = null, bool isW3C = true) - { - HostingDiagnosticListener hostingListener; - if (config != null) - { - hostingListener = new HostingDiagnosticListener( - config, - CommonMocks.MockTelemetryClient(telemetry => this.sentTelemetry.Enqueue(telemetry), isW3C), - CommonMocks.GetMockApplicationIdProvider(), - injectResponseHeaders: true, - trackExceptions: true, - enableW3CHeaders: false, - aspNetCoreMajorVersion: GetAspNetCoreMajorVersion(aspNetCoreMajorVersion)); - } - else - { - hostingListener = new HostingDiagnosticListener( - CommonMocks.MockTelemetryClient(telemetry => this.sentTelemetry.Enqueue(telemetry), isW3C), - CommonMocks.GetMockApplicationIdProvider(), - injectResponseHeaders: true, - trackExceptions: true, - enableW3CHeaders: false, - aspNetCoreMajorVersion: GetAspNetCoreMajorVersion(aspNetCoreMajorVersion)); - } - - hostingListener.OnSubscribe(); - return hostingListener; - } - - [Theory] - [InlineData(AspNetCoreMajorVersion.Two)] - [InlineData(AspNetCoreMajorVersion.Three)] - public void TestConditionalAppIdFlagIsRespected(AspNetCoreMajorVersion aspNetCoreMajorVersion) - { - HttpContext context = CreateContext(HttpRequestScheme, HttpRequestHost); - TelemetryConfiguration config = TelemetryConfiguration.CreateDefault(); - // This flag tells sdk to not add app id in response header, unless its received in incoming headers. - // For this test, no incoming headers is add, so the response should not have app id as well. - config.ExperimentalFeatures.Add("conditionalAppId"); - - using (var hostingListener = CreateHostingListener(aspNetCoreMajorVersion, config)) - { - HandleRequestBegin(hostingListener, context, 0, aspNetCoreMajorVersion); - - Assert.NotNull(context.Features.Get()); - - // VALIDATE - Assert.Null(HttpHeadersUtilities.GetRequestContextKeyValue(context.Response.Headers, - RequestResponseHeaders.RequestContextTargetKey)); - - HandleRequestEnd(hostingListener, context, 0, aspNetCoreMajorVersion); - } - - Assert.Single(sentTelemetry); - Assert.IsType(this.sentTelemetry.First()); - - RequestTelemetry requestTelemetry = this.sentTelemetry.First() as RequestTelemetry; - Assert.True(string.IsNullOrEmpty(requestTelemetry.Source)); - Assert.True(requestTelemetry.Duration.TotalMilliseconds >= 0); - Assert.True(requestTelemetry.Success); - Assert.Equal(CommonMocks.InstrumentationKey, requestTelemetry.Context.InstrumentationKey); - Assert.Equal(CreateUri(HttpRequestScheme, HttpRequestHost), requestTelemetry.Url); - Assert.NotEmpty(requestTelemetry.Context.GetInternalContext().SdkVersion); - Assert.Contains(SdkVersionTestUtils.VersionPrefix, requestTelemetry.Context.GetInternalContext().SdkVersion); - } - - [Theory] - [InlineData(AspNetCoreMajorVersion.Two)] - [InlineData(AspNetCoreMajorVersion.Three)] - public void TestSdkVersionIsPopulatedByMiddleware(AspNetCoreMajorVersion aspNetCoreMajorVersion) - { - HttpContext context = CreateContext(HttpRequestScheme, HttpRequestHost); - TelemetryConfiguration config = TelemetryConfiguration.CreateDefault(); - - using (var hostingListener = CreateHostingListener(aspNetCoreMajorVersion, config)) - { - HandleRequestBegin(hostingListener, context, 0, aspNetCoreMajorVersion); - - Assert.NotNull(context.Features.Get()); - HandleRequestEnd(hostingListener, context, 0, aspNetCoreMajorVersion); - } - - Assert.Single(sentTelemetry); - Assert.IsType(this.sentTelemetry.First()); - - RequestTelemetry requestTelemetry = this.sentTelemetry.First() as RequestTelemetry; - Assert.True(requestTelemetry.Duration.TotalMilliseconds >= 0); - Assert.True(requestTelemetry.Success); - Assert.Equal(CommonMocks.InstrumentationKey, requestTelemetry.Context.InstrumentationKey); - Assert.True(string.IsNullOrEmpty(requestTelemetry.Source)); - Assert.Equal(CreateUri(HttpRequestScheme, HttpRequestHost), requestTelemetry.Url); - Assert.NotEmpty(requestTelemetry.Context.GetInternalContext().SdkVersion); - Assert.Contains(SdkVersionTestUtils.VersionPrefix, requestTelemetry.Context.GetInternalContext().SdkVersion); - } - - [Theory] - [InlineData(AspNetCoreMajorVersion.Two)] - [InlineData(AspNetCoreMajorVersion.Three)] - public void TestRequestUriIsPopulatedByMiddleware(AspNetCoreMajorVersion aspNetCoreMajorVersion) - { - HttpContext context = CreateContext(HttpRequestScheme, HttpRequestHost, HttpRequestPath, HttpRequestQueryString); - - using (var hostingListener = CreateHostingListener(aspNetCoreMajorVersion)) - { - HandleRequestBegin(hostingListener, context, 0, aspNetCoreMajorVersion); - - Assert.NotNull(context.Features.Get()); - Assert.Equal(CommonMocks.TestApplicationId, - HttpHeadersUtilities.GetRequestContextKeyValue(context.Response.Headers, RequestResponseHeaders.RequestContextTargetKey)); - - HandleRequestEnd(hostingListener, context, 0, aspNetCoreMajorVersion); - } - - Assert.Single(sentTelemetry); - Assert.IsType(this.sentTelemetry.First()); - RequestTelemetry requestTelemetry = sentTelemetry.First() as RequestTelemetry; - Assert.NotNull(requestTelemetry.Url); - Assert.True(requestTelemetry.Duration.TotalMilliseconds >= 0); - Assert.True(requestTelemetry.Success); - Assert.Equal(CommonMocks.InstrumentationKey, requestTelemetry.Context.InstrumentationKey); - Assert.True(string.IsNullOrEmpty(requestTelemetry.Source)); - Assert.Equal(CreateUri(HttpRequestScheme, HttpRequestHost, HttpRequestPath, HttpRequestQueryString), requestTelemetry.Url); - Assert.NotEmpty(requestTelemetry.Context.GetInternalContext().SdkVersion); - Assert.Contains(SdkVersionTestUtils.VersionPrefix, requestTelemetry.Context.GetInternalContext().SdkVersion); - } - - [Theory] - [InlineData(AspNetCoreMajorVersion.Two)] - [InlineData(AspNetCoreMajorVersion.Three)] - public void RequestWillBeMarkedAsFailedForRunawayException(AspNetCoreMajorVersion aspNetCoreMajorVersion) - { - HttpContext context = CreateContext(HttpRequestScheme, HttpRequestHost); - - using (var hostingListener = CreateHostingListener(aspNetCoreMajorVersion)) - { - HandleRequestBegin(hostingListener, context, 0, aspNetCoreMajorVersion); - - Assert.NotNull(context.Features.Get()); - Assert.Equal(CommonMocks.TestApplicationId, - HttpHeadersUtilities.GetRequestContextKeyValue(context.Response.Headers, RequestResponseHeaders.RequestContextTargetKey)); - - hostingListener.OnDiagnosticsUnhandledException(context, null); - HandleRequestEnd(hostingListener, context, 0, aspNetCoreMajorVersion); - } - - var telemetries = sentTelemetry.ToArray(); - Assert.Equal(2, sentTelemetry.Count); - Assert.IsType(telemetries[0]); - - Assert.IsType(telemetries[1]); - RequestTelemetry requestTelemetry = telemetries[1] as RequestTelemetry; - Assert.True(requestTelemetry.Duration.TotalMilliseconds >= 0); - Assert.False(requestTelemetry.Success); - Assert.Equal(CommonMocks.InstrumentationKey, requestTelemetry.Context.InstrumentationKey); - Assert.True(string.IsNullOrEmpty(requestTelemetry.Source)); - Assert.Equal(CreateUri(HttpRequestScheme, HttpRequestHost), requestTelemetry.Url); - Assert.NotEmpty(requestTelemetry.Context.GetInternalContext().SdkVersion); - Assert.Contains(SdkVersionTestUtils.VersionPrefix, requestTelemetry.Context.GetInternalContext().SdkVersion); - } - - [Theory] - [InlineData(AspNetCoreMajorVersion.Two,true)] - [InlineData(AspNetCoreMajorVersion.Three, true)] - [InlineData(AspNetCoreMajorVersion.Two, false)] - [InlineData(AspNetCoreMajorVersion.Three, false)] - public void RequestWithNoHeadersCreateNewActivityAndPopulateRequestTelemetry(AspNetCoreMajorVersion aspNetCoreMajorVersion, bool IsW3C) - { - // Tests Request correlation when incoming request has no correlation headers. - HttpContext context = CreateContext(HttpRequestScheme, HttpRequestHost, "/Test", method: "POST"); - - using (var hostingListener = CreateHostingListener(aspNetCoreMajorVersion, isW3C: IsW3C)) - { - HandleRequestBegin(hostingListener, context, 0, aspNetCoreMajorVersion); - - var activity = Activity.Current; - Assert.NotNull(activity); - - Assert.NotNull(context.Features.Get()); - - HandleRequestEnd(hostingListener, context, 0, aspNetCoreMajorVersion); - - Assert.Single(sentTelemetry); - var requestTelemetry = (RequestTelemetry)this.sentTelemetry.Single(); - - ValidateRequestTelemetry(requestTelemetry, activity, IsW3C, expectedParentId: null, expectedSource: null); - } - } - - [Theory] - [InlineData(AspNetCoreMajorVersion.Two, true)] - [InlineData(AspNetCoreMajorVersion.Three, true)] - [InlineData(AspNetCoreMajorVersion.Two, false)] - [InlineData(AspNetCoreMajorVersion.Three, false)] - public void RequestWithW3CCompatibleRequestIdCreateNewActivityAndPopulateRequestTelemetry(AspNetCoreMajorVersion aspNetCoreMajorVersion, bool IsW3C) - { - // Tests Request correlation when incoming request has only Request-ID headers. - HttpContext context = CreateContext(HttpRequestScheme, HttpRequestHost, "/Test", method: "POST"); - // requestid with rootid part compatible with W3C TraceID - var requestId = "|40d1a5a08a68c0998e4a3b7c91915ca6.b9e41c35_1."; - context.Request.Headers[RequestResponseHeaders.RequestIdHeader] = requestId; - context.Request.Headers[RequestResponseHeaders.CorrelationContextHeader] = "prop1=value1, prop2=value2"; - - var tags = new Dictionary - { - ["tag1"] = "v1", - ["tag2"] = "v2", - }; - - using (var hostingListener = CreateHostingListener(aspNetCoreMajorVersion, isW3C:IsW3C)) - { - HandleRequestBegin(hostingListener, context, 0, aspNetCoreMajorVersion, tags); - - var activity = Activity.Current; - Assert.NotNull(activity); - - // Hosting in 2,3 creates Activity which are ignored by SDK in W3C Mode to use the w3c compatible trace-id from Request-Id - // Validate that activity is the one created by SDK HostingListener - if (IsW3C) - { - Assert.Equal(ActivityCreatedByHostingDiagnosticListener, activity.OperationName); - } - - Assert.Equal(tags, activity.Tags.ToDictionary(kvp => kvp.Key, kvp => kvp.Value)); - - Assert.Single(activity.Baggage.Where(b => b.Key == "prop1" && b.Value == "value1")); - Assert.Single(activity.Baggage.Where(b => b.Key == "prop2" && b.Value == "value2")); - - Assert.NotNull(context.Features.Get()); - - HandleRequestEnd(hostingListener, context, 0, aspNetCoreMajorVersion); - - Assert.Single(sentTelemetry); - var requestTelemetry = (RequestTelemetry)this.sentTelemetry.Single(); - ValidateRequestTelemetry(requestTelemetry, activity, IsW3C, expectedParentId: requestId, expectedSource: null); - Assert.Equal("40d1a5a08a68c0998e4a3b7c91915ca6", requestTelemetry.Context.Operation.Id); - Assert.Equal("value1", requestTelemetry.Properties["prop1"]); - Assert.Equal("value2", requestTelemetry.Properties["prop2"]); - } - } - - [Theory] - [InlineData(AspNetCoreMajorVersion.Two, true)] - [InlineData(AspNetCoreMajorVersion.Three, true)] - [InlineData(AspNetCoreMajorVersion.Two, false)] - [InlineData(AspNetCoreMajorVersion.Three, false)] - public void RequestWithNonW3CCompatibleRequestIdCreateNewActivityAndPopulateRequestTelemetry(AspNetCoreMajorVersion aspNetCoreMajorVersion, bool IsW3C) - { - // Tests Request correlation when incoming request has only Request-ID headers and is not compatible w3c trace id - HttpContext context = CreateContext(HttpRequestScheme, HttpRequestHost, "/Test", method: "POST"); - // requestid with rootid part NOT compatible with W3C TraceID - var requestId = "|noncompatible.b9e41c35_1."; - context.Request.Headers[RequestResponseHeaders.RequestIdHeader] = requestId; - context.Request.Headers[RequestResponseHeaders.CorrelationContextHeader] = "prop1=value1, prop2=value2"; - - var tags = new Dictionary - { - ["tag1"] = "v1", - ["tag2"] = "v2", - }; - - using (var hostingListener = CreateHostingListener(aspNetCoreMajorVersion, isW3C: IsW3C)) - { - HandleRequestBegin(hostingListener, context, 0, aspNetCoreMajorVersion, tags); - - var activity = Activity.Current; - Assert.NotNull(activity); - - // Hosting in 2,3 creates Activity ignoring the request-id. The request-id is not w3c compatible - // hence SDK also ignores them, and just uses Activity from Hosting. - // Validate that activity is Not created by SDK Hosting - Assert.NotEqual(ActivityCreatedByHostingDiagnosticListener, activity.OperationName); - Assert.Equal(tags, activity.Tags.ToDictionary(kvp => kvp.Key, kvp => kvp.Value)); - - Assert.Single(activity.Baggage.Where(b => b.Key == "prop1" && b.Value == "value1")); - Assert.Single(activity.Baggage.Where(b => b.Key == "prop2" && b.Value == "value2")); - - Assert.NotNull(context.Features.Get()); - - HandleRequestEnd(hostingListener, context, 0, aspNetCoreMajorVersion); - - Assert.Single(sentTelemetry); - var requestTelemetry = (RequestTelemetry)this.sentTelemetry.Single(); - ValidateRequestTelemetry(requestTelemetry, activity, IsW3C, expectedParentId: requestId, expectedSource: null); - - if(IsW3C) - { - Assert.Equal("noncompatible", requestTelemetry.Properties[HostingDiagnosticListener.LegacyRootIdProperty]); - Assert.NotEqual("noncompatible", requestTelemetry.Context.Operation.Id); - } - else - { - Assert.Equal("noncompatible", requestTelemetry.Context.Operation.Id); - } - - Assert.Equal("value1", requestTelemetry.Properties["prop1"]); - Assert.Equal("value2", requestTelemetry.Properties["prop2"]); - } - } - - [Theory] - [InlineData(AspNetCoreMajorVersion.Two, true)] - [InlineData(AspNetCoreMajorVersion.Three, true)] - [InlineData(AspNetCoreMajorVersion.Two, false)] - [InlineData(AspNetCoreMajorVersion.Three, false)] - public void RequestWithNonW3CCompatibleNonHierarchicalRequestIdCreateNewActivityAndPopulateRequestTelemetry(AspNetCoreMajorVersion aspNetCoreMajorVersion, bool IsW3C) - { - // Tests Request correlation when incoming request has only Request-ID headers and is not compatible w3c trace id and not a hierrachical id either. - HttpContext context = CreateContext(HttpRequestScheme, HttpRequestHost, "/Test", method: "POST"); - // requestid with rootid part NOT compatible with W3C TraceID, and not a Hierrarchical id either. - var requestId = "somerequestidsomeformat"; - context.Request.Headers[RequestResponseHeaders.RequestIdHeader] = requestId; - context.Request.Headers[RequestResponseHeaders.CorrelationContextHeader] = "prop1=value1, prop2=value2"; - - var tags = new Dictionary - { - ["tag1"] = "v1", - ["tag2"] = "v2", - }; - - using (var hostingListener = CreateHostingListener(aspNetCoreMajorVersion, isW3C: IsW3C)) - { - HandleRequestBegin(hostingListener, context, 0, aspNetCoreMajorVersion, tags); - - var activity = Activity.Current; - Assert.NotNull(activity); - - // Hosting in 2,3 creates Activity ignoring the request-id. The request-id is not w3c compatible - // hence SDK also ignores them, and just uses Activity from Hosting. - // Validate that activity is Not created by SDK Hosting - Assert.NotEqual(ActivityCreatedByHostingDiagnosticListener, activity.OperationName); - Assert.Equal(tags, activity.Tags.ToDictionary(kvp => kvp.Key, kvp => kvp.Value)); - - Assert.Single(activity.Baggage.Where(b => b.Key == "prop1" && b.Value == "value1")); - Assert.Single(activity.Baggage.Where(b => b.Key == "prop2" && b.Value == "value2")); - - Assert.NotNull(context.Features.Get()); - - HandleRequestEnd(hostingListener, context, 0, aspNetCoreMajorVersion); - - Assert.Single(sentTelemetry); - var requestTelemetry = (RequestTelemetry)this.sentTelemetry.Single(); - ValidateRequestTelemetry(requestTelemetry, activity, IsW3C, expectedParentId: requestId, expectedSource: null); - - if (IsW3C) - { - Assert.Equal("somerequestidsomeformat", requestTelemetry.Properties[HostingDiagnosticListener.LegacyRootIdProperty]); - Assert.NotEqual("somerequestidsomeformat", requestTelemetry.Context.Operation.Id); - } - else - { - Assert.Equal("somerequestidsomeformat", requestTelemetry.Context.Operation.Id); - } - - Assert.Equal("value1", requestTelemetry.Properties["prop1"]); - Assert.Equal("value2", requestTelemetry.Properties["prop2"]); - } - } - - [Theory] - [InlineData(AspNetCoreMajorVersion.Two, true)] - [InlineData(AspNetCoreMajorVersion.Three, true)] - [InlineData(AspNetCoreMajorVersion.Two, false)] - [InlineData(AspNetCoreMajorVersion.Three, false)] - public void RequestWithW3CTraceParentCreateNewActivityAndPopulateRequestTelemetry(AspNetCoreMajorVersion aspNetCoreMajorVersion, - bool isW3C) - { - // Tests Request correlation when incoming request has only Request-ID headers. - HttpContext context = CreateContext(HttpRequestScheme, HttpRequestHost, "/Test", method: "POST"); - // Trace Parent - var traceParent = "00-4e3083444c10254ba40513c7316332eb-e2a5f830c0ee2c46-00"; - context.Request.Headers[Microsoft.ApplicationInsights.W3C.W3CConstants.TraceParentHeader] = traceParent; - context.Request.Headers[Microsoft.ApplicationInsights.W3C.W3CConstants.TraceStateHeader] = "w3cprop1=value1, w3cprop2=value2"; - context.Request.Headers[RequestResponseHeaders.CorrelationContextHeader] = "prop1=value1, prop2=value2"; - - var tags = new Dictionary - { - ["tag1"] = "v1", - ["tag2"] = "v2", - }; - - using (var hostingListener = CreateHostingListener(aspNetCoreMajorVersion, isW3C: isW3C)) - { - HandleRequestBegin(hostingListener, context, 0, aspNetCoreMajorVersion, tags); - var activity = Activity.Current; - Assert.NotNull(activity); - - if (aspNetCoreMajorVersion == AspNetCoreMajorVersion.Two && isW3C) - { - Assert.Equal(ActivityCreatedByHostingDiagnosticListener, activity.OperationName); - Assert.Equal(tags, activity.Tags.ToDictionary(kvp => kvp.Key, kvp => kvp.Value)); - } - else if (aspNetCoreMajorVersion == AspNetCoreMajorVersion.Three) - { - // in W3C Mode, SDK Hosting simply uses Activity from Hosting. Validate the same. - Assert.NotEqual(ActivityCreatedByHostingDiagnosticListener, activity.OperationName); - } - - if (isW3C) - { - Assert.Equal("w3cprop1=value1, w3cprop2=value2", activity.TraceStateString); - } - - Assert.NotNull(context.Features.Get()); - - HandleRequestEnd(hostingListener, context, 0, aspNetCoreMajorVersion); - - Assert.Single(sentTelemetry); - var requestTelemetry = (RequestTelemetry)this.sentTelemetry.Single(); - - if (isW3C) - { - // parentid populated only in W3C mode - ValidateRequestTelemetry(requestTelemetry, activity, true, expectedParentId: "e2a5f830c0ee2c46", expectedSource: null); - Assert.Equal("value1", requestTelemetry.Properties["prop1"]); - Assert.Equal("value2", requestTelemetry.Properties["prop2"]); - } - else - { - ValidateRequestTelemetry(requestTelemetry, activity, false, expectedParentId: null, expectedSource: null); - } - } - } - - [Theory] - [InlineData(AspNetCoreMajorVersion.Two, true)] - [InlineData(AspNetCoreMajorVersion.Three, true)] - [InlineData(AspNetCoreMajorVersion.Two, false)] - [InlineData(AspNetCoreMajorVersion.Three, false)] - public void RequestWithW3CTraceParentButInvalidEntryCreateNewActivityAndPopulateRequestTelemetry( - AspNetCoreMajorVersion aspNetCoreMajorVersion, - bool isW3C) - { - // Tests Request correlation when incoming request has only Request-ID headers. - HttpContext context = CreateContext(HttpRequestScheme, HttpRequestHost, "/Test", method: "POST"); - // Trace Parent which does not follow w3c spec. - var traceParent = "004e3083444c10254ba40513c7316332eb-e2a5f830c0ee2c4600"; - context.Request.Headers[Microsoft.ApplicationInsights.W3C.W3CConstants.TraceParentHeader] = traceParent; - context.Request.Headers[Microsoft.ApplicationInsights.W3C.W3CConstants.TraceStateHeader] = "prop1=value1, prop2=value2"; - - using (var hostingListener = CreateHostingListener(aspNetCoreMajorVersion, isW3C: isW3C)) - { - HandleRequestBegin(hostingListener, context, 0, aspNetCoreMajorVersion); - var activity = Activity.Current; - Assert.NotNull(activity); - Assert.NotEqual(traceParent, activity.Id); - - if (isW3C) - { - Assert.Equal("prop1=value1, prop2=value2", activity.TraceStateString); - } - - Assert.NotNull(context.Features.Get()); - - HandleRequestEnd(hostingListener, context, 0, aspNetCoreMajorVersion); - - Assert.Single(sentTelemetry); - var requestTelemetry = (RequestTelemetry)this.sentTelemetry.Single(); - - if (isW3C) - { - // parentid populated only in W3C mode - ValidateRequestTelemetry(requestTelemetry, activity, true, expectedParentId: traceParent, expectedSource: null); - } - else - { - ValidateRequestTelemetry(requestTelemetry, activity, false, expectedParentId: null, expectedSource: null); - } - } - } - - [Theory] - [InlineData(AspNetCoreMajorVersion.Two, true)] - [InlineData(AspNetCoreMajorVersion.Three, true)] - [InlineData(AspNetCoreMajorVersion.Two, false)] - // Commenting out unsupported scenario. We may support this in future. [InlineData(AspNetCoreMajorVersion.Three, false)] - public void RequestWithBothW3CAndRequestIdCreateNewActivityAndPopulateRequestTelemetry(AspNetCoreMajorVersion aspNetCoreMajorVersion, bool IsW3C) - { - // Tests Request correlation when incoming request has both W3C TraceParent and Request-ID headers, - HttpContext context = CreateContext(HttpRequestScheme, HttpRequestHost, "/Test", method: "POST"); - // Trace Parent - var traceParent = "00-4e3083444c10254ba40513c7316332eb-e2a5f830c0ee2c46-00"; - context.Request.Headers[Microsoft.ApplicationInsights.W3C.W3CConstants.TraceParentHeader] = traceParent; - - // And Request ID - var requestId = "|40d1a5a08a68c0998e4a3b7c91915ca6.b9e41c35_1."; - context.Request.Headers[RequestResponseHeaders.RequestIdHeader] = requestId; - context.Request.Headers[RequestResponseHeaders.CorrelationContextHeader] = "prop1=value1, prop2=value2"; - - using (var hostingListener = CreateHostingListener(aspNetCoreMajorVersion, isW3C: IsW3C)) - { - HandleRequestBegin(hostingListener, context, 0, aspNetCoreMajorVersion); - var activity = Activity.Current; - Assert.NotNull(activity); - - Assert.NotNull(context.Features.Get()); - - HandleRequestEnd(hostingListener, context, 0, aspNetCoreMajorVersion); - - Assert.Single(sentTelemetry); - var requestTelemetry = (RequestTelemetry)this.sentTelemetry.Single(); - - if (IsW3C) - { - Assert.Equal("4e3083444c10254ba40513c7316332eb", requestTelemetry.Context.Operation.Id); - ValidateRequestTelemetry(requestTelemetry, activity, IsW3C, expectedParentId: "e2a5f830c0ee2c46", expectedSource:null); - } - else - { - Assert.Equal("40d1a5a08a68c0998e4a3b7c91915ca6", requestTelemetry.Context.Operation.Id); - ValidateRequestTelemetry(requestTelemetry, activity, IsW3C, expectedParentId: requestId, expectedSource: null); - } - - Assert.Equal("value1", requestTelemetry.Properties["prop1"]); - Assert.Equal("value2", requestTelemetry.Properties["prop2"]); - } - } - - [Theory] - [InlineData(AspNetCoreMajorVersion.Two, true)] - [InlineData(AspNetCoreMajorVersion.Three, true)] - [InlineData(AspNetCoreMajorVersion.Two, false)] - [InlineData(AspNetCoreMajorVersion.Three, false)] - public void RequestWithOutCorrelationHeaderStillReadsCorrelationContextIntoActivity(AspNetCoreMajorVersion aspNetCoreMajorVersion, bool isW3C) - { - // Tests Correlation-Context is read and populated even when neither request-id nor traceparent is present. - HttpContext context = CreateContext(HttpRequestScheme, HttpRequestHost, "/Test", method: "POST"); - - // Just correlationcontext - context.Request.Headers[RequestResponseHeaders.CorrelationContextHeader] = "prop1=value1, prop2=value2"; - - using (var hostingListener = CreateHostingListener(aspNetCoreMajorVersion, isW3C: isW3C)) - { - HandleRequestBegin(hostingListener, context, 0, aspNetCoreMajorVersion); - var activity = Activity.Current; - Assert.NotNull(activity); - - // Activity baggage should be populated by SDK request collection module. - Assert.Single(activity.Baggage.Where(b => b.Key == "prop1" && b.Value == "value1")); - Assert.Single(activity.Baggage.Where(b => b.Key == "prop2" && b.Value == "value2")); - Assert.NotNull(context.Features.Get()); - - HandleRequestEnd(hostingListener, context, 0, aspNetCoreMajorVersion); - - Assert.Single(sentTelemetry); - var requestTelemetry = (RequestTelemetry)this.sentTelemetry.Single(); - - ValidateRequestTelemetry(requestTelemetry, activity, isW3C, expectedParentId: null, expectedSource: null); - - // Enriching telemetry from activity baggage is done by base sdk, still validating it here. - Assert.Equal("value1", requestTelemetry.Properties["prop1"]); - Assert.Equal("value2", requestTelemetry.Properties["prop2"]); - } - } - - [Theory] - [InlineData("prop1", AspNetCoreMajorVersion.Three)] - [InlineData(", , ,,", AspNetCoreMajorVersion.Three)] - [InlineData(",", AspNetCoreMajorVersion.Three)] - [InlineData(" ", AspNetCoreMajorVersion.Three)] - [InlineData("prop1", AspNetCoreMajorVersion.Two)] - [InlineData(", , ,,", AspNetCoreMajorVersion.Two)] - [InlineData(",", AspNetCoreMajorVersion.Two)] - [InlineData(" ", AspNetCoreMajorVersion.Two)] - public void RequestPopulateCorrelationHeaderVariousInputsNone(string correlationcontext, AspNetCoreMajorVersion aspNetCoreMajorVersion) - { - // Tests Correlation-Context is read and populated even when neither request-id nor traceparent is present. - HttpContext context = CreateContext(HttpRequestScheme, HttpRequestHost, "/Test", method: "POST"); - context.Request.Headers[RequestResponseHeaders.CorrelationContextHeader] = correlationcontext; - - using (var hostingListener = CreateHostingListener(aspNetCoreMajorVersion)) - { - HandleRequestBegin(hostingListener, context, 0, aspNetCoreMajorVersion); - var activity = Activity.Current; - Assert.NotNull(activity); - - foreach (var bag in activity.Baggage) - { - this.output.WriteLine($"bag.key {bag.Key} bag.value {bag.Value}"); - } - Assert.Empty(activity.Baggage); - - Assert.NotNull(context.Features.Get()); - - HandleRequestEnd(hostingListener, context, 0, aspNetCoreMajorVersion); - - Assert.Single(sentTelemetry); - var requestTelemetry = (RequestTelemetry)this.sentTelemetry.Single(); - - ValidateRequestTelemetry(requestTelemetry, activity, true, expectedParentId: null, expectedSource: null); - } - } - - [Theory] - [InlineData("prop1=value1, prop2=", AspNetCoreMajorVersion.Three)] - [InlineData("prop1=value1, prop2", AspNetCoreMajorVersion.Three)] - [InlineData("123, prop1=value1", AspNetCoreMajorVersion.Three)] - [InlineData("prop1=value1", AspNetCoreMajorVersion.Three)] - [InlineData("prop1=value1, prop2=", AspNetCoreMajorVersion.Two)] - [InlineData("prop1=value1, prop2", AspNetCoreMajorVersion.Two)] - [InlineData("123, prop1=value1", AspNetCoreMajorVersion.Two)] - [InlineData("prop1=value1", AspNetCoreMajorVersion.Two)] - public void RequestPopulateCorrelationHeaderVariousInputsOne(string correlationcontext, AspNetCoreMajorVersion aspNetCoreMajorVersion) - { - // Tests Correlation-Context is read and populated even when neither request-id nor traceparent is present. - HttpContext context = CreateContext(HttpRequestScheme, HttpRequestHost, "/Test", method: "POST"); - context.Request.Headers[RequestResponseHeaders.CorrelationContextHeader] = correlationcontext; - - using (var hostingListener = CreateHostingListener(aspNetCoreMajorVersion)) - { - HandleRequestBegin(hostingListener, context, 0, aspNetCoreMajorVersion); - var activity = Activity.Current; - Assert.NotNull(activity); - - foreach (var bag in activity.Baggage) - { - this.output.WriteLine($"bag.key {bag.Key} bag.value {bag.Value}"); - } - Assert.Single(activity.Baggage.Where(b => b.Key == "prop1" && b.Value == "value1")); - - Assert.NotNull(context.Features.Get()); - - HandleRequestEnd(hostingListener, context, 0, aspNetCoreMajorVersion); - - Assert.Single(sentTelemetry); - var requestTelemetry = (RequestTelemetry)this.sentTelemetry.Single(); - - ValidateRequestTelemetry(requestTelemetry, activity, true, expectedParentId: null, expectedSource: null); - } - } - - [Theory] - [InlineData("prop1=value1,prop2=value2", AspNetCoreMajorVersion.Three)] - [InlineData("prop1=value1 , prop2= value2", AspNetCoreMajorVersion.Three)] - [InlineData("123, prop1=value1, prop2=value2,567,=", AspNetCoreMajorVersion.Three)] - [InlineData("prop1=value1,prop2=value2", AspNetCoreMajorVersion.Two)] - [InlineData("prop1=value1 , prop2= value2", AspNetCoreMajorVersion.Two)] - [InlineData("123, prop1=value1, prop2=value2,567,=", AspNetCoreMajorVersion.Two)] - public void RequestPopulateCorrelationHeaderVariousInputsTwo(string correlationcontext, AspNetCoreMajorVersion aspNetCoreMajorVersion) - { - // Tests Correlation-Context is read and populated even when neither request-id nor traceparent is present. - HttpContext context = CreateContext(HttpRequestScheme, HttpRequestHost, "/Test", method: "POST"); - context.Request.Headers[RequestResponseHeaders.CorrelationContextHeader] = correlationcontext; - - using (var hostingListener = CreateHostingListener(aspNetCoreMajorVersion)) - { - HandleRequestBegin(hostingListener, context, 0, aspNetCoreMajorVersion); - var activity = Activity.Current; - Assert.NotNull(activity); - - foreach(var bag in activity.Baggage) - { - this.output.WriteLine($"bag.key {bag.Key} bag.value {bag.Value}"); - } - Assert.Single(activity.Baggage.Where(b => b.Key == "prop1" && b.Value == "value1")); - Assert.Single(activity.Baggage.Where(b => b.Key == "prop2" && b.Value == "value2")); - - Assert.NotNull(context.Features.Get()); - - HandleRequestEnd(hostingListener, context, 0, aspNetCoreMajorVersion); - - Assert.Single(sentTelemetry); - var requestTelemetry = (RequestTelemetry)this.sentTelemetry.Single(); - - ValidateRequestTelemetry(requestTelemetry, activity, true, expectedParentId: null, expectedSource: null); - } - } - - [Theory] - [InlineData(true)] - [InlineData(false)] - public void OnHttpRequestInStartInitializeTelemetryIfActivityParentIdIsNotNull(bool isW3C) - { - var context = CreateContext(HttpRequestScheme, HttpRequestHost, "/Test", method: "POST"); - - var parent = "|8ee8641cbdd8dd280d239fa2121c7e4e.df07da90a5b27d93."; - context.Request.Headers[RequestResponseHeaders.RequestIdHeader] = parent; - - Activity activity; - Activity activityBySDK; - - using (var hostingListener = CreateHostingListener(AspNetCoreMajorVersion.Two, isW3C: isW3C)) - { - activity = new Activity("operation"); - - // pretend ASP.NET Core read it - activity.SetParentId(parent); - activity.AddBaggage("item1", "value1"); - activity.AddBaggage("item2", "value2"); - - activity.Start(); - HandleRequestBegin(hostingListener, context, 0, AspNetCoreMajorVersion.Two); - activityBySDK = Activity.Current; - this.output.WriteLine(activityBySDK.Id); - this.output.WriteLine(activity.Id); - HandleRequestEnd(hostingListener, context, 0, AspNetCoreMajorVersion.Two); - } - - Assert.Single(sentTelemetry); - var requestTelemetry = this.sentTelemetry.First() as RequestTelemetry; - - ValidateRequestTelemetry(requestTelemetry, activityBySDK, isW3C, expectedParentId: "|8ee8641cbdd8dd280d239fa2121c7e4e.df07da90a5b27d93."); - Assert.Equal("8ee8641cbdd8dd280d239fa2121c7e4e", requestTelemetry.Context.Operation.Id); - Assert.Equal(requestTelemetry.Properties.Count, activity.Baggage.Count()); - - foreach (var prop in activity.Baggage) - { - Assert.True(requestTelemetry.Properties.ContainsKey(prop.Key)); - Assert.Equal(requestTelemetry.Properties[prop.Key], prop.Value); - } - } - - [Theory] - [InlineData(AspNetCoreMajorVersion.Two)] - [InlineData(AspNetCoreMajorVersion.Three)] - public void OnEndRequestSetsRequestNameToMethodAndPathForPostRequest(AspNetCoreMajorVersion aspNetCoreMajorVersion) - { - HttpContext context = CreateContext(HttpRequestScheme, HttpRequestHost, "/Test", method: "POST"); - - using (var hostingListener = CreateHostingListener(aspNetCoreMajorVersion)) - { - HandleRequestBegin(hostingListener, context, 0, aspNetCoreMajorVersion); - - Assert.NotNull(context.Features.Get()); - Assert.Equal(CommonMocks.TestApplicationId, - HttpHeadersUtilities.GetRequestContextKeyValue(context.Response.Headers, RequestResponseHeaders.RequestContextTargetKey)); - - HandleRequestEnd(hostingListener, context, 0, aspNetCoreMajorVersion); - } - - Assert.Single(sentTelemetry); - Assert.IsType(this.sentTelemetry.First()); - RequestTelemetry requestTelemetry = this.sentTelemetry.Single() as RequestTelemetry; - Assert.True(requestTelemetry.Duration.TotalMilliseconds >= 0); - Assert.True(requestTelemetry.Success); - Assert.Equal(CommonMocks.InstrumentationKey, requestTelemetry.Context.InstrumentationKey); - Assert.True(string.IsNullOrEmpty(requestTelemetry.Source)); - Assert.Equal(CreateUri(HttpRequestScheme, HttpRequestHost, "/Test"), requestTelemetry.Url); - Assert.NotEmpty(requestTelemetry.Context.GetInternalContext().SdkVersion); - Assert.Contains(SdkVersionTestUtils.VersionPrefix, requestTelemetry.Context.GetInternalContext().SdkVersion); - Assert.Equal("POST /Test", requestTelemetry.Name); - } - - [Theory] - [InlineData(AspNetCoreMajorVersion.Two)] - [InlineData(AspNetCoreMajorVersion.Three)] - public void OnEndRequestSetsRequestNameToMethodAndPath(AspNetCoreMajorVersion aspNetCoreMajorVersion) - { - HttpContext context = CreateContext(HttpRequestScheme, HttpRequestHost, "/Test", method: "GET"); - TelemetryConfiguration config = TelemetryConfiguration.CreateDefault(); - - using (var hostingListener = CreateHostingListener(aspNetCoreMajorVersion, config)) - { - HandleRequestBegin(hostingListener, context, 0, aspNetCoreMajorVersion); - - Assert.NotNull(context.Features.Get()); - - HandleRequestEnd(hostingListener, context, 0, aspNetCoreMajorVersion); - } - - Assert.NotNull(this.sentTelemetry); - Assert.IsType(this.sentTelemetry.First()); - RequestTelemetry requestTelemetry = this.sentTelemetry.First() as RequestTelemetry; - Assert.True(requestTelemetry.Duration.TotalMilliseconds >= 0); - Assert.True(requestTelemetry.Success); - Assert.Equal(CommonMocks.InstrumentationKey, requestTelemetry.Context.InstrumentationKey); - Assert.True(string.IsNullOrEmpty(requestTelemetry.Source)); - Assert.Equal(CreateUri(HttpRequestScheme, HttpRequestHost, "/Test"), requestTelemetry.Url); - Assert.NotEmpty(requestTelemetry.Context.GetInternalContext().SdkVersion); - Assert.Contains(SdkVersionTestUtils.VersionPrefix, requestTelemetry.Context.GetInternalContext().SdkVersion); - Assert.Equal("GET /Test", requestTelemetry.Name); - } - - [Theory] - [InlineData(AspNetCoreMajorVersion.Two)] - [InlineData(AspNetCoreMajorVersion.Three)] - public void OnEndRequestFromSameInstrumentationKey(AspNetCoreMajorVersion aspNetCoreMajorVersion) - { - HttpContext context = CreateContext(HttpRequestScheme, HttpRequestHost, "/Test", method: "GET"); - HttpHeadersUtilities.SetRequestContextKeyValue(context.Request.Headers, RequestResponseHeaders.RequestContextSourceKey, CommonMocks.TestApplicationId); - - using (var hostingListener = CreateHostingListener(aspNetCoreMajorVersion)) - { - HandleRequestBegin(hostingListener, context, 0, aspNetCoreMajorVersion); - - Assert.NotNull(context.Features.Get()); - Assert.Equal(CommonMocks.TestApplicationId, - HttpHeadersUtilities.GetRequestContextKeyValue(context.Response.Headers, RequestResponseHeaders.RequestContextTargetKey)); - - HandleRequestEnd(hostingListener, context, 0, aspNetCoreMajorVersion); - } - - Assert.NotNull(this.sentTelemetry); - Assert.IsType(this.sentTelemetry.First()); - RequestTelemetry requestTelemetry = this.sentTelemetry.First() as RequestTelemetry; - Assert.True(requestTelemetry.Duration.TotalMilliseconds >= 0); - Assert.True(requestTelemetry.Success); - Assert.Equal(CommonMocks.InstrumentationKey, requestTelemetry.Context.InstrumentationKey); - Assert.True(string.IsNullOrEmpty(requestTelemetry.Source)); - Assert.Equal(CreateUri(HttpRequestScheme, HttpRequestHost, "/Test"), requestTelemetry.Url); - Assert.NotEmpty(requestTelemetry.Context.GetInternalContext().SdkVersion); - Assert.Contains(SdkVersionTestUtils.VersionPrefix, requestTelemetry.Context.GetInternalContext().SdkVersion); - Assert.Equal("GET /Test", requestTelemetry.Name); - } - - [Theory] - [InlineData(AspNetCoreMajorVersion.Two)] - [InlineData(AspNetCoreMajorVersion.Three)] - public void OnEndRequestFromDifferentInstrumentationKey(AspNetCoreMajorVersion aspNetCoreMajorVersion) - { - HttpContext context = CreateContext(HttpRequestScheme, HttpRequestHost, "/Test", method: "GET"); - HttpHeadersUtilities.SetRequestContextKeyValue(context.Request.Headers, RequestResponseHeaders.RequestContextSourceKey, "DIFFERENT_APP_ID"); - - using (var hostingListener = CreateHostingListener(aspNetCoreMajorVersion)) - { - HandleRequestBegin(hostingListener, context, 0, aspNetCoreMajorVersion); - - Assert.NotNull(context.Features.Get()); - Assert.Equal(CommonMocks.TestApplicationId, - HttpHeadersUtilities.GetRequestContextKeyValue(context.Response.Headers, - RequestResponseHeaders.RequestContextTargetKey)); - - HandleRequestEnd(hostingListener, context, 0, aspNetCoreMajorVersion); - } - - Assert.Single(sentTelemetry); - Assert.IsType(this.sentTelemetry.First()); - RequestTelemetry requestTelemetry = this.sentTelemetry.First() as RequestTelemetry; - Assert.True(requestTelemetry.Duration.TotalMilliseconds >= 0); - Assert.True(requestTelemetry.Success); - Assert.Equal(CommonMocks.InstrumentationKey, requestTelemetry.Context.InstrumentationKey); - Assert.Equal("DIFFERENT_APP_ID", requestTelemetry.Source); - Assert.Equal(CreateUri(HttpRequestScheme, HttpRequestHost, "/Test"), requestTelemetry.Url); - Assert.NotEmpty(requestTelemetry.Context.GetInternalContext().SdkVersion); - Assert.Contains(SdkVersionTestUtils.VersionPrefix, requestTelemetry.Context.GetInternalContext().SdkVersion); - Assert.Equal("GET /Test", requestTelemetry.Name); - } - - [Theory] - [InlineData(AspNetCoreMajorVersion.Two)] - [InlineData(AspNetCoreMajorVersion.Three)] - public async void SimultaneousRequestsGetDifferentIds(AspNetCoreMajorVersion aspNetCoreMajorVersion) - { - var context1 = new DefaultHttpContext(); - context1.Request.Scheme = HttpRequestScheme; - context1.Request.Host = HttpRequestHost; - context1.Request.Method = "GET"; - context1.Request.Path = "/Test?id=1"; - - var context2 = new DefaultHttpContext(); - context2.Request.Scheme = HttpRequestScheme; - context2.Request.Host = HttpRequestHost; - context2.Request.Method = "GET"; - context2.Request.Path = "/Test?id=2"; - - using (var hostingListener = CreateHostingListener(aspNetCoreMajorVersion)) - { - var task1 = Task.Run(() => - { - var act = new Activity("operation1"); - act.Start(); - HandleRequestBegin(hostingListener, context1, 0, aspNetCoreMajorVersion); - HandleRequestEnd(hostingListener, context1, 0, aspNetCoreMajorVersion); - }); - - var task2 = Task.Run(() => - { - var act = new Activity("operation2"); - act.Start(); - HandleRequestBegin(hostingListener, context2, 0, aspNetCoreMajorVersion); - HandleRequestEnd(hostingListener, context2, 0, aspNetCoreMajorVersion); - }); - - await Task.WhenAll(task1, task2); - - Assert.Equal(2, sentTelemetry.Count); - - var telemetries = this.sentTelemetry.ToArray(); - Assert.IsType(telemetries[0]); - Assert.IsType(telemetries[1]); - var id1 = ((RequestTelemetry) telemetries[0]).Id; - var id2 = ((RequestTelemetry) telemetries[1]).Id; - Assert.NotEqual(id1, id2); - } - } - - [Theory] - [InlineData(AspNetCoreMajorVersion.Two)] - [InlineData(AspNetCoreMajorVersion.Three)] - public void SetsSourceProvidedInHeaders(AspNetCoreMajorVersion aspNetCoreMajorVersion) - { - HttpContext context = CreateContext(HttpRequestScheme, HttpRequestHost); - HttpHeadersUtilities.SetRequestContextKeyValue(context.Request.Headers, RequestResponseHeaders.RequestContextTargetKey, "someAppId"); - - using (var hostingListener = CreateHostingListener(aspNetCoreMajorVersion)) - { - HandleRequestBegin(hostingListener, context, 0, aspNetCoreMajorVersion); - HandleRequestEnd(hostingListener, context, 0, aspNetCoreMajorVersion); - } - - Assert.Single(sentTelemetry); - Assert.IsType(this.sentTelemetry.Single()); - RequestTelemetry requestTelemetry = this.sentTelemetry.OfType().Single(); - - Assert.Equal("someAppId", requestTelemetry.Source); - } - - [Theory] - [InlineData(AspNetCoreMajorVersion.Two)] - [InlineData(AspNetCoreMajorVersion.Three)] - public void ResponseHeadersAreNotInjectedWhenDisabled(AspNetCoreMajorVersion aspNetCoreMajorVersion) - { - HttpContext context = CreateContext(HttpRequestScheme, HttpRequestHost); - - using (var noHeadersMiddleware = new HostingDiagnosticListener( - CommonMocks.MockTelemetryClient(telemetry => this.sentTelemetry.Enqueue(telemetry)), - CommonMocks.GetMockApplicationIdProvider(), - injectResponseHeaders: false, - trackExceptions: true, - enableW3CHeaders: false, - aspNetCoreMajorVersion: GetAspNetCoreMajorVersion(aspNetCoreMajorVersion))) - { - noHeadersMiddleware.OnSubscribe(); - - HandleRequestBegin(noHeadersMiddleware, context, 0, aspNetCoreMajorVersion); - Assert.False(context.Response.Headers.ContainsKey(RequestResponseHeaders.RequestContextHeader)); - - HandleRequestEnd(noHeadersMiddleware, context, 0, aspNetCoreMajorVersion); - Assert.False(context.Response.Headers.ContainsKey(RequestResponseHeaders.RequestContextHeader)); - - Assert.Single(sentTelemetry); - Assert.IsType(this.sentTelemetry.First()); - } - } - - [Theory] - [InlineData(AspNetCoreMajorVersion.Two)] - [InlineData(AspNetCoreMajorVersion.Three)] - public void DoesntAddSourceIfRequestHeadersDontHaveSource(AspNetCoreMajorVersion aspNetCoreMajorVersion) - { - HttpContext context = CreateContext(HttpRequestScheme, HttpRequestHost); - - using (var hostingListener = CreateHostingListener(aspNetCoreMajorVersion)) - { - HandleRequestBegin(hostingListener, context, 0, aspNetCoreMajorVersion); - HandleRequestEnd(hostingListener, context, 0, aspNetCoreMajorVersion); - } - - Assert.Single(sentTelemetry); - Assert.IsType(this.sentTelemetry.Single()); - RequestTelemetry requestTelemetry = this.sentTelemetry.OfType().Single(); - - Assert.True(string.IsNullOrEmpty(requestTelemetry.Source)); - } - - [Theory] - [InlineData(AspNetCoreMajorVersion.Two)] - [InlineData(AspNetCoreMajorVersion.Three)] - public void RequestTelemetryIsProactivelySampledOutIfFeatureFlagIsOn(AspNetCoreMajorVersion aspNetCoreMajorVersion) - { - TelemetryConfiguration config = TelemetryConfiguration.CreateDefault(); - config.ExperimentalFeatures.Add("proactiveSampling"); - config.SetLastObservedSamplingPercentage(SamplingTelemetryItemTypes.Request, 0); - - HttpContext context = CreateContext(HttpRequestScheme, HttpRequestHost, "/Test", method: "POST"); - - using (var hostingListener = CreateHostingListener(aspNetCoreMajorVersion, config)) - { - HandleRequestBegin(hostingListener, context, 0, aspNetCoreMajorVersion); - - Assert.NotNull(Activity.Current); - - var requestTelemetry = context.Features.Get(); - Assert.NotNull(requestTelemetry); - Assert.Equal(SamplingDecision.SampledOut, requestTelemetry.ProactiveSamplingDecision); - ValidateRequestTelemetry(requestTelemetry, Activity.Current, true); - Assert.Null(requestTelemetry.Context.Operation.ParentId); - } - } - - [Theory] - [InlineData(AspNetCoreMajorVersion.Two)] - [InlineData(AspNetCoreMajorVersion.Three)] - public void RequestTelemetryIsProactivelySampledInIfFeatureFlagIsOnButActivityIsRecorded(AspNetCoreMajorVersion aspNetCoreMajorVersion) - { - TelemetryConfiguration config = TelemetryConfiguration.CreateDefault(); - config.ExperimentalFeatures.Add("proactiveSampling"); - config.SetLastObservedSamplingPercentage(SamplingTelemetryItemTypes.Request, 0); - - HttpContext context = CreateContext(HttpRequestScheme, HttpRequestHost, "/Test", method: "POST"); - var traceParent = "00-4e3083444c10254ba40513c7316332eb-e2a5f830c0ee2c46-01"; - context.Request.Headers[Microsoft.ApplicationInsights.W3C.W3CConstants.TraceParentHeader] = traceParent; - - using (var hostingListener = CreateHostingListener(aspNetCoreMajorVersion, config, true)) - { - HandleRequestBegin(hostingListener, context, 0, aspNetCoreMajorVersion); - - Assert.NotNull(Activity.Current); - Assert.True(Activity.Current.Recorded); - - var requestTelemetry = context.Features.Get(); - Assert.NotNull(requestTelemetry); - Assert.NotEqual(SamplingDecision.SampledOut, requestTelemetry.ProactiveSamplingDecision); - ValidateRequestTelemetry(requestTelemetry, Activity.Current, true, "e2a5f830c0ee2c46"); - } - } - - [Theory] - [InlineData(AspNetCoreMajorVersion.Two)] - [InlineData(AspNetCoreMajorVersion.Three)] - public void RequestTelemetryIsNotProactivelySampledOutIfFeatureFlagIfOff(AspNetCoreMajorVersion aspNetCoreMajorVersion) - { - TelemetryConfiguration config = TelemetryConfiguration.CreateDefault(); - config.SetLastObservedSamplingPercentage(SamplingTelemetryItemTypes.Request, 0); - - HttpContext context = CreateContext(HttpRequestScheme, HttpRequestHost, "/Test", method: "POST"); - - using (var hostingListener = CreateHostingListener(aspNetCoreMajorVersion, config)) - { - HandleRequestBegin(hostingListener, context, 0, aspNetCoreMajorVersion); - - Assert.NotNull(Activity.Current); - - var requestTelemetry = context.Features.Get(); - Assert.NotNull(requestTelemetry); - Assert.NotEqual(SamplingDecision.SampledOut, requestTelemetry.ProactiveSamplingDecision); - ValidateRequestTelemetry(requestTelemetry, Activity.Current, true); - Assert.Null(requestTelemetry.Context.Operation.ParentId); - } - } - - [Theory] - [Trait("Trait", "RoleName")] - [InlineData(AspNetCoreMajorVersion.Two)] - [InlineData(AspNetCoreMajorVersion.Three)] - public void VerifyRequestsUpdateRoleNameContainer(AspNetCoreMajorVersion aspNetCoreMajorVersion) - { - HttpContext context = CreateContext(HttpRequestScheme, HttpRequestHost, "/Test", method: "POST"); - - RoleNameContainer.Instance = new RoleNameContainer(hostNameSuffix: ".azurewebsites.net"); - - using (var hostingListener = CreateHostingListener(aspNetCoreMajorVersion)) - { - context.Request.Headers["WAS-DEFAULT-HOSTNAME"] = "a.b.c.azurewebsites.net"; - HandleRequestBegin(hostingListener, context, 0, aspNetCoreMajorVersion); - Assert.Equal("a.b.c", RoleNameContainer.Instance.RoleName); - - context.Request.Headers["WAS-DEFAULT-HOSTNAME"] = "d.e.f.azurewebsites.net"; - HandleRequestBegin(hostingListener, context, 0, aspNetCoreMajorVersion); - Assert.Equal("d.e.f", RoleNameContainer.Instance.RoleName); - } - } - - [Theory] - [InlineData(AspNetCoreMajorVersion.Two)] - [InlineData(AspNetCoreMajorVersion.Three)] - public void VerifyLongRunningRequestDoesNotGenerateTelemetry(AspNetCoreMajorVersion aspNetCoreMajorVersion) - { - HttpContext context = CreateContext(HttpRequestScheme, HttpRequestHost); - TelemetryConfiguration config = TelemetryConfiguration.CreateDefault(); - - using (var hostingListener = CreateHostingListener(aspNetCoreMajorVersion, config)) - { - HandleRequestBegin(hostingListener, context, 0, aspNetCoreMajorVersion); - - var activity = Activity.Current; - activity.AddTag("http.long_running", "true"); - Assert.NotNull(activity); - - Assert.NotNull(context.Features.Get()); - - HandleRequestEnd(hostingListener, context, 0, aspNetCoreMajorVersion); - - Assert.Empty(sentTelemetry); - } - } - - [Theory] - [InlineData(AspNetCoreMajorVersion.Two)] - [InlineData(AspNetCoreMajorVersion.Three)] - public void NullActivityDoesGenerateTelemetry(AspNetCoreMajorVersion aspNetCoreMajorVersion) - { - HttpContext context = CreateContext(HttpRequestScheme, HttpRequestHost); - TelemetryConfiguration config = TelemetryConfiguration.CreateDefault(); - - using (var hostingListener = CreateHostingListener(aspNetCoreMajorVersion, config)) - { - HandleRequestBegin(hostingListener, context, 0, aspNetCoreMajorVersion); - - Activity.Current = null; - Assert.NotNull(context.Features.Get()); - - HandleRequestEnd(hostingListener, context, 0, aspNetCoreMajorVersion); - - Assert.Single(sentTelemetry); - } - } - - private void HandleRequestBegin( - HostingDiagnosticListener hostingListener, - HttpContext context, - long timestamp, - AspNetCoreMajorVersion aspNetCoreMajorVersion, - IEnumerable> tags = null) - { - if (aspNetCoreMajorVersion == AspNetCoreMajorVersion.Two) - { - if (Activity.Current == null) - { - var activity = new Activity("operation"); - - if (tags != null) - { - foreach (var tag in tags) - { - activity.AddTag(tag.Key, tag.Value); - } - } - - // Simulating the behaviour of Hosting layer in 2.xx, which parses Request-Id Header and - // set Activity parent. - if (context.Request.Headers.TryGetValue("Request-Id", out var requestId)) - { - activity.SetParentId(requestId); - - string[] baggage = context.Request.Headers.GetCommaSeparatedValues(RequestResponseHeaders.CorrelationContextHeader); - if (baggage != StringValues.Empty && !activity.Baggage.Any()) - { - foreach (var item in baggage) - { - var parts = item.Split('='); - if (parts.Length == 2) - { - var itemName = StringUtilities.EnforceMaxLength(parts[0], InjectionGuardConstants.ContextHeaderKeyMaxLength); - var itemValue = StringUtilities.EnforceMaxLength(parts[1], InjectionGuardConstants.ContextHeaderValueMaxLength); - activity.AddBaggage(itemName, itemValue); - } - } - } - } - activity.Start(); - this.output.WriteLine("Test code created and started Activity to simulate HostingLayer behaviour"); - - } - hostingListener.OnHttpRequestInStart(context); - } - else if (aspNetCoreMajorVersion == AspNetCoreMajorVersion.Three) - { - if (Activity.Current == null) - { - var activity = new Activity("operation"); - if (tags != null) - { - foreach (var tag in tags) - { - activity.AddTag(tag.Key, tag.Value); - } - } - - // Simulating the behaviour of Hosting layer in 3.xx, which parses TraceParent if available, or Request-Id Header and - // set Activity parent. - if (context.Request.Headers.TryGetValue("traceparent", out var requestId) - || context.Request.Headers.TryGetValue("Request-Id", out requestId)) - { - activity.SetParentId(requestId); - - if (context.Request.Headers.TryGetValue("tracestate", out var traceState)) - { - activity.TraceStateString = traceState; - } - - string[] baggage = context.Request.Headers.GetCommaSeparatedValues(RequestResponseHeaders.CorrelationContextHeader); - if (baggage != StringValues.Empty && !activity.Baggage.Any()) - { - foreach (var item in baggage) - { - var parts = item.Split('='); - if (parts.Length == 2) - { - var itemName = StringUtilities.EnforceMaxLength(parts[0], InjectionGuardConstants.ContextHeaderKeyMaxLength); - var itemValue = StringUtilities.EnforceMaxLength(parts[1], InjectionGuardConstants.ContextHeaderValueMaxLength); - activity.AddBaggage(itemName, itemValue); - } - } - } - } - activity.Start(); - this.output.WriteLine("Test code created and started Activity to simulate HostingLayer behaviour"); - - } - hostingListener.OnHttpRequestInStart(context); - } - } - - private void HandleRequestEnd(HostingDiagnosticListener hostingListener, HttpContext context, long timestamp, AspNetCoreMajorVersion aspNetCoreMajorVersion) - { - if (aspNetCoreMajorVersion == AspNetCoreMajorVersion.Two || aspNetCoreMajorVersion == AspNetCoreMajorVersion.Three) - { - hostingListener.OnHttpRequestInStop(context); - } - else - { - } - } - - private void ValidateRequestTelemetry(RequestTelemetry requestTelemetry, Activity activity, bool isW3C, string expectedParentId = null, string expectedSource = null) - { - Assert.NotNull(requestTelemetry); - Assert.Equal(expectedParentId, requestTelemetry.Context.Operation.ParentId); - Assert.Equal(expectedSource, requestTelemetry.Source); - if (isW3C) - { - Assert.Equal(requestTelemetry.Id, activity.SpanId.ToHexString()); - Assert.Equal(requestTelemetry.Context.Operation.Id, activity.TraceId.ToHexString()); - } - else - { - Assert.Equal(requestTelemetry.Id, activity.Id); - Assert.Equal(requestTelemetry.Context.Operation.Id, activity.RootId); - } - } - - private Microsoft.ApplicationInsights.AspNetCore.Implementation.AspNetCoreMajorVersion GetAspNetCoreMajorVersion(Microsoft.ApplicationInsights.AspNetCore.Tests.AspNetCoreMajorVersion testVersion) - { - switch (testVersion) - { - case Microsoft.ApplicationInsights.AspNetCore.Tests.AspNetCoreMajorVersion.One: - return Microsoft.ApplicationInsights.AspNetCore.Implementation.AspNetCoreMajorVersion.One; - case Microsoft.ApplicationInsights.AspNetCore.Tests.AspNetCoreMajorVersion.Two: - return Microsoft.ApplicationInsights.AspNetCore.Implementation.AspNetCoreMajorVersion.Two; - case Microsoft.ApplicationInsights.AspNetCore.Tests.AspNetCoreMajorVersion.Three: - return Microsoft.ApplicationInsights.AspNetCore.Implementation.AspNetCoreMajorVersion.Three; - default: throw new ArgumentOutOfRangeException(nameof(testVersion)); - } - } - - public void Dispose() - { - while (Activity.Current != null) - { - Activity.Current.Stop(); - } - } - } -} diff --git a/NETCORE/test/Microsoft.ApplicationInsights.AspNetCore.Tests/HttpHeadersUtilitiesTest.cs b/NETCORE/test/Microsoft.ApplicationInsights.AspNetCore.Tests/HttpHeadersUtilitiesTest.cs deleted file mode 100644 index 29781e4d5e..0000000000 --- a/NETCORE/test/Microsoft.ApplicationInsights.AspNetCore.Tests/HttpHeadersUtilitiesTest.cs +++ /dev/null @@ -1,224 +0,0 @@ -namespace Microsoft.ApplicationInsights.AspNetCore.Tests -{ - using System; - using System.Collections.Generic; - using System.Linq; - using DiagnosticListeners; - using Microsoft.AspNetCore.Http; - using Microsoft.Extensions.Primitives; - using Xunit; - - public class HttpHeadersUtilitiesTest - { - [Fact] - public void GetHeaderValuesShouldReturnHeader() - { - IHeaderDictionary headerDictionary = new HeaderDictionary( - new Dictionary() { - { "HeaderName", new StringValues("app=id") }, - { "NoizyName", new StringValues("noizy=noizy-id") } - }); - - IEnumerable headerValues = HttpHeadersUtilities.GetHeaderValues(headerDictionary, "HeaderName"); - - Assert.NotNull(headerValues); - Assert.True(headerValues.Count() == 1); - Assert.Equal("app=id", headerValues.First()); - } - - [Fact] - public void GetHeaderKeyValueShouldReturnValue() - { - IHeaderDictionary headerDictionary = new HeaderDictionary( - new Dictionary() { - { "HeaderName", new StringValues("app=id") }, - { "NoizyName", new StringValues("noizy=noizy-id") } - }); - - string actual = HttpHeadersUtilities.GetHeaderKeyValue(headerDictionary, "HeaderName", "app"); - - Assert.Equal("id", actual); - } - - [Fact] - public void GetRequestContextKeyValueShouldReturnContextKeyValue() - { - IHeaderDictionary headerDictionary = new HeaderDictionary( - new Dictionary() - { - {RequestResponseHeaders.RequestContextHeader, new StringValues("app=id")}, - {"NoizyName", new StringValues("noizy=noizy-id")} - }); - - string actual = HttpHeadersUtilities.GetRequestContextKeyValue(headerDictionary, "app"); - - Assert.Equal("id", actual); - } - - [Fact] - public void SetHeaderKeyValueShouldRequireHeaders() - { - Assert.ThrowsAny(() => - { - IHeaderDictionary nullDictionary = null; - HttpHeadersUtilities.SetHeaderKeyValue(nullDictionary, "header", "key", "value"); - }); - } - - [Fact] - public void SetHeaderKeyValueShouldAddTheHeader() - { - IHeaderDictionary headers = new HeaderDictionary(); - HttpHeadersUtilities.SetHeaderKeyValue(headers, "newHeader", "key", "value"); - - Assert.Equal(1, headers.Count); - - Assert.Equal("newHeader", headers.First().Key); - Assert.Equal("key=value", headers.First().Value); - } - - [Fact] - public void SetHeaderKeyValuesShouldAppendToExistingHeaders() - { - IHeaderDictionary headers = new HeaderDictionary( - new Dictionary() { { "HeaderName", new StringValues("app=id") } }); - HttpHeadersUtilities.SetHeaderKeyValue(headers, "newHeader", "key", "value"); - - Assert.Equal(2, headers.Count); - - Assert.Equal("HeaderName", headers.First().Key); - Assert.Equal("app=id", headers.First().Value); - Assert.Equal("newHeader", headers.Skip(1).First().Key); - Assert.Equal("key=value", headers.Skip(1).First().Value); - } - - [Fact] - public void SetHeaderKeyValuesShouldUpdateExistingHeaders() - { - IHeaderDictionary headers = new HeaderDictionary( - new Dictionary() { { "HeaderName", new StringValues("app=id") } }); - HttpHeadersUtilities.SetHeaderKeyValue(headers, "HeaderName", "key", "value"); - - Assert.Equal(1, headers.Count); - - Assert.Equal("HeaderName", headers.First().Key); - Assert.Equal("app=id,key=value", headers.First().Value); - } - - [Fact] - public void SetRequestContextKeyValueShouldSetTheHeaders() - { - IHeaderDictionary headers = new HeaderDictionary(); - HttpHeadersUtilities.SetRequestContextKeyValue(headers, "key", "value"); - - Assert.Equal(1, headers.Count); - - Assert.Equal(RequestResponseHeaders.RequestContextHeader, headers.First().Key); - Assert.Equal("key=value", headers.First().Value); - } - - [Fact] - public void ContainsRequestContextKeyValueShouldReturnTrueWhenExists() - { - IHeaderDictionary headers = new HeaderDictionary( - new Dictionary { { RequestResponseHeaders.RequestContextHeader, new StringValues("app=id,other=otherValue") } }); - Assert.True(HttpHeadersUtilities.ContainsRequestContextKeyValue(headers, "app")); - Assert.True(HttpHeadersUtilities.ContainsRequestContextKeyValue(headers, "other")); - Assert.False(HttpHeadersUtilities.ContainsRequestContextKeyValue(headers, "Non-exists")); - } - - [Fact] - public void GetHeaderValueEmpty() - { - IHeaderDictionary headers = new HeaderDictionary(); - var values = HttpHeadersUtilities.SafeGetCommaSeparatedHeaderValues(headers, W3C.W3CConstants.TraceStateHeader, 100500, 100500)?.ToList(); - Assert.NotNull(values); - Assert.Empty(values); - } - - [Fact] - public void GetHeaderValueNoMax1() - { - IHeaderDictionary headers = new HeaderDictionary(new Dictionary { [W3C.W3CConstants.TraceStateHeader] = "k1=v1,k2=v2" }); - var values = HttpHeadersUtilities.SafeGetCommaSeparatedHeaderValues(headers, W3C.W3CConstants.TraceStateHeader, 100500, 100500)?.ToList(); - Assert.NotNull(values); - Assert.Equal(2, values.Count); - Assert.Equal("k1=v1", values.First()); - Assert.Equal("k2=v2", values.Last()); - } - - [Fact] - public void GetHeaderValueNoMax2() - { - IHeaderDictionary headers = new HeaderDictionary(new Dictionary { [W3C.W3CConstants.TraceStateHeader] = new []{"k1=v1,k2=v2", "k3=v3,k4=v4" }}); - var values = HttpHeadersUtilities.SafeGetCommaSeparatedHeaderValues(headers, W3C.W3CConstants.TraceStateHeader, 100500, 100500)?.ToList(); - Assert.NotNull(values); - Assert.Equal(4, values.Count); - Assert.Equal("k1=v1", values[0]); - Assert.Equal("k2=v2", values[1]); - Assert.Equal("k3=v3", values[2]); - Assert.Equal("k4=v4", values[3]); - } - - [Theory] - [InlineData(12)] // k1=v1,k2=v2,".Length - [InlineData(11)] // k1=v1,k2=v2".Length - [InlineData(15)] // k1=v1,k2=v2,k3=".Length - [InlineData(13)] // k1=v1,k2=v2,k".Length - public void GetHeaderValueMaxLenTruncatesEnd(int maxLength) - { - IHeaderDictionary headers = new HeaderDictionary(new Dictionary { [W3C.W3CConstants.TraceStateHeader] = "k1=v1,k2=v2,k3=v3,k4=v4" }); - var values = HttpHeadersUtilities.SafeGetCommaSeparatedHeaderValues(headers, W3C.W3CConstants.TraceStateHeader, maxLength, 100500)?.ToList(); - Assert.NotNull(values); - Assert.Equal(2, values.Count); - Assert.Equal("k1=v1", values.First()); - Assert.Equal("k2=v2", values.Last()); - } - - [Theory] - [InlineData(12)] // k1=v1,k2=v2,".Length - [InlineData(11)] // k1=v1,k2=v2".Length - [InlineData(15)] // k1=v1,k2=v2,k3=".Length - [InlineData(13)] // k1=v1,k2=v2,k".Length - public void GetHeaderValueMaxLenTruncatesEnd2(int maxLength) - { - IHeaderDictionary headers = new HeaderDictionary(new Dictionary { [W3C.W3CConstants.TraceStateHeader] = new[] { "k1=v1,k2=v2", "k3=v3,k4=v4" } }); - var values = HttpHeadersUtilities.SafeGetCommaSeparatedHeaderValues(headers, W3C.W3CConstants.TraceStateHeader, maxLength, 100500)?.ToList(); - Assert.NotNull(values); - Assert.Equal(2, values.Count); - Assert.Equal("k1=v1", values.First()); - Assert.Equal("k2=v2", values.Last()); - } - - [Theory] - [InlineData(0)] - [InlineData(3)] - public void GetHeaderValueMaxLenTruncatesEndInvalid(int maxLength) - { - IHeaderDictionary headers = new HeaderDictionary(new Dictionary { [W3C.W3CConstants.TraceStateHeader] = "k1=v1,k2=v2" }); - var values = HttpHeadersUtilities.SafeGetCommaSeparatedHeaderValues(headers, W3C.W3CConstants.TraceStateHeader, maxLength, 100500)?.ToList(); - Assert.NotNull(values); - Assert.Empty(values); - } - - [Fact] - public void GetHeaderValueMaxItemsTruncatesEndInvalid() - { - IHeaderDictionary headers = new HeaderDictionary(new Dictionary { [W3C.W3CConstants.TraceStateHeader] = "k1=v1,k2=v2" }); - var values = HttpHeadersUtilities.SafeGetCommaSeparatedHeaderValues(headers, W3C.W3CConstants.TraceStateHeader, 100500, 0)?.ToList(); - Assert.NotNull(values); - Assert.Empty(values); - } - - [Fact] - public void GetHeaderValueMaxItemsTruncatesEnd() - { - IHeaderDictionary headers = new HeaderDictionary(new Dictionary { [W3C.W3CConstants.TraceStateHeader] = "k1=v1,k2=v2,k3=v3,k4=v4" }); - var values = HttpHeadersUtilities.SafeGetCommaSeparatedHeaderValues(headers, W3C.W3CConstants.TraceStateHeader, 100500, 2)?.ToList(); - Assert.NotNull(values); - Assert.Equal(2, values.Count); - Assert.Equal("k1=v1", values.First()); - Assert.Equal("k2=v2", values.Last()); - } - } -} diff --git a/NETCORE/test/Microsoft.ApplicationInsights.AspNetCore.Tests/JavaScript/ApplicationInsightsJavaScriptTest.cs b/NETCORE/test/Microsoft.ApplicationInsights.AspNetCore.Tests/JavaScript/ApplicationInsightsJavaScriptTest.cs deleted file mode 100644 index 8d2a8cdd13..0000000000 --- a/NETCORE/test/Microsoft.ApplicationInsights.AspNetCore.Tests/JavaScript/ApplicationInsightsJavaScriptTest.cs +++ /dev/null @@ -1,135 +0,0 @@ -namespace Microsoft.Framework.DependencyInjection.Test -{ - using System.Security.Principal; - using System.Text.Encodings.Web; - using System.Text.Unicode; - using Microsoft.ApplicationInsights.AspNetCore; - using Microsoft.ApplicationInsights.AspNetCore.Extensions; - using Microsoft.ApplicationInsights.AspNetCore.Tests.Helpers; - using Microsoft.ApplicationInsights.Extensibility; - using Microsoft.AspNetCore.Http; - using Microsoft.Extensions.Options; - using Xunit; - - public static class ApplicationInsightsJavaScriptTest - { - private static JavaScriptEncoder encoder = JavaScriptEncoder.Create(new UnicodeRange[] { UnicodeRanges.BasicLatin }); - - [Fact] - public static void SnippetWillBeEmptyWhenInstrumentationKeyIsNotDefined() - { - var telemetryConfigurationWithNullKey = new TelemetryConfiguration(); - var snippet = new JavaScriptSnippet(telemetryConfigurationWithNullKey, GetOptions(false), null, encoder); - Assert.Equal(string.Empty, snippet.FullScript); - } - - [Fact] - public static void SnippetWillBeEmptyWhenInstrumentationKeyIsEmpty() - { - var telemetryConfigurationWithEmptyKey = new TelemetryConfiguration {InstrumentationKey = string.Empty}; - var snippet = new JavaScriptSnippet(telemetryConfigurationWithEmptyKey, GetOptions(false), null, encoder); - Assert.Equal(string.Empty, snippet.FullScript); - } - - [Fact] - public static void SnippetWillBeEmptyWhenTelemetryDisabled() - { - var telemetryConfigurationWithEmptyKey = new TelemetryConfiguration - { - InstrumentationKey = "NonEmpty", - DisableTelemetry = true - }; - var snippet = new JavaScriptSnippet(telemetryConfigurationWithEmptyKey, GetOptions(false), null, encoder); - Assert.Equal(string.Empty, snippet.FullScript); - } - - [Fact] - [Trait("Trait", "ConnectionString")] - public static void SnippetWillIncludeConnectionStringAsSubstring() - { - string testConnString = "InstrumentationKey=00000000-0000-0000-0000-000000000000"; - var telemetryConfiguration = new TelemetryConfiguration { ConnectionString = testConnString }; - var snippet = new JavaScriptSnippet(telemetryConfiguration, GetOptions(false), null, encoder); - Assert.Contains("connectionString: '" + testConnString + "'", snippet.FullScript); - } - - [Fact] - public static void SnippetWillIncludeInstrumentationKeyAsSubstring() - { - string unittestkey = "unittestkey"; - var telemetryConfiguration = new TelemetryConfiguration { InstrumentationKey = unittestkey }; - var snippet = new JavaScriptSnippet(telemetryConfiguration, GetOptions(false), null, encoder); - Assert.Contains("instrumentationKey: '" + unittestkey + "'", snippet.FullScript); - } - - [Fact] - public static void SnippetWillIncludeAuthUserNameIfEnabledAndAuthenticated() - { - string unittestkey = "unittestkey"; - var telemetryConfiguration = new TelemetryConfiguration { InstrumentationKey = unittestkey }; - var snippet = new JavaScriptSnippet(telemetryConfiguration, GetOptions(true), GetHttpContextAccessor("username", true), encoder); - Assert.Contains("setAuthenticatedUserContext(\"username\")", snippet.FullScript); - } - - [Fact] - public static void SnippetWillNotIncludeAuthUserNameIfEnabledAndAuthenticated() - { - string unittestkey = "unittestkey"; - var telemetryConfiguration = new TelemetryConfiguration { InstrumentationKey = unittestkey }; - var snippet = new JavaScriptSnippet(telemetryConfiguration, GetOptions(true), GetHttpContextAccessor("username", false), encoder); - Assert.DoesNotContain("appInsights.setAuthenticatedUserContext(", snippet.FullScript); - } - - [Fact] - public static void SnippetWillIncludeEscapedAuthUserNameIfEnabledAndAuthenticated() - { - string unittestkey = "unittestkey"; - var telemetryConfiguration = new TelemetryConfiguration { InstrumentationKey = unittestkey }; - var snippet = new JavaScriptSnippet(telemetryConfiguration, GetOptions(true), GetHttpContextAccessor("user\\name", true), encoder); - Assert.Contains("setAuthenticatedUserContext(\"user\\\\name\")", snippet.FullScript); - } - - [Fact] - public static void CrossSiteScriptingIsBlockedByEncoding() - { - string unittestkey = "unittestkey"; - var telemetryConfiguration = new TelemetryConfiguration { InstrumentationKey = unittestkey }; - var snippet = new JavaScriptSnippet(telemetryConfiguration, GetOptions(true), GetHttpContextAccessor("", true), encoder); - Assert.Contains("setAuthenticatedUserContext(\"\\u003Cscript\\u003Ealert(\\u0027hack\\u0027);", snippet.FullScript); - } - - private static IOptions GetOptions(bool enableAuthSnippet) - { - return new OptionsWrapper(new ApplicationInsightsServiceOptions() - { - EnableAuthenticationTrackingJavaScript = enableAuthSnippet - }); - } - - private static IHttpContextAccessor GetHttpContextAccessor(string name, bool isAuthenticated) - { - return new HttpContextAccessor - { - HttpContext = new DefaultHttpContext - { - User = new GenericPrincipal(new IdentityStub() { Name = name, IsAuthenticated = isAuthenticated }, new string[0]) - } - }; - } - - /// - /// Class that is used in unit tests and allows to override main IIdentity properties. - /// - private class IdentityStub : IIdentity - { - /// - public string AuthenticationType { get; set; } - - /// - public bool IsAuthenticated { get; set; } - - /// - public string Name { get; set; } - } - } -} diff --git a/NETCORE/test/Microsoft.ApplicationInsights.AspNetCore.Tests/Logging/ApplicationInsightsLoggerTests.cs b/NETCORE/test/Microsoft.ApplicationInsights.AspNetCore.Tests/Logging/ApplicationInsightsLoggerTests.cs deleted file mode 100644 index e02fb89d0a..0000000000 --- a/NETCORE/test/Microsoft.ApplicationInsights.AspNetCore.Tests/Logging/ApplicationInsightsLoggerTests.cs +++ /dev/null @@ -1,469 +0,0 @@ -using System; -using Microsoft.ApplicationInsights.AspNetCore.Logging; -using Microsoft.ApplicationInsights.AspNetCore.Tests.Helpers; -using Microsoft.ApplicationInsights.DataContracts; -using Microsoft.ApplicationInsights.Extensibility.Implementation; -using Microsoft.Extensions.Logging; -using Xunit; - -namespace Microsoft.ApplicationInsights.AspNetCore.Tests.Logging -{ -#pragma warning disable CS0618 // ApplicationInsightsLoggerOptions is obsolete. Are we ready to delete these tests? - /// - /// Tests for the Application Insights ILogger implementation. - /// - public class ApplicationInsightsLoggerTests - { - private static readonly ApplicationInsightsLoggerOptions defaultOptions = new ApplicationInsightsLoggerOptions(); - - /// - /// Tests that the SDK version is correctly set on the telemetry context when messages are logged to AI. - /// - [Fact] - public void TestLoggerSetsSdkVersionOnLoggedTelemetry() - { - bool isCorrectVersion = false; - TelemetryClient client = CommonMocks.MockTelemetryClient((t) => - { - isCorrectVersion = t.Context.GetInternalContext().SdkVersion.StartsWith(ApplicationInsightsLogger.VersionPrefix); - }); - - ILogger logger = new ApplicationInsightsLogger("test", client, (s, l) => { return true; }, null); - logger.LogTrace("This is a test.", new object[] { }); - Assert.True(isCorrectVersion); - } - - /// - /// Tests that logging an information results in tracking an instance. - /// - [Fact] - public void TestLoggerCreatesTraceTelemetryOnLoggedInfo() - { - TelemetryClient client = CommonMocks.MockTelemetryClient((t) => - { - Assert.IsType(t); - var traceTelemetry = (TraceTelemetry)t; - Assert.Equal("This is an information", traceTelemetry.Message); - Assert.Equal(SeverityLevel.Information, traceTelemetry.SeverityLevel); - Assert.Equal("test-category", traceTelemetry.Properties["CategoryName"]); - }); - - ILogger logger = new ApplicationInsightsLogger("test-category", client, (s, l) => { return true; }, null); - logger.LogInformation(0, "This is an information"); - } - - /// - /// Tests that logging a warning with parameters results in tracking an instance with telemetry properties. - /// - [Fact] - public void TestLoggerCreatesTraceTelemetryOnLoggedWarningWithParameters() - { - TelemetryClient client = CommonMocks.MockTelemetryClient((t) => - { - Assert.IsType(t); - var traceTelemetry = (TraceTelemetry)t; - Assert.Equal("This is 123 value: Hello, World!", traceTelemetry.Message); - Assert.Equal(SeverityLevel.Warning, traceTelemetry.SeverityLevel); - Assert.Equal("test-category", traceTelemetry.Properties["CategoryName"]); - - Assert.Equal("123", traceTelemetry.Properties["testParam"]); - Assert.Equal("Hello, World!", traceTelemetry.Properties["param2"]); - }); - - ILogger logger = new ApplicationInsightsLogger("test-category", client, (s, l) => { return true; }, null); - logger.LogWarning(0, "This is {testParam} value: {param2}", 123, "Hello, World!"); - } - - /// - /// Tests that logging an information with results in tracking an instance, when includeEventId is false. - /// - [Fact] - public void TestLoggerCreatesTraceTelemetryWithoutEventIdOnLoggedDebug() - { - TelemetryClient client = CommonMocks.MockTelemetryClient((t) => - { - Assert.IsType(t); - var traceTelemetry = (TraceTelemetry)t; - Assert.Equal("This is an information", traceTelemetry.Message); - Assert.Equal(SeverityLevel.Verbose, traceTelemetry.SeverityLevel); - Assert.Equal("test-category", traceTelemetry.Properties["CategoryName"]); - - Assert.False(traceTelemetry.Properties.ContainsKey("EventId")); - Assert.False(traceTelemetry.Properties.ContainsKey("EventName")); - }); - - ILogger logger = new ApplicationInsightsLogger("test-category", client, (s, l) => { return true; }, null); - logger.LogDebug(new EventId(22, "TestEvent"), "This is an information"); - } - - /// - /// Tests that logging an error with results in tracking an instance with event properties, when includeEventId is true. - /// - [Fact] - public void TestLoggerIncludingEventIdCreatesTraceTelemetryWithEventIdOnLoggedError() - { - TelemetryClient client = CommonMocks.MockTelemetryClient((t) => - { - Assert.IsType(t); - var traceTelemetry = (TraceTelemetry)t; - Assert.Equal("This is an error", traceTelemetry.Message); - Assert.Equal(SeverityLevel.Error, traceTelemetry.SeverityLevel); - Assert.Equal("test-category", traceTelemetry.Properties["CategoryName"]); - - Assert.Equal("22", traceTelemetry.Properties["EventId"]); - Assert.Equal("TestEvent", traceTelemetry.Properties["EventName"]); - }); - var options = new ApplicationInsightsLoggerOptions { IncludeEventId = true }; - - ILogger logger = new ApplicationInsightsLogger("test-category", client, (s, l) => { return true; }, options); - logger.LogError(new EventId(22, "TestEvent"), "This is an error"); - } - - /// - /// Tests that logging an information without results in tracking an instance. - /// - [Fact] - public void TestLoggerIncludingEventIdCreatesTraceTelemetryWithoutEventIdOnLoggedInfo() - { - TelemetryClient client = CommonMocks.MockTelemetryClient((t) => - { - Assert.IsType(t); - var traceTelemetry = (TraceTelemetry)t; - Assert.Equal("This is an information", traceTelemetry.Message); - Assert.Equal(SeverityLevel.Information, traceTelemetry.SeverityLevel); - Assert.Equal("test-category", traceTelemetry.Properties["CategoryName"]); - - Assert.False(traceTelemetry.Properties.ContainsKey("EventId")); - Assert.False(traceTelemetry.Properties.ContainsKey("EventName")); - }); - var options = new ApplicationInsightsLoggerOptions { IncludeEventId = true }; - - ILogger logger = new ApplicationInsightsLogger("test-category", client, (s, l) => { return true; }, options); - logger.LogInformation(0, "This is an information"); - } - - /// - /// Tests that logging an information with emtpy event name results in tracking an instance. - /// - [Fact] - public void TestLoggerIncludingEventIdCreatesTraceTelemetryWithoutEventNameOnLoggedInfo() - { - TelemetryClient client = CommonMocks.MockTelemetryClient((t) => - { - Assert.IsType(t); - var traceTelemetry = (TraceTelemetry)t; - Assert.Equal("This is an information", traceTelemetry.Message); - Assert.Equal(SeverityLevel.Information, traceTelemetry.SeverityLevel); - Assert.Equal("test-category", traceTelemetry.Properties["CategoryName"]); - - Assert.Equal("100", traceTelemetry.Properties["EventId"]); - Assert.False(traceTelemetry.Properties.ContainsKey("EventName")); - }); - var options = new ApplicationInsightsLoggerOptions { IncludeEventId = true }; - - ILogger logger = new ApplicationInsightsLogger("test-category", client, (s, l) => { return true; }, options); - logger.LogInformation(new EventId(100, string.Empty), "This is an information"); - } - - /// - /// Tests that logging an error with results in tracking an instance with event properties, - /// when includeEventId is true and parameter is named EventId. - /// - [Fact] - public void TestLoggerIncludingEventIdCreatesTraceTelemetryWithEventIdOnLoggedErrorWithParameters() - { - TelemetryClient client = CommonMocks.MockTelemetryClient((t) => - { - Assert.IsType(t); - var traceTelemetry = (TraceTelemetry)t; - Assert.Equal("This is an ERROR error. 15", traceTelemetry.Message); - Assert.Equal(SeverityLevel.Error, traceTelemetry.SeverityLevel); - Assert.Equal("test-category", traceTelemetry.Properties["CategoryName"]); - - Assert.Equal("ERROR", traceTelemetry.Properties["EventId"]); - Assert.Equal("TestEvent", traceTelemetry.Properties["EventName"]); - Assert.Equal("15", traceTelemetry.Properties["Message"]); - }); - var options = new ApplicationInsightsLoggerOptions { IncludeEventId = true }; - - ILogger logger = new ApplicationInsightsLogger("test-category", client, (s, l) => { return true; }, options); - logger.LogError(new EventId(22, "TestEvent"), "This is an {EventId} error. {Message}", "ERROR", 15); - } - - /// - /// Tests that logging an information results in not tracking an instance, when filter returns false. - /// - [Fact] - public void TestLoggerWithNegativeFilterDoesNotCreateTraceTelemetryOnLoggedInfo() - { - bool trackedTelemetry = false; - TelemetryClient client = CommonMocks.MockTelemetryClient((t) => trackedTelemetry = true); - - ILogger logger = new ApplicationInsightsLogger("test-category", client, (s, l) => { return false; }, defaultOptions); - logger.LogInformation(0, "This is an information"); - - Assert.False(trackedTelemetry); - } - - /// - /// Tests that logging an exception results in tracking an instance. - /// - [Fact] - public void TestLoggerCreatesExceptionTelemetryOnLoggedError() - { - TelemetryClient client = CommonMocks.MockTelemetryClient((t) => - { - Assert.IsType(t); - var exceptionTelemetry = (ExceptionTelemetry)t; - Assert.Equal(SeverityLevel.Error, exceptionTelemetry.SeverityLevel); - Assert.Equal("test-category", exceptionTelemetry.Properties["CategoryName"]); - Assert.Equal("System.Exception: This is an error", exceptionTelemetry.Properties["Exception"]); - Assert.Equal("Error: This is an error", exceptionTelemetry.Message); - }); - - ILogger logger = new ApplicationInsightsLogger("test-category", client, (s, l) => { return true; }, defaultOptions); - var exception = new Exception("This is an error"); - logger.LogError(0, exception, "Error: " + exception.Message); - } - - /// - /// Tests that logging an exception with parameters results in tracking an instance with parameters. - /// - [Fact] - public void TestLoggerCreatesExceptionTelemetryOnLoggedErrorWithParameters() - { - TelemetryClient client = CommonMocks.MockTelemetryClient((t) => - { - Assert.IsType(t); - var exceptionTelemetry = (ExceptionTelemetry)t; - Assert.Equal(SeverityLevel.Error, exceptionTelemetry.SeverityLevel); - Assert.Equal("test-category", exceptionTelemetry.Properties["CategoryName"]); - Assert.Equal("System.Exception: This is an error", exceptionTelemetry.Properties["Exception"]); - Assert.Equal("Error: This is an error, Value: 123", exceptionTelemetry.Message); - - Assert.Equal("This is an error", exceptionTelemetry.Properties["ex"]); - Assert.Equal("123", exceptionTelemetry.Properties["value"]); - }); - - ILogger logger = new ApplicationInsightsLogger("test-category", client, (s, l) => { return true; }, defaultOptions); - var exception = new Exception("This is an error"); - logger.LogError(0, exception, "Error: {ex}, Value: {value}", exception.Message, 123); - } - - /// - /// Tests that logging an exception with results in tracking an instance, when includeEventId is false. - /// - [Fact] - public void TestLoggerCreatesExceptionWithoutEventIdTelemetryOnLoggedError() - { - TelemetryClient client = CommonMocks.MockTelemetryClient((t) => - { - Assert.IsType(t); - var exceptionTelemetry = (ExceptionTelemetry)t; - Assert.Equal(SeverityLevel.Error, exceptionTelemetry.SeverityLevel); - Assert.Equal("test-category", exceptionTelemetry.Properties["CategoryName"]); - Assert.Equal("System.Exception: This is an error", exceptionTelemetry.Properties["Exception"]); - Assert.Equal("Error: This is an error", exceptionTelemetry.Message); - - Assert.False(exceptionTelemetry.Properties.ContainsKey("EventId")); - Assert.False(exceptionTelemetry.Properties.ContainsKey("EventName")); - }); - - ILogger logger = new ApplicationInsightsLogger("test-category", client, (s, l) => { return true; }, defaultOptions); - var exception = new Exception("This is an error"); - logger.LogError(new EventId(22, "TestEvent"), exception, "Error: " + exception.Message); - } - - /// - /// Tests that logging an exception with results in tracking an instance, when includeEventId is true. - /// - [Fact] - public void TestLoggerIncludingEventIdCreatesExceptionWithEventIdTelemetryOnLoggedError() - { - TelemetryClient client = CommonMocks.MockTelemetryClient((t) => - { - Assert.IsType(t); - var exceptionTelemetry = (ExceptionTelemetry)t; - Assert.Equal(SeverityLevel.Error, exceptionTelemetry.SeverityLevel); - Assert.Equal("test-category", exceptionTelemetry.Properties["CategoryName"]); - Assert.Equal("System.Exception: This is an error", exceptionTelemetry.Properties["Exception"]); - Assert.Equal("Error: This is an error", exceptionTelemetry.Message); - - Assert.Equal("22", exceptionTelemetry.Properties["EventId"]); - Assert.Equal("TestEvent", exceptionTelemetry.Properties["EventName"]); - }); - var options = new ApplicationInsightsLoggerOptions { IncludeEventId = true }; - - ILogger logger = new ApplicationInsightsLogger("test-category", client, (s, l) => { return true; }, options); - var exception = new Exception("This is an error"); - logger.LogError(new EventId(22, "TestEvent"), exception, "Error: " + exception.Message); - } - - /// - /// Tests that logging an exception without results in tracking an instance, when includeEventId is true. - /// - [Fact] - public void TestLoggerIncludingEventIdCreatesExceptionWithoutEventIdTelemetryOnLoggedError() - { - TelemetryClient client = CommonMocks.MockTelemetryClient((t) => - { - Assert.IsType(t); - var exceptionTelemetry = (ExceptionTelemetry)t; - Assert.Equal(SeverityLevel.Error, exceptionTelemetry.SeverityLevel); - Assert.Equal("test-category", exceptionTelemetry.Properties["CategoryName"]); - Assert.Equal("System.Exception: This is an error", exceptionTelemetry.Properties["Exception"]); - Assert.Equal("Error: This is an error", exceptionTelemetry.Message); - - Assert.False(exceptionTelemetry.Properties.ContainsKey("EventId")); - Assert.False(exceptionTelemetry.Properties.ContainsKey("EventName")); - }); - var options = new ApplicationInsightsLoggerOptions { IncludeEventId = true }; - - ILogger logger = new ApplicationInsightsLogger("test-category", client, (s, l) => { return true; }, options); - var exception = new Exception("This is an error"); - logger.LogError(0, exception, "Error: " + exception.Message); - } - - /// - /// Tests that logging an exception with empty event name results in tracking an instance, when includeEventId is true. - /// - [Fact] - public void TestLoggerIncludingEventIdCreatesExceptionWithoutEventNameTelemetryOnLoggedError() - { - TelemetryClient client = CommonMocks.MockTelemetryClient((t) => - { - Assert.IsType(t); - var exceptionTelemetry = (ExceptionTelemetry)t; - Assert.Equal(SeverityLevel.Error, exceptionTelemetry.SeverityLevel); - Assert.Equal("test-category", exceptionTelemetry.Properties["CategoryName"]); - Assert.Equal("System.Exception: This is an error", exceptionTelemetry.Properties["Exception"]); - Assert.Equal("Error: This is an error", exceptionTelemetry.Message); - - Assert.Equal("100", exceptionTelemetry.Properties["EventId"]); - Assert.False(exceptionTelemetry.Properties.ContainsKey("EventName")); - }); - var options = new ApplicationInsightsLoggerOptions { IncludeEventId = true }; - - ILogger logger = new ApplicationInsightsLogger("test-category", client, (s, l) => { return true; }, options); - var exception = new Exception("This is an error"); - logger.LogError(new EventId(100, string.Empty), exception, "Error: " + exception.Message); - } - - /// - /// Tests that logging an exception with results in tracking an instance, - /// when includeEventId is true and parameter is EventName. - /// - [Fact] - public void TestLoggerIncludingEventIdCreatesExceptionWithEventIdTelemetryOnLoggedErrorWithParameters() - { - TelemetryClient client = CommonMocks.MockTelemetryClient((t) => - { - Assert.IsType(t); - var exceptionTelemetry = (ExceptionTelemetry)t; - Assert.Equal(SeverityLevel.Error, exceptionTelemetry.SeverityLevel); - Assert.Equal("test-category", exceptionTelemetry.Properties["CategoryName"]); - Assert.Equal("System.Exception: This is an error", exceptionTelemetry.Properties["Exception"]); - Assert.Equal("Error: ERROR This is an error", exceptionTelemetry.Message); - - Assert.Equal("22", exceptionTelemetry.Properties["EventId"]); - Assert.Equal("ERROR", exceptionTelemetry.Properties["EventName"]); - Assert.Equal("This is an error", exceptionTelemetry.Properties["Message"]); - }); - var options = new ApplicationInsightsLoggerOptions { IncludeEventId = true }; - - ILogger logger = new ApplicationInsightsLogger("test-category", client, (s, l) => { return true; }, options); - var exception = new Exception("This is an error"); - logger.LogError(new EventId(22, "TestEvent"), exception, "Error: {EventName} {Message}", "ERROR", exception.Message); - } - - /// - /// Tests that logging an exception results in not tracking an instance, when filter returns false. - /// - [Fact] - public void TestLoggerWithNegativeFilterDoesNotCreateExceptionTelemetryOnLoggedError() - { - bool trackedTelemetry = false; - TelemetryClient client = CommonMocks.MockTelemetryClient((t) => trackedTelemetry = true); - - ILogger logger = new ApplicationInsightsLogger("test-category", client, (s, l) => { return false; }, defaultOptions); - var exception = new Exception("This is an error"); - - logger.LogError(0, exception, "Error: " + exception.Message); - - Assert.False(trackedTelemetry); - } - - [Fact] - public void TestLoggerCreatesTraceTelemetryOnLoggedErrorWhenTrackExceptionsAsExceptionTelemetryIsSetToFalse() - { - TelemetryClient client = CommonMocks.MockTelemetryClient((t) => - { - Assert.IsType(t); - var traceTelemetry = (TraceTelemetry)t; - - Assert.Equal("Error: This is an error", traceTelemetry.Message); - Assert.Equal(SeverityLevel.Error, traceTelemetry.SeverityLevel); - }); - - ILogger logger = new ApplicationInsightsLogger("test", client, (s, l) => { return true; }, new ApplicationInsightsLoggerOptions { TrackExceptionsAsExceptionTelemetry = false }); - var exception = new Exception("This is an error"); - - logger.LogError(0, exception, "Error: " + exception.Message); - } - - [Fact] - public void TestLoggerCreatesExceptionTelemetryOnLoggedErrorWhenTrackExceptionsAsExceptionTelemetryIsSetToTrue() - { - TelemetryClient client = CommonMocks.MockTelemetryClient((t) => - { - Assert.IsType(t); - var exceptionTelemetry = (ExceptionTelemetry)t; - - Assert.Equal("Error: This is an error", exceptionTelemetry.Message); - Assert.Equal(SeverityLevel.Error, exceptionTelemetry.SeverityLevel); - }); - - ILogger logger = new ApplicationInsightsLogger("test", client, (s, l) => { return true; }, new ApplicationInsightsLoggerOptions { TrackExceptionsAsExceptionTelemetry = true }); - var exception = new Exception("This is an error"); - - logger.LogError(0, exception, "Error: " + exception.Message); - } - - /// - /// Tests that logging an exception with parameters results in tracking an instance with parameters. - /// - [Fact] - public void TestLoggerAdditionalExceptionDataIsAddedToTelemetry() - { - TelemetryClient client = CommonMocks.MockTelemetryClient((t) => - { - Assert.IsType(t); - var exceptionTelemetry = (ExceptionTelemetry)t; - Assert.Equal(SeverityLevel.Error, exceptionTelemetry.SeverityLevel); - Assert.Equal("test-category", exceptionTelemetry.Properties["CategoryName"]); - Assert.Equal("System.Exception: This is an error", exceptionTelemetry.Properties["Exception"]); - Assert.Equal("Error: This is an error, Value: 123", exceptionTelemetry.Message); - - Assert.Equal("test", exceptionTelemetry.Properties["AdditionalProperty1"]); - Assert.Equal("test2", exceptionTelemetry.Properties["AdditionalProperty2"]); - }); - - ILogger logger = new ApplicationInsightsLogger("test-category", client, (s, l) => { return true; }, defaultOptions); - var exception = new Exception("This is an error"); - exception.Data.Add("AdditionalProperty1", "test"); - exception.Data.Add("AdditionalProperty2", "test2"); - logger.LogError(0, exception, "Error: {ex}, Value: {value}", exception.Message, 123); - } - - /// - /// Tests that an incorrectly constructed or uninitialized Application Insights ILogger does not throw exceptions. - /// - [Fact] - public void TestUninitializedLoggerDoesNotThrowExceptions() - { - ILogger logger = new ApplicationInsightsLogger("test", null, null, null); - logger.LogTrace("This won't do anything.", new object[] { }); - } - } -#pragma warning restore CS0618 // ApplicationInsightsLoggerOptions is obsolete. Are we ready to delete these tests? -} diff --git a/NETCORE/test/Microsoft.ApplicationInsights.AspNetCore.Tests/Microsoft.ApplicationInsights.AspNetCore.Tests.csproj b/NETCORE/test/Microsoft.ApplicationInsights.AspNetCore.Tests/Microsoft.ApplicationInsights.AspNetCore.Tests.csproj deleted file mode 100644 index 047711bcbc..0000000000 --- a/NETCORE/test/Microsoft.ApplicationInsights.AspNetCore.Tests/Microsoft.ApplicationInsights.AspNetCore.Tests.csproj +++ /dev/null @@ -1,46 +0,0 @@ - - - - - - $(TargetFrameworks_NetCoreOnly) - - - - - - - - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - - - - - - - - - - - - - - - Always - SettingsSingleFileGenerator - - - Always - - - Always - - - - diff --git a/NETCORE/test/Microsoft.ApplicationInsights.AspNetCore.Tests/Properties/launchSettings.json b/NETCORE/test/Microsoft.ApplicationInsights.AspNetCore.Tests/Properties/launchSettings.json deleted file mode 100644 index cfb47117df..0000000000 --- a/NETCORE/test/Microsoft.ApplicationInsights.AspNetCore.Tests/Properties/launchSettings.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "iisSettings": { - "windowsAuthentication": false, - "anonymousAuthentication": true, - "iisExpress": { - "applicationUrl": "http://localhost:4822/", - "sslPort": 0 - } - }, - "profiles": { - "IIS Express": { - "commandName": "IISExpress", - "launchBrowser": true, - "environmentVariables": { - "ASPNET_ENVIRONMENT": "Development" - } - } - } -} \ No newline at end of file diff --git a/NETCORE/test/Microsoft.ApplicationInsights.AspNetCore.Tests/RequestTrackingTelemetryModuleTest.cs b/NETCORE/test/Microsoft.ApplicationInsights.AspNetCore.Tests/RequestTrackingTelemetryModuleTest.cs deleted file mode 100644 index 7a2e9eccd6..0000000000 --- a/NETCORE/test/Microsoft.ApplicationInsights.AspNetCore.Tests/RequestTrackingTelemetryModuleTest.cs +++ /dev/null @@ -1,14 +0,0 @@ -namespace Microsoft.ApplicationInsights.AspNetCore.Tests -{ - using Microsoft.ApplicationInsights.Extensibility; - using Xunit; - - public class RequestTrackingTelemetryModuleTest - { - [Fact] - public void RequestTrackingTelemetryModuleDoesNoThrowWhenAppIdProviderisNull() - { - RequestTrackingTelemetryModule requestTrackingTelemetryModule = new RequestTrackingTelemetryModule(null); - } - } -} \ No newline at end of file diff --git a/NETCORE/test/Microsoft.ApplicationInsights.AspNetCore.Tests/SdkVersionTestUtils.cs b/NETCORE/test/Microsoft.ApplicationInsights.AspNetCore.Tests/SdkVersionTestUtils.cs deleted file mode 100644 index de8d0d4eab..0000000000 --- a/NETCORE/test/Microsoft.ApplicationInsights.AspNetCore.Tests/SdkVersionTestUtils.cs +++ /dev/null @@ -1,11 +0,0 @@ -namespace Microsoft.ApplicationInsights.AspNetCore.Tests -{ - public class SdkVersionTestUtils - { -#if NETFRAMEWORK - public const string VersionPrefix = "aspnet5f:"; -#else - public const string VersionPrefix = "aspnet5c:"; -#endif - } -} diff --git a/NETCORE/test/Microsoft.ApplicationInsights.AspNetCore.Tests/TelemetryInitializers/AspNetCoreEnvironmentTelemetryInitializerTests.cs b/NETCORE/test/Microsoft.ApplicationInsights.AspNetCore.Tests/TelemetryInitializers/AspNetCoreEnvironmentTelemetryInitializerTests.cs deleted file mode 100644 index c7522dca80..0000000000 --- a/NETCORE/test/Microsoft.ApplicationInsights.AspNetCore.Tests/TelemetryInitializers/AspNetCoreEnvironmentTelemetryInitializerTests.cs +++ /dev/null @@ -1,39 +0,0 @@ -namespace Microsoft.ApplicationInsights.AspNetCore.Tests.TelemetryInitializers -{ - using Microsoft.ApplicationInsights.AspNetCore.TelemetryInitializers; - using Microsoft.ApplicationInsights.DataContracts; - using Microsoft.AspNetCore.Hosting.Internal; - using Xunit; - - public class AspNetCoreEnvironmentTelemetryInitializerTests - { - [Fact] - public void InitializeDoesNotThrowIfHostingEnvironmentIsNull() - { - var initializer = new AspNetCoreEnvironmentTelemetryInitializer(environment: null); - initializer.Initialize(new RequestTelemetry()); - } - - [Fact] - public void InitializeDoesNotOverrideExistingProperty() - { - var initializer = new AspNetCoreEnvironmentTelemetryInitializer(environment: EnvironmentHelper.GetIHostingEnvironment()); - var telemetry = new RequestTelemetry(); - telemetry.Context.GlobalProperties.Add("AspNetCoreEnvironment", "Development"); - initializer.Initialize(telemetry); - - Assert.Equal("Development", telemetry.Context.GlobalProperties["AspNetCoreEnvironment"]); - Assert.Equal("UnitTest", telemetry.Properties["AspNetCoreEnvironment"]); - } - - [Fact] - public void InitializeSetsCurrentEnvironmentNameToProperty() - { - var initializer = new AspNetCoreEnvironmentTelemetryInitializer(environment: EnvironmentHelper.GetIHostingEnvironment()); - var telemetry = new RequestTelemetry(); - initializer.Initialize(telemetry); - - Assert.Equal("UnitTest", telemetry.Properties["AspNetCoreEnvironment"]); - } - } -} diff --git a/NETCORE/test/Microsoft.ApplicationInsights.AspNetCore.Tests/TelemetryInitializers/AzureAppServiceRoleNameFromHostNameHeaderInitializerTests.cs b/NETCORE/test/Microsoft.ApplicationInsights.AspNetCore.Tests/TelemetryInitializers/AzureAppServiceRoleNameFromHostNameHeaderInitializerTests.cs deleted file mode 100644 index 5aace9d620..0000000000 --- a/NETCORE/test/Microsoft.ApplicationInsights.AspNetCore.Tests/TelemetryInitializers/AzureAppServiceRoleNameFromHostNameHeaderInitializerTests.cs +++ /dev/null @@ -1,213 +0,0 @@ -namespace Microsoft.ApplicationInsights.AspNetCore.Tests.TelemetryInitializers -{ - using System; - using Microsoft.ApplicationInsights.AspNetCore.Implementation; - using Microsoft.ApplicationInsights.AspNetCore.TelemetryInitializers; - using Microsoft.ApplicationInsights.AspNetCore.Tests.Helpers; - using Microsoft.ApplicationInsights.DataContracts; - using Microsoft.AspNetCore.Http; - - using Xunit; - - [Trait("Trait", "RoleName")] - public class AzureAppServiceRoleNameFromHostNameHeaderInitializerTests : IDisposable - { - public AzureAppServiceRoleNameFromHostNameHeaderInitializerTests() - { - Environment.SetEnvironmentVariable("WEBSITE_HOSTNAME", "SomeName"); - } - - [Fact] - public void VerifyInitializerWorksAsExpected() - { - try - { - Environment.SetEnvironmentVariable("WEBSITE_HOSTNAME", "a.b.c.azurewebsites.net"); - - var initializer = new AzureAppServiceRoleNameFromHostNameHeaderInitializer(webAppSuffix: ".azurewebsites.net"); - - var requestTelemetry1 = new RequestTelemetry(); - initializer.Initialize(requestTelemetry1); - Assert.Equal("a.b.c", requestTelemetry1.Context.Cloud.RoleName); - } - finally - { - Environment.SetEnvironmentVariable("WEBSITE_HOSTNAME", null); - } - } - - [Fact] - public void VerifyInitializerCanBeChangedAfterConstructor() - { - try - { - Environment.SetEnvironmentVariable("WEBSITE_HOSTNAME", "a.b.c.azurewebsites.net"); - - var initializer = new AzureAppServiceRoleNameFromHostNameHeaderInitializer(webAppSuffix: ".azurewebsites.net"); - - var requestTelemetry1 = new RequestTelemetry(); - initializer.Initialize(requestTelemetry1); - Assert.Equal("a.b.c", requestTelemetry1.Context.Cloud.RoleName); - - initializer.WebAppSuffix = ".c.azurewebsites.net"; - - var requestTelemetry2 = new RequestTelemetry(); - initializer.Initialize(requestTelemetry2); - Assert.Equal("a.b", requestTelemetry2.Context.Cloud.RoleName); - } - finally - { - Environment.SetEnvironmentVariable("WEBSITE_HOSTNAME", null); - } - } - - [Fact] - public void VerifyInitializerRespectsChangesToRoleNameContainerRoleName() - { - try - { - Environment.SetEnvironmentVariable("WEBSITE_HOSTNAME", "a.b.c.azurewebsites.net"); - var ac = new HttpContextAccessor { HttpContext = null }; - - var initializer = new AzureAppServiceRoleNameFromHostNameHeaderInitializer(webAppSuffix: ".azurewebsites.net"); - - var requestTelemetry1 = new RequestTelemetry(); - initializer.Initialize(requestTelemetry1); - Assert.Equal("a.b.c", requestTelemetry1.Context.Cloud.RoleName); - - RoleNameContainer.Instance.RoleName = "test"; - - var requestTelemetry2 = new RequestTelemetry(); - initializer.Initialize(requestTelemetry2); - Assert.Equal("test", requestTelemetry2.Context.Cloud.RoleName); - } - finally - { - Environment.SetEnvironmentVariable("WEBSITE_HOSTNAME", null); - } - } - - [Fact] - public void InitializeFallsbackToEnvIfHttpContextIsUnavailableWithAzureWebsitesHostnameending() - { - try - { - Environment.SetEnvironmentVariable("WEBSITE_HOSTNAME", "RoleNameEnv.azurewebsites.net"); - var ac = new HttpContextAccessor { HttpContext = null }; - - var initializer = new AzureAppServiceRoleNameFromHostNameHeaderInitializer(); - var req = new RequestTelemetry(); - initializer.Initialize(req); - - Assert.Equal("RoleNameEnv", req.Context.Cloud.RoleName); - } - finally - { - Environment.SetEnvironmentVariable("WEBSITE_HOSTNAME", null); - } - } - - [Fact] - public void InitializeFallsbackToEnvIfRequestServicesAreUnavailable() - { - try - { - Environment.SetEnvironmentVariable("WEBSITE_HOSTNAME", "RoleNameEnv"); - var ac = new HttpContextAccessor { HttpContext = new DefaultHttpContext() }; - - var initializer = new AzureAppServiceRoleNameFromHostNameHeaderInitializer(); - var req = new RequestTelemetry(); - initializer.Initialize(req); - - Assert.Equal("RoleNameEnv", req.Context.Cloud.RoleName); - } - finally - { - Environment.SetEnvironmentVariable("WEBSITE_HOSTNAME", null); - } - } - - [Fact] - public void InitializeDoesNotThrowIfRequestIsUnavailable() - { - var initializer = new AzureAppServiceRoleNameFromHostNameHeaderInitializer(); - - initializer.Initialize(new EventTelemetry()); - } - - [Fact] - public void InitializeFallsbackToEnvIfRequestIsUnavailable() - { - try - { - Environment.SetEnvironmentVariable("WEBSITE_HOSTNAME", "RoleNameEnv"); - var initializer = new AzureAppServiceRoleNameFromHostNameHeaderInitializer(); - var req = new RequestTelemetry(); - initializer.Initialize(req); - - Assert.Equal("RoleNameEnv", req.Context.Cloud.RoleName); - } - finally - { - Environment.SetEnvironmentVariable("WEBSITE_HOSTNAME", null); - } - } - - [Fact] - public void InitializeFallsbackToEnvIfHostNameIsEmptyInHeader() - { - try - { - Environment.SetEnvironmentVariable("WEBSITE_HOSTNAME", "RoleNameEnv"); - var requestTelemetry = new RequestTelemetry(); - var contextAccessor = HttpContextAccessorHelper.CreateHttpContextAccessor(requestTelemetry); - - contextAccessor.HttpContext.Request.Headers.Add("WAS-DEFAULT-HOSTNAME", new string[] { string.Empty }); - - var initializer = new AzureAppServiceRoleNameFromHostNameHeaderInitializer(); - - initializer.Initialize(requestTelemetry); - - Assert.Equal("RoleNameEnv", requestTelemetry.Context.Cloud.RoleName); - } - finally - { - Environment.SetEnvironmentVariable("WEBSITE_HOSTNAME", null); - } - } - - [Fact] - public void InitializeDoesNotOverrideRoleName() - { - var requestTelemetry = new RequestTelemetry(); - requestTelemetry.Context.Cloud.RoleName = "ExistingRoleName"; - - var contextAccessor = HttpContextAccessorHelper.CreateHttpContextAccessor(requestTelemetry); - contextAccessor.HttpContext.Request.Headers.Add("WAS-DEFAULT-HOSTNAME", new string[] { "MyAppServiceProd" }); - - var initializer = new AzureAppServiceRoleNameFromHostNameHeaderInitializer(); - - initializer.Initialize(requestTelemetry); - - Assert.Equal("ExistingRoleName", requestTelemetry.Context.Cloud.RoleName); - } - - [Fact] - public void InitializewithNoEnvToHostNameHeader() - { - Environment.SetEnvironmentVariable("WEBSITE_HOSTNAME", null); - var ac = new HttpContextAccessor { HttpContext = null }; - - var initializer = new AzureAppServiceRoleNameFromHostNameHeaderInitializer(); - - var requestTelemetry = new RequestTelemetry(); - initializer.Initialize(requestTelemetry); - Assert.Null(requestTelemetry.Context.Cloud.RoleName); - } - - public void Dispose() - { - Environment.SetEnvironmentVariable("WEBSITE_HOSTNAME", null); - } - } -} \ No newline at end of file diff --git a/NETCORE/test/Microsoft.ApplicationInsights.AspNetCore.Tests/TelemetryInitializers/ClientIpHeaderTelemetryInitializerTests.cs b/NETCORE/test/Microsoft.ApplicationInsights.AspNetCore.Tests/TelemetryInitializers/ClientIpHeaderTelemetryInitializerTests.cs deleted file mode 100644 index c6db4b6209..0000000000 --- a/NETCORE/test/Microsoft.ApplicationInsights.AspNetCore.Tests/TelemetryInitializers/ClientIpHeaderTelemetryInitializerTests.cs +++ /dev/null @@ -1,133 +0,0 @@ -namespace Microsoft.ApplicationInsights.AspNetCore.Tests.TelemetryInitializers -{ - using System; - using System.Net; - using Microsoft.ApplicationInsights.AspNetCore.TelemetryInitializers; - using Microsoft.ApplicationInsights.AspNetCore.Tests.Helpers; - using Microsoft.ApplicationInsights.DataContracts; - using Xunit; - using Microsoft.AspNetCore.Http; - using Microsoft.AspNetCore.Http.Features; - - public class ClientIpHeaderTelemetryInitializerTests - { - [Fact] - public void InitializeThrowIfHttpContextAccessorIsNull() - { - Assert.ThrowsAny(() => { var initializer = new ClientIpHeaderTelemetryInitializer(null); }); - } - - [Fact] - public void InitializeDoesNotThrowIfHttpContextIsUnavailable() - { - var ac = new HttpContextAccessor { HttpContext = null }; - - var initializer = new ClientIpHeaderTelemetryInitializer(ac); - - initializer.Initialize(new RequestTelemetry()); - } - - [Fact] - public void InitializeDoesNotThrowIfRequestServicesAreUnavailable() - { - var ac = new HttpContextAccessor { HttpContext = new DefaultHttpContext() }; - - var initializer = new ClientIpHeaderTelemetryInitializer(ac); - - initializer.Initialize(new RequestTelemetry()); - } - - [Fact] - public void InitializeDoesNotThrowIfRequestIsUnavailable() - { - var contextAccessor = HttpContextAccessorHelper.CreateHttpContextAccessorWithoutRequest(new DefaultHttpContext(), new RequestTelemetry()); - - var initializer = new ClientIpHeaderTelemetryInitializer(contextAccessor); - - initializer.Initialize(new EventTelemetry()); - } - - [Fact] - public void InitializeDoesNotThrowIfHeaderCollectionIsUnavailable() - { - var contextAccessor = HttpContextAccessorHelper.CreateHttpContextAccessorWithoutRequest(new DefaultHttpContext(), new RequestTelemetry()); - - var initializer = new ClientIpHeaderTelemetryInitializer(contextAccessor); - - initializer.Initialize(new EventTelemetry()); - } - - [Fact] - public void InitializeDoesNotThrowIfRemoteIpAddressIsNull() - { - var requestTelemetry = new RequestTelemetry(); - var contextAccessor = HttpContextAccessorHelper.CreateHttpContextAccessor(requestTelemetry); - - contextAccessor.HttpContext.Features.Set(new HttpConnectionFeature()); - - var initializer = new ClientIpHeaderTelemetryInitializer(contextAccessor); - - initializer.Initialize(requestTelemetry); - } - - [Fact] - public void InitializeSetsIpFromRemoteIpAddress() - { - var requestTelemetry = new RequestTelemetry(); - var contextAccessor = HttpContextAccessorHelper.CreateHttpContextAccessor(requestTelemetry); - - var httpConnectionFeature = new HttpConnectionFeature - { - RemoteIpAddress = new IPAddress(new byte[] { 1, 2, 3, 4 }) - }; - contextAccessor.HttpContext.Features.Set(httpConnectionFeature); - - var initializer = new ClientIpHeaderTelemetryInitializer(contextAccessor); - - initializer.Initialize(requestTelemetry); - - Assert.Equal("1.2.3.4", requestTelemetry.Context.Location.Ip); - } - - [Theory] - [InlineData("X-Forwarded-For", "127.0.0.3", null, "127.0.0.3")] - [InlineData("X-Forwarded-For", "127.0.0.3:80", null, "127.0.0.3")] - [InlineData("X-Forwarded-For", "[::1]:80", null, "::1")] - [InlineData("X-Forwarded-For", "0:0:0:0:0:0:0:1", null, "::1")] - [InlineData("HEADER", "127.0.0.3;127.0.0.4", ",;", "127.0.0.3")] - [InlineData("X-Forwarded-For", "bad", null, null)] - public void InitializeSetsIPFromStandardHeader(string headerName, string headerValue, string separators, string expected) - { - var requestTelemetry = new RequestTelemetry(); - var contextAccessor = HttpContextAccessorHelper.CreateHttpContextAccessor(requestTelemetry); - - contextAccessor.HttpContext.Request.Headers.Add(headerName, new string[] { headerValue }); - - var initializer = new ClientIpHeaderTelemetryInitializer(contextAccessor); - initializer.HeaderNames.Add(headerName); - if (separators != null) - { - initializer.HeaderValueSeparators = separators; - } - initializer.Initialize(requestTelemetry); - - Assert.Equal(expected, requestTelemetry.Context.Location.Ip); - } - - [Fact] - public void InitializeDoesNotOverrideIPProvidedInline() - { - var requestTelemetry = new RequestTelemetry(); - requestTelemetry.Context.Location.Ip = "127.0.0.4"; - - var contextAccessor = HttpContextAccessorHelper.CreateHttpContextAccessor(requestTelemetry); - contextAccessor.HttpContext.Request.Headers.Add("X-Forwarded-For", new string[] { "127.0.0.3" }); - - var initializer = new ClientIpHeaderTelemetryInitializer(contextAccessor); - - initializer.Initialize(requestTelemetry); - - Assert.Equal("127.0.0.4", requestTelemetry.Context.Location.Ip); - } - } -} diff --git a/NETCORE/test/Microsoft.ApplicationInsights.AspNetCore.Tests/TelemetryInitializers/ComponentVersionTelemetryInitializerTests.cs b/NETCORE/test/Microsoft.ApplicationInsights.AspNetCore.Tests/TelemetryInitializers/ComponentVersionTelemetryInitializerTests.cs deleted file mode 100644 index 84cadda1c9..0000000000 --- a/NETCORE/test/Microsoft.ApplicationInsights.AspNetCore.Tests/TelemetryInitializers/ComponentVersionTelemetryInitializerTests.cs +++ /dev/null @@ -1,63 +0,0 @@ -using Microsoft.ApplicationInsights.AspNetCore.Extensions; -using Microsoft.Extensions.Options; - -namespace Microsoft.ApplicationInsights.AspNetCore.Tests.TelemetryInitializers -{ - using Microsoft.ApplicationInsights.AspNetCore.TelemetryInitializers; - using Microsoft.ApplicationInsights.DataContracts; - using Xunit; - - public class ComponentVersionTelemetryInitializerTests - { - - [Fact] - public void InitializeDoesNotThrowIfHttpContextIsUnavailable() - { - var initializer = new ComponentVersionTelemetryInitializer(this.BuildConfigurationWithVersion()); - initializer.Initialize(new RequestTelemetry()); - } - - [Fact] - public void InitializeDoesNotThrowIfRequestTelemetryIsUnavailable() - { - var initializer = new ComponentVersionTelemetryInitializer(this.BuildConfigurationWithVersion()); - initializer.Initialize(new RequestTelemetry()); - } - - [Fact] - public void InitializeAssignsVersionToTelemetry() - { - var initializer = new ComponentVersionTelemetryInitializer(this.BuildConfigurationWithVersion()); - var telemetry = new RequestTelemetry(); - initializer.Initialize(telemetry); - Assert.NotNull(telemetry.Context.Component.Version); - } - - [Fact] - public void InitializeDoesNotOverrideExistingVersion() - { - var initializer = new ComponentVersionTelemetryInitializer(this.BuildConfigurationWithVersion()); - var telemetry = new RequestTelemetry(); - telemetry.Context.Component.Version = "TestVersion"; - initializer.Initialize(telemetry); - - Assert.Equal("TestVersion", telemetry.Context.Component.Version); - } - - [Fact] - public void InitializeDoesNotThrowIfVersionDoesNotExist() - { - var initializer = new ComponentVersionTelemetryInitializer(this.BuildConfigurationWithVersion(null)); - var telemetry = new RequestTelemetry(); - initializer.Initialize(telemetry); - } - - private IOptions BuildConfigurationWithVersion(string versions = "1.0.0") - { - return new OptionsWrapper(new ApplicationInsightsServiceOptions() - { - ApplicationVersion = versions - }); - } - } -} diff --git a/NETCORE/test/Microsoft.ApplicationInsights.AspNetCore.Tests/TelemetryInitializers/DomainNameRoleInstanceTelemetryInitializerTests.cs b/NETCORE/test/Microsoft.ApplicationInsights.AspNetCore.Tests/TelemetryInitializers/DomainNameRoleInstanceTelemetryInitializerTests.cs deleted file mode 100644 index ac723ad0e4..0000000000 --- a/NETCORE/test/Microsoft.ApplicationInsights.AspNetCore.Tests/TelemetryInitializers/DomainNameRoleInstanceTelemetryInitializerTests.cs +++ /dev/null @@ -1,48 +0,0 @@ -namespace Microsoft.ApplicationInsights.AspNetCore.Tests.ContextInitializers -{ - using System; - using System.Globalization; - using System.Net; - using System.Net.NetworkInformation; - using Helpers; - using Microsoft.ApplicationInsights.AspNetCore.TelemetryInitializers; - using Microsoft.ApplicationInsights.DataContracts; - using Microsoft.ApplicationInsights.Extensibility.Implementation; - using Microsoft.AspNetCore.Http; - using Xunit; - - public class DomainNameRoleInstanceTelemetryInitializerTests - { - private const string TestListenerName = "TestListener"; - - [Fact] - public void RoleInstanceNameIsSetToDomainAndHost() - { - var source = new DomainNameRoleInstanceTelemetryInitializer(); - var requestTelemetry = new RequestTelemetry(); - source.Initialize(requestTelemetry); - - string hostName = Dns.GetHostName(); - -#if NETFRAMEWORK - string domainName = IPGlobalProperties.GetIPGlobalProperties().DomainName; - if (hostName.EndsWith(domainName, StringComparison.OrdinalIgnoreCase) == false) - { - hostName = string.Format(CultureInfo.InvariantCulture, "{0}.{1}", hostName, domainName); - } -#endif - - Assert.Equal(hostName, requestTelemetry.Context.Cloud.RoleInstance); - } - - [Fact] - public void ContextInitializerDoesNotOverrideMachineName() - { - var source = new DomainNameRoleInstanceTelemetryInitializer(); - var requestTelemetry = new RequestTelemetry(); - requestTelemetry.Context.Cloud.RoleInstance = "Test"; - source.Initialize(requestTelemetry); - Assert.Equal("Test", requestTelemetry.Context.Cloud.RoleInstance); - } - } -} \ No newline at end of file diff --git a/NETCORE/test/Microsoft.ApplicationInsights.AspNetCore.Tests/TelemetryInitializers/OperationNameTelemetryInitializerTests.cs b/NETCORE/test/Microsoft.ApplicationInsights.AspNetCore.Tests/TelemetryInitializers/OperationNameTelemetryInitializerTests.cs deleted file mode 100644 index 52dfbe5632..0000000000 --- a/NETCORE/test/Microsoft.ApplicationInsights.AspNetCore.Tests/TelemetryInitializers/OperationNameTelemetryInitializerTests.cs +++ /dev/null @@ -1,241 +0,0 @@ -using Microsoft.ApplicationInsights.AspNetCore.DiagnosticListeners; - -namespace Microsoft.ApplicationInsights.AspNetCore.Tests.TelemetryInitializers -{ - using System; - using System.Diagnostics; - using Microsoft.ApplicationInsights.AspNetCore.TelemetryInitializers; - using Microsoft.ApplicationInsights.AspNetCore.Tests.Helpers; - using Microsoft.ApplicationInsights.DataContracts; - using Microsoft.AspNetCore.Mvc; - using Microsoft.AspNetCore.Routing; - using Xunit; - using Microsoft.AspNetCore.Routing.Tree; - using Microsoft.AspNetCore.Http; - using Microsoft.ApplicationInsights.AspNetCore.Implementation; - - public class OperationNameTelemetryInitializerTests - { - private const string TestListenerName = "TestListener"; - - private HostingDiagnosticListener CreateHostingListener(AspNetCoreMajorVersion aspNetCoreMajorVersion) - { - var hostingListener = new HostingDiagnosticListener( - CommonMocks.MockTelemetryClient(telemetry => {}), - CommonMocks.GetMockApplicationIdProvider(), - injectResponseHeaders: true, - trackExceptions: true, - enableW3CHeaders: false, - aspNetCoreMajorVersion: aspNetCoreMajorVersion); - hostingListener.OnSubscribe(); - - return hostingListener; - } - - [Fact] - public void InitializeThrowIfHttpContextAccessorIsNull() - { - Assert.ThrowsAny(() => - { - var initializer = new OperationNameTelemetryInitializer(null); - }); - } - - [Fact] - public void InitializeDoesNotThrowIfHttpContextIsUnavailable() - { - var ac = new HttpContextAccessor() { HttpContext = null }; - - var initializer = new OperationNameTelemetryInitializer(ac); - - initializer.Initialize(new RequestTelemetry()); - } - - [Fact] - public void InitializeDoesNotThrowIfRequestTelemetryIsUnavailable() - { - var ac = new HttpContextAccessor() { HttpContext = new DefaultHttpContext() }; - - var initializer = new OperationNameTelemetryInitializer(ac); - - initializer.Initialize(new RequestTelemetry()); - } - - [Fact] - public void InitializeDoesNotOverrideOperationNameProvidedInline() - { - var contextAccessor = HttpContextAccessorHelper.CreateHttpContextAccessor(new RequestTelemetry(), null); - - var initializer = new OperationNameTelemetryInitializer(contextAccessor); - - var telemetry = new EventTelemetry(); - telemetry.Context.Operation.Name = "Name"; - initializer.Initialize(telemetry); - - Assert.Equal("Name", telemetry.Context.Operation.Name); - } - - [Fact] - public void InitializeSetsTelemetryOperationNameToMethodAndPath() - { - var contextAccessor = HttpContextAccessorHelper.CreateHttpContextAccessor(new RequestTelemetry(), null); - - var initializer = new OperationNameTelemetryInitializer(contextAccessor); - - var telemetry = new EventTelemetry(); - initializer.Initialize(telemetry); - - Assert.Equal("GET /Test", telemetry.Context.Operation.Name); - } - - [Fact] - public void InitializeSetsTelemetryOperationNameToControllerFromActionContext() - { - var actionContext = new ActionContext(); - actionContext.RouteData = new RouteData(); - actionContext.RouteData.Values.Add("controller", "home"); - - var contextAccessor = HttpContextAccessorHelper.CreateHttpContextAccessor(new RequestTelemetry(), actionContext); - - var telemetryListener = new DiagnosticListener(TestListenerName); - using (var listener = CreateHostingListener(AspNetCoreMajorVersion.One)) - { - telemetryListener.Subscribe(listener); - telemetryListener.Write("Microsoft.AspNetCore.Mvc.BeforeAction", - new { httpContext = contextAccessor.HttpContext, routeData = actionContext.RouteData }); - } - var telemetry = contextAccessor.HttpContext.Features.Get(); - - Assert.Equal("GET home", telemetry.Name); - } - - [Fact] - public void InitializeSetsTelemetryOperationNameToControllerAndActionFromActionContext() - { - var actionContext = new ActionContext(); - actionContext.RouteData = new RouteData(); - actionContext.RouteData.Values.Add("controller", "account"); - actionContext.RouteData.Values.Add("action", "login"); - - var contextAccessor = HttpContextAccessorHelper.CreateHttpContextAccessor(new RequestTelemetry(), actionContext); - - var telemetryListener = new DiagnosticListener(TestListenerName); - using (var listener = CreateHostingListener(AspNetCoreMajorVersion.One)) - { - telemetryListener.Subscribe(listener); - telemetryListener.Write("Microsoft.AspNetCore.Mvc.BeforeAction", - new { httpContext = contextAccessor.HttpContext, routeData = actionContext.RouteData }); - } - var telemetry = contextAccessor.HttpContext.Features.Get(); - - Assert.Equal("GET account/login", telemetry.Name); - } - - [Fact] - public void InitializeSetsTelemetryOperationNameToPageFromActionContext() - { - var actionContext = new ActionContext(); - actionContext.RouteData = new RouteData(); - actionContext.RouteData.Values.Add("page", "/Index"); - - var contextAccessor = HttpContextAccessorHelper.CreateHttpContextAccessor(new RequestTelemetry(), actionContext); - - var telemetryListener = new DiagnosticListener(TestListenerName); - using (var listener = CreateHostingListener(AspNetCoreMajorVersion.One)) - { - telemetryListener.Subscribe(listener); - telemetryListener.Write("Microsoft.AspNetCore.Mvc.BeforeAction", - new { httpContext = contextAccessor.HttpContext, routeData = actionContext.RouteData }); - } - var telemetry = contextAccessor.HttpContext.Features.Get(); - - Assert.Equal("GET /Index", telemetry.Name); - } - - [Fact] - public void InitializeSetsTelemetryOperationNameToControllerAndActionAndParameterFromActionContext() - { - var actionContext = new ActionContext(); - actionContext.RouteData = new RouteData(); - actionContext.RouteData.Values.Add("controller", "account"); - actionContext.RouteData.Values.Add("action", "login"); - actionContext.RouteData.Values.Add("parameter", "myName"); - - var contextAccessor = HttpContextAccessorHelper.CreateHttpContextAccessor(new RequestTelemetry(), actionContext); - - var telemetryListener = new DiagnosticListener(TestListenerName); - using (var listener = CreateHostingListener(AspNetCoreMajorVersion.One)) - { - telemetryListener.Subscribe(listener); - telemetryListener.Write("Microsoft.AspNetCore.Mvc.BeforeAction", - new { httpContext = contextAccessor.HttpContext, routeData = actionContext.RouteData }); - } - - var telemetry = contextAccessor.HttpContext.Features.Get(); - - Assert.Equal("GET account/login [parameter]", telemetry.Name); - } - - [Fact] - public void InitializeSortsParameters() - { - var actionContext = new ActionContext(); - actionContext.RouteData = new RouteData(); - actionContext.RouteData.Values.Add("controller", "account"); - actionContext.RouteData.Values.Add("action", "login"); - actionContext.RouteData.Values.Add("parameterZ", "myName1"); - actionContext.RouteData.Values.Add("parameterA", "myName2"); - actionContext.RouteData.Values.Add("parameterN", "myName1"); - - var contextAccessor = HttpContextAccessorHelper.CreateHttpContextAccessor(new RequestTelemetry(), actionContext); - - var telemetryListener = new DiagnosticListener(TestListenerName); - using (var listener = CreateHostingListener(AspNetCoreMajorVersion.One)) - { - telemetryListener.Subscribe(listener); - telemetryListener.Write("Microsoft.AspNetCore.Mvc.BeforeAction", - new { httpContext = contextAccessor.HttpContext, routeData = actionContext.RouteData }); - } - var telemetry = contextAccessor.HttpContext.Features.Get(); - - Assert.Equal("GET account/login [parameterA/parameterN/parameterZ]", telemetry.Name); - } - - [Fact] - public void InitializeDoesNotIncludeRouteGroupKeyInParametersList() - { - var actionContext = new ActionContext(); - actionContext.RouteData = new RouteData(); - actionContext.RouteData.Values.Add("controller", "account"); - actionContext.RouteData.Values.Add("action", "login"); - actionContext.RouteData.Values.Add(TreeRouter.RouteGroupKey, "RouteGroupKey"); - - var contextAccessor = HttpContextAccessorHelper.CreateHttpContextAccessor(new RequestTelemetry(), actionContext); - var telemetryListener = new DiagnosticListener(TestListenerName); - using (var listener = CreateHostingListener(AspNetCoreMajorVersion.One)) - { - telemetryListener.Subscribe(listener); - telemetryListener.Write("Microsoft.AspNetCore.Mvc.BeforeAction", - new { httpContext = contextAccessor.HttpContext, routeData = actionContext.RouteData }); - } - var telemetry = contextAccessor.HttpContext.Features.Get(); - - Assert.Equal("GET account/login", telemetry.Name); - } - - [Fact] - public void InitializeSetsRequestContextOperationNameToRequestName() - { - var telemetry = new RequestTelemetry(); - telemetry.Name = "POST /Test"; - - var contextAccessor = HttpContextAccessorHelper.CreateHttpContextAccessor(telemetry); - var initializer = new OperationNameTelemetryInitializer(contextAccessor); - - initializer.Initialize(telemetry); - - Assert.Equal("POST /Test", telemetry.Context.Operation.Name); - } - - } -} \ No newline at end of file diff --git a/NETCORE/test/Microsoft.ApplicationInsights.AspNetCore.Tests/TelemetryInitializers/RoleNameContainerTests.cs b/NETCORE/test/Microsoft.ApplicationInsights.AspNetCore.Tests/TelemetryInitializers/RoleNameContainerTests.cs deleted file mode 100644 index e803cbe3f4..0000000000 --- a/NETCORE/test/Microsoft.ApplicationInsights.AspNetCore.Tests/TelemetryInitializers/RoleNameContainerTests.cs +++ /dev/null @@ -1,90 +0,0 @@ -using System; - -using Microsoft.ApplicationInsights.AspNetCore.Implementation; -using Microsoft.AspNetCore.Http; - -using Xunit; - -namespace Microsoft.ApplicationInsights.AspNetCore.Tests.TelemetryInitializers -{ - [Trait("Trait", "RoleName")] - public class RoleNameContainerTests : IDisposable - { - public RoleNameContainerTests() - { - Environment.SetEnvironmentVariable("WEBSITE_HOSTNAME", "initialize"); - } - - [Fact] - public void VerifyCanSetRoleNameFromEnvironmentVariableAndSetsIsWebAppProperty() - { - try - { - Environment.SetEnvironmentVariable("WEBSITE_HOSTNAME", "a.b.c.azurewebsites.net"); - - var roleNameContainer = new RoleNameContainer(hostNameSuffix: ".azurewebsites.net"); - - Assert.Equal("a.b.c", roleNameContainer.RoleName); - Assert.True(roleNameContainer.IsAzureWebApp); - } - finally - { - this.ClearEnvironmentVariable(); - } - } - - [Fact (Skip = "this test fails when run in parallel because other tests modify the environment variable.")] - public void VerifyWhenEnvironmentVariableIsNull() - { - try - { - Environment.SetEnvironmentVariable("WEBSITE_HOSTNAME", null); - - var roleNameContainer = new RoleNameContainer(hostNameSuffix: ".azurewebsites.net"); - - Assert.Equal(string.Empty, roleNameContainer.RoleName); - Assert.False(roleNameContainer.IsAzureWebApp); - } - finally - { - this.ClearEnvironmentVariable(); - } - } - - [Fact] - public void VerifyCanSetRoleNameFromHeaders() - { - var roleNameContainer = new RoleNameContainer(hostNameSuffix: ".azurewebsites.net"); - - var headers = new HeaderDictionary(); - headers.Add("WAS-DEFAULT-HOSTNAME", "d.e.f.azurewebsites.net"); - roleNameContainer.Set(headers); - - Assert.Equal("d.e.f", roleNameContainer.RoleName); - } - - [Fact] - public void VerifyEmptyHeadersDoNotOverwriteEnvironmentVaribaleValue() - { - try - { - Environment.SetEnvironmentVariable("WEBSITE_HOSTNAME", "a.b.c.azurewebsites.net"); - var roleNameContainer = new RoleNameContainer(hostNameSuffix: ".azurewebsites.net"); - - Assert.Equal("a.b.c", roleNameContainer.RoleName); - - roleNameContainer.Set(new HeaderDictionary()); // empty headers - - Assert.Equal("a.b.c", roleNameContainer.RoleName); - } - finally - { - this.ClearEnvironmentVariable(); - } - } - - public void Dispose() => this.ClearEnvironmentVariable(); - - private void ClearEnvironmentVariable() => Environment.SetEnvironmentVariable("WEBSITE_HOSTNAME", null); - } -} diff --git a/NETCORE/test/Microsoft.ApplicationInsights.AspNetCore.Tests/TelemetryInitializers/SyntheticTelemetryInitializerTests.cs b/NETCORE/test/Microsoft.ApplicationInsights.AspNetCore.Tests/TelemetryInitializers/SyntheticTelemetryInitializerTests.cs deleted file mode 100644 index 04560a73d4..0000000000 --- a/NETCORE/test/Microsoft.ApplicationInsights.AspNetCore.Tests/TelemetryInitializers/SyntheticTelemetryInitializerTests.cs +++ /dev/null @@ -1,119 +0,0 @@ -namespace Microsoft.ApplicationInsights.AspNet.Tests.TelemetryInitializers -{ - using System; - using Microsoft.ApplicationInsights.AspNetCore.TelemetryInitializers; - using Microsoft.ApplicationInsights.AspNetCore.Tests.Helpers; - using Microsoft.ApplicationInsights.DataContracts; - using Microsoft.AspNetCore.Http; - using Xunit; - - public class SyntheticTelemetryInitializerTests - { - [Fact] - public void InitializeThrowIfHttpContextAccessorIsNull() - { - Assert.Throws(() => { var initializer = new SyntheticTelemetryInitializer(null); }); - } - - [Fact] - public void InitializeDoesNotThrowIfHttpContextIsUnavailable() - { - var ac = new HttpContextAccessor() { HttpContext = null }; - - var initializer = new SyntheticTelemetryInitializer(ac); - - initializer.Initialize(new RequestTelemetry()); - } - - [Fact] - public void InitializeDoesNotThrowIfRequestTelemetryIsUnavailable() - { - var ac = new HttpContextAccessor() { HttpContext = new DefaultHttpContext() }; - - var initializer = new SyntheticTelemetryInitializer(ac); - - initializer.Initialize(new RequestTelemetry()); - } - - [Fact] - public void InitializeSetSyntheticTrafficToDesiredValue() - { - var requestTelemetry = new RequestTelemetry(); - var contextAccessor = HttpContextAccessorHelper.CreateHttpContextAccessor(requestTelemetry); - requestTelemetry.Context.Operation.SyntheticSource = null; - contextAccessor.HttpContext.Request.Headers.Add("SyntheticTest-Location", new string[] { "location" }); - contextAccessor.HttpContext.Request.Headers.Add("SyntheticTest-RunId", new string[] { "runId" }); - - var initializer = new SyntheticTelemetryInitializer(contextAccessor); - - initializer.Initialize(requestTelemetry); - - Assert.Equal("Application Insights Availability Monitoring", requestTelemetry.Context.Operation.SyntheticSource); - } - - [Fact] - public void InitializeDoesNotHaveSyntheticTrafficSpecified() - { - var requestTelemetry = new RequestTelemetry(); - var contextAccessor = HttpContextAccessorHelper.CreateHttpContextAccessor(requestTelemetry); - requestTelemetry.Context.Operation.SyntheticSource = "some value"; - - var initializer = new SyntheticTelemetryInitializer(contextAccessor); - - initializer.Initialize(requestTelemetry); - - Assert.Equal("some value", requestTelemetry.Context.Operation.SyntheticSource); - } - - [Fact] - public void InitializeRequestDoesNotHaveRunIdHeaderButHasLocationHeader() - { - var requestTelemetry = new RequestTelemetry(); - var contextAccessor = HttpContextAccessorHelper.CreateHttpContextAccessor(requestTelemetry); - requestTelemetry.Context.Operation.SyntheticSource = null; - contextAccessor.HttpContext.Request.Headers.Add("SyntheticTest-Location", new string[] { "location" }); - contextAccessor.HttpContext.Request.Headers.Remove("SyntheticTest-RunId"); - - var initializer = new SyntheticTelemetryInitializer(contextAccessor); - - initializer.Initialize(requestTelemetry); - - Assert.Null(requestTelemetry.Context.Operation.SyntheticSource); - } - - [Fact] - public void InitializeRequestDoesHaveRunIdHeaderButNoLocationHeader() - { - var requestTelemetry = new RequestTelemetry(); - var contextAccessor = HttpContextAccessorHelper.CreateHttpContextAccessor(requestTelemetry); - requestTelemetry.Context.Operation.SyntheticSource = null; - contextAccessor.HttpContext.Request.Headers.Remove("SyntheticTest-Location"); - contextAccessor.HttpContext.Request.Headers.Add("SyntheticTest-RunId", new string[] { "runId" }); - - var initializer = new SyntheticTelemetryInitializer(contextAccessor); - - initializer.Initialize(requestTelemetry); - - Assert.Null(requestTelemetry.Context.Operation.SyntheticSource); - } - - [Fact] - public void InitializeRequestValidateLocationAndUserAreSetCorrectly() - { - var requestTelemetry = new RequestTelemetry(); - var contextAccessor = HttpContextAccessorHelper.CreateHttpContextAccessor(requestTelemetry); - var desiredLocation = "location_runId"; - - requestTelemetry.Context.Operation.SyntheticSource = null; - contextAccessor.HttpContext.Request.Headers.Add("SyntheticTest-Location", new string[] { "location" }); - contextAccessor.HttpContext.Request.Headers.Add("SyntheticTest-RunId", new string[] { "runId" }); - - var initializer = new SyntheticTelemetryInitializer(contextAccessor); - - initializer.Initialize(requestTelemetry); - - Assert.Equal(desiredLocation, requestTelemetry.Context.User.Id); - Assert.Equal("runId", requestTelemetry.Context.Session.Id); - } - } -} diff --git a/NETCORE/test/Microsoft.ApplicationInsights.AspNetCore.Tests/TelemetryInitializers/WebSessionTelemetryInitializerTests.cs b/NETCORE/test/Microsoft.ApplicationInsights.AspNetCore.Tests/TelemetryInitializers/WebSessionTelemetryInitializerTests.cs deleted file mode 100644 index 8a424241bd..0000000000 --- a/NETCORE/test/Microsoft.ApplicationInsights.AspNetCore.Tests/TelemetryInitializers/WebSessionTelemetryInitializerTests.cs +++ /dev/null @@ -1,67 +0,0 @@ -namespace Microsoft.ApplicationInsights.AspNetCore.Tests.TelemetryInitializers -{ - using System; - - using Microsoft.ApplicationInsights.AspNetCore.TelemetryInitializers; - using Microsoft.ApplicationInsights.AspNetCore.Tests.Helpers; - using Microsoft.ApplicationInsights.DataContracts; - using Microsoft.AspNetCore.Http; - - using Xunit; - - public class WebSessionTelemetryInitializerTests - { - [Fact] - public void InitializeThrowIfHttpContextAccessorIsNull() - { - Assert.ThrowsAny(() => { var initializer = new WebSessionTelemetryInitializer(null); }); - } - - [Fact] - public void InitializeDoesNotThrowIfHttpContextIsUnavailable() - { - var ac = new HttpContextAccessor() { HttpContext = null }; - - var initializer = new WebSessionTelemetryInitializer(ac); - - initializer.Initialize(new RequestTelemetry()); - } - - [Fact] - public void InitializeDoesNotThrowIfRequestTelemetryIsUnavailable() - { - var ac = new HttpContextAccessor() { HttpContext = new DefaultHttpContext() }; - - var initializer = new WebSessionTelemetryInitializer(ac); - - initializer.Initialize(new RequestTelemetry()); - } - - [Fact] - public void InitializeSetsSessionFromCookie() - { - var requestTelemetry = new RequestTelemetry(); - var contextAccessor = HttpContextAccessorHelper.CreateHttpContextAccessor(requestTelemetry); - contextAccessor.HttpContext.Request.Headers["Cookie"] = "ai_session=test|2015-04-10T17:11:38.378Z|2015-04-10T17:11:39.180Z"; - var initializer = new WebSessionTelemetryInitializer(contextAccessor); - - initializer.Initialize(requestTelemetry); - - Assert.Equal("test", requestTelemetry.Context.Session.Id); - } - - [Fact] - public void InitializeDoesNotOverrideSessionProvidedInline() - { - var requestTelemetry = new RequestTelemetry(); - requestTelemetry.Context.Session.Id = "Inline"; - var contextAccessor = HttpContextAccessorHelper.CreateHttpContextAccessor(requestTelemetry); - contextAccessor.HttpContext.Request.Headers["Cookie"] = "ai_session=test|2015-04-10T17:11:38.378Z|2015-04-10T17:11:39.180Z"; - var initializer = new WebSessionTelemetryInitializer(contextAccessor); - - initializer.Initialize(requestTelemetry); - - Assert.Equal("Inline", requestTelemetry.Context.Session.Id); - } - } -} \ No newline at end of file diff --git a/NETCORE/test/Microsoft.ApplicationInsights.AspNetCore.Tests/TelemetryInitializers/WebUserTelemetryInitializerTests.cs b/NETCORE/test/Microsoft.ApplicationInsights.AspNetCore.Tests/TelemetryInitializers/WebUserTelemetryInitializerTests.cs deleted file mode 100644 index 23c64af4ec..0000000000 --- a/NETCORE/test/Microsoft.ApplicationInsights.AspNetCore.Tests/TelemetryInitializers/WebUserTelemetryInitializerTests.cs +++ /dev/null @@ -1,67 +0,0 @@ -namespace Microsoft.ApplicationInsights.AspNetCore.Tests.TelemetryInitializers -{ - using System; - - using Microsoft.ApplicationInsights.AspNetCore.TelemetryInitializers; - using Microsoft.ApplicationInsights.AspNetCore.Tests.Helpers; - using Microsoft.ApplicationInsights.DataContracts; - using Microsoft.AspNetCore.Http; - - using Xunit; - - public class WebUserTelemetryInitializerTests - { - [Fact] - public void InitializeThrowIfHttpContextAccessorIsNull() - { - Assert.Throws(() => { var initializer = new WebUserTelemetryInitializer(null); }); - } - - [Fact] - public void InitializeDoesNotThrowIfHttpContextIsUnavailable() - { - var ac = new HttpContextAccessor() { HttpContext = null }; - - var initializer = new WebUserTelemetryInitializer(ac); - - initializer.Initialize(new RequestTelemetry()); - } - - [Fact] - public void InitializeDoesNotThrowIfRequestTelemetryIsUnavailable() - { - var ac = new HttpContextAccessor() { HttpContext = new DefaultHttpContext() }; - - var initializer = new WebUserTelemetryInitializer(ac); - - initializer.Initialize(new RequestTelemetry()); - } - - [Fact] - public void InitializeSetsUserFromCookie() - { - var requestTelemetry = new RequestTelemetry(); - var contextAccessor = HttpContextAccessorHelper.CreateHttpContextAccessor(requestTelemetry); - contextAccessor.HttpContext.Request.Headers["Cookie"] = "ai_user=test"; - var initializer = new WebUserTelemetryInitializer(contextAccessor); - - initializer.Initialize(requestTelemetry); - - Assert.Equal("test", requestTelemetry.Context.User.Id); - } - - [Fact] - public void InitializeDoesNotOverrideUserProvidedInline() - { - var requestTelemetry = new RequestTelemetry(); - requestTelemetry.Context.User.Id = "Inline"; - var contextAccessor = HttpContextAccessorHelper.CreateHttpContextAccessor(requestTelemetry); - contextAccessor.HttpContext.Request.Headers["Cookie"] = "ai_user=test"; - var initializer = new WebUserTelemetryInitializer(contextAccessor); - - initializer.Initialize(requestTelemetry); - - Assert.Equal("Inline", requestTelemetry.Context.User.Id); - } - } -} \ No newline at end of file diff --git a/NETCORE/test/Microsoft.ApplicationInsights.AspNetCore.Tests/TestTelemetryModule.cs b/NETCORE/test/Microsoft.ApplicationInsights.AspNetCore.Tests/TestTelemetryModule.cs deleted file mode 100644 index 19fbabeb16..0000000000 --- a/NETCORE/test/Microsoft.ApplicationInsights.AspNetCore.Tests/TestTelemetryModule.cs +++ /dev/null @@ -1,22 +0,0 @@ -namespace Microsoft.ApplicationInsights.AspNetCore.Tests -{ - using System; - using Microsoft.ApplicationInsights.Extensibility; - - internal class TestTelemetryModule : ITelemetryModule - { - public TestTelemetryModule() - { - this.IsInitialized = false; - } - - public bool IsInitialized { get; private set; } - - public string CustomProperty { get; set; } - - public void Initialize(TelemetryConfiguration configuration) - { - this.IsInitialized = true; - } - } -} diff --git a/NETCORE/test/Microsoft.ApplicationInsights.AspNetCore.Tests/appsettings.json b/NETCORE/test/Microsoft.ApplicationInsights.AspNetCore.Tests/appsettings.json deleted file mode 100644 index 0ab6b527b4..0000000000 --- a/NETCORE/test/Microsoft.ApplicationInsights.AspNetCore.Tests/appsettings.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "ApplicationInsights": { - "InstrumentationKey": "33333333-2222-3333-4444-555555555555", - "TelemetryChannel": { - "EndpointAddress": "http://hosthere/v2/track/", - "DeveloperMode": true - } - } -} \ No newline at end of file diff --git a/NETCORE/test/Microsoft.ApplicationInsights.AspNetCore.Tests/content/config-all-default.json b/NETCORE/test/Microsoft.ApplicationInsights.AspNetCore.Tests/content/config-all-default.json deleted file mode 100644 index 1309ab9199..0000000000 --- a/NETCORE/test/Microsoft.ApplicationInsights.AspNetCore.Tests/content/config-all-default.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "ApplicationInsights": { - "InstrumentationKey": "11111111-2222-3333-4444-555555555555", - "ConnectionString": "InstrumentationKey=11111111-2222-3333-4444-555555555555;IngestionEndpoint=http://testendpoint", - "EnablePerformanceCounterCollectionModule": true, - "EnableAzureInstanceMetadataTelemetryModule": true, - "EnableRequestTrackingTelemetryModule": true, - "EnableDependencyTrackingTelemetryModule": true, - "EnableAppServicesHeartbeatTelemetryModule": true, - "EnableEventCounterCollectionModule": true, - "AddAutoCollectedMetricExtractor": true, - "EnableQuickPulseMetricStream": true, - "EnableHeartbeat": true, - "EnableAuthenticationTrackingJavaScript": false, - "ApplicationVersion": "Version", - "TelemetryChannel": { - "EndpointAddress": "http://testendpoint/v2/track", - "DeveloperMode": true - } - } -} \ No newline at end of file diff --git a/NETCORE/test/Microsoft.ApplicationInsights.AspNetCore.Tests/content/config-all-settings-false.json b/NETCORE/test/Microsoft.ApplicationInsights.AspNetCore.Tests/content/config-all-settings-false.json deleted file mode 100644 index c0716fd140..0000000000 --- a/NETCORE/test/Microsoft.ApplicationInsights.AspNetCore.Tests/content/config-all-settings-false.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "ApplicationInsights": { - "InstrumentationKey": "22222222-2222-3333-4444-555555555555", - "ConnectionString": "InstrumentationKey=22222222-2222-3333-4444-555555555555;IngestionEndpoint=http://testendpoint", - "EnablePerformanceCounterCollectionModule": false, - "EnableAzureInstanceMetadataTelemetryModule": false, - "EnableRequestTrackingTelemetryModule": false, - "EnableDependencyTrackingTelemetryModule": false, - "EnableAppServicesHeartbeatTelemetryModule": false, - "EnableEventCounterCollectionModule": false, - "AddAutoCollectedMetricExtractor": false, - "EnableQuickPulseMetricStream": false, - "EnableHeartbeat": false, - "EnableAuthenticationTrackingJavaScript": false, - "EnableDiagnosticsTelemetryModule": false, - "EnableActiveTelemetryConfigurationSetup": false, - "TelemetryChannel": { - "EndpointAddress": "http://testendpoint/v2/track", - "DeveloperMode": false - } - } -} \ No newline at end of file diff --git a/NETCORE/test/Microsoft.ApplicationInsights.AspNetCore.Tests/content/config-all-settings-true.json b/NETCORE/test/Microsoft.ApplicationInsights.AspNetCore.Tests/content/config-all-settings-true.json deleted file mode 100644 index 4b20494b84..0000000000 --- a/NETCORE/test/Microsoft.ApplicationInsights.AspNetCore.Tests/content/config-all-settings-true.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "ApplicationInsights": { - "InstrumentationKey": "22222222-2222-3333-4444-555555555555", - "ConnectionString": "InstrumentationKey=22222222-2222-3333-4444-555555555555;IngestionEndpoint=http://testendpoint", - "EnablePerformanceCounterCollectionModule": true, - "EnableAzureInstanceMetadataTelemetryModule": true, - "EnableRequestTrackingTelemetryModule": true, - "EnableDependencyTrackingTelemetryModule": true, - "EnableAppServicesHeartbeatTelemetryModule": true, - "EnableEventCounterCollectionModule": true, - "AddAutoCollectedMetricExtractor": true, - "EnableQuickPulseMetricStream": true, - "EnableHeartbeat": true, - "EnableAuthenticationTrackingJavaScript": true, - "EnableDiagnosticsTelemetryModule": true, - "EnableActiveTelemetryConfigurationSetup": true, - "TelemetryChannel": { - "EndpointAddress": "http://testendpoint/v2/track", - "DeveloperMode": true - } - } -} \ No newline at end of file diff --git a/NETCORE/test/Microsoft.ApplicationInsights.AspNetCore.Tests/content/config-connection-string-and-instrumentation-key.json b/NETCORE/test/Microsoft.ApplicationInsights.AspNetCore.Tests/content/config-connection-string-and-instrumentation-key.json deleted file mode 100644 index 4d837ba827..0000000000 --- a/NETCORE/test/Microsoft.ApplicationInsights.AspNetCore.Tests/content/config-connection-string-and-instrumentation-key.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "ApplicationInsights": { - "ConnectionString": "InstrumentationKey=11111111-2222-3333-4444-555555555555;IngestionEndpoint=http://127.0.0.1", - "InstrumentationKey": "33333333-4444-5555-6666-777777777777" - } - } \ No newline at end of file diff --git a/NETCORE/test/Microsoft.ApplicationInsights.AspNetCore.Tests/content/config-connection-string.json b/NETCORE/test/Microsoft.ApplicationInsights.AspNetCore.Tests/content/config-connection-string.json deleted file mode 100644 index ed4a8e6461..0000000000 --- a/NETCORE/test/Microsoft.ApplicationInsights.AspNetCore.Tests/content/config-connection-string.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "ApplicationInsights": { - "ConnectionString" : "InstrumentationKey=11111111-2222-3333-4444-555555555555;IngestionEndpoint=http://127.0.0.1" - } - } \ No newline at end of file diff --git a/NETCORE/test/Microsoft.ApplicationInsights.AspNetCore.Tests/content/config-developer-mode.json b/NETCORE/test/Microsoft.ApplicationInsights.AspNetCore.Tests/content/config-developer-mode.json deleted file mode 100644 index 9e7541ca02..0000000000 --- a/NETCORE/test/Microsoft.ApplicationInsights.AspNetCore.Tests/content/config-developer-mode.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "ApplicationInsights": { - "TelemetryChannel": { - "DeveloperMode": true - } - } -} \ No newline at end of file diff --git a/NETCORE/test/Microsoft.ApplicationInsights.AspNetCore.Tests/content/config-endpoint-address.json b/NETCORE/test/Microsoft.ApplicationInsights.AspNetCore.Tests/content/config-endpoint-address.json deleted file mode 100644 index 7fd7c6b27c..0000000000 --- a/NETCORE/test/Microsoft.ApplicationInsights.AspNetCore.Tests/content/config-endpoint-address.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "ApplicationInsights": { - "TelemetryChannel": { - "EndpointAddress": "http://localhost:1234/v2/track/" - } - } -} \ No newline at end of file diff --git a/NETCORE/test/Microsoft.ApplicationInsights.AspNetCore.Tests/content/config-instrumentation-key-new.json b/NETCORE/test/Microsoft.ApplicationInsights.AspNetCore.Tests/content/config-instrumentation-key-new.json deleted file mode 100644 index 9032cd4744..0000000000 --- a/NETCORE/test/Microsoft.ApplicationInsights.AspNetCore.Tests/content/config-instrumentation-key-new.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "ApplicationInsights": { - "InstrumentationKey": "33333333-4444-5555-6666-777777777777" - } -} \ No newline at end of file diff --git a/NETCORE/test/Microsoft.ApplicationInsights.AspNetCore.Tests/content/config-instrumentation-key.json b/NETCORE/test/Microsoft.ApplicationInsights.AspNetCore.Tests/content/config-instrumentation-key.json deleted file mode 100644 index 253df23438..0000000000 --- a/NETCORE/test/Microsoft.ApplicationInsights.AspNetCore.Tests/content/config-instrumentation-key.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "ApplicationInsights": { - "InstrumentationKey": "11111111-2222-3333-4444-555555555555" - } -} \ No newline at end of file diff --git a/NETCORE/test/Microsoft.ApplicationInsights.WorkerService.Tests/ExtensionsTest.cs b/NETCORE/test/Microsoft.ApplicationInsights.WorkerService.Tests/ExtensionsTest.cs deleted file mode 100644 index 3930669f22..0000000000 --- a/NETCORE/test/Microsoft.ApplicationInsights.WorkerService.Tests/ExtensionsTest.cs +++ /dev/null @@ -1,863 +0,0 @@ -using Microsoft.ApplicationInsights.WorkerService.TelemetryInitializers; -using Microsoft.ApplicationInsights.Channel; -using Microsoft.ApplicationInsights.DataContracts; -using Microsoft.ApplicationInsights.DependencyCollector; -using Microsoft.ApplicationInsights.Extensibility; -using Microsoft.ApplicationInsights.Extensibility.EventCounterCollector; -using Microsoft.ApplicationInsights.Extensibility.Implementation.ApplicationId; -using Microsoft.ApplicationInsights.Extensibility.PerfCounterCollector; -using Microsoft.ApplicationInsights.Extensibility.PerfCounterCollector.QuickPulse; -using Microsoft.ApplicationInsights.WindowsServer; -using Microsoft.ApplicationInsights.WindowsServer.TelemetryChannel; -using Microsoft.Extensions.Configuration; -using Microsoft.Extensions.DependencyInjection; -using System; -using System.IO; -using System.Linq; -using Xunit; -using Xunit.Abstractions; -using System.Reflection; -using Microsoft.Extensions.Options; -using Microsoft.ApplicationInsights.Extensibility.Implementation.Tracing; - -namespace Microsoft.ApplicationInsights.WorkerService.Tests -{ - public class ExtensionsTests - { - private readonly ITestOutputHelper output; - private const string TestConnectionString = "InstrumentationKey=11111111-2222-3333-4444-555555555555;IngestionEndpoint=http://127.0.0.1"; - public const string TestInstrumentationKey = "11111111-2222-3333-4444-555555555555"; - public const string TestInstrumentationKeyEnv = "AAAAAAAA-BBBB-CCCC-DDDD-DDDDDDDDDD"; - public const string TestEndPoint = "http://testendpoint/v2/track"; - public const string TestEndPointEnv = "http://testendpointend/v2/track"; - public ExtensionsTests(ITestOutputHelper output) - { - this.output = output; - this.output.WriteLine("Initialized"); - } - - private static IServiceProvider TestShim(string configType, bool isEnabled, Action testConfig) - { - // ARRANGE - Action serviceOptions = null; - var filePath = Path.Combine(Directory.GetCurrentDirectory(), "content", "config-all-settings-" + isEnabled.ToString().ToLower() + ".json"); - - if (configType == "Code") - { - filePath = null; - - // This will set the property defined in the test. - serviceOptions = o => { testConfig(o, isEnabled); }; - } - - // ACT - var services = CreateServicesAndAddApplicationinsightsWorker( - jsonPath: filePath, - serviceOptions: serviceOptions, - useDefaultConfig: configType == "DefaultConfiguration" ? true : false); - - IServiceProvider serviceProvider = services.BuildServiceProvider(); - - // Get telemetry client to trigger TelemetryConfig setup. - var tc = serviceProvider.GetService(); - - // Verify that Modules were added to DI. - var modules = serviceProvider.GetServices(); - Assert.NotNull(modules); - - return serviceProvider; - } - - public static ServiceCollection CreateServicesAndAddApplicationinsightsWorker(string jsonPath, Action serviceOptions = null, bool useDefaultConfig = true) - { - IConfigurationRoot config; - var services = new ServiceCollection(); - - if (jsonPath != null) - { - var jsonFullPath = Path.Combine(Directory.GetCurrentDirectory(), jsonPath); - Console.WriteLine("json:" + jsonFullPath); - try - { - config = new ConfigurationBuilder().SetBasePath(Directory.GetCurrentDirectory()).AddJsonFile(jsonFullPath).Build(); - } - catch (Exception) - { - throw new Exception("Unable to build with json:" + jsonFullPath); - } - } - else - { - var configBuilder = new ConfigurationBuilder() - .AddJsonFile(Path.Combine(Directory.GetCurrentDirectory(), "appsettings.json"), true) - .AddEnvironmentVariables(); - config = configBuilder.Build(); - } - - if (useDefaultConfig) - { - services.AddSingleton(config); - services.AddApplicationInsightsTelemetryWorkerService(); - } - else - { - services.AddApplicationInsightsTelemetryWorkerService(config); - } - - if (serviceOptions != null) - { - services.Configure(serviceOptions); - } - - return services; - } - - private static ServiceCollection CreateServicesAndAddApplicationinsightsWorker(Action serviceOptions = null) - { - var services = new ServiceCollection(); - services.AddApplicationInsightsTelemetryWorkerService(); - if (serviceOptions != null) - { - services.Configure(serviceOptions); - } - return services; - } - - [Theory] - [InlineData(true)] - [InlineData(false)] - public static void TelemetryModulesResolvableWhenKeyedServiceRegistered(bool manuallyRegisterDiagnosticsTelemetryModule) - { - // Note: This test verifies a regression doesn't get introduced for: - // https://github.com/microsoft/ApplicationInsights-dotnet/issues/2879 - - var services = new ServiceCollection(); - - services.AddSingleton(); - if (manuallyRegisterDiagnosticsTelemetryModule) - { - services.AddSingleton(); - } - - services.AddKeyedSingleton(typeof(ITestService), serviceKey: new(), implementationType: typeof(TestService)); - services.AddKeyedSingleton(typeof(ITestService), serviceKey: new(), implementationInstance: new TestService()); - services.AddKeyedSingleton(typeof(ITestService), serviceKey: new(), implementationFactory: (sp, key) => new TestService()); - - services.AddApplicationInsightsTelemetryWorkerService(); - - using var sp = services.BuildServiceProvider(); - - var telemetryModules = sp.GetServices(); - - Assert.Equal(8, telemetryModules.Count()); - - Assert.Single(telemetryModules.Where(m => m.GetType() == typeof(DiagnosticsTelemetryModule))); - } - - [Theory] - [InlineData(typeof(ITelemetryInitializer), typeof(ApplicationInsights.WorkerService.TelemetryInitializers.DomainNameRoleInstanceTelemetryInitializer), ServiceLifetime.Singleton)] - [InlineData(typeof(ITelemetryInitializer), typeof(AzureWebAppRoleEnvironmentTelemetryInitializer), ServiceLifetime.Singleton)] - [InlineData(typeof(ITelemetryInitializer), typeof(ComponentVersionTelemetryInitializer), ServiceLifetime.Singleton)] - [InlineData(typeof(ITelemetryInitializer), typeof(HttpDependenciesParsingTelemetryInitializer), ServiceLifetime.Singleton)] - [InlineData(typeof(TelemetryConfiguration), null, ServiceLifetime.Singleton)] - [InlineData(typeof(TelemetryClient), typeof(TelemetryClient), ServiceLifetime.Singleton)] - [InlineData(typeof(ITelemetryChannel), typeof(ServerTelemetryChannel), ServiceLifetime.Singleton)] - public void RegistersExpectedServices(Type serviceType, Type implementationType, ServiceLifetime lifecycle) - { - var services = CreateServicesAndAddApplicationinsightsWorker(null); - ServiceDescriptor service = services.Single(s => s.ServiceType == serviceType && s.ImplementationType == implementationType); - Assert.Equal(lifecycle, service.Lifetime); - } - - [Theory] - [InlineData(typeof(ITelemetryInitializer), typeof(ApplicationInsights.WorkerService.TelemetryInitializers.DomainNameRoleInstanceTelemetryInitializer), ServiceLifetime.Singleton)] - [InlineData(typeof(ITelemetryInitializer), typeof(AzureWebAppRoleEnvironmentTelemetryInitializer), ServiceLifetime.Singleton)] - [InlineData(typeof(ITelemetryInitializer), typeof(ComponentVersionTelemetryInitializer), ServiceLifetime.Singleton)] - [InlineData(typeof(ITelemetryInitializer), typeof(HttpDependenciesParsingTelemetryInitializer), ServiceLifetime.Singleton)] - [InlineData(typeof(TelemetryConfiguration), null, ServiceLifetime.Singleton)] - [InlineData(typeof(TelemetryClient), typeof(TelemetryClient), ServiceLifetime.Singleton)] - [InlineData(typeof(ITelemetryChannel), typeof(ServerTelemetryChannel), ServiceLifetime.Singleton)] - public void RegistersExpectedServicesOnlyOnce(Type serviceType, Type implementationType, ServiceLifetime lifecycle) - { - var services = CreateServicesAndAddApplicationinsightsWorker(null); - services.AddApplicationInsightsTelemetryWorkerService(); - ServiceDescriptor service = services.Single(s => s.ServiceType == serviceType && s.ImplementationType == implementationType); - Assert.Equal(lifecycle, service.Lifetime); - } - - [Fact] - public void DoesNotThrowWithoutInstrumentationKey() - { - var services = CreateServicesAndAddApplicationinsightsWorker(null); - } - - [Fact] - public void ReadsSettingsFromSuppliedConfiguration() - { - var jsonFullPath = Path.Combine(Directory.GetCurrentDirectory(), "content", "sample-appsettings.json"); - - this.output.WriteLine("json:" + jsonFullPath); - var config = new ConfigurationBuilder().AddJsonFile(jsonFullPath).Build(); - var services = new ServiceCollection(); - - services.AddApplicationInsightsTelemetryWorkerService(config); - IServiceProvider serviceProvider = services.BuildServiceProvider(); - var telemetryConfiguration = serviceProvider.GetRequiredService(); - Assert.Equal(TestInstrumentationKey, telemetryConfiguration.InstrumentationKey); - Assert.Equal(TestEndPoint, telemetryConfiguration.TelemetryChannel.EndpointAddress); - Assert.Equal(true, telemetryConfiguration.TelemetryChannel.DeveloperMode); - } - - [Fact] - public void ReadsSettingsFromDefaultConfiguration() - { - // Host.CreateDefaultBuilder() in .NET Core 3.0 adds appsetting.json and env variable - // to configuration and is made available for constructor injection. - // this test validates that SDK reads settings from this configuration by default. - // ARRANGE - var jsonFullPath = Path.Combine(Directory.GetCurrentDirectory(), "content", "sample-appsettings.json"); - this.output.WriteLine("json:" + jsonFullPath); - var config = new ConfigurationBuilder().AddJsonFile(jsonFullPath).Build(); - var services = new ServiceCollection(); - // This line mimics the default behavior by CreateDefaultBuilder - services.AddSingleton(config); - - // ACT - services.AddApplicationInsightsTelemetryWorkerService(); - - // VALIDATE - IServiceProvider serviceProvider = services.BuildServiceProvider(); - var telemetryConfiguration = serviceProvider.GetRequiredService(); - Assert.Equal(TestInstrumentationKey, telemetryConfiguration.InstrumentationKey); - Assert.Equal(TestEndPoint, telemetryConfiguration.TelemetryChannel.EndpointAddress); - Assert.Equal(true, telemetryConfiguration.TelemetryChannel.DeveloperMode); - } - - /// - /// Tests that the connection string can be read from a JSON file by the configuration factory. - /// - /// - /// Calls services.AddApplicationInsightsTelemetryWorkerService() when the value is true and reads IConfiguration from user application automatically. - /// Else, it invokes services.AddApplicationInsightsTelemetryWorkerService(configuration) where IConfiguration object is supplied by caller. - /// - [Theory] - [InlineData(true)] - [InlineData(false)] - [Trait("Trait", "ConnectionString")] - public void ReadsConnectionStringFromConfiguration(bool useDefaultConfig) - { - var jsonFullPath = Path.Combine(Directory.GetCurrentDirectory(), "content", "config-connection-string.json"); - - this.output.WriteLine("json:" + jsonFullPath); - var config = new ConfigurationBuilder().AddJsonFile(jsonFullPath).Build(); - - var services = CreateServicesAndAddApplicationinsightsWorker(jsonFullPath, null, useDefaultConfig); - - services.AddApplicationInsightsTelemetryWorkerService(config); - IServiceProvider serviceProvider = services.BuildServiceProvider(); - var telemetryConfiguration = serviceProvider.GetRequiredService(); - Assert.Equal(TestConnectionString, telemetryConfiguration.ConnectionString); - Assert.Equal(TestInstrumentationKey, telemetryConfiguration.InstrumentationKey); - Assert.Equal("http://127.0.0.1/", telemetryConfiguration.EndpointContainer.Ingestion.AbsoluteUri); - } - - [Fact] - public void ReadsSettingsFromDefaultConfigurationWithEnvOverridingConfig() - { - // Host.CreateDefaultBuilder() in .NET Core 3.0 adds appsetting.json and env variable - // to configuration and is made available for constructor injection. - // this test validates that SDK reads settings from this configuration by default - // and gives priority to the ENV variables than the one from config. - - // ARRANGE - Environment.SetEnvironmentVariable("APPINSIGHTS_INSTRUMENTATIONKEY", TestInstrumentationKeyEnv); - Environment.SetEnvironmentVariable("APPINSIGHTS_ENDPOINTADDRESS", TestEndPointEnv); - try - { - var jsonFullPath = Path.Combine(Directory.GetCurrentDirectory(), "content", "sample-appsettings.json"); - this.output.WriteLine("json:" + jsonFullPath); - - // This config will have ikey,endpoint from json and env. ENV one is expected to win. - var config = new ConfigurationBuilder().AddJsonFile(jsonFullPath).AddEnvironmentVariables().Build(); - var services = new ServiceCollection(); - - // This line mimics the default behavior by CreateDefaultBuilder - services.AddSingleton(config); - - // ACT - services.AddApplicationInsightsTelemetryWorkerService(); - - // VALIDATE - IServiceProvider serviceProvider = services.BuildServiceProvider(); - var telemetryConfiguration = serviceProvider.GetRequiredService(); - Assert.Equal(TestInstrumentationKeyEnv, telemetryConfiguration.InstrumentationKey); - Assert.Equal(TestEndPointEnv, telemetryConfiguration.TelemetryChannel.EndpointAddress); - } - finally - { - Environment.SetEnvironmentVariable("APPINSIGHTS_INSTRUMENTATIONKEY", null); - Environment.SetEnvironmentVariable("APPINSIGHTS_ENDPOINTADDRESS", null); - } - } - - [Fact] - public void VerifiesIkeyProvidedInAddApplicationInsightsAlwaysWinsOverOtherOptions() - { - // ARRANGE - Environment.SetEnvironmentVariable("APPINSIGHTS_INSTRUMENTATIONKEY", TestInstrumentationKeyEnv); - try - { - var jsonFullPath = Path.Combine(Directory.GetCurrentDirectory(), "content", "sample-appsettings.json"); - this.output.WriteLine("json:" + jsonFullPath); - - // This config will have ikey,endpoint from json and env. But the one - // user explicitly provider is expected to win. - var config = new ConfigurationBuilder().AddJsonFile(jsonFullPath).AddEnvironmentVariables().Build(); - var services = new ServiceCollection(); - - // This line mimics the default behavior by CreateDefaultBuilder - services.AddSingleton(config); - - // ACT - services.AddApplicationInsightsTelemetryWorkerService("userkey"); - - // VALIDATE - IServiceProvider serviceProvider = services.BuildServiceProvider(); - var telemetryConfiguration = serviceProvider.GetRequiredService(); - Assert.Equal("userkey", telemetryConfiguration.InstrumentationKey); - } - finally - { - Environment.SetEnvironmentVariable("APPINSIGHTS_INSTRUMENTATIONKEY", null); - } - } - - [Fact] - public void DoesNoThrowIfNoSettingsFound() - { - // Host.CreateDefaultBuilder() in .NET Core 3.0 adds appsetting.json and env variable - // to configuration and is made available for constructor injection. - // This test validates that SDK does not throw any error if it cannot find - // application insights configuration in default IConfiguration. - // ARRANGE - var jsonFullPath = Path.Combine(Directory.GetCurrentDirectory(), "content", "sample-appsettings_dontexist.json"); - this.output.WriteLine("json:" + jsonFullPath); - var config = new ConfigurationBuilder().AddJsonFile(jsonFullPath, true).Build(); - var services = new ServiceCollection(); - // This line mimics the default behavior by CreateDefaultBuilder - services.AddSingleton(config); - - // ACT - services.AddApplicationInsightsTelemetryWorkerService(); - - // VALIDATE - IServiceProvider serviceProvider = services.BuildServiceProvider(); - var telemetryConfiguration = serviceProvider.GetRequiredService(); - Assert.True(string.IsNullOrEmpty(telemetryConfiguration.InstrumentationKey)); - } - - [Fact] - public void VerifyAddAIWorkerServiceSetsUpDefaultConfigurationAndModules() - { - var services = new ServiceCollection(); - - // ACT - services.AddApplicationInsightsTelemetryWorkerService("ikey"); - - // VALIDATE - IServiceProvider serviceProvider = services.BuildServiceProvider(); - var telemetryConfiguration = serviceProvider.GetRequiredService(); - Assert.Equal("ikey", telemetryConfiguration.InstrumentationKey); - - // AppID - var appIdProvider = serviceProvider.GetRequiredService(); - Assert.NotNull(appIdProvider); - Assert.True(appIdProvider is ApplicationInsightsApplicationIdProvider); - - // AppID - var channel = serviceProvider.GetRequiredService(); - Assert.NotNull(channel); - Assert.True(channel is ServerTelemetryChannel); - - // TelemetryModules - var modules = serviceProvider.GetServices(); - Assert.NotNull(modules); - Assert.Equal(7, modules.Count()); - - var perfCounterModule = modules.FirstOrDefault(t => t.GetType() == typeof(PerformanceCollectorModule)); - Assert.NotNull(perfCounterModule); - - var qpModule = modules.FirstOrDefault(t => t.GetType() == typeof(QuickPulseTelemetryModule)); - Assert.NotNull(qpModule); - - var evtCounterModule = modules.FirstOrDefault(t => t.GetType() == typeof(EventCounterCollectionModule)); - Assert.NotNull(evtCounterModule); - - var depModule = modules.FirstOrDefault(t => t.GetType() == typeof(DependencyTrackingTelemetryModule)); - Assert.NotNull(depModule); - - var hbModule = modules.FirstOrDefault(t => t.GetType() == typeof(AppServicesHeartbeatTelemetryModule)); - Assert.NotNull(hbModule); - - var azMetadataModule = modules.FirstOrDefault(t => t.GetType() == typeof(AzureInstanceMetadataTelemetryModule)); - Assert.NotNull(azMetadataModule); - - // TelemetryProcessors - Assert.Contains(telemetryConfiguration.DefaultTelemetrySink.TelemetryProcessors, proc => proc.GetType().Name.Contains("AutocollectedMetricsExtractor")); - Assert.Contains(telemetryConfiguration.DefaultTelemetrySink.TelemetryProcessors, proc => proc.GetType().Name.Contains("QuickPulseTelemetryProcessor")); - - // TelemetryInitializers - // 4 added by WorkerService SDK, 1 from Base Sdk - Assert.Equal(5, telemetryConfiguration.TelemetryInitializers.Count); - Assert.Contains(telemetryConfiguration.TelemetryInitializers, initializer => initializer.GetType().Name.Contains("DomainNameRoleInstanceTelemetryInitializer")); - Assert.Contains(telemetryConfiguration.TelemetryInitializers, initializer => initializer.GetType().Name.Contains("AzureWebAppRoleEnvironmentTelemetryInitializer")); - Assert.Contains(telemetryConfiguration.TelemetryInitializers, initializer => initializer.GetType().Name.Contains("ComponentVersionTelemetryInitializer")); - Assert.Contains(telemetryConfiguration.TelemetryInitializers, initializer => initializer.GetType().Name.Contains("HttpDependenciesParsingTelemetryInitializer")); - Assert.Contains(telemetryConfiguration.TelemetryInitializers, initializer => initializer.GetType().Name.Contains("OperationCorrelationTelemetryInitializer")); - - // TelemetryClient - var tc = serviceProvider.GetRequiredService(); - Assert.NotNull(tc); - } - - [Fact] - public static void RegistersTelemetryConfigurationFactoryMethodThatPopulatesEventCounterCollectorWithDefaultListOfCounters() - { - // ARRANGE - var services = new ServiceCollection(); - services.AddApplicationInsightsTelemetryWorkerService(); - - // ACT - IServiceProvider serviceProvider = services.BuildServiceProvider(); - var modules = serviceProvider.GetServices(); - var telemetryConfiguration = serviceProvider.GetRequiredService(); - var eventCounterModule = modules.OfType().Single(); - - // VALIDATE - // By default, no counters are collected. - Assert.Equal(0, eventCounterModule.Counters.Count); - } - - [Fact] - public void VerifyAddAIWorkerServiceUsesTelemetryInitializerAddedToDI() - { - var services = new ServiceCollection(); - var telemetryInitializer = new FakeTelemetryInitializer(); - - // ACT - services.AddApplicationInsightsTelemetryWorkerService(); - services.AddSingleton(telemetryInitializer); - - - // VALIDATE - IServiceProvider serviceProvider = services.BuildServiceProvider(); - var telemetryConfiguration = serviceProvider.GetRequiredService(); - Assert.Contains(telemetryInitializer, telemetryConfiguration.TelemetryInitializers); - } - - [Fact] - public void VerifyAddAIWorkerServiceUsesTelemetryChannelAddedToDI() - { - var services = new ServiceCollection(); - var telChannel = new ServerTelemetryChannel() {StorageFolder = "c:\\mycustom" }; - - // ACT - services.AddApplicationInsightsTelemetryWorkerService("ikey"); - services.AddSingleton(telChannel); - - // VALIDATE - IServiceProvider serviceProvider = services.BuildServiceProvider(); - var telemetryConfiguration = serviceProvider.GetRequiredService(); - Assert.Equal(telChannel, telemetryConfiguration.TelemetryChannel); - Assert.Equal("c:\\mycustom", ((ServerTelemetryChannel) telemetryConfiguration.TelemetryChannel).StorageFolder); - - } - - - [Fact] - public void VerifyAddAIWorkerServiceRespectsAIOptions() - { - var services = new ServiceCollection(); - - // ACT - var aiOptions = new ApplicationInsightsServiceOptions(); - aiOptions.AddAutoCollectedMetricExtractor = false; - aiOptions.EnableQuickPulseMetricStream = false; - aiOptions.InstrumentationKey = "keyfromaioption"; - services.AddApplicationInsightsTelemetryWorkerService(aiOptions); - - // VALIDATE - IServiceProvider serviceProvider = services.BuildServiceProvider(); - var telemetryConfiguration = serviceProvider.GetRequiredService(); - Assert.Equal("keyfromaioption", telemetryConfiguration.InstrumentationKey); - Assert.DoesNotContain(telemetryConfiguration.DefaultTelemetrySink.TelemetryProcessors, proc => proc.GetType().Name.Contains("AutocollectedMetricsExtractor")); - Assert.DoesNotContain(telemetryConfiguration.DefaultTelemetrySink.TelemetryProcessors, proc => proc.GetType().Name.Contains("QuickPulseTelemetryProcessor")); - } - - /// - /// Sanity check to validate that node name and roleinstance are populated - /// - [Fact] - public static void SanityCheckRoleInstance() - { - // ARRANGE - string expected = Environment.MachineName; - var services = new ServiceCollection(); - services.AddApplicationInsightsTelemetryWorkerService(); - IServiceProvider serviceProvider = services.BuildServiceProvider(); - - // Request TC from DI which would be made with the default TelemetryConfiguration which should - // contain the telemetry initializer capable of populate node name and role instance name. - var tc = serviceProvider.GetRequiredService(); - var mockItem = new EventTelemetry(); - - // ACT - // This is expected to run all TI and populate the node name and role instance. - tc.Initialize(mockItem); - - // VERIFY - Assert.Contains(expected, mockItem.Context.Cloud.RoleInstance, StringComparison.CurrentCultureIgnoreCase); - } - - /// - /// User could enable or disable PerformanceCounterCollectionModule by setting EnablePerformanceCounterCollectionModule. - /// This configuration can be read from a JSON file by the configuration factory or through code by passing ApplicationInsightsServiceOptions. - /// - /// - /// DefaultConfiguration - calls services.AddApplicationInsightsTelemetryWorkerService() which reads IConfiguration from user application automatically. - /// SuppliedConfiguration - invokes services.AddApplicationInsightsTelemetryWorkerService(configuration) where IConfiguration object is supplied by caller. - /// Code - Caller creates an instance of ApplicationInsightsServiceOptions and passes it. This option overrides all configuration being used in JSON file. - /// There is a special case where NULL values in these properties - InstrumentationKey, ConnectionString, EndpointAddress and DeveloperMode are overwritten. We check IConfiguration object to see if these properties have values, if values are present then we override it. - /// - /// Sets the value for property EnablePerformanceCounterCollectionModule. - [Theory] - [InlineData("DefaultConfiguration", true)] - [InlineData("DefaultConfiguration", false)] - [InlineData("SuppliedConfiguration", true)] - [InlineData("SuppliedConfiguration", false)] - [InlineData("Code", true)] - [InlineData("Code", false)] - public static void UserCanEnableAndDisablePerfCollectorModule(string configType, bool isEnable) - { - IServiceProvider serviceProvider = TestShim(configType: configType, isEnabled: isEnable, testConfig: (o, b) => o.EnablePerformanceCounterCollectionModule = b); - - var modules = serviceProvider.GetServices(); - var module = modules.OfType().Single(); - Assert.Equal(isEnable, module.IsInitialized); - } - - /// - /// User could enable or disable EventCounterCollectionModule by setting EnableEventCounterCollectionModule. - /// This configuration can be read from a JSON file by the configuration factory or through code by passing ApplicationInsightsServiceOptions. - /// - /// - /// DefaultConfiguration - calls services.AddApplicationInsightsTelemetryWorkerService() which reads IConfiguration from user application automatically. - /// SuppliedConfiguration - invokes services.AddApplicationInsightsTelemetryWorkerService(configuration) where IConfiguration object is supplied by caller. - /// Code - Caller creates an instance of ApplicationInsightsServiceOptions and passes it. This option overrides all configuration being used in JSON file. - /// There is a special case where NULL values in these properties - InstrumentationKey, ConnectionString, EndpointAddress and DeveloperMode are overwritten. We check IConfiguration object to see if these properties have values, if values are present then we override it. - /// - /// Sets the value for property EnableEventCounterCollectionModule. - [Theory] - [InlineData("DefaultConfiguration", true)] - [InlineData("DefaultConfiguration", false)] - [InlineData("SuppliedConfiguration", true)] - [InlineData("SuppliedConfiguration", false)] - [InlineData("Code", true)] - [InlineData("Code", false)] - public static void UserCanEnableAndDisableEventCounterCollectorModule(string configType, bool isEnable) - { - IServiceProvider serviceProvider = TestShim(configType: configType, isEnabled: isEnable, testConfig: (o, b) => o.EnableEventCounterCollectionModule = b); - - var modules = serviceProvider.GetServices(); - var module = modules.OfType().Single(); - Assert.Equal(isEnable, module.IsInitialized); - } - - /// - /// User could enable or disable DependencyTrackingTelemetryModule by setting EnableDependencyTrackingTelemetryModule. - /// This configuration can be read from a JSON file by the configuration factory or through code by passing ApplicationInsightsServiceOptions. - /// - /// - /// DefaultConfiguration - calls services.AddApplicationInsightsTelemetryWorkerService() which reads IConfiguration from user application automatically. - /// SuppliedConfiguration - invokes services.AddApplicationInsightsTelemetryWorkerService(configuration) where IConfiguration object is supplied by caller. - /// Code - Caller creates an instance of ApplicationInsightsServiceOptions and passes it. This option overrides all configuration being used in JSON file. - /// There is a special case where NULL values in these properties - InstrumentationKey, ConnectionString, EndpointAddress and DeveloperMode are overwritten. We check IConfiguration object to see if these properties have values, if values are present then we override it. - /// - /// Sets the value for property EnableDependencyTrackingTelemetryModule. - [Theory] - [InlineData("DefaultConfiguration", true)] - [InlineData("DefaultConfiguration", false)] - [InlineData("SuppliedConfiguration", true)] - [InlineData("SuppliedConfiguration", false)] - [InlineData("Code", true)] - [InlineData("Code", false)] - public static void UserCanEnableAndDisableDependencyCollectorModule(string configType, bool isEnable) - { - IServiceProvider serviceProvider = TestShim(configType: configType, isEnabled: isEnable, testConfig: (o, b) => o.EnableDependencyTrackingTelemetryModule = b); - - var modules = serviceProvider.GetServices(); - var module = modules.OfType().Single(); - Assert.Equal(isEnable, module.IsInitialized); - } - - /// - /// User could enable or disable QuickPulseCollectorModule by setting EnableQuickPulseMetricStream. - /// This configuration can be read from a JSON file by the configuration factory or through code by passing ApplicationInsightsServiceOptions. - /// - /// - /// DefaultConfiguration - calls services.AddApplicationInsightsTelemetryWorkerService() which reads IConfiguration from user application automatically. - /// SuppliedConfiguration - invokes services.AddApplicationInsightsTelemetryWorkerService(configuration) where IConfiguration object is supplied by caller. - /// Code - Caller creates an instance of ApplicationInsightsServiceOptions and passes it. This option overrides all configuration being used in JSON file. - /// There is a special case where NULL values in these properties - InstrumentationKey, ConnectionString, EndpointAddress and DeveloperMode are overwritten. We check IConfiguration object to see if these properties have values, if values are present then we override it. - /// - /// Sets the value for property EnableQuickPulseMetricStream. - [Theory] - [InlineData("DefaultConfiguration", true)] - [InlineData("DefaultConfiguration", false)] - [InlineData("SuppliedConfiguration", true)] - [InlineData("SuppliedConfiguration", false)] - [InlineData("Code", true)] - [InlineData("Code", false)] - public static void UserCanEnableAndDisableQuickPulseCollectorModule(string configType, bool isEnable) - { - IServiceProvider serviceProvider = TestShim(configType: configType, isEnabled: isEnable, testConfig: (o, b) => o.EnableQuickPulseMetricStream = b); - - var modules = serviceProvider.GetServices(); - var module = modules.OfType().Single(); - Assert.Equal(isEnable, module.IsInitialized); - } - - /// - /// User could enable or disable AzureInstanceMetadataModule by setting EnableAzureInstanceMetadataTelemetryModule. - /// This configuration can be read from a JSON file by the configuration factory or through code by passing ApplicationInsightsServiceOptions. - /// - /// - /// DefaultConfiguration - calls services.AddApplicationInsightsTelemetryWorkerService() which reads IConfiguration from user application automatically. - /// SuppliedConfiguration - invokes services.AddApplicationInsightsTelemetryWorkerService(configuration) where IConfiguration object is supplied by caller. - /// Code - Caller creates an instance of ApplicationInsightsServiceOptions and passes it. This option overrides all configuration being used in JSON file. - /// There is a special case where NULL values in these properties - InstrumentationKey, ConnectionString, EndpointAddress and DeveloperMode are overwritten. We check IConfiguration object to see if these properties have values, if values are present then we override it. - /// - /// Sets the value for property EnableAzureInstanceMetadataTelemetryModule. - [Theory] - [InlineData("DefaultConfiguration", true)] - [InlineData("DefaultConfiguration", false)] - [InlineData("SuppliedConfiguration", true)] - [InlineData("SuppliedConfiguration", false)] - [InlineData("Code", true)] - [InlineData("Code", false)] - public static void UserCanEnableAndDisableAzureInstanceMetadataModule(string configType, bool isEnable) - { - IServiceProvider serviceProvider = TestShim(configType: configType, isEnabled: isEnable, testConfig: (o, b) => o.EnableAzureInstanceMetadataTelemetryModule = b); - - var modules = serviceProvider.GetServices(); - var module = modules.OfType().Single(); - Assert.Equal(isEnable, module.IsInitialized); - } - - /// - /// User could enable or disable AppServiceHeartbeatModule by setting EnableAppServicesHeartbeatTelemetryModule. - /// - [Theory] - [InlineData("DefaultConfiguration", true)] - [InlineData("DefaultConfiguration", false)] - [InlineData("SuppliedConfiguration", true)] - [InlineData("SuppliedConfiguration", false)] - [InlineData("Code", true)] - [InlineData("Code", false)] - public static void UserCanEnableAndDisableAppServiceHeartbeatModule(string configType, bool isEnable) - { - IServiceProvider serviceProvider = TestShim(configType: configType, isEnabled: isEnable, testConfig: (o, b) => o.EnableAppServicesHeartbeatTelemetryModule = b); - - var modules = serviceProvider.GetServices(); - var module = modules.OfType().Single(); - Assert.Equal(isEnable, module.IsInitialized); - } - - /// - /// User could enable or disable by setting . - /// - [Theory] - [InlineData("DefaultConfiguration", true)] - [InlineData("DefaultConfiguration", false)] - [InlineData("SuppliedConfiguration", true)] - [InlineData("SuppliedConfiguration", false)] - [InlineData("Code", true)] - [InlineData("Code", false)] - public static void UserCanEnableAndDisableDiagnosticsTelemetryModule(string configType, bool isEnable) - { - IServiceProvider serviceProvider = TestShim(configType: configType, isEnabled: isEnable, testConfig: (o, b) => o.EnableDiagnosticsTelemetryModule = b); - - var modules = serviceProvider.GetServices(); - var module = modules.OfType().Single(); - Assert.Equal(isEnable, module.IsInitialized); - } - - /// - /// User could enable or disable the Heartbeat feature by setting . - /// - /// - /// Config file tests are not valid in this test because they set ALL settings to either TRUE/FALSE. - /// This test is specifically evaluating what happens when the DiagnosticsTelemetryModule is enabled, but the Heartbeat feature is disabled. - /// - [Theory] - [InlineData("Code", true)] - [InlineData("Code", false)] - public static void UserCanEnableAndDisableHeartbeatFeature(string configType, bool isEnable) - { - IServiceProvider serviceProvider = TestShim(configType: configType, isEnabled: isEnable, - testConfig: (o, b) => { - o.EnableDiagnosticsTelemetryModule = true; - o.EnableHeartbeat = b; - }); - - var modules = serviceProvider.GetServices(); - var module = modules.OfType().Single(); - Assert.True(module.IsInitialized, "module was not initialized"); - Assert.Equal(isEnable, module.IsHeartbeatEnabled); - } - - /// - /// User could enable or disable auto collected metrics by setting AddAutoCollectedMetricExtractor. - /// This configuration can be read from a JSON file by the configuration factory or through code by passing ApplicationInsightsServiceOptions. - /// - /// - /// DefaultConfiguration - calls services.AddApplicationInsightsTelemetryWorkerService() which reads IConfiguration from user application automatically. - /// SuppliedConfiguration - invokes services.AddApplicationInsightsTelemetryWorkerService(configuration) where IConfiguration object is supplied by caller. - /// Code - Caller creates an instance of ApplicationInsightsServiceOptions and passes it. This option overrides all configuration being used in JSON file. - /// There is a special case where NULL values in these properties - InstrumentationKey, ConnectionString, EndpointAddress and DeveloperMode are overwritten. We check IConfiguration object to see if these properties have values, if values are present then we override it. - /// - /// Sets the value for property AddAutoCollectedMetricExtractor. - [Theory] - [InlineData("DefaultConfiguration", true)] - [InlineData("DefaultConfiguration", false)] - [InlineData("SuppliedConfiguration", true)] - [InlineData("SuppliedConfiguration", false)] - [InlineData("Code", true)] - [InlineData("Code", false)] - public static void DoesNotAddAutoCollectedMetricsExtractorToConfigurationIfExplicitlyControlledThroughParameter(string configType, bool isEnable) - { - // ARRANGE - Action serviceOptions = null; - var filePath = Path.Combine("content", "config-all-settings-" + isEnable.ToString().ToLower() + ".json"); - - if (configType == "Code") - { - serviceOptions = o => { o.AddAutoCollectedMetricExtractor = isEnable; }; - filePath = null; - } - - // ACT - var services = CreateServicesAndAddApplicationinsightsWorker(filePath, serviceOptions, configType == "DefaultConfiguration" ? true : false); - - // VALIDATE - IServiceProvider serviceProvider = services.BuildServiceProvider(); - var telemetryConfiguration = serviceProvider.GetRequiredService>().Value; - var metricExtractorProcessorCount = GetTelemetryProcessorsCountInConfigurationDefaultSink(telemetryConfiguration); - Assert.Equal(isEnable ? 1 : 0, metricExtractorProcessorCount); - } - - /// - /// Creates two copies of ApplicationInsightsServiceOptions. First object is created by calling services.AddApplicationInsightsTelemetryWorkerService() or services.AddApplicationInsightsTelemetryWorkerService(config). - /// Second object is created directly from configuration file without using any of SDK functionality. - /// Compares ApplicationInsightsServiceOptions object from dependency container and one created directly from configuration. - /// This proves all that SDK read configuration successfully from configuration file. - /// Properties from appSettings.json, appsettings.{env.EnvironmentName}.json and Environmental Variables are read if no IConfiguration is supplied or used in an application. - /// - /// If this is set, read value from appsettings.json, else from passed file. - /// - /// Calls services.AddApplicationInsightsTelemetryWorkerService() when the value is true and reads IConfiguration from user application automatically. - /// Else, it invokes services.AddApplicationInsightsTelemetryWorkerService(configuration) where IConfiguration object is supplied by caller. - /// - [Theory] - [InlineData(true, true)] - [InlineData(true, false)] - [InlineData(false, true)] - [InlineData(false, false)] - public static void ReadsSettingsFromDefaultAndSuppliedConfiguration(bool readFromAppSettings, bool useDefaultConfig) - { - // ARRANGE - IConfigurationBuilder configBuilder = null; - var fileName = "config-all-default.json"; - - // ACT - var services = CreateServicesAndAddApplicationinsightsWorker( - readFromAppSettings ? null : Path.Combine("content", fileName), - null, useDefaultConfig); - - // VALIDATE - - // Generate config and don't pass to services - // this is directly generated from config file - // which could be used to validate the data from dependency container - - if (!readFromAppSettings) - { - configBuilder = new ConfigurationBuilder() - .SetBasePath(Directory.GetCurrentDirectory()); - if (useDefaultConfig) - { - configBuilder.AddJsonFile("appsettings.json", false); - } - configBuilder.AddJsonFile(Path.Combine("content", fileName)); - } - else - { - configBuilder = new ConfigurationBuilder() - .SetBasePath(Directory.GetCurrentDirectory()) - .AddJsonFile("appsettings.json", false); - } - - var config = configBuilder.Build(); - - // Compare ApplicationInsightsServiceOptions from dependency container and configuration - IServiceProvider serviceProvider = services.BuildServiceProvider(); - // ApplicationInsightsServiceOptions from dependency container - var servicesOptions = serviceProvider.GetRequiredService>().Value; - - // Create ApplicationInsightsServiceOptions from configuration for validation. - var aiOptions = new ApplicationInsightsServiceOptions(); - config.GetSection("ApplicationInsights").Bind(aiOptions); - config.GetSection("ApplicationInsights:TelemetryChannel").Bind(aiOptions); - - Type optionsType = typeof(ApplicationInsightsServiceOptions); - PropertyInfo[] properties = optionsType.GetProperties(BindingFlags.Public | BindingFlags.Instance); - Assert.True(properties.Length > 0); - foreach (PropertyInfo property in properties) - { - Assert.Equal(property.GetValue(aiOptions)?.ToString(), property.GetValue(servicesOptions)?.ToString()); - } - } - - private static int GetTelemetryProcessorsCountInConfigurationDefaultSink(TelemetryConfiguration telemetryConfiguration) - { - return telemetryConfiguration.DefaultTelemetrySink.TelemetryProcessors.Where(processor => processor.GetType() == typeof(T)).Count(); - } - - private sealed class TestService : ITestService - { - } - - private sealed class TestTelemetryModule : ITelemetryModule - { - public void Initialize(TelemetryConfiguration configuration) - { - } - } - - private interface ITestService - { - } - } - - internal class FakeTelemetryInitializer : ITelemetryInitializer - { - public FakeTelemetryInitializer() - { - } - - public void Initialize(ITelemetry telemetry) - { - - } - } -} diff --git a/NETCORE/test/Microsoft.ApplicationInsights.WorkerService.Tests/FunctionalTests.cs b/NETCORE/test/Microsoft.ApplicationInsights.WorkerService.Tests/FunctionalTests.cs deleted file mode 100644 index 90ce540641..0000000000 --- a/NETCORE/test/Microsoft.ApplicationInsights.WorkerService.Tests/FunctionalTests.cs +++ /dev/null @@ -1,180 +0,0 @@ -using Microsoft.ApplicationInsights.Channel; -using Microsoft.ApplicationInsights.DataContracts; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Hosting; -using System; -using System.Collections.Concurrent; -using System.Collections.Generic; -using System.Text; -using System.Threading.Tasks; -using Xunit; -using Xunit.Abstractions; - -namespace Microsoft.ApplicationInsights.WorkerService.Tests -{ - public class FunctionalTests - { - protected readonly ITestOutputHelper output; - - public FunctionalTests(ITestOutputHelper output) - { - this.output = output; - } - - [Fact(Skip = "Temporarily skipping. This fails when run inside same process as DepCollector ignores the 2nd host on the same process. validated locally.")] - public void BasicCollectionTest() - { - ConcurrentBag sentItems = new ConcurrentBag(); - - var host = new HostBuilder() - .ConfigureServices((hostContext, services) => - { - services.AddSingleton(new StubChannel() - { - OnSend = (item) => sentItems.Add(item) - }); ; - services.AddApplicationInsightsTelemetryWorkerService("ikey"); - services.AddHostedService(); - }).Build(); - - host.Start(); - - // Run the worker for ~5 secs. - Task.Delay(5000).Wait(); - - host.StopAsync(); - - // The worker would have completed 5 loops in 5 sec, - // each look making dependency call and some ilogger logs, - // inside "myoperation" - Assert.True(sentItems.Count > 0); - PrintItems(sentItems); - - // Validate - var reqs = GetTelemetryOfType(sentItems); - Assert.True(reqs.Count >= 1); - var traces = GetTelemetryOfType(sentItems); - Assert.True(traces.Count >= 1); - var deps = GetTelemetryOfType(sentItems); - Assert.True(deps.Count >= 1); - - // Pick one RequestTelemetry and validate that trace/deps are found which are child of the parent request. - var reqOperationId = reqs[0].Context.Operation.Id; - var reqId = reqs[0].Id; - var trace = traces.Find((tr) => tr.Context.Operation.Id != null && tr.Context.Operation.Id.Equals(reqOperationId)); - Assert.NotNull(trace); - trace = traces.Find((tr) => tr.Context.Operation.ParentId != null && tr.Context.Operation.ParentId.Equals(reqId)); - Assert.NotNull(trace); - - var dep = deps.Find((de) => de.Context.Operation.Id.Equals(reqOperationId)); - Assert.NotNull(dep); - dep = deps.Find((de) => de.Context.Operation.ParentId.Equals(reqId)); - Assert.NotNull(dep); - } - - private List GetTelemetryOfType(ConcurrentBag items) - { - List foundItems = new List(); - foreach (var item in items) - { - if (item is T) - { - foundItems.Add((T)item); - } - } - - return foundItems; - } - - private void PrintItems(ConcurrentBag items) - { - int i = 1; - foreach (var item in items) - { - this.output.WriteLine("Item " + (i++) + "."); - - if (item is RequestTelemetry req) - { - this.output.WriteLine("RequestTelemetry"); - this.output.WriteLine(req.Name); - this.output.WriteLine(req.Id); - PrintOperation(item); - this.output.WriteLine(req.Duration.ToString()); - } - else if (item is DependencyTelemetry dep) - { - this.output.WriteLine("DependencyTelemetry"); - this.output.WriteLine(dep.Name); - this.output.WriteLine(dep.Data); - PrintOperation(item); - } - else if (item is TraceTelemetry trace) - { - this.output.WriteLine("TraceTelemetry"); - this.output.WriteLine(trace.Message); - PrintOperation(item); - } - else if (item is ExceptionTelemetry exc) - { - this.output.WriteLine("ExceptionTelemetry"); - this.output.WriteLine(exc.Message); - PrintOperation(item); - } - else if (item is MetricTelemetry met) - { - this.output.WriteLine("MetricTelemetry"); - this.output.WriteLine(met.Name + "" + met.Sum); - PrintOperation(item); - } - - PrintProperties(item as ISupportProperties); - this.output.WriteLine("----------------------------"); - } - } - - private void PrintProperties(ISupportProperties itemProps) - { - foreach (var prop in itemProps.Properties) - { - this.output.WriteLine(prop.Key + ":" + prop.Value); - } - } - - private void PrintOperation(ITelemetry item) - { - if(item.Context.Operation.Id != null) - this.output.WriteLine(item.Context.Operation.Id); - if(item.Context.Operation.ParentId != null) - this.output.WriteLine(item.Context.Operation.ParentId); - } - } - - internal class StubChannel : ITelemetryChannel - { - public Action OnSend = t => { }; - - public string EndpointAddress - { - get; - set; - } - - public bool? DeveloperMode { get; set; } - - public void Dispose() - { - } - - public void Flush() - { - } - - public void Send(ITelemetry item) - { - this.OnSend(item); - } - } - - - -} diff --git a/NETCORE/test/Microsoft.ApplicationInsights.WorkerService.Tests/Microsoft.ApplicationInsights.WorkerService.Tests.csproj b/NETCORE/test/Microsoft.ApplicationInsights.WorkerService.Tests/Microsoft.ApplicationInsights.WorkerService.Tests.csproj deleted file mode 100644 index cfc970e6c6..0000000000 --- a/NETCORE/test/Microsoft.ApplicationInsights.WorkerService.Tests/Microsoft.ApplicationInsights.WorkerService.Tests.csproj +++ /dev/null @@ -1,38 +0,0 @@ - - - - - - - - - - - - - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - - - - - - - - - - - - - - Always - - - Always - - - - diff --git a/NETCORE/test/Microsoft.ApplicationInsights.WorkerService.Tests/Worker.cs b/NETCORE/test/Microsoft.ApplicationInsights.WorkerService.Tests/Worker.cs deleted file mode 100644 index 69ac9f8475..0000000000 --- a/NETCORE/test/Microsoft.ApplicationInsights.WorkerService.Tests/Worker.cs +++ /dev/null @@ -1,60 +0,0 @@ -using Microsoft.ApplicationInsights.DataContracts; -using Microsoft.Extensions.Hosting; -using Microsoft.Extensions.Logging; -using System; -using System.Net.Http; -using System.Threading; -using System.Threading.Tasks; - -namespace Microsoft.ApplicationInsights.WorkerService.Tests -{ - internal class Worker : IHostedService - { - private readonly ILogger _logger; - private static HttpClient httpClient = new HttpClient(); - private Timer _timer; - private TelemetryClient tc; - - public Worker(ILogger logger, TelemetryClient tc) - { - _logger = logger; - this.tc = tc; - } - - public Task StartAsync(CancellationToken cancellationToken) - { - _logger.LogInformation("information level log - starting"); - _logger.LogWarning("warning level log - starting"); - - _timer = new Timer(DoWork, null, TimeSpan.Zero, - TimeSpan.FromSeconds(1)); - - return Task.CompletedTask; - } - - private void DoWork(object state) - { - using (tc.StartOperation("myoperation")) - { - _logger.LogInformation("information level log - running"); - _logger.LogWarning("warning level log - calling bing"); - var res = httpClient.GetAsync("http://bing.com").Result.StatusCode; - _logger.LogWarning("warning level log - calling bing completed with status:" + res); - } - } - - public Task StopAsync(CancellationToken cancellationToken) - { - _logger.LogInformation("Timed Background Service is stopping."); - - _timer?.Change(Timeout.Infinite, 0); - - return Task.CompletedTask; - } - - public void Dispose() - { - _timer?.Dispose(); - } - } -} \ No newline at end of file diff --git a/NETCORE/test/Microsoft.ApplicationInsights.WorkerService.Tests/WorkerServiceAadIntegrationTests.cs b/NETCORE/test/Microsoft.ApplicationInsights.WorkerService.Tests/WorkerServiceAadIntegrationTests.cs deleted file mode 100644 index 8b0be3a394..0000000000 --- a/NETCORE/test/Microsoft.ApplicationInsights.WorkerService.Tests/WorkerServiceAadIntegrationTests.cs +++ /dev/null @@ -1,118 +0,0 @@ -namespace Microsoft.ApplicationInsights.WorkerService.Tests -{ - using System; - using Azure.Core; - using Azure.Monitor.OpenTelemetry.Exporter; - using Microsoft.ApplicationInsights.Extensibility; - using Microsoft.ApplicationInsights.WorkerService; - using Microsoft.Extensions.DependencyInjection; - using Microsoft.Extensions.Options; - using Xunit; - - /// - /// Integration tests for Azure Active Directory (AAD) authentication support in WorkerService. - /// - public class WorkerServiceAadIntegrationTests - { - /// - /// Tests that credential flows from ApplicationInsightsServiceOptions to AzureMonitorExporterOptions. - /// - [Fact] - public void AddApplicationInsightsTelemetryWorkerService_WithCredential_FlowsCredentialToExporter() - { - // Arrange - var services = new ServiceCollection(); - var credential = new MockTokenCredential(); - var connectionString = "InstrumentationKey=test-ikey;IngestionEndpoint=https://test.endpoint.com/"; - - // Act - services.AddApplicationInsightsTelemetryWorkerService(options => - { - options.ConnectionString = connectionString; - options.Credential = credential; - }); - - var serviceProvider = services.BuildServiceProvider(); - - // Get the configured AzureMonitorExporterOptions - var exporterOptions = serviceProvider.GetService>(); - - // Assert - Assert.NotNull(exporterOptions); - Assert.NotNull(exporterOptions.Value); - Assert.Same(credential, exporterOptions.Value.Credential); - } - - /// - /// Tests that credential is null when not set. - /// - [Fact] - public void AddApplicationInsightsTelemetryWorkerService_WithoutCredential_HasNullCredentialInExporter() - { - // Arrange - var services = new ServiceCollection(); - var connectionString = "InstrumentationKey=test-ikey;IngestionEndpoint=https://test.endpoint.com/"; - - // Act - services.AddApplicationInsightsTelemetryWorkerService(options => - { - options.ConnectionString = connectionString; - // No credential set - }); - - var serviceProvider = services.BuildServiceProvider(); - - // Get the configured AzureMonitorExporterOptions - var exporterOptions = serviceProvider.GetService>(); - - // Assert - Assert.NotNull(exporterOptions); - Assert.NotNull(exporterOptions.Value); - Assert.Null(exporterOptions.Value.Credential); - } - - /// - /// Tests that TelemetryClient can be created with credential configured. - /// - [Fact] - public void TelemetryClient_WithCredential_CreatesSuccessfully() - { - // Arrange - var services = new ServiceCollection(); - var credential = new MockTokenCredential(); - var connectionString = "InstrumentationKey=test-ikey;IngestionEndpoint=https://test.endpoint.com/"; - - services.AddApplicationInsightsTelemetryWorkerService(options => - { - options.ConnectionString = connectionString; - options.Credential = credential; - }); - - var serviceProvider = services.BuildServiceProvider(); - - // Act - var telemetryClient = serviceProvider.GetService(); - - // Assert - Assert.NotNull(telemetryClient); - Assert.NotNull(telemetryClient.TelemetryConfiguration); - } - - /// - /// Mock TokenCredential for testing purposes. - /// - private class MockTokenCredential : TokenCredential - { - public override AccessToken GetToken(TokenRequestContext requestContext, System.Threading.CancellationToken cancellationToken) - { - return new AccessToken("mock-token", DateTimeOffset.UtcNow.AddHours(1)); - } - - public override System.Threading.Tasks.ValueTask GetTokenAsync(TokenRequestContext requestContext, System.Threading.CancellationToken cancellationToken) - { - return new System.Threading.Tasks.ValueTask( - new AccessToken("mock-token", DateTimeOffset.UtcNow.AddHours(1))); - } - } - } -} diff --git a/NETCORE/test/Microsoft.ApplicationInsights.WorkerService.Tests/appsettings.json b/NETCORE/test/Microsoft.ApplicationInsights.WorkerService.Tests/appsettings.json deleted file mode 100644 index 0ab6b527b4..0000000000 --- a/NETCORE/test/Microsoft.ApplicationInsights.WorkerService.Tests/appsettings.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "ApplicationInsights": { - "InstrumentationKey": "33333333-2222-3333-4444-555555555555", - "TelemetryChannel": { - "EndpointAddress": "http://hosthere/v2/track/", - "DeveloperMode": true - } - } -} \ No newline at end of file diff --git a/NETCORE/test/Microsoft.ApplicationInsights.WorkerService.Tests/content/config-all-default.json b/NETCORE/test/Microsoft.ApplicationInsights.WorkerService.Tests/content/config-all-default.json deleted file mode 100644 index 1309ab9199..0000000000 --- a/NETCORE/test/Microsoft.ApplicationInsights.WorkerService.Tests/content/config-all-default.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "ApplicationInsights": { - "InstrumentationKey": "11111111-2222-3333-4444-555555555555", - "ConnectionString": "InstrumentationKey=11111111-2222-3333-4444-555555555555;IngestionEndpoint=http://testendpoint", - "EnablePerformanceCounterCollectionModule": true, - "EnableAzureInstanceMetadataTelemetryModule": true, - "EnableRequestTrackingTelemetryModule": true, - "EnableDependencyTrackingTelemetryModule": true, - "EnableAppServicesHeartbeatTelemetryModule": true, - "EnableEventCounterCollectionModule": true, - "AddAutoCollectedMetricExtractor": true, - "EnableQuickPulseMetricStream": true, - "EnableHeartbeat": true, - "EnableAuthenticationTrackingJavaScript": false, - "ApplicationVersion": "Version", - "TelemetryChannel": { - "EndpointAddress": "http://testendpoint/v2/track", - "DeveloperMode": true - } - } -} \ No newline at end of file diff --git a/NETCORE/test/Microsoft.ApplicationInsights.WorkerService.Tests/content/config-all-settings-false.json b/NETCORE/test/Microsoft.ApplicationInsights.WorkerService.Tests/content/config-all-settings-false.json deleted file mode 100644 index c0716fd140..0000000000 --- a/NETCORE/test/Microsoft.ApplicationInsights.WorkerService.Tests/content/config-all-settings-false.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "ApplicationInsights": { - "InstrumentationKey": "22222222-2222-3333-4444-555555555555", - "ConnectionString": "InstrumentationKey=22222222-2222-3333-4444-555555555555;IngestionEndpoint=http://testendpoint", - "EnablePerformanceCounterCollectionModule": false, - "EnableAzureInstanceMetadataTelemetryModule": false, - "EnableRequestTrackingTelemetryModule": false, - "EnableDependencyTrackingTelemetryModule": false, - "EnableAppServicesHeartbeatTelemetryModule": false, - "EnableEventCounterCollectionModule": false, - "AddAutoCollectedMetricExtractor": false, - "EnableQuickPulseMetricStream": false, - "EnableHeartbeat": false, - "EnableAuthenticationTrackingJavaScript": false, - "EnableDiagnosticsTelemetryModule": false, - "EnableActiveTelemetryConfigurationSetup": false, - "TelemetryChannel": { - "EndpointAddress": "http://testendpoint/v2/track", - "DeveloperMode": false - } - } -} \ No newline at end of file diff --git a/NETCORE/test/Microsoft.ApplicationInsights.WorkerService.Tests/content/config-all-settings-true.json b/NETCORE/test/Microsoft.ApplicationInsights.WorkerService.Tests/content/config-all-settings-true.json deleted file mode 100644 index 4b20494b84..0000000000 --- a/NETCORE/test/Microsoft.ApplicationInsights.WorkerService.Tests/content/config-all-settings-true.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "ApplicationInsights": { - "InstrumentationKey": "22222222-2222-3333-4444-555555555555", - "ConnectionString": "InstrumentationKey=22222222-2222-3333-4444-555555555555;IngestionEndpoint=http://testendpoint", - "EnablePerformanceCounterCollectionModule": true, - "EnableAzureInstanceMetadataTelemetryModule": true, - "EnableRequestTrackingTelemetryModule": true, - "EnableDependencyTrackingTelemetryModule": true, - "EnableAppServicesHeartbeatTelemetryModule": true, - "EnableEventCounterCollectionModule": true, - "AddAutoCollectedMetricExtractor": true, - "EnableQuickPulseMetricStream": true, - "EnableHeartbeat": true, - "EnableAuthenticationTrackingJavaScript": true, - "EnableDiagnosticsTelemetryModule": true, - "EnableActiveTelemetryConfigurationSetup": true, - "TelemetryChannel": { - "EndpointAddress": "http://testendpoint/v2/track", - "DeveloperMode": true - } - } -} \ No newline at end of file diff --git a/NETCORE/test/Microsoft.ApplicationInsights.WorkerService.Tests/content/config-connection-string-and-instrumentation-key.json b/NETCORE/test/Microsoft.ApplicationInsights.WorkerService.Tests/content/config-connection-string-and-instrumentation-key.json deleted file mode 100644 index 4d837ba827..0000000000 --- a/NETCORE/test/Microsoft.ApplicationInsights.WorkerService.Tests/content/config-connection-string-and-instrumentation-key.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "ApplicationInsights": { - "ConnectionString": "InstrumentationKey=11111111-2222-3333-4444-555555555555;IngestionEndpoint=http://127.0.0.1", - "InstrumentationKey": "33333333-4444-5555-6666-777777777777" - } - } \ No newline at end of file diff --git a/NETCORE/test/Microsoft.ApplicationInsights.WorkerService.Tests/content/config-connection-string.json b/NETCORE/test/Microsoft.ApplicationInsights.WorkerService.Tests/content/config-connection-string.json deleted file mode 100644 index ed4a8e6461..0000000000 --- a/NETCORE/test/Microsoft.ApplicationInsights.WorkerService.Tests/content/config-connection-string.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "ApplicationInsights": { - "ConnectionString" : "InstrumentationKey=11111111-2222-3333-4444-555555555555;IngestionEndpoint=http://127.0.0.1" - } - } \ No newline at end of file diff --git a/NETCORE/test/Microsoft.ApplicationInsights.WorkerService.Tests/content/config-developer-mode.json b/NETCORE/test/Microsoft.ApplicationInsights.WorkerService.Tests/content/config-developer-mode.json deleted file mode 100644 index 9e7541ca02..0000000000 --- a/NETCORE/test/Microsoft.ApplicationInsights.WorkerService.Tests/content/config-developer-mode.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "ApplicationInsights": { - "TelemetryChannel": { - "DeveloperMode": true - } - } -} \ No newline at end of file diff --git a/NETCORE/test/Microsoft.ApplicationInsights.WorkerService.Tests/content/config-endpoint-address.json b/NETCORE/test/Microsoft.ApplicationInsights.WorkerService.Tests/content/config-endpoint-address.json deleted file mode 100644 index 7fd7c6b27c..0000000000 --- a/NETCORE/test/Microsoft.ApplicationInsights.WorkerService.Tests/content/config-endpoint-address.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "ApplicationInsights": { - "TelemetryChannel": { - "EndpointAddress": "http://localhost:1234/v2/track/" - } - } -} \ No newline at end of file diff --git a/NETCORE/test/Microsoft.ApplicationInsights.WorkerService.Tests/content/config-instrumentation-key-new.json b/NETCORE/test/Microsoft.ApplicationInsights.WorkerService.Tests/content/config-instrumentation-key-new.json deleted file mode 100644 index 9032cd4744..0000000000 --- a/NETCORE/test/Microsoft.ApplicationInsights.WorkerService.Tests/content/config-instrumentation-key-new.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "ApplicationInsights": { - "InstrumentationKey": "33333333-4444-5555-6666-777777777777" - } -} \ No newline at end of file diff --git a/NETCORE/test/Microsoft.ApplicationInsights.WorkerService.Tests/content/config-instrumentation-key.json b/NETCORE/test/Microsoft.ApplicationInsights.WorkerService.Tests/content/config-instrumentation-key.json deleted file mode 100644 index 253df23438..0000000000 --- a/NETCORE/test/Microsoft.ApplicationInsights.WorkerService.Tests/content/config-instrumentation-key.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "ApplicationInsights": { - "InstrumentationKey": "11111111-2222-3333-4444-555555555555" - } -} \ No newline at end of file diff --git a/NETCORE/test/Microsoft.ApplicationInsights.WorkerService.Tests/content/sample-appsettings.json b/NETCORE/test/Microsoft.ApplicationInsights.WorkerService.Tests/content/sample-appsettings.json deleted file mode 100644 index cf174743aa..0000000000 --- a/NETCORE/test/Microsoft.ApplicationInsights.WorkerService.Tests/content/sample-appsettings.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "ApplicationInsights": { - "InstrumentationKey": "11111111-2222-3333-4444-555555555555", - "TelemetryChannel": { - "EndpointAddress": "http://testendpoint/v2/track", - "DeveloperMode": true - } - } -} \ No newline at end of file diff --git a/WEB/Src/Web/Web/AccountIdActivityProcessor.cs b/WEB/Src/Web/Web/AccountIdActivityProcessor.cs index dbac65f15e..9b23c6b6f2 100644 --- a/WEB/Src/Web/Web/AccountIdActivityProcessor.cs +++ b/WEB/Src/Web/Web/AccountIdActivityProcessor.cs @@ -40,7 +40,7 @@ public override void OnEnd(Activity activity) // Only process if account ID is not already set var existingAccountId = activity.GetTagItem("enduser.id"); - if (existingAccountId == null || string.IsNullOrEmpty(existingAccountId?.ToString())) + if (existingAccountId == null || string.IsNullOrEmpty(existingAccountId.ToString())) { var authUserCookie = context.Request.UnvalidatedGetCookie(RequestTrackingConstants.WebAuthenticatedUserCookieName); if (authUserCookie != null && !string.IsNullOrEmpty(authUserCookie.Value)) diff --git a/WEB/Src/Web/Web/AuthenticatedUserIdActivityProcessor.cs b/WEB/Src/Web/Web/AuthenticatedUserIdActivityProcessor.cs index e943379cfe..d5118c688a 100644 --- a/WEB/Src/Web/Web/AuthenticatedUserIdActivityProcessor.cs +++ b/WEB/Src/Web/Web/AuthenticatedUserIdActivityProcessor.cs @@ -38,7 +38,7 @@ public override void OnEnd(Activity activity) // Only process if authenticated user ID is not already set var existingUserId = activity.GetTagItem("enduser.id"); - if (existingUserId == null || string.IsNullOrEmpty(existingUserId?.ToString())) + if (existingUserId == null || string.IsNullOrEmpty(existingUserId.ToString())) { var authUserCookie = context.Request.UnvalidatedGetCookie(RequestTrackingConstants.WebAuthenticatedUserCookieName); if (authUserCookie != null && !string.IsNullOrEmpty(authUserCookie.Value)) diff --git a/WEB/Src/Web/Web/ClientIpHeaderActivityProcessor.cs b/WEB/Src/Web/Web/ClientIpHeaderActivityProcessor.cs index da291d5bfd..686bd7cc7d 100644 --- a/WEB/Src/Web/Web/ClientIpHeaderActivityProcessor.cs +++ b/WEB/Src/Web/Web/ClientIpHeaderActivityProcessor.cs @@ -84,7 +84,7 @@ public override void OnEnd(Activity activity) // Only process if client IP is not already set var existingIp = activity.GetTagItem("client.address") ?? activity.GetTagItem("microsoft.client.ip"); - if (existingIp == null || string.IsNullOrEmpty(existingIp?.ToString())) + if (existingIp == null || string.IsNullOrEmpty(existingIp.ToString())) { string resultIp = null; foreach (var clientIpHeaderName in this.HeaderNames) diff --git a/WEB/Src/Web/Web/SessionActivityProcessor.cs b/WEB/Src/Web/Web/SessionActivityProcessor.cs index c120e3802c..594d4d892c 100644 --- a/WEB/Src/Web/Web/SessionActivityProcessor.cs +++ b/WEB/Src/Web/Web/SessionActivityProcessor.cs @@ -42,7 +42,7 @@ public override void OnEnd(Activity activity) // Only process if session ID is not already set var existingSessionId = activity.GetTagItem("session.id"); - if (existingSessionId == null || string.IsNullOrEmpty(existingSessionId?.ToString())) + if (existingSessionId == null || string.IsNullOrEmpty(existingSessionId.ToString())) { // Try Unvalidated first, fall back to regular Cookies for test environments var sessionCookie = context.Request.UnvalidatedGetCookie(WebSessionCookieName) ?? context.Request.Cookies[WebSessionCookieName]; diff --git a/WEB/Src/Web/Web/SyntheticUserAgentActivityProcessor.cs b/WEB/Src/Web/Web/SyntheticUserAgentActivityProcessor.cs index 19b94b6128..52eee4a27e 100644 --- a/WEB/Src/Web/Web/SyntheticUserAgentActivityProcessor.cs +++ b/WEB/Src/Web/Web/SyntheticUserAgentActivityProcessor.cs @@ -17,6 +17,8 @@ internal class SyntheticUserAgentActivityProcessor : BaseProcessor // Default bot/synthetic traffic patterns private const string DefaultFilters = "search|spider|crawl|Bot|Monitor|BrowserMob|PhantomJS|HeadlessChrome|Selenium|URLNormalization"; + private static readonly string[] PipeSeparator = new[] { "|" }; + private string filters = string.Empty; private string[] filterPatterns; @@ -47,7 +49,7 @@ public string Filters // We expect customers to configure the processor before they add it to active configuration // So we will not protect it with locks (to improve perf) - this.filterPatterns = value.Split(new[] { "|" }, StringSplitOptions.RemoveEmptyEntries); + this.filterPatterns = value.Split(PipeSeparator, StringSplitOptions.RemoveEmptyEntries); } } } @@ -65,7 +67,7 @@ public override void OnEnd(Activity activity) // Only process if synthetic source is not already set var existingSyntheticSource = activity.GetTagItem("ai.operation.syntheticSource"); - if (existingSyntheticSource == null || string.IsNullOrEmpty(existingSyntheticSource?.ToString())) + if (existingSyntheticSource == null || string.IsNullOrEmpty(existingSyntheticSource.ToString())) { var context = HttpContext.Current; if (context != null) diff --git a/WEB/Src/Web/Web/UserActivityProcessor.cs b/WEB/Src/Web/Web/UserActivityProcessor.cs index 7579c60471..c07853a7ea 100644 --- a/WEB/Src/Web/Web/UserActivityProcessor.cs +++ b/WEB/Src/Web/Web/UserActivityProcessor.cs @@ -40,7 +40,7 @@ public override void OnEnd(Activity activity) // Only process if user ID is not already set (check for anonymous user ID) var existingUserId = activity.GetTagItem("ai.user.id"); - if (existingUserId == null || string.IsNullOrEmpty(existingUserId?.ToString())) + if (existingUserId == null || string.IsNullOrEmpty(existingUserId.ToString())) { // Try Unvalidated first, fall back to regular Cookies for test environments var userCookie = context.Request.UnvalidatedGetCookie(WebUserCookieName) ?? context.Request.Cookies[WebUserCookieName]; diff --git a/WEB/Src/Web/Web/WebTestActivityProcessor.cs b/WEB/Src/Web/Web/WebTestActivityProcessor.cs index 99766d85b0..d3dff1111a 100644 --- a/WEB/Src/Web/Web/WebTestActivityProcessor.cs +++ b/WEB/Src/Web/Web/WebTestActivityProcessor.cs @@ -41,7 +41,7 @@ public override void OnEnd(Activity activity) // Only process if synthetic source is not already set var existingSyntheticSource = activity.GetTagItem("ai.operation.syntheticSource"); - if (existingSyntheticSource == null || string.IsNullOrEmpty(existingSyntheticSource?.ToString())) + if (existingSyntheticSource == null || string.IsNullOrEmpty(existingSyntheticSource.ToString())) { var request = context.GetRequest(); if (request != null)