Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,15 @@

using Microsoft.Extensions.Logging;
using System;
using System.Diagnostics.CodeAnalysis;

namespace AMT.Extensions.Logging.IP
{
/// <summary>
/// Scope provider that does nothing.
/// </summary>
internal class NullExternalScopeProvider : IExternalScopeProvider
[ExcludeFromCodeCoverage]
public class NullExternalScopeProvider : IExternalScopeProvider
{
private NullExternalScopeProvider()
{
Expand Down
2 changes: 2 additions & 0 deletions AMT.Extensions.Logging/IP/Internal/NullScope.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,14 @@
// due to it being internal access there.

using System;
using System.Diagnostics.CodeAnalysis;

namespace AMT.Extensions.Logging.IP
{
/// <summary>
/// An empty scope without any logic
/// </summary>
[ExcludeFromCodeCoverage]
internal class NullScope : IDisposable
{
public static NullScope Instance { get; } = new NullScope();
Expand Down
10 changes: 5 additions & 5 deletions AMT.Extensions.Logging/IP/UdpLoggerProcessor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -49,11 +49,7 @@ public virtual void EnqueueMessage(LogMessageEntry message)
}

// Adding is completed so just log the message
try
{
WriteMessage(message);
}
catch (Exception) { }
WriteMessage(message);
}

internal virtual void WriteMessage(LogMessageEntry entry)
Expand Down Expand Up @@ -96,13 +92,17 @@ public void Dispose()
_messageQueue.CompleteAdding();
_shutdown = true;

// Give the sender time to complete its tasks
try
{
// TODO: use a config value for timeout
_outputThread.Join(1500); // with timeout in-case Console is locked by user input
}
catch (ThreadStateException) { }

_udpSender.Dispose();
// Clear any messages
_messageQueue.Dispose();
}

#endregion IDisposable impl
Expand Down
8 changes: 7 additions & 1 deletion AMT.Extensions.Logging/IP/UdpLoggerProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,13 @@ public ILogger CreateLogger(string category)

public void SetScopeProvider(IExternalScopeProvider scopeProvider)
{
_scopeProvider = scopeProvider;
if (null == scopeProvider)
{
_scopeProvider = NullExternalScopeProvider.Instance;
} else
{
_scopeProvider = scopeProvider;
}
}

#endregion ISupportExternalScope impl
Expand Down
44 changes: 44 additions & 0 deletions Test.AMT.Extensions.Logging/IP/UdpLoggerProcessorTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// Copyright (c) AltaModa Technologies. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

using Ext = AMT.Extensions.Logging.IP;
using FluentAssertions;
using System;
using System.Diagnostics.CodeAnalysis;
using Xunit;
using AMT.Extensions.Logging.IP;


namespace Test.AMT.Extensions.Logging.IP
{
[ExcludeFromCodeCoverage]
public class UdpLoggerProcessorTests
{

[Fact]
public void excp_on_null_options()
{
Action act = () => new Ext.UdpLoggerProcessor(null);
act.Should().Throw<ArgumentNullException>();
}


#region IDisposable tests

[Fact]
public void verify_disposable()
{
using (var proc = new Ext.UdpLoggerProcessor(_opts))
{
var udpProv = new Ext.UdpLoggerProvider(_opts);
}

}

#endregion IDisposable tests


private static readonly UdpLoggerOptions _opts = new UdpLoggerOptions();
}

}
54 changes: 45 additions & 9 deletions Test.AMT.Extensions.Logging/IP/UdpLoggerProviderTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
using Xunit;
using AMT.Extensions.Logging.IP;
using Microsoft.Extensions.Logging;
using System.Configuration.Provider;


namespace Test.AMT.Extensions.Logging.IP
Expand All @@ -17,6 +16,16 @@ namespace Test.AMT.Extensions.Logging.IP
public class UdpLoggerProviderTests
{

[Fact]
public void excp_on_null_category()
{
var provider = new Ext.UdpLoggerProvider(_opts);
Action act = () => provider.CreateLogger(null);

act.Should().Throw<ArgumentNullException>();
}


[Fact]
public void excp_on_null_options()
{
Expand All @@ -28,21 +37,48 @@ public void excp_on_null_options()
#region ILoggerProvider tests

[Fact]
public void foo()
public void can_log_to_category()
{
var udpProv = new Ext.UdpLoggerProvider(_opts);
using (var udpProv = new Ext.UdpLoggerProvider(_opts))
{
ILoggerProvider prov = udpProv as ILoggerProvider;
Assert.NotNull(prov);

ILogger l = prov.CreateLogger("randomCategory");
Assert.NotNull(l);

l.LogInformation("using ILogger.LogInformation...");
}
}

#endregion ILoggerProvider tests

ILoggerProvider prov = udpProv as ILoggerProvider;
Assert.NotNull(prov);

ILogger l = prov.CreateLogger("randomCategory");
Assert.NotNull(l);
#region ISupportExternalScope tests

l.LogInformation("using ILogger.LogInformation...");
[Fact]
public void can_set_scope_provider()
{
var testEsps = new IExternalScopeProvider[] {
null,
NullExternalScopeProvider.Instance
};
// TODO: consider disabling null
foreach (IExternalScopeProvider esp in testEsps ) {
using (var udpProv = new Ext.UdpLoggerProvider(_opts))
{
udpProv.SetScopeProvider(esp);

ILogger l = udpProv.CreateLogger("randomCategory");
Assert.NotNull(l);

l.LogInformation("using ILogger.LogInformation...");
}
}
}

#endregion ILoggerProvider tests
#endregion ISupportExternalScope tests



private static readonly UdpLoggerOptions _opts = new UdpLoggerOptions();
Expand Down
68 changes: 51 additions & 17 deletions Test.AMT.Extensions.Logging/IP/UdpLoggerTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using Xunit;
using System.Net;
using System.Runtime.CompilerServices;


namespace Test.AMT.Extensions.Logging.IP
Expand All @@ -19,30 +21,31 @@ public class UdpLoggerTests
[Fact]
public void verify_each_loglevel()
{
// Prepare listener to receive messages
var opts = new Ext.UdpLoggerOptions();
// Prepare listener to receive messages; isolate port for message count
var opts = new Ext.UdpLoggerOptions(new IPEndPoint(IPAddress.Loopback, 17460));

using (_receiver = new UdpReceiver())
{
_receiver.Start(opts);

// Add options to provider before create logger
_provider = new Ext.UdpLoggerProvider(opts);
var logger = _provider.CreateLogger("test") as Ext.UdpLogger;

// Log a message of each LogLevel
foreach (int level in _logLevels)
{
logger.Log((LogLevel)level, DEFAULT_EVENTID, DEFAULT_STATE, DEFAULT_EXCEPTION, setStringFormatter);
using (_provider = new Ext.UdpLoggerProvider(opts)) {
_logger = _provider.CreateLogger("test") as Ext.UdpLogger;

// Log a message of each LogLevel
foreach (int level in _logLevels)
{
_logger.Log((LogLevel)level, DEFAULT_EVENTID, DEFAULT_STATE, DEFAULT_EXCEPTION, setStringFormatter);
}

// Brief wait, then stop listener
System.Threading.Thread.Sleep(100);
_receiver.Stop();

// NOTE: RetrieveMessages returns a _consuming_ enumerator, so it can only be used once.
// LogLevel.None filtered, so reduce by 1.
_receiver.RetrieveMessages().Count().Should().Be(_logLevels.Length - 1);
}

// Brief wait, then stop listener
System.Threading.Thread.Sleep(100);
_receiver.Stop();

// NOTE: RetrieveMessages returns a _consuming_ enumerator, so it can only be used once.
// 2024.09.17, JB: previously None was filtered, but it seems that changed in logging fx.
_receiver.RetrieveMessages().Count().Should().Be(_logLevels.Length);
}
}

Expand Down Expand Up @@ -119,6 +122,36 @@ public void verify_few_log_messages()
}


[Fact]
public void verify_begin_scope()
{
// Prepare listener to receive messages
var opts = new Ext.UdpLoggerOptions();

using (_receiver = new UdpReceiver())
{
_receiver.Start(opts);

// Add options to provider before create logger
using (_provider = new Ext.UdpLoggerProvider(opts)) {
_logger = _provider.CreateLogger("test") as Ext.UdpLogger;

using (_logger.BeginScope("SCOPE L1: ", null))
{
_logger.Log(LogLevel.Trace, "some log message");
using (_logger.BeginScope("SCOPE L2: ", null))
{
_logger.Log(LogLevel.Trace, "some log message");
}

// TODO: confirm scope messages?
}

}
}
}


private LogLevel GetRandomLogLevel(bool excludeNone = true)
{
return (LogLevel)_randomizer.Next(0, excludeNone ? _logLevels.Length - 1 : _logLevels.Length);
Expand All @@ -139,6 +172,7 @@ public UdpLoggerTests(Xunit.Abstractions.ITestOutputHelper outputHelper)


private ILoggerProvider _provider;
private ILogger _logger;
private UdpReceiver _receiver;
private readonly object DEFAULT_STATE = "### Default state for testing ###";
private readonly object NULL_STATE = "[null-state]"; // TODO: use null;
Expand Down
18 changes: 15 additions & 3 deletions Test.AMT.Extensions.Logging/IP/Utils/UdpReceiver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ namespace Test.AMT.Extensions.Logging.IP
internal class UdpReceiver : IDisposable
{
private static int _maxQueuedMessages = 1024;
private readonly BlockingCollection<string> _messageQueue = new BlockingCollection<string>(_maxQueuedMessages);
private BlockingCollection<string> _messageQueue = new BlockingCollection<string>(_maxQueuedMessages);

private bool _stopListener = false;
private UdpClient _client;
Expand Down Expand Up @@ -54,14 +54,27 @@ public void Stop()
}


private static IEnumerable<string> emptyList = new List<string>();
public IEnumerable<string> RetrieveMessages()
{
return _messageQueue.GetConsumingEnumerable();
if (_messageQueue.Count > 0)
{
return _messageQueue.GetConsumingEnumerable();
} else
{
return emptyList;
}
}

#region IDisposable impl
public void Dispose()
{
// Drain the queue
if (_messageQueue != null)
{
_messageQueue = null;
}

if (null != _client)
{
_client.Close();
Expand All @@ -71,6 +84,5 @@ public void Dispose()
}
#endregion IDisposable impl


}
}
16 changes: 16 additions & 0 deletions Test.AMT.Extensions.System/ConvertTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,14 @@ public void excp_on_null()
};

act.Should().Throw<ArgumentNullException>();


// Verify proper exception when encoded is null
act = () => {
Ext.Convert.FromBase64UrlString(null);
};

act.Should().Throw<ArgumentNullException>();
}


Expand All @@ -79,6 +87,14 @@ public void excp_on_empty_string()
};

act.Should().Throw<ArgumentOutOfRangeException>();


// Verify proper exception when encoded is empty
act = () => {
Ext.Convert.FromBase64UrlString(string.Empty);
};

act.Should().Throw<ArgumentOutOfRangeException>();
}


Expand Down