cron_test.go 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. package cron
  2. import (
  3. "fmt"
  4. "testing"
  5. "time"
  6. )
  7. // Start and stop cron with no entries.
  8. func TestNoEntries(t *testing.T) {
  9. cron := New()
  10. done := startAndSignal(cron)
  11. go cron.Stop()
  12. select {
  13. case <-time.After(1 * time.Second):
  14. t.FailNow()
  15. case <-done:
  16. }
  17. }
  18. // Add a job, start cron, expect it runs.
  19. func TestAddBeforeRunning(t *testing.T) {
  20. cron := New()
  21. cron.AddFunc("* * * * * ?", func() {
  22. cron.Stop()
  23. })
  24. done := startAndSignal(cron)
  25. // Give cron 2 seconds to run our job (which is always activated).
  26. select {
  27. case <-time.After(2 * time.Second):
  28. t.FailNow()
  29. case <-done:
  30. }
  31. }
  32. // Start cron, add a job, expect it runs.
  33. func TestAddWhileRunning(t *testing.T) {
  34. cron := New()
  35. done := startAndSignal(cron)
  36. go func() {
  37. cron.AddFunc("* * * * * ?", func() {
  38. cron.Stop()
  39. })
  40. }()
  41. select {
  42. case <-time.After(2 * time.Second):
  43. t.FailNow()
  44. case <-done:
  45. }
  46. }
  47. // Test that the entries are correctly sorted.
  48. // Add a bunch of long-in-the-future entries, and an immediate entry, and ensure
  49. // that the immediate entry runs immediately.
  50. func TestMultipleEntries(t *testing.T) {
  51. cron := New()
  52. cron.AddFunc("0 0 0 1 1 ?", func() {})
  53. cron.AddFunc("* * * * * ?", func() {
  54. cron.Stop()
  55. })
  56. cron.AddFunc("0 0 0 31 12 ?", func() {})
  57. done := startAndSignal(cron)
  58. select {
  59. case <-time.After(2 * time.Second):
  60. t.FailNow()
  61. case <-done:
  62. }
  63. }
  64. // Test that the cron is run in the local time zone (as opposed to UTC).
  65. func TestLocalTimezone(t *testing.T) {
  66. cron := New()
  67. now := time.Now().Local()
  68. spec := fmt.Sprintf("%d %d %d %d %d ?",
  69. now.Second()+1, now.Minute(), now.Hour(), now.Day(), now.Month())
  70. cron.AddFunc(spec, func() { cron.Stop() })
  71. done := startAndSignal(cron)
  72. select {
  73. case <-time.After(2 * time.Second):
  74. t.FailNow()
  75. case <-done:
  76. }
  77. }
  78. type testRunnable struct {
  79. cron *Cron
  80. name string
  81. }
  82. func (t testRunnable) Run() {
  83. t.cron.Stop()
  84. }
  85. // Simple test using Runnables.
  86. func TestRunnable(t *testing.T) {
  87. cron := New()
  88. cron.AddJob("0 0 0 30 Feb ?", testRunnable{cron, "job0"})
  89. cron.AddJob("0 0 0 1 1 ?", testRunnable{cron, "job1"})
  90. cron.AddJob("* * * * * ?", testRunnable{cron, "job2"})
  91. cron.AddJob("1 0 0 1 1 ?", testRunnable{cron, "job3"})
  92. done := startAndSignal(cron)
  93. select {
  94. case <-time.After(2 * time.Second):
  95. t.FailNow()
  96. case <-done:
  97. }
  98. // Ensure the entries are in the right order.
  99. answers := []string{"job2", "job1", "job3", "job0"}
  100. for i, answer := range answers {
  101. actual := cron.Entries[i].Job.(testRunnable).name
  102. if actual != answer {
  103. t.Errorf("Jobs not in the right order. (expected) %s != %s (actual)", answer, actual)
  104. }
  105. }
  106. }
  107. // Return a channel that signals when the cron's Start() method returns.
  108. func startAndSignal(cron *Cron) <-chan struct{} {
  109. ch := make(chan struct{})
  110. go func() {
  111. cron.Run()
  112. ch <- struct{}{}
  113. }()
  114. return ch
  115. }