testbot 0.6.3 → 0.6.4
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +8 -0
- data/README.markdown +1 -1
- data/lib/requester/requester.rb +12 -2
- data/lib/server/runner.rb +1 -1
- data/lib/server/server.rb +5 -1
- data/lib/shared/adapters/helpers/ruby_env.rb +3 -3
- data/lib/shared/version.rb +1 -1
- data/test/requester/requester_test.rb +45 -15
- data/test/server/server_test.rb +20 -4
- data/test/shared/adapters/helpers/ruby_env_test.rb +10 -2
- metadata +3 -3
data/CHANGELOG
CHANGED
@@ -1,3 +1,11 @@
|
|
1
|
+
0.6.4
|
2
|
+
|
3
|
+
Fixed bug with running test unit tests that caused errors like '/bin/ruby:1: Invalid char `\317' in expression`'.
|
4
|
+
|
5
|
+
Now handling errors creating builds.
|
6
|
+
|
7
|
+
Returning 503 and reporting that there are no runners when that is the case.
|
8
|
+
|
1
9
|
0.6.3
|
2
10
|
|
3
11
|
Results are now shown as they happen. It takes care not to break escape codes used for
|
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.6.
|
67
|
+
ruby script/plugin install git://github.com/joakimk/testbot.git -r 'refs/tags/v0.6.4'
|
68
68
|
script/generate testbot --connect 192.168.0.100
|
69
69
|
|
70
70
|
rake testbot:spec (or :rspec, :test, :features)
|
data/lib/requester/requester.rb
CHANGED
@@ -51,13 +51,23 @@ module Testbot::Requester
|
|
51
51
|
|
52
52
|
build_id = nil
|
53
53
|
log "Requesting run" do
|
54
|
-
|
54
|
+
response = HTTParty.post("#{server_uri}/builds", :body => { :root => root,
|
55
55
|
:type => adapter.type.to_s,
|
56
56
|
:project => config.project,
|
57
57
|
:available_runner_usage => config.available_runner_usage,
|
58
58
|
:files => files.join(' '),
|
59
59
|
:sizes => sizes.join(' '),
|
60
|
-
:jruby => jruby? })
|
60
|
+
:jruby => jruby? }).response
|
61
|
+
|
62
|
+
if response.code == "503"
|
63
|
+
puts "No runners available. If you just started a runner, try again. It usually takes a few seconds before they're available."
|
64
|
+
return false
|
65
|
+
elsif response.code != "200"
|
66
|
+
puts "Could not create build, #{response.code}: #{response.body}"
|
67
|
+
return false
|
68
|
+
else
|
69
|
+
build_id = response.body
|
70
|
+
end
|
61
71
|
end
|
62
72
|
|
63
73
|
trap("SIGINT") { HTTParty.delete("#{server_uri}/builds/#{build_id}"); return false }
|
data/lib/server/runner.rb
CHANGED
@@ -30,7 +30,7 @@ module Testbot::Server
|
|
30
30
|
end
|
31
31
|
|
32
32
|
def self.find_all_available
|
33
|
-
all.find_all { |r| r.version == Testbot.version && r.last_seen_at > (Time.now - Runner.timeout) }
|
33
|
+
all.find_all { |r| r.idle_instances && r.version == Testbot.version && r.last_seen_at > (Time.now - Runner.timeout) }
|
34
34
|
end
|
35
35
|
|
36
36
|
def self.available_instances
|
data/lib/server/server.rb
CHANGED
@@ -24,7 +24,11 @@ module Testbot::Server
|
|
24
24
|
end
|
25
25
|
|
26
26
|
post '/builds' do
|
27
|
-
|
27
|
+
if Runner.total_instances == 0
|
28
|
+
[ 503, "No runners available" ]
|
29
|
+
else
|
30
|
+
Build.create_and_build_jobs(params).id.to_s
|
31
|
+
end
|
28
32
|
end
|
29
33
|
|
30
34
|
get '/builds/:id' do
|
@@ -12,13 +12,13 @@ class RubyEnv
|
|
12
12
|
elsif opts[:bin]
|
13
13
|
command = opts[:bin]
|
14
14
|
else
|
15
|
-
command =
|
15
|
+
command = nil
|
16
16
|
end
|
17
17
|
|
18
18
|
if bundler?(project_path)
|
19
|
-
"#{ruby_interpreter} -S bundle exec #{command}"
|
19
|
+
"#{ruby_interpreter} -S bundle exec #{command}".strip
|
20
20
|
else
|
21
|
-
"#{ruby_interpreter} -S #{command}"
|
21
|
+
"#{ruby_interpreter} -S #{command}".strip
|
22
22
|
end
|
23
23
|
end
|
24
24
|
|
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.6.
|
4
|
+
version = "0.6.4"
|
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)
|
@@ -17,7 +17,7 @@ module Testbot::Requester
|
|
17
17
|
requester = Requester.new(:server_host => "192.168.1.100", :rsync_path => 'user@server:/tmp/somewhere')
|
18
18
|
|
19
19
|
flexmock(requester).should_receive(:find_tests).and_return([])
|
20
|
-
flexmock(HTTParty).should_receive(:post).and_return(
|
20
|
+
flexmock(HTTParty).should_receive(:post).and_return(response_with_build_id)
|
21
21
|
flexmock(requester).should_receive(:sleep).once
|
22
22
|
flexmock(requester).should_receive(:print).once
|
23
23
|
flexmock(requester).should_receive(:puts).once
|
@@ -27,6 +27,14 @@ module Testbot::Requester
|
|
27
27
|
requester
|
28
28
|
end
|
29
29
|
|
30
|
+
def response_with_build_id
|
31
|
+
OpenStruct.new(:response => OpenStruct.new(:code => "200", :body => "5"))
|
32
|
+
end
|
33
|
+
|
34
|
+
def error_response(opts = {})
|
35
|
+
OpenStruct.new(:response => OpenStruct.new(opts))
|
36
|
+
end
|
37
|
+
|
30
38
|
def build_with_result(results)
|
31
39
|
requester_with_result(results).run_tests(RspecAdapter, 'spec')
|
32
40
|
end
|
@@ -97,7 +105,7 @@ module Testbot::Requester
|
|
97
105
|
:files => "spec/models/house_spec.rb" +
|
98
106
|
" spec/models/car_spec.rb",
|
99
107
|
:sizes => "10 20",
|
100
|
-
:jruby => false })
|
108
|
+
:jruby => false }).and_return(response_with_build_id)
|
101
109
|
|
102
110
|
flexmock(HTTParty).should_receive(:get).and_return({ "done" => true, 'results' => '', "success" => true })
|
103
111
|
flexmock(requester).should_receive(:sleep)
|
@@ -108,13 +116,35 @@ module Testbot::Requester
|
|
108
116
|
assert_equal true, requester.run_tests(RspecAdapter, 'spec')
|
109
117
|
end
|
110
118
|
|
119
|
+
should "print a message and exit if the status is 503" do
|
120
|
+
requester = Requester.new(:server_host => "192.168.1.100")
|
121
|
+
|
122
|
+
flexmock(requester).should_receive(:find_tests).and_return([ 'spec/models/house_spec.rb', 'spec_models/car_spec.rb' ])
|
123
|
+
flexmock(requester).should_receive(:system)
|
124
|
+
|
125
|
+
flexmock(HTTParty).should_receive(:post).and_return(error_response(:code => "503"))
|
126
|
+
flexmock(requester).should_receive(:puts)
|
127
|
+
assert_equal false, requester.run_tests(RspecAdapter, 'spec')
|
128
|
+
end
|
129
|
+
|
130
|
+
should "print what the server returns in case there is anything but a 200 response" do
|
131
|
+
requester = Requester.new(:server_host => "192.168.1.100")
|
132
|
+
|
133
|
+
flexmock(requester).should_receive(:find_tests).and_return([ 'spec/models/house_spec.rb', 'spec_models/car_spec.rb' ])
|
134
|
+
flexmock(requester).should_receive(:system)
|
135
|
+
|
136
|
+
flexmock(HTTParty).should_receive(:post).and_return(error_response(:code => "123", :body => "Some error"))
|
137
|
+
flexmock(requester).should_receive(:puts).with("Could not create build, 123: Some error")
|
138
|
+
assert_equal false, requester.run_tests(RspecAdapter, 'spec')
|
139
|
+
end
|
140
|
+
|
111
141
|
should "print the sum of results formatted by the adapter" do
|
112
142
|
requester = Requester.new(:server_host => "192.168.1.100")
|
113
143
|
|
114
144
|
flexmock(requester).should_receive(:find_tests).and_return([ 'spec/models/house_spec.rb', 'spec_models/car_spec.rb' ])
|
115
145
|
flexmock(requester).should_receive(:system)
|
116
146
|
|
117
|
-
flexmock(HTTParty).should_receive(:post).and_return(
|
147
|
+
flexmock(HTTParty).should_receive(:post).and_return(response_with_build_id)
|
118
148
|
|
119
149
|
flexmock(HTTParty).should_receive(:get).times(2).with("http://192.168.1.100:#{Testbot::SERVER_PORT}/builds/5",
|
120
150
|
:format => :json).and_return({ "done" => false, "results" => "job 2 done: ...." },
|
@@ -136,7 +166,7 @@ module Testbot::Requester
|
|
136
166
|
flexmock(requester).should_receive(:find_tests).and_return([ 'spec/models/house_spec.rb', 'spec_models/car_spec.rb' ])
|
137
167
|
flexmock(requester).should_receive(:system)
|
138
168
|
|
139
|
-
flexmock(HTTParty).should_receive(:post).and_return(
|
169
|
+
flexmock(HTTParty).should_receive(:post).and_return(response_with_build_id)
|
140
170
|
|
141
171
|
flexmock(HTTParty).should_receive(:get).times(2).with("http://192.168.1.100:#{Testbot::SERVER_PORT}/builds/5",
|
142
172
|
:format => :json).and_return({ "done" => false, "results" => "job 2 done: ...." },
|
@@ -157,7 +187,7 @@ module Testbot::Requester
|
|
157
187
|
flexmock(requester).should_receive(:find_tests).and_return([ 'spec/models/house_spec.rb', 'spec_models/car_spec.rb' ])
|
158
188
|
flexmock(requester).should_receive(:system)
|
159
189
|
|
160
|
-
flexmock(HTTParty).should_receive(:post).and_return(
|
190
|
+
flexmock(HTTParty).should_receive(:post).and_return(response_with_build_id)
|
161
191
|
|
162
192
|
flexmock(HTTParty).should_receive(:get).once.with("http://192.168.1.100:#{Testbot::SERVER_PORT}/builds/5",
|
163
193
|
:format => :json).and_return({ "success" => false, "done" => true, "results" => "job 2 done: ....job 1 done: ...." })
|
@@ -176,7 +206,7 @@ module Testbot::Requester
|
|
176
206
|
flexmock(requester).should_receive(:find_tests).and_return([ 'spec/models/house_spec.rb', 'spec_models/car_spec.rb' ])
|
177
207
|
flexmock(requester).should_receive(:system)
|
178
208
|
|
179
|
-
flexmock(HTTParty).should_receive(:post).and_return(
|
209
|
+
flexmock(HTTParty).should_receive(:post).and_return(response_with_build_id)
|
180
210
|
|
181
211
|
flexmock(HTTParty).should_receive(:get).times(2).with("http://192.168.1.100:#{Testbot::SERVER_PORT}/builds/5",
|
182
212
|
:format => :json).and_return({ "done" => false, "results" => "" },
|
@@ -196,7 +226,7 @@ module Testbot::Requester
|
|
196
226
|
flexmock(requester).should_receive(:find_tests).and_return([ 'spec/models/house_spec.rb', 'spec_models/car_spec.rb' ])
|
197
227
|
flexmock(requester).should_receive(:system)
|
198
228
|
|
199
|
-
flexmock(HTTParty).should_receive(:post).and_return(
|
229
|
+
flexmock(HTTParty).should_receive(:post).and_return(response_with_build_id)
|
200
230
|
flexmock(requester).should_receive(:sleep).once
|
201
231
|
flexmock(requester).should_receive(:print)
|
202
232
|
flexmock(requester).should_receive(:puts)
|
@@ -215,7 +245,7 @@ module Testbot::Requester
|
|
215
245
|
flexmock(requester).should_receive(:find_tests).and_return([ 'spec/models/house_spec.rb', 'spec_models/car_spec.rb' ])
|
216
246
|
flexmock(requester).should_receive(:system)
|
217
247
|
|
218
|
-
flexmock(HTTParty).should_receive(:post).and_return(
|
248
|
+
flexmock(HTTParty).should_receive(:post).and_return(response_with_build_id)
|
219
249
|
|
220
250
|
flexmock(HTTParty).should_receive(:get).times(5).with("http://192.168.1.100:#{Testbot::SERVER_PORT}/builds/5",
|
221
251
|
:format => :json).and_raise('some connection error')
|
@@ -237,7 +267,7 @@ module Testbot::Requester
|
|
237
267
|
flexmock(requester).should_receive(:find_tests).and_return([ 'spec/models/house_spec.rb', 'spec_models/car_spec.rb' ])
|
238
268
|
flexmock(requester).should_receive(:system)
|
239
269
|
|
240
|
-
flexmock(HTTParty).should_receive(:post).and_return(
|
270
|
+
flexmock(HTTParty).should_receive(:post).and_return(response_with_build_id)
|
241
271
|
|
242
272
|
flexmock(HTTParty).should_receive(:get).times(2).with("http://192.168.1.100:#{Testbot::SERVER_PORT}/builds/5",
|
243
273
|
:format => :json).and_return(nil,
|
@@ -257,7 +287,7 @@ module Testbot::Requester
|
|
257
287
|
flexmock(requester).should_receive(:find_tests).and_return([ 'spec/models/house_spec.rb', 'spec_models/car_spec.rb' ])
|
258
288
|
flexmock(requester).should_receive(:system)
|
259
289
|
|
260
|
-
flexmock(HTTParty).should_receive(:post).and_return(
|
290
|
+
flexmock(HTTParty).should_receive(:post).and_return(response_with_build_id)
|
261
291
|
|
262
292
|
flexmock(HTTParty).should_receive(:get).times(2).with("http://192.168.1.100:#{Testbot::SERVER_PORT}/builds/5",
|
263
293
|
:format => :json).and_return(nil,
|
@@ -282,7 +312,7 @@ module Testbot::Requester
|
|
282
312
|
flexmock(ssh_tunnel).should_receive(:open).once
|
283
313
|
|
284
314
|
flexmock(requester).should_receive(:find_tests).and_return([ 'spec/models/house_spec.rb' ])
|
285
|
-
flexmock(HTTParty).should_receive(:post).with("http://127.0.0.1:2299/builds", any).and_return(
|
315
|
+
flexmock(HTTParty).should_receive(:post).with("http://127.0.0.1:2299/builds", any).and_return(response_with_build_id)
|
286
316
|
flexmock(HTTParty).should_receive(:get).and_return({ "done" => true, "results" => "job 1 done: ...." })
|
287
317
|
flexmock(requester).should_receive(:sleep)
|
288
318
|
flexmock(requester).should_receive(:print)
|
@@ -300,7 +330,7 @@ module Testbot::Requester
|
|
300
330
|
flexmock(ssh_tunnel).should_receive(:open).once
|
301
331
|
|
302
332
|
flexmock(requester).should_receive(:find_tests).and_return([ 'spec/models/house_spec.rb' ])
|
303
|
-
flexmock(HTTParty).should_receive(:post).with("http://127.0.0.1:2299/builds", any).and_return(
|
333
|
+
flexmock(HTTParty).should_receive(:post).with("http://127.0.0.1:2299/builds", any).and_return(response_with_build_id)
|
304
334
|
flexmock(HTTParty).should_receive(:get).and_return({ "done" => true, "results" => "job 1 done: ...." })
|
305
335
|
flexmock(requester).should_receive(:sleep)
|
306
336
|
flexmock(requester).should_receive(:print)
|
@@ -320,7 +350,7 @@ module Testbot::Requester
|
|
320
350
|
flexmock(ssh_tunnel).should_receive(:open).once
|
321
351
|
|
322
352
|
flexmock(requester).should_receive(:find_tests).and_return([ 'features/some.feature' ])
|
323
|
-
flexmock(HTTParty).should_receive(:post).with("http://127.0.0.1:2230/builds", any).and_return(
|
353
|
+
flexmock(HTTParty).should_receive(:post).with("http://127.0.0.1:2230/builds", any).and_return(response_with_build_id)
|
324
354
|
flexmock(HTTParty).should_receive(:get).and_return({ "done" => true, "results" => "job 1 done: ...." })
|
325
355
|
flexmock(requester).should_receive(:sleep)
|
326
356
|
flexmock(requester).should_receive(:print)
|
@@ -338,7 +368,7 @@ module Testbot::Requester
|
|
338
368
|
flexmock(ssh_tunnel).should_receive(:open).once
|
339
369
|
|
340
370
|
flexmock(requester).should_receive(:find_tests).and_return([ 'test/some_test.rb' ])
|
341
|
-
flexmock(HTTParty).should_receive(:post).with("http://127.0.0.1:2231/builds", any).and_return(
|
371
|
+
flexmock(HTTParty).should_receive(:post).with("http://127.0.0.1:2231/builds", any).and_return(response_with_build_id)
|
342
372
|
flexmock(HTTParty).should_receive(:get).and_return({ "done" => true, "results" => "job 1 done: ...." })
|
343
373
|
flexmock(requester).should_receive(:sleep)
|
344
374
|
flexmock(requester).should_receive(:print)
|
@@ -359,7 +389,7 @@ module Testbot::Requester
|
|
359
389
|
:sizes=>"0", :project=>"project" }
|
360
390
|
|
361
391
|
flexmock(TestUnitAdapter).should_receive(:test_files).and_return([ 'test/some_test.rb' ])
|
362
|
-
flexmock(HTTParty).should_receive(:post).with(any, :body => other_args.merge({ :jruby => true })).and_return(
|
392
|
+
flexmock(HTTParty).should_receive(:post).with(any, :body => other_args.merge({ :jruby => true })).and_return(response_with_build_id)
|
363
393
|
flexmock(HTTParty).should_receive(:get).and_return({ "done" => true, "results" => "job 1 done: ...." })
|
364
394
|
flexmock(requester).should_receive(:sleep)
|
365
395
|
flexmock(requester).should_receive(:print)
|
data/test/server/server_test.rb
CHANGED
@@ -62,6 +62,14 @@ module Testbot::Server
|
|
62
62
|
assert_equal Build.all.first, first_job.build
|
63
63
|
end
|
64
64
|
|
65
|
+
should "return a 503 error if there are no known runners" do
|
66
|
+
flexmock(Runner).should_receive(:total_instances).and_return(0)
|
67
|
+
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%", :project => 'things', :sizes => "1 1 1 1", :jruby => true
|
68
|
+
assert_equal 0, Job.count
|
69
|
+
assert_equal 503, last_response.status
|
70
|
+
assert_equal "No runners available", last_response.body
|
71
|
+
end
|
72
|
+
|
65
73
|
should "only use resources according to available_runner_usage" do
|
66
74
|
flexmock(Runner).should_receive(:total_instances).and_return(4)
|
67
75
|
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([])
|
@@ -267,6 +275,14 @@ module Testbot::Server
|
|
267
275
|
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
|
268
276
|
end
|
269
277
|
|
278
|
+
should "not return a runner as available when it hasnt pinged the server yet" do
|
279
|
+
get '/jobs/next', :version => Testbot.version, :hostname => 'macmini1.local', :uid => "00:01", :username => 'user1'
|
280
|
+
get '/jobs/next', :version => Testbot.version, :hostname => 'macmini2.local', :uid => "00:02", :idle_instances => 4, :username => 'user2'
|
281
|
+
get '/runners/available'
|
282
|
+
assert last_response.ok?
|
283
|
+
assert_equal "127.0.0.1 macmini2.local 00:02 user2 4", last_response.body
|
284
|
+
end
|
285
|
+
|
270
286
|
should "not return runners as available when not seen the last 10 seconds" do
|
271
287
|
get '/jobs/next', :version => Testbot.version, :hostname => 'macmini1.local', :uid => "00:01", :idle_instances => 2, :username => "user1"
|
272
288
|
get '/jobs/next', :version => Testbot.version, :hostname => 'macmini2.local', :uid => "00:02", :idle_instances => 4
|
@@ -301,16 +317,16 @@ module Testbot::Server
|
|
301
317
|
context "GET /runners/total_instances" do
|
302
318
|
|
303
319
|
should "return the number of available runner instances" do
|
304
|
-
get '/jobs/next', :version => Testbot.version, :hostname => 'macmini1.local', :uid => "00:01", :max_instances => 2
|
305
|
-
get '/jobs/next', :version => Testbot.version, :hostname => 'macmini2.local', :uid => "00:02", :max_instances => 4
|
320
|
+
get '/jobs/next', :version => Testbot.version, :hostname => 'macmini1.local', :uid => "00:01", :max_instances => 2, :idle_instances => 1
|
321
|
+
get '/jobs/next', :version => Testbot.version, :hostname => 'macmini2.local', :uid => "00:02", :max_instances => 4, :idle_instances => 2
|
306
322
|
get '/runners/total_instances'
|
307
323
|
assert last_response.ok?
|
308
324
|
assert_equal "6", last_response.body
|
309
325
|
end
|
310
326
|
|
311
327
|
should "not return instances as available when not seen the last 10 seconds" do
|
312
|
-
get '/jobs/next', :version => Testbot.version, :hostname => 'macmini1.local', :uid => "00:01", :max_instances => 2
|
313
|
-
get '/jobs/next', :version => Testbot.version, :hostname => 'macmini2.local', :uid => "00:02", :max_instances => 4
|
328
|
+
get '/jobs/next', :version => Testbot.version, :hostname => 'macmini1.local', :uid => "00:01", :max_instances => 2, :idle_instances => 1
|
329
|
+
get '/jobs/next', :version => Testbot.version, :hostname => 'macmini2.local', :uid => "00:02", :max_instances => 4, :idle_instances => 2
|
314
330
|
Runner.find_by_uid("00:02").update(:last_seen_at => Time.now - 10)
|
315
331
|
get '/runners/total_instances'
|
316
332
|
assert last_response.ok?
|
@@ -71,11 +71,19 @@ class RubyEnvTest < Test::Unit::TestCase
|
|
71
71
|
:bin => "rspec", :ruby_interpreter => "jruby")
|
72
72
|
end
|
73
73
|
|
74
|
-
should "
|
74
|
+
should "work when there is no binary specified and bundler is present" do
|
75
75
|
flexmock(RubyEnv).should_receive(:bundler?).and_return(true)
|
76
76
|
flexmock(File).should_receive(:exists?).and_return(false)
|
77
|
-
assert_equal 'ruby -S bundle exec
|
77
|
+
assert_equal 'ruby -S bundle exec', RubyEnv.ruby_command("path/to/project")
|
78
78
|
end
|
79
|
+
|
80
|
+
should "work when there is no binary specified and bundler is not present" do
|
81
|
+
flexmock(RubyEnv).should_receive(:bundler?).and_return(false)
|
82
|
+
flexmock(File).should_receive(:exists?).and_return(false)
|
83
|
+
assert_equal 'ruby -S', RubyEnv.ruby_command("path/to/project")
|
84
|
+
end
|
85
|
+
|
86
|
+
|
79
87
|
end
|
80
88
|
|
81
89
|
end
|
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: 15
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 6
|
9
|
-
-
|
10
|
-
version: 0.6.
|
9
|
+
- 4
|
10
|
+
version: 0.6.4
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- "Joakim Kolsj\xC3\xB6"
|