Skip to content

Commit

Permalink
feat: Support for Puma 6 and Rack 3 (#152)
Browse files Browse the repository at this point in the history
  • Loading branch information
dazuma authored Apr 5, 2023
1 parent 31d1790 commit d6a3fbb
Show file tree
Hide file tree
Showing 6 changed files with 93 additions and 23 deletions.
62 changes: 52 additions & 10 deletions .toys/ci.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

desc "Run CI checks"

TESTS = ["unit", "rubocop", "yardoc", "build", "examples", "conformance"]
TESTS = ["unit", "dependencies", "rubocop", "yardoc", "build", "examples", "conformance"]

flag :only
TESTS.each do |name|
Expand All @@ -26,26 +26,68 @@

def handle_result result
if result.success?
puts "** #{result.name} passed\n\n", :green, :bold
puts "** Passed: #{result.name}\n\n", :green, :bold
else
puts "** CI terminated: #{result.name} failed!", :red, :bold
exit 1
puts "** Failed: #{result.name}\n\n", :red, :bold
@errors << result.name
end
end

def run
@errors = []
::Dir.chdir context_directory
TESTS.each do |name|
key = "test_#{name}".to_sym
set key, !only if get(key).nil?
end
exec ["toys", "test"], name: "Unit tests" if test_unit
exec ["toys", "rubocop"], name: "Style checker" if test_rubocop
exec ["toys", "yardoc"], name: "Docs generation" if test_yardoc
exec ["toys", "build"], name: "Gem build" if test_build
exec_separate_tool ["test"], name: "Unit tests" if test_unit
exec_separate_tool ["ci", "deps-matrix"], name: "Dependency matrix tests" if test_dependencies
exec_separate_tool ["rubocop"], name: "Style checker" if test_rubocop
exec_separate_tool ["yardoc"], name: "Docs generation" if test_yardoc
exec_separate_tool ["build"], name: "Gem build" if test_build
::Dir.foreach "examples" do |dir|
next if dir =~ /^\.+$/
exec ["toys", "test"], name: "Tests for #{dir} example", chdir: ::File.join("examples", dir)
exec_separate_tool ["test"], name: "Tests for #{dir} example", chdir: ::File.join("examples", dir)
end if test_examples
exec ["toys", "conformance"], name: "Conformance tests" if test_conformance
exec_separate_tool ["conformance"], name: "Conformance tests" if test_conformance
@errors.each do |err|
puts "Failed: #{err}", :red, :bold
end
exit 1 unless @errors.empty?
end

tool "deps-matrix" do
static :puma_versions, ["4.0", "5.0", "6.0"]
static :rack_versions, ["2.1", "3.0"]

include :exec, result_callback: :handle_result
include :terminal

def handle_result result
if result.success?
puts "** Passed: #{result.name}\n\n", :green, :bold
else
puts "** Failed: #{result.name}\n\n", :red, :bold
@errors << result.name
end
end

def run
@errors = []
::Dir.chdir context_directory
puma_versions.each do |puma_version|
rack_versions.each do |rack_version|
name = "Puma #{puma_version} / Rack #{rack_version}"
env = {
"FF_DEPENDENCY_TEST_PUMA" => "~> #{puma_version}",
"FF_DEPENDENCY_TEST_RACK" => "~> #{rack_version}",
}
exec_separate_tool ["test", "test/test_server.rb"], env: env, name: name
end
end
@errors.each do |err|
puts "Failed: #{err}", :red, :bold
end
exit 1 unless @errors.empty?
end
end
4 changes: 3 additions & 1 deletion Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,11 @@ source "https://rubygems.org"

gemspec

gem "google-style", "~> 1.26.1"
gem "google-style", "~> 1.26.3"
gem "minitest", "~> 5.16"
gem "minitest-focus", "~> 1.2"
gem "minitest-rg", "~> 5.2"
gem "puma", ENV["FF_DEPENDENCY_TEST_PUMA"] if ENV["FF_DEPENDENCY_TEST_PUMA"]
gem "rack", ENV["FF_DEPENDENCY_TEST_RACK"] if ENV["FF_DEPENDENCY_TEST_RACK"]
gem "redcarpet", "~> 3.5" unless ::RUBY_PLATFORM == "java"
gem "yard", "~> 0.9.25"
4 changes: 2 additions & 2 deletions functions_framework.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,8 @@ version = ::FunctionsFramework::VERSION

spec.required_ruby_version = ">= 2.6.0"
spec.add_dependency "cloud_events", ">= 0.7.0", "< 2.a"
spec.add_dependency "puma", ">= 4.3.0", "< 6.a"
spec.add_dependency "rack", "~> 2.1"
spec.add_dependency "puma", ">= 4.3.0", "< 7.a"
spec.add_dependency "rack", ">= 2.1", "< 4.a"

if spec.respond_to? :metadata
spec.metadata["changelog_uri"] =
Expand Down
23 changes: 17 additions & 6 deletions lib/functions_framework/server.rb
Original file line number Diff line number Diff line change
Expand Up @@ -82,10 +82,21 @@ def initialize function, globals
def start
synchronize do
unless running?
@server = ::Puma::Server.new @app
@server.min_threads = @config.min_threads
@server.max_threads = @config.max_threads
@server.leak_stack_on_error = @config.show_error_details?
# Puma >= 6.0 interprets these settings from options
options = {
min_threads: @config.min_threads,
max_threads: @config.max_threads,
environment: @config.show_error_details? ? "development" : "production"
}
# Puma::Events.stdio for Puma < 6.0; otherwise nil for Puma >= 6.0
events = ::Puma::Events.stdio if ::Puma::Events.respond_to? :stdio
@server = ::Puma::Server.new @app, events, options
if @server.respond_to? :min_threads=
# Puma < 6.0 sets server attributes for these settings
@server.min_threads = @config.min_threads
@server.max_threads = @config.max_threads
@server.leak_stack_on_error = @config.show_error_details?
end
@server.binder.add_tcp_listener @config.bind_addr, @config.port
@config.logger.info "FunctionsFramework: Serving function #{@function.name.inspect} " \
"on port #{@config.port}..."
Expand Down Expand Up @@ -377,8 +388,8 @@ def string_response string, status, content_type: nil
content_type = "#{content_type}; charset=#{string.encoding.name.downcase}"
end
headers = {
"Content-Type" => content_type,
"Content-Length" => string.bytesize
"content-type" => content_type,
"content-length" => string.bytesize
}
[status, headers, [string]]
end
Expand Down
2 changes: 1 addition & 1 deletion lib/functions_framework/testing.rb
Original file line number Diff line number Diff line change
Expand Up @@ -367,8 +367,8 @@ def build_standard_env url, headers
::Rack::QUERY_STRING => url.query,
::Rack::SERVER_NAME => url.host,
::Rack::SERVER_PORT => url.port,
::Rack::SERVER_PROTOCOL => "HTTP/1.1",
::Rack::RACK_URL_SCHEME => url.scheme,
::Rack::RACK_VERSION => ::Rack::VERSION,
::Rack::RACK_LOGGER => ::FunctionsFramework.logger,
::Rack::RACK_INPUT => ::StringIO.new,
::Rack::RACK_ERRORS => ::StringIO.new
Expand Down
21 changes: 18 additions & 3 deletions test/test_server.rb
Original file line number Diff line number Diff line change
Expand Up @@ -43,15 +43,15 @@
let(:retry_interval) { 0.5 }
let(:app_context) { {} }

def make_basic_server function
def make_basic_server function, show_error_details: true
FunctionsFramework::Server.new function, app_context do |config|
config.min_threads = 1
config.max_threads = 1
config.port = port
config.bind_addr = "127.0.0.1"
config.rack_env = "development"
config.logger = quiet_logger
config.show_error_details = true
config.show_error_details = show_error_details
end
end

Expand Down Expand Up @@ -235,7 +235,7 @@ def query_server_with_retry server
assert_match(/あああ/, err)
end

it "interprets exceptions" do
it "interprets exceptions showing error details" do
function = FunctionsFramework::Function.new "my-func", :http do |_request|
raise "Whoops!"
end
Expand All @@ -245,6 +245,21 @@ def query_server_with_retry server
end
assert_equal "500", response.code
assert_match(/RuntimeError: Whoops!\n\t#{__FILE__}/, response.body)
assert_match %r{test/test_server\.rb:}, response.body
assert_equal "text/plain; charset=utf-8", response["Content-Type"]
end

it "interprets exceptions hiding error details" do
function = FunctionsFramework::Function.new "my-func", :http do |_request|
raise "Whoops!"
end
server = make_basic_server function, show_error_details: false
response = query_server_with_retry server do
::Net::HTTP.get_response URI("#{server_url}/")
end
assert_equal "500", response.code
refute_match(/Whoops/, response.body)
assert_equal "Unexpected internal error", response.body
assert_equal "text/plain; charset=utf-8", response["Content-Type"]
end

Expand Down

0 comments on commit d6a3fbb

Please sign in to comment.