Skip to content

Commit afebeba

Browse files
authored
fixed flaky test Log4Net_WritesLogFile_WithDateAndSizeRoll_Config_Works (#277)
- failed when the minute changed unexpectedly - now with completely deterministic dates
1 parent 2fec026 commit afebeba

File tree

5 files changed

+56
-58
lines changed

5 files changed

+56
-58
lines changed

src/Directory.Build.props

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
<RunAnalyzersDuringLiveAnalysis>true</RunAnalyzersDuringLiveAnalysis>
1212
<_SkipUpgradeNetAnalyzersNuGetWarning>true</_SkipUpgradeNetAnalyzersNuGetWarning>
1313
<AccelerateBuildsInVisualStudio>true</AccelerateBuildsInVisualStudio>
14+
<SatelliteResourceLanguages>en;en-US</SatelliteResourceLanguages>
1415
</PropertyGroup>
1516
<PropertyGroup Label="Package Versions">
1617
<SystemConfigurationConfigurationManagerPackageVersion>4.5.0</SystemConfigurationConfigurationManagerPackageVersion>

src/log4net.Tests/Integration/Log4NetIntegrationTests.cs

Lines changed: 52 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,12 @@
2323
using System.Linq;
2424
using log4net.Appender;
2525
using log4net.Config;
26+
using log4net.Core;
27+
using log4net.Layout;
2628
using log4net.Repository;
29+
using log4net.Repository.Hierarchy;
2730
using NUnit.Framework;
31+
using LoggerHierarchy = log4net.Repository.Hierarchy.Hierarchy;
2832

2933
namespace log4net.Tests.Integration
3034
{
@@ -172,17 +176,24 @@ public void Log4Net_WritesLogFile_WithMaxSizeRoll_Config_Works()
172176
public void Log4Net_WritesLogFile_WithDateAndSizeRoll_Config_Works()
173177
{
174178
DirectoryInfo logDir = CreateLogDirectory("integrationTestLogDir_maxsizerolldate");
175-
(ILog log, ILoggerRepository repo) = ArrangeLogger("log4net.maxsizeroll_date.config");
176-
MockDateTime mockDateTime = new();
177-
repo.GetAppenders().OfType<RollingFileAppender>().First().DateTimeStrategy = mockDateTime;
178-
// Write enough lines to trigger rolling by size and date
179-
for (int i = 1; i < 10000; ++i)
179+
DateTime startDate = new(2025, 12, 08, 15, 55, 50);
180+
MockDateTime mockDateTime = new(startDate); // start at the end of a minute
181+
(ILog log, ILoggerRepository repo) = ArrangeCompositeLogger(mockDateTime);
182+
// distribute 10.000 log entries over 60 seconds
183+
TimeSpan stepIncrement = new(TimeSpan.FromSeconds(60).Ticks / 10000);
184+
// 1000 entries (each 100 bytes) -> ~100KB total - 10 rolls expected - 4 will survive
185+
for (int i = 1; i < 1000; ++i)
180186
{
181-
log.Debug($"DateRoll entry {i}");
182-
if (i % 5000 == 0)
183-
{
184-
mockDateTime.Offset = TimeSpan.FromMinutes(1); // allow time for date to change if needed
185-
}
187+
log.Debug($"DateRoll entry {i:D5}");
188+
mockDateTime.Now += stepIncrement;
189+
}
190+
// switch to next minute to force date roll
191+
mockDateTime.Now = startDate.AddSeconds(10);
192+
// 1000 entries (each 100 bytes) -> ~100KB total - 10 rolls expected - 4 will survive
193+
for (int i = 1; i < 1000; ++i)
194+
{
195+
log.Debug($"DateRoll entry {i:D5}");
196+
mockDateTime.Now += stepIncrement;
186197
}
187198
repo.Shutdown();
188199
// Assert: rolled files exist (date+size pattern)
@@ -270,5 +281,36 @@ private static (ILog log, ILoggerRepository repo) ArrangeLogger(string configFil
270281
ILog log = LogManager.GetLogger(repo.Name, "IntegrationTestLogger");
271282
return (log, repo);
272283
}
284+
285+
private static (ILog log, ILoggerRepository repo) ArrangeCompositeLogger(RollingFileAppender.IDateTime dateTime)
286+
{
287+
LoggerHierarchy repo = (LoggerHierarchy)LogManager.CreateRepository(Guid.NewGuid().ToString());
288+
PatternLayout layout = new() { ConversionPattern = "%d{yyyy/MM/dd HH:mm:ss.fff} %m-%M%n" };
289+
layout.ActivateOptions();
290+
RollingFileAppender rollingAppender = new()
291+
{
292+
Name = "LogFileAppender",
293+
File = "integrationTestLogDir_maxsizerolldate/.log",
294+
AppendToFile = true,
295+
RollingStyle = RollingFileAppender.RollingMode.Composite,
296+
DatePattern = "HH-mm",
297+
DateTimeStrategy = dateTime,
298+
MaximumFileSize = "10KB",
299+
MaxSizeRollBackups = 3,
300+
StaticLogFileName = false,
301+
CountDirection = 1,
302+
PreserveLogFileNameExtension = true,
303+
LockingModel = new FileAppender.NoLock(),
304+
Layout = layout
305+
};
306+
rollingAppender.ActivateOptions();
307+
repo.Configured = true;
308+
Logger logger = (Logger)repo.GetLogger("IntegrationTestLogger");
309+
logger.Level = Level.Debug;
310+
logger.AddAppender(rollingAppender);
311+
logger.Additivity = false;
312+
return (log: new LogImpl(logger), repo);
313+
}
314+
273315
}
274316
}

src/log4net.Tests/Integration/MockDateTime.cs

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,8 @@ namespace log4net.Tests.Integration;
2525
/// <summary>
2626
/// Mock implementation of <see cref="RollingFileAppender.IDateTime"/>
2727
/// </summary>
28-
internal sealed class MockDateTime : RollingFileAppender.IDateTime
28+
internal sealed class MockDateTime(DateTime now) : RollingFileAppender.IDateTime
2929
{
30-
/// <summary>
31-
/// Offset to apply to the current time.
32-
/// </summary>
33-
internal TimeSpan Offset { get; set; }
34-
3530
/// <inheritdoc/>
36-
public DateTime Now => DateTime.Now + Offset;
31+
public DateTime Now { get; set; } = now;
3732
}

src/log4net.Tests/Integration/log4net.maxsizeroll_date.config

Lines changed: 0 additions & 25 deletions
This file was deleted.

src/log4net.Tests/log4net.Tests.csproj

Lines changed: 1 addition & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -35,22 +35,7 @@
3535
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="$(MicrosoftNetTestSdkPackageVersion)" />
3636
</ItemGroup>
3737
<ItemGroup>
38-
<None Update="Integration\log4net.maxsizeroll.config">
39-
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
40-
</None>
41-
<None Update="Integration\log4net.maxsizeroll_date.config">
42-
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
43-
</None>
44-
<None Update="Integration\log4net.no_file_name.config">
45-
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
46-
</None>
47-
<None Update="Integration\log4net.roll.config">
48-
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
49-
</None>
50-
<None Update="Integration\log4net.roll.config.xml">
51-
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
52-
</None>
53-
<None Update="Integration\log4net.integration.basic.config">
38+
<None Update="Integration\*.config">
5439
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
5540
</None>
5641
</ItemGroup>

0 commit comments

Comments
 (0)