sunshine 1.0.0.pre

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.
Files changed (71) hide show
  1. data/History.txt +237 -0
  2. data/Manifest.txt +70 -0
  3. data/README.txt +277 -0
  4. data/Rakefile +46 -0
  5. data/bin/sunshine +5 -0
  6. data/examples/deploy.rb +61 -0
  7. data/examples/deploy_tasks.rake +112 -0
  8. data/examples/standalone_deploy.rb +31 -0
  9. data/lib/commands/add.rb +96 -0
  10. data/lib/commands/default.rb +169 -0
  11. data/lib/commands/list.rb +322 -0
  12. data/lib/commands/restart.rb +62 -0
  13. data/lib/commands/rm.rb +83 -0
  14. data/lib/commands/run.rb +151 -0
  15. data/lib/commands/start.rb +72 -0
  16. data/lib/commands/stop.rb +61 -0
  17. data/lib/sunshine/app.rb +876 -0
  18. data/lib/sunshine/binder.rb +70 -0
  19. data/lib/sunshine/crontab.rb +143 -0
  20. data/lib/sunshine/daemon.rb +380 -0
  21. data/lib/sunshine/daemons/ar_sendmail.rb +28 -0
  22. data/lib/sunshine/daemons/delayed_job.rb +30 -0
  23. data/lib/sunshine/daemons/nginx.rb +104 -0
  24. data/lib/sunshine/daemons/rainbows.rb +35 -0
  25. data/lib/sunshine/daemons/server.rb +66 -0
  26. data/lib/sunshine/daemons/unicorn.rb +26 -0
  27. data/lib/sunshine/dependencies.rb +103 -0
  28. data/lib/sunshine/dependency_lib.rb +200 -0
  29. data/lib/sunshine/exceptions.rb +54 -0
  30. data/lib/sunshine/healthcheck.rb +83 -0
  31. data/lib/sunshine/output.rb +131 -0
  32. data/lib/sunshine/package_managers/apt.rb +48 -0
  33. data/lib/sunshine/package_managers/dependency.rb +349 -0
  34. data/lib/sunshine/package_managers/gem.rb +54 -0
  35. data/lib/sunshine/package_managers/yum.rb +62 -0
  36. data/lib/sunshine/remote_shell.rb +241 -0
  37. data/lib/sunshine/repo.rb +128 -0
  38. data/lib/sunshine/repos/git_repo.rb +122 -0
  39. data/lib/sunshine/repos/rsync_repo.rb +29 -0
  40. data/lib/sunshine/repos/svn_repo.rb +78 -0
  41. data/lib/sunshine/server_app.rb +554 -0
  42. data/lib/sunshine/shell.rb +384 -0
  43. data/lib/sunshine.rb +391 -0
  44. data/templates/logrotate/logrotate.conf.erb +11 -0
  45. data/templates/nginx/nginx.conf.erb +109 -0
  46. data/templates/nginx/nginx_optimize.conf +23 -0
  47. data/templates/nginx/nginx_proxy.conf +13 -0
  48. data/templates/rainbows/rainbows.conf.erb +18 -0
  49. data/templates/tasks/sunshine.rake +114 -0
  50. data/templates/unicorn/unicorn.conf.erb +6 -0
  51. data/test/fixtures/app_configs/test_app.yml +11 -0
  52. data/test/fixtures/sunshine_test/test_upload +0 -0
  53. data/test/mocks/mock_object.rb +179 -0
  54. data/test/mocks/mock_open4.rb +117 -0
  55. data/test/test_helper.rb +188 -0
  56. data/test/unit/test_app.rb +489 -0
  57. data/test/unit/test_binder.rb +20 -0
  58. data/test/unit/test_crontab.rb +128 -0
  59. data/test/unit/test_git_repo.rb +26 -0
  60. data/test/unit/test_healthcheck.rb +70 -0
  61. data/test/unit/test_nginx.rb +107 -0
  62. data/test/unit/test_rainbows.rb +26 -0
  63. data/test/unit/test_remote_shell.rb +102 -0
  64. data/test/unit/test_repo.rb +42 -0
  65. data/test/unit/test_server.rb +324 -0
  66. data/test/unit/test_server_app.rb +425 -0
  67. data/test/unit/test_shell.rb +97 -0
  68. data/test/unit/test_sunshine.rb +157 -0
  69. data/test/unit/test_svn_repo.rb +55 -0
  70. data/test/unit/test_unicorn.rb +22 -0
  71. 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