test-queue-split 0.3.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/Gemfile +3 -0
- data/Gemfile-minitest4 +3 -0
- data/Gemfile-minitest4.lock +38 -0
- data/Gemfile-rspec3-0 +3 -0
- data/Gemfile-rspec3-0.lock +40 -0
- data/Gemfile-rspec3-1 +3 -0
- data/Gemfile-rspec3-1.lock +40 -0
- data/Gemfile-rspec3-2 +3 -0
- data/Gemfile-rspec3-2.lock +41 -0
- data/Gemfile-testunit +3 -0
- data/Gemfile-testunit.lock +44 -0
- data/Gemfile.lock +54 -0
- data/README.md +114 -0
- data/Thorfile +9 -0
- data/bin/cucumber-queue +4 -0
- data/bin/minitest-queue +5 -0
- data/bin/rspec-queue +4 -0
- data/bin/testunit-queue +5 -0
- data/features/bad.feature +5 -0
- data/features/sample.feature +25 -0
- data/features/sample2.feature +29 -0
- data/features/step_definitions/common.rb +15 -0
- data/lib/test-queue.rb +1 -0
- data/lib/test_queue/iterator.rb +72 -0
- data/lib/test_queue/runner/cucumber.rb +46 -0
- data/lib/test_queue/runner/minitest.rb +25 -0
- data/lib/test_queue/runner/minitest4.rb +65 -0
- data/lib/test_queue/runner/minitest5.rb +62 -0
- data/lib/test_queue/runner/puppet_lint.rb +31 -0
- data/lib/test_queue/runner/rspec.rb +35 -0
- data/lib/test_queue/runner/rspec2.rb +35 -0
- data/lib/test_queue/runner/rspec3.rb +45 -0
- data/lib/test_queue/runner/sample.rb +76 -0
- data/lib/test_queue/runner/testunit.rb +56 -0
- data/lib/test_queue/runner.rb +395 -0
- data/lib/test_queue/version.rb +4 -0
- data/lib/test_queue.rb +8 -0
- data/test/sample_minispec.rb +31 -0
- data/test/sample_minitest4.rb +23 -0
- data/test/sample_minitest5.rb +23 -0
- data/test/sample_spec.rb +23 -0
- data/test/sample_testunit.rb +23 -0
- data/test-multi.sh +8 -0
- data/test-queue-split.gemspec +28 -0
- data/test.sh +23 -0
- metadata +141 -0
@@ -0,0 +1,395 @@
|
|
1
|
+
require 'socket'
|
2
|
+
require 'fileutils'
|
3
|
+
require 'securerandom'
|
4
|
+
|
5
|
+
module TestQueue
|
6
|
+
class Worker
|
7
|
+
attr_accessor :pid, :status, :output, :stats, :num, :host
|
8
|
+
attr_accessor :start_time, :end_time
|
9
|
+
attr_accessor :summary, :failure_output
|
10
|
+
|
11
|
+
def initialize(pid, num)
|
12
|
+
@pid = pid
|
13
|
+
@num = num
|
14
|
+
@start_time = Time.now
|
15
|
+
@output = ''
|
16
|
+
@stats = {}
|
17
|
+
end
|
18
|
+
|
19
|
+
def lines
|
20
|
+
@output.split("\n")
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
class Runner
|
25
|
+
attr_accessor :concurrency
|
26
|
+
|
27
|
+
def initialize(queue, concurrency=nil, socket=nil, relay=nil)
|
28
|
+
raise ArgumentError, 'array required' unless Array === queue
|
29
|
+
|
30
|
+
if forced = ENV['TEST_QUEUE_FORCE']
|
31
|
+
forced = forced.split(/\s*,\s*/)
|
32
|
+
whitelist = Set.new(forced)
|
33
|
+
queue = queue.select{ |s| whitelist.include?(s.to_s) }
|
34
|
+
queue.sort_by!{ |s| forced.index(s.to_s) }
|
35
|
+
end
|
36
|
+
|
37
|
+
@procline = $0
|
38
|
+
@queue = queue
|
39
|
+
@suites = queue.inject(Hash.new){ |hash, suite| hash.update suite.to_s => suite }
|
40
|
+
|
41
|
+
@workers = {}
|
42
|
+
@completed = []
|
43
|
+
|
44
|
+
@concurrency =
|
45
|
+
concurrency ||
|
46
|
+
(ENV['TEST_QUEUE_WORKERS'] && ENV['TEST_QUEUE_WORKERS'].to_i) ||
|
47
|
+
if File.exists?('/proc/cpuinfo')
|
48
|
+
File.read('/proc/cpuinfo').split("\n").grep(/processor/).size
|
49
|
+
elsif RUBY_PLATFORM =~ /darwin/
|
50
|
+
`/usr/sbin/sysctl -n hw.activecpu`.to_i
|
51
|
+
else
|
52
|
+
2
|
53
|
+
end
|
54
|
+
|
55
|
+
@slave_connection_timeout =
|
56
|
+
(ENV['TEST_QUEUE_RELAY_TIMEOUT'] && ENV['TEST_QUEUE_RELAY_TIMEOUT'].to_i) ||
|
57
|
+
30
|
58
|
+
|
59
|
+
@run_token = ENV['TEST_QUEUE_RELAY_TOKEN'] || SecureRandom.hex(8)
|
60
|
+
|
61
|
+
@socket =
|
62
|
+
socket ||
|
63
|
+
ENV['TEST_QUEUE_SOCKET'] ||
|
64
|
+
"/tmp/test_queue_#{$$}_#{object_id}.sock"
|
65
|
+
|
66
|
+
@relay =
|
67
|
+
relay ||
|
68
|
+
ENV['TEST_QUEUE_RELAY']
|
69
|
+
|
70
|
+
@slave_message = ENV["TEST_QUEUE_SLAVE_MESSAGE"] if ENV.has_key?("TEST_QUEUE_SLAVE_MESSAGE")
|
71
|
+
|
72
|
+
if @relay == @socket
|
73
|
+
STDERR.puts "*** Detected TEST_QUEUE_RELAY == TEST_QUEUE_SOCKET. Disabling relay mode."
|
74
|
+
@relay = nil
|
75
|
+
elsif @relay
|
76
|
+
@queue = []
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
def stats
|
81
|
+
@stats ||=
|
82
|
+
if File.exists?(file = stats_file)
|
83
|
+
Marshal.load(IO.binread(file)) || {}
|
84
|
+
else
|
85
|
+
{}
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
def execute
|
90
|
+
$stdout.sync = $stderr.sync = true
|
91
|
+
@start_time = Time.now
|
92
|
+
|
93
|
+
@concurrency > 0 ?
|
94
|
+
execute_parallel :
|
95
|
+
execute_sequential
|
96
|
+
ensure
|
97
|
+
summarize_internal unless $!
|
98
|
+
end
|
99
|
+
|
100
|
+
def summarize_internal
|
101
|
+
puts
|
102
|
+
puts "==> Summary (#{@completed.size} workers in %.4fs)" % (Time.now-@start_time)
|
103
|
+
puts
|
104
|
+
|
105
|
+
@failures = ''
|
106
|
+
@completed.each do |worker|
|
107
|
+
summarize_worker(worker)
|
108
|
+
@failures << worker.failure_output if worker.failure_output
|
109
|
+
|
110
|
+
puts " [%2d] %60s %4d suites in %.4fs (pid %d exit %d%s)" % [
|
111
|
+
worker.num,
|
112
|
+
worker.summary,
|
113
|
+
worker.stats.size,
|
114
|
+
worker.end_time - worker.start_time,
|
115
|
+
worker.pid,
|
116
|
+
worker.status.exitstatus,
|
117
|
+
worker.host && " on #{worker.host.split('.').first}"
|
118
|
+
]
|
119
|
+
end
|
120
|
+
|
121
|
+
unless @failures.empty?
|
122
|
+
puts
|
123
|
+
puts "==> Failures"
|
124
|
+
puts
|
125
|
+
puts @failures
|
126
|
+
end
|
127
|
+
|
128
|
+
puts
|
129
|
+
|
130
|
+
if @stats
|
131
|
+
File.open(stats_file, 'wb') do |f|
|
132
|
+
f.write Marshal.dump(stats)
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
summarize
|
137
|
+
|
138
|
+
estatus = @completed.inject(0){ |s, worker| s + worker.status.exitstatus }
|
139
|
+
estatus = 255 if estatus > 255
|
140
|
+
exit!(estatus)
|
141
|
+
end
|
142
|
+
|
143
|
+
def summarize
|
144
|
+
end
|
145
|
+
|
146
|
+
def stats_file
|
147
|
+
ENV['TEST_QUEUE_STATS'] ||
|
148
|
+
'.test_queue_stats'
|
149
|
+
end
|
150
|
+
|
151
|
+
def execute_sequential
|
152
|
+
exit! run_worker(@queue)
|
153
|
+
end
|
154
|
+
|
155
|
+
def execute_parallel
|
156
|
+
start_master
|
157
|
+
prepare(@concurrency)
|
158
|
+
@prepared_time = Time.now
|
159
|
+
start_relay if relay?
|
160
|
+
spawn_workers
|
161
|
+
distribute_queue
|
162
|
+
ensure
|
163
|
+
stop_master
|
164
|
+
|
165
|
+
@workers.each do |pid, worker|
|
166
|
+
Process.kill 'KILL', pid
|
167
|
+
end
|
168
|
+
|
169
|
+
until @workers.empty?
|
170
|
+
reap_worker
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
174
|
+
def start_master
|
175
|
+
if !relay?
|
176
|
+
if @socket =~ /^(?:(.+):)?(\d+)$/
|
177
|
+
address = $1 || '0.0.0.0'
|
178
|
+
port = $2.to_i
|
179
|
+
@socket = "#$1:#$2"
|
180
|
+
@server = TCPServer.new(address, port)
|
181
|
+
else
|
182
|
+
FileUtils.rm(@socket) if File.exists?(@socket)
|
183
|
+
@server = UNIXServer.new(@socket)
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
187
|
+
desc = "test-queue master (#{relay?? "relaying to #{@relay}" : @socket})"
|
188
|
+
puts "Starting #{desc}"
|
189
|
+
$0 = "#{desc} - #{@procline}"
|
190
|
+
end
|
191
|
+
|
192
|
+
def start_relay
|
193
|
+
return unless relay?
|
194
|
+
|
195
|
+
sock = connect_to_relay
|
196
|
+
message = @slave_message ? " #{@slave_message}" : ""
|
197
|
+
message.gsub!(/(\r|\n)/, "") # Our "protocol" is newline-separated
|
198
|
+
sock.puts("SLAVE #{@concurrency} #{Socket.gethostname} #{@run_token}#{message}")
|
199
|
+
response = sock.gets.strip
|
200
|
+
unless response == "OK"
|
201
|
+
STDERR.puts "*** Got non-OK response from master: #{response}"
|
202
|
+
sock.close
|
203
|
+
exit! 1
|
204
|
+
end
|
205
|
+
sock.close
|
206
|
+
rescue Errno::ECONNREFUSED
|
207
|
+
STDERR.puts "*** Unable to connect to relay #{@relay}. Aborting.."
|
208
|
+
exit! 1
|
209
|
+
end
|
210
|
+
|
211
|
+
def stop_master
|
212
|
+
return if relay?
|
213
|
+
|
214
|
+
FileUtils.rm_f(@socket) if @socket && @server.is_a?(UNIXServer)
|
215
|
+
@server.close rescue nil if @server
|
216
|
+
@socket = @server = nil
|
217
|
+
end
|
218
|
+
|
219
|
+
def spawn_workers
|
220
|
+
@concurrency.times do |i|
|
221
|
+
num = i+1
|
222
|
+
|
223
|
+
pid = fork do
|
224
|
+
@server.close if @server
|
225
|
+
|
226
|
+
iterator = Iterator.new(relay?? @relay : @socket, @suites, method(:around_filter))
|
227
|
+
after_fork_internal(num, iterator)
|
228
|
+
ret = run_worker(iterator) || 0
|
229
|
+
cleanup_worker
|
230
|
+
Kernel.exit! ret
|
231
|
+
end
|
232
|
+
|
233
|
+
@workers[pid] = Worker.new(pid, num)
|
234
|
+
end
|
235
|
+
end
|
236
|
+
|
237
|
+
def after_fork_internal(num, iterator)
|
238
|
+
srand
|
239
|
+
|
240
|
+
output = File.open("/tmp/test_queue_worker_#{$$}_output", 'w')
|
241
|
+
|
242
|
+
$stdout.reopen(output)
|
243
|
+
$stderr.reopen($stdout)
|
244
|
+
$stdout.sync = $stderr.sync = true
|
245
|
+
|
246
|
+
$0 = "test-queue worker [#{num}]"
|
247
|
+
puts
|
248
|
+
puts "==> Starting #$0 (#{Process.pid} on #{Socket.gethostname}) - iterating over #{iterator.sock}"
|
249
|
+
puts
|
250
|
+
|
251
|
+
after_fork(num)
|
252
|
+
end
|
253
|
+
|
254
|
+
# Run in the master before the fork. Used to create
|
255
|
+
# concurrency copies of any databases required by the
|
256
|
+
# test workers.
|
257
|
+
def prepare(concurrency)
|
258
|
+
end
|
259
|
+
|
260
|
+
def around_filter(suite)
|
261
|
+
yield
|
262
|
+
end
|
263
|
+
|
264
|
+
# Prepare a worker for executing jobs after a fork.
|
265
|
+
def after_fork(num)
|
266
|
+
end
|
267
|
+
|
268
|
+
# Entry point for internal runner implementations. The iterator will yield
|
269
|
+
# jobs from the shared queue on the master.
|
270
|
+
#
|
271
|
+
# Returns nothing. exits 0 on success.
|
272
|
+
# exits N on error, where N is the number of failures.
|
273
|
+
def run_worker(iterator)
|
274
|
+
iterator.each do |item|
|
275
|
+
puts " #{item.inspect}"
|
276
|
+
end
|
277
|
+
|
278
|
+
return 0 # exit status
|
279
|
+
end
|
280
|
+
|
281
|
+
def cleanup_worker
|
282
|
+
end
|
283
|
+
|
284
|
+
def summarize_worker(worker)
|
285
|
+
worker.summary = ''
|
286
|
+
worker.failure_output = ''
|
287
|
+
end
|
288
|
+
|
289
|
+
def reap_worker(blocking=true)
|
290
|
+
if pid = Process.waitpid(-1, blocking ? 0 : Process::WNOHANG) and worker = @workers.delete(pid)
|
291
|
+
worker.status = $?
|
292
|
+
worker.end_time = Time.now
|
293
|
+
|
294
|
+
if File.exists?(file = "/tmp/test_queue_worker_#{pid}_output")
|
295
|
+
worker.output = IO.binread(file)
|
296
|
+
FileUtils.rm(file)
|
297
|
+
end
|
298
|
+
|
299
|
+
if File.exists?(file = "/tmp/test_queue_worker_#{pid}_stats")
|
300
|
+
worker.stats = Marshal.load(IO.binread(file))
|
301
|
+
FileUtils.rm(file)
|
302
|
+
end
|
303
|
+
|
304
|
+
relay_to_master(worker) if relay?
|
305
|
+
worker_completed(worker)
|
306
|
+
end
|
307
|
+
end
|
308
|
+
|
309
|
+
def worker_completed(worker)
|
310
|
+
@completed << worker
|
311
|
+
puts worker.output if ENV['TEST_QUEUE_VERBOSE'] || worker.status.exitstatus != 0
|
312
|
+
end
|
313
|
+
|
314
|
+
def distribute_queue
|
315
|
+
return if relay?
|
316
|
+
remote_workers = 0
|
317
|
+
|
318
|
+
until @queue.empty? && remote_workers == 0
|
319
|
+
if IO.select([@server], nil, nil, 0.1).nil?
|
320
|
+
reap_worker(false) if @workers.any? # check for worker deaths
|
321
|
+
else
|
322
|
+
sock = @server.accept
|
323
|
+
cmd = sock.gets.strip
|
324
|
+
case cmd
|
325
|
+
when /^POP/
|
326
|
+
# If we have a slave from a different test run, don't respond, and it will consider the test run done.
|
327
|
+
if obj = @queue.shift
|
328
|
+
data = Marshal.dump(obj.to_s)
|
329
|
+
sock.write(data)
|
330
|
+
end
|
331
|
+
when /^SLAVE (\d+) ([\w\.-]+) (\w+)(?: (.+))?/
|
332
|
+
num = $1.to_i
|
333
|
+
slave = $2
|
334
|
+
run_token = $3
|
335
|
+
slave_message = $4
|
336
|
+
if run_token == @run_token
|
337
|
+
# If we have a slave from a different test run, don't respond, and it will consider the test run done.
|
338
|
+
sock.write("OK\n")
|
339
|
+
remote_workers += num
|
340
|
+
else
|
341
|
+
STDERR.puts "*** Worker from run #{run_token} connected to master for run #{@run_token}; ignoring."
|
342
|
+
sock.write("WRONG RUN\n")
|
343
|
+
end
|
344
|
+
message = "*** #{num} workers connected from #{slave} after #{Time.now-@start_time}s"
|
345
|
+
message << " " + slave_message if slave_message
|
346
|
+
STDERR.puts message
|
347
|
+
when /^WORKER (\d+)/
|
348
|
+
data = sock.read($1.to_i)
|
349
|
+
worker = Marshal.load(data)
|
350
|
+
worker_completed(worker)
|
351
|
+
remote_workers -= 1
|
352
|
+
end
|
353
|
+
sock.close
|
354
|
+
end
|
355
|
+
end
|
356
|
+
ensure
|
357
|
+
stop_master
|
358
|
+
|
359
|
+
until @workers.empty?
|
360
|
+
reap_worker
|
361
|
+
end
|
362
|
+
end
|
363
|
+
|
364
|
+
def relay?
|
365
|
+
!!@relay
|
366
|
+
end
|
367
|
+
|
368
|
+
def connect_to_relay
|
369
|
+
sock = nil
|
370
|
+
start = Time.now
|
371
|
+
puts "Attempting to connect for #{@slave_connection_timeout}s..."
|
372
|
+
while sock.nil?
|
373
|
+
begin
|
374
|
+
sock = TCPSocket.new(*@relay.split(':'))
|
375
|
+
rescue Errno::ECONNREFUSED => e
|
376
|
+
raise e if Time.now - start > @slave_connection_timeout
|
377
|
+
puts "Master not yet available, sleeping..."
|
378
|
+
sleep 0.5
|
379
|
+
end
|
380
|
+
end
|
381
|
+
sock
|
382
|
+
end
|
383
|
+
|
384
|
+
def relay_to_master(worker)
|
385
|
+
worker.host = Socket.gethostname
|
386
|
+
data = Marshal.dump(worker)
|
387
|
+
|
388
|
+
sock = connect_to_relay
|
389
|
+
sock.puts("WORKER #{data.bytesize}")
|
390
|
+
sock.write(data)
|
391
|
+
ensure
|
392
|
+
sock.close if sock
|
393
|
+
end
|
394
|
+
end
|
395
|
+
end
|
data/lib/test_queue.rb
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'minitest/spec'
|
2
|
+
|
3
|
+
class Meme
|
4
|
+
def i_can_has_cheezburger?
|
5
|
+
"OHAI!"
|
6
|
+
end
|
7
|
+
|
8
|
+
def will_it_blend?
|
9
|
+
"YES!"
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
describe Meme do
|
14
|
+
before do
|
15
|
+
@meme = Meme.new
|
16
|
+
end
|
17
|
+
|
18
|
+
describe "when asked about cheeseburgers" do
|
19
|
+
it "must respond positively" do
|
20
|
+
sleep 0.1
|
21
|
+
@meme.i_can_has_cheezburger?.must_equal "OHAI!"
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
describe "when asked about blending possibilities" do
|
26
|
+
it "won't say no" do
|
27
|
+
sleep 0.1
|
28
|
+
@meme.will_it_blend?.wont_match /^no/i
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'minitest/unit'
|
2
|
+
|
3
|
+
class MiniTestEqual < MiniTest::Unit::TestCase
|
4
|
+
def test_equal
|
5
|
+
assert_equal 1, 1
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
30.times do |i|
|
10
|
+
Object.const_set("MiniTestSleep#{i}", Class.new(MiniTest::Unit::TestCase) do
|
11
|
+
define_method('test_sleep') do
|
12
|
+
start = Time.now
|
13
|
+
sleep(0.25)
|
14
|
+
assert_in_delta Time.now-start, 0.25, 0.02
|
15
|
+
end
|
16
|
+
end)
|
17
|
+
end
|
18
|
+
|
19
|
+
class MiniTestFailure < MiniTest::Unit::TestCase
|
20
|
+
def test_fail
|
21
|
+
assert_equal 0, 1
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'minitest/autorun'
|
2
|
+
|
3
|
+
class MiniTestEqual < MiniTest::Test
|
4
|
+
def test_equal
|
5
|
+
assert_equal 1, 1
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
30.times do |i|
|
10
|
+
Object.const_set("MiniTestSleep#{i}", Class.new(MiniTest::Test) do
|
11
|
+
define_method('test_sleep') do
|
12
|
+
start = Time.now
|
13
|
+
sleep(0.25)
|
14
|
+
assert_in_delta Time.now-start, 0.25, 0.02
|
15
|
+
end
|
16
|
+
end)
|
17
|
+
end
|
18
|
+
|
19
|
+
class MiniTestFailure < MiniTest::Test
|
20
|
+
def test_fail
|
21
|
+
assert_equal 0, 1
|
22
|
+
end
|
23
|
+
end
|
data/test/sample_spec.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'rspec'
|
2
|
+
|
3
|
+
describe 'RSpecEqual' do
|
4
|
+
it 'checks equality' do
|
5
|
+
expect(1).to eq 1
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
30.times do |i|
|
10
|
+
describe "RSpecSleep(#{i})" do
|
11
|
+
it "sleeps" do
|
12
|
+
start = Time.now
|
13
|
+
sleep(0.25)
|
14
|
+
expect(Time.now-start).to be_within(0.02).of(0.25)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
describe 'RSpecFailure' do
|
20
|
+
it 'fails' do
|
21
|
+
expect(:foo).to eq :bar
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
|
3
|
+
class TestUnitEqual < Test::Unit::TestCase
|
4
|
+
def test_equal
|
5
|
+
assert_equal 1, 1
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
30.times do |i|
|
10
|
+
Object.const_set("TestUnitSleep#{i}", Class.new(Test::Unit::TestCase) do
|
11
|
+
define_method('test_sleep') do
|
12
|
+
start = Time.now
|
13
|
+
sleep(0.25)
|
14
|
+
assert_in_delta Time.now-start, 0.25, 0.02
|
15
|
+
end
|
16
|
+
end)
|
17
|
+
end
|
18
|
+
|
19
|
+
class TestUnitFailure < Test::Unit::TestCase
|
20
|
+
def test_fail
|
21
|
+
assert_equal 0, 1
|
22
|
+
end
|
23
|
+
end
|
data/test-multi.sh
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
require_relative 'lib/test_queue/version'
|
2
|
+
|
3
|
+
spec = Gem::Specification.new do |s|
|
4
|
+
s.name = 'test-queue-split'
|
5
|
+
s.version = TestQueue::VERSION
|
6
|
+
s.date = TestQueue::DATE
|
7
|
+
s.summary = 'parallel test runner'
|
8
|
+
s.description = 'minitest/rspec parallel test runner for CI environments'
|
9
|
+
|
10
|
+
s.homepage = 'http://github.com/tmm1/test-queue'
|
11
|
+
|
12
|
+
s.authors = ['Aman Gupta']
|
13
|
+
s.email = 'ruby@tmm1.net'
|
14
|
+
s.license = 'MIT'
|
15
|
+
|
16
|
+
s.has_rdoc = false
|
17
|
+
s.bindir = 'bin'
|
18
|
+
s.executables << 'rspec-queue'
|
19
|
+
s.executables << 'minitest-queue'
|
20
|
+
s.executables << 'testunit-queue'
|
21
|
+
s.executables << 'cucumber-queue'
|
22
|
+
|
23
|
+
s.add_development_dependency 'rspec', '>= 2.13', '< 4.0'
|
24
|
+
s.add_development_dependency 'cucumber', '~> 1.3.10'
|
25
|
+
s.add_development_dependency 'appium_thor', '~> 1.0.1'
|
26
|
+
|
27
|
+
s.files = `git ls-files`.split("\n")
|
28
|
+
end
|
data/test.sh
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
#!/bin/sh
|
2
|
+
set -x
|
3
|
+
|
4
|
+
export TEST_QUEUE_WORKERS=2 TEST_QUEUE_VERBOSE=1
|
5
|
+
|
6
|
+
export BUNDLE_GEMFILE=Gemfile-testunit
|
7
|
+
bundle install
|
8
|
+
bundle exec testunit-queue ./test/*_testunit.rb
|
9
|
+
|
10
|
+
export BUNDLE_GEMFILE=Gemfile-minitest4
|
11
|
+
bundle install
|
12
|
+
bundle exec minitest-queue ./test/*_minitest4.rb
|
13
|
+
bundle exec minitest-queue ./test/*_minispec.rb
|
14
|
+
|
15
|
+
export BUNDLE_GEMFILE=Gemfile
|
16
|
+
bundle install
|
17
|
+
bundle exec minitest-queue ./test/*_minitest4.rb
|
18
|
+
bundle exec minitest-queue ./test/*_minitest5.rb
|
19
|
+
bundle exec minitest-queue ./test/*_minispec.rb
|
20
|
+
bundle exec rspec-queue test
|
21
|
+
bundle exec cucumber-queue
|
22
|
+
|
23
|
+
TEST_QUEUE_WORKERS=1 TEST_QUEUE_FORCE="MiniTestSleep21,MiniTestSleep8,MiniTestFailure" bundle exec minitest-queue ./test/*_minitest5.rb
|