testbot 0.5.8 → 0.5.9
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +8 -0
- data/README.markdown +2 -1
- data/lib/requester/requester.rb +1 -0
- data/lib/runner/job.rb +13 -1
- data/lib/runner/runner.rb +7 -3
- data/lib/server/server.rb +12 -1
- data/lib/shared/version.rb +1 -1
- data/test/server/server_test.rb +19 -3
- metadata +68 -68
data/CHANGELOG
CHANGED
@@ -1,3 +1,11 @@
|
|
1
|
+
0.5.9
|
2
|
+
|
3
|
+
When you hit ctrl+c all related test jobs will be stopped (within about 5 seconds). You can
|
4
|
+
now exit, change code and re-run much faster than before.
|
5
|
+
|
6
|
+
It does not stop before_run or code fetch. But no tests will be run after
|
7
|
+
those complete when the build is stopped.
|
8
|
+
|
1
9
|
0.5.8
|
2
10
|
|
3
11
|
Now only running tests from one build on a runner at a time.
|
data/README.markdown
CHANGED
@@ -64,7 +64,7 @@ Using testbot with Rails 2:
|
|
64
64
|
|
65
65
|
# Add testbot to your Gemfile if you use bundler. You also need the plugin because
|
66
66
|
# Rails 2 does not load raketasks from gems.
|
67
|
-
ruby script/plugin install git://github.com/joakimk/testbot.git -r 'refs/tags/v0.5.
|
67
|
+
ruby script/plugin install git://github.com/joakimk/testbot.git -r 'refs/tags/v0.5.9'
|
68
68
|
script/generate testbot --connect 192.168.0.100
|
69
69
|
|
70
70
|
rake testbot:spec (or :rspec, :test, :features)
|
@@ -107,6 +107,7 @@ Features
|
|
107
107
|
* Testbot will try to balance the testload so that every computer finishes running the tests at the same time to reduce the time it takes to run the entire test suite. It does a good job, but has potential for further improvement.
|
108
108
|
* You can access your testbot network through SSH by using the built in SSH tunneling code.
|
109
109
|
* You can use the same testbot network with multiple projects.
|
110
|
+
* You can abort a test run with ctrl+c and all remote processes will be stopped.
|
110
111
|
* Testbot is continuously tested for compability with Ruby 1.8.7 and 1.9.2.
|
111
112
|
|
112
113
|
Contributing to testbot
|
data/lib/requester/requester.rb
CHANGED
data/lib/runner/job.rb
CHANGED
@@ -14,6 +14,7 @@ module Testbot::Runner
|
|
14
14
|
end
|
15
15
|
|
16
16
|
def run(instance)
|
17
|
+
return if @killed
|
17
18
|
puts "Running job #{@id} (build #{@build_id})... "
|
18
19
|
test_env_number = (instance == 0) ? '' : instance + 1
|
19
20
|
result = "\n#{`hostname`.chomp}:#{Dir.pwd}\n"
|
@@ -28,6 +29,14 @@ module Testbot::Runner
|
|
28
29
|
puts "Job #{@id} finished."
|
29
30
|
end
|
30
31
|
|
32
|
+
def kill!(build_id)
|
33
|
+
if @build_id == build_id && @test_process
|
34
|
+
# The child process that runs the tests is a shell, we need to kill it's child process
|
35
|
+
system("pkill -KILL -P #{@test_process.pid}")
|
36
|
+
@killed = true
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
31
40
|
private
|
32
41
|
|
33
42
|
def measure_run_time
|
@@ -37,7 +46,10 @@ module Testbot::Runner
|
|
37
46
|
end
|
38
47
|
|
39
48
|
def run_and_return_result(command)
|
40
|
-
|
49
|
+
@test_process = open("|#{command} 2>&1", 'r')
|
50
|
+
output = @test_process.read
|
51
|
+
@test_process.close
|
52
|
+
output
|
41
53
|
end
|
42
54
|
|
43
55
|
def success?
|
data/lib/runner/runner.rb
CHANGED
@@ -107,9 +107,9 @@ module Testbot::Runner
|
|
107
107
|
before_run(job) if File.exists?("#{job.project}/lib/tasks/testbot.rake")
|
108
108
|
end
|
109
109
|
|
110
|
+
@last_build_id = job.build_id
|
110
111
|
@instances << [ Thread.new { job.run(free_instance_number) },
|
111
112
|
free_instance_number, job ]
|
112
|
-
@last_build_id = job.build_id
|
113
113
|
loop do
|
114
114
|
clear_completed_instances
|
115
115
|
break unless max_instances_running?
|
@@ -164,7 +164,7 @@ module Testbot::Runner
|
|
164
164
|
|
165
165
|
def ping_params
|
166
166
|
{ :hostname => (@hostname ||= `hostname`.chomp), :max_instances => @config.max_instances,
|
167
|
-
:idle_instances => (@config.max_instances - @instances.size), :username => ENV['USER'] }.merge(base_params)
|
167
|
+
:idle_instances => (@config.max_instances - @instances.size), :username => ENV['USER'], :build_id => @last_build_id }.merge(base_params)
|
168
168
|
end
|
169
169
|
|
170
170
|
def base_params
|
@@ -191,7 +191,11 @@ module Testbot::Runner
|
|
191
191
|
Thread.new do
|
192
192
|
while true
|
193
193
|
begin
|
194
|
-
Server.get("/runners/ping", :body => ping_params)
|
194
|
+
response = Server.get("/runners/ping", :body => ping_params).body
|
195
|
+
if response.include?('stop_build')
|
196
|
+
build_id = response.split(',').last
|
197
|
+
@instances.each { |instance, n, job| job.kill!(build_id) }
|
198
|
+
end
|
195
199
|
rescue
|
196
200
|
end
|
197
201
|
sleep TIME_BETWEEN_PINGS
|
data/lib/server/server.rb
CHANGED
@@ -33,6 +33,12 @@ module Testbot::Server
|
|
33
33
|
{ "done" => build.done, "results" => build.results, "success" => build.success }.to_json
|
34
34
|
end
|
35
35
|
|
36
|
+
delete '/builds/:id' do
|
37
|
+
build = Build.find(params[:id])
|
38
|
+
build.destroy if build
|
39
|
+
nil
|
40
|
+
end
|
41
|
+
|
36
42
|
get '/jobs/next' do
|
37
43
|
next_job, runner = Job.next(params, @env['REMOTE_ADDR'])
|
38
44
|
if next_job
|
@@ -48,7 +54,12 @@ module Testbot::Server
|
|
48
54
|
get '/runners/ping' do
|
49
55
|
return unless Server.valid_version?(params[:version])
|
50
56
|
runner = Runner.find_by_uid(params[:uid])
|
51
|
-
|
57
|
+
if runner
|
58
|
+
runner.update(params.reject { |k, v| k == "build_id" }.merge({ :last_seen_at => Time.now, :build => Build.find(params[:build_id]) }))
|
59
|
+
unless params[:build_id] == '' || params[:build_id] == nil || runner.build
|
60
|
+
return "stop_build,#{params[:build_id]}"
|
61
|
+
end
|
62
|
+
end
|
52
63
|
nil
|
53
64
|
end
|
54
65
|
|
data/lib/shared/version.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
module Testbot
|
2
2
|
# Don't forget to update readme and changelog
|
3
3
|
def self.version
|
4
|
-
version = "0.5.
|
4
|
+
version = "0.5.9"
|
5
5
|
dev_version_file = File.join(File.dirname(__FILE__), '..', '..', 'DEV_VERSION')
|
6
6
|
if File.exists?(dev_version_file)
|
7
7
|
version += File.read(dev_version_file)
|
data/test/server/server_test.rb
CHANGED
@@ -330,8 +330,9 @@ module Testbot::Server
|
|
330
330
|
end
|
331
331
|
|
332
332
|
should "update data on the runner" do
|
333
|
+
build = Build.create
|
333
334
|
runner = Runner.create(:uid => 'aa:aa:..')
|
334
|
-
get "/runners/ping", :uid => 'aa:aa:..', :max_instances => 4, :idle_instances => 2, :hostname => "hostname1", :version => Testbot.version, :username => 'jocke'
|
335
|
+
get "/runners/ping", :uid => 'aa:aa:..', :max_instances => 4, :idle_instances => 2, :hostname => "hostname1", :version => Testbot.version, :username => 'jocke', :build_id => build.id
|
335
336
|
assert last_response.ok?
|
336
337
|
assert_equal 'aa:aa:..', runner.uid
|
337
338
|
assert_equal 4, runner.max_instances
|
@@ -339,6 +340,7 @@ module Testbot::Server
|
|
339
340
|
assert_equal 'hostname1', runner.hostname
|
340
341
|
assert_equal Testbot.version, runner.version
|
341
342
|
assert_equal 'jocke', runner.username
|
343
|
+
assert_equal build, runner.build
|
342
344
|
end
|
343
345
|
|
344
346
|
should "do nothing if the version does not match" do
|
@@ -353,6 +355,20 @@ module Testbot::Server
|
|
353
355
|
assert last_response.ok?
|
354
356
|
end
|
355
357
|
|
358
|
+
should "return an order to stop the build if the build id does not exist anymore" do
|
359
|
+
runner = Runner.create(:uid => 'aa:aa:..')
|
360
|
+
get "/runners/ping", :uid => 'aa:aa:..', :max_instances => 4, :idle_instances => 2, :hostname => "hostname1", :version => Testbot.version, :username => 'jocke', :build_id => 1
|
361
|
+
assert_equal last_response.body, "stop_build,1"
|
362
|
+
end
|
363
|
+
|
364
|
+
should "not return an order to stop a build without an id" do
|
365
|
+
runner = Runner.create(:uid => 'aa:aa:..')
|
366
|
+
get "/runners/ping", :uid => 'aa:aa:..', :max_instances => 4, :idle_instances => 2, :hostname => "hostname1", :version => Testbot.version, :username => 'jocke', :build_id => ''
|
367
|
+
assert_equal last_response.body, ''
|
368
|
+
get "/runners/ping", :uid => 'aa:aa:..', :max_instances => 4, :idle_instances => 2, :hostname => "hostname1", :version => Testbot.version, :username => 'jocke', :build_id => nil
|
369
|
+
assert_equal last_response.body, ''
|
370
|
+
end
|
371
|
+
|
356
372
|
end
|
357
373
|
|
358
374
|
context "PUT /jobs/:id" do
|
@@ -409,11 +425,11 @@ module Testbot::Server
|
|
409
425
|
|
410
426
|
should "return runner information in json format" do
|
411
427
|
get '/jobs/next', :version => Testbot.version, :uid => "00:01"
|
412
|
-
get "/runners/ping", :uid => '00:01', :max_instances => 4, :idle_instances => 2, :hostname => "hostname1", :version => Testbot.version, :username => 'testbot'
|
428
|
+
get "/runners/ping", :uid => '00:01', :max_instances => 4, :idle_instances => 2, :hostname => "hostname1", :version => Testbot.version, :username => 'testbot', :build_id => nil
|
413
429
|
get '/runners'
|
414
430
|
|
415
431
|
assert last_response.ok?
|
416
|
-
assert_equal ([ { "version" => Testbot.version.to_s, "hostname" => 'hostname1', "uid" => "00:01",
|
432
|
+
assert_equal ([ { "version" => Testbot.version.to_s, "build" => nil, "hostname" => 'hostname1', "uid" => "00:01",
|
417
433
|
"idle_instances" => 2, "max_instances" => 4, "username" => 'testbot',
|
418
434
|
"ip" => "127.0.0.1", "last_seen_at" => Runner.first.last_seen_at.to_s } ]),
|
419
435
|
JSON.parse(last_response.body)
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: testbot
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 25
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 5
|
9
|
-
-
|
10
|
-
version: 0.5.
|
9
|
+
- 9
|
10
|
+
version: 0.5.9
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- "Joakim Kolsj\xC3\xB6"
|
@@ -15,11 +15,13 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2011-06-
|
18
|
+
date: 2011-06-30 00:00:00 +02:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
22
|
-
|
22
|
+
name: sinatra
|
23
|
+
prerelease: false
|
24
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
23
25
|
none: false
|
24
26
|
requirements:
|
25
27
|
- - "="
|
@@ -30,12 +32,12 @@ dependencies:
|
|
30
32
|
- 0
|
31
33
|
- 0
|
32
34
|
version: 1.0.0
|
33
|
-
prerelease: false
|
34
|
-
name: sinatra
|
35
35
|
type: :runtime
|
36
|
-
|
36
|
+
version_requirements: *id001
|
37
37
|
- !ruby/object:Gem::Dependency
|
38
|
-
|
38
|
+
name: httparty
|
39
|
+
prerelease: false
|
40
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
39
41
|
none: false
|
40
42
|
requirements:
|
41
43
|
- - ">="
|
@@ -46,12 +48,12 @@ dependencies:
|
|
46
48
|
- 6
|
47
49
|
- 1
|
48
50
|
version: 0.6.1
|
49
|
-
prerelease: false
|
50
|
-
name: httparty
|
51
51
|
type: :runtime
|
52
|
-
|
52
|
+
version_requirements: *id002
|
53
53
|
- !ruby/object:Gem::Dependency
|
54
|
-
|
54
|
+
name: macaddr
|
55
|
+
prerelease: false
|
56
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
55
57
|
none: false
|
56
58
|
requirements:
|
57
59
|
- - ">="
|
@@ -62,12 +64,12 @@ dependencies:
|
|
62
64
|
- 0
|
63
65
|
- 0
|
64
66
|
version: 1.0.0
|
65
|
-
prerelease: false
|
66
|
-
name: macaddr
|
67
67
|
type: :runtime
|
68
|
-
|
68
|
+
version_requirements: *id003
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
|
-
|
70
|
+
name: net-ssh
|
71
|
+
prerelease: false
|
72
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
71
73
|
none: false
|
72
74
|
requirements:
|
73
75
|
- - ">="
|
@@ -78,12 +80,12 @@ dependencies:
|
|
78
80
|
- 0
|
79
81
|
- 23
|
80
82
|
version: 2.0.23
|
81
|
-
prerelease: false
|
82
|
-
name: net-ssh
|
83
83
|
type: :runtime
|
84
|
-
|
84
|
+
version_requirements: *id004
|
85
85
|
- !ruby/object:Gem::Dependency
|
86
|
-
|
86
|
+
name: json_pure
|
87
|
+
prerelease: false
|
88
|
+
requirement: &id005 !ruby/object:Gem::Requirement
|
87
89
|
none: false
|
88
90
|
requirements:
|
89
91
|
- - ">="
|
@@ -94,12 +96,12 @@ dependencies:
|
|
94
96
|
- 4
|
95
97
|
- 6
|
96
98
|
version: 1.4.6
|
97
|
-
prerelease: false
|
98
|
-
name: json_pure
|
99
99
|
type: :runtime
|
100
|
-
|
100
|
+
version_requirements: *id005
|
101
101
|
- !ruby/object:Gem::Dependency
|
102
|
-
|
102
|
+
name: daemons
|
103
|
+
prerelease: false
|
104
|
+
requirement: &id006 !ruby/object:Gem::Requirement
|
103
105
|
none: false
|
104
106
|
requirements:
|
105
107
|
- - ">="
|
@@ -110,12 +112,12 @@ dependencies:
|
|
110
112
|
- 0
|
111
113
|
- 10
|
112
114
|
version: 1.0.10
|
113
|
-
prerelease: false
|
114
|
-
name: daemons
|
115
115
|
type: :runtime
|
116
|
-
|
116
|
+
version_requirements: *id006
|
117
117
|
- !ruby/object:Gem::Dependency
|
118
|
-
|
118
|
+
name: acts_as_rails3_generator
|
119
|
+
prerelease: false
|
120
|
+
requirement: &id007 !ruby/object:Gem::Requirement
|
119
121
|
none: false
|
120
122
|
requirements:
|
121
123
|
- - ">="
|
@@ -124,12 +126,12 @@ dependencies:
|
|
124
126
|
segments:
|
125
127
|
- 0
|
126
128
|
version: "0"
|
127
|
-
prerelease: false
|
128
|
-
name: acts_as_rails3_generator
|
129
129
|
type: :runtime
|
130
|
-
|
130
|
+
version_requirements: *id007
|
131
131
|
- !ruby/object:Gem::Dependency
|
132
|
-
|
132
|
+
name: shoulda
|
133
|
+
prerelease: false
|
134
|
+
requirement: &id008 !ruby/object:Gem::Requirement
|
133
135
|
none: false
|
134
136
|
requirements:
|
135
137
|
- - ">="
|
@@ -138,12 +140,12 @@ dependencies:
|
|
138
140
|
segments:
|
139
141
|
- 0
|
140
142
|
version: "0"
|
141
|
-
prerelease: false
|
142
|
-
name: shoulda
|
143
143
|
type: :development
|
144
|
-
|
144
|
+
version_requirements: *id008
|
145
145
|
- !ruby/object:Gem::Dependency
|
146
|
-
|
146
|
+
name: rack-test
|
147
|
+
prerelease: false
|
148
|
+
requirement: &id009 !ruby/object:Gem::Requirement
|
147
149
|
none: false
|
148
150
|
requirements:
|
149
151
|
- - ">="
|
@@ -152,12 +154,12 @@ dependencies:
|
|
152
154
|
segments:
|
153
155
|
- 0
|
154
156
|
version: "0"
|
155
|
-
prerelease: false
|
156
|
-
name: rack-test
|
157
157
|
type: :development
|
158
|
-
|
158
|
+
version_requirements: *id009
|
159
159
|
- !ruby/object:Gem::Dependency
|
160
|
-
|
160
|
+
name: flexmock
|
161
|
+
prerelease: false
|
162
|
+
requirement: &id010 !ruby/object:Gem::Requirement
|
161
163
|
none: false
|
162
164
|
requirements:
|
163
165
|
- - ">="
|
@@ -166,12 +168,12 @@ dependencies:
|
|
166
168
|
segments:
|
167
169
|
- 0
|
168
170
|
version: "0"
|
169
|
-
prerelease: false
|
170
|
-
name: flexmock
|
171
171
|
type: :development
|
172
|
-
|
172
|
+
version_requirements: *id010
|
173
173
|
- !ruby/object:Gem::Dependency
|
174
|
-
|
174
|
+
name: cucumber
|
175
|
+
prerelease: false
|
176
|
+
requirement: &id011 !ruby/object:Gem::Requirement
|
175
177
|
none: false
|
176
178
|
requirements:
|
177
179
|
- - ">="
|
@@ -180,12 +182,12 @@ dependencies:
|
|
180
182
|
segments:
|
181
183
|
- 0
|
182
184
|
version: "0"
|
183
|
-
prerelease: false
|
184
|
-
name: cucumber
|
185
185
|
type: :development
|
186
|
-
|
186
|
+
version_requirements: *id011
|
187
187
|
- !ruby/object:Gem::Dependency
|
188
|
-
|
188
|
+
name: rvm
|
189
|
+
prerelease: false
|
190
|
+
requirement: &id012 !ruby/object:Gem::Requirement
|
189
191
|
none: false
|
190
192
|
requirements:
|
191
193
|
- - ">="
|
@@ -194,12 +196,12 @@ dependencies:
|
|
194
196
|
segments:
|
195
197
|
- 0
|
196
198
|
version: "0"
|
197
|
-
prerelease: false
|
198
|
-
name: rvm
|
199
199
|
type: :development
|
200
|
-
|
200
|
+
version_requirements: *id012
|
201
201
|
- !ruby/object:Gem::Dependency
|
202
|
-
|
202
|
+
name: rake
|
203
|
+
prerelease: false
|
204
|
+
requirement: &id013 !ruby/object:Gem::Requirement
|
203
205
|
none: false
|
204
206
|
requirements:
|
205
207
|
- - ">="
|
@@ -208,12 +210,12 @@ dependencies:
|
|
208
210
|
segments:
|
209
211
|
- 0
|
210
212
|
version: "0"
|
211
|
-
prerelease: false
|
212
|
-
name: rake
|
213
213
|
type: :development
|
214
|
-
|
214
|
+
version_requirements: *id013
|
215
215
|
- !ruby/object:Gem::Dependency
|
216
|
-
|
216
|
+
name: bundler
|
217
|
+
prerelease: false
|
218
|
+
requirement: &id014 !ruby/object:Gem::Requirement
|
217
219
|
none: false
|
218
220
|
requirements:
|
219
221
|
- - ">="
|
@@ -222,12 +224,12 @@ dependencies:
|
|
222
224
|
segments:
|
223
225
|
- 0
|
224
226
|
version: "0"
|
225
|
-
prerelease: false
|
226
|
-
name: bundler
|
227
227
|
type: :development
|
228
|
-
|
228
|
+
version_requirements: *id014
|
229
229
|
- !ruby/object:Gem::Dependency
|
230
|
-
|
230
|
+
name: guard
|
231
|
+
prerelease: false
|
232
|
+
requirement: &id015 !ruby/object:Gem::Requirement
|
231
233
|
none: false
|
232
234
|
requirements:
|
233
235
|
- - ">="
|
@@ -236,12 +238,12 @@ dependencies:
|
|
236
238
|
segments:
|
237
239
|
- 0
|
238
240
|
version: "0"
|
239
|
-
prerelease: false
|
240
|
-
name: guard
|
241
241
|
type: :development
|
242
|
-
|
242
|
+
version_requirements: *id015
|
243
243
|
- !ruby/object:Gem::Dependency
|
244
|
-
|
244
|
+
name: guard-test
|
245
|
+
prerelease: false
|
246
|
+
requirement: &id016 !ruby/object:Gem::Requirement
|
245
247
|
none: false
|
246
248
|
requirements:
|
247
249
|
- - ">="
|
@@ -250,10 +252,8 @@ dependencies:
|
|
250
252
|
segments:
|
251
253
|
- 0
|
252
254
|
version: "0"
|
253
|
-
prerelease: false
|
254
|
-
name: guard-test
|
255
255
|
type: :development
|
256
|
-
|
256
|
+
version_requirements: *id016
|
257
257
|
description: Testbot is a test distribution tool that works with Rails, RSpec, RSpec2, Test::Unit and Cucumber.
|
258
258
|
email:
|
259
259
|
- joakim.kolsjo@gmail.com
|