@@ -49,10 +49,8 @@ func TestFileWatcher_WatchFile(t *testing.T) {
49
49
name : "all updates notified" ,
50
50
fileReader : newMockReader ("test" , "original" , nil ),
51
51
genUpdates : func (reader * mockReader ) {
52
- reader .setData ([]byte ("update 1" ))
53
- reader .waitForRead ()
54
- reader .setData ([]byte ("update 2" ))
55
- reader .waitForRead ()
52
+ reader .setDataAndWaitForRead ([]byte ("update 1" ))
53
+ reader .setDataAndWaitForRead ([]byte ("update 2" ))
56
54
},
57
55
interval : watcherInterval ,
58
56
wantCallbacks : 2 ,
@@ -63,14 +61,10 @@ func TestFileWatcher_WatchFile(t *testing.T) {
63
61
name : "no content changes don't notify" ,
64
62
fileReader : newMockReader ("test" , "original" , nil ),
65
63
genUpdates : func (reader * mockReader ) {
66
- reader .setData ([]byte ("update 1" ))
67
- reader .waitForRead ()
68
- reader .setData ([]byte ("update 2" ))
69
- reader .waitForRead ()
70
- reader .setData ([]byte ("update 2" ))
71
- reader .waitForRead ()
72
- reader .setData ([]byte ("update 2" ))
73
- reader .waitForRead ()
64
+ reader .setDataAndWaitForRead ([]byte ("update 1" ))
65
+ reader .setDataAndWaitForRead ([]byte ("update 2" ))
66
+ reader .setDataAndWaitForRead ([]byte ("update 2" ))
67
+ reader .setDataAndWaitForRead ([]byte ("update 2" ))
74
68
},
75
69
interval : watcherInterval ,
76
70
wantCallbacks : 2 ,
@@ -81,11 +75,8 @@ func TestFileWatcher_WatchFile(t *testing.T) {
81
75
name : "missed update due to slow interval" ,
82
76
fileReader : newMockReader ("test" , "original" , nil ),
83
77
genUpdates : func (reader * mockReader ) {
84
- reader .setData ([]byte ("update 1" ))
85
- // no waiting for the read to happen and performing next update
86
- // reader.waitForRead()
87
- reader .setData ([]byte ("update 2" ))
88
- reader .waitForRead ()
78
+ reader .setData ([]byte ("update 1" )) // no waiting for the read to happen and performing next update
79
+ reader .setDataAndWaitForRead ([]byte ("update 2" ))
89
80
},
90
81
interval : watcherInterval ,
91
82
wantCallbacks : 1 ,
@@ -102,15 +93,12 @@ func TestFileWatcher_WatchFile(t *testing.T) {
102
93
name : "error reading file after start" ,
103
94
fileReader : newMockReader ("test" , "original" , nil ),
104
95
genUpdates : func (reader * mockReader ) {
105
- reader .setData ([]byte ("update 1" ))
106
- reader .waitForRead ()
107
- reader .setErr (errors .New ("error reading file" ))
108
- reader .waitForRead ()
96
+ reader .setDataAndWaitForRead ([]byte ("update 1" ))
97
+ reader .setErrAdnWaitForRead (errors .New ("error reading file" ))
109
98
// stop error
110
- reader .setErr ( nil )
99
+ reader .unsetErr ( )
111
100
// even if an error happens, next updates should be notified
112
- reader .setData ([]byte ("update 2" ))
113
- reader .waitForRead ()
101
+ reader .setDataAndWaitForRead ([]byte ("update 2" ))
114
102
},
115
103
interval : watcherInterval ,
116
104
wantCallbacks : 2 ,
@@ -158,7 +146,7 @@ func TestFileWatcher_WatchFile(t *testing.T) {
158
146
require .False (t , ok )
159
147
}
160
148
161
- tt .fileReader .waitForRead () // Wait for the first read to happen, the one synchronous
149
+ tt .fileReader .waitForRead (got ) // Wait for the first read to happen, the one synchronous
162
150
require .Equal (t , tt .want , string (got ))
163
151
require .NoError (t , err )
164
152
@@ -199,7 +187,7 @@ func TestFileWatcher_WatchFile(t *testing.T) {
199
187
mu1 .Unlock ()
200
188
})
201
189
require .NoError (t , err )
202
- file1 .waitForRead () // Wait for the first read to happen
190
+ file1 .waitForRead ([] byte ( "original1" ) ) // Wait for the first read to happen
203
191
204
192
file2 := newMockReader ("test2" , "original2" , nil )
205
193
got2 , err := fw .WatchFile (file2 , watcherInterval , func (data []byte ) {
@@ -209,14 +197,11 @@ func TestFileWatcher_WatchFile(t *testing.T) {
209
197
mu2 .Unlock ()
210
198
})
211
199
require .NoError (t , err )
212
- file2 .waitForRead () // Wait for the first read to happen
200
+ file2 .waitForRead ([] byte ( "original2" ) ) // Wait for the first read to happen
213
201
214
- file1 .setData ([]byte ("update 1-1" ))
215
- file1 .waitForRead ()
216
- file2 .setData ([]byte ("update 2-1" ))
217
- file2 .waitForRead ()
218
- file1 .setData ([]byte ("update 1-2" ))
219
- file1 .waitForRead ()
202
+ file1 .setDataAndWaitForRead ([]byte ("update 1-1" ))
203
+ file2 .setDataAndWaitForRead ([]byte ("update 2-1" ))
204
+ file1 .setDataAndWaitForRead ([]byte ("update 1-2" ))
220
205
221
206
// ensure no more updates are notified before verifying the results
222
207
cancel ()
@@ -250,7 +235,7 @@ func TestFileWatcher_WatchFile(t *testing.T) {
250
235
muU .Unlock ()
251
236
})
252
237
require .NoError (t , err )
253
- file1 .waitForRead () // Wait for the first read to happen
238
+ file1 .waitForRead ([] byte ( "original" ) ) // Wait for the first read to happen
254
239
255
240
wg := sync.WaitGroup {}
256
241
wg .Add (2 ) // 2 callbacks to be notified
@@ -263,12 +248,10 @@ func TestFileWatcher_WatchFile(t *testing.T) {
263
248
muO .Unlock ()
264
249
})
265
250
require .NoError (t , err )
266
- file1 .waitForRead () // Wait for the first read to happen again
251
+ file1 .waitForRead ([] byte ( "override" ) ) // Wait for the first read to happen again
267
252
268
- file1 .setData ([]byte ("update 1" ))
269
- file1 .waitForRead ()
270
- file1 .setData ([]byte ("update 2" ))
271
- file1 .waitForRead ()
253
+ file1 .setDataAndWaitForRead ([]byte ("update 1" ))
254
+ file1 .setDataAndWaitForRead ([]byte ("update 2" ))
272
255
273
256
// ensure no more updates are notified before verifying the results
274
257
cancel ()
@@ -284,57 +267,90 @@ func TestFileWatcher_WatchFile(t *testing.T) {
284
267
285
268
var _ Reader = (* mockReader )(nil )
286
269
287
- type mockReader struct {
288
- id string
289
- err error
270
+ type (
271
+ mockReader struct {
272
+ id string
273
+ err error
290
274
291
- m sync.Mutex
292
- fileData []byte
275
+ m sync.Mutex
276
+ fileData []byte
293
277
294
- // reads is used to signal that a read happened, it should be buffered to avoid deadlocks.
295
- // It is used to know if a read happened but there's no need to block reads happening if no one is waiting for them.
296
- reads chan struct {}
297
- }
278
+ // reads is used to signal that a read happened, it should be buffered to avoid deadlocks.
279
+ // It is used to know if a read happened but there's no need to block reads happening if no one is waiting for them.
280
+ reads chan msg
281
+ }
282
+
283
+ msg struct {
284
+ data []byte
285
+ err error
286
+ }
287
+ )
298
288
299
289
func newMockReader (id , data string , err error ) * mockReader {
300
290
return & mockReader {
301
291
id : id ,
302
292
fileData : []byte (data ),
303
293
err : err ,
304
- reads : make (chan struct {} , 50 ),
294
+ reads : make (chan msg , 50 ),
305
295
}
306
296
}
307
297
298
+ // Implement Reader interface
308
299
func (m * mockReader ) ID () string {
309
300
return m .id
310
301
}
311
302
303
+ // Implement Reader interface
312
304
func (m * mockReader ) Read () ([]byte , error ) {
313
- // Notify that a read happened
314
- defer func () { m .reads <- struct {}{} }()
315
-
316
305
m .m .Lock ()
317
306
defer m .m .Unlock ()
318
307
308
+ // Notify that a read happened
309
+ defer func () { m .reads <- msg {data : m .fileData , err : m .err } }()
310
+
319
311
if m .err != nil {
320
312
return nil , m .err
321
313
}
322
314
323
315
return m .fileData , nil
324
316
}
325
317
318
+ // setData sets the data to be read.
326
319
func (m * mockReader ) setData (data []byte ) {
327
320
m .m .Lock ()
328
321
defer m .m .Unlock ()
329
322
m .fileData = data
330
323
}
331
324
332
- func (m * mockReader ) setErr (err error ) {
325
+ // setDataAndWaitForRead sets the data and waits for the read to happen with the given data.
326
+ func (m * mockReader ) setDataAndWaitForRead (data []byte ) {
327
+ m .setData (data )
328
+ m .waitForRead (data )
329
+ }
330
+
331
+ // waitForRead waits for the given data to be read.
332
+ func (m * mockReader ) waitForRead (data []byte ) {
333
+ readData := <- m .reads // wait for at least first read
334
+ for string (readData .data ) != string (data ) {
335
+ readData = <- m .reads
336
+ }
337
+ }
338
+
339
+ // setErrAndWaitForRead sets the error and waits for the read to happen with the given error.
340
+ func (m * mockReader ) setErrAdnWaitForRead (err error ) {
333
341
m .m .Lock ()
334
- defer m .m .Unlock ()
335
342
m .err = err
343
+ m .m .Unlock ()
344
+
345
+ readData := <- m .reads // wait for at least first read
346
+ for ! errors .Is (err , readData .err ) {
347
+ readData = <- m .reads
348
+ }
336
349
}
337
350
338
- func (m * mockReader ) waitForRead () {
339
- <- m .reads
351
+ // unsetErr unsets the error to stop the mockReader to fail on Read().
352
+ func (m * mockReader ) unsetErr () {
353
+ m .m .Lock ()
354
+ defer m .m .Unlock ()
355
+ m .err = nil
340
356
}
0 commit comments