flatware 0.4.0 → 2.0.0.rc1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. checksums.yaml +5 -5
  2. data/README.md +40 -42
  3. data/bin/flatware +2 -2
  4. data/lib/flatware.rb +33 -3
  5. data/lib/flatware/broadcaster.rb +20 -3
  6. data/lib/flatware/cli.rb +45 -21
  7. data/lib/flatware/configuration.rb +40 -0
  8. data/lib/flatware/job.rb +22 -0
  9. data/lib/flatware/pid.rb +41 -0
  10. data/lib/flatware/serialized_exception.rb +16 -4
  11. data/lib/flatware/sink.rb +97 -65
  12. data/lib/flatware/sink/client.rb +7 -5
  13. data/lib/flatware/version.rb +3 -1
  14. data/lib/flatware/worker.rb +50 -31
  15. metadata +21 -82
  16. data/lib/flatware-cucumber.rb +0 -1
  17. data/lib/flatware-rspec.rb +0 -1
  18. data/lib/flatware/cucumber.rb +0 -51
  19. data/lib/flatware/cucumber/checkpoint.rb +0 -28
  20. data/lib/flatware/cucumber/cli.rb +0 -22
  21. data/lib/flatware/cucumber/formatter.rb +0 -66
  22. data/lib/flatware/cucumber/formatters/console.rb +0 -48
  23. data/lib/flatware/cucumber/formatters/console/summary.rb +0 -66
  24. data/lib/flatware/cucumber/result.rb +0 -27
  25. data/lib/flatware/cucumber/runtime.rb +0 -36
  26. data/lib/flatware/cucumber/scenario_result.rb +0 -38
  27. data/lib/flatware/cucumber/step_result.rb +0 -30
  28. data/lib/flatware/pids.rb +0 -25
  29. data/lib/flatware/poller.rb +0 -35
  30. data/lib/flatware/processor_info.rb +0 -24
  31. data/lib/flatware/rspec.rb +0 -28
  32. data/lib/flatware/rspec/checkpoint.rb +0 -29
  33. data/lib/flatware/rspec/cli.rb +0 -16
  34. data/lib/flatware/rspec/example_notification.rb +0 -21
  35. data/lib/flatware/rspec/examples_notification.rb +0 -24
  36. data/lib/flatware/rspec/formatter.rb +0 -50
  37. data/lib/flatware/rspec/formatters/console.rb +0 -33
  38. data/lib/flatware/rspec/summary.rb +0 -40
  39. data/lib/flatware/socket.rb +0 -181
