tork 15.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.
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ (the ISC license)
2
+
3
+ Copyright 2010 Suraj N. Kurapati <sunaku@gmail.com>
4
+ Copyright 2011 Brian D. Burns <burns180@gmail.com>
5
+ Copyright 2011 Daniel Pittman <daniel@rimspace.net>
6
+ Copyright 2011 Jacob Helwig <jacob@technosorcery.net>
7
+ Copyright 2011 Corné Verbruggen <corne@g-majeur.nl>
8
+ Copyright 2012 Jose Pablo Barrantes <xjpablobrx@gmail.com>
9
+ Copyright 2012 Spencer Steffen <spencer@citrusme.com>
10
+
11
+ Permission to use, copy, modify, and/or distribute this software for any
12
+ purpose with or without fee is hereby granted, provided that the above
13
+ copyright notice and this permission notice appear in all copies.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
16
+ WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
17
+ MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
18
+ ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
19
+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
20
+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
21
+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
@@ -0,0 +1,305 @@
1
+ _______ _______
2
+ ___ /___________ /__
3
+ _ __/ __ \ __/ /_/
4
+ / /_/ /_/ / / / ,\
5
+ \__/\____/_/ /_/|_\
6
+ >>>------>
7
+
8
+ _Test with fork_
9
+ ==============================================================================
10
+
11
+ Tork is a continuous testing tool for Ruby that automatically detects and
12
+ tests changes in your Ruby application or test suite in an efficient manner:
13
+
14
+ 1. Absorbs your test execution overhead into a master process.
15
+
16
+ 2. Forks to run your test files in parallel, without overhead.
17
+
18
+ 3. Avoids running unchanged tests inside changed test files.
19
+
20
+ ------------------------------------------------------------------------------
21
+ Features
22
+ ------------------------------------------------------------------------------
23
+
24
+ * Executes test files in parallel, making full use of multi-core CPUs.
25
+
26
+ * Tests *changes* in your Ruby application: avoids running (1) unchanged
27
+ test files and (2) unchanged tests inside changed test files.
28
+
29
+ * Supports MiniTest, Test::Unit, RSpec, and any testing framework that (1)
30
+ reflects failures in the process' exit status and (2) is loaded by your
31
+ application's `test/test_helper.rb` or `spec/spec_helper.rb` file.
32
+
33
+ * Logs the output from your tests into separate files: one log per test.
34
+ The path of a log file is simply the path of its test file plus ".log".
35
+
36
+ * Configurable through a Ruby script in your current working directory.
37
+
38
+ * Implemented in less than 400 lines (SLOC) of pure Ruby code! :-)
39
+
40
+ ------------------------------------------------------------------------------
41
+ Architecture
42
+ ------------------------------------------------------------------------------
43
+
44
+ Following UNIX philosophy, Tork is made of simple text-based programs: thus
45
+ you can build your own custom Tork user interface by wrapping `tork-driver`!
46
+
47
+ * `tork` is an interactive command-line user interface (CLI) for driver
48
+ * `tork-herald` monitors current directory tree and reports changed files
49
+ * `tork-driver` tells master to run tests and keeps track of test results
50
+ * `tork-master` absorbs test execution overhead and forks to run your tests
51
+
52
+ When the herald observes that files in or beneath the current directory have
53
+ been written to, it tells the driver, which then commands the master to fork a
54
+ worker process to run the tests affected by those changed files. This is all
55
+ performed automatically. But what if you want to manually run a test file?
56
+
57
+ You can (re)run any test file by simply saving it! When you do, Tork tries to
58
+ figure out which tests inside your newly saved test file have changed (using
59
+ diff and regexps) and then attempts to run just those. To make it run *all*
60
+ tests in your saved file, simply save the file *again* without changing it.
61
+
62
+ ------------------------------------------------------------------------------
63
+ Prerequisites
64
+ ------------------------------------------------------------------------------
65
+
66
+ * Ruby 1.8.7 or 1.9.2 or newer.
67
+
68
+ * Operating system that supports POSIX signals and the `fork()` system call.
69
+
70
+ To check if your system qualifies, launch `irb` and enter the following:
71
+
72
+ Process.respond_to? :fork # must be true
73
+ Signal.list.key? 'TERM' # must be true
74
+
75
+ ------------------------------------------------------------------------------
76
+ Installation
77
+ ------------------------------------------------------------------------------
78
+
79
+ As a Ruby gem:
80
+
81
+ gem install tork
82
+
83
+ As a Git clone:
84
+
85
+ git clone git://github.com/sunaku/tork
86
+ cd tork
87
+ rake install
88
+
89
+ ------------------------------------------------------------------------------
90
+ Invocation
91
+ ------------------------------------------------------------------------------
92
+
93
+ If installed as a Ruby gem:
94
+
95
+ tork --help
96
+
97
+ If installed as a Git clone:
98
+
99
+ bundle exec ruby -Ilib bin/tork --help
100
+
101
+ You can monitor your test processes in another terminal:
102
+
103
+ watch 'ps xuw | sed -n "1p; /test[r]/p" | fgrep -v sed'
104
+
105
+ You can forcefully terminate Tork from another terminal:
106
+
107
+ pkill -f tork
108
+
109
+ ------------------------------------------------------------------------------
110
+ Configuration
111
+ ------------------------------------------------------------------------------
112
+
113
+ Tork looks for a configuration file named `.tork.rb` in its current working
114
+ directory. The configuration file is a normal Ruby script. Inside it, you
115
+ can query and modify the `Tork::Config` object (OpenStruct) according to the
116
+ configuration options listed below.
117
+
118
+ ### Tork::Config.max_forked_workers
119
+
120
+ Maximum number of worker processes at any given time. The default value is
121
+ the number of processors detected on your system, or 1 if detection fails.
122
+
123
+ ### Tork::Config.overhead_load_paths
124
+
125
+ Array of paths that are prepended to Ruby's `$LOAD_PATH` before the
126
+ test execution overhead is loaded into `tork-master`.
127
+
128
+ ### Tork::Config.overhead_file_globs
129
+
130
+ Array of file globbing patterns that describe a set of Ruby scripts that are
131
+ loaded into `tork-master` as test execution overhead.
132
+
133
+ ### Tork::Config.reabsorb_file_greps
134
+
135
+ Array of regular expressions that describe a set of file paths that cause the
136
+ test execution overhead to be reabsorbed in `tork-master` when they change.
137
+
138
+ ### Tork::Config.all_test_file_globs
139
+
140
+ Array of file globbing patterns that describe the set of all test files in
141
+ your Ruby application.
142
+
143
+ ### Tork::Config.test_file_globbers
144
+
145
+ Hash that maps (1) a regular expression describing a set of file paths to (2)
146
+ a lambda function yielding a file globbing pattern describing a set of
147
+ test files that need to be run. In other words, whenever the source files
148
+ (the hash key; left-hand side of the mapping) change, their associated test
149
+ files (the hash value; right-hand side of the mapping) are run.
150
+
151
+ For example, if test files had the same names as their source files followed
152
+ by an underscore and the file name in reverse like this:
153
+
154
+ * `lib/hello.rb` => `test/hello_olleh.rb`
155
+ * `app/world.rb` => `spec/world_ldrow.rb`
156
+
157
+ Then you would add the following to your configuration file:
158
+
159
+ Tork::Config.test_file_globbers[%r<^(lib|app)/.+\.rb$>] = lambda do |path|
160
+ name = File.basename(path, '.rb')
161
+ "{test,spec}/**/#{name}_#{name.reverse}.rb"
162
+ end
163
+
164
+ In addition, these lambda functions can return `nil` if they do not wish for a
165
+ particular source file to be tested. For example, to ignore tests for all
166
+ source files except those within a `models/` directory, you would write:
167
+
168
+ Tork::Config.test_file_globbers[%r<^(lib|app)/.+\.rb$>] = lambda do |path|
169
+ if path.include? '/models/'
170
+ "{test,spec}/**/#{File.basename(path)}"
171
+ end
172
+ end
173
+
174
+ ### Tork::Config.test_name_extractor
175
+
176
+ Lambda function that is given a line of source code to determine whether it
177
+ can be considered as a test definition. In which case, the function must
178
+ extract and return the name of the test being defined.
179
+
180
+ ### Tork::Config.before_fork_hooks
181
+
182
+ Array of lambda functions that are executed inside `tork-master` before a
183
+ worker process is forked to run a test file. These functions are given:
184
+
185
+ 1. The sequence number of the worker process that will be forked shortly.
186
+
187
+ 2. The path of the log file containing the live output of the worker process.
188
+
189
+ 3. The path of the test file that will be run by the worker process.
190
+
191
+ 4. An array of names of tests inside the test file that will be run. If this
192
+ array is empty, then all tests in the test file will be run.
193
+
194
+ For example, to see some real values:
195
+
196
+ Tork::Config.before_fork_hooks << lambda do |worker_number, log_file, test_file, test_names|
197
+ p :before_fork_hooks => {
198
+ :worker_number => worker_number,
199
+ :log_file => log_file,
200
+ :test_file => test_file,
201
+ :test_names => test_names,
202
+ }
203
+ end
204
+
205
+ ### Tork::Config.after_fork_hooks
206
+
207
+ Array of lambda functions that are executed inside a worker process forked
208
+ by `tork-master`. These functions are given:
209
+
210
+ 1. The sequence number of the worker process.
211
+
212
+ 2. The path of the log file containing the live output of the worker process.
213
+
214
+ 3. The path of the test file that will be run by the worker process.
215
+
216
+ 4. An array of names of tests inside the test file that will be run. If this
217
+ array is empty, then all tests in the test file will be run.
218
+
219
+ For example, to see some real values, including the worker process' PID:
220
+
221
+ Tork::Config.after_fork_hooks << lambda do |worker_number, log_file, test_file, test_names|
222
+ p :after_fork_hooks => {
223
+ :worker_pid => $$,
224
+ :worker_number => worker_number,
225
+ :log_file => log_file,
226
+ :test_file => test_file,
227
+ :test_names => test_names,
228
+ }
229
+ end
230
+
231
+ The first function in this array instructs Test::Unit and RSpec to only run
232
+ those tests that correspond to the given `test_names` values. This
233
+ accelerates your test-driven development cycle and improves productivity!
234
+
235
+ ------------------------------------------------------------------------------
236
+ Configuration helpers
237
+ ------------------------------------------------------------------------------
238
+
239
+ The following libraries assist you with configuring Tork. To use them,
240
+ simply add the `require()` lines shown below to your configuration file
241
+ *or* pass their basenames to the tork(1) command, also as shown below.
242
+
243
+ ### require 'tork/config/rails' # tork rails
244
+
245
+ Support for the [Ruby on Rails] web framework.
246
+
247
+ ### require 'tork/config/parallel_tests' # tork parallel_tests
248
+
249
+ Support for the [parallel_tests] library.
250
+
251
+ ------------------------------------------------------------------------------
252
+ Usage tips
253
+ ------------------------------------------------------------------------------
254
+
255
+ ### [factory_girl] factories
256
+
257
+ Don't load your factories in master process (as part of your test execution
258
+ overhead) because that would necessitate the reloading of said overhead
259
+ whenever you change an existing factory definition or create a new one.
260
+
261
+ Instead, use `at_exit()` to wait until (1) after the master process has forked
262
+ a worker process and (2) just before that worker process runs its test suite
263
+ (whose execution is started by your test framework's own `at_exit()` handler):
264
+
265
+ require 'factory_girl'
266
+ at_exit { FactoryGirl.find_definitions unless $! }
267
+
268
+ This way, worker processes will pick up changes in your factories "for free"
269
+ whenever they (re)run your test files. Also, don't load your factories or do
270
+ anything else in your `at_exit()` handler if Ruby is exiting because of a
271
+ raised exception (denoted by the `$!` global variable in the snippet above).
272
+
273
+ ------------------------------------------------------------------------------
274
+ Known issues
275
+ ------------------------------------------------------------------------------
276
+
277
+ ### Ruby on Rails
278
+
279
+ * Ensure that your `config/environments/test.rb` file disables class caching
280
+ as follows (**NOTE:** if you are using Rails 3, the `tork/config/rails`
281
+ configuration helper can do this for you automatically):
282
+
283
+ config.cache_classes = false
284
+
285
+ Otherwise, Tork will appear to ignore source-code changes in your
286
+ models, controllers, helpers, and other Ruby source files.
287
+
288
+ * If SQLite3 raises one of the following errors, try using an [in-memory
289
+ adapter for SQLite3][memory_test_fix] or use different database software
290
+ (such as MySQL) for your test environment.
291
+
292
+ * SQLite3::BusyException: database is locked
293
+
294
+ * cannot start a transaction within a transaction
295
+
296
+ ------------------------------------------------------------------------------
297
+ License
298
+ ------------------------------------------------------------------------------
299
+
300
+ Released under the ISC license. See the LICENSE file for details.
301
+
302
+ [factory_girl]: https://github.com/thoughtbot/factory_girl
303
+ [memory_test_fix]: https://github.com/mvz/memory_test_fix
304
+ [parallel_tests]: https://github.com/grosser/parallel_tests
305
+ [Ruby on Rails]: http://rubyonrails.org
@@ -0,0 +1,2 @@
1
+ require "bundler/gem_tasks"
2
+ require "binman/rakefile"
@@ -0,0 +1,105 @@
1
+ #!/usr/bin/env ruby
2
+ =begin
3
+
4
+ TORK 1 2012-01-23 15.0.0
5
+ ==============================================================================
6
+
7
+ NAME
8
+ ------------------------------------------------------------------------------
9
+
10
+ tork - Continuous testing tool for Ruby
11
+
12
+ SYNOPSIS
13
+ ------------------------------------------------------------------------------
14
+
15
+ `tork` [*OPTION*]... [*CONFIG*]...
16
+
17
+ DESCRIPTION
18
+ ------------------------------------------------------------------------------
19
+
20
+ This program is a simple command-line user interface for tork-driver(1). It
21
+ loads the given *CONFIG* files (which are either paths to actual files or
22
+ names of helper libraries in the tork/config/ namespace of Ruby's load path)
23
+ and then waits for you to supply interactive commands on its stdin. You may
24
+ press the ENTER key (supplying no command) to see a menu of accepted commands.
25
+
26
+ OPTIONS
27
+ ------------------------------------------------------------------------------
28
+
29
+ `-h`, `--help`
30
+ Display this help manual using man(1).
31
+
32
+ SEE ALSO
33
+ ------------------------------------------------------------------------------
34
+
35
+ tork(1), tork-driver(1), tork-master(1), tork-herald(1)
36
+
37
+ =end =========================================================================
38
+
39
+ $0 = File.basename(__FILE__) # for easier indentification in ps(1) output
40
+
41
+ require 'binman'
42
+ BinMan.help
43
+
44
+ require 'json'
45
+ ENV['TORK_CONFIGS'] = JSON.dump(ARGV)
46
+
47
+ #-----------------------------------------------------------------------------
48
+ # backend
49
+ #-----------------------------------------------------------------------------
50
+
51
+ require 'tork/client'
52
+
53
+ warn 'tork: Absorbing test execution overhead...'
54
+ @driver = Tork::Client::Transceiver.new('tork-driver') do |line|
55
+ evstr, *details = JSON.load(line)
56
+ event = evstr.to_sym
57
+
58
+ case event
59
+ when :load then warn 'tork: Overhead absorbed. Ready for testing!'
60
+ when :over then warn 'tork: Reabsorbing changed overhead files...'
61
+ else
62
+ test_file, test_names, *details = details
63
+ message = [evstr.upcase, test_file, test_names.inspect, details].join(' ')
64
+
65
+ color = case event
66
+ when :pass then "\e[34m%s\e[0m" # blue
67
+ when :fail then "\e[31m%s\e[0m" # red
68
+ end
69
+ message = color % message if color and STDOUT.tty?
70
+ message = [message, File.read(test_file + '.log'), message] if event == :fail
71
+
72
+ puts message
73
+ end
74
+ end
75
+
76
+ #-----------------------------------------------------------------------------
77
+ # frontend
78
+ #-----------------------------------------------------------------------------
79
+
80
+ COMMANDS = {
81
+ 't' => :run_all_test_files,
82
+ 's' => :stop_running_test_files,
83
+ 'p' => :rerun_passed_test_files,
84
+ 'f' => :rerun_failed_test_files,
85
+ 'o' => :reabsorb_overhead_files,
86
+ 'q' => :quit,
87
+ }
88
+
89
+ begin
90
+ while key = STDIN.gets.chomp
91
+ if command = COMMANDS[key]
92
+ warn "tork: Sending #{command.to_s.inspect} command..."
93
+ @driver.send [command]
94
+ break if command == :quit
95
+ else # invalid command
96
+ COMMANDS.each do |key, command|
97
+ warn "tork: Type #{key} then ENTER to #{command.to_s.tr('_', ' ')}."
98
+ end
99
+ end
100
+ end
101
+ rescue Interrupt
102
+ # forced quit
103
+ end
104
+
105
+ Process.waitall
@@ -0,0 +1,86 @@
1
+ #!/usr/bin/env ruby
2
+ =begin
3
+
4
+ TORK-DRIVER 1 2012-01-23 15.0.0
5
+ ==============================================================================
6
+
7
+ NAME
8
+ ------------------------------------------------------------------------------
9
+
10
+ tork-driver - drives tork-master(1) and does bookkeeping
11
+
12
+ SYNOPSIS
13
+ ------------------------------------------------------------------------------
14
+
15
+ `tork-driver` [*OPTION*]...
16
+
17
+ DESCRIPTION
18
+ ------------------------------------------------------------------------------
19
+
20
+ This program reads the following single-line commands (JSON arrays) from its
21
+ standard input stream and performs the respective actions as described below.
22
+ It also funnels the standard output stream of tork-master(1) into its own.
23
+
24
+ `["run_all_test_files"]`
25
+ Runs all test files found within and beneath the current working directory.
26
+
27
+ `["stop_running_test_files"]`
28
+ Stops any test files that are currently running.
29
+
30
+ `["rerun_passed_test_files"]`
31
+ Runs all test files that have passed during their most recent run.
32
+
33
+ `["reabsorb_overhead_files"]`
34
+ Stops any test files that are currently running, reabsorbs the test
35
+ execution overhead, and resumes running those interrupted test files.
36
+
37
+ `["quit"]`
38
+ Stops all tests that are currently running and exits.
39
+
40
+ When tork-herald(1) reports that a file belonging to the test execution
41
+ overhead has been modified, this program replaces tork-master(1) with a new
42
+ instance, which then absorbs the modified test execution overhead into itself.
43
+
44
+ This program emits the following single-line status messages (JSON arrays) on
45
+ its standard output stream to provide notifications about its activity:
46
+
47
+ `["over",` *overhead_file*`]`
48
+ The test execution overhead is currently being reabsorbed, by replacing
49
+ tork-master(1) with a new instance, because *overhead_file* has changed.
50
+
51
+ OPTIONS
52
+ ------------------------------------------------------------------------------
53
+
54
+ `-h`, `--help`
55
+ Display this help manual using man(1).
56
+
57
+ FILES
58
+ ------------------------------------------------------------------------------
59
+
60
+ *.tork.rb*
61
+ Optional Ruby script for configuring tork(1).
62
+
63
+ ENVIRONMENT
64
+ ------------------------------------------------------------------------------
65
+
66
+ `TORK_CONFIGS`
67
+ A single-line JSON array containing paths to actual files or names of
68
+ helper libraries in the tork/config/ namespace of Ruby's load path.
69
+ These configuration files are loaded just before *.tork.rb* is loaded.
70
+
71
+ SEE ALSO
72
+ ------------------------------------------------------------------------------
73
+
74
+ tork(1), tork-driver(1), tork-master(1), tork-herald(1)
75
+
76
+ =end =========================================================================
77
+
78
+ $0 = File.basename(__FILE__) # for easier indentification in ps(1) output
79
+
80
+ require 'binman'
81
+ BinMan.help
82
+
83
+ require 'tork/driver'
84
+ Tork::Driver.loop
85
+
86
+ Process.waitall