Skip to content

Commit fb8b42f

Browse files
committed
#194 fixed a bug in the Dispose-Logic of TelnetAppender
1 parent 8f3c3d4 commit fb8b42f

File tree

4 files changed

+209
-103
lines changed

4 files changed

+209
-103
lines changed

scripts/build-preview.ps1

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
$Version = '3.0.1'
2-
$Preview = '2'
1+
$Version = '3.0.2'
2+
$Preview = '1'
33
'building ...'
44
dotnet build -c Release "-p:GeneratePackages=true;PackageVersion=$Version-preview.$Preview" $PSScriptRoot/../src/log4net/log4net.csproj
55
'signing ...'
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
using System;
2+
using System.Net;
3+
using System.Net.Sockets;
4+
using System.Threading;
5+
using System.Threading.Tasks;
6+
7+
namespace log4net.Tests.Appender.Internal
8+
{
9+
/// <summary>
10+
/// Telnet Client for unit testing
11+
/// </summary>
12+
/// <param name="received">Callback for received messages</param>
13+
/// <param name="port">TCP-Port to use</param>
14+
internal sealed class SimpleTelnetClient(
15+
Action<string> received, int port) : IDisposable
16+
{
17+
private readonly CancellationTokenSource cancellationTokenSource = new();
18+
private readonly TcpClient client = new();
19+
20+
/// <summary>
21+
/// Runs the client (in a task)
22+
/// </summary>
23+
internal void Run() => Task.Run(() =>
24+
{
25+
client.Connect(new IPEndPoint(IPAddress.Loopback, port));
26+
// Get a stream object for reading and writing
27+
using NetworkStream stream = client.GetStream();
28+
29+
int i;
30+
byte[] bytes = new byte[256];
31+
32+
// Loop to receive all the data sent by the server
33+
while ((i = stream.Read(bytes, 0, bytes.Length)) != 0)
34+
{
35+
string data = System.Text.Encoding.ASCII.GetString(bytes, 0, i);
36+
received(data);
37+
if (cancellationTokenSource.Token.IsCancellationRequested)
38+
{
39+
return;
40+
}
41+
}
42+
}, cancellationTokenSource.Token);
43+
44+
/// <inheritdoc/>
45+
public void Dispose()
46+
{
47+
cancellationTokenSource.Cancel();
48+
cancellationTokenSource.Dispose();
49+
client.Dispose();
50+
}
51+
}
52+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
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.Collections.Generic;
22+
using System.Threading;
23+
using System.Xml;
24+
using log4net.Appender;
25+
using log4net.Config;
26+
using log4net.Core;
27+
using log4net.Repository;
28+
using log4net.Tests.Appender.Internal;
29+
using NUnit.Framework;
30+
31+
namespace log4net.Tests.Appender;
32+
33+
/// <summary>
34+
/// Tests for <see cref="TelnetAppender"/>
35+
/// </summary>
36+
[TestFixture]
37+
public sealed class TelnetAppenderTest
38+
{
39+
/// <summary>
40+
/// Simple Test für the <see cref="TelnetAppender"/>
41+
/// </summary>
42+
/// <remarks>
43+
/// https://github.com/apache/logging-log4net/issues/194
44+
/// https://stackoverflow.com/questions/79053363/log4net-telnetappender-doesnt-work-after-migrate-to-log4net-3
45+
/// </remarks>
46+
[Test]
47+
public void TelnetTest()
48+
{
49+
List<string> received = [];
50+
51+
XmlDocument log4netConfig = new();
52+
int port = 9090;
53+
log4netConfig.LoadXml($"""
54+
<log4net>
55+
<appender name="TelnetAppender" type="log4net.Appender.TelnetAppender">
56+
<port value="{port}" />
57+
<layout type="log4net.Layout.PatternLayout">
58+
<conversionPattern value="%date %-5level - %message%newline" />
59+
</layout>
60+
</appender>
61+
<root>
62+
<level value="INFO"/>
63+
<appender-ref ref="TelnetAppender"/>
64+
</root>
65+
</log4net>
66+
""");
67+
string logId = Guid.NewGuid().ToString();
68+
ILoggerRepository repository = LogManager.CreateRepository(logId);
69+
XmlConfigurator.Configure(repository, log4netConfig["log4net"]!);
70+
using (SimpleTelnetClient telnetClient = new(Received, port))
71+
{
72+
telnetClient.Run();
73+
WaitForReceived(1); // wait for welcome message
74+
ILogger logger = repository.GetLogger("Telnet");
75+
logger.Log(typeof(TelnetAppenderTest), Level.Info, logId, null);
76+
WaitForReceived(2); // wait for log message
77+
}
78+
repository.Shutdown();
79+
Assert.AreEqual(2, received.Count);
80+
StringAssert.Contains(logId, received[1]);
81+
82+
void Received(string message) => received.Add(message);
83+
84+
void WaitForReceived(int count)
85+
{
86+
while (received.Count < count)
87+
{
88+
Thread.Sleep(10);
89+
}
90+
}
91+
}
92+
}

0 commit comments

Comments
 (0)