threads.rb 1.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041
  1. # Copyright (C) 2012-2022 Zammad Foundation, https://zammad-foundation.org/
  2. module ThreadsHelper
  3. # Ensure that any new threads which might be spawned by the block will be cleaned up
  4. # to not interfere with any subsequent tests.
  5. def ensure_threads_exited()
  6. initial_threads = Thread.list
  7. yield
  8. ensure
  9. # Keep going until no more changes are needed to catch threads spawned in between.
  10. (Thread.list - initial_threads).each(&:kill) while (Thread.list - initial_threads).count.positive?
  11. end
  12. # Thread control loops usually run forever. This method can test that they were started.
  13. def ensure_block_keeps_running(timeout: 2.seconds, &block)
  14. # Stop after timeout and return true if everything was ok.
  15. Timeout.timeout(timeout, &block)
  16. raise 'Process ended unexpectedly.'
  17. rescue SystemExit
  18. # Convert SystemExit to a RuntimeError as otherwise rspec will shut down without an error.
  19. raise 'Process tried to shut down unexpectedly.'
  20. rescue Timeout::Error
  21. # Default case: process started fine and kept running, interrupted by timeout.
  22. true
  23. end
  24. def ensure_block_keeps_running_in_thread(timeout: 2.seconds, sleep_duration: 0.1.seconds, &block)
  25. thread = Thread.new { ensure_block_keeps_running(&block) }
  26. sleep sleep_duration
  27. thread
  28. end
  29. end
  30. RSpec.configure do |config|
  31. config.include ThreadsHelper
  32. config.around(:each, :ensure_threads_exited) do |example|
  33. ensure_threads_exited { example.run }
  34. end
  35. end