@@ -286,6 +286,100 @@ func TestCtrlCWhenREngineIsRunning(t *testing.T) {
286
286
assert .False (t , engine .running )
287
287
}
288
288
289
+ func TestFixCloseOfChannelAfterCtrlC (t * testing.T ) {
290
+ // fix https://github.com/cosmtrek/air/issues/294
291
+ dir := initWithBuildFailedCode (t )
292
+
293
+ err := os .Chdir (dir )
294
+ if err != nil {
295
+ t .Fatalf ("Should not be fail: %s." , err )
296
+ }
297
+ engine , err := NewEngine ("" , true )
298
+ if err != nil {
299
+ t .Fatalf ("Should not be fail: %s." , err )
300
+ }
301
+ sigs := make (chan os.Signal , 1 )
302
+ signal .Notify (sigs , syscall .SIGINT , syscall .SIGTERM )
303
+ go func () {
304
+ engine .Run ()
305
+ t .Logf ("engine stopped" )
306
+ }()
307
+
308
+ go func () {
309
+ <- sigs
310
+ engine .Stop ()
311
+ t .Logf ("engine stopped" )
312
+ }()
313
+ // waiting for compile error
314
+ time .Sleep (time .Second * 3 )
315
+ port , f := GetPort ()
316
+ f ()
317
+ // correct code
318
+ err = generateGoCode (dir , port )
319
+ if err != nil {
320
+ t .Fatalf ("Should not be fail: %s." , err )
321
+ }
322
+
323
+ if err := waitingPortReady (t , port , time .Second * 5 ); err != nil {
324
+ t .Fatalf ("Should not be fail: %s." , err )
325
+ }
326
+
327
+ // ctrl + c
328
+ sigs <- syscall .SIGINT
329
+ time .Sleep (time .Second * 1 )
330
+ if err := waitingPortConnectionRefused (t , port , time .Second * 10 ); err != nil {
331
+ t .Fatalf ("Should not be fail: %s." , err )
332
+ }
333
+ assert .False (t , engine .running )
334
+
335
+ }
336
+
337
+ func TestFixCloseOfChannelAfterTwoFailedBuild (t * testing.T ) {
338
+ // fix https://github.com/cosmtrek/air/issues/294
339
+ // happens after two failed builds
340
+ dir := initWithBuildFailedCode (t )
341
+ // change dir to tmpDir
342
+ err := os .Chdir (dir )
343
+ if err != nil {
344
+ t .Fatalf ("Should not be fail: %s." , err )
345
+ }
346
+ engine , err := NewEngine ("" , true )
347
+ if err != nil {
348
+ t .Fatalf ("Should not be fail: %s." , err )
349
+ }
350
+ sigs := make (chan os.Signal , 1 )
351
+ signal .Notify (sigs , syscall .SIGINT , syscall .SIGTERM )
352
+ go func () {
353
+ engine .Run ()
354
+ t .Logf ("engine stopped" )
355
+ }()
356
+
357
+ go func () {
358
+ <- sigs
359
+ engine .Stop ()
360
+ t .Logf ("engine stopped" )
361
+ }()
362
+
363
+ // waiting for compile error
364
+ time .Sleep (time .Second * 3 )
365
+
366
+ // edit *.go file to create build error again
367
+ file , err := os .OpenFile ("main.go" , os .O_APPEND | os .O_WRONLY , 0644 )
368
+ if err != nil {
369
+ t .Fatalf ("Should not be fail: %s." , err )
370
+ }
371
+ defer file .Close ()
372
+ _ , err = file .WriteString ("\n " )
373
+ if err != nil {
374
+ t .Fatalf ("Should not be fail: %s." , err )
375
+ }
376
+ time .Sleep (time .Second * 3 )
377
+ // ctrl + c
378
+ sigs <- syscall .SIGINT
379
+ time .Sleep (time .Second * 1 )
380
+ assert .False (t , engine .running )
381
+ }
382
+
289
383
// waitingPortReady waits until the port is ready to be used.
290
384
func waitingPortReady (t * testing.T , port int , timeout time.Duration ) error {
291
385
t .Logf ("waiting port %d ready" , port )
@@ -368,6 +462,49 @@ func initTestEnv(t *testing.T, port int) string {
368
462
return tempDir
369
463
}
370
464
465
+ func initWithBuildFailedCode (t * testing.T ) string {
466
+ tempDir := t .TempDir ()
467
+ t .Logf ("tempDir: %s" , tempDir )
468
+ // generate golang code to tempdir
469
+ err := generateBuildErrorGoCode (tempDir )
470
+ if err != nil {
471
+ t .Fatalf ("Should not be fail: %s." , err )
472
+ }
473
+ return tempDir
474
+ }
475
+
476
+ func generateBuildErrorGoCode (dir string ) error {
477
+ code := `package main
478
+ // You can edit this code!
479
+ // Click here and start typing.
480
+
481
+ func main() {
482
+ Println("Hello, 世界")
483
+
484
+ }
485
+ `
486
+ file , err := os .Create (dir + "/main.go" )
487
+ if err != nil {
488
+ return err
489
+ }
490
+ _ , err = file .WriteString (code )
491
+
492
+ // generate go mod file
493
+ mod := `module air.sample.com
494
+
495
+ go 1.17
496
+ `
497
+ file , err = os .Create (dir + "/go.mod" )
498
+ if err != nil {
499
+ return err
500
+ }
501
+ _ , err = file .WriteString (mod )
502
+ if err != nil {
503
+ return err
504
+ }
505
+ return nil
506
+ }
507
+
371
508
// generateGoCode generates golang code to tempdir
372
509
func generateGoCode (dir string , port int ) error {
373
510
0 commit comments