diff --git a/spec/unit/lib/delayed_job/local_worker_drain_plugin_spec.rb b/spec/unit/lib/delayed_job/local_worker_drain_plugin_spec.rb index 5fb09db1cac..6a873c8a0cf 100644 --- a/spec/unit/lib/delayed_job/local_worker_drain_plugin_spec.rb +++ b/spec/unit/lib/delayed_job/local_worker_drain_plugin_spec.rb @@ -23,19 +23,37 @@ after { Delayed::Worker.sleep_delay = Delayed::Worker::DEFAULT_SLEEP_DELAY } it 'works off all remaining jobs in the queue before exiting' do - work_off_calls = Queue.new + work_off_count = 0 + worker_started = Queue.new + resume_worker = Queue.new allow(worker).to receive(:work_off) do - work_off_calls.push(:called) - work_off_calls.size < 3 ? [1, 0] : [0, 0] + work_off_count += 1 + if work_off_count == 1 + worker_started.push(:yes) + # Block after the first call until the test has confirmed the TERM handler ran, + # so the number of work_off calls does not depend on signal-delivery timing. + resume_worker.pop + end + work_off_count < 3 ? [1, 0] : [0, 0] end worker_thread = Thread.new { worker.start } - work_off_calls.pop # wait until worker has started + worker_started.pop # wait until worker has started + Process.kill('TERM', Process.pid) + # Wait (max. 1s) until the drain TERM handler has actually flipped the flag. + deadline = Process.clock_gettime(Process::CLOCK_MONOTONIC) + 1 + until Delayed::Worker.exit_on_complete + raise 'Timed out waiting for Delayed::Worker.exit_on_complete' if Process.clock_gettime(Process::CLOCK_MONOTONIC) >= deadline + + sleep 0.01 + end + resume_worker.push(:now) + worker_thread.join(5) expect(worker_thread.alive?).to be(false) - expect(work_off_calls.size).to eq(3) + expect(work_off_count).to eq(3) end end end