Class: Paraspec::Master
- Inherits:
-
Object
- Object
- Paraspec::Master
- Defined in:
- lib/paraspec/master.rb
Overview
The master process has three responsibilities:
-
Load all tests and abort the run if there are errors outside of examples.
-
Maintain the queue of tests to feed the workers. The master process also synchronizes access to this queue.
-
Aggregate test reports from the workers and present them to the outside world in a coherent fashion. The latter means that numbers presented are for the entire suite, not for parts of it as executed by any single worker, and that output from a single test execution is not broken up by output from other test executions.
Instance Attribute Summary collapse
-
#non_example_exception_count ⇒ Object
readonly
Returns the value of attribute non_example_exception_count.
Instance Method Summary collapse
- #do_example_passed(spec, execution_result) ⇒ Object
- #dump_summary ⇒ Object
- #example_count ⇒ Object
- #example_passed(payload) ⇒ Object
- #find_example(spec) ⇒ Object
- #get_spec ⇒ Object
- #ident ⇒ Object
-
#initialize(options = {}) ⇒ Master
constructor
A new instance of Master.
- #notify_example_started(payload) ⇒ Object
- #ping ⇒ Object
- #reporter ⇒ Object
- #run ⇒ Object
- #status ⇒ Object
- #stop ⇒ Object
- #stop? ⇒ Boolean
- #suite_ok? ⇒ Boolean
- #suite_started ⇒ Object
Constructor Details
#initialize(options = {}) ⇒ Master
Returns a new instance of Master.
14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 |
# File 'lib/paraspec/master.rb', line 14 def initialize(={}) @supervisor_pipe = [:supervisor_pipe] #RSpec.configuration.formatter = 'progress' if RSpec.world.example_groups.count > 0 raise 'Example groups loaded too early/spilled across processes' end = RSpec::Core::ConfigurationOptions.new(ARGV) @non_example_exception_count = 0 begin # This can fail if for example a nonexistent formatter is referenced .configure(RSpec.configuration) rescue Exception => e puts "#{e.class}: #{e}" puts e.backtrace.join("\n") # TODO and report this situation as a configuration problem # and not a test suite problem @non_example_exception_count = 1 end =begin if RSpec.configuration.files_to_run.empty? RSpec.configuration.send(:remove_instance_variable, '@files_to_run') RSpec.configuration.files_or_directories_to_run = RSpec.configuration.default_path RSpec.configuration.files_to_run p ['aa1',RSpec.configuration.files_to_run] rspec_options.configure(RSpec.configuration) RSpec.configuration.load_spec_files end =end # It seems that load_spec_files sometimes rescues exceptions outside of # examples and sometimes does not, handle it both ways if @non_example_exception_count == 0 begin RSpec.configuration.load_spec_files rescue Exception => e puts "#{e.class}: #{e}" puts e.backtrace.join("\n") @non_example_exception_count = 1 end end if @non_example_exception_count == 0 @non_example_exception_count = RSpec.world.reporter.non_example_exception_count end @queue = [] if @non_example_exception_count == 0 @queue += RSpecFacade.queueable_example_groups puts "#{@queue.length} example groups queued" else puts "#{@non_example_exception_count} errors outside of examples, aborting" end end |
Instance Attribute Details
#non_example_exception_count ⇒ Object (readonly)
Returns the value of attribute non_example_exception_count.
68 69 70 |
# File 'lib/paraspec/master.rb', line 68 def non_example_exception_count @non_example_exception_count end |
Instance Method Details
#do_example_passed(spec, execution_result) ⇒ Object
140 141 142 143 144 145 146 147 148 149 |
# File 'lib/paraspec/master.rb', line 140 def do_example_passed(spec, execution_result) #return example = find_example(spec) # Can write to example here example.[:execution_result] = execution_result status = execution_result.status m = "example_#{status}" reporter.send(m, example) nil end |
#dump_summary ⇒ Object
187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 |
# File 'lib/paraspec/master.rb', line 187 def dump_summary reporter.stop all_examples = RSpecFacade.all_examples notification = RSpec::Core::Notifications::SummaryNotification.new( @start_time ? Time.now-@start_time : 0, all_examples, all_examples.select { |e| e.execution_result.status == :failed }, all_examples.select { |e| e.execution_result.status == :pending }, 0, non_example_exception_count, ) examples_notification = RSpec::Core::Notifications::ExamplesNotification.new(reporter) RSpec.configuration.formatters.each do |f| if f.respond_to?(:dump_summary) f.dump_summary(notification) end if f.respond_to?(:dump_failures) f.dump_failures(examples_notification) end if f.respond_to?(:dump_pending) f.dump_pending(examples_notification) end end nil end |
#example_count ⇒ Object
98 99 100 |
# File 'lib/paraspec/master.rb', line 98 def example_count RSpecFacade.all_examples.count end |
#example_passed(payload) ⇒ Object
128 129 130 131 132 133 |
# File 'lib/paraspec/master.rb', line 128 def example_passed(payload) spec = payload[:spec] # ExecutionResult result = payload['result'] do_example_passed(spec, result) end |
#find_example(spec) ⇒ Object
151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 |
# File 'lib/paraspec/master.rb', line 151 def find_example(spec) if spec.nil? #byebug raise ArgumentError, 'Nil spec' end example = (RSpecFacade.all_example_groups + RSpecFacade.all_examples).detect do |example| example.[:file_path] == spec[:file_path] && example.[:scoped_id] == spec[:scoped_id] end unless example puts "Not found: #{spec[:file_path]}[#{spec[:scoped_id]}]" #byebug raise "Not found: #{spec[:file_path]}[#{spec[:scoped_id]}]" end example end |
#get_spec ⇒ Object
102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 |
# File 'lib/paraspec/master.rb', line 102 def get_spec while true example_group = @queue.shift return nil if example_group.nil? if example_group.[:paraspec] && example_group.[:paraspec][:group] # unsplittable example group # pass to worker as is and have the worker prune examples m = example_group. else # TODO I am still not 100% on what should be filtered and pruned where, # but we shouldn't be returning a specification here unless # there are tests in it that a worker will run pruned_examples = RSpec.configuration.filter_manager.prune(example_group.examples) next if pruned_examples.empty? m = example_group. end return { file_path: m[:file_path], scoped_id: m[:scoped_id], } end end |
#ident ⇒ Object
222 223 224 |
# File 'lib/paraspec/master.rb', line 222 def ident "[m]" end |
#notify_example_started(payload) ⇒ Object
135 136 137 138 |
# File 'lib/paraspec/master.rb', line 135 def notify_example_started(payload) example = find_example(payload[:spec]) reporter.example_started(example) end |
#ping ⇒ Object
81 82 83 |
# File 'lib/paraspec/master.rb', line 81 def ping true end |
#reporter ⇒ Object
168 169 170 |
# File 'lib/paraspec/master.rb', line 168 def reporter @reporter ||= RSpec.configuration.reporter end |
#run ⇒ Object
70 71 72 73 74 75 76 77 78 79 |
# File 'lib/paraspec/master.rb', line 70 def run Thread.new do #HttpServer.set(:master, self).run!(port: 6031) MsgpackServer.new(self).run end until @stop sleep 1 end Paraspec.logger.debug_state("Exiting") end |
#status ⇒ Object
214 215 216 217 218 219 220 |
# File 'lib/paraspec/master.rb', line 214 def status if RSpecFacade.all_examples.any? { |example| example.execution_result.status == :failed } 1 else 0 end end |
#stop ⇒ Object
85 86 87 88 |
# File 'lib/paraspec/master.rb', line 85 def stop Paraspec.logger.debug_state("Stopping") @stop = true end |
#stop? ⇒ Boolean
90 91 92 |
# File 'lib/paraspec/master.rb', line 90 def stop? @stop end |
#suite_ok? ⇒ Boolean
94 95 96 |
# File 'lib/paraspec/master.rb', line 94 def suite_ok? RSpec.configuration.reporter.send(:instance_variable_get,'@non_example_exception_count') == 0 end |
#suite_started ⇒ Object
172 173 174 175 176 177 178 179 180 181 182 183 184 185 |
# File 'lib/paraspec/master.rb', line 172 def suite_started @start_time = Time.now notification = RSpec::Core::Notifications::StartNotification.new( RSpecFacade.all_examples.count, 0 ) RSpec.configuration.formatters.each do |f| if f.respond_to?(:start) f.start(notification) end end true end |