Skip to content

Commit

Permalink
Merge pull request #146 from serilog/dev
Browse files Browse the repository at this point in the history
3.0.1 Release
  • Loading branch information
tsimbalar authored Oct 17, 2018
2 parents 51a4fca + 3834bda commit 008a61e
Show file tree
Hide file tree
Showing 6 changed files with 220 additions and 17 deletions.
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<Description>Microsoft.Extensions.Configuration (appsettings.json) support for Serilog.</Description>
<VersionPrefix>3.0.0</VersionPrefix>
<VersionPrefix>3.0.1</VersionPrefix>
<Authors>Serilog Contributors</Authors>
<TargetFrameworks>netstandard2.0;net451;net461</TargetFrameworks>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ public ConfigurationReader(IConfiguration configuration, DependencyContext depen

// Generally the initial call should use IConfiguration rather than IConfigurationSection, otherwise
// IConfiguration parameters in the target methods will not be populated.
ConfigurationReader(IConfigurationSection configSection, DependencyContext dependencyContext)
public ConfigurationReader(IConfigurationSection configSection, DependencyContext dependencyContext)
{
_section = configSection ?? throw new ArgumentNullException(nameof(configSection));
_dependencyContext = dependencyContext;
Expand Down Expand Up @@ -331,7 +331,15 @@ static void CallConfigurationMethods(ILookup<string, Dictionary<string, IConfigu
select directive.Key == null ? p.DefaultValue : directive.Value.ConvertTo(p.ParameterType, declaredLevelSwitches)).ToList();

var parm = methodInfo.GetParameters().FirstOrDefault(i => i.ParameterType == typeof(IConfiguration));
if (parm != null) call[parm.Position - 1] = _configuration;
if (parm != null && !parm.HasDefaultValue)
{
if (_configuration is null)
{
throw new InvalidOperationException("Trying to invoke a configuration method accepting a `IConfiguration` argument. " +
$"This is not supported when only a `IConfigSection` has been provided. (method '{methodInfo}')");
}
call[parm.Position - 1] = _configuration;
}

call.Insert(0, receiver);

Expand All @@ -348,7 +356,11 @@ internal static MethodInfo SelectConfigurationMethod(IEnumerable<MethodInfo> can
return candidateMethods
.Where(m => m.Name == name &&
m.GetParameters().Skip(1)
.All(p => p.HasDefaultValue || suppliedArgumentValues.Any(s => s.Key.Equals(p.Name, StringComparison.OrdinalIgnoreCase))))
.All(p => p.HasDefaultValue
|| suppliedArgumentValues.Any(s => s.Key.Equals(p.Name, StringComparison.OrdinalIgnoreCase))
// parameters of type IConfiguration are implicitly populated with provided Configuration
|| p.ParameterType == typeof(IConfiguration)
))
.OrderByDescending(m =>
{
var matchingArgs = m.GetParameters().Where(p => suppliedArgumentValues.Any(s => s.Key.Equals(p.Name, StringComparison.OrdinalIgnoreCase))).ToList();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -419,32 +419,77 @@ public void LoggingLevelSwitchCanBeUsedForMinimumLevelOverrides()
}

[Fact]

[Trait("BugFix", "https://github.com/serilog/serilog-settings-configuration/issues/142")]
public void SinkWithIConfigurationArguments()
{
var json = @"{
""Serilog"": {
""Using"": [""TestDummies""],
""WriteTo"": [{
""Name"": ""DummyRollingFile"",
""Args"": {""pathFormat"" : ""C:\\"",
""configurationSection"" : { ""foo"" : ""bar"" } }
""Name"": ""DummyWithConfiguration"",
""Args"": {}
}]
}
}";

// IConfiguration and IConfigurationSection arguments do not have
// default values so they will throw if they are not populated

DummyConfigurationSink.Reset();
var log = ConfigFromJson(json)
.CreateLogger();

DummyRollingFileSink.Reset();
log.Write(Some.InformationEvent());

Assert.NotNull(DummyConfigurationSink.Configuration);
}

[Fact]
[Trait("BugFix", "https://github.com/serilog/serilog-settings-configuration/issues/142")]
public void SinkWithOptionalIConfigurationArguments()
{
var json = @"{
""Serilog"": {
""Using"": [""TestDummies""],
""WriteTo"": [{
""Name"": ""DummyWithOptionalConfiguration"",
""Args"": {}
}]
}
}";

DummyConfigurationSink.Reset();
var log = ConfigFromJson(json)
.CreateLogger();

log.Write(Some.InformationEvent());

Assert.Equal(1, DummyRollingFileSink.Emitted.Count);
// null is the default value
Assert.Null(DummyConfigurationSink.Configuration);
}

[Fact]
public void SinkWithIConfigSectionArguments()
{
var json = @"{
""Serilog"": {
""Using"": [""TestDummies""],
""WriteTo"": [{
""Name"": ""DummyWithConfigSection"",
""Args"": {""configurationSection"" : { ""foo"" : ""bar"" } }
}]
}
}";

DummyConfigurationSink.Reset();
var log = ConfigFromJson(json)
.CreateLogger();

log.Write(Some.InformationEvent());

Assert.NotNull(DummyConfigurationSink.ConfigSection);
Assert.Equal("bar", DummyConfigurationSink.ConfigSection["foo"]);
}


[Fact]
public void SinkWithConfigurationBindingArgument()
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
using System;
using System;
using Microsoft.Extensions.Configuration;
using Serilog.Events;
using Serilog.Settings.Configuration.Tests.Support;
using Xunit;

namespace Serilog.Settings.Configuration.Tests
Expand All @@ -14,5 +16,89 @@ public void ReadFromConfigurationShouldNotThrowOnEmptyConfiguration()
// should not throw
act();
}

