unit LoggerProTestU; interface uses DUnitX.TestFramework, LoggerPro, LoggerPro.Proxy, System.SysUtils; type [TestFixture] TLoggerProTest = class(TObject) public [Setup] procedure Setup; [TearDown] procedure TearDown; [Test] procedure TestTLogItemClone; [Test] [TestCase('Type DEBUG', '0,DEBUG')] [TestCase('Type INFO', '1,INFO')] [TestCase('Type WARN', '2,WARNING')] [TestCase('Type ERROR', '3,ERROR')] [TestCase('Type FATAL', '4,FATAL')] procedure TestTLogItemTypeAsString(aLogType: Byte; aExpected: String); // [Test] {refactor this} // procedure TestOnAppenderError; [Test] [TestCase('No proxy', 'false')] [TestCase('With proxy', 'true')] procedure TestLogLevel(UseProxy: boolean); [Test] procedure TestAddAndDeleteAppenders; [Test] [TestCase('Case1', '{timestamp}|{threadid}|{loglevel}|{message}|{tag},2020-03-15 12:30:20:123| 1234|LOGLEVEL|THIS IS THE MESSAGE|THE_TAG')] [TestCase('Case2', '{timestamp}|{loglevel}|{message}|{tag},2020-03-15 12:30:20:123|LOGLEVEL|THIS IS THE MESSAGE|THE_TAG')] [TestCase('Case3', '{timestamp} -- {message},2020-03-15 12:30:20:123 -- THIS IS THE MESSAGE')] [TestCase('Case4', '{timestamp}[TID {threadid}][{loglevel}]{message}[{tag}],2020-03-15 12:30:20:123[TID 1234][LOGLEVEL]THIS IS THE MESSAGE[THE_TAG]')] procedure TestLogLayoutToLogIndices(const LogLayout, ResultOutput: string); end; implementation uses TestSupportAppendersU, System.SyncObjs, LoggerPro.OutputDebugStringAppender; function LogItemAreEquals(A, B: TLogItem): Boolean; begin Assert.AreEqual(A.LogType, B.LogType, 'LogType is different'); Assert.AreEqual(A.LogMessage, B.LogMessage, 'LogMessage is different'); Assert.AreEqual(A.LogTag, B.LogTag, 'LogTag is different'); Assert.AreEqual(A.TimeStamp, B.TimeStamp, 'TimeStamp is different'); Assert.AreEqual(A.ThreadID, B.ThreadID, 'ThreadID is different'); Result := True; end; procedure TLoggerProTest.Setup; begin end; procedure TLoggerProTest.TearDown; begin end; procedure TLoggerProTest.TestAddAndDeleteAppenders; var LAppender1, LAppender2: ILogAppender; LLogWriter: ILogWriter; begin LAppender1 := TLoggerProOutputDebugStringAppender.Create(); LAppender2 := TLoggerProOutputDebugStringAppender.Create(); LLogWriter := BuildLogWriter([LAppender1, LAppender2]); LLogWriter.Debug('Added Appenders', 'Appender'); Assert.AreEqual(2, LLogWriter.AppendersCount); LLogWriter.DelAppender(LAppender1); LLogWriter.Debug('Deleted Appenders', 'Appender'); Assert.AreEqual(1, LLogWriter.AppendersCount); LLogWriter.DelAppender(LAppender2); LLogWriter.Debug('Deleted Appenders', 'Appender'); Assert.AreEqual(0, LLogWriter.AppendersCount); LLogWriter.Debug('Deleted Appenders', 'Appender'); end; procedure TLoggerProTest.TestLogLayoutToLogIndices(const LogLayout, ResultOutput: string); begin var lWithIndices := LogLayoutByPlaceHoldersToLogLayoutByIndexes(LogLayout); var s := Format( lWithIndices, [ FormatDateTime('yyyy-mm-dd hh:nn:ss:zzz', encodedate(2020,3,15) + EncodeTime(12,30,20,123)), '1234', 'LOGLEVEL', 'THIS IS THE MESSAGE', 'THE_TAG' ]); Assert.AreEqual(ResultOutput, s); end; procedure TLoggerProTest.TestLogLevel(UseProxy: boolean); var lSetup, lTearDown: TProc; lTearDownCalled, lSetupCalled: Boolean; lWriteLog: TProc; lLogWriter: ILogWriter; lLogItem: TLogItem; lEvent: TEvent; lLock: TObject; lHistory: TArray; Appender: ILogAppender; InvalidItemLogged: int64; const STR_FORBIDDEN = 'ignoredmessage'; begin lHistory := []; lLock := TObject.Create; try lSetup := procedure begin lHistory := lHistory + ['setup']; lSetupCalled := True; end; lTearDown := procedure begin lHistory := lHistory + ['teardown']; lTearDownCalled := True; end; lWriteLog := procedure(aLogItem: TLogItem) begin lHistory := lHistory + ['writelog' + aLogItem.LogTypeAsString]; // If the logged message is suppsed to be filtered, increase the "InvalidItemLogged" count if aLogItem.LogMessage.Equals(STR_FORBIDDEN) then TInterlocked.Increment(InvalidItemLogged); TMonitor.Enter(lLock); try FreeAndNil(lLogItem); lLogItem := aLogItem.Clone; lEvent.SetEvent; finally TMonitor.Exit(lLock); end; end; Appender := TMyAppender.Create(lSetup, lTearDown, lWriteLog); if UseProxy then begin Appender := TLoggerProFilter.Build(Appender, function (LogItem: TLogItem): Boolean begin result := not LogItem.LogMessage.Equals(STR_FORBIDDEN); end ); end; InvalidItemLogged := 0; lLogWriter := BuildLogWriter([Appender]); lEvent := TEvent.Create(nil, True, false, ''); try // debug message lEvent.ResetEvent; InvalidItemLogged := 0; lLogWriter.Debug('debug message', 'debug'); if UseProxy then lLogWriter.Debug('ignoredmessage', 'debug'); Assert.AreEqual(TWaitResult.wrSignaled, lEvent.WaitFor(5000), 'Event not released after 5 seconds'); Assert.AreEqual('debug message', lLogItem.LogMessage); Assert.AreEqual('debug', lLogItem.LogTag); Assert.AreEqual('DEBUG', lLogItem.LogTypeAsString); Assert.AreEqual(Int64(0), Int64(TInterlocked.Read(InvalidItemLogged))); // info message lEvent.ResetEvent; InvalidItemLogged := 0; lLogWriter.Info('info message', 'info'); if UseProxy then lLogWriter.Info('ignoredmessage', 'info'); Assert.AreEqual(TWaitResult.wrSignaled, lEvent.WaitFor(5000), 'Event not released after 5 seconds'); Assert.AreEqual('info message', lLogItem.LogMessage); Assert.AreEqual('info', lLogItem.LogTag); Assert.AreEqual('INFO', lLogItem.LogTypeAsString); Assert.AreEqual(Int64(0), Int64(TInterlocked.Read(InvalidItemLogged))); // warning message lEvent.ResetEvent; InvalidItemLogged := 0; lLogWriter.Warn('warning message', 'warning'); if UseProxy then lLogWriter.Warn('ignoredmessage', 'warning'); Assert.AreEqual(TWaitResult.wrSignaled, lEvent.WaitFor(5000), 'Event not released after 5 seconds'); Assert.AreEqual('warning message', lLogItem.LogMessage); Assert.AreEqual('warning', lLogItem.LogTag); Assert.AreEqual('WARNING', lLogItem.LogTypeAsString); Assert.AreEqual(Int64(0), Int64(TInterlocked.Read(InvalidItemLogged))); // error message lEvent.ResetEvent; InvalidItemLogged := 0; lLogWriter.Error('error message', 'error'); if UseProxy then lLogWriter.Error('ignoredmessage', 'error'); Assert.AreEqual(TWaitResult.wrSignaled, lEvent.WaitFor(5000), 'Event not released after 5 seconds'); Assert.AreEqual('error message', lLogItem.LogMessage); Assert.AreEqual('error', lLogItem.LogTag); Assert.AreEqual('ERROR', lLogItem.LogTypeAsString); Assert.AreEqual(Int64(0), Int64(TInterlocked.Read(InvalidItemLogged))); // fatal message lEvent.ResetEvent; InvalidItemLogged := 0; lLogWriter.Fatal('fatal message', 'fatal'); if UseProxy then lLogWriter.Fatal('ignoredmessage', 'fatal'); Assert.AreEqual(TWaitResult.wrSignaled, lEvent.WaitFor(5000), 'Event not released after 5 seconds'); Assert.AreEqual('fatal message', lLogItem.LogMessage); Assert.AreEqual('fatal', lLogItem.LogTag); Assert.AreEqual('FATAL', lLogItem.LogTypeAsString); Assert.AreEqual(Int64(0), Int64(TInterlocked.Read(InvalidItemLogged))); lLogWriter := nil; Assert.AreEqual(7, Length(lHistory)); Assert.AreEqual('setup', lHistory[0]); Assert.AreEqual('writelogDEBUG', lHistory[1]); Assert.AreEqual('writelogINFO', lHistory[2]); Assert.AreEqual('writelogWARNING', lHistory[3]); Assert.AreEqual('writelogERROR', lHistory[4]); Assert.AreEqual('writelogFATAL', lHistory[5]); Assert.AreEqual('teardown', lHistory[6]); finally lEvent.Free; end; finally lLock.Free; end; end; //procedure TLoggerProTest.TestOnAppenderError; //var // lLog: ILogWriter; // I: Integer; // lEventsHandlers: TLoggerProEventsHandler; // lAppenders: TArray; // lSavedLoggerProAppenderQueueSize: Cardinal; // lOldestsDiscarded: Int64; // lNewestsSkipped: Int64; // lCount: Int64; // lTempCount: Int64; //begin // lCount := 0; // lSavedLoggerProAppenderQueueSize := DefaultLoggerProAppenderQueueSize; // DefaultLoggerProMainQueueSize := 1; // DefaultLoggerProAppenderQueueSize := 1; // // lNewestsSkipped := 0; // lOldestsDiscarded := 0; // lEventsHandlers := TLoggerProEventsHandler.Create; // try // lEventsHandlers.OnAppenderError := // procedure(const AppenderClassName: String; // const FailedLogItem: TLogItem; const Reason: TLogErrorReason; // var Action: TLogErrorAction) // var // lLocalCount: Int64; // begin // lLocalCount := TInterlocked.Add(lCount, 1); // if lLocalCount <= 20 then // begin // Action := TLogErrorAction.SkipNewest; // TInterlocked.Increment(lNewestsSkipped); // end // else // begin // Action := TLogErrorAction.DiscardOlder; // TInterlocked.Increment(lOldestsDiscarded); // end; // end; // // lLog := BuildLogWriter([TMyVerySlowAppender.Create(1000)], lEventsHandlers); // for I := 1 to 40 do // begin // lLog.Debug('log message ' + I.ToString, 'tag'); // end; // // {TODO -oDanieleT -cGeneral : Refactor this test} //// while True do //// begin //// lTempCount := TInterlocked.Read(lNewestsSkipped); //// if lTempCount < 20 then //// Sleep(10) //// else //// break; //// end; // // {TODO -oDanieleT -cGeneral : Refactor this test} //// while True do //// begin //// lTempCount := TInterlocked.Read(lOldestsDiscarded); //// if lTempCount < 20 then //// Sleep(10) //// else //// break; //// end; // //// while TInterlocked.Read(lCount) < 40 do //// Sleep(100); // // lAppenders := lLog.GetAppendersClassNames; // Assert.AreEqual(1, Length(lAppenders)); // Assert.AreEqual('TMyVerySlowAppender', lAppenders[0]); // lLog := nil; // finally // DefaultLoggerProAppenderQueueSize := lSavedLoggerProAppenderQueueSize; // lEventsHandlers.Free; // end; // //end; procedure TLoggerProTest.TestTLogItemClone; var lLogItem: TLogItem; lClonedLogItem: TLogItem; begin lLogItem := TLogItem.Create(TLogType.Debug, 'message', 'tag'); try lClonedLogItem := lLogItem.Clone; try LogItemAreEquals(lLogItem, lClonedLogItem); finally lClonedLogItem.Free; end; finally lLogItem.Free; end; end; procedure TLoggerProTest.TestTLogItemTypeAsString(aLogType: Byte; aExpected: String); var lLogItem: TLogItem; begin lLogItem := TLogItem.Create(TLogType(aLogType), 'message', 'tag'); try Assert.AreEqual(aExpected, lLogItem.LogTypeAsString); finally lLogItem.Free; end; end; initialization TDUnitX.RegisterTestFixture(TLoggerProTest); end.