testbot 0.6.3 → 0.6.4

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG CHANGED
@@ -1,3 +1,11 @@
1
+ 0.6.4
2
+
3
+ Fixed bug with running test unit tests that caused errors like '/bin/ruby:1: Invalid char `\317' in expression`'.
4
+
5
+ Now handling errors creating builds.
6
+
7
+ Returning 503 and reporting that there are no runners when that is the case.
8
+
1
9
  0.6.3
2
10
 
3
11
  Results are now shown as they happen. It takes care not to break escape codes used for
@@ -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.3'
67
+ ruby script/plugin install git://github.com/joakimk/testbot.git -r 'refs/tags/v0.6.4'
68
68
  script/generate testbot --connect 192.168.0.100
69
69
 
70
70
  rake testbot:spec (or :rspec, :test, :features)
@@ -51,13 +51,23 @@ module Testbot::Requester
51
51
 
52
52
  build_id = nil
53
53
  log "Requesting run" do
54
- build_id = HTTParty.post("#{server_uri}/builds", :body => { :root => root,
54
+ response = HTTParty.post("#{server_uri}/builds", :body => { :root => root,
55
55
  :type => adapter.type.to_s,
56
56
  :project => config.project,
57
57
  :available_runner_usage => config.available_runner_usage,
58
58
  :files => files.join(' '),
59
59
  :sizes => sizes.join(' '),
60
- :jruby => jruby? })
60
+ :jruby => jruby? }).response
61
+
62
+ if response.code == "503"
63
+ puts "No runners available. If you just started a runner, try again. It usually takes a few seconds before they're available."
64
+ return false
65
+ elsif response.code != "200"
66
+ puts "Could not create build, #{response.code}: #{response.body}"
67
+ return false
68
+ else
69
+ build_id = response.body
70
+ end
61
71
  end
62
72
 
63
73
  trap("SIGINT") { HTTParty.delete("#{server_uri}/builds/#{build_id}"); return false }
@@ -30,7 +30,7 @@ module Testbot::Server
30
30
  end
31
31
 
32
32
  def self.find_all_available
33
- all.find_all { |r| r.version == Testbot.version && r.last_seen_at > (Time.now - Runner.timeout) }
33
+ all.find_all { |r| r.idle_instances && r.version == Testbot.version && r.last_seen_at > (Time.now - Runner.timeout) }
34
34
  end
35
35
 
36
36
  def self.available_instances
@@ -24,7 +24,11 @@ module Testbot::Server
24
24
  end
25
25
 
26
26
  post '/builds' do
27
- build = Build.create_and_build_jobs(params).id.to_s
27
+ if Runner.total_instances == 0
28
+ [ 503, "No runners available" ]
29
+ else
30
+ Build.create_and_build_jobs(params).id.to_s
31
+ end
28
32
  end
29
33
 
30
34
  get '/builds/:id' do
@@ -12,13 +12,13 @@ class RubyEnv
12
12
  elsif opts[:bin]
13
13
  command = opts[:bin]
14
14
  else
15
- command = ruby_interpreter
15
+ command = nil
16
16
  end
17
17
 
18
18
  if bundler?(project_path)
19
- "#{ruby_interpreter} -S bundle exec #{command}"
19
+ "#{ruby_interpreter} -S bundle exec #{command}".strip
20
20
  else
21
- "#{ruby_interpreter} -S #{command}"
21
+ "#{ruby_interpreter} -S #{command}".strip
22
22
  end
23
23
  end
24
24
 
@@ -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.3"
4
+ version = "0.6.4"
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)
@@ -17,7 +17,7 @@ module Testbot::Requester
17
17
  requester = Requester.new(:server_host => "192.168.1.100", :rsync_path => 'user@server:/tmp/somewhere')
18
18
 
19
19
  flexmock(requester).should_receive(:find_tests).and_return([])
20
- flexmock(HTTParty).should_receive(:post).and_return('5')
20
+ flexmock(HTTParty).should_receive(:post).and_return(response_with_build_id)
21
21
  flexmock(requester).should_receive(:sleep).once
22
22
  flexmock(requester).should_receive(:print).once
23
23
  flexmock(requester).should_receive(:puts).once
@@ -27,6 +27,14 @@ module Testbot::Requester
27
27
  requester
28
28
  end
29
29
 
30
+ def response_with_build_id
31
+ OpenStruct.new(:response => OpenStruct.new(:code => "200", :body => "5"))
32
+ end
33
+
34
+ def error_response(opts = {})
35
+ OpenStruct.new(:response => OpenStruct.new(opts))
36
+ end
37
+
30
38
  def build_with_result(results)
31
39
  requester_with_result(results).run_tests(RspecAdapter, 'spec')
32
40
  end
@@ -97,7 +105,7 @@ module Testbot::Requester
97
105
  :files => "spec/models/house_spec.rb" +
98
106
  " spec/models/car_spec.rb",
99
107
  :sizes => "10 20",
100
- :jruby => false })
108
+ :jruby => false }).and_return(response_with_build_id)
101
109
 
102
110
  flexmock(HTTParty).should_receive(:get).and_return({ "done" => true, 'results' => '', "success" => true })
103
111
  flexmock(requester).should_receive(:sleep)
@@ -108,13 +116,35 @@ module Testbot::Requester
108
116
  assert_equal true, requester.run_tests(RspecAdapter, 'spec')
109
117
  end
110
118
 
119
+ should "print a message and exit if the status is 503" do
120
+ requester = Requester.new(:server_host => "192.168.1.100")
121
+
122
+ flexmock(requester).should_receive(:find_tests).and_return([ 'spec/models/house_spec.rb', 'spec_models/car_spec.rb' ])
123
+ flexmock(requester).should_receive(:system)
124
+
125
+ flexmock(HTTParty).should_receive(:post).and_return(error_response(:code => "503"))
126
+ flexmock(requester).should_receive(:puts)
127
+ assert_equal false, requester.run_tests(RspecAdapter, 'spec')
128
+ end
129
+
130
+ should "print what the server returns in case there is anything but a 200 response" do
131
+ requester = Requester.new(:server_host => "192.168.1.100")
132
+
133
+ flexmock(requester).should_receive(:find_tests).and_return([ 'spec/models/house_spec.rb', 'spec_models/car_spec.rb' ])
134
+ flexmock(requester).should_receive(:system)
135
+
136
+ flexmock(HTTParty).should_receive(:post).and_return(error_response(:code => "123", :body => "Some error"))
137
+ flexmock(requester).should_receive(:puts).with("Could not create build, 123: Some error")
138
+ assert_equal false, requester.run_tests(RspecAdapter, 'spec')
139
+ end
140
+
111
141
  should "print the sum of results formatted by the adapter" do
112
142
  requester = Requester.new(:server_host => "192.168.1.100")
113
143
 
114
144
  flexmock(requester).should_receive(:find_tests).and_return([ 'spec/models/house_spec.rb', 'spec_models/car_spec.rb' ])
115
145
  flexmock(requester).should_receive(:system)
116
146
 
117
- flexmock(HTTParty).should_receive(:post).and_return('5')
147
+ flexmock(HTTParty).should_receive(:post).and_return(response_with_build_id)
118
148
 
119
149
  flexmock(HTTParty).should_receive(:get).times(2).with("http://192.168.1.100:#{Testbot::SERVER_PORT}/builds/5",
120
150
  :format => :json).and_return({ "done" => false, "results" => "job 2 done: ...." },
@@ -136,7 +166,7 @@ module Testbot::Requester
136
166
  flexmock(requester).should_receive(:find_tests).and_return([ 'spec/models/house_spec.rb', 'spec_models/car_spec.rb' ])
137
167
  flexmock(requester).should_receive(:system)
138
168
 
139
- flexmock(HTTParty).should_receive(:post).and_return('5')
169
+ flexmock(HTTParty).should_receive(:post).and_return(response_with_build_id)
140
170
 
141
171
  flexmock(HTTParty).should_receive(:get).times(2).with("http://192.168.1.100:#{Testbot::SERVER_PORT}/builds/5",
142
172
  :format => :json).and_return({ "done" => false, "results" => "job 2 done: ...." },
@@ -157,7 +187,7 @@ module Testbot::Requester
157
187
  flexmock(requester).should_receive(:find_tests).and_return([ 'spec/models/house_spec.rb', 'spec_models/car_spec.rb' ])
158
188
  flexmock(requester).should_receive(:system)
159
189
 
160
- flexmock(HTTParty).should_receive(:post).and_return('5')
190
+ flexmock(HTTParty).should_receive(:post).and_return(response_with_build_id)
161
191
 
162
192
  flexmock(HTTParty).should_receive(:get).once.with("http://192.168.1.100:#{Testbot::SERVER_PORT}/builds/5",
163
193
  :format => :json).and_return({ "success" => false, "done" => true, "results" => "job 2 done: ....job 1 done: ...." })
@@ -176,7 +206,7 @@ module Testbot::Requester
176
206
  flexmock(requester).should_receive(:find_tests).and_return([ 'spec/models/house_spec.rb', 'spec_models/car_spec.rb' ])
177
207
  flexmock(requester).should_receive(:system)
178
208
 
179
- flexmock(HTTParty).should_receive(:post).and_return('5')
209
+ flexmock(HTTParty).should_receive(:post).and_return(response_with_build_id)
180
210
 
181
211
  flexmock(HTTParty).should_receive(:get).times(2).with("http://192.168.1.100:#{Testbot::SERVER_PORT}/builds/5",
182
212
  :format => :json).and_return({ "done" => false, "results" => "" },
@@ -196,7 +226,7 @@ module Testbot::Requester
196
226
  flexmock(requester).should_receive(:find_tests).and_return([ 'spec/models/house_spec.rb', 'spec_models/car_spec.rb' ])
197
227
  flexmock(requester).should_receive(:system)
198
228
 
199
- flexmock(HTTParty).should_receive(:post).and_return('5')
229
+ flexmock(HTTParty).should_receive(:post).and_return(response_with_build_id)
200
230
  flexmock(requester).should_receive(:sleep).once
201
231
  flexmock(requester).should_receive(:print)
202
232
  flexmock(requester).should_receive(:puts)
@@ -215,7 +245,7 @@ module Testbot::Requester
215
245
  flexmock(requester).should_receive(:find_tests).and_return([ 'spec/models/house_spec.rb', 'spec_models/car_spec.rb' ])
216
246
  flexmock(requester).should_receive(:system)
217
247
 
218
- flexmock(HTTParty).should_receive(:post).and_return('5')
248
+ flexmock(HTTParty).should_receive(:post).and_return(response_with_build_id)
219
249
 
220
250
  flexmock(HTTParty).should_receive(:get).times(5).with("http://192.168.1.100:#{Testbot::SERVER_PORT}/builds/5",
221
251
  :format => :json).and_raise('some connection error')
@@ -237,7 +267,7 @@ module Testbot::Requester
237
267
  flexmock(requester).should_receive(:find_tests).and_return([ 'spec/models/house_spec.rb', 'spec_models/car_spec.rb' ])
238
268
  flexmock(requester).should_receive(:system)
239
269
 
240
- flexmock(HTTParty).should_receive(:post).and_return('5')
270
+ flexmock(HTTParty).should_receive(:post).and_return(response_with_build_id)
241
271
 
242
272
  flexmock(HTTParty).should_receive(:get).times(2).with("http://192.168.1.100:#{Testbot::SERVER_PORT}/builds/5",
243
273
  :format => :json).and_return(nil,
@@ -257,7 +287,7 @@ module Testbot::Requester
257
287
  flexmock(requester).should_receive(:find_tests).and_return([ 'spec/models/house_spec.rb', 'spec_models/car_spec.rb' ])
258
288
  flexmock(requester).should_receive(:system)
259
289
 
260
- flexmock(HTTParty).should_receive(:post).and_return('5')
290
+ flexmock(HTTParty).should_receive(:post).and_return(response_with_build_id)
261
291
 
262
292
  flexmock(HTTParty).should_receive(:get).times(2).with("http://192.168.1.100:#{Testbot::SERVER_PORT}/builds/5",
263
293
  :format => :json).and_return(nil,
@@ -282,7 +312,7 @@ module Testbot::Requester
282
312
  flexmock(ssh_tunnel).should_receive(:open).once
283
313
 
284
314
  flexmock(requester).should_receive(:find_tests).and_return([ 'spec/models/house_spec.rb' ])
285
- flexmock(HTTParty).should_receive(:post).with("http://127.0.0.1:2299/builds", any).and_return('5')
315
+ flexmock(HTTParty).should_receive(:post).with("http://127.0.0.1:2299/builds", any).and_return(response_with_build_id)
286
316
  flexmock(HTTParty).should_receive(:get).and_return({ "done" => true, "results" => "job 1 done: ...." })
287
317
  flexmock(requester).should_receive(:sleep)
288
318
  flexmock(requester).should_receive(:print)
@@ -300,7 +330,7 @@ module Testbot::Requester
300
330
  flexmock(ssh_tunnel).should_receive(:open).once
301
331
 
302
332
  flexmock(requester).should_receive(:find_tests).and_return([ 'spec/models/house_spec.rb' ])
303
- flexmock(HTTParty).should_receive(:post).with("http://127.0.0.1:2299/builds", any).and_return('5')
333
+ flexmock(HTTParty).should_receive(:post).with("http://127.0.0.1:2299/builds", any).and_return(response_with_build_id)
304
334
  flexmock(HTTParty).should_receive(:get).and_return({ "done" => true, "results" => "job 1 done: ...." })
305
335
  flexmock(requester).should_receive(:sleep)
306
336
  flexmock(requester).should_receive(:print)
@@ -320,7 +350,7 @@ module Testbot::Requester
320
350
  flexmock(ssh_tunnel).should_receive(:open).once
321
351
 
322
352
  flexmock(requester).should_receive(:find_tests).and_return([ 'features/some.feature' ])
323
- flexmock(HTTParty).should_receive(:post).with("http://127.0.0.1:2230/builds", any).and_return('5')
353
+ flexmock(HTTParty).should_receive(:post).with("http://127.0.0.1:2230/builds", any).and_return(response_with_build_id)
324
354
  flexmock(HTTParty).should_receive(:get).and_return({ "done" => true, "results" => "job 1 done: ...." })
325
355
  flexmock(requester).should_receive(:sleep)
326
356
  flexmock(requester).should_receive(:print)
@@ -338,7 +368,7 @@ module Testbot::Requester
338
368
  flexmock(ssh_tunnel).should_receive(:open).once
339
369
 
340
370
  flexmock(requester).should_receive(:find_tests).and_return([ 'test/some_test.rb' ])
341
- flexmock(HTTParty).should_receive(:post).with("http://127.0.0.1:2231/builds", any).and_return('5')
371
+ flexmock(HTTParty).should_receive(:post).with("http://127.0.0.1:2231/builds", any).and_return(response_with_build_id)
342
372
  flexmock(HTTParty).should_receive(:get).and_return({ "done" => true, "results" => "job 1 done: ...." })
343
373
  flexmock(requester).should_receive(:sleep)
344
374
  flexmock(requester).should_receive(:print)
@@ -359,7 +389,7 @@ module Testbot::Requester
359
389
  :sizes=>"0", :project=>"project" }
360
390
 
361
391
  flexmock(TestUnitAdapter).should_receive(:test_files).and_return([ 'test/some_test.rb' ])
362
- flexmock(HTTParty).should_receive(:post).with(any, :body => other_args.merge({ :jruby => true })).and_return('5')
392
+ flexmock(HTTParty).should_receive(:post).with(any, :body => other_args.merge({ :jruby => true })).and_return(response_with_build_id)
363
393
  flexmock(HTTParty).should_receive(:get).and_return({ "done" => true, "results" => "job 1 done: ...." })
364
394
  flexmock(requester).should_receive(:sleep)
365
395
  flexmock(requester).should_receive(:print)
@@ -62,6 +62,14 @@ module Testbot::Server
62
62
  assert_equal Build.all.first, first_job.build
63
63
  end
64
64
 
65
+ should "return a 503 error if there are no known runners" do
66
+ flexmock(Runner).should_receive(:total_instances).and_return(0)
67
+ post '/builds', :files => 'spec/models/car_spec.rb spec/models/car2_spec.rb spec/models/house_spec.rb spec/models/house2_spec.rb', :root => 'server:/path/to/project', :type => 'spec', :available_runner_usage => "100%", :project => 'things', :sizes => "1 1 1 1", :jruby => true
68
+ assert_equal 0, Job.count
69
+ assert_equal 503, last_response.status
70
+ assert_equal "No runners available", last_response.body
71
+ end
72
+
65
73
  should "only use resources according to available_runner_usage" do
66
74
  flexmock(Runner).should_receive(:total_instances).and_return(4)
67
75
  flexmock(Group).should_receive(:build).with(["spec/models/car_spec.rb", "spec/models/car2_spec.rb", "spec/models/house_spec.rb", "spec/models/house2_spec.rb"], [ 1, 1, 1, 1 ], 2, 'spec').and_return([])
@@ -267,6 +275,14 @@ module Testbot::Server
267
275
  assert_equal "127.0.0.1 macmini1.local 00:01 user1 2\n127.0.0.1 macmini2.local 00:02 user2 4", last_response.body
268
276
  end
269
277
 
278
+ should "not return a runner as available when it hasnt pinged the server yet" do
279
+ get '/jobs/next', :version => Testbot.version, :hostname => 'macmini1.local', :uid => "00:01", :username => 'user1'
280
+ get '/jobs/next', :version => Testbot.version, :hostname => 'macmini2.local', :uid => "00:02", :idle_instances => 4, :username => 'user2'
281
+ get '/runners/available'
282
+ assert last_response.ok?
283
+ assert_equal "127.0.0.1 macmini2.local 00:02 user2 4", last_response.body
284
+ end
285
+
270
286
  should "not return runners as available when not seen the last 10 seconds" do
271
287
  get '/jobs/next', :version => Testbot.version, :hostname => 'macmini1.local', :uid => "00:01", :idle_instances => 2, :username => "user1"
272
288
  get '/jobs/next', :version => Testbot.version, :hostname => 'macmini2.local', :uid => "00:02", :idle_instances => 4
@@ -301,16 +317,16 @@ module Testbot::Server
301
317
  context "GET /runners/total_instances" do
302
318
 
303
319
  should "return the number of available runner instances" do
304
- get '/jobs/next', :version => Testbot.version, :hostname => 'macmini1.local', :uid => "00:01", :max_instances => 2
305
- get '/jobs/next', :version => Testbot.version, :hostname => 'macmini2.local', :uid => "00:02", :max_instances => 4
320
+ get '/jobs/next', :version => Testbot.version, :hostname => 'macmini1.local', :uid => "00:01", :max_instances => 2, :idle_instances => 1
321
+ get '/jobs/next', :version => Testbot.version, :hostname => 'macmini2.local', :uid => "00:02", :max_instances => 4, :idle_instances => 2
306
322
  get '/runners/total_instances'
307
323
  assert last_response.ok?
308
324
  assert_equal "6", last_response.body
309
325
  end
310
326
 
311
327
  should "not return instances as available when not seen the last 10 seconds" do
312
- get '/jobs/next', :version => Testbot.version, :hostname => 'macmini1.local', :uid => "00:01", :max_instances => 2
313
- get '/jobs/next', :version => Testbot.version, :hostname => 'macmini2.local', :uid => "00:02", :max_instances => 4
328
+ get '/jobs/next', :version => Testbot.version, :hostname => 'macmini1.local', :uid => "00:01", :max_instances => 2, :idle_instances => 1
329
+ get '/jobs/next', :version => Testbot.version, :hostname => 'macmini2.local', :uid => "00:02", :max_instances => 4, :idle_instances => 2
314
330
  Runner.find_by_uid("00:02").update(:last_seen_at => Time.now - 10)
315
331
  get '/runners/total_instances'
316
332
  assert last_response.ok?
@@ -71,11 +71,19 @@ class RubyEnvTest < Test::Unit::TestCase
71
71
  :bin => "rspec", :ruby_interpreter => "jruby")
72
72
  end
73
73
 
74
- should "use the interpeter when there is no binary specified" do
74
+ should "work when there is no binary specified and bundler is present" do
75
75
  flexmock(RubyEnv).should_receive(:bundler?).and_return(true)
76
76
  flexmock(File).should_receive(:exists?).and_return(false)
77
- assert_equal 'ruby -S bundle exec ruby', RubyEnv.ruby_command("path/to/project")
77
+ assert_equal 'ruby -S bundle exec', RubyEnv.ruby_command("path/to/project")
78
78
  end
79
+
80
+ should "work when there is no binary specified and bundler is not present" do
81
+ flexmock(RubyEnv).should_receive(:bundler?).and_return(false)
82
+ flexmock(File).should_receive(:exists?).and_return(false)
83
+ assert_equal 'ruby -S', RubyEnv.ruby_command("path/to/project")
84
+ end
85
+
86
+
79
87
  end
80
88
 
81
89
  end
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: 1
4
+ hash: 15
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 6
9
- - 3
10
- version: 0.6.3
9
+ - 4
10
+ version: 0.6.4
11
11
  platform: ruby
12
12
  authors:
13
13
  - "Joakim Kolsj\xC3\xB6"