1
1
import 'dart:io' ;
2
2
3
+ import 'package:file/memory.dart' ;
3
4
import 'package:logger/logger.dart' ;
4
5
import 'package:test/test.dart' ;
5
6
6
- void main () {
7
- var file = File ("${Directory .systemTemp .path }/dart_advanced_logger_test.log" );
8
- var dir = Directory ("${Directory .systemTemp .path }/dart_advanced_logger_dir" );
9
- setUp (() async {
10
- await file.create (recursive: true );
11
- await dir.create (recursive: true );
7
+ var memory = MemoryFileSystem ();
8
+
9
+ class MemoryAdvancedFileOutput extends AdvancedFileOutput {
10
+ MemoryAdvancedFileOutput ({
11
+ required super .path,
12
+ super .maxDelay,
13
+ super .maxFileSizeKB,
14
+ super .writeImmediately,
15
+ super .maxRotatedFilesCount,
16
+ super .fileNameFormatter,
17
+ super .fileSorter,
18
+ super .fileHeader,
19
+ super .fileFooter,
12
20
});
13
21
14
- tearDown (() async {
15
- await file.delete ();
16
- await dir.delete (recursive: true );
22
+ late File _file;
23
+
24
+ get file => _file;
25
+
26
+ @override
27
+ File createFile (String path) {
28
+ return _file = memory.file (path);
29
+ }
30
+ }
31
+
32
+ void main () {
33
+ final fileName = "dart_advanced_logger_test.log" ;
34
+ final dirName = "dart_advanced_logger_dir" ;
35
+
36
+ tearDown (() {
37
+ var file = memory.file (fileName);
38
+ if (file.existsSync ()) {
39
+ file.deleteSync ();
40
+ }
41
+
42
+ var directory = memory.directory (dirName);
43
+ if (directory.existsSync ()) {
44
+ directory.deleteSync (recursive: true );
45
+ }
17
46
});
18
47
19
48
test ('Real file read and write with buffer accumulation' , () async {
20
- var output = AdvancedFileOutput (
21
- path: file.path ,
49
+ var output = MemoryAdvancedFileOutput (
50
+ path: fileName ,
22
51
maxDelay: const Duration (milliseconds: 500 ),
23
52
maxFileSizeKB: 0 ,
24
53
);
@@ -32,12 +61,9 @@ void main() {
32
61
output.output (event1);
33
62
output.output (event2);
34
63
35
- // Wait until buffer is flushed to file
36
- await Future .delayed (const Duration (seconds: 1 ));
37
-
38
64
await output.destroy ();
39
65
40
- var content = await file.readAsString ();
66
+ var content = await output. file.readAsString ();
41
67
expect (
42
68
content,
43
69
allOf (
@@ -50,8 +76,8 @@ void main() {
50
76
51
77
test ('Real file read and write with rotating file names and immediate output' ,
52
78
() async {
53
- var output = AdvancedFileOutput (
54
- path: dir.path ,
79
+ var output = MemoryAdvancedFileOutput (
80
+ path: dirName ,
55
81
writeImmediately: [Level .info],
56
82
);
57
83
await output.init ();
@@ -66,8 +92,7 @@ void main() {
66
92
67
93
await output.destroy ();
68
94
69
- final logFile = File ('${dir .path }/latest.log' );
70
- var content = await logFile.readAsString ();
95
+ var content = await output.file.readAsString ();
71
96
expect (
72
97
content,
73
98
allOf (
@@ -79,8 +104,8 @@ void main() {
79
104
});
80
105
81
106
test ('Rolling files' , () async {
82
- var output = AdvancedFileOutput (
83
- path: dir.path ,
107
+ var output = MemoryAdvancedFileOutput (
108
+ path: dirName ,
84
109
maxFileSizeKB: 1 ,
85
110
);
86
111
await output.init ();
@@ -100,17 +125,16 @@ void main() {
100
125
output.output (event2);
101
126
await output.destroy ();
102
127
103
- final files = dir.listSync ();
104
-
128
+ final files = output.file.parent.listSync ();
105
129
expect (
106
130
files,
107
131
(hasLength (3 )),
108
132
);
109
133
});
110
134
111
135
test ('Rolling files with rotated files deletion' , () async {
112
- var output = AdvancedFileOutput (
113
- path: dir.path ,
136
+ var output = MemoryAdvancedFileOutput (
137
+ path: dirName ,
114
138
maxFileSizeKB: 1 ,
115
139
maxRotatedFilesCount: 1 ,
116
140
);
@@ -120,34 +144,25 @@ void main() {
120
144
output.output (event0);
121
145
await output.destroy ();
122
146
123
- // TODO Find out why test is so flaky with durations <1000ms
124
- // Give the OS a chance to flush to the file system (should reduce flakiness)
125
- await Future .delayed (const Duration (milliseconds: 1000 ));
126
-
127
147
// Start again to roll files on init without waiting for timer tick
128
148
await output.init ();
129
149
final event1 = OutputEvent (LogEvent (Level .fatal, "" ), ["2" * 1500 ]);
130
150
output.output (event1);
131
151
await output.destroy ();
132
152
133
- await Future .delayed (const Duration (milliseconds: 1000 ));
134
-
135
153
// And again for another roll
136
154
await output.init ();
137
155
final event2 = OutputEvent (LogEvent (Level .fatal, "" ), ["3" * 1500 ]);
138
156
output.output (event2);
139
157
await output.destroy ();
140
158
141
- await Future .delayed (const Duration (milliseconds: 1000 ));
142
-
143
- final files = dir.listSync ();
144
-
159
+ final latestFile = output.file;
160
+ final files = latestFile.parent.listSync ();
145
161
// Expect only 2 files: the "latest" that is the current log file
146
162
// and only one rotated file. The first created file should be deleted.
147
163
expect (files, hasLength (2 ));
148
- final latestFile = File ('${dir .path }/latest.log' );
149
- final rotatedFile = dir
150
- .listSync ()
164
+
165
+ final rotatedFile = files
151
166
.whereType <File >()
152
167
.firstWhere ((file) => file.path != latestFile.path);
153
168
expect (await latestFile.readAsString (), contains ("3" ));
@@ -158,8 +173,8 @@ void main() {
158
173
const fileHeader = "TEST-HEADER" ;
159
174
const fileFooter = "TEST-FOOTER" ;
160
175
161
- var output = AdvancedFileOutput (
162
- path: dir.path ,
176
+ var output = MemoryAdvancedFileOutput (
177
+ path: dirName ,
163
178
maxFileSizeKB: 1 ,
164
179
maxRotatedFilesCount: 1 ,
165
180
fileHeader: fileHeader,
@@ -172,23 +187,23 @@ void main() {
172
187
output.output (event0);
173
188
await output.destroy ();
174
189
175
- // Give the OS a chance to flush to the file system (should reduce flakiness)
176
- await Future .delayed (const Duration (milliseconds: 1000 ));
177
-
178
- final latestFile = File ('${dir .path }/latest.log' );
190
+ final latestFile = output.file;
179
191
expect (await latestFile.readAsString (), startsWith (fileHeader));
180
192
expect (await latestFile.readAsString (), endsWith ("$fileFooter \n " ));
181
193
});
182
194
183
195
test ('Rolling files with custom file sorter' , () async {
184
- var output = AdvancedFileOutput (
185
- path: dir.path,
196
+ int fileNameCounter = 0 ;
197
+ var output = MemoryAdvancedFileOutput (
198
+ path: dirName,
186
199
maxFileSizeKB: 1 ,
187
200
maxRotatedFilesCount: 1 ,
188
201
// Define a custom file sorter that sorts files by their length
189
202
// (strange behavior for testing purposes) from the longest to
190
203
// the shortest: the longest file should be deleted first.
191
204
fileSorter: (a, b) => b.lengthSync ().compareTo (a.lengthSync ()),
205
+ // The default uses date time until milliseconds and sometimes this test is faster and would re-use the same name multiple times.
206
+ fileNameFormatter: (timestamp) => "${fileNameCounter ++}.log" ,
192
207
);
193
208
194
209
await output.init ();
@@ -203,31 +218,27 @@ void main() {
203
218
output.output (event1);
204
219
await output.destroy ();
205
220
206
- // Give the OS a chance to flush to the file system (should reduce flakiness)
207
- await Future .delayed (const Duration (milliseconds: 50 ));
208
-
209
221
// And again for another roll
210
222
await output.init ();
211
223
final event2 = OutputEvent (LogEvent (Level .fatal, "" ), ["3" * 1500 ]);
212
224
output.output (event2);
213
225
await output.destroy ();
214
226
215
- final files = dir. listSync () ;
216
-
227
+ final latestFile = output.file ;
228
+ final files = latestFile.parent. listSync ();
217
229
// Expect only 2 files: the "latest" that is the current log file
218
230
// and only one rotated file (the shortest one).
219
231
expect (files, hasLength (2 ));
220
- final latestFile = File ('${dir .path }/latest.log' );
221
- final rotatedFile = dir
222
- .listSync ()
232
+
233
+ final rotatedFile = files
223
234
.whereType <File >()
224
235
.firstWhere ((file) => file.path != latestFile.path);
225
236
expect (await latestFile.readAsString (), contains ("3" ));
226
237
expect (await rotatedFile.readAsString (), contains ("1" ));
227
238
});
228
239
229
240
test ('Flush temporary buffer on destroy' , () async {
230
- var output = AdvancedFileOutput (path: dir.path );
241
+ var output = MemoryAdvancedFileOutput (path: dirName );
231
242
await output.init ();
232
243
233
244
final event0 = OutputEvent (LogEvent (Level .info, "" ), ["Last event" ]);
@@ -238,8 +249,7 @@ void main() {
238
249
239
250
await output.destroy ();
240
251
241
- final logFile = File ('${dir .path }/latest.log' );
242
- var content = await logFile.readAsString ();
252
+ var content = await output.file.readAsString ();
243
253
expect (
244
254
content,
245
255
allOf (
0 commit comments