flatware 0.3.0 → 0.3.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 004764c1a65d325a871a4e5dc10959436dbe7b11
4
- data.tar.gz: 6fde0c535fa7868237c65bc066d449db2fe506ed
3
+ metadata.gz: bfb0b2fec0892b096fda85d7117ecb063ead5624
4
+ data.tar.gz: be3acf00d8248975adb052c4004bd2017b66c8f8
5
5
  SHA512:
6
- metadata.gz: ccdef8b34f2425936014ad0fbb9a53bad94c29df3c72f770e46aae3d75cafcd9659e8c1533624783667c4238f1a1a0fedaaf82ce2595f3d0bed409ec7c542ad2
7
- data.tar.gz: 55b5196a2d5a08231d5440bc683c249b3508356666f719bfa566302b558978e5c3c5fdeae35e6c801800913de0c8d084818ceffe7db29c43dae2a8aa97519f19
6
+ metadata.gz: 8154c907e8c51bb3a83771cbfba07e4751b9b284965cfcd5ea634f8dd9563c28ee5da2f6c44ddbd6d326bff5ce440b42e3c30981e3f2ef3131c494037d5086a1
7
+ data.tar.gz: 4d1d8adb80cb44a973427cb1af117f321c597279246bb804d13c8978e22d33f2b2f367ebc0df7b6247b9423aae49dc1e42f487d5776c3eeafb87d71c4669abf0
@@ -1,20 +1,21 @@
1
- Copyright (c) 2011 Brian Dunn
1
+ The MIT License (MIT)
2
2
 
3
- Permission is hereby granted, free of charge, to any person obtaining
4
- a copy of this software and associated documentation files (the
5
- "Software"), to deal in the Software without restriction, including
6
- without limitation the rights to use, copy, modify, merge, publish,
7
- distribute, sublicense, and/or sell copies of the Software, and to
8
- permit persons to whom the Software is furnished to do so, subject to
9
- the following conditions:
3
+ Copyright (c) 2014 Brian Dunn
10
4
 
11
- The above copyright notice and this permission notice shall be
12
- included in all copies or substantial portions of the Software.
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
13
11
 
