state_test.go 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. package daemon
  2. import (
  3. "sync/atomic"
  4. "testing"
  5. "time"
  6. )
  7. func TestStateRunStop(t *testing.T) {
  8. s := NewState()
  9. for i := 1; i < 3; i++ { // full lifecycle two times
  10. started := make(chan struct{})
  11. var pid int64
  12. go func() {
  13. runPid, _ := s.WaitRunning(-1 * time.Second)
  14. atomic.StoreInt64(&pid, int64(runPid))
  15. close(started)
  16. }()
  17. s.SetRunning(i + 100)
  18. if !s.IsRunning() {
  19. t.Fatal("State not running")
  20. }
  21. if s.Pid != i+100 {
  22. t.Fatalf("Pid %v, expected %v", s.Pid, i+100)
  23. }
  24. if s.ExitCode != 0 {
  25. t.Fatalf("ExitCode %v, expected 0", s.ExitCode)
  26. }
  27. select {
  28. case <-time.After(100 * time.Millisecond):
  29. t.Fatal("Start callback doesn't fire in 100 milliseconds")
  30. case <-started:
  31. t.Log("Start callback fired")
  32. }
  33. runPid := int(atomic.LoadInt64(&pid))
  34. if runPid != i+100 {
  35. t.Fatalf("Pid %v, expected %v", runPid, i+100)
  36. }
  37. if pid, err := s.WaitRunning(-1 * time.Second); err != nil || pid != i+100 {
  38. t.Fatalf("WaitRunning returned pid: %v, err: %v, expected pid: %v, err: %v", pid, err, i+100, nil)
  39. }
  40. stopped := make(chan struct{})
  41. var exit int64
  42. go func() {
  43. exitCode, _ := s.WaitStop(-1 * time.Second)
  44. atomic.StoreInt64(&exit, int64(exitCode))
  45. close(stopped)
  46. }()
  47. s.SetStopped(i)
  48. if s.IsRunning() {
  49. t.Fatal("State is running")
  50. }
  51. if s.ExitCode != i {
  52. t.Fatalf("ExitCode %v, expected %v", s.ExitCode, i)
  53. }
  54. if s.Pid != 0 {
  55. t.Fatalf("Pid %v, expected 0", s.Pid)
  56. }
  57. select {
  58. case <-time.After(100 * time.Millisecond):
  59. t.Fatal("Stop callback doesn't fire in 100 milliseconds")
  60. case <-stopped:
  61. t.Log("Stop callback fired")
  62. }
  63. exitCode := int(atomic.LoadInt64(&exit))
  64. if exitCode != i {
  65. t.Fatalf("ExitCode %v, expected %v", exitCode, i)
  66. }
  67. if exitCode, err := s.WaitStop(-1 * time.Second); err != nil || exitCode != i {
  68. t.Fatalf("WaitStop returned exitCode: %v, err: %v, expected exitCode: %v, err: %v", exitCode, err, i, nil)
  69. }
  70. }
  71. }
  72. func TestStateTimeoutWait(t *testing.T) {
  73. s := NewState()
  74. started := make(chan struct{})
  75. go func() {
  76. s.WaitRunning(100 * time.Millisecond)
  77. close(started)
  78. }()
  79. select {
  80. case <-time.After(200 * time.Millisecond):
  81. t.Fatal("Start callback doesn't fire in 100 milliseconds")
  82. case <-started:
  83. t.Log("Start callback fired")
  84. }
  85. s.SetRunning(42)
  86. stopped := make(chan struct{})
  87. go func() {
  88. s.WaitRunning(100 * time.Millisecond)
  89. close(stopped)
  90. }()
  91. select {
  92. case <-time.After(200 * time.Millisecond):
  93. t.Fatal("Start callback doesn't fire in 100 milliseconds")
  94. case <-stopped:
  95. t.Log("Start callback fired")
  96. }
  97. }