ruby/spec/bundler/support/artifice/helpers/endpoint.rb
David Rodríguez 7c115b8633 [rubygems/rubygems] Fix flaky test failures in mirror probing specs
The mirror probing spec file was moved to our regular suite, which runs
in parallel, recently. These specs rely on starting and stopping actual
servers in localhost, but this does not play nice with parallelization,
because a spec may kill the webserver another spec has created.

This commit moves mirror probing specs to not need to start servers in
localhost and do something more similar to what the other specs do.

ca9a19706f
2025-06-23 11:06:57 +09:00

113 lines
3 KiB
Ruby

# frozen_string_literal: true
require_relative "../../path"
$LOAD_PATH.unshift(*Spec::Path.sinatra_dependency_paths)
require "sinatra/base"
ALL_REQUESTS = [] # rubocop:disable Style/MutableConstant
ALL_REQUESTS_MUTEX = Thread::Mutex.new
at_exit do
if expected = ENV["BUNDLER_SPEC_ALL_REQUESTS"]
expected = expected.split("\n").sort
actual = ALL_REQUESTS.sort
unless expected == actual
raise "Unexpected requests!\nExpected:\n\t#{expected.join("\n\t")}\n\nActual:\n\t#{actual.join("\n\t")}"
end
end
end
class Endpoint < Sinatra::Base
def self.all_requests
@all_requests ||= []
end
set :raise_errors, true
set :show_exceptions, false
set :host_authorization, permitted_hosts: [".example.org", ".local", ".mirror", ".repo", ".repo1", ".repo2", ".repo3", ".repo4", ".rubygems.org", ".security", ".source", ".test", "127.0.0.1"]
def call!(*)
super.tap do
ALL_REQUESTS_MUTEX.synchronize do
ALL_REQUESTS << @request.url
end
end
end
helpers do
include Spec::Path
def default_gem_repo
if ENV["BUNDLER_SPEC_GEM_REPO"]
Pathname.new(ENV["BUNDLER_SPEC_GEM_REPO"])
else
case request.host
when "gem.repo1"
Spec::Path.gem_repo1
when "gem.repo2"
Spec::Path.gem_repo2
when "gem.repo3"
Spec::Path.gem_repo3
when "gem.repo4"
Spec::Path.gem_repo4
else
Spec::Path.gem_repo1
end
end
end
def dependencies_for(gem_names, gem_repo = default_gem_repo)
return [] if gem_names.nil? || gem_names.empty?
all_specs = %w[specs.4.8 prerelease_specs.4.8].map do |filename|
Marshal.load(File.binread(gem_repo.join(filename)))
end.inject(:+)
all_specs.filter_map do |name, version, platform|
spec = load_spec(name, version, platform, gem_repo)
next unless gem_names.include?(spec.name)
{
name: spec.name,
number: spec.version.version,
platform: spec.platform.to_s,
dependencies: spec.runtime_dependencies.map do |dep|
[dep.name, dep.requirement.requirements.map {|a| a.join(" ") }.join(", ")]
end,
}
end
end
def load_spec(name, version, platform, gem_repo)
full_name = "#{name}-#{version}"
full_name += "-#{platform}" if platform != "ruby"
Marshal.load(Bundler.rubygems.inflate(File.binread(gem_repo.join("quick/Marshal.4.8/#{full_name}.gemspec.rz"))))
end
end
get "/quick/Marshal.4.8/:id" do
redirect "/fetch/actual/gem/#{params[:id]}"
end
get "/fetch/actual/gem/:id" do
File.binread("#{default_gem_repo}/quick/Marshal.4.8/#{params[:id]}")
end
get "/gems/:id" do
File.binread("#{default_gem_repo}/gems/#{params[:id]}")
end
get "/api/v1/dependencies" do
Marshal.dump(dependencies_for(params[:gems]))
end
get "/specs.4.8.gz" do
File.binread("#{default_gem_repo}/specs.4.8.gz")
end
get "/prerelease_specs.4.8.gz" do
File.binread("#{default_gem_repo}/prerelease_specs.4.8.gz")
end
end