14
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
- LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
- OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
- WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,132 @@
1
+ # Flatware [![Build Status][travis-badge]][travis] [![Code Climate][code-climate-badge]][code-climate]
2
+
3
+ [travis-badge]: https://travis-ci.org/briandunn/flatware.png
4
+ [travis]: http://travis-ci.org/briandunn/flatware
5
+ [code-climate-badge]: https://codeclimate.com/github/briandunn/flatware.png
6
+ [code-climate]: https://codeclimate.com/github/briandunn/flatware
7
+
8
+ Flatware is a distributed cucumber runner.
9
+
10
+ ## Requirements
11
+
12
+ * ZeroMQ > 2.1
13
+
14
+ ## Installation
15
+
16
+ Add this to your Gemfile:
17
+
18
+ ```
19
+ gem 'flatware'
20
+ ```
21
+
22
+ and `bundle install`.
23
+
24
+ ## Usage
25
+
26
+ To run your entire suite with the default cucumber options, just:
27
+
28
+ ```
29
+ $ flatware
30
+ ```
31
+
32
+ If you'd like to limit the number of forked workers, you can pass the 'w' flag:
33
+
34
+ ```
35
+ $ flatware -w 3
36
+ ```
37
+
38
+ You can also pass most cucumber options to Flatware. For example, to run only
39
+ features that are not tagged 'javascript', you can:
40
+
41
+ ```
42
+ $ flatware cucumber -t ~@javascript
43
+ ```
44
+
45
+ ## Typical Usage in a Rails App
46
+
47
+ Add the following to your config/database.yml:
48
+
49
+ ```
50
+ test:
51
+ database: foo_test
52
+ ```
53
+
54
+ becomes:
55
+
56
+ ```
57
+ test:
58
+ database: foo_test<%=ENV['TEST_ENV_NUMBER']%>
59
+ ```
60
+
61
+ Run the following:
62
+
63
+ ```
64
+ $ rake db:setup # if not already done
65
+ $ flatware fan rake db:test:prepare
66
+ ```
67
+
68
+ Now you are ready to rock:
69
+
70
+ ```
71
+ $ flatware
72
+ ```
73
+
74
+ ## Planned Features
75
+
76
+ * Reliable enough to use as part of your Continuous Integration system
77
+ * Always accounts for every feature you ask it to run
78
+ * Use heuristics to run your slowest tests first
79
+ * speak Cucumber's DRB protocol; if you know how to use Spork you know how to
80
+ use Flatware
81
+
82
+ ## Design Goals
83
+
84
+ ### Maintainable
85
+
86
+ * Fully test at an integration level. Don't be afraid to change the code. If you
87
+ break it you'll know.
88
+ * Couple as loosely as possible, and only to the most stable/public bits of
89
+ Cucumber.
90
+
91
+ ### Minimal
92
+
93
+ * Projects define their own preperation scripts
94
+ * Only distribute to local cores (for now)
95
+ * Only handle cucumber
96
+
97
+ ### Robust
98
+
99
+ * Depend on a dedicated messaging library
100
+ * Be acountable for completed work; provide progress report regardless of
101
+ completing the suite.
102
+
103
+ ## Tinkering
104
+
105
+ Flatware is tested with [aruba][]. In order to get a demo cucumber project you
106
+ can add the `@no-clobber` tag to `features/flatware.feature` and run the test
107
+ with `cucumber features/flatware.feature`. Now you should have a `./tmp/aruba`
108
+ directory. CD there and `flatware` will be in your path so you can tinker away.
109
+
110
+ [aruba]: https://github.com/cucumber/aruba
111
+
112
+ ## Resources
113
+
114
+ To learn more about the messaging system that Flatware uses, take a look at the
115
+ [excellent ZeroMQ guide][z].
116
+
117
+ [z]: http://zguide.zeromq.org/page:all
118
+
119
+ ## Contributing to Flatware
120
+
121
+ * Check out the latest master to make sure the feature hasn't been implemented
122
+ or the bug hasn't been fixed yet
123
+ * Check out the issue tracker to make sure someone already hasn't requested it
124
+ and/or contributed it
125
+ * Fork the project
126
+ * Start a feature/bugfix branch
127
+ * Commit and push until you are happy with your contribution
128
+ * Make sure to add tests for it. This is important so I don't break it in a
129
+ future version unintentionally.
130
+ * Please try not to mess with the Rakefile, version, or history. If you want to
131
+ have your own version, or is otherwise necessary, that is fine, but please
132
+ isolate to its own commit so I can cherry-pick around it.
@@ -23,22 +23,14 @@ module Flatware
23
23
  worker_option
24
24
  method_option 'fail-fast', type: :boolean, default: false, desc: "Abort the run on first failure"
25
25
  method_option 'formatters', aliases: "-f", type: :array, default: %w[console], desc: "The formatters to use for output"
26
+ method_option 'dispatch-endpoint', type: :string, default: 'ipc://dispatch'
27
+ method_option 'sink-endpoint', type: :string, default: 'ipc://task'
26
28
  desc "[FLATWARE_OPTS] cucumber [CUCUMBER_ARGS]", "parallelizes cucumber with custom arguments"
27
29
  def cucumber(*)
28
- Process.setpgrp
29
- Flatware.verbose = options[:log]
30
- log "flatware options:", options
31
- log "cucumber options:", cucumber_args
32
30
  jobs = Cucumber.extract_jobs_from_args cucumber_args
33
- Worker.spawn workers
34
- fork do
35
- $0 = 'flatware dispatcher'
36
- Dispatcher.start jobs
37
- end
38
- $0 = 'flatware sink'
39
- passed = Sink.start_server jobs, Formatters.load_by_name(options['formatters']), fail_fast: options['fail-fast']
40
- Process.waitall
41
- exit passed ? 0 : 1
31
+ Worker.spawn workers, Cucumber, options['dispatch-endpoint'], options['sink-endpoint']
32
+ formatter = Formatters.load_by_name(:cucumber, options['formatters'])
33
+ start_sink jobs, formatter
42
34
  end
43
35
 
44
36
  worker_option
@@ -67,6 +59,16 @@ module Flatware
67
59
 
68
60
  private
69
61
 
