flatware 0.2.0 → 0.3.0
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.
- checksums.yaml +7 -0
- data/lib/flatware.rb +4 -73
- data/lib/flatware/checkpoint.rb +1 -1
- data/lib/flatware/checkpoint_handler.rb +25 -7
- data/lib/flatware/cli.rb +7 -7
- data/lib/flatware/cucumber.rb +1 -13
- data/lib/flatware/cucumber/formatter.rb +62 -12
- data/lib/flatware/dispatcher.rb +10 -13
- data/lib/flatware/fireable.rb +4 -20
- data/lib/flatware/formatters.rb +26 -0
- data/lib/flatware/formatters/console.rb +48 -0
- data/lib/flatware/formatters/console/summary.rb +67 -0
- data/lib/flatware/formatters/http.rb +83 -0
- data/lib/flatware/pids.rb +25 -0
- data/lib/flatware/poller.rb +35 -0
- data/lib/flatware/processor_info.rb +4 -0
- data/lib/flatware/result.rb +5 -4
- data/lib/flatware/scenario_decorator.rb +10 -12
- data/lib/flatware/scenario_result.rb +19 -1
- data/lib/flatware/serialized_exception.rb +20 -0
- data/lib/flatware/sink.rb +29 -40
- data/lib/flatware/socket.rb +116 -0
- data/lib/flatware/step_result.rb +1 -18
- data/lib/flatware/version.rb +1 -1
- data/lib/flatware/worker.rb +17 -25
- metadata +17 -24
- data/lib/flatware/summary.rb +0 -60
@@ -0,0 +1,116 @@
|
|
1
|
+
require 'ffi-rzmq'
|
2
|
+
|
3
|
+
module Flatware
|
4
|
+
SINK_PORT = 'ipc://sink'
|
5
|
+
DISPATCH_PORT = 'ipc://dispatch'
|
6
|
+
|
7
|
+
Error = Class.new StandardError
|
8
|
+
|
9
|
+
Job = Struct.new :id, :args do
|
10
|
+
attr_accessor :worker
|
11
|
+
end
|
12
|
+
|
13
|
+
extend self
|
14
|
+
|
15
|
+
def socket(*args)
|
16
|
+
context.socket(*args)
|
17
|
+
end
|
18
|
+
|
19
|
+
def close
|
20
|
+
context.close
|
21
|
+
@context = nil
|
22
|
+
end
|
23
|
+
|
24
|
+
def log(*message)
|
25
|
+
if verbose?
|
26
|
+
$stderr.print "#$0 "
|
27
|
+
$stderr.puts *message
|
28
|
+
$stderr.flush
|
29
|
+
end
|
30
|
+
message
|
31
|
+
end
|
32
|
+
|
33
|
+
attr_writer :verbose
|
34
|
+
def verbose?
|
35
|
+
!!@verbose
|
36
|
+
end
|
37
|
+
|
38
|
+
def context
|
39
|
+
@context ||= Context.new
|
40
|
+
end
|
41
|
+
|
42
|
+
class Context
|
43
|
+
attr_reader :sockets, :c
|
44
|
+
|
45
|
+
def initialize
|
46
|
+
@c = ZMQ::Context.new
|
47
|
+
@sockets = []
|
48
|
+
end
|
49
|
+
|
50
|
+
def socket(type, options={})
|
51
|
+
Socket.new(c.socket(type)).tap do |socket|
|
52
|
+
sockets.push socket
|
53
|
+
if port = options[:connect]
|
54
|
+
socket.connect port
|
55
|
+
sleep 0.05
|
56
|
+
end
|
57
|
+
if port = options[:bind]
|
58
|
+
socket.bind port
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def close
|
64
|
+
sockets.each &:close
|
65
|
+
raise(Error, ZMQ::Util.error_string, caller) unless c.terminate == 0
|
66
|
+
Flatware.log "terminated context"
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
class Socket
|
71
|
+
attr_reader :s
|
72
|
+
def initialize(socket)
|
73
|
+
@s = socket
|
74
|
+
end
|
75
|
+
|
76
|
+
def setsockopt(*args)
|
77
|
+
s.setsockopt(*args)
|
78
|
+
end
|
79
|
+
|
80
|
+
def send(message)
|
81
|
+
result = s.send_string(Marshal.dump(message))
|
82
|
+
raise Error, ZMQ::Util.error_string, caller if result == -1
|
83
|
+
Flatware.log "#@type #@port send #{message}"
|
84
|
+
message
|
85
|
+
end
|
86
|
+
|
87
|
+
def connect(port)
|
88
|
+
@type = 'connected'
|
89
|
+
@port = port
|
90
|
+
raise(Error, ZMQ::Util.error_string, caller) unless s.connect(port) == 0
|
91
|
+
Flatware.log "connect #@port"
|
92
|
+
end
|
93
|
+
|
94
|
+
def bind(port)
|
95
|
+
@type = 'bound'
|
96
|
+
@port = port
|
97
|
+
raise(Error, ZMQ::Util.error_string, caller) unless s.bind(port) == 0
|
98
|
+
Flatware.log "bind #@port"
|
99
|
+
end
|
100
|
+
|
101
|
+
def close
|
102
|
+
setsockopt ZMQ::LINGER, 0
|
103
|
+
raise(Error, ZMQ::Util.error_string, caller) unless s.close == 0
|
104
|
+
Flatware.log "close #@type #@port"
|
105
|
+
end
|
106
|
+
|
107
|
+
def recv
|
108
|
+
message = ''
|
109
|
+
result = s.recv_string(message)
|
110
|
+
raise Error, ZMQ::Util.error_string, caller if result == -1
|
111
|
+
message = Marshal.load message
|
112
|
+
Flatware.log "#@type #@port recv #{message}"
|
113
|
+
message
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
data/lib/flatware/step_result.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
require 'flatware/serialized_exception'
|
1
2
|
module Flatware
|
2
3
|
class StepResult
|
3
4
|
attr_reader :status, :exception
|
@@ -22,23 +23,5 @@ module Flatware
|
|
22
23
|
def serialized(e)
|
23
24
|
SerializedException.new(e.class, e.message, e.backtrace) if e
|
24
25
|
end
|
25
|
-
|
26
|
-
class SerializedException
|
27
|
-
attr_reader :class, :message, :backtrace
|
28
|
-
def initialize(klass, message, backtrace)
|
29
|
-
@class, @message, @backtrace = serialized(klass), message, backtrace
|
30
|
-
end
|
31
|
-
|
32
|
-
private
|
33
|
-
def serialized(klass)
|
34
|
-
SerializedClass.new(klass.to_s)
|
35
|
-
end
|
36
|
-
end
|
37
|
-
|
38
|
-
class SerializedClass
|
39
|
-
attr_reader :name
|
40
|
-
alias to_s name
|
41
|
-
def initialize(name); @name = name end
|
42
|
-
end
|
43
26
|
end
|
44
27
|
end
|
data/lib/flatware/version.rb
CHANGED
data/lib/flatware/worker.rb
CHANGED
@@ -1,9 +1,15 @@
|
|
1
|
-
require 'benchmark'
|
2
1
|
module Flatware
|
3
2
|
class Worker
|
3
|
+
attr_reader :id
|
4
4
|
|
5
|
-
def self.listen!
|
6
|
-
new.listen
|
5
|
+
def self.listen!(id=0)
|
6
|
+
new(id).listen
|
7
|
+
end
|
8
|
+
|
9
|
+
def initialize(id)
|
10
|
+
@id = id
|
11
|
+
@fireable = Fireable.new
|
12
|
+
@task = Flatware.socket ZMQ::REQ, connect: Dispatcher::PORT
|
7
13
|
end
|
8
14
|
|
9
15
|
def self.spawn(worker_count)
|
@@ -11,39 +17,25 @@ module Flatware
|
|
11
17
|
fork do
|
12
18
|
$0 = "flatware worker #{i}"
|
13
19
|
ENV['TEST_ENV_NUMBER'] = i.to_s
|
14
|
-
listen!
|
20
|
+
listen!(i)
|
15
21
|
end
|
16
22
|
end
|
17
23
|
end
|
18
24
|
|
19
25
|
def listen
|
20
|
-
|
21
|
-
|
26
|
+
report_for_duty
|
27
|
+
fireable.until_fired task do |job|
|
28
|
+
job.worker = id
|
29
|
+
Sink.started job
|
30
|
+
Cucumber.run job.id, job.args
|
31
|
+
Sink.finished job
|
22
32
|
report_for_duty
|
23
|
-
fireable.until_fired task do |job|
|
24
|
-
log 'working!'
|
25
|
-
Cucumber.run job.id, job.args
|
26
|
-
Sink.finished job
|
27
|
-
report_for_duty
|
28
|
-
log 'waiting'
|
29
|
-
end
|
30
33
|
end
|
31
|
-
log time
|
32
34
|
end
|
33
35
|
|
34
36
|
private
|
35
37
|
|
36
|
-
|
37
|
-
Flatware.log *args
|
38
|
-
end
|
39
|
-
|
40
|
-
def fireable
|
41
|
-
@fireable ||= Fireable.new
|
42
|
-
end
|
43
|
-
|
44
|
-
def task
|
45
|
-
@task ||= Flatware.socket ZMQ::REQ, connect: Dispatcher::PORT
|
46
|
-
end
|
38
|
+
attr_reader :fireable, :task
|
47
39
|
|
48
40
|
def report_for_duty
|
49
41
|
task.send 'ready'
|
metadata
CHANGED
@@ -1,20 +1,18 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: flatware
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
5
|
-
prerelease:
|
4
|
+
version: 0.3.0
|
6
5
|
platform: ruby
|
7
6
|
authors:
|
8
7
|
- Brian Dunn
|
9
8
|
autorequire:
|
10
9
|
bindir: bin
|
11
10
|
cert_chain: []
|
12
|
-
date: 2013-
|
11
|
+
date: 2013-09-05 00:00:00.000000000 Z
|
13
12
|
dependencies:
|
14
13
|
- !ruby/object:Gem::Dependency
|
15
14
|
name: ffi-rzmq
|
16
15
|
requirement: !ruby/object:Gem::Requirement
|
17
|
-
none: false
|
18
16
|
requirements:
|
19
17
|
- - ~>
|
20
18
|
- !ruby/object:Gem::Version
|
@@ -22,7 +20,6 @@ dependencies:
|
|
22
20
|
type: :runtime
|
23
21
|
prerelease: false
|
24
22
|
version_requirements: !ruby/object:Gem::Requirement
|
25
|
-
none: false
|
26
23
|
requirements:
|
27
24
|
- - ~>
|
28
25
|
- !ruby/object:Gem::Version
|
@@ -30,7 +27,6 @@ dependencies:
|
|
30
27
|
- !ruby/object:Gem::Dependency
|
31
28
|
name: thor
|
32
29
|
requirement: !ruby/object:Gem::Requirement
|
33
|
-
none: false
|
34
30
|
requirements:
|
35
31
|
- - ~>
|
36
32
|
- !ruby/object:Gem::Version
|
@@ -38,7 +34,6 @@ dependencies:
|
|
38
34
|
type: :runtime
|
39
35
|
prerelease: false
|
40
36
|
version_requirements: !ruby/object:Gem::Requirement
|
41
|
-
none: false
|
42
37
|
requirements:
|
43
38
|
- - ~>
|
44
39
|
- !ruby/object:Gem::Version
|
@@ -46,23 +41,20 @@ dependencies:
|
|
46
41
|
- !ruby/object:Gem::Dependency
|
47
42
|
name: cucumber
|
48
43
|
requirement: !ruby/object:Gem::Requirement
|
49
|
-
none: false
|
50
44
|
requirements:
|
51
|
-
- -
|
45
|
+
- - '>='
|
52
46
|
- !ruby/object:Gem::Version
|
53
47
|
version: 1.3.0
|
54
48
|
type: :runtime
|
55
49
|
prerelease: false
|
56
50
|
version_requirements: !ruby/object:Gem::Requirement
|
57
|
-
none: false
|
58
51
|
requirements:
|
59
|
-
- -
|
52
|
+
- - '>='
|
60
53
|
- !ruby/object:Gem::Version
|
61
54
|
version: 1.3.0
|
62
55
|
- !ruby/object:Gem::Dependency
|
63
56
|
name: aruba
|
64
57
|
requirement: !ruby/object:Gem::Requirement
|
65
|
-
none: false
|
66
58
|
requirements:
|
67
59
|
- - ~>
|
68
60
|
- !ruby/object:Gem::Version
|
@@ -70,7 +62,6 @@ dependencies:
|
|
70
62
|
type: :development
|
71
63
|
prerelease: false
|
72
64
|
version_requirements: !ruby/object:Gem::Requirement
|
73
|
-
none: false
|
74
65
|
requirements:
|
75
66
|
- - ~>
|
76
67
|
- !ruby/object:Gem::Version
|
@@ -78,7 +69,6 @@ dependencies:
|
|
78
69
|
- !ruby/object:Gem::Dependency
|
79
70
|
name: rake
|
80
71
|
requirement: !ruby/object:Gem::Requirement
|
81
|
-
none: false
|
82
72
|
requirements:
|
83
73
|
- - ~>
|
84
74
|
- !ruby/object:Gem::Version
|
@@ -86,7 +76,6 @@ dependencies:
|
|
86
76
|
type: :development
|
87
77
|
prerelease: false
|
88
78
|
version_requirements: !ruby/object:Gem::Requirement
|
89
|
-
none: false
|
90
79
|
requirements:
|
91
80
|
- - ~>
|
92
81
|
- !ruby/object:Gem::Version
|
@@ -94,7 +83,6 @@ dependencies:
|
|
94
83
|
- !ruby/object:Gem::Dependency
|
95
84
|
name: rspec
|
96
85
|
requirement: !ruby/object:Gem::Requirement
|
97
|
-
none: false
|
98
86
|
requirements:
|
99
87
|
- - ~>
|
100
88
|
- !ruby/object:Gem::Version
|
@@ -102,7 +90,6 @@ dependencies:
|
|
102
90
|
type: :development
|
103
91
|
prerelease: false
|
104
92
|
version_requirements: !ruby/object:Gem::Requirement
|
105
|
-
none: false
|
106
93
|
requirements:
|
107
94
|
- - ~>
|
108
95
|
- !ruby/object:Gem::Version
|
@@ -125,13 +112,20 @@ files:
|
|
125
112
|
- lib/flatware/cucumber/runtime.rb
|
126
113
|
- lib/flatware/dispatcher.rb
|
127
114
|
- lib/flatware/fireable.rb
|
115
|
+
- lib/flatware/formatters.rb
|
116
|
+
- lib/flatware/formatters/console.rb
|
117
|
+
- lib/flatware/formatters/console/summary.rb
|
118
|
+
- lib/flatware/formatters/http.rb
|
119
|
+
- lib/flatware/pids.rb
|
120
|
+
- lib/flatware/poller.rb
|
128
121
|
- lib/flatware/processor_info.rb
|
129
122
|
- lib/flatware/result.rb
|
130
123
|
- lib/flatware/scenario_decorator.rb
|
131
124
|
- lib/flatware/scenario_result.rb
|
125
|
+
- lib/flatware/serialized_exception.rb
|
132
126
|
- lib/flatware/sink.rb
|
127
|
+
- lib/flatware/socket.rb
|
133
128
|
- lib/flatware/step_result.rb
|
134
|
-
- lib/flatware/summary.rb
|
135
129
|
- lib/flatware/version.rb
|
136
130
|
- lib/flatware/worker.rb
|
137
131
|
- LICENSE.txt
|
@@ -140,26 +134,25 @@ files:
|
|
140
134
|
homepage: http://github.com/briandunn/flatware
|
141
135
|
licenses:
|
142
136
|
- MIT
|
137
|
+
metadata: {}
|
143
138
|
post_install_message:
|
144
139
|
rdoc_options: []
|
145
140
|
require_paths:
|
146
141
|
- lib
|
147
142
|
required_ruby_version: !ruby/object:Gem::Requirement
|
148
|
-
none: false
|
149
143
|
requirements:
|
150
|
-
- -
|
144
|
+
- - '>='
|
151
145
|
- !ruby/object:Gem::Version
|
152
146
|
version: '0'
|
153
147
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
154
|
-
none: false
|
155
148
|
requirements:
|
156
|
-
- -
|
149
|
+
- - '>='
|
157
150
|
- !ruby/object:Gem::Version
|
158
151
|
version: '0'
|
159
152
|
requirements: []
|
160
153
|
rubyforge_project:
|
161
|
-
rubygems_version:
|
154
|
+
rubygems_version: 2.0.6
|
162
155
|
signing_key:
|
163
|
-
specification_version:
|
156
|
+
specification_version: 4
|
164
157
|
summary: A distributed cucumber runner
|
165
158
|
test_files: []
|
data/lib/flatware/summary.rb
DELETED
@@ -1,60 +0,0 @@
|
|
1
|
-
require 'cucumber/formatter/console'
|
2
|
-
require 'flatware/checkpoint'
|
3
|
-
module Flatware
|
4
|
-
class Summary
|
5
|
-
include ::Cucumber::Formatter::Console
|
6
|
-
attr_reader :io, :steps, :scenarios
|
7
|
-
|
8
|
-
def initialize(steps, scenarios=[], io=StringIO.new)
|
9
|
-
@io = io
|
10
|
-
@steps = steps
|
11
|
-
@scenarios = scenarios
|
12
|
-
end
|
13
|
-
|
14
|
-
def summarize
|
15
|
-
2.times { io.puts }
|
16
|
-
print_steps :failed
|
17
|
-
print_failed_scenarios scenarios
|
18
|
-
print_counts 'scenario', scenarios
|
19
|
-
print_counts 'step', steps
|
20
|
-
end
|
21
|
-
|
22
|
-
private
|
23
|
-
|
24
|
-
def print_failed_scenarios(scenarios)
|
25
|
-
return unless scenarios.any? &with_status(:failed)
|
26
|
-
|
27
|
-
io.puts format_string "Failing Scenarios:", :failed
|
28
|
-
scenarios.select(&with_status(:failed)).sort_by(&:file_colon_line).each do |scenario|
|
29
|
-
io.puts format_string(scenario.file_colon_line, :failed) + format_string(" # Scenario: " + scenario.name, :comment)
|
30
|
-
end
|
31
|
-
io.puts
|
32
|
-
end
|
33
|
-
|
34
|
-
def print_steps(status)
|
35
|
-
print_elements steps.select(&with_status(status)), status, 'steps'
|
36
|
-
end
|
37
|
-
|
38
|
-
def print_counts(label, collection)
|
39
|
-
io.puts pluralize(label, collection.size) + count_summary(collection)
|
40
|
-
end
|
41
|
-
|
42
|
-
def pluralize(word, number)
|
43
|
-
"#{number} #{number == 1 ? word : word + 's'}"
|
44
|
-
end
|
45
|
-
|
46
|
-
def with_status(status)
|
47
|
-
proc {|r| r.status == status}
|
48
|
-
end
|
49
|
-
|
50
|
-
def count_summary(results)
|
51
|
-
return "" unless results.any?
|
52
|
-
status_counts = Cucumber::STATUSES.map do |status|
|
53
|
-
count = results.select(&with_status(status)).size
|
54
|
-
format_string "#{count} #{status}", status if count > 0
|
55
|
-
end.compact.join ", "
|
56
|
-
|
57
|
-
" (#{status_counts})"
|
58
|
-
end
|
59
|
-
end
|
60
|
-
end
|