123456789_123456789_123456789_123456789_123456789_

Module: TestPuma::ShutdownRequests

Relationships & Source Files
Defined in: test/helpers/test_puma/shutdown_requests.rb

Instance Method Summary

Instance Method Details

#shutdown_requests(s1_complete: true, s1_response: nil, post: false, s2_response: nil, **options)

[ GitHub ]

  
# File 'test/helpers/test_puma/shutdown_requests.rb', line 7

def shutdown_requests(s1_complete: true, s1_response: nil, post: false, s2_response: nil, **options)
  mutex = Mutex.new
  app_finished = ConditionVariable.new

  server_run(**options) { |env|
    path = env["REQUEST_PATH"]
    mutex.synchronize do
      app_finished.signal
      app_finished.wait(mutex) if path == "/s1"
    end
    [204, {}, []]
  }

  pool = @server.instance_variable_get(:@thread_pool)

  # Trigger potential race condition by pausing Reactor#add until shutdown begins
  if options.fetch(:queue_requests, true)
    reactor = @server.instance_variable_get(:@reactor)
    reactor.instance_variable_set(:@pool, pool)
    reactor.extend(Module.new do
      def add(client)
        if client.env["REQUEST_PATH"] == "/s2"
          Thread.pass until @pool.instance_variable_get(:@shutdown)
        end
        super
      end
    end)
  end

  s1 = nil
  s2 = send_http(
    post ?
      "POST /s2 HTTP/1.1\r\nHost: test.com\r\nContent-Type: text/plain\r\nContent-Length: 5\r\n\r\nhi!" :
      "GET /s2 HTTP/1.1\r\n"
  )
  mutex.synchronize do
    s1 = send_http("GET /s1 HTTP/1.1\r\n\r\n")
    app_finished.wait(mutex)
    app_finished.signal if s1_complete
  end

  @server.stop
  Thread.pass until pool.instance_variable_get(:@shutdown)

  if s1_response
    s1_result = begin
      s1.read_response.status
    rescue Errno::ECONNABORTED, Errno::ECONNRESET, EOFError, Timeout::Error
      nil
    end

    assert_match s1_response, s1_result if s1_result || !options[:force_shutdown_after]
  end

  s2 << "\r\n" unless s2.wait_readable(0.2)
  assert s2.wait_readable(10), "timeout waiting for s2 response"

  s2_result = begin
    s2.read_response.status
  rescue Errno::ECONNABORTED, Errno::ECONNRESET, EOFError
    post ? "408" : nil
  end

  if s2_response
    assert_match s2_response, s2_result
  else
    assert_nil s2_result
  end
end