62
+ def start_sink(jobs, formatter)
63
+ $0 = 'flatware sink'
64
+ Process.setpgrp
65
+ Flatware.verbose = options[:log]
66
+ Dispatcher.spawn jobs, options['dispatch-endpoint']
67
+ passed = Sink.start_server jobs, formatter, options['sink-endpoint'], fail_fast: options['fail-fast']
68
+ Process.waitall
69
+ exit passed ? 0 : 1
70
+ end
71
+
70
72
  def cucumber_args
71
73
  if index = ARGV.index('cucumber')
72
74
  ARGV[index + 1..-1]
@@ -20,7 +20,7 @@ module Flatware
20
20
  end
21
21
  scenario.failed_outside_step!(file_colon_line) if scenario
22
22
  end
23
- Sink.checkpoint checkpoint
23
+ Sink::client.checkpoint checkpoint
24
24
  end
25
25
 
26
26
  def after_step_result(_, _, _, status, *)
@@ -82,7 +82,7 @@ module Flatware
82
82
  end
83
83
 
84
84
  def send_progress(status)
85
- Sink.progress Result.new status
85
+ Sink::client.progress Result.new status
86
86
  end
87
87
 
88
88
  class Collector
@@ -1,19 +1,17 @@
1
1
  module Flatware
2
2
  class Dispatcher
3
- PORT = 'ipc://dispatch'
4
-
5
- def self.start(jobs)
6
- trap 'INT' do
7
- Flatware.close
8
- exit 1
3
+ def self.spawn(jobs, endpoint)
4
+ fork do
5
+ $0 = 'flatware dispatcher'
6
+ trap('INT') { exit 1 }
7
+ new(jobs, endpoint).dispatch!
9
8
  end
10
- new(jobs).dispatch!
11
9
  end
12
10
 
13
- def initialize(jobs)
11
+ def initialize(jobs, endpoint)
14
12
  @jobs = jobs
15
13
  @fireable = Fireable.new
16
- @dispatch = Flatware.socket ZMQ::REP, bind: PORT
14
+ @dispatch = Flatware.socket ZMQ::REP, bind: endpoint
17
15
  end
18
16
 
19
17
  def dispatch!
@@ -1,9 +1,10 @@
1
1
  module Flatware
2
2
  module Formatters
3
- def self.load_by_name(names)
3
+ def self.load_by_name(runner, names)
4
4
  formatters = names.map do |name|
5
- require "flatware/formatters/#{name}"
6
- klass = const_get name.capitalize
5
+ require "flatware/formatters/#{runner}/#{name}"
6
+ namespace = const_get({cucumber: 'Cucumber'}.fetch(runner))
7
+ klass = namespace.const_get name.capitalize
7
8
  klass.new $stdout, $stderr
8
9
  end
9
10
  Broadcaster.new formatters
