Class: Paraspec::Worker

Inherits:
Object
  • Object
show all
Includes:
DrbHelpers
Defined in:
lib/paraspec/worker.rb

Overview

A worker process obtains a test to run from the master, runs the test and reports the results, as well as any output, back to the master, then obtains the next test to run and so on. There can be one or more workers participating in a test run. A worker generally loads all of the tests but runs a subset of them.

Constant Summary

Constants included from DrbHelpers

DrbHelpers::WAIT_TIME

Instance Method Summary collapse

Methods included from DrbHelpers

#master_client

Constructor Details

#initialize(options = {}) ⇒ Worker

Returns a new instance of Worker.



10
11
12
13
14
15
16
17
18
19
20
21
22
23
# File 'lib/paraspec/worker.rb', line 10

def initialize(options={})
  @number = options[:number]
  ENV['TEST_ENV_NUMBER'] = @number.to_s
  @supervisor_pipe = options[:supervisor_pipe]
  if RSpec.world.example_groups.count > 0
    raise 'Example groups loaded too early/spilled across processes'
  end
  @terminal = options[:terminal]

  #RSpec.configuration.load_spec_files
  # possibly need to signal to supervisor when we are ready to
  # start running tests - there is a race otherwise I think
  #puts "#{RSpecFacade.all_example_groups.count} example groups known"
end

Instance Method Details

#identObject



66
67
68
# File 'lib/paraspec/worker.rb', line 66

def ident
  "[w#{@number}]"
end

#runObject



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
# File 'lib/paraspec/worker.rb', line 25

def run
#puts "worker: #{Process.pid} #{Process.getpgrp}"
  #@master = drb_connect(MASTER_DRB_URI, timeout: !@terminal)

  runner = WorkerRunner.new(master_client: master_client)

  # fill cache when pruning is not set up
  RSpecFacade.all_example_groups
  RSpecFacade.all_examples

  master_example_count = master_client.request('example-count')
  if master_example_count != RSpecFacade.all_examples.count
    # Workers and master should have the same examples defined.
    # If a test suite conditionally defines examples, it needs to
    # ensure that master and worker use the same settings.
    # If worker and master sets of examples differ, when the worker
    # requests an example from master it may receive an example
    # that it can't run.
    # We just check the count for now but may take a digest of
    # defined examples in the future.
    # A mismatch here usually indicates an issue with the test suite
    # being run.
    puts "Worker #{@number} has #{RSpecFacade.all_examples.count} examples, master has #{master_example_count}"
    #byebug
    raise "Worker #{@number} has #{RSpecFacade.all_examples.count} examples, master has #{master_example_count}"
  end

  while true
    Paraspec.logger.debug_state("Requesting a spec")
    spec = master_client.request('get-spec')
    Paraspec.logger.debug_state("Got spec #{spec || 'nil'}")
    # HTTP transport returns no spec as an empty hash,
    # msgpack transport returns as nil
    break if spec.nil? || spec.empty?
    spec = IpcHash.new.merge(spec)
    Paraspec.logger.debug_state("Running spec #{spec}")
    runner.run(spec)
    Paraspec.logger.debug_state("Finished running spec #{spec}")
  end
end