You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@logging.apache.org by da...@apache.org on 2022/07/22 12:37:09 UTC
[logging-log4net] 05/06: :white_check_mark: add test trying to repro LOG4NET-684, but the issue doesn't repro
This is an automated email from the ASF dual-hosted git repository.
davydm pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/logging-log4net.git
commit dd6e40acf8e53c507cd1d22a352a53495f3c44f8
Author: Davyd McColl <da...@gmail.com>
AuthorDate: Fri Jul 22 14:35:32 2022 +0200
:white_check_mark: add test trying to repro LOG4NET-684, but the issue doesn't repro
---
src/log4net.Tests/Context/ThreadContextTest.cs | 352 ++++++++++++++-----------
1 file changed, 203 insertions(+), 149 deletions(-)
diff --git a/src/log4net.Tests/Context/ThreadContextTest.cs b/src/log4net.Tests/Context/ThreadContextTest.cs
index e489efc4..951d32d2 100644
--- a/src/log4net.Tests/Context/ThreadContextTest.cs
+++ b/src/log4net.Tests/Context/ThreadContextTest.cs
@@ -1,4 +1,5 @@
#region Apache License
+
//
// Licensed to the Apache Software Foundation (ASF) under one or more
// contributor license agreements. See the NOTICE file distributed with
@@ -15,213 +16,266 @@
// See the License for the specific language governing permissions and
// limitations under the License.
//
+
#endregion
using System;
+using System.Collections.Generic;
using System.Threading;
-
using log4net.Config;
using log4net.Layout;
using log4net.Repository;
using log4net.Tests.Appender;
using log4net.Util;
-
using NUnit.Framework;
+using static NExpect.Expectations;
+using NExpect;
namespace log4net.Tests.Context
{
- /// <summary>
- /// Used for internal unit testing the <see cref="ThreadContext"/> class.
- /// </summary>
- /// <remarks>
- /// Used for internal unit testing the <see cref="ThreadContext"/> class.
- /// </remarks>
- [TestFixture]
- public class ThreadContextTest
- {
+ /// <summary>
+ /// Used for internal unit testing the <see cref="ThreadContext"/> class.
+ /// </summary>
+ /// <remarks>
+ /// Used for internal unit testing the <see cref="ThreadContext"/> class.
+ /// </remarks>
+ [TestFixture]
+ public class ThreadContextTest
+ {
[TearDown]
- public void TearDown() {
+ public void TearDown()
+ {
Utils.RemovePropertyFromAllContexts();
}
[Test]
- public void TestThreadPropertiesPattern()
- {
- StringAppender stringAppender = new StringAppender();
- stringAppender.Layout = new PatternLayout("%property{" + Utils.PROPERTY_KEY + "}");
+ public void TestThreadPropertiesPattern()
+ {
+ StringAppender stringAppender = new StringAppender();
+ stringAppender.Layout = new PatternLayout("%property{" + Utils.PROPERTY_KEY + "}");
- ILoggerRepository rep = LogManager.CreateRepository(Guid.NewGuid().ToString());
- BasicConfigurator.Configure(rep, stringAppender);
+ ILoggerRepository rep = LogManager.CreateRepository(Guid.NewGuid().ToString());
+ BasicConfigurator.Configure(rep, stringAppender);
- ILog log1 = LogManager.GetLogger(rep.Name, "TestThreadProperiesPattern");
+ ILog log1 = LogManager.GetLogger(rep.Name, "TestThreadProperiesPattern");
- log1.Info("TestMessage");
- Assert.AreEqual(SystemInfo.NullText, stringAppender.GetString(), "Test no thread properties value set");
- stringAppender.Reset();
+ log1.Info("TestMessage");
+ Assert.AreEqual(SystemInfo.NullText, stringAppender.GetString(), "Test no thread properties value set");
+ stringAppender.Reset();
- ThreadContext.Properties[Utils.PROPERTY_KEY] = "val1";
+ ThreadContext.Properties[Utils.PROPERTY_KEY] = "val1";
- log1.Info("TestMessage");
- Assert.AreEqual("val1", stringAppender.GetString(), "Test thread properties value set");
- stringAppender.Reset();
+ log1.Info("TestMessage");
+ Assert.AreEqual("val1", stringAppender.GetString(), "Test thread properties value set");
+ stringAppender.Reset();
- ThreadContext.Properties.Remove(Utils.PROPERTY_KEY);
+ ThreadContext.Properties.Remove(Utils.PROPERTY_KEY);
- log1.Info("TestMessage");
- Assert.AreEqual(SystemInfo.NullText, stringAppender.GetString(), "Test thread properties value removed");
- stringAppender.Reset();
- }
+ log1.Info("TestMessage");
+ Assert.AreEqual(SystemInfo.NullText, stringAppender.GetString(), "Test thread properties value removed");
+ stringAppender.Reset();
+ }
- [Test]
- public void TestThreadStackPattern()
- {
- StringAppender stringAppender = new StringAppender();
+ [Test]
+ public void TestThreadStackPattern()
+ {
+ StringAppender stringAppender = new StringAppender();
stringAppender.Layout = new PatternLayout("%property{" + Utils.PROPERTY_KEY + "}");
- ILoggerRepository rep = LogManager.CreateRepository(Guid.NewGuid().ToString());
- BasicConfigurator.Configure(rep, stringAppender);
+ ILoggerRepository rep = LogManager.CreateRepository(Guid.NewGuid().ToString());
+ BasicConfigurator.Configure(rep, stringAppender);
- ILog log1 = LogManager.GetLogger(rep.Name, "TestThreadStackPattern");
+ ILog log1 = LogManager.GetLogger(rep.Name, "TestThreadStackPattern");
- log1.Info("TestMessage");
- Assert.AreEqual(SystemInfo.NullText, stringAppender.GetString(), "Test no thread stack value set");
- stringAppender.Reset();
+ log1.Info("TestMessage");
+ Assert.AreEqual(SystemInfo.NullText, stringAppender.GetString(), "Test no thread stack value set");
+ stringAppender.Reset();
- using(ThreadContext.Stacks[Utils.PROPERTY_KEY].Push("val1"))
- {
- log1.Info("TestMessage");
- Assert.AreEqual("val1", stringAppender.GetString(), "Test thread stack value set");
- stringAppender.Reset();
- }
+ using (ThreadContext.Stacks[Utils.PROPERTY_KEY].Push("val1"))
+ {
+ log1.Info("TestMessage");
+ Assert.AreEqual("val1", stringAppender.GetString(), "Test thread stack value set");
+ stringAppender.Reset();
+ }
- log1.Info("TestMessage");
- Assert.AreEqual(SystemInfo.NullText, stringAppender.GetString(), "Test thread stack value removed");
- stringAppender.Reset();
- }
+ log1.Info("TestMessage");
+ Assert.AreEqual(SystemInfo.NullText, stringAppender.GetString(), "Test thread stack value removed");
+ stringAppender.Reset();
+ }
- [Test]
- public void TestThreadStackPattern2()
- {
- StringAppender stringAppender = new StringAppender();
+ [Test]
+ public void TestThreadStackPattern2()
+ {
+ StringAppender stringAppender = new StringAppender();
stringAppender.Layout = new PatternLayout("%property{" + Utils.PROPERTY_KEY + "}");
- ILoggerRepository rep = LogManager.CreateRepository(Guid.NewGuid().ToString());
- BasicConfigurator.Configure(rep, stringAppender);
-
- ILog log1 = LogManager.GetLogger(rep.Name, "TestThreadStackPattern");
-
- log1.Info("TestMessage");
- Assert.AreEqual(SystemInfo.NullText, stringAppender.GetString(), "Test no thread stack value set");
- stringAppender.Reset();
-
- using(ThreadContext.Stacks[Utils.PROPERTY_KEY].Push("val1"))
- {
- log1.Info("TestMessage");
- Assert.AreEqual("val1", stringAppender.GetString(), "Test thread stack value set");
- stringAppender.Reset();
-
- using(ThreadContext.Stacks[Utils.PROPERTY_KEY].Push("val2"))
- {
- log1.Info("TestMessage");
- Assert.AreEqual("val1 val2", stringAppender.GetString(), "Test thread stack value pushed 2nd val");
- stringAppender.Reset();
- }
- }
-
- log1.Info("TestMessage");
- Assert.AreEqual(SystemInfo.NullText, stringAppender.GetString(), "Test thread stack value removed");
- stringAppender.Reset();
- }
-
- [Test]
- public void TestThreadStackPatternNullVal()
- {
- StringAppender stringAppender = new StringAppender();
+ ILoggerRepository rep = LogManager.CreateRepository(Guid.NewGuid().ToString());
+ BasicConfigurator.Configure(rep, stringAppender);
+
+ ILog log1 = LogManager.GetLogger(rep.Name, "TestThreadStackPattern");
+
+ log1.Info("TestMessage");
+ Assert.AreEqual(SystemInfo.NullText, stringAppender.GetString(), "Test no thread stack value set");
+ stringAppender.Reset();
+
+ using (ThreadContext.Stacks[Utils.PROPERTY_KEY].Push("val1"))
+ {
+ log1.Info("TestMessage");
+ Assert.AreEqual("val1", stringAppender.GetString(), "Test thread stack value set");
+ stringAppender.Reset();
+
+ using (ThreadContext.Stacks[Utils.PROPERTY_KEY].Push("val2"))
+ {
+ log1.Info("TestMessage");
+ Assert.AreEqual("val1 val2", stringAppender.GetString(), "Test thread stack value pushed 2nd val");
+ stringAppender.Reset();
+ }
+ }
+
+ log1.Info("TestMessage");
+ Assert.AreEqual(SystemInfo.NullText, stringAppender.GetString(), "Test thread stack value removed");
+ stringAppender.Reset();
+ }
+
+ [Test]
+ public void TestThreadStackPatternNullVal()
+ {
+ StringAppender stringAppender = new StringAppender();
stringAppender.Layout = new PatternLayout("%property{" + Utils.PROPERTY_KEY + "}");
- ILoggerRepository rep = LogManager.CreateRepository(Guid.NewGuid().ToString());
- BasicConfigurator.Configure(rep, stringAppender);
+ ILoggerRepository rep = LogManager.CreateRepository(Guid.NewGuid().ToString());
+ BasicConfigurator.Configure(rep, stringAppender);
- ILog log1 = LogManager.GetLogger(rep.Name, "TestThreadStackPattern");
+ ILog log1 = LogManager.GetLogger(rep.Name, "TestThreadStackPattern");
- log1.Info("TestMessage");
- Assert.AreEqual(SystemInfo.NullText, stringAppender.GetString(), "Test no thread stack value set");
- stringAppender.Reset();
+ log1.Info("TestMessage");
+ Assert.AreEqual(SystemInfo.NullText, stringAppender.GetString(), "Test no thread stack value set");
+ stringAppender.Reset();
- using(ThreadContext.Stacks[Utils.PROPERTY_KEY].Push(null))
- {
- log1.Info("TestMessage");
- Assert.AreEqual(SystemInfo.NullText, stringAppender.GetString(), "Test thread stack value set");
- stringAppender.Reset();
- }
+ using (ThreadContext.Stacks[Utils.PROPERTY_KEY].Push(null))
+ {
+ log1.Info("TestMessage");
+ Assert.AreEqual(SystemInfo.NullText, stringAppender.GetString(), "Test thread stack value set");
+ stringAppender.Reset();
+ }
- log1.Info("TestMessage");
- Assert.AreEqual(SystemInfo.NullText, stringAppender.GetString(), "Test thread stack value removed");
- stringAppender.Reset();
- }
+ log1.Info("TestMessage");
+ Assert.AreEqual(SystemInfo.NullText, stringAppender.GetString(), "Test thread stack value removed");
+ stringAppender.Reset();
+ }
- [Test]
- public void TestThreadStackPatternNullVal2()
- {
- StringAppender stringAppender = new StringAppender();
+ [Test]
+ public void TestThreadStackPatternNullVal2()
+ {
+ StringAppender stringAppender = new StringAppender();
stringAppender.Layout = new PatternLayout("%property{" + Utils.PROPERTY_KEY + "}");
- ILoggerRepository rep = LogManager.CreateRepository(Guid.NewGuid().ToString());
- BasicConfigurator.Configure(rep, stringAppender);
+ ILoggerRepository rep = LogManager.CreateRepository(Guid.NewGuid().ToString());
+ BasicConfigurator.Configure(rep, stringAppender);
- ILog log1 = LogManager.GetLogger(rep.Name, "TestThreadStackPattern");
+ ILog log1 = LogManager.GetLogger(rep.Name, "TestThreadStackPattern");
- log1.Info("TestMessage");
- Assert.AreEqual(SystemInfo.NullText, stringAppender.GetString(), "Test no thread stack value set");
- stringAppender.Reset();
+ log1.Info("TestMessage");
+ Assert.AreEqual(SystemInfo.NullText, stringAppender.GetString(), "Test no thread stack value set");
+ stringAppender.Reset();
- using(ThreadContext.Stacks[Utils.PROPERTY_KEY].Push("val1"))
- {
- log1.Info("TestMessage");
- Assert.AreEqual("val1", stringAppender.GetString(), "Test thread stack value set");
- stringAppender.Reset();
+ using (ThreadContext.Stacks[Utils.PROPERTY_KEY].Push("val1"))
+ {
+ log1.Info("TestMessage");
+ Assert.AreEqual("val1", stringAppender.GetString(), "Test thread stack value set");
+ stringAppender.Reset();
- using(ThreadContext.Stacks[Utils.PROPERTY_KEY].Push(null))
- {
- log1.Info("TestMessage");
- Assert.AreEqual("val1 ", stringAppender.GetString(), "Test thread stack value pushed null");
- stringAppender.Reset();
- }
- }
+ using (ThreadContext.Stacks[Utils.PROPERTY_KEY].Push(null))
+ {
+ log1.Info("TestMessage");
+ Assert.AreEqual("val1 ", stringAppender.GetString(), "Test thread stack value pushed null");
+ stringAppender.Reset();
+ }
+ }
- log1.Info("TestMessage");
- Assert.AreEqual(SystemInfo.NullText, stringAppender.GetString(), "Test thread stack value removed");
- stringAppender.Reset();
- }
+ log1.Info("TestMessage");
+ Assert.AreEqual(SystemInfo.NullText, stringAppender.GetString(), "Test thread stack value removed");
+ stringAppender.Reset();
+ }
private static string TestBackgroundThreadContextPropertyRepository;
- [Test]
- public void TestBackgroundThreadContextProperty()
- {
- StringAppender stringAppender = new StringAppender();
- stringAppender.Layout = new PatternLayout("%property{DateTimeTodayToString}");
+ [Test]
+ public void TestBackgroundThreadContextProperty()
+ {
+ StringAppender stringAppender = new StringAppender();
+ stringAppender.Layout = new PatternLayout("%property{DateTimeTodayToString}");
- ILoggerRepository rep = LogManager.CreateRepository(TestBackgroundThreadContextPropertyRepository = "TestBackgroundThreadContextPropertyRepository" + Guid.NewGuid().ToString());
- BasicConfigurator.Configure(rep, stringAppender);
+ ILoggerRepository rep = LogManager.CreateRepository(TestBackgroundThreadContextPropertyRepository =
+ "TestBackgroundThreadContextPropertyRepository" + Guid.NewGuid().ToString());
+ BasicConfigurator.Configure(rep, stringAppender);
- Thread thread = new Thread(new ThreadStart(ExecuteBackgroundThread));
- thread.Start();
+ Thread thread = new Thread(new ThreadStart(ExecuteBackgroundThread));
+ thread.Start();
- Thread.CurrentThread.Join(2000);
- }
+ Thread.CurrentThread.Join(2000);
+ }
- private static void ExecuteBackgroundThread()
- {
+ private static void ExecuteBackgroundThread()
+ {
ILog log = LogManager.GetLogger(TestBackgroundThreadContextPropertyRepository, "ExecuteBackGroundThread");
- ThreadContext.Properties["DateTimeTodayToString"] = DateTime.Today.ToString();
+ ThreadContext.Properties["DateTimeTodayToString"] = DateTime.Today.ToString();
- log.Info("TestMessage");
+ log.Info("TestMessage");
- Repository.Hierarchy.Hierarchy hierarchyLoggingRepository = (Repository.Hierarchy.Hierarchy)log.Logger.Repository;
- StringAppender stringAppender = (StringAppender)hierarchyLoggingRepository.Root.Appenders[0];
+ Repository.Hierarchy.Hierarchy hierarchyLoggingRepository =
+ (Repository.Hierarchy.Hierarchy) log.Logger.Repository;
+ StringAppender stringAppender = (StringAppender) hierarchyLoggingRepository.Root.Appenders[0];
- Assert.AreEqual(DateTime.Today.ToString(), stringAppender.GetString());
- }
- }
+ Assert.AreEqual(DateTime.Today.ToString(), stringAppender.GetString());
+ }
+
+ [Test]
+ public void PropertiesShouldBeThreadSafe()
+ {
+ // Arrange
+ var threads = new List<Thread>();
+ var flags = new List<FlagContainer>();
+
+ // Act
+ for (var i = 0; i < 256; i++)
+ {
+ var t = new Thread(SpinAndCheck);
+ var flag = new FlagContainer();
+ t.Start(flag);
+ flags.Add(flag);
+ threads.Add(t);
+ }
+
+ foreach (var t in threads)
+ {
+ t.Join();
+ }
+
+ // Assert
+ Expect(flags)
+ .To.Contain.All.Matched.By(o => o.Flag == false);
+ }
+
+ public class FlagContainer
+ {
+ public bool Flag { get; set; }
+ }
+
+ private void SpinAndCheck(object obj)
+ {
+ var container = obj as FlagContainer;
+ var threadid = Thread.CurrentThread.ManagedThreadId;
+ for (var i = 0; i < 100000; i++)
+ {
+ ThreadContext.Properties["threadid"] = threadid;
+ Thread.Sleep(0);
+ if ((int) ThreadContext.Properties["threadid"] != threadid)
+ {
+ container.Flag = true;
+ break;
+ }
+ }
+ }
+ }
}
\ No newline at end of file