#region Apache License
//
// Licensed to the Apache Software Foundation (ASF) under one or more
// contributor license agreements. See the NOTICE file distributed with
// this work for additional information regarding copyright ownership.
// The ASF licenses this file to you under the Apache License, Version 2.0
// (the "License"); you may not use this file except in compliance with
// the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#endregion

using System;
using System.Collections;
using System.Diagnostics;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;

using log4net.Appender;
using log4net.Core;
using log4net.Layout;
using log4net.Repository.Hierarchy;
using log4net.Util;

using NUnit.Framework;
using System.Globalization;

namespace log4net.Tests.Appender
{
	/// <summary>
	/// Used for internal unit testing the <see cref="RollingFileAppender"/> class.
	/// </summary>
	[TestFixture]
	public class RollingFileAppenderTest
	{
		private const string c_fileName = "test_41d3d834_4320f4da.log";
		private const string c_testMessage98Chars = "01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567";
		private const string c_testMessage99Chars = "012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678";
		private const int c_iMaximumFileSize = 450; // in bytes
		private int _iMessagesLoggedThisFile = 0;
		private int _iMessagesLogged = 0;
		private int _iCountDirection = 0;
		private int _MaxSizeRollBackups = 3;
		private CountingAppender _caRoot;
		private Logger _root;
#if !NETSTANDARD1_3
		private CultureInfo _currentCulture;
		private CultureInfo _currentUICulture;
#endif
		private class SilentErrorHandler : IErrorHandler
		{
			private StringBuilder m_buffer = new StringBuilder();

			public string Message
			{
				get { return m_buffer.ToString(); }
			}

			public void Error(string message)
			{
				m_buffer.Append(message + "\n");
			}

			public void Error(string message, Exception e)
			{
				m_buffer.Append(message + "\n" + e.Message + "\n");
			}

			public void Error(string message, Exception e, ErrorCode errorCode)
			{
				m_buffer.Append(message + "\n" + e.Message + "\n");
			}
		}

		/// <summary>
		/// Sets up variables used for the tests
		/// </summary>
		private void InitializeVariables()
		{
			_iMessagesLoggedThisFile = 0;
			_iMessagesLogged = 0;
			_iCountDirection = +1; // Up
			_MaxSizeRollBackups = 3;
		}

		/// <summary>
		/// Shuts down any loggers in the hierarchy, along
		/// with all appenders, and deletes any test files used
		/// for logging.
		/// </summary>
		private static void ResetAndDeleteTestFiles()
		{
			// Regular users should not use the clear method lightly!
			Utils.GetRepository().ResetConfiguration();
			Utils.GetRepository().Shutdown();
			((Repository.Hierarchy.Hierarchy)Utils.GetRepository()).Clear();

			DeleteTestFiles();
		}

		/// <summary>
		/// Any initialization that happens before each test can
		/// go here
		/// </summary>
		[SetUp]
		public void SetUp()
		{
			ResetAndDeleteTestFiles();
			InitializeVariables();

#if !NETSTANDARD1_3
			// set correct thread culture
			_currentCulture = System.Threading.Thread.CurrentThread.CurrentCulture;
			_currentUICulture = System.Threading.Thread.CurrentThread.CurrentUICulture;
			System.Threading.Thread.CurrentThread.CurrentCulture = System.Threading.Thread.CurrentThread.CurrentUICulture = System.Globalization.CultureInfo.InvariantCulture;
#endif
		}

		/// <summary>
		/// Any steps that happen after each test go here
		/// </summary>
		[TearDown]
		public void TearDown()
		{
			ResetAndDeleteTestFiles();

#if !NETSTANDARD1_3
			// restore previous culture
			System.Threading.Thread.CurrentThread.CurrentCulture = _currentCulture;
			System.Threading.Thread.CurrentThread.CurrentUICulture = _currentUICulture;
#endif
		}

		/// <summary>
		/// Finds the number of files that match the base file name,
		/// and matches the result against an expected count
		/// </summary>
		/// <param name="iExpectedCount"></param>
		private static void VerifyFileCount(int iExpectedCount)
		{
					VerifyFileCount(iExpectedCount, false);
				}
		/// <summary>
		/// Finds the number of files that match the base file name,
		/// and matches the result against an expected count
		/// </summary>
		/// <param name="iExpectedCount"></param>
		private static void VerifyFileCount(int iExpectedCount, bool preserveLogFileNameExtension)
		{
			ArrayList alFiles = GetExistingFiles(c_fileName, preserveLogFileNameExtension);
			Assert.IsNotNull(alFiles);
			Assert.AreEqual(iExpectedCount, alFiles.Count);
		}

		/// <summary>
		/// Creates a file with the given number, and the shared base file name
		/// </summary>
		/// <param name="iFileNumber"></param>
		private static void CreateFile(int iFileNumber)
		{
			FileInfo fileInfo = new FileInfo(MakeFileName(c_fileName, iFileNumber));

			FileStream fileStream = null;
			try
			{
				fileStream = fileInfo.Create();
			}
			finally
			{
				if (null != fileStream)
				{
					try
					{
						fileStream.Close();
					}
					catch
					{
					}
				}
			}
		}

		/// <summary>
		/// Verifies that the code correctly loads all filenames
		/// </summary>
		[Test]
		public void TestGetExistingFiles()
		{
			VerifyFileCount(0);
			CreateFile(0);
			VerifyFileCount(1);
			CreateFile(1);
			VerifyFileCount(2);
		}

		[Test]
		public void RollingCombinedWithPreserveExtension()
		{
			_root = ((Repository.Hierarchy.Hierarchy)Utils.GetRepository()).Root;
			_root.Level = Level.All;
			PatternLayout patternLayout = new PatternLayout();
			patternLayout.ActivateOptions();

			RollingFileAppender roller = new RollingFileAppender();
			roller.StaticLogFileName = false;
			roller.Layout = patternLayout;
			roller.AppendToFile = true;
			roller.RollingStyle = RollingFileAppender.RollingMode.Composite;
			roller.DatePattern = "dd_MM_yyyy";
			roller.MaxSizeRollBackups = 1;
			roller.CountDirection = 1;
			roller.PreserveLogFileNameExtension = true;
			roller.MaximumFileSize = "10KB";
			roller.File = c_fileName;
			roller.ActivateOptions();
			_root.AddAppender(roller);

			_root.Repository.Configured = true;

			for (int i = 0; i < 1000; i++)
			{
				StringBuilder s = new StringBuilder();
				for (int j = 50; j < 100; j++)
				{
					if (j > 50) {
						s.Append(" ");
					}
					s.Append(j);
				}
				_root.Log(Level.Debug, s.ToString(), null);
			}
			VerifyFileCount(2, true);
		}

		/// <summary>
		/// Removes all test files that exist
		/// </summary>
		private static void DeleteTestFiles()
		{
			ArrayList alFiles = GetExistingFiles(c_fileName);
						alFiles.AddRange(GetExistingFiles(c_fileName, true));
			foreach(string sFile in alFiles)
			{
				try
				{
					Debug.WriteLine("Deleting test file " + sFile);
					File.Delete(sFile);
				}
				catch(Exception ex)
				{
					Debug.WriteLine("Exception while deleting test file " + ex);
				}
			}
		}

		///// <summary>
		///// Generates a file name associated with the count.
		///// </summary>
		///// <param name="iFileCount"></param>
		///// <returns></returns>
		//private string MakeFileName(int iFileCount)
		//{
		//	  return MakeFileName(_fileName, iFileCount);
		//}

		/// <summary>
		/// Generates a file name associated with the count, using
		/// the base file name.
		/// </summary>
		/// <param name="sBaseFile"></param>
		/// <param name="iFileCount"></param>
		/// <returns></returns>
		private static string MakeFileName(string sBaseFile, int iFileCount)
		{
			if (0 == iFileCount)
			{
				return sBaseFile;
			}
			return sBaseFile + "." + iFileCount;
		}

		/// <summary>
		/// Returns a RollingFileAppender using all the internal settings for maximum
		/// file size and number of backups
		/// </summary>
		/// <returns></returns>
		private RollingFileAppender CreateAppender()
		{
			return CreateAppender(new FileAppender.ExclusiveLock());
		}

