sunshine 1.0.0.pre
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +237 -0
- data/Manifest.txt +70 -0
- data/README.txt +277 -0
- data/Rakefile +46 -0
- data/bin/sunshine +5 -0
- data/examples/deploy.rb +61 -0
- data/examples/deploy_tasks.rake +112 -0
- data/examples/standalone_deploy.rb +31 -0
- data/lib/commands/add.rb +96 -0
- data/lib/commands/default.rb +169 -0
- data/lib/commands/list.rb +322 -0
- data/lib/commands/restart.rb +62 -0
- data/lib/commands/rm.rb +83 -0
- data/lib/commands/run.rb +151 -0
- data/lib/commands/start.rb +72 -0
- data/lib/commands/stop.rb +61 -0
- data/lib/sunshine/app.rb +876 -0
- data/lib/sunshine/binder.rb +70 -0
- data/lib/sunshine/crontab.rb +143 -0
- data/lib/sunshine/daemon.rb +380 -0
- data/lib/sunshine/daemons/ar_sendmail.rb +28 -0
- data/lib/sunshine/daemons/delayed_job.rb +30 -0
- data/lib/sunshine/daemons/nginx.rb +104 -0
- data/lib/sunshine/daemons/rainbows.rb +35 -0
- data/lib/sunshine/daemons/server.rb +66 -0
- data/lib/sunshine/daemons/unicorn.rb +26 -0
- data/lib/sunshine/dependencies.rb +103 -0
- data/lib/sunshine/dependency_lib.rb +200 -0
- data/lib/sunshine/exceptions.rb +54 -0
- data/lib/sunshine/healthcheck.rb +83 -0
- data/lib/sunshine/output.rb +131 -0
- data/lib/sunshine/package_managers/apt.rb +48 -0
- data/lib/sunshine/package_managers/dependency.rb +349 -0
- data/lib/sunshine/package_managers/gem.rb +54 -0
- data/lib/sunshine/package_managers/yum.rb +62 -0
- data/lib/sunshine/remote_shell.rb +241 -0
- data/lib/sunshine/repo.rb +128 -0
- data/lib/sunshine/repos/git_repo.rb +122 -0
- data/lib/sunshine/repos/rsync_repo.rb +29 -0
- data/lib/sunshine/repos/svn_repo.rb +78 -0
- data/lib/sunshine/server_app.rb +554 -0
- data/lib/sunshine/shell.rb +384 -0
- data/lib/sunshine.rb +391 -0
- data/templates/logrotate/logrotate.conf.erb +11 -0
- data/templates/nginx/nginx.conf.erb +109 -0
- data/templates/nginx/nginx_optimize.conf +23 -0
- data/templates/nginx/nginx_proxy.conf +13 -0
- data/templates/rainbows/rainbows.conf.erb +18 -0
- data/templates/tasks/sunshine.rake +114 -0
- data/templates/unicorn/unicorn.conf.erb +6 -0
- data/test/fixtures/app_configs/test_app.yml +11 -0
- data/test/fixtures/sunshine_test/test_upload +0 -0
- data/test/mocks/mock_object.rb +179 -0
- data/test/mocks/mock_open4.rb +117 -0
- data/test/test_helper.rb +188 -0
- data/test/unit/test_app.rb +489 -0
- data/test/unit/test_binder.rb +20 -0
- data/test/unit/test_crontab.rb +128 -0
- data/test/unit/test_git_repo.rb +26 -0
- data/test/unit/test_healthcheck.rb +70 -0
- data/test/unit/test_nginx.rb +107 -0
- data/test/unit/test_rainbows.rb +26 -0
- data/test/unit/test_remote_shell.rb +102 -0
- data/test/unit/test_repo.rb +42 -0
- data/test/unit/test_server.rb +324 -0
- data/test/unit/test_server_app.rb +425 -0
- data/test/unit/test_shell.rb +97 -0
- data/test/unit/test_sunshine.rb +157 -0
- data/test/unit/test_svn_repo.rb +55 -0
- data/test/unit/test_unicorn.rb +22 -0
- metadata +217 -0
@@ -0,0 +1,489 @@
|
|
1
|
+
require 'test/test_helper'
|
2
|
+
|
3
|
+
class TestApp < Test::Unit::TestCase
|
4
|
+
|
5
|
+
def setup
|
6
|
+
mock_remote_shell_popen4
|
7
|
+
@svn_url = "svn://subversion/path/to/app_name/trunk"
|
8
|
+
|
9
|
+
@config = {:name => "app_name",
|
10
|
+
:repo => {:type => "svn", :url => @svn_url},
|
11
|
+
:remote_shells => ["user@some_server.com"],
|
12
|
+
:root_path => "/usr/local/my_user/app_name"}
|
13
|
+
|
14
|
+
@app = Sunshine::App.new @config
|
15
|
+
@app.each do |server_app|
|
16
|
+
server_app.extend MockObject
|
17
|
+
server_app.shell.extend MockObject
|
18
|
+
end
|
19
|
+
|
20
|
+
@tmpdir = File.join Dir.tmpdir, "test_sunshine_#{$$}"
|
21
|
+
|
22
|
+
mock_svn_response @app.repo.url
|
23
|
+
end
|
24
|
+
|
25
|
+
def teardown
|
26
|
+
FileUtils.rm_f @tmpdir
|
27
|
+
end
|
28
|
+
|
29
|
+
|
30
|
+
def test_initialize_without_name
|
31
|
+
app = Sunshine::App.new :repo => {:type => "svn", :url => @svn_url},
|
32
|
+
:remote_shells => ["user@some_server.com"]
|
33
|
+
|
34
|
+
assert_equal "app_name", app.name
|
35
|
+
end
|
36
|
+
|
37
|
+
|
38
|
+
def test_initialize_with_config_file
|
39
|
+
app = Sunshine::App.new TEST_APP_CONFIG_FILE
|
40
|
+
config = YAML.load_file(TEST_APP_CONFIG_FILE)[:default]
|
41
|
+
assert_attributes_equal config, app
|
42
|
+
end
|
43
|
+
|
44
|
+
|
45
|
+
def test_initialize_with_file_object
|
46
|
+
file = File.open TEST_APP_CONFIG_FILE
|
47
|
+
app = Sunshine::App.new file
|
48
|
+
config = YAML.load_file(TEST_APP_CONFIG_FILE)[:default]
|
49
|
+
assert_attributes_equal config, app
|
50
|
+
end
|
51
|
+
|
52
|
+
|
53
|
+
def test_initialize_with_options
|
54
|
+
assert_attributes_equal @config, @app
|
55
|
+
end
|
56
|
+
|
57
|
+
|
58
|
+
def test_initialize_with_options_and_config_file
|
59
|
+
app = Sunshine::App.new TEST_APP_CONFIG_FILE, @config
|
60
|
+
assert_attributes_equal @config, app
|
61
|
+
end
|
62
|
+
|
63
|
+
|
64
|
+
def test_app_deploy
|
65
|
+
yield_called = false
|
66
|
+
|
67
|
+
@app.deploy do |app|
|
68
|
+
assert app.connected?
|
69
|
+
|
70
|
+
yield_called = true
|
71
|
+
end
|
72
|
+
|
73
|
+
assert !@app.connected?
|
74
|
+
|
75
|
+
setup_cmd =
|
76
|
+
"test -d #{@app.checkout_path} && rm -rf #{@app.checkout_path}"+
|
77
|
+
" || echo false"
|
78
|
+
|
79
|
+
mkdir_cmd = "mkdir -p #{@app.checkout_path}"
|
80
|
+
|
81
|
+
checkout_cmd = "svn checkout " +
|
82
|
+
"#{@app.repo.scm_flags} #{@app.repo.url} #{@app.checkout_path}"
|
83
|
+
|
84
|
+
run_results = [
|
85
|
+
"mkdir -p #{@app.server_apps.first.directories.join(" ")}",
|
86
|
+
setup_cmd,
|
87
|
+
mkdir_cmd,
|
88
|
+
checkout_cmd,
|
89
|
+
"ln -sfT #{@app.checkout_path} #{@app.current_path}"
|
90
|
+
]
|
91
|
+
|
92
|
+
|
93
|
+
@app.each do |server_app|
|
94
|
+
use_remote_shell server_app.shell
|
95
|
+
|
96
|
+
run_results.each_index do |i|
|
97
|
+
assert_ssh_call run_results[i]
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
assert yield_called
|
102
|
+
end
|
103
|
+
|
104
|
+
|
105
|
+
TEST_CONFIG = <<-STR
|
106
|
+
:conf1:
|
107
|
+
:common: "conf1"
|
108
|
+
:from_conf1: true
|
109
|
+
:not_conf4: "conf1"
|
110
|
+
|
111
|
+
:conf2:
|
112
|
+
:inherits: :conf1
|
113
|
+
:common: "conf2"
|
114
|
+
:from_conf2: true
|
115
|
+
:not_conf4: "conf2"
|
116
|
+
|
117
|
+
:conf3:
|
118
|
+
:common: "conf3"
|
119
|
+
:from_conf3: true
|
120
|
+
:not_conf4: "conf3"
|
121
|
+
|
122
|
+
:conf4:
|
123
|
+
:inherits:
|
124
|
+
- :conf2
|
125
|
+
- :conf3
|
126
|
+
:common: "conf4"
|
127
|
+
:from_conf4: true
|
128
|
+
STR
|
129
|
+
|
130
|
+
def test_merge_config_inheritance
|
131
|
+
all_configs = YAML.load TEST_CONFIG
|
132
|
+
main_conf = all_configs[:conf2]
|
133
|
+
|
134
|
+
main_conf = @app.send(:merge_config_inheritance, main_conf, all_configs)
|
135
|
+
|
136
|
+
assert main_conf[:from_conf1]
|
137
|
+
assert_equal "conf2", main_conf[:common]
|
138
|
+
end
|
139
|
+
|
140
|
+
|
141
|
+
def test_multiple_merge_config_inheritance
|
142
|
+
all_configs = YAML.load TEST_CONFIG
|
143
|
+
main_conf = all_configs[:conf4]
|
144
|
+
|
145
|
+
main_conf = @app.send(:merge_config_inheritance, main_conf, all_configs)
|
146
|
+
|
147
|
+
assert main_conf[:from_conf1]
|
148
|
+
assert main_conf[:from_conf2]
|
149
|
+
assert main_conf[:from_conf3]
|
150
|
+
assert_equal "conf4", main_conf[:common]
|
151
|
+
assert_equal "conf3", main_conf[:not_conf4]
|
152
|
+
end
|
153
|
+
|
154
|
+
|
155
|
+
class MockError < Exception; end
|
156
|
+
|
157
|
+
def test_app_deploy_error_handling
|
158
|
+
[ MockError,
|
159
|
+
Sunshine::CriticalDeployError,
|
160
|
+
Sunshine::FatalDeployError ].each do |error|
|
161
|
+
|
162
|
+
begin
|
163
|
+
app = Sunshine::App.deploy @config do |app|
|
164
|
+
raise error, "#{error} was not caught"
|
165
|
+
end
|
166
|
+
|
167
|
+
rescue MockError => e
|
168
|
+
assert_equal MockError, e.class
|
169
|
+
end
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
|
174
|
+
def test_revert
|
175
|
+
set_mock_response_for @app, 0,
|
176
|
+
"ls -rc1 #{@app.deploys_path}" => [:out, "last_deploy_dir"]
|
177
|
+
|
178
|
+
@app.revert!
|
179
|
+
|
180
|
+
@app.each do |sa|
|
181
|
+
use_remote_shell sa.shell
|
182
|
+
|
183
|
+
assert_ssh_call "rm -rf #{@app.checkout_path}"
|
184
|
+
|
185
|
+
assert_ssh_call "ls -rc1 #{@app.deploys_path}"
|
186
|
+
|
187
|
+
last_deploy = "#{@app.deploys_path}/last_deploy_dir"
|
188
|
+
assert_ssh_call "ln -sfT #{last_deploy} #{@app.current_path}"
|
189
|
+
end
|
190
|
+
end
|
191
|
+
|
192
|
+
|
193
|
+
def test_build_control_scripts
|
194
|
+
@app.add_to_script :start, "start script"
|
195
|
+
@app.add_to_script :stop, "stop script"
|
196
|
+
@app.add_to_script :custom, "custom script"
|
197
|
+
|
198
|
+
@app.build_control_scripts
|
199
|
+
|
200
|
+
each_remote_shell do |ds|
|
201
|
+
|
202
|
+
%w{start stop restart custom env}.each do |script|
|
203
|
+
assert_rsync(/#{script}/, "#{ds.host}:#{@app.checkout_path}/#{script}")
|
204
|
+
end
|
205
|
+
end
|
206
|
+
end
|
207
|
+
|
208
|
+
|
209
|
+
def test_build_deploy_info_file
|
210
|
+
@app.build_deploy_info_file
|
211
|
+
|
212
|
+
each_remote_shell do |ds|
|
213
|
+
assert_rsync(/info/, "#{ds.host}:#{@app.checkout_path}/info")
|
214
|
+
end
|
215
|
+
end
|
216
|
+
|
217
|
+
|
218
|
+
def test_build_erb
|
219
|
+
erb_file = File.join(@tmpdir, "tmp.erb")
|
220
|
+
|
221
|
+
FileUtils.mkdir_p @tmpdir
|
222
|
+
File.open(erb_file, "w+") do |f|
|
223
|
+
f.write "<%= name %>"
|
224
|
+
end
|
225
|
+
|
226
|
+
name = "test name"
|
227
|
+
|
228
|
+
local_name = @app.build_erb(erb_file, binding)
|
229
|
+
app_name = @app.build_erb(erb_file)
|
230
|
+
|
231
|
+
assert_equal name, local_name
|
232
|
+
assert_equal @app.name, app_name
|
233
|
+
end
|
234
|
+
|
235
|
+
|
236
|
+
def test_checkout_codebase
|
237
|
+
@app.checkout_codebase
|
238
|
+
|
239
|
+
each_remote_shell do |ds|
|
240
|
+
path = @app.checkout_path
|
241
|
+
setup_cmd = "test -d #{path} && rm -rf #{path} || echo false"
|
242
|
+
|
243
|
+
url = @app.repo.url
|
244
|
+
flags = @app.repo.scm_flags
|
245
|
+
checkout_cmd =
|
246
|
+
"svn checkout #{flags} #{url} #{path}"
|
247
|
+
|
248
|
+
assert_ssh_call setup_cmd
|
249
|
+
assert_ssh_call checkout_cmd
|
250
|
+
end
|
251
|
+
end
|
252
|
+
|
253
|
+
|
254
|
+
def test_deployed?
|
255
|
+
deployed = @app.deployed?
|
256
|
+
|
257
|
+
state = true
|
258
|
+
@app.server_apps.each do |sa|
|
259
|
+
assert sa.method_called? :deployed?
|
260
|
+
state = false unless sa.deployed?
|
261
|
+
end
|
262
|
+
|
263
|
+
assert_equal state, deployed
|
264
|
+
end
|
265
|
+
|
266
|
+
|
267
|
+
def test_install_deps
|
268
|
+
nginx_dep = Sunshine.dependencies.get 'nginx'
|
269
|
+
ruby_dep = Sunshine.dependencies.get 'ruby'
|
270
|
+
|
271
|
+
yum_sudo = Sunshine::Yum.sudo
|
272
|
+
|
273
|
+
check_nginx = "test \"$(yum list installed #{nginx_dep.pkg} | "+
|
274
|
+
"grep -c #{nginx_dep.pkg})\" -ge 1"
|
275
|
+
check_ruby = "test \"$(yum list installed #{ruby_dep.pkg} | "+
|
276
|
+
"grep -c #{ruby_dep.pkg})\" -ge 1"
|
277
|
+
|
278
|
+
|
279
|
+
set_mock_response_for @app, 1,
|
280
|
+
{check_nginx => [:err, ""],
|
281
|
+
check_ruby => [:err, ""]},
|
282
|
+
{:sudo => yum_sudo}
|
283
|
+
|
284
|
+
@app.install_deps 'ruby', nginx_dep
|
285
|
+
|
286
|
+
|
287
|
+
each_remote_shell do |ds|
|
288
|
+
[nginx_dep, ruby_dep].each do |dep|
|
289
|
+
check =
|
290
|
+
"test \"$(yum list installed #{dep.pkg} | grep -c #{dep.pkg})\" -ge 1"
|
291
|
+
install = dep.instance_variable_get "@install"
|
292
|
+
|
293
|
+
assert_ssh_call check, ds, :sudo => yum_sudo
|
294
|
+
assert_ssh_call install, ds, :sudo => yum_sudo
|
295
|
+
end
|
296
|
+
end
|
297
|
+
end
|
298
|
+
|
299
|
+
|
300
|
+
def test_install_gem_deps
|
301
|
+
rake_dep = Sunshine.dependencies.get 'rake'
|
302
|
+
bundler_dep = Sunshine.dependencies.get 'bundler'
|
303
|
+
|
304
|
+
gem_sudo = Sunshine::Gem.sudo
|
305
|
+
|
306
|
+
checks = {
|
307
|
+
rake_dep => "gem list #{rake_dep.pkg} -i --version '>=0.8'",
|
308
|
+
bundler_dep => "gem list #{bundler_dep.pkg} -i --version '>=0.9'"
|
309
|
+
}
|
310
|
+
|
311
|
+
checks.values.each do |check|
|
312
|
+
set_mock_response_for @app, 1, {check => [:err, ""]}, {:sudo => gem_sudo}
|
313
|
+
end
|
314
|
+
|
315
|
+
@app.install_deps 'rake', bundler_dep
|
316
|
+
|
317
|
+
|
318
|
+
each_remote_shell do |ds|
|
319
|
+
[rake_dep, bundler_dep].each do |dep|
|
320
|
+
|
321
|
+
install = dep.instance_variable_get "@install"
|
322
|
+
|
323
|
+
assert_ssh_call checks[dep], ds, :sudo => gem_sudo
|
324
|
+
assert_ssh_call install, ds, :sudo => gem_sudo
|
325
|
+
end
|
326
|
+
end
|
327
|
+
end
|
328
|
+
|
329
|
+
|
330
|
+
def test_make_app_directories
|
331
|
+
@app.make_app_directories
|
332
|
+
|
333
|
+
each_remote_shell do |ds|
|
334
|
+
assert_ssh_call "mkdir -p #{@app.server_apps.first.directories.join(" ")}"
|
335
|
+
end
|
336
|
+
end
|
337
|
+
|
338
|
+
|
339
|
+
def test_rake
|
340
|
+
@app.rake("test:task")
|
341
|
+
|
342
|
+
each_remote_shell do |ds|
|
343
|
+
assert_ssh_call "cd #{@app.checkout_path} && rake test:task"
|
344
|
+
end
|
345
|
+
end
|
346
|
+
|
347
|
+
|
348
|
+
def test_register_as_deployed
|
349
|
+
@app.register_as_deployed
|
350
|
+
|
351
|
+
each_remote_shell do |ds|
|
352
|
+
assert_ssh_call "test -d #{@app.root_path}"
|
353
|
+
|
354
|
+
yml_list = {@app.name => @app.root_path}.to_yaml
|
355
|
+
path = ds.expand_path(Sunshine::APP_LIST_PATH)
|
356
|
+
|
357
|
+
assert ds.method_called?(:make_file, :args => [path, yml_list])
|
358
|
+
end
|
359
|
+
end
|
360
|
+
|
361
|
+
|
362
|
+
def test_remove_old_deploys
|
363
|
+
returned_dirs = %w{old_deploy1 old_deploy2 old_deploy3 main_deploy}
|
364
|
+
old_deploys = returned_dirs[0..-2].map{|d| "#{@app.deploys_path}/#{d}"}
|
365
|
+
|
366
|
+
list_cmd = "ls -1 #{@app.deploys_path}"
|
367
|
+
rm_cmd = "rm -rf #{old_deploys.join(" ")}"
|
368
|
+
|
369
|
+
set_mock_response_for @app, 0,
|
370
|
+
list_cmd => [:out, returned_dirs.join("\n")]
|
371
|
+
|
372
|
+
Sunshine.setup 'max_deploy_versions' => 1
|
373
|
+
|
374
|
+
@app.remove_old_deploys
|
375
|
+
|
376
|
+
each_remote_shell do |ds|
|
377
|
+
assert_ssh_call list_cmd
|
378
|
+
assert_ssh_call rm_cmd
|
379
|
+
end
|
380
|
+
end
|
381
|
+
|
382
|
+
|
383
|
+
def test_run_post_user_lambdas
|
384
|
+
lambdas_ran = 0
|
385
|
+
count = 5
|
386
|
+
|
387
|
+
count.times do
|
388
|
+
@app.after_user_script do |app|
|
389
|
+
lambdas_ran = lambdas_ran.next
|
390
|
+
end
|
391
|
+
end
|
392
|
+
|
393
|
+
assert_equal 0, lambdas_ran
|
394
|
+
|
395
|
+
@app.run_post_user_lambdas
|
396
|
+
|
397
|
+
assert_equal count, lambdas_ran
|
398
|
+
end
|
399
|
+
|
400
|
+
|
401
|
+
def test_shell_env
|
402
|
+
new_env = {
|
403
|
+
"PATH" => "/etc/lib:$PATH",
|
404
|
+
"RACK_ENV" => "test",
|
405
|
+
"RAILS_ENV" => "test"
|
406
|
+
}
|
407
|
+
|
408
|
+
@app.shell_env new_env
|
409
|
+
|
410
|
+
assert_equal new_env, @app.shell_env
|
411
|
+
end
|
412
|
+
|
413
|
+
|
414
|
+
def test_symlink_current_dir
|
415
|
+
@app.symlink_current_dir
|
416
|
+
|
417
|
+
each_remote_shell do |ds|
|
418
|
+
assert_ssh_call "ln -sfT #{@app.checkout_path} #{@app.current_path}"
|
419
|
+
end
|
420
|
+
end
|
421
|
+
|
422
|
+
|
423
|
+
def test_upload_tasks
|
424
|
+
path = "/path/to/tasks"
|
425
|
+
|
426
|
+
@app.upload_tasks 'common', 'tpkg',
|
427
|
+
:host => 'some_server.com',
|
428
|
+
:remote_path => path
|
429
|
+
|
430
|
+
each_remote_shell do |ds|
|
431
|
+
assert_ssh_call "mkdir -p /path/to/tasks"
|
432
|
+
|
433
|
+
%w{common tpkg}.each do |task|
|
434
|
+
from = "#{Sunshine::ROOT}/templates/tasks/#{task}.rake"
|
435
|
+
to = "#{ds.host}:#{path}/#{task}.rake"
|
436
|
+
|
437
|
+
assert_rsync from, to
|
438
|
+
end
|
439
|
+
end
|
440
|
+
end
|
441
|
+
|
442
|
+
|
443
|
+
def test_upload_tasks_simple
|
444
|
+
@app.upload_tasks
|
445
|
+
|
446
|
+
path = "#{@app.checkout_path}/lib/tasks"
|
447
|
+
|
448
|
+
tasks =
|
449
|
+
Dir.glob("#{Sunshine::ROOT}/templates/tasks/*").map{|t| File.basename t}
|
450
|
+
|
451
|
+
each_remote_shell do |ds|
|
452
|
+
assert_ssh_call "mkdir -p #{path}"
|
453
|
+
|
454
|
+
tasks.each do |task|
|
455
|
+
from = "#{Sunshine::ROOT}/templates/tasks/#{task}"
|
456
|
+
to = "#{ds.host}:#{path}/#{task}"
|
457
|
+
|
458
|
+
assert_rsync from, to
|
459
|
+
end
|
460
|
+
end
|
461
|
+
end
|
462
|
+
|
463
|
+
|
464
|
+
def test_sudo_assignment
|
465
|
+
@app.sudo = "someuser"
|
466
|
+
|
467
|
+
@app.each do |server_app|
|
468
|
+
assert_equal "someuser", server_app.shell.sudo
|
469
|
+
end
|
470
|
+
end
|
471
|
+
|
472
|
+
|
473
|
+
private
|
474
|
+
|
475
|
+
|
476
|
+
def assert_attributes_equal(attr_hash, app)
|
477
|
+
assert_equal attr_hash[:name], app.name
|
478
|
+
assert_equal attr_hash[:repo][:url], app.repo.url
|
479
|
+
assert_equal attr_hash[:root_path], app.root_path
|
480
|
+
|
481
|
+
attr_hash[:remote_shells].each_with_index do |server_def, i|
|
482
|
+
server_def = server_def.first if Array === server_def
|
483
|
+
user, host = server_def.split("@")
|
484
|
+
assert_equal host, app.server_apps[i].shell.host
|
485
|
+
assert_equal user, app.server_apps[i].shell.user
|
486
|
+
end
|
487
|
+
end
|
488
|
+
|
489
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'test/test_helper'
|
2
|
+
|
3
|
+
class TestBinder < Test::Unit::TestCase
|
4
|
+
|
5
|
+
def setup
|
6
|
+
@target = [1,2,3]
|
7
|
+
@binder = Sunshine::Binder.new @target
|
8
|
+
end
|
9
|
+
|
10
|
+
def test_set
|
11
|
+
@binder.set :blah, "somevalue"
|
12
|
+
assert_equal "somevalue", @binder.blah
|
13
|
+
end
|
14
|
+
|
15
|
+
def test_forward
|
16
|
+
@binder.forward :join, :length
|
17
|
+
assert_equal @target.join(" "), @binder.join(" ")
|
18
|
+
assert_equal @target.length, @binder.length
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,128 @@
|
|
1
|
+
require 'test/test_helper'
|
2
|
+
|
3
|
+
class TestCrontab < Test::Unit::TestCase
|
4
|
+
|
5
|
+
def setup
|
6
|
+
@crontab_str = <<-STR
|
7
|
+
# sunshine crontest:job1:begin
|
8
|
+
this job should stay
|
9
|
+
# sunshine crontest:job1:end
|
10
|
+
|
11
|
+
# sunshine crontest:job2:begin
|
12
|
+
job2 part 1
|
13
|
+
# sunshine crontest:job2:end
|
14
|
+
|
15
|
+
# sunshine otherapp:blah:begin
|
16
|
+
otherapp blah job
|
17
|
+
# sunshine otherapp:blah:end
|
18
|
+
|
19
|
+
# sunshine crontest:job2:begin
|
20
|
+
job2 part 2
|
21
|
+
# sunshine crontest:job2:end
|
22
|
+
|
23
|
+
# sunshine otherapp:job1:begin
|
24
|
+
job for otherapp
|
25
|
+
# sunshine otherapp:job1:end
|
26
|
+
STR
|
27
|
+
|
28
|
+
@shell = mock_remote_shell
|
29
|
+
|
30
|
+
@cron = Sunshine::Crontab.new "crontest", @shell
|
31
|
+
|
32
|
+
@othercron = Sunshine::Crontab.new "otherapp", @shell
|
33
|
+
|
34
|
+
@shell.set_mock_response 0, "crontab -l" => [:out, @crontab_str]
|
35
|
+
end
|
36
|
+
|
37
|
+
|
38
|
+
def test_parse
|
39
|
+
jobs = @cron.parse @crontab_str
|
40
|
+
assert_equal "this job should stay\n", jobs['job1']
|
41
|
+
assert_equal "job2 part 1\njob2 part 2\n", jobs['job2']
|
42
|
+
assert jobs['blah'].nil?
|
43
|
+
end
|
44
|
+
|
45
|
+
|
46
|
+
def test_build
|
47
|
+
@cron.jobs["job2"] << "new job2"
|
48
|
+
@cron.jobs["job3"] = "new job3"
|
49
|
+
|
50
|
+
@cron.build @crontab_str
|
51
|
+
|
52
|
+
assert_cronjob "job1", "this job should stay"
|
53
|
+
assert_cronjob "job2", "job2 part 1\njob2 part 2\nnew job2"
|
54
|
+
assert_cronjob "job3", "new job3"
|
55
|
+
|
56
|
+
assert_cronjob "blah", "otherapp blah job", @othercron
|
57
|
+
assert_cronjob "job1", "job for otherapp", @othercron
|
58
|
+
end
|
59
|
+
|
60
|
+
|
61
|
+
def test_delete!
|
62
|
+
assert_cronjob "blah", "otherapp blah job", @othercron
|
63
|
+
assert_cronjob "job1", "job for otherapp", @othercron
|
64
|
+
|
65
|
+
@crontab_str = @othercron.delete!
|
66
|
+
|
67
|
+
assert !@crontab_str.include?("job for otherapp")
|
68
|
+
assert !@crontab_str.include?("otherapp blah job")
|
69
|
+
|
70
|
+
assert_cronjob "job1", "this job should stay"
|
71
|
+
assert_cronjob "job2", "job2 part 1"
|
72
|
+
assert_cronjob "job2", "job2 part 2"
|
73
|
+
end
|
74
|
+
|
75
|
+
|
76
|
+
def test_write!
|
77
|
+
@cron.jobs["job2"] << "new job2"
|
78
|
+
@cron.jobs["job3"] = "new job3"
|
79
|
+
|
80
|
+
@shell.set_mock_response 0, "crontab -l" => [:out, @crontab_str]
|
81
|
+
|
82
|
+
@crontab_str = @cron.write!
|
83
|
+
|
84
|
+
assert_cronjob "job1", "this job should stay"
|
85
|
+
assert_cronjob "job2", "job2 part 1\njob2 part 2\nnew job2"
|
86
|
+
assert_cronjob "job3", "new job3"
|
87
|
+
|
88
|
+
assert_cronjob "blah", "otherapp blah job", @othercron
|
89
|
+
assert_cronjob "job1", "job for otherapp", @othercron
|
90
|
+
|
91
|
+
cmd = "echo '#{@crontab_str.gsub(/'/){|s| "'\\''"}}' | crontab"
|
92
|
+
|
93
|
+
assert_ssh_call cmd
|
94
|
+
end
|
95
|
+
|
96
|
+
|
97
|
+
def test_deleted_jobs_write!
|
98
|
+
@cron.jobs.delete "job1"
|
99
|
+
|
100
|
+
@shell.set_mock_response 0, "crontab -l" => [:out, @crontab_str]
|
101
|
+
|
102
|
+
@crontab_str = @cron.write!
|
103
|
+
|
104
|
+
assert !@crontab_str.include?("this job should stay")
|
105
|
+
assert_cronjob "job2", "job2 part 1\njob2 part 2"
|
106
|
+
|
107
|
+
assert_cronjob "blah", "otherapp blah job", @othercron
|
108
|
+
assert_cronjob "job1", "job for otherapp", @othercron
|
109
|
+
|
110
|
+
cmd = "echo '#{@crontab_str.gsub(/'/){|s| "'\\''"}}' | crontab"
|
111
|
+
|
112
|
+
assert_ssh_call cmd
|
113
|
+
end
|
114
|
+
|
115
|
+
|
116
|
+
def assert_cronjob namespace, job, crontab=@cron
|
117
|
+
assert @crontab_str.include?(cronjob(namespace, job, crontab))
|
118
|
+
end
|
119
|
+
|
120
|
+
|
121
|
+
def cronjob namespace, job, crontab
|
122
|
+
<<-STR
|
123
|
+
# sunshine #{crontab.name}:#{namespace}:begin
|
124
|
+
#{job}
|
125
|
+
# sunshine #{crontab.name}:#{namespace}:end
|
126
|
+
STR
|
127
|
+
end
|
128
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'test/test_helper'
|
2
|
+
|
3
|
+
class TestGitRepo < Test::Unit::TestCase
|
4
|
+
|
5
|
+
def test_name
|
6
|
+
git = Sunshine::GitRepo.new "git://myrepo/project.git"
|
7
|
+
assert_equal "project", git.name
|
8
|
+
|
9
|
+
git = Sunshine::GitRepo.new "ssh://user@host.xz:456/path/to/project.git"
|
10
|
+
assert_equal "project", git.name
|
11
|
+
|
12
|
+
git = Sunshine::GitRepo.new "user@host.xz:~user/path/to/project.git"
|
13
|
+
assert_equal "project", git.name
|
14
|
+
end
|
15
|
+
|
16
|
+
|
17
|
+
def test_invalid_name
|
18
|
+
git = Sunshine::GitRepo.new "project.git"
|
19
|
+
git.name
|
20
|
+
raise "GitRepo didn't catch invalid naming scheme: #{git.url}"
|
21
|
+
rescue => e
|
22
|
+
assert_equal "Git url must match #{Sunshine::GitRepo::NAME_MATCH.inspect}",
|
23
|
+
e.message
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|