1
1
import { MongoLogManager , mongoLogId } from '.' ;
2
2
import { ObjectId } from 'bson' ;
3
3
import { once } from 'events' ;
4
+ import type { Stats } from 'fs' ;
4
5
import { promises as fs } from 'fs' ;
5
6
import path from 'path' ;
6
7
import os from 'os' ;
@@ -27,6 +28,7 @@ describe('MongoLogManager', function () {
27
28
} ) ;
28
29
afterEach ( async function ( ) {
29
30
await fs . rmdir ( directory , { recursive : true } ) ;
31
+ sinon . restore ( ) ;
30
32
} ) ;
31
33
32
34
it ( 'allows creating and writing to log files' , async function ( ) {
@@ -124,6 +126,58 @@ describe('MongoLogManager', function () {
124
126
expect ( await getFilesState ( paths ) ) . to . equal ( '0000011111' ) ;
125
127
} ) ;
126
128
129
+ it ( 'if fs.stat fails, it errors and is not considered towards the logs limit' , async function ( ) {
130
+ const manager = new MongoLogManager ( {
131
+ directory,
132
+ retentionDays,
133
+ retentionGB : 3 ,
134
+ onwarn,
135
+ onerror,
136
+ } ) ;
137
+
138
+ const offset = Math . floor ( Date . now ( ) / 1000 ) ;
139
+
140
+ const faultyFile = path . join (
141
+ directory ,
142
+ ObjectId . createFromTime ( offset - 10 ) . toHexString ( ) + '_log'
143
+ ) ;
144
+ await fs . writeFile ( faultyFile , '' ) ;
145
+
146
+ const faultyFileError = new Error ( 'test error' ) ;
147
+
148
+ const validFiles : string [ ] = [ ] ;
149
+ // Create 5 valid files.
150
+ for ( let i = 5 ; i >= 0 ; i -- ) {
151
+ const filename = path . join (
152
+ directory ,
153
+ ObjectId . createFromTime ( offset - i ) . toHexString ( ) + '_log'
154
+ ) ;
155
+ await fs . writeFile ( filename , '' ) ;
156
+ validFiles . push ( filename ) ;
157
+ }
158
+
159
+ expect ( onerror ) . not . called ;
160
+
161
+ const fsStatStub = sinon . stub ( fs , 'stat' ) ;
162
+
163
+ fsStatStub . resolves ( {
164
+ size : 1024 * 1024 * 1024 ,
165
+ } as Stats ) ;
166
+ fsStatStub . withArgs ( faultyFile ) . rejects ( faultyFileError ) ;
167
+
168
+ await manager . cleanupOldLogFiles ( ) ;
169
+
170
+ expect ( onerror ) . calledOnceWithExactly ( faultyFileError , faultyFile ) ;
171
+
172
+ // fs.stat is stubbed so getFilesState will not be accurate.
173
+ const leftoverFiles = ( await fs . readdir ( directory ) )
174
+ . sort ( )
175
+ . map ( ( file ) => path . join ( directory , file ) ) ;
176
+
177
+ expect ( leftoverFiles ) . to . have . lengthOf ( 4 ) ;
178
+ expect ( leftoverFiles ) . deep . equals ( [ faultyFile , ...validFiles . slice ( 3 ) ] ) ;
179
+ } ) ;
180
+
127
181
it ( 'cleans up least recent log files when requested with a storage limit' , async function ( ) {
128
182
const manager = new MongoLogManager ( {
129
183
directory,
0 commit comments