		/// <summary>
		/// Returns a RollingFileAppender using all the internal settings for maximum
		/// file size and number of backups
		/// </summary>
		/// <param name="lockModel">The locking model to test</param>
		/// <returns></returns>
		private RollingFileAppender CreateAppender(FileAppender.LockingModelBase lockModel)
		{
			//
			// Use a basic pattern that
			// includes just the message and a CR/LF.
			//
			PatternLayout layout = new PatternLayout("%m%n");

			//
			// Create the new appender
			//
			RollingFileAppender appender = new RollingFileAppender();
			appender.Layout = layout;
			appender.File = c_fileName;
			appender.Encoding = Encoding.ASCII;
			appender.MaximumFileSize = c_iMaximumFileSize.ToString();
			appender.MaxSizeRollBackups = _MaxSizeRollBackups;
			appender.CountDirection = _iCountDirection;
			appender.RollingStyle = RollingFileAppender.RollingMode.Size;
			appender.LockingModel = lockModel;

			appender.ActivateOptions();

			return appender;
		}

		/// <summary>
		/// Used for test purposes, a table of these objects can be used to identify
		/// any existing files and their expected length.
		/// </summary>
		public class RollFileEntry
		{
			/// <summary>
			/// Stores the name of the file
			/// </summary>
			private string m_fileName;

			/// <summary>
			/// The expected length of the file
			/// </summary>
			private long m_fileLength;

			/// <summary>
			/// Default constructor
			/// </summary>
			public RollFileEntry()
			{
			}

			/// <summary>
			/// Constructor used when the fileInfo and expected length are known
			/// </summary>
			/// <param name="fileName"></param>
			/// <param name="fileLength"></param>
			public RollFileEntry(string fileName, long fileLength)
			{
				m_fileName = fileName;
				m_fileLength = fileLength;
			}

			/// <summary>
			/// Stores the name of the file
			/// </summary>
			public string FileName
			{
				get { return m_fileName; }
			}

			/// <summary>
			/// The expected length of the file
			/// </summary>
			public long FileLength
			{
				get { return m_fileLength; }
			}
		}

		/// <summary>
		/// Used for table-driven testing.	This class holds information that can be used
		/// for testing of file rolling.
		/// </summary>
		public class RollConditions
		{
			/// <summary>
			/// A table of entries showing files that should exist and their expected sizes
			/// before logging is called
			/// </summary>
			private RollFileEntry[] m_preLogFileEntries;

			/// <summary>
			/// A table of entries showing files that should exist and their expected sizes
			/// after a message is logged
			/// </summary>
			private RollFileEntry[] m_postLogFileEntries;

			/// <summary>
			/// Constructor, taking all required parameters
			/// </summary>
			/// <param name="preLogFileEntries"></param>
			/// <param name="postLogFileEntries"></param>
			public RollConditions(RollFileEntry[] preLogFileEntries, RollFileEntry[] postLogFileEntries)
			{
				m_preLogFileEntries = preLogFileEntries;
				m_postLogFileEntries = postLogFileEntries;
			}

			/// <summary>
			/// A table of entries showing files that should exist and their expected sizes
			/// before logging is called
			/// </summary>
			public RollFileEntry[] GetPreLogFileEntries()
			{
				return m_preLogFileEntries;
			}

			/// <summary>
			/// A table of entries showing files that should exist and their expected sizes
			/// after a message is logged
			/// </summary>
			public RollFileEntry[] GetPostLogFileEntries()
			{
				return m_postLogFileEntries;
			}
		}

		private static void VerifyExistenceAndRemoveFromList(ArrayList alExisting, string sFileName, FileInfo file, RollFileEntry entry)
		{
			Assert.IsTrue(alExisting.Contains(sFileName), "filename {0} not found in test directory", sFileName);
			Assert.AreEqual(entry.FileLength, file.Length, "file length mismatch");
			// Remove this file from the list
			alExisting.Remove(sFileName);
		}

		/// <summary>
		/// Checks that all the expected files exist, and only the expected files.	Also
		/// verifies the length of all files against the expected length
		/// </summary>
		/// <param name="sBaseFileName"></param>
		/// <param name="fileEntries"></param>
		private static void VerifyFileConditions(string sBaseFileName, RollFileEntry[] fileEntries)
		{
			ArrayList alExisting = GetExistingFiles(sBaseFileName);
			if (null != fileEntries)
			{
				//					AssertEquals( "File count mismatch", alExisting.Count, fileEntries.Length );
				foreach(RollFileEntry rollFile in fileEntries)
				{
					string sFileName = rollFile.FileName;
					FileInfo file = new FileInfo(sFileName);

					if (rollFile.FileLength > 0)
					{
						Assert.IsTrue(file.Exists, "filename {0} does not exist", sFileName);
						VerifyExistenceAndRemoveFromList(alExisting, sFileName, file, rollFile);
					}
					else
					{
						// If length is 0, file may not exist yet.	If file exists, make sure length
						// is zero.  If file doesn't exist, this is OK

						if (file.Exists)
						{
							VerifyExistenceAndRemoveFromList(alExisting, sFileName, file, rollFile);
						}
					}
				}
			}
			else
			{
				Assert.AreEqual(0, alExisting.Count);
			}

			// This check ensures no extra files matching the wildcard pattern exist.
			// We only want the files we expect, and no others
			Assert.AreEqual(0, alExisting.Count);
		}

		/// <summary>
		/// Called before logging a message to check that all the expected files exist,
		/// and only the expected files.  Also verifies the length of all files against
		/// the expected length
		/// </summary>
		/// <param name="sBaseFileName"></param>
		/// <param name="entry"></param>
		private static void VerifyPreConditions(string sBaseFileName, RollConditions entry)
		{
			VerifyFileConditions(sBaseFileName, entry.GetPreLogFileEntries());
		}

		/// <summary>
		/// Called after logging a message to check that all the expected files exist,
		/// and only the expected files.  Also verifies the length of all files against
		/// the expected length
		/// </summary>
		/// <param name="sBaseFileName"></param>
		/// <param name="entry"></param>
		private static void VerifyPostConditions(string sBaseFileName, RollConditions entry)
		{
			VerifyFileConditions(sBaseFileName, entry.GetPostLogFileEntries());
		}

		/// <summary>
		/// Logs a message, verifying the expected message counts against the
		/// current running totals.
		/// </summary>
		/// <param name="entry"></param>
		/// <param name="sMessageToLog"></param>
		private void LogMessage(RollConditions entry, string sMessageToLog)
		{
			Assert.AreEqual(_caRoot.Counter, _iMessagesLogged++);
			_root.Log(Level.Debug, sMessageToLog, null);
			Assert.AreEqual(_caRoot.Counter, _iMessagesLogged);
			_iMessagesLoggedThisFile++;
		}

		/// <summary>
		/// Runs through all table entries, logging messages.  Before each message is logged,
		/// pre-conditions are checked to ensure the expected files exist and they are the
		/// expected size.	After logging, verifies the same.
		/// </summary>
		/// <param name="sBaseFileName"></param>
		/// <param name="entries"></param>
		/// <param name="sMessageToLog"></param>
		private void RollFromTableEntries(string sBaseFileName, RollConditions[] entries, string sMessageToLog)
		{
			for(int i = 0; i < entries.Length; i++)
			{
				RollConditions entry = entries[i];

				// System.Diagnostics.Debug.WriteLine( i + ": Entry " + i + " pre/post conditions");
				// DumpTableEntry( entry );
				// System.Diagnostics.Debug.WriteLine( i + ": Testing entry pre-conditions");
				VerifyPreConditions(sBaseFileName, entry);
				// System.Diagnostics.Debug.WriteLine( i + ": Logging message");
				LogMessage(entry, sMessageToLog);
				// System.Diagnostics.Debug.WriteLine( i + ": Testing entry post-conditions");
				VerifyPostConditions(sBaseFileName, entry);
				// System.Diagnostics.Debug.WriteLine( i + ": Finished validating entry\n");
			}
		}

		private static readonly int s_Newline_Length = Environment.NewLine.Length;

		/// <summary>
		/// Returns the number of bytes logged per message, including
		/// any newline characters in addition to the message length.
		/// </summary>
		/// <param name="sMessage"></param>
		/// <returns></returns>
		private static int TotalMessageLength(string sMessage)
		{
			return sMessage.Length + s_Newline_Length;
		}

		/// <summary>
		/// Determines how many messages of a fixed length can be logged
		/// to a single file before the file rolls.
		/// </summary>
		/// <param name="iMessageLength"></param>
		/// <returns></returns>
		private static int MessagesPerFile(int iMessageLength)
		{
			int iMessagesPerFile = c_iMaximumFileSize / iMessageLength;

			//
			// RollingFileAppender checks for wrap BEFORE logging,
			// so we will actually get one more message per file than
			// we would otherwise.
			//
			if (iMessagesPerFile * iMessageLength < c_iMaximumFileSize)
			{
				iMessagesPerFile++;
			}

			return iMessagesPerFile;
		}

		/// <summary>
		/// Determines the name of the current file
		/// </summary>
		/// <returns></returns>
		private static string GetCurrentFile()
		{
			// Current file name is always the base file name when
			// counting.  Dates will need a different approach
			return c_fileName;
		}

