test-queue 0.4.2 → 0.6.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.github/workflows/test.yml +93 -0
- data/.gitignore +5 -0
- data/Appraisals +35 -0
- data/Gemfile +4 -2
- data/LICENSE +21 -0
- data/README.md +19 -19
- data/Rakefile +14 -0
- data/{bin → exe}/cucumber-queue +4 -0
- data/{bin → exe}/minitest-queue +4 -0
- data/{bin → exe}/rspec-queue +4 -0
- data/{bin → exe}/testunit-queue +4 -0
- data/gemfiles/cucumber1_3.gemfile +9 -0
- data/gemfiles/cucumber2_4.gemfile +9 -0
- data/gemfiles/minitest4.gemfile +7 -0
- data/gemfiles/minitest5.gemfile +7 -0
- data/gemfiles/rspec2.gemfile +8 -0
- data/gemfiles/rspec3.gemfile +7 -0
- data/gemfiles/testunit.gemfile +7 -0
- data/lib/test-queue.rb +1 -1
- data/lib/test_queue/runner/minitest.rb +2 -2
- data/lib/test_queue/runner/minitest4.rb +1 -1
- data/lib/test_queue/runner/minitest5.rb +8 -1
- data/lib/test_queue/runner/puppet_lint.rb +1 -1
- data/lib/test_queue/runner/rspec.rb +8 -7
- data/lib/test_queue/runner/rspec2.rb +6 -0
- data/lib/test_queue/runner/rspec3.rb +6 -0
- data/lib/test_queue/runner/sample.rb +2 -2
- data/lib/test_queue/runner/testunit.rb +1 -1
- data/lib/test_queue/runner.rb +33 -28
- data/lib/test_queue.rb +2 -2
- data/script/bootstrap +1 -0
- data/spec/stats_spec.rb +3 -0
- data/test/minitest4.bats +1 -1
- data/test/minitest5.bats +15 -5
- data/test/{rspec.bats → rspec2.bats} +4 -4
- data/test/rspec3.bats +56 -0
- data/test/sleepy_runner.rb +3 -1
- data/test-queue.gemspec +5 -5
- metadata +26 -37
- data/.travis.yml +0 -18
- data/Gemfile-cucumber1-3 +0 -4
- data/Gemfile-cucumber1-3.lock +0 -33
- data/Gemfile-cucumber2-4 +0 -4
- data/Gemfile-cucumber2-4.lock +0 -37
- data/Gemfile-minitest4 +0 -3
- data/Gemfile-minitest4.lock +0 -19
- data/Gemfile-minitest5 +0 -3
- data/Gemfile-minitest5.lock +0 -19
- data/Gemfile-rspec2-1 +0 -3
- data/Gemfile-rspec2-1.lock +0 -27
- data/Gemfile-rspec3-0 +0 -3
- data/Gemfile-rspec3-0.lock +0 -31
- data/Gemfile-rspec3-1 +0 -3
- data/Gemfile-rspec3-1.lock +0 -31
- data/Gemfile-rspec3-2 +0 -3
- data/Gemfile-rspec3-2.lock +0 -32
- data/Gemfile-testunit +0 -3
- data/Gemfile-testunit.lock +0 -21
- data/Gemfile.lock +0 -41
- data/script/cibuild +0 -19
- data/script/spec +0 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: f689a4cffa234a32b4e3919fe2f263258cd32682925c29d59e26fdd0a8218236
|
4
|
+
data.tar.gz: 5e2f51214fa2dfcc184386fc588767f7ce15ac9738de0a3c8a730aed33995669
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1f76dbac0466294ffca4a780f7c411611cba1c55006a22343bdc11d789e400b135d4457c889d591498ede4ec92dd12ce615239f3569667b061117729e2e61fbc
|
7
|
+
data.tar.gz: a9666ce78f35e7d1a4cf3f877782ef86b7909396fb12f27c6df883f483ff07907db6b3a9ced68c2f36eae55b2d3f28c9ed3699df3b4ed9a1fc9151b9147306a8
|
@@ -0,0 +1,93 @@
|
|
1
|
+
name: CI
|
2
|
+
|
3
|
+
on:
|
4
|
+
push:
|
5
|
+
branches:
|
6
|
+
- master
|
7
|
+
pull_request:
|
8
|
+
|
9
|
+
jobs:
|
10
|
+
main:
|
11
|
+
name: >-
|
12
|
+
${{ matrix.ruby }} ${{ matrix.entry.name }}
|
13
|
+
runs-on: ${{ matrix.os }}-latest
|
14
|
+
env:
|
15
|
+
TEST_QUEUE_WORKERS: 2
|
16
|
+
TEST_QUEUE_VERBOSE: 1
|
17
|
+
strategy:
|
18
|
+
fail-fast: false
|
19
|
+
matrix:
|
20
|
+
os: [ubuntu]
|
21
|
+
# Lowest and Latest version.
|
22
|
+
ruby: ['2.7', '3.2']
|
23
|
+
entry:
|
24
|
+
- { name: cucumber1_3, bats: test/cucumber.bats }
|
25
|
+
- { name: cucumber2_4, bats: test/cucumber.bats }
|
26
|
+
- { name: minitest4, bats: test/minitest4.bats }
|
27
|
+
- { name: minitest5, bats: test/minitest5.bats }
|
28
|
+
- { name: rspec3, bats: test/rspec3.bats }
|
29
|
+
- { name: testunit, bats: test/testunit.bats }
|
30
|
+
|
31
|
+
steps:
|
32
|
+
- name: checkout
|
33
|
+
uses: actions/checkout@v3
|
34
|
+
- name: set up Ruby
|
35
|
+
uses: ruby/setup-ruby@v1
|
36
|
+
with:
|
37
|
+
ruby-version: ${{ matrix.ruby }}
|
38
|
+
|
39
|
+
- name: install dependencies
|
40
|
+
run: bundle install --jobs 3 --retry 3
|
41
|
+
- name: setup for Bats
|
42
|
+
run: bundle exec rake setup
|
43
|
+
- name: spec
|
44
|
+
run: bundle exec rake spec
|
45
|
+
- name: install dependencies for ${{ matrix.entry.name }}
|
46
|
+
run: BUNDLE_GEMFILE=gemfiles/${{ matrix.entry.name }}.gemfile bundle install --jobs 3 --retry 3
|
47
|
+
- name: test
|
48
|
+
run: BUNDLE_GEMFILE=gemfiles/${{ matrix.entry.name }}.gemfile vendor/bats/bin/bats ${{ matrix.entry.bats }}
|
49
|
+
|
50
|
+
# RSpec 2 doesn't work with Ruby 3.2:
|
51
|
+
#
|
52
|
+
# /opt/hostedtoolcache/Ruby/3.2.1/x64/lib/ruby/gems/3.2.0/gems/rspec-core-2.99.2/lib/rspec/core/ruby_project.rb:27:
|
53
|
+
# in `block in find_first_parent_containing': undefined method `exists?' for File:Class (NoMethodError)
|
54
|
+
#
|
55
|
+
# ascend_until {|path| File.exists?(File.join(path, dir))}
|
56
|
+
# ^^^^^^^^
|
57
|
+
# Did you mean? exist?
|
58
|
+
#
|
59
|
+
# Up to Ruby 3.1 is the supported version for RSpec 2.
|
60
|
+
rspec2:
|
61
|
+
name: >-
|
62
|
+
${{ matrix.ruby }} ${{ matrix.entry.name }}
|
63
|
+
runs-on: ${{ matrix.os }}-latest
|
64
|
+
env:
|
65
|
+
TEST_QUEUE_WORKERS: 2
|
66
|
+
TEST_QUEUE_VERBOSE: 1
|
67
|
+
strategy:
|
68
|
+
fail-fast: false
|
69
|
+
matrix:
|
70
|
+
os: [ubuntu]
|
71
|
+
# Lowest and Latest version.
|
72
|
+
ruby: ['2.7', '3.1']
|
73
|
+
entry:
|
74
|
+
- { name: rspec2, bats: test/rspec2.bats }
|
75
|
+
|
76
|
+
steps:
|
77
|
+
- name: checkout
|
78
|
+
uses: actions/checkout@v3
|
79
|
+
- name: set up Ruby
|
80
|
+
uses: ruby/setup-ruby@v1
|
81
|
+
with:
|
82
|
+
ruby-version: ${{ matrix.ruby }}
|
83
|
+
|
84
|
+
- name: install dependencies
|
85
|
+
run: bundle install --jobs 3 --retry 3
|
86
|
+
- name: setup for Bats
|
87
|
+
run: bundle exec rake setup
|
88
|
+
- name: spec
|
89
|
+
run: bundle exec rake spec
|
90
|
+
- name: install dependencies for ${{ matrix.entry.name }}
|
91
|
+
run: BUNDLE_GEMFILE=gemfiles/${{ matrix.entry.name }}.gemfile bundle install --jobs 3 --retry 3
|
92
|
+
- name: test
|
93
|
+
run: BUNDLE_GEMFILE=gemfiles/${{ matrix.entry.name }}.gemfile vendor/bats/bin/bats ${{ matrix.entry.bats }}
|
data/.gitignore
CHANGED
data/Appraisals
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
appraise "cucumber1-3" do
|
2
|
+
gem 'cucumber', '~> 1.3.10'
|
3
|
+
# Pin Rake version to Prevent `NoMethodError: undefined method `last_comment'`.
|
4
|
+
gem 'rake', '< 11.0'
|
5
|
+
end
|
6
|
+
|
7
|
+
appraise "cucumber2-4" do
|
8
|
+
gem 'cucumber', '~> 2.4.0'
|
9
|
+
# Pin Rake version to Prevent `NoMethodError: undefined method `last_comment'`.
|
10
|
+
gem 'rake', '< 11.0'
|
11
|
+
end
|
12
|
+
|
13
|
+
appraise "minitest4" do
|
14
|
+
gem 'rake'
|
15
|
+
gem 'minitest', '~> 4.7'
|
16
|
+
end
|
17
|
+
|
18
|
+
appraise "minitest5" do
|
19
|
+
gem 'rake'
|
20
|
+
gem 'minitest', '5.10.0'
|
21
|
+
end
|
22
|
+
|
23
|
+
appraise "rspec2" do
|
24
|
+
# Pin Rake version to Prevent `NoMethodError: undefined method `last_comment'`.
|
25
|
+
gem 'rake', '< 11.0'
|
26
|
+
gem 'rspec', '~> 2.99'
|
27
|
+
end
|
28
|
+
|
29
|
+
appraise "rspec3" do
|
30
|
+
gem 'rspec', '~> 3.12'
|
31
|
+
end
|
32
|
+
|
33
|
+
appraise "testunit" do
|
34
|
+
gem 'test-unit'
|
35
|
+
end
|
data/Gemfile
CHANGED
data/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
MIT License
|
2
|
+
|
3
|
+
Copyright (c) 2018 Aman Gupta
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
+
SOFTWARE.
|
data/README.md
CHANGED
@@ -1,7 +1,7 @@
|
|
1
|
-
|
1
|
+
# test-queue
|
2
2
|
|
3
3
|
[![Gem Version](https://badge.fury.io/rb/test-queue.svg)](https://rubygems.org/gems/test-queue)
|
4
|
-
[![
|
4
|
+
[![CI](https://github.com/tmm1/test-queue/actions/workflows/test.yml/badge.svg)](https://github.com/tmm1/test-queue/actions/workflows/test.yml)
|
5
5
|
|
6
6
|
Yet another parallel test runner, built using a centralized queue to ensure
|
7
7
|
optimal distribution of tests between workers.
|
@@ -10,13 +10,13 @@ Specifically optimized for CI environments: build statistics from each run
|
|
10
10
|
are stored locally and used to sort the queue at the beginning of the
|
11
11
|
next run.
|
12
12
|
|
13
|
-
|
13
|
+
## Design
|
14
14
|
|
15
15
|
test-queue uses a simple master + pre-fork worker model. The master
|
16
16
|
exposes a unix domain socket server which workers use to grab tests off
|
17
17
|
the queue.
|
18
18
|
|
19
|
-
```
|
19
|
+
```console
|
20
20
|
─┬─ 21232 minitest-queue master
|
21
21
|
├─── 21571 minitest-queue worker [3] - AuthenticationTest
|
22
22
|
├─── 21568 minitest-queue worker [2] - ApiTest
|
@@ -27,7 +27,7 @@ the queue.
|
|
27
27
|
test-queue also has a distributed mode, where additional masters can share
|
28
28
|
the workload and relay results back to a central master.
|
29
29
|
|
30
|
-
|
30
|
+
## Environment variables
|
31
31
|
|
32
32
|
- `TEST_QUEUE_WORKERS`: number of workers to use per master (default: all available cores)
|
33
33
|
- `TEST_QUEUE_VERBOSE`: show results as they are available (default: `0`)
|
@@ -35,16 +35,16 @@ the workload and relay results back to a central master.
|
|
35
35
|
- `TEST_QUEUE_RELAY`: relay results back to a central master, specified as tcp `address:port`
|
36
36
|
- `TEST_QUEUE_STATS`: `path` to cache build stats in-build CI runs (default: `.test_queue_stats`)
|
37
37
|
- `TEST_QUEUE_FORCE`: comma separated list of suites to run
|
38
|
-
- `TEST_QUEUE_RELAY_TIMEOUT`: when using
|
39
|
-
- `TEST_QUEUE_RELAY_TOKEN`: when using
|
40
|
-
- `
|
38
|
+
- `TEST_QUEUE_RELAY_TIMEOUT`: when using distributed builds, the amount of time a remote master will try to reconnect to start work
|
39
|
+
- `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.
|
40
|
+
- `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.
|
41
41
|
- `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.
|
42
42
|
|
43
|
-
|
43
|
+
## Usage
|
44
44
|
|
45
45
|
test-queue bundles `testunit-queue`, `minitest-queue` and `rspec-queue` binaries which can be used directly:
|
46
46
|
|
47
|
-
```
|
47
|
+
```console
|
48
48
|
$ minitest-queue $(find test/ -name \*_test.rb)
|
49
49
|
$ rspec-queue --format progress spec
|
50
50
|
```
|
@@ -53,7 +53,7 @@ But the underlying `TestQueue::Runner::TestUnit`, `TestQueue::Runner::MiniTest`
|
|
53
53
|
built to be subclassed by your application. I recommend checking a new
|
54
54
|
executable into your project using one of these superclasses.
|
55
55
|
|
56
|
-
```
|
56
|
+
```console
|
57
57
|
$ vim script/test-queue
|
58
58
|
$ chmod +x script/test-queue
|
59
59
|
$ git add script/test-queue
|
@@ -69,7 +69,7 @@ runner to reset any global state.
|
|
69
69
|
class MyAppTestRunner < TestQueue::Runner::MiniTest
|
70
70
|
def after_fork(num)
|
71
71
|
# use separate mysql database (we assume it exists and has the right schema already)
|
72
|
-
ActiveRecord::Base.configurations
|
72
|
+
ActiveRecord::Base.configurations.configs_for(env_name: 'test', name: 'primary').database << num.to_s
|
73
73
|
ActiveRecord::Base.establish_connection(:test)
|
74
74
|
|
75
75
|
# use separate redis database
|
@@ -83,8 +83,8 @@ class MyAppTestRunner < TestQueue::Runner::MiniTest
|
|
83
83
|
# ...
|
84
84
|
end
|
85
85
|
|
86
|
-
# If this is a remote
|
87
|
-
@
|
86
|
+
# If this is a remote master, tell the central master something about us
|
87
|
+
@remote_master_message = "Output for remote master 123: http://myhost.com/build/123"
|
88
88
|
end
|
89
89
|
|
90
90
|
def around_filter(suite)
|
@@ -97,13 +97,13 @@ end
|
|
97
97
|
MyAppTestRunner.new.execute
|
98
98
|
```
|
99
99
|
|
100
|
-
|
100
|
+
## Distributed mode
|
101
101
|
|
102
102
|
To use distributed mode, the central master must listen on a tcp port. Additional masters can be booted
|
103
|
-
in relay mode to connect to the central master.
|
104
|
-
the master's.
|
103
|
+
in relay mode to connect to the central master. Remote masters must provide a `TEST_QUEUE_RELAY_TOKEN`
|
104
|
+
to match the central master's.
|
105
105
|
|
106
|
-
```
|
106
|
+
```console
|
107
107
|
$ TEST_QUEUE_RELAY_TOKEN=123 TEST_QUEUE_SOCKET=0.0.0.0:12345 bundle exec minitest-queue ./test/sample_test.rb
|
108
108
|
$ TEST_QUEUE_RELAY_TOKEN=123 TEST_QUEUE_RELAY=0.0.0.0:12345 bundle exec minitest-queue ./test/sample_test.rb
|
109
109
|
$ TEST_QUEUE_RELAY_TOKEN=123 ./test-multi.sh
|
@@ -112,7 +112,7 @@ $ TEST_QUEUE_RELAY_TOKEN=123 ./test-multi.sh
|
|
112
112
|
See the [Parameterized Trigger Plugin](https://wiki.jenkins-ci.org/display/JENKINS/Parameterized+Trigger+Plugin)
|
113
113
|
for a simple way to do this with jenkins.
|
114
114
|
|
115
|
-
|
115
|
+
## See also
|
116
116
|
|
117
117
|
* https://github.com/Shopify/rails_parallel
|
118
118
|
* https://github.com/grosser/parallel_tests
|
data/Rakefile
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
2
|
+
require "rspec/core/rake_task"
|
3
|
+
|
4
|
+
RSpec::Core::RakeTask.new(:spec)
|
5
|
+
|
6
|
+
task :default => [:setup, :spec, :feature]
|
7
|
+
|
8
|
+
task :setup do
|
9
|
+
sh 'script/bootstrap' unless File.exist?("#{Dir.pwd}/vendor/bats/bin/bats")
|
10
|
+
end
|
11
|
+
|
12
|
+
task :feature do
|
13
|
+
sh 'TEST_QUEUE_WORKERS=2 TEST_QUEUE_VERBOSE=1 vendor/bats/bin/bats test'
|
14
|
+
end
|
data/{bin → exe}/cucumber-queue
RENAMED
data/{bin → exe}/minitest-queue
RENAMED
data/{bin → exe}/rspec-queue
RENAMED
data/{bin → exe}/testunit-queue
RENAMED
data/lib/test-queue.rb
CHANGED
@@ -1 +1 @@
|
|
1
|
-
|
1
|
+
require_relative 'test_queue'
|
@@ -1,9 +1,9 @@
|
|
1
1
|
begin
|
2
2
|
require 'minitest'
|
3
|
-
|
3
|
+
require_relative '../runner/minitest5'
|
4
4
|
rescue LoadError => e
|
5
5
|
require 'minitest/unit'
|
6
|
-
|
6
|
+
require_relative '../runner/minitest4'
|
7
7
|
end
|
8
8
|
|
9
9
|
module TestQueue
|
@@ -1,4 +1,4 @@
|
|
1
|
-
|
1
|
+
require_relative '../runner'
|
2
2
|
|
3
3
|
module MiniTest
|
4
4
|
def self.__run reporter, options
|
@@ -56,6 +56,13 @@ module TestQueue
|
|
56
56
|
class Runner
|
57
57
|
class MiniTest < Runner
|
58
58
|
def initialize
|
59
|
+
options = Minitest.process_args ARGV
|
60
|
+
|
61
|
+
if Minitest.respond_to?(:seed)
|
62
|
+
Minitest.seed = options[:seed]
|
63
|
+
srand Minitest.seed
|
64
|
+
end
|
65
|
+
|
59
66
|
if ::MiniTest::Test.runnables.any? { |r| r.runnable_methods.any? }
|
60
67
|
fail "Do not `require` test files. Pass them via ARGV instead and they will be required as needed."
|
61
68
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
|
1
|
+
require_relative '../runner'
|
2
2
|
require 'rspec/core'
|
3
3
|
|
4
4
|
case ::RSpec::Core::Version::STRING.to_i
|
@@ -10,12 +10,6 @@ else
|
|
10
10
|
fail 'requires rspec version 2 or 3'
|
11
11
|
end
|
12
12
|
|
13
|
-
class ::RSpec::Core::ExampleGroup
|
14
|
-
def self.failure_count
|
15
|
-
examples.map {|e| e.execution_result[:status] == "failed"}.length
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
13
|
module TestQueue
|
20
14
|
class Runner
|
21
15
|
class RSpec < Runner
|
@@ -42,6 +36,11 @@ module TestQueue
|
|
42
36
|
options.parse_options if options.respond_to?(:parse_options)
|
43
37
|
options.configure(::RSpec.configuration)
|
44
38
|
|
39
|
+
if ::RSpec.configuration.instance_variable_defined?(:@files_or_directories_to_run) &&
|
40
|
+
::RSpec.configuration.instance_variable_get(:@files_or_directories_to_run).empty?
|
41
|
+
::RSpec.configuration.instance_variable_set(:@files_or_directories_to_run, [::RSpec.configuration.default_path])
|
42
|
+
end
|
43
|
+
|
45
44
|
::RSpec.configuration.files_to_run.uniq
|
46
45
|
end
|
47
46
|
|
@@ -53,6 +52,8 @@ module TestQueue
|
|
53
52
|
example_or_group.id
|
54
53
|
elsif example_or_group.respond_to?(:full_description)
|
55
54
|
example_or_group.full_description
|
55
|
+
elsif example_or_group.metadata.key?(:full_description)
|
56
|
+
example_or_group.metadata[:full_description]
|
56
57
|
else
|
57
58
|
example_or_group.metadata[:example_group][:full_description]
|
58
59
|
end
|