private void WaitForMessages() { while (queuedMessages.Count == 0) { var data = messageBuffer.Read(); var fragment = new OutputDebugString(messageBuffer.Name, data); if (NewMessageFragment(fragment)) { FlushPartialMessage(); } if (String.IsNullOrEmpty(fragment.Message)) { continue; } AppendToPartialMessage(fragment); if (LastFragment(fragment) || ExceedsMaxMessageLength(partial)) { FlushPartialMessage(); } } }
private Boolean LastFragment(OutputDebugString fragment) { // HACK: Unfortunately, the good folks who wrote the implementation of OutputDebugString did not feel compelled to include a message length in the // serialized data. As such, let's assume that any message that exactly fills the messageBuffer is likely just a fragment provided the next message // comes from the same process. This may be a lie, but it is far more likely that a message overflows the messageBuffer than exactly fills the // messageBuffer (worst case: formatting is lost - no data will be lost). return(fragment.Message.Length < OutputDebugString.MaxMessageSize); }
public void RenderMessageIfNoParserFound() { var message = new OutputDebugString("MySource", 123, "My Message"); var resetEvent = new ManualResetEvent(false); renderer.Setup(mock => mock.Render(It.IsAny<SystemEvent>())).Callback(() => resetEvent.Set()); parser.Setup(mock => mock.CanParseMessage("My Message")).Returns(false); processor.Process(message); Assert.True(resetEvent.WaitOne(TimeSpan.FromSeconds(1)), "ManualResetEvent not signalled within expected time."); renderer.Verify(mock => mock.Render(It.Is((SystemEvent e) => e.ProcessName == "Process #123")), Times.Once()); parser.Verify(mock => mock.Parse(message), Times.Never()); }
public void TraceLevelFromMessage(String level, SystemEventLevel systemEventlevel) { processRetriever.Setup(mock => mock.GetProcessById(123)).Returns(new UnknownProcess(123)); var message = new OutputDebugString("xUnit Source", 123, String.Format("<log4j:event level=\"{0}\"></log4j:event>", level)); var e = messageParser.Parse(message); Assert.Equal(systemEventlevel, e.Level); }
private void AppendToPartialMessage(OutputDebugString fragment) { partial = partial == null ? fragment : new OutputDebugString(messageBuffer.Name, partial.ProcessId, partial.Message + fragment.Message); }
private void FlushPartialMessage() { queuedMessages.Enqueue(partial); partial = null; }
private Boolean NewMessageFragment(OutputDebugString fragment) { return(partial != null && (partial.ProcessId != fragment.ProcessId || String.IsNullOrEmpty(fragment.Message))); }
private Boolean ExceedsMaxMessageLength(OutputDebugString fragment) { // HACK: As we are forced to rely on a FULL messageBuffer denoting a message fragment, guard against all messages being exactly MaxFragmentSize. // In the case of OutputDebugString we will cap at approximately 64K before we force flush the message regardless. return(fragment.Message.Length >= MaxFragmentSize); }