rick-vlad 1.2.0.4
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.
- data/History.txt +49 -0
- data/Manifest.txt +35 -0
- data/README.txt +78 -0
- data/Rakefile +51 -0
- data/considerations.txt +91 -0
- data/doco/faq.txt +75 -0
- data/doco/getting_started.txt +41 -0
- data/doco/migration.txt +43 -0
- data/doco/perforce.txt +5 -0
- data/doco/variables.txt +77 -0
- data/lib/rake_remote_task.rb +573 -0
- data/lib/vlad/apache.rb +37 -0
- data/lib/vlad/core.rb +178 -0
- data/lib/vlad/git.rb +43 -0
- data/lib/vlad/lighttpd.rb +85 -0
- data/lib/vlad/maintenance.rb +23 -0
- data/lib/vlad/merb.god.rb +21 -0
- data/lib/vlad/mercurial.rb +34 -0
- data/lib/vlad/mongrel.rb +61 -0
- data/lib/vlad/nginx.rb +44 -0
- data/lib/vlad/perforce.rb +117 -0
- data/lib/vlad/subversion.rb +34 -0
- data/lib/vlad/thin.rb +71 -0
- data/lib/vlad/web.rb +12 -0
- data/lib/vlad.rb +90 -0
- data/test/test_rake_remote_task.rb +186 -0
- data/test/test_vlad.rb +211 -0
- data/test/test_vlad_git.rb +39 -0
- data/test/test_vlad_mercurial.rb +26 -0
- data/test/test_vlad_perforce.rb +37 -0
- data/test/test_vlad_subversion.rb +27 -0
- data/test/vlad_test_case.rb +71 -0
- data/vladdemo.sh +64 -0
- metadata +127 -0
data/lib/vlad/thin.rb
ADDED
@@ -0,0 +1,71 @@
|
|
1
|
+
# $GEM_HOME/gems/vlad-1.2.0/lib/vlad/thin.rb
|
2
|
+
# Thin tasks for Vlad the Deployer
|
3
|
+
# By cnantais
|
4
|
+
require 'vlad'
|
5
|
+
|
6
|
+
namespace :vlad do
|
7
|
+
##
|
8
|
+
# Thin app server
|
9
|
+
|
10
|
+
set :thin_address, "127.0.0.1"
|
11
|
+
set :thin_command, 'thin'
|
12
|
+
set(:thin_conf) { "#{shared_path}/thin_cluster.conf" }
|
13
|
+
set :thin_environment, "production"
|
14
|
+
set :thin_group, nil
|
15
|
+
set :thin_log_file, nil
|
16
|
+
set :thin_pid_file, nil
|
17
|
+
set :thin_port, nil
|
18
|
+
set :thin_socket, "/tmp/thin.sock"
|
19
|
+
set :thin_prefix, nil
|
20
|
+
set :thin_servers, 2
|
21
|
+
set :thin_user, nil
|
22
|
+
set :thin_rackup, nil
|
23
|
+
|
24
|
+
desc "Prepares application servers for deployment. thin
|
25
|
+
configuration is set via the thin_* variables.".cleanup
|
26
|
+
|
27
|
+
remote_task :setup_app, :roles => :app do
|
28
|
+
cmd = [
|
29
|
+
"#{thin_command} config",
|
30
|
+
"-s #{thin_servers}",
|
31
|
+
"-S #{thin_socket}",
|
32
|
+
"-e #{thin_environment}",
|
33
|
+
"-c #{current_path}",
|
34
|
+
"-C #{thin_conf}",
|
35
|
+
("-a #{thin_address}" if thin_address),
|
36
|
+
("-R #{thin_rackup}" if thin_rackup ),
|
37
|
+
("-P #{thin_pid_file}" if thin_pid_file),
|
38
|
+
("-l #{thin_log_file}" if thin_log_file),
|
39
|
+
("--user #{thin_user}" if thin_user),
|
40
|
+
("--group #{thin_group}" if thin_group),
|
41
|
+
("--prefix #{thin_prefix}" if thin_prefix),
|
42
|
+
("-p #{thin_port}" if thin_port),
|
43
|
+
].compact.join ' '
|
44
|
+
|
45
|
+
run cmd
|
46
|
+
end
|
47
|
+
|
48
|
+
def thin(cmd) # :nodoc:
|
49
|
+
"#{thin_command} #{cmd} -C #{thin_conf}"
|
50
|
+
end
|
51
|
+
|
52
|
+
desc "Restart the app servers"
|
53
|
+
|
54
|
+
remote_task :start_app, :roles => :app do
|
55
|
+
if (use_sudo)
|
56
|
+
sudo thin("restart -s #{thin_servers}")
|
57
|
+
else
|
58
|
+
run thin("restart -s #{thin_servers}")
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
desc "Stop the app servers"
|
63
|
+
|
64
|
+
remote_task :stop_app, :roles => :app do
|
65
|
+
if (use_sudo)
|
66
|
+
sudo thin("stop -s #{thin_servers}")
|
67
|
+
else
|
68
|
+
run thin("stop -s #{thin_servers}")
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
data/lib/vlad/web.rb
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
require 'vlad'
|
2
|
+
|
3
|
+
namespace :vlad do
|
4
|
+
namespace :web do
|
5
|
+
remote_task :enable, :roles => [:web] do
|
6
|
+
run "if [ -f #{shared_path}/system/maintenance.html ]; then rm -f #{shared_path}/system/maintenance.html; fi"
|
7
|
+
end
|
8
|
+
remote_task :disable, :roles => [:web] do
|
9
|
+
run "cp -f #{shared_path}/config/maintenance.html #{shared_path}/system/"
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
data/lib/vlad.rb
ADDED
@@ -0,0 +1,90 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'thread'
|
3
|
+
require 'rake_remote_task'
|
4
|
+
|
5
|
+
$TESTING ||= false
|
6
|
+
|
7
|
+
##
|
8
|
+
# Vlad the Deployer - Pragmatic application deployment automation, without mercy.
|
9
|
+
#
|
10
|
+
# Please read doco/getting_started.txt or http://rubyhitsquad.com/
|
11
|
+
#
|
12
|
+
# === Basic scenario:
|
13
|
+
#
|
14
|
+
# 1. rake vlad:setup (first time only)
|
15
|
+
# 2. rake vlad:update
|
16
|
+
# 3. rake vlad:migrate (optional)
|
17
|
+
# 4. rake vlad:start
|
18
|
+
|
19
|
+
module Vlad
|
20
|
+
|
21
|
+
##
|
22
|
+
# This is the version of Vlad you are running.
|
23
|
+
VERSION = '1.2.0.3'
|
24
|
+
|
25
|
+
##
|
26
|
+
# Base error class for all Vlad errors.
|
27
|
+
class Error < RuntimeError; end
|
28
|
+
|
29
|
+
##
|
30
|
+
# Raised when you have incorrectly configured Vlad.
|
31
|
+
class ConfigurationError < Error; end
|
32
|
+
|
33
|
+
##
|
34
|
+
# Raised when a remote command fails.
|
35
|
+
class CommandFailedError < Error; end
|
36
|
+
|
37
|
+
##
|
38
|
+
# Raised when an environment variable hasn't been set.
|
39
|
+
class FetchError < Error; end
|
40
|
+
|
41
|
+
##
|
42
|
+
# Loads tasks file +tasks_file+ and various recipe styles as a hash
|
43
|
+
# of category/style pairs. Recipes default to:
|
44
|
+
#
|
45
|
+
# :app => :mongrel
|
46
|
+
# :config => 'config/deploy.rb'
|
47
|
+
# :core => :core
|
48
|
+
# :scm => :subversion
|
49
|
+
# :web => :apache
|
50
|
+
#
|
51
|
+
# You can override individual values and/or set to nil to
|
52
|
+
# deactivate. :config will get loaded last to ensure that user
|
53
|
+
# variables override default values.
|
54
|
+
#
|
55
|
+
# And by all means, feel free to skip this entirely if it doesn't
|
56
|
+
# fit for you. All it does is a fancy-pants require. Require
|
57
|
+
# whatever files you need as you see fit straight from your
|
58
|
+
# Rakefile. YAY for simple and clean!
|
59
|
+
def self.load options = {}
|
60
|
+
options = {:config => options} if String === options
|
61
|
+
|
62
|
+
recipes = {
|
63
|
+
:config => 'config/deploy.rb',
|
64
|
+
:core => :core,
|
65
|
+
:scm => :git,
|
66
|
+
:app => :passenger
|
67
|
+
}.merge(options)
|
68
|
+
|
69
|
+
# be sure core comes first so base tasks aren't clobbered
|
70
|
+
if core = recipes.delete(:core)
|
71
|
+
require "vlad/#{core}"
|
72
|
+
end
|
73
|
+
recipes.each do |flavor, recipe|
|
74
|
+
next if recipe.nil? or flavor == :config
|
75
|
+
require "vlad/#{recipe}"
|
76
|
+
end
|
77
|
+
|
78
|
+
Kernel.load recipes[:config]
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
class String #:nodoc:
|
83
|
+
def cleanup
|
84
|
+
if ENV['FULL'] then
|
85
|
+
gsub(/\s+/, ' ').strip
|
86
|
+
else
|
87
|
+
self[/\A.*?\./]
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
@@ -0,0 +1,186 @@
|
|
1
|
+
require 'test/vlad_test_case'
|
2
|
+
require 'vlad'
|
3
|
+
|
4
|
+
class TestRakeRemoteTask < VladTestCase
|
5
|
+
def test_enhance
|
6
|
+
util_set_hosts
|
7
|
+
body = Proc.new { 5 }
|
8
|
+
task = @vlad.remote_task(:some_task => :foo, &body)
|
9
|
+
action = Rake::RemoteTask::Action.new(task, body)
|
10
|
+
assert_equal [action], task.remote_actions
|
11
|
+
assert_equal task, action.task
|
12
|
+
assert_equal ["foo"], task.prerequisites
|
13
|
+
end
|
14
|
+
|
15
|
+
def test_enhance_with_no_task_body
|
16
|
+
util_set_hosts
|
17
|
+
util_setup_task
|
18
|
+
assert_equal [], @task.remote_actions
|
19
|
+
assert_equal [], @task.prerequisites
|
20
|
+
end
|
21
|
+
|
22
|
+
def test_execute
|
23
|
+
util_set_hosts
|
24
|
+
set :some_variable, 1
|
25
|
+
x = 5
|
26
|
+
task = @vlad.remote_task(:some_task) { x += some_variable }
|
27
|
+
task.execute nil
|
28
|
+
assert_equal 1, task.some_variable
|
29
|
+
assert_equal 2, task.remote_actions.first.workers.size
|
30
|
+
assert_equal 7, x
|
31
|
+
end
|
32
|
+
|
33
|
+
def test_execute_exposes_target_host
|
34
|
+
host "app.example.com", :app
|
35
|
+
task = remote_task(:target_task) { set(:test_target_host, target_host) }
|
36
|
+
task.execute nil
|
37
|
+
assert_equal "app.example.com", Rake::RemoteTask.fetch(:test_target_host)
|
38
|
+
end
|
39
|
+
|
40
|
+
def test_execute_with_no_hosts
|
41
|
+
@vlad.host "app.example.com", :app
|
42
|
+
t = @vlad.remote_task(:flunk, :roles => :db) { flunk "should not have run" }
|
43
|
+
e = assert_raise(Vlad::ConfigurationError) { t.execute nil }
|
44
|
+
assert_equal "No target hosts specified for task: flunk", e.message
|
45
|
+
end
|
46
|
+
|
47
|
+
def test_execute_with_no_roles
|
48
|
+
t = @vlad.remote_task(:flunk, :roles => :junk) { flunk "should not have run" }
|
49
|
+
e = assert_raise(Vlad::ConfigurationError) { t.execute nil }
|
50
|
+
assert_equal "No target hosts specified for task: flunk", e.message
|
51
|
+
end
|
52
|
+
|
53
|
+
def test_execute_with_roles
|
54
|
+
util_set_hosts
|
55
|
+
set :some_variable, 1
|
56
|
+
x = 5
|
57
|
+
task = @vlad.remote_task(:some_task, :roles => :db) { x += some_variable }
|
58
|
+
task.execute nil
|
59
|
+
assert_equal 1, task.some_variable
|
60
|
+
assert_equal 6, x
|
61
|
+
end
|
62
|
+
|
63
|
+
def test_rsync
|
64
|
+
util_setup_task
|
65
|
+
@task.target_host = "app.example.com"
|
66
|
+
|
67
|
+
@task.rsync 'localfile', 'remotefile'
|
68
|
+
|
69
|
+
commands = @task.commands
|
70
|
+
|
71
|
+
assert_equal 1, commands.size, 'not enough commands'
|
72
|
+
assert_equal %w[rsync -azP --delete localfile app.example.com:remotefile],
|
73
|
+
commands.first, 'rsync'
|
74
|
+
end
|
75
|
+
|
76
|
+
def test_rsync_fail
|
77
|
+
util_setup_task
|
78
|
+
@task.target_host = "app.example.com"
|
79
|
+
@task.action = lambda { false }
|
80
|
+
|
81
|
+
e = assert_raise(Vlad::CommandFailedError) { @task.rsync 'local', 'remote' }
|
82
|
+
assert_equal "execution failed: rsync -azP --delete local app.example.com:remote", e.message
|
83
|
+
end
|
84
|
+
|
85
|
+
def test_run
|
86
|
+
util_setup_task
|
87
|
+
@task.output << "file1\nfile2\n"
|
88
|
+
@task.target_host = "app.example.com"
|
89
|
+
result = nil
|
90
|
+
|
91
|
+
out, err = util_capture do
|
92
|
+
result = @task.run("ls")
|
93
|
+
end
|
94
|
+
|
95
|
+
commands = @task.commands
|
96
|
+
|
97
|
+
assert_equal 1, commands.size, 'not enough commands'
|
98
|
+
assert_equal ["ssh", "app.example.com", "ls"],
|
99
|
+
commands.first, 'app'
|
100
|
+
assert_equal "file1\nfile2\n", result
|
101
|
+
|
102
|
+
assert_equal "file1\nfile2\n", out.read
|
103
|
+
assert_equal '', err.read
|
104
|
+
end
|
105
|
+
|
106
|
+
def test_run_failing_command
|
107
|
+
util_set_hosts
|
108
|
+
util_setup_task
|
109
|
+
@task.input = StringIO.new "file1\nfile2\n"
|
110
|
+
@task.target_host = 'app.example.com'
|
111
|
+
@task.action = lambda { 1 }
|
112
|
+
|
113
|
+
e = assert_raise(Vlad::CommandFailedError) { @task.run("ls") }
|
114
|
+
assert_equal "execution failed with status 1: ssh app.example.com ls", e.message
|
115
|
+
|
116
|
+
assert_equal 1, @task.commands.size
|
117
|
+
end
|
118
|
+
|
119
|
+
def test_run_sudo
|
120
|
+
util_setup_task
|
121
|
+
@task.output << "file1\nfile2\n"
|
122
|
+
@task.error << 'Password:'
|
123
|
+
@task.target_host = "app.example.com"
|
124
|
+
def @task.sudo_password() "my password" end # gets defined by set
|
125
|
+
result = nil
|
126
|
+
|
127
|
+
out, err = util_capture do
|
128
|
+
result = @task.run("sudo ls")
|
129
|
+
end
|
130
|
+
|
131
|
+
commands = @task.commands
|
132
|
+
|
133
|
+
assert_equal 1, commands.size, 'not enough commands'
|
134
|
+
assert_equal ['ssh', 'app.example.com', 'sudo ls'],
|
135
|
+
commands.first
|
136
|
+
|
137
|
+
assert_equal "my password\n", @task.input.string
|
138
|
+
|
139
|
+
# WARN: Technically incorrect, the password line should be
|
140
|
+
# first... this is an artifact of changes to the IO code in run
|
141
|
+
# and the fact that we have a very simplistic (non-blocking)
|
142
|
+
# testing model.
|
143
|
+
assert_equal "file1\nfile2\nPassword:\n", result
|
144
|
+
|
145
|
+
assert_equal "file1\nfile2\n", out.read
|
146
|
+
assert_equal "Password:\n", err.read
|
147
|
+
end
|
148
|
+
|
149
|
+
def test_sudo
|
150
|
+
util_setup_task
|
151
|
+
@task.target_host = "app.example.com"
|
152
|
+
@task.sudo "ls"
|
153
|
+
|
154
|
+
commands = @task.commands
|
155
|
+
|
156
|
+
assert_equal 1, commands.size, 'wrong number of commands'
|
157
|
+
assert_equal ["ssh", "app.example.com", "sudo ls"],
|
158
|
+
commands.first, 'app'
|
159
|
+
end
|
160
|
+
|
161
|
+
def util_capture
|
162
|
+
require 'stringio'
|
163
|
+
orig_stdout = $stdout.dup
|
164
|
+
orig_stderr = $stderr.dup
|
165
|
+
captured_stdout = StringIO.new
|
166
|
+
captured_stderr = StringIO.new
|
167
|
+
$stdout = captured_stdout
|
168
|
+
$stderr = captured_stderr
|
169
|
+
yield
|
170
|
+
captured_stdout.rewind
|
171
|
+
captured_stderr.rewind
|
172
|
+
return captured_stdout, captured_stderr
|
173
|
+
ensure
|
174
|
+
$stdout = orig_stdout
|
175
|
+
$stderr = orig_stderr
|
176
|
+
end
|
177
|
+
|
178
|
+
def util_setup_task(options = {})
|
179
|
+
@task = @vlad.remote_task :test_task, options
|
180
|
+
@task.commands = []
|
181
|
+
@task.output = []
|
182
|
+
@task.error = []
|
183
|
+
@task.action = nil
|
184
|
+
@task
|
185
|
+
end
|
186
|
+
end
|
data/test/test_vlad.rb
ADDED
@@ -0,0 +1,211 @@
|
|
1
|
+
require 'test/vlad_test_case'
|
2
|
+
require 'vlad'
|
3
|
+
|
4
|
+
$TESTING = true
|
5
|
+
|
6
|
+
class TestVlad < VladTestCase
|
7
|
+
def test_all_hosts
|
8
|
+
util_set_hosts
|
9
|
+
assert_equal %w[app.example.com db.example.com], @vlad.all_hosts
|
10
|
+
end
|
11
|
+
|
12
|
+
def test_fetch
|
13
|
+
set :foo, 5
|
14
|
+
assert_equal 5, @vlad.fetch(:foo)
|
15
|
+
end
|
16
|
+
|
17
|
+
def test_fetch_with_default
|
18
|
+
assert_equal 5, @vlad.fetch(:not_here, 5)
|
19
|
+
end
|
20
|
+
|
21
|
+
def test_host
|
22
|
+
@vlad.host "test.example.com", :app, :db
|
23
|
+
expected = {"test.example.com" => {}}
|
24
|
+
assert_equal expected, @vlad.roles[:app]
|
25
|
+
assert_equal expected, @vlad.roles[:db]
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_host_invalid
|
29
|
+
assert_raise(ArgumentError) { @vlad.host "", :app, :db }
|
30
|
+
assert_raise(ArgumentError) { @vlad.host nil, :web }
|
31
|
+
end
|
32
|
+
|
33
|
+
def test_host_multiple_hosts
|
34
|
+
@vlad.host "test.example.com", :app, :db
|
35
|
+
@vlad.host "yarr.example.com", :app, :db, :no_release => true
|
36
|
+
|
37
|
+
expected = {
|
38
|
+
"test.example.com" => {},
|
39
|
+
"yarr.example.com" => {:no_release => true}
|
40
|
+
}
|
41
|
+
|
42
|
+
assert_equal expected, @vlad.roles[:app]
|
43
|
+
assert_equal expected, @vlad.roles[:db]
|
44
|
+
assert_not_equal(@vlad.roles[:db]["test.example.com"].object_id,
|
45
|
+
@vlad.roles[:app]["test.example.com"].object_id)
|
46
|
+
end
|
47
|
+
|
48
|
+
def test_hosts_for_array_of_roles
|
49
|
+
util_set_hosts
|
50
|
+
assert_equal %w[app.example.com db.example.com], @vlad.hosts_for([:app, :db])
|
51
|
+
end
|
52
|
+
|
53
|
+
def test_hosts_for_one_role
|
54
|
+
util_set_hosts
|
55
|
+
@vlad.host "app2.example.com", :app
|
56
|
+
assert_equal %w[app.example.com app2.example.com], @vlad.hosts_for(:app)
|
57
|
+
end
|
58
|
+
|
59
|
+
def test_hosts_for_multiple_roles
|
60
|
+
util_set_hosts
|
61
|
+
assert_equal %w[app.example.com db.example.com], @vlad.hosts_for(:app, :db)
|
62
|
+
end
|
63
|
+
|
64
|
+
def test_hosts_for_unique
|
65
|
+
util_set_hosts
|
66
|
+
@vlad.host "app.example.com", :web
|
67
|
+
assert_equal %w[app.example.com db.example.com], @vlad.hosts_for(:app, :db, :web)
|
68
|
+
end
|
69
|
+
|
70
|
+
def test_initialize
|
71
|
+
@vlad.set_defaults # ensure these three are virginal
|
72
|
+
assert_raise(Vlad::ConfigurationError) { @vlad.code_repo }
|
73
|
+
assert_raise(Vlad::ConfigurationError) { @vlad.deploy_to }
|
74
|
+
assert_raise(Vlad::ConfigurationError) { @vlad.domain }
|
75
|
+
end
|
76
|
+
|
77
|
+
def test_role
|
78
|
+
@vlad.role :app, "test.example.com"
|
79
|
+
expected = {"test.example.com" => {}}
|
80
|
+
assert_equal expected, @vlad.roles[:app]
|
81
|
+
end
|
82
|
+
|
83
|
+
def test_role_multiple_hosts
|
84
|
+
@vlad.role :app, "test.example.com"
|
85
|
+
@vlad.role :app, "yarr.example.com", :no_release => true
|
86
|
+
expected = {
|
87
|
+
"test.example.com" => {},
|
88
|
+
"yarr.example.com" => {:no_release => true}
|
89
|
+
}
|
90
|
+
assert_equal expected, @vlad.roles[:app]
|
91
|
+
end
|
92
|
+
|
93
|
+
def test_role_multiple_roles
|
94
|
+
@vlad.role :app, "test.example.com", :primary => true
|
95
|
+
@vlad.role :db, "yarr.example.com", :no_release => true
|
96
|
+
expected_db = { "yarr.example.com" => {:no_release => true} }
|
97
|
+
assert_equal expected_db, @vlad.roles[:db]
|
98
|
+
expected_app = { "test.example.com" => {:primary => true} }
|
99
|
+
assert_equal expected_app, @vlad.roles[:app]
|
100
|
+
end
|
101
|
+
|
102
|
+
def test_remote_task
|
103
|
+
t = @vlad.remote_task(:test_task) { 5 }
|
104
|
+
assert_equal @task_count + 1, Rake.application.tasks.size
|
105
|
+
assert_equal Hash.new, t.options
|
106
|
+
end
|
107
|
+
|
108
|
+
def test_remote_task_all_hosts_by_default
|
109
|
+
util_set_hosts
|
110
|
+
t = @vlad.remote_task(:test_task) { 5 }
|
111
|
+
assert_equal %w[app.example.com db.example.com], t.target_hosts
|
112
|
+
end
|
113
|
+
|
114
|
+
def test_remote_task_environment_override
|
115
|
+
old_env_hosts = ENV["HOSTS"]
|
116
|
+
ENV["HOSTS"] = 'other1.example.com, other2.example.com'
|
117
|
+
util_set_hosts
|
118
|
+
t = @vlad.remote_task(:test_task) { 5 }
|
119
|
+
assert_equal %w[other1.example.com other2.example.com], t.target_hosts
|
120
|
+
ensure
|
121
|
+
ENV["HOSTS"] = old_env_hosts
|
122
|
+
end
|
123
|
+
|
124
|
+
def test_remote_task_body_set
|
125
|
+
set(:some_variable, 5)
|
126
|
+
@vlad.host 'www.example.com', :app
|
127
|
+
@vlad.remote_task(:some_task) do $some_task_result = some_variable end
|
128
|
+
|
129
|
+
Rake::Task['some_task'].execute nil
|
130
|
+
assert_equal @vlad.fetch(:some_variable), $some_task_result
|
131
|
+
end
|
132
|
+
|
133
|
+
def test_remote_task_with_options
|
134
|
+
t = @vlad.remote_task :test_task, :roles => [:app, :db] do
|
135
|
+
fail "should not run"
|
136
|
+
end
|
137
|
+
assert_equal({:roles => [:app, :db]}, t.options)
|
138
|
+
end
|
139
|
+
|
140
|
+
def test_remote_task_before_host_declaration
|
141
|
+
t = @vlad.remote_task :test_task, :roles => :web do 5 end
|
142
|
+
@vlad.host 'www.example.com', :web
|
143
|
+
assert_equal %w[www.example.com], t.target_hosts
|
144
|
+
end
|
145
|
+
|
146
|
+
def test_remote_task_role_override
|
147
|
+
host "db1", :db
|
148
|
+
host "db2", :db
|
149
|
+
host "db3", :db
|
150
|
+
host "master", :master_db
|
151
|
+
|
152
|
+
remote_task(:migrate_the_db, :roles => [:db]) { flunk "bad!" }
|
153
|
+
task = Rake::Task["migrate_the_db"]
|
154
|
+
assert_equal %w[db1 db2 db3], task.target_hosts
|
155
|
+
|
156
|
+
task.options[:roles] = :master_db
|
157
|
+
assert_equal %w[master], task.target_hosts
|
158
|
+
|
159
|
+
task.options[:roles] = [:master_db]
|
160
|
+
assert_equal %w[master], task.target_hosts
|
161
|
+
end
|
162
|
+
|
163
|
+
def test_set
|
164
|
+
set :test, 5
|
165
|
+
assert_equal 5, @vlad.test
|
166
|
+
end
|
167
|
+
|
168
|
+
def test_set_lazy_block_evaluation
|
169
|
+
set(:test) { fail "lose" }
|
170
|
+
assert_raise(RuntimeError) { @vlad.test }
|
171
|
+
end
|
172
|
+
|
173
|
+
def test_set_with_block
|
174
|
+
x = 1
|
175
|
+
set(:test) { x += 2 }
|
176
|
+
|
177
|
+
assert_equal 3, @vlad.test
|
178
|
+
assert_equal 3, @vlad.test
|
179
|
+
end
|
180
|
+
|
181
|
+
def test_set_with_reference
|
182
|
+
@vlad.instance_eval do
|
183
|
+
set(:var_one) { var_two }
|
184
|
+
set(:var_two) { var_three }
|
185
|
+
set(:var_three) { 5 }
|
186
|
+
end
|
187
|
+
|
188
|
+
assert_equal 5, @vlad.var_one
|
189
|
+
end
|
190
|
+
|
191
|
+
def test_set_with_block_and_value
|
192
|
+
e = assert_raise(ArgumentError) do
|
193
|
+
set(:test, 5) { 6 }
|
194
|
+
end
|
195
|
+
assert_equal "cannot provide both a value and a block", e.message
|
196
|
+
end
|
197
|
+
|
198
|
+
def test_set_with_nil
|
199
|
+
set(:test, nil)
|
200
|
+
assert_equal nil, @vlad.test
|
201
|
+
end
|
202
|
+
|
203
|
+
def test_set_with_reserved_name
|
204
|
+
$TESTING = false
|
205
|
+
e = assert_raise(ArgumentError) { set(:all_hosts, []) }
|
206
|
+
assert_equal "cannot set reserved name: 'all_hosts'", e.message
|
207
|
+
ensure
|
208
|
+
$TESTING = true
|
209
|
+
end
|
210
|
+
end
|
211
|
+
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'test/vlad_test_case'
|
2
|
+
require 'vlad'
|
3
|
+
require 'vlad/git'
|
4
|
+
|
5
|
+
class TestVladGit < VladTestCase
|
6
|
+
def setup
|
7
|
+
super
|
8
|
+
@scm = Vlad::Git.new
|
9
|
+
set :code_repo, "git@myhost:/home/john/project1"
|
10
|
+
end
|
11
|
+
|
12
|
+
def test_checkout
|
13
|
+
# Checkout to the current directory (which is what the :update task passes)
|
14
|
+
cmd = @scm.checkout 'master', '.'
|
15
|
+
assert_equal 'rm -rf repo && git clone git@myhost:/home/john/project1 repo && cd repo && git checkout -f -b deployed-master master', cmd
|
16
|
+
|
17
|
+
# Mimic :update task
|
18
|
+
# 'head' should become HEAD
|
19
|
+
cmd = @scm.checkout 'head', '.'
|
20
|
+
assert_equal 'rm -rf repo && git clone git@myhost:/home/john/project1 repo && cd repo && git checkout -f -b deployed-HEAD HEAD', cmd
|
21
|
+
|
22
|
+
# Checkout to a relative path
|
23
|
+
cmd = @scm.checkout 'master', 'some/relative/path'
|
24
|
+
assert_equal 'rm -rf some/relative/path && git clone git@myhost:/home/john/project1 some/relative/path && cd some/relative/path && git checkout -f -b deployed-master master', cmd
|
25
|
+
end
|
26
|
+
|
27
|
+
def test_export
|
28
|
+
cmd = @scm.export 'master', 'the/release/path'
|
29
|
+
assert_equal 'mkdir -p the/release/path && git archive --format=tar master | (cd the/release/path && tar xf -)', cmd
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_revision
|
33
|
+
['head', 'HEAD'].each do |head|
|
34
|
+
cmd = @scm.revision(head)
|
35
|
+
expected = "`git rev-parse HEAD`"
|
36
|
+
assert_equal expected, cmd
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'test/vlad_test_case'
|
2
|
+
require 'vlad'
|
3
|
+
require 'vlad/mercurial'
|
4
|
+
|
5
|
+
class TestVladMercurial < Test::Unit::TestCase
|
6
|
+
def setup
|
7
|
+
@scm = Vlad::Mercurial.new
|
8
|
+
set :code_repo, "http://repo/project"
|
9
|
+
end
|
10
|
+
|
11
|
+
def test_checkout
|
12
|
+
cmd = @scm.checkout 'head', '/the/place'
|
13
|
+
assert_equal 'hg pull -r tip -R /the/place http://repo/project', cmd
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_export
|
17
|
+
cmd = @scm.export 'head', '/the/place'
|
18
|
+
assert_equal 'hg archive -r tip -R http://repo/project /the/place', cmd
|
19
|
+
end
|
20
|
+
|
21
|
+
def test_revision
|
22
|
+
cmd = @scm.revision('tip')
|
23
|
+
expected = "`hg identify -R http://repo/project | cut -f1 -d\\ `"
|
24
|
+
assert_equal expected, cmd
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'test/vlad_test_case'
|
2
|
+
require 'vlad'
|
3
|
+
require 'vlad/perforce'
|
4
|
+
|
5
|
+
class TestVladPerforce < VladTestCase
|
6
|
+
def setup
|
7
|
+
super
|
8
|
+
@scm = Vlad::Perforce.new
|
9
|
+
end
|
10
|
+
|
11
|
+
def test_checkout
|
12
|
+
cmd = @scm.checkout 'head', '/the/place'
|
13
|
+
assert_equal 'p4 sync ...#head', cmd
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_checkout_revision
|
17
|
+
cmd = @scm.checkout 555, '/the/place'
|
18
|
+
assert_equal 'p4 sync ...@555', cmd
|
19
|
+
end
|
20
|
+
|
21
|
+
def test_export
|
22
|
+
cmd = @scm.export 'head', '/the/place'
|
23
|
+
assert_equal '(cd /the/place && p4 sync ...#head)', cmd
|
24
|
+
end
|
25
|
+
|
26
|
+
def test_revision
|
27
|
+
cmd = @scm.revision('head')
|
28
|
+
assert_equal '`p4 changes -s submitted -m 1 ...#head | cut -f 2 -d\\ `', cmd
|
29
|
+
end
|
30
|
+
|
31
|
+
def test_rev_no
|
32
|
+
assert_equal "@555", @scm.rev_no(555)
|
33
|
+
assert_equal "#head", @scm.rev_no('head')
|
34
|
+
assert_equal "#head", @scm.rev_no('HEAD')
|
35
|
+
assert_equal "@666", @scm.rev_no("@666")
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'test/vlad_test_case'
|
2
|
+
require 'vlad'
|
3
|
+
require 'vlad/subversion'
|
4
|
+
|
5
|
+
class TestVladSubversion < VladTestCase
|
6
|
+
def setup
|
7
|
+
super
|
8
|
+
@scm = Vlad::Subversion.new
|
9
|
+
set :code_repo, "svn+ssh://repo/myproject"
|
10
|
+
end
|
11
|
+
|
12
|
+
def test_checkout
|
13
|
+
cmd = @scm.checkout 'HEAD', '/the/place'
|
14
|
+
assert_equal 'svn co -r HEAD svn+ssh://repo/myproject /the/place', cmd
|
15
|
+
end
|
16
|
+
|
17
|
+
def test_export
|
18
|
+
cmd = @scm.export 'HEAD', '/the/place'
|
19
|
+
assert_equal 'svn export -r HEAD svn+ssh://repo/myproject /the/place', cmd
|
20
|
+
end
|
21
|
+
|
22
|
+
def test_revision
|
23
|
+
cmd = @scm.revision('HEAD')
|
24
|
+
expected = "`svn info svn+ssh://repo/myproject | grep 'Revision:' | cut -f2 -d\\ `"
|
25
|
+
assert_equal expected, cmd
|
26
|
+
end
|
27
|
+
end
|