test-queue-patched 0.4.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (71) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +1 -0
  3. data/.travis.yml +18 -0
  4. data/Gemfile +5 -0
  5. data/Gemfile-cucumber1-3 +4 -0
  6. data/Gemfile-cucumber1-3.lock +33 -0
  7. data/Gemfile-cucumber2-4 +4 -0
  8. data/Gemfile-cucumber2-4.lock +37 -0
  9. data/Gemfile-minitest4 +3 -0
  10. data/Gemfile-minitest4.lock +19 -0
  11. data/Gemfile-minitest5 +3 -0
  12. data/Gemfile-minitest5.lock +19 -0
  13. data/Gemfile-rspec2-1 +3 -0
  14. data/Gemfile-rspec2-1.lock +27 -0
  15. data/Gemfile-rspec3-0 +3 -0
  16. data/Gemfile-rspec3-0.lock +31 -0
  17. data/Gemfile-rspec3-1 +3 -0
  18. data/Gemfile-rspec3-1.lock +31 -0
  19. data/Gemfile-rspec3-2 +3 -0
  20. data/Gemfile-rspec3-2.lock +32 -0
  21. data/Gemfile-testunit +3 -0
  22. data/Gemfile-testunit.lock +21 -0
  23. data/Gemfile.lock +41 -0
  24. data/README.md +126 -0
  25. data/bin/cucumber-queue +4 -0
  26. data/bin/minitest-queue +4 -0
  27. data/bin/rspec-queue +4 -0
  28. data/bin/testunit-queue +4 -0
  29. data/lib/test-queue.rb +1 -0
  30. data/lib/test_queue/iterator.rb +107 -0
  31. data/lib/test_queue/runner/cucumber.rb +115 -0
  32. data/lib/test_queue/runner/minitest.rb +21 -0
  33. data/lib/test_queue/runner/minitest4.rb +88 -0
  34. data/lib/test_queue/runner/minitest5.rb +87 -0
  35. data/lib/test_queue/runner/puppet_lint.rb +31 -0
  36. data/lib/test_queue/runner/rspec.rb +79 -0
  37. data/lib/test_queue/runner/rspec2.rb +44 -0
  38. data/lib/test_queue/runner/rspec3.rb +54 -0
  39. data/lib/test_queue/runner/sample.rb +74 -0
  40. data/lib/test_queue/runner/testunit.rb +74 -0
  41. data/lib/test_queue/runner.rb +632 -0
  42. data/lib/test_queue/stats.rb +95 -0
  43. data/lib/test_queue/test_framework.rb +29 -0
  44. data/lib/test_queue.rb +8 -0
  45. data/script/bootstrap +12 -0
  46. data/script/cibuild +19 -0
  47. data/script/spec +7 -0
  48. data/spec/stats_spec.rb +76 -0
  49. data/test/cucumber.bats +57 -0
  50. data/test/minitest4.bats +34 -0
  51. data/test/minitest5.bats +194 -0
  52. data/test/rspec.bats +46 -0
  53. data/test/samples/features/bad.feature +5 -0
  54. data/test/samples/features/sample.feature +25 -0
  55. data/test/samples/features/sample2.feature +29 -0
  56. data/test/samples/features/step_definitions/common.rb +19 -0
  57. data/test/samples/sample_minispec.rb +37 -0
  58. data/test/samples/sample_minitest4.rb +25 -0
  59. data/test/samples/sample_minitest5.rb +33 -0
  60. data/test/samples/sample_rspec_helper.rb +1 -0
  61. data/test/samples/sample_shared_examples_for_spec.rb +5 -0
  62. data/test/samples/sample_spec.rb +25 -0
  63. data/test/samples/sample_split_spec.rb +17 -0
  64. data/test/samples/sample_testunit.rb +25 -0
  65. data/test/samples/sample_use_shared_example1_spec.rb +8 -0
  66. data/test/samples/sample_use_shared_example2_spec.rb +8 -0
  67. data/test/sleepy_runner.rb +14 -0
  68. data/test/testlib.bash +89 -0
  69. data/test/testunit.bats +20 -0
  70. data/test-queue-patched.gemspec +21 -0
  71. metadata +117 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: c22a16c63770cebc1d74b4daf3f50b1ba2195736
