flatware 0.3.2 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +83 -39
- data/lib/flatware-cucumber.rb +1 -0
- data/lib/flatware-rspec.rb +1 -0
- data/lib/flatware.rb +2 -10
- data/lib/flatware/broadcaster.rb +15 -0
- data/lib/flatware/cli.rb +10 -34
- data/lib/flatware/cucumber.rb +37 -12
- data/lib/flatware/cucumber/checkpoint.rb +28 -0
- data/lib/flatware/cucumber/cli.rb +22 -0
- data/lib/flatware/cucumber/formatter.rb +36 -84
- data/lib/flatware/{formatters/cucumber → cucumber/formatters}/console.rb +5 -3
- data/lib/flatware/{formatters/cucumber → cucumber/formatters}/console/summary.rb +3 -3
- data/lib/flatware/cucumber/result.rb +27 -0
- data/lib/flatware/cucumber/scenario_result.rb +38 -0
- data/lib/flatware/cucumber/step_result.rb +30 -0
- data/lib/flatware/poller.rb +2 -2
- data/lib/flatware/rspec.rb +28 -0
- data/lib/flatware/rspec/checkpoint.rb +29 -0
- data/lib/flatware/rspec/cli.rb +16 -0
- data/lib/flatware/rspec/example_notification.rb +21 -0
- data/lib/flatware/rspec/examples_notification.rb +24 -0
- data/lib/flatware/rspec/formatter.rb +50 -0
- data/lib/flatware/rspec/formatters/console.rb +33 -0
- data/lib/flatware/rspec/summary.rb +40 -0
- data/lib/flatware/serialized_exception.rb +12 -8
- data/lib/flatware/sink.rb +43 -33
- data/lib/flatware/socket.rb +89 -25
- data/lib/flatware/version.rb +1 -1
- data/lib/flatware/worker.rb +16 -9
- metadata +27 -55
- data/lib/flatware/checkpoint.rb +0 -28
- data/lib/flatware/checkpoint_handler.rb +0 -45
- data/lib/flatware/dispatcher.rb +0 -31
- data/lib/flatware/fireable.rb +0 -34
- data/lib/flatware/formatters.rb +0 -27
- data/lib/flatware/formatters/cucumber/http.rb +0 -83
- data/lib/flatware/result.rb +0 -25
- data/lib/flatware/scenario_decorator.rb +0 -22
- data/lib/flatware/scenario_result.rb +0 -36
- data/lib/flatware/step_result.rb +0 -27
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 00a71ce8a23e22600391980c40aac3425a1efd27
|
4
|
+
data.tar.gz: '082d74e5882c2cb99bfc4af567618e70817bb08d'
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c591c042ab1bae59ba7e25309ceae39ca389f60b1d6f340882db31e3b0806e9acd0a8dfaa512e5529a2f1f636c297c9ba5335e247d3de3b65b90e3929b2adbf3
|
7
|
+
data.tar.gz: 33043b7af9e2d929e7a99c8e53c127ac9bbc4bb366f78e74ae32e53432980d64bb2b61aa7eecf818b2611df25da68d12c0ff975a463125b35748c4227d22ab16
|
data/README.md
CHANGED
@@ -1,83 +1,124 @@
|
|
1
1
|
# Flatware [![Build Status][travis-badge]][travis] [![Code Climate][code-climate-badge]][code-climate]
|
2
2
|
|
3
|
-
[travis-badge]: https://travis-ci.org/briandunn/flatware.
|
3
|
+
[travis-badge]: https://travis-ci.org/briandunn/flatware.svg?branch=master
|
4
4
|
[travis]: http://travis-ci.org/briandunn/flatware
|
5
5
|
[code-climate-badge]: https://codeclimate.com/github/briandunn/flatware.png
|
6
6
|
[code-climate]: https://codeclimate.com/github/briandunn/flatware
|
7
7
|
|
8
|
-
Flatware
|
8
|
+
Flatware parallelizes your test suite to significantly reduce test time.
|
9
9
|
|
10
10
|
## Requirements
|
11
11
|
|
12
|
-
* ZeroMQ >
|
12
|
+
* ZeroMQ > 4.0
|
13
13
|
|
14
14
|
## Installation
|
15
15
|
|
16
|
-
|
16
|
+
### ZeroMQ
|
17
17
|
|
18
|
+
#### Linux Ubuntu
|
19
|
+
|
20
|
+
```sh
|
21
|
+
sudo apt-get install -qq libzmq3-dev
|
18
22
|
```
|
19
|
-
|
23
|
+
|
24
|
+
(Never you mind the 3. This package contains ZMQ version 4.)
|
25
|
+
|
26
|
+
#### Mac OSX
|
27
|
+
|
28
|
+
Ruby FFI isn't getting along with the latest ZMQ formula. A tweaked verson is available in the Hashrocket tap.
|
29
|
+
|
30
|
+
```sh
|
31
|
+
brew tap hashrocket/formulas
|
32
|
+
brew install hashrocket/formulas/zeromq
|
33
|
+
brew install zeromq
|
20
34
|
```
|
21
35
|
|
22
|
-
|
36
|
+
### Flatware
|
37
|
+
|
38
|
+
Add the runners you need to your Gemfile:
|
39
|
+
|
40
|
+
```ruby
|
41
|
+
gem 'flatware-rspec' # one
|
42
|
+
gem 'flatware-cucumber' # or both
|
43
|
+
```
|
44
|
+
|
45
|
+
then run
|
46
|
+
|
47
|
+
```sh
|
48
|
+
bundle install
|
49
|
+
```
|
23
50
|
|
24
51
|
## Usage
|
25
52
|
|
26
|
-
|
53
|
+
### Cucumber
|
54
|
+
|
55
|
+
To run your entire suite with the default cucumber options, add the `flatware-cucumber` gem and just:
|
27
56
|
|
57
|
+
```sh
|
58
|
+
$ flatware cucumber
|
28
59
|
```
|
29
|
-
|
60
|
+
|
61
|
+
### RSpec
|
62
|
+
|
63
|
+
To run your entire suite with the default rspec options add the `flatware-rspec` gem and just:
|
64
|
+
|
65
|
+
```sh
|
66
|
+
$ flatware rspec
|
30
67
|
```
|
31
68
|
|
69
|
+
### Options
|
70
|
+
|
32
71
|
If you'd like to limit the number of forked workers, you can pass the 'w' flag:
|
33
72
|
|
34
|
-
```
|
73
|
+
```sh
|
35
74
|
$ flatware -w 3
|
36
75
|
```
|
37
76
|
|
38
|
-
You can also pass most cucumber options to Flatware. For example, to run only
|
77
|
+
You can also pass most cucumber/rspec options to Flatware. For example, to run only
|
39
78
|
features that are not tagged 'javascript', you can:
|
40
79
|
|
41
|
-
```
|
80
|
+
```sh
|
42
81
|
$ flatware cucumber -t ~@javascript
|
43
82
|
```
|
44
83
|
|
84
|
+
Additionally, for either cucumber or rspec you can specify a directory:
|
85
|
+
|
86
|
+
```sh
|
87
|
+
$ flatware rspec spec/features
|
88
|
+
```
|
89
|
+
|
45
90
|
## Typical Usage in a Rails App
|
46
91
|
|
47
|
-
Add the following to your config/database.yml
|
92
|
+
Add the following to your `config/database.yml`:
|
48
93
|
|
49
|
-
```
|
94
|
+
```yml
|
50
95
|
test:
|
51
96
|
database: foo_test
|
52
97
|
```
|
53
98
|
|
54
99
|
becomes:
|
55
100
|
|
56
|
-
```
|
101
|
+
```yml
|
57
102
|
test:
|
58
103
|
database: foo_test<%=ENV['TEST_ENV_NUMBER']%>
|
59
104
|
```
|
60
105
|
|
61
106
|
Run the following:
|
62
107
|
|
63
|
-
```
|
108
|
+
```sh
|
64
109
|
$ rake db:setup # if not already done
|
65
110
|
$ flatware fan rake db:test:prepare
|
66
111
|
```
|
67
112
|
|
68
113
|
Now you are ready to rock:
|
69
114
|
|
70
|
-
```
|
71
|
-
$ flatware
|
115
|
+
```sh
|
116
|
+
$ flatware rspec && flatware cucumber
|
72
117
|
```
|
73
118
|
|
74
119
|
## Planned Features
|
75
120
|
|
76
|
-
* Reliable enough to use as part of your Continuous Integration system
|
77
|
-
* Always accounts for every feature you ask it to run
|
78
121
|
* 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
122
|
|
82
123
|
## Design Goals
|
83
124
|
|
@@ -86,28 +127,35 @@ $ flatware
|
|
86
127
|
* Fully test at an integration level. Don't be afraid to change the code. If you
|
87
128
|
break it you'll know.
|
88
129
|
* Couple as loosely as possible, and only to the most stable/public bits of
|
89
|
-
Cucumber.
|
130
|
+
Cucumber and RSpec.
|
90
131
|
|
91
132
|
### Minimal
|
92
133
|
|
93
|
-
* Projects define their own
|
134
|
+
* Projects define their own preparation scripts
|
94
135
|
* Only distribute to local cores (for now)
|
95
|
-
* Only handle cucumber
|
96
136
|
|
97
137
|
### Robust
|
98
138
|
|
99
139
|
* Depend on a dedicated messaging library
|
100
|
-
* Be
|
140
|
+
* Be accountable for completed work; provide progress report regardless of
|
101
141
|
completing the suite.
|
102
142
|
|
103
143
|
## Tinkering
|
104
144
|
|
105
|
-
Flatware
|
145
|
+
Flatware integration tests use [aruba][a]. In order to get a demo cucumber project you
|
106
146
|
can add the `@no-clobber` tag to `features/flatware.feature` and run the test
|
107
147
|
with `cucumber features/flatware.feature`. Now you should have a `./tmp/aruba`
|
108
148
|
directory. CD there and `flatware` will be in your path so you can tinker away.
|
109
149
|
|
110
|
-
|
150
|
+
## How it works
|
151
|
+
|
152
|
+
Flatware relies on a message passing system to enable concurrency.
|
153
|
+
The main process declares a worker for each cpu in the computer. Each
|
154
|
+
worker forks from the main process and is then assigned a portion of the
|
155
|
+
test suite. As the worker runs the test suite it sends progress
|
156
|
+
messages to the main process. These messages are collected and when
|
157
|
+
the last worker is finished the main process provides a report on the
|
158
|
+
collected progress messages.
|
111
159
|
|
112
160
|
## Resources
|
113
161
|
|
@@ -115,18 +163,14 @@ To learn more about the messaging system that Flatware uses, take a look at the
|
|
115
163
|
[excellent ZeroMQ guide][z].
|
116
164
|
|
117
165
|
[z]: http://zguide.zeromq.org/page:all
|
166
|
+
[a]: https://github.com/cucumber/aruba
|
118
167
|
|
119
168
|
## Contributing to Flatware
|
120
169
|
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
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.
|
170
|
+
Do whatever you want. I'd love to help make sure Flatware meets your needs.
|
171
|
+
|
172
|
+
## About
|
173
|
+
|
174
|
+
[![Hashrocket logo](https://hashrocket.com/hashrocket_logo.svg)](https://hashrocket.com)
|
175
|
+
|
176
|
+
Flatware is supported by the team at [Hashrocket](https://hashrocket.com), a multidisciplinary design & development consultancy. If you'd like to [work with us](https://hashrocket.com/contact-us/hire-us) or [join our team](https://hashrocket.com/contact-us/jobs), don't hesitate to get in touch.
|
@@ -0,0 +1 @@
|
|
1
|
+
require 'flatware/cucumber'
|
@@ -0,0 +1 @@
|
|
1
|
+
require 'flatware/rspec'
|
data/lib/flatware.rb
CHANGED
@@ -1,17 +1,9 @@
|
|
1
1
|
module Flatware
|
2
|
-
require 'flatware/checkpoint'
|
3
|
-
require 'flatware/checkpoint_handler'
|
4
2
|
require 'flatware/processor_info'
|
5
3
|
require 'flatware/cli'
|
6
|
-
require 'flatware/
|
7
|
-
require 'flatware/dispatcher'
|
8
|
-
require 'flatware/fireable'
|
9
|
-
require 'flatware/formatters'
|
10
|
-
require 'flatware/result'
|
11
|
-
require 'flatware/scenario_decorator'
|
12
|
-
require 'flatware/scenario_result'
|
4
|
+
require 'flatware/poller'
|
13
5
|
require 'flatware/sink'
|
14
6
|
require 'flatware/socket'
|
15
|
-
require 'flatware/step_result'
|
16
7
|
require 'flatware/worker'
|
8
|
+
require 'flatware/broadcaster'
|
17
9
|
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module Flatware
|
2
|
+
class Broadcaster
|
3
|
+
attr_reader :formatters
|
4
|
+
|
5
|
+
def initialize(formatters)
|
6
|
+
@formatters = formatters
|
7
|
+
end
|
8
|
+
|
9
|
+
def method_missing(name, *args)
|
10
|
+
formatters.each do |formatter|
|
11
|
+
formatter.send name, *args if formatter.respond_to? name
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
data/lib/flatware/cli.rb
CHANGED
@@ -13,26 +13,6 @@ module Flatware
|
|
13
13
|
|
14
14
|
class_option :log, aliases: "-l", type: :boolean, desc: "Print debug messages to $stderr"
|
15
15
|
|
16
|
-
default_task :default
|
17
|
-
worker_option
|
18
|
-
desc "default [FLATWARE_OPTS]", "parallelizes cucumber with default arguments"
|
19
|
-
def default(*)
|
20
|
-
invoke :cucumber
|
21
|
-
end
|
22
|
-
|
23
|
-
worker_option
|
24
|
-
method_option 'fail-fast', type: :boolean, default: false, desc: "Abort the run on first failure"
|
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'
|
28
|
-
desc "[FLATWARE_OPTS] cucumber [CUCUMBER_ARGS]", "parallelizes cucumber with custom arguments"
|
29
|
-
def cucumber(*)
|
30
|
-
jobs = Cucumber.extract_jobs_from_args cucumber_args
|
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
|
34
|
-
end
|
35
|
-
|
36
16
|
worker_option
|
37
17
|
desc "fan [COMMAND]", "executes the given job on all of the workers"
|
38
18
|
def fan(*command)
|
@@ -49,7 +29,6 @@ module Flatware
|
|
49
29
|
Process.waitall
|
50
30
|
end
|
51
31
|
|
52
|
-
|
53
32
|
desc "clear", "kills all flatware processes"
|
54
33
|
def clear
|
55
34
|
(Flatware.pids - [$$]).each do |pid|
|
@@ -59,24 +38,13 @@ module Flatware
|
|
59
38
|
|
60
39
|
private
|
61
40
|
|
62
|
-
def start_sink(jobs
|
41
|
+
def start_sink(jobs:, workers:, formatter:)
|
63
42
|
$0 = 'flatware sink'
|
64
43
|
Process.setpgrp
|
65
|
-
Flatware.
|
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
|
44
|
+
passed = Sink.start_server jobs: jobs, formatter: Flatware::Broadcaster.new([formatter]), sink: options['sink-endpoint'], dispatch: options['dispatch-endpoint'], worker_count: workers
|
69
45
|
exit passed ? 0 : 1
|
70
46
|
end
|
71
47
|
|
72
|
-
def cucumber_args
|
73
|
-
if index = ARGV.index('cucumber')
|
74
|
-
ARGV[index + 1..-1]
|
75
|
-
else
|
76
|
-
[]
|
77
|
-
end
|
78
|
-
end
|
79
|
-
|
80
48
|
def log(*args)
|
81
49
|
Flatware.log(*args)
|
82
50
|
end
|
@@ -86,3 +54,11 @@ module Flatware
|
|
86
54
|
end
|
87
55
|
end
|
88
56
|
end
|
57
|
+
|
58
|
+
flatware_gems = Gem.loaded_specs.keys.grep(/^flatware-/)
|
59
|
+
|
60
|
+
if flatware_gems.count > 0
|
61
|
+
flatware_gems.each(&method(:require))
|
62
|
+
else
|
63
|
+
puts "The flatware gem is a dependency of flatware runners for rspec and cucumber. Try adding flatware-rspec or flatware-cucumber to your Gemfile."
|
64
|
+
end
|
data/lib/flatware/cucumber.rb
CHANGED
@@ -1,26 +1,51 @@
|
|
1
1
|
require 'cucumber'
|
2
|
-
require 'flatware/cucumber/
|
2
|
+
require 'flatware/cucumber/checkpoint'
|
3
|
+
require 'flatware/cucumber/formatter'
|
4
|
+
require 'flatware/cucumber/result'
|
5
|
+
require 'flatware/cucumber/scenario_result'
|
6
|
+
require 'flatware/cucumber/step_result'
|
7
|
+
require 'flatware/cucumber/formatters/console'
|
8
|
+
require 'flatware/cucumber/cli'
|
9
|
+
|
3
10
|
module Flatware
|
4
11
|
module Cucumber
|
12
|
+
class Config
|
13
|
+
attr_reader :config, :args
|
14
|
+
def initialize(cucumber_config, args)
|
15
|
+
@config, @args = cucumber_config, args
|
16
|
+
end
|
5
17
|
|
6
|
-
|
18
|
+
def feature_dir
|
19
|
+
@config.feature_dirs.first
|
20
|
+
end
|
21
|
+
|
22
|
+
def jobs
|
23
|
+
feature_files.map { |file| Job.new file, args }.to_a
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
7
27
|
|
8
|
-
|
28
|
+
def feature_files
|
29
|
+
config.feature_files - config.feature_dirs
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
extend self
|
9
34
|
|
10
|
-
def
|
35
|
+
def configure(args, out_stream=$stdout, error_stream=$stderr)
|
11
36
|
raw_args = args.dup
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
37
|
+
cli_config = ::Cucumber::Cli::Configuration.new(out_stream, error_stream)
|
38
|
+
cli_config.parse! args + %w[--format Flatware::Cucumber::Formatter]
|
39
|
+
cucumber_config = ::Cucumber::Configuration.new cli_config
|
40
|
+
Config.new cucumber_config, raw_args
|
16
41
|
end
|
17
42
|
|
18
|
-
def run(feature_files
|
19
|
-
runtime
|
43
|
+
def run(feature_files, options)
|
44
|
+
runtime(Array(feature_files) + options).run!
|
20
45
|
end
|
21
46
|
|
22
|
-
def runtime
|
23
|
-
|
47
|
+
def runtime(args)
|
48
|
+
::Cucumber::Runtime.new(configure(args).config)
|
24
49
|
end
|
25
50
|
end
|
26
51
|
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module Flatware
|
2
|
+
module Cucumber
|
3
|
+
class Checkpoint
|
4
|
+
attr_reader :steps, :scenarios
|
5
|
+
def initialize(steps, scenarios)
|
6
|
+
@steps, @scenarios = serialize_steps(steps), serialize_scenarios(scenarios)
|
7
|
+
end
|
8
|
+
|
9
|
+
def failures?
|
10
|
+
scenarios.any? &:failed?
|
11
|
+
end
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
def serialize_steps(steps)
|
16
|
+
steps.map do |step|
|
17
|
+
StepResult.new step.status, step.exception
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def serialize_scenarios(scenarios)
|
22
|
+
scenarios.map do |scenario|
|
23
|
+
ScenarioResult.new scenario.status, scenario.file_colon_line, scenario.name, scenario.exception
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,22 @@
|
|
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 "cucumber [FLATWARE_OPTS] [CUCUMBER_ARGS]", "parallelizes cucumber with custom arguments"
|
9
|
+
def cucumber(*args)
|
10
|
+
config = Cucumber.configure args
|
11
|
+
|
12
|
+
unless config.jobs.any?
|
13
|
+
puts "Please create some feature files in the #{config.feature_dir} directory."
|
14
|
+
exit 1
|
15
|
+
end
|
16
|
+
|
17
|
+
Flatware.verbose = options[:log]
|
18
|
+
Worker.spawn count: workers, runner: Cucumber, dispatch: options['dispatch-endpoint'], sink: options['sink-endpoint']
|
19
|
+
start_sink jobs: config.jobs, workers: workers, formatter: Flatware::Cucumber::Formatters::Console.new($stdout, $stderr)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|