test-queue-patched 0.4.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +1 -0
- data/.travis.yml +18 -0
- data/Gemfile +5 -0
- data/Gemfile-cucumber1-3 +4 -0
- data/Gemfile-cucumber1-3.lock +33 -0
- data/Gemfile-cucumber2-4 +4 -0
- data/Gemfile-cucumber2-4.lock +37 -0
- data/Gemfile-minitest4 +3 -0
- data/Gemfile-minitest4.lock +19 -0
- data/Gemfile-minitest5 +3 -0
- data/Gemfile-minitest5.lock +19 -0
- data/Gemfile-rspec2-1 +3 -0
- data/Gemfile-rspec2-1.lock +27 -0
- data/Gemfile-rspec3-0 +3 -0
- data/Gemfile-rspec3-0.lock +31 -0
- data/Gemfile-rspec3-1 +3 -0
- data/Gemfile-rspec3-1.lock +31 -0
- data/Gemfile-rspec3-2 +3 -0
- data/Gemfile-rspec3-2.lock +32 -0
- data/Gemfile-testunit +3 -0
- data/Gemfile-testunit.lock +21 -0
- data/Gemfile.lock +41 -0
- data/README.md +126 -0
- data/bin/cucumber-queue +4 -0
- data/bin/minitest-queue +4 -0
- data/bin/rspec-queue +4 -0
- data/bin/testunit-queue +4 -0
- data/lib/test-queue.rb +1 -0
- data/lib/test_queue/iterator.rb +107 -0
- data/lib/test_queue/runner/cucumber.rb +115 -0
- data/lib/test_queue/runner/minitest.rb +21 -0
- data/lib/test_queue/runner/minitest4.rb +88 -0
- data/lib/test_queue/runner/minitest5.rb +87 -0
- data/lib/test_queue/runner/puppet_lint.rb +31 -0
- data/lib/test_queue/runner/rspec.rb +79 -0
- data/lib/test_queue/runner/rspec2.rb +44 -0
- data/lib/test_queue/runner/rspec3.rb +54 -0
- data/lib/test_queue/runner/sample.rb +74 -0
- data/lib/test_queue/runner/testunit.rb +74 -0
- data/lib/test_queue/runner.rb +632 -0
- data/lib/test_queue/stats.rb +95 -0
- data/lib/test_queue/test_framework.rb +29 -0
- data/lib/test_queue.rb +8 -0
- data/script/bootstrap +12 -0
- data/script/cibuild +19 -0
- data/script/spec +7 -0
- data/spec/stats_spec.rb +76 -0
- data/test/cucumber.bats +57 -0
- data/test/minitest4.bats +34 -0
- data/test/minitest5.bats +194 -0
- data/test/rspec.bats +46 -0
- data/test/samples/features/bad.feature +5 -0
- data/test/samples/features/sample.feature +25 -0
- data/test/samples/features/sample2.feature +29 -0
- data/test/samples/features/step_definitions/common.rb +19 -0
- data/test/samples/sample_minispec.rb +37 -0
- data/test/samples/sample_minitest4.rb +25 -0
- data/test/samples/sample_minitest5.rb +33 -0
- data/test/samples/sample_rspec_helper.rb +1 -0
- data/test/samples/sample_shared_examples_for_spec.rb +5 -0
- data/test/samples/sample_spec.rb +25 -0
- data/test/samples/sample_split_spec.rb +17 -0
- data/test/samples/sample_testunit.rb +25 -0
- data/test/samples/sample_use_shared_example1_spec.rb +8 -0
- data/test/samples/sample_use_shared_example2_spec.rb +8 -0
- data/test/sleepy_runner.rb +14 -0
- data/test/testlib.bash +89 -0
- data/test/testunit.bats +20 -0
- data/test-queue-patched.gemspec +21 -0
- 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
data/Gemfile-cucumber1-3
ADDED
@@ -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
|
data/Gemfile-cucumber2-4
ADDED
@@ -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
data/Gemfile-minitest5
ADDED
data/Gemfile-rspec2-1
ADDED
@@ -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,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,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,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,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
|
data/bin/cucumber-queue
ADDED
data/bin/minitest-queue
ADDED
data/bin/rspec-queue
ADDED
data/bin/testunit-queue
ADDED
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
|