httpx/standalone_tests/system_resolver_timeout_test.rb

48 lines
1.6 KiB
Ruby

# frozen_string_literal: true
require "test_helper"
require "support/http_helpers"
require "support/minitest_extensions"
class SystemResolverTimeoutTest < Minitest::Test
include HTTPHelpers
# this test mocks an unresponsive DNS server which doesn't return a DNS asnwer back.
def test_resolver_system_timeout
with_unresponsive_dns do
session = HTTPX.plugin(SessionWithPool)
# before_time = Process.clock_gettime(Process::CLOCK_MONOTONIC, :second)
# WARNING: system timeout lower than 5 secs does not work anyway, getaddrinfo is unterruptible.
# https://bugs.ruby-lang.org/issues/16476
response = session.head("https://#{httpbin}", resolver_class: :system, resolver_options: { timeouts: 5 })
# after_time = Process.clock_gettime(Process::CLOCK_MONOTONIC, :second)
# total_time = after_time - before_time
verify_error_response(response, HTTPX::ResolveTimeoutError)
# TODO: addrinfo blocks the ruby VM, setting a timeout is pointless
# assert_in_delta 5, total_time, 6, "request didn't take as expected to retry dns queries (#{total_time} secs)"
end
end
private
def with_unresponsive_dns
fake_dns_ip = "127.0.0.1"
th = Thread.new do
server = UDPSocket.new
server.bind(fake_dns_ip, 53)
server.recvfrom(16)
sleep
end
original_dns = `cat /etc/resolv.conf |grep -i '^nameserver'|head -n1|cut -d ' ' -f2`.strip
`echo "$(sed 's/#{original_dns}/#{fake_dns_ip}/g' /etc/resolv.conf)" > /etc/resolv.conf`
yield
ensure
`echo "$(sed 's/#{fake_dns_ip}/#{original_dns}/g' /etc/resolv.conf)" > /etc/resolv.conf`
th.kill
th.join
end
end