From ea24015af9a4723f254a0390e65fb23751340cd5 Mon Sep 17 00:00:00 2001 From: Samuel Williams Date: Sat, 27 Jun 2026 12:17:05 +1200 Subject: [PATCH] Run container tests in async scheduler context --- fixtures/container_context.rb | 16 +++++++++++ test/falcon/command/serve.rb | 37 ++++++++++++++----------- test/falcon/command/top.rb | 29 ++++++++++++-------- test/falcon/command/virtual.rb | 24 ++++++++++------- test/falcon/service/server.rb | 49 ++++++++++++++++++++-------------- 5 files changed, 99 insertions(+), 56 deletions(-) create mode 100644 fixtures/container_context.rb diff --git a/fixtures/container_context.rb b/fixtures/container_context.rb new file mode 100644 index 00000000..24f955ef --- /dev/null +++ b/fixtures/container_context.rb @@ -0,0 +1,16 @@ +# frozen_string_literal: true + +require "async" +require "async/container/group" + +module ContainerContext + def container_context(&block) + # Newer async-container supervises containers using Async tasks, while + # released versions can fail when forking under a scheduler on Ruby 3.x. + if Async::Container::Group.method_defined?(:supervise) + Sync(&block) + else + block.call + end + end +end diff --git a/test/falcon/command/serve.rb b/test/falcon/command/serve.rb index 43f1e535..d47663a2 100644 --- a/test/falcon/command/serve.rb +++ b/test/falcon/command/serve.rb @@ -5,9 +5,12 @@ # Copyright, 2019, by Sho Ito. require "falcon/command/serve" +require "container_context" require "sus/fixtures/console/captured_logger" ServeCommand = Sus::Shared("falcon serve") do + include ContainerContext + let(:command) do subject[ "--port", port, @@ -16,23 +19,25 @@ end it "can listen on specified port" do - configuration = command.configuration - controller = configuration.make_controller - - controller.start - - begin - Async do - client = command.client - - response = client.get("/") - expect(response).to be(:success?) - - response.finish - client.close + container_context do + configuration = command.configuration + controller = configuration.make_controller + + controller.start + + begin + Async do + client = command.client + + response = client.get("/") + expect(response).to be(:success?) + + response.finish + client.close + end + ensure + controller.stop end - ensure - controller.stop end end end diff --git a/test/falcon/command/top.rb b/test/falcon/command/top.rb index 8cc3ee00..bc948e92 100644 --- a/test/falcon/command/top.rb +++ b/test/falcon/command/top.rb @@ -4,9 +4,11 @@ # Copyright, 2018-2026, by Samuel Williams. require "falcon/command" +require "container_context" require "sus/fixtures/console/captured_logger" describe Falcon::Command::Top do + include ContainerContext include Sus::Fixtures::Console::CapturedLogger with "basic server configuration" do @@ -19,20 +21,25 @@ ] serve = top.command - controller = serve.configuration.make_controller - controller.start - Async do - client = serve.client + container_context do + controller = serve.configuration.make_controller + controller.start - response = client.get("/") - expect(response).to be(:success?) - - response.finish - client.close + begin + Async do + client = serve.client + + response = client.get("/") + expect(response).to be(:success?) + + response.finish + client.close + end + ensure + controller.stop + end end - - controller.stop end end diff --git a/test/falcon/command/virtual.rb b/test/falcon/command/virtual.rb index 7e940ef5..cac3bae4 100644 --- a/test/falcon/command/virtual.rb +++ b/test/falcon/command/virtual.rb @@ -4,6 +4,8 @@ # Copyright, 2019-2026, by Samuel Williams. require "falcon/command/virtual" +require "async" +require "container_context" require "sus/fixtures/console/captured_logger" require "async/http" @@ -12,6 +14,8 @@ require "async/websocket/client" VirtualCommand = Sus::Shared("falcon virtual") do + include ContainerContext + let(:paths) {[ File.expand_path("hello/falcon.rb", examples_root), File.expand_path("beer/falcon.rb", examples_root), @@ -32,15 +36,17 @@ end def around - configuration = command.configuration - controller = configuration.make_controller - - controller.start - - begin - yield - ensure - controller.stop + container_context do + configuration = command.configuration + controller = configuration.make_controller + + controller.start + + begin + yield + ensure + controller.stop + end end end diff --git a/test/falcon/service/server.rb b/test/falcon/service/server.rb index 4b0d73dd..b234ee52 100644 --- a/test/falcon/service/server.rb +++ b/test/falcon/service/server.rb @@ -6,8 +6,13 @@ require "falcon/service/server" require "falcon/environment/server" require "falcon/environment/rackup" +require "async/container" +require "async/service/environment" +require "container_context" describe Falcon::Service::Server do + include ContainerContext + let(:environment) do Async::Service::Environment.new(Falcon::Environment::Server).with( Falcon::Environment::Rackup, @@ -26,16 +31,18 @@ end it "can start and stop server" do - container = Async::Container.new - - server.start - server.setup(container) - container.wait_until_ready - - expect(container.group.running).to have_attributes(size: be == Etc.nprocessors) - - server.stop - container.stop + container_context do + container = Async::Container.new + + server.start + server.setup(container) + container.wait_until_ready + + expect(container.group.running).to have_attributes(size: be == Etc.nprocessors) + ensure + server.stop + container&.stop + end end with "a limited count" do @@ -50,16 +57,18 @@ end it "can start and stop server" do - container = Async::Container.new - - server.start - server.setup(container) - container.wait_until_ready - - expect(container.group.running).to have_attributes(size: be == 1) - - server.stop - container.stop + container_context do + container = Async::Container.new + + server.start + server.setup(container) + container.wait_until_ready + + expect(container.group.running).to have_attributes(size: be == 1) + ensure + server.stop + container&.stop + end end end