@@ -0,0 +1,46 @@
1
+ require 'flatware/formatters/cucumber/console/summary'
2
+ require 'cucumber/formatter/console'
3
+
4
+ module Flatware::Formatters::Cucumber
5
+ class Console
6
+ #for format_string
7
+ include ::Cucumber::Formatter::Console
8
+
9
+ FORMATS = {
10
+ passed: '.',
11
+ failed: 'F',
12
+ undefined: 'U',
13
+ pending: 'P',
14
+ skipped: '-'
15
+ }
16
+
17
+ STATUSES = FORMATS.keys
18
+
19
+ attr_reader :out, :err
20
+
21
+ def initialize(stdout, stderr)
22
+ @out, @err = stdout, stderr
23
+ end
24
+
25
+ def progress(result)
26
+ out.print format result.progress
27
+ end
28
+
29
+ def summarize(steps, scenarios)
30
+ Summary.new(steps, scenarios, out).summarize
31
+ end
32
+
33
+ def summarize_remaining(remaining_jobs)
34
+ out.puts
35
+ out.puts "The following features have not been run:"
36
+ for job in remaining_jobs
37
+ out.puts job.id
38
+ end
39
+ end
40
+
41
+ private
42
+ def format(status)
43
+ format_string FORMATS[status], status
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,66 @@
1
+ require 'cucumber/formatter/console'
2
+ require 'flatware/formatters/cucumber/console'
3
+ require 'flatware/checkpoint'
4
+
5
+ module Flatware::Formatters::Cucumber
6
+ class Console
7
+ class Summary
8
+ include ::Cucumber::Formatter::Console
9
+ attr_reader :io, :steps, :scenarios
10
+
11
+ def initialize(steps, scenarios=[], io=StringIO.new)
12
+ @io = io
13
+ @steps = steps
14
+ @scenarios = scenarios
15
+ end
16
+
17
+ def summarize
18
+ 2.times { io.puts }
19
+ print_failures(steps, 'step')
20
+ print_failures(scenarios.select(&:failed_outside_step?), 'scenario')
21
+ print_failed_scenarios scenarios
22
+ print_counts 'scenario', scenarios
23
+ print_counts 'step', steps
24
+ end
25
+
26
+ private
27
+
28
+ def print_failed_scenarios(scenarios)
29
+ return unless scenarios.any? &with_status(:failed)
30
+
31
+ io.puts format_string "Failing Scenarios:", :failed
32
+ scenarios.select(&with_status(:failed)).sort_by(&:file_colon_line).each do |scenario|
33
+ io.puts format_string(scenario.file_colon_line, :failed) + format_string(" # Scenario: " + scenario.name, :comment)
34
+ end
35
+ io.puts
36
+ end
37
+
38
+ def print_failures(collection, label)
39
+ failures = collection.select(&with_status(:failed))
40
+ print_elements failures, :failed, pluralize(label, failures.size)
41
+ end
42
+
43
+ def print_counts(label, collection)
44
+ io.puts pluralize(label, collection.size) + count_summary(collection)
45
+ end
46
+
47
+ def pluralize(word, number)
48
+ "#{number} #{number == 1 ? word : word + 's'}"
49
+ end
50
+
51
+ def with_status(status)
52
+ proc {|r| r.status == status}
53
+ end
54
+
55
+ def count_summary(results)
56
+ return "" unless results.any?
57
+ status_counts = STATUSES.map do |status|
58
+ count = results.select(&with_status(status)).size
59
+ format_string "#{count} #{status}", status if count > 0
60
+ end.compact.join ", "
61
+
62
+ " (#{status_counts})"
63
+ end
64
+ end
65
+ end
66
+ end
@@ -1,34 +1,20 @@
1
1
  require 'flatware'
2
2
  module Flatware
3
- class Sink
4
- PORT = 'ipc://sink'
5
- class << self
6
- def push(message)
7
- client.push message
8
- end
9
-
10
- def start_server(*args)
11
- Server.new(*args).start
12
- end
3
+ module Sink
4
+ extend self
13
5
 
14
- private
15
-
16
- def client
17
- @client ||= Client.new
18
- end
19
- end
20
-
21
- %w[finished started progress checkpoint].each do |message|
22
- define_singleton_method message do |content|
23
- push [message.to_sym, content]
24
- end
6
+ def start_server(*args)
7
+ Server.new(*args).start
25
8
  end
26
9
 
27
10
  class Server
28
- def initialize(jobs, formatter, options={})
11
+ attr_reader :socket
12
+
13
+ def initialize(jobs, formatter, endpoint, options={})
29
14
  @jobs, @formatter = jobs, formatter
30
15
  options = {fail_fast: false}.merge options
31
16
  @fail_fast = options[:fail_fast]
17
+ @socket = Flatware.socket(ZMQ::PULL, bind: endpoint)
32
18
  end
33
19
 
34
20
  def start
@@ -64,13 +50,17 @@ module Flatware
64
50
  end
65
51
  end
66
52
  checkpoint_handler.summarize
67
- !checkpoint_handler.had_failures?
53
+ !failures?
68
54
  rescue Error => e
69
55
  raise unless e.message == "Interrupted system call"
70
56
  end
71
57
 
72
58
  private
73
59
 
60
+ def failures?
61
+ checkpoint_handler.had_failures? || completed_jobs.any?(&:failed?)
62
+ end
63
+
74
64
  def fail_fast?
75
65
  @fail_fast
76
66
  end
@@ -101,22 +91,6 @@ module Flatware
101
91
  def fireable
102
92
  @fireable ||= Fireable.new
103
93
  end
