diff --git a/spec/integration/reconnect_spec.rb b/spec/integration/reconnect_spec.rb index f478e233dd..0fa47c29af 100644 --- a/spec/integration/reconnect_spec.rb +++ b/spec/integration/reconnect_spec.rb @@ -111,6 +111,8 @@ # thread.kill should've similarly failed, but it doesn't. fails_on_jruby + minimum_mri_version '3.0.0' + it 'recreates SRV monitor' do wait_for_discovery @@ -181,8 +183,6 @@ end around do |example| - require 'support/dns' - rules = [ ['_mongodb._tcp.test-fake.test.build.10gen.cc', :srv, [0, 0, 2799, 'localhost.test.build.10gen.cc'], diff --git a/spec/integration/srv_monitoring_spec.rb b/spec/integration/srv_monitoring_spec.rb index 6d7da1f730..ffa58b053f 100644 --- a/spec/integration/srv_monitoring_spec.rb +++ b/spec/integration/srv_monitoring_spec.rb @@ -76,9 +76,7 @@ # NotImplementedError: recvmsg_nonblock is not implemented fails_on_jruby - before(:all) do - require 'support/dns' - end + minimum_mri_version '3.0.0' around do |example| # Speed up the tests by listening on the fake ports we are using. diff --git a/spec/integration/srv_spec.rb b/spec/integration/srv_spec.rb index da3d529339..594ff9e69b 100644 --- a/spec/integration/srv_spec.rb +++ b/spec/integration/srv_spec.rb @@ -12,10 +12,6 @@ # NotImplementedError: recvmsg_nonblock is not implemented fails_on_jruby - before(:all) do - require 'support/dns' - end - let(:uri) do "mongodb+srv://test-fake.test.build.10gen.cc/?tls=#{SpecConfig.instance.ssl?}&tlsInsecure=true" end diff --git a/spec/support/common_shortcuts.rb b/spec/support/common_shortcuts.rb index 8eacdf2c7c..bdb4c8511f 100644 --- a/spec/support/common_shortcuts.rb +++ b/spec/support/common_shortcuts.rb @@ -337,51 +337,33 @@ def stop_monitoring(*clients) [:tcp, "0.0.0.0", 5300], ] - def mock_dns(config) - semaphore = Mongo::Semaphore.new - - thread = Thread.new do - RubyDNS::run_server(DNS_INTERFACES) do - config.each do |(query, type, *answers)| - - resource_cls = Resolv::DNS::Resource::IN.const_get(type.to_s.upcase) - resources = answers.map do |answer| - resource_cls.new(*answer) - end - match(query, resource_cls) do |req| - req.add(resources) - end + # Starts the DNS server and returns it; should be run from within an + # Async block. Prefer #mock_dns instead, which does the setup for you. + def start_dns_server(config) + RubyDNS::run_server(DNS_INTERFACES) do + config.each do |(query, type, *answers)| + resource_cls = Resolv::DNS::Resource::IN.const_get(type.to_s.upcase) + resources = answers.map do |answer| + resource_cls.new(*answer) end - semaphore.signal + match(query, resource_cls) do |req| + req.add(resources) + end end end + end - semaphore.wait + # Starts and runs a DNS server, then yields to the attached block. + def mock_dns(config) + # only require rubydns when we need it; it's MRI-only. + require 'rubydns' - begin + Async do |task| + server = start_dns_server(config) yield ensure - 10.times do - if $last_async_task - break - end - sleep 0.5 - end - - # Hack to stop the server - https://github.com/socketry/rubydns/issues/75 - if $last_async_task.nil? - STDERR.puts "No async task - server never started?" - else - begin - $last_async_task.stop - rescue NoMethodError => e - STDERR.puts "Error stopping async task: #{e}" - end - end - - thread.kill - thread.join + server.stop end end diff --git a/spec/support/constraints.rb b/spec/support/constraints.rb index 6d92409937..8c7f3f940d 100644 --- a/spec/support/constraints.rb +++ b/spec/support/constraints.rb @@ -17,6 +17,16 @@ def require_local_tls end end + def minimum_mri_version(version) + require_mri + + before(:all) do + if RUBY_VERSION < version + skip "Ruby #{version} or greater is required" + end + end + end + def forbid_x509_auth before(:all) do skip 'X.509 auth not allowed' if SpecConfig.instance.x509_auth? diff --git a/spec/support/dns.rb b/spec/support/dns.rb deleted file mode 100644 index d868f7bc3b..0000000000 --- a/spec/support/dns.rb +++ /dev/null @@ -1,16 +0,0 @@ -# frozen_string_literal: true -# rubocop:todo all - -require 'rubydns' - -# Hack to stop the server - https://github.com/socketry/rubydns/issues/75 -module Async - class Task - alias :run_without_record :run - def run(*args) - run_without_record.tap do - $last_async_task = self - end - end - end -end