test-queue-split 0.3.0

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