4
+ data.tar.gz: 501d9fe8071639c8d8e403d2463f9c0330e089f1
5
+ SHA512:
6
+ metadata.gz: 44049ae27cb810b32bc079b57c3ca7b550526cb0d6ad7c02ef4cdafae64165b7be063177f67b520c6a9257b52eae0312497b2faad0bfd5736943d367a0956a0e
7
+ data.tar.gz: b4bd46ffa050eeef91e4a4464a1f285f85b8bab251744a0e6cd3539cb537765b36db5021b1551e8ad49c99a2f93d54c06d0a412e60f57ea9e227f7df4c877f35
data/.gitignore ADDED
@@ -0,0 +1 @@
1
+ .test_queue_stats
data/.travis.yml ADDED
@@ -0,0 +1,18 @@
1
+ language: ruby
2
+ install: script/bootstrap
3
+ rvm:
4
+ - 2.2
5
+ env:
6
+ - SUITE=ruby
7
+ - SUITE=cucumber1-3
8
+ - SUITE=cucumber2-4
9
+ - SUITE=minitest4
10
+ - SUITE=minitest5
11
+ - SUITE=rspec2-1
12
+ - SUITE=rspec3-0
13
+ - SUITE=rspec3-1
14
+ - SUITE=rspec3-2
15
+ - SUITE=testunit
16
+ script: script/cibuild
17
+ notifications:
18
+ email: false
data/Gemfile ADDED
@@ -0,0 +1,5 @@
1
+ source 'https://rubygems.org'
2
+ gemspec
3
+ gem 'minitest', '5.3.3'
4
+ gem 'rspec', '>= 2.13', '< 4.0'
5
+ gem 'cucumber', '~> 1.3.10'
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+ gemspec
3
+ gem 'cucumber', '~> 1.3.10'
4
+ gem 'rspec-expectations', '~> 2.14.4'
@@ -0,0 +1,33 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ test-queue (0.4.2)
5
+
6
+ GEM
7
+ remote: https://rubygems.org/
8
+ specs:
9
+ builder (3.2.2)
10
+ cucumber (1.3.20)
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.12.1)
20
+ multi_test (0.1.2)
21
+ rspec-expectations (2.14.5)
22
+ diff-lcs (>= 1.1.3, < 2.0)
23
+
24
+ PLATFORMS
25
+ ruby
26
+
27
+ DEPENDENCIES
28
+ cucumber (~> 1.3.10)
29
+ rspec-expectations (~> 2.14.4)
30
+ test-queue!
31
+
32
+ BUNDLED WITH
33
+ 1.13.1
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+ gemspec
3
+ gem 'cucumber', '2.4.0'
4
+ gem 'rspec-expectations', '2.14.4'
@@ -0,0 +1,37 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ test-queue (0.4.2)
5
+
6
+ GEM
7
+ remote: https://rubygems.org/
8
+ specs:
9
+ builder (3.2.2)
10
+ cucumber (2.4.0)
11
+ builder (>= 2.1.2)
12
+ cucumber-core (~> 1.5.0)
13
+ cucumber-wire (~> 0.0.1)
14
+ diff-lcs (>= 1.1.3)
15
+ gherkin (~> 4.0)
16
+ multi_json (>= 1.7.5, < 2.0)
17
+ multi_test (>= 0.1.2)
18
+ cucumber-core (1.5.0)
19
+ gherkin (~> 4.0)
20
+ cucumber-wire (0.0.1)
21
+ diff-lcs (1.2.5)
22
+ gherkin (4.0.0)
23
+ multi_json (1.12.1)
24
+ multi_test (0.1.2)
25
+ rspec-expectations (2.14.4)
26
+ diff-lcs (>= 1.1.3, < 2.0)
27
+
28
+ PLATFORMS
29
+ ruby
30
+
31
+ DEPENDENCIES
32
+ cucumber (= 2.4.0)
33
+ rspec-expectations (= 2.14.4)
34
+ test-queue!
35
+
36
+ BUNDLED WITH
37
+ 1.13.1
data/Gemfile-minitest4 ADDED
@@ -0,0 +1,3 @@
1
+ source 'https://rubygems.org'
2
+ gemspec
3
+ gem 'minitest', '4.7.3'
@@ -0,0 +1,19 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ test-queue (0.4.2)
5
+
6
+ GEM
7
+ remote: https://rubygems.org/
8
+ specs:
9
+ minitest (4.7.3)
10
+
11
+ PLATFORMS
12
+ ruby
13
+
14
+ DEPENDENCIES
15
+ minitest (= 4.7.3)
16
+ test-queue!
17
+
18
+ BUNDLED WITH
19
+ 1.13.1
data/Gemfile-minitest5 ADDED
@@ -0,0 +1,3 @@
1
+ source 'https://rubygems.org'
2
+ gemspec
3
+ gem 'minitest', '5.3.3'
@@ -0,0 +1,19 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ test-queue (0.4.2)
5
+
6
+ GEM
7
+ remote: https://rubygems.org/
8
+ specs:
9
+ minitest (5.3.3)
10
+
11
+ PLATFORMS
12
+ ruby
13
+
14
+ DEPENDENCIES
15
+ minitest (= 5.3.3)
16
+ test-queue!
17
+
18
+ BUNDLED WITH
19
+ 1.13.1
data/Gemfile-rspec2-1 ADDED
@@ -0,0 +1,3 @@
1
+ source 'https://rubygems.org'
2
+ gemspec
3
+ gem 'rspec', '2.13.0'
@@ -0,0 +1,27 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ test-queue (0.4.2)
5
+
6
+ GEM
7
+ remote: https://rubygems.org/
8
+ specs:
9
+ diff-lcs (1.2.5)
10
+ rspec (2.13.0)
11
+ rspec-core (~> 2.13.0)
12
+ rspec-expectations (~> 2.13.0)
13
+ rspec-mocks (~> 2.13.0)
14
+ rspec-core (2.13.1)
15
+ rspec-expectations (2.13.0)
16
+ diff-lcs (>= 1.1.3, < 2.0)
17
+ rspec-mocks (2.13.1)
18
+
19
+ PLATFORMS
20
+ ruby
21
+
22
+ DEPENDENCIES
23
+ rspec (= 2.13.0)
24
+ test-queue!
25
+
26
+ BUNDLED WITH
27
+ 1.13.1
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,31 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ test-queue (0.4.2)
5
+
6
+ GEM
7
+ remote: https://rubygems.org/
8
+ specs:
9
+ diff-lcs (1.2.5)
10
+ rspec (3.0.0)
11
+ rspec-core (~> 3.0.0)
12
+ rspec-expectations (~> 3.0.0)
13
+ rspec-mocks (~> 3.0.0)
14
+ rspec-core (3.0.4)
15
+ rspec-support (~> 3.0.0)
16
+ rspec-expectations (3.0.4)
17
+ diff-lcs (>= 1.2.0, < 2.0)
18
+ rspec-support (~> 3.0.0)
19
+ rspec-mocks (3.0.4)
20
+ rspec-support (~> 3.0.0)
21
+ rspec-support (3.0.4)
22
+
23
+ PLATFORMS
24
+ ruby
25
+
26
+ DEPENDENCIES
27
+ rspec (~> 3.0.0)
28
+ test-queue!
29
+
30
+ BUNDLED WITH
31
+ 1.13.1
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,31 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ test-queue (0.4.2)
5
+
6
+ GEM
7
+ remote: https://rubygems.org/
8
+ specs:
9
+ diff-lcs (1.2.5)
10
+ rspec (3.1.0)
11
+ rspec-core (~> 3.1.0)
12
+ rspec-expectations (~> 3.1.0)
13
+ rspec-mocks (~> 3.1.0)
14
+ rspec-core (3.1.7)
15
+ rspec-support (~> 3.1.0)
16
+ rspec-expectations (3.1.2)
17
+ diff-lcs (>= 1.2.0, < 2.0)
18
+ rspec-support (~> 3.1.0)
19
+ rspec-mocks (3.1.3)
20
+ rspec-support (~> 3.1.0)
21
+ rspec-support (3.1.2)
22
+
23
+ PLATFORMS
24
+ ruby
25
+
26
+ DEPENDENCIES
27
+ rspec (~> 3.1.0)
28
+ test-queue!
29
+
30
+ BUNDLED WITH
31
+ 1.13.1
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,32 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ test-queue (0.4.2)
5
+
6
+ GEM
7
+ remote: https://rubygems.org/
8
+ specs:
9
+ diff-lcs (1.2.5)
10
+ rspec (3.2.0)
11
+ rspec-core (~> 3.2.0)
12
+ rspec-expectations (~> 3.2.0)
13
+ rspec-mocks (~> 3.2.0)
14
+ rspec-core (3.2.3)
15
+ rspec-support (~> 3.2.0)
16
+ rspec-expectations (3.2.1)
17
+ diff-lcs (>= 1.2.0, < 2.0)
18
+ rspec-support (~> 3.2.0)
19
+ rspec-mocks (3.2.1)
20
+ diff-lcs (>= 1.2.0, < 2.0)
21
+ rspec-support (~> 3.2.0)
22
+ rspec-support (3.2.2)
23
+
24
+ PLATFORMS
25
+ ruby
26
+
27
+ DEPENDENCIES
28
+ rspec (~> 3.2.0)
29
+ test-queue!
30
+
31
+ BUNDLED WITH
32
+ 1.13.1
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,21 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ test-queue (0.4.2)
5
+
6
+ GEM
7
+ remote: https://rubygems.org/
8
+ specs:
9
+ power_assert (0.2.2)
10
+ test-unit (3.0.8)
11
+ power_assert
12
+
13
+ PLATFORMS
14
+ ruby
15
+
16
+ DEPENDENCIES
17
+ test-queue!
18
+ test-unit (= 3.0.8)
19
+
20
+ BUNDLED WITH
21
+ 1.13.1
data/Gemfile.lock ADDED
@@ -0,0 +1,41 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ test-queue (0.4.2)
5
+
6
+ GEM
7
+ remote: https://rubygems.org/
8
+ specs:
9
+ builder (3.2.2)
10
+ cucumber (1.3.10)
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.0.2)
16
+ diff-lcs (1.2.4)
17
+ gherkin (2.12.2)
18
+ multi_json (~> 1.3)
19
+ minitest (5.3.3)
20
+ multi_json (1.8.4)
21
+ multi_test (0.0.3)
22
+ rspec (2.13.0)
23
+ rspec-core (~> 2.13.0)
24
+ rspec-expectations (~> 2.13.0)
25
+ rspec-mocks (~> 2.13.0)
26
+ rspec-core (2.13.1)
27
+ rspec-expectations (2.13.0)
28
+ diff-lcs (>= 1.1.3, < 2.0)
29
+ rspec-mocks (2.13.1)
30
+
31
+ PLATFORMS
32
+ ruby
33
+
34
+ DEPENDENCIES
35
+ cucumber (~> 1.3.10)
36
+ minitest (= 5.3.3)
37
+ rspec (>= 2.13, < 4.0)
38
+ test-queue!
39
+
40
+ BUNDLED WITH
41
+ 1.13.1
data/README.md ADDED
@@ -0,0 +1,126 @@
1
+ ## test-queue-patched
2
+
3
+ [![Gem Version](https://badge.fury.io/rb/test-queue.svg)](https://rubygems.org/gems/test-queue)
4
+ [![Build Status](https://travis-ci.org/tmm1/test-queue.svg?branch=master)](https://travis-ci.org/tmm1/test-queue)
5
+
6
+ ### patches
7
+
8
+ `test-queue-patched` is the upstream test-queue master branch with the following patches applied:
9
+
10
+ - `git am -3 https://github.com/tmm1/test-queue/pull/73`
11
+
12
+ ---
13
+
14
+ Yet another parallel test runner, built using a centralized queue to ensure
15
+ optimal distribution of tests between workers.
16
+
17
+ Specifically optimized for CI environments: build statistics from each run
18
+ are stored locally and used to sort the queue at the beginning of the
19
+ next run.
20
+
21
+ ### design
22
+
23
+ test-queue uses a simple master + pre-fork worker model. The master
24
+ exposes a unix domain socket server which workers use to grab tests off
25
+ the queue.
26
+
27
+ ```
28
+ ─┬─ 21232 minitest-queue master
29
+ ├─── 21571 minitest-queue worker [3] - AuthenticationTest
30
+ ├─── 21568 minitest-queue worker [2] - ApiTest
31
+ ├─── 21565 minitest-queue worker [1] - UsersControllerTest
32
+ └─── 21562 minitest-queue worker [0] - UserTest
33
+ ```
34
+
35
+ test-queue also has a distributed mode, where additional masters can share
36
+ the workload and relay results back to a central master.
37
+
38
+ ### environment variables
39
+
40
+ - `TEST_QUEUE_WORKERS`: number of workers to use per master (default: all available cores)
41
+ - `TEST_QUEUE_VERBOSE`: show results as they are available (default: `0`)
42
+ - `TEST_QUEUE_SOCKET`: unix socket `path` (or tcp `address:port` pair) used for communication (default: `/tmp/test_queue_XXXXX.sock`)
43
+ - `TEST_QUEUE_RELAY`: relay results back to a central master, specified as tcp `address:port`
44
+ - `TEST_QUEUE_STATS`: `path` to cache build stats in-build CI runs (default: `.test_queue_stats`)
45
+ - `TEST_QUEUE_FORCE`: comma separated list of suites to run
46
+ - `TEST_QUEUE_RELAY_TIMEOUT`: when using distributed builds, the amount of time a remote master will try to reconnect to start work
47
+ - `TEST_QUEUE_RELAY_TOKEN`: when using distributed builds, this must be the same on remote masters and the central master for remote masters to be able to connect.
48
+ - `TEST_QUEUE_REMOTE_MASTER_MESSAGE`: when using distributed builds, set this on a remote master and it will appear in that master's connection message on the central master.
49
+ - `TEST_QUEUE_SPLIT_GROUPS`: split tests up by example rather than example group. Faster for tests with short setup time such as selenium. RSpec only. Add the :no_split tag to ExampleGroups you don't want split.
50
+
51
+ ### usage
52
+
53
+ test-queue bundles `testunit-queue`, `minitest-queue` and `rspec-queue` binaries which can be used directly:
54
+
55
+ ```
56
+ $ minitest-queue $(find test/ -name \*_test.rb)
57
+ $ rspec-queue --format progress spec
58
+ ```
59
+
60
+ But the underlying `TestQueue::Runner::TestUnit`, `TestQueue::Runner::MiniTest` and `TestQueue::Runner::RSpec` are
61
+ built to be subclassed by your application. I recommend checking a new
62
+ executable into your project using one of these superclasses.
63
+
64
+ ```
65
+ $ vim script/test-queue
66
+ $ chmod +x script/test-queue
67
+ $ git add script/test-queue
68
+ ```
69
+
70
+ Since test-queue uses `fork(2)` to spawn off workers, you must ensure each worker
71
+ runs in an isolated environment. Use the `after_fork` hook with a custom
72
+ runner to reset any global state.
73
+
74
+ ``` ruby
75
+ #!/usr/bin/env ruby
76
+
77
+ class MyAppTestRunner < TestQueue::Runner::MiniTest
78
+ def after_fork(num)
79
+ # use separate mysql database (we assume it exists and has the right schema already)
80
+ ActiveRecord::Base.configurations['test']['database'] << num.to_s
81
+ ActiveRecord::Base.establish_connection(:test)
82
+
83
+ # use separate redis database
84
+ $redis.client.db = num
85
+ $redis.client.reconnect
86
+ end
87
+
88
+ def prepare(concurrency)
89
+ # create mysql databases exists with correct schema
90
+ concurrency.times do |i|
91
+ # ...
92
+ end
93
+
94
+ # If this is a remote master, tell the central master something about us
95
+ @remote_master_message = "Output for remote master 123: http://myhost.com/build/123"
96
+ end
97
+
98
+ def around_filter(suite)
99
+ $stats.timing("test.#{suite}.runtime") do
100
+ yield
101
+ end
102
+ end
103
+ end
104
+
105
+ MyAppTestRunner.new.execute
106
+ ```
107
+
108
+ ### distributed mode
109
+
110
+ To use distributed mode, the central master must listen on a tcp port. Additional masters can be booted
111
+ in relay mode to connect to the central master. Remote masters must provide a TEST_QUEUE_RELAY_TOKEN
112
+ to match the central master's.
113
+
114
+ ```
115
+ $ TEST_QUEUE_RELAY_TOKEN=123 TEST_QUEUE_SOCKET=0.0.0.0:12345 bundle exec minitest-queue ./test/sample_test.rb
116
+ $ TEST_QUEUE_RELAY_TOKEN=123 TEST_QUEUE_RELAY=0.0.0.0:12345 bundle exec minitest-queue ./test/sample_test.rb
117
+ $ TEST_QUEUE_RELAY_TOKEN=123 ./test-multi.sh
118
+ ```
119
+
120
+ See the [Parameterized Trigger Plugin](https://wiki.jenkins-ci.org/display/JENKINS/Parameterized+Trigger+Plugin)
121
+ for a simple way to do this with jenkins.
122
+
123
+ ### see also
124
+
125
+ * https://github.com/Shopify/rails_parallel
126
+ * https://github.com/grosser/parallel_tests
@@ -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,4 @@
1
+ #!/usr/bin/env ruby
2
+ require 'test_queue'
3
+ require 'test_queue/runner/minitest'
4
+ 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,4 @@
1
+ #!/usr/bin/env ruby
2
+ require 'test_queue'
3
+ require 'test_queue/runner/testunit'
4
+ TestQueue::Runner::TestUnit.new.execute
data/lib/test-queue.rb ADDED
@@ -0,0 +1 @@
1
+ require 'test_queue'
@@ -0,0 +1,107 @@
1
+ module TestQueue
2
+ class Iterator
3
+ attr_reader :sock
4
+
5
+ def initialize(test_framework, sock, filter=nil, run_token:, early_failure_limit: nil)
6
+ @test_framework = test_framework
7
+ @done = false
8
+ @suite_stats = []
9
+ @sock = sock
10
+ @filter = filter
11
+ if @sock =~ /^(.+):(\d+)$/
12
+ @tcp_address = $1
13
+ @tcp_port = $2.to_i
14
+ end
15
+ @failures = 0
16
+ @early_failure_limit = early_failure_limit
17
+ @run_token = run_token
18
+ end
19
+
20
+ def each
21
+ fail "already used this iterator. previous caller: #@done" if @done
22
+
23
+ procline = $0
24
+
25
+ while true
26
+ # If we've hit too many failures in one worker, assume the entire
27
+ # test suite is broken, and notify master so the run
28
+ # can be immediately halted.
29
+ if @early_failure_limit && @failures >= @early_failure_limit
30
+ connect_to_master("KABOOM")
31
+ break
32
+ else
33
+ client = connect_to_master("POP #{Socket.gethostname} #{Process.pid}")
34
+ end
35
+ break if client.nil?
36
+ _r, _w, e = IO.select([client], nil, [client], nil)
37
+ break if !e.empty?
38
+
39
+ if data = client.read(65536)
40
+ client.close
41
+ item = Marshal.load(data)
42
+ break if item.nil? || item.empty?
43
+ if item == "WAIT"
44
+ $0 = "#{procline} - Waiting for work"
45
+ sleep 0.1
46
+ next
47
+ end
48
+ suite_name, path = item
49
+ suite = load_suite(suite_name, path)
50
+
51
+ # Maybe we were told to load a suite that doesn't exist anymore.
52
+ next unless suite
53
+
54
+ $0 = "#{procline} - #{suite.respond_to?(:description) ? suite.description : suite}"
55
+ start = Time.now
56
+ if @filter
57
+ @filter.call(suite){ yield suite }
58
+ else
59
+ yield suite
60
+ end
61
+ @suite_stats << TestQueue::Stats::Suite.new(suite_name, path, Time.now - start, Time.now)
62
+ @failures += suite.failure_count if suite.respond_to? :failure_count
63
+ else
64
+ break
65
+ end
66
+ end
67
+ rescue Errno::ENOENT, Errno::ECONNRESET, Errno::ECONNREFUSED
68
+ ensure
69
+ $0 = procline
70
+ @done = caller.first
71
+ File.open("/tmp/test_queue_worker_#{$$}_suites", "wb") do |f|
72
+ Marshal.dump(@suite_stats, f)
73
+ end
74
+ end
75
+
76
+ def connect_to_master(cmd)
77
+ sock =
78
+ if @tcp_address
79
+ TCPSocket.new(@tcp_address, @tcp_port)
80
+ else
81
+ UNIXSocket.new(@sock)
82
+ end
83
+ sock.puts("TOKEN=#{@run_token}")
84
+ sock.puts(cmd)
85
+ sock
86
+ rescue Errno::EPIPE
87
+ nil
88
+ end
89
+
90
+ include Enumerable
91
+
92
+ def empty?
93
+ false
94
+ end
95
+
96
+ def load_suite(suite_name, path)
97
+ @loaded_suites ||= {}
98
+ suite = @loaded_suites[suite_name]
99
+ return suite if suite
100
+
101
+ @test_framework.suites_from_file(path).each do |name, suite|
102
+ @loaded_suites[name] = suite
103
+ end
104
+ @loaded_suites[suite_name]
105
+ end
106
+ end
107
+ end