104
-
105
- def socket
106
- @socket ||= Flatware.socket(ZMQ::PULL, bind: PORT)
107
- end
108
- end
109
-
110
- class Client
111
- def push(message)
112
- socket.send message
113
- end
114
-
115
- private
116
-
117
- def socket
118
- @socket ||= Flatware.socket(ZMQ::PUSH, connect: PORT)
119
- end
120
94
  end
121
95
  end
122
96
  end
@@ -0,0 +1,25 @@
1
+ require 'flatware/socket'
2
+ module Flatware
3
+ module Sink
4
+ extend self
5
+ attr_accessor :client
6
+
7
+ class Client
8
+ def initialize(sink_endpoint)
9
+ @socket = Flatware.socket ZMQ::PUSH, connect: sink_endpoint
10
+ end
11
+
12
+ %w[finished started progress checkpoint].each do |message|
13
+ define_method message do |content|
14
+ push [message.to_sym, content]
15
+ end
16
+ end
17
+
18
+ private
19
+
20
+ def push(message)
21
+ @socket.send message
22
+ end
23
+ end
24
+ end
25
+ end
@@ -1,13 +1,15 @@
1
1
  require 'ffi-rzmq'
2
2
 
3
3
  module Flatware
4
- SINK_PORT = 'ipc://sink'
5
- DISPATCH_PORT = 'ipc://dispatch'
6
-
7
4
  Error = Class.new StandardError
8
5
 
9
6
  Job = Struct.new :id, :args do
10
7
  attr_accessor :worker
8
+ attr_writer :failed
9
+
10
+ def failed?
11
+ !!@failed
12
+ end
11
13
  end
12
14
 
13
15
  extend self
@@ -52,7 +54,6 @@ module Flatware
52
54
  sockets.push socket
53
55
  if port = options[:connect]
54
56
  socket.connect port
55
- sleep 0.05
56
57
  end
57
58
  if port = options[:bind]
58
59
  socket.bind port
@@ -1,3 +1,3 @@
1
1
  module Flatware
2
- VERSION = '0.3.0'
2
+ VERSION = '0.3.2'
3
3
  end
@@ -1,41 +1,47 @@
1
+ require 'flatware/sink/client'
1
2
  module Flatware
2
3
  class Worker
3
4
  attr_reader :id
4
5
 
5
- def self.listen!(id=0)
6
- new(id).listen
7
- end
8
-
9
- def initialize(id)
6
+ def initialize(id, runner, dispatch_endpoint, sink_endpoint)
10
7
  @id = id
8
+ @runner = runner
11
9
  @fireable = Fireable.new
12
- @task = Flatware.socket ZMQ::REQ, connect: Dispatcher::PORT
10
+ @sink = Sink::Client.new sink_endpoint
11
+ @task = Flatware.socket ZMQ::REQ, connect: dispatch_endpoint
13
12
  end
14
13
 
15
- def self.spawn(worker_count)
14
+ def self.spawn(worker_count, runner, dispatch_endpoint, sink_endpoint)
16
15
  worker_count.times do |i|
17
16
  fork do
18
17
  $0 = "flatware worker #{i}"
19
18
  ENV['TEST_ENV_NUMBER'] = i.to_s
20
- listen!(i)
19
+ new(i, runner, dispatch_endpoint, sink_endpoint).listen
21
20
  end
22
21
  end
23
22
  end
24
23
 
25
24
  def listen
25
+ Sink.client = sink
26
26
  report_for_duty
27
27
  fireable.until_fired task do |job|
28
28
  job.worker = id
29
- Sink.started job
30
- Cucumber.run job.id, job.args
31
- Sink.finished job
29
+ sink.started job
30
+ begin
31
+ runner.run job.id, job.args
32
+ rescue Errno::ENOENT
33
+ job.failed = true
34
+ sink.finished job
35
+ raise
36
+ end
37
+ sink.finished job
32
38
  report_for_duty
33
39
  end
34
40
  end
35
41
 
36
42
  private
37
43
 
38
- attr_reader :fireable, :task
44
+ attr_reader :fireable, :task, :sink, :runner
39
45
 
40
46
  def report_for_duty
41
47
  task.send 'ready'
