From 89b94aa51d5c564074efc8e6de0a94f1a014e8f9 Mon Sep 17 00:00:00 2001 From: Stijn Moreels <9039753+stijnmoreels@users.noreply.github.com> Date: Wed, 1 Jun 2022 10:06:18 +0200 Subject: [PATCH] feat: add dependency id to event hubs dep tracking (#378) * feat: add dependency id to event hubs dep tracking * pr-sug: add better description for duration measurement * pr-fix: use 'duration' io 'latency' in duration measurement description --- .../ILoggerEventHubsDependencyExtensions.cs | 78 +++++- .../ILoggerHttpDependencyExtensions.cs | 26 +- .../ApplicationInsights/EventHubsTests.cs | 39 ++- .../EventHubsDependencyLoggingTests.cs | 251 ++++++++++++++++-- 4 files changed, 338 insertions(+), 56 deletions(-) diff --git a/src/Arcus.Observability.Telemetry.Core/Extensions/ILoggerEventHubsDependencyExtensions.cs b/src/Arcus.Observability.Telemetry.Core/Extensions/ILoggerEventHubsDependencyExtensions.cs index 70a2aa12..99839860 100644 --- a/src/Arcus.Observability.Telemetry.Core/Extensions/ILoggerEventHubsDependencyExtensions.cs +++ b/src/Arcus.Observability.Telemetry.Core/Extensions/ILoggerEventHubsDependencyExtensions.cs @@ -48,7 +48,7 @@ public static void LogEventHubsDependency( /// The namespace of the resource. /// The name of the Event Hub resource. /// The indication whether or not the operation was successful. - /// The measuring the latency to call the dependency. + /// The measuring of the duration to call the dependency. /// The context that provides more insights on the dependency that was measured. /// Thrown when the or is null. /// Thrown when the or is blank. @@ -72,12 +72,74 @@ public static void LogEventHubsDependency( /// Logs an Azure Event Hub Dependency. /// /// The logger to track the telemetry. - /// Namespace of the resource - /// Name of the Event Hub resource - /// Indication whether or not the operation was successful - /// Point in time when the interaction with the dependency was started - /// Duration of the operation - /// Context that provides more insights on the dependency that was measured + /// The namespace of the resource. + /// The name of the Event Hub resource. + /// The indication whether or not the operation was successful. + /// The measuring of the duration to call the dependency. + /// The ID of the dependency to link as parent ID. + /// The context that provides more insights on the dependency that was measured. + /// Thrown when the or is null. + /// Thrown when the or is blank. + public static void LogEventHubsDependency( + this ILogger logger, + string namespaceName, + string eventHubName, + bool isSuccessful, + DurationMeasurement measurement, + string dependencyId, + Dictionary context = null) + { + Guard.NotNull(logger, nameof(logger), "Requires a logger instance to track telemetry"); + Guard.NotNullOrWhitespace(namespaceName, nameof(namespaceName), "Requires a non-blank resource namespace of the Azure Event Hub to track an Azure Event Hub dependency"); + Guard.NotNullOrWhitespace(eventHubName, nameof(eventHubName), "Requires a non-blank Azure Event Hub name to track an Azure Event Hub dependency"); + Guard.NotNull(measurement, nameof(measurement), "Requires a dependency measurement instance to track the latency of the Azure Event Hub resource when tracking an Azure Event Hub dependency"); + + LogEventHubsDependency(logger, namespaceName, eventHubName, isSuccessful, measurement.StartTime, measurement.Elapsed, dependencyId, context); + } + + /// + /// Logs an Azure Event Hub Dependency. + /// + /// The logger to track the telemetry. + /// The namespace of the resource. + /// The name of the Event Hub resource. + /// The indication whether or not the operation was successful. + /// The point in time when the interaction with the dependency was started. + /// The duration of the operation. + /// The context that provides more insights on the dependency that was measured. + /// Thrown when the is null. + /// Thrown when the or is blank. + /// Thrown when the is a negative time range. + public static void LogEventHubsDependency( + this ILogger logger, + string namespaceName, + string eventHubName, + bool isSuccessful, + DateTimeOffset startTime, + TimeSpan duration, + Dictionary context = null) + { + Guard.NotNull(logger, nameof(logger), "Requires a logger instance to track telemetry"); + Guard.NotNullOrWhitespace(namespaceName, nameof(namespaceName), "Requires a non-blank resource namespace of the Azure Event Hub to track an Azure Event Hub dependency"); + Guard.NotNullOrWhitespace(eventHubName, nameof(eventHubName), "Requires a non-blank Azure Event Hub name to track an Azure Event Hub dependency"); + Guard.NotLessThan(duration, TimeSpan.Zero, nameof(duration), "Requires a positive time duration of the Azure Events Hubs operation"); + + context = context ?? new Dictionary(); + + LogEventHubsDependency(logger, namespaceName, eventHubName, isSuccessful, startTime, duration, dependencyId: null, context); + } + + /// + /// Logs an Azure Event Hub Dependency. + /// + /// The logger to track the telemetry. + /// The namespace of the resource. + /// The name of the Event Hub resource. + /// The indication whether or not the operation was successful. + /// The point in time when the interaction with the dependency was started. + /// The duration of the operation. + /// The ID of the dependency to link as parent ID. + /// The context that provides more insights on the dependency that was measured. /// Thrown when the is null. /// Thrown when the or is blank. /// Thrown when the is a negative time range. @@ -88,6 +150,7 @@ public static void LogEventHubsDependency( bool isSuccessful, DateTimeOffset startTime, TimeSpan duration, + string dependencyId, Dictionary context = null) { Guard.NotNull(logger, nameof(logger), "Requires a logger instance to track telemetry"); @@ -104,6 +167,7 @@ public static void LogEventHubsDependency( targetName: eventHubName, duration: duration, startTime: startTime, + dependencyId: dependencyId, resultCode: null, isSuccessful: isSuccessful, context: context)); diff --git a/src/Arcus.Observability.Telemetry.Core/Extensions/ILoggerHttpDependencyExtensions.cs b/src/Arcus.Observability.Telemetry.Core/Extensions/ILoggerHttpDependencyExtensions.cs index 856239cf..7353d07c 100644 --- a/src/Arcus.Observability.Telemetry.Core/Extensions/ILoggerHttpDependencyExtensions.cs +++ b/src/Arcus.Observability.Telemetry.Core/Extensions/ILoggerHttpDependencyExtensions.cs @@ -19,10 +19,10 @@ public static partial class ILoggerExtensions /// Logs an HTTP dependency /// /// The logger to track the telemetry. - /// Request that started the HTTP communication - /// Status code that was returned by the service for this HTTP communication - /// Measuring the latency of the HTTP dependency - /// Context that provides more insights on the dependency that was measured + /// The request that started the HTTP communication. + /// The status code that was returned by the service for this HTTP communication. + /// The measuring the latency of the HTTP dependency. + /// The context that provides more insights on the dependency that was measured. /// Thrown when the , , or is null. /// /// Thrown when the doesn't have a request URI or HTTP method, the is outside the bounds of the enumeration. @@ -106,10 +106,10 @@ public static void LogHttpDependency( /// Logs an HTTP dependency /// /// The logger to track the telemetry. - /// Request that started the HTTP communication - /// Status code that was returned by the service for this HTTP communication - /// Point in time when the interaction with the HTTP dependency was started - /// Duration of the operation + /// The request that started the HTTP communication. + /// The status code that was returned by the service for this HTTP communication. + /// The point in time when the interaction with the HTTP dependency was started. + /// The duration of the operation. /// Context that provides more insights on the dependency that was measured /// Thrown when the or is null. /// Thrown when the is a negative time range. @@ -141,12 +141,12 @@ public static void LogHttpDependency( /// Logs an HTTP dependency /// /// The logger to track the telemetry. - /// Request that started the HTTP communication - /// Status code that was returned by the service for this HTTP communication - /// Point in time when the interaction with the HTTP dependency was started - /// Duration of the operation + /// The request that started the HTTP communication. + /// The status code that was returned by the service for this HTTP communication. + /// The point in time when the interaction with the HTTP dependency was started. + /// The duration of the operation. /// The ID of the dependency to link as parent ID. - /// Context that provides more insights on the dependency that was measured + /// The context that provides more insights on the dependency that was measured. /// Thrown when the or is null. /// Thrown when the is a negative time range. /// diff --git a/src/Arcus.Observability.Tests.Integration/Serilog/Sinks/ApplicationInsights/EventHubsTests.cs b/src/Arcus.Observability.Tests.Integration/Serilog/Sinks/ApplicationInsights/EventHubsTests.cs index f6373626..add641d9 100644 --- a/src/Arcus.Observability.Tests.Integration/Serilog/Sinks/ApplicationInsights/EventHubsTests.cs +++ b/src/Arcus.Observability.Tests.Integration/Serilog/Sinks/ApplicationInsights/EventHubsTests.cs @@ -30,6 +30,7 @@ public async Task LogEventHubsDependency_SinksToApplicationInsights_ResultsIEven string eventHubName = BogusGenerator.Commerce.ProductName(); string namespaceName = BogusGenerator.Finance.AccountName(); string dependencyName = eventHubName; + string dependencyId = BogusGenerator.Random.Guid().ToString(); using (ILoggerFactory loggerFactory = CreateLoggerFactory(config => config.Enrich.WithComponentName(componentName))) { @@ -41,7 +42,7 @@ public async Task LogEventHubsDependency_SinksToApplicationInsights_ResultsIEven Dictionary telemetryContext = CreateTestTelemetryContext(); // Act - logger.LogEventHubsDependency(namespaceName, eventHubName, isSuccessful, startTime, duration, telemetryContext); + logger.LogEventHubsDependency(namespaceName, eventHubName, isSuccessful, startTime, duration, dependencyId, telemetryContext); } // Assert @@ -49,33 +50,45 @@ public async Task LogEventHubsDependency_SinksToApplicationInsights_ResultsIEven { await RetryAssertUntilTelemetryShouldBeAvailableAsync(async () => { - EventsResults results = await client.Events.GetDependencyEventsAsync(ApplicationId, timespan: "PT30M"); + EventsResults results = await client.Events.GetDependencyEventsAsync(ApplicationId, PastHalfHourTimeSpan); Assert.NotEmpty(results.Value); - Assert.Contains(results.Value, result => + AssertX.Any(results.Value, result => { - return result.Dependency.Type == dependencyType - && result.Dependency.Target == eventHubName - && result.Dependency.Data == namespaceName - && result.Cloud.RoleName == componentName - && result.Dependency.Name == dependencyName; + Assert.Equal(dependencyType, result.Dependency.Type); + Assert.Equal(eventHubName, result.Dependency.Target); + Assert.Equal(namespaceName, result.Dependency.Data); + Assert.Equal(componentName, result.Cloud.RoleName); + Assert.Equal(dependencyName, result.Dependency.Name); + Assert.Equal(dependencyId, result.Dependency.Id); }); }); } - AssertX.Any(GetLogEventsFromMemory(), logEvent => { + AssertSerilogLogProperties(dependencyType, namespaceName, eventHubName, dependencyName); + } + + private void AssertSerilogLogProperties( + string dependencyType, + string namespaceName, + string eventHubName, + string dependencyName) + { + IEnumerable logEvents = GetLogEventsFromMemory(); + AssertX.Any(logEvents, logEvent => + { StructureValue logEntry = logEvent.Properties.GetAsStructureValue(ContextProperties.DependencyTracking.DependencyLogEntry); Assert.NotNull(logEntry); - var actualDependencyType = Assert.Single(logEntry.Properties, prop => prop.Name == nameof(DependencyLogEntry.DependencyType)); + LogEventProperty actualDependencyType = Assert.Single(logEntry.Properties, prop => prop.Name == nameof(DependencyLogEntry.DependencyType)); Assert.Equal(dependencyType, actualDependencyType.Value.ToDecentString()); - var actualDependencyData = Assert.Single(logEntry.Properties, prop => prop.Name == nameof(DependencyLogEntry.DependencyData)); + LogEventProperty actualDependencyData = Assert.Single(logEntry.Properties, prop => prop.Name == nameof(DependencyLogEntry.DependencyData)); Assert.Equal(namespaceName, actualDependencyData.Value.ToDecentString()); - var actualTargetName = Assert.Single(logEntry.Properties, prop => prop.Name == nameof(DependencyLogEntry.TargetName)); + LogEventProperty actualTargetName = Assert.Single(logEntry.Properties, prop => prop.Name == nameof(DependencyLogEntry.TargetName)); Assert.Equal(eventHubName, actualTargetName.Value.ToDecentString()); - var actualDependencyName = Assert.Single(logEntry.Properties, prop => prop.Name == nameof(DependencyLogEntry.DependencyName)); + LogEventProperty actualDependencyName = Assert.Single(logEntry.Properties, prop => prop.Name == nameof(DependencyLogEntry.DependencyName)); Assert.Equal(dependencyName, actualDependencyName.Value.ToDecentString()); Assert.Single(logEntry.Properties, prop => prop.Name == nameof(DependencyLogEntry.Context)); diff --git a/src/Arcus.Observability.Tests.Unit/Telemetry/Logging/EventHubsDependencyLoggingTests.cs b/src/Arcus.Observability.Tests.Unit/Telemetry/Logging/EventHubsDependencyLoggingTests.cs index 9f64a5a5..6a94dee2 100644 --- a/src/Arcus.Observability.Tests.Unit/Telemetry/Logging/EventHubsDependencyLoggingTests.cs +++ b/src/Arcus.Observability.Tests.Unit/Telemetry/Logging/EventHubsDependencyLoggingTests.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using Arcus.Observability.Telemetry.Core; using Arcus.Observability.Telemetry.Core.Logging; using Bogus; @@ -10,18 +11,18 @@ namespace Arcus.Observability.Tests.Unit.Telemetry.Logging [Trait("Category", "Unit")] public class EventHubsDependencyLoggingTests { - private readonly Faker _bogusGenerator = new Faker(); + private static readonly Faker BogusGenerator = new Faker(); [Fact] public void LogEventHubsDependency_ValidArguments_Succeeds() { // Arrange var logger = new TestLogger(); - string eventHubName = _bogusGenerator.Commerce.ProductName(); - string namespaceName = _bogusGenerator.Finance.AccountName(); - bool isSuccessful = _bogusGenerator.Random.Bool(); - DateTimeOffset startTime = _bogusGenerator.Date.PastOffset(); - TimeSpan duration = _bogusGenerator.Date.Timespan(); + string eventHubName = BogusGenerator.Commerce.ProductName(); + string namespaceName = BogusGenerator.Finance.AccountName(); + bool isSuccessful = BogusGenerator.Random.Bool(); + DateTimeOffset startTime = BogusGenerator.Date.PastOffset(); + TimeSpan duration = BogusGenerator.Date.Timespan(); // Act logger.LogEventHubsDependency(namespaceName, eventHubName, isSuccessful, startTime, duration); @@ -38,29 +39,145 @@ public void LogEventHubsDependency_ValidArguments_Succeeds() Assert.Contains("Azure Event Hubs " + dependencyName, logMessage); } + [Fact] + public void LogEventHubsDependencyWithDependencyId_ValidArguments_Succeeds() + { + // Arrange + var logger = new TestLogger(); + string eventHubName = BogusGenerator.Lorem.Word(); + string namespaceName = BogusGenerator.Lorem.Word(); + bool isSuccessful = BogusGenerator.Random.Bool(); + DateTimeOffset startTime = BogusGenerator.Date.PastOffset(); + TimeSpan duration = BogusGenerator.Date.Timespan(); + string dependencyId = BogusGenerator.Lorem.Word(); + + string key = BogusGenerator.Lorem.Word(); + string value = BogusGenerator.Lorem.Word(); + var context = new Dictionary { [key] = value }; + + // Act + logger.LogEventHubsDependency(namespaceName, eventHubName, isSuccessful, startTime, duration, dependencyId, context); + + // Assert + DependencyLogEntry dependency = logger.GetMessageAsDependency(); + Assert.Equal("Azure Event Hubs", dependency.DependencyType); + Assert.Equal(eventHubName, dependency.DependencyName); + Assert.Equal(namespaceName, dependency.DependencyData); + Assert.Equal(duration, dependency.Duration); + Assert.Equal(startTime.ToString(FormatSpecifiers.InvariantTimestampFormat), dependency.StartTime); + Assert.Equal(dependencyId, dependency.DependencyId); + Assert.Equal(isSuccessful, dependency.IsSuccessful); + Assert.Equal(value, Assert.Contains(key, dependency.Context)); + } + + [Theory] + [ClassData(typeof(Blanks))] + public void LogEventHubsDependency_WithoutNamespaceName_Fails(string namespaceName) + { + // Arrange + var logger = new TestLogger(); + string eventHubName = BogusGenerator.Commerce.ProductName(); + bool isSuccessful = BogusGenerator.Random.Bool(); + DateTimeOffset startTime = BogusGenerator.Date.PastOffset(); + TimeSpan duration = BogusGenerator.Date.Timespan(); + + // Act / Assert + Assert.ThrowsAny( + () => logger.LogEventHubsDependency(namespaceName, eventHubName, isSuccessful, startTime, duration)); + } + + [Theory] + [ClassData(typeof(Blanks))] + public void LogEventHubsDependencyWithDependencyId_WithoutNamespaceName_Fails(string namespaceName) + { + // Arrange + var logger = new TestLogger(); + string eventHubName = BogusGenerator.Commerce.ProductName(); + bool isSuccessful = BogusGenerator.Random.Bool(); + + DateTimeOffset startTime = BogusGenerator.Date.PastOffset(); + TimeSpan duration = BogusGenerator.Date.Timespan(); + string dependencyId = BogusGenerator.Lorem.Word(); + + // Act / Assert + Assert.ThrowsAny( + () => logger.LogEventHubsDependency(namespaceName, eventHubName, isSuccessful, startTime, duration, dependencyId)); + } + + [Theory] + [ClassData(typeof(Blanks))] + public void LogEventHubsDependency_WithoutEventHubName_Fails(string eventHubName) + { + // Arrange + var logger = new TestLogger(); + string namespaceName = BogusGenerator.Commerce.ProductName(); + bool isSuccessful = BogusGenerator.Random.Bool(); + + DateTimeOffset startTime = BogusGenerator.Date.PastOffset(); + TimeSpan duration = BogusGenerator.Date.Timespan(); + + // Act / Assert + Assert.ThrowsAny( + () => logger.LogEventHubsDependency(namespaceName, eventHubName, isSuccessful, startTime, duration)); + } + + [Theory] + [ClassData(typeof(Blanks))] + public void LogEventHubsDependencyWithDependencyId_WithoutEventHubName_Fails(string eventHubName) + { + // Arrange + var logger = new TestLogger(); + string namespaceName = BogusGenerator.Commerce.ProductName(); + bool isSuccessful = BogusGenerator.Random.Bool(); + + DateTimeOffset startTime = BogusGenerator.Date.PastOffset(); + TimeSpan duration = BogusGenerator.Date.Timespan(); + string dependencyId = BogusGenerator.Lorem.Word(); + + // Act / Assert + Assert.ThrowsAny( + () => logger.LogEventHubsDependency(namespaceName, eventHubName, isSuccessful, startTime, duration, dependencyId)); + } + [Fact] public void LogEventHubsDependency_WithNegativeDuration_Fails() { // Arrange var logger = new TestLogger(); - string eventHubName = _bogusGenerator.Commerce.ProductName(); - string namespaceName = _bogusGenerator.Finance.AccountName(); - bool isSuccessful = _bogusGenerator.Random.Bool(); - DateTimeOffset startTime = _bogusGenerator.Date.PastOffset(); + string eventHubName = BogusGenerator.Commerce.ProductName(); + string namespaceName = BogusGenerator.Finance.AccountName(); + bool isSuccessful = BogusGenerator.Random.Bool(); + DateTimeOffset startTime = BogusGenerator.Date.PastOffset(); TimeSpan duration = TimeSpanGenerator.GeneratePositiveDuration().Negate(); // Act / Assert Assert.ThrowsAny(() => logger.LogEventHubsDependency(namespaceName, eventHubName, isSuccessful, startTime, duration)); } + [Fact] + public void LogEventHubsDependencyWithDependencyId_WithNegativeDuration_Fails() + { + // Arrange + var logger = new TestLogger(); + string eventHubName = BogusGenerator.Commerce.ProductName(); + string namespaceName = BogusGenerator.Finance.AccountName(); + bool isSuccessful = BogusGenerator.Random.Bool(); + DateTimeOffset startTime = BogusGenerator.Date.PastOffset(); + TimeSpan duration = TimeSpanGenerator.GeneratePositiveDuration().Negate(); + string dependencyId = BogusGenerator.Lorem.Word(); + + // Act / Assert + Assert.ThrowsAny(() => logger.LogEventHubsDependency(namespaceName, eventHubName, isSuccessful, startTime, duration, dependencyId)); + } + [Fact] public void LogEventHubsDependencyWithDependencyMeasurement_ValidArguments_Succeeds() { // Arrange var logger = new TestLogger(); - string eventHubName = _bogusGenerator.Commerce.ProductName(); - string namespaceName = _bogusGenerator.Finance.AccountName(); - bool isSuccessful = _bogusGenerator.Random.Bool(); + string eventHubName = BogusGenerator.Commerce.ProductName(); + string namespaceName = BogusGenerator.Finance.AccountName(); + bool isSuccessful = BogusGenerator.Random.Bool(); var measurement = DependencyMeasurement.Start(); DateTimeOffset startTime = measurement.StartTime; @@ -87,9 +204,9 @@ public void LogEventHubsDependencyWithDurationMeasurement_ValidArguments_Succeed { // Arrange var logger = new TestLogger(); - string eventHubName = _bogusGenerator.Lorem.Word(); - string namespaceName = _bogusGenerator.Lorem.Word(); - bool isSuccessful = _bogusGenerator.Random.Bool(); + string eventHubName = BogusGenerator.Lorem.Word(); + string namespaceName = BogusGenerator.Lorem.Word(); + bool isSuccessful = BogusGenerator.Random.Bool(); var measurement = DurationMeasurement.Start(); DateTimeOffset startTime = measurement.StartTime; @@ -110,14 +227,48 @@ public void LogEventHubsDependencyWithDurationMeasurement_ValidArguments_Succeed Assert.Equal(isSuccessful, dependency.IsSuccessful); } + [Fact] + public void LogEventHubsDependencyWithDurationMeasurementWithDependencyId_ValidArguments_Succeeds() + { + // Arrange + var logger = new TestLogger(); + string eventHubName = BogusGenerator.Lorem.Word(); + string namespaceName = BogusGenerator.Lorem.Word(); + bool isSuccessful = BogusGenerator.Random.Bool(); + + var measurement = DurationMeasurement.Start(); + DateTimeOffset startTime = measurement.StartTime; + measurement.Dispose(); + TimeSpan duration = measurement.Elapsed; + string dependencyId = BogusGenerator.Lorem.Word(); + + string key = BogusGenerator.Lorem.Word(); + string value = BogusGenerator.Lorem.Word(); + var context = new Dictionary { [key] = value }; + + // Act + logger.LogEventHubsDependency(namespaceName, eventHubName, isSuccessful, measurement, dependencyId, context); + + // Assert + DependencyLogEntry dependency = logger.GetMessageAsDependency(); + Assert.Equal(eventHubName, dependency.TargetName); + Assert.Equal("Azure Event Hubs", dependency.DependencyType); + Assert.Equal(eventHubName, dependency.DependencyName); + Assert.Equal(namespaceName, dependency.DependencyData); + Assert.Equal(startTime.ToString(FormatSpecifiers.InvariantTimestampFormat), dependency.StartTime); + Assert.Equal(duration, dependency.Duration); + Assert.Equal(isSuccessful, dependency.IsSuccessful); + Assert.Equal(value, Assert.Contains(key, dependency.Context)); + } + [Theory] [ClassData(typeof(Blanks))] public void LogEventHubsDependencyWithDurationMeasurement_WithoutNamespaceName_Fails(string namespaceName) { // Arrange var logger = new TestLogger(); - string eventHubName = _bogusGenerator.Commerce.ProductName(); - bool isSuccessful = _bogusGenerator.Random.Bool(); + string eventHubName = BogusGenerator.Commerce.ProductName(); + bool isSuccessful = BogusGenerator.Random.Bool(); var measurement = DurationMeasurement.Start(); measurement.Dispose(); @@ -127,14 +278,32 @@ public void LogEventHubsDependencyWithDurationMeasurement_WithoutNamespaceName_F () => logger.LogEventHubsDependency(namespaceName, eventHubName, isSuccessful, measurement)); } + [Theory] + [ClassData(typeof(Blanks))] + public void LogEventHubsDependencyWithDurationMeasurementWithDependencyId_WithoutNamespaceName_Fails(string namespaceName) + { + // Arrange + var logger = new TestLogger(); + string eventHubName = BogusGenerator.Commerce.ProductName(); + bool isSuccessful = BogusGenerator.Random.Bool(); + + var measurement = DurationMeasurement.Start(); + measurement.Dispose(); + string dependencyId = BogusGenerator.Lorem.Word(); + + // Act / Assert + Assert.ThrowsAny( + () => logger.LogEventHubsDependency(namespaceName, eventHubName, isSuccessful, measurement, dependencyId)); + } + [Theory] [ClassData(typeof(Blanks))] public void LogEventHubsDependencyWithDurationMeasurement_WithoutEventHubName_Fails(string eventHubName) { // Arrange var logger = new TestLogger(); - string namespaceName = _bogusGenerator.Commerce.ProductName(); - bool isSuccessful = _bogusGenerator.Random.Bool(); + string namespaceName = BogusGenerator.Commerce.ProductName(); + bool isSuccessful = BogusGenerator.Random.Bool(); var measurement = DurationMeasurement.Start(); measurement.Dispose(); @@ -144,14 +313,32 @@ public void LogEventHubsDependencyWithDurationMeasurement_WithoutEventHubName_Fa () => logger.LogEventHubsDependency(namespaceName, eventHubName, isSuccessful, measurement)); } + [Theory] + [ClassData(typeof(Blanks))] + public void LogEventHubsDependencyWithDurationMeasurementWithDependencyId_WithoutEventHubName_Fails(string eventHubName) + { + // Arrange + var logger = new TestLogger(); + string namespaceName = BogusGenerator.Commerce.ProductName(); + bool isSuccessful = BogusGenerator.Random.Bool(); + + var measurement = DurationMeasurement.Start(); + measurement.Dispose(); + string dependencyId = BogusGenerator.Lorem.Word(); + + // Act / Assert + Assert.ThrowsAny( + () => logger.LogEventHubsDependency(namespaceName, eventHubName, isSuccessful, measurement, dependencyId)); + } + [Fact] public void LogEventHubsDependencyWithDurationMeasurement_WithoutMeasurement_Fails() { // Arrange var logger = new TestLogger(); - string namespaceName = _bogusGenerator.Commerce.ProductName(); - string eventHubName = _bogusGenerator.Commerce.ProductName(); - bool isSuccessful = _bogusGenerator.Random.Bool(); + string namespaceName = BogusGenerator.Commerce.ProductName(); + string eventHubName = BogusGenerator.Commerce.ProductName(); + bool isSuccessful = BogusGenerator.Random.Bool(); var measurement = DurationMeasurement.Start(); measurement.Dispose(); @@ -160,5 +347,23 @@ public void LogEventHubsDependencyWithDurationMeasurement_WithoutMeasurement_Fai Assert.ThrowsAny( () => logger.LogEventHubsDependency(namespaceName, eventHubName, isSuccessful, measurement: (DurationMeasurement)null)); } + + [Fact] + public void LogEventHubsDependencyWithDurationMeasurementWithDependencyId_WithoutMeasurement_Fails() + { + // Arrange + var logger = new TestLogger(); + string namespaceName = BogusGenerator.Commerce.ProductName(); + string eventHubName = BogusGenerator.Commerce.ProductName(); + bool isSuccessful = BogusGenerator.Random.Bool(); + + var measurement = DurationMeasurement.Start(); + measurement.Dispose(); + string dependencyId = BogusGenerator.Lorem.Word(); + + // Act / Assert + Assert.ThrowsAny( + () => logger.LogEventHubsDependency(namespaceName, eventHubName, isSuccessful, measurement: null, dependencyId)); + } } }