Class: RSpec::Distrib::Leader

Inherits:
Object
  • Object
show all
Includes:
DistribCore::Leader
Defined in:
lib/rspec/distrib/leader.rb,
lib/rspec/distrib/leader/reporter.rb,
lib/rspec/distrib/leader/rspec_helper.rb,
lib/rspec/distrib/leader/tests_provider.rb

Overview

Interface exposed over the network that Workers connect to in order to receive spec file names and report back the results to.

Transport used is [DRb](rubydoc.info/stdlib/drb/DRb)

Defined Under Namespace

Modules: RSpecHelper Classes: Reporter, TestsProvider

Constant Summary collapse

DRB_SERVER_URL =

Used to interpolate with leader ip in order to generate the actual DRb server URL

'druby://%s:8787'.freeze
FAKE_TOTAL_EXAMPLES_COUNT =

We can’t calculate total amount of examples. But we need to provide a big number to prevent warnings

1_000_000_000

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(queue, reporter, seed) ⇒ Leader

Returns a new instance of Leader.



84
85
86
87
88
89
# File 'lib/rspec/distrib/leader.rb', line 84

def initialize(queue, reporter, seed)
  @queue = queue
  @reporter = reporter
  @seed = seed
  logger.info "Using seed #{@seed}"
end

Instance Attribute Details

#non_example_exceptionObject (readonly)

Returns the value of attribute non_example_exception.



82
83
84
# File 'lib/rspec/distrib/leader.rb', line 82

def non_example_exception
  @non_example_exception
end

#seedObject (readonly)

Returns the value of attribute seed.



82
83
84
# File 'lib/rspec/distrib/leader.rb', line 82

def seed
  @seed
end

Class Method Details

.start_service(seed = nil) ⇒ Object

Starts the DRb server and Watchdog thread

rubocop:disable Metrics/AbcSize,Metrics/MethodLength,Metrics/CyclomaticComplexity,Metrics/PerceivedComplexity

Parameters:

  • seed (Integer) (defaults to: nil)

    a seed for workers to randomize order of examples



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
# File 'lib/rspec/distrib/leader.rb', line 25

def start_service(seed = nil)
  files = ::DistribCore::Leader::QueueBuilder.tests
  queue = ::DistribCore::Leader::QueueWithLease.new(files)

  logger.info "#{files.count} files have been enqueued"

  seed ||= rand(0xFFFF) # Mimic how RSpec::Core::Ordering::ConfigurationManager randomizes it
  RSpec.configuration.seed = seed # it is going to be used by reporter

  reporter = Leader::Reporter.new

  leader = new(queue, reporter, seed)

  watchdog = ::DistribCore::Leader::Watchdog.new(queue)
  watchdog.start

  DRb.start_service(DRB_SERVER_URL % '0.0.0.0', leader, RSpec::Distrib.configuration.drb)
  logger.info 'Leader ready'
  ::DistribCore::Metrics.queue_exposed
  DRb.thread.join

  reporter.finish
  RSpec::Distrib.configuration.on_finish&.call

  failed = reporter.failures? || watchdog.failed? || leader.non_example_exception
  count_mismatch = (queue.size + queue.completed_size != files.count)

  if failed || ::DistribCore::ReceivedSignals.any? || count_mismatch
    print_failure_status(reporter, watchdog, leader, queue, count_mismatch)
    Kernel.exit(::DistribCore::ReceivedSignals.any? ? ::DistribCore::ReceivedSignals.exit_code : 1)
  else
    logger.info "Build succeeded. Files processed: #{queue.completed_size}"
  end
end

Instance Method Details

#next_file_to_runString

Get the next spec from the queue

Examples:

leader.next_file_to_run # => 'spec/services/user_service_spec.rb'

Returns:

  • (String)

    spec file name



95
96
97
98
99
100
101
# File 'lib/rspec/distrib/leader.rb', line 95

drb_callable def next_file_to_run
  ::DistribCore::Metrics.test_taken

  queue.lease.tap do |file|
    logger.debug "Serving #{file}"
  end
end