Skip to content

Commit 33d668d

Browse files
committed
#255 added unit test for RemoteSyslogAppender
1 parent add0603 commit 33d668d

File tree

12 files changed

+321
-99
lines changed

12 files changed

+321
-99
lines changed
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
#region Apache License
2+
//
3+
// Licensed to the Apache Software Foundation (ASF) under one or more
4+
// contributor license agreements. See the NOTICE file distributed with
5+
// this work for additional information regarding copyright ownership.
6+
// The ASF licenses this file to you under the Apache License, Version 2.0
7+
// (the "License"); you may not use this file except in compliance with
8+
// the License. You may obtain a copy of the License at
9+
//
10+
// http://www.apache.org/licenses/LICENSE-2.0
11+
//
12+
// Unless required by applicable law or agreed to in writing, software
13+
// distributed under the License is distributed on an "AS IS" BASIS,
14+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
// See the License for the specific language governing permissions and
16+
// limitations under the License.
17+
//
18+
#endregion
19+
20+
using System.Collections.Generic;
21+
using System.Net;
22+
using System.Threading.Tasks;
23+
using log4net.Appender.Internal;
24+
25+
namespace log4net.Tests.Appender.Internal;
26+
27+
/// <summary>
28+
/// Mock implementation of <see cref="IUdpConnection"/> for testing purposes.
29+
/// </summary>
30+
internal sealed class UdpMock : IUdpConnection
31+
{
32+
/// <summary>
33+
/// Passed to <see cref="SendAsync(byte[], int)"/>
34+
/// </summary>
35+
public List<(byte[] Datagram, int Bytes)> Sent { get; } = [];
36+
37+
/// <summary>
38+
/// Was <see cref="Dispose"/> called
39+
/// </summary>
40+
internal bool WasDisposed { get; private set; }
41+
42+
/// <summary>
43+
/// Parameters passed to <see cref="Connect(int, IPAddress, int)"/>
44+
/// </summary>
45+
internal (int LocalPort, IPAddress Host, int RemotePort)? ConnectedTo { get; private set; }
46+
47+
/// <inheritdoc/>
48+
public void Connect(int localPort, IPAddress host, int remotePort)
49+
=> ConnectedTo = (localPort, host, remotePort);
50+
51+
/// <inheritdoc/>
52+
public void Dispose() => WasDisposed = true;
53+
54+
/// <inheritdoc/>
55+
public Task<int> SendAsync(byte[] datagram, int bytes)
56+
{
57+
Sent.Add((datagram, bytes));
58+
return Task.FromResult(bytes);
59+
}
60+
}
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
#region Apache License
2+
//
3+
// Licensed to the Apache Software Foundation (ASF) under one or more
4+
// contributor license agreements. See the NOTICE file distributed with
5+
// this work for additional information regarding copyright ownership.
6+
// The ASF licenses this file to you under the Apache License, Version 2.0
7+
// (the "License"); you may not use this file except in compliance with
8+
// the License. You may obtain a copy of the License at
9+
//
10+
// http://www.apache.org/licenses/LICENSE-2.0
11+
//
12+
// Unless required by applicable law or agreed to in writing, software
13+
// distributed under the License is distributed on an "AS IS" BASIS,
14+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
// See the License for the specific language governing permissions and
16+
// limitations under the License.
17+
//
18+
#endregion
19+
20+
using System.Text;
21+
using log4net.Appender;
22+
using log4net.Appender.Internal;
23+
using log4net.Core;
24+
using log4net.Layout;
25+
using log4net.Tests.Appender.Internal;
26+
using NUnit.Framework;
27+
28+
namespace log4net.Tests.Appender;
29+
30+
/// <summary>
31+
/// Tests for <see cref="RemoteSyslogAppender"/>
32+
/// </summary>
33+
[TestFixture]
34+
public sealed class RemoteSyslogAppenderTest
35+
{
36+
private sealed class RemoteAppender : RemoteSyslogAppender
37+
{
38+
/// <summary>
39+
/// Mock
40+
/// </summary>
41+
internal UdpMock Mock { get; } = new();
42+
43+
/// <inheritdoc/>
44+
protected override IUdpConnection CreateUdpConnection() => Mock;
45+
}
46+
47+
/// <summary>
48+
/// Simple Test for the <see cref="RemoteSyslogAppenderTest"/>
49+
/// </summary>
50+
/// <remarks>
51+
/// https://github.com/apache/logging-log4net/issues/255
52+
/// </remarks>
53+
[Test]
54+
public void RemoteSyslogTest()
55+
{
56+
System.Net.IPAddress ipAddress = new([127, 0, 0, 1]);
57+
RemoteAppender appender = new() { RemoteAddress = ipAddress, Layout = new PatternLayout("%-5level - %message%newline") };
58+
appender.ActivateOptions();
59+
LoggingEvent loggingEvent = new(new()
60+
{
61+
Level = Level.Info,
62+
Message = "Test message",
63+
LoggerName = "TestLogger",
64+
Domain = "TestDomain",
65+
});
66+
appender.DoAppend(loggingEvent);
67+
appender.Close();
68+
Assert.That(appender.Mock.ConnectedTo, Is.EqualTo((0, ipAddress, 514)));
69+
Assert.That(appender.Mock.Sent, Has.Count.EqualTo(1));
70+
Assert.That(appender.Mock.WasDisposed, Is.True);
71+
Assert.That(appender.Mock.Sent, Has.Count.EqualTo(1));
72+
const string expectedData = @"<14>TestDomain: INFO - Test message";
73+
Assert.That(Encoding.ASCII.GetString(appender.Mock.Sent[0].Datagram), Is.EqualTo(expectedData));
74+
}
75+
}

