void SafeOnErrorHandler(object source, CriticalErrorCollector.ErrorEventArgs e) { if (_inSafeErrorHandler) { _errorsFromBackground.Add("Error events are not raised simultaneously."); return; } // As soon as the first error, we increase the capacity to avoid losing any error. // This tests the tread-safety of the operation and shows that no deadlock occur (we are // receiving an error event and can safely change the internal buffer capacity). ActivityMonitor.CriticalErrorCollector.Capacity = 500; _inSafeErrorHandler = true; _maxNumberOfErrorReceivedAtOnce = Math.Max(_maxNumberOfErrorReceivedAtOnce, e.LoggingErrors.Count); foreach (var error in e.LoggingErrors) { if (error.SequenceNumber % 10 == 0) { int clearedErrors; int notYetRaisedErrors; ActivityMonitor.CriticalErrorCollector.Clear(out clearedErrors, out notYetRaisedErrors); _nbClearedWhileRaised += clearedErrors; _nbNotClearedWhileRaised += notYetRaisedErrors; } if (_lastSequenceNumberReceived != error.SequenceNumber - 1) { _errorsFromBackground.Add(String.Format("Received {0}, expected {1}.", error.SequenceNumber - 1, _lastSequenceNumberReceived)); _inSafeErrorHandler = false; return; } _lastSequenceNumberReceived = error.SequenceNumber; string msg = error.Exception.Message; if (msg.StartsWith("BuggyClient")) { int idx = Int32.Parse(Regex.Match(msg, "\\d+").Value); _buggyClients[idx].FailureHasBeenReceivedThroughEvent = true; } else if (msg.StartsWith("BuggyErrorHandler")) { ++_buggyOnErrorHandlerReceivedCount; if (!error.ToString().StartsWith(Impl.CoreResources.ErrorWhileCollectorRaiseError)) { _errorsFromBackground.Add("Bad comment for error handling."); _inSafeErrorHandler = false; return; } } else { _errorsFromBackground.Add("Unexpected error: " + error.Exception.Message); _inSafeErrorHandler = false; return; } } _inSafeErrorHandler = false; }
void BuggyOnErrorHandler(object source, CriticalErrorCollector.ErrorEventArgs e) { // Force at least one error regardless of the probability. if (_buggyOnErrorHandlerFailCount == 0 || _random.NextDouble() < _probBuggyOnErrorHandlerFailure) { // Subscribe again to this buggy event. ActivityMonitor.CriticalErrorCollector.OnErrorFromBackgroundThreads += BuggyOnErrorHandler; throw new CKException("BuggyErrorHandler{0}", _buggyOnErrorHandlerFailCount++); } }
public void catching_one_event() { CriticalErrorCollector c = new CriticalErrorCollector(); CriticalErrorCollector.ErrorEventArgs catched = null; EventHandler <CriticalErrorCollector.ErrorEventArgs> h = (sender, e) => catched = e; c.OnErrorFromBackgroundThreads += h; try { c.Add(new Exception("The-Test-Exception-Message"), "Produced by SimpleTest"); c.WaitOnErrorFromBackgroundThreadsPending(); catched.Should().NotBeNull(); catched.Errors.Should().HaveCount(1); catched.Errors[0].Exception.Message.Should().Contain("The-Test-Exception-Message"); catched.Errors[0].Comment.Should().Contain("Produced by SimpleTest"); } finally { c.OnErrorFromBackgroundThreads -= h; } }