1+ #region Apache License
2+ //
3+ // Licensed to the Apache Software Foundation (ASF) under one or more
4+ // contributor license agreements. See the NOTICE file distributed with
5+ // this work for additional information regarding copyright ownership.
6+ // The ASF licenses this file to you under the Apache License, Version 2.0
7+ // (the "License"); you may not use this file except in compliance with
8+ // the License. You may obtain a copy of the License at
9+ //
10+ // http://www.apache.org/licenses/LICENSE-2.0
11+ //
12+ // Unless required by applicable law or agreed to in writing, software
13+ // distributed under the License is distributed on an "AS IS" BASIS,
14+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+ // See the License for the specific language governing permissions and
16+ // limitations under the License.
17+ //
18+ #endregion
19+
120using System ;
2- using System . IO ;
321using System . Collections . Generic ;
22+ using System . IO ;
423using System . Linq ;
5- using log4net ;
24+ using log4net . Appender ;
625using log4net . Config ;
26+ using log4net . Repository ;
727using NUnit . Framework ;
828
929namespace log4net . Tests . Integration
@@ -13,8 +33,9 @@ namespace log4net.Tests.Integration
1333 /// <para>
1434 /// Expectations for test log files and directories:
1535 /// <list type="bullet">
16- /// <item>Test log files may be placed directly in the test directory with names starting with <c>TestLogFilePrefix</c>, or inside directories whose names start with <c>TestLogDirectoryPrefix</c> and may have arbitrary file names.</item>
17- /// <item>Each test run starts with a clean environment: any files or directories from previous runs matching these prefixes are deleted in <c>SetUp</c>.</item>
36+ /// <item>Test log files may be placed directly in the test directory with names starting with <see cref="TestLogFilePrefix"/>,
37+ /// or inside directories whose names start with <see cref="TestLogDirectoryPrefix"/> and may have arbitrary file names.</item>
38+ /// <item>Each test run starts with a clean environment: any files or directories from previous runs matching these prefixes are deleted in <see cref="SetUp"/>.</item>
1839 /// <item>Tests assert the existence, count, and content of log files and directories as part of their validation.</item>
1940 /// </list>
2041 /// </para>
@@ -44,16 +65,16 @@ public void SetUp()
4465 [ Test ]
4566 public void Log4Net_WritesLogFile_AndContentIsCorrect ( )
4667 {
47- var ( log , repo ) = ArrangeLogger ( "log4net.integration.basic.config" ) ;
48- log . Info ( "Hello integration test" ) ;
49- log . Error ( "This is an error" ) ;
50- repo . Shutdown ( ) ;
68+ ( ILog log , ILoggerRepository repo ) = ArrangeLogger ( "log4net.integration.basic.config" ) ;
69+ log . Info ( "Hello integration test" ) ;
70+ log . Error ( "This is an error" ) ;
71+ repo . Shutdown ( ) ;
5172
52- // Assert: log file exists and contains expected content
53- string [ ] logLines = File . ReadAllLines ( "integrationTestLogFile_integration.log" ) ;
54- Assert . That ( logLines . Length , Is . EqualTo ( 2 ) ) ;
55- Assert . That ( logLines [ 0 ] , Does . Contain ( "Hello integration test" ) ) ;
56- Assert . That ( logLines [ 1 ] , Does . Contain ( "This is an error" ) ) ;
73+ // Assert: log file exists and contains expected content
74+ string [ ] logLines = File . ReadAllLines ( "integrationTestLogFile_integration.log" ) ;
75+ Assert . That ( logLines , Has . Length . EqualTo ( 2 ) ) ;
76+ Assert . That ( logLines [ 0 ] , Does . Contain ( "Hello integration test" ) ) ;
77+ Assert . That ( logLines [ 1 ] , Does . Contain ( "This is an error" ) ) ;
5778 }
5879
5980 /// <summary>
@@ -67,21 +88,21 @@ public void Log4Net_WritesLogFile_AndContentIsCorrect()
6788 [ Test ]
6889 public void Log4Net_WritesLogFile_AndContentIsCorrectAfterRestart ( )
6990 {
70- for ( int i = 0 ; i < 10 ; i ++ )
71- {
72- var ( log , repo ) = ArrangeLogger ( "log4net.integration.basic.config" ) ;
73- log . Info ( "Hello integration test" ) ;
74- log . Error ( "This is an error" ) ;
75- repo . Shutdown ( ) ;
76- }
77- // Assert: log file exists and contains expected content
78- string [ ] logLines = File . ReadAllLines ( "integrationTestLogFile_integration.log" ) ;
79- Assert . That ( logLines . Length , Is . EqualTo ( 20 ) ) ;
80- for ( int i = 0 ; i < 10 ; i ++ )
81- {
82- Assert . That ( logLines [ i * 2 ] , Does . Contain ( "Hello integration test" ) ) ;
83- Assert . That ( logLines [ i * 2 + 1 ] , Does . Contain ( "This is an error" ) ) ;
84- }
91+ for ( int i = 0 ; i < 10 ; i ++ )
92+ {
93+ ( ILog log , ILoggerRepository repo ) = ArrangeLogger ( "log4net.integration.basic.config" ) ;
94+ log . Info ( "Hello integration test" ) ;
95+ log . Error ( "This is an error" ) ;
96+ repo . Shutdown ( ) ;
97+ }
98+ // Assert: log file exists and contains expected content
99+ string [ ] logLines = File . ReadAllLines ( "integrationTestLogFile_integration.log" ) ;
100+ Assert . That ( logLines , Has . Length . EqualTo ( 20 ) ) ;
101+ for ( int i = 0 ; i < 10 ; i ++ )
102+ {
103+ Assert . That ( logLines [ i * 2 ] , Does . Contain ( "Hello integration test" ) ) ;
104+ Assert . That ( logLines [ i * 2 + 1 ] , Does . Contain ( "This is an error" ) ) ;
105+ }
85106 }
86107
87108 /// <summary>
@@ -96,18 +117,18 @@ public void Log4Net_WritesLogFile_AndContentIsCorrectAfterRestart()
96117 [ Test ]
97118 public void Log4Net_WritesLogFile_WithRollAndNoAppend_AndContentIsCorrectAfterRestart ( )
98119 {
99- for ( int i = 0 ; i < 20 ; i ++ )
120+ for ( int i = 0 ; i < 20 ; i ++ )
121+ {
122+ ( ILog log , ILoggerRepository repo ) = ArrangeLogger ( "log4net.roll.config" ) ;
123+ for ( int j = 0 ; j < 10 ; ++ j )
100124 {
101- var ( log , repo ) = ArrangeLogger ( "log4net.roll.config" ) ;
102- for ( int j = 0 ; j < 10 ; ++ j )
103- {
104- log . Info ( $ "Hello, log4net! { i } { j } ") ;
105- }
106- repo . Shutdown ( ) ;
125+ log . Info ( $ "Hello, log4net! { i } { j } ") ;
107126 }
108- // Assert: log file exists and contains expected content
109- string [ ] logFiles = Directory . GetFiles ( "integrationTestLogDir_roll" ) ;
110- Assert . That ( logFiles . Length , Is . EqualTo ( 12 + 1 ) ) ;
127+ repo . Shutdown ( ) ;
128+ }
129+ // Assert: log file exists and contains expected content
130+ string [ ] logFiles = Directory . GetFiles ( "integrationTestLogDir_roll" ) ;
131+ Assert . That ( logFiles , Has . Length . EqualTo ( 12 + 1 ) ) ;
111132 }
112133
113134 /// <summary>
@@ -122,21 +143,19 @@ public void Log4Net_WritesLogFile_WithRollAndNoAppend_AndContentIsCorrectAfterRe
122143 [ Test ]
123144 public void Log4Net_WritesLogFile_WithMaxSizeRoll_Config_Works ( )
124145 {
125- string logDir = Path . Combine ( TestContext . CurrentContext . TestDirectory , "integrationTestLogDir_maxsizeroll" ) ;
126- if ( Directory . Exists ( logDir ) ) Directory . Delete ( logDir , true ) ;
127- Directory . CreateDirectory ( logDir ) ;
128- var ( log , repo ) = ArrangeLogger ( "log4net.maxsizeroll.config" ) ;
129- for ( int i = 0 ; i < 1000 ; ++ i )
130- {
131- log . Info ( $ "Log entry { i } ") ;
132- }
133- repo . Shutdown ( ) ;
134- // Assert: rolled files exist
135- string [ ] logFiles = Directory . GetFiles ( logDir , "*.log" ) ;
136- Assert . That ( logFiles . Length , Is . EqualTo ( 4 ) ) ; // 1 current + 3 backups
137- // Optionally, check that each file is <= 10KB
138- foreach ( var file in logFiles )
139- Assert . That ( new FileInfo ( file ) . Length , Is . LessThanOrEqualTo ( 10 * 1024 + 100 ) ) ;
146+ DirectoryInfo logDir = CreateLogDirectory ( "integrationTestLogDir_maxsizeroll" ) ;
147+ ( ILog log , ILoggerRepository repo ) = ArrangeLogger ( "log4net.maxsizeroll.config" ) ;
148+ for ( int i = 0 ; i < 1000 ; ++ i )
149+ {
150+ log . Info ( $ "Log entry { i } ") ;
151+ }
152+ repo . Shutdown ( ) ;
153+ // Assert: rolled files exist
154+ FileInfo [ ] logFiles = logDir . GetFiles ( "*.log" ) ;
155+ Assert . That ( logFiles , Has . Length . EqualTo ( 4 ) ) ; // 1 current + 3 backups
156+ // Check that each file is <= 10KB
157+ foreach ( FileInfo file in logFiles )
158+ Assert . That ( file . Length , Is . LessThanOrEqualTo ( 10 * 1024 + 100 ) ) ;
140159 }
141160
142161 /// <summary>
@@ -152,32 +171,35 @@ public void Log4Net_WritesLogFile_WithMaxSizeRoll_Config_Works()
152171 [ Test ]
153172 public void Log4Net_WritesLogFile_WithDateAndSizeRoll_Config_Works ( )
154173 {
155- string logDir = Path . Combine ( TestContext . CurrentContext . TestDirectory , "integrationTestLogDir_maxsizerolldate" ) ;
156- if ( Directory . Exists ( logDir ) ) Directory . Delete ( logDir , true ) ;
157- Directory . CreateDirectory ( logDir ) ;
158- var ( log , repo ) = ArrangeLogger ( "log4net.maxsizeroll_date.config" ) ;
159- // Write enough lines to trigger rolling by size and date
160- for ( int i = 1 ; i < 10000 ; ++ i )
161- {
162- log . Debug ( $ "DateRoll entry { i } ") ;
163- if ( i % 5000 == 0 ) System . Threading . Thread . Sleep ( TimeSpan . FromMinutes ( 1 ) ) ; // allow time for date to change if needed
164- }
165- repo . Shutdown ( ) ;
166- // Assert: rolled files exist (date+size pattern)
167- string [ ] logFiles = Directory . GetFiles ( logDir , "*.log" ) ;
168- Assert . That ( logFiles . Length , Is . EqualTo ( 8 ) ) ;
169- // Group files by date part in the filename (yyyy-MM-dd-mm)
170- var dateGroups = logFiles
171- . Select ( f => Path . GetFileNameWithoutExtension ( f ) )
172- . Select ( name => name . Split ( '.' ) . First ( ) )
173- . GroupBy ( date => date )
174- . ToDictionary ( g => g . Key , g => g . Count ( ) ) ;
175- // Assert that at least one group exists and print group counts
176- Assert . That ( dateGroups . Count , Is . EqualTo ( 2 ) ) ;
177- foreach ( var group in dateGroups )
174+ DirectoryInfo logDir = CreateLogDirectory ( "integrationTestLogDir_maxsizerolldate" ) ;
175+ ( ILog log , ILoggerRepository repo ) = ArrangeLogger ( "log4net.maxsizeroll_date.config" ) ;
176+ MockDateTime mockDateTime = new ( ) ;
177+ repo . GetAppenders ( ) . OfType < RollingFileAppender > ( ) . First ( ) . DateTimeStrategy = mockDateTime ;
178+ // Write enough lines to trigger rolling by size and date
179+ for ( int i = 1 ; i < 10000 ; ++ i )
180+ {
181+ log . Debug ( $ "DateRoll entry { i } ") ;
182+ if ( i % 5000 == 0 )
178183 {
179- TestContext . Out . WriteLine ( $ "Date group: { group . Key } , file count: { group . Value } " ) ;
184+ mockDateTime . Offset = TimeSpan . FromMinutes ( 1 ) ; // allow time for date to change if needed
180185 }
186+ }
187+ repo . Shutdown ( ) ;
188+ // Assert: rolled files exist (date+size pattern)
189+ FileInfo [ ] logFiles = logDir . GetFiles ( "*.log" ) ;
190+ Assert . That ( logFiles , Has . Length . EqualTo ( 8 ) ) ;
191+ // Group files by date part in the filename (yyyy-MM-dd-mm)
192+ Dictionary < string , int > dateGroups = logFiles
193+ . Select ( f => Path . GetFileNameWithoutExtension ( f . Name ) )
194+ . Select ( name => name . Split ( '.' ) . First ( ) )
195+ . GroupBy ( date => date )
196+ . ToDictionary ( g => g . Key , g => g . Count ( ) ) ;
197+ // Assert that at least one group exists and print group counts
198+ Assert . That ( dateGroups , Has . Count . EqualTo ( 2 ) ) ;
199+ foreach ( KeyValuePair < string , int > group in dateGroups )
200+ {
201+ TestContext . Out . WriteLine ( $ "Date group: { group . Key } , file count: { group . Value } ") ;
202+ }
181203 }
182204
183205 /// <summary>
@@ -192,53 +214,61 @@ public void Log4Net_WritesLogFile_WithDateAndSizeRoll_Config_Works()
192214 [ Test ]
193215 public void Log4Net_ConfigWithoutFileName_CreatesOneFile ( )
194216 {
195- string logDir = Path . Combine ( TestContext . CurrentContext . TestDirectory , "integrationTestLogDir_no_file_name" ) ;
196- if ( Directory . Exists ( logDir ) ) Directory . Delete ( logDir , true ) ;
197- Directory . CreateDirectory ( logDir ) ;
198- var ( log , repo ) = ArrangeLogger ( "log4net.no_file_name.config" ) ;
199- log . Info ( "Test entry with no file name" ) ;
200- repo . Shutdown ( ) ;
201- // Assert: exactly one log file was created in the directory
202- var files = Directory . GetFiles ( logDir , "*" , SearchOption . AllDirectories ) ;
203- Assert . That ( files . Length , Is . EqualTo ( 1 ) , "Should create exactly one log file" ) ;
204- var fileName = Path . GetFileName ( files [ 0 ] ) ;
205- TestContext . Out . WriteLine ( $ "Created file: { fileName } ") ;
206- // Assert the file name matches the date pattern yyyy-MM-dd.log
207- string todayPattern = DateTime . Now . ToString ( "yyyy-MM-dd" ) + ".log" ;
208- Assert . That ( fileName , Is . EqualTo ( todayPattern ) , $ "File name should match pattern: { todayPattern } ") ;
217+ DirectoryInfo logDir = CreateLogDirectory ( "integrationTestLogDir_no_file_name" ) ;
218+ ( ILog log , ILoggerRepository repo ) = ArrangeLogger ( "log4net.no_file_name.config" ) ;
219+ log . Info ( "Test entry with no file name" ) ;
220+ repo . Shutdown ( ) ;
221+ // Assert: exactly one log file was created in the directory
222+ FileInfo [ ] files = logDir . GetFiles ( "*" , SearchOption . AllDirectories ) ;
223+ Assert . That ( files , Has . Length . EqualTo ( 1 ) , "Should create exactly one log file" ) ;
224+ TestContext . Out . WriteLine ( $ "Created file: { files [ 0 ] . Name } ") ;
225+ // Assert the file name matches the date pattern yyyy-MM-dd.log
226+ string todayPattern = DateTime . Now . ToString ( "yyyy-MM-dd" ) + ".log" ;
227+ Assert . That ( files [ 0 ] . Name , Is . EqualTo ( todayPattern ) , $ "File name should match pattern: { todayPattern } ") ;
228+ }
229+
230+ private static DirectoryInfo CreateLogDirectory ( string name )
231+ {
232+ DirectoryInfo logDir = new ( Path . Combine ( TestContext . CurrentContext . TestDirectory , name ) ) ;
233+ if ( logDir . Exists )
234+ {
235+ logDir . Delete ( true ) ;
236+ }
237+ logDir . Create ( ) ;
238+ return logDir ;
209239 }
210240
211241 private const string TestLogFilePrefix = "integrationTestLogFile" ;
212242 private const string TestLogDirectoryPrefix = "integrationTestLogDir" ;
213243
214244 private static void RemoveDirsFromPreviousRuns ( )
215245 {
216- List < string > directoriesFromPreviousRuns =
217- Directory . EnumerateDirectories ( TestContext . CurrentContext . TestDirectory )
218- . Where ( dirPath => Path . GetFileName ( dirPath ) . StartsWith ( TestLogDirectoryPrefix , StringComparison . InvariantCultureIgnoreCase ) )
219- . ToList ( ) ;
220- directoriesFromPreviousRuns . ForEach ( d => Directory . Delete ( d , true ) ) ;
246+ List < DirectoryInfo > directoriesFromPreviousRuns = new DirectoryInfo ( TestContext . CurrentContext . TestDirectory )
247+ . EnumerateDirectories ( )
248+ . Where ( directory => directory . Name . StartsWith ( TestLogDirectoryPrefix , StringComparison . InvariantCultureIgnoreCase ) )
249+ . ToList ( ) ;
250+ directoriesFromPreviousRuns . ForEach ( d => d . Delete ( true ) ) ;
221251 }
222252
223253 private static void RemoveFilesFromPreviousRuns ( )
224254 {
225- List < string > filesFromPreviousRuns =
226- Directory . EnumerateFiles ( TestContext . CurrentContext . TestDirectory )
227- . Where ( filePath => Path . GetFileName ( filePath ) . StartsWith ( TestLogFilePrefix , StringComparison . InvariantCultureIgnoreCase ) )
228- . ToList ( ) ;
229- filesFromPreviousRuns . ForEach ( File . Delete ) ;
255+ List < FileInfo > filesFromPreviousRuns = new DirectoryInfo ( TestContext . CurrentContext . TestDirectory )
256+ . EnumerateFiles ( )
257+ . Where ( filePath => filePath . Name . StartsWith ( TestLogFilePrefix , StringComparison . InvariantCultureIgnoreCase ) )
258+ . ToList ( ) ;
259+ filesFromPreviousRuns . ForEach ( file => file . Delete ( ) ) ;
230260 }
231261
232262 private static string GetConfigPath ( string configFile )
233263 => Path . Combine ( TestContext . CurrentContext . TestDirectory , "Integration" , configFile ) ;
234264
235- private static ( ILog log , log4net . Repository . ILoggerRepository repo ) ArrangeLogger ( string configFile )
265+ private static ( ILog log , ILoggerRepository repo ) ArrangeLogger ( string configFile )
236266 {
237- string configPath = GetConfigPath ( configFile ) ;
238- var repo = LogManager . CreateRepository ( Guid . NewGuid ( ) . ToString ( ) ) ;
239- XmlConfigurator . Configure ( repo , new FileInfo ( configPath ) ) ;
240- var log = LogManager . GetLogger ( repo . Name , "IntegrationTestLogger" ) ;
241- return ( log , repo ) ;
267+ string configPath = GetConfigPath ( configFile ) ;
268+ ILoggerRepository repo = LogManager . CreateRepository ( Guid . NewGuid ( ) . ToString ( ) ) ;
269+ XmlConfigurator . Configure ( repo , new FileInfo ( configPath ) ) ;
270+ ILog log = LogManager . GetLogger ( repo . Name , "IntegrationTestLogger" ) ;
271+ return ( log , repo ) ;
242272 }
243273 }
244- }
274+ }
0 commit comments