metadata CHANGED
@@ -1,99 +1,105 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: flatware
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.3.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brian Dunn
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-09-05 00:00:00.000000000 Z
11
+ date: 2015-03-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: ffi-rzmq
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - ~>
17
+ - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: 1.0.0
19
+ version: '2.0'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - ~>
24
+ - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: 1.0.0
26
+ version: '2.0'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: thor
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - ~>
31
+ - - "~>"
32
32
  - !ruby/object:Gem::Version
33
33
  version: '0.13'
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - ~>
38
+ - - "~>"
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0.13'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: cucumber
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - '>='
45
+ - - ">="
46
46
  - !ruby/object:Gem::Version
47
47
  version: 1.3.0
48
+ - - "<"
49
+ - !ruby/object:Gem::Version
50
+ version: '2.0'
48
51
  type: :runtime
49
52
  prerelease: false
50
53
  version_requirements: !ruby/object:Gem::Requirement
51
54
  requirements:
52
- - - '>='
55
+ - - ">="
53
56
  - !ruby/object:Gem::Version
54
57
  version: 1.3.0
58
+ - - "<"
59
+ - !ruby/object:Gem::Version
60
+ version: '2.0'
55
61
  - !ruby/object:Gem::Dependency
56
62
  name: aruba
57
63
  requirement: !ruby/object:Gem::Requirement
58
64
  requirements:
59
- - - ~>
65
+ - - "~>"
60
66
  - !ruby/object:Gem::Version
61
67
  version: 0.5.1
62
68
  type: :development
63
69
  prerelease: false
64
70
  version_requirements: !ruby/object:Gem::Requirement
65
71
  requirements:
66
- - - ~>
72
+ - - "~>"
67
73
  - !ruby/object:Gem::Version
68
74
  version: 0.5.1
69
75
  - !ruby/object:Gem::Dependency
70
76
  name: rake
71
77
  requirement: !ruby/object:Gem::Requirement
72
78
  requirements:
73
- - - ~>
79
+ - - "~>"
74
80
  - !ruby/object:Gem::Version
75
- version: 10.0.3
81
+ version: 10.1.0
76
82
  type: :development
77
83
  prerelease: false
78
84
  version_requirements: !ruby/object:Gem::Requirement
79
85
  requirements:
80
- - - ~>
86
+ - - "~>"
81
87
  - !ruby/object:Gem::Version
82
- version: 10.0.3
88
+ version: 10.1.0
83
89
  - !ruby/object:Gem::Dependency
84
90
  name: rspec
85
91
  requirement: !ruby/object:Gem::Requirement
86
92
  requirements:
87
- - - ~>
93
+ - - "~>"
88
94
  - !ruby/object:Gem::Version
89
- version: 2.13.0
95
+ version: 2.14.0
90
96
  type: :development
91
97
  prerelease: false
92
98
  version_requirements: !ruby/object:Gem::Requirement
93
99
  requirements:
94
- - - ~>
100
+ - - "~>"
95
101
  - !ruby/object:Gem::Version
96
- version: 2.13.0
102
+ version: 2.14.0
97
103
  description: A distributed cucumber runner
98
104
  email: brian@hashrocket.com
99
105
  executables:
@@ -101,8 +107,11 @@ executables:
101
107
  extensions: []
102
108
  extra_rdoc_files:
103
109
  - LICENSE.txt
104
- - README.rdoc
110
+ - README.md
105
111
  files:
112
+ - LICENSE.txt
113
+ - README.md
114
+ - bin/flatware
106
115
  - lib/flatware.rb
107
116
  - lib/flatware/checkpoint.rb
108
117
  - lib/flatware/checkpoint_handler.rb
@@ -113,9 +122,9 @@ files:
113
122
  - lib/flatware/dispatcher.rb
114
123
  - lib/flatware/fireable.rb
115
124
  - lib/flatware/formatters.rb
116
- - lib/flatware/formatters/console.rb
117
- - lib/flatware/formatters/console/summary.rb
118
- - lib/flatware/formatters/http.rb
125
+ - lib/flatware/formatters/cucumber/console.rb
126
+ - lib/flatware/formatters/cucumber/console/summary.rb
127
+ - lib/flatware/formatters/cucumber/http.rb
119
128
  - lib/flatware/pids.rb
