flatware 0.2.0 → 0.3.0

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