		/// <summary>
		/// Turns a group of file names into an array of file entries that include the name
		/// and a size.  This is useful for assigning the properties of backup files, when
		/// the length of the files are all the same size due to a fixed message length.
		/// </summary>
		/// <param name="sBackupGroup"></param>
		/// <param name="iBackupFileLength"></param>
		/// <returns></returns>
		private static RollFileEntry[] MakeBackupFileEntriesFromBackupGroup(string sBackupGroup, int iBackupFileLength)
		{
			string[] sFiles = sBackupGroup.Split(' ');

			ArrayList alEntries = new ArrayList();

			for(int i = 0; i < sFiles.Length; i++)
			{
				// Weed out any whitespace entries from the array
				if (sFiles[i].Trim().Length > 0)
				{
					alEntries.Add(new RollFileEntry(sFiles[i], iBackupFileLength));
				}
			}

			return (RollFileEntry[])alEntries.ToArray(typeof(RollFileEntry));
		}

		/// <summary>
		/// Finds the iGroup group in the string (comma separated groups)
		/// </summary>
		/// <param name="sBackupGroups"></param>
		/// <param name="iGroup"></param>
		/// <returns></returns>
		private static string GetBackupGroup(string sBackupGroups, int iGroup)
		{
			string[] sGroups = sBackupGroups.Split(',');
			return sGroups[iGroup];
		}

		/// <summary>
		/// Builds a collection of file entries based on the file names
		/// specified in a groups string and the max file size from the
		/// stats object
		/// </summary>
		/// <param name="sBackupGroups"></param>
		/// <param name="stats"></param>
		/// <returns></returns>
		private static RollFileEntry[] MakeBackupFileEntriesForPostCondition(string sBackupGroups, RollingStats stats)
		{
			if (0 == stats.NumberOfFileRolls)
			{
				return null; // first round has no previous backups
			}
			string sGroup = GetBackupGroup(sBackupGroups, stats.NumberOfFileRolls - 1);
			return MakeBackupFileEntriesFromBackupGroup(sGroup, stats.MaximumFileSize);
		}


		/// <summary>
		/// This class holds information that is used while we are generating
		/// test data sets
		/// </summary>
		public class RollingStats
		{
			private int iTotalMessageLength;
			private int iMessagesPerFile;
			private int iMessagesThisFile;
			private int iNumberOfFileRolls;

			/// <summary>
			/// Number of total bytes a log file can reach.
			/// </summary>
			public int MaximumFileSize
			{
				get { return TotalMessageLength * MessagesPerFile; }
			}

			/// <summary>
			/// The length of a message, including any CR/LF characters.
			/// This length assumes all messages are a fixed length for
			/// test purposes.
			/// </summary>
			public int TotalMessageLength
			{
				get { return iTotalMessageLength; }
				set { iTotalMessageLength = value; }
			}

			/// <summary>
			/// A count of the number of messages that are logged to each
			/// file.
			/// </summary>
			public int MessagesPerFile
			{
				get { return iMessagesPerFile; }
				set { iMessagesPerFile = value; }
			}

			/// <summary>
			/// Counts how many messages have been logged to the current file
			/// </summary>
			public int MessagesThisFile
			{
				get { return iMessagesThisFile; }
				set { iMessagesThisFile = value; }
			}

			/// <summary>
			/// Counts how many times a file roll has occurred
			/// </summary>
			public int NumberOfFileRolls
			{
				get { return iNumberOfFileRolls; }
				set { iNumberOfFileRolls = value; }
			}
		}

		/// <summary>
		/// The stats are used to keep track of progress while we are algorithmically
		/// generating a table of pre/post condition tests for file rolling.
		/// </summary>
		/// <param name="sTestMessage"></param>
		/// <returns></returns>
		private static RollingStats InitializeStats(string sTestMessage)
		{
			RollingStats rollingStats = new RollingStats();

			rollingStats.TotalMessageLength = TotalMessageLength(sTestMessage);
			rollingStats.MessagesPerFile = MessagesPerFile(rollingStats.TotalMessageLength);
			rollingStats.MessagesThisFile = 0;
			rollingStats.NumberOfFileRolls = 0;

			return rollingStats;
		}

		/// <summary>
		/// Takes an existing array of RollFileEntry objects, creates a new array one element
		/// bigger, and appends the final element to the end.  If the existing entries are
		/// null (no entries), then a one-element array is returned with the final element
		/// as the only entry.
		/// </summary>
		/// <param name="existing"></param>
		/// <param name="final"></param>
		/// <returns></returns>
		private static RollFileEntry[] AddFinalElement(RollFileEntry[] existing, RollFileEntry final)
		{
			int iLength = 1;
			if (null != existing)
			{
				iLength += existing.Length;
			}
			RollFileEntry[] combined = new RollFileEntry[iLength];
			if (null != existing)
			{
				Array.Copy(existing, 0, combined, 0, existing.Length);
			}
			combined[iLength - 1] = final;
			return combined;
		}

		/// <summary>
		/// Generates the pre and post condition arrays from an array of backup files and the
		/// current file / next file.
		/// </summary>
		/// <param name="sBackupFiles"></param>
		/// <param name="preCondition"></param>
		/// <param name="current"></param>
		/// <param name="currentNext"></param>
		/// <param name="rollingStats"></param>
		/// <returns></returns>
		private static RollConditions BuildTableEntry(string sBackupFiles, RollConditions preCondition, RollFileEntry current, RollFileEntry currentNext, RollingStats rollingStats)
		{
			RollFileEntry[] backupsPost = MakeBackupFileEntriesForPostCondition(sBackupFiles, rollingStats);
			RollFileEntry[] post = AddFinalElement(backupsPost, currentNext);
			if (null == preCondition)
			{
				return new RollConditions(AddFinalElement(null, current), post);
			}
			return new RollConditions(preCondition.GetPostLogFileEntries(), post);
		}

		/// <summary>
		/// Returns a RollFileEntry that represents the next state of the current file,
		/// based on the current state.  When the current state would roll, the next
		/// entry is the current file wrapped to 0 bytes.  Otherwise, the next state
		/// is the post-condition passed in as the currentNext parameter
		/// </summary>
		/// <param name="rollingStats"></param>
		/// <param name="currentNext"></param>
		/// <returns></returns>
		private static RollFileEntry MoveNextEntry(RollingStats rollingStats, RollFileEntry currentNext)
		{
			rollingStats.MessagesThisFile = rollingStats.MessagesThisFile + 1;
			if (rollingStats.MessagesThisFile >= rollingStats.MessagesPerFile)
			{
				rollingStats.MessagesThisFile = 0;
				rollingStats.NumberOfFileRolls = rollingStats.NumberOfFileRolls + 1;

				return new RollFileEntry(GetCurrentFile(), 0);
			}
			else
			{
				return currentNext;
			}
		}

		/// <summary>
		/// Callback point for the regular expression parser.  Turns
		/// the number into a file name.
		/// </summary>
		/// <param name="match"></param>
		/// <returns></returns>
		private static string NumberedNameMaker(Match match)
		{
			Int32 iValue = Int32.Parse(match.Value);
			return MakeFileName(c_fileName, iValue);
		}

		/// <summary>
		/// Parses a numeric list of files, turning them into file names.
		/// Calls back to a method that does the actual replacement, turning
		/// the numeric value into a filename.
		/// </summary>
		/// <param name="sBackupInfo"></param>
		/// <param name="evaluator"></param>
		/// <returns></returns>
		private static string ConvertToFiles(string sBackupInfo, MatchEvaluator evaluator)
		{
			Regex regex = new Regex(@"\d+");
			return regex.Replace(sBackupInfo, evaluator);
		}

		/// <summary>
		/// Makes test entries used for verifying counted file names
		/// </summary>
		/// <param name="sTestMessage">A message to log repeatedly</param>
		/// <param name="sBackupInfo">Filename groups used to indicate backup file name progression
		/// that results after each message is logged</param>
		/// <param name="iMessagesToLog">How many times the test message will be repeatedly logged</param>
		/// <returns></returns>
		private static RollConditions[] MakeNumericTestEntries(string sTestMessage, string sBackupInfo, int iMessagesToLog)
		{
			return MakeTestEntries(
				sTestMessage,
				sBackupInfo,
				iMessagesToLog,
				new MatchEvaluator(NumberedNameMaker));
		}

