minitest-fork_executor 1.0.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.
- checksums.yaml +7 -0
- data/lib/minitest/fork_executor.rb +48 -0
- data/test/minitest/fork_executor_test.rb +42 -0
- metadata +74 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: b399f50e3a52b2505c2125113c05ab712b1db59d26f00dd1075d7be2346c979b
|
4
|
+
data.tar.gz: a3394aab364af126482879b30badfd400ab2168185b1e746305555c42ef84ff2
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: b6014495cb3f12a88165cb983533be9a9b2f4e3188cbb67fa2e355577de3af285fc0ea6bf575e82e194d2526bedfa25ef979482be9377d96e1ca67082994a211
|
7
|
+
data.tar.gz: d887d4b98c08f8c7ba5e5c41687b88875ea431c9dd4ea0fbf5cb546947a524c6326ea5212519c98dcf3c91bceb417cc8feaeb04c1ef6e00cf6face124e8fef62
|
@@ -0,0 +1,48 @@
|
|
1
|
+
module Minitest
|
2
|
+
class ForkExecutor
|
3
|
+
def start
|
4
|
+
# Minitest runs test cases via Minitest.run_one_method. Each test case
|
5
|
+
# in a test class is run separately. We need to override that method and
|
6
|
+
# fork there. run_one_method is a method on the Minitest module so we need
|
7
|
+
# to *prepend* our version so that it's called first.
|
8
|
+
metaclass = (class << Minitest; self; end)
|
9
|
+
metaclass.prepend ClassMethods
|
10
|
+
end
|
11
|
+
|
12
|
+
def shutdown
|
13
|
+
# Nothing to do here but required by Minitest.
|
14
|
+
end
|
15
|
+
|
16
|
+
module ClassMethods
|
17
|
+
# The updated version of Minitest.run_one_method that forks before
|
18
|
+
# actually running a test case, makes the child run it and send the result
|
19
|
+
# to the parent process.
|
20
|
+
def run_one_method klass, method_name
|
21
|
+
read_io, write_io = IO.pipe
|
22
|
+
read_io.binmode
|
23
|
+
write_io.binmode
|
24
|
+
|
25
|
+
if fork
|
26
|
+
# Parent: load the result sent from the child
|
27
|
+
|
28
|
+
write_io.close
|
29
|
+
result = Marshal.load(read_io)
|
30
|
+
read_io.close
|
31
|
+
|
32
|
+
Process.wait
|
33
|
+
else
|
34
|
+
# Child: just run normally, dump the result, and exit the process to
|
35
|
+
# avoid double-reporting.
|
36
|
+
result = super
|
37
|
+
|
38
|
+
read_io.close
|
39
|
+
Marshal.dump(result, write_io)
|
40
|
+
write_io.close
|
41
|
+
exit
|
42
|
+
end
|
43
|
+
|
44
|
+
result
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'tempfile'
|
2
|
+
|
3
|
+
require 'minitest/autorun'
|
4
|
+
require 'minitest/fork_executor'
|
5
|
+
|
6
|
+
Minitest.parallel_executor = Minitest::ForkExecutor.new
|
7
|
+
|
8
|
+
# This test may seem to be more complicated than necessary but it's actually
|
9
|
+
# not. If we had only one test method then an implementation that forked an
|
10
|
+
# run *all* tests in the fork would pass the test.
|
11
|
+
#
|
12
|
+
# We need to ensure that:
|
13
|
+
#
|
14
|
+
# 1. Different test methods are run in different processes - hence two tests.
|
15
|
+
# 2. These processes are different from the parent process that spawned the
|
16
|
+
# test suite - hence recording @@parent_pid at the top.
|
17
|
+
class ForkTest < Minitest::Test
|
18
|
+
@@log = Tempfile.new
|
19
|
+
@@parent_pid = Process.pid
|
20
|
+
|
21
|
+
def test_run_in_process_one
|
22
|
+
log_and_assert
|
23
|
+
end
|
24
|
+
|
25
|
+
def test_run_in_process_two
|
26
|
+
log_and_assert
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def log_and_assert
|
32
|
+
@@log.seek(0, IO::SEEK_END)
|
33
|
+
@@log.write("#{Process.pid}\n")
|
34
|
+
@@log.rewind
|
35
|
+
|
36
|
+
pids = @@log.readlines.map(&:chop).map(&:to_i)
|
37
|
+
if pids.count == 2
|
38
|
+
assert_equal 2, pids.uniq.count
|
39
|
+
refute pids.include?(@@parent_pid)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
metadata
ADDED
@@ -0,0 +1,74 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: minitest-fork_executor
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Greg Navis
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2019-01-03 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: minitest
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
description: Run each test_* method in a separate process thus eliminating test case
|
42
|
+
interference.
|
43
|
+
email: contact@gregnavis.com
|
44
|
+
executables: []
|
45
|
+
extensions: []
|
46
|
+
extra_rdoc_files: []
|
47
|
+
files:
|
48
|
+
- lib/minitest/fork_executor.rb
|
49
|
+
- test/minitest/fork_executor_test.rb
|
50
|
+
homepage: https://github.com/gregnavis/minitest-fork_executor
|
51
|
+
licenses:
|
52
|
+
- MIT
|
53
|
+
metadata: {}
|
54
|
+
post_install_message:
|
55
|
+
rdoc_options: []
|
56
|
+
require_paths:
|
57
|
+
- lib
|
58
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
59
|
+
requirements:
|
60
|
+
- - ">="
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: '0'
|
63
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
64
|
+
requirements:
|
65
|
+
- - ">="
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
version: '0'
|
68
|
+
requirements: []
|
69
|
+
rubygems_version: 3.0.1
|
70
|
+
signing_key:
|
71
|
+
specification_version: 4
|
72
|
+
summary: Near-perfect process-level test case isolation.
|
73
|
+
test_files:
|
74
|
+
- test/minitest/fork_executor_test.rb
|