capistrano-fanfare 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,2 @@
1
+ web: bundle exec thin start
2
+ job: bundle exec rake jobs:work
@@ -0,0 +1,14 @@
1
+ module Capistrano::Fanfare::Bark
2
+ def self.load_into(configuration)
3
+ configuration.load do
4
+ task :bark do
5
+ set :message, 'ruff ruff'
6
+ message
7
+ end
8
+ end
9
+ end
10
+ end
11
+
12
+ if Capistrano::Configuration.instance
13
+ Capistrano::Fanfare::Bark.load_into(Capistrano::Configuration.instance)
14
+ end
@@ -0,0 +1,14 @@
1
+ module Capistrano::Fanfare::Meow
2
+ def self.load_into(configuration)
3
+ configuration.load do
4
+ task :meow do
5
+ 'purr purr'
6
+ end
7
+ end
8
+ end
9
+ end
10
+
11
+ if Capistrano::Configuration.instance
12
+ Capistrano::Fanfare::Meow.load_into(Capistrano::Configuration.instance)
13
+ end
14
+
@@ -0,0 +1,83 @@
1
+ require 'minitest/autorun'
2
+ require 'minitest/capistrano'
3
+ require 'capistrano/fanfare'
4
+ require 'capistrano/fanfare/foreman/strategy/runit'
5
+
6
+ describe Capistrano::Fanfare::Foreman::Strategy::Runit do
7
+ before do
8
+ @config = Capistrano::Configuration.new
9
+ @config.extend(MiniTest::Capistrano::ConfigurationExtension)
10
+ end
11
+
12
+ let(:strategy) { Capistrano::Fanfare::Foreman::Strategy::Runit.new(@config) }
13
+
14
+ it "#export generates runit services from the Procfile" do
15
+ @config.set :current_release, "/srv/fooapp/releases/thisone"
16
+ @config.set :foreman_cmd, "bin/foreman"
17
+ @config.set :shared_path, "/srv/fooapp/shared"
18
+ @config.set :runit_sv_path, "/srv/fooapp/shared/sv"
19
+ @config.set :runit_app_name, "fooapp_production"
20
+ @config.set :user, "deploy"
21
+ strategy.export
22
+
23
+ @config.must_have_run [
24
+ "cd /srv/fooapp/releases/thisone &&",
25
+ "if [ -f Procfile ] ; then",
26
+ "mkdir -p /srv/fooapp/shared/sv &&",
27
+ "bin/foreman export runit /srv/fooapp/shared/sv",
28
+ "--app=fooapp_production --log=/srv/fooapp/shared/log",
29
+ "--user=deploy &&",
30
+ "find /srv/fooapp/shared/sv -type f -name run",
31
+ "-exec chmod 755 {} \\; ; else",
32
+ "echo '>>>> A Procfile must exist in this project.' && exit 10 ; fi"
33
+ ].join(' ')
34
+ end
35
+
36
+ it "#register symlinks services in :runit_sv_path to :runit_service_path" do
37
+ @config.set :runit_sv_path, "/apps/foo/shared/sv"
38
+ @config.set :runit_service_path, "/home/foouser/service"
39
+ strategy.register
40
+
41
+ @config.must_have_run "ln -snf /apps/foo/shared/sv/* /home/foouser/service/"
42
+ end
43
+
44
+ describe "#start" do
45
+ it "starts all services without arguments" do
46
+ @config.set :runit_service_path, "/home/foouser/service"
47
+ @config.set :runit_app_name, "wuzzle_production"
48
+ strategy.start
49
+
50
+ @config.must_have_run "sv start /home/foouser/service/wuzzle_production-*"
51
+ end
52
+ end
53
+
54
+ describe "#stop" do
55
+ it "stops all services without arguments" do
56
+ @config.set :runit_service_path, "/home/foouser/service"
57
+ @config.set :runit_app_name, "wuzzle_production"
58
+ strategy.stop
59
+
60
+ @config.must_have_run "sv stop /home/foouser/service/wuzzle_production-*"
61
+ end
62
+ end
63
+
64
+ describe "#restart" do
65
+ it "restarts all services without arguments" do
66
+ @config.set :runit_service_path, "/home/foouser/service"
67
+ @config.set :runit_app_name, "wuzzle_production"
68
+ strategy.restart
69
+
70
+ @config.must_have_run "sv restart /home/foouser/service/wuzzle_production-*"
71
+ end
72
+ end
73
+
74
+ describe "#ps" do
75
+ it "returns all service process statuses" do
76
+ @config.set :runit_service_path, "/home/foouser/service"
77
+ @config.set :runit_app_name, "wuzzle_production"
78
+ strategy.ps
79
+
80
+ @config.must_have_run "sv status /home/foouser/service/wuzzle_production-*"
81
+ end
82
+ end
83
+ end
@@ -0,0 +1,234 @@
1
+ require 'minitest/autorun'
2
+ require 'minitest/capistrano'
3
+ require 'capistrano/fanfare'
4
+ require 'capistrano/fanfare/foreman'
5
+
6
+ describe Capistrano::Fanfare::Foreman do
7
+ before do
8
+ @config = Capistrano::Configuration.new
9
+ @config.load "deploy"
10
+ Capistrano::Fanfare::Foreman.load_into(@config)
11
+ @config.extend(MiniTest::Capistrano::ConfigurationExtension)
12
+ end
13
+
14
+ describe "for variables" do
15
+ it "sets :local_procfile to 'Procfile'" do
16
+ @config.fetch(:local_procfile).must_equal "Procfile"
17
+ end
18
+
19
+ it "sets :user_home to the capistrano user's home directory" do
20
+ @config.captures_responses["echo $HOME"] = "/u/home/fooguy\n"
21
+
22
+ @config.fetch(:user_home).must_equal "/u/home/fooguy"
23
+ end
24
+
25
+ it "sets :foreman_cmd to 'foreman'" do
26
+ @config.fetch(:foreman_cmd).must_equal "foreman"
27
+ end
28
+
29
+ it "sets :foreman_export_via to :runit" do
30
+ @config.fetch(:foreman_export_via).must_equal :runit
31
+ end
32
+
33
+ it "sets :foreman_strategy to an Runit strategy" do
34
+ @config.fetch(:foreman_strategy).class.
35
+ must_equal Capistrano::Fanfare::Foreman::Strategy::Runit
36
+ end
37
+
38
+ it "sets :runit_service_path to :user_home/service" do
39
+ @config.set :user_home, "/home/app"
40
+
41
+ @config.fetch(:runit_service_path).must_equal "/home/app/service"
42
+ end
43
+
44
+ it "sets :runit_app_name to a combination of :application and :deploy_env" do
45
+ @config.set :application, "barness"
46
+ @config.set :deploy_env, "production"
47
+
48
+ @config.fetch(:runit_app_name).must_equal "barness_production"
49
+ end
50
+
51
+ it "sets :runit_sv_path to shared_path/sv" do
52
+ @config.set :shared_path, "/srv/wakka/shared"
53
+
54
+ @config.fetch(:runit_sv_path).must_equal "/srv/wakka/shared/sv"
55
+ end
56
+ end
57
+
58
+ describe "for namespace :foreman" do
59
+ let(:strategy) { MiniTest::Mock.new }
60
+
61
+ before do
62
+ @config.set :foreman_strategy, strategy
63
+ end
64
+
65
+ describe "task :cp_env" do
66
+ it "copies env file from shared_path into current_release as .env" do
67
+ @config.set :shared_path, "/tmp/app/shared"
68
+ @config.set :current_release, "/tmp/app/releases/blah"
69
+ @config.find_and_execute_task("foreman:cp_env")
70
+
71
+ @config.must_have_run "cp /tmp/app/shared/env /tmp/app/releases/blah/.env"
72
+ end
73
+
74
+ it "gets called after deploy:updated_code task" do
75
+ @config.must_have_callback_after "deploy:update_code", "foreman:cp_env"
76
+ end
77
+ end
78
+
79
+ describe "task :run_cmd" do
80
+ before do
81
+ ENV['_FOREMAN_COMMAND'] = ENV['COMMAND']
82
+ ENV['COMMAND'] = "rake db:migrate"
83
+ end
84
+
85
+ after do
86
+ ENV['COMMAND'] = ENV.delete('_FOREMAN_COMMAND')
87
+ end
88
+
89
+ it "runs a command in a foreman environment context" do
90
+ @config.set :current_path, "/apps/fuyou/current"
91
+ @config.set :foreman_cmd, "bin/foreman"
92
+ @config.find_and_execute_task("foreman:run_cmd")
93
+
94
+ @config.must_have_run [
95
+ "cd /apps/fuyou/current &&",
96
+ "bin/foreman run 'rake db:migrate'"
97
+ ].join(' ')
98
+ end
99
+
100
+ it "raises an exception when ENV['COMMAND'] is not found" do
101
+ ENV.delete('COMMAND')
102
+ proc { @config.find_and_execute_task("foreman:run_cmd") }.
103
+ must_raise RuntimeError
104
+ end
105
+ end
106
+
107
+ describe "task :export" do
108
+ it "delegates to forman_strategy.export" do
109
+ strategy.expect :export, true
110
+ @config.find_and_execute_task("foreman:export")
111
+
112
+ strategy.verify
113
+ end
114
+ end
115
+
116
+ describe "task :register" do
117
+ it "delegates to forman_strategy.register" do
118
+ strategy.expect :register, true
119
+ @config.find_and_execute_task("foreman:register")
120
+
121
+ strategy.verify
122
+ end
123
+ end
124
+
125
+ describe "task :start" do
126
+ it "delegates to forman_strategy.start" do
127
+ strategy.expect :start, true
128
+ @config.find_and_execute_task("foreman:start")
129
+
130
+ strategy.verify
131
+ end
132
+ end
133
+
134
+ describe "task :stop" do
135
+ it "delegates to forman_strategy.stop" do
136
+ strategy.expect :stop, true
137
+ @config.find_and_execute_task("foreman:stop")
138
+
139
+ strategy.verify
140
+ end
141
+ end
142
+
143
+ describe "task :restart" do
144
+ it "delegates to forman_strategy.restart" do
145
+ strategy.expect :restart, true
146
+ @config.find_and_execute_task("foreman:restart")
147
+
148
+ strategy.verify
149
+ end
150
+ end
151
+
152
+ describe "task :ps" do
153
+ it "delegates to forman_strategy.ps" do
154
+ strategy.expect :ps, true
155
+ @config.find_and_execute_task("foreman:ps")
156
+
157
+ strategy.verify
158
+ end
159
+ end
160
+
161
+ describe "dynamic tasks" do
162
+ before do
163
+ ENV['PROCFILE'] =
164
+ File.expand_path(File.join(File.dirname(__FILE__), %w{fixtures Procfile}))
165
+ @config = Capistrano::Configuration.new
166
+ @config.load "deploy"
167
+ Capistrano::Fanfare::Foreman.load_into(@config)
168
+ @config.extend(MiniTest::Capistrano::ConfigurationExtension)
169
+ @config.set :foreman_strategy, strategy
170
+ end
171
+
172
+ after do
173
+ ENV.delete('PROCFILE')
174
+ end
175
+
176
+ describe "for namespace :start" do
177
+ it "creates a task for each Procfile entry (on client side copy)" do
178
+ @config.must_have_task "foreman:start:web"
179
+ @config.must_have_task "foreman:start:job"
180
+ end
181
+
182
+ it "task :web delegates to foreman_strategy.start" do
183
+ strategy.expect :start, true, ["web"]
184
+ @config.find_and_execute_task("foreman:start:web")
185
+
186
+ strategy.verify
187
+ end
188
+ end
189
+
190
+ describe "for namespace :stop" do
191
+ it "creates a task for each Procfile entry (on client side copy)" do
192
+ @config.must_have_task "foreman:stop:web"
193
+ @config.must_have_task "foreman:stop:job"
194
+ end
195
+
196
+ it "task :web delegates to foreman_strategy.stop" do
197
+ strategy.expect :stop, true, ["web"]
198
+ @config.find_and_execute_task("foreman:stop:web")
199
+
200
+ strategy.verify
201
+ end
202
+ end
203
+
204
+ describe "for namespace :restart" do
205
+ it "creates a task for each Procfile entry (on client side copy)" do
206
+ @config.must_have_task "foreman:restart:web"
207
+ @config.must_have_task "foreman:restart:job"
208
+ end
209
+
210
+ it "task :web delegates to foreman_strategy.restart" do
211
+ strategy.expect :restart, true, ["web"]
212
+ @config.find_and_execute_task("foreman:restart:web")
213
+
214
+ strategy.verify
215
+ end
216
+ end
217
+ end
218
+ end
219
+
220
+ describe "task :frun" do
221
+ it "delegates to foreman:run_cmd task" do
222
+ @config.load do
223
+ def methods_called ; @methods_called ||= [] ; end
224
+
225
+ namespace :foreman do
226
+ task(:run_cmd) { methods_called << "foreman:run_cmd" }
227
+ end
228
+ end
229
+ @config.find_and_execute_task("frun")
230
+
231
+ @config.methods_called.must_equal ["foreman:run_cmd"]
232
+ end
233
+ end
234
+ end
@@ -0,0 +1,168 @@
1
+ require 'minitest/autorun'
2
+ require 'minitest/capistrano'
3
+ require 'capistrano/fanfare'
4
+ require 'capistrano/fanfare/git_style'
5
+ require 'timecop'
6
+
7
+ describe Capistrano::Fanfare::GitStyle do
8
+ before do
9
+ @config = Capistrano::Configuration.new
10
+ @config.load "deploy"
11
+ Capistrano::Fanfare::GitStyle.load_into(@config)
12
+ @config.extend(MiniTest::Capistrano::ConfigurationExtension)
13
+
14
+ @config.set :application, "fooapp"
15
+ @config.set :repository, "git@example.com:fooapp.git"
16
+ end
17
+
18
+ describe "for variables" do
19
+ it "sets :scm to :git" do
20
+ @config.fetch(:scm).must_equal :git
21
+ end
22
+
23
+ it "sets :deploy_via to :git_style" do
24
+ @config.fetch(:deploy_via).must_equal :git_style
25
+ end
26
+
27
+ it "sets :release_name to a timestamp and git commit id" do
28
+ @config.set :real_revision, "git123"
29
+
30
+ Timecop.freeze(Time.utc(2012, 1, 1, 2, 3, 4)) do
31
+ @config.fetch(:release_name).must_equal "20120101020304-git123"
32
+ end
33
+ end
34
+
35
+ it "sets :release_path to :current_path" do
36
+ @config.fetch(:release_path).must_equal @config.fetch(:current_path)
37
+ end
38
+
39
+ it "sets :current_release to :current_path" do
40
+ @config.fetch(:current_release).must_equal @config.fetch(:current_path)
41
+ end
42
+
43
+ it "sets :latest_release to :current_path" do
44
+ @config.fetch(:latest_release).must_equal @config.fetch(:current_path)
45
+ end
46
+
47
+ it "sets :current_revision to current git revision on server" do
48
+ @config.set :current_path, "/a/apps/barapp/current"
49
+ capture_cmd = "cd /a/apps/barapp/current && git rev-parse HEAD"
50
+ @config.captures_responses[capture_cmd] = "gitZZZ"
51
+
52
+ @config.fetch(:current_revision).must_equal "gitZZZ"
53
+ end
54
+
55
+ it "sets :latest_revision to current git revision on the server" do
56
+ @config.set :releases_path, "/a/apps/zurb/releases"
57
+ @config.set :releases, ["first-one", "20120101020304-gitFAB"]
58
+ capture_cmd = "basename /a/apps/zurb/releases/20120101020304-gitFAB | cut -d - -f 2"
59
+ @config.captures_responses[capture_cmd] = "gitFAB"
60
+
61
+ @config.fetch(:latest_revision).must_equal "gitFAB"
62
+ end
63
+
64
+ it "sets :previous_revision to git revision of last deployment" do
65
+ @config.set :previous_release, "/a/apps/zurb/releases/20060212125959-gitCC"
66
+ capture_cmd = "basename /a/apps/zurb/releases/20060212125959-gitCC | cut -d - -f 2"
67
+ @config.captures_responses[capture_cmd] = "gitCC"
68
+
69
+ @config.fetch(:previous_revision).must_equal "gitCC"
70
+ end
71
+
72
+ it "sets :previous_revision to nil if :previous_release is not set" do
73
+ @config.set :previous_release, nil
74
+
75
+ @config.captures.must_be_empty
76
+ @config.fetch(:previous_revision).must_be_nil
77
+ end
78
+ end
79
+
80
+ describe "for namespace :deploy" do
81
+ describe "task :update_code" do
82
+ before do
83
+ @config.load do
84
+ def methods_called ; @methods_called ||= [] ; end
85
+
86
+ namespace :deploy do
87
+ task(:finalize_update) { methods_called << "deploy:finalize_update" }
88
+ end
89
+ end
90
+
91
+ # stub out strategy.deploy!
92
+ strategy = @config.strategy
93
+ def strategy.deploy! ; methods_called << "strategy.deploy!" ; end
94
+
95
+ # stub out on_rollback
96
+ def @config.on_rollback ; methods_called << "on_rollback" ; end
97
+ end
98
+
99
+ it "calls same tasks as delivered gem code" do
100
+ @config.find_and_execute_task("deploy:update_code")
101
+
102
+ @config.methods_called.must_equal(["strategy.deploy!", "deploy:finalize_update"])
103
+ end
104
+ end
105
+
106
+ it "task :create_symlink must not run anything (no-op)" do
107
+ @config.find_and_execute_task("deploy:create_symlink")
108
+
109
+ @config.wont_have_run_anything
110
+ end
111
+
112
+ describe "in namespace :rollback" do
113
+ before do
114
+ @config.load do
115
+ def methods_called ; @methods_called ||= [] ; end
116
+
117
+ namespace :deploy do
118
+ task(:update_code) { methods_called << "deploy:update_code" }
119
+ end
120
+ end
121
+ end
122
+
123
+ def runs_msg(cmd)
124
+ runs_list = @config.runs.keys.sort.
125
+ map { |c|c.sub(/^/, '\'').sub(/$/, '\'')}.join(', ')
126
+ "Expected run call of '#{cmd}' in run list of: [#{runs_list}]"
127
+ end
128
+
129
+ it "task :revision sets :branch to :previous_release" do
130
+ @config.set :branch, "ding"
131
+ @config.set :previous_revision, "gitPREV"
132
+ @config.set :previous_release, "/u/apps/rofl/releases/20080808082800-gitPREV"
133
+ @config.find_and_execute_task("deploy:rollback:revision")
134
+
135
+ @config.fetch(:branch).must_equal "gitPREV"
136
+ end
137
+
138
+ it "task :revision runs deploy:update_code" do
139
+ @config.set :previous_revision, "gitPREV"
140
+ @config.set :previous_release, "/u/apps/rofl/releases/20080808082800-gitPREV"
141
+ @config.find_and_execute_task("deploy:rollback:revision")
142
+
143
+ @config.methods_called.must_include "deploy:update_code"
144
+ end
145
+
146
+ it "task :revision raises an exception if no previous release exists" do
147
+ @config.set :previous_release, nil
148
+
149
+ proc { @config.find_and_execute_task("deploy:rollback:revision") }.
150
+ must_raise RuntimeError
151
+ @config.methods_called.wont_include "deploy:update_code"
152
+ end
153
+
154
+ it "task :cleanup removes :current_release directory conditionally" do
155
+ @config.set :current_path, "/u/apps/rofl/current"
156
+ @config.set :latest_revision, "gitAAA"
157
+ @config.set :current_release, "/u/apps/rofl/releases/20120101020304-gitAAA"
158
+ @config.find_and_execute_task("deploy:rollback:cleanup")
159
+
160
+ cmd = [
161
+ "if [ `(cd /u/apps/rofl/current && git rev-parse HEAD)` != `gitAAA` ]; " +
162
+ "then rm -rf /u/apps/rofl/releases/20120101020304-gitAAA; fi"
163
+ ]
164
+ @config.must_have_run cmd.join, runs_msg(cmd.join)
165
+ end
166
+ end
167
+ end
168
+ end