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." );
}