120
129
  - lib/flatware/poller.rb
121
130
  - lib/flatware/processor_info.rb
@@ -124,13 +133,11 @@ files:
124
133
  - lib/flatware/scenario_result.rb
125
134
  - lib/flatware/serialized_exception.rb
126
135
  - lib/flatware/sink.rb
136
+ - lib/flatware/sink/client.rb
127
137
  - lib/flatware/socket.rb
128
138
  - lib/flatware/step_result.rb
129
139
  - lib/flatware/version.rb
130
140
  - lib/flatware/worker.rb
131
- - LICENSE.txt
132
- - README.rdoc
133
- - bin/flatware
134
141
  homepage: http://github.com/briandunn/flatware
135
142
  licenses:
136
143
  - MIT
@@ -141,17 +148,17 @@ require_paths:
141
148
  - lib
142
149
  required_ruby_version: !ruby/object:Gem::Requirement
143
150
  requirements:
144
- - - '>='
151
+ - - ">="
145
152
  - !ruby/object:Gem::Version
146
153
  version: '0'
147
154
  required_rubygems_version: !ruby/object:Gem::Requirement
148
155
  requirements:
149
- - - '>='
156
+ - - ">="
150
157
  - !ruby/object:Gem::Version
151
158
  version: '0'
152
159
  requirements: []
153
160
  rubyforge_project:
154
- rubygems_version: 2.0.6
161
+ rubygems_version: 2.4.6
155
162
  signing_key:
156
163
  specification_version: 4
157
164
  summary: A distributed cucumber runner
