testbot 0.6.2 → 0.6.3
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +7 -0
- data/README.markdown +2 -1
- data/lib/generators/testbot/templates/testbot.yml.erb +3 -0
- data/lib/requester/requester.rb +33 -13
- data/lib/runner/job.rb +18 -7
- data/lib/runner/safe_result_text.rb +29 -0
- data/lib/server/job.rb +22 -4
- data/lib/server/server.rb +1 -1
- data/lib/shared/version.rb +1 -1
- data/test/requester/requester_test.rb +24 -15
- data/test/runner/job_test.rb +6 -6
- data/test/runner/safe_result_text_test.rb +20 -0
- data/test/server/server_test.rb +23 -8
- metadata +6 -4
data/CHANGELOG
CHANGED
@@ -1,3 +1,10 @@
|
|
1
|
+
0.6.3
|
2
|
+
|
3
|
+
Results are now shown as they happen. It takes care not to break escape codes used for
|
4
|
+
coloring output (only tested with rspec, add a script/spec file containing "rspec --tty $@").
|
5
|
+
|
6
|
+
Also, you can add a "logging: true" option to testbot.yml to see when files are synced, etc.
|
7
|
+
|
1
8
|
0.6.2
|
2
9
|
|
3
10
|
Fixed "invalid byte sequence in UTF-8" errors cased by test output in some cases.
|
data/README.markdown
CHANGED
@@ -64,7 +64,7 @@ Using testbot with Rails 2:
|
|
64
64
|
|
65
65
|
# Add testbot to your Gemfile if you use bundler. You also need the plugin because
|
66
66
|
# Rails 2 does not load raketasks from gems.
|
67
|
-
ruby script/plugin install git://github.com/joakimk/testbot.git -r 'refs/tags/v0.6.
|
67
|
+
ruby script/plugin install git://github.com/joakimk/testbot.git -r 'refs/tags/v0.6.3'
|
68
68
|
script/generate testbot --connect 192.168.0.100
|
69
69
|
|
70
70
|
rake testbot:spec (or :rspec, :test, :features)
|
@@ -108,6 +108,7 @@ Features
|
|
108
108
|
* You can access your testbot network through SSH by using the built in SSH tunneling code.
|
109
109
|
* You can use the same testbot network with multiple projects.
|
110
110
|
* You can abort a test run with ctrl+c and all remote processes will be stopped.
|
111
|
+
* It shows you the output as it happens.
|
111
112
|
* Testbot is continuously tested for compatibility with Ruby 1.8.7 and 1.9.2.
|
112
113
|
|
113
114
|
Contributing to testbot
|
data/lib/requester/requester.rb
CHANGED
@@ -30,36 +30,45 @@ module Testbot::Requester
|
|
30
30
|
end
|
31
31
|
|
32
32
|
def run_tests(adapter, dir)
|
33
|
-
puts if config.simple_output
|
33
|
+
puts if config.simple_output || config.logging
|
34
34
|
|
35
35
|
if config.ssh_tunnel
|
36
|
-
|
36
|
+
log "Setting up ssh tunnel" do
|
37
|
+
SSHTunnel.new(config.server_host, config.server_user, adapter.requester_port).open
|
38
|
+
end
|
37
39
|
server_uri = "http://127.0.0.1:#{adapter.requester_port}"
|
38
40
|
else
|
39
41
|
server_uri = "http://#{config.server_host}:#{Testbot::SERVER_PORT}"
|
40
42
|
end
|
41
43
|
|
42
|
-
|
43
|
-
|
44
|
+
log "Syncing files" do
|
45
|
+
rsync_ignores = config.rsync_ignores.to_s.split.map { |pattern| "--exclude='#{pattern}'" }.join(' ')
|
46
|
+
system "rsync -az --delete -e ssh #{rsync_ignores} . #{rsync_uri}"
|
47
|
+
end
|
44
48
|
|
45
49
|
files = adapter.test_files(dir)
|
46
50
|
sizes = adapter.get_sizes(files)
|
47
51
|
|
48
|
-
build_id =
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
52
|
+
build_id = nil
|
53
|
+
log "Requesting run" do
|
54
|
+
build_id = HTTParty.post("#{server_uri}/builds", :body => { :root => root,
|
55
|
+
:type => adapter.type.to_s,
|
56
|
+
:project => config.project,
|
57
|
+
:available_runner_usage => config.available_runner_usage,
|
58
|
+
:files => files.join(' '),
|
59
|
+
:sizes => sizes.join(' '),
|
60
|
+
:jruby => jruby? })
|
61
|
+
end
|
55
62
|
|
56
63
|
trap("SIGINT") { HTTParty.delete("#{server_uri}/builds/#{build_id}"); return false }
|
57
64
|
|
65
|
+
puts if config.logging
|
66
|
+
|
58
67
|
last_results_size = 0
|
59
68
|
success = true
|
60
69
|
error_count = 0
|
61
70
|
while true
|
62
|
-
sleep
|
71
|
+
sleep 0.5
|
63
72
|
|
64
73
|
begin
|
65
74
|
@build = HTTParty.get("#{server_uri}/builds/#{build_id}", :format => :json)
|
@@ -79,7 +88,8 @@ module Testbot::Requester
|
|
79
88
|
print results.gsub(/[^\.F]|Finished/, '')
|
80
89
|
STDOUT.flush
|
81
90
|
else
|
82
|
-
|
91
|
+
print results
|
92
|
+
STDOUT.flush
|
83
93
|
end
|
84
94
|
end
|
85
95
|
|
@@ -103,6 +113,16 @@ module Testbot::Requester
|
|
103
113
|
|
104
114
|
private
|
105
115
|
|
116
|
+
def log(text)
|
117
|
+
if config.logging
|
118
|
+
print "#{text}... "; STDOUT.flush
|
119
|
+
yield
|
120
|
+
puts "done"
|
121
|
+
else
|
122
|
+
yield
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
106
126
|
def root
|
107
127
|
if localhost?
|
108
128
|
config.rsync_path
|
data/lib/runner/job.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
require File.expand_path(File.join(File.dirname(__FILE__), 'runner.rb'))
|
2
|
-
require '
|
2
|
+
require File.expand_path(File.join(File.dirname(__FILE__), 'safe_result_text.rb'))
|
3
3
|
|
4
4
|
module Testbot::Runner
|
5
5
|
class Job
|
@@ -26,7 +26,7 @@ module Testbot::Runner
|
|
26
26
|
result += run_and_return_result("#{base_environment} #{adapter.command(@project, ruby_cmd, @files)}")
|
27
27
|
end
|
28
28
|
|
29
|
-
Server.put("/jobs/#{@id}", :body => { :result =>
|
29
|
+
Server.put("/jobs/#{@id}", :body => { :result => SafeResultText.clean(result), :status => status, :time => run_time })
|
30
30
|
puts "Job #{@id} finished."
|
31
31
|
end
|
32
32
|
|
@@ -40,10 +40,8 @@ module Testbot::Runner
|
|
40
40
|
|
41
41
|
private
|
42
42
|
|
43
|
-
def
|
44
|
-
|
45
|
-
ic = Iconv.new('UTF-8//IGNORE', 'UTF-8')
|
46
|
-
ic.iconv(text + ' ')[0..-2]
|
43
|
+
def status
|
44
|
+
success? ? "successful" : "failed"
|
47
45
|
end
|
48
46
|
|
49
47
|
def measure_run_time
|
@@ -52,9 +50,22 @@ module Testbot::Runner
|
|
52
50
|
(Time.now - start_time) * 100
|
53
51
|
end
|
54
52
|
|
53
|
+
def post_results(output)
|
54
|
+
Server.put("/jobs/#{@id}", :body => { :result => SafeResultText.clean(output), :status => "building" })
|
55
|
+
end
|
56
|
+
|
55
57
|
def run_and_return_result(command)
|
56
58
|
@test_process = open("|#{command} 2>&1", 'r')
|
57
|
-
output =
|
59
|
+
output = ""
|
60
|
+
t = Time.now
|
61
|
+
while char = @test_process.getc
|
62
|
+
char = (char.is_a?(Fixnum) ? char.chr : char) # 1.8 <-> 1.9
|
63
|
+
output << char
|
64
|
+
if Time.now - t > 0.5
|
65
|
+
post_results(output)
|
66
|
+
t = Time.now
|
67
|
+
end
|
68
|
+
end
|
58
69
|
@test_process.close
|
59
70
|
output
|
60
71
|
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'iconv'
|
2
|
+
|
3
|
+
module Testbot::Runner
|
4
|
+
class SafeResultText
|
5
|
+
def self.clean(text)
|
6
|
+
clean_escape_sequences(strip_invalid_utf8(text))
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.strip_invalid_utf8(text)
|
10
|
+
# http://po-ru.com/diary/fixing-invalid-utf-8-in-ruby-revisited/
|
11
|
+
ic = Iconv.new('UTF-8//IGNORE', 'UTF-8')
|
12
|
+
ic.iconv(text + ' ')[0..-2]
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.clean_escape_sequences(text)
|
16
|
+
tail_marker = "^[[0m"
|
17
|
+
tail = text.rindex(tail_marker) && text[text.rindex(tail_marker)+tail_marker.length..-1]
|
18
|
+
if !tail
|
19
|
+
text
|
20
|
+
elsif tail.include?("^[[") && !tail.include?("m")
|
21
|
+
text[0..text.rindex(tail_marker) + tail_marker.length - 1]
|
22
|
+
elsif text.scan(/\[.*?m/).last != tail_marker
|
23
|
+
text[0..text.rindex(tail_marker) + tail_marker.length - 1]
|
24
|
+
else
|
25
|
+
text
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
data/lib/server/job.rb
CHANGED
@@ -5,11 +5,11 @@ module Testbot::Server
|
|
5
5
|
def update(hash)
|
6
6
|
super(hash)
|
7
7
|
if self.build
|
8
|
-
done =
|
9
|
-
|
10
|
-
|
8
|
+
self.done = done?
|
9
|
+
done = !Job.all.find { |j| !j.done && j.build == self.build }
|
10
|
+
self.build.update(:results => build_results(build), :done => done)
|
11
11
|
|
12
|
-
build_broken_by_job = (self.
|
12
|
+
build_broken_by_job = (self.status == "failed" && build.success)
|
13
13
|
self.build.update(:success => false) if build_broken_by_job
|
14
14
|
end
|
15
15
|
end
|
@@ -23,6 +23,24 @@ module Testbot::Server
|
|
23
23
|
|
24
24
|
private
|
25
25
|
|
26
|
+
def build_results(build)
|
27
|
+
self.last_result_position ||= 0
|
28
|
+
new_results = self.result.to_s[self.last_result_position..-1]
|
29
|
+
self.last_result_position = self.result.to_s.size
|
30
|
+
|
31
|
+
# Don't know why this is needed as the job should cleanup
|
32
|
+
# escape sequences.
|
33
|
+
if new_results[0,4] == '[32m'
|
34
|
+
new_results = new_results[4..-1]
|
35
|
+
end
|
36
|
+
|
37
|
+
build.results.to_s + new_results
|
38
|
+
end
|
39
|
+
|
40
|
+
def done?
|
41
|
+
self.status == "successful" || self.status == "failed"
|
42
|
+
end
|
43
|
+
|
26
44
|
def self.next_job(build_id, no_jruby)
|
27
45
|
release_jobs_taken_by_missing_runners!
|
28
46
|
jobs = Job.all.find_all { |j|
|
data/lib/server/server.rb
CHANGED
@@ -48,7 +48,7 @@ module Testbot::Server
|
|
48
48
|
end
|
49
49
|
|
50
50
|
put '/jobs/:id' do
|
51
|
-
Job.find(params[:id]).update(:result => params[:result], :
|
51
|
+
Job.find(params[:id]).update(:result => params[:result], :status => params[:status]); nil
|
52
52
|
end
|
53
53
|
|
54
54
|
get '/runners/ping' do
|
data/lib/shared/version.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
module Testbot
|
2
2
|
# Don't forget to update readme and changelog
|
3
3
|
def self.version
|
4
|
-
version = "0.6.
|
4
|
+
version = "0.6.3"
|
5
5
|
dev_version_file = File.join(File.dirname(__FILE__), '..', '..', 'DEV_VERSION')
|
6
6
|
if File.exists?(dev_version_file)
|
7
7
|
version += File.read(dev_version_file)
|
@@ -19,6 +19,7 @@ module Testbot::Requester
|
|
19
19
|
flexmock(requester).should_receive(:find_tests).and_return([])
|
20
20
|
flexmock(HTTParty).should_receive(:post).and_return('5')
|
21
21
|
flexmock(requester).should_receive(:sleep).once
|
22
|
+
flexmock(requester).should_receive(:print).once
|
22
23
|
flexmock(requester).should_receive(:puts).once
|
23
24
|
flexmock(requester).should_receive(:system)
|
24
25
|
flexmock(HTTParty).should_receive(:get).once.with("http://192.168.1.100:#{Testbot::SERVER_PORT}/builds/5",
|
@@ -100,6 +101,7 @@ module Testbot::Requester
|
|
100
101
|
|
101
102
|
flexmock(HTTParty).should_receive(:get).and_return({ "done" => true, 'results' => '', "success" => true })
|
102
103
|
flexmock(requester).should_receive(:sleep)
|
104
|
+
flexmock(requester).should_receive(:print)
|
103
105
|
flexmock(requester).should_receive(:puts)
|
104
106
|
flexmock(requester).should_receive(:system)
|
105
107
|
|
@@ -119,9 +121,9 @@ module Testbot::Requester
|
|
119
121
|
{ "done" => true, "results" => "job 2 done: ....job 1 done: ...." })
|
120
122
|
mock_file_sizes
|
121
123
|
|
122
|
-
flexmock(requester).should_receive(:sleep).times(2).with(
|
123
|
-
flexmock(requester).should_receive(:
|
124
|
-
flexmock(requester).should_receive(:
|
124
|
+
flexmock(requester).should_receive(:sleep).times(2).with(0.5)
|
125
|
+
flexmock(requester).should_receive(:print).once.with("job 2 done: ....")
|
126
|
+
flexmock(requester).should_receive(:print).once.with("job 1 done: ....")
|
125
127
|
flexmock(requester).should_receive(:puts).once.with("\nformatted result")
|
126
128
|
|
127
129
|
flexmock(RspecAdapter).should_receive(:sum_results).with("job 2 done: ....job 1 done: ....").and_return("formatted result")
|
@@ -141,9 +143,9 @@ module Testbot::Requester
|
|
141
143
|
{ "done" => true, "results" => "job 2 done: ....job 1 done: ...." })
|
142
144
|
mock_file_sizes
|
143
145
|
|
144
|
-
flexmock(requester).should_receive(:sleep).times(2).with(
|
145
|
-
flexmock(requester).should_receive(:
|
146
|
-
flexmock(requester).should_receive(:
|
146
|
+
flexmock(requester).should_receive(:sleep).times(2).with(0.5)
|
147
|
+
flexmock(requester).should_receive(:print).once.with("job 2 done: ....")
|
148
|
+
flexmock(requester).should_receive(:print).once.with("job 1 done: ....")
|
147
149
|
flexmock(requester).should_receive(:puts).once.with("\n\033[32m0 examples, 0 failures\033[0m")
|
148
150
|
|
149
151
|
requester.run_tests(RspecAdapter, 'spec')
|
@@ -160,8 +162,8 @@ module Testbot::Requester
|
|
160
162
|
flexmock(HTTParty).should_receive(:get).once.with("http://192.168.1.100:#{Testbot::SERVER_PORT}/builds/5",
|
161
163
|
:format => :json).and_return({ "success" => false, "done" => true, "results" => "job 2 done: ....job 1 done: ...." })
|
162
164
|
|
163
|
-
flexmock(requester).should_receive(:sleep).once.with(
|
164
|
-
flexmock(requester).should_receive(:
|
165
|
+
flexmock(requester).should_receive(:sleep).once.with(0.5)
|
166
|
+
flexmock(requester).should_receive(:print).once.with("job 2 done: ....job 1 done: ....")
|
165
167
|
flexmock(requester).should_receive(:puts).once.with("\n\033[32m0 examples, 0 failures\033[0m")
|
166
168
|
mock_file_sizes
|
167
169
|
|
@@ -180,8 +182,8 @@ module Testbot::Requester
|
|
180
182
|
:format => :json).and_return({ "done" => false, "results" => "" },
|
181
183
|
{ "done" => true, "results" => "job 2 done: ....job 1 done: ...." })
|
182
184
|
|
183
|
-
flexmock(requester).should_receive(:sleep).times(2).with(
|
184
|
-
flexmock(requester).should_receive(:
|
185
|
+
flexmock(requester).should_receive(:sleep).times(2).with(0.5)
|
186
|
+
flexmock(requester).should_receive(:print).once.with("job 2 done: ....job 1 done: ....")
|
185
187
|
flexmock(requester).should_receive(:puts).once.with("\n\033[32m0 examples, 0 failures\033[0m")
|
186
188
|
mock_file_sizes
|
187
189
|
|
@@ -196,6 +198,7 @@ module Testbot::Requester
|
|
196
198
|
|
197
199
|
flexmock(HTTParty).should_receive(:post).and_return('5')
|
198
200
|
flexmock(requester).should_receive(:sleep).once
|
201
|
+
flexmock(requester).should_receive(:print)
|
199
202
|
flexmock(requester).should_receive(:puts)
|
200
203
|
flexmock(HTTParty).should_receive(:get).once.with("http://192.168.1.100:#{Testbot::SERVER_PORT}/builds/5",
|
201
204
|
:format => :json).and_return({ "done" => true, "results" => "" })
|
@@ -219,9 +222,9 @@ module Testbot::Requester
|
|
219
222
|
flexmock(HTTParty).should_receive(:get).times(1).with("http://192.168.1.100:#{Testbot::SERVER_PORT}/builds/5",
|
220
223
|
:format => :json).and_return({ "done" => true, "results" => "job 2 done: ....job 1 done: ...." })
|
221
224
|
|
222
|
-
flexmock(requester).should_receive(:sleep).times(6).with(
|
225
|
+
flexmock(requester).should_receive(:sleep).times(6).with(0.5)
|
223
226
|
flexmock(requester).should_receive(:puts).once.with("Failed to get status: some connection error")
|
224
|
-
flexmock(requester).should_receive(:
|
227
|
+
flexmock(requester).should_receive(:print).once.with("job 2 done: ....job 1 done: ....")
|
225
228
|
flexmock(requester).should_receive(:puts).once.with("\n\033[32m0 examples, 0 failures\033[0m")
|
226
229
|
mock_file_sizes
|
227
230
|
|
@@ -240,8 +243,8 @@ module Testbot::Requester
|
|
240
243
|
:format => :json).and_return(nil,
|
241
244
|
{ "done" => true, "results" => "job 2 done: ....job 1 done: ...." })
|
242
245
|
|
243
|
-
flexmock(requester).should_receive(:sleep).times(2).with(
|
244
|
-
flexmock(requester).should_receive(:
|
246
|
+
flexmock(requester).should_receive(:sleep).times(2).with(0.5)
|
247
|
+
flexmock(requester).should_receive(:print).once.with("job 2 done: ....job 1 done: ....")
|
245
248
|
flexmock(requester).should_receive(:puts).once.with("\n\033[32m0 examples, 0 failures\033[0m")
|
246
249
|
mock_file_sizes
|
247
250
|
|
@@ -260,10 +263,11 @@ module Testbot::Requester
|
|
260
263
|
:format => :json).and_return(nil,
|
261
264
|
{ "done" => true, "results" => "testbot4:\n....\n\nFinished in 84.333 seconds\n\n206 examples, 0 failures, 2 pending; testbot4:\n.F..\n\nFinished in 84.333 seconds\n\n206 examples, 0 failures, 2 pending" })
|
262
265
|
|
263
|
-
flexmock(requester).should_receive(:sleep).times(2).with(
|
266
|
+
flexmock(requester).should_receive(:sleep).times(2).with(0.5)
|
264
267
|
|
265
268
|
# Imperfect match, includes "." in 84.333, but good enough.
|
266
269
|
flexmock(requester).should_receive(:print).once.with("......F...")
|
270
|
+
flexmock(requester).should_receive(:print)
|
267
271
|
flexmock(requester).should_receive(:puts)
|
268
272
|
mock_file_sizes
|
269
273
|
|
@@ -281,6 +285,7 @@ module Testbot::Requester
|
|
281
285
|
flexmock(HTTParty).should_receive(:post).with("http://127.0.0.1:2299/builds", any).and_return('5')
|
282
286
|
flexmock(HTTParty).should_receive(:get).and_return({ "done" => true, "results" => "job 1 done: ...." })
|
283
287
|
flexmock(requester).should_receive(:sleep)
|
288
|
+
flexmock(requester).should_receive(:print)
|
284
289
|
flexmock(requester).should_receive(:puts)
|
285
290
|
mock_file_sizes
|
286
291
|
|
@@ -298,6 +303,7 @@ module Testbot::Requester
|
|
298
303
|
flexmock(HTTParty).should_receive(:post).with("http://127.0.0.1:2299/builds", any).and_return('5')
|
299
304
|
flexmock(HTTParty).should_receive(:get).and_return({ "done" => true, "results" => "job 1 done: ...." })
|
300
305
|
flexmock(requester).should_receive(:sleep)
|
306
|
+
flexmock(requester).should_receive(:print)
|
301
307
|
flexmock(requester).should_receive(:puts)
|
302
308
|
|
303
309
|
flexmock(requester).should_receive('system').with("rsync -az --delete -e ssh . cruise@somewhere:/tmp/testbot/foo")
|
@@ -317,6 +323,7 @@ module Testbot::Requester
|
|
317
323
|
flexmock(HTTParty).should_receive(:post).with("http://127.0.0.1:2230/builds", any).and_return('5')
|
318
324
|
flexmock(HTTParty).should_receive(:get).and_return({ "done" => true, "results" => "job 1 done: ...." })
|
319
325
|
flexmock(requester).should_receive(:sleep)
|
326
|
+
flexmock(requester).should_receive(:print)
|
320
327
|
flexmock(requester).should_receive(:puts)
|
321
328
|
mock_file_sizes
|
322
329
|
|
@@ -334,6 +341,7 @@ module Testbot::Requester
|
|
334
341
|
flexmock(HTTParty).should_receive(:post).with("http://127.0.0.1:2231/builds", any).and_return('5')
|
335
342
|
flexmock(HTTParty).should_receive(:get).and_return({ "done" => true, "results" => "job 1 done: ...." })
|
336
343
|
flexmock(requester).should_receive(:sleep)
|
344
|
+
flexmock(requester).should_receive(:print)
|
337
345
|
flexmock(requester).should_receive(:puts)
|
338
346
|
mock_file_sizes
|
339
347
|
|
@@ -354,6 +362,7 @@ module Testbot::Requester
|
|
354
362
|
flexmock(HTTParty).should_receive(:post).with(any, :body => other_args.merge({ :jruby => true })).and_return('5')
|
355
363
|
flexmock(HTTParty).should_receive(:get).and_return({ "done" => true, "results" => "job 1 done: ...." })
|
356
364
|
flexmock(requester).should_receive(:sleep)
|
365
|
+
flexmock(requester).should_receive(:print)
|
357
366
|
flexmock(requester).should_receive(:puts)
|
358
367
|
mock_file_sizes
|
359
368
|
|
data/test/runner/job_test.rb
CHANGED
@@ -8,11 +8,11 @@ module Testbot::Runner
|
|
8
8
|
|
9
9
|
class JobTest < Test::Unit::TestCase
|
10
10
|
|
11
|
-
def expect_put_with(id, result_text,
|
11
|
+
def expect_put_with(id, result_text, status, time = 0)
|
12
12
|
expected_result = "\n#{`hostname`.chomp}:#{Dir.pwd}\n"
|
13
13
|
expected_result += result_text
|
14
14
|
flexmock(Server).should_receive(:put).once.with("/jobs/#{id}", :body =>
|
15
|
-
{ :result => expected_result, :
|
15
|
+
{ :result => expected_result, :status => status, :time => time })
|
16
16
|
end
|
17
17
|
|
18
18
|
def stub_duration(seconds)
|
@@ -25,7 +25,7 @@ module Testbot::Runner
|
|
25
25
|
flexmock(job).should_receive(:puts)
|
26
26
|
stub_duration(0)
|
27
27
|
|
28
|
-
expect_put_with(10, "result text",
|
28
|
+
expect_put_with(10, "result text", "successful")
|
29
29
|
flexmock(job).should_receive(:run_and_return_result).once.
|
30
30
|
with("export RAILS_ENV=test; export TEST_ENV_NUMBER=; cd project; export RSPEC_COLOR=true; ruby -S bundle exec rspec spec/foo_spec.rb spec/bar_spec.rb").
|
31
31
|
and_return('result text')
|
@@ -38,7 +38,7 @@ module Testbot::Runner
|
|
38
38
|
flexmock(job).should_receive(:puts)
|
39
39
|
stub_duration(0)
|
40
40
|
|
41
|
-
expect_put_with(10, "result text",
|
41
|
+
expect_put_with(10, "result text", "failed")
|
42
42
|
flexmock(job).should_receive(:run_and_return_result).and_return('result text')
|
43
43
|
flexmock(job).should_receive(:success?).and_return(false)
|
44
44
|
job.run(0)
|
@@ -49,7 +49,7 @@ module Testbot::Runner
|
|
49
49
|
flexmock(job).should_receive(:puts)
|
50
50
|
stub_duration(0)
|
51
51
|
|
52
|
-
expect_put_with(10, "result text",
|
52
|
+
expect_put_with(10, "result text", "successful")
|
53
53
|
flexmock(job).should_receive(:run_and_return_result).
|
54
54
|
with(/TEST_ENV_NUMBER=2/).
|
55
55
|
and_return('result text')
|
@@ -61,7 +61,7 @@ module Testbot::Runner
|
|
61
61
|
flexmock(job).should_receive(:puts)
|
62
62
|
|
63
63
|
stub_duration(10.55)
|
64
|
-
expect_put_with(10, "result text",
|
64
|
+
expect_put_with(10, "result text", "successful", 1055)
|
65
65
|
flexmock(job).should_receive(:run_and_return_result).and_return('result text')
|
66
66
|
job.run(0)
|
67
67
|
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), '../../lib/shared/testbot.rb'))
|
2
|
+
require File.expand_path(File.join(File.dirname(__FILE__), '../../lib/runner/safe_result_text.rb'))
|
3
|
+
require 'test/unit'
|
4
|
+
require 'shoulda'
|
5
|
+
|
6
|
+
module Testbot::Runner
|
7
|
+
|
8
|
+
class SafeResultTextTest < Test::Unit::TestCase
|
9
|
+
|
10
|
+
should "not break escape sequences" do
|
11
|
+
assert_equal "^[[32m.^[[0m^[[32m.^[[0m", SafeResultText.clean("^[[32m.^[[0m^[[32m.^[[0m^[[32m.")
|
12
|
+
assert_equal "^[[32m.^[[0m^[[32m.^[[0m", SafeResultText.clean("^[[32m.^[[0m^[[32m.^[[0m^[[3")
|
13
|
+
assert_equal "^[[32m.^[[0m", SafeResultText.clean("^[[32m.^[[0m^[")
|
14
|
+
assert_equal "[32m.[0m[32m.[0m[3", SafeResultText.clean("[32m.[0m[32m.[0m[3")
|
15
|
+
assert_equal "...", SafeResultText.clean("...")
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
data/test/server/server_test.rb
CHANGED
@@ -375,18 +375,18 @@ module Testbot::Server
|
|
375
375
|
|
376
376
|
should "receive the results of a job" do
|
377
377
|
job = Job.create :files => 'spec/models/car_spec.rb', :taken_at => Time.now - 30
|
378
|
-
put "/jobs/#{job.id}", :result => 'test run result', :
|
378
|
+
put "/jobs/#{job.id}", :result => 'test run result', :status => "successful"
|
379
379
|
assert last_response.ok?
|
380
380
|
assert_equal 'test run result', job.result
|
381
|
-
assert_equal '
|
381
|
+
assert_equal 'successful', job.status
|
382
382
|
end
|
383
383
|
|
384
384
|
should "update the related build" do
|
385
385
|
build = Build.create
|
386
386
|
job1 = Job.create :files => 'spec/models/car_spec.rb', :taken_at => Time.now - 30, :build => build
|
387
387
|
job2 = Job.create :files => 'spec/models/car_spec.rb', :taken_at => Time.now - 30, :build => build
|
388
|
-
put "/jobs/#{job1.id}", :result => 'test run result 1\n', :
|
389
|
-
put "/jobs/#{job2.id}", :result => 'test run result 2\n', :
|
388
|
+
put "/jobs/#{job1.id}", :result => 'test run result 1\n', :status => "successful"
|
389
|
+
put "/jobs/#{job2.id}", :result => 'test run result 2\n', :status => "successful"
|
390
390
|
assert_equal 'test run result 1\ntest run result 2\n', build.results
|
391
391
|
assert_equal true, build.success
|
392
392
|
end
|
@@ -395,8 +395,8 @@ module Testbot::Server
|
|
395
395
|
build = Build.create
|
396
396
|
job1 = Job.create :files => 'spec/models/car_spec.rb', :taken_at => Time.now - 30, :build => build
|
397
397
|
job2 = Job.create :files => 'spec/models/car_spec.rb', :taken_at => Time.now - 30, :build => build
|
398
|
-
put "/jobs/#{job1.id}", :result => 'test run result 1\n', :
|
399
|
-
put "/jobs/#{job2.id}", :result => 'test run result 2\n', :
|
398
|
+
put "/jobs/#{job1.id}", :result => 'test run result 1\n', :status => "successful"
|
399
|
+
put "/jobs/#{job2.id}", :result => 'test run result 2\n', :status => "successful"
|
400
400
|
assert_equal true, build.done
|
401
401
|
end
|
402
402
|
|
@@ -404,11 +404,26 @@ module Testbot::Server
|
|
404
404
|
build = Build.create
|
405
405
|
job1 = Job.create :files => 'spec/models/car_spec.rb', :taken_at => Time.now - 30, :build => build
|
406
406
|
job2 = Job.create :files => 'spec/models/car_spec.rb', :taken_at => Time.now - 30, :build => build
|
407
|
-
put "/jobs/#{job1.id}", :result => 'test run result 1\n', :
|
408
|
-
put "/jobs/#{job2.id}", :result => 'test run result 2\n', :
|
407
|
+
put "/jobs/#{job1.id}", :result => 'test run result 1\n', :status => "failed"
|
408
|
+
put "/jobs/#{job2.id}", :result => 'test run result 2\n', :status => "successful"
|
409
409
|
assert_equal false, build.success
|
410
410
|
end
|
411
411
|
|
412
|
+
should "be able to update from multiple result postings" do
|
413
|
+
build = Build.create
|
414
|
+
job1 = Job.create :files => 'spec/models/car_spec.rb', :taken_at => Time.now - 30, :build => build
|
415
|
+
job2 = Job.create :files => 'spec/models/car_spec.rb', :taken_at => Time.now - 30, :build => build
|
416
|
+
# maybe later:
|
417
|
+
# put "/jobs/#{job.id}", :result => 'Preparing, db setup, etc.', :status => "preparing"
|
418
|
+
put "/jobs/#{job1.id}", :result => 'Running tests..', :status => "running"
|
419
|
+
put "/jobs/#{job2.id}", :result => 'Running other tests. done.', :status => "successful"
|
420
|
+
put "/jobs/#{job1.id}", :result => 'Running tests....', :status => "running"
|
421
|
+
assert_equal false, build.done
|
422
|
+
assert_equal false, job1.done
|
423
|
+
assert_equal "Running tests....", job1.result
|
424
|
+
assert_equal "Running tests..Running other tests. done...", build.results
|
425
|
+
end
|
426
|
+
|
412
427
|
end
|
413
428
|
|
414
429
|
context "GET /version" do
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: testbot
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 1
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 6
|
9
|
-
-
|
10
|
-
version: 0.6.
|
9
|
+
- 3
|
10
|
+
version: 0.6.3
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- "Joakim Kolsj\xC3\xB6"
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2012-04-
|
18
|
+
date: 2012-04-28 00:00:00 +02:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
@@ -259,6 +259,7 @@ files:
|
|
259
259
|
- lib/requester/requester.rb
|
260
260
|
- lib/runner/job.rb
|
261
261
|
- lib/runner/runner.rb
|
262
|
+
- lib/runner/safe_result_text.rb
|
262
263
|
- lib/server/build.rb
|
263
264
|
- lib/server/group.rb
|
264
265
|
- lib/server/job.rb
|
@@ -295,6 +296,7 @@ files:
|
|
295
296
|
- test/requester/testbot_with_erb.yml
|
296
297
|
- test/runner/job_test.rb
|
297
298
|
- test/runner/runner_test.rb
|
299
|
+
- test/runner/safe_result_text_test.rb
|
298
300
|
- test/server/group_test.rb
|
299
301
|
- test/server/server_test.rb
|
300
302
|
- test/shared/adapters/adapter_test.rb
|