[rubygems/rubygems] Vendor timeout in RubyGems too
https://github.com/rubygems/rubygems/commit/e2e7440ede
This commit is contained in:
parent
90317472e8
commit
a7c9163b5d
@ -106,7 +106,7 @@ class Gem::CommandManager
|
||||
# Register all the subcommands supported by the gem command.
|
||||
|
||||
def initialize
|
||||
require "timeout"
|
||||
require_relative "timeout"
|
||||
@commands = {}
|
||||
|
||||
BUILTIN_COMMANDS.each do |name|
|
||||
@ -149,7 +149,7 @@ class Gem::CommandManager
|
||||
|
||||
def run(args, build_args=nil)
|
||||
process_args(args, build_args)
|
||||
rescue StandardError, Timeout::Error => ex
|
||||
rescue StandardError, Gem::Timeout::Error => ex
|
||||
if ex.respond_to?(:detailed_message)
|
||||
msg = ex.detailed_message(highlight: false).sub(/\A(.*?)(?: \(.+?\))/) { $1 }
|
||||
else
|
||||
|
@ -37,13 +37,13 @@ module Gem::GemcutterUtilities
|
||||
thread.abort_on_exception = true
|
||||
thread.report_on_exception = false
|
||||
thread[:otp] = new(options, host).poll_for_otp(webauthn_url, credentials)
|
||||
rescue Gem::WebauthnVerificationError, Timeout::Error => e
|
||||
rescue Gem::WebauthnVerificationError, Gem::Timeout::Error => e
|
||||
thread[:error] = e
|
||||
end
|
||||
end
|
||||
|
||||
def poll_for_otp(webauthn_url, credentials)
|
||||
Timeout.timeout(TIMEOUT_IN_SECONDS) do
|
||||
Gem::Timeout.timeout(TIMEOUT_IN_SECONDS) do
|
||||
loop do
|
||||
response = webauthn_verification_poll_response(webauthn_url, credentials)
|
||||
raise Gem::WebauthnVerificationError, response.message unless response.is_a?(Gem::Net::HTTPSuccess)
|
||||
|
@ -46,7 +46,7 @@ module Gem::Net #:nodoc:
|
||||
# == Strategies
|
||||
#
|
||||
# - If you will make only a few GET requests,
|
||||
# consider using {OpenURI}[https://docs.ruby-lang.org/en/master/OpenURI.html].
|
||||
# consider using {OpenURI}[rdoc-ref:OpenURI].
|
||||
# - If you will make only a few requests of all kinds,
|
||||
# consider using the various singleton convenience methods in this class.
|
||||
# Each of the following methods automatically starts and finishes
|
||||
@ -106,7 +106,7 @@ module Gem::Net #:nodoc:
|
||||
# It consists of some or all of: scheme, hostname, path, query, and fragment;
|
||||
# see {URI syntax}[https://en.wikipedia.org/wiki/Uniform_Resource_Identifier#Syntax].
|
||||
#
|
||||
# A Ruby {URI::Generic}[https://docs.ruby-lang.org/en/master/URI/Generic.html] object
|
||||
# A Ruby {URI::Generic}[rdoc-ref:URI::Generic] object
|
||||
# represents an internet URI.
|
||||
# It provides, among others, methods
|
||||
# +scheme+, +hostname+, +path+, +query+, and +fragment+.
|
||||
@ -1217,7 +1217,7 @@ module Gem::Net #:nodoc:
|
||||
# - The name of an encoding.
|
||||
# - An alias for an encoding name.
|
||||
#
|
||||
# See {Encoding}[https://docs.ruby-lang.org/en/master/Encoding.html].
|
||||
# See {Encoding}[rdoc-ref:Encoding].
|
||||
#
|
||||
# Examples:
|
||||
#
|
||||
@ -1308,7 +1308,7 @@ module Gem::Net #:nodoc:
|
||||
# Sets the maximum number of times to retry an idempotent request in case of
|
||||
# \Gem::Net::ReadTimeout, IOError, EOFError, Errno::ECONNRESET,
|
||||
# Errno::ECONNABORTED, Errno::EPIPE, OpenSSL::SSL::SSLError,
|
||||
# Timeout::Error.
|
||||
# Gem::Timeout::Error.
|
||||
# The initial value is 1.
|
||||
#
|
||||
# Argument +retries+ must be a non-negative numeric value:
|
||||
@ -1490,11 +1490,11 @@ module Gem::Net #:nodoc:
|
||||
attr_accessor :cert_store
|
||||
|
||||
# Sets or returns the available SSL ciphers.
|
||||
# See {OpenSSL::SSL::SSLContext#ciphers=}[https://docs.ruby-lang.org/en/master/OpenSSL/SSL/SSLContext.html#method-i-ciphers-3D].
|
||||
# See {OpenSSL::SSL::SSLContext#ciphers=}[rdoc-ref:OpenSSL::SSL::SSLContext#ciphers-3D].
|
||||
attr_accessor :ciphers
|
||||
|
||||
# Sets or returns the extra X509 certificates to be added to the certificate chain.
|
||||
# See {OpenSSL::SSL::SSLContext#add_certificate}[https://docs.ruby-lang.org/en/master/OpenSSL/SSL/SSLContext.html#method-i-add_certificate].
|
||||
# See {OpenSSL::SSL::SSLContext#add_certificate}[rdoc-ref:OpenSSL::SSL::SSLContext#add_certificate].
|
||||
attr_accessor :extra_chain_cert
|
||||
|
||||
# Sets or returns the OpenSSL::PKey::RSA or OpenSSL::PKey::DSA object.
|
||||
@ -1504,15 +1504,15 @@ module Gem::Net #:nodoc:
|
||||
attr_accessor :ssl_timeout
|
||||
|
||||
# Sets or returns the SSL version.
|
||||
# See {OpenSSL::SSL::SSLContext#ssl_version=}[https://docs.ruby-lang.org/en/master/OpenSSL/SSL/SSLContext.html#method-i-ssl_version-3D].
|
||||
# See {OpenSSL::SSL::SSLContext#ssl_version=}[rdoc-ref:OpenSSL::SSL::SSLContext#ssl_version-3D].
|
||||
attr_accessor :ssl_version
|
||||
|
||||
# Sets or returns the minimum SSL version.
|
||||
# See {OpenSSL::SSL::SSLContext#min_version=}[https://docs.ruby-lang.org/en/master/OpenSSL/SSL/SSLContext.html#method-i-min_version-3D].
|
||||
# See {OpenSSL::SSL::SSLContext#min_version=}[rdoc-ref:OpenSSL::SSL::SSLContext#min_version-3D].
|
||||
attr_accessor :min_version
|
||||
|
||||
# Sets or returns the maximum SSL version.
|
||||
# See {OpenSSL::SSL::SSLContext#max_version=}[https://docs.ruby-lang.org/en/master/OpenSSL/SSL/SSLContext.html#method-i-max_version-3D].
|
||||
# See {OpenSSL::SSL::SSLContext#max_version=}[rdoc-ref:OpenSSL::SSL::SSLContext#max_version-3D].
|
||||
attr_accessor :max_version
|
||||
|
||||
# Sets or returns the callback for the server certification verification.
|
||||
@ -1528,7 +1528,7 @@ module Gem::Net #:nodoc:
|
||||
|
||||
# Sets or returns whether to verify that the server certificate is valid
|
||||
# for the hostname.
|
||||
# See {OpenSSL::SSL::SSLContext#verify_hostname=}[https://docs.ruby-lang.org/en/master/OpenSSL/SSL/SSLContext.html#attribute-i-verify_mode].
|
||||
# See {OpenSSL::SSL::SSLContext#verify_hostname=}[rdoc-ref:OpenSSL::SSL::SSLContext#attribute-i-verify_mode].
|
||||
attr_accessor :verify_hostname
|
||||
|
||||
# Returns the X509 certificate chain (an array of strings)
|
||||
@ -1598,7 +1598,7 @@ module Gem::Net #:nodoc:
|
||||
end
|
||||
|
||||
debug "opening connection to #{conn_addr}:#{conn_port}..."
|
||||
s = Timeout.timeout(@open_timeout, Gem::Net::OpenTimeout) {
|
||||
s = Gem::Timeout.timeout(@open_timeout, Gem::Net::OpenTimeout) {
|
||||
begin
|
||||
TCPSocket.open(conn_addr, conn_port, @local_host, @local_port)
|
||||
rescue => e
|
||||
@ -2358,7 +2358,7 @@ module Gem::Net #:nodoc:
|
||||
Errno::ECONNRESET, Errno::ECONNABORTED, Errno::EPIPE, Errno::ETIMEDOUT,
|
||||
# avoid a dependency on OpenSSL
|
||||
defined?(OpenSSL::SSL) ? OpenSSL::SSL::SSLError : IOError,
|
||||
Timeout::Error => exception
|
||||
Gem::Timeout::Error => exception
|
||||
if count < max_retries && IDEMPOTENT_METHODS_.include?(req.method)
|
||||
count += 1
|
||||
@socket.close if @socket
|
||||
|
@ -589,7 +589,7 @@ module Gem::Net
|
||||
HAS_BODY = true
|
||||
end
|
||||
|
||||
# Response class for <tt>Request Timeout</tt> responses (status code 408).
|
||||
# Response class for <tt>Request Gem::Timeout</tt> responses (status code 408).
|
||||
#
|
||||
# The server timed out waiting for the request.
|
||||
#
|
||||
@ -980,7 +980,7 @@ module Gem::Net
|
||||
HAS_BODY = true
|
||||
end
|
||||
|
||||
# Response class for <tt>Gateway Timeout</tt> responses (status code 504).
|
||||
# Response class for <tt>Gateway Gem::Timeout</tt> responses (status code 504).
|
||||
#
|
||||
# The server was acting as a gateway or proxy
|
||||
# and did not receive a timely response from the upstream server.
|
||||
|
@ -20,7 +20,7 @@
|
||||
#
|
||||
|
||||
require 'socket'
|
||||
require 'timeout'
|
||||
require_relative '../../../timeout/lib/timeout'
|
||||
require 'io/wait'
|
||||
|
||||
module Gem::Net # :nodoc:
|
||||
@ -68,16 +68,16 @@ module Gem::Net # :nodoc:
|
||||
ProtocRetryError = ProtoRetriableError
|
||||
|
||||
##
|
||||
# OpenTimeout, a subclass of Timeout::Error, is raised if a connection cannot
|
||||
# OpenTimeout, a subclass of Gem::Timeout::Error, is raised if a connection cannot
|
||||
# be created within the open_timeout.
|
||||
|
||||
class OpenTimeout < Timeout::Error; end
|
||||
class OpenTimeout < Gem::Timeout::Error; end
|
||||
|
||||
##
|
||||
# ReadTimeout, a subclass of Timeout::Error, is raised if a chunk of the
|
||||
# ReadTimeout, a subclass of Gem::Timeout::Error, is raised if a chunk of the
|
||||
# response cannot be read within the read_timeout.
|
||||
|
||||
class ReadTimeout < Timeout::Error
|
||||
class ReadTimeout < Gem::Timeout::Error
|
||||
def initialize(io = nil)
|
||||
@io = io
|
||||
end
|
||||
@ -93,10 +93,10 @@ module Gem::Net # :nodoc:
|
||||
end
|
||||
|
||||
##
|
||||
# WriteTimeout, a subclass of Timeout::Error, is raised if a chunk of the
|
||||
# WriteTimeout, a subclass of Gem::Timeout::Error, is raised if a chunk of the
|
||||
# response cannot be written within the write_timeout. Not raised on Windows.
|
||||
|
||||
class WriteTimeout < Timeout::Error
|
||||
class WriteTimeout < Gem::Timeout::Error
|
||||
def initialize(io = nil)
|
||||
@io = io
|
||||
end
|
||||
|
@ -261,7 +261,7 @@ class Gem::RemoteFetcher
|
||||
end
|
||||
|
||||
data
|
||||
rescue Timeout::Error, IOError, SocketError, SystemCallError,
|
||||
rescue Gem::Timeout::Error, IOError, SocketError, SystemCallError,
|
||||
*(OpenSSL::SSL::SSLError if Gem::HAVE_OPENSSL) => e
|
||||
raise FetchError.new("#{e.class}: #{e}", uri)
|
||||
end
|
||||
|
@ -244,7 +244,7 @@ class Gem::Request
|
||||
# HACK: work around EOFError bug in Gem::Net::HTTP
|
||||
# NOTE Errno::ECONNABORTED raised a lot on Windows, and make impossible
|
||||
# to install gems.
|
||||
rescue EOFError, Timeout::Error,
|
||||
rescue EOFError, Gem::Timeout::Error,
|
||||
Errno::ECONNABORTED, Errno::ECONNRESET, Errno::EPIPE
|
||||
|
||||
requests = @requests[connection.object_id]
|
||||
|
3
lib/rubygems/timeout.rb
Normal file
3
lib/rubygems/timeout.rb
Normal file
@ -0,0 +1,3 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require_relative "timeout/lib/timeout"
|
199
lib/rubygems/timeout/lib/timeout.rb
Normal file
199
lib/rubygems/timeout/lib/timeout.rb
Normal file
@ -0,0 +1,199 @@
|
||||
# frozen_string_literal: true
|
||||
# Timeout long-running blocks
|
||||
#
|
||||
# == Synopsis
|
||||
#
|
||||
# require 'rubygems/timeout/lib/timeout'
|
||||
# status = Gem::Timeout::timeout(5) {
|
||||
# # Something that should be interrupted if it takes more than 5 seconds...
|
||||
# }
|
||||
#
|
||||
# == Description
|
||||
#
|
||||
# Gem::Timeout provides a way to auto-terminate a potentially long-running
|
||||
# operation if it hasn't finished in a fixed amount of time.
|
||||
#
|
||||
# Previous versions didn't use a module for namespacing, however
|
||||
# #timeout is provided for backwards compatibility. You
|
||||
# should prefer Gem::Timeout.timeout instead.
|
||||
#
|
||||
# == Copyright
|
||||
#
|
||||
# Copyright:: (C) 2000 Network Applied Communication Laboratory, Inc.
|
||||
# Copyright:: (C) 2000 Information-technology Promotion Agency, Japan
|
||||
|
||||
module Gem::Timeout
|
||||
VERSION = "0.4.1"
|
||||
|
||||
# Internal error raised to when a timeout is triggered.
|
||||
class ExitException < Exception
|
||||
def exception(*)
|
||||
self
|
||||
end
|
||||
end
|
||||
|
||||
# Raised by Gem::Timeout.timeout when the block times out.
|
||||
class Error < RuntimeError
|
||||
def self.handle_timeout(message)
|
||||
exc = ExitException.new(message)
|
||||
|
||||
begin
|
||||
yield exc
|
||||
rescue ExitException => e
|
||||
raise new(message) if exc.equal?(e)
|
||||
raise
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# :stopdoc:
|
||||
CONDVAR = ConditionVariable.new
|
||||
QUEUE = Queue.new
|
||||
QUEUE_MUTEX = Mutex.new
|
||||
TIMEOUT_THREAD_MUTEX = Mutex.new
|
||||
@timeout_thread = nil
|
||||
private_constant :CONDVAR, :QUEUE, :QUEUE_MUTEX, :TIMEOUT_THREAD_MUTEX
|
||||
|
||||
class Request
|
||||
attr_reader :deadline
|
||||
|
||||
def initialize(thread, timeout, exception_class, message)
|
||||
@thread = thread
|
||||
@deadline = GET_TIME.call(Process::CLOCK_MONOTONIC) + timeout
|
||||
@exception_class = exception_class
|
||||
@message = message
|
||||
|
||||
@mutex = Mutex.new
|
||||
@done = false # protected by @mutex
|
||||
end
|
||||
|
||||
def done?
|
||||
@mutex.synchronize do
|
||||
@done
|
||||
end
|
||||
end
|
||||
|
||||
def expired?(now)
|
||||
now >= @deadline
|
||||
end
|
||||
|
||||
def interrupt
|
||||
@mutex.synchronize do
|
||||
unless @done
|
||||
@thread.raise @exception_class, @message
|
||||
@done = true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def finished
|
||||
@mutex.synchronize do
|
||||
@done = true
|
||||
end
|
||||
end
|
||||
end
|
||||
private_constant :Request
|
||||
|
||||
def self.create_timeout_thread
|
||||
watcher = Thread.new do
|
||||
requests = []
|
||||
while true
|
||||
until QUEUE.empty? and !requests.empty? # wait to have at least one request
|
||||
req = QUEUE.pop
|
||||
requests << req unless req.done?
|
||||
end
|
||||
closest_deadline = requests.min_by(&:deadline).deadline
|
||||
|
||||
now = 0.0
|
||||
QUEUE_MUTEX.synchronize do
|
||||
while (now = GET_TIME.call(Process::CLOCK_MONOTONIC)) < closest_deadline and QUEUE.empty?
|
||||
CONDVAR.wait(QUEUE_MUTEX, closest_deadline - now)
|
||||
end
|
||||
end
|
||||
|
||||
requests.each do |req|
|
||||
req.interrupt if req.expired?(now)
|
||||
end
|
||||
requests.reject!(&:done?)
|
||||
end
|
||||
end
|
||||
ThreadGroup::Default.add(watcher) unless watcher.group.enclosed?
|
||||
watcher.name = "Gem::Timeout stdlib thread"
|
||||
watcher.thread_variable_set(:"\0__detached_thread__", true)
|
||||
watcher
|
||||
end
|
||||
private_class_method :create_timeout_thread
|
||||
|
||||
def self.ensure_timeout_thread_created
|
||||
unless @timeout_thread and @timeout_thread.alive?
|
||||
TIMEOUT_THREAD_MUTEX.synchronize do
|
||||
unless @timeout_thread and @timeout_thread.alive?
|
||||
@timeout_thread = create_timeout_thread
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# We keep a private reference so that time mocking libraries won't break
|
||||
# Gem::Timeout.
|
||||
GET_TIME = Process.method(:clock_gettime)
|
||||
private_constant :GET_TIME
|
||||
|
||||
# :startdoc:
|
||||
|
||||
# Perform an operation in a block, raising an error if it takes longer than
|
||||
# +sec+ seconds to complete.
|
||||
#
|
||||
# +sec+:: Number of seconds to wait for the block to terminate. Any number
|
||||
# may be used, including Floats to specify fractional seconds. A
|
||||
# value of 0 or +nil+ will execute the block without any timeout.
|
||||
# +klass+:: Exception Class to raise if the block fails to terminate
|
||||
# in +sec+ seconds. Omitting will use the default, Gem::Timeout::Error
|
||||
# +message+:: Error message to raise with Exception Class.
|
||||
# Omitting will use the default, "execution expired"
|
||||
#
|
||||
# Returns the result of the block *if* the block completed before
|
||||
# +sec+ seconds, otherwise throws an exception, based on the value of +klass+.
|
||||
#
|
||||
# The exception thrown to terminate the given block cannot be rescued inside
|
||||
# the block unless +klass+ is given explicitly. However, the block can use
|
||||
# ensure to prevent the handling of the exception. For that reason, this
|
||||
# method cannot be relied on to enforce timeouts for untrusted blocks.
|
||||
#
|
||||
# If a scheduler is defined, it will be used to handle the timeout by invoking
|
||||
# Scheduler#timeout_after.
|
||||
#
|
||||
# Note that this is both a method of module Gem::Timeout, so you can <tt>include
|
||||
# Gem::Timeout</tt> into your classes so they have a #timeout method, as well as
|
||||
# a module method, so you can call it directly as Gem::Timeout.timeout().
|
||||
def timeout(sec, klass = nil, message = nil, &block) #:yield: +sec+
|
||||
return yield(sec) if sec == nil or sec.zero?
|
||||
|
||||
message ||= "execution expired"
|
||||
|
||||
if Fiber.respond_to?(:current_scheduler) && (scheduler = Fiber.current_scheduler)&.respond_to?(:timeout_after)
|
||||
return scheduler.timeout_after(sec, klass || Error, message, &block)
|
||||
end
|
||||
|
||||
Gem::Timeout.ensure_timeout_thread_created
|
||||
perform = Proc.new do |exc|
|
||||
request = Request.new(Thread.current, sec, exc, message)
|
||||
QUEUE_MUTEX.synchronize do
|
||||
QUEUE << request
|
||||
CONDVAR.signal
|
||||
end
|
||||
begin
|
||||
return yield(sec)
|
||||
ensure
|
||||
request.finished
|
||||
end
|
||||
end
|
||||
|
||||
if klass
|
||||
perform.call(klass)
|
||||
else
|
||||
Error.handle_timeout(message, &perform)
|
||||
end
|
||||
end
|
||||
module_function :timeout
|
||||
end
|
@ -554,7 +554,7 @@ PeIQQkFng2VVot/WAQbv3ePqWq07g1BBcwIBAg==
|
||||
@fetcher = fetcher
|
||||
|
||||
def fetcher.fetch_http(uri, mtime = nil, head = nil)
|
||||
raise Timeout::Error, "timed out"
|
||||
raise Gem::Timeout::Error, "timed out"
|
||||
end
|
||||
|
||||
url = "http://example.com/uri"
|
||||
@ -563,7 +563,7 @@ PeIQQkFng2VVot/WAQbv3ePqWq07g1BBcwIBAg==
|
||||
fetcher.fetch_path url
|
||||
end
|
||||
|
||||
assert_match(/Timeout::Error: timed out \(#{Regexp.escape url}\)\z/,
|
||||
assert_match(/Gem::Timeout::Error: timed out \(#{Regexp.escape url}\)\z/,
|
||||
e.message)
|
||||
assert_equal url, e.uri
|
||||
end
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
require_relative "helper"
|
||||
require "rubygems/request"
|
||||
require "timeout"
|
||||
require "rubygems/timeout"
|
||||
|
||||
class TestGemRequestConnectionPool < Gem::TestCase
|
||||
class FakeHttp
|
||||
@ -141,8 +141,8 @@ class TestGemRequestConnectionPool < Gem::TestCase
|
||||
pool.checkout
|
||||
|
||||
Thread.new do
|
||||
assert_raise(Timeout::Error) do
|
||||
Timeout.timeout(1) do
|
||||
assert_raise(Gem::Timeout::Error) do
|
||||
Gem::Timeout.timeout(1) do
|
||||
pool.checkout
|
||||
end
|
||||
end
|
||||
|
@ -2,7 +2,6 @@
|
||||
|
||||
require_relative "helper"
|
||||
require "rubygems/user_interaction"
|
||||
require "timeout"
|
||||
|
||||
class TestGemSilentUI < Gem::TestCase
|
||||
def setup
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
require_relative "helper"
|
||||
require "rubygems/user_interaction"
|
||||
require "timeout"
|
||||
require "rubygems/timeout/lib/timeout"
|
||||
|
||||
class TestGemStreamUI < Gem::TestCase
|
||||
# increase timeout with RJIT for --jit-wait testing
|
||||
@ -40,7 +40,7 @@ class TestGemStreamUI < Gem::TestCase
|
||||
end
|
||||
|
||||
def test_ask
|
||||
Timeout.timeout(5) do
|
||||
Gem::Timeout.timeout(5) do
|
||||
expected_answer = "Arthur, King of the Britons"
|
||||
@in.string = "#{expected_answer}\n"
|
||||
actual_answer = @sui.ask("What is your name?")
|
||||
@ -51,14 +51,14 @@ class TestGemStreamUI < Gem::TestCase
|
||||
def test_ask_no_tty
|
||||
@in.tty = false
|
||||
|
||||
Timeout.timeout(SHORT_TIMEOUT) do
|
||||
Gem::Timeout.timeout(SHORT_TIMEOUT) do
|
||||
answer = @sui.ask("what is your favorite color?")
|
||||
assert_nil answer
|
||||
end
|
||||
end
|
||||
|
||||
def test_ask_for_password
|
||||
Timeout.timeout(5) do
|
||||
Gem::Timeout.timeout(5) do
|
||||
expected_answer = "Arthur, King of the Britons"
|
||||
@in.string = "#{expected_answer}\n"
|
||||
actual_answer = @sui.ask_for_password("What is your name?")
|
||||
@ -69,7 +69,7 @@ class TestGemStreamUI < Gem::TestCase
|
||||
def test_ask_for_password_no_tty
|
||||
@in.tty = false
|
||||
|
||||
Timeout.timeout(SHORT_TIMEOUT) do
|
||||
Gem::Timeout.timeout(SHORT_TIMEOUT) do
|
||||
answer = @sui.ask_for_password("what is the airspeed velocity of an unladen swallow?")
|
||||
assert_nil answer
|
||||
end
|
||||
@ -78,7 +78,7 @@ class TestGemStreamUI < Gem::TestCase
|
||||
def test_ask_yes_no_no_tty_with_default
|
||||
@in.tty = false
|
||||
|
||||
Timeout.timeout(SHORT_TIMEOUT) do
|
||||
Gem::Timeout.timeout(SHORT_TIMEOUT) do
|
||||
answer = @sui.ask_yes_no("do coconuts migrate?", false)
|
||||
assert_equal false, answer
|
||||
|
||||
@ -90,7 +90,7 @@ class TestGemStreamUI < Gem::TestCase
|
||||
def test_ask_yes_no_no_tty_without_default
|
||||
@in.tty = false
|
||||
|
||||
Timeout.timeout(SHORT_TIMEOUT) do
|
||||
Gem::Timeout.timeout(SHORT_TIMEOUT) do
|
||||
assert_raise(Gem::OperationNotSupportedError) do
|
||||
@sui.ask_yes_no("do coconuts migrate?")
|
||||
end
|
||||
|
@ -45,8 +45,8 @@ class WebauthnPollerTest < Gem::TestCase
|
||||
end
|
||||
|
||||
def test_poll_thread_timeout_error
|
||||
raise_error = ->(*_args) { raise Timeout::Error, "execution expired" }
|
||||
Timeout.stub(:timeout, raise_error) do
|
||||
raise_error = ->(*_args) { raise Gem::Timeout::Error, "execution expired" }
|
||||
Gem::Timeout.stub(:timeout, raise_error) do
|
||||
thread = Gem::GemcutterUtilities::WebauthnPoller.poll_thread({}, @host, @webauthn_url, @credentials)
|
||||
thread.join
|
||||
assert_equal thread[:error].message, "execution expired"
|
||||
@ -72,8 +72,8 @@ class WebauthnPollerTest < Gem::TestCase
|
||||
msg: "OK"
|
||||
)
|
||||
|
||||
assert_raise Timeout::Error do
|
||||
Timeout.timeout(0.1) do
|
||||
assert_raise Gem::Timeout::Error do
|
||||
Gem::Timeout.timeout(0.1) do
|
||||
Gem::GemcutterUtilities::WebauthnPoller.new({}, @host).poll_for_otp(@webauthn_url, @credentials)
|
||||
end
|
||||
end
|
||||
|
Loading…
x
Reference in New Issue
Block a user