From 66bbed5242dca83fa8f24a6f72118d53e51674cd Mon Sep 17 00:00:00 2001 From: Jarek Kowalski Date: Sat, 20 Aug 2011 05:53:25 -0700 Subject: [PATCH] Fixed two bugs in LogFactory/LogManager 1. 6354 - Nlog config file locater url encodes the path when using Nlog.dll.nlog config name 2. Invalid config file precedence when multiple config files were found. Added unit tests. --- src/NLog/LogFactory.cs | 11 +- .../NLog.UnitTests/ConfigFileLocatorTests.cs | 350 ++++++++++++++++++ .../NLog.UnitTests.monodevelop.csproj | 1 + .../NLog.UnitTests.netcf20.csproj | 1 + .../NLog.UnitTests.netcf35.csproj | 1 + .../NLog.UnitTests.netfx20.csproj | 1 + .../NLog.UnitTests.netfx35.csproj | 1 + .../NLog.UnitTests.netfx40.csproj | 1 + .../NLog.UnitTests/NLog.UnitTests.sl2.csproj | 1 + .../NLog.UnitTests/NLog.UnitTests.sl3.csproj | 1 + .../NLog.UnitTests/NLog.UnitTests.sl4.csproj | 1 + .../NLog.UnitTests/NLog.UnitTests.wp7.csproj | 1 + .../NLog.UnitTests/NLog.UnitTests.wp71.csproj | 1 + 13 files changed, 365 insertions(+), 7 deletions(-) create mode 100644 tests/NLog.UnitTests/ConfigFileLocatorTests.cs diff --git a/src/NLog/LogFactory.cs b/src/NLog/LogFactory.cs index 9dd35764..eac8631d 100644 --- a/src/NLog/LogFactory.cs +++ b/src/NLog/LogFactory.cs @@ -146,6 +146,7 @@ public LoggingConfiguration Configuration { InternalLogger.Debug("Attempting to load config from {0}", configFile); this.config = new XmlLoggingConfiguration(configFile); + break; } #else Uri configFileUri = new Uri(configFile, UriKind.Relative); @@ -153,6 +154,7 @@ public LoggingConfiguration Configuration { InternalLogger.Debug("Attempting to load config from {0}", configFile); this.config = new XmlLoggingConfiguration(configFile); + break; } #endif } @@ -662,14 +664,9 @@ private static IEnumerable GetCandidateFileNames() var nlogAssembly = typeof(LogFactory).Assembly; if (!nlogAssembly.GlobalAssemblyCache) { - var codeBase = nlogAssembly.GetName().CodeBase; - if (!string.IsNullOrEmpty(codeBase)) + if (!string.IsNullOrEmpty(nlogAssembly.Location)) { - var uri = new Uri(codeBase, UriKind.RelativeOrAbsolute); - if (uri.Scheme == "file") - { - yield return uri.AbsolutePath + ".nlog"; - } + yield return nlogAssembly.Location + ".nlog"; } } #endif diff --git a/tests/NLog.UnitTests/ConfigFileLocatorTests.cs b/tests/NLog.UnitTests/ConfigFileLocatorTests.cs new file mode 100644 index 00000000..4fd1f5ac --- /dev/null +++ b/tests/NLog.UnitTests/ConfigFileLocatorTests.cs @@ -0,0 +1,350 @@ +// +// Copyright (c) 2004-2011 Jaroslaw Kowalski +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * Neither the name of Jaroslaw Kowalski nor the names of its +// contributors may be used to endorse or promote products derived from this +// software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +// THE POSSIBILITY OF SUCH DAMAGE. +// + +#if !SILVERLIGHT && !NET_CF + +using System; +using System.CodeDom.Compiler; +using System.Diagnostics; +using System.IO; +using System.Text; +using Microsoft.CSharp; +using NUnit.Framework; + +#if !NUNIT + using SetUp = Microsoft.VisualStudio.TestTools.UnitTesting.TestInitializeAttribute; + using TestFixture = Microsoft.VisualStudio.TestTools.UnitTesting.TestClassAttribute; + using Test = Microsoft.VisualStudio.TestTools.UnitTesting.TestMethodAttribute; + using TearDown = Microsoft.VisualStudio.TestTools.UnitTesting.TestCleanupAttribute; +#endif + +namespace NLog.UnitTests +{ + [TestFixture] + public class ConfigFileLocatorTests + { + private string appConfigContents = @" + + +
+ + + + + + + + + + + +"; + + private string appNLogContents = @" + + + + + + + + +"; + + private string nlogConfigContents = @" + + + + + + + + +"; + + private string nlogDllNLogContents = @" + + + + + + + + +"; + + private string appConfigOutput = "--BEGIN--|AC InfoMsg|AC WarnMsg|AC ErrorMsg|AC FatalMsg|--END--|"; + private string appNLogOutput = "--BEGIN--|AN InfoMsg|AN WarnMsg|AN ErrorMsg|AN FatalMsg|--END--|"; + private string nlogConfigOutput = "--BEGIN--|NLC InfoMsg|NLC WarnMsg|NLC ErrorMsg|NLC FatalMsg|--END--|"; + private string nlogDllNLogOutput = "--BEGIN--|NDN InfoMsg|NDN WarnMsg|NDN ErrorMsg|NDN FatalMsg|--END--|"; + private string missingConfigOutput = "--BEGIN--|--END--|"; + + [Test] + public void MissingConfigFileTest() + { + string dir = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString("N")); + + Directory.CreateDirectory(dir); + try + { + string output = RunTestIn(dir); + Assert.AreEqual(missingConfigOutput, output); + } + finally + { + Directory.Delete(dir, true); + } + } + + [Test] + public void NLogDotConfigTest() + { + string dir = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString("N")); + + Directory.CreateDirectory(dir); + try + { + File.WriteAllText(Path.Combine(dir, "NLog.config"), nlogConfigContents); + string output = RunTestIn(dir); + Assert.AreEqual(nlogConfigOutput, output); + } + finally + { + Directory.Delete(dir, true); + } + } + + [Test] + public void NLogDotDllDotNLogTest() + { + string dir = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString("N")); + + Directory.CreateDirectory(dir); + try + { + File.WriteAllText(Path.Combine(dir, "NLog.dll.nlog"), nlogDllNLogContents); + string output = RunTestIn(dir); + Assert.AreEqual(nlogDllNLogOutput, output); + } + finally + { + Directory.Delete(dir, true); + } + } + + [Test] + public void NLogDotDllDotNLogInDirectoryWithSpaces() + { + string dir = Path.Combine(Path.GetTempPath(), "abc " + Guid.NewGuid().ToString("N") + " def"); + + Directory.CreateDirectory(dir); + try + { + File.WriteAllText(Path.Combine(dir, "NLog.dll.nlog"), nlogDllNLogContents); + string output = RunTestIn(dir); + Assert.AreEqual(nlogDllNLogOutput, output); + } + finally + { + Directory.Delete(dir, true); + } + } + + [Test] + public void AppDotConfigTest() + { + string dir = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString("N")); + + Directory.CreateDirectory(dir); + try + { + File.WriteAllText(Path.Combine(dir, "ConfigFileLocator.exe.config"), appConfigContents); + string output = RunTestIn(dir); + Assert.AreEqual(appConfigOutput, output); + } + finally + { + Directory.Delete(dir, true); + } + } + + [Test] + public void AppDotNLogTest() + { + string dir = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString("N")); + + Directory.CreateDirectory(dir); + try + { + File.WriteAllText(Path.Combine(dir, "ConfigFileLocator.exe.nlog"), appNLogContents); + string output = RunTestIn(dir); + Assert.AreEqual(appNLogOutput, output); + } + finally + { + Directory.Delete(dir, true); + } + } + + [Test] + public void PrecedenceTest() + { + var precedence = new[] + { + new + { + File = "ConfigFileLocator.exe.config", + Contents = appConfigContents, + Output = appConfigOutput + }, + new + { + File = "NLog.config", + Contents = nlogConfigContents, + Output = nlogConfigOutput + }, + new + { + File = "ConfigFileLocator.exe.nlog", + Contents = appNLogContents, + Output = appNLogOutput + }, + new + { + File = "NLog.dll.nlog", + Contents = nlogDllNLogContents, + Output = nlogDllNLogOutput + }, + }; + string dir = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString("N")); + + Directory.CreateDirectory(dir); + try + { + // deploy all files + foreach (var p in precedence) + { + File.WriteAllText(Path.Combine(dir, p.File), p.Contents); + } + + string output; + + // walk files in precedence order and delete config files + foreach (var p in precedence) + { + output = RunTestIn(dir); + Assert.AreEqual(p.Output, output); + File.Delete(Path.Combine(dir, p.File)); + } + + output = RunTestIn(dir); + Assert.AreEqual(missingConfigOutput, output); + + } + finally + { + Directory.Delete(dir, true); + } + + } + + private static string RunTestIn(string directory) + { + string sourceCode = @" +using System; +using System.Reflection; +using NLog; + +class C1 +{ + private static Logger logger = LogManager.GetCurrentClassLogger(); + + static void Main(string[] args) + { + Console.WriteLine(""--BEGIN--""); + logger.Trace(""TraceMsg""); + logger.Debug(""DebugMsg""); + logger.Info(""InfoMsg""); + logger.Warn(""WarnMsg""); + logger.Error(""ErrorMsg""); + logger.Fatal(""FatalMsg""); + Console.WriteLine(""--END--""); + } +}"; + var provider = new CSharpCodeProvider(); + var options = new CompilerParameters(); + options.OutputAssembly = Path.Combine(directory, "ConfigFileLocator.exe"); + options.GenerateExecutable = true; + options.ReferencedAssemblies.Add(typeof(Logger).Assembly.Location); + options.IncludeDebugInformation = true; + if (!File.Exists(options.OutputAssembly)) + { + var results = provider.CompileAssemblyFromSource(options, sourceCode); + Assert.IsFalse(results.Errors.HasWarnings); + Assert.IsFalse(results.Errors.HasErrors); + File.Copy(typeof (Logger).Assembly.Location, Path.Combine(directory, "NLog.dll")); + } + + return RunAndRedirectOutput(options.OutputAssembly); + } + + public static string RunAndRedirectOutput(string exeFile) + { + var sb = new StringBuilder(); +#if MONO + sb.AppendFormat("\"{0}\" ", exeFile); +#endif + + using (var proc = new Process()) + { + proc.StartInfo.Arguments = sb.ToString(); +#if MONO + proc.StartInfo.FileName = "mono"; +#else + proc.StartInfo.FileName = exeFile; +#endif + proc.StartInfo.UseShellExecute = false; + proc.StartInfo.WindowStyle = ProcessWindowStyle.Normal; + proc.StartInfo.RedirectStandardInput = false; + proc.StartInfo.RedirectStandardOutput = true; + proc.StartInfo.WindowStyle = ProcessWindowStyle.Hidden; + proc.StartInfo.CreateNoWindow = true; + proc.Start(); + proc.WaitForExit(); + return proc.StandardOutput.ReadToEnd().Replace("\r", "").Replace("\n", "|"); + } + } + } +} + +#endif \ No newline at end of file diff --git a/tests/NLog.UnitTests/NLog.UnitTests.monodevelop.csproj b/tests/NLog.UnitTests/NLog.UnitTests.monodevelop.csproj index 61912551..bd595c39 100644 --- a/tests/NLog.UnitTests/NLog.UnitTests.monodevelop.csproj +++ b/tests/NLog.UnitTests/NLog.UnitTests.monodevelop.csproj @@ -75,6 +75,7 @@ + diff --git a/tests/NLog.UnitTests/NLog.UnitTests.netcf20.csproj b/tests/NLog.UnitTests/NLog.UnitTests.netcf20.csproj index 2e33c306..f1d780fd 100644 --- a/tests/NLog.UnitTests/NLog.UnitTests.netcf20.csproj +++ b/tests/NLog.UnitTests/NLog.UnitTests.netcf20.csproj @@ -81,6 +81,7 @@ + diff --git a/tests/NLog.UnitTests/NLog.UnitTests.netcf35.csproj b/tests/NLog.UnitTests/NLog.UnitTests.netcf35.csproj index 8987f6c4..2808f110 100644 --- a/tests/NLog.UnitTests/NLog.UnitTests.netcf35.csproj +++ b/tests/NLog.UnitTests/NLog.UnitTests.netcf35.csproj @@ -79,6 +79,7 @@ + diff --git a/tests/NLog.UnitTests/NLog.UnitTests.netfx20.csproj b/tests/NLog.UnitTests/NLog.UnitTests.netfx20.csproj index 3f18076d..6396bb34 100644 --- a/tests/NLog.UnitTests/NLog.UnitTests.netfx20.csproj +++ b/tests/NLog.UnitTests/NLog.UnitTests.netfx20.csproj @@ -79,6 +79,7 @@ + diff --git a/tests/NLog.UnitTests/NLog.UnitTests.netfx35.csproj b/tests/NLog.UnitTests/NLog.UnitTests.netfx35.csproj index b417a87a..0c2552ce 100644 --- a/tests/NLog.UnitTests/NLog.UnitTests.netfx35.csproj +++ b/tests/NLog.UnitTests/NLog.UnitTests.netfx35.csproj @@ -81,6 +81,7 @@ + diff --git a/tests/NLog.UnitTests/NLog.UnitTests.netfx40.csproj b/tests/NLog.UnitTests/NLog.UnitTests.netfx40.csproj index 0add1fa2..53d5787d 100644 --- a/tests/NLog.UnitTests/NLog.UnitTests.netfx40.csproj +++ b/tests/NLog.UnitTests/NLog.UnitTests.netfx40.csproj @@ -78,6 +78,7 @@ + diff --git a/tests/NLog.UnitTests/NLog.UnitTests.sl2.csproj b/tests/NLog.UnitTests/NLog.UnitTests.sl2.csproj index a91fef30..1fad6df1 100644 --- a/tests/NLog.UnitTests/NLog.UnitTests.sl2.csproj +++ b/tests/NLog.UnitTests/NLog.UnitTests.sl2.csproj @@ -109,6 +109,7 @@ + diff --git a/tests/NLog.UnitTests/NLog.UnitTests.sl3.csproj b/tests/NLog.UnitTests/NLog.UnitTests.sl3.csproj index c0bc6500..de9e9290 100644 --- a/tests/NLog.UnitTests/NLog.UnitTests.sl3.csproj +++ b/tests/NLog.UnitTests/NLog.UnitTests.sl3.csproj @@ -95,6 +95,7 @@ + diff --git a/tests/NLog.UnitTests/NLog.UnitTests.sl4.csproj b/tests/NLog.UnitTests/NLog.UnitTests.sl4.csproj index 5becfeb4..2e36f155 100644 --- a/tests/NLog.UnitTests/NLog.UnitTests.sl4.csproj +++ b/tests/NLog.UnitTests/NLog.UnitTests.sl4.csproj @@ -96,6 +96,7 @@ + diff --git a/tests/NLog.UnitTests/NLog.UnitTests.wp7.csproj b/tests/NLog.UnitTests/NLog.UnitTests.wp7.csproj index fd709b47..a4b1ba74 100644 --- a/tests/NLog.UnitTests/NLog.UnitTests.wp7.csproj +++ b/tests/NLog.UnitTests/NLog.UnitTests.wp7.csproj @@ -88,6 +88,7 @@ + diff --git a/tests/NLog.UnitTests/NLog.UnitTests.wp71.csproj b/tests/NLog.UnitTests/NLog.UnitTests.wp71.csproj index 7a3425bb..c818d2e7 100644 --- a/tests/NLog.UnitTests/NLog.UnitTests.wp71.csproj +++ b/tests/NLog.UnitTests/NLog.UnitTests.wp71.csproj @@ -88,6 +88,7 @@ +