		/// <summary>
		/// This routine takes a list of backup file names and a message that will be logged
		/// repeatedly, and generates a collection of objects containing pre-condition and
		/// post-condition information.  This pre/post information shows the names and expected
		/// file sizes for all files just before and just after a message is logged.
		/// </summary>
		/// <param name="sTestMessage">A message to log repeatedly</param>
		/// <param name="sBackupInfo">Filename groups used to indicate backup file name progression
		/// that results after each message is logged</param>
		/// <param name="iMessagesToLog">How many times the test message will be repeatedly logged</param>
		/// <param name="evaluator">Function that can turn a number into a filename</param>
		/// <returns></returns>
		private static RollConditions[] MakeTestEntries(string sTestMessage, string sBackupInfo, int iMessagesToLog, MatchEvaluator evaluator)
		{
			string sBackupFiles = ConvertToFiles(sBackupInfo, evaluator);

			RollConditions[] table = new RollConditions[iMessagesToLog];

			RollingStats rollingStats = InitializeStats(sTestMessage);

			RollConditions preCondition = null;
			rollingStats.MessagesThisFile = 0;

			RollFileEntry currentFile = new RollFileEntry(GetCurrentFile(), 0);
			for(int i = 0; i < iMessagesToLog; i++)
			{
				RollFileEntry currentNext = new RollFileEntry(
					GetCurrentFile(),
					(1 + rollingStats.MessagesThisFile) * rollingStats.TotalMessageLength);

				table[i] = BuildTableEntry(sBackupFiles, preCondition, currentFile, currentNext, rollingStats);
				preCondition = table[i];

				//System.Diagnostics.Debug.WriteLine( "Message " + i );
				//DumpTableEntry( table[i] );

				currentFile = MoveNextEntry(rollingStats, currentNext);
			}

			return table;
		}

		/// <summary>
		/// Uses the externally defined rolling table to verify rolling names/sizes
		/// </summary>
		/// <remarks>
		/// Pattern is:  check pre-conditions.	Log messages, checking size of current file.
		/// when size exceeds limit, check post conditions.  Can determine from message the
		/// number of messages N that will cause a roll to occur.  Challenge is to verify the
		/// expected files, their sizes, and the names.  For a message of length L, the backups
		/// will be of size (N * L), and the current file will be of size (K * L), where K is
		/// the number of messages that have been logged to this file.
		///
		/// File sizes can be checked algorithmically.
		///
		/// File names are generated using a table driven algorithm, where a number is turned into
		/// the actual filename.
		///
		/// The entries are comma-separated, with spaces between the names.  Each comma indicates
		/// a 'roll', and the group between commas indicates the numbers for all backup files that
		/// occur as a result of the roll.	It is assumed that no backup files exist before a roll
		/// occurs
		/// </remarks>
		/// <param name="table"></param>
		private void VerifyRolling(RollConditions[] table)
		{
			ConfigureRootAppender();
			RollFromTableEntries(c_fileName, table, GetTestMessage());
		}

		/// <summary>
		/// Validates rolling using a fixed number of backup files, with
		/// count direction set to up, so that newer files have higher counts.
		/// Newest = N, Oldest = N-K, where K is the number of backups to allow
		/// and N is the number of times rolling has occurred.
		/// </summary>
		[Test]
		public void TestRollingCountUpFixedBackups()
		{
			//
			// Oldest to newest when reading in a group left-to-right, so 1 2 3 means 1 is the
			// oldest, and 3 is the newest
			//
			string sBackupInfo = "1, 1 2, 1 2 3, 2 3 4, 3 4 5";

			//
			// Count Up
			//
			_iCountDirection = +1;

			//
			// Log 30 messages.  This is 5 groups, 6 checks per group ( 0, 100, 200, 300, 400, 500
			// bytes for current file as messages are logged.
			//
			int iMessagesToLog = 30;

			VerifyRolling(MakeNumericTestEntries(GetTestMessage(), sBackupInfo, iMessagesToLog));
		}

		/// <summary>
		/// Validates rolling using an infinite number of backup files, with
		/// count direction set to up, so that newer files have higher counts.
		/// Newest = N, Oldest = 1, where N is the number of times rolling has
		/// occurred.
		/// </summary>
		[Test]
		public void TestRollingCountUpInfiniteBackups()
		{
			//
			// Oldest to newest when reading in a group left-to-right, so 1 2 3 means 1 is the
			// oldest, and 3 is the newest
			//
			string sBackupInfo = "1, 1 2, 1 2 3, 1 2 3 4, 1 2 3 4 5";

			//
			// Count Up
			//
			_iCountDirection = +1;

			//
			// Infinite backups
			//
			_MaxSizeRollBackups = -1;

			//
			// Log 30 messages.  This is 5 groups, 6 checks per group ( 0, 100, 200, 300, 400, 500
			// bytes for current file as messages are logged.
			//
			int iMessagesToLog = 30;

			VerifyRolling(MakeNumericTestEntries(GetTestMessage(), sBackupInfo, iMessagesToLog));
		}

		/// <summary>
		/// Validates rolling with no backup files, with count direction set to up.
		/// Only the current file should be present, wrapping to 0 bytes once the
		/// previous file fills up.
		/// </summary>
		[Test]
		public void TestRollingCountUpZeroBackups()
		{
			//
			// Oldest to newest when reading in a group left-to-right, so 1 2 3 means 1 is the
			// oldest, and 3 is the newest
			//
			string sBackupInfo = ", , , , ";

			//
			// Count Up
			//
			_iCountDirection = +1;

			//
			// No backups
			//
			_MaxSizeRollBackups = 0;

			//
			// Log 30 messages.  This is 5 groups, 6 checks per group ( 0, 100, 200, 300, 400, 500
			// bytes for current file as messages are logged.
			//
			int iMessagesToLog = 30;

			VerifyRolling(MakeNumericTestEntries(GetTestMessage(), sBackupInfo, iMessagesToLog));
		}


		/// <summary>
		/// Validates rolling using a fixed number of backup files, with
		/// count direction set to down, so that older files have higher counts.
		/// Newest = 1, Oldest = N, where N is the number of backups to allow
		/// </summary>
		[Test]
		public void TestRollingCountDownFixedBackups()
		{
			//
			// Oldest to newest when reading in a group left-to-right, so 1 2 3 means 1 is the
			// oldest, and 3 is the newest
			//
			string sBackupInfo = "1, 1 2, 1 2 3, 1 2 3, 1 2 3";

			//
			// Count Up
			//
			_iCountDirection = -1;

			//
			// Log 30 messages.  This is 5 groups, 6 checks per group ( 0, 100, 200, 300, 400, 500
			// bytes for current file as messages are logged.
			//
			int iMessagesToLog = 30;

			VerifyRolling(MakeNumericTestEntries(GetTestMessage(), sBackupInfo, iMessagesToLog));
		}

		/// <summary>
		/// Validates rolling using an infinite number of backup files, with
		/// count direction set to down, so that older files have higher counts.
		/// Newest = 1, Oldest = N, where N is the number of times rolling has
		/// occurred
		/// </summary>
		[Test]
		public void TestRollingCountDownInfiniteBackups()
		{
			//
			// Oldest to newest when reading in a group left-to-right, so 1 2 3 means 1 is the
			// oldest, and 3 is the newest
			//
			string sBackupInfo = "1, 1 2, 1 2 3, 1 2 3 4, 1 2 3 4 5";

			//
			// Count Down
			//
			_iCountDirection = -1;

			//
			// Infinite backups
			//
			_MaxSizeRollBackups = -1;

			//
			// Log 30 messages.  This is 5 groups, 6 checks per group ( 0, 100, 200, 300, 400, 500
			// bytes for current file as messages are logged.
			//
			int iMessagesToLog = 30;

			VerifyRolling(MakeNumericTestEntries(GetTestMessage(), sBackupInfo, iMessagesToLog));
		}

		/// <summary>
		/// Validates rolling with no backup files, with count direction set to down.
		/// Only the current file should be present, wrapping to 0 bytes once the
		/// previous file fills up.
		/// </summary>
		[Test]
		public void TestRollingCountDownZeroBackups()
		{
			//
			// Oldest to newest when reading in a group left-to-right, so 1 2 3 means 1 is the
			// oldest, and 3 is the newest
			//
			string sBackupInfo = ", , , , ";

			//
			// Count Up
			//
			_iCountDirection = -1;

			//
			// No backups
			//
			_MaxSizeRollBackups = 0;

			//
			// Log 30 messages.  This is 5 groups, 6 checks per group ( 0, 100, 200, 300, 400, 500
			// bytes for current file as messages are logged.
			//
			int iMessagesToLog = 30;

			VerifyRolling(MakeNumericTestEntries(GetTestMessage(), sBackupInfo, iMessagesToLog));
		}