@@ -1,102 +0,0 @@
1
- = Flatware
2
-
3
- {<img src="https://travis-ci.org/briandunn/flatware.png" />}[https://travis-ci.org/briandunn/flatware]
4
- {<img src="https://codeclimate.com/badge.png" />}[https://codeclimate.com/github/briandunn/flatware]
5
-
6
- Flatware is a distributed cucumber runner.
7
-
8
- == Requirements
9
-
10
- * ZeroMQ > 2.1
11
-
12
- == Installation
13
-
14
- Add this to your Gemfile:
15
-
16
- gem 'flatware'
17
-
18
- and `bundle install`.
19
-
20
- == Usage
21
-
22
- To run your entire suite with the default cucumber options, just:
23
-
24
- flatware
25
-
26
- If you'd like to limit the number of forked workers, you can pass the 'w' flag:
27
-
28
- flatware -w 3
29
-
30
- You can also pass most cucumber options to flatware. For example, to run only features that are not tagged 'javascript', you can:
31
-
32
- flatware cucumber -t ~@javascript
33
-
34
- == Typical Usage in a Rails App
35
-
36
- Add the following to your config/database.yml:
37
-
38
- test:
39
- database: foo_test
40
-
41
- becomes:
42
-
43
- test:
44
- database: foo_test<%=ENV['TEST_ENV_NUMBER']%>
45
-
46
- Run the following:
47
-
48
- rake db:setup # if not already done
49
- flatware fan rake db:test:prepare
50
-
51
- Now you are ready to rock:
52
-
53
- flatware
54
-
55
- == Planned Features
56
-
57
- * Reliable enough to use as part of your Continuous Integration system
58
- * Always accounts for every feature you ask it to run
59
- * Use heuristics to run your slowest tests first
60
- * speak Cucumber's DRB protocol; if you know how to use Spork you know how to use Flatware
61
-
62
- == Design Goals
63
-
64
- === Maintainable
65
-
66
- * Fully test at an integration level. Don't be afraid to change the code. If you break it you'll know.
67
- * Couple as loosely as possible, and only to the most stable/public bits of Cucumber.
68
-
69
- === Minimal
70
-
71
- * Projects define their own preperation scripts
72
- * Only distribute to local cores (for now)
73
- * Only handle cucumber
74
-
75
- === Robust
76
-
77
- * Depend on a dedicated messaging library
78
- * Be acountable for completed work; provide progress report regardless of completing the suite.
79
-
80
- == Tinkering
81
-
82
- Flatware is tested with aruba. In order to get a demo cucumber project you can add the `@no-clobber` tag to `features/flatware.feature` and run the test with `cucumber features/flatware.feature`. Now you should have a `./tmp/aruba` directory. CD there and `flatware` will be in your path so you can tinker away.
83
-
84
- == Resources
85
-
86
- The excellent ZeroMQ guide: http://zguide.zeromq.org/page:all
87
-
88
- == Contributing to Flatware
89
-
90
- * Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet
91
- * Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it
92
- * Fork the project
93
- * Start a feature/bugfix branch
94
- * Commit and push until you are happy with your contribution
95
- * Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
96
- * Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
97
-
98
- == Copyright
99
-
100
- Copyright (c) 2011-2012 Brian Dunn. See LICENSE.txt for
101
- further details.
102
-
@@ -1,48 +0,0 @@
1
- require 'flatware/formatters/console/summary'
2
- require 'cucumber/formatter/console'
3
-
4
- module Flatware
5
- module Formatters
6
- class Console
7
- #for format_string
8
- include ::Cucumber::Formatter::Console
9
-
10
- FORMATS = {
11
- passed: '.',
12
- failed: 'F',
13
- undefined: 'U',
14
- pending: 'P',
15
- skipped: '-'
16
- }
17
-
18
- STATUSES = FORMATS.keys
19
-
20
- attr_reader :out, :err
21
-
22
- def initialize(stdout, stderr)
23
- @out, @err = stdout, stderr
24
- end
25
-
26
- def progress(result)
27
- out.print format result.progress
28
- end
29
-
30
- def summarize(steps, scenarios)
31
- Summary.new(steps, scenarios, out).summarize
32
- end
33
-
34
- def summarize_remaining(remaining_jobs)
35
- out.puts
36
- out.puts "The following features have not been run:"
37
- for job in remaining_jobs
38
- out.puts job.id
39
- end
40
- end
41
-
42
- private
43
- def format(status)
44
- format_string FORMATS[status], status
45
- end
46
- end
47
- end
48
- end
@@ -1,67 +0,0 @@
1
- require 'cucumber/formatter/console'
2
- require 'flatware/formatters/console'
3
- require 'flatware/checkpoint'
4
- module Flatware
5
- module Formatters
6
- class Console
7
- class Summary
8
- include ::Cucumber::Formatter::Console
9
- attr_reader :io, :steps, :scenarios
10
-
11
- def initialize(steps, scenarios=[], io=StringIO.new)
12
- @io = io
13
- @steps = steps
14
- @scenarios = scenarios
15
- end
16
-
17
- def summarize
18
- 2.times { io.puts }
19
- print_failures(steps, 'step')
20
- print_failures(scenarios.select(&:failed_outside_step?), 'scenario')
21
- print_failed_scenarios scenarios
22
- print_counts 'scenario', scenarios
23
- print_counts 'step', steps
24
- end
25
-
26
- private
27
-
28
- def print_failed_scenarios(scenarios)
29
- return unless scenarios.any? &with_status(:failed)
30
-
31
- io.puts format_string "Failing Scenarios:", :failed
32
- scenarios.select(&with_status(:failed)).sort_by(&:file_colon_line).each do |scenario|
33
- io.puts format_string(scenario.file_colon_line, :failed) + format_string(" # Scenario: " + scenario.name, :comment)
34
- end
35
- io.puts
36
- end
37
-
38
- def print_failures(collection, label)
39
- failures = collection.select(&with_status(:failed))
40
- print_elements failures, :failed, pluralize(label, failures.size)
41
- end
42
-
43
- def print_counts(label, collection)
44
- io.puts pluralize(label, collection.size) + count_summary(collection)
45
- end
46
-
47
- def pluralize(word, number)
48
- "#{number} #{number == 1 ? word : word + 's'}"
49
- end
50
-
51
- def with_status(status)
52
- proc {|r| r.status == status}
53
- end
54
-
55
- def count_summary(results)
56
- return "" unless results.any?
57
- status_counts = STATUSES.map do |status|
58
- count = results.select(&with_status(status)).size
59
- format_string "#{count} #{status}", status if count > 0
60
- end.compact.join ", "
61
-
62
- " (#{status_counts})"
63
- end
64
- end
65
- end
66
- end
67
- end