using System.Reflection; using log4net; using log4net.Repository.Hierarchy; using Newtonsoft.Json; namespace skyscraper8.Tests.NUnit; [NonParallelizable] public class SkyscrapersTestingFramework { private static readonly ILog logger = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name); private Dictionary _testTimes; private VoileOnlineTestSessionMetadata _voileOnlineTestSessionMetadata; private VoileOnlineTestSessionMetadata GetVoileOnlineTestSessionMetadata() { if (_voileOnlineTestSessionMetadata == null) { _voileOnlineTestSessionMetadata = new VoileOnlineTestSessionMetadata(); _voileOnlineTestSessionMetadata.Guid = Guid.NewGuid(); _voileOnlineTestSessionMetadata.MachineName = Environment.MachineName; _voileOnlineTestSessionMetadata.StartTime = DateTime.Now; _voileOnlineTestSessionMetadata.OS = Environment.OSVersion.ToString(); _voileOnlineTestSessionMetadata.ProductName = Assembly.GetExecutingAssembly().GetName().Name; } return _voileOnlineTestSessionMetadata; } private HashSet testIds; private long ResolveTestId() { string testId = TestContext.CurrentContext.Test.ID; if (testIds == null) testIds = new HashSet(); long decodedTestId = 0; for (int i = 0; i < testId.Length; i++) { char current = testId[i]; if (!char.IsDigit(current)) continue; int currentDigit = current - '0'; if (i != 0) decodedTestId *= 10; decodedTestId += currentDigit; } if (testIds.Contains(decodedTestId)) throw new SkyscraperTestException("Test ID already used"); testIds.Add(decodedTestId); return decodedTestId; } private long GetTestDuration() { if (_testTimes == null) return -1; string key = TestContext.CurrentContext.Test.FullName; if (!_testTimes.ContainsKey(key)) return -2; return DateTime.Now.Subtract(_testTimes[key]).Milliseconds; } private DirectoryInfo _samplesDirectory; private DirectoryInfo GetSamplesDirectory() { if (_samplesDirectory == null) { FileInfo fi = new FileInfo("sample_path.txt"); if (!fi.Exists) { logger.WarnFormat("Could not find {0}", fi.FullName); } else { logger.InfoFormat("Reading samples path from: {0}", fi.FullName); string readAllText = File.ReadAllText(fi.FullName).Trim(); _samplesDirectory = new DirectoryInfo(readAllText); } } if (_samplesDirectory == null) { Assert.Inconclusive("Could not find samples directory"); } return _samplesDirectory; } protected FileStream GetStreamSample(string filename) { DirectoryInfo samplesDirectory = GetSamplesDirectory(); FileInfo file = new FileInfo(Path.Combine(samplesDirectory.FullName, filename)); if (!file.Exists) { Assert.Inconclusive(String.Format("Could not find sample file: {0}", file.FullName)); } return file.OpenRead(); } [SetUp] public void Setup() { Console.WriteLine("Setup"); if (_testTimes == null) _testTimes = new Dictionary(); SetUpLogCapture(); string key = TestContext.CurrentContext.Test.FullName; DateTime value = DateTime.Now; _testTimes[key] = value; } [TearDown] public void TearDown() { Console.WriteLine("TearDown"); TestContext currentContext = TestContext.CurrentContext; VoileOnlineTestResult voileOnlineTestResult = new VoileOnlineTestResult(); voileOnlineTestResult.ClassName = currentContext.Test.ClassName; voileOnlineTestResult.MethodName = currentContext.Test.MethodName; voileOnlineTestResult.OutcomeLabel = currentContext.Result.Outcome.Label; voileOnlineTestResult.OutcomeSite = (int)currentContext.Result.Outcome.Site; voileOnlineTestResult.OutcomeStatus = (int)currentContext.Result.Outcome.Status; voileOnlineTestResult.TimeTaken = GetTestDuration(); voileOnlineTestResult.LogOutput = TearDownLogCapture(); voileOnlineTestResult.AssertionCount = currentContext.AssertCount; voileOnlineTestResult.TestId = ResolveTestId(); VoileOnlineTestPost voileOnlinePost = new VoileOnlineTestPost(); voileOnlinePost.SessionMetadata = GetVoileOnlineTestSessionMetadata(); voileOnlinePost.TestResult = voileOnlineTestResult; VoileOnlineUploader.Upload(voileOnlinePost); } public TException AssertTargetInvocation(TestDelegate action) where TException : Exception { TargetInvocationException exeption = Assert.Throws(action); Assert.That(exeption.InnerException, Is.TypeOf()); return (TException)exeption.InnerException; } private TestLog4NetAppender? _testLogAppender; protected TestLog4NetAppender TestLogAppender => _testLogAppender ?? throw new InvalidOperationException("Test log appender is not initialized."); private void SetUpLogCapture() { Hierarchy hierarchy = (Hierarchy)LogManager.GetRepository(); _testLogAppender = new TestLog4NetAppender { Name = $"TestLogAppender-{TestContext.CurrentContext.Test.ID}" }; _testLogAppender.ActivateOptions(); hierarchy.Root.AddAppender(_testLogAppender); if (hierarchy.Root.Level == null) { hierarchy.Root.Level = log4net.Core.Level.Debug; } hierarchy.Configured = true; } private string TearDownLogCapture() { string logText = _testLogAppender?.GetText() ?? string.Empty; if (!string.IsNullOrWhiteSpace(logText)) { TestContext.WriteLine("Captured log4net output:"); TestContext.WriteLine(logText); } if (_testLogAppender is not null) { Hierarchy hierarchy = (Hierarchy)LogManager.GetRepository(); hierarchy.Root.RemoveAppender(_testLogAppender); _testLogAppender.Close(); _testLogAppender = null; } return logText; } }