		/// <summary>
		/// Configures the root appender for counting and rolling
		/// </summary>
		private void ConfigureRootAppender()
		{
			_root = ((Repository.Hierarchy.Hierarchy)Utils.GetRepository()).Root;
			_root.Level = Level.Debug;
			_caRoot = new CountingAppender();
			_root.AddAppender(_caRoot);
			Assert.AreEqual(_caRoot.Counter, 0);

			//
			// Set the root appender with a RollingFileAppender
			//
			_root.AddAppender(CreateAppender());

			_root.Repository.Configured = true;
		}

		/// <summary>
		/// Verifies that the current backup index is detected correctly when initializing
		/// </summary>
		/// <param name="sBaseFile"></param>
		/// <param name="alFiles"></param>
		/// <param name="iExpectedCurSizeRollBackups"></param>
		private static void VerifyInitializeRollBackupsFromBaseFile(string sBaseFile, ArrayList alFiles, int iExpectedCurSizeRollBackups)
		{
			InitializeAndVerifyExpectedValue(alFiles, sBaseFile, CreateRollingFileAppender("5,0,1"), iExpectedCurSizeRollBackups);
		}

		/// <summary>
		/// Tests that the current backup index is 0 when no
		/// existing files are seen
		/// </summary>
		[Test]
		public void TestInitializeRollBackups1()
		{
			string sBaseFile = "LogFile.log";
			ArrayList arrFiles = new ArrayList();
			arrFiles.Add("junk1");
			arrFiles.Add("junk1.log");
			arrFiles.Add("junk2.log");
			arrFiles.Add("junk.log.1");
			arrFiles.Add("junk.log.2");

			int iExpectedCurSizeRollBackups = 0;
			VerifyInitializeRollBackupsFromBaseFile(sBaseFile, arrFiles, iExpectedCurSizeRollBackups);
		}

		/// <summary>
		/// Verifies that files are detected when the base file is specified
		/// </summary>
		/// <param name="sBaseFile"></param>
		private static void VerifyInitializeRollBackupsFromBaseFile(string sBaseFile)
		{
			ArrayList alFiles = MakeTestDataFromString(sBaseFile, "0,1,2");

			int iExpectedCurSizeRollBackups = 2;
			VerifyInitializeRollBackupsFromBaseFile(sBaseFile, alFiles, iExpectedCurSizeRollBackups);
		}

		/// <summary>
		/// Verifies that count goes to the highest when counting up
		/// </summary>
		[Test]
		public void TestInitializeCountUpFixed()
		{
			ArrayList alFiles = MakeTestDataFromString("3,4,5");
			int iExpectedValue = 5;
			InitializeAndVerifyExpectedValue(alFiles, c_fileName, CreateRollingFileAppender("3,0,1"), iExpectedValue);
		}

		/// <summary>
		/// Verifies that count goes to the highest when counting up
		/// </summary>
		[Test]
		public void TestInitializeCountUpFixed2()
		{
			ArrayList alFiles = MakeTestDataFromString("0,3");
			int iExpectedValue = 3;
			InitializeAndVerifyExpectedValue(alFiles, c_fileName, CreateRollingFileAppender("3,0,1"), iExpectedValue);
		}

		/// <summary>
		/// Verifies that count stays at 0 for the zero backups case
		/// when counting up
		/// </summary>
		[Test]
		public void TestInitializeCountUpZeroBackups()
		{
			ArrayList alFiles = MakeTestDataFromString("0,3");
			int iExpectedValue = 0;
			InitializeAndVerifyExpectedValue(alFiles, c_fileName, CreateRollingFileAppender("0,0,1"), iExpectedValue);
		}

		/// <summary>
		/// Verifies that count stays at 0 for the zero backups case
		/// when counting down
		/// </summary>
		[Test]
		public void TestInitializeCountDownZeroBackups()
		{
			ArrayList alFiles = MakeTestDataFromString("0,3");
			int iExpectedValue = 0;
			InitializeAndVerifyExpectedValue(alFiles, c_fileName, CreateRollingFileAppender("0,0,-1"), iExpectedValue);
		}


		/// <summary>
		/// Verifies that count goes to the highest when counting up
		/// </summary>
		[Test]
		public void TestInitializeCountDownFixed()
		{
			ArrayList alFiles = MakeTestDataFromString("4,5,6");
			VerifyInitializeDownFixedExpectedValue(alFiles, c_fileName, 0);
		}

		/// <summary>
		/// Verifies that count goes to the highest when counting up
		/// </summary>
		[Test]
		public void TestInitializeCountDownFixed2()
		{
			ArrayList alFiles = MakeTestDataFromString("1,5,6");
			VerifyInitializeDownFixedExpectedValue(alFiles, c_fileName, 1);
		}

		/// <summary>
		/// Verifies that count goes to the highest when counting up
		/// </summary>
		[Test]
		public void TestInitializeCountDownFixed3()
		{
			ArrayList alFiles = MakeTestDataFromString("2,5,6");
			VerifyInitializeDownFixedExpectedValue(alFiles, c_fileName, 2);
		}

		/// <summary>
		/// Verifies that count goes to the highest when counting up
		/// </summary>
		[Test]
		public void TestInitializeCountDownFixed4()
		{
			ArrayList alFiles = MakeTestDataFromString("3,5,6");
			VerifyInitializeDownFixedExpectedValue(alFiles, c_fileName, 3);
		}

		/// <summary>
		/// Verifies that count goes to the highest when counting up
		/// </summary>
		[Test]
		public void TestInitializeCountDownFixed5()
		{
			ArrayList alFiles = MakeTestDataFromString("1,2,3");
			VerifyInitializeDownFixedExpectedValue(alFiles, c_fileName, 3);
		}

		/// <summary>
		/// Verifies that count goes to the highest when counting up
		/// </summary>
		[Test]
		public void TestInitializeCountDownFixed6()
		{
			ArrayList alFiles = MakeTestDataFromString("1,2");
			VerifyInitializeDownFixedExpectedValue(alFiles, c_fileName, 2);
		}

		/// <summary>
		/// Verifies that count goes to the highest when counting up
		/// </summary>
		[Test]
		public void TestInitializeCountDownFixed7()
		{
			ArrayList alFiles = MakeTestDataFromString("2,3");
			VerifyInitializeDownFixedExpectedValue(alFiles, c_fileName, 3);
		}

		private static void InitializeAndVerifyExpectedValue(ArrayList alFiles, string sBaseFile, RollingFileAppender rfa, int iExpectedValue)
		{
			InitializeRollBackups(rfa, sBaseFile, alFiles);
			Assert.AreEqual(iExpectedValue, GetFieldCurSizeRollBackups(rfa));
		}

		/// <summary>
		/// Tests the count down case, with infinite max backups, to see that
		/// initialization of the rolling file appender results in the expected value
		/// </summary>
		/// <param name="alFiles"></param>
		/// <param name="sBaseFile"></param>
		/// <param name="iExpectedValue"></param>
		private static void VerifyInitializeDownInfiniteExpectedValue(ArrayList alFiles, string sBaseFile, int iExpectedValue)
		{
			InitializeAndVerifyExpectedValue(alFiles, sBaseFile, CreateRollingFileAppender("-1,0,-1"), iExpectedValue);
		}

		/// <summary>
		/// Creates a RollingFileAppender with the desired values, where the
		/// values are passed as a comma separated string, with 3 parameters,
		/// m_maxSizeRollBackups, m_curSizeRollBackups, CountDirection
		/// </summary>
		/// <param name="sParams"></param>
		/// <returns></returns>
		private static RollingFileAppender CreateRollingFileAppender(string sParams)
		{
			string[] asParams = sParams.Split(',');
			if (null == asParams || asParams.Length != 3)
			{
				throw new ArgumentOutOfRangeException(sParams, sParams, "Must have 3 comma separated params: MaxSizeRollBackups, CurSizeRollBackups, CountDirection");
			}

			RollingFileAppender rfa = new RollingFileAppender();
			rfa.RollingStyle = RollingFileAppender.RollingMode.Size;
			SetFieldMaxSizeRollBackups(rfa, Int32.Parse(asParams[0].Trim()));
			SetFieldCurSizeRollBackups(rfa, Int32.Parse(asParams[1].Trim()));
			rfa.CountDirection = Int32.Parse(asParams[2].Trim());

			return rfa;
		}

		/// <summary>
		/// Verifies that count goes to the highest when counting down
		/// and infinite backups are selected
		/// </summary>
		[Test]
		public void TestInitializeCountDownInfinite()
		{
			ArrayList alFiles = MakeTestDataFromString("2,3");
			VerifyInitializeDownInfiniteExpectedValue(alFiles, c_fileName, 3);
		}

