Skip to content

Commit 8342d8e

Browse files
committed
Run tests for Puma plugin with Solid Queue as fork and async
1 parent 5907948 commit 8342d8e

File tree

7 files changed

+191
-108
lines changed

7 files changed

+191
-108
lines changed

test/dummy/config/puma.rb

Lines changed: 0 additions & 46 deletions
This file was deleted.

test/dummy/config/puma.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
puma_fork.rb

test/dummy/config/puma_async.rb

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
# Puma can serve each request in a thread from an internal thread pool.
2+
# The `threads` method setting takes two numbers: a minimum and maximum.
3+
# Any libraries that use thread pools should be configured to match
4+
# the maximum value specified for Puma. Default is set to 5 threads for minimum
5+
# and maximum; this matches the default thread size of Active Record.
6+
#
7+
max_threads_count = ENV.fetch("RAILS_MAX_THREADS") { 5 }
8+
min_threads_count = ENV.fetch("RAILS_MIN_THREADS") { max_threads_count }
9+
threads min_threads_count, max_threads_count
10+
11+
# Specifies the `worker_timeout` threshold that Puma will use to wait before
12+
# terminating a worker in development environments.
13+
#
14+
worker_timeout 3600 if ENV.fetch("RAILS_ENV", "development") == "development"
15+
16+
# Specifies the `port` that Puma will listen on to receive requests; default is 3000.
17+
#
18+
port ENV.fetch("PORT") { 3000 }
19+
20+
# Specifies the `environment` that Puma will run in.
21+
#
22+
environment ENV.fetch("RAILS_ENV") { "development" }
23+
24+
# Specifies the `pidfile` that Puma will use.
25+
pidfile ENV.fetch("PIDFILE") { "tmp/pids/server.pid" }
26+
27+
# Specifies the number of `workers` to boot in clustered mode.
28+
# Workers are forked web server processes. If using threads and workers together
29+
# the concurrency of the application would be max `threads` * `workers`.
30+
# Workers do not work on JRuby or Windows (both of which do not support
31+
# processes).
32+
#
33+
# workers ENV.fetch("WEB_CONCURRENCY") { 2 }
34+
35+
# Use the `preload_app!` method when specifying a `workers` number.
36+
# This directive tells Puma to first boot the application and load code
37+
# before forking the application. This takes advantage of Copy On Write
38+
# process behavior so workers use less memory.
39+
#
40+
# preload_app!
41+
42+
# Allow puma to be restarted by `bin/rails restart` command.
43+
plugin :tmp_restart
44+
plugin :solid_queue
45+
46+
solid_queue_mode :async

test/dummy/config/puma_fork.rb

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
# Puma can serve each request in a thread from an internal thread pool.
2+
# The `threads` method setting takes two numbers: a minimum and maximum.
3+
# Any libraries that use thread pools should be configured to match
4+
# the maximum value specified for Puma. Default is set to 5 threads for minimum
5+
# and maximum; this matches the default thread size of Active Record.
6+
#
7+
max_threads_count = ENV.fetch("RAILS_MAX_THREADS") { 5 }
8+
min_threads_count = ENV.fetch("RAILS_MIN_THREADS") { max_threads_count }
9+
threads min_threads_count, max_threads_count
10+
11+
# Specifies the `worker_timeout` threshold that Puma will use to wait before
12+
# terminating a worker in development environments.
13+
#
14+
worker_timeout 3600 if ENV.fetch("RAILS_ENV", "development") == "development"
15+
16+
# Specifies the `port` that Puma will listen on to receive requests; default is 3000.
17+
#
18+
port ENV.fetch("PORT") { 3000 }
19+
20+
# Specifies the `environment` that Puma will run in.
21+
#
22+
environment ENV.fetch("RAILS_ENV") { "development" }
23+
24+
# Specifies the `pidfile` that Puma will use.
25+
pidfile ENV.fetch("PIDFILE") { "tmp/pids/server.pid" }
26+
27+
# Specifies the number of `workers` to boot in clustered mode.
28+
# Workers are forked web server processes. If using threads and workers together
29+
# the concurrency of the application would be max `threads` * `workers`.
30+
# Workers do not work on JRuby or Windows (both of which do not support
31+
# processes).
32+
#
33+
# workers ENV.fetch("WEB_CONCURRENCY") { 2 }
34+
35+
# Use the `preload_app!` method when specifying a `workers` number.
36+
# This directive tells Puma to first boot the application and load code
37+
# before forking the application. This takes advantage of Copy On Write
38+
# process behavior so workers use less memory.
39+
#
40+
# preload_app!
41+
42+
# Allow puma to be restarted by `bin/rails restart` command.
43+
plugin :tmp_restart
44+
plugin :solid_queue
45+
46+
solid_queue_mode :fork
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# frozen_string_literal: true
2+
3+
require "test_helper"
4+
require_relative "plugin_testing"
5+
6+
class PluginAsyncTest < ActiveSupport::TestCase
7+
include PluginTesting
8+
9+
private
10+
def solid_queue_mode
11+
:async
12+
end
13+
end
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# frozen_string_literal: true
2+
3+
require "test_helper"
4+
require_relative "plugin_testing"
5+
6+
class PluginForkTest < ActiveSupport::TestCase
7+
include PluginTesting
8+
9+
test "stop puma when solid queue's supervisor dies" do
10+
supervisor = find_processes_registered_as("Supervisor(fork)").first
11+
12+
signal_process(supervisor.pid, :KILL)
13+
wait_for_process_termination_with_timeout(@pid)
14+
15+
assert_not process_exists?(@pid)
16+
end
17+
18+
private
19+
def solid_queue_mode
20+
:fork
21+
end
22+
end

test/integration/puma/plugin_test.rb

Lines changed: 0 additions & 62 deletions
This file was deleted.
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
# frozen_string_literal: true
2+
3+
require "test_helper"
4+
5+
module PluginTesting
6+
extend ActiveSupport::Concern
7+
extend ActiveSupport::Testing::Declarative
8+
9+
included do
10+
self.use_transactional_tests = false
11+
12+
setup do
13+
FileUtils.mkdir_p Rails.root.join("tmp", "pids")
14+
15+
Dir.chdir("test/dummy") do
16+
cmd = %W[
17+
bundle exec puma
18+
-b tcp://127.0.0.1:9222
19+
-C config/puma_#{solid_queue_mode}.rb
20+
-s
21+
config.ru
22+
]
23+
24+
@pid = fork do
25+
exec(*cmd)
26+
end
27+
end
28+
29+
wait_for_registered_processes(4, timeout: 3.second)
30+
end
31+
32+
teardown do
33+
terminate_process(@pid, signal: :INT) if process_exists?(@pid)
34+
35+
wait_for_registered_processes 0, timeout: 1.second
36+
37+
JobResult.delete_all
38+
end
39+
end
40+
41+
test "perform jobs inside puma's process" do
42+
StoreResultJob.perform_later(:puma_plugin)
43+
44+
wait_for_jobs_to_finish_for(1.second)
45+
assert_equal 1, JobResult.where(queue_name: :background, status: "completed", value: :puma_plugin).count
46+
end
47+
48+
test "stop the queue on puma's restart" do
49+
signal_process(@pid, :SIGUSR2)
50+
# Ensure the restart finishes before we try to continue with the test
51+
wait_for_registered_processes(0, timeout: 3.second)
52+
wait_for_registered_processes(4, timeout: 3.second)
53+
54+
StoreResultJob.perform_later(:puma_plugin)
55+
wait_for_jobs_to_finish_for(2.seconds)
56+
assert_equal 1, JobResult.where(queue_name: :background, status: "completed", value: :puma_plugin).count
57+
end
58+
59+
private
60+
def solid_queue_mode
61+
raise NotImplementedError
62+
end
63+
end

0 commit comments

Comments
 (0)