/// <summary> /// Generate an IDictionary where Key is the minimum EventId.Id value for the combination /// of EventLevel+subSystem, and the value is the type <typeparamref name="T"/> instance /// returned from the <c>Func</c> argument <paramref name="generateValueFromEventId"/>. /// /// The notion is to create a dictionary with an entry for every combination of subsystem and /// eventLevel. Uses include things like LogEventId tests housekeeping when scanning for any /// combinations that do not have a zero entry (see EnsureZeroOriginEventIdsPerCategory in /// Gridwich.Core/tests/Constants/LogEventIdTests.cs). /// </summary> /// <returns>The ranges.</returns> /// <typeparam name="T">The type of the value type which</typeparam> /// <param name="generateValueFromEventId">A <c>Func<int,T></c> called with the minimum id value for each combination of subsystem/level. It is to return a corresponding <typeparamref name="T"/> instance which becomes the IDictionary value associated with the int id argument value it receives.</param> public static IDictionary <int, T> GenerateRangeBracketsForEventIds <T>(Func <int, T> generateValueFromEventId) { var subSystems = TestHelpers.GetEnumerators <LogEventIds.LogEventIdSubsystem, int>(); var eventLevels = TestHelpers.GetEnumerators <LogEventIds.LogEventIdLevel, int>(); var rangeInfo = new Dictionary <int, T>(subSystems.Count * eventLevels.Count); // Generate the index of the zero'th element of every eventLevel/subSystem combination. // Skip the enumerator values that are just there to indicated the theoretical upper // limit of the particular enumeration. foreach (var el in eventLevels) { if (!LogEventIds.IsUpperLimtEnumerator(el.Key)) { var level = (LogEventIds.LogEventIdLevel)el.Value; foreach (var ss in subSystems) { if (!LogEventIds.IsUpperLimtEnumerator(ss.Key)) { var id = LogEventIds.GenerateId(level, (LogEventIds.LogEventIdSubsystem)ss.Value, 0); T val = generateValueFromEventId(id); rangeInfo[id] = val; } } } } return(rangeInfo); }
/// <summary> /// Create a new Microsoft.Extensions.Logging.EventId instance. /// /// Note that this construction is preferred via static method, rather than /// directly via EventId constructor inline, in order to control the way /// the components of the Id are combined to produce a single integer ID value. /// i.e. let's combine them in one place, not in many. /// </summary> /// <param name="subsystem">The subsystem.</param> /// <param name="severity">The severity.</param> /// <param name="eventIndex">Index of the event. The range is currently [0..99]. /// The upper limit is dictated by <see cref="LogEventIds.LogEventIdsIdEncoding.MaxLevel"/> /// </param> /// <param name="messageText">Descriptive text to associate with the /// subsystem/severity/eventIndex triple. Intended to be human readable.</param> /// <returns>The new <see cref="EventId"/></returns> /// <remarks>Sequences of events usually start at 0 and monotonically increase - so 0, 1, 2...</remarks> /// <exception cref="ArgumentOutOfRangeException"> /// Thrown if <paramref name="eventIndex"> is negative or too large. /// See parameter description for range information. /// </exception> /// <exception cref="ArgumentNullException">If <paramref name="messageText"> is null.</exception> /// <exception cref="ArgumentException">If <paramref name="messageText"> is non-null, but either empty or all whitespace.</exception> public static EventId CreateEventId( LogEventIds.LogEventIdSubsystem subsystem, LogEventIds.LogEventIdLevel severity, int eventIndex, string messageText) { if (string.IsNullOrWhiteSpace(messageText)) { throw (messageText == null) ? new ArgumentNullException(nameof(messageText)) : new ArgumentException($"{nameof(messageText)} must be a non-empty string", nameof(messageText)); } // Now the id generation is contained within LogEventIds. If // the eventIndex is too large (or negative), GenerateId will throw // an argument exception, which we'll just let propogate to the caller. // // In normal use, this caller would be the C# runtime performing static // initialization which will result in unit testing failing. // So fails at test time, as desired. var id = LogEventIds.GenerateId(severity, subsystem, eventIndex); return(new EventId(id, messageText)); }
public async Task Geocoder_status_is_logged_from_google(string address, LogEventIds expected) { var geocodeRequest = new GeocodeRequest { Address = address }; await googleGeocoder.GeocodeAddressAsync(geocodeRequest); Assert.Contains(logger.LoggedEventIds, l => l.Id == (int)expected); }
/// <summary> /// Check that both EventHelper.CreateEventId and the EventId constructor proper create the same thing /// </summary> public void EventHelperShouldCreateExactSameEventViaAnyConstructor() { var subSystem = LogEventIds.LogEventIdSubsystem.Encode; var level = LogEventIds.LogEventIdLevel.Debug; var index = 22; var msgText = "Some interesting text"; int computedId = ((int)level * 100000) + ((int)subSystem * 1000) + index; int ehComputedId = LogEventIds.GenerateId(level, subSystem, index); var ev1 = new EventId(computedId, msgText); var ev2 = EventHelpers.CreateEventId(subSystem, level, index, msgText); ehComputedId.ShouldBe(computedId, "LogEventIds.GenerateId != computed ID"); ev1.GetLevelName().ShouldBe(ev2.GetLevelName()); ev1.GetSubsystemName().ShouldBe(ev2.GetSubsystemName()); ev1.Id.ShouldBe(ev2.Id); ev1.Name.ShouldBe(ev2.Name); ev1.GetHashCode().ShouldBe(ev2.GetHashCode()); }