		/// <summary>
		/// Verifies that count goes to the highest when counting down
		/// and infinite backups are selected
		/// </summary>
		[Test]
		public void TestInitializeCountDownInfinite2()
		{
			ArrayList alFiles = MakeTestDataFromString("2,3,4,5,6,7,8,9,10");
			VerifyInitializeDownInfiniteExpectedValue(alFiles, c_fileName, 10);
		}

		/// <summary>
		/// Verifies that count goes to the highest when counting down
		/// and infinite backups are selected
		/// </summary>
		[Test]
		public void TestInitializeCountDownInfinite3()
		{
			ArrayList alFiles = MakeTestDataFromString("9,10,3,4,5,7,9,6,1,2,8");
			VerifyInitializeDownInfiniteExpectedValue(alFiles, c_fileName, 10);
		}

		/// <summary>
		/// Verifies that count goes to the highest when counting up
		/// and infinite backups are selected
		/// </summary>
		[Test]
		public void TestInitializeCountUpInfinite()
		{
			ArrayList alFiles = MakeTestDataFromString("2,3");
			VerifyInitializeUpInfiniteExpectedValue(alFiles, c_fileName, 3);
		}

		/// <summary>
		/// Verifies that count goes to the highest when counting up
		/// and infinite backups are selected
		/// </summary>
		[Test]
		public void TestInitializeCountUpInfinite2()
		{
			ArrayList alFiles = MakeTestDataFromString("2,3,4,5,6,7,8,9,10");
			VerifyInitializeUpInfiniteExpectedValue(alFiles, c_fileName, 10);
		}

		/// <summary>
		/// Verifies that count goes to the highest when counting up
		/// and infinite backups are selected
		/// </summary>
		[Test]
		public void TestInitializeCountUpInfinite3()
		{
			ArrayList alFiles = MakeTestDataFromString("9,10,3,4,5,7,9,6,1,2,8");
			VerifyInitializeUpInfiniteExpectedValue(alFiles, c_fileName, 10);
		}

		/// <summary>
		/// Creates a logger hierarchy, configures a rolling file appender and returns an ILogger
		/// </summary>
		/// <param name="filename">The filename to log to</param>
		/// <param name="lockModel">The locking model to use.</param>
		/// <param name="handler">The error handler to use.</param>
		/// <returns>A configured ILogger</returns>
		private static ILogger CreateLogger(string filename, FileAppender.LockingModelBase lockModel, IErrorHandler handler)
		{
			return CreateLogger(filename, lockModel, handler, 100000, 0);
		}

		/// <summary>
		/// Creates a logger hierarchy, configures a rolling file appender and returns an ILogger
		/// </summary>
		/// <param name="filename">The filename to log to</param>
		/// <param name="lockModel">The locking model to use.</param>
		/// <param name="handler">The error handler to use.</param>
		/// <param name="maxFileSize">Maximum file size for roll</param>
		/// <param name="maxSizeRollBackups">Maximum number of roll backups</param>
		/// <returns>A configured ILogger</returns>
		private static ILogger CreateLogger(string filename, FileAppender.LockingModelBase lockModel, IErrorHandler handler, int maxFileSize, int maxSizeRollBackups)
		{
			Repository.Hierarchy.Hierarchy h = (Repository.Hierarchy.Hierarchy)LogManager.CreateRepository("TestRepository");

			RollingFileAppender appender = new RollingFileAppender();
			appender.File = filename;
			appender.AppendToFile = false;
			appender.CountDirection = 0;
			appender.RollingStyle = RollingFileAppender.RollingMode.Size;
			appender.MaxFileSize = maxFileSize;
			appender.Encoding = Encoding.ASCII;
			appender.ErrorHandler = handler;
			appender.MaxSizeRollBackups = maxSizeRollBackups;
			if (lockModel != null)
			{
				appender.LockingModel = lockModel;
			}

			PatternLayout layout = new PatternLayout();
			layout.ConversionPattern = "%m%n";
			layout.ActivateOptions();

			appender.Layout = layout;
			appender.ActivateOptions();

			h.Root.AddAppender(appender);
			h.Configured = true;

			ILogger log = h.GetLogger("Logger");
			return log;
		}

		/// <summary>
		/// Destroys the logger hierarchy created by <see cref="RollingFileAppenderTest.CreateLogger"/>
		/// </summary>
		private static void DestroyLogger()
		{
			Repository.Hierarchy.Hierarchy h = (Repository.Hierarchy.Hierarchy)LogManager.GetRepository("TestRepository");
			h.ResetConfiguration();
			//Replace the repository selector so that we can recreate the hierarchy with the same name if necessary
			LoggerManager.RepositorySelector = new DefaultRepositorySelector(typeof(log4net.Repository.Hierarchy.Hierarchy));
		}

		private static void AssertFileEquals(string filename, string contents)
		{
#if NETSTANDARD1_3
			StreamReader sr = new StreamReader(File.Open(filename, FileMode.Open));
#else
			StreamReader sr = new StreamReader(filename);
#endif
			string logcont = sr.ReadToEnd();
			sr.Close();

			Assert.AreEqual(contents, logcont, "Log contents is not what is expected");

			File.Delete(filename);
		}

		/// <summary>
		/// Verifies that logging a message actually produces output
		/// </summary>
		[Test]
		public void TestLogOutput()
		{
			String filename = "test.log";
			SilentErrorHandler sh = new SilentErrorHandler();
			ILogger log = CreateLogger(filename, new FileAppender.ExclusiveLock(), sh);
			log.Log(GetType(), Level.Info, "This is a message", null);
			log.Log(GetType(), Level.Info, "This is a message 2", null);
			DestroyLogger();

			AssertFileEquals(filename, "This is a message" + Environment.NewLine + "This is a message 2" + Environment.NewLine);
			Assert.AreEqual("", sh.Message, "Unexpected error message");
		}

		/// <summary>
		/// Verifies that attempting to log to a locked file fails gracefully
		/// </summary>
		[Test]
		public void TestExclusiveLockFails()
		{
			String filename = "test.log";

			FileStream fs = new FileStream(filename, FileMode.Create, FileAccess.Write, FileShare.None);
			fs.Write(Encoding.ASCII.GetBytes("Test"), 0, 4);

			SilentErrorHandler sh = new SilentErrorHandler();
			ILogger log = CreateLogger(filename, new FileAppender.ExclusiveLock(), sh);
			log.Log(GetType(), Level.Info, "This is a message", null);
			log.Log(GetType(), Level.Info, "This is a message 2", null);
			DestroyLogger();
			fs.Close();

			AssertFileEquals(filename, "Test");
			Assert.AreEqual(sh.Message.Substring(0, 30), "Unable to acquire lock on file", "Expecting an error message");
		}

		/// <summary>
		/// Verifies that attempting to log to a locked file recovers if the lock is released
		/// </summary>
		[Test]
		public void TestExclusiveLockRecovers()
		{
			String filename = "test.log";

			FileStream fs = new FileStream(filename, FileMode.Create, FileAccess.Write, FileShare.None);
			fs.Write(Encoding.ASCII.GetBytes("Test"), 0, 4);

			SilentErrorHandler sh = new SilentErrorHandler();
			ILogger log = CreateLogger(filename, new FileAppender.ExclusiveLock(), sh);
			log.Log(GetType(), Level.Info, "This is a message", null);
			fs.Close();
			log.Log(GetType(), Level.Info, "This is a message 2", null);
			DestroyLogger();

			AssertFileEquals(filename, "This is a message 2" + Environment.NewLine);
			Assert.AreEqual("Unable to acquire lock on file", sh.Message.Substring(0, 30), "Expecting an error message");
		}

		/// <summary>
		/// Verifies that attempting to log to a file with ExclusiveLock really locks the file
		/// </summary>
		[Test]
		public void TestExclusiveLockLocks()
		{
			String filename = "test.log";
			bool locked = false;

			SilentErrorHandler sh = new SilentErrorHandler();
			ILogger log = CreateLogger(filename, new FileAppender.ExclusiveLock(), sh);
			log.Log(GetType(), Level.Info, "This is a message", null);

			try
			{
				FileStream fs = new FileStream(filename, FileMode.Create, FileAccess.Write, FileShare.None);
				fs.Write(Encoding.ASCII.GetBytes("Test"), 0, 4);
				fs.Close();
			}
			catch(IOException e1)
			{
#if MONO
				Assert.AreEqual("Sharing violation on path ", e1.Message.Substring(0, 26), "Unexpected exception");
#else
				Assert.AreEqual("The process cannot access the file ", e1.Message.Substring(0, 35), "Unexpected exception");
#endif
				locked = true;
			}

			log.Log(GetType(), Level.Info, "This is a message 2", null);
			DestroyLogger();

			Assert.IsTrue(locked, "File was not locked");
#if !MONO || MONO_3_5 || MONO_4_0 // at least on Linux with Mono 2.4 exclusive locking doesn't work as one would expect
#if !NET_STANDARD_1_ON_LINUX // exclusive locking doesn't seem to work properly on .NET Core 1.x on Linux
			AssertFileEquals(filename, "This is a message" + Environment.NewLine + "This is a message 2" + Environment.NewLine);
#endif
#endif
			Assert.AreEqual("", sh.Message, "Unexpected error message");
		}


