From a18b04431e98ebfd85e775aa45552a6b8e89a85b Mon Sep 17 00:00:00 2001 From: helto4real Date: Fri, 10 Apr 2020 21:49:35 +0200 Subject: [PATCH] Added Special loggers --- exampleapps/apps/test1.cs | 3 +- exampleapps/apps/test2.cs | 3 + exampleapps/apps/test2.yaml | 2 +- src/App/NetDaemon.App/Common/NetDaemonApp.cs | 83 +++++++++++++++++- tests/NetDaemon.Daemon.Tests/LoggerMock.cs | 32 +++++++ .../NetDaemonApp/NetDaemonAppTests.cs | 87 +++++++++++++++++++ 6 files changed, 206 insertions(+), 4 deletions(-) diff --git a/exampleapps/apps/test1.cs b/exampleapps/apps/test1.cs index e68fab285..ee389402f 100644 --- a/exampleapps/apps/test1.cs +++ b/exampleapps/apps/test1.cs @@ -13,7 +13,8 @@ public class GlobalApp : NetDaemonApp public override async Task InitializeAsync() { SharedThing = "Hello world"; - + Log("Logging from global app"); + LogError("OMG SOMETING IS WRONG {error}", "The error!"); } } diff --git a/exampleapps/apps/test2.cs b/exampleapps/apps/test2.cs index a6d7002d2..d2f493ef1 100644 --- a/exampleapps/apps/test2.cs +++ b/exampleapps/apps/test2.cs @@ -12,6 +12,9 @@ public class BatteryManager : NetDaemonApp public string? HelloWorldSecret { get; set; } public override async Task InitializeAsync() { + Log("Hello"); + Log("Hello {name}", "Tomas"); + // Scheduler.RunEvery(5000, () => { var x = 0; var z = 4 / x; return Task.CompletedTask; }); // Entity("sun.sun").WhenStateChange(allChanges: true).Call((entityid, to, from) => throw new Exception("Test")).Execute(); // var app = (GlobalApp)GetApp("global_app"); diff --git a/exampleapps/apps/test2.yaml b/exampleapps/apps/test2.yaml index 1fdf52149..8704d2289 100644 --- a/exampleapps/apps/test2.yaml +++ b/exampleapps/apps/test2.yaml @@ -1,4 +1,4 @@ -app: +my_app: class: BatteryManager # HelloWorldSecret: !secret test_secret dependencies: diff --git a/src/App/NetDaemon.App/Common/NetDaemonApp.cs b/src/App/NetDaemon.App/Common/NetDaemonApp.cs index f0a76ff02..43f36f7dc 100644 --- a/src/App/NetDaemon.App/Common/NetDaemonApp.cs +++ b/src/App/NetDaemon.App/Common/NetDaemonApp.cs @@ -147,10 +147,89 @@ public Task SaveDataAsync(string id, T data) } /// - public void Log(string message, LogLevel level = LogLevel.Information) => Logger.Log(level, message); + public void Log(string message) => Log(LogLevel.Information, message); /// - public void Log(string message, Exception exception, LogLevel level = LogLevel.Information) => Logger.Log(level, exception, message); + public void LogWarning(string message) => Log(LogLevel.Warning, message); + + /// + public void LogError(string message) => Log(LogLevel.Error, message); + + /// + public void LogTrace(string message) => Log(LogLevel.Trace, message); + + /// + public void LogDebug(string message) => Log(LogLevel.Debug, message); + + /// + public void Log(Exception exception, string message) => Log(LogLevel.Information, exception, message); + /// + public void LogWarning(Exception exception, string message) => Log(LogLevel.Warning, exception, message); + /// + public void LogError(Exception exception, string message) => Log(LogLevel.Error, exception, message); + /// + public void LogDebug(Exception exception, string message) => Log(LogLevel.Debug, exception, message); + /// + public void LogTrace(Exception exception, string message) => Log(LogLevel.Trace, exception, message); + + /// + public void Log(LogLevel level, string message, params object[] param) + { + if (param is object && param.Length > 0) + { + var result = param.Prepend(Id).ToArray(); + Logger.Log(level, $" {{Id}}: {message}", result); + } + else + { + Logger.Log(level, $" {{Id}}: {message}", new object[] { Id ?? "" }); + } + } + + /// + public void Log(string message, params object[] param) => Log(LogLevel.Information, message, param); + + /// + public void LogWarning(string message, params object[] param) => Log(LogLevel.Warning, message, param); + + /// + public void LogError(string message, params object[] param) => Log(LogLevel.Error, message, param); + + /// + public void LogDebug(string message, params object[] param) => Log(LogLevel.Debug, message, param); + + /// + public void LogTrace(string message, params object[] param) => Log(LogLevel.Trace, message, param); + + + /// + public void Log(LogLevel level, Exception exception, string message, params object[] param) + { + if (param is object && param.Length > 0) + { + var result = param.Prepend(Id).ToArray(); + Logger.Log(level, exception, $" {{Id}}: {message}", result); + } + else + { + Logger.Log(level, exception, $" {{Id}}: {message}", new object[] { Id ?? "" }); + } + } + + /// + public void Log(Exception exception, string message, params object[] param) => Log(LogLevel.Information, exception, message, param); + + /// + public void LogWarning(Exception exception, string message, params object[] param) => Log(LogLevel.Warning, exception, message, param); + + /// + public void LogError(Exception exception, string message, params object[] param) => Log(LogLevel.Error, exception, message, param); + + /// + public void LogDebug(Exception exception, string message, params object[] param) => Log(LogLevel.Debug, exception, message, param); + + /// + public void LogTrace(Exception exception, string message, params object[] param) => Log(LogLevel.Trace, exception, message, param); /// public IMediaPlayer MediaPlayer(params string[] entityIds) diff --git a/tests/NetDaemon.Daemon.Tests/LoggerMock.cs b/tests/NetDaemon.Daemon.Tests/LoggerMock.cs index f359a48c3..4c8429f21 100644 --- a/tests/NetDaemon.Daemon.Tests/LoggerMock.cs +++ b/tests/NetDaemon.Daemon.Tests/LoggerMock.cs @@ -33,5 +33,37 @@ public void AssertLogged(LogLevel level, Times times) It.IsAny(), It.Is>((v, t) => true)), times); } + + /// + /// Assert if the log has been used at times + /// + /// The loglevel being checked + /// The Times it has been logged + public void AssertLogged(LogLevel level, string message, Times times) + { + MockLogger.Verify( + x => x.Log( + level, + It.IsAny(), + It.Is((v, t) => v.ToString() == message), + It.IsAny(), + It.Is>((v, t) => true)), times); + } + + /// + /// Assert if the log has been used at times + /// + /// The loglevel being checked + /// The Times it has been logged + public void AssertLogged(LogLevel level, Exception exception, string message, Times times) + { + MockLogger.Verify( + x => x.Log( + level, + It.IsAny(), + It.Is((v, t) => v.ToString() == message), + exception, + It.Is>((v, t) => true)), times); + } } } \ No newline at end of file diff --git a/tests/NetDaemon.Daemon.Tests/NetDaemonApp/NetDaemonAppTests.cs b/tests/NetDaemon.Daemon.Tests/NetDaemonApp/NetDaemonAppTests.cs index 45f322065..548378776 100644 --- a/tests/NetDaemon.Daemon.Tests/NetDaemonApp/NetDaemonAppTests.cs +++ b/tests/NetDaemon.Daemon.Tests/NetDaemonApp/NetDaemonAppTests.cs @@ -1,21 +1,108 @@ using JoySoftware.HomeAssistant.NetDaemon.Common; +using Microsoft.Extensions.Logging; using Moq; using System; using System.Collections.Generic; +using System.Reflection; using Xunit; namespace NetDaemon.Daemon.Tests.NetDaemonApp { public class NetDaemonApptests { + private readonly LoggerMock _logMock; private Mock _netDaemonMock; + + private const string appTemplate = " app: "; private JoySoftware.HomeAssistant.NetDaemon.Common.NetDaemonApp _app; public NetDaemonApptests() { + _logMock = new LoggerMock(); _netDaemonMock = new Mock(); + _netDaemonMock.SetupGet(n => n.Logger).Returns(_logMock.Logger); + _app = new JoySoftware.HomeAssistant.NetDaemon.Common.NetDaemonApp(); _app.StartUpAsync(_netDaemonMock.Object); + _app.Id = "app"; + } + + + [Theory] + [InlineData(LogLevel.Information, "Log")] + [InlineData(LogLevel.Warning, "LogWarning")] + [InlineData(LogLevel.Error, "LogError")] + [InlineData(LogLevel.Trace, "LogTrace")] + [InlineData(LogLevel.Debug, "LogDebug")] + public void LogMessageWithDifferentLogLevelsShoulCallCorrectLogger(LogLevel level, string methodName) + { + // ARRANGE + var message = "message"; + MethodInfo? methodInfo; + + // ACT + methodInfo = _app.GetType().GetMethod(methodName, new Type[] { typeof(string) }); + + methodInfo?.Invoke(_app, new object[] { message }); + // ASSERT + _logMock.AssertLogged(level, appTemplate + message, Times.Once()); + } + + [Theory] + [InlineData(LogLevel.Information, "Log")] + [InlineData(LogLevel.Warning, "LogWarning")] + [InlineData(LogLevel.Error, "LogError")] + [InlineData(LogLevel.Trace, "LogTrace")] + [InlineData(LogLevel.Debug, "LogDebug")] + public void LogMessageWithParamsAndDifferentLogLevelsShoulCallCorrectLogger(LogLevel level, string methodName) + { + // ARRANGE + var message = "Hello {name}"; + + // ACT + var methodInfo = _app.GetType().GetMethod(methodName, new Type[] { typeof(string), typeof(object[]) }); + + methodInfo?.Invoke(_app, new object[] { message, new object[] { "Bob" } }); + // ASSERT + _logMock.AssertLogged(level, appTemplate + "Hello Bob", Times.Once()); + } + + [Theory] + [InlineData(LogLevel.Information, "Log")] + [InlineData(LogLevel.Warning, "LogWarning")] + [InlineData(LogLevel.Error, "LogError")] + [InlineData(LogLevel.Trace, "LogTrace")] + [InlineData(LogLevel.Debug, "LogDebug")] + public void LogMessageWithParamsExceptionAndDifferentLogLevelsShoulCallCorrectLogger(LogLevel level, string methodName) + { + // ARRANGE + var message = "Hello {name}"; + var exception = new NullReferenceException("Null"); + // ACT + var methodInfo = _app.GetType().GetMethod(methodName, new Type[] { typeof(Exception), typeof(string), typeof(object[]) }); + + methodInfo?.Invoke(_app, new object[] { exception, message, new object[] { "Bob" } }); + // ASSERT + _logMock.AssertLogged(level, exception, appTemplate + "Hello Bob", Times.Once()); + } + + [Theory] + [InlineData(LogLevel.Information, "Log")] + [InlineData(LogLevel.Warning, "LogWarning")] + [InlineData(LogLevel.Error, "LogError")] + [InlineData(LogLevel.Trace, "LogTrace")] + [InlineData(LogLevel.Debug, "LogDebug")] + public void LogMessageWithExceptionAndDifferentLogLevelsShoulCallCorrectLogger(LogLevel level, string methodName) + { + // ARRANGE + var message = "message"; + var exception = new NullReferenceException("Null"); + // ACT + var methodInfo = _app.GetType().GetMethod(methodName, new Type[] { typeof(Exception), typeof(string) }); + + methodInfo?.Invoke(_app, new object[] { exception, message }); + // ASSERT + _logMock.AssertLogged(level, exception, appTemplate + message, Times.Once()); } [Fact]