nitra 0.9.4 → 0.9.5
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/README.md +88 -0
- data/bin/nitra +2 -1
- data/lib/nitra/channel.rb +37 -35
- data/lib/nitra/command_line.rb +58 -38
- data/lib/nitra/configuration.rb +39 -17
- data/lib/nitra/ext/cucumber.rb +32 -0
- data/lib/nitra/formatter.rb +59 -0
- data/lib/nitra/master.rb +69 -14
- data/lib/nitra/progress.rb +19 -1
- data/lib/nitra/rails_tooling.rb +22 -0
- data/lib/nitra/runner.rb +125 -68
- data/lib/nitra/slave.rb +18 -6
- data/lib/nitra/tasks.rb +55 -0
- data/lib/nitra/utils.rb +30 -26
- data/lib/nitra/worker.rb +175 -92
- data/lib/nitra/workers/cucumber.rb +62 -0
- data/lib/nitra/workers/rspec.rb +65 -0
- data/lib/nitra.rb +5 -1
- data/spec/nitra/channel_spec.rb +44 -0
- data/spec/nitra/command_line_spec.rb +133 -0
- data/spec/nitra/configuration_spec.rb +60 -0
- data/spec/nitra/formatter.rb +126 -0
- data/spec/nitra/tasks_spec.rb +16 -0
- data/spec/nitra/worker_spec.rb +13 -0
- metadata +78 -46
- data/README +0 -3
- data/lib/nitra/client.rb +0 -43
data/lib/nitra/worker.rb
CHANGED
@@ -1,128 +1,211 @@
|
|
1
1
|
require 'stringio'
|
2
2
|
require 'tempfile'
|
3
3
|
|
4
|
-
|
5
|
-
|
4
|
+
module Nitra
|
5
|
+
module Workers
|
6
|
+
class Worker
|
7
|
+
class << self
|
6
8
|
|
7
|
-
|
8
|
-
@runner_id = runner_id
|
9
|
-
@worker_number = worker_number
|
10
|
-
@configuration = configuration
|
11
|
-
end
|
9
|
+
@@worker_classes = {}
|
12
10
|
|
13
|
-
|
14
|
-
|
11
|
+
def inherited(klass)
|
12
|
+
@@worker_classes[klass.framework_name] = klass
|
13
|
+
end
|
15
14
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
run
|
20
|
-
end
|
15
|
+
def worker_classes
|
16
|
+
@@worker_classes
|
17
|
+
end
|
21
18
|
|
22
|
-
|
23
|
-
|
24
|
-
|
19
|
+
##
|
20
|
+
# Return the framework name of this worker
|
21
|
+
#
|
22
|
+
def framework_name
|
23
|
+
self.name.split("::").last.downcase
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
|
28
|
+
attr_reader :runner_id, :worker_number, :configuration, :channel, :io
|
29
|
+
|
30
|
+
def initialize(runner_id, worker_number, configuration)
|
31
|
+
@runner_id = runner_id
|
32
|
+
@worker_number = worker_number
|
33
|
+
@configuration = configuration
|
34
|
+
@forked_worker_pid = nil
|
35
|
+
|
36
|
+
ENV["TEST_ENV_NUMBER"] = worker_number.to_s
|
37
|
+
|
38
|
+
# Frameworks don't like it when you change the IO between invocations.
|
39
|
+
# So we make one object and flush it after every invocation.
|
40
|
+
@io = StringIO.new
|
41
|
+
end
|
25
42
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
# database. If we're forking for each file, we need to initialise first so it doesn't try to initialise
|
46
|
-
# for every single file.
|
47
|
-
if configuration.fork_for_each_file
|
48
|
-
debug "running empty spec to make rspec run its initialisation"
|
49
|
-
file = Tempfile.new("nitra")
|
50
|
-
begin
|
51
|
-
file.write("require 'spec_helper'; describe('nitra preloading') { it('preloads the fixtures') { 1.should == 1 } }\n")
|
52
|
-
file.close
|
53
|
-
output = Nitra::Utils.capture_output do
|
54
|
-
RSpec::Core::CommandLine.new(["-f", "p", file.path]).run(io, io)
|
43
|
+
|
44
|
+
def fork_and_run
|
45
|
+
client, server = Nitra::Channel.pipe
|
46
|
+
|
47
|
+
pid = fork do
|
48
|
+
# This is important. We don't want anything bubbling up to the master that we didn't send there.
|
49
|
+
# We reopen later to get the output from the framework run.
|
50
|
+
$stdout.reopen('/dev/null', 'a')
|
51
|
+
$stderr.reopen('/dev/null', 'a')
|
52
|
+
|
53
|
+
trap("USR1") { interrupt_forked_worker_and_exit }
|
54
|
+
|
55
|
+
server.close
|
56
|
+
@channel = client
|
57
|
+
begin
|
58
|
+
run
|
59
|
+
rescue => e
|
60
|
+
channel.write("command" => "error", "process" => "init framework", "text" => e.message, "worker_number" => worker_number)
|
61
|
+
end
|
55
62
|
end
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
63
|
+
|
64
|
+
client.close
|
65
|
+
|
66
|
+
[pid, server]
|
60
67
|
end
|
61
|
-
RSpec.reset
|
62
|
-
io.string = ""
|
63
|
-
end
|
64
68
|
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
+
protected
|
70
|
+
def load_environment
|
71
|
+
raise 'Subclasses must impliment this method.'
|
72
|
+
end
|
69
73
|
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
74
|
+
def minimal_file
|
75
|
+
raise 'Subclasses must impliment this method.'
|
76
|
+
end
|
77
|
+
|
78
|
+
def run_file(filename, preload = false)
|
79
|
+
raise 'Subclasses must impliment this method.'
|
75
80
|
end
|
76
81
|
|
77
|
-
|
78
|
-
|
82
|
+
def clean_up
|
83
|
+
raise 'Subclasses must impliment this method.'
|
84
|
+
end
|
85
|
+
|
86
|
+
def run
|
87
|
+
trap("SIGTERM") do
|
88
|
+
channel.write("command" => "error", "process" => "trap", "text" => 'Received SIGTERM', "worker_number" => worker_number)
|
89
|
+
Process.kill("SIGKILL", Process.pid)
|
90
|
+
end
|
91
|
+
trap("SIGINT") do
|
92
|
+
channel.write("command" => "error", "process" => "trap", "text" => 'Received SIGINT', "worker_number" => worker_number)
|
93
|
+
Process.kill("SIGKILL", Process.pid)
|
94
|
+
end
|
95
|
+
|
96
|
+
debug "Started, using TEST_ENV_NUMBER #{ENV['TEST_ENV_NUMBER']}"
|
97
|
+
connect_to_database
|
98
|
+
reset_cache
|
99
|
+
|
100
|
+
preload_framework
|
101
|
+
|
102
|
+
# Loop until our runner passes us a message from the master to tells us we're finished.
|
103
|
+
loop do
|
104
|
+
debug "Announcing availability"
|
105
|
+
channel.write("command" => "ready", "framework" => self.class.framework_name, "worker_number" => worker_number)
|
106
|
+
debug "Waiting for next job"
|
107
|
+
data = channel.read
|
108
|
+
if data.nil? || data["command"] == "close"
|
109
|
+
debug "Channel closed, exiting"
|
110
|
+
exit
|
111
|
+
elsif data['command'] == "process"
|
112
|
+
filename = data["filename"].chomp
|
113
|
+
process_file(filename)
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
79
117
|
|
80
|
-
|
118
|
+
def preload_framework
|
119
|
+
debug "running empty spec/feature to make framework run its initialisation"
|
120
|
+
file = Tempfile.new("nitra")
|
81
121
|
begin
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
122
|
+
load_environment
|
123
|
+
file.write(minimal_file)
|
124
|
+
file.close
|
125
|
+
|
126
|
+
output = Nitra::Utils.capture_output do
|
127
|
+
run_file(file.path, true)
|
128
|
+
end
|
129
|
+
|
130
|
+
channel.write("command" => "stdout", "process" => "init framework", "text" => output, "worker_number" => worker_number) unless output.empty?
|
131
|
+
ensure
|
132
|
+
file.close unless file.closed?
|
133
|
+
file.unlink
|
134
|
+
io.string = ""
|
86
135
|
end
|
136
|
+
clean_up
|
137
|
+
end
|
87
138
|
|
88
|
-
|
139
|
+
def connect_to_database
|
140
|
+
if defined?(Rails)
|
141
|
+
Nitra::RailsTooling.connect_to_database
|
142
|
+
debug("Connected to database #{ActiveRecord::Base.connection.current_database}")
|
89
143
|
end
|
144
|
+
end
|
145
|
+
|
146
|
+
def reset_cache
|
147
|
+
Nitra::RailsTooling.reset_cache if defined?(Rails)
|
148
|
+
end
|
149
|
+
|
150
|
+
##
|
151
|
+
# Process the file, forking before hand.
|
152
|
+
#
|
153
|
+
# There's two sets of data we're interested in, the output from the test framework, and any other output.
|
154
|
+
# 1) We capture the framework's output in the @io object and send that up to the runner in a results message.
|
155
|
+
# This happens in the run_x_file methods.
|
156
|
+
# 2) Anything else we capture off the stdout/stderr using the pipe and fire off in the stdout message.
|
157
|
+
#
|
158
|
+
def process_file(filename)
|
159
|
+
debug "Starting to process #{filename}"
|
160
|
+
start_time = Time.now
|
90
161
|
|
91
|
-
if configuration.fork_for_each_file
|
92
162
|
rd, wr = IO.pipe
|
93
|
-
|
94
|
-
|
163
|
+
@forked_worker_pid = fork do
|
164
|
+
trap('USR1') { exit! } # at_exit hooks will be run in the parent.
|
95
165
|
$stdout.reopen(wr)
|
96
166
|
$stderr.reopen(wr)
|
97
|
-
|
167
|
+
rd.close
|
168
|
+
$0 = filename
|
169
|
+
run_file(filename)
|
170
|
+
wr.close
|
171
|
+
exit! # at_exit hooks will be run in the parent.
|
98
172
|
end
|
99
173
|
wr.close
|
100
|
-
|
174
|
+
output = ""
|
101
175
|
loop do
|
102
176
|
IO.select([rd])
|
103
177
|
text = rd.read
|
104
178
|
break if text.nil? || text.length.zero?
|
105
|
-
|
179
|
+
output.concat text
|
106
180
|
end
|
107
181
|
rd.close
|
108
|
-
Process.wait(
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
182
|
+
Process.wait(@forked_worker_pid) if @forked_worker_pid
|
183
|
+
|
184
|
+
@forked_worker_pid = nil
|
185
|
+
|
186
|
+
end_time = Time.now
|
187
|
+
channel.write("command" => "stdout", "process" => "test framework", "filename" => filename, "text" => output, "worker_number" => worker_number) unless output.empty?
|
188
|
+
debug "#{filename} processed in #{'%0.2f' % (end_time - start_time)}s"
|
115
189
|
end
|
116
|
-
channel.write("command" => "stdout", "process" => "rspec", "filename" => filename, "text" => stdout_buffer) unless stdout_buffer.empty?
|
117
190
|
|
118
|
-
debug "#{filename} processed"
|
119
|
-
end
|
120
|
-
end
|
121
191
|
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
192
|
+
##
|
193
|
+
# Interrupts the forked worker cleanly and exits
|
194
|
+
#
|
195
|
+
def interrupt_forked_worker_and_exit
|
196
|
+
Process.kill('USR1', @forked_worker_pid) if @forked_worker_pid
|
197
|
+
Process.waitall
|
198
|
+
exit
|
199
|
+
end
|
200
|
+
|
201
|
+
##
|
202
|
+
# Sends debug data up to the runner.
|
203
|
+
#
|
204
|
+
def debug(*text)
|
205
|
+
if configuration.debug
|
206
|
+
channel.write("command" => "debug", "text" => "worker #{runner_id}.#{worker_number}: #{text.join}", "worker_number" => worker_number)
|
207
|
+
end
|
208
|
+
end
|
209
|
+
end
|
127
210
|
end
|
128
211
|
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
module Nitra::Workers
|
2
|
+
class Cucumber < Worker
|
3
|
+
def self.files
|
4
|
+
Dir["features/**/*.feature"].sort_by {|f| File.size(f)}.reverse
|
5
|
+
end
|
6
|
+
|
7
|
+
def self.filename_match?(filename)
|
8
|
+
filename =~ /\.feature/
|
9
|
+
end
|
10
|
+
|
11
|
+
def initialize(runner_id, worker_number, configuration)
|
12
|
+
super(runner_id, worker_number, configuration)
|
13
|
+
end
|
14
|
+
|
15
|
+
def load_environment
|
16
|
+
require 'cucumber'
|
17
|
+
require 'nitra/ext/cucumber'
|
18
|
+
end
|
19
|
+
|
20
|
+
def minimal_file
|
21
|
+
<<-EOS
|
22
|
+
Feature: cucumber preloading
|
23
|
+
Scenario: a fake scenario
|
24
|
+
Given every step is unimplemented
|
25
|
+
When we run this file
|
26
|
+
Then Cucumber will load it's environment
|
27
|
+
EOS
|
28
|
+
end
|
29
|
+
|
30
|
+
##
|
31
|
+
# Run a Cucumber file and write the results back to the runner.
|
32
|
+
#
|
33
|
+
# Doesn't write back to the runner if we mark the run as preloading.
|
34
|
+
#
|
35
|
+
def run_file(filename, preloading = false)
|
36
|
+
@cuke_runtime ||= ::Cucumber::ResetableRuntime.new # This runtime gets reused, this is important as it's the part that loads the steps...
|
37
|
+
begin
|
38
|
+
result = 1
|
39
|
+
cuke_config = ::Cucumber::Cli::Configuration.new(io, io)
|
40
|
+
cuke_config.parse!(["--no-color", "--require", "features", filename])
|
41
|
+
@cuke_runtime.configure(cuke_config)
|
42
|
+
@cuke_runtime.run!
|
43
|
+
result = 0 unless @cuke_runtime.results.failure?
|
44
|
+
rescue LoadError => e
|
45
|
+
io << "\nCould not load file #{filename}: #{e.message}\n\n"
|
46
|
+
rescue Exception => e
|
47
|
+
io << "Exception when running #{filename}: #{e.message}"
|
48
|
+
io << e.backtrace[0..7].join("\n")
|
49
|
+
end
|
50
|
+
|
51
|
+
if preloading
|
52
|
+
puts(io.string)
|
53
|
+
else
|
54
|
+
channel.write("command" => "result", "filename" => filename, "return_code" => result.to_i, "text" => io.string, "worker_number" => worker_number)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def clean_up
|
59
|
+
@cuke_runtime.reset
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
module Nitra::Workers
|
2
|
+
class Rspec < Worker
|
3
|
+
def self.files
|
4
|
+
Dir["spec/**/*_spec.rb"].sort_by {|f| File.size(f)}.reverse
|
5
|
+
end
|
6
|
+
|
7
|
+
def self.filename_match?(filename)
|
8
|
+
filename =~ /_spec\.rb/
|
9
|
+
end
|
10
|
+
|
11
|
+
def initialize(runner_id, worker_number, configuration)
|
12
|
+
super(runner_id, worker_number, configuration)
|
13
|
+
end
|
14
|
+
|
15
|
+
def load_environment
|
16
|
+
require 'rspec'
|
17
|
+
RSpec::Core::Runner.disable_autorun!
|
18
|
+
end
|
19
|
+
|
20
|
+
def minimal_file
|
21
|
+
<<-EOS
|
22
|
+
require 'spec_helper'
|
23
|
+
describe('nitra preloading') do
|
24
|
+
it('preloads the fixtures') do
|
25
|
+
expect(1).to eq(1)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
EOS
|
29
|
+
end
|
30
|
+
|
31
|
+
##
|
32
|
+
# Run an rspec file and write the results back to the runner.
|
33
|
+
#
|
34
|
+
# Doesn't write back to the runner if we mark the run as preloading.
|
35
|
+
#
|
36
|
+
def run_file(filename, preloading = false)
|
37
|
+
begin
|
38
|
+
result = RSpec::Core::CommandLine.new(["-f", "p", filename]).run(io, io)
|
39
|
+
rescue LoadError => e
|
40
|
+
io << "\nCould not load file #{filename}: #{e.message}\n\n"
|
41
|
+
result = 1
|
42
|
+
rescue Exception => e
|
43
|
+
io << "Exception when running #{filename}: #{e.message}"
|
44
|
+
io << e.backtrace[0..7].join("\n")
|
45
|
+
result = 1
|
46
|
+
end
|
47
|
+
|
48
|
+
if preloading
|
49
|
+
puts io.string
|
50
|
+
else
|
51
|
+
channel.write("command" => "result", "filename" => filename, "return_code" => result.to_i, "text" => io.string, "worker_number" => worker_number)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def clean_up
|
56
|
+
# Rspec.reset in 2.6 didn't destroy your rspec_rails fixture loading, we can't use it anymore for it's intended purpose.
|
57
|
+
# This means our world object will be slightly polluted by the preload_framework code, but that's a small price to pay
|
58
|
+
# to upgrade.
|
59
|
+
#
|
60
|
+
# RSpec.reset
|
61
|
+
#
|
62
|
+
RSpec.instance_variable_set(:@world, nil)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
data/lib/nitra.rb
CHANGED
@@ -2,12 +2,16 @@ module Nitra
|
|
2
2
|
end
|
3
3
|
|
4
4
|
require 'nitra/channel'
|
5
|
-
require 'nitra/client'
|
6
5
|
require 'nitra/command_line'
|
7
6
|
require 'nitra/configuration'
|
8
7
|
require 'nitra/master'
|
8
|
+
require 'nitra/formatter'
|
9
9
|
require 'nitra/progress'
|
10
10
|
require 'nitra/runner'
|
11
|
+
require 'nitra/tasks'
|
11
12
|
require 'nitra/slave'
|
12
13
|
require 'nitra/utils'
|
13
14
|
require 'nitra/worker'
|
15
|
+
require 'nitra/workers/cucumber'
|
16
|
+
require 'nitra/workers/rspec'
|
17
|
+
require 'nitra/rails_tooling'
|
@@ -0,0 +1,44 @@
|
|
1
|
+
gem 'minitest'
|
2
|
+
require 'minitest/spec'
|
3
|
+
require 'minitest/autorun'
|
4
|
+
require_relative '../../lib/nitra/channel'
|
5
|
+
|
6
|
+
describe Nitra::Channel do
|
7
|
+
describe ".pipe" do
|
8
|
+
it "creates a pipe pair" do
|
9
|
+
server, client = Nitra::Channel.pipe
|
10
|
+
server.must_be_instance_of Nitra::Channel
|
11
|
+
client.must_be_instance_of Nitra::Channel
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
describe "#close" do
|
16
|
+
it "closes channels" do
|
17
|
+
server, client = Nitra::Channel.pipe
|
18
|
+
server.close
|
19
|
+
server.rd.must_be :closed?
|
20
|
+
server.wr.must_be :closed?
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
describe "#write" do
|
25
|
+
it "writes a NITRA encoded yaml message" do
|
26
|
+
server, client = Nitra::Channel.pipe
|
27
|
+
server.write(['encode all the things'])
|
28
|
+
client.read.must_equal ['encode all the things']
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
describe "#read" do
|
33
|
+
it "reads NITRA encoded yaml messages" do
|
34
|
+
server, client = Nitra::Channel.pipe
|
35
|
+
client.write(['encode all the things'])
|
36
|
+
server.read.must_equal ['encode all the things']
|
37
|
+
end
|
38
|
+
it "rejects bad messages" do
|
39
|
+
server, client = Nitra::Channel.pipe
|
40
|
+
client.wr.write("not a nitra packet\n")
|
41
|
+
proc {server.read}.must_raise Nitra::Channel::ProtocolInvalidError
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,133 @@
|
|
1
|
+
gem 'minitest'
|
2
|
+
require 'minitest/spec'
|
3
|
+
require 'minitest/autorun'
|
4
|
+
require_relative '../../lib/nitra/command_line'
|
5
|
+
|
6
|
+
describe Nitra::CommandLine do
|
7
|
+
|
8
|
+
let(:config){ m = MiniTest::Mock.new; m.expect(:set_default_framework, []); m}
|
9
|
+
|
10
|
+
describe "option parsing" do
|
11
|
+
describe "-c" do
|
12
|
+
it "sets process count" do
|
13
|
+
config.expect(:set_process_count, nil, [2])
|
14
|
+
Nitra::CommandLine.new(config, ['-c','2'])
|
15
|
+
config.verify
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
describe "--cucumber" do
|
20
|
+
it "adds cucumber to framework" do
|
21
|
+
config.expect(:add_framework, nil, ['cucumber'])
|
22
|
+
Nitra::CommandLine.new(config, ['--cucumber'])
|
23
|
+
config.verify
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
describe "--debug" do
|
28
|
+
it "adds debug flag" do
|
29
|
+
config.expect(:debug=, nil, [true])
|
30
|
+
Nitra::CommandLine.new(config, ['--debug'])
|
31
|
+
config.verify
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
describe "-p" do
|
36
|
+
it "adds print failure flag" do
|
37
|
+
config.expect(:print_failures=, nil, [true])
|
38
|
+
Nitra::CommandLine.new(config, ['-p'])
|
39
|
+
config.verify
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
describe "-q" do
|
44
|
+
it "adds quiet flag" do
|
45
|
+
config.expect(:quiet=, nil, [true])
|
46
|
+
Nitra::CommandLine.new(config, ['-q'])
|
47
|
+
config.verify
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
describe "-e" do
|
52
|
+
it "sets the rails environment" do
|
53
|
+
config.expect(:environment=, nil, ["test"])
|
54
|
+
Nitra::CommandLine.new(config, ["-e", "test"])
|
55
|
+
config.verify
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
describe "--rake-after-runner" do
|
60
|
+
it "adds rake tasks to run after runner finishes" do
|
61
|
+
config.expect(:add_rake_task, nil, [:after_runner, ['list:of','rake:tasks']])
|
62
|
+
Nitra::CommandLine.new(config, ['--rake-after-runner', 'list:of,rake:tasks'])
|
63
|
+
config.verify
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
describe "--rake-before-runner" do
|
68
|
+
it "adds rake tasks to run before runner starts" do
|
69
|
+
config.expect(:add_rake_task, nil, [:before_runner, ['list:of','rake:tasks']])
|
70
|
+
Nitra::CommandLine.new(config, ['--rake-before-runner', 'list:of,rake:tasks'])
|
71
|
+
config.verify
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
describe "--rake-before-worker" do
|
76
|
+
it "adds rake tasks to run before worker starts" do
|
77
|
+
config.expect(:add_rake_task, nil, [:before_worker, ['list:of','rake:tasks']])
|
78
|
+
Nitra::CommandLine.new(config, ['--rake-before-worker', 'list:of,rake:tasks'])
|
79
|
+
config.verify
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
describe "-r" do
|
84
|
+
it "adds the db:reset rake task to run before worker starts" do
|
85
|
+
config.expect(:add_rake_task, nil, [:before_worker, ['db:reset']])
|
86
|
+
Nitra::CommandLine.new(config, ['-r'])
|
87
|
+
config.verify
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
describe "--reset" do
|
92
|
+
it "adds the db:reset rake task to run before worker starts" do
|
93
|
+
config.expect(:add_rake_task, nil, [:before_worker, ['db:reset']])
|
94
|
+
Nitra::CommandLine.new(config, ['--reset'])
|
95
|
+
config.verify
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
describe "--rspec" do
|
100
|
+
it "adds rspec to framework" do
|
101
|
+
config.expect(:add_framework, nil, ['rspec'])
|
102
|
+
Nitra::CommandLine.new(config, ['--rspec'])
|
103
|
+
config.verify
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
describe "--slave-mode" do
|
108
|
+
it "turns on slave mode" do
|
109
|
+
config.expect(:slave_mode=, nil, [true])
|
110
|
+
Nitra::CommandLine.new(config, ['--slave-mode'])
|
111
|
+
config.verify
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
describe "--slave" do
|
116
|
+
it "adds a command that will be run later as a slave" do
|
117
|
+
config.expect(:add_slave, nil, ['the command to run'])
|
118
|
+
Nitra::CommandLine.new(config, ['--slave', 'the command to run'])
|
119
|
+
config.verify
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
describe "file lists" do
|
125
|
+
it "parses out options and leavs only files in list" do
|
126
|
+
argv = ['--slave','the slave command','this_test_file_spec.rb']
|
127
|
+
config.expect(:add_slave, nil, ['the slave command'])
|
128
|
+
Nitra::CommandLine.new(config, argv)
|
129
|
+
config.verify
|
130
|
+
argv.must_equal ['this_test_file_spec.rb']
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
gem 'minitest'
|
2
|
+
require 'minitest/spec'
|
3
|
+
require 'minitest/autorun'
|
4
|
+
require_relative '../../lib/nitra/configuration'
|
5
|
+
|
6
|
+
describe Nitra::Configuration do
|
7
|
+
let(:config){ Nitra::Configuration.new }
|
8
|
+
it "has default values" do
|
9
|
+
config.slaves.must_equal []
|
10
|
+
config.frameworks.must_equal []
|
11
|
+
config.rake_tasks.must_equal Hash.new;
|
12
|
+
config.process_count.must_equal Nitra::Utils.processor_count
|
13
|
+
end
|
14
|
+
|
15
|
+
describe "#add_framework" do
|
16
|
+
it "adds a framework to frameworks" do
|
17
|
+
config.add_framework("cucumber")
|
18
|
+
config.add_framework("rspec")
|
19
|
+
config.frameworks.must_equal ["cucumber", "rspec"]
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
describe "#add_rake_task" do
|
24
|
+
it "adds a rake task to the rake task hash" do
|
25
|
+
config.add_rake_task(:task_name, ['list','of','tasks'])
|
26
|
+
config.rake_tasks.must_equal({:task_name => ['list','of','tasks']})
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
describe "#add_slave" do
|
31
|
+
it "adds a slave command to the slave array" do
|
32
|
+
command = 'command to run to get a nitra slave'
|
33
|
+
config.add_slave(command)
|
34
|
+
config.slaves[0].must_equal({:command => command, :cpus => nil})
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
describe "#set_default_framework" do
|
39
|
+
it "sets the default framework to the first one in the list" do
|
40
|
+
config.add_framework 'rspec'
|
41
|
+
config.add_framework 'cucumber'
|
42
|
+
config.set_default_framework
|
43
|
+
config.framework.must_equal 'rspec'
|
44
|
+
end
|
45
|
+
|
46
|
+
it "does nothing when there's no frameworks" do
|
47
|
+
config.set_default_framework
|
48
|
+
config.framework.must_be_nil
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
# We want slaves to inherit all config except for process count.
|
53
|
+
# This needs refactoring to not be so frickin retardedk.
|
54
|
+
it "does interesting things with slave process configs" do
|
55
|
+
config.process_count.must_equal Nitra::Utils.processor_count
|
56
|
+
config.slaves << {}
|
57
|
+
config.set_process_count 1000
|
58
|
+
config.slaves.first[:cpus].must_equal 1000
|
59
|
+
end
|
60
|
+
end
|