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.
@@ -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
@@ -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
@@ -1,3 +1,3 @@
1
1
  module Flatware
2
- VERSION = '0.2.0'
2
+ VERSION = '0.3.0'
3
3
  end
@@ -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
- time = Benchmark.realtime do
21
- fireable
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
- def log(*args)
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.2.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-07-10 00:00:00.000000000 Z
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: 1.8.23
154
+ rubygems_version: 2.0.6
162
155
  signing_key:
163
- specification_version: 3
156
+ specification_version: 4
164
157
  summary: A distributed cucumber runner
165
158
  test_files: []
@@ -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