engineyard-serverside 1.6.5 → 1.7.0.pre2
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/engineyard-serverside.rb +2 -0
- data/lib/engineyard-serverside/cli.rb +83 -48
- data/lib/engineyard-serverside/configuration.rb +85 -18
- data/lib/engineyard-serverside/deploy.rb +105 -91
- data/lib/engineyard-serverside/deploy_hook.rb +22 -20
- data/lib/engineyard-serverside/deprecation.rb +9 -17
- data/lib/engineyard-serverside/future.rb +10 -4
- data/lib/engineyard-serverside/futures/celluloid.rb +3 -13
- data/lib/engineyard-serverside/futures/dataflow.rb +8 -13
- data/lib/engineyard-serverside/lockfile_parser.rb +1 -1
- data/lib/engineyard-serverside/rails_asset_support.rb +26 -10
- data/lib/engineyard-serverside/server.rb +17 -12
- data/lib/engineyard-serverside/shell.rb +98 -0
- data/lib/engineyard-serverside/shell/formatter.rb +71 -0
- data/lib/engineyard-serverside/shell/helpers.rb +29 -0
- data/lib/engineyard-serverside/strategies/git.rb +33 -63
- data/lib/engineyard-serverside/task.rb +34 -13
- data/lib/engineyard-serverside/version.rb +1 -1
- data/spec/basic_deploy_spec.rb +15 -50
- data/spec/bundler_deploy_spec.rb +3 -44
- data/spec/configuration_spec.rb +72 -0
- data/spec/custom_deploy_spec.rb +3 -4
- data/spec/deploy_hook_spec.rb +210 -162
- data/spec/deprecation_spec.rb +4 -26
- data/spec/ey_yml_customized_deploy_spec.rb +68 -0
- data/spec/fixtures/repos/assets_disabled/Gemfile +6 -0
- data/spec/fixtures/repos/assets_disabled/Gemfile.lock +90 -0
- data/spec/fixtures/repos/assets_disabled/README +1 -0
- data/spec/fixtures/repos/assets_disabled/Rakefile +5 -0
- data/spec/fixtures/repos/assets_disabled/config/application.rb +5 -0
- data/spec/fixtures/repos/assets_disabled_in_ey_yml/Gemfile +6 -0
- data/spec/fixtures/repos/assets_disabled_in_ey_yml/Gemfile.lock +90 -0
- data/spec/fixtures/repos/assets_disabled_in_ey_yml/README +1 -0
- data/spec/fixtures/repos/assets_disabled_in_ey_yml/Rakefile +5 -0
- data/spec/fixtures/repos/assets_disabled_in_ey_yml/config/application.rb +5 -0
- data/spec/fixtures/repos/assets_disabled_in_ey_yml/config/ey.yml +4 -0
- data/spec/fixtures/repos/assets_enabled/Gemfile +6 -0
- data/spec/fixtures/repos/assets_enabled/Gemfile.lock +90 -0
- data/spec/fixtures/repos/assets_enabled/README +1 -0
- data/spec/fixtures/repos/assets_enabled/Rakefile +5 -0
- data/spec/fixtures/repos/assets_enabled/config/application.rb +5 -0
- data/spec/fixtures/repos/assets_enabled_in_ey_yml/README +1 -0
- data/spec/fixtures/repos/assets_enabled_in_ey_yml/Rakefile +5 -0
- data/spec/fixtures/repos/assets_enabled_in_ey_yml/config/ey.yml +4 -0
- data/spec/fixtures/repos/assets_in_hook/Gemfile +6 -0
- data/spec/fixtures/repos/assets_in_hook/Gemfile.lock +90 -0
- data/spec/fixtures/repos/assets_in_hook/README +2 -0
- data/spec/fixtures/repos/assets_in_hook/Rakefile +5 -0
- data/spec/fixtures/repos/assets_in_hook/config/application.rb +5 -0
- data/spec/fixtures/repos/assets_in_hook/deploy/before_migrate.rb +1 -0
- data/spec/fixtures/repos/default/Gemfile +5 -0
- data/spec/fixtures/repos/default/Gemfile.lock +14 -0
- data/spec/fixtures/repos/default/README +5 -0
- data/spec/fixtures/repos/ey_yml/Gemfile +4 -0
- data/spec/fixtures/repos/ey_yml/Gemfile.lock +12 -0
- data/spec/fixtures/repos/ey_yml/README +1 -0
- data/spec/fixtures/repos/ey_yml/config/ey.yml +12 -0
- data/spec/fixtures/repos/ey_yml/deploy/before_migrate.rb +6 -0
- data/spec/fixtures/repos/ey_yml_alt/Gemfile +4 -0
- data/spec/fixtures/repos/ey_yml_alt/Gemfile.lock +12 -0
- data/spec/fixtures/repos/ey_yml_alt/README +1 -0
- data/spec/fixtures/repos/ey_yml_alt/deploy/before_migrate.rb +6 -0
- data/spec/fixtures/repos/ey_yml_alt/ey.yml +12 -0
- data/spec/fixtures/repos/hook_fails/README +1 -0
- data/spec/fixtures/repos/hook_fails/deploy/before_migrate.rb +1 -0
- data/spec/fixtures/repos/hooks/README +1 -0
- data/spec/fixtures/repos/hooks/deploy/after_bundle.rb +1 -0
- data/spec/fixtures/repos/hooks/deploy/after_compile_assets.rb +1 -0
- data/spec/fixtures/repos/hooks/deploy/after_migrate.rb +1 -0
- data/spec/fixtures/repos/hooks/deploy/after_restart.rb +1 -0
- data/spec/fixtures/repos/hooks/deploy/after_symlink.rb +1 -0
- data/spec/fixtures/repos/hooks/deploy/before_bundle.rb +1 -0
- data/spec/fixtures/repos/hooks/deploy/before_compile_assets.rb +1 -0
- data/spec/fixtures/repos/hooks/deploy/before_migrate.rb +1 -0
- data/spec/fixtures/repos/hooks/deploy/before_restart.rb +1 -0
- data/spec/fixtures/repos/hooks/deploy/before_symlink.rb +1 -0
- data/spec/fixtures/repos/no_ey_config/Gemfile +4 -0
- data/spec/fixtures/repos/no_ey_config/Gemfile.lock +12 -0
- data/spec/fixtures/repos/no_ey_config/README +1 -0
- data/spec/fixtures/repos/no_gemfile_lock/Gemfile +5 -0
- data/spec/fixtures/repos/no_gemfile_lock/README +1 -0
- data/spec/fixtures/repos/nodejs/README +1 -0
- data/spec/fixtures/repos/nodejs/package.json +7 -0
- data/spec/fixtures/repos/not_bundled/README +1 -0
- data/spec/fixtures/{gemfiles/1.0.21-rails-31-with-sqlite → repos/sqlite3/Gemfile} +0 -0
- data/spec/fixtures/{lockfiles/1.0.21-rails-31-with-sqlite → repos/sqlite3/Gemfile.lock} +0 -0
- data/spec/fixtures/repos/sqlite3/README +1 -0
- data/spec/git_strategy_spec.rb +11 -2
- data/spec/lockfile_parser_spec.rb +8 -3
- data/spec/nodejs_deploy_spec.rb +1 -26
- data/spec/rails31_deploy_spec.rb +23 -31
- data/spec/services_deploy_spec.rb +41 -100
- data/spec/shell_spec.rb +50 -0
- data/spec/spec_helper.rb +80 -66
- data/spec/sqlite3_deploy_spec.rb +10 -16
- data/spec/support/integration.rb +45 -139
- metadata +233 -78
- data/lib/engineyard-serverside/logged_output.rb +0 -91
- data/spec/logged_output_spec.rb +0 -55
@@ -0,0 +1,72 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe EY::Serverside::Deploy::Configuration do
|
4
|
+
describe "ey.yml loading" do
|
5
|
+
before(:each) do
|
6
|
+
@tempdir = `mktemp -d -t ey_yml_spec.XXXXX`.strip
|
7
|
+
@config = EY::Serverside::Deploy::Configuration.new({
|
8
|
+
'repository_cache' => @tempdir,
|
9
|
+
'environment_name' => 'env_name',
|
10
|
+
'account_name' => 'acc',
|
11
|
+
'migrate' => nil,
|
12
|
+
'branch' => 'branch_from_command_line',
|
13
|
+
'config' => {'custom' => 'custom_from_extra_config'}.to_json
|
14
|
+
})
|
15
|
+
|
16
|
+
@deploy = FullTestDeploy.new(@config, test_shell)
|
17
|
+
|
18
|
+
@yaml_data = {
|
19
|
+
'environments' => {
|
20
|
+
'env_name' => {
|
21
|
+
'copy_exclude' => ['.git'],
|
22
|
+
'migrate' => true,
|
23
|
+
'migration_command' => 'uh oh',
|
24
|
+
'branch' => 'branch_from_ey_yml',
|
25
|
+
'custom' => 'custom_from_ey_yml',
|
26
|
+
'bundle_without' => 'only test',
|
27
|
+
}
|
28
|
+
}
|
29
|
+
}
|
30
|
+
end
|
31
|
+
|
32
|
+
def write_ey_yml(relative_path, data)
|
33
|
+
FileUtils.mkdir_p(File.join(
|
34
|
+
@tempdir,
|
35
|
+
File.dirname(relative_path)))
|
36
|
+
|
37
|
+
File.open(File.join(@tempdir, relative_path), 'w') do |f|
|
38
|
+
f.write data.to_yaml
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
it "requires 'ey.yml' and adds any defined methods to the deploy" do
|
43
|
+
write_ey_yml 'ey.yml', @yaml_data
|
44
|
+
@deploy.load_ey_yml
|
45
|
+
@deploy.config.copy_exclude.should == ['.git']
|
46
|
+
end
|
47
|
+
|
48
|
+
it "falls back to 'config/ey.yml'" do
|
49
|
+
write_ey_yml 'config/ey.yml', @yaml_data
|
50
|
+
@deploy.load_ey_yml
|
51
|
+
@deploy.config.copy_exclude.should == ['.git']
|
52
|
+
end
|
53
|
+
|
54
|
+
it "loads at lower priority than command line options" do
|
55
|
+
write_ey_yml 'ey.yml', @yaml_data
|
56
|
+
@deploy.load_ey_yml
|
57
|
+
@deploy.config.migrate?.should == false
|
58
|
+
end
|
59
|
+
|
60
|
+
it "loads at lower priority than json config option" do
|
61
|
+
write_ey_yml 'ey.yml', @yaml_data
|
62
|
+
@deploy.load_ey_yml
|
63
|
+
@deploy.config.branch.should == 'branch_from_command_line'
|
64
|
+
end
|
65
|
+
|
66
|
+
it "loads bundle_without from the config, which overrides the default" do
|
67
|
+
write_ey_yml 'ey.yml', @yaml_data
|
68
|
+
@deploy.load_ey_yml
|
69
|
+
@deploy.config.bundle_without.should == 'only test'
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
data/spec/custom_deploy_spec.rb
CHANGED
@@ -11,7 +11,6 @@ describe "the EY::Serverside::Deploy API" do
|
|
11
11
|
# cheat a bit; we don't actually want to do these things
|
12
12
|
def require_custom_tasks() end
|
13
13
|
def callback(*_) end
|
14
|
-
def puts(*_) 'stfu' end
|
15
14
|
|
16
15
|
attr_reader :call_order
|
17
16
|
def initialize(*a)
|
@@ -34,7 +33,7 @@ describe "the EY::Serverside::Deploy API" do
|
|
34
33
|
def disable_maintenance_page() @call_order << 'disable_maintenance_page' end
|
35
34
|
end
|
36
35
|
|
37
|
-
td = TestDeploy.new(EY::Serverside::Deploy::Configuration.new)
|
36
|
+
td = TestDeploy.new(EY::Serverside::Deploy::Configuration.new, test_shell)
|
38
37
|
td.deploy
|
39
38
|
td.call_order.should == %w(
|
40
39
|
push_code
|
@@ -60,7 +59,7 @@ describe "the EY::Serverside::Deploy API" do
|
|
60
59
|
before(:each) do
|
61
60
|
@tempdir = `mktemp -d -t custom_deploy_spec.XXXXX`.strip
|
62
61
|
@config = EY::Serverside::Deploy::Configuration.new('repository_cache' => @tempdir)
|
63
|
-
@deploy = TestQuietDeploy.new(@config)
|
62
|
+
@deploy = TestQuietDeploy.new(@config, test_shell)
|
64
63
|
end
|
65
64
|
|
66
65
|
def write_eydeploy(relative_path, contents = "def got_new_methods() 'from the file on disk' end")
|
@@ -92,7 +91,7 @@ describe "the EY::Serverside::Deploy API" do
|
|
92
91
|
def value() 'base' end
|
93
92
|
end
|
94
93
|
|
95
|
-
deploy = TestDeploySuper.new(@config)
|
94
|
+
deploy = TestDeploySuper.new(@config, test_shell)
|
96
95
|
deploy.require_custom_tasks.should be_true
|
97
96
|
deploy.value.should == "base + derived"
|
98
97
|
end
|
data/spec/deploy_hook_spec.rb
CHANGED
@@ -1,213 +1,261 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
describe "
|
4
|
-
|
5
|
-
|
6
|
-
|
3
|
+
describe "deploy hooks" do
|
4
|
+
context "successful deploy with all hooks" do
|
5
|
+
before(:all) do
|
6
|
+
deploy_test_application('hooks')
|
7
|
+
end
|
7
8
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
9
|
+
it "runs all the hooks" do
|
10
|
+
@deploy_dir.join('current', 'before_bundle.ran' ).should exist
|
11
|
+
@deploy_dir.join('current', 'after_bundle.ran' ).should exist
|
12
|
+
@deploy_dir.join('current', 'before_migrate.ran').should exist
|
13
|
+
@deploy_dir.join('current', 'after_migrate.ran' ).should exist
|
14
|
+
@deploy_dir.join('current', 'before_compile_assets.ran').should exist
|
15
|
+
@deploy_dir.join('current', 'after_compile_assets.ran' ).should exist
|
16
|
+
@deploy_dir.join('current', 'before_symlink.ran').should exist
|
17
|
+
@deploy_dir.join('current', 'after_symlink.ran' ).should exist
|
18
|
+
@deploy_dir.join('current', 'before_restart.ran').should exist
|
19
|
+
@deploy_dir.join('current', 'after_restart.ran' ).should exist
|
20
|
+
end
|
16
21
|
end
|
17
22
|
|
18
|
-
context "
|
19
|
-
|
20
|
-
|
23
|
+
context "with failing deploy hook" do
|
24
|
+
before(:all) do
|
25
|
+
begin
|
26
|
+
deploy_test_application('hook_fails')
|
27
|
+
rescue EY::Serverside::RemoteFailure
|
28
|
+
end
|
21
29
|
end
|
22
30
|
|
23
|
-
it "
|
24
|
-
|
25
|
-
|
31
|
+
it "retains the failed release" do
|
32
|
+
release_name = File.basename(@config.release_path)
|
33
|
+
@deploy_dir.join('releases_failed', release_name).should be_directory
|
34
|
+
end
|
35
|
+
end
|
26
36
|
|
27
|
-
|
37
|
+
context "deploy hook API" do
|
28
38
|
|
29
|
-
|
39
|
+
def deploy_hook(options={})
|
40
|
+
config = EY::Serverside::Deploy::Configuration.new(options)
|
41
|
+
EY::Serverside::DeployHook.new(config, test_shell)
|
30
42
|
end
|
31
43
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
end
|
44
|
+
context "#run" do
|
45
|
+
it "is available" do
|
46
|
+
deploy_hook.eval_hook('respond_to?(:run)').should be_true
|
47
|
+
end
|
37
48
|
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
end
|
49
|
+
it "runs commands like the shell does" do
|
50
|
+
ENV['COUNT'] = 'Chocula'
|
51
|
+
File.unlink("/tmp/deploy_hook_spec.the_count") rescue nil
|
42
52
|
|
43
|
-
|
44
|
-
callback = deploy_hook.callback_context
|
45
|
-
callback.should_receive(:system).with("sudo sh -l -c 'do it as root'").and_return(true)
|
46
|
-
callback.instance_eval { sudo("do it as root") }
|
47
|
-
end
|
48
|
-
end
|
53
|
+
deploy_hook.eval_hook('run("echo $COUNT > /tmp/deploy_hook_spec.the_count")')
|
49
54
|
|
50
|
-
|
51
|
-
|
52
|
-
run_hook { respond_to?(:latest_release) }.should be_true
|
53
|
-
run_hook { respond_to?(:previous_release) }.should be_true
|
54
|
-
run_hook { respond_to?(:all_releases) }.should be_true
|
55
|
-
run_hook { respond_to?(:current_path) }.should be_true
|
56
|
-
run_hook { respond_to?(:shared_path) }.should be_true
|
57
|
-
run_hook { respond_to?(:release_dir) }.should be_true
|
58
|
-
run_hook { respond_to?(:failed_release_dir)}.should be_true
|
59
|
-
run_hook { respond_to?(:release_path) }.should be_true
|
60
|
-
end
|
61
|
-
end
|
55
|
+
IO.read("/tmp/deploy_hook_spec.the_count").strip.should == "Chocula"
|
56
|
+
end
|
62
57
|
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
'applications' => {
|
68
|
-
'myapp' => {
|
69
|
-
'type' => 'rails',
|
70
|
-
'branch' => 'master',
|
71
|
-
}
|
72
|
-
}
|
73
|
-
}.to_json
|
58
|
+
it "returns true/false to indicate the command's success" do
|
59
|
+
deploy_hook.eval_hook('run("true")').should be_true
|
60
|
+
deploy_hook.eval_hook('run("false")').should be_false
|
61
|
+
end
|
74
62
|
end
|
75
63
|
|
76
|
-
|
77
|
-
|
78
|
-
|
64
|
+
context "#sudo" do
|
65
|
+
it "is available" do
|
66
|
+
deploy_hook.eval_hook('respond_to?(:sudo)').should be_true
|
67
|
+
end
|
79
68
|
|
80
|
-
|
81
|
-
|
82
|
-
|
69
|
+
it "runs things with sudo" do
|
70
|
+
hook = deploy_hook
|
71
|
+
cmd = "sudo sh -l -c 'do it as root'"
|
72
|
+
result = EY::Serverside::Shell::CommandResult.new(cmd, 0, "out\nerr")
|
73
|
+
hook.callback_context.shell.should_receive(:logged_system).with(cmd).and_return(result)
|
74
|
+
hook.eval_hook('sudo("do it as root") || raise("failed")')
|
75
|
+
end
|
83
76
|
end
|
84
77
|
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
78
|
+
context "capistrano-ish methods" do
|
79
|
+
it "has them" do
|
80
|
+
deploy_hook.eval_hook('respond_to?(:latest_release) ').should be_true
|
81
|
+
deploy_hook.eval_hook('respond_to?(:previous_release) ').should be_true
|
82
|
+
deploy_hook.eval_hook('respond_to?(:all_releases) ').should be_true
|
83
|
+
deploy_hook.eval_hook('respond_to?(:current_path) ').should be_true
|
84
|
+
deploy_hook.eval_hook('respond_to?(:shared_path) ').should be_true
|
85
|
+
deploy_hook.eval_hook('respond_to?(:release_dir) ').should be_true
|
86
|
+
deploy_hook.eval_hook('respond_to?(:failed_release_dir)').should be_true
|
87
|
+
deploy_hook.eval_hook('respond_to?(:release_path) ').should be_true
|
88
|
+
end
|
89
89
|
end
|
90
|
-
end
|
91
90
|
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
91
|
+
context "access to command line options that should be handed through to the config" do
|
92
|
+
before do
|
93
|
+
@hook = deploy_hook({'app' => 'app', 'environment_name' => 'env', 'account_name' => 'acc'})
|
94
|
+
end
|
96
95
|
|
97
|
-
|
98
|
-
|
99
|
-
|
96
|
+
it "has account_name" do
|
97
|
+
@hook.eval_hook('account_name').should == 'acc'
|
98
|
+
end
|
100
99
|
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
run_hook('bert' => 'ernie') { @configuration['bert'] }.should == 'ernie'
|
105
|
-
end
|
100
|
+
it "has environment_name" do
|
101
|
+
@hook.eval_hook('environment_name').should == 'env'
|
102
|
+
end
|
106
103
|
|
107
|
-
|
108
|
-
|
109
|
-
:branch,
|
110
|
-
:shared_path,
|
111
|
-
:deploy_to,
|
112
|
-
:user,
|
113
|
-
:revision,
|
114
|
-
:environment].each do |attribute|
|
115
|
-
it "has the #{attribute.inspect} attribute for compatibility with chef-deploy" do
|
116
|
-
run_hook { @configuration.has_key?(attribute) }.should be_true
|
104
|
+
it "has app_name" do
|
105
|
+
@hook.eval_hook('app_name').should == 'app'
|
117
106
|
end
|
118
107
|
end
|
119
|
-
end
|
120
108
|
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
109
|
+
context "the @node ivar" do
|
110
|
+
before(:each) do
|
111
|
+
EY::Serverside.dna_json = {
|
112
|
+
'instance_role' => 'solo',
|
113
|
+
'applications' => {
|
114
|
+
'myapp' => {
|
115
|
+
'type' => 'rails',
|
116
|
+
'branch' => 'master',
|
117
|
+
}
|
118
|
+
}
|
119
|
+
}.to_json
|
120
|
+
end
|
121
|
+
|
122
|
+
it "is available" do
|
123
|
+
deploy_hook.eval_hook('@node.nil?').should be_false
|
124
|
+
end
|
129
125
|
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
{:instance_role => 'util', :name => "alpha"},
|
141
|
-
{:instance_role => 'util', :name => "beta"},
|
142
|
-
{:instance_role => 'util', :name => "gamma"},
|
143
|
-
]
|
126
|
+
it "has indifferent access" do
|
127
|
+
deploy_hook.eval_hook('@node[:instance_role] ').should == 'solo'
|
128
|
+
deploy_hook.eval_hook('@node["instance_role"]').should == 'solo'
|
129
|
+
end
|
130
|
+
|
131
|
+
it "has deep indifferent access" do
|
132
|
+
deploy_hook.eval_hook('@node["applications"]["myapp"]["type"]').should == 'rails'
|
133
|
+
deploy_hook.eval_hook('@node[:applications]["myapp"][:type] ').should == 'rails'
|
134
|
+
deploy_hook.eval_hook('@node[:applications][:myapp][:type] ').should == 'rails'
|
135
|
+
end
|
144
136
|
end
|
145
137
|
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
138
|
+
context "the @configuration ivar" do
|
139
|
+
it "is available" do
|
140
|
+
deploy_hook.eval_hook('@configuration.nil?').should be_false
|
141
|
+
end
|
142
|
+
|
143
|
+
it "has the configuration in it" do
|
144
|
+
deploy_hook('bert' => 'ernie').eval_hook('@configuration.bert').should == 'ernie'
|
145
|
+
end
|
146
|
+
|
147
|
+
it "can be accessed with method calls, with [:symbols], or ['strings']" do
|
148
|
+
deploy_hook('bert' => 'ernie').eval_hook('@configuration.bert ').should == 'ernie'
|
149
|
+
deploy_hook('bert' => 'ernie').eval_hook('@configuration[:bert] ').should == 'ernie'
|
150
|
+
deploy_hook('bert' => 'ernie').eval_hook('@configuration["bert"]').should == 'ernie'
|
151
|
+
end
|
151
152
|
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
153
|
+
[:repository_cache,
|
154
|
+
:release_path,
|
155
|
+
:branch,
|
156
|
+
:shared_path,
|
157
|
+
:deploy_to,
|
158
|
+
:user,
|
159
|
+
:revision,
|
160
|
+
:environment].each do |attribute|
|
161
|
+
it "has the #{attribute.inspect} attribute for compatibility with chef-deploy" do
|
162
|
+
deploy_hook.eval_hook("@configuration.has_key?(#{attribute.inspect})").should be_true
|
156
163
|
end
|
157
|
-
end
|
164
|
+
end
|
158
165
|
end
|
159
166
|
|
160
|
-
|
161
|
-
|
167
|
+
context "environment variables" do
|
168
|
+
it "sets the framework env variables" do
|
169
|
+
run_hook('framework_env' => 'production') { ENV['RAILS_ENV'] }.should == 'production'
|
170
|
+
run_hook('framework_env' => 'production') { ENV['RACK_ENV'] }.should == 'production'
|
171
|
+
run_hook('framework_env' => 'production') { ENV['MERB_ENV'] }.should == 'production'
|
172
|
+
run_hook('framework_env' => 'production') { ENV['NODE_ENV'] }.should == 'production'
|
173
|
+
end
|
162
174
|
end
|
163
175
|
|
164
|
-
|
165
|
-
|
166
|
-
|
176
|
+
context "has methods to run code only on certain instances" do
|
177
|
+
def scenarios
|
178
|
+
[
|
179
|
+
['solo' ],
|
180
|
+
['app_master' ],
|
181
|
+
['app' ],
|
182
|
+
['db_master' ],
|
183
|
+
['db_slave' ],
|
184
|
+
['multi_role,app'],
|
185
|
+
['multi,util' ],
|
186
|
+
['util', 'alpha' ],
|
187
|
+
['util', 'beta' ],
|
188
|
+
['util', 'gamma' ],
|
189
|
+
]
|
190
|
+
end
|
167
191
|
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
192
|
+
def where_code_runs_with(code)
|
193
|
+
scenarios.select do |role, name|
|
194
|
+
hook = deploy_hook(:current_roles => role.split(','), :current_name => name)
|
195
|
+
hook.eval_hook("#{code} { 'ran' } == 'ran'")
|
196
|
+
end.map do |scenario|
|
197
|
+
scenario.compact.join("_")
|
198
|
+
end.compact
|
199
|
+
end
|
172
200
|
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
end
|
201
|
+
it "#on_app_master runs on app masters and solos" do
|
202
|
+
where_code_runs_with("on_app_master").should == %w(solo app_master)
|
203
|
+
end
|
177
204
|
|
178
|
-
|
179
|
-
|
180
|
-
|
205
|
+
it "#on_app_servers runs on app masters, app slaves, and solos" do
|
206
|
+
where_code_runs_with("on_app_servers").should == %w(solo app_master app multi_role,app)
|
207
|
+
end
|
181
208
|
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
209
|
+
it "#on_app_servers_and_utilities does what it says on the tin" do
|
210
|
+
where_code_runs_with("on_app_servers_and_utilities").should ==
|
211
|
+
%w(solo app_master app multi_role,app multi,util util_alpha util_beta util_gamma)
|
212
|
+
end
|
186
213
|
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
214
|
+
it "#on_utilities() runs on all utility instances" do
|
215
|
+
where_code_runs_with("on_utilities").should ==
|
216
|
+
%w(multi,util util_alpha util_beta util_gamma)
|
217
|
+
end
|
191
218
|
|
192
|
-
|
219
|
+
it "#on_utilities('sometype') runs on only utilities of type 'sometype'" do
|
220
|
+
where_code_runs_with("on_utilities('alpha')").should == %w(util_alpha)
|
221
|
+
end
|
222
|
+
|
223
|
+
it "#on_utilities('type1', 'type2') runs on utilities of both types" do
|
224
|
+
where_code_runs_with("on_utilities('alpha', 'beta')").should ==
|
225
|
+
%w(util_alpha util_beta)
|
226
|
+
end
|
193
227
|
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
228
|
+
it "#on_utilities can be invoked with (['a', 'b']) or ('a', 'b')" do
|
229
|
+
where_code_runs_with("on_utilities(%w[alpha beta])").should ==
|
230
|
+
where_code_runs_with("on_utilities('alpha', 'beta')")
|
231
|
+
end
|
198
232
|
end
|
199
233
|
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
234
|
+
context "#syntax_error" do
|
235
|
+
it "returns nil for hook files containing valid Ruby syntax" do
|
236
|
+
hook_path = File.expand_path('../fixtures/valid_hook.rb', __FILE__)
|
237
|
+
deploy_hook.syntax_error(hook_path).should be_nil
|
238
|
+
end
|
239
|
+
|
240
|
+
it "returns a brief problem description for hook files containing valid Ruby syntax" do
|
241
|
+
hook_path = File.expand_path('../fixtures/invalid_hook.rb', __FILE__)
|
242
|
+
error = Regexp.escape("spec/fixtures/invalid_hook.rb:1: syntax error, unexpected '^'")
|
243
|
+
deploy_hook.syntax_error(hook_path).should =~ /#{error}/
|
244
|
+
end
|
205
245
|
end
|
206
|
-
end
|
207
246
|
|
208
|
-
|
209
|
-
|
210
|
-
|
247
|
+
context "is compatible with older deploy hook scripts" do
|
248
|
+
it "#current_role returns the first role" do
|
249
|
+
deploy_hook(:current_roles => %w(a b)).eval_hook('current_role').should == 'a'
|
250
|
+
end
|
251
|
+
|
252
|
+
it "has info, warning, debug, logged_system, and access to shell" do
|
253
|
+
deploy_hook.eval_hook('respond_to?(:info) ').should be_true
|
254
|
+
deploy_hook.eval_hook('respond_to?(:warning) ').should be_true
|
255
|
+
deploy_hook.eval_hook('respond_to?(:debug) ').should be_true
|
256
|
+
deploy_hook.eval_hook('respond_to?(:logged_system)').should be_true
|
257
|
+
deploy_hook.eval_hook('respond_to?(:shell) ').should be_true
|
258
|
+
end
|
211
259
|
end
|
212
260
|
end
|
213
261
|
end
|