		/// <summary>
		/// Verifies that attempting to log to a locked file fails gracefully
		/// </summary>
		[Test]
		public void TestMinimalLockFails()
		{
			String filename = "test.log";

			FileStream fs = new FileStream(filename, FileMode.Create, FileAccess.Write, FileShare.None);
			fs.Write(Encoding.ASCII.GetBytes("Test"), 0, 4);

			SilentErrorHandler sh = new SilentErrorHandler();
			ILogger log = CreateLogger(filename, new FileAppender.MinimalLock(), sh);
			log.Log(GetType(), Level.Info, "This is a message", null);
			log.Log(GetType(), Level.Info, "This is a message 2", null);
			DestroyLogger();
			fs.Close();

			AssertFileEquals(filename, "Test");
			Assert.AreEqual("Unable to acquire lock on file", sh.Message.Substring(0, 30), "Expecting an error message");
		}

		/// <summary>
		/// Verifies that attempting to log to a locked file recovers if the lock is released
		/// </summary>
		[Test]
		public void TestMinimalLockRecovers()
		{
			String filename = "test.log";

			FileStream fs = new FileStream(filename, FileMode.Create, FileAccess.Write, FileShare.None);
			fs.Write(Encoding.ASCII.GetBytes("Test"), 0, 4);

			SilentErrorHandler sh = new SilentErrorHandler();
			ILogger log = CreateLogger(filename, new FileAppender.MinimalLock(), sh);
			log.Log(GetType(), Level.Info, "This is a message", null);
			fs.Close();
			log.Log(GetType(), Level.Info, "This is a message 2", null);
			DestroyLogger();

			AssertFileEquals(filename, "This is a message 2" + Environment.NewLine);
			Assert.AreEqual("Unable to acquire lock on file", sh.Message.Substring(0, 30), "Expecting an error message");
		}

		/// <summary>
		/// Verifies that attempting to log to a file with MinimalLock doesn't lock the file
		/// </summary>
		[Test]
		public void TestMinimalLockUnlocks()
		{
			String filename = "test.log";
			bool locked;

			SilentErrorHandler sh = new SilentErrorHandler();
			ILogger log = CreateLogger(filename, new FileAppender.MinimalLock(), sh);
			log.Log(GetType(), Level.Info, "This is a message", null);

			locked = true;
			FileStream fs = new FileStream(filename, FileMode.Append, FileAccess.Write, FileShare.None);
			fs.Write(Encoding.ASCII.GetBytes("Test" + Environment.NewLine), 0, 4 + Environment.NewLine.Length);
			fs.Close();

			log.Log(GetType(), Level.Info, "This is a message 2", null);
			DestroyLogger();

			Assert.IsTrue(locked, "File was not locked");
			AssertFileEquals(filename, "This is a message" + Environment.NewLine + "Test" + Environment.NewLine + "This is a message 2" + Environment.NewLine);
			Assert.AreEqual("", sh.Message, "Unexpected error message");
		}

#if !NETCF
		/// <summary>
		/// Verifies that attempting to log to a locked file fails gracefully
		/// </summary>
		[Test]
		public void TestInterProcessLockFails() {
			String filename = "test.log";

			FileStream fs = new FileStream(filename, FileMode.Create, FileAccess.Write, FileShare.None);
			fs.Write(Encoding.ASCII.GetBytes("Test"), 0, 4);

			SilentErrorHandler sh = new SilentErrorHandler();
			ILogger log = CreateLogger(filename, new FileAppender.InterProcessLock(), sh);
			log.Log(GetType(), Level.Info, "This is a message", null);
			log.Log(GetType(), Level.Info, "This is a message 2", null);
			DestroyLogger();
			fs.Close();

			AssertFileEquals(filename, "Test");
			Assert.AreEqual("Unable to acquire lock on file", sh.Message.Substring(0, 30), "Expecting an error message");
		}

		/// <summary>
		/// Verifies that attempting to log to a locked file recovers if the lock is released
		/// </summary>
		[Test]
		public void TestInterProcessLockRecovers() {
			String filename = "test.log";

			FileStream fs = new FileStream(filename, FileMode.Create, FileAccess.Write, FileShare.None);
			fs.Write(Encoding.ASCII.GetBytes("Test"), 0, 4);

			SilentErrorHandler sh = new SilentErrorHandler();
			ILogger log = CreateLogger(filename, new FileAppender.InterProcessLock(), sh);
			log.Log(GetType(), Level.Info, "This is a message", null);
			fs.Close();
			log.Log(GetType(), Level.Info, "This is a message 2", null);
			DestroyLogger();

			AssertFileEquals(filename, "This is a message 2" + Environment.NewLine);
			Assert.AreEqual("Unable to acquire lock on file", sh.Message.Substring(0, 30), "Expecting an error message");
		}

		/// <summary>
		/// Verifies that attempting to log to a file with InterProcessLock really locks the file
		/// </summary>
		[Test]
		public void TestInterProcessLockUnlocks() {
			String filename = "test.log";
			bool locked;

			SilentErrorHandler sh = new SilentErrorHandler();
			ILogger log = CreateLogger(filename, new FileAppender.InterProcessLock(), sh);
			log.Log(GetType(), Level.Info, "This is a message", null);

			locked = true;
			FileStream fs = new FileStream(filename, FileMode.Append, FileAccess.Write, FileShare.ReadWrite);
			fs.Write(Encoding.ASCII.GetBytes("Test" + Environment.NewLine), 0, 4 + Environment.NewLine.Length);
			fs.Close();

			log.Log(GetType(), Level.Info, "This is a message 2", null);
			DestroyLogger();

			Assert.IsTrue(locked, "File was not locked");
			AssertFileEquals(filename, "This is a message" + Environment.NewLine + "Test" + Environment.NewLine + "This is a message 2" + Environment.NewLine);
			Assert.AreEqual("", sh.Message, "Unexpected error message");
		}

		/// <summary>
		/// Verifies that rolling file works
		/// </summary>
		[Test]
		public void TestInterProcessLockRoll()
		{
			String filename = "test.log";

			SilentErrorHandler sh = new SilentErrorHandler();
			ILogger log = CreateLogger(filename, new FileAppender.InterProcessLock(), sh, 1, 2);

			Assert.DoesNotThrow(delegate { log.Log(GetType(), Level.Info, "A", null); });
			Assert.DoesNotThrow(delegate { log.Log(GetType(), Level.Info, "A", null); });
			DestroyLogger();

			AssertFileEquals(filename, "A" + Environment.NewLine);
			AssertFileEquals(filename + ".1", "A" + Environment.NewLine);
			Assert.IsEmpty(sh.Message);
		}
#endif

		/// <summary>
		/// Verify that the default LockModel is ExclusiveLock, to maintain backwards compatibility with previous behaviour
		/// </summary>
		[Test]
		public void TestDefaultLockingModel()
		{
			String filename = "test.log";
			SilentErrorHandler sh = new SilentErrorHandler();
			ILogger log = CreateLogger(filename, null, sh);

			IAppender[] appenders = log.Repository.GetAppenders();
			Assert.AreEqual(1, appenders.Length, "The wrong number of appenders are configured");

			RollingFileAppender rfa = (RollingFileAppender)(appenders[0]);
			Assert.AreEqual(typeof(log4net.Appender.FileAppender.ExclusiveLock), rfa.LockingModel.GetType(), "The LockingModel is of an unexpected type");

			DestroyLogger();
		}

		/// <summary>
		/// Tests the count up case, with infinite max backups , to see that
		/// initialization of the rolling file appender results in the expected value
		/// </summary>
		/// <param name="alFiles"></param>
		/// <param name="sBaseFile"></param>
		/// <param name="iExpectedValue"></param>
		private static void VerifyInitializeUpInfiniteExpectedValue(ArrayList alFiles, string sBaseFile, int iExpectedValue)
		{
			InitializeAndVerifyExpectedValue(alFiles, sBaseFile, CreateRollingFileAppender("-1,0,1"), iExpectedValue);
		}