@@ -1,35 +0,0 @@
1
- module Flatware
2
- class Poller
3
- attr_reader :sockets, :zmq_poller
4
- def initialize(*sockets)
5
- @sockets = sockets
6
- @zmq_poller = ZMQ::Poller.new
7
- register_sockets
8
- end
9
-
10
- def each(&block)
11
- while (result = zmq_poller.poll) != 0
12
- raise Error, ZMQ::Util.error_string, caller if result == -1
13
- for socket in zmq_poller.readables.map &find_wrapped_socket
14
- yield socket
15
- end
16
- end
17
- end
18
-
19
- private
20
-
21
- def find_wrapped_socket
22
- ->(s) do
23
- sockets.find do |socket|
24
- socket.socket == s
25
- end
26
- end
27
- end
28
-
29
- def register_sockets
30
- sockets.each do |socket|
31
- zmq_poller.register_readable socket.socket
32
- end
33
- end
34
- end
35
- end
@@ -1,24 +0,0 @@
1
- module Flatware
2
- class ProcessorInfo
3
- def count
4
- case operating_system
5
- when 'Darwin'
6
- `hostinfo`.match(/^(?<processors>\d+) processors are logically available\.$/)[:processors].to_i
7
- when 'Linux'
8
- `grep --count '^processor' /proc/cpuinfo`.to_i
9
- end
10
- end
11
-
12
- def operating_system
13
- `uname`.chomp
14
- end
15
-
16
- def self.count
17
- new.count
18
- end
19
-
20
- def self.operating_system
21
- new.operating_system
22
- end
23
- end
24
- end
@@ -1,28 +0,0 @@
1
- require 'rspec/core'
2
- require 'rspec/expectations'
3
- require 'flatware/rspec/cli'
4
-
5
- module Flatware
6
- module RSpec
7
- require 'flatware/rspec/formatters/console'
8
- require 'flatware/rspec/formatter'
9
-
10
- def self.extract_jobs_from_args(args, workers:)
11
-
12
- options = ::RSpec::Core::ConfigurationOptions.new(args)
13
- configuration = ::RSpec::Core::Configuration.new
14
- def configuration.command() 'rspec' end
15
- options.configure(configuration)
16
- configuration.files_to_run.uniq.map do |file|
17
- Job.new(file, args)
18
- end
19
- end
20
-
21
- def self.run(job, options={})
22
- runner = ::RSpec::Core::Runner
23
- def runner.trap_interrupt() end
24
-
25
- runner.run(%w[--format Flatware::RSpec::Formatter] + Array(job), $stderr, $stdout)
26
- end
27
- end
28
- end
@@ -1,29 +0,0 @@
1
- require 'flatware/rspec/examples_notification'
2
-
3
- module Flatware
4
- module RSpec
5
- class Checkpoint
6
- attr_reader :summary, :failures_notification
7
-
8
- def initialize(summary, failures_notification)
9
- @summary, @failures_notification = summary, ExamplesNotification.new(failures_notification.failure_notifications)
10
- end
11
-
12
- def +(other)
13
- self.class.new summary + other.summary, failures_notification + other.failures_notification
14
- end
15
-
16
- def failures?
17
- summary.failure_count > 0
18
- end
19
-
20
- def failure_notifications
21
- failures_notification.failure_notifications
22
- end
23
-
24
- def fully_formatted_failed_examples(*args)
25
- failures_notification.fully_formatted_failed_examples(*args)
26
- end
27
- end
28
- end
29
- end
@@ -1,16 +0,0 @@
1
- require 'flatware/cli'
2
-
3
- module Flatware
4
- class CLI
5
- worker_option
6
- method_option 'dispatch-endpoint', type: :string, default: 'ipc://dispatch'
7
- method_option 'sink-endpoint', type: :string, default: 'ipc://task'
8
- desc "rspec [FLATWARE_OPTS]", "parallelizes rspec"
9
- def rspec(*rspec_args)
10
- jobs = RSpec.extract_jobs_from_args rspec_args, workers: workers
11
- Flatware.verbose = options[:log]
12
- Worker.spawn count: workers, runner: RSpec, dispatch: options['dispatch-endpoint'], sink: options['sink-endpoint']
13
- start_sink jobs: jobs, workers: workers, formatter: Flatware::RSpec::Formatters::Console.new($stdout, $stderr)
14
- end
15
- end
16
- end
@@ -1,21 +0,0 @@
1
- require 'rspec/core/formatters/console_codes'
2
-
3
- module Flatware
4
- module RSpec
5
- class ExampleNotification
6
- attr_reader :formatted
7
- def initialize(notification)
8
- @formatted = notification.fully_formatted '!', default_colorizer
9
- end
10
-
11
- def fully_formatted(i, _=nil)
12
- formatted.sub '!', i.to_s
13
- end
14
-
15
- private
16
- def default_colorizer
17
- ::RSpec::Core::Formatters::ConsoleCodes
18
- end
19
- end
20
- end
21
- end
@@ -1,24 +0,0 @@
1
- require 'flatware/rspec/example_notification'
2
- module Flatware
3
- module RSpec
4
- class ExamplesNotification
5
- attr_reader :failure_notifications
6
-
7
- def initialize(failure_notifications)
8
- @failure_notifications = failure_notifications.map(&ExampleNotification.method(:new))
9
- end
10
-
11
- def +(other)
12
- self.class.new failure_notifications + other.failure_notifications
13
- end
14
-
15
- def fully_formatted_failed_examples(*)
16
- formatted = "\n\nFailures:\n"
17
- failure_notifications.each_with_index do |failure, index|
18
- formatted << failure.fully_formatted(index.next)
19
- end
20
- formatted
21
- end
22
- end
23
- end
24
- end
@@ -1,50 +0,0 @@
1
- require 'flatware/rspec/checkpoint'
2
- require 'flatware/rspec/summary'
3
- require 'rspec/core/formatters/console_codes'
4
-
5
- module Flatware
6
- module RSpec
7
- ProgressMessage = Struct.new(:progress)
8
-
9
- class Formatter
10
- attr_reader :summary, :output
11
-
12
- def initialize(stdout)
13
- @output = stdout
14
- end
15
-
16
- def example_passed(example)
17
- send_progress :passed
18
- end
19
-
20
- def example_failed(example)
21
- send_progress :failed
22
- end
23
-
24
- def example_pending(example)
25
- send_progress :pending
26
- end
27
-
28
- def dump_summary(summary)
29
- @summary = Summary.from_notification(summary)
30
- end
31
-
32
- def dump_failures(failure_notification)
33
- @failure_notification = failure_notification
34
- end
35
-
36
- def close(*)
37
- Sink::client.checkpoint Checkpoint.new(summary, @failure_notification)
38
- @failure_notification = nil
39
- end
40
-
41
- private
42
-
43
- def send_progress(status)
44
- Sink::client.progress ProgressMessage.new status
45
- end
46
- end
47
-
48
- ::RSpec::Core::Formatters.register Formatter, :example_passed, :example_failed, :example_pending, :dump_summary, :dump_failures, :close
49
- end
50
- end
@@ -1,33 +0,0 @@
1
- module Flatware::RSpec::Formatters
2
- class Console
3
- attr_reader :formatter
4
-
5
- def initialize(out, err)
6
- ::RSpec::configuration.tty = true
7
- ::RSpec::configuration.color = true
8
- @formatter = ::RSpec::Core::Formatters::ProgressFormatter.new(out)
9
- end
10
-
11
- def progress(result)
12
- formatter.send(message_for(result),nil)
13
- end
14
-
15
- def summarize(checkpoints)
16
- result = checkpoints.reduce :+
17
- if result
18
- formatter.dump_failures result
19
- formatter.dump_summary result.summary
20
- end
21
- end
22
-
23
- private
24
-
25
- def message_for(result)
26
- {
27
- passed: :example_passed,
28
- failed: :example_failed,
29
- pending: :example_pending
30
- }.fetch result.progress
31
- end
32
- end
33
- end
@@ -1,40 +0,0 @@
1
- require 'rspec/core/notifications'
2
- module Flatware
3
- module RSpec
4
- Summary = Struct.new(:duration, :examples, :failed_examples, :pending_examples, :load_time)
5
-
6
- class Example
7
- attr_reader :location_rerun_argument, :full_description
8
- def initialize(rspec_example)
9
- @full_description = rspec_example.full_description
10
- @location_rerun_argument = rspec_example.location_rerun_argument
11
- end
12
- end
13
-
14
- class Summary
15
- def +(other)
16
- self.class.new duration + other.duration,
17
- examples + other.examples,
18
- failed_examples + other.failed_examples,
19
- pending_examples + other.pending_examples,
20
- load_time + other.load_time
21
- end
22
-
23
- def fully_formatted
24
- ::RSpec::Core::Notifications::SummaryNotification.new(duration, examples, failed_examples, pending_examples, load_time).fully_formatted
25
- end
26
-
27
- def failure_count
28
- failed_examples.size
29
- end
30
-
31
- def self.from_notification(summary)
32
- serialized_examples = [summary.examples, summary.failed_examples, summary.pending_examples].map do |examples|
33
- examples.map(&Example.method(:new))
34
- end
35
-
36
- new summary.duration, *serialized_examples, summary.load_time
37
- end
38
- end
39
- end
40
- end
@@ -1,181 +0,0 @@
1
- require 'ffi-rzmq'
2
- require 'securerandom'
3
- require 'logger'
4
-
5
- module Flatware
6
- Error = Class.new StandardError
7
-
8
- Job = Struct.new :id, :args do
9
- attr_accessor :worker
10
- attr_writer :failed
11
-
12
- def failed?
13
- !!@failed
14
- end
15
- end
16
-
17
- extend self
18
-
19
- def logger
20
- @logger ||= Logger.new($stderr)
21
- end
22
-
23
- def logger=(logger)
24
- @logger = logger
25
- end
26
-
27
- def socket(*args)
28
- context.socket(*args)
29
- end
30
-
31
- def close(force: false)
32
- @ignore_errors = true if force
33
- context.close(force: force)
34
- @context = nil
35
- end
36
-
37
- def close!
38
- close force: true
39
- end
40
-
41
- def socket_error
42
- raise(Error, ZMQ::Util.error_string, caller) unless @ignore_errors
43
- end
44
-
45
- def log(*message)
46
- if Exception === message.first
47
- logger.error message.first
48
- elsif verbose?
49
- logger.info ([$0] + message).join(' ')
50
- end
51
- message
52
- end
53
-
54
- attr_writer :verbose
55
- def verbose?
56
- !!@verbose
57
- end
58
-
59
- def context
60
- @context ||= begin
61
- @ignore_errors = nil
62
- Context.new
63
- end
64
- end
65
-
66
- class Context
67
- attr_reader :sockets, :c
68
-
69
- def initialize
70
- @c = ZMQ::Context.new
71
- @sockets = []
72
- end
73
-
74
- def socket(zmq_type, options={})
75
- Socket.new(c.socket(zmq_type)).tap do |socket|
76
- sockets.push socket
77
- if port = options[:connect]
78
- socket.connect port
79
- end
80
- if port = options[:bind]
81
- socket.bind port
82
- end
83
- end
84
- end
85
-
86
- def close(force: false)
87
- sockets.each do |socket|
88
- socket.setsockopt ZMQ::LINGER, 0
89
- end if force
90
- sockets.each(&:close)
91
- Flatware::socket_error unless c.terminate == 0
92
- Flatware.log "terminated context"
93
- end
94
- end
95
-
96
- class Socket
97
- attr_reader :socket
98
-
99
- def initialize(socket)
100
- @socket = socket
101
- end
102
-
103
- def setsockopt(*args)
104
- socket.setsockopt(*args)
105
- end
106
-
107
- def name
108
- socket.name
109
- end
110
-
111
- def send(message)
112
- result = socket.send_string(Marshal.dump(message))
113
- Flatware::socket_error if result == -1
114
- Flatware.log "#@type #@port send #{message}"
115
- message
116
- end
117
-
118
- def connect(port)
119
- @type = 'connected'
120
- @port = port
121
- Flatware::socket_error unless socket.connect(port) == 0
122
- Flatware.log "connect #@port"
123
- end
124
-
125
- def monitor
126
- name = "inproc://monitor#{SecureRandom.hex(10)}"
127
- LibZMQ.zmq_socket_monitor(socket.socket, name, ZMQ::EVENT_ALL)
128
- Monitor.new(name)
129
- end
130
-
131
- class Monitor
132
- def initialize(port)
133
- @socket = Flatware.socket ZMQ::PAIR
134
- @socket.connect port
135
- end
136
-
137
- def recv
138
- bytes = @socket.recv marshal: false
139
- data = LibZMQ::EventData.new FFI::MemoryPointer.from_string bytes
140
- event[data.event]
141
- end
142
-
143
- private
144
-
145
- def event
146
- ZMQ.constants.select do |c|
147
- c.to_s =~ /^EVENT/
148
- end.map do |s|
149
- {s => ZMQ.const_get(s)}
150
- end.reduce(:merge).invert
151
- end
152
- end
153
-
154
- def bind(port)
155
- @type = 'bound'
156
- @port = port
157
- Flatware::socket_error unless socket.bind(port) == 0
158
- Flatware.log "bind #@port"
159
- end
160
-
161
- def close
162
- Flatware::socket_error unless socket.close == 0
163
- Flatware.log "close #@type #@port"
164
- end
165
-
166
- def recv(block: true, marshal: true)
167
- message = ''
168
- if block
169
- result = socket.recv_string(message)
170
- Flatware::socket_error if result == -1
171
- else
172
- socket.recv_string(message, ZMQ::NOBLOCK)
173
- end
174
- if message != '' and marshal
175
- message = Marshal.load(message)
176
- end
177
- Flatware.log "#@type #@port recv #{message}"
178
- message
179
- end
180
- end
181
- end