src/log4net.Tests/Appender/TelnetAppenderTest.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#region Apache License
1+
#region Apache License
22
//
33
// Licensed to the Apache Software Foundation (ASF) under one or more
44
// contributor license agreements. See the NOTICE file distributed with
@@ -37,7 +37,7 @@ namespace log4net.Tests.Appender;
3737
public sealed class TelnetAppenderTest
3838
{
3939
/// <summary>
40-
/// Simple Test für the <see cref="TelnetAppender"/>
40+
/// Simple Test for the <see cref="TelnetAppender"/>
4141
/// </summary>
4242
/// <remarks>
4343
/// https://github.com/apache/logging-log4net/issues/194

src/log4net/Appender/AppenderSkeleton.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -353,7 +353,7 @@ public void DoAppend(LoggingEvent[] loggingEvents)
353353
{
354354
_recursiveGuard = true;
355355

356-
var filteredEvents = new List<LoggingEvent>(loggingEvents.Length);
356+
List<LoggingEvent> filteredEvents = new(loggingEvents.Length);
357357

358358
foreach (LoggingEvent loggingEvent in loggingEvents)
359359
{
@@ -628,7 +628,7 @@ protected string RenderLoggingEvent(LoggingEvent loggingEvent)
628628
lock (LockObj)
629629
{
630630
// Create the render writer on first use
631-
_renderWriter ??= new ReusableStringWriter(System.Globalization.CultureInfo.InvariantCulture);
631+
_renderWriter ??= new(System.Globalization.CultureInfo.InvariantCulture);
632632

633633
// Reset the writer so we can reuse it
634634
_renderWriter.Reset(RenderBufferMaxCapacity, RenderBufferSize);
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
#region Apache License
2+
//
3+
// Licensed to the Apache Software Foundation (ASF) under one or more
4+
// contributor license agreements. See the NOTICE file distributed with
5+
// this work for additional information regarding copyright ownership.
6+
// The ASF licenses this file to you under the Apache License, Version 2.0
7+
// (the "License"); you may not use this file except in compliance with
8+
// the License. You may obtain a copy of the License at
9+
//
10+
// http://www.apache.org/licenses/LICENSE-2.0
11+
//
12+
// Unless required by applicable law or agreed to in writing, software
13+
// distributed under the License is distributed on an "AS IS" BASIS,
14+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
// See the License for the specific language governing permissions and
16+
// limitations under the License.
17+
//
18+
#endregion
19+
20+
using System;
21+
using System.ComponentModel;
22+
using System.Net;
23+
using System.Threading.Tasks;
24+
25+
namespace log4net.Appender.Internal;
26+
27+
/// <summary>
28+
/// Interface for UDP connection management.
29+
/// Only public for unit testing purposes.
30+
/// Do not use outside of log4net.
31+
/// Signatures may change without notice.
32+
/// </summary>
33+
[EditorBrowsable(EditorBrowsableState.Never)]
34+
public interface IUdpConnection : IDisposable
35+
{
36+
/// <summary>
37+
/// Establishes a default remote host using the specified host name and port number.
38+
/// </summary>
39+
/// <param name="localPort">The local port number</param>
40+
/// <param name="host">The remote host to which you intend send data.</param>
41+
/// <param name="remotePort">The port number on the remote host to which you intend to send data.</param>
42+
void Connect(int localPort, IPAddress host, int remotePort);
43+
44+
/// <summary>
45+
/// Sends a UDP datagram asynchronously to a remote host.
46+
/// </summary>
47+
/// <param name="datagram">An array of type System.Byte that specifies the UDP datagram that you intend to send represented as an array of bytes.</param>
48+
/// <param name="bytes">The number of bytes in the datagram.</param>
49+
/// <returns>Task for Completion</returns>
50+
Task<int> SendAsync(byte[] datagram, int bytes);
51+
}
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
#region Apache License
2+
//
3+
// Licensed to the Apache Software Foundation (ASF) under one or more
4+
// contributor license agreements. See the NOTICE file distributed with
5+
// this work for additional information regarding copyright ownership.
6+
// The ASF licenses this file to you under the Apache License, Version 2.0
7+
// (the "License"); you may not use this file except in compliance with
8+
// the License. You may obtain a copy of the License at
9+
//
10+
// http://www.apache.org/licenses/LICENSE-2.0
11+
//
12+
// Unless required by applicable law or agreed to in writing, software
13+
// distributed under the License is distributed on an "AS IS" BASIS,
14+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
// See the License for the specific language governing permissions and
16+
// limitations under the License.
17+
//
18+
#endregion
19+
20+
using System.Net;
21+
using System.Net.Sockets;
22+
using System.Threading.Tasks;
23+
using log4net.Util;
24+
25+
namespace log4net.Appender.Internal;
26+
27+
/// <summary>
28+
/// Wrapper for <see cref="UdpClient"/> to manage UDP connections.
29+
/// </summary>
30+
internal sealed class UdpConnection : IUdpConnection
31+
{
32+
private UdpClient? _client;
33+
34+
private UdpClient Client
35+
=> _client.EnsureNotNull(errorMessage: "Client is not initialized. Call Connect first.");
36+
37+
/// <inheritdoc/>
38+
public void Connect(int localPort, IPAddress remoteAddress, int remotePort)
39+
{
40+
_client = CreateClient(localPort, remoteAddress);
41+
Client.Connect(remoteAddress, remotePort);
42+
}
43+
44+
/// <inheritdoc/>
45+
public Task<int> SendAsync(byte[] datagram, int bytes) => Client.SendAsync(datagram, bytes);
46+
47+
/// <inheritdoc/>
48+
public void Dispose() => _client?.Dispose();
49+
50+
/// <summary>
51+
/// Creates a new <see cref="UdpClient"/> instance configured with the specified local port and remote address.
52+
/// </summary>
53+
/// <returns>A <see cref="UdpClient"/> instance configured with the specified parameters.</returns>
54+
internal static UdpClient CreateClient(int localPort, System.Net.IPAddress remoteAddress)
55+
=> localPort == 0
56+
? new (remoteAddress.AddressFamily)
57+
: new (localPort, remoteAddress.AddressFamily);
58+
}

0 commit comments

Comments
 (0)