testbot 0.5.2 → 0.5.3

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.
@@ -0,0 +1,70 @@
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/job.rb'))
3
+ require 'test/unit'
4
+ require 'shoulda'
5
+ require 'flexmock/test_unit'
6
+
7
+ module Testbot::Runner
8
+
9
+ class JobTest < Test::Unit::TestCase
10
+
11
+ def expect_put_with(id, result_text, success, time = 0)
12
+ expected_result = "\n#{`hostname`.chomp}:#{Dir.pwd}\n"
13
+ expected_result += result_text
14
+ flexmock(Server).should_receive(:put).once.with("/jobs/#{id}", :body =>
15
+ { :result => expected_result, :success => success, :time => time })
16
+ end
17
+
18
+ def stub_duration(seconds)
19
+ time ||= Time.now
20
+ flexmock(Time).should_receive(:now).and_return(time, time + seconds)
21
+ end
22
+
23
+ should "be able to run a successful job" do
24
+ job = Job.new(Runner.new({}), 10, "00:00", "project", "/tmp/testbot/user", "spec", "ruby", "spec/foo_spec.rb spec/bar_spec.rb")
25
+ flexmock(job).should_receive(:puts)
26
+ stub_duration(0)
27
+
28
+ expect_put_with(10, "result text", true)
29
+ flexmock(job).should_receive(:run_and_return_result).once.
30
+ with("export RAILS_ENV=test; export TEST_ENV_NUMBER=; cd project; export RSPEC_COLOR=true; ruby -S rspec spec/foo_spec.rb spec/bar_spec.rb").
31
+ and_return('result text')
32
+ job.run(0)
33
+ end
34
+
35
+ should "return false on success if the job fails" do
36
+ job = Job.new(Runner.new({}), 10, "00:00", "project", "/tmp/testbot/user", "spec", "ruby", "spec/foo_spec.rb spec/bar_spec.rb")
37
+ flexmock(job).should_receive(:puts)
38
+ stub_duration(0)
39
+
40
+ expect_put_with(10, "result text", false)
41
+ flexmock(job).should_receive(:run_and_return_result).and_return('result text')
42
+ flexmock(job).should_receive(:success?).and_return(false)
43
+ job.run(0)
44
+ end
45
+
46
+ should "set an instance number when the instance is not 0" do
47
+ job = Job.new(Runner.new({}), 10, "00:00", "project", "/tmp/testbot/user", "spec", "ruby", "spec/foo_spec.rb spec/bar_spec.rb")
48
+ flexmock(job).should_receive(:puts)
49
+ stub_duration(0)
50
+
51
+ expect_put_with(10, "result text", true)
52
+ flexmock(job).should_receive(:run_and_return_result).
53
+ with(/TEST_ENV_NUMBER=2/).
54
+ and_return('result text')
55
+ job.run(1)
56
+ end
57
+
58
+ should "return test runtime in milliseconds" do
59
+ job = Job.new(Runner.new({}), 10, "00:00", "project", "/tmp/testbot/user", "spec", "ruby", "spec/foo_spec.rb spec/bar_spec.rb")
60
+ flexmock(job).should_receive(:puts)
61
+
62
+ stub_duration(10.55)
63
+ expect_put_with(10, "result text", true, 1055)
64
+ flexmock(job).should_receive(:run_and_return_result).and_return('result text')
65
+ job.run(0)
66
+ end
67
+
68
+ end
69
+
70
+ end
@@ -0,0 +1,43 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), '../../lib/server/group'))
2
+ require 'test/unit'
3
+ require 'shoulda'
4
+ require 'flexmock/test_unit'
5
+
6
+ module Testbot::Server
7
+
8
+ class GroupTest < Test::Unit::TestCase
9
+
10
+ context "self.build" do
11
+
12
+ should "create file groups based on the number of instances" do
13
+ groups = Group.build([ 'spec/models/car_spec.rb', 'spec/models/car2_spec.rb',
14
+ 'spec/models/house_spec.rb', 'spec/models/house2_spec.rb' ], [ 1, 1, 1, 1 ], 2, 'spec')
15
+
16
+ assert_equal 2, groups.size
17
+ assert_equal [ 'spec/models/house2_spec.rb', 'spec/models/house_spec.rb' ], groups[0]
18
+ assert_equal [ 'spec/models/car2_spec.rb', 'spec/models/car_spec.rb' ], groups[1]
19
+ end
20
+
21
+ should "create a small grop when there isn't enough specs to fill a normal one" do
22
+ groups = Group.build(["spec/models/car_spec.rb", "spec/models/car2_spec.rb",
23
+ "spec/models/house_spec.rb", "spec/models/house2_spec.rb",
24
+ "spec/models/house3_spec.rb"], [ 1, 1, 1, 1, 1 ], 3, 'spec')
25
+
26
+ assert_equal 3, groups.size
27
+ assert_equal [ "spec/models/car_spec.rb" ], groups[2]
28
+ end
29
+
30
+ should "use sizes when building groups" do
31
+ groups = Group.build([ 'spec/models/car_spec.rb', 'spec/models/car2_spec.rb',
32
+ 'spec/models/house_spec.rb', 'spec/models/house2_spec.rb' ], [ 40, 10, 10, 20 ], 2, 'spec')
33
+
34
+ assert_equal [ 'spec/models/car_spec.rb' ], groups[0]
35
+ assert ![ 'spec/models/house2_spec.rb', 'spec/models/car2_spec.rb', 'spec/models/house_spec.rb' ].
36
+ find { |file| !groups[1].include?(file) }
37
+ end
38
+
39
+ end
40
+
41
+ end
42
+
43
+ end
@@ -0,0 +1,451 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), '../../lib/server/server'))
2
+ require 'test/unit'
3
+ require 'rack/test'
4
+ require 'shoulda'
5
+ require 'flexmock/test_unit'
6
+
7
+ set :environment, :test
8
+
9
+ module Testbot::Server
10
+
11
+ class ServerTest < Test::Unit::TestCase
12
+ include Rack::Test::Methods
13
+
14
+ def setup
15
+ Job.delete_all
16
+ Runner.delete_all
17
+ Build.delete_all
18
+ end
19
+
20
+ def app
21
+ Sinatra::Application
22
+ end
23
+
24
+ context "POST /builds" do
25
+
26
+ should "create a build and return its id" do
27
+ flexmock(Runner).should_receive(:total_instances).and_return(2)
28
+ post '/builds', :files => 'spec/models/car_spec.rb spec/models/house_spec.rb', :root => 'server:/path/to/project', :type => 'spec', :available_runner_usage => "100%", :requester_mac => "bb:bb:bb:bb:bb:bb", :project => 'things', :sizes => "10 20", :jruby => false
29
+
30
+ first_build = Build.all.first
31
+ assert last_response.ok?
32
+
33
+ assert_equal first_build.id.to_s, last_response.body
34
+ assert_equal 'spec/models/car_spec.rb spec/models/house_spec.rb', first_build.files
35
+ assert_equal '10 20', first_build.sizes
36
+ assert_equal 'server:/path/to/project', first_build.root
37
+ assert_equal 'spec', first_build.type
38
+ assert_equal 'bb:bb:bb:bb:bb:bb', first_build.requester_mac
39
+ assert_equal 'things', first_build.project
40
+ assert_equal 0, first_build.jruby
41
+ assert_equal '', first_build.results
42
+ assert_equal true, first_build.success
43
+ end
44
+
45
+ should "create jobs from the build based on the number of total instances" do
46
+ flexmock(Runner).should_receive(:total_instances).and_return(2)
47
+ 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').once.and_return([
48
+ ["spec/models/car_spec.rb", "spec/models/car2_spec.rb"],
49
+ ["spec/models/house_spec.rb", "spec/models/house2_spec.rb"]
50
+ ])
51
+
52
+ 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%", :requester_mac => "bb:bb:bb:bb:bb:bb", :project => 'things', :sizes => "1 1 1 1", :jruby => true
53
+
54
+ assert_equal 2, Job.count
55
+ first_job, last_job = Job.all
56
+ assert_equal 'spec/models/car_spec.rb spec/models/car2_spec.rb', first_job.files
57
+ assert_equal 'spec/models/house_spec.rb spec/models/house2_spec.rb', last_job.files
58
+
59
+ assert_equal 'server:/path/to/project', first_job.root
60
+ assert_equal 'spec', first_job.type
61
+ assert_equal 'bb:bb:bb:bb:bb:bb', first_job.requester_mac
62
+ assert_equal 'things', first_job.project
63
+ assert_equal 1, first_job.jruby
64
+ assert_equal Build.all.first, first_job.build
65
+ end
66
+
67
+ should "only use resources according to available_runner_usage" do
68
+ flexmock(Runner).should_receive(:total_instances).and_return(4)
69
+ 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([])
70
+ 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', :sizes => "1 1 1 1", :available_runner_usage => "50%"
71
+ end
72
+
73
+ end
74
+
75
+ context "GET /builds/:id" do
76
+
77
+ should 'return the build status' do
78
+ build = Build.create(:done => false, :results => "testbot5\n..........\ncompleted", :success => false)
79
+ get "/builds/#{build.id}"
80
+ assert_equal true, last_response.ok?
81
+ assert_equal ({ "done" => false, "results" => "testbot5\n..........\ncompleted", "success" => false }),
82
+ JSON.parse(last_response.body)
83
+ end
84
+
85
+ should 'remove a build that is done' do
86
+ build = Build.create(:done => true)
87
+ get "/builds/#{build.id}"
88
+ assert_equal true, JSON.parse(last_response.body)['done']
89
+ assert_equal 0, Build.count
90
+ end
91
+
92
+ should 'remove all related jobs of a build that is done' do
93
+ build = Build.create(:done => true)
94
+ related_job = Job.create(:build => build)
95
+ other_job = Job.create(:build => nil)
96
+ get "/builds/#{build.id}"
97
+ assert !Job.find(related_job.id)
98
+ assert Job.find(other_job.id)
99
+ end
100
+
101
+ end
102
+
103
+ context "GET /jobs/next" do
104
+
105
+ should "be able to return a job and mark it as taken" do
106
+ job1 = Job.create :files => 'spec/models/car_spec.rb', :root => 'server:/project', :type => 'spec', :requester_mac => "bb:bb:bb:bb:bb:bb", :project => 'things', :jruby => 1
107
+
108
+ get '/jobs/next', :version => Testbot.version
109
+ assert last_response.ok?
110
+
111
+ assert_equal [ job1.id, "bb:bb:bb:bb:bb:bb", "things", "server:/project", "spec", "jruby", "spec/models/car_spec.rb" ].join(','), last_response.body
112
+ assert job1.taken_at != nil
113
+ end
114
+
115
+ should "not return a job that has already been taken" do
116
+ job1 = Job.create :files => 'spec/models/car_spec.rb', :taken_at => Time.now, :type => 'spec'
117
+ job2 = Job.create :files => 'spec/models/house_spec.rb', :root => 'server:/project', :type => 'spec', :requester_mac => "aa:aa:aa:aa:aa:aa", :project => 'things', :jruby => 0
118
+ get '/jobs/next', :version => Testbot.version
119
+ assert last_response.ok?
120
+ assert_equal [ job2.id, "aa:aa:aa:aa:aa:aa", "things", "server:/project", "spec", "ruby", "spec/models/house_spec.rb" ].join(','), last_response.body
121
+ assert job2.taken_at != nil
122
+ end
123
+
124
+ should "not return a job if there isnt any" do
125
+ get '/jobs/next', :version => Testbot.version
126
+ assert last_response.ok?
127
+ assert_equal '', last_response.body
128
+ end
129
+
130
+ should "save which runner takes a job" do
131
+ job = Job.create :files => 'spec/models/house_spec.rb', :root => 'server:/project', :type => 'spec', :requester_mac => "aa:aa:aa:aa:aa:aa"
132
+ get '/jobs/next', :version => Testbot.version
133
+ assert_equal Runner.first, job.taken_by
134
+ end
135
+
136
+ should "save information about the runners" do
137
+ get '/jobs/next', :version => Testbot.version, :hostname => 'macmini.local', :uid => "00:01:...", :idle_instances => 2, :max_instances => 4
138
+ runner = Runner.first
139
+ assert_equal Testbot.version, runner.version
140
+ assert_equal '127.0.0.1', runner.ip
141
+ assert_equal 'macmini.local', runner.hostname
142
+ assert_equal '00:01:...', runner.uid
143
+ assert_equal 2, runner.idle_instances
144
+ assert_equal 4, runner.max_instances
145
+ assert (Time.now - 5) < runner.last_seen_at
146
+ assert (Time.now + 5) > runner.last_seen_at
147
+ end
148
+
149
+ should "only create one record for the same mac" do
150
+ get '/jobs/next', :version => Testbot.version, :uid => "00:01:..."
151
+ get '/jobs/next', :version => Testbot.version, :uid => "00:01:..."
152
+ assert_equal 1, Runner.count
153
+ end
154
+
155
+ should "not return anything to outdated clients" do
156
+ Job.create :files => 'spec/models/house_spec.rb', :root => 'server:/project'
157
+ get '/jobs/next', :version => "1", :uid => "00:..."
158
+ assert last_response.ok?
159
+ assert_equal '', last_response.body
160
+ end
161
+
162
+ should "only give jobs from the same source to a runner" do
163
+ job1 = Job.create :files => 'spec/models/car_spec.rb', :type => 'spec', :requester_mac => "bb:bb:bb:bb:bb:bb"
164
+ get '/jobs/next', :version => Testbot.version, :uid => "00:..."
165
+
166
+ # Creating the second job here because of the random lookup.
167
+ job2 = Job.create :files => 'spec/models/house_spec.rb', :root => 'server:/project', :type => 'spec', :requester_mac => "aa:aa:aa:aa:aa:aa"
168
+ get '/jobs/next', :version => Testbot.version, :uid => "00:...", :requester_mac => "bb:bb:bb:bb:bb:bb"
169
+
170
+ assert last_response.ok?
171
+ assert_equal '', last_response.body
172
+ end
173
+
174
+ should "not give more jruby jobs to an instance that can't take more" do
175
+ job1 = Job.create :files => 'spec/models/car_spec.rb', :type => 'spec', :requester_mac => "bb:bb:bb:bb:bb:bb", :jruby => 1
176
+ get '/jobs/next', :version => Testbot.version, :uid => "00:..."
177
+
178
+ # Creating the second job here because of the random lookup.
179
+ job2 = Job.create :files => 'spec/models/house_spec.rb', :root => 'server:/project', :type => 'spec', :jruby => 1
180
+ get '/jobs/next', :version => Testbot.version, :uid => "00:...", :no_jruby => "true"
181
+
182
+ assert last_response.ok?
183
+ assert_equal '', last_response.body
184
+ end
185
+
186
+ should "still return other jobs when the runner cant take more jruby jobs" do
187
+ job1 = Job.create :files => 'spec/models/car_spec.rb', :type => 'spec', :requester_mac => "bb:bb:bb:bb:bb:bb", :jruby => 1
188
+ get '/jobs/next', :version => Testbot.version, :uid => "00:..."
189
+
190
+ # Creating the second job here because of the random lookup.
191
+ job2 = Job.create :files => 'spec/models/house_spec.rb', :root => 'server:/project', :type => 'spec', :jruby => 0
192
+ get '/jobs/next', :version => Testbot.version, :uid => "00:...", :no_jruby => "true"
193
+
194
+ assert last_response.ok?
195
+ assert_equal job2.id.to_s, last_response.body.split(',')[0]
196
+ end
197
+
198
+ should "return the jobs in random order in order to start working for a new requester right away" do
199
+ 20.times { Job.create :files => 'spec/models/house_spec.rb', :root => 'server:/project', :type => 'spec', :requester_mac => "bb:bb:bb:bb:bb:bb" }
200
+
201
+ 20.times { Job.create :files => 'spec/models/house_spec.rb', :root => 'server:/project', :type => 'spec', :requester_mac => "aa:aa:aa:aa:aa:aa" }
202
+
203
+ macs = (0...10).map {
204
+ get '/jobs/next', :version => Testbot.version, :uid => "00:..."
205
+ last_response.body.split(',')[1]
206
+ }
207
+
208
+ assert macs.find { |mac| mac == 'bb:bb:bb:bb:bb:bb' }
209
+ assert macs.find { |mac| mac == 'aa:aa:aa:aa:aa:aa' }
210
+ end
211
+
212
+ should "return the jobs randomly when passing requester" do
213
+ 20.times { Job.create :files => 'spec/models/house_spec.rb', :root => 'server:/project', :type => 'spec', :requester_mac => "bb:bb:bb:bb:bb:bb" }
214
+
215
+ 20.times { Job.create :files => 'spec/models/car_spec.rb', :root => 'server:/project', :type => 'spec', :requester_mac => "bb:bb:bb:bb:bb:bb" }
216
+
217
+ files = (0...10).map {
218
+ get '/jobs/next', :version => Testbot.version, :uid => "00:...", :requester_mac => "bb:bb:bb:bb:bb:bb"
219
+ last_response.body.split(',').last
220
+ }
221
+
222
+ assert files.find { |file| file.include?('car') }
223
+ assert files.find { |file| file.include?('house') }
224
+ end
225
+
226
+ should "return taken jobs to other runners if the runner hasn't been seen for 10 seconds or more" do
227
+ missing_runner = Runner.create(:last_seen_at => Time.now - 15)
228
+ old_taken_job = Job.create :files => 'spec/models/house_spec.rb', :root => 'server:/project', :type => 'spec', :requester_mac => "aa:aa:aa:aa:aa:aa", :taken_by => missing_runner, :taken_at => Time.now - 30, :project => 'things'
229
+
230
+ new_runner = Runner.create(:uid => "00:01")
231
+ get '/jobs/next', :version => Testbot.version, :uid => "00:01"
232
+ assert_equal new_runner, old_taken_job.taken_by
233
+
234
+ assert last_response.ok?
235
+ assert_equal [ old_taken_job.id, "aa:aa:aa:aa:aa:aa", "things", "server:/project", "spec", "ruby", "spec/models/house_spec.rb" ].join(','), last_response.body
236
+ end
237
+
238
+ end
239
+
240
+ context "/runners/outdated" do
241
+
242
+ should "return a list of outdated runners" do
243
+ get '/jobs/next', :version => "1", :hostname => 'macmini1.local', :uid => "00:01"
244
+ get '/jobs/next', :version => "1", :hostname => 'macmini2.local', :uid => "00:02"
245
+ get '/jobs/next'
246
+ get '/jobs/next', :version => Testbot.version.to_s, :hostname => 'macmini3.local', :uid => "00:03"
247
+ assert_equal 4, Runner.count
248
+ get '/runners/outdated'
249
+ assert last_response.ok?
250
+ assert_equal "127.0.0.1 macmini1.local 00:01\n127.0.0.1 macmini2.local 00:02\n127.0.0.1", last_response.body
251
+ end
252
+
253
+ end
254
+
255
+ context "GET /runners/available_runners" do
256
+
257
+ should "return a list of available runners" do
258
+ get '/jobs/next', :version => Testbot.version, :hostname => 'macmini1.local', :uid => "00:01", :idle_instances => 2, :username => 'user1'
259
+ get '/jobs/next', :version => Testbot.version, :hostname => 'macmini2.local', :uid => "00:02", :idle_instances => 4, :username => 'user2'
260
+ get '/runners/available'
261
+ assert last_response.ok?
262
+ 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
263
+ end
264
+
265
+ should "not return runners as available when not seen the last 10 seconds" do
266
+ get '/jobs/next', :version => Testbot.version, :hostname => 'macmini1.local', :uid => "00:01", :idle_instances => 2, :username => "user1"
267
+ get '/jobs/next', :version => Testbot.version, :hostname => 'macmini2.local', :uid => "00:02", :idle_instances => 4
268
+ Runner.find_by_uid("00:02").update(:last_seen_at => Time.now - 10)
269
+ get '/runners/available'
270
+ assert_equal "127.0.0.1 macmini1.local 00:01 user1 2", last_response.body
271
+ end
272
+
273
+ end
274
+
275
+ context "GET /runners/available_instances" do
276
+
277
+ should "return the number of available runner instances" do
278
+ get '/jobs/next', :version => Testbot.version, :hostname => 'macmini1.local', :uid => "00:01", :idle_instances => 2
279
+ get '/jobs/next', :version => Testbot.version, :hostname => 'macmini2.local', :uid => "00:02", :idle_instances => 4
280
+ get '/runners/available_instances'
281
+ assert last_response.ok?
282
+ assert_equal "6", last_response.body
283
+ end
284
+
285
+ should "not return instances as available when not seen the last 10 seconds" do
286
+ get '/jobs/next', :version => Testbot.version, :hostname => 'macmini1.local', :uid => "00:01", :idle_instances => 2
287
+ get '/jobs/next', :version => Testbot.version, :hostname => 'macmini2.local', :uid => "00:02", :idle_instances => 4
288
+ Runner.find_by_uid("00:02").update(:last_seen_at => Time.now - 10)
289
+ get '/runners/available_instances'
290
+ assert last_response.ok?
291
+ assert_equal "2", last_response.body
292
+ end
293
+
294
+ end
295
+
296
+ context "GET /runners/total_instances" do
297
+
298
+ should "return the number of available runner instances" do
299
+ get '/jobs/next', :version => Testbot.version, :hostname => 'macmini1.local', :uid => "00:01", :max_instances => 2
300
+ get '/jobs/next', :version => Testbot.version, :hostname => 'macmini2.local', :uid => "00:02", :max_instances => 4
301
+ get '/runners/total_instances'
302
+ assert last_response.ok?
303
+ assert_equal "6", last_response.body
304
+ end
305
+
306
+ should "not return instances as available when not seen the last 10 seconds" do
307
+ get '/jobs/next', :version => Testbot.version, :hostname => 'macmini1.local', :uid => "00:01", :max_instances => 2
308
+ get '/jobs/next', :version => Testbot.version, :hostname => 'macmini2.local', :uid => "00:02", :max_instances => 4
309
+ Runner.find_by_uid("00:02").update(:last_seen_at => Time.now - 10)
310
+ get '/runners/total_instances'
311
+ assert last_response.ok?
312
+ assert_equal "2", last_response.body
313
+ end
314
+
315
+ end
316
+
317
+ context "GET /runners/ping" do
318
+
319
+ should "update last_seen_at for the runner" do
320
+ runner = Runner.create(:uid => 'aa:aa:aa:aa:aa:aa')
321
+ get "/runners/ping", :uid => 'aa:aa:aa:aa:aa:aa', :version => Testbot.version
322
+ assert last_response.ok?
323
+ assert (Time.now - 5) < runner.last_seen_at
324
+ assert (Time.now + 5) > runner.last_seen_at
325
+ end
326
+
327
+ should "update data on the runner" do
328
+ runner = Runner.create(:uid => 'aa:aa:..')
329
+ get "/runners/ping", :uid => 'aa:aa:..', :max_instances => 4, :idle_instances => 2, :hostname => "hostname1", :version => Testbot.version, :username => 'jocke'
330
+ assert last_response.ok?
331
+ assert_equal 'aa:aa:..', runner.uid
332
+ assert_equal 4, runner.max_instances
333
+ assert_equal 2, runner.idle_instances
334
+ assert_equal 'hostname1', runner.hostname
335
+ assert_equal Testbot.version, runner.version
336
+ assert_equal 'jocke', runner.username
337
+ end
338
+
339
+ should "do nothing if the version does not match" do
340
+ runner = Runner.create(:uid => 'aa:aa:..', :version => Testbot.version)
341
+ get "/runners/ping", :uid => 'aa:aa:..', :version => "OLD"
342
+ assert last_response.ok?
343
+ assert_equal Testbot.version, runner.version
344
+ end
345
+
346
+ should "do nothing if the runners isnt known yet found" do
347
+ get "/runners/ping", :uid => 'aa:aa:aa:aa:aa:aa', :version => Testbot.version
348
+ assert last_response.ok?
349
+ end
350
+
351
+ end
352
+
353
+ context "PUT /jobs/:id" do
354
+
355
+ should "receive the results of a job" do
356
+ job = Job.create :files => 'spec/models/car_spec.rb', :taken_at => Time.now - 30
357
+ put "/jobs/#{job.id}", :result => 'test run result', :success => true
358
+ assert last_response.ok?
359
+ assert_equal 'test run result', job.result
360
+ assert_equal 'true', job.success
361
+ end
362
+
363
+ should "update the related build" do
364
+ build = Build.create
365
+ job1 = Job.create :files => 'spec/models/car_spec.rb', :taken_at => Time.now - 30, :build => build
366
+ job2 = Job.create :files => 'spec/models/car_spec.rb', :taken_at => Time.now - 30, :build => build
367
+ put "/jobs/#{job1.id}", :result => 'test run result 1\n', :success => "true"
368
+ put "/jobs/#{job2.id}", :result => 'test run result 2\n', :success => "true"
369
+ assert_equal 'test run result 1\ntest run result 2\n', build.results
370
+ assert_equal true, build.success
371
+ end
372
+
373
+ should "make the related build done if there are no more jobs for the build" do
374
+ build = Build.create
375
+ job1 = Job.create :files => 'spec/models/car_spec.rb', :taken_at => Time.now - 30, :build => build
376
+ job2 = Job.create :files => 'spec/models/car_spec.rb', :taken_at => Time.now - 30, :build => build
377
+ put "/jobs/#{job1.id}", :result => 'test run result 1\n', :success => true
378
+ put "/jobs/#{job2.id}", :result => 'test run result 2\n', :success => true
379
+ assert_equal true, build.done
380
+ end
381
+
382
+ should "make the build fail if one of the jobs fail" do
383
+ build = Build.create
384
+ job1 = Job.create :files => 'spec/models/car_spec.rb', :taken_at => Time.now - 30, :build => build
385
+ job2 = Job.create :files => 'spec/models/car_spec.rb', :taken_at => Time.now - 30, :build => build
386
+ put "/jobs/#{job1.id}", :result => 'test run result 1\n', :success => false
387
+ put "/jobs/#{job2.id}", :result => 'test run result 2\n', :success => true
388
+ assert_equal false, build.success
389
+ end
390
+
391
+ end
392
+
393
+ context "GET /version" do
394
+
395
+ should "return its version" do
396
+ get '/version'
397
+ assert last_response.ok?
398
+ assert_equal Testbot.version.to_s, last_response.body
399
+ end
400
+
401
+ end
402
+
403
+ context "GET /runners" do
404
+
405
+ should "return runner information in json format" do
406
+ get '/jobs/next', :version => Testbot.version, :uid => "00:01"
407
+ get "/runners/ping", :uid => '00:01', :max_instances => 4, :idle_instances => 2, :hostname => "hostname1", :version => Testbot.version, :username => 'testbot'
408
+ get '/runners'
409
+
410
+ assert last_response.ok?
411
+ assert_equal ([ { "version" => Testbot.version.to_s, "hostname" => 'hostname1', "uid" => "00:01",
412
+ "idle_instances" => 2, "max_instances" => 4, "username" => 'testbot',
413
+ "ip" => "127.0.0.1", "last_seen_at" => Runner.first.last_seen_at.to_s } ]),
414
+ JSON.parse(last_response.body)
415
+ end
416
+
417
+ should "not return instances when not seen the last 10 seconds" do
418
+ get '/jobs/next', :version => Testbot.version, :hostname => 'macmini1.local', :uid => "00:01", :idle_instances => 2
419
+ get '/jobs/next', :version => Testbot.version, :hostname => 'macmini2.local', :uid => "00:02", :idle_instances => 4
420
+ Runner.find_by_uid("00:02").update(:last_seen_at => Time.now - 10)
421
+ get '/runners'
422
+ assert last_response.ok?
423
+ parsed_body = JSON.parse(last_response.body)
424
+ assert_equal 1, parsed_body.size
425
+ assert_equal '00:01', parsed_body.first["uid"]
426
+ end
427
+
428
+ end
429
+
430
+ context "GET /status" do
431
+
432
+ should "return the contents of the status page" do
433
+ get '/status'
434
+ assert_equal true, last_response.body.include?('Testbot status')
435
+ end
436
+
437
+ end
438
+
439
+ context "GET /status/:dir/:file" do
440
+
441
+ should "return the file" do
442
+ get "/status/javascripts/jquery-1.4.4.min.js"
443
+ assert_equal true, last_response.body.include?('jQuery JavaScript Library v1.4.4')
444
+ end
445
+
446
+ end
447
+
448
+ end
449
+
450
+ end
451
+