test-queue-split 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.
Files changed (47) hide show
  1. checksums.yaml +7 -0
  2. data/Gemfile +3 -0
  3. data/Gemfile-minitest4 +3 -0
  4. data/Gemfile-minitest4.lock +38 -0
  5. data/Gemfile-rspec3-0 +3 -0
  6. data/Gemfile-rspec3-0.lock +40 -0
  7. data/Gemfile-rspec3-1 +3 -0
  8. data/Gemfile-rspec3-1.lock +40 -0
  9. data/Gemfile-rspec3-2 +3 -0
  10. data/Gemfile-rspec3-2.lock +41 -0
  11. data/Gemfile-testunit +3 -0
  12. data/Gemfile-testunit.lock +44 -0
  13. data/Gemfile.lock +54 -0
  14. data/README.md +114 -0
  15. data/Thorfile +9 -0
  16. data/bin/cucumber-queue +4 -0
  17. data/bin/minitest-queue +5 -0
  18. data/bin/rspec-queue +4 -0
  19. data/bin/testunit-queue +5 -0
  20. data/features/bad.feature +5 -0
  21. data/features/sample.feature +25 -0
  22. data/features/sample2.feature +29 -0
  23. data/features/step_definitions/common.rb +15 -0
  24. data/lib/test-queue.rb +1 -0
  25. data/lib/test_queue/iterator.rb +72 -0
  26. data/lib/test_queue/runner/cucumber.rb +46 -0
  27. data/lib/test_queue/runner/minitest.rb +25 -0
  28. data/lib/test_queue/runner/minitest4.rb +65 -0
  29. data/lib/test_queue/runner/minitest5.rb +62 -0
  30. data/lib/test_queue/runner/puppet_lint.rb +31 -0
  31. data/lib/test_queue/runner/rspec.rb +35 -0
  32. data/lib/test_queue/runner/rspec2.rb +35 -0
  33. data/lib/test_queue/runner/rspec3.rb +45 -0
  34. data/lib/test_queue/runner/sample.rb +76 -0
  35. data/lib/test_queue/runner/testunit.rb +56 -0
  36. data/lib/test_queue/runner.rb +395 -0
  37. data/lib/test_queue/version.rb +4 -0
  38. data/lib/test_queue.rb +8 -0
  39. data/test/sample_minispec.rb +31 -0
  40. data/test/sample_minitest4.rb +23 -0
  41. data/test/sample_minitest5.rb +23 -0
  42. data/test/sample_spec.rb +23 -0
  43. data/test/sample_testunit.rb +23 -0
  44. data/test-multi.sh +8 -0
  45. data/test-queue-split.gemspec +28 -0
  46. data/test.sh +23 -0
  47. metadata +141 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 109d87b665a30d8712019bf2812a5a14fd2daefe
