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.
- 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
|
+
|