spicycode-hardcore_forking_action 3.1.480

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.
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2008-2009 Rob Sanheim, Chad Humphries
2
+
3
+ Except for the entire first version, which is Copyright from the beginning of time to April 17, 2009, Ryan Davis.
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Rakefile ADDED
@@ -0,0 +1,20 @@
1
+ begin
2
+ require 'jeweler'
3
+ Jeweler::Tasks.new do |s|
4
+ s.name = "hardcore_forking_action"
5
+ s.summary = "You see son, when a man loves a woman, he really wants his test suite to run as fast as possible."
6
+ s.email = "rsanheim@gmail.com, chad@spicycode.com"
7
+ s.homepage = "http://github.com/spicycode/hardcore_forking_action"
8
+ s.description = "You see son, when a man loves a woman, he really wants his test suite to run as fast as possible."
9
+ s.authors = "Rob Sanheim, Chad Humphries"
10
+ s.has_rdoc = false
11
+ s.extra_rdoc_files = ["readme.markdown", "LICENSE"]
12
+ s.bindir = 'bin'
13
+ s.default_executable = 'hfac'
14
+ s.executables = ["hfa", "hfac"]
15
+ s.require_path = 'lib'
16
+ s.files = %w(LICENSE readme.markdown Rakefile) + Dir.glob("{lib,test}/**/*")
17
+ end
18
+ rescue LoadError
19
+ puts "Jeweler not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
20
+ end
data/bin/hfa ADDED
@@ -0,0 +1,5 @@
1
+ #! /usr/bin/env ruby
2
+ $LOAD_PATH.unshift(File.expand_path(File.dirname(__FILE__) + '/../lib'))
3
+ require 'hardcore_forking_action'
4
+ HardcoreForkingAction.start_server ARGV
5
+
data/bin/hfac ADDED
@@ -0,0 +1,4 @@
1
+ #! /usr/bin/env ruby
2
+ $LOAD_PATH.unshift(File.expand_path(File.dirname(__FILE__) + '/../lib'))
3
+ require 'hardcore_forking_action'
4
+ HardcoreForkingAction.start_client ARGV
@@ -0,0 +1,178 @@
1
+ require 'optparse'
2
+ require 'socket'
3
+
4
+ module HardcoreForkingAction
5
+
6
+ PORT = 9084
7
+
8
+ DEFAULT_SETTINGS = {
9
+ :requires => [],
10
+ :code => [],
11
+ :extra_paths => [],
12
+ :port => PORT,
13
+ }
14
+
15
+ def self.add_env_args(opts, settings)
16
+ opts.separator ''
17
+ opts.separator 'Process environment options:'
18
+
19
+ opts.separator ''
20
+ opts.on('-e CODE', 'Execute CODE in parent process.',
21
+ 'May be specified multiple times.') do |code|
22
+ settings[:code] << code
23
+ end
24
+
25
+ opts.separator ''
26
+ opts.on('-I DIRECTORY', 'Adds DIRECTORY to $LOAD_PATH.',
27
+ 'May be specified multiple times.') do |dir|
28
+ settings[:extra_paths] << dir
29
+ end
30
+
31
+ opts.separator ''
32
+ opts.on('-r LIBRARY', 'Require LIBRARY in the parent process.',
33
+ 'May be specified multiple times.') do |lib|
34
+ settings[:requires] << lib
35
+ end
36
+ end
37
+
38
+ def self.daemonize(io = File.open('/dev/null', 'r+'))
39
+ fork and exit!
40
+ Process.setsid
41
+ fork and exit!
42
+
43
+ STDIN.reopen io
44
+ STDOUT.reopen io
45
+ #STDERR.reopen io
46
+
47
+ yield if block_given?
48
+ end
49
+
50
+ def self.parse_client_args(args)
51
+ settings = Marshal.load Marshal.dump(DEFAULT_SETTINGS)
52
+
53
+ opts = OptionParser.new do |opts|
54
+ opts.banner = "Usage: #{$0} [options]"
55
+
56
+ opts.separator ''
57
+ opts.on('-p', '--port PORT',
58
+ 'Listen for connections on PORT.',
59
+ "Default: #{settings[:port]}") do |port|
60
+ settings[:port] = port.to_i
61
+ end
62
+
63
+ opts.separator ''
64
+ opts.on('-h', '--help', 'You\'re looking at it.') do
65
+ $stderr.puts opts
66
+ exit 1
67
+ end
68
+
69
+ add_env_args opts, settings
70
+ end
71
+
72
+ opts.parse! args
73
+
74
+ return settings
75
+ end
76
+
77
+ def self.parse_server_args(args)
78
+ settings = Marshal.load Marshal.dump(DEFAULT_SETTINGS)
79
+ settings[:daemonize] = false
80
+
81
+ opts = OptionParser.new do |opts|
82
+ opts.banner = "Usage: #{$0} [options]"
83
+
84
+ opts.separator ''
85
+ opts.on('-d', '--daemonize',
86
+ 'Run as a daemon.',
87
+ "Default: #{settings[:daemonize]}") do |val|
88
+ settings[:daemonize] = val
89
+ end
90
+
91
+ opts.separator ''
92
+ opts.on('-p', '--port PORT',
93
+ 'Listen for connections on PORT.',
94
+ "Default: #{settings[:port]}") do |port|
95
+ settings[:port] = port.to_i
96
+ end
97
+
98
+ opts.separator ''
99
+ opts.on('-h', '--help', 'You\'re looking at it.') do
100
+ $stderr.puts opts
101
+ exit 1
102
+ end
103
+
104
+ add_env_args opts, settings
105
+ end
106
+
107
+ opts.parse! args
108
+
109
+ return settings
110
+ end
111
+
112
+ def self.start_client(args = ARGV)
113
+ trap 'INT' do exit 1 end # Exit gracefully
114
+
115
+ settings = parse_client_args args
116
+
117
+ args = Marshal.dump [settings, ARGV]
118
+
119
+ socket = TCPSocket.new 'localhost', settings[:port]
120
+
121
+ socket.puts args.length
122
+ socket.write args
123
+ socket.close_write
124
+
125
+ until socket.eof?
126
+ $stdout.puts socket.gets
127
+ end
128
+ end
129
+
130
+ def self.start_server(args = ARGV)
131
+ settings = parse_server_args args
132
+ setup_environment settings
133
+
134
+ daemonize if settings[:daemonize]
135
+
136
+ server = TCPServer.new 'localhost', settings[:port]
137
+
138
+ $stderr.puts "#{$0} Running as PID #{$$} on #{settings[:port]}" unless
139
+ settings[:daemonize]
140
+
141
+ loop do
142
+ Thread.new server.accept do |socket|
143
+ begin
144
+ args_length = socket.gets.to_i
145
+ args = socket.read args_length
146
+ settings, argv = Marshal.load args
147
+
148
+ fork do
149
+ daemonize socket do
150
+ ARGV.replace argv
151
+ setup_environment settings
152
+ socket.close
153
+ end
154
+ end
155
+
156
+ socket.close # close my copy.
157
+ rescue => e
158
+ socket.close if socket
159
+ end
160
+ end
161
+ end
162
+ rescue Exception => e
163
+ puts "Failed to catch #{e.class}:#{e.message}"
164
+ puts "\t#{e.backtrace.join "\n\t"}"
165
+ end
166
+
167
+ def self.setup_environment(settings)
168
+ settings[:extra_paths].map! { |dir| dir.split ':' }
169
+ settings[:extra_paths].flatten!
170
+ settings[:extra_paths].each { |dir| $:.unshift dir }
171
+
172
+ settings[:requires].each { |file| require file }
173
+
174
+ settings[:code].each { |code| eval code }
175
+ end
176
+
177
+ end
178
+
data/readme.markdown ADDED
@@ -0,0 +1,35 @@
1
+ Hardcore Forking Action
2
+ ==================
3
+
4
+ We like skittles.
5
+
6
+ Starting the hardcore forking
7
+ ------------
8
+ Edit your config/environments/test.rb. Make it so there is more of this in there:
9
+
10
+ config.cache_classes = false
11
+ config.eager_load_paths = []
12
+
13
+
14
+ Making the dream a reality
15
+ ------------
16
+ Then you could run the following to load your code into the "cloud". Replace "examples/example_helper.rb" with your drink of choice.
17
+
18
+ hfa -r examples/example_helper.rb
19
+
20
+
21
+ Meanwhile, in abandonded baby warehouse downtown you could run the test with the following command. The first time you will get the hit from loading rails, and all subsequent runs will not.
22
+
23
+ hfac -r examples/your_totally_awesome_example.rb
24
+
25
+ Caveats
26
+ ------------
27
+ It's late and I don't care a great deal if this works anywhere other than my laptop, or Rob's laptop.
28
+
29
+
30
+ Contributors
31
+ ------------
32
+ * Rob Sanheim
33
+ * Chad Humphries
34
+ * Ryan Davis
35
+ * 1987 Harlem Globetrotters
@@ -0,0 +1,172 @@
1
+ lib_path = File.expand_path(File.dirname(__FILE__) + "/../lib")
2
+ $LOAD_PATH.unshift lib_path unless $LOAD_PATH.include?(lib_path)
3
+
4
+ require 'hardcore_forking_action'
5
+ require 'test/unit'
6
+
7
+ class TestHardcoreForkingAction < Test::Unit::TestCase
8
+
9
+ def test_parse_client_args
10
+ expected = util_make_settings
11
+ settings = HardcoreForkingAction.parse_client_args []
12
+ assert_equal expected, settings
13
+ end
14
+
15
+ def test_parse_client_args_help
16
+ util_capture do
17
+ assert_raises SystemExit do
18
+ HardcoreForkingAction.parse_client_args ['-h']
19
+ end
20
+
21
+ assert_raises SystemExit do
22
+ HardcoreForkingAction.parse_client_args ['--help']
23
+ end
24
+ end
25
+ end
26
+
27
+ def test_parse_client_args_port
28
+ expected = util_make_settings [], [], [], 5
29
+
30
+ settings = HardcoreForkingAction.parse_client_args ['-p', '5']
31
+ assert_equal expected, settings
32
+
33
+ settings = HardcoreForkingAction.parse_client_args ['--port', '5']
34
+ assert_equal expected, settings
35
+ end
36
+
37
+ def test_parse_server_args
38
+ settings = HardcoreForkingAction.parse_server_args []
39
+ expected = util_make_settings nil, nil, nil, nil, false
40
+ assert_equal expected, settings
41
+ end
42
+
43
+ def test_parse_server_args_daemonize
44
+ expected = util_make_settings [], [], [], HardcoreForkingAction::PORT, true
45
+
46
+ settings = HardcoreForkingAction.parse_server_args ['-d']
47
+ assert_equal expected, settings
48
+
49
+ settings = HardcoreForkingAction.parse_server_args ['--daemonize']
50
+ assert_equal expected, settings
51
+ end
52
+
53
+ def test_parse_server_args_include
54
+ expected = util_make_settings nil, nil, ['lib'], nil, false
55
+
56
+ settings = HardcoreForkingAction.parse_server_args ['-I', 'lib']
57
+ assert_equal expected, settings
58
+
59
+ expected = util_make_settings nil, nil, ['lib', 'test'], nil, false
60
+
61
+ settings = HardcoreForkingAction.parse_server_args ['-I', 'lib', '-I', 'test']
62
+ assert_equal expected, settings
63
+
64
+ expected = util_make_settings nil, nil, ['lib:test'], nil, false
65
+
66
+ settings = HardcoreForkingAction.parse_server_args ['-I', 'lib:test']
67
+ assert_equal expected, settings
68
+ end
69
+
70
+ def test_parse_server_args_help
71
+ util_capture do
72
+ assert_raises SystemExit do
73
+ HardcoreForkingAction.parse_server_args ['-h']
74
+ end
75
+
76
+ assert_raises SystemExit do
77
+ HardcoreForkingAction.parse_server_args ['--help']
78
+ end
79
+ end
80
+ end
81
+
82
+ def test_parse_server_args_port
83
+ expected = util_make_settings nil, nil, nil, 5, false
84
+
85
+ settings = HardcoreForkingAction.parse_server_args ['-p', '5']
86
+ assert_equal expected, settings
87
+
88
+ settings = HardcoreForkingAction.parse_server_args ['--port', '5']
89
+ assert_equal expected, settings
90
+ end
91
+
92
+ def test_parse_server_args_execute
93
+ expected = util_make_settings [], ['foo'], nil, nil, false
94
+
95
+ settings = HardcoreForkingAction.parse_server_args ['-e', 'foo']
96
+ assert_equal expected, settings
97
+
98
+ expected = util_make_settings [], ['foo', 'bar'], nil, nil, false
99
+
100
+ settings = HardcoreForkingAction.parse_server_args ['-e', 'foo', '-e', 'bar']
101
+ assert_equal expected, settings
102
+ end
103
+
104
+ def test_parse_server_args_execute_duplicate_test? # FIX
105
+ expected = util_make_settings ['zentest'], nil, nil, nil, false
106
+
107
+ settings = HardcoreForkingAction.parse_server_args ['-r', 'zentest']
108
+ assert_equal expected, settings
109
+
110
+ expected = util_make_settings ['zentest', 'unit_diff'], nil, nil, nil, false
111
+
112
+ settings = HardcoreForkingAction.parse_server_args ['-r', 'zentest', '-r', 'unit_diff']
113
+ assert_equal expected, settings
114
+ end
115
+
116
+ def test_setup_environment_extra_paths
117
+ load_path = $LOAD_PATH.dup
118
+
119
+ HardcoreForkingAction.setup_environment :extra_paths => ['no_such_dir'],
120
+ :requires => [], :code => []
121
+
122
+ assert_equal 'no_such_dir', $LOAD_PATH.first
123
+ ensure
124
+ $LOAD_PATH.replace load_path
125
+ end
126
+
127
+ def test_setup_environment_extra_paths_with_colon
128
+ load_path = $LOAD_PATH.dup
129
+
130
+ HardcoreForkingAction.setup_environment :extra_paths => ['no_such_dir:other_bad_dir'],
131
+ :requires => [], :code => []
132
+
133
+ assert_equal 'other_bad_dir', $LOAD_PATH[0]
134
+ assert_equal 'no_such_dir', $LOAD_PATH[1]
135
+ ensure
136
+ $LOAD_PATH.replace load_path
137
+ end
138
+
139
+ def test_setup_environment_requires
140
+ assert_raises LoadError do
141
+ HardcoreForkingAction.setup_environment :extra_paths => [],
142
+ :requires => ['no_such_file'], :code => []
143
+ end
144
+ end
145
+
146
+ def test_setup_environment_code
147
+ HardcoreForkingAction.setup_environment :extra_paths => [],
148
+ :requires => [], :code => ['$trf_env_code = 0']
149
+
150
+ assert_equal 0, $trf_env_code
151
+ end
152
+
153
+ def util_make_settings(requires = nil, code = nil, extra_paths = nil,
154
+ port = nil, daemonize = nil)
155
+ settings = {
156
+ :requires => [],
157
+ :code => [],
158
+ :extra_paths => [],
159
+ :port => HardcoreForkingAction::PORT,
160
+ }
161
+
162
+ settings[:code] = code unless code.nil?
163
+ settings[:daemonize] = daemonize unless daemonize.nil?
164
+ settings[:extra_paths] = extra_paths unless extra_paths.nil?
165
+ settings[:port] = port unless port.nil?
166
+ settings[:requires] = requires unless requires.nil?
167
+
168
+ return settings
169
+ end
170
+
171
+ end
172
+
metadata ADDED
@@ -0,0 +1,59 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: spicycode-hardcore_forking_action
3
+ version: !ruby/object:Gem::Version
4
+ version: 3.1.480
5
+ platform: ruby
6
+ authors:
7
+ - Rob Sanheim, Chad Humphries
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-04-18 00:00:00 -07:00
13
+ default_executable: hfac
14
+ dependencies: []
15
+
16
+ description: You see son, when a man loves a woman, he really wants his test suite to run as fast as possible.
17
+ email: rsanheim@gmail.com, chad@spicycode.com
18
+ executables:
19
+ - hfa
20
+ - hfac
21
+ extensions: []
22
+
23
+ extra_rdoc_files:
24
+ - LICENSE
25
+ - readme.markdown
26
+ files:
27
+ - LICENSE
28
+ - Rakefile
29
+ - lib/hardcore_forking_action.rb
30
+ - readme.markdown
31
+ - test/test_hardcore_forking_action.rb
32
+ has_rdoc: false
33
+ homepage: http://github.com/spicycode/hardcore_forking_action
34
+ post_install_message:
35
+ rdoc_options:
36
+ - --charset=UTF-8
37
+ require_paths:
38
+ - lib
39
+ required_ruby_version: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ version: "0"
44
+ version:
45
+ required_rubygems_version: !ruby/object:Gem::Requirement
46
+ requirements:
47
+ - - ">="
48
+ - !ruby/object:Gem::Version
49
+ version: "0"
50
+ version:
51
+ requirements: []
52
+
53
+ rubyforge_project:
54
+ rubygems_version: 1.2.0
55
+ signing_key:
56
+ specification_version: 2
57
+ summary: You see son, when a man loves a woman, he really wants his test suite to run as fast as possible.
58
+ test_files:
59
+ - test/test_hardcore_forking_action.rb