forking_test_runner 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: f37240f61aa8ac0e9020b79cc2d3c7482e072022
4
+ data.tar.gz: bce3260c8d8b39a57ce69c7ad942f886a080ffe8
5
+ SHA512:
6
+ metadata.gz: 4483cbd72e290e710ac6608fee73935d4f88b509e76e8b3d57ca7fe9cb07cec41bc1eb187c0cc97448aa11ac858a63cfefbfd5fc9e04e957cf0a7cbe16e08c00
7
+ data.tar.gz: 4d79162fd8512fe21669bdfe131efcc2cdd8f4a2aa5016f2b40cee9194ff6e78eb4e20a34b08c121dccc1e085aae5fbf35fb125b354aac6d52f19b98b7177c27
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (C) 2013 Michael Grosser <michael@grosser.it>
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,55 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # enable local usage from cloned repo
4
+ root = File.expand_path("../..", __FILE__)
5
+ $LOAD_PATH << "#{root}/lib" if File.exist?("#{root}/Gemfile")
6
+
7
+ require 'forking_test_runner'
8
+
9
+ ForkingTestRunner.disable_minitest_autorun
10
+
11
+ runtime_log = ForkingTestRunner.delete_argv("--runtime-log", ARGV)
12
+ helper = ForkingTestRunner.delete_argv("--helper", ARGV) || "test/test_helper"
13
+
14
+ require "./#{helper}"
15
+
16
+ tests = ForkingTestRunner.find_tests_for_group(ARGV, runtime_log)
17
+ puts "Running tests #{tests.map(&:first).join(" ")}"
18
+
19
+ show_time = tests[0][1]
20
+
21
+ clear = "------"
22
+ results = tests.map do |file, expected|
23
+ puts "#{clear} >>> #{file}"
24
+ success = false
25
+ time = Benchmark.realtime do
26
+ success = ForkingTestRunner.run_test(file)
27
+ end
28
+ puts "Time: expected #{expected.round(2)}, actual #{time.round(2)}" if show_time
29
+ puts "#{clear} <<< #{file} ---- #{success ? "OK" : "Failed"}"
30
+ [file, time, expected, success]
31
+ end
32
+
33
+ puts "\nResults:"
34
+ puts results.map { |f,_,_,r| "#{f}: #{r ? "OK" : "Fail"}"}
35
+
36
+ if show_time
37
+ puts "Time: #{results.map { |_,time,expected,_| time - expected }.inject(:+).to_f.round(2)} diff to expected"
38
+ end
39
+
40
+ # log runtime and then curl it into the runtime log location
41
+ if ENV["RECORD_RUNTIME"]
42
+ require 'tempfile'
43
+ slug = ENV.fetch("TRAVIS_REPO_SLUG").sub("/", "-")
44
+ id = ENV.fetch("TRAVIS_BUILD_NUMBER")
45
+ url = "https://amend.herokuapp.com/amend/#{slug}-#{id}"
46
+ data = results.map { |f,time,_,_| "#{f}:#{time.round(2)}" }.join("\n") << "\n"
47
+ Tempfile.open("runtime.log") do |f|
48
+ f.write(data)
49
+ f.close
50
+ result = `curl -X POST --data-binary @#{f.path} #{url}`
51
+ puts "amended runtime log\ncurl #{url} | sort > #{runtime_log}\nStatus: #{$?.success?}\nResponse: #{result}"
52
+ end
53
+ end
54
+
55
+ exit(results.map(&:last).all? ? 0 : 1)
@@ -0,0 +1,3 @@
1
+ module ForkingTestRunner
2
+ VERSION = "0.1.0"
3
+ end
@@ -0,0 +1,85 @@
1
+ module ForkingTestRunner
2
+ class << self
3
+ # This forces Rails to load all fixtures, then prevents it from deleting and then
4
+ # re-inserting all fixtures when a test is run.
5
+ # Saves us a couple of seconds when the test includes a call to fixtures :all.
6
+ def preload_fixtures
7
+ return if @preloaded
8
+ @preloaded = true
9
+
10
+ # reuse our pre-loaded fixtures even if we have a different connection
11
+ class << ActiveRecord::Fixtures
12
+ def cache_for_connection(connection)
13
+ ActiveRecord::Fixtures.class_variable_get(:@@all_cached_fixtures)[:unique]
14
+ end
15
+ end
16
+
17
+ ActiveSupport::TestCase.fixtures :all
18
+
19
+ ActiveRecord::Fixtures.create_fixtures(
20
+ ActiveRecord::TestCase.fixture_path,
21
+ ActiveRecord::TestCase.fixture_table_names,
22
+ ActiveRecord::TestCase.fixture_class_names
23
+ )
24
+ end
25
+
26
+ # don't let minitest setup another exit hook
27
+ def disable_minitest_autorun
28
+ require 'minitest/unit'
29
+ MiniTest::Unit.class_variable_set("@@installed_at_exit", true)
30
+ end
31
+
32
+ def enabled_minitest_autorun
33
+ MiniTest::Unit.class_variable_set(:@@installed_at_exit, false)
34
+ MiniTest::Unit.autorun
35
+ end
36
+
37
+ def run_test(file)
38
+ preload_fixtures
39
+ ActiveRecord::Base.connection.disconnect!
40
+ child = fork do
41
+ ActiveRecord::Base.establish_connection 'test'
42
+ enabled_minitest_autorun
43
+ require "./#{file}"
44
+ end
45
+ Process.wait(child)
46
+ $?.success?
47
+ end
48
+
49
+ def find_tests_for_group(argv, runtime_log)
50
+ require 'parallel_tests/test/runner'
51
+
52
+ if argv.include?("--group")
53
+ # delete options we want while leaving others as they are (-v / --seed etc)
54
+ group, number_of_groups = ['--group', '--groups'].map do |arg|
55
+ value = delete_argv(arg, argv) || raise("Did not find option #{arg}")
56
+ value.to_i
57
+ end
58
+ dir = ARGV.shift
59
+ raise "Unable to find directory #{dir.inspect}" unless File.exist?(dir.to_s)
60
+ tests = [dir]
61
+ else
62
+ group = 1
63
+ number_of_groups = 1
64
+ size = argv.index("--") || argv.size
65
+ tests = argv.slice!(0, size)
66
+ argv.shift # remove --
67
+ end
68
+
69
+ group_by = (runtime_log ? :runtime : :filesize)
70
+ tests = ParallelTests::Test::Runner.send(:tests_with_size, tests, runtime_log: runtime_log, group_by: group_by)
71
+ groups = ParallelTests::Grouper.in_even_groups_by_size(tests, number_of_groups, {})
72
+ group = groups[group - 1] || raise("Group #{group} not found")
73
+
74
+ # return tests with runtime
75
+ tests = Hash[tests]
76
+ group.map { |test| [test, (tests[test] if group_by == :runtime)] }
77
+ end
78
+
79
+ def delete_argv(arg, argv)
80
+ return unless index = argv.index(arg)
81
+ argv.delete_at(index)
82
+ argv.delete_at(index)
83
+ end
84
+ end
85
+ end
metadata ADDED
@@ -0,0 +1,76 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: forking_test_runner
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Michael Grosser
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-03-19 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: parallel_tests
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '='
18
+ - !ruby/object:Gem::Version
19
+ version: 1.3.7
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '='
25
+ - !ruby/object:Gem::Version
26
+ version: 1.3.7
27
+ - !ruby/object:Gem::Dependency
28
+ name: activerecord
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "<"
32
+ - !ruby/object:Gem::Version
33
+ version: 4.0.0
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "<"
39
+ - !ruby/object:Gem::Version
40
+ version: 4.0.0
41
+ description:
42
+ email: michael@grosser.it
43
+ executables:
44
+ - forking-test-runner
45
+ extensions: []
46
+ extra_rdoc_files: []
47
+ files:
48
+ - MIT-LICENSE
49
+ - bin/forking-test-runner
50
+ - lib/forking_test_runner.rb
51
+ - lib/forking_test_runner/version.rb
52
+ homepage: https://github.com/grosser/forking_test_runner
53
+ licenses:
54
+ - MIT
55
+ metadata: {}
56
+ post_install_message:
57
+ rdoc_options: []
58
+ require_paths:
59
+ - lib
60
+ required_ruby_version: !ruby/object:Gem::Requirement
61
+ requirements:
62
+ - - ">="
63
+ - !ruby/object:Gem::Version
64
+ version: '0'
65
+ required_rubygems_version: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - ">="
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ requirements: []
71
+ rubyforge_project:
72
+ rubygems_version: 2.2.2
73
+ signing_key:
74
+ specification_version: 4
75
+ summary: Run every test in a fork to avoid pollution and get clean output per test
76
+ test_files: []