[Fact]
[Trait("BugFix", "https://github.com/serilog/serilog-settings-configuration/issues/143")]
public void ReadFromConfigurationSectionReadsFromAnArbitrarySection()
{
LogEvent evt = null;

var json = @"{
""NotSerilog"": {
""Properties"": {
""App"": ""Test""
}
}
}";

var config = new ConfigurationBuilder()
.AddJsonString(json)
.Build();

var log = new LoggerConfiguration()
.ReadFrom.ConfigurationSection(config.GetSection("NotSerilog"))
.WriteTo.Sink(new DelegatingSink(e => evt = e))
.CreateLogger();

log.Information("Has a test property");

Assert.NotNull(evt);
Assert.Equal("Test", evt.Properties["App"].LiteralValue());
}

[Fact(Skip = "Passes when run alone, but fails when the whole suite is run - to fix")]
[Trait("BugFix", "https://github.com/serilog/serilog-settings-configuration/issues/143")]
public void ReadFromConfigurationSectionThrowsWhenTryingToCallConfigurationMethodWithIConfigurationParam()
{
var json = @"{
""NotSerilog"": {
""Using"": [""TestDummies""],
""WriteTo"": [{
""Name"": ""DummyWithConfiguration"",
""Args"": {}
}]
}
}";

var config = new ConfigurationBuilder()
.AddJsonString(json)
.Build();

var exception = Assert.Throws<InvalidOperationException>(() =>
new LoggerConfiguration()
.ReadFrom.ConfigurationSection(config.GetSection("NotSerilog"))
.CreateLogger());

Assert.Equal("Trying to invoke a configuration method accepting a `IConfiguration` argument. " +
"This is not supported when only a `IConfigSection` has been provided. " +
"(method 'Serilog.LoggerConfiguration DummyWithConfiguration(Serilog.Configuration.LoggerSinkConfiguration, Microsoft.Extensions.Configuration.IConfiguration, Microsoft.Extensions.Configuration.IConfigurationSection, System.String, Serilog.Events.LogEventLevel)')",
exception.Message);

}

[Fact]
[Trait("BugFix", "https://github.com/serilog/serilog-settings-configuration/issues/143")]
public void ReadFromConfigurationSectionDoesNotThrowWhenTryingToCallConfigurationMethodWithOptionalIConfigurationParam()
{
var json = @"{
""NotSerilog"": {
""Using"": [""TestDummies""],
""WriteTo"": [{
""Name"": ""DummyWithOptionalConfiguration"",
""Args"": {}
}]
}
}";

var config = new ConfigurationBuilder()
.AddJsonString(json)
.Build();

// this should not throw because DummyWithOptionalConfiguration accepts an optional config
new LoggerConfiguration()
.ReadFrom.ConfigurationSection(config.GetSection("NotSerilog"))
.CreateLogger();

}
}
}
46 changes: 46 additions & 0 deletions test/TestDummies/DummyConfigurationSink.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
using System;
using System.Collections.Generic;
using Microsoft.Extensions.Configuration;
using Serilog.Core;
using Serilog.Events;

namespace TestDummies
{
public class DummyConfigurationSink : ILogEventSink
{
[ThreadStatic]
static List<LogEvent> _emitted;

[ThreadStatic]
static IConfiguration _configuration;

[ThreadStatic]
static IConfigurationSection _configSection;

public static List<LogEvent> Emitted => _emitted ?? (_emitted = new List<LogEvent>());

public static IConfiguration Configuration => _configuration;

public static IConfigurationSection ConfigSection => _configSection;


public DummyConfigurationSink(IConfiguration configuration, IConfigurationSection configSection)
{
_configuration = configuration;
_configSection = configSection;
}

public void Emit(LogEvent logEvent)
{
Emitted.Add(logEvent);
}

public static void Reset()
{
_emitted = null;
_configuration = null;
_configSection = null;
}

}
}
20 changes: 17 additions & 3 deletions test/TestDummies/DummyLoggerConfigurationExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,14 +37,28 @@ public static LoggerConfiguration DummyRollingFile(
return loggerSinkConfiguration.Sink(new DummyRollingFileSink(), restrictedToMinimumLevel);
}

public static LoggerConfiguration DummyRollingFile(
public static LoggerConfiguration DummyWithConfiguration(
this LoggerSinkConfiguration loggerSinkConfiguration,
IConfiguration appConfiguration,
LogEventLevel restrictedToMinimumLevel = LevelAlias.Minimum)
{
return loggerSinkConfiguration.Sink(new DummyConfigurationSink(appConfiguration, null), restrictedToMinimumLevel);
}

public static LoggerConfiguration DummyWithOptionalConfiguration(
this LoggerSinkConfiguration loggerSinkConfiguration,
IConfiguration appConfiguration = null,
LogEventLevel restrictedToMinimumLevel = LevelAlias.Minimum)
{
return loggerSinkConfiguration.Sink(new DummyConfigurationSink(appConfiguration, null), restrictedToMinimumLevel);
}

public static LoggerConfiguration DummyWithConfigSection(
this LoggerSinkConfiguration loggerSinkConfiguration,
IConfigurationSection configurationSection,
string pathFormat,
LogEventLevel restrictedToMinimumLevel = LevelAlias.Minimum)
{
return loggerSinkConfiguration.Sink(new DummyRollingFileSink(), restrictedToMinimumLevel);
return loggerSinkConfiguration.Sink(new DummyConfigurationSink(null, configurationSection), restrictedToMinimumLevel);
}

public static LoggerConfiguration DummyRollingFile(
Expand Down

0 comments on commit 008a61e

Please sign in to comment.