testbot 0.5.2 → 0.5.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
+