4
+ data.tar.gz: 2dd5c3c1671ff672832fd92f9b970f808bdf50e7
5
+ SHA512:
6
+ metadata.gz: d153890bea9cfadef47dc1b7645175ff90a62693a2c3db809af20c311016490571f3bebc1cdafa5d93628709dbff3021f88cfcebb300216d66f64450e7280475
7
+ data.tar.gz: 30dc8854757eab9b6e82161a1506bd6370a2ef58c2f3e63b3916d6c74d548d6fe7ae4deeefb76db210456d5efdc8e8a431e484b8ec26405d71f8b0afb3060686
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source 'https://rubygems.org'
2
+ gemspec
3
+ gem 'minitest', '5.3.3'
data/Gemfile-minitest4 ADDED
@@ -0,0 +1,3 @@
1
+ source 'https://rubygems.org'
2
+ gemspec
3
+ gem 'minitest', '4.7.3'
@@ -0,0 +1,38 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ test-queue (0.2.13)
5
+
6
+ GEM
7
+ remote: https://rubygems.org/
8
+ specs:
9
+ builder (3.2.2)
10
+ cucumber (1.3.15)
11
+ builder (>= 2.1.2)
12
+ diff-lcs (>= 1.1.3)
13
+ gherkin (~> 2.12)
14
+ multi_json (>= 1.7.5, < 2.0)
15
+ multi_test (>= 0.1.1)
16
+ diff-lcs (1.2.5)
17
+ gherkin (2.12.2)
18
+ multi_json (~> 1.3)
19
+ minitest (4.7.3)
20
+ multi_json (1.10.1)
21
+ multi_test (0.1.1)
22
+ rspec (2.99.0)
23
+ rspec-core (~> 2.99.0)
24
+ rspec-expectations (~> 2.99.0)
25
+ rspec-mocks (~> 2.99.0)
26
+ rspec-core (2.99.1)
27
+ rspec-expectations (2.99.1)
28
+ diff-lcs (>= 1.1.3, < 2.0)
29
+ rspec-mocks (2.99.1)
30
+
31
+ PLATFORMS
32
+ ruby
33
+
34
+ DEPENDENCIES
35
+ cucumber (~> 1.3.10)
36
+ minitest (= 4.7.3)
37
+ rspec (>= 2.13, < 4.0)
38
+ test-queue!
data/Gemfile-rspec3-0 ADDED
@@ -0,0 +1,3 @@
1
+ source 'https://rubygems.org'
2
+ gemspec
3
+ gem 'rspec', '~> 3.0.0'
@@ -0,0 +1,40 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ test-queue (0.2.12)
5
+
6
+ GEM
7
+ remote: https://rubygems.org/
8
+ specs:
9
+ builder (3.2.2)
10
+ cucumber (1.3.19)
11
+ builder (>= 2.1.2)
12
+ diff-lcs (>= 1.1.3)
13
+ gherkin (~> 2.12)
14
+ multi_json (>= 1.7.5, < 2.0)
15
+ multi_test (>= 0.1.2)
16
+ diff-lcs (1.2.5)
17
+ gherkin (2.12.2)
18
+ multi_json (~> 1.3)
19
+ multi_json (1.11.0)
20
+ multi_test (0.1.2)
21
+ rspec (3.0.0)
22
+ rspec-core (~> 3.0.0)
23
+ rspec-expectations (~> 3.0.0)
24
+ rspec-mocks (~> 3.0.0)
25
+ rspec-core (3.0.4)
26
+ rspec-support (~> 3.0.0)
27
+ rspec-expectations (3.0.4)
28
+ diff-lcs (>= 1.2.0, < 2.0)
29
+ rspec-support (~> 3.0.0)
30
+ rspec-mocks (3.0.4)
31
+ rspec-support (~> 3.0.0)
32
+ rspec-support (3.0.4)
33
+
34
+ PLATFORMS
35
+ ruby
36
+
37
+ DEPENDENCIES
38
+ cucumber (~> 1.3.10)
39
+ rspec (~> 3.0.0)
40
+ test-queue!
data/Gemfile-rspec3-1 ADDED
@@ -0,0 +1,3 @@
1
+ source 'https://rubygems.org'
2
+ gemspec
3
+ gem 'rspec', '~> 3.1.0'
@@ -0,0 +1,40 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ test-queue (0.2.12)
5
+
6
+ GEM
7
+ remote: https://rubygems.org/
8
+ specs:
9
+ builder (3.2.2)
10
+ cucumber (1.3.19)
11
+ builder (>= 2.1.2)
12
+ diff-lcs (>= 1.1.3)
13
+ gherkin (~> 2.12)
14
+ multi_json (>= 1.7.5, < 2.0)
15
+ multi_test (>= 0.1.2)
16
+ diff-lcs (1.2.5)
17
+ gherkin (2.12.2)
18
+ multi_json (~> 1.3)
19
+ multi_json (1.11.0)
20
+ multi_test (0.1.2)
21
+ rspec (3.1.0)
22
+ rspec-core (~> 3.1.0)
23
+ rspec-expectations (~> 3.1.0)
24
+ rspec-mocks (~> 3.1.0)
25
+ rspec-core (3.1.7)
26
+ rspec-support (~> 3.1.0)
27
+ rspec-expectations (3.1.2)
28
+ diff-lcs (>= 1.2.0, < 2.0)
29
+ rspec-support (~> 3.1.0)
30
+ rspec-mocks (3.1.3)
31
+ rspec-support (~> 3.1.0)
32
+ rspec-support (3.1.2)
33
+
34
+ PLATFORMS
35
+ ruby
36
+
37
+ DEPENDENCIES
38
+ cucumber (~> 1.3.10)
39
+ rspec (~> 3.1.0)
40
+ test-queue!
data/Gemfile-rspec3-2 ADDED
@@ -0,0 +1,3 @@
1
+ source 'https://rubygems.org'
2
+ gemspec
3
+ gem 'rspec', '~> 3.2.0'
@@ -0,0 +1,41 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ test-queue (0.2.12)
5
+
6
+ GEM
7
+ remote: https://rubygems.org/
8
+ specs:
9
+ builder (3.2.2)
10
+ cucumber (1.3.19)
11
+ builder (>= 2.1.2)
12
+ diff-lcs (>= 1.1.3)
13
+ gherkin (~> 2.12)
14
+ multi_json (>= 1.7.5, < 2.0)
15
+ multi_test (>= 0.1.2)
16
+ diff-lcs (1.2.5)
17
+ gherkin (2.12.2)
18
+ multi_json (~> 1.3)
19
+ multi_json (1.11.0)
20
+ multi_test (0.1.2)
21
+ rspec (3.2.0)
22
+ rspec-core (~> 3.2.0)
23
+ rspec-expectations (~> 3.2.0)
24
+ rspec-mocks (~> 3.2.0)
25
+ rspec-core (3.2.3)
26
+ rspec-support (~> 3.2.0)
27
+ rspec-expectations (3.2.1)
28
+ diff-lcs (>= 1.2.0, < 2.0)
29
+ rspec-support (~> 3.2.0)
30
+ rspec-mocks (3.2.1)
31
+ diff-lcs (>= 1.2.0, < 2.0)
32
+ rspec-support (~> 3.2.0)
33
+ rspec-support (3.2.2)
34
+
35
+ PLATFORMS
36
+ ruby
37
+
38
+ DEPENDENCIES
39
+ cucumber (~> 1.3.10)
40
+ rspec (~> 3.2.0)
41
+ test-queue!
data/Gemfile-testunit ADDED
@@ -0,0 +1,3 @@
1
+ source 'https://rubygems.org'
2
+ gemspec
3
+ gem 'test-unit', '3.0.8'
@@ -0,0 +1,44 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ test-queue (0.2.13)
5
+
6
+ GEM
7
+ remote: https://rubygems.org/
8
+ specs:
9
+ builder (3.2.2)
10
+ cucumber (1.3.18)
11
+ builder (>= 2.1.2)
12
+ diff-lcs (>= 1.1.3)
13
+ gherkin (~> 2.12)
14
+ multi_json (>= 1.7.5, < 2.0)
15
+ multi_test (>= 0.1.1)
16
+ diff-lcs (1.2.5)
17
+ gherkin (2.12.2)
18
+ multi_json (~> 1.3)
19
+ multi_json (1.10.1)
20
+ multi_test (0.1.1)
21
+ power_assert (0.2.2)
22
+ rspec (3.1.0)
23
+ rspec-core (~> 3.1.0)
24
+ rspec-expectations (~> 3.1.0)
25
+ rspec-mocks (~> 3.1.0)
26
+ rspec-core (3.1.7)
27
+ rspec-support (~> 3.1.0)
28
+ rspec-expectations (3.1.2)
29
+ diff-lcs (>= 1.2.0, < 2.0)
30
+ rspec-support (~> 3.1.0)
31
+ rspec-mocks (3.1.3)
32
+ rspec-support (~> 3.1.0)
33
+ rspec-support (3.1.2)
34
+ test-unit (3.0.8)
35
+ power_assert
36
+
37
+ PLATFORMS
38
+ ruby
39
+
40
+ DEPENDENCIES
41
+ cucumber (~> 1.3.10)
42
+ rspec (>= 2.13, < 4.0)
43
+ test-queue!
44
+ test-unit (= 3.0.8)
data/Gemfile.lock ADDED
@@ -0,0 +1,54 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ test-queue-split (0.3.0)
5
+
6
+ GEM
7
+ remote: https://rubygems.org/
8
+ specs:
9
+ appium_thor (1.0.1)
10
+ posix-spawn (~> 0.3, >= 0.3.8)
11
+ redcarpet (~> 3.1, >= 3.1.2)
12
+ yard (~> 0.8, >= 0.8.7.4)
13
+ builder (3.2.2)
14
+ cucumber (1.3.20)
15
+ builder (>= 2.1.2)
16
+ diff-lcs (>= 1.1.3)
17
+ gherkin (~> 2.12)
18
+ multi_json (>= 1.7.5, < 2.0)
19
+ multi_test (>= 0.1.2)
20
+ diff-lcs (1.2.5)
21
+ gherkin (2.12.2)
22
+ multi_json (~> 1.3)
23
+ minitest (5.3.3)
24
+ multi_json (1.11.2)
25
+ multi_test (0.1.2)
26
+ posix-spawn (0.3.11)
27
+ redcarpet (3.3.2)
28
+ rspec (3.3.0)
29
+ rspec-core (~> 3.3.0)
30
+ rspec-expectations (~> 3.3.0)
31
+ rspec-mocks (~> 3.3.0)
32
+ rspec-core (3.3.2)
33
+ rspec-support (~> 3.3.0)
34
+ rspec-expectations (3.3.1)
35
+ diff-lcs (>= 1.2.0, < 2.0)
36
+ rspec-support (~> 3.3.0)
37
+ rspec-mocks (3.3.2)
38
+ diff-lcs (>= 1.2.0, < 2.0)
39
+ rspec-support (~> 3.3.0)
40
+ rspec-support (3.3.0)
41
+ yard (0.8.7.6)
42
+
43
+ PLATFORMS
44
+ ruby
45
+
46
+ DEPENDENCIES
47
+ appium_thor (~> 1.0.1)
48
+ cucumber (~> 1.3.10)
49
+ minitest (= 5.3.3)
50
+ rspec (>= 2.13, < 4.0)
51
+ test-queue-split!
52
+
53
+ BUNDLED WITH
54
+ 1.10.6
data/README.md ADDED
@@ -0,0 +1,114 @@
1
+ ## test-queue
2
+
3
+ Yet another parallel test runner, built using a centralized queue to ensure
4
+ optimal distribution of tests between workers.
5
+
6
+ Specifically optimized for CI environments: build statistics from each run
7
+ are stored locally and used to sort the queue at the beginning of the
8
+ next run.
9
+
10
+ ### design
11
+
12
+ test-queue uses a simple master + pre-fork worker model. The master
13
+ exposes a unix domain socket server which workers use to grab tests off
14
+ the queue.
15
+
16
+ ```
17
+ ─┬─ 21232 minitest-queue master
18
+ ├─── 21571 minitest-queue worker [3] - AuthenticationTest
19
+ ├─── 21568 minitest-queue worker [2] - ApiTest
20
+ ├─── 21565 minitest-queue worker [1] - UsersControllerTest
21
+ └─── 21562 minitest-queue worker [0] - UserTest
22
+ ```
23
+
24
+ test-queue also has a distributed mode, where additional masters can share
25
+ the workload and relay results back to a central master.
26
+
27
+ ### environment variables
28
+
29
+ - `TEST_QUEUE_WORKERS`: number of workers to use per master (default: all available cores)
30
+ - `TEST_QUEUE_VERBOSE`: show results as they are available (default: `0`)
31
+ - `TEST_QUEUE_SOCKET`: unix socket `path` (or tcp `address:port` pair) used for communication (default: `/tmp/test_queue_XXXXX.sock`)
32
+ - `TEST_QUEUE_RELAY`: relay results back to a central master, specified as tcp `address:port`
33
+ - `TEST_QUEUE_STATS`: `path` to cache build stats in-build CI runs (default: `.test_queue_stats`)
34
+ - `TEST_QUEUE_FORCE`: comma separated list of suites to run
35
+ - `TEST_QUEUE_RELAY_TIMEOUT`: when using remote workers, the amount of time a worker will try to reconnect to start work
36
+ - `TEST_QUEUE_RELAY_TOKEN`: when using remote workers, this must be the same on both workers and the server for remote workers to run tests.
37
+ - `TEST_QUEUE_SLAVE_MESSAGE`: when using remote workers, set this on a slave worker and it will appear on the slave's connection message on the master.
38
+
39
+ ### usage
40
+
41
+ test-queue bundles `testunit-queue`, `minitest-queue` and `rspec-queue` binaries which can be used directly:
42
+
43
+ ```
44
+ $ minitest-queue $(find test/ -name \*_test.rb)
45
+ $ rspec-queue --format progress spec
46
+ ```
47
+
48
+ But the underlying `TestQueue::Runner::TestUnit`, `TestQueue::Runner::MiniTest` and `TestQueue::Runner::RSpec` are
49
+ built to be subclassed by your application. I recommend checking a new
50
+ executable into your project using one of these superclasses.
51
+
52
+ ```
53
+ $ vim script/test-queue
54
+ $ chmod +x script/test-queue
55
+ $ git add script/test-queue
56
+ ```
57
+
58
+ Since test-queue uses `fork(2)` to spawn off workers, you must ensure each worker
59
+ runs in an isolated environment. Use the `after_fork` hook with a custom
60
+ runner to reset any global state.
61
+
62
+ ``` ruby
63
+ #!/usr/bin/env ruby
64
+
65
+ class MyAppTestRunner < TestQueue::Runner::MiniTest
66
+ def after_fork(num)
67
+ # use separate mysql database (we assume it exists and has the right schema already)
68
+ ActiveRecord::Base.configurations['test']['database'] << num.to_s
69
+ ActiveRecord::Base.establish_connection(:test)
70
+
71
+ # use separate redis database
72
+ $redis.client.db = num
73
+ $redis.client.reconnect
74
+ end
75
+
76
+ def prepare(concurrency)
77
+ # create mysql databases exists with correct schema
78
+ concurrency.times do |i|
79
+ # ...
80
+ end
81
+
82
+ # If this is a remote slave, tell the master something about us
83
+ @slave_message = "Output for slave 123: http://myhost.com/build/123"
84
+ end
85
+
86
+ def around_filter(suite)
87
+ $stats.timing("test.#{suite}.runtime") do
88
+ yield
89
+ end
90
+ end
91
+ end
92
+
93
+ MyAppTestRunner.new.execute
94
+ ```
95
+
96
+ ### distributed mode
97
+
98
+ To use distributed mode, the central master must listen on a tcp port. Additional masters can be booted
99
+ in relay mode to connect to the central master. Workers must provide a TEST_QUEUE_RELAY_TOKEN to match
100
+ the master's.
101
+
102
+ ```
103
+ $ TEST_QUEUE_RELAY_TOKEN=123 TEST_QUEUE_SOCKET=0.0.0.0:12345 bundle exec minitest-queue ./test/sample_test.rb
104
+ $ TEST_QUEUE_RELAY_TOKEN=123 TEST_QUEUE_RELAY=0.0.0.0:12345 bundle exec minitest-queue ./test/sample_test.rb
105
+ $ TEST_QUEUE_RELAY_TOKEN=123 ./test-multi.sh
106
+ ```
107
+
108
+ See the [Parameterized Trigger Plugin](https://wiki.jenkins-ci.org/display/JENKINS/Parameterized+Trigger+Plugin)
109
+ for a simple way to do this with jenkins.
110
+
111
+ ### see also
112
+
113
+ * https://github.com/Shopify/rails_parallel
114
+ * https://github.com/grosser/parallel_tests
data/Thorfile ADDED
@@ -0,0 +1,9 @@
1
+ require 'rubygems'
2
+ require 'appium_thor'
3
+
4
+ Appium::Thor::Config.set do
5
+ gem_name 'test-queue-split'
6
+ github_owner 'sbonebrake'
7
+ github_name 'test-queue'
8
+ version_file 'lib/test_queue/version.rb'
9
+ end
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env ruby
2
+ require 'test_queue'
3
+ require 'test_queue/runner/cucumber'
4
+ TestQueue::Runner::Cucumber.new.execute
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+ require 'test_queue'
3
+ require 'test_queue/runner/minitest'
4
+ ARGV.each{ |f| require(f) }
5
+ TestQueue::Runner::MiniTest.new.execute
data/bin/rspec-queue ADDED
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env ruby
2
+ require 'test_queue'
3
+ require 'test_queue/runner/rspec'
4
+ TestQueue::Runner::RSpec.new.execute
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+ require 'test_queue'
3
+ require 'test_queue/runner/testunit'
4
+ ARGV.each{ |f| require(f) }
5
+ TestQueue::Runner::TestUnit.new.execute
@@ -0,0 +1,5 @@
1
+ Feature: bad
2
+ Scenario: failure
3
+ Given a
4
+ When bad
5
+ Then c
@@ -0,0 +1,25 @@
1
+ Feature: Foobar
2
+ Scenario: Bar
3
+ Given a
4
+ When b
5
+ Then c
6
+ Scenario: Baz
7
+ Given a
8
+ When b
9
+ Then c
10
+ Scenario: Bam
11
+ Given a
12
+ When b
13
+ Then c
14
+ Scenario: Car
15
+ Given a
16
+ When b
17
+ Then c
18
+ Scenario: Caz
19
+ Given a
20
+ When b
21
+ Then c
22
+ Scenario: Cam
23
+ Given a
24
+ When b
25
+ Then c
@@ -0,0 +1,29 @@
1
+ Feature: Foobar2
2
+ Scenario: Bar
3
+ Given a
4
+ When b
5
+ Then c
6
+ Scenario: Baz
7
+ Given a
8
+ When b
9
+ Then c
10
+ Scenario: Bam
11
+ Given a
12
+ When b
13
+ Then c
14
+ Scenario: Car
15
+ Given a
16
+ When b
17
+ Then c
18
+ Scenario: Caz
19
+ Given a
20
+ When b
21
+ Then c
22
+ Scenario: Cam
23
+ Given a
24
+ When b
25
+ Then c
26
+ Scenario: failure
27
+ Given a
28
+ When bad
29
+ Then c
@@ -0,0 +1,15 @@
1
+ Given(/^a$/) do
2
+ sleep 0.10
3
+ end
4
+
5
+ When(/^b$/) do
6
+ sleep 0.25
7
+ end
8
+
9
+ When(/^bad$/) do
10
+ 1.should == 0
11
+ end
12
+
13
+ Then(/^c$/) do
14
+ 1.should == 1
15
+ end
data/lib/test-queue.rb ADDED
@@ -0,0 +1 @@
1
+ require 'test_queue'
@@ -0,0 +1,72 @@
1
+ module TestQueue
2
+ class Iterator
3
+ attr_reader :stats, :sock
4
+
5
+ def initialize(sock, suites, filter=nil)
6
+ @done = false
7
+ @stats = {}
8
+ @procline = $0
9
+ @sock = sock
10
+ @suites = suites
11
+ @filter = filter
12
+ if @sock =~ /^(.+):(\d+)$/
13
+ @tcp_address = $1
14
+ @tcp_port = $2.to_i
15
+ end
16
+ end
17
+
18
+ def each
19
+ fail "already used this iterator. previous caller: #@done" if @done
20
+
21
+ while true
22
+ client = connect_to_master('POP')
23
+ break if client.nil?
24
+ r, w, e = IO.select([client], nil, [client], nil)
25
+ break if !e.empty?
26
+
27
+ if data = client.read(65536)
28
+ client.close
29
+ item = Marshal.load(data)
30
+ break if item.nil? || item.empty?
31
+ suite = @suites[item]
32
+
33
+ $0 = "#{@procline} - #{suite.respond_to?(:description) ? suite.description : suite}"
34
+ start = Time.now
35
+ if @filter
36
+ @filter.call(suite){ yield suite }
37
+ else
38
+ yield suite
39
+ end
40
+ @stats[suite.to_s] = Time.now - start
41
+ else
42
+ break
43
+ end
44
+ end
45
+ rescue Errno::ENOENT, Errno::ECONNRESET, Errno::ECONNREFUSED
46
+ ensure
47
+ @done = caller.first
48
+ File.open("/tmp/test_queue_worker_#{$$}_stats", "wb") do |f|
49
+ f.write Marshal.dump(@stats)
50
+ end
51
+ end
52
+
53
+ def connect_to_master(cmd)
54
+ sock =
55
+ if @tcp_address
56
+ TCPSocket.new(@tcp_address, @tcp_port)
57
+ else
58
+ UNIXSocket.new(@sock)
59
+ end
60
+ sock.puts(cmd)
61
+ sock
62
+ rescue Errno::EPIPE
63
+ nil
64
+ end
65
+
66
+ include Enumerable
67
+
68
+ def empty?
69
+ false
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,46 @@
1
+ require 'cucumber'
2
+ require 'cucumber/rspec/disable_option_parser'
3
+ require 'cucumber/cli/main'
4
+
5
+ module Cucumber
6
+ module Ast
7
+ class Features
8
+ attr_accessor :features
9
+ end
10
+
11
+ class Feature
12
+ def to_s
13
+ title
14
+ end
15
+ end
16
+ end
17
+ end
18
+
19
+ module TestQueue
20
+ class Runner
21
+ class Cucumber < Runner
22
+ def initialize
23
+ @cli = ::Cucumber::Cli::Main.new(ARGV.dup)
24
+ @runtime = ::Cucumber::Runtime.new(@cli.configuration)
25
+ @features_loader = @runtime.send(:features)
26
+ features = @features_loader.features.sort_by{ |s| -(stats[s.to_s] || 0) }
27
+ super(features)
28
+ end
29
+
30
+ def run_worker(iterator)
31
+ @features_loader.features = iterator
32
+ @cli.execute!(@runtime)
33
+ end
34
+
35
+ def summarize_worker(worker)
36
+ worker.stats.each do |s, val|
37
+ stats[s.to_s] = val
38
+ end
39
+
40
+ output = worker.output.gsub(/\e\[\d+./,'')
41
+ worker.summary = output.split("\n").grep(/^\d+ (scenarios?|steps?)/).first
42
+ worker.failure_output = output.scan(/^Failing Scenarios:\n(.*)\n\d+ scenarios?/m).join("\n")
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,25 @@
1
+ begin
2
+ require 'minitest'
3
+ require 'test_queue/runner/minitest5'
4
+ rescue LoadError => e
5
+ require 'minitest/unit'
6
+ require 'test_queue/runner/minitest4'
7
+ end
8
+
9
+ module TestQueue
10
+ class Runner
11
+ class MiniTest < Runner
12
+ def summarize_worker(worker)
13
+ worker.stats.each do |s, val|
14
+ stats[s.to_s] = val
15
+ end
16
+
17
+ worker.summary = worker.lines.grep(/, \d+ errors?, /).first
18
+ failures = worker.lines.select{ |line|
19
+ line if (line =~ /^Finished/) ... (line =~ /, \d+ errors?, /)
20
+ }[1..-2]
21
+ worker.failure_output = failures.join("\n") if failures
22
+ end
23
+ end
24
+ end
25
+ end