Fork of events package with fixes for Illumos

signal_test.go 3.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. package events
  2. import (
  3. "context"
  4. "os"
  5. "reflect"
  6. "syscall"
  7. "testing"
  8. "time"
  9. )
  10. func TestSignal(t *testing.T) {
  11. evlist := []*Event{}
  12. sigchan := make(chan os.Signal, 1)
  13. handler := HandlerFunc(func(e *Event) { evlist = append(evlist, e.Clone()) })
  14. sigchan <- os.Interrupt
  15. output := SignalWith(handler, sigchan)
  16. select {
  17. case sig := <-output:
  18. if sig != os.Interrupt {
  19. t.Error("bad signal received:", sig)
  20. }
  21. case <-time.After(time.Second):
  22. t.Error("no signal received after 1s")
  23. }
  24. if len(evlist) != 1 {
  25. t.Error("bad result count:", len(evlist))
  26. return
  27. }
  28. if evlist[0].Source == "" {
  29. t.Error("missing source in generated event")
  30. }
  31. if evlist[0].Time == (time.Time{}) {
  32. t.Error("missing time in generated event")
  33. }
  34. // Unpredictable values.
  35. evlist[0].Source = ""
  36. evlist[0].Time = time.Time{}
  37. if !reflect.DeepEqual(*evlist[0], Event{
  38. Message: "interrupt",
  39. Args: Args{{"signal", os.Interrupt}},
  40. }) {
  41. t.Errorf("bad event: %#v", *evlist[0])
  42. }
  43. }
  44. func TestWithSignals(t *testing.T) {
  45. t.Run("cancelling returns context.Canceled", func(t *testing.T) {
  46. ctx, cancel := WithSignals(context.Background(), os.Interrupt)
  47. // Ensure we can call cancel multiple times
  48. cancel()
  49. cancel()
  50. select {
  51. case <-ctx.Done():
  52. default:
  53. t.Error("the context should have been canceled after the cancellation function was called")
  54. return
  55. }
  56. if err := ctx.Err(); err != context.Canceled {
  57. t.Error("bad error returned after the context was canceled:", err)
  58. }
  59. })
  60. t.Run("receive os.Interrupt", func(t *testing.T) {
  61. ctx, cancel := WithSignals(context.Background(), os.Interrupt)
  62. defer cancel()
  63. p, _ := os.FindProcess(os.Getpid())
  64. p.Signal(os.Interrupt)
  65. select {
  66. case <-ctx.Done():
  67. case <-time.After(time.Second):
  68. t.Error("no signals received within 1 second")
  69. return
  70. }
  71. err := ctx.Err()
  72. switch e := err.(type) {
  73. case *SignalError:
  74. if e.Signal != os.Interrupt {
  75. t.Error("bad signal returned by the context:", e)
  76. }
  77. default:
  78. t.Error("bad error returned by the context:", e)
  79. }
  80. })
  81. t.Run("report cancellation of the parent context", func(t *testing.T) {
  82. ctx, cancel := context.WithCancel(context.Background())
  83. defer cancel()
  84. sig, stop := WithSignals(ctx, os.Interrupt)
  85. defer stop()
  86. cancel()
  87. select {
  88. case <-sig.Done():
  89. case <-time.After(1 * time.Second):
  90. t.Error("no cancellation received within 1 second")
  91. return
  92. }
  93. if err := sig.Err(); err != context.Canceled {
  94. t.Error("the parent error wasn't reported:", err)
  95. }
  96. })
  97. }
  98. func TestIsTermination(t *testing.T) {
  99. if !IsTermination(&SignalError{Signal: syscall.SIGTERM}) {
  100. t.Error("SIGTERM wasn't recognized as a termination error")
  101. }
  102. if IsTermination(&SignalError{Signal: syscall.SIGINT}) {
  103. t.Error("SIGINT was mistakenly recognized as a termination error")
  104. }
  105. }
  106. func TestIsInterruption(t *testing.T) {
  107. if !IsInterruption(&SignalError{Signal: syscall.SIGINT}) {
  108. t.Error("SIGINT wasn't recognized as a interruption error")
  109. }
  110. if IsInterruption(&SignalError{Signal: syscall.SIGTERM}) {
  111. t.Error("SIGTERM was mistakenly recognized as a interruption error")
  112. }
  113. }