flatware 0.4.0 → 2.0.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
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