flatware 0.3.2 → 0.4.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 +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
|
+
[](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
|