public void CompressedReadWriteTests() { TestHelper.CleanupTestFolder(); string directoryPath = Path.Combine(TestHelper.TestFolder, "GzipCKMonWriterClientTest"); ActivityMonitor m = new ActivityMonitor(); var client = new CKMonWriterClient(directoryPath, 20000, LogFilter.Undefined, true); m.Output.RegisterClient(client); using (m.OpenWarn().Send("Group test")) { m.Info().Send("Line test"); } // This closes the client: the file is then compressed asynchronously // on a thread from the ThreadPool. Assert.That(client.IsOpened); m.Output.UnregisterClient(client); string ckmonPath = TestHelper.WaitForCkmonFilesInDirectory(directoryPath, 1)[0]; LogReader r = LogReader.Open(ckmonPath); r.MoveNext(); Assert.That(r.Current.LogType, Is.EqualTo(LogEntryType.OpenGroup)); Assert.That(r.Current.Text, Is.EqualTo("Group test")); r.MoveNext(); Assert.That(r.Current.LogType, Is.EqualTo(LogEntryType.Line)); Assert.That(r.Current.Text, Is.EqualTo("Line test")); r.MoveNext(); Assert.That(r.Current.LogType, Is.EqualTo(LogEntryType.CloseGroup)); bool hasRemainingEntries = r.MoveNext(); Assert.That(hasRemainingEntries, Is.False); }
public async Task persistent_error_for_sender_deactivate_the_handler_Async() { FakeLogSender.Reset(); // Let FakeLogSender.FakeSenderCanBeCreated = false: the handler is activated // but cannot create the sender yet. FakeLogSender.FakeSenderPersistentError = true; var host = await StartHostAsync(); Debug.Assert(FakeLogSender.ActivatedSender != null); FakeLogSender.ActivatedSender.FakeSender.Should().BeNull(); // Conditions to create the sender becomes true. FakeLogSender.FakeSenderCanBeCreated = true; // Handling a log entry triggers the sender creation but the "persistent error" // throws an exception: the handler is condemned (deactivation and removed). var monitor = new ActivityMonitor() { AutoTags = FakeLogSender.TestTag }; monitor.Info("NOSHOW"); await Task.Delay(50); FakeLogSender.ActivatedSender.Should().BeNull("The handler has been deactivated and removed."); await host.StopAsync(); }
public void buggy_clients_are_removed_from_Output() { ActivityMonitor.AutoConfiguration = null; ActivityMonitor monitor = new ActivityMonitor(); int clientCount = 0; if (TestHelper.LogsToConsole) { ++clientCount; monitor.Output.RegisterClient(new ActivityMonitorConsoleClient()); } ++clientCount; WaitActivityMonitorClient client = monitor.Output.RegisterClient(new WaitActivityMonitorClient()); Assert.That(monitor.Output.Clients.Count, Is.EqualTo(clientCount)); try { Task.Factory.StartNew(() => { monitor.Info().Send("Test must work in task"); }); client.WaitForOnUnfilteredLog(); Assert.That(() => monitor.Info().Send("Test must fail"), Throws.TypeOf(typeof(InvalidOperationException)). And.Message.EqualTo(Impl.ActivityMonitorResources.ActivityMonitorConcurrentThreadAccess)); Assert.That(monitor.Output.Clients.Count, Is.EqualTo(clientCount), "Still " + clientCount + ": Concurrent call: not the fault of the Client."); } finally { client.Free(); } Thread.Sleep(50); monitor.Info().Send("Test must work after task"); ++clientCount; monitor.Output.RegisterClient(new ActionActivityMonitorClient(() => { Assert.That(() => monitor.Info().Send("Test must fail reentrant client"), Throws.TypeOf(typeof(InvalidOperationException)). And.Message.EqualTo(Impl.ActivityMonitorResources.ActivityMonitorReentrancyError)); })); monitor.Info().Send("Test must work after reentrant client"); Assert.That(monitor.Output.Clients.Count, Is.EqualTo(clientCount), "The RegisterClient action above is ok: it checks that it triggered a reentrant call."); ++clientCount; monitor.Output.RegisterClient(new ActionActivityMonitorClient(() => { monitor.Info().Send("Test must fail reentrant client"); })); monitor.Info().Send("Test must work after reentrant client"); Assert.That(monitor.Output.Clients.Count, Is.EqualTo(clientCount - 1), "The BUGGY RegisterClient action above is NOT ok: it triggers a reentrant call exception => We have removed it."); }
public void EventsTest() { bool IsSendOnStarImmediate = true; // or false // create monitor var monitor = new ActivityMonitor(IsSendOnStarImmediate); // assign events monitor.Hand2NoteStarted += H2NStarted; monitor.Hand2NoteClosed += H2NStop; // you can change poll delay for ActivityMonitor (time interval between IsHand2NoteRunning checks) Assert.AreEqual(300, monitor.PollDelayMs); // 300ms by default monitor.PollDelayMs = 100; if (ActivityMonitor.IsHand2NoteRunning) { // if h2n is running and IsSendOnStarImmediate is set to true we expect OnHand2NoteStart to be fired almost immediately Assert.AreEqual(IsSendOnStarImmediate, _waitH2NStart.WaitOne(500)); // close h2n manually and wait some time for ActivityMonitor::OnHand2NoteStop // Thread.Sleep(10000); } // ActivityMonitor is IDisposable monitor.Dispose(); monitor.Dispose(); }
public void handler_can_send_some_log() { using (var server = TestHelper.DefaultMockServer()) { server.Open(); using (var grandOutputServer = GrandOutputHelper.GetNewGrandOutputServer()) using (var grandOutputClient = GrandOutputHelper.GetNewGrandOutputClient()) { var serverActivityMonitor = new ActivityMonitor { MinimalFilter = LogFilter.Debug }; grandOutputServer.EnsureGrandOutputClient(serverActivityMonitor); var clientActivityMonitor = new ActivityMonitor { MinimalFilter = LogFilter.Debug }; grandOutputClient.EnsureGrandOutputClient(clientActivityMonitor); var guid = Guid.NewGuid().ToString(); clientActivityMonitor.Info(guid); Thread.Sleep(TestHelper.DefaultSleepTime); server.GetLogEntry(guid).Validate(guid).Should().BeTrue(); serverActivityMonitor.CloseGroup(); clientActivityMonitor.CloseGroup(); } } }
public async Task creating_sender_waits_for_SenderCanBeCreated_and_Sender_is_Disposed_Async() { FakeLogSender.Reset(); var host = await StartHostAsync(); Debug.Assert(FakeLogSender.ActivatedSender != null); var monitor = new ActivityMonitor() { AutoTags = FakeLogSender.TestTag }; monitor.Info("NOSHOW"); await Task.Delay(50); FakeLogSender.ActivatedSender.Should().NotBeNull(); FakeLogSender.ActivatedSender.FakeSender.Should().BeNull(); FakeLogSender.FakeSenderCanBeCreated = true; monitor.Info("NOSHOW"); await Task.Delay(50); var sender = FakeLogSender.ActivatedSender.FakeSender; Debug.Assert(sender != null); sender.Disposed.Should().BeFalse(); FakeLogSender.LogSent.Should().BeEmpty("FakeSenderIsActuallyConnected is false: no log can be sent."); await host.StopAsync(); sender.Disposed.Should().BeTrue(); }
public void registering_multiple_times_the_same_client_is_an_error() { ActivityMonitor.AutoConfiguration = null; IActivityMonitor monitor = new ActivityMonitor(); Assert.That( monitor.Output.Clients.Count, Is.EqualTo( 0 ) ); var counter = new ActivityMonitorErrorCounter(); monitor.Output.RegisterClient( counter ); Assert.That( monitor.Output.Clients.Count, Is.EqualTo( 1 ) ); Assert.Throws<InvalidOperationException>( () => TestHelper.ConsoleMonitor.Output.RegisterClient( counter ), "Counter can be registered in one source at a time." ); var pathCatcher = new ActivityMonitorPathCatcher(); monitor.Output.RegisterClient( pathCatcher ); Assert.That( monitor.Output.Clients.Count, Is.EqualTo( 2 ) ); Assert.Throws<InvalidOperationException>( () => TestHelper.ConsoleMonitor.Output.RegisterClient( pathCatcher ), "PathCatcher can be registered in one source at a time." ); IActivityMonitor other = new ActivityMonitor( applyAutoConfigurations: false ); ActivityMonitorBridge bridgeToConsole; using( monitor.Output.CreateBridgeTo( TestHelper.ConsoleMonitor.Output.BridgeTarget ) ) { bridgeToConsole = monitor.Output.FindBridgeTo( TestHelper.ConsoleMonitor.Output.BridgeTarget ); Assert.That( monitor.Output.Clients.Count, Is.EqualTo( 3 ) ); Assert.That( bridgeToConsole.TargetMonitor, Is.SameAs( TestHelper.ConsoleMonitor ) ); Assert.Throws<InvalidOperationException>( () => other.Output.RegisterClient( bridgeToConsole ), "Bridge can be associated to only one source monitor." ); } Assert.That( monitor.Output.Clients.Count, Is.EqualTo( 2 ) ); Assert.DoesNotThrow( () => other.Output.RegisterClient( bridgeToConsole ), "Now we can." ); Assert.DoesNotThrow( () => monitor.Output.UnregisterClient( bridgeToConsole ), "Already removed." ); monitor.Output.UnregisterClient( counter ); monitor.Output.UnregisterClient( pathCatcher ); Assert.That( monitor.Output.Clients.Count, Is.EqualTo( 0 ) ); }
public void FindInactiveRssFeeds_CompanyWithMultipleFeedMixActivity_ReturnEmptyList() { DateTimeOffset activeDate = DateTimeOffset.Now.AddHours(-23); DateTimeOffset inactiveDate = DateTimeOffset.Now.AddHours(-25); string companyName = "Fake Company"; var mock = new Mock <IRssReader>(); mock.Setup(r => r.LoadRssFeed(It.IsAny <string>())).Returns(true); mock.SetupSequence(r => r.MostRecentItemPublished) .Returns(activeDate) .Returns(activeDate) .Returns(inactiveDate) .Returns(inactiveDate); mock.Setup(r => r.IsLoaded).Returns(true); mockReader = mock.Object; IRssActivityMonitor monitor = new ActivityMonitor(mockReader); Dictionary <string, List <string> > inputRssFeeds = new Dictionary <string, List <string> >(); inputRssFeeds.Add(companyName, new List <string>() { "http://fake.feed.xml", "http://fake.second-feed.xml" }); List <string> InactiveCompanies = monitor.FindInactiveRssFeeds(inputRssFeeds); Assert.AreEqual(0, InactiveCompanies.Count); }
public void ApplyConfigSimple() { GrandOutputConfiguration c = new GrandOutputConfiguration(); Assert.That(c.Load(XDocument.Parse(@" <GrandOutputConfiguration AppDomainDefaultFilter=""Release"" > <Channel MinimalFilter=""{Trace,Info}""> <Add Type=""BinaryFile"" Name=""GlobalCatch"" Path=""Configuration/ApplyConfig"" /> </Channel> </GrandOutputConfiguration>").Root, TestHelper.ConsoleMonitor)); Assert.That(c.ChannelsConfiguration.Configurations.Count, Is.EqualTo(1)); ActivityMonitor m = new ActivityMonitor(false); using (GrandOutput g = new GrandOutput()) { m.Info().Send("Before Registering - NOSHOW"); g.Register(m); m.Info().Send("Before configuration - NOSHOW"); Assert.That(g.SetConfiguration(c, TestHelper.ConsoleMonitor)); m.Info().Send("After configuration. INFO1"); Assert.That(m.ActualFilter, Is.EqualTo(new LogFilter(LogLevelFilter.Trace, LogLevelFilter.Info))); m.Trace().Send("TRACE1-NOSHOW (MinimalFilter of the Channel)."); Assert.That(g.SetConfiguration(new GrandOutputConfiguration(), TestHelper.ConsoleMonitor)); g.Dispose(TestHelper.ConsoleMonitor); m.Info().Send("After disposing - NOSHOW."); Assert.That(m.ActualFilter, Is.EqualTo(LogFilter.Undefined)); } }
public void FindInactiveRssFeeds_RssReaderErrorTreatAsInactive_ReturnListOfOne() { DateTimeOffset inactiveDate1 = DateTimeOffset.Now.AddHours(-21); DateTimeOffset inactiveDate2 = DateTimeOffset.Now.AddHours(-21); string companyName1 = "Fake Company"; string companyName2 = "Other Company"; var mock = new Mock <IRssReader>(); mock.Setup(r => r.LoadRssFeed(It.IsAny <string>())).Returns(true); mock.SetupSequence(r => r.MostRecentItemPublished) .Returns(inactiveDate1) .Returns(inactiveDate1) .Throws(new Exception("This is a fake error")); mock.Setup(r => r.IsLoaded).Returns(true); mockReader = mock.Object; IRssActivityMonitor monitor = new ActivityMonitor(mockReader); Dictionary <string, List <string> > inputRssFeeds = new Dictionary <string, List <string> >(); inputRssFeeds.Add(companyName1, new List <string>() { "http://fake.feed.xml" }); inputRssFeeds.Add(companyName2, new List <string>() { "http://fake.second-feed.xml" }); List <string> InactiveCompanies = monitor.FindInactiveRssFeeds(inputRssFeeds); Assert.AreEqual(1, InactiveCompanies.Count); }
public void FindInactiveRssFeeds_RssReaderErrorGetThrown_ExceptionThrown() { DateTimeOffset inactiveDate1 = DateTimeOffset.Now.AddHours(-21); DateTimeOffset inactiveDate2 = DateTimeOffset.Now.AddHours(-21); string companyName1 = "Fake Company"; string companyName2 = "Other Company"; var mock = new Mock <IRssReader>(); mock.Setup(r => r.LoadRssFeed(It.IsAny <string>())).Returns(true); mock.SetupSequence(r => r.MostRecentItemPublished) .Returns(inactiveDate1) .Returns(inactiveDate1) .Throws(new Exception("This is a fake error")); mock.Setup(r => r.IsLoaded).Returns(true); mockReader = mock.Object; IRssActivityMonitor monitor = new ActivityMonitor(mockReader); Dictionary <string, List <string> > inputRssFeeds = new Dictionary <string, List <string> >(); inputRssFeeds.Add(companyName1, new List <string>() { "http://fake.feed.xml" }); inputRssFeeds.Add(companyName2, new List <string>() { "http://fake.second-feed.xml" }); List <string> InactiveCompanies = monitor.FindInactiveRssFeeds(inputRssFeeds, 1, false); Assert.Fail("Exeption should have been raised prior to this point"); }
public void FindInactiveRssFeeds_CompanyWith1InactiveFeed_ReturnCompanyInList() { DateTimeOffset inactiveDate = DateTimeOffset.Now.AddHours(-25); string companyName = "Fake Company"; var mock = new Mock <IRssReader>(); mock.Setup(r => r.LoadRssFeed(It.IsAny <string>())).Returns(true); mock.Setup(r => r.MostRecentItemPublished).Returns(inactiveDate); mock.SetupSequence(r => r.IsLoaded) .Returns(false) .Returns(true); mockReader = mock.Object; IRssActivityMonitor monitor = new ActivityMonitor(mockReader); Dictionary <string, List <string> > inputRssFeeds = new Dictionary <string, List <string> >(); inputRssFeeds.Add(companyName, new List <string>() { "http://fake.feed.xml" }); List <string> InactiveCompanies = monitor.FindInactiveRssFeeds(inputRssFeeds); Assert.AreEqual(1, InactiveCompanies.Count); Assert.AreEqual(companyName, InactiveCompanies[0], false, "Company Name is not the correct value"); }
public void SourceFileOverrideFilterTest() { { var m = new ActivityMonitor( applyAutoConfigurations: false ); var c = m.Output.RegisterClient( new StupidStringClient() ); Assert.That( m.ActualFilter, Is.EqualTo( LogFilter.Undefined ) ); m.Trace().Send( "Trace1" ); m.OpenTrace().Send( "OTrace1" ); ActivityMonitor.SourceFilter.SetOverrideFilter( LogFilter.Release ); m.Trace().Send( "NOSHOW" ); m.OpenTrace().Send( "NOSHOW" ); ActivityMonitor.SourceFilter.SetOverrideFilter( LogFilter.Undefined ); m.Trace().Send( "Trace2" ); m.OpenTrace().Send( "OTrace2" ); CollectionAssert.AreEqual( new[] { "Trace1", "OTrace1", "Trace2", "OTrace2" }, c.Entries.Select( e => e.Text ).ToArray(), StringComparer.OrdinalIgnoreCase ); } { var m = new ActivityMonitor( applyAutoConfigurations: false ); var c = m.Output.RegisterClient( new StupidStringClient() ); m.MinimalFilter = LogFilter.Terse; m.Trace().Send( "NOSHOW" ); m.OpenTrace().Send( "NOSHOW" ); ActivityMonitor.SourceFilter.SetOverrideFilter( LogFilter.Debug ); m.Trace().Send( "Trace1" ); m.OpenTrace().Send( "OTrace1" ); ActivityMonitor.SourceFilter.SetOverrideFilter( LogFilter.Undefined ); m.Trace().Send( "NOSHOW" ); m.OpenTrace().Send( "NOSHOW" ); CollectionAssert.AreEqual( new[] { "Trace1", "OTrace1" }, c.Entries.Select( e => e.Text ).ToArray(), StringComparer.OrdinalIgnoreCase ); } }
/// <summary> /// Resumes the given task. /// </summary> /// <param name="p_tskTask">The task to resume.</param> public void ResumeTask(IBackgroundTask p_tskTask) { if (ActivityMonitor.CanResume(p_tskTask)) { ActivityMonitor.ResumeActivity(p_tskTask); } }
public void ThreadSafeOnClientMinimalFilterChanged() { var monitor = new ActivityMonitor(false); var c = monitor.Output.RegisterClient(new ActivityMonitorClientTester()); Parallel.For(0, 20, i => c.AsyncSetMinimalFilterBlock(new LogFilter(LogLevelFilter.Info, (LogLevelFilter)(i % 5 + 1)), 1)); }
/// <summary> /// Puases the given task. /// </summary> /// <param name="p_tskTask">The task to pause.</param> public void PauseTask(IBackgroundTask p_tskTask) { if (ActivityMonitor.CanPause(p_tskTask)) { ActivityMonitor.PauseActivity(p_tskTask); } }
public void parsing_DependentToken_with_topics( string topic ) { var monitor = new ActivityMonitor(); var t1 = monitor.DependentActivity().CreateTokenWithTopic( topic ); var t2 = monitor.DependentActivity().CreateTokenWithTopic( topic ); var t3 = monitor.DependentActivity().CreateTokenWithTopic( topic ); Assume.That( t2.CreationDate.Uniquifier + t3.CreationDate.Uniquifier > 0 ); var r1 = ActivityMonitor.DependentToken.Parse( t1.ToString() ); Assert.That( r1.OriginatorId, Is.EqualTo( t1.OriginatorId ) ); Assert.That( r1.CreationDate, Is.EqualTo( t1.CreationDate ) ); Assert.That( r1.Topic, Is.EqualTo( t1.Topic ) ); Assert.That( r1.ToString(), Is.EqualTo( t1.ToString() ) ); var r2 = ActivityMonitor.DependentToken.Parse( t2.ToString() ); Assert.That( r2.OriginatorId, Is.EqualTo( t2.OriginatorId ) ); Assert.That( r2.CreationDate, Is.EqualTo( t2.CreationDate ) ); Assert.That( r2.Topic, Is.EqualTo( t2.Topic ) ); Assert.That( r2.ToString(), Is.EqualTo( t2.ToString() ) ); var r3 = ActivityMonitor.DependentToken.Parse( t3.ToString() ); Assert.That( r3.OriginatorId, Is.EqualTo( t3.OriginatorId ) ); Assert.That( r3.CreationDate, Is.EqualTo( t3.CreationDate ) ); Assert.That( r3.Topic, Is.EqualTo( t3.Topic ) ); Assert.That( r3.ToString(), Is.EqualTo( t3.ToString() ) ); }
static GrandOutput CreateGrandOutputWithFakeHandler(int handlerExtralLoad, bool useAdaptive, int dispatcherMaxCapacity) { IActivityMonitor mLoad = new ActivityMonitor(false); GrandOutputConfiguration c = new GrandOutputConfiguration(); var textConfig = @"<GrandOutputConfiguration><Channel><Add Type=""FakeHandler, CK.Monitoring.Tests"" Name=""GlobalCatch"" ExtraLoad=""" + handlerExtralLoad.ToString() + @""" /></Channel></GrandOutputConfiguration>"; Assert.That(c.Load(XDocument.Parse(textConfig).Root, mLoad)); Assert.That(c.ChannelsConfiguration.Configurations.Count, Is.EqualTo(1)); IGrandOutputDispatcherStrategy strat; if (useAdaptive) { strat = new Impl.EventDispatcherLocalTestStrategy(dispatcherMaxCapacity); } else { strat = new Impl.EventDispatcherBasicStrategy(dispatcherMaxCapacity); } GrandOutput g = new GrandOutput(strat); g.SetConfiguration(c, mLoad); return(g); }
private static void Main(string[] args) { SetupActivityMonitor(); var m = new ActivityMonitor(); var doContinue = true; while (doContinue) { System.Console.WriteLine("Press q to quit, m to send a line, s to send a CriticalError"); var k = System.Console.ReadKey(true); switch (k.Key) { case ConsoleKey.Q: m.Info("Goodbye"); doContinue = false; break; case ConsoleKey.M: m.Info($"Hello world - {DateTime.Now:R} - {Guid.NewGuid()}"); break; case ConsoleKey.S: m.Error($"CriticalError - {DateTime.Now:R}"); break; default: m.Warn($"Unknown key {k.Key}"); break; } } }
public void FindInactiveRssFeeds_ChangeDaysParamToTwo_ReturnListOfZero() { DateTimeOffset inactiveDate1 = DateTimeOffset.Now.AddHours(-26); DateTimeOffset inactiveDate2 = DateTimeOffset.Now.AddHours(-25); string companyName1 = "Fake Company"; string companyName2 = "Other Company"; var mock = new Mock <IRssReader>(); mock.Setup(r => r.LoadRssFeed(It.IsAny <string>())).Returns(true); mock.SetupSequence(r => r.MostRecentItemPublished) .Returns(inactiveDate1) .Returns(inactiveDate1) .Returns(inactiveDate2) .Returns(inactiveDate2); mock.Setup(r => r.IsLoaded).Returns(true); mockReader = mock.Object; IRssActivityMonitor monitor = new ActivityMonitor(mockReader); Dictionary <string, List <string> > inputRssFeeds = new Dictionary <string, List <string> >(); inputRssFeeds.Add(companyName1, new List <string>() { "http://fake.feed.xml" }); inputRssFeeds.Add(companyName2, new List <string>() { "http://fake.second-feed.xml" }); List <string> InactiveCompanies = monitor.FindInactiveRssFeeds(inputRssFeeds, 2); Assert.AreEqual(0, InactiveCompanies.Count); }
public static void ConstructIndex() { if (_initialized) { return; } using (var server = TestHelper.DefaultGloutonServer()) { server.Open(new HandlersManagerConfiguration { GloutonHandlers = { LuceneGloutonHandlerConfiguration } }); using (var grandOutputClient = GrandOutputHelper.GetNewGrandOutputClient()) { var activityMonitor = new ActivityMonitor(false) { MinimalFilter = LogFilter.Debug }; grandOutputClient.EnsureGrandOutputClient(activityMonitor); activityMonitor.Info("Hello world"); activityMonitor.Error("CriticalError"); TotalLogCount += 2; activityMonitor.Fatal(ThrowAggregateException(3)); } } _initialized = true; }
public void ThreadSafeOnClientMinimalFilterChanged() { var monitor = new ActivityMonitor( false ); var c = monitor.Output.RegisterClient( new ActivityMonitorClientTester() ); Parallel.For( 0, 20, i => c.AsyncSetMinimalFilterBlock( new LogFilter( LogLevelFilter.Info, (LogLevelFilter)(i % 5 + 1) ), 1 ) ); }
public async Task Configuration_changes_dont_stutter_Async() { DemoSinkHandler.Reset(); var config = new DynamicConfigurationSource(); config["CK-Monitoring:GrandOutput:Handlers:CK.Monitoring.Hosting.Tests.DemoSinkHandler, CK.Monitoring.Hosting.Tests"] = "true"; var host = new HostBuilder() .ConfigureAppConfiguration((hostingContext, c) => c.Add(config)) .UseCKMonitoring() .Build(); await host.StartAsync(); var m = new ActivityMonitor("The starting topic!"); config["CK-Monitoring:GrandOutput:Handlers:Console"] = "true"; await Task.Delay(200); m.Info("DONE!"); await host.StopAsync(); var texts = DemoSinkHandler.LogEvents.OrderBy(e => e.LogTime).Select(e => e.Text).Concatenate(System.Environment.NewLine); texts.Should() .Contain("GrandOutput.Default configuration n°0") .And.Contain("GrandOutput.Default configuration n°1") .And.NotContain("GrandOutput.Default configuration n°2") .And.Contain("DONE!"); }
public async Task Invalid_configurations_are_skipped_and_errors_go_to_the_current_handlers_Async() { DemoSinkHandler.Reset(); var config = new DynamicConfigurationSource(); config["CK-Monitoring:GrandOutput:Handlers:CK.Monitoring.Hosting.Tests.DemoSinkHandler, CK.Monitoring.Hosting.Tests"] = "true"; var host = new HostBuilder() .ConfigureAppConfiguration((hostingContext, c) => c.Add(config)) .UseCKMonitoring() .Build(); await host.StartAsync(); var m = new ActivityMonitor("The topic!"); m.Info("BEFORE"); config["CK-Monitoring:GrandOutput:Handlers:Invalid Handler"] = "true"; m.Info("AFTER"); await host.StopAsync(); DemoSinkHandler.LogEvents.Select(e => e.Text).Should() .Contain("Topic: The topic!") .And.Contain("BEFORE") .And.Contain("While applying dynamic configuration.") .And.Contain("AFTER"); }
static IActivityMonitor CreateMonitorAndRegisterGrandOutput(string topic, GrandOutput go) { var m = new ActivityMonitor(topic); go.Register(m); return(m); }
public DispatcherSink(Action <IActivityMonitor> initialRegister, IdentityCard identityCard, TimeSpan timerDuration, TimeSpan externalTimerDuration, Action externalTimer, Action <LogFilter?, LogLevelFilter?> filterChange, bool isDefaultGrandOutput) { _initialRegister = initialRegister; _identityCard = identityCard; _queue = Channel.CreateUnbounded <IMulticastLogEntry?>(new UnboundedChannelOptions() { SingleReader = true }); _handlers = new List <IGrandOutputHandler>(); _confTrigger = new object(); _stopTokenSource = new CancellationTokenSource(); _timerDuration = timerDuration; _deltaTicks = timerDuration.Ticks; _deltaExternalTicks = externalTimerDuration.Ticks; _externalOnTimer = externalTimer; _filterChange = filterChange; _externalLogLock = new object(); _externalLogLastTime = DateTimeStamp.MinValue; _isDefaultGrandOutput = isDefaultGrandOutput; _newConf = Array.Empty <GrandOutputConfiguration>(); var monitor = new ActivityMonitor(applyAutoConfigurations: false); // We emit the identity card changed from this monitor (so we need its id). // But more importantly, this monitor identifier is the one of the GrandOutput: each log entry // references this identifier. _sinkMonitorId = monitor.UniqueId; _task = ProcessAsync(monitor); }
public void parsing_DependentToken_with_topics(string topic) { var monitor = new ActivityMonitor(); var t1 = monitor.DependentActivity().CreateTokenWithTopic(topic); var t2 = monitor.DependentActivity().CreateTokenWithTopic(topic); var t3 = monitor.DependentActivity().CreateTokenWithTopic(topic); Assume.That(t2.CreationDate.Uniquifier + t3.CreationDate.Uniquifier > 0); var r1 = ActivityMonitor.DependentToken.Parse(t1.ToString()); Assert.That(r1.OriginatorId, Is.EqualTo(t1.OriginatorId)); Assert.That(r1.CreationDate, Is.EqualTo(t1.CreationDate)); Assert.That(r1.Topic, Is.EqualTo(t1.Topic)); Assert.That(r1.ToString(), Is.EqualTo(t1.ToString())); var r2 = ActivityMonitor.DependentToken.Parse(t2.ToString()); Assert.That(r2.OriginatorId, Is.EqualTo(t2.OriginatorId)); Assert.That(r2.CreationDate, Is.EqualTo(t2.CreationDate)); Assert.That(r2.Topic, Is.EqualTo(t2.Topic)); Assert.That(r2.ToString(), Is.EqualTo(t2.ToString())); var r3 = ActivityMonitor.DependentToken.Parse(t3.ToString()); Assert.That(r3.OriginatorId, Is.EqualTo(t3.OriginatorId)); Assert.That(r3.CreationDate, Is.EqualTo(t3.CreationDate)); Assert.That(r3.Topic, Is.EqualTo(t3.Topic)); Assert.That(r3.ToString(), Is.EqualTo(t3.ToString())); }
public void SourceFileMinimalFilterTest() { { var m = new ActivityMonitor(applyAutoConfigurations: false); var c = m.Output.RegisterClient(new StupidStringClient()); Assert.That(m.ActualFilter, Is.EqualTo(LogFilter.Undefined)); m.Trace().Send("Trace1"); m.OpenTrace().Send("OTrace1"); ActivityMonitor.SourceFilter.SetMinimalFilter(LogFilter.Release); m.Trace().Send("NOSHOW"); m.OpenTrace().Send("NOSHOW"); ActivityMonitor.SourceFilter.SetMinimalFilter(LogFilter.Undefined); m.Trace().Send("Trace2"); m.OpenTrace().Send("OTrace2"); CollectionAssert.AreEqual(new[] { "Trace1", "OTrace1", "Trace2", "OTrace2" }, c.Entries.Select(e => e.Text).ToArray(), StringComparer.OrdinalIgnoreCase); } { var m = new ActivityMonitor(applyAutoConfigurations: false); var c = m.Output.RegisterClient(new StupidStringClient()); m.MinimalFilter = LogFilter.Terse; m.Trace().Send("NOSHOW"); m.OpenTrace().Send("NOSHOW"); ActivityMonitor.SourceFilter.SetMinimalFilter(LogFilter.Debug); m.Trace().Send("Trace1"); m.OpenTrace().Send("OTrace1"); ActivityMonitor.SourceFilter.SetMinimalFilter(LogFilter.Undefined); m.Trace().Send("NOSHOW"); m.OpenTrace().Send("NOSHOW"); CollectionAssert.AreEqual(new[] { "Trace1", "OTrace1" }, c.Entries.Select(e => e.Text).ToArray(), StringComparer.OrdinalIgnoreCase); } }
static void Main(string[] args) { var m = new ActivityMonitor(topic: "I'm full of colors (and I'm playing with levels and filters)."); m.Output.RegisterClient(new ColoredActivityMonitorConsoleClient()); m.MinimalFilter = LogFilter.Terse; using (m.OpenInfo($"Let's go: the actual filter is {m.ActualFilter}.")) { m.Info("In Terse filter, only Info (and above) groups and only Error or Fatal lines are logged. So you won't see this."); using (m.OpenError("A whole group of error.")) { m.Debug("Debug is the lowest level."); m.Debug($"In an Error or Fatal group, the minimal filter is automatically set to {m.ActualFilter} (that's why you can see this line)."); m.Trace("Trace is low level."); m.Info("Info is interesting."); m.Warn("Warning is not serious."); m.Error("Error should be investigated."); m.Fatal("Fatal ruins the process."); m.CloseGroup("This concludes the error (the using } close below will do nothing)."); } m.MinimalFilter = LogFilter.Verbose; m.Info("Verbose filter let's the Info lines be logged."); m.Info("Note that closing a group restores the minimal filter level that was set on the opening."); } Debug.Assert(m.ActualFilter == LogFilter.Terse); m.MinimalFilter = LogFilter.Monitor; m.Warn("Using Monitor filter, only Warn, Error and Fatal lines are logged."); System.Console.ReadLine(); }
public void BinaryGzip_reconfiguration() { string folder = TestHelper.PrepareLogFolder(nameof(BinaryGzip_reconfiguration)); var h = new Handlers.BinaryFileConfiguration() { Path = folder + @"\FirstPath", UseGzipCompression = false }; var c = new GrandOutputConfiguration().AddHandler(h); var m = new ActivityMonitor(applyAutoConfigurations: false); using (GrandOutput g = new GrandOutput(c)) { g.EnsureGrandOutputClient(m); m.Trace("No Compression."); // We must ensure that the log above will use the current configuration. // This is by design and is a good thing: there is no causality/ordering between log emission and sink reconfigurations. Thread.Sleep(100); h.UseGzipCompression = true; g.ApplyConfiguration(c, true); m.Trace("With Compression."); Thread.Sleep(100); h.Path = folder + @"\SecondPath"; g.ApplyConfiguration(c, true); m.Trace("With Compression (in second folder)."); Thread.Sleep(100); h.UseGzipCompression = false; g.ApplyConfiguration(c, true); m.Trace("No Compression (in second folder)."); } // First file is NOT compressed, the second one is. var fileNamesFirst = Directory.EnumerateFiles(folder + @"\FirstPath").ToList(); fileNamesFirst.Should().BeInAscendingOrder().And.HaveCount(2).And.NotContain(s => s.EndsWith(".tmp"), "Temporary files have been closed."); File.ReadAllText(fileNamesFirst[0]).Should().Contain("No Compression."); File.ReadAllText(fileNamesFirst[1]).Should().NotContain("With Compression.", "Cannot read it in clear text since it is compressed..."); using (var reader = LogReader.Open(fileNamesFirst[1])) { reader.MoveNext().Should().BeTrue(); reader.Current.Text.Should().Be("With Compression."); } // First file is compressed, not the second one. var fileNamesSecond = Directory.EnumerateFiles(folder + @"\SecondPath").ToList(); fileNamesSecond.Should().BeInAscendingOrder().And.HaveCount(2).And.NotContain(s => s.EndsWith(".tmp"), "Temporary files have been closed."); File.ReadAllText(fileNamesSecond[0]).Should().NotContain("With Compression (in second folder).", "The fist file is compressed..."); // We restrict the log entries to the one of our monitor: this filters out the logs from the DispatcherSink. using (var reader = LogReader.Open(fileNamesSecond[0], filter: new LogReader.MulticastFilter(m))) { reader.MoveNext().Should().BeTrue(); reader.Current.Text.Should().Be("With Compression (in second folder)."); } File.ReadAllText(fileNamesSecond[1]).Should().Contain("No Compression (in second folder)."); }
public void can_add_alert() { using (var server = TestHelper.DefaultGloutonServer()) { server.Open(new HandlersManagerConfiguration { GloutonHandlers = { new AlertHandlerConfiguration { DatabasePath = @"%localappdata%/Glouton/Alerts".GetPathWithSpecialFolders() } } }); using (var grandOutputClient = GrandOutputHelper.GetNewGrandOutputClient()) { var activityMonitor = new ActivityMonitor(false) { MinimalFilter = LogFilter.Debug }; grandOutputClient.EnsureGrandOutputClient(activityMonitor); using (var receiver = new SingleHttpReceiver(SingleHttpReceiver.DefaultUrl)) { activityMonitor.Info("Hello world"); Thread.Sleep(TestHelper.DefaultSleepTime); receiver.Alerted.Should().BeFalse(); } server.ApplyConfiguration(new HandlersManagerConfiguration { GloutonHandlers = { new AlertHandlerConfiguration { DatabasePath = @"%localappdata%/Glouton/Alerts".GetPathWithSpecialFolders(), Alerts = new List <IAlertExpressionModel> { new AlertExpressionModelMock ( new [] { new [] { "Text", "EqualTo", "Hello world" } }, new IAlertSenderConfiguration[] { new HttpSenderConfiguration { Url = SingleHttpReceiver.DefaultUrl } } ) } } } }); Thread.Sleep(TestHelper.DefaultSleepTime); using (var receiver = new SingleHttpReceiver(SingleHttpReceiver.DefaultUrl)) { activityMonitor.Info("Hello world"); Thread.Sleep(TestHelper.DefaultSleepTime * 10); receiver.Alerted.Should().BeTrue(); } } } }
public WorkQueueBatch WaitAll(int millisecondsTimeout) { var activityMonitor = new ActivityMonitor(); Array.ForEach(CopyAndClearFutures(), future => activityMonitor.Monitor(() => future.Wait(millisecondsTimeout))); activityMonitor.Resolve(); return(this); }
public async Task ISender_buffers_the_logs_while_connection_is_lost_Async(string mode) { void Open(bool open) { if (mode == "UseIsActuallyConnected") { FakeLogSender.FakeSenderImplIsActuallyConnected = open; FakeLogSender.FakeSenderImplTrySendSuccess = true; } else { FakeLogSender.FakeSenderImplIsActuallyConnected = true; FakeLogSender.FakeSenderImplTrySendSuccess = open; } } FakeLogSender.Reset(); FakeLogSender.FakeSenderCanBeCreated = true; Open(true); var host = await StartHostAsync(); Debug.Assert(FakeLogSender.ActivatedSender != null, "The handler is activated."); var monitor = new ActivityMonitor() { AutoTags = FakeLogSender.TestTag }; monitor.Info("n°1"); await Task.Delay(50); Open(false); // The LostBufferSize is 3: these 3 will be eventually sent. monitor.Info("n°2"); monitor.Info("n°3"); monitor.Info("n°4"); await Task.Delay(50); Open(true); monitor.Info("n°5"); await Task.Delay(50); Open(false); monitor.Info("NOSHOW - will be evicted."); monitor.Info("n°6"); monitor.Info("n°7"); monitor.Info("n°8"); await Task.Delay(50); Open(true); monitor.Info("n°9"); await Task.Delay(50); FakeLogSender.LogSent.Concatenate().Should().Contain("n°1, n°2, n°3, n°4, n°5, n°6, n°7, n°8, n°9").And.NotContain("NOSHOW"); await host.StopAsync(); }
void Create() { { var m = new ActivityMonitor(); } { var m = new ActivityMonitor(applyAutoConfigurations: false); } { IActivityMonitor m = new ActivityMonitor(); var counter = new ActivityMonitorErrorCounter(); m.Output.RegisterClient(counter); m.Fatal().Send("An horrible error occurred."); Assert.That(counter.Current.FatalCount == 1); m.Output.UnregisterClient(counter); } { IActivityMonitor m = new ActivityMonitor(); int errorCount = 0; using (m.OnError(() => ++ errorCount)) { m.Fatal().Send("An horrible error occurred."); } Assert.That(errorCount == 1); } { IActivityMonitor m = new ActivityMonitor(); m.MinimalFilter = LogFilter.Off; // ... m.MinimalFilter = LogFilter.Debug; } { IActivityMonitor m = new ActivityMonitor(); m.MinimalFilter = LogFilter.Terse; using (m.SetMinimalFilter(LogFilter.Debug)) { Assert.That(m.ActualFilter == LogFilter.Debug); } Assert.That(m.ActualFilter == LogFilter.Terse, "Filter has been restored to previous value."); } { IActivityMonitor m = new ActivityMonitor(); m.MinimalFilter = LogFilter.Off; // ... using (m.OpenWarn().Send("Ouch...")) { Assert.That(m.ActualFilter == LogFilter.Off); m.MinimalFilter = LogFilter.Debug; // ... in debug filter ... } Assert.That(m.ActualFilter == LogFilter.Off, "Back to Off."); var strange = new LogFilter(LogLevelFilter.Fatal, LogLevelFilter.Trace); } }
static void Main(string[] args) { ActivityMonitor monitor = new ActivityMonitor(); monitor.ActivedTimeOut = 2000;// 2 秒钟超时 monitor.TimerInterval = 1000;//1秒钟检查一次 monitor.OnSleep += delegate { Console.WriteLine("无操作,等待中......"); }; monitor.OnActive += delegate { Console.WriteLine("已捕捉到输入"); }; monitor.Start(); Console.ReadLine(); }
public void ClientFilterPropagatesToMonitor() { var monitor = new ActivityMonitor( false ); var client = new ActivityMonitorConsoleClient(); monitor.Output.RegisterClient( client ); Assert.That( monitor.MinimalFilter, Is.EqualTo( LogFilter.Undefined ) ); client.Filter = LogFilter.Release; Assert.That( client.Filter, Is.EqualTo( LogFilter.Release ) ); Assert.That( monitor.ActualFilter, Is.EqualTo( LogFilter.Release ) ); }
public void TestArtificialCollision() { ActivityMonitor m = new ActivityMonitor( applyAutoConfigurations: false ); var detect = new DateCollision(); m.Output.RegisterClient( detect ); DateTimeStamp now = DateTimeStamp.UtcNow; m.UnfilteredLog( ActivityMonitor.Tags.Empty, LogLevel.Info, "This should clash!", now, null ); m.UnfilteredLog( ActivityMonitor.Tags.Empty, LogLevel.Info, "This should clash!", now, null ); m.UnfilteredLog( ActivityMonitor.Tags.Empty, LogLevel.Info, "This should clash!", new DateTimeStamp( now.TimeUtc.AddDays( -1 ) ), null ); m.UnfilteredOpenGroup( ActivityMonitor.Tags.Empty, LogLevel.Info, null, "This should clash!", now, null ); m.UnfilteredOpenGroup( ActivityMonitor.Tags.Empty, LogLevel.Info, null, "This should clash!", new DateTimeStamp( now.TimeUtc.AddTicks( -1 ) ), null ); m.CloseGroup( new DateTimeStamp( now.TimeUtc.AddTicks( -1 ) ) ); m.CloseGroup( now ); Assert.That( detect.NbClash, Is.EqualTo( 0 ) ); }
public void logging_multiple_lines() { TestHelper.LogsToConsole = true; var m = new ActivityMonitor( false ); m.MinimalFilter = LogFilter.Debug; StringBuilder b = new StringBuilder(); var client = new ActivityMonitorTextWriterClient( s => b.Append( s ) ); m.Output.RegisterClient( client ); using( TestHelper.ConsoleMonitor.SetMinimalFilter( LogFilter.Debug ) ) using( m.Output.CreateBridgeTo( TestHelper.ConsoleMonitor.Output.BridgeTarget ) ) { using( m.OpenInfo().Send( "IL1" + Environment.NewLine + "IL2" + Environment.NewLine + "IL3" ) ) { using( m.OpenTrace().Send( "TL1" + Environment.NewLine + "TL2" + Environment.NewLine + "TL3" ) ) { m.Warn().Send( "WL1" + Environment.NewLine + "WL2" + Environment.NewLine + "WL3" ); m.CloseGroup( new[] { new ActivityLogGroupConclusion("c1"), new ActivityLogGroupConclusion("c2"), new ActivityLogGroupConclusion("Multi"+Environment.NewLine+"Line"+Environment.NewLine), new ActivityLogGroupConclusion("Another"+Environment.NewLine+"Multi"+Environment.NewLine+"Line"+Environment.NewLine) } ); } } } string result = b.ToString(); Assert.That( result, Is.EqualTo( @"> Info: IL1 | IL2 | IL3 | > Trace: TL1 | | TL2 | | TL3 | | - Warn: WL1 | | WL2 | | WL3 | < c1 - c2 | < Multi | Line | < Another | Multi | Line ".NormalizeEOL() ) ); }
public void automatic_configuration_of_monitors_just_uses_ActivityMonitor_AutoConfiguration_delegate() { StupidStringClient c = new StupidStringClient(); ActivityMonitor.AutoConfiguration = null; ActivityMonitor.AutoConfiguration += m => m.Output.RegisterClient( c ); int i = 0; ActivityMonitor.AutoConfiguration += m => m.Trace().Send( "This monitors has been created at {0:O}, n°{1}", DateTime.UtcNow, ++i ); ActivityMonitor monitor1 = new ActivityMonitor(); ActivityMonitor monitor2 = new ActivityMonitor(); Assert.That( c.ToString(), Does.Contain( "This monitors has been created at" ) ); Assert.That( c.ToString(), Does.Contain( "n°1" ) ); Assert.That( c.ToString(), Does.Contain( "n°2" ) ); ActivityMonitor.AutoConfiguration = null; }
public void DependentToken_API_use() { var monitor = new ActivityMonitor(); monitor.Output.CreateBridgeTo( TestHelper.ConsoleMonitor.Output.BridgeTarget ); using( monitor.OpenTrace().Send( "Create token and dependent monitor." ) ) { // Creates the token. var token = monitor.DependentActivity().CreateToken(); // Creates a dependent monitor. using( var monitorDep = token.CreateDependentMonitor( m => m.Output.CreateBridgeTo( TestHelper.ConsoleMonitor.Output.BridgeTarget ) ) ) { monitor.Trace().Send( "Doing something..." ); // ... } } using( monitor.OpenTrace().Send( "Create token with delayed launch of the dependent activity." ) ) { // Creates the token. var token = monitor.DependentActivity().CreateToken( delayedLaunch: true ); // Signals the launch of the dependent activity. monitor.DependentActivity().Launch( token ); // Creates a dependent monitor. using( var monitorDep = token.CreateDependentMonitor( m => m.Output.CreateBridgeTo( TestHelper.ConsoleMonitor.Output.BridgeTarget ) ) ) { monitor.Trace().Send( "Doing something..." ); // ... } } using( monitor.OpenTrace().Send( "Starting a dependent activity on an existing monitor." ) ) { // Creates the token. var token = monitor.DependentActivity().CreateToken(); IActivityMonitor wMonitor = monitor; using( wMonitor.StartDependentActivity( token ) ) { wMonitor.Trace().Send( "Doing something..." ); // ... } } }
public void TestNaturalCollision() { ActivityMonitor m = new ActivityMonitor( applyAutoConfigurations: false ); var detect = new DateCollision(); m.Output.RegisterClient( detect ); for( int i = 0; i < 10; ++i ) { m.UnfilteredLog( ActivityMonitor.Tags.Empty, LogLevel.Info, "This should clash!", DateTimeStamp.UtcNow, null ); } for( int i = 0; i < 10; ++i ) { m.Trace().Send( "This should clash!" ); } for( int i = 0; i < 10; ++i ) { using( m.OpenTrace().Send( "This should clash!" ) ) { } } Assert.That( detect.NbClash, Is.EqualTo( 0 ) ); }
private static StupidStringClient.Entry[] LaunchAndRunDependentActivityWithTopic( ActivityMonitor m, string dependentTopic ) { StupidStringClient.Entry[] dependentLogs = null; m.DependentActivity().LaunchWithTopic( token => { dependentLogs = RunDependentActivity( token ); }, dependentTopic ); return dependentLogs; }
public void parsing_start_and_create_messages() { ActivityMonitor m = new ActivityMonitor( false ); StupidStringClient cLaunch = m.Output.RegisterClient( new StupidStringClient() ); StupidStringClient.Entry[] dependentLogs = null; string dependentTopic = "A topic 'with' quotes '-\"..." + Environment.NewLine + " and multi-line"; dependentLogs = LaunchAndRunDependentActivityWithTopic( m, dependentTopic ); string launchMessage = cLaunch.Entries[0].Text; string topicSetMessage = dependentLogs[0].Text; string startMessage = dependentLogs[1].Text; Assert.That( topicSetMessage, Is.EqualTo( ActivityMonitor.SetTopicPrefix + dependentTopic ) ); Assert.That( dependentLogs[2].Text, Is.EqualTo( "Hello!" ) ); Assert.That( launchMessage, Does.StartWith( "Launching dependent activity" ) ); bool launched; bool launchWithTopic; string launchDependentTopic; Assert.That( ActivityMonitor.DependentToken.TryParseLaunchOrCreateMessage( launchMessage, out launched, out launchWithTopic, out launchDependentTopic ) ); Assert.That( launched ); Assert.That( launchWithTopic ); Assert.That( launchDependentTopic, Is.EqualTo( dependentTopic ) ); Assert.That( startMessage, Does.StartWith( "Starting dependent activity" ) ); Guid id; DateTimeStamp time; Assert.That( ActivityMonitor.DependentToken.TryParseStartMessage( startMessage, out id, out time ) ); Assert.That( id, Is.EqualTo( ((IUniqueId)m).UniqueId ) ); Assert.That( time, Is.EqualTo( cLaunch.Entries[0].LogTime ) ); }
public void MultipleConclusions() { IActivityMonitor l = new ActivityMonitor(); using( l.Output.CreateBridgeTo( TestHelper.ConsoleMonitor.Output.BridgeTarget ) ) { l.Output.RegisterClient( new ActivityMonitorErrorCounter( true ) ); var log = l.Output.RegisterClient( new StupidStringClient() ); // No explicit close conclusion: Success! using( l.OpenTrace().Send( "G" ).ConcludeWith( () => "From Opener" ) ) { l.Error().Send( "Pouf" ); l.CloseGroup( new ObjectAsConclusion() ); } Assert.That( log.Writer.ToString(), Does.Contain( "Explicit User Conclusion, From Opener, 1 Error" ) ); } }
public void PathCatcherToStringPath() { var monitor = new ActivityMonitor(); ActivityMonitorPathCatcher p = monitor.Output.RegisterClient( new ActivityMonitorPathCatcher() ); using( monitor.OpenTrace().Send( "!T" ) ) using( monitor.OpenInfo().Send( "!I" ) ) using( monitor.OpenWarn().Send( "!W" ) ) using( monitor.OpenError().Send( "!E" ) ) using( monitor.OpenFatal().Send( "!F" ) ) { Assert.That( p.DynamicPath.ToStringPath(), Does.Contain( "!T" ).And.Contain( "!I" ).And.Contain( "!W" ).And.Contain( "!E" ).And.Contain( "!F" ) ); } var path = p.DynamicPath; path = null; Assert.That( path.ToStringPath(), Is.Empty ); }
public void registering_a_null_client_is_an_error() { IActivityMonitor monitor = new ActivityMonitor(); Assert.Throws<ArgumentNullException>( () => monitor.Output.RegisterClient( null ) ); Assert.Throws<ArgumentNullException>( () => monitor.Output.UnregisterClient( null ) ); }
public void parsing_dependent_token_and_start_and_create_messages_with_time_collision() { ActivityMonitor m = new ActivityMonitor( false ); m.Output.CreateBridgeTo( TestHelper.ConsoleMonitor.Output.BridgeTarget ); StupidStringClient cLaunch = m.Output.RegisterClient( new StupidStringClient() ); // Generates a token with time collision. int loopNeeded = 0; ActivityMonitor.DependentToken token; while( (token = m.DependentActivity().CreateTokenWithTopic( "Test..." )).CreationDate.Uniquifier == 0 ) ++loopNeeded; Assert.That( token.Topic, Is.EqualTo( "Test..." ) ); m.Trace().Send( "Generating time collision required {0} loops.", loopNeeded ); string launchMessage = cLaunch.Entries[loopNeeded].Text; { bool launched; bool launchWithTopic; string launchDependentTopic; Assert.That( ActivityMonitor.DependentToken.TryParseLaunchOrCreateMessage( launchMessage, out launched, out launchWithTopic, out launchDependentTopic ) ); Assert.That( !launched, "We used CreateToken." ); Assert.That( launchWithTopic ); Assert.That( launchDependentTopic, Is.EqualTo( "Test..." ) ); } string tokenToString = token.ToString(); { ActivityMonitor.DependentToken t2 = ActivityMonitor.DependentToken.Parse( tokenToString ); Assert.That( t2.OriginatorId, Is.EqualTo( ((IUniqueId)m).UniqueId ) ); Assert.That( t2.CreationDate, Is.EqualTo( cLaunch.Entries[loopNeeded].LogTime ) ); Assert.That( t2.Topic, Is.EqualTo( "Test..." ) ); } StupidStringClient.Entry[] logs = RunDependentActivity( token ); { Assert.That( logs[0].Text, Is.EqualTo( ActivityMonitor.SetTopicPrefix + "Test..." ) ); Guid id; DateTimeStamp time; Assert.That( ActivityMonitor.DependentToken.TryParseStartMessage( logs[1].Text, out id, out time ) ); Assert.That( id, Is.EqualTo( ((IUniqueId)m).UniqueId ) ); Assert.That( time, Is.EqualTo( cLaunch.Entries[loopNeeded].LogTime ) ); } }
public void SimpleCollectorTest() { IActivityMonitor d = new ActivityMonitor(); var c = new ActivityMonitorSimpleCollector(); d.Output.RegisterClient( c ); d.Warn().Send( "1" ); d.Error().Send( "2" ); d.Fatal().Send( "3" ); d.Trace().Send( "4" ); d.Info().Send( "5" ); d.Warn().Send( "6" ); Assert.That( String.Join( ",", c.Entries.Select( e => e.Text ) ), Is.EqualTo( "2,3" ) ); c.MinimalFilter = LogLevelFilter.Fatal; Assert.That( String.Join( ",", c.Entries.Select( e => e.Text ) ), Is.EqualTo( "3" ) ); c.MinimalFilter = LogLevelFilter.Off; Assert.That( String.Join( ",", c.Entries.Select( e => e.Text ) ), Is.EqualTo( "" ) ); c.MinimalFilter = LogLevelFilter.Warn; using( d.OpenWarn().Send( "1" ) ) { d.Error().Send( "2" ); using( d.OpenFatal().Send( "3" ) ) { d.Trace().Send( "4" ); d.Info().Send( "5" ); } } d.Warn().Send( "6" ); Assert.That( String.Join( ",", c.Entries.Select( e => e.Text ) ), Is.EqualTo( "1,2,3,6" ) ); c.MinimalFilter = LogLevelFilter.Fatal; Assert.That( String.Join( ",", c.Entries.Select( e => e.Text ) ), Is.EqualTo( "3" ) ); }
public void buggy_clients_are_removed_from_Output() { ActivityMonitor.AutoConfiguration = null; ActivityMonitor monitor = new ActivityMonitor(); int clientCount = 0; if( TestHelper.LogsToConsole ) { ++clientCount; monitor.Output.RegisterClient( new ActivityMonitorConsoleClient() ); } ++clientCount; WaitActivityMonitorClient client = monitor.Output.RegisterClient( new WaitActivityMonitorClient() ); Assert.That( monitor.Output.Clients.Count, Is.EqualTo( clientCount ) ); try { Task.Factory.StartNew( () => { monitor.Info().Send( "Test must work in task" ); } ); client.WaitForOnUnfilteredLog(); Assert.That( () => monitor.Info().Send( "Test must fail" ), Throws.TypeOf( typeof( InvalidOperationException ) ). And.Message.EqualTo( Impl.ActivityMonitorResources.ActivityMonitorConcurrentThreadAccess ) ); Assert.That( monitor.Output.Clients.Count, Is.EqualTo( clientCount ), "Still " + clientCount + ": Concurrent call: not the fault of the Client." ); } finally { client.Free(); } Thread.Sleep( 50 ); monitor.Info().Send( "Test must work after task" ); ++clientCount; monitor.Output.RegisterClient( new ActionActivityMonitorClient( () => { Assert.That( () => monitor.Info().Send( "Test must fail reentrant client" ), Throws.TypeOf( typeof( InvalidOperationException ) ). And.Message.EqualTo( Impl.ActivityMonitorResources.ActivityMonitorReentrancyError ) ); } ) ); monitor.Info().Send( "Test must work after reentrant client" ); Assert.That( monitor.Output.Clients.Count, Is.EqualTo( clientCount ), "The RegisterClient action above is ok: it checks that it triggered a reentrant call." ); ++clientCount; monitor.Output.RegisterClient( new ActionActivityMonitorClient( () => { monitor.Info().Send( "Test must fail reentrant client" ); } ) ); monitor.Info().Send( "Test must work after reentrant client" ); Assert.That( monitor.Output.Clients.Count, Is.EqualTo( clientCount - 1 ), "The BUGGY RegisterClient action above is NOT ok: it triggers a reentrant call exception => We have removed it." ); }
public void FilteredTextWriterTests() { StringBuilder sb = new StringBuilder(); IActivityMonitor d = new ActivityMonitor(); d.SetMinimalFilter( LogFilter.Debug ); var c = new ActivityMonitorTextWriterClient(s => sb.Append(s), LogFilter.Release); d.Output.RegisterClient( c ); d.Trace().Send( "NO SHOW" ); d.Trace().Send( "NO SHOW" ); using( d.OpenTrace().Send( "NO SHOW" ) ) { d.Info().Send( "NO SHOW" ); d.Info().Send( "NO SHOW" ); } d.Error().Send( "Error line at root" ); using( d.OpenInfo().Send( "NO SHOW" ) ) { d.Warn().Send( "NO SHOW" ); d.Error().Send( "Send error line inside group" ); using( d.OpenError().Send( "Open error group" ) ) { d.Error().Send( "Send error line inside sub group" ); } } Assert.That( sb.ToString(), Does.Not.Contain( "NO SHOW" ) ); Assert.That( sb.ToString(), Does.Contain( "Error line at root" ) ); Assert.That( sb.ToString(), Does.Contain( "Send error line inside group" ) ); Assert.That( sb.ToString(), Does.Contain( "Open error group" ) ); Assert.That( sb.ToString(), Does.Contain( "Send error line inside sub group" ) ); }
/// <summary> /// Initialize SensorCore /// </summary> /// <param name="rec">Recording instance</param> /// <param name="type">Sense type</param> /// <returns>Asynchronous task</returns> private async Task HandleSensorActivity(Recording rec, SenseType type) { if (rec.Recorder == null) { if (await CallSensorcoreApiAsync(async () => { switch (type) { case SenseType.Activity: _aMonitor = await ActivityMonitor.GetDefaultAsync(); break; case SenseType.Places: _pMonitor = await PlaceMonitor.GetDefaultAsync(); break; case SenseType.Route: _rTracker = await TrackPointMonitor.GetDefaultAsync(); break; case SenseType.Steps: _sCounter = await StepCounter.GetDefaultAsync(); break; } })) { Debug.WriteLine("Recorder initialized."); switch (type) { case SenseType.Activity: rec.Recorder = new SenseRecorder(_aMonitor); break; case SenseType.Places: rec.Recorder = new SenseRecorder(_pMonitor); break; case SenseType.Route: rec.Recorder = new SenseRecorder(_rTracker); break; case SenseType.Steps: rec.Recorder = new SenseRecorder(_sCounter); break; } } else return; } if (rec.Recorder == null) return; else { await ActivateAsync(); switch (rec.ItemState) { case Status.Recording: await rec.Recorder.StartAsync(); break; case Status.Stopped: await rec.Recorder.StopAsync(); break; case Status.Empty: await rec.Recorder.GetRecording().SaveAsync(); break; } } }
public void OnError_fires_synchronously() { var m = new ActivityMonitor( false ); bool hasError = false; using( m.OnError( () => hasError = true ) ) using( m.OpenInfo().Send( "Handling StObj objects." ) ) { m.Fatal().Send( "Oops!" ); Assert.That( hasError ); hasError = false; m.OpenFatal().Send( "Oops! (Group)" ).Dispose(); Assert.That( hasError ); hasError = false; } hasError = false; m.Fatal().Send( "Oops!" ); Assert.That( hasError, Is.False ); bool hasFatal = false; using( m.OnError( () => hasFatal = true, () => hasError = true ) ) { m.Fatal().Send( "Big Oops!" ); Assert.That( hasFatal && !hasError ); m.Error().Send( "Oops!" ); Assert.That( hasFatal && hasError ); hasFatal = hasError = false; m.OpenError().Send( "Oops! (Group)" ).Dispose(); Assert.That( !hasFatal && hasError ); m.OpenFatal().Send( "Oops! (Group)" ).Dispose(); Assert.That( hasFatal && hasError ); hasFatal = hasError = false; } m.Fatal().Send( "Oops!" ); Assert.That( hasFatal || hasError, Is.False ); }
private static StupidStringClient.Entry[] RunDependentActivity( ActivityMonitor.DependentToken token ) { string depMonitorTopic = null; StupidStringClient.Entry[] dependentLogs = null; var task = Task.Factory.StartNew( t => { StupidStringClient cStarted = new StupidStringClient(); using( var depMonitor = token.CreateDependentMonitor( mD => mD.Output.RegisterClient( cStarted ) ) ) { depMonitorTopic = depMonitor.Topic; depMonitor.Trace().Send( "Hello!" ); } dependentLogs = cStarted.Entries.ToArray(); }, token ); task.Wait(); Assert.That( depMonitorTopic, Is.EqualTo( token.Topic ) ); return dependentLogs; }
public void AsyncSetMininimalFilter() { ActivityMonitor m = new ActivityMonitor( false ); var tester = m.Output.RegisterClient( new ActivityMonitorClientTester() ); Assert.That( m.ActualFilter, Is.EqualTo( LogFilter.Undefined ) ); tester.AsyncSetMinimalFilterBlock( LogFilter.Monitor ); Assert.That( m.ActualFilter, Is.EqualTo( LogFilter.Monitor ) ); }
public void simple_reentrancy_detection() { IActivityMonitor monitor = new ActivityMonitor(); using( monitor.Output.CreateBridgeTo( TestHelper.ConsoleMonitor.Output.BridgeTarget ) ) { int clientCount = monitor.Output.Clients.Count; Assert.That( monitor.Output.Clients.Count, Is.EqualTo( clientCount ) ); BuggyActivityMonitorClient client = new BuggyActivityMonitorClient( monitor ); monitor.Output.RegisterClient( client ); Assert.That( monitor.Output.Clients.Count, Is.EqualTo( clientCount + 1 ) ); monitor.Info().Send( "Test" ); Assert.That( monitor.Output.Clients.Count, Is.EqualTo( clientCount ) ); Assert.DoesNotThrow( () => monitor.Info().Send( "Test" ) ); } }
/// <summary> /// A simple constructor that initializes the object with its dependencies. /// </summary> /// <param name="p_amnActivityMonitor">The activity manager to use to manage the monitored activities.</param> /// <param name="p_setSettings">The application and user settings.</param> public ActivityMonitorVM(ActivityMonitor p_amnActivityMonitor, ISettings p_setSettings) { ActivityMonitor = p_amnActivityMonitor; Settings = p_setSettings; CancelTaskCommand = new Command<IBackgroundTask>("Cancel", "Cancels the selected activity.", CancelTask); RemoveTaskCommand = new Command<IBackgroundTask>("Remove", "Removes the selected activity.", RemoveTask); PauseTaskCommand = new Command<IBackgroundTask>("Pause", "Pauses the selected activity.", PauseTask); ResumeTaskCommand = new Command<IBackgroundTask>("Resume", "Resumes the selected activity.", ResumeTask); }
public void PathCatcherTests() { var monitor = new ActivityMonitor( applyAutoConfigurations: false ); using( monitor.Output.CreateBridgeTo( TestHelper.ConsoleMonitor.Output.BridgeTarget ) ) { ActivityMonitorPathCatcher p = new ActivityMonitorPathCatcher(); monitor.Output.RegisterClient( p ); monitor.Trace().Send( "Trace n°1" ); Assert.That( p.DynamicPath.Select( e => e.MaskedLevel.ToString() + '|' + e.Text ).Single(), Is.EqualTo( "Trace|Trace n°1" ) ); Assert.That( p.LastErrorPath, Is.Null ); Assert.That( p.LastWarnOrErrorPath, Is.Null ); monitor.Trace().Send( "Trace n°2" ); Assert.That( p.DynamicPath.Select( e => e.MaskedLevel.ToString() + '|' + e.Text ).Single(), Is.EqualTo( "Trace|Trace n°2" ) ); Assert.That( p.LastErrorPath, Is.Null ); Assert.That( p.LastWarnOrErrorPath, Is.Null ); monitor.Warn().Send( "W1" ); Assert.That( p.DynamicPath.Select( e => e.MaskedLevel.ToString() + '|' + e.Text ).Single(), Is.EqualTo( "Warn|W1" ) ); Assert.That( p.LastErrorPath, Is.Null ); Assert.That( p.LastWarnOrErrorPath.Select( e => e.MaskedLevel.ToString() + '|' + e.Text ).Single(), Is.EqualTo( "Warn|W1" ) ); monitor.Error().Send( "E2" ); monitor.Warn().Send( "W1bis" ); Assert.That( p.DynamicPath.Select( e => e.MaskedLevel.ToString() + '|' + e.Text ).Single(), Is.EqualTo( "Warn|W1bis" ) ); Assert.That( p.LastErrorPath.Select( e => e.MaskedLevel.ToString() + '|' + e.Text ).Single(), Is.EqualTo( "Error|E2" ) ); Assert.That( p.LastWarnOrErrorPath.Select( e => e.MaskedLevel.ToString() + '|' + e.Text ).Single(), Is.EqualTo( "Warn|W1bis" ) ); p.ClearLastWarnPath(); Assert.That( p.LastErrorPath, Is.Not.Null ); Assert.That( p.LastWarnOrErrorPath, Is.Null ); p.ClearLastErrorPath(); Assert.That( p.LastErrorPath, Is.Null ); using( monitor.OpenTrace().Send( "G1" ) ) { using( monitor.OpenInfo().Send( "G2" ) ) { Assert.That( String.Join( ">", p.DynamicPath.Select( e => e.Text ) ), Is.EqualTo( "G1>G2" ) ); Assert.That( p.LastErrorPath, Is.Null ); using( monitor.OpenTrace().Send( "G3" ) ) { using( monitor.OpenInfo().Send( "G4" ) ) { monitor.Warn().Send( "W1" ); Assert.That( String.Join( ">", p.DynamicPath.Select( e => e.Text ) ), Is.EqualTo( "G1>G2>G3>G4>W1" ) ); monitor.Info().Send( new Exception( "An exception logged as an Info.", new Exception( "With an inner exception. Since these exceptions have not been thrown, there is no stack trace." ) ), "Test With an exception: a Group is created. Since the text of the log is given, the Exception.Message must be displayed explicitely." ); Assert.That( String.Join( ">", p.DynamicPath.Select( e => e.Text ) ), Is.EqualTo( "G1>G2>G3>G4>Test With an exception: a Group is created. Since the text of the log is given, the Exception.Message must be displayed explicitely." ) ); try { try { try { try { throw new Exception( "Deepest exception." ); } catch( Exception ex ) { throw new Exception( "Yet another inner with inner Exception.", ex ); } } catch( Exception ex ) { throw new Exception( "Exception with inner Exception.", ex ); } } catch( Exception ex ) { throw new Exception( "Log without log text: the text of the entry is the Exception.Message.", ex ); } } catch( Exception ex ) { monitor.Trace().Send( ex ); Assert.That( p.DynamicPath.ToStringPath().Length > 0 ); } Assert.That( p.LastErrorPath, Is.Null ); Assert.That( String.Join( ">", p.LastWarnOrErrorPath.Select( e => e.MaskedLevel.ToString() + '|' + e.Text ) ), Is.EqualTo( "Trace|G1>Info|G2>Trace|G3>Info|G4>Warn|W1" ) ); } Assert.That( String.Join( ">", p.DynamicPath.Select( e => e.ToString() ) ), Is.EqualTo( "G1>G2>G3>G4" ) ); Assert.That( p.LastErrorPath, Is.Null ); Assert.That( String.Join( ">", p.LastWarnOrErrorPath.Select( e => e.MaskedLevel.ToString() + '|' + e.Text ) ), Is.EqualTo( "Trace|G1>Info|G2>Trace|G3>Info|G4>Warn|W1" ) ); monitor.Error().Send( "E1" ); Assert.That( String.Join( ">", p.DynamicPath.Select( e => e.Text ) ), Is.EqualTo( "G1>G2>G3>E1" ) ); Assert.That( String.Join( ">", p.LastErrorPath.Select( e => e.MaskedLevel.ToString() + '|' + e.Text ) ), Is.EqualTo( "Trace|G1>Info|G2>Trace|G3>Error|E1" ) ); Assert.That( String.Join( ">", p.LastWarnOrErrorPath.Select( e => e.MaskedLevel.ToString() + '|' + e.Text ) ), Is.EqualTo( "Trace|G1>Info|G2>Trace|G3>Error|E1" ) ); } Assert.That( String.Join( ">", p.DynamicPath.Select( e => e.Text ) ), Is.EqualTo( "G1>G2>G3" ) ); Assert.That( String.Join( ">", p.LastErrorPath.Select( e => e.MaskedLevel.ToString() + '|' + e.Text ) ), Is.EqualTo( "Trace|G1>Info|G2>Trace|G3>Error|E1" ) ); Assert.That( String.Join( ">", p.LastWarnOrErrorPath.Select( e => e.MaskedLevel.ToString() + '|' + e.Text ) ), Is.EqualTo( "Trace|G1>Info|G2>Trace|G3>Error|E1" ) ); } Assert.That( String.Join( ">", p.DynamicPath.Select( e => e.Text ) ), Is.EqualTo( "G1>G2" ) ); using( monitor.OpenTrace().Send( "G2Bis" ) ) { Assert.That( String.Join( ">", p.DynamicPath.Select( e => e.Text ) ), Is.EqualTo( "G1>G2Bis" ) ); Assert.That( String.Join( ">", p.LastErrorPath.Select( e => e.MaskedLevel.ToString() + '|' + e.Text ) ), Is.EqualTo( "Trace|G1>Info|G2>Trace|G3>Error|E1" ) ); Assert.That( String.Join( ">", p.LastWarnOrErrorPath.Select( e => e.MaskedLevel.ToString() + '|' + e.Text ) ), Is.EqualTo( "Trace|G1>Info|G2>Trace|G3>Error|E1" ) ); monitor.Warn().Send( "W2" ); Assert.That( String.Join( ">", p.DynamicPath.Select( e => e.Text ) ), Is.EqualTo( "G1>G2Bis>W2" ) ); Assert.That( String.Join( ">", p.LastWarnOrErrorPath.Select( e => e.MaskedLevel.ToString() + '|' + e.Text ) ), Is.EqualTo( "Trace|G1>Trace|G2Bis>Warn|W2" ) ); Assert.That( String.Join( ">", p.LastErrorPath.Select( e => e.MaskedLevel.ToString() + '|' + e.Text ) ), Is.EqualTo( "Trace|G1>Info|G2>Trace|G3>Error|E1" ) ); } monitor.Fatal().Send( "F1" ); Assert.That( String.Join( ">", p.DynamicPath.Select( e => e.Text ) ), Is.EqualTo( "G1>F1" ) ); Assert.That( String.Join( ">", p.LastWarnOrErrorPath.Select( e => e.MaskedLevel.ToString() + '|' + e.Text ) ), Is.EqualTo( "Trace|G1>Fatal|F1" ) ); Assert.That( String.Join( ">", p.LastErrorPath.Select( e => e.MaskedLevel.ToString() + '|' + e.Text ) ), Is.EqualTo( "Trace|G1>Fatal|F1" ) ); } // Extraneous closing are ignored. monitor.CloseGroup( null ); monitor.Warn().Send( "W3" ); Assert.That( String.Join( ">", p.DynamicPath.Select( e => e.Text ) ), Is.EqualTo( "W3" ) ); Assert.That( String.Join( ">", p.LastWarnOrErrorPath.Select( e => e.MaskedLevel.ToString() + '|' + e.Text ) ), Is.EqualTo( "Warn|W3" ) ); Assert.That( String.Join( ">", p.LastErrorPath.Select( e => e.MaskedLevel.ToString() + '|' + e.Text ) ), Is.EqualTo( "Trace|G1>Fatal|F1" ) ); // Extraneous closing are ignored. monitor.CloseGroup( null ); monitor.Warn().Send( "W4" ); Assert.That( String.Join( ">", p.DynamicPath.Select( e => e.Text ) ), Is.EqualTo( "W4" ) ); Assert.That( String.Join( ">", p.LastWarnOrErrorPath.Select( e => e.MaskedLevel.ToString() + '|' + e.Text ) ), Is.EqualTo( "Warn|W4" ) ); Assert.That( String.Join( ">", p.LastErrorPath.Select( e => e.MaskedLevel.ToString() + '|' + e.Text ) ), Is.EqualTo( "Trace|G1>Fatal|F1" ) ); p.ClearLastWarnPath( true ); Assert.That( p.LastErrorPath, Is.Null ); Assert.That( p.LastWarnOrErrorPath, Is.Null ); } }
public void Overloads() { Exception ex = new Exception( "EXCEPTION" ); string fmt0 = "fmt", fmt1 = "fmt{0}", fmt2 = "fmt{0}{1}", fmt3 = "fmt{0}{1}{2}", fmt4 = "fmt{0}{1}{2}{3}", fmt5 = "fmt{0}{1}{2}{3}{4}", fmt6 = "fmt{0}{1}{2}{3}{4}{5}"; string p1 = "p1", p2 = "p2", p3 = "p3", p4 = "p4", p5 = "p5", p6 = "p6"; Func<string> onDemandText = () => "onDemand"; Func<int,string> onDemandTextP1 = ( i ) => "onDemand" + i.ToString(); Func<int,int,string> onDemandTextP2 = ( i, j ) => "onDemand" + i.ToString() + j.ToString(); IActivityMonitor d = new ActivityMonitor(); var collector = new ActivityMonitorSimpleCollector() { MinimalFilter = LogLevelFilter.Trace, Capacity = 1 }; d.Output.RegisterClients( collector, new CheckAlwaysFilteredClient() ); // d.UnfilteredLog( ActivityMonitor.Tags.Empty, LogLevel.Trace, "CheckAlwaysFilteredClient works", DateTime.UtcNow, null ); d.Trace().Send( fmt0 ); Assert.That( collector.Entries.Last().Text, Is.EqualTo( "fmt" ) ); d.Trace().Send( fmt1, p1 ); Assert.That( collector.Entries.Last().Text, Is.EqualTo( "fmtp1" ) ); Assert.Throws<ArgumentException>( () => d.Trace().Send( fmt1, ex ) ); d.Trace().Send( onDemandText ); Assert.That( collector.Entries.Last().Text, Is.EqualTo( "onDemand" ) ); d.Trace().Send( onDemandTextP1, 1 ); Assert.That( collector.Entries.Last().Text, Is.EqualTo( "onDemand1" ) ); d.Trace().Send( onDemandTextP2, 1, 2 ); Assert.That( collector.Entries.Last().Text, Is.EqualTo( "onDemand12" ) ); d.Trace().Send( fmt2, p1, p2 ); Assert.That( collector.Entries.Last().Text, Is.EqualTo( "fmtp1p2" ) ); d.Trace().Send( fmt3, p1, p2, p3 ); Assert.That( collector.Entries.Last().Text, Is.EqualTo( "fmtp1p2p3" ) ); d.Trace().Send( fmt4, p1, p2, p3, p4 ); Assert.That( collector.Entries.Last().Text, Is.EqualTo( "fmtp1p2p3p4" ) ); d.Trace().Send( fmt5, p1, p2, p3, p4, p5 ); Assert.That( collector.Entries.Last().Text, Is.EqualTo( "fmtp1p2p3p4p5" ) ); d.Trace().Send( fmt6, p1, p2, p3, p4, p5, p6 ); Assert.That( collector.Entries.Last().Text, Is.EqualTo( "fmtp1p2p3p4p5p6" ) ); d.Info().Send( fmt0 ); Assert.That( collector.Entries.Last().Text, Is.EqualTo( "fmt" ) ); d.Info().Send( fmt1, p1 ); Assert.That( collector.Entries.Last().Text, Is.EqualTo( "fmtp1" ) ); Assert.Throws<ArgumentException>( () => d.Info().Send( fmt1, ex ) ); d.Info().Send( onDemandText ); Assert.That( collector.Entries.Last().Text, Is.EqualTo( "onDemand" ) ); d.Info().Send( onDemandTextP1, 1 ); Assert.That( collector.Entries.Last().Text, Is.EqualTo( "onDemand1" ) ); d.Info().Send( onDemandTextP2, 1, 2 ); Assert.That( collector.Entries.Last().Text, Is.EqualTo( "onDemand12" ) ); d.Info().Send( fmt2, p1, p2 ); Assert.That( collector.Entries.Last().Text, Is.EqualTo( "fmtp1p2" ) ); d.Info().Send( fmt3, p1, p2, p3 ); Assert.That( collector.Entries.Last().Text, Is.EqualTo( "fmtp1p2p3" ) ); d.Info().Send( fmt4, p1, p2, p3, p4 ); Assert.That( collector.Entries.Last().Text, Is.EqualTo( "fmtp1p2p3p4" ) ); d.Info().Send( fmt5, p1, p2, p3, p4, p5 ); Assert.That( collector.Entries.Last().Text, Is.EqualTo( "fmtp1p2p3p4p5" ) ); d.Info().Send( fmt6, p1, p2, p3, p4, p5, p6 ); Assert.That( collector.Entries.Last().Text, Is.EqualTo( "fmtp1p2p3p4p5p6" ) ); d.Warn().Send( fmt0 ); Assert.That( collector.Entries.Last().Text, Is.EqualTo( "fmt" ) ); d.Warn().Send( fmt1, p1 ); Assert.That( collector.Entries.Last().Text, Is.EqualTo( "fmtp1" ) ); Assert.Throws<ArgumentException>( () => d.Warn().Send( fmt1, ex ) ); d.Warn().Send( onDemandText ); Assert.That( collector.Entries.Last().Text, Is.EqualTo( "onDemand" ) ); d.Warn().Send( onDemandTextP1, 1 ); Assert.That( collector.Entries.Last().Text, Is.EqualTo( "onDemand1" ) ); d.Warn().Send( onDemandTextP2, 1, 2 ); Assert.That( collector.Entries.Last().Text, Is.EqualTo( "onDemand12" ) ); d.Warn().Send( fmt2, p1, p2 ); Assert.That( collector.Entries.Last().Text, Is.EqualTo( "fmtp1p2" ) ); d.Warn().Send( fmt3, p1, p2, p3 ); Assert.That( collector.Entries.Last().Text, Is.EqualTo( "fmtp1p2p3" ) ); d.Warn().Send( fmt4, p1, p2, p3, p4 ); Assert.That( collector.Entries.Last().Text, Is.EqualTo( "fmtp1p2p3p4" ) ); d.Warn().Send( fmt5, p1, p2, p3, p4, p5 ); Assert.That( collector.Entries.Last().Text, Is.EqualTo( "fmtp1p2p3p4p5" ) ); d.Warn().Send( fmt6, p1, p2, p3, p4, p5, p6 ); Assert.That( collector.Entries.Last().Text, Is.EqualTo( "fmtp1p2p3p4p5p6" ) ); d.Error().Send( fmt0 ); Assert.That( collector.Entries.Last().Text, Is.EqualTo( "fmt" ) ); d.Error().Send( fmt1, p1 ); Assert.That( collector.Entries.Last().Text, Is.EqualTo( "fmtp1" ) ); Assert.Throws<ArgumentException>( () => d.Error().Send( fmt1, ex ) ); d.Error().Send( onDemandText ); Assert.That( collector.Entries.Last().Text, Is.EqualTo( "onDemand" ) ); d.Error().Send( onDemandTextP1, 1 ); Assert.That( collector.Entries.Last().Text, Is.EqualTo( "onDemand1" ) ); d.Error().Send( onDemandTextP2, 1, 2 ); Assert.That( collector.Entries.Last().Text, Is.EqualTo( "onDemand12" ) ); d.Error().Send( fmt2, p1, p2 ); Assert.That( collector.Entries.Last().Text, Is.EqualTo( "fmtp1p2" ) ); d.Error().Send( fmt3, p1, p2, p3 ); Assert.That( collector.Entries.Last().Text, Is.EqualTo( "fmtp1p2p3" ) ); d.Error().Send( fmt4, p1, p2, p3, p4 ); Assert.That( collector.Entries.Last().Text, Is.EqualTo( "fmtp1p2p3p4" ) ); d.Error().Send( fmt5, p1, p2, p3, p4, p5 ); Assert.That( collector.Entries.Last().Text, Is.EqualTo( "fmtp1p2p3p4p5" ) ); d.Error().Send( fmt6, p1, p2, p3, p4, p5, p6 ); Assert.That( collector.Entries.Last().Text, Is.EqualTo( "fmtp1p2p3p4p5p6" ) ); d.Fatal().Send( fmt0 ); Assert.That( collector.Entries.Last().Text, Is.EqualTo( "fmt" ) ); d.Fatal().Send( fmt1, p1 ); Assert.That( collector.Entries.Last().Text, Is.EqualTo( "fmtp1" ) ); Assert.Throws<ArgumentException>( () => d.Fatal().Send( fmt1, ex ) ); d.Fatal().Send( onDemandText ); Assert.That( collector.Entries.Last().Text, Is.EqualTo( "onDemand" ) ); d.Fatal().Send( onDemandTextP1, 1 ); Assert.That( collector.Entries.Last().Text, Is.EqualTo( "onDemand1" ) ); d.Fatal().Send( onDemandTextP2, 1, 2 ); Assert.That( collector.Entries.Last().Text, Is.EqualTo( "onDemand12" ) ); d.Fatal().Send( fmt2, p1, p2 ); Assert.That( collector.Entries.Last().Text, Is.EqualTo( "fmtp1p2" ) ); d.Fatal().Send( fmt3, p1, p2, p3 ); Assert.That( collector.Entries.Last().Text, Is.EqualTo( "fmtp1p2p3" ) ); d.Fatal().Send( fmt4, p1, p2, p3, p4 ); Assert.That( collector.Entries.Last().Text, Is.EqualTo( "fmtp1p2p3p4" ) ); d.Fatal().Send( fmt5, p1, p2, p3, p4, p5 ); Assert.That( collector.Entries.Last().Text, Is.EqualTo( "fmtp1p2p3p4p5" ) ); d.Fatal().Send( fmt6, p1, p2, p3, p4, p5, p6 ); Assert.That( collector.Entries.Last().Text, Is.EqualTo( "fmtp1p2p3p4p5p6" ) ); d.OpenTrace().Send( fmt0 ); Assert.That( collector.Entries.Last().Text, Is.EqualTo( "fmt" ) ); d.OpenTrace().Send( fmt1, p1 ); Assert.That( collector.Entries.Last().Text, Is.EqualTo( "fmtp1" ) ); d.OpenTrace().Send( fmt2, p1, p2 ); Assert.That( collector.Entries.Last().Text, Is.EqualTo( "fmtp1p2" ) ); d.OpenTrace().Send( fmt3, p1, p2, p3 ); Assert.That( collector.Entries.Last().Text, Is.EqualTo( "fmtp1p2p3" ) ); d.OpenTrace().Send( fmt4, p1, p2, p3, p4 ); Assert.That( collector.Entries.Last().Text, Is.EqualTo( "fmtp1p2p3p4" ) ); d.OpenTrace().Send( fmt5, p1, p2, p3, p4, p5 ); Assert.That( collector.Entries.Last().Text, Is.EqualTo( "fmtp1p2p3p4p5" ) ); d.OpenTrace().Send( fmt6, p1, p2, p3, p4, p5, p6 ); Assert.That( collector.Entries.Last().Text, Is.EqualTo( "fmtp1p2p3p4p5p6" ) ); d.Trace().Send( ex ); Assert.That( collector.Entries.Last().Text, Is.EqualTo( "EXCEPTION" ) ); Assert.That( collector.Entries.Last().Exception, Is.SameAs( ex ) ); d.Trace().Send( ex, fmt0 ); Assert.That( collector.Entries.Last().Text, Is.EqualTo( "fmt" ) ); Assert.That( collector.Entries.Last().Exception, Is.SameAs( ex ) ); d.Trace().Send( ex, fmt1, p1 ); Assert.That( collector.Entries.Last().Text, Is.EqualTo( "fmtp1" ) ); Assert.That( collector.Entries.Last().Exception, Is.SameAs( ex ) ); d.Trace().Send( ex, fmt2, p1, p2 ); Assert.That( collector.Entries.Last().Text, Is.EqualTo( "fmtp1p2" ) ); Assert.That( collector.Entries.Last().Exception, Is.SameAs( ex ) ); d.Trace().Send( ex, fmt3, p1, p2, p3 ); Assert.That( collector.Entries.Last().Text, Is.EqualTo( "fmtp1p2p3" ) ); Assert.That( collector.Entries.Last().Exception, Is.SameAs( ex ) ); d.Trace().Send( ex, fmt4, p1, p2, p3, p4 ); Assert.That( collector.Entries.Last().Text, Is.EqualTo( "fmtp1p2p3p4" ) ); Assert.That( collector.Entries.Last().Exception, Is.SameAs( ex ) ); d.Trace().Send( ex, fmt5, p1, p2, p3, p4, p5 ); Assert.That( collector.Entries.Last().Text, Is.EqualTo( "fmtp1p2p3p4p5" ) ); Assert.That( collector.Entries.Last().Exception, Is.SameAs( ex ) ); d.Trace().Send( ex, fmt6, p1, p2, p3, p4, p5, p6 ); Assert.That( collector.Entries.Last().Text, Is.EqualTo( "fmtp1p2p3p4p5p6" ) ); Assert.That( collector.Entries.Last().Exception, Is.SameAs( ex ) ); d.Info().Send( ex ); Assert.That( collector.Entries.Last().Text, Is.EqualTo( "EXCEPTION" ) ); Assert.That( collector.Entries.Last().Exception, Is.SameAs( ex ) ); d.Info().Send( ex, fmt0 ); Assert.That( collector.Entries.Last().Text, Is.EqualTo( "fmt" ) ); Assert.That( collector.Entries.Last().Exception, Is.SameAs( ex ) ); d.Info().Send( ex, fmt1, p1 ); Assert.That( collector.Entries.Last().Text, Is.EqualTo( "fmtp1" ) ); Assert.That( collector.Entries.Last().Exception, Is.SameAs( ex ) ); d.Info().Send( ex, fmt2, p1, p2 ); Assert.That( collector.Entries.Last().Text, Is.EqualTo( "fmtp1p2" ) ); Assert.That( collector.Entries.Last().Exception, Is.SameAs( ex ) ); d.Info().Send( ex, fmt3, p1, p2, p3 ); Assert.That( collector.Entries.Last().Text, Is.EqualTo( "fmtp1p2p3" ) ); Assert.That( collector.Entries.Last().Exception, Is.SameAs( ex ) ); d.Info().Send( ex, fmt4, p1, p2, p3, p4 ); Assert.That( collector.Entries.Last().Text, Is.EqualTo( "fmtp1p2p3p4" ) ); Assert.That( collector.Entries.Last().Exception, Is.SameAs( ex ) ); d.Info().Send( ex, fmt5, p1, p2, p3, p4, p5 ); Assert.That( collector.Entries.Last().Text, Is.EqualTo( "fmtp1p2p3p4p5" ) ); Assert.That( collector.Entries.Last().Exception, Is.SameAs( ex ) ); d.Info().Send( ex, fmt6, p1, p2, p3, p4, p5, p6 ); Assert.That( collector.Entries.Last().Text, Is.EqualTo( "fmtp1p2p3p4p5p6" ) ); Assert.That( collector.Entries.Last().Exception, Is.SameAs( ex ) ); d.Warn().Send( ex ); Assert.That( collector.Entries.Last().Text, Is.EqualTo( "EXCEPTION" ) ); Assert.That( collector.Entries.Last().Exception, Is.SameAs( ex ) ); d.Warn().Send( ex, fmt0 ); Assert.That( collector.Entries.Last().Text, Is.EqualTo( "fmt" ) ); Assert.That( collector.Entries.Last().Exception, Is.SameAs( ex ) ); d.Warn().Send( ex, fmt1, p1 ); Assert.That( collector.Entries.Last().Text, Is.EqualTo( "fmtp1" ) ); Assert.That( collector.Entries.Last().Exception, Is.SameAs( ex ) ); d.Warn().Send( ex, fmt2, p1, p2 ); Assert.That( collector.Entries.Last().Text, Is.EqualTo( "fmtp1p2" ) ); Assert.That( collector.Entries.Last().Exception, Is.SameAs( ex ) ); d.Warn().Send( ex, fmt3, p1, p2, p3 ); Assert.That( collector.Entries.Last().Text, Is.EqualTo( "fmtp1p2p3" ) ); Assert.That( collector.Entries.Last().Exception, Is.SameAs( ex ) ); d.Warn().Send( ex, fmt4, p1, p2, p3, p4 ); Assert.That( collector.Entries.Last().Text, Is.EqualTo( "fmtp1p2p3p4" ) ); Assert.That( collector.Entries.Last().Exception, Is.SameAs( ex ) ); d.Warn().Send( ex, fmt5, p1, p2, p3, p4, p5 ); Assert.That( collector.Entries.Last().Text, Is.EqualTo( "fmtp1p2p3p4p5" ) ); Assert.That( collector.Entries.Last().Exception, Is.SameAs( ex ) ); d.Warn().Send( ex, fmt6, p1, p2, p3, p4, p5, p6 ); Assert.That( collector.Entries.Last().Text, Is.EqualTo( "fmtp1p2p3p4p5p6" ) ); Assert.That( collector.Entries.Last().Exception, Is.SameAs( ex ) ); d.Error().Send( ex ); Assert.That( collector.Entries.Last().Text, Is.EqualTo( "EXCEPTION" ) ); Assert.That( collector.Entries.Last().Exception, Is.SameAs( ex ) ); d.Error().Send( ex, fmt0 ); Assert.That( collector.Entries.Last().Text, Is.EqualTo( "fmt" ) ); Assert.That( collector.Entries.Last().Exception, Is.SameAs( ex ) ); d.Error().Send( ex, fmt1, p1 ); Assert.That( collector.Entries.Last().Text, Is.EqualTo( "fmtp1" ) ); Assert.That( collector.Entries.Last().Exception, Is.SameAs( ex ) ); d.Error().Send( ex, fmt2, p1, p2 ); Assert.That( collector.Entries.Last().Text, Is.EqualTo( "fmtp1p2" ) ); Assert.That( collector.Entries.Last().Exception, Is.SameAs( ex ) ); d.Error().Send( ex, fmt3, p1, p2, p3 ); Assert.That( collector.Entries.Last().Text, Is.EqualTo( "fmtp1p2p3" ) ); Assert.That( collector.Entries.Last().Exception, Is.SameAs( ex ) ); d.Error().Send( ex, fmt4, p1, p2, p3, p4 ); Assert.That( collector.Entries.Last().Text, Is.EqualTo( "fmtp1p2p3p4" ) ); Assert.That( collector.Entries.Last().Exception, Is.SameAs( ex ) ); d.Error().Send( ex, fmt5, p1, p2, p3, p4, p5 ); Assert.That( collector.Entries.Last().Text, Is.EqualTo( "fmtp1p2p3p4p5" ) ); Assert.That( collector.Entries.Last().Exception, Is.SameAs( ex ) ); d.Error().Send( ex, fmt6, p1, p2, p3, p4, p5, p6 ); Assert.That( collector.Entries.Last().Text, Is.EqualTo( "fmtp1p2p3p4p5p6" ) ); Assert.That( collector.Entries.Last().Exception, Is.SameAs( ex ) ); d.Fatal().Send( ex ); Assert.That( collector.Entries.Last().Text, Is.EqualTo( "EXCEPTION" ) ); Assert.That( collector.Entries.Last().Exception, Is.SameAs( ex ) ); d.Fatal().Send( ex, fmt0 ); Assert.That( collector.Entries.Last().Text, Is.EqualTo( "fmt" ) ); Assert.That( collector.Entries.Last().Exception, Is.SameAs( ex ) ); d.Fatal().Send( ex, fmt1, p1 ); Assert.That( collector.Entries.Last().Text, Is.EqualTo( "fmtp1" ) ); Assert.That( collector.Entries.Last().Exception, Is.SameAs( ex ) ); d.Fatal().Send( ex, fmt2, p1, p2 ); Assert.That( collector.Entries.Last().Text, Is.EqualTo( "fmtp1p2" ) ); Assert.That( collector.Entries.Last().Exception, Is.SameAs( ex ) ); d.Fatal().Send( ex, fmt3, p1, p2, p3 ); Assert.That( collector.Entries.Last().Text, Is.EqualTo( "fmtp1p2p3" ) ); Assert.That( collector.Entries.Last().Exception, Is.SameAs( ex ) ); d.Fatal().Send( ex, fmt4, p1, p2, p3, p4 ); Assert.That( collector.Entries.Last().Text, Is.EqualTo( "fmtp1p2p3p4" ) ); Assert.That( collector.Entries.Last().Exception, Is.SameAs( ex ) ); d.Fatal().Send( ex, fmt5, p1, p2, p3, p4, p5 ); Assert.That( collector.Entries.Last().Text, Is.EqualTo( "fmtp1p2p3p4p5" ) ); Assert.That( collector.Entries.Last().Exception, Is.SameAs( ex ) ); d.Fatal().Send( ex, fmt6, p1, p2, p3, p4, p5, p6 ); Assert.That( collector.Entries.Last().Text, Is.EqualTo( "fmtp1p2p3p4p5p6" ) ); Assert.That( collector.Entries.Last().Exception, Is.SameAs( ex ) ); d.OpenTrace().Send( ex ); Assert.That( collector.Entries.Last().Text, Is.EqualTo( "EXCEPTION" ) ); Assert.That( collector.Entries.Last().Exception, Is.SameAs( ex ) ); d.OpenTrace().Send( ex, fmt0 ); Assert.That( collector.Entries.Last().Text, Is.EqualTo( "fmt" ) ); Assert.That( collector.Entries.Last().Exception, Is.SameAs( ex ) ); d.OpenTrace().Send( ex, fmt1, p1 ); Assert.That( collector.Entries.Last().Text, Is.EqualTo( "fmtp1" ) ); Assert.That( collector.Entries.Last().Exception, Is.SameAs( ex ) ); d.OpenTrace().Send( ex, fmt2, p1, p2 ); Assert.That( collector.Entries.Last().Text, Is.EqualTo( "fmtp1p2" ) ); Assert.That( collector.Entries.Last().Exception, Is.SameAs( ex ) ); d.OpenTrace().Send( ex, fmt3, p1, p2, p3 ); Assert.That( collector.Entries.Last().Text, Is.EqualTo( "fmtp1p2p3" ) ); Assert.That( collector.Entries.Last().Exception, Is.SameAs( ex ) ); d.OpenTrace().Send( ex, fmt4, p1, p2, p3, p4 ); Assert.That( collector.Entries.Last().Text, Is.EqualTo( "fmtp1p2p3p4" ) ); Assert.That( collector.Entries.Last().Exception, Is.SameAs( ex ) ); d.OpenTrace().Send( ex, fmt5, p1, p2, p3, p4, p5 ); Assert.That( collector.Entries.Last().Text, Is.EqualTo( "fmtp1p2p3p4p5" ) ); Assert.That( collector.Entries.Last().Exception, Is.SameAs( ex ) ); d.OpenTrace().Send( ex, fmt6, p1, p2, p3, p4, p5, p6 ); Assert.That( collector.Entries.Last().Text, Is.EqualTo( "fmtp1p2p3p4p5p6" ) ); Assert.That( collector.Entries.Last().Exception, Is.SameAs( ex ) ); }
public void ErrorCounterTests() { var monitor = new ActivityMonitor( applyAutoConfigurations: false ); using( monitor.Output.CreateBridgeTo( TestHelper.ConsoleMonitor.Output.BridgeTarget ) ) { // Registers the ErrorCounter first: it will be the last one to be called, but // this does not prevent the PathCatcher to work: the path elements reference the group // so that any conclusion arriving after PathCatcher.OnClosing are available. ActivityMonitorErrorCounter c = new ActivityMonitorErrorCounter(); monitor.Output.RegisterClient( c ); // Registers the PathCatcher now: it will be called BEFORE the ErrorCounter. ActivityMonitorPathCatcher p = new ActivityMonitorPathCatcher(); monitor.Output.RegisterClient( p ); Assert.That( c.GenerateConclusion, Is.False, "False by default." ); c.GenerateConclusion = true; Assert.That( c.Root.MaxLogLevel == LogLevel.None ); monitor.Trace().Send( "T1" ); Assert.That( !c.Root.HasWarnOrError && !c.Root.HasError ); Assert.That( c.Root.MaxLogLevel == LogLevel.Trace ); Assert.That( c.Root.ToString(), Is.Null ); monitor.Warn().Send( "W1" ); Assert.That( c.Root.HasWarnOrError && !c.Root.HasError ); Assert.That( c.Root.MaxLogLevel == LogLevel.Warn ); Assert.That( c.Root.ToString(), Is.Not.Null.And.Not.Empty ); monitor.Error().Send( "E2" ); Assert.That( c.Root.HasWarnOrError && c.Root.HasError ); Assert.That( c.Root.ErrorCount == 1 ); Assert.That( c.Root.MaxLogLevel == LogLevel.Error ); Assert.That( c.Root.ToString(), Is.Not.Null.And.Not.Empty ); c.Root.ClearError(); Assert.That( c.Root.HasWarnOrError && !c.Root.HasError ); Assert.That( c.Root.ErrorCount == 0 ); Assert.That( c.Root.MaxLogLevel == LogLevel.Warn ); Assert.That( c.Root.ToString(), Is.Not.Null ); c.Root.ClearWarn(); Assert.That( !c.Root.HasWarnOrError && !c.Root.HasError ); Assert.That( c.Root.MaxLogLevel == LogLevel.Info ); Assert.That( c.Root.ToString(), Is.Null ); using( monitor.OpenTrace().Send( "G1" ) ) { string errorMessage; using( monitor.OpenInfo().Send( "G2" ) ) { monitor.Error().Send( "E1" ); monitor.Fatal().Send( "F1" ); Assert.That( c.Root.HasWarnOrError && c.Root.HasError ); Assert.That( c.Root.ErrorCount == 1 && c.Root.FatalCount == 1 ); Assert.That( c.Root.WarnCount == 0 ); using( monitor.OpenInfo().Send( "G3" ) ) { Assert.That( !c.Current.HasWarnOrError && !c.Current.HasError ); Assert.That( c.Current.ErrorCount == 0 && c.Current.FatalCount == 0 && c.Current.WarnCount == 0 ); monitor.Error().Send( "An error..." ); Assert.That( c.Current.HasWarnOrError && c.Current.HasError ); Assert.That( c.Current.ErrorCount == 1 && c.Current.FatalCount == 0 && c.Current.WarnCount == 0 ); errorMessage = String.Join( "|", p.LastErrorPath.Select( e => e.Text + '-' + e.GroupConclusion.ToStringGroupConclusion() ) ); Assert.That( errorMessage, Is.EqualTo( "G1-|G2-|G3-|An error...-" ), "Groups are not closed: no conclusion exist yet." ); } errorMessage = String.Join( "|", p.LastErrorPath.Select( e => e.Text + '-' + e.GroupConclusion.ToStringGroupConclusion() ) ); Assert.That( errorMessage, Is.EqualTo( "G1-|G2-|G3-1 Error|An error...-" ), "G3 is closed: its conclusion is available." ); } errorMessage = String.Join( "|", p.LastErrorPath.Select( e => e.Text + '-' + e.GroupConclusion.ToStringGroupConclusion() ) ); Assert.That( errorMessage, Is.EqualTo( "G1-|G2-1 Fatal error, 2 Errors|G3-1 Error|An error...-" ) ); monitor.Error().Send( "E3" ); monitor.Fatal().Send( "F2" ); monitor.Warn().Send( "W2" ); Assert.That( c.Root.HasWarnOrError && c.Root.HasError ); Assert.That( c.Root.FatalCount == 2 ); Assert.That( c.Root.ErrorCount == 3 ); Assert.That( c.Root.MaxLogLevel == LogLevel.Fatal ); } Assert.That( String.Join( ">", p.LastErrorPath.Select( e => e.Text + '-' + e.GroupConclusion.ToStringGroupConclusion() ) ), Is.EqualTo( "G1-2 Fatal errors, 3 Errors, 1 Warning>F2-" ) ); Assert.That( String.Join( ">", p.LastWarnOrErrorPath.Select( e => e.Text + '-' + e.GroupConclusion.ToStringGroupConclusion() ) ), Is.EqualTo( "G1-2 Fatal errors, 3 Errors, 1 Warning>W2-" ) ); } }
public void concurrent_access_are_detected() { IActivityMonitor monitor = new ActivityMonitor(); if( TestHelper.LogsToConsole ) monitor.Output.RegisterClient( new ActivityMonitorConsoleClient() ); // Artficially slows down logging to ensure that concurrent access occurs. monitor.Output.RegisterClient( new ActionActivityMonitorClient( () => Thread.Sleep( 50 )) ); object lockTasks = new object(); object lockRunner = new object(); int enteredThread = 0; Action getLock = () => { lock( lockTasks ) { Interlocked.Increment( ref enteredThread ); lock( lockRunner ) Monitor.Pulse( lockRunner ); Monitor.Wait( lockTasks ); } }; Task[] tasks = new Task[] { new Task( () => { getLock(); monitor.Info().Send( "Test T1" ); } ), new Task( () => { getLock(); monitor.Info().Send( new Exception(), "Test T2" ); } ), new Task( () => { getLock(); monitor.Info().Send( "Test T3" ); } ) }; Parallel.ForEach( tasks, t => t.Start() ); lock( lockRunner ) while( enteredThread < tasks.Length ) Monitor.Wait( lockRunner ); lock( lockTasks ) Monitor.PulseAll( lockTasks ); Assert.Throws<AggregateException>( () => Task.WaitAll( tasks ) ); CollectionAssert.AllItemsAreInstancesOfType( tasks.Where( x => x.IsFaulted ). SelectMany( x => x.Exception.Flatten().InnerExceptions ), typeof( InvalidOperationException ) ); Assert.DoesNotThrow( () => monitor.Info().Send( "Test" ) ); }