		/// <summary>
		/// Tests the count down case, with max backups limited to 3, to see that
		/// initialization of the rolling file appender results in the expected value
		/// </summary>
		/// <param name="alFiles"></param>
		/// <param name="sBaseFile"></param>
		/// <param name="iExpectedValue"></param>
		private static void VerifyInitializeDownFixedExpectedValue(ArrayList alFiles, string sBaseFile, int iExpectedValue)
		{
			InitializeAndVerifyExpectedValue(alFiles, sBaseFile, CreateRollingFileAppender("3,0,-1"), iExpectedValue);
		}

		/// <summary>
		/// Turns a string of comma separated numbers into a collection of filenames
		/// generated from the numbers.
		///
		/// Defaults to filename in _fileName variable.
		///
		/// </summary>
		/// <param name="sFileNumbers">Comma separated list of numbers for counted file names</param>
		/// <returns></returns>
		private static ArrayList MakeTestDataFromString(string sFileNumbers)
		{
			return MakeTestDataFromString(c_fileName, sFileNumbers);
		}

		/// <summary>
		/// Turns a string of comma separated numbers into a collection of filenames
		/// generated from the numbers
		///
		/// Uses the input filename.
		/// </summary>
		/// <param name="sFileName">Name of file to combine with numbers when generating counted file names</param>
		/// <param name="sFileNumbers">Comma separated list of numbers for counted file names</param>
		/// <returns></returns>
		private static ArrayList MakeTestDataFromString(string sFileName, string sFileNumbers)
		{
			ArrayList alFiles = new ArrayList();

			string[] sNumbers = sFileNumbers.Split(',');
			foreach(string sNumber in sNumbers)
			{
				Int32 iValue = Int32.Parse(sNumber.Trim());
				alFiles.Add(MakeFileName(sFileName, iValue));
			}

			return alFiles;
		}

		/// <summary>
		/// Tests that the current backup index is correctly detected
		/// for a file with no extension
		/// </summary>
		[Test]
		public void TestInitializeRollBackups2()
		{
			VerifyInitializeRollBackupsFromBaseFile("LogFile");
		}

		/// <summary>
		/// Tests that the current backup index is correctly detected
		/// for a file with a .log extension
		/// </summary>
		[Test]
		public void TestInitializeRollBackups3()
		{
			VerifyInitializeRollBackupsFromBaseFile("LogFile.log");
		}

		/// <summary>
		/// Makes sure that the initialization can detect the backup
		/// number correctly.
		/// </summary>
		/// <param name="iBackups"></param>
		/// <param name="iMaxSizeRollBackups"></param>
		public void VerifyInitializeRollBackups(int iBackups, int iMaxSizeRollBackups)
		{
			string sBaseFile = "LogFile.log";
			ArrayList arrFiles = new ArrayList();
			arrFiles.Add("junk1");
			for(int i = 0; i < iBackups; i++)
			{
				arrFiles.Add(MakeFileName(sBaseFile, i));
			}
			RollingFileAppender rfa = new RollingFileAppender();
			rfa.RollingStyle = RollingFileAppender.RollingMode.Size;
			SetFieldMaxSizeRollBackups(rfa, iMaxSizeRollBackups);
			SetFieldCurSizeRollBackups(rfa, 0);
			InitializeRollBackups(rfa, sBaseFile, arrFiles);

			// iBackups	/ Meaning
			// 0 = none
			// 1 = file.log
			// 2 = file.log.1
			// 3 = file.log.2
			if (0 == iBackups ||
				1 == iBackups)
			{
				Assert.AreEqual(0, GetFieldCurSizeRollBackups(rfa));
			}
			else
			{
				Assert.AreEqual(Math.Min(iBackups - 1, iMaxSizeRollBackups), GetFieldCurSizeRollBackups(rfa));
			}
		}

		/// <summary>
		/// Tests that the current backup index is correctly detected,
		/// and gets no bigger than the max backups setting
		/// </summary>
		[Test]
		public void TestInitializeRollBackups4()
		{
			const int iMaxRollBackups = 5;
			VerifyInitializeRollBackups(0, iMaxRollBackups);
			VerifyInitializeRollBackups(1, iMaxRollBackups);
			VerifyInitializeRollBackups(2, iMaxRollBackups);
			VerifyInitializeRollBackups(3, iMaxRollBackups);
			VerifyInitializeRollBackups(4, iMaxRollBackups);
			VerifyInitializeRollBackups(5, iMaxRollBackups);
			VerifyInitializeRollBackups(6, iMaxRollBackups);
			// Final we cap out at the max value
			VerifyInitializeRollBackups(7, iMaxRollBackups);
			VerifyInitializeRollBackups(8, iMaxRollBackups);
		}

		/// <summary>
		///
		/// </summary>
		[Test, Ignore("Not Implemented: Want to test counted files limited up, to see that others are ?? ignored? deleted?")]
		public void TestInitialization3()
		{
		}

		/// <summary>
		///
		/// </summary>
		[Test, Ignore("Not Implemented: Want to test counted files limited down, to see that others are ?? ignored? deleted?")]
		public void TestInitialization4()
		{
		}

		/// <summary>
		///
		/// </summary>
		[Test, Ignore("Not Implemented: Want to test dated files with a limit, to see that others are ?? ignored? deleted?")]
		public void TestInitialization5()
		{
		}

		/// <summary>
		///
		/// </summary>
		[Test, Ignore("Not Implemented: Want to test dated files with no limit, to see that others are ?? ignored? deleted?")]
		public void TestInitialization6()
		{
		}

		/// <summary>
		///
		/// </summary>
		[Test, Ignore("Not Implemented: Want to test dated files with mixed dates existing, to see that other dates do not matter")]
		public void TestInitialization7()
		{
		}


		//
		// Helper functions to dig into the appender
		//

		private static ArrayList GetExistingFiles(string baseFilePath)
		{
			return GetExistingFiles(baseFilePath, false);
		}

		private static ArrayList GetExistingFiles(string baseFilePath, bool preserveLogFileNameExtension)
		{
			RollingFileAppender appender = new RollingFileAppender();
						appender.PreserveLogFileNameExtension = preserveLogFileNameExtension;
			appender.SecurityContext = NullSecurityContext.Instance;

			return (ArrayList)Utils.InvokeMethod(appender, "GetExistingFiles", baseFilePath);
		}

		private static void InitializeRollBackups(RollingFileAppender appender, string baseFile, ArrayList arrayFiles)
		{
			Utils.InvokeMethod(appender, "InitializeRollBackups", baseFile, arrayFiles);
		}

		private static int GetFieldCurSizeRollBackups(RollingFileAppender appender)
		{
			return (int)Utils.GetField(appender, "m_curSizeRollBackups");
		}

		private static void SetFieldCurSizeRollBackups(RollingFileAppender appender, int val)
		{
			Utils.SetField(appender, "m_curSizeRollBackups", val);
		}

		private static void SetFieldMaxSizeRollBackups(RollingFileAppender appender, int val)
		{
			Utils.SetField(appender, "m_maxSizeRollBackups", val);
		}

		private static string GetTestMessage()
		{
			switch (Environment.NewLine.Length)
			{
				case 2:
					return c_testMessage98Chars;

				case 1:
					return c_testMessage99Chars;

				default:
					throw new Exception("Unexpected Environment.NewLine.Length");
			}
		}
	}

	[TestFixture]
	public class RollingFileAppenderSubClassTest : RollingFileAppender
	{
		[Test]
		public void TestComputeCheckPeriod()
		{
			RollingFileAppender rfa = new RollingFileAppender();

			Assert.AreEqual(RollPoint.TopOfMinute, InvokeComputeCheckPeriod(rfa, ".yyyy-MM-dd HH:mm"), "TopOfMinute pattern");
			Assert.AreEqual(RollPoint.TopOfHour, InvokeComputeCheckPeriod(rfa, ".yyyy-MM-dd HH"), "TopOfHour pattern");
			Assert.AreEqual(RollPoint.HalfDay, InvokeComputeCheckPeriod(rfa, ".yyyy-MM-dd tt"), "HalfDay pattern");
			Assert.AreEqual(RollPoint.TopOfDay, InvokeComputeCheckPeriod(rfa, ".yyyy-MM-dd"), "TopOfDay pattern");
			Assert.AreEqual(RollPoint.TopOfMonth, InvokeComputeCheckPeriod(rfa, ".yyyy-MM"), "TopOfMonth pattern");

			// Test invalid roll point
			Assert.AreEqual(RollPoint.InvalidRollPoint, InvokeComputeCheckPeriod(rfa, "..."), "TopOfMonth pattern");
		}

		private static RollPoint InvokeComputeCheckPeriod(RollingFileAppender rollingFileAppender, string datePattern)
		{
			return (RollPoint)Utils.InvokeMethod(rollingFileAppender, "ComputeCheckPeriod", datePattern);
		}
	}
}
