scheduler_spec.rb 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. require 'rails_helper'
  2. RSpec::Matchers.define_negated_matcher :not_change, :change
  3. RSpec.describe Scheduler do
  4. before do
  5. module SpecSpace
  6. class DelayedJobBackend
  7. def self.start
  8. # noop
  9. end
  10. # rubocop:disable Style/TrivialAccessors
  11. def self.reschedule=(reschedule)
  12. @reschedule = reschedule
  13. end
  14. def self.reschedule?(_delayed_job)
  15. @reschedule || false
  16. end
  17. end
  18. end
  19. end
  20. after do
  21. SpecSpace.send(:remove_const, :DelayedJobBackend)
  22. end
  23. describe '.cleanup' do
  24. it 'gets called by .threads' do
  25. expect(described_class).to receive(:cleanup).and_throw(:called)
  26. expect do
  27. described_class.threads
  28. end.to throw_symbol(:called)
  29. end
  30. context 'not called from .threads method' do
  31. it 'throws an exception' do
  32. expect do
  33. described_class.cleanup
  34. end.to raise_error(RuntimeError)
  35. end
  36. it 'throws no exception with force parameter' do
  37. expect do
  38. described_class.cleanup(force: true)
  39. end.not_to raise_error
  40. end
  41. end
  42. # helpers to avoid the throwing behaviour "describe"d above
  43. def simulate_threads_call
  44. threads
  45. end
  46. def threads
  47. described_class.cleanup
  48. end
  49. it 'keeps unlocked Delayed::Job-s' do
  50. # meta :)
  51. described_class.delay.cleanup
  52. expect do
  53. simulate_threads_call
  54. end.not_to change {
  55. Delayed::Job.count
  56. }
  57. end
  58. context 'locked Delayed::Job' do
  59. it 'gets destroyed' do
  60. # meta :)
  61. described_class.delay.cleanup
  62. # lock job (simluates interrupted scheduler task)
  63. locked_job = Delayed::Job.last
  64. locked_job.update_attribute(:locked_at, Time.zone.now)
  65. expect do
  66. simulate_threads_call
  67. end.to change {
  68. Delayed::Job.count
  69. }.by(-1)
  70. end
  71. context 'respond to reschedule?' do
  72. it 'gets rescheduled for positive responses' do
  73. SpecSpace::DelayedJobBackend.reschedule = true
  74. SpecSpace::DelayedJobBackend.delay.start
  75. # lock job (simluates interrupted scheduler task)
  76. locked_job = Delayed::Job.last
  77. locked_job.update_attribute(:locked_at, Time.zone.now)
  78. expect do
  79. simulate_threads_call
  80. end.to not_change {
  81. Delayed::Job.count
  82. }.and change {
  83. Delayed::Job.last.locked_at
  84. }
  85. end
  86. it 'gets destroyed for negative responses' do
  87. SpecSpace::DelayedJobBackend.reschedule = false
  88. SpecSpace::DelayedJobBackend.delay.start
  89. # lock job (simluates interrupted scheduler task)
  90. locked_job = Delayed::Job.last
  91. locked_job.update_attribute(:locked_at, Time.zone.now)
  92. expect do
  93. simulate_threads_call
  94. end.to change {
  95. Delayed::Job.count
  96. }.by(-1)
  97. end
  98. end
  99. end
  100. end
  101. end