Class: RSpec::MultiprocessRunner::Worker
- Inherits:
-
Object
- Object
- RSpec::MultiprocessRunner::Worker
- Defined in:
- lib/rspec/multiprocess_runner/worker.rb
Overview
This object has several roles:
-
It forks the worker process
-
In the coordinator process, it is used to send messages to the worker and track the worker’s status, completed specs, and example results.
-
In the worker process, it is used to send messages to the coordinator and actually run specs.
Constant Summary collapse
- COMMAND_QUIT =
"quit"- COMMAND_RUN_FILE =
"run_file"- STATUS_EXAMPLE_COMPLETE =
"example_complete"- STATUS_RUN_COMPLETE =
"run_complete"
Instance Attribute Summary collapse
-
#current_file ⇒ Object
readonly
Returns the value of attribute current_file.
-
#deactivation_reason ⇒ Object
Returns the value of attribute deactivation_reason.
-
#environment_number ⇒ Object
readonly
Returns the value of attribute environment_number.
-
#example_results ⇒ Object
readonly
Returns the value of attribute example_results.
-
#options ⇒ Object
Returns the value of attribute options.
-
#pid ⇒ Object
readonly
Returns the value of attribute pid.
Instance Method Summary collapse
-
#==(other) ⇒ Object
Workers can be found in the coordinator process by their coordinator socket.
-
#initialize(environment_number, options) ⇒ Worker
constructor
A new instance of Worker.
- #kill_now ⇒ Object
- #quit_when_idle_and_wait_for_quit ⇒ Object
- #reap ⇒ Object
- #receive_and_act_on_message_from_worker ⇒ Object
- #report_example_result(example_status, description, line_number, details) ⇒ Object
- #run_file(filename) ⇒ Object
- #shutdown_now ⇒ Object
- #socket ⇒ Object
- #stalled? ⇒ Boolean
-
#start ⇒ Object
Forks the worker process.
- #test_env_number ⇒ Object
- #to_json(options = nil) ⇒ Object
- #working? ⇒ Boolean
Constructor Details
#initialize(environment_number, options) ⇒ Worker
Returns a new instance of Worker.
33 34 35 36 37 38 39 |
# File 'lib/rspec/multiprocess_runner/worker.rb', line 33 def initialize(environment_number, ) @environment_number = environment_number @worker_socket, @coordinator_socket = Socket.pair(:UNIX, :STREAM) @rspec_arguments = (. || []) + ["--format", ReportingFormatter.to_s] self. = @example_results = [] end |
Instance Attribute Details
#current_file ⇒ Object (readonly)
Returns the value of attribute current_file.
24 25 26 |
# File 'lib/rspec/multiprocess_runner/worker.rb', line 24 def current_file @current_file end |
#deactivation_reason ⇒ Object
Returns the value of attribute deactivation_reason.
25 26 27 |
# File 'lib/rspec/multiprocess_runner/worker.rb', line 25 def deactivation_reason @deactivation_reason end |
#environment_number ⇒ Object (readonly)
Returns the value of attribute environment_number.
24 25 26 |
# File 'lib/rspec/multiprocess_runner/worker.rb', line 24 def environment_number @environment_number end |
#example_results ⇒ Object (readonly)
Returns the value of attribute example_results.
24 25 26 |
# File 'lib/rspec/multiprocess_runner/worker.rb', line 24 def example_results @example_results end |
#options ⇒ Object
Returns the value of attribute options.
25 26 27 |
# File 'lib/rspec/multiprocess_runner/worker.rb', line 25 def end |
#pid ⇒ Object (readonly)
Returns the value of attribute pid.
24 25 26 |
# File 'lib/rspec/multiprocess_runner/worker.rb', line 24 def pid @pid end |
Instance Method Details
#==(other) ⇒ Object
Workers can be found in the coordinator process by their coordinator socket.
43 44 45 46 47 48 49 50 |
# File 'lib/rspec/multiprocess_runner/worker.rb', line 43 def ==(other) case other when Socket other == @coordinator_socket else super end end |
#kill_now ⇒ Object
135 136 137 138 |
# File 'lib/rspec/multiprocess_runner/worker.rb', line 135 def kill_now Process.kill(:KILL, pid) Process.detach(pid) end |
#quit_when_idle_and_wait_for_quit ⇒ Object
104 105 106 107 |
# File 'lib/rspec/multiprocess_runner/worker.rb', line 104 def quit_when_idle_and_wait_for_quit (command: COMMAND_QUIT) Process.wait(self.pid) end |
#reap ⇒ Object
140 141 142 |
# File 'lib/rspec/multiprocess_runner/worker.rb', line 140 def reap terminate_then_kill(3, "Reaping troubled process #{environment_number} (#{pid}; #{@current_file})") end |
#receive_and_act_on_message_from_worker ⇒ Object
144 145 146 |
# File 'lib/rspec/multiprocess_runner/worker.rb', line 144 def () end |
#report_example_result(example_status, description, line_number, details) ⇒ Object
215 216 217 218 219 220 221 222 223 224 |
# File 'lib/rspec/multiprocess_runner/worker.rb', line 215 def report_example_result(example_status, description, line_number, details) ( status: STATUS_EXAMPLE_COMPLETE, example_status: example_status, description: description, line_number: line_number, details: details, filename: @current_file ) end |
#run_file(filename) ⇒ Object
109 110 111 112 113 |
# File 'lib/rspec/multiprocess_runner/worker.rb', line 109 def run_file(filename) (command: COMMAND_RUN_FILE, filename: filename) @current_file = filename @current_file_started_at = @current_example_started_at = Time.now end |
#shutdown_now ⇒ Object
131 132 133 |
# File 'lib/rspec/multiprocess_runner/worker.rb', line 131 def shutdown_now terminate_then_kill(5) end |
#socket ⇒ Object
90 91 92 93 94 95 96 |
# File 'lib/rspec/multiprocess_runner/worker.rb', line 90 def socket if self.pid == Process.pid @worker_socket else @coordinator_socket end end |
#stalled? ⇒ Boolean
119 120 121 122 123 124 125 126 127 128 129 |
# File 'lib/rspec/multiprocess_runner/worker.rb', line 119 def stalled? file_stalled = if .file_timeout_seconds working? && (Time.now - @current_file_started_at > .file_timeout_seconds) end example_stalled = if .example_timeout_seconds working? && (Time.now - @current_example_started_at > .example_timeout_seconds) end file_stalled || example_stalled end |
#start ⇒ Object
Forks the worker process. In the parent, returns the PID.
62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 |
# File 'lib/rspec/multiprocess_runner/worker.rb', line 62 def start pid = fork if pid @worker_socket.close @pid = pid else @coordinator_socket.close @pid = Process.pid ENV["TEST_ENV_NUMBER"] = test_env_number # reset TERM handler so that # - the coordinator's version (if any) is not executed twice # - it actually terminates the process, instead of doing the ruby # default (throw an exception, which gets caught by RSpec) Kernel.trap("TERM", "SYSTEM_DEFAULT") # rely on the coordinator to handle INT Kernel.trap("INT", "IGNORE") # prevent RSpec from trapping INT, also ::RSpec::Core::Runner.instance_eval { def self.trap_interrupt; end } # Disable RSpec's at_exit hook that would try to run whatever is in ARGV ::RSpec::Core::Runner.disable_autorun! set_process_name run_loop end end |
#test_env_number ⇒ Object
52 53 54 55 56 57 58 |
# File 'lib/rspec/multiprocess_runner/worker.rb', line 52 def test_env_number if environment_number == 1 && !.first_is_1 "" else environment_number.to_s end end |
#to_json(options = nil) ⇒ Object
148 149 150 |
# File 'lib/rspec/multiprocess_runner/worker.rb', line 148 def to_json( = nil) { "pid" => @pid, "environment_number" => @environment_number, "current_file" => @current_file, "deactivation_reason" => @deactivation_reason }.to_json end |
#working? ⇒ Boolean
115 116 117 |
# File 'lib/rspec/multiprocess_runner/worker.rb', line 115 def working? @current_file end |