testbot 0.5.2 → 0.5.3
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +1 -1
- data/README.markdown +1 -1
- data/Rakefile +53 -0
- data/lib/shared/testbot.rb +1 -1
- data/test/fixtures/local/Rakefile +7 -0
- data/test/fixtures/local/config/testbot.yml +5 -0
- data/test/fixtures/local/log/test.log +0 -0
- data/test/fixtures/local/script/spec +2 -0
- data/test/fixtures/local/spec/models/car_spec.rb +0 -0
- data/test/fixtures/local/spec/models/house_spec.rb +0 -0
- data/test/fixtures/local/spec/spec.opts +0 -0
- data/test/fixtures/local/tmp/restart.txt +0 -0
- data/test/requester/test_requester.rb +346 -0
- data/test/runner/test_job.rb +70 -0
- data/test/server/test_group.rb +43 -0
- data/test/server/test_server.rb +451 -0
- data/test/shared/adapters/helpers/test_ruby_env.rb +76 -0
- data/test/shared/adapters/test_adapter.rb +21 -0
- data/test/shared/test_testbot.rb +185 -0
- data/test/test_integration.rb +55 -0
- data/testbot.gemspec +2 -1
- metadata +34 -3
@@ -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
|
+
|