omtslug commented on issue #292:
URL: 
https://github.com/apache/logging-log4net/issues/292#issuecomment-4269993824

   '' Failed to upload ''
   
   Here's Log4NetConcurrencyRepro.csproj
   ```
   <Project Sdk="Microsoft.NET.Sdk">
     <PropertyGroup>
       <TargetFrameworks>net472;net10.0-windows</TargetFrameworks>
       <IsPackable>false</IsPackable>
       <IsTestProject>true</IsTestProject>
       <Log4NetVersion Condition="'$(Log4NetVersion)' == 
''">3.3.0</Log4NetVersion>
     </PropertyGroup>
   
     <ItemGroup>
       <PackageReference Include="log4net" Version="$(Log4NetVersion)" />
       <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.10.0" />
       <PackageReference Include="xunit" Version="2.9.0" />
       <PackageReference Include="xunit.runner.visualstudio" Version="2.8.1">
         <PrivateAssets>all</PrivateAssets>
         <IncludeAssets>runtime; build; native; contentfiles; analyzers; 
buildtransitive</IncludeAssets>
       </PackageReference>
     </ItemGroup>
   </Project>
   ```
   
   Here's LoggingConcurrencyTests.cs
   ```
   using System;
   using System.Collections.Generic;
   using System.Linq;
   using System.Threading;
   using System.Threading.Tasks;
   using log4net;
   using log4net.Appender;
   using log4net.Core;
   using log4net.Layout;
   using log4net.Repository;
   using log4net.Repository.Hierarchy;
   using Xunit;
   
   namespace Log4NetConcurrencyRepro
   {
       public class LoggingConcurrencyTests : IDisposable
       {
           private readonly TestMemoryAppender _memoryAppender;
           private readonly ILoggerRepository _repository;
   
           public LoggingConcurrencyTests()
           {
               _repository = 
LogManager.CreateRepository(Guid.NewGuid().ToString());
   
               _memoryAppender = new TestMemoryAppender();
               _memoryAppender.Layout = new PatternLayout("%message");
               _memoryAppender.ActivateOptions();
   
               var hierarchy = (Hierarchy)_repository;
               hierarchy.Root.AddAppender(_memoryAppender);
               hierarchy.Root.Level = Level.All;
               hierarchy.Configured = true;
           }
   
           [Fact]
           public void Logging_DuringHighConcurrency_ShouldNotLoseMessages()
           {
               const int messageCount = 400;
               const int loggerCount = 20;
   
               // alt b: var loggers = Enumerable.Range(0, 
loggerCount).Select(i => LogManager.GetLogger(_repository.Name, 
"ConcurrencyTest-" + i)).ToArray();
   
               Parallel.For(0, messageCount, i =>
               {
                   // alt b: var logger = loggers[i % loggerCount];
                   var logger = LogManager.GetLogger(_repository.Name, 
"ConcurrencyTest-" + (i % loggerCount));
                   logger.Info("High concurrency message " + i);
               });
   
               Assert.Equal(messageCount, _memoryAppender.GetAppendCount());
   
               var events = _memoryAppender.GetEvents();
               Assert.Equal(messageCount, events.Length);
   
               for (var i = 0; i < messageCount; i++)
               {
                   var expectedMessage = "High concurrency message " + i;
                   Assert.Contains(events, e => e.RenderedMessage == 
expectedMessage);
               }
           }
   
           public void Dispose()
           {
               _memoryAppender.Clear();
               _repository.Shutdown();
           }
   
           private sealed class TestMemoryAppender : AppenderSkeleton
           {
               private readonly List<LoggingEvent> _events = new 
List<LoggingEvent>();
               private readonly object _lock = new object();
               private int _appendCount;
   
               protected override void Append(LoggingEvent loggingEvent)
               {
                   Interlocked.Increment(ref _appendCount);
   
                   if (loggingEvent == null)
                       return;
   
                   loggingEvent.Fix = FixFlags.All;
   
                   lock (_lock)
                   {
                       _events.Add(loggingEvent);
                   }
               }
   
               public int GetAppendCount()
               {
                   return Volatile.Read(ref _appendCount);
               }
   
               public LoggingEvent[] GetEvents()
               {
                   lock (_lock)
                   {
                       return _events.ToArray();
                   }
               }
   
               public void Clear()
               {
                   lock (_lock)
                   {
                       _events.Clear();
                       _appendCount = 0;
                   }
               }
           }
       }
   }
   ```
   Here's script.ps1
   ```
   
   function BuildAndTest([string]$tfm, [string]$l4n) {
     ""
     "************************************************************"
     "*** Running $l4n on $tfm"
     "*** "
     remove-item .\bin,.\obj -rec -ea 0
     dotnet build .\Log4NetConcurrencyRepro.csproj -c Release -f $tfm -p 
Log4NetVersion=$l4n
     1..20 | 
      %{ $testok = 0; $testnok = 0 } `
        { dotnet vstest .\bin\Release\$tfm\Log4NetConcurrencyRepro.dll; if 
(!$lastexitcode) { $testok++ } else { $testnok++ } } `
        { "***`n***`n*** Completed $l4n on $tfm. Outcome: OK=$testok, 
NOK=$testnok`n***" 
          $script:result += "$l4n on $tfm : `tOK=$testok, NOK=$testnok"
        }
     ""
   }
   
   $result = @()
   
   BuildAndTest 'net472'          '3.3.0'
   BuildAndTest 'net472'          '2.0.14'
   BuildAndTest 'net10.0-windows' '3.3.0'
   BuildAndTest 'net10.0-windows' '2.0.14'
   BuildAndTest 'net472'          '3.0.4'
   BuildAndTest 'net472'          '2.0.17'
   BuildAndTest 'net10.0-windows' '3.0.4'
   BuildAndTest 'net10.0-windows' '2.0.17'
   
   ""
   "************************************************************"
   "*** Overall results:"
   $result
   ""
   ```
   
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to