using k8s.Tests.Logging; using System; using System.Reactive.Disposables; using System.Reflection; using System.Threading; using Microsoft.Extensions.Logging; using Xunit; using Xunit.Abstractions; namespace k8s.Tests { /// /// The base class for test suites. /// public abstract class TestBase : IDisposable { /// /// Create a new test-suite. /// /// /// Output for the current test. /// protected TestBase(ITestOutputHelper testOutput) { if (testOutput == null) throw new ArgumentNullException(nameof(testOutput)); // We *must* have a synchronisation context for the test, or we'll see random deadlocks. if (SynchronizationContext.Current == null) { SynchronizationContext.SetSynchronizationContext( new SynchronizationContext() ); } TestOutput = testOutput; LoggerFactory = new LoggerFactory().AddTestOutput(TestOutput, MinLogLevel); Log = LoggerFactory.CreateLogger("CurrentTest"); // Ugly hack to get access to metadata for the current test. CurrentTest = (ITest) TestOutput.GetType() .GetField("test", BindingFlags.NonPublic | BindingFlags.Instance) .GetValue(TestOutput); Assert.True(CurrentTest != null, "Cannot retrieve current test from ITestOutputHelper."); Disposal.Add( Log.BeginScope("CurrentTest", CurrentTest.DisplayName) ); } /// /// Finaliser for . /// ~TestBase() { Dispose(false); } /// /// Dispose of resources being used by the test suite. /// public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } /// /// Dispose of resources being used by the test suite. /// /// /// Explicit disposal? /// protected virtual void Dispose(bool disposing) { if (disposing) { try { Disposal.Dispose(); } finally { if (LoggerFactory is IDisposable loggerFactoryDisposal) loggerFactoryDisposal.Dispose(); if (Log is IDisposable logDisposal) logDisposal.Dispose(); } } } /// /// A representing resources used by the test. /// protected CompositeDisposable Disposal { get; } = new CompositeDisposable(); /// /// Output for the current test. /// protected ITestOutputHelper TestOutput { get; } /// /// A representing the current test. /// protected ITest CurrentTest { get; } /// /// The logger for the current test. /// protected ILogger Log { get; } /// /// The logger factory for the current test. /// protected ILoggerFactory LoggerFactory { get; } /// /// The logging level for the current test. /// protected virtual LogLevel MinLogLevel => LogLevel.Information; /// /// The test server logging level for the current test. /// protected virtual LogLevel MinServerLogLevel => LogLevel.Warning; } }