testbot 0.6.3 → 0.6.4

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/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"