qspec 0.1.3 → 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/qspec.rb +9 -2
- data/lib/qspec/command_line.rb +128 -28
- data/lib/qspec/formatters/redis_formatter.rb +8 -18
- data/lib/qspec/helper.rb +1 -8
- data/lib/qspec/version.rb +1 -1
- data/qspec.gemspec +2 -1
- metadata +27 -25
- data/lib/qspec/manager.rb +0 -131
- data/lib/qspec/spork_helper.rb +0 -65
- data/lib/spork/test_framework/qspec.rb +0 -11
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 60f88a4ea3ba943add6780bee19d0aeda39e56a9
|
4
|
+
data.tar.gz: 303ff003aaf98ad67bc9aba6206c0bbb3d24ef56
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 11d3fb8ff5803f5a06dc607a3f5443a02a554eeea6c8c4463b4753a4904bee1955533136076cdfb3ec27e756db1f09bba6af1bc957c886539118e407eeff51b9
|
7
|
+
data.tar.gz: 7f5de6de95d530444e49665ad410d52b879523c40ea75035dcdbb89aed257dff024af1bbeb67709b1234c27a22de3ebe4b43bf47f813747168525b6ddf72b271
|
data/lib/qspec.rb
CHANGED
@@ -1,8 +1,15 @@
|
|
1
1
|
require 'rspec/core'
|
2
|
+
|
3
|
+
# workaround https://github.com/rspec/rspec-core/pull/1637
|
4
|
+
require 'rspec/core/notifications'
|
5
|
+
class RSpec::Core::Notifications::NullColorizer
|
6
|
+
def wrap(line, ignored)
|
7
|
+
line
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
2
11
|
require 'qspec/version'
|
3
12
|
require 'qspec/ipc'
|
4
|
-
require 'qspec/manager'
|
5
|
-
require 'qspec/spork_helper'
|
6
13
|
require 'qspec/command_line'
|
7
14
|
require 'qspec/formatters/redis_formatter'
|
8
15
|
require 'qspec/config'
|
data/lib/qspec/command_line.rb
CHANGED
@@ -1,54 +1,154 @@
|
|
1
|
-
require '
|
2
|
-
|
1
|
+
require 'parallel'
|
3
2
|
module Qspec
|
4
|
-
class CommandLine
|
5
|
-
|
6
|
-
|
7
|
-
attr_reader :
|
3
|
+
class CommandLine
|
4
|
+
TIME_LOG_NAME = 'elapsed_time'
|
5
|
+
DEFAULT_ELAPSED_TIME = 3.0
|
6
|
+
attr_reader :ipc, :config, :id
|
8
7
|
|
9
|
-
def initialize(
|
8
|
+
def initialize(args)
|
10
9
|
@config = Config.new()
|
11
10
|
@ipc = IPC.from_config(@config)
|
12
|
-
@id =
|
13
|
-
|
14
|
-
|
11
|
+
@id = rand(10000)
|
12
|
+
@stats = []
|
13
|
+
@rspec_options = RSpec::Core::ConfigurationOptions.new(args)
|
14
|
+
@rspec_configuration = RSpec.configuration
|
15
|
+
@rspec_options.configure(@rspec_configuration)
|
15
16
|
end
|
16
17
|
|
17
18
|
def run(err, out)
|
18
|
-
@
|
19
|
-
@
|
20
|
-
|
19
|
+
@rspec_configuration.error_stream = err
|
20
|
+
@rspec_configuration.output_stream = out if @rspec_configuration.output_stream == $stdout
|
21
|
+
|
22
|
+
out.puts "ID: #{id}"
|
23
|
+
register_files(id)
|
24
|
+
puts "Forking #{@config['workers']} workers"
|
21
25
|
|
22
|
-
|
26
|
+
thread = start_progress_thread(id)
|
27
|
+
success = Parallel.map(1..@config['workers'], in_processes: @config['workers']) do |no|
|
28
|
+
ENV['TEST_ENV_NUMBER'] = no == 1 ? '' : no.to_s
|
23
29
|
process
|
24
|
-
|
25
|
-
|
30
|
+
end
|
31
|
+
thread.exit
|
32
|
+
|
33
|
+
pop_stat(id)
|
34
|
+
|
35
|
+
@rspec_configuration.output_stream.puts "Failures: " if ipc.llen("failure_#{id}") > 0
|
36
|
+
|
37
|
+
each_object("failure_#{id}") do |failure|
|
38
|
+
dump_failure(failure)
|
39
|
+
end
|
40
|
+
|
41
|
+
log_elapsed_times
|
42
|
+
dump_summary
|
43
|
+
exit(success ? 0 : 1)
|
44
|
+
ensure
|
45
|
+
if ipc
|
46
|
+
ipc.del("to_run_#{id}")
|
47
|
+
ipc.del("stat_#{id}")
|
48
|
+
ipc.del("failure_#{id}")
|
26
49
|
end
|
27
50
|
end
|
28
51
|
|
29
52
|
def process
|
53
|
+
ipc = IPC.from_config(@config)
|
30
54
|
success = true
|
31
55
|
while f = ipc.lpop("to_run_#{id}")
|
32
|
-
@
|
56
|
+
@rspec_configuration.add_formatter(Qspec::Formatters::RedisFormatterFactory.build(id, f))
|
57
|
+
|
58
|
+
require File.expand_path(f)
|
59
|
+
world = RSpec.world
|
60
|
+
example_groups = world.ordered_example_groups
|
61
|
+
|
33
62
|
begin
|
34
|
-
|
35
|
-
@configuration.reporter.report(@world.example_count, @configuration.randomize? ? @configuration.seed : nil) do |reporter|
|
63
|
+
@rspec_configuration.reporter.report(world.example_count(example_groups)) do |reporter|
|
36
64
|
begin
|
37
|
-
|
38
|
-
@
|
39
|
-
success
|
65
|
+
hook_context = RSpec::Core::SuiteHookContext.new
|
66
|
+
@rspec_configuration.hooks.run(:before, :suite, hook_context)
|
67
|
+
success = example_groups.map { |g| g.run(reporter) }.all? && success
|
40
68
|
ensure
|
41
|
-
@
|
42
|
-
GC.enable if @config['no_gc']
|
43
|
-
GC.start if @config['no_gc']
|
69
|
+
@rspec_configuration.hooks.run(:after, :suite, hook_context)
|
44
70
|
end
|
45
71
|
end
|
46
72
|
ensure
|
47
|
-
|
48
|
-
@
|
73
|
+
world.example_groups.clear
|
74
|
+
@rspec_configuration.reset # formatter, reporter
|
75
|
+
end
|
76
|
+
end
|
77
|
+
success
|
78
|
+
end
|
79
|
+
|
80
|
+
private
|
81
|
+
def start_progress_thread(id)
|
82
|
+
Thread.new do
|
83
|
+
loop do
|
84
|
+
pop_stat(id)
|
85
|
+
sleep 1
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
def pop_stat(id)
|
91
|
+
o = @rspec_configuration.output_stream
|
92
|
+
each_object("stat_#{id}") do |obj|
|
93
|
+
@stats << obj
|
94
|
+
o.print "!!! " if obj[3] > 0
|
95
|
+
o.puts obj.inspect
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
def each_object(key)
|
100
|
+
while data = ipc.lpop(key)
|
101
|
+
yield(Marshal.load(data))
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
def dump_summary
|
106
|
+
sum = @stats.each_with_object({ example: 0, failure: 0, pending: 0 }) do |stat, sum|
|
107
|
+
sum[:example] += stat[2]
|
108
|
+
sum[:failure] += stat[3]
|
109
|
+
sum[:pending] += stat[4]
|
110
|
+
end
|
111
|
+
@rspec_configuration.output_stream.puts "\n#{sum[:example]} examples, #{sum[:failure]} failures, #{sum[:pending]} pendings"
|
112
|
+
end
|
113
|
+
|
114
|
+
def dump_failure(failure)
|
115
|
+
@rspec_configuration.output_stream.puts ""
|
116
|
+
@rspec_configuration.output_stream.puts failure[:exception]
|
117
|
+
failure[:backtrace].each do |line|
|
118
|
+
@rspec_configuration.output_stream.puts "\t#{line}"
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
def log_elapsed_times
|
123
|
+
File.open(Qspec.path(TIME_LOG_NAME), 'w') do |f|
|
124
|
+
@stats.each do |stat|
|
125
|
+
f.puts "#{File.expand_path(stat[0])}:#{stat[1].to_f}"
|
49
126
|
end
|
50
127
|
end
|
51
|
-
|
128
|
+
end
|
129
|
+
|
130
|
+
def register_files(id)
|
131
|
+
sorted_files_to_run.uniq.each do |f|
|
132
|
+
ipc.rpush "to_run_#{id}", f
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
def sorted_files_to_run
|
137
|
+
@sorted_files_to_run ||= if @config['sort_by'] == 'time' && File.exists?(Qspec.path(TIME_LOG_NAME))
|
138
|
+
sort_by_time(@rspec_configuration.files_to_run)
|
139
|
+
else
|
140
|
+
sort_by_size(@rspec_configuration.files_to_run)
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
def sort_by_time(files)
|
145
|
+
log = Hash[File.readlines(Qspec.path(TIME_LOG_NAME)).map { |line| line.strip.split(":") }]
|
146
|
+
files.sort_by { |file| log[File.expand_path(file)].to_f || DEFAULT_ELAPSED_TIME }.reverse
|
147
|
+
end
|
148
|
+
|
149
|
+
# large to small
|
150
|
+
def sort_by_size(files)
|
151
|
+
files.sort_by { |file| -File.stat(file).size }
|
52
152
|
end
|
53
153
|
end
|
54
154
|
end
|
@@ -5,6 +5,7 @@ module Qspec
|
|
5
5
|
module RedisFormatterFactory
|
6
6
|
def self.build(id, file)
|
7
7
|
Class.new(RSpec::Core::Formatters::BaseFormatter) do
|
8
|
+
RSpec::Core::Formatters.register self, :dump_summary, :dump_failures
|
8
9
|
@@id = id
|
9
10
|
@@file = file
|
10
11
|
include RedisFormatterFactory
|
@@ -16,32 +17,21 @@ module Qspec
|
|
16
17
|
super
|
17
18
|
end
|
18
19
|
|
19
|
-
def dump_failures
|
20
|
-
|
21
|
-
ex = example.execution_result[:exception]
|
20
|
+
def dump_failures(notification)
|
21
|
+
notification.failure_notifications.each do |failure|
|
22
22
|
data = {
|
23
|
-
description:
|
24
|
-
exception:
|
25
|
-
backtrace:
|
23
|
+
description: failure.description,
|
24
|
+
exception: failure.message_lines.join("\n"),
|
25
|
+
backtrace: failure.formatted_backtrace
|
26
26
|
}
|
27
27
|
@ipc.rpush("failure_#{@@id}", Marshal.dump(data))
|
28
28
|
end
|
29
29
|
end
|
30
30
|
|
31
|
-
def dump_summary(
|
32
|
-
data = [@@file, duration,
|
31
|
+
def dump_summary(summary)
|
32
|
+
data = [@@file, summary.duration, summary.examples.size, summary.failed_examples.count, summary.pending_examples.count]
|
33
33
|
@ipc.rpush("stat_#{@@id}", Marshal.dump(data))
|
34
34
|
end
|
35
|
-
|
36
|
-
def format_exception(example, ex)
|
37
|
-
exception_class_name = ex.class.to_s
|
38
|
-
output = StringIO.new
|
39
|
-
output.puts "* #{example.full_description}"
|
40
|
-
output.puts "\tFailure/Error: #{read_failed_line(ex, example)}"
|
41
|
-
output.puts "\t#{exception_class_name}:" unless exception_class_name =~ /RSpec/
|
42
|
-
ex.message.to_s.split("\n").each { |line| output.puts "\t #{line}" } if ex.message
|
43
|
-
output.string
|
44
|
-
end
|
45
35
|
end
|
46
36
|
end
|
47
37
|
end
|
data/lib/qspec/helper.rb
CHANGED
@@ -1,9 +1,7 @@
|
|
1
1
|
module Qspec
|
2
2
|
class Helper
|
3
|
-
include SporkHelper
|
4
|
-
|
5
3
|
def initialize(argv)
|
6
|
-
@argv
|
4
|
+
@argv = argv
|
7
5
|
end
|
8
6
|
|
9
7
|
def serve
|
@@ -11,11 +9,6 @@ module Qspec
|
|
11
9
|
when 'init'
|
12
10
|
puts "Creating template"
|
13
11
|
Config.create_template
|
14
|
-
when 'spork'
|
15
|
-
Qspec.create_tmp_directory_if_not_exist
|
16
|
-
@config = Config.new
|
17
|
-
puts "Start #{@config['workers']} sporks"
|
18
|
-
start_spork_workers(@config['workers'])
|
19
12
|
end
|
20
13
|
end
|
21
14
|
end
|
data/lib/qspec/version.rb
CHANGED
data/qspec.gemspec
CHANGED
metadata
CHANGED
@@ -1,32 +1,43 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: qspec
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
5
|
-
prerelease:
|
4
|
+
version: 1.0.0
|
6
5
|
platform: ruby
|
7
6
|
authors:
|
8
7
|
- tomykaira
|
9
8
|
autorequire:
|
10
9
|
bindir: bin
|
11
10
|
cert_chain: []
|
12
|
-
date:
|
11
|
+
date: 2014-07-16 00:00:00.000000000 Z
|
13
12
|
dependencies:
|
14
13
|
- !ruby/object:Gem::Dependency
|
15
14
|
name: rspec-core
|
16
15
|
requirement: !ruby/object:Gem::Requirement
|
17
|
-
none: false
|
18
16
|
requirements:
|
19
|
-
- - ~>
|
17
|
+
- - "~>"
|
20
18
|
- !ruby/object:Gem::Version
|
21
|
-
version:
|
19
|
+
version: '3.0'
|
22
20
|
type: :runtime
|
23
21
|
prerelease: false
|
24
22
|
version_requirements: !ruby/object:Gem::Requirement
|
25
|
-
none: false
|
26
23
|
requirements:
|
27
|
-
- - ~>
|
24
|
+
- - "~>"
|
28
25
|
- !ruby/object:Gem::Version
|
29
|
-
version:
|
26
|
+
version: '3.0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: parallel
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
30
41
|
description: QSpec inserts spec files to a queue. Workers process that queue one
|
31
42
|
by one.
|
32
43
|
email:
|
@@ -37,7 +48,7 @@ executables:
|
|
37
48
|
extensions: []
|
38
49
|
extra_rdoc_files: []
|
39
50
|
files:
|
40
|
-
- .gitignore
|
51
|
+
- ".gitignore"
|
41
52
|
- Gemfile
|
42
53
|
- LICENSE.txt
|
43
54
|
- README.md
|
@@ -52,39 +63,30 @@ files:
|
|
52
63
|
- lib/qspec/ipc.rb
|
53
64
|
- lib/qspec/ipc/file.rb
|
54
65
|
- lib/qspec/ipc/redis.rb
|
55
|
-
- lib/qspec/manager.rb
|
56
|
-
- lib/qspec/spork_helper.rb
|
57
66
|
- lib/qspec/version.rb
|
58
|
-
- lib/spork/test_framework/qspec.rb
|
59
67
|
- qspec.gemspec
|
60
68
|
homepage: ''
|
61
69
|
licenses: []
|
70
|
+
metadata: {}
|
62
71
|
post_install_message: Run qspec-helper init to create your config file
|
63
72
|
rdoc_options: []
|
64
73
|
require_paths:
|
65
74
|
- lib
|
66
75
|
required_ruby_version: !ruby/object:Gem::Requirement
|
67
|
-
none: false
|
68
76
|
requirements:
|
69
|
-
- -
|
77
|
+
- - ">="
|
70
78
|
- !ruby/object:Gem::Version
|
71
79
|
version: '0'
|
72
|
-
segments:
|
73
|
-
- 0
|
74
|
-
hash: 901026415
|
75
80
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
76
|
-
none: false
|
77
81
|
requirements:
|
78
|
-
- -
|
82
|
+
- - ">="
|
79
83
|
- !ruby/object:Gem::Version
|
80
84
|
version: '0'
|
81
|
-
segments:
|
82
|
-
- 0
|
83
|
-
hash: 901026415
|
84
85
|
requirements: []
|
85
86
|
rubyforge_project:
|
86
|
-
rubygems_version:
|
87
|
+
rubygems_version: 2.2.0
|
87
88
|
signing_key:
|
88
|
-
specification_version:
|
89
|
+
specification_version: 4
|
89
90
|
summary: QSpec is extension of RSpec. Q is for queue, and quick.
|
90
91
|
test_files: []
|
92
|
+
has_rdoc:
|
data/lib/qspec/manager.rb
DELETED
@@ -1,131 +0,0 @@
|
|
1
|
-
require 'rspec/core/formatters/helpers'
|
2
|
-
|
3
|
-
module Qspec
|
4
|
-
module Manager
|
5
|
-
TIME_LOG_NAME = 'elapsed_time'
|
6
|
-
DEFAULT_ELAPSED_TIME = 3.0
|
7
|
-
attr_reader :output
|
8
|
-
attr_reader :id
|
9
|
-
|
10
|
-
def start_worker
|
11
|
-
@id = rand(10000)
|
12
|
-
output.puts "ID: #{id}"
|
13
|
-
register_files(id)
|
14
|
-
if runnning_ports
|
15
|
-
puts "Connecting to spork: #{runnning_ports.inspect}"
|
16
|
-
runnning_ports.each do |port|
|
17
|
-
fork do
|
18
|
-
connect_spork(port, id, @configuration.error_stream, output)
|
19
|
-
end
|
20
|
-
end
|
21
|
-
else
|
22
|
-
puts "Forking #{@config['workers']} workers"
|
23
|
-
command = "qspec #{@options.drb_argv.join " "}"
|
24
|
-
@config['workers'].times do |i|
|
25
|
-
env = {
|
26
|
-
"qspec_id" => id.to_s,
|
27
|
-
"TEST_ENV_NUMBER" => i == 0 ? '' : (i + 1).to_s }
|
28
|
-
spawn(env,
|
29
|
-
command,
|
30
|
-
out: '/dev/null')
|
31
|
-
end
|
32
|
-
end
|
33
|
-
|
34
|
-
@stats = []
|
35
|
-
thread = start_progress_thread(id)
|
36
|
-
success = Process.waitall.all? { |pid, status| status.exitstatus == 0 }
|
37
|
-
thread.exit
|
38
|
-
|
39
|
-
pop_stat(id)
|
40
|
-
|
41
|
-
output.puts "Failures: " if ipc.llen("failure_#{id}") > 0
|
42
|
-
|
43
|
-
each_object("failure_#{id}") do |failure|
|
44
|
-
dump_failure(failure)
|
45
|
-
end
|
46
|
-
|
47
|
-
log_elapsed_times
|
48
|
-
dump_summary
|
49
|
-
exit(success ? 0 : 1)
|
50
|
-
ensure
|
51
|
-
if ipc
|
52
|
-
ipc.del("to_run_#{id}")
|
53
|
-
ipc.del("stat_#{id}")
|
54
|
-
ipc.del("failure_#{id}")
|
55
|
-
end
|
56
|
-
end
|
57
|
-
|
58
|
-
private
|
59
|
-
def start_progress_thread(id)
|
60
|
-
Thread.new do
|
61
|
-
loop do
|
62
|
-
pop_stat(id)
|
63
|
-
sleep 1
|
64
|
-
end
|
65
|
-
end
|
66
|
-
end
|
67
|
-
|
68
|
-
def pop_stat(id)
|
69
|
-
each_object("stat_#{id}") do |obj|
|
70
|
-
@stats << obj
|
71
|
-
output.print "!!! " if obj[3] > 0
|
72
|
-
output.puts obj.inspect
|
73
|
-
end
|
74
|
-
end
|
75
|
-
|
76
|
-
def each_object(key)
|
77
|
-
while data = ipc.lpop(key)
|
78
|
-
yield(Marshal.load(data))
|
79
|
-
end
|
80
|
-
end
|
81
|
-
|
82
|
-
def dump_summary
|
83
|
-
sum = @stats.each_with_object({ example: 0, failure: 0, pending: 0 }) do |stat, sum|
|
84
|
-
sum[:example] += stat[2]
|
85
|
-
sum[:failure] += stat[3]
|
86
|
-
sum[:pending] += stat[4]
|
87
|
-
end
|
88
|
-
output.puts "\n#{sum[:example]} examples, #{sum[:failure]} failures, #{sum[:pending]} pendings"
|
89
|
-
end
|
90
|
-
|
91
|
-
def dump_failure(failure)
|
92
|
-
puts ""
|
93
|
-
puts failure[:exception]
|
94
|
-
failure[:backtrace].each do |line|
|
95
|
-
output.puts "\t#{line}"
|
96
|
-
end
|
97
|
-
end
|
98
|
-
|
99
|
-
def log_elapsed_times
|
100
|
-
File.open(Qspec.path(TIME_LOG_NAME), 'w') do |f|
|
101
|
-
@stats.each do |stat|
|
102
|
-
f.puts "#{File.expand_path(stat[0])}:#{stat[1].to_f}"
|
103
|
-
end
|
104
|
-
end
|
105
|
-
end
|
106
|
-
|
107
|
-
def register_files(id)
|
108
|
-
sorted_files_to_run.uniq.each do |f|
|
109
|
-
ipc.rpush "to_run_#{id}", f
|
110
|
-
end
|
111
|
-
end
|
112
|
-
|
113
|
-
def sorted_files_to_run
|
114
|
-
@sorted_files_to_run ||= if @config['sort_by'] == 'time' && File.exists?(Qspec.path(TIME_LOG_NAME))
|
115
|
-
sort_by_time(@configuration.files_to_run)
|
116
|
-
else
|
117
|
-
sort_by_size(@configuration.files_to_run)
|
118
|
-
end
|
119
|
-
end
|
120
|
-
|
121
|
-
def sort_by_time(files)
|
122
|
-
log = Hash[File.readlines(Qspec.path(TIME_LOG_NAME)).map { |line| line.strip.split(":") }]
|
123
|
-
files.sort_by { |file| log[File.expand_path(file)].to_f || DEFAULT_ELAPSED_TIME }.reverse
|
124
|
-
end
|
125
|
-
|
126
|
-
# large to small
|
127
|
-
def sort_by_size(files)
|
128
|
-
files.sort_by { |file| -File.stat(file).size }
|
129
|
-
end
|
130
|
-
end
|
131
|
-
end
|
data/lib/qspec/spork_helper.rb
DELETED
@@ -1,65 +0,0 @@
|
|
1
|
-
# spork is optional
|
2
|
-
begin
|
3
|
-
require 'drb/drb'
|
4
|
-
require 'spork/test_framework/qspec'
|
5
|
-
rescue LoadError
|
6
|
-
end
|
7
|
-
|
8
|
-
require 'rspec/core/drb_options'
|
9
|
-
|
10
|
-
module Qspec
|
11
|
-
module SporkHelper
|
12
|
-
def start_spork_workers(count)
|
13
|
-
Signal.trap(:INT){
|
14
|
-
puts "Stop spork processes"
|
15
|
-
remove_port_file
|
16
|
-
exit(0)
|
17
|
-
}
|
18
|
-
|
19
|
-
default_port = (@config['spork_port'] || ::Spork::TestFramework::Qspec::DEFAULT_PORT).to_i
|
20
|
-
ports = []
|
21
|
-
count.times do |i|
|
22
|
-
port = default_port+i
|
23
|
-
spawn({ "TEST_ENV_NUMBER" => i == 0 ? '' : (i + 1).to_s },
|
24
|
-
"spork qspec --port #{port}")
|
25
|
-
ports << port
|
26
|
-
end
|
27
|
-
create_port_file(ports)
|
28
|
-
Process.waitall.all? { |pid, status| status.exitstatus == 0 } ? 0 : 1
|
29
|
-
end
|
30
|
-
|
31
|
-
def connect_spork(port, id, err, out)
|
32
|
-
begin
|
33
|
-
DRb.start_service("druby://localhost:0")
|
34
|
-
rescue SocketError, Errno::EADDRNOTAVAIL
|
35
|
-
DRb.start_service("druby://:0")
|
36
|
-
end
|
37
|
-
spec_server = DRbObject.new_with_uri("druby://127.0.0.1:#{port||PORT}")
|
38
|
-
exit spec_server.run(@options.drb_argv + [id], err, out).to_i
|
39
|
-
end
|
40
|
-
|
41
|
-
def create_port_file(ports)
|
42
|
-
File.open(port_file, 'w') do |f|
|
43
|
-
f.puts ports.join("\n")
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
|
-
def runnning_ports
|
48
|
-
@runnning_ports ||= begin
|
49
|
-
ports = File.readlines(port_file).map { |line| line.strip.to_i }
|
50
|
-
ports.empty? ? nil : ports
|
51
|
-
rescue Errno::ENOENT
|
52
|
-
nil
|
53
|
-
end
|
54
|
-
end
|
55
|
-
|
56
|
-
def remove_port_file
|
57
|
-
File.unlink(port_file)
|
58
|
-
end
|
59
|
-
|
60
|
-
private
|
61
|
-
def port_file
|
62
|
-
@port_file ||= Qspec.path('spork_ports')
|
63
|
-
end
|
64
|
-
end
|
65
|
-
end
|
@@ -1,11 +0,0 @@
|
|
1
|
-
require 'spork'
|
2
|
-
class Spork::TestFramework::Qspec < Spork::TestFramework
|
3
|
-
DEFAULT_PORT = 9240
|
4
|
-
HELPER_FILE = File.join(Dir.pwd, "spec/spec_helper.rb")
|
5
|
-
|
6
|
-
def run_tests(argv, stderr, stdout)
|
7
|
-
require 'qspec'
|
8
|
-
ENV['qspec_id'] = argv.pop.to_s
|
9
|
-
::Qspec::CommandLine.new(argv).run(stderr, stdout)
|
10
|
-
end
|
11
|
-
end
|