Skip to content

Commit

Permalink
Nullability and modernization updates, part 3 (#126)
Browse files Browse the repository at this point in the history
* Nullability and modernization updates, part 3

* PR comments and fix remoting NDC test

* Additional PR comment
  • Loading branch information
erikmav authored Mar 20, 2024
1 parent 5e790e1 commit b5f6ea2
Show file tree
Hide file tree
Showing 55 changed files with 1,542 additions and 3,335 deletions.
142 changes: 61 additions & 81 deletions src/log4net.Tests/Appender/RemotingAppenderTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
Expand All @@ -47,29 +49,28 @@ namespace log4net.Tests.Appender
[TestFixture]
public class RemotingAppenderTest
{
private IChannel m_remotingChannel = null;
private IChannel? m_remotingChannel;

/// <summary>
/// Test that the Message property is correctly remoted
/// </summary>
[Test]
public void TestRemotedMessage()
{
// Setup the remoting appender
// Set up the remoting appender
ConfigureRootAppender(FixFlags.Partial);

RemoteLoggingSinkImpl.Instance.Reset();

Logger root;
root = ((Repository.Hierarchy.Hierarchy)LogManager.GetRepository()).Root;
Logger root = ((Repository.Hierarchy.Hierarchy)LogManager.GetRepository()).Root;

string testMessage = string.Format("test message [ {0} ]", (new Random()).Next());
string testMessage = $"test message [ {(new Random()).Next()} ]";

// Log a message that will be remoted
root.Log(Level.Debug, testMessage, null);

// Wait for the remoted object to be delivered
Thread.Sleep(2000);
WaitFor("Remote instance should have received all remoting events", () => RemoteLoggingSinkImpl.Instance.Events.Length > 0);

LoggingEvent[] events = RemoteLoggingSinkImpl.Instance.Events;
Assert.AreEqual(1, events.Length, "Expect to receive 1 remoted event");
Expand All @@ -83,19 +84,18 @@ public void TestRemotedMessage()
[Test]
public void TestPartialFix()
{
// Setup the remoting appender
// Set up the remoting appender
ConfigureRootAppender(FixFlags.Partial);

RemoteLoggingSinkImpl.Instance.Reset();

Logger root;
root = ((Repository.Hierarchy.Hierarchy)LogManager.GetRepository()).Root;
Logger root = ((Repository.Hierarchy.Hierarchy)LogManager.GetRepository()).Root;

// Log a message that will be remoted
root.Log(Level.Debug, "test message", null);

// Wait for the remoted object to be delivered
Thread.Sleep(2000);
WaitFor("Remote instance should have received all remoting events", () => RemoteLoggingSinkImpl.Instance.Events.Length > 0);

LoggingEvent[] events = RemoteLoggingSinkImpl.Instance.Events;
Assert.AreEqual(1, events.Length, "Expect to receive 1 remoted event");
Expand All @@ -109,28 +109,25 @@ public void TestPartialFix()
[Test]
public void TestFullFix()
{
// Setup the remoting appender
// Set up the remoting appender
ConfigureRootAppender(FixFlags.All);

RemoteLoggingSinkImpl.Instance.Reset();

Logger root;
root = ((Repository.Hierarchy.Hierarchy)LogManager.GetRepository()).Root;
Logger root = ((Repository.Hierarchy.Hierarchy)LogManager.GetRepository()).Root;

// Log a message that will be remoted
root.Log(Level.Debug, "test message", null);

// Wait for the remoted object to be delivered
Thread.Sleep(5000);

WaitFor("Remote instance should have received a remoting event", () => RemoteLoggingSinkImpl.Instance.Events.Length > 0);
LoggingEvent[] events = RemoteLoggingSinkImpl.Instance.Events;
Assert.AreEqual(1, events.Length, "Expect to receive 1 remoted event");

Assert.IsNotNull(events[0].LocationInfo, "Expect LocationInfo to not be null because doing a full fix");
}

private void WaitFor(
private static void WaitFor(
string failMessage,
Func<bool> condition,
int maxWaitMilliseconds = 5000)
Expand All @@ -139,7 +136,9 @@ private void WaitFor(
do
{
if (condition())
{
return;
}
Thread.Sleep(100);
} while ((DateTime.Now - start).TotalMilliseconds < maxWaitMilliseconds);
throw new TimeoutException($"Condition not achieved within {maxWaitMilliseconds}ms: {failMessage}");
Expand All @@ -151,15 +150,14 @@ private void WaitFor(
[Test]
public void TestRemotedMessageNdcPushPop()
{
// Setup the remoting appender
// Set up the remoting appender
ConfigureRootAppender(FixFlags.Partial);

RemoteLoggingSinkImpl.Instance.Reset();

Logger root;
root = ((Repository.Hierarchy.Hierarchy)LogManager.GetRepository()).Root;
Logger root = ((Repository.Hierarchy.Hierarchy)LogManager.GetRepository()).Root;

string testMessage = string.Format("test message [ {0} ]", (new Random()).Next());
string testMessage = $"test message [ {(new Random()).Next()} ]";

using (NDC.Push("value"))
{
Expand All @@ -169,7 +167,7 @@ public void TestRemotedMessageNdcPushPop()
root.Log(Level.Debug, testMessage, null);

// Wait for the remoted object to be delivered
Thread.Sleep(2000);
WaitFor("Remote instance should have received all remoting events", () => RemoteLoggingSinkImpl.Instance.Events.Length > 0);

LoggingEvent[] events = RemoteLoggingSinkImpl.Instance.Events;
Assert.AreEqual(1, events.Length, "Expect to receive 1 remoted event");
Expand All @@ -180,47 +178,43 @@ public void TestRemotedMessageNdcPushPop()
[Test]
public void TestNestedNdc()
{
// This test can suffer from timing and ordering issues as the RemotingAppender does dispatch events asynchronously

// Setup the remoting appender
// Set up the remoting appender
ConfigureRootAppender(FixFlags.Partial);

RemoteLoggingSinkImpl.Instance.Reset();

TestService t;
t = new TestService();
var t = new TestService();
t.Test();

// Wait for the remoted objects to be delivered
Thread.Sleep(3000);
WaitFor("Remote instance should have received all remoting events", () => RemoteLoggingSinkImpl.Instance.Events.Length == 5);

LoggingEvent[] events = RemoteLoggingSinkImpl.Instance.Events;
Assert.AreEqual(5, events.Length, "Expect to receive 5 remoted event");

Assert.AreEqual("begin test", events[0].RenderedMessage, "Verify event 1 RenderedMessage");
Assert.AreEqual("feature", events[1].RenderedMessage, "Verify event 2 RenderedMessage");
Assert.AreEqual("return", events[2].RenderedMessage, "Verify event 3 RenderedMessage");
Assert.AreEqual("return", events[3].RenderedMessage, "Verify event 4 RenderedMessage");
Assert.AreEqual("end test", events[4].RenderedMessage, "Verify event 5 RenderedMessage");

Assert.IsNull(events[0].Properties["NDC"], "Verify event 1 Properties");
Assert.AreEqual("test1", events[1].Properties["NDC"], "Verify event 2 Properties");
Assert.AreEqual("test1 test2", events[2].Properties["NDC"], "Verify event 3 Properties");
Assert.AreEqual("test1", events[3].Properties["NDC"], "Verify event 4 Properties");
Assert.IsNull(events[4].Properties["NDC"], "Verify event 5 Properties");
}

// RemotingAppender dispatches events asynchronously, messages could be in any order.
LoggingEvent beingTest = events.First(e => e.RenderedMessage == "begin test");
Assert.IsNull(beingTest.Properties["NDC"], "Verify 'being test' event Properties");

LoggingEvent feature = events.First(e => e.RenderedMessage == "feature");
Assert.AreEqual("test1", feature.Properties["NDC"], "Verify 'feature' event Properties");

LoggingEvent return1 = events.First(e => e.RenderedMessage == "return" && Equals(e.Properties["NDC"], "test1 test2"));

LoggingEvent return2 = events.First(e => e.RenderedMessage == "return" && Equals(e.Properties["NDC"], "test1"));

LoggingEvent endTest = events.First(e => e.RenderedMessage == "end test");
Assert.IsNull(endTest.Properties["NDC"], "Verify 'end test' event Properties");
}

private void RegisterRemotingServerChannel()
{
if (m_remotingChannel == null)
if (m_remotingChannel is null)
{
BinaryClientFormatterSinkProvider clientSinkProvider = new BinaryClientFormatterSinkProvider();

BinaryServerFormatterSinkProvider serverSinkProvider = new BinaryServerFormatterSinkProvider();
serverSinkProvider.TypeFilterLevel = System.Runtime.Serialization.Formatters.TypeFilterLevel.Full;

Hashtable channelProperties = new Hashtable();
var channelProperties = new Hashtable();
channelProperties["port"] = 8085;

m_remotingChannel = new TcpChannel(channelProperties, clientSinkProvider, serverSinkProvider);
Expand Down Expand Up @@ -277,7 +271,7 @@ public void TearDown()
[OneTimeTearDown]
public void UnregisterRemotingServerChannel()
{
if (m_remotingChannel != null)
if (m_remotingChannel is not null)
{
((TcpChannel)m_remotingChannel).StopListening(null);
try
Expand All @@ -296,20 +290,21 @@ public void UnregisterRemotingServerChannel()
/// </summary>
private static void ConfigureRootAppender(FixFlags fixFlags)
{
Logger root;
root = ((Repository.Hierarchy.Hierarchy)LogManager.GetRepository()).Root;
Logger root = ((Repository.Hierarchy.Hierarchy)LogManager.GetRepository()).Root;
root.Level = Level.Debug;
root.AddAppender(CreateAppender(fixFlags));
root.Repository.Configured = true;
root.Repository!.Configured = true;
}

private static RemotingAppender CreateAppender(FixFlags fixFlags)
{
RemotingAppender appender = new RemotingAppender();
appender.Sink = "tcp://localhost:8085/LoggingSink";
appender.Lossy = false;
appender.BufferSize = 1;
appender.Fix = fixFlags;
var appender = new RemotingAppender
{
Sink = "tcp://localhost:8085/LoggingSink",
Lossy = false,
BufferSize = 1,
Fix = fixFlags
};

appender.ActivateOptions();

Expand All @@ -318,33 +313,25 @@ private static RemotingAppender CreateAppender(FixFlags fixFlags)

public class RemoteLoggingSinkImpl : MarshalByRefObject, RemotingAppender.IRemoteLoggingSink
{
public static readonly RemoteLoggingSinkImpl Instance = new RemoteLoggingSinkImpl();
public static readonly RemoteLoggingSinkImpl Instance = new();

private ArrayList m_events = new ArrayList();
private readonly List<LoggingEvent> m_events = new();

#region Public Instance Constructors
private RemoteLoggingSinkImpl()
{
}
#endregion Public Instance Constructors

#region Implementation of IRemoteLoggingSink
/// <summary>
/// Logs the events to to an internal buffer
/// Logs the events to an internal buffer.
/// </summary>
/// <param name="events">The events to log.</param>
/// <remarks>
/// Logs the events to to an internal buffer. The logged events can
/// The logged events can
/// be retrieved via the <see cref="Events"/> property. To clear
/// the buffer call the <see cref="Reset"/> method.
/// </remarks>
public void LogEvents(LoggingEvent[] events)
{
m_events.AddRange(events);
}
#endregion Implementation of IRemoteLoggingSink
public void LogEvents(LoggingEvent[] events) => m_events.AddRange(events);

#region Override implementation of MarshalByRefObject
/// <summary>
/// Obtains a lifetime service object to control the lifetime
/// policy for this instance.
Expand All @@ -353,21 +340,14 @@ public void LogEvents(LoggingEvent[] events)
/// <c>null</c> to indicate that this instance should live
/// forever.
/// </returns>
public override object InitializeLifetimeService()
public override object? InitializeLifetimeService()
{
return null;
}
#endregion Override implementation of MarshalByRefObject

public void Reset()
{
m_events.Clear();
}
public void Reset() => m_events.Clear();

public LoggingEvent[] Events
{
get { return (LoggingEvent[])m_events.ToArray(typeof(LoggingEvent)); }
}
public LoggingEvent[] Events => m_events.ToArray();
}
}
}
Expand All @@ -378,14 +358,14 @@ namespace log4net.Tests.Appender.Remoting.UserInterfaces
{
public class TestService
{
private static ILog log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private static ILog log = LogManager.GetLogger(MethodBase.GetCurrentMethod()!.DeclaringType!);

public void Test()
{
log.Info("begin test");
Thread.Sleep(100);

Feature f = new Feature();
var f = new Feature();
f.Test();
log.Info("end test");
Thread.Sleep(100);
Expand All @@ -399,7 +379,7 @@ namespace log4net.Tests.Appender.Remoting
{
public class Feature
{
private static ILog log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private static ILog log = LogManager.GetLogger(MethodBase.GetCurrentMethod()!.DeclaringType!);

public void Test()
{
Expand All @@ -408,7 +388,7 @@ public void Test()
log.Info("feature");
Thread.Sleep(100);

Dal d = new Dal();
var d = new Dal();
d.Test();
log.Info("return");
Thread.Sleep(100);
Expand All @@ -423,7 +403,7 @@ namespace log4net.Tests.Appender.Remoting.Data
{
public class Dal
{
private static ILog log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private static ILog log = LogManager.GetLogger(MethodBase.GetCurrentMethod()!.DeclaringType!);

public void Test()
{
Expand Down
7 changes: 2 additions & 5 deletions src/log4net.Tests/Appender/StringAppender.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ namespace log4net.Tests.Appender
/// <author>Nicko Cadell</author>
public class StringAppender : AppenderSkeleton
{
private StringBuilder m_buf = new StringBuilder();
private StringBuilder m_buf = new();

/// <summary>
/// Initializes a new instance of the <see cref="StringAppender" /> class.
Expand Down Expand Up @@ -68,9 +68,6 @@ protected override void Append(LoggingEvent loggingEvent)
/// This appender requires a <see cref="Layout"/> to be set.
/// </summary>
/// <value><c>true</c></value>
protected override bool RequiresLayout
{
get { return true; }
}
protected override bool RequiresLayout => true;
}
}
Loading

0 comments on commit b5f6ea2

Please sign in to comment.