man_eb_deployer 0.8.0
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.
- checksums.yaml +7 -0
- data/.github/workflows/release.yml +31 -0
- data/.github/workflows/test.yml +16 -0
- data/.gitignore +12 -0
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/CHANGELOG.md +143 -0
- data/Gemfile +10 -0
- data/LICENSE +22 -0
- data/README.md +138 -0
- data/Rakefile +12 -0
- data/TODOS.md +11 -0
- data/bin/eb_deploy +13 -0
- data/eb_deployer.gemspec +22 -0
- data/lib/eb_deployer/application.rb +96 -0
- data/lib/eb_deployer/aws_driver/beanstalk.rb +158 -0
- data/lib/eb_deployer/aws_driver/cloud_formation_driver.rb +53 -0
- data/lib/eb_deployer/aws_driver/s3_driver.rb +35 -0
- data/lib/eb_deployer/aws_driver.rb +8 -0
- data/lib/eb_deployer/cf_event_source.rb +26 -0
- data/lib/eb_deployer/cloud_formation_provisioner.rb +120 -0
- data/lib/eb_deployer/component.rb +45 -0
- data/lib/eb_deployer/config_loader.rb +64 -0
- data/lib/eb_deployer/default_component.rb +32 -0
- data/lib/eb_deployer/default_config.rb +20 -0
- data/lib/eb_deployer/default_config.yml +159 -0
- data/lib/eb_deployer/deployment_strategy/blue_green.rb +79 -0
- data/lib/eb_deployer/deployment_strategy/blue_only.rb +45 -0
- data/lib/eb_deployer/deployment_strategy/inplace_update.rb +16 -0
- data/lib/eb_deployer/deployment_strategy.rb +20 -0
- data/lib/eb_deployer/eb_environment.rb +204 -0
- data/lib/eb_deployer/eb_event_source.rb +35 -0
- data/lib/eb_deployer/environment.rb +60 -0
- data/lib/eb_deployer/event_poller.rb +51 -0
- data/lib/eb_deployer/package.rb +39 -0
- data/lib/eb_deployer/resource_stacks.rb +20 -0
- data/lib/eb_deployer/smoke_test.rb +23 -0
- data/lib/eb_deployer/tasks.rb +45 -0
- data/lib/eb_deployer/throttling_handling.rb +17 -0
- data/lib/eb_deployer/utils.rb +33 -0
- data/lib/eb_deployer/version.rb +3 -0
- data/lib/eb_deployer/version_cleaner.rb +30 -0
- data/lib/eb_deployer.rb +339 -0
- data/lib/generators/eb_deployer/install/install_generator.rb +82 -0
- data/lib/generators/eb_deployer/install/templates/eb_deployer.rake +1 -0
- data/lib/generators/eb_deployer/install/templates/eb_deployer.yml.erb +181 -0
- data/lib/generators/eb_deployer/install/templates/ebextensions/01_postgres_packages.config +5 -0
- data/lib/generators/eb_deployer/install/templates/postgres_rds.json +88 -0
- data/test/aws_driver_stubs.rb +350 -0
- data/test/beanstalk_test.rb +23 -0
- data/test/blue_green_deploy_test.rb +114 -0
- data/test/blue_only_deploy_test.rb +78 -0
- data/test/cf_event_poller_test.rb +32 -0
- data/test/cloud_formation_provisioner_test.rb +47 -0
- data/test/config_loader_test.rb +205 -0
- data/test/deploy_test.rb +42 -0
- data/test/eb_environment_test.rb +120 -0
- data/test/eb_event_poller_test.rb +32 -0
- data/test/inplace_update_deploy_test.rb +110 -0
- data/test/multi_components_deploy_test.rb +164 -0
- data/test/rails_generators_test.rb +67 -0
- data/test/resources_deploy_test.rb +191 -0
- data/test/smoke_test_test.rb +23 -0
- data/test/template_deploy_test.rb +13 -0
- data/test/test_helper.rb +68 -0
- data/test/tier_setting_deploy_test.rb +24 -0
- data/test/versions_deploy_test.rb +120 -0
- metadata +176 -0
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
require 'deploy_test'
|
|
2
|
+
|
|
3
|
+
class InplaceUpdateDeployTest < DeployTest
|
|
4
|
+
def test_first_deployment_create_eb_application
|
|
5
|
+
assert !@eb.application_exists?('simple')
|
|
6
|
+
deploy(:application => 'simple', :environment => "production")
|
|
7
|
+
assert @eb.application_exists?('simple')
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def test_set_option_settings_on_deployment
|
|
11
|
+
redudant = [{:namespace => 'aws:autoscaling:launchconfiguration',
|
|
12
|
+
:option_name => 'MinSize',
|
|
13
|
+
:value => '2' }]
|
|
14
|
+
deploy(:application => 'simple', :environment => "production",
|
|
15
|
+
:option_settings => [redudant])
|
|
16
|
+
|
|
17
|
+
assert_equal [redudant], @eb.environment_settings('simple', t('production', 'simple'))
|
|
18
|
+
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def test_first_deployment_create_environment
|
|
22
|
+
assert !@eb.environment_exists?('simple', t('production', 'simple'))
|
|
23
|
+
deploy(:application => 'simple', :environment => "production")
|
|
24
|
+
assert @eb.environment_exists?('simple', t('production', 'simple'))
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def test_support_very_very_long_app_name
|
|
28
|
+
deploy(:application => 'ver-very-simple-application', :environment => "production")
|
|
29
|
+
assert @eb.environment_exists?('ver-very-simple-application', t('production', 'ver-very-simple-application'))
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def test_should_raise_error_when_env_name_is_too_long
|
|
33
|
+
assert_raises(RuntimeError) { deploy(:application => 'simple', :environment => "p" * 24) }
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def test_update_environment_with_new_version_should_change_version_that_deployed
|
|
37
|
+
deploy(:application => 'simple',
|
|
38
|
+
:environment => "production",
|
|
39
|
+
:version_label => 1)
|
|
40
|
+
assert_equal '1', @eb.environment_verion_label('simple', t('production', 'simple'))
|
|
41
|
+
|
|
42
|
+
deploy(:application => 'simple',
|
|
43
|
+
:environment => "production",
|
|
44
|
+
:version_label => 2)
|
|
45
|
+
|
|
46
|
+
assert_equal '2', @eb.environment_verion_label('simple', t('production', 'simple'))
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def test_smoke_test_should_be_run_after_env_created_or_update
|
|
50
|
+
host_for_smoke_test = nil
|
|
51
|
+
deploy(:application => 'simple',
|
|
52
|
+
:environment => "production",
|
|
53
|
+
:cname_prefix => 'foobar',
|
|
54
|
+
:smoke_test => lambda { |host| host_for_smoke_test = host },
|
|
55
|
+
:version_label => 42)
|
|
56
|
+
assert_equal 'foobar.us-west-1.elasticbeanstalk.com', host_for_smoke_test
|
|
57
|
+
|
|
58
|
+
host_for_smoke_test = nil
|
|
59
|
+
deploy(:application => 'simple',
|
|
60
|
+
:environment => "production",
|
|
61
|
+
:cname_prefix => 'foobar',
|
|
62
|
+
:smoke_test => lambda { |host| host_for_smoke_test = host },
|
|
63
|
+
:version_label => 43)
|
|
64
|
+
|
|
65
|
+
assert_equal 'foobar.us-west-1.elasticbeanstalk.com', host_for_smoke_test
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def test_should_terminate_old_environment_if_phoenix_mode_is_enabled
|
|
69
|
+
deploy(:application => 'simple', :environment => "production", :phoenix_mode => true)
|
|
70
|
+
assert @eb.environment_exists?('simple', t('production', 'simple'))
|
|
71
|
+
deploy(:application => 'simple', :environment => "production", :phoenix_mode => true)
|
|
72
|
+
assert @eb.environments_been_deleted('simple').include?(t('production', 'simple'))
|
|
73
|
+
assert @eb.environment_exists?('simple', t('production', 'simple'))
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def test_destroy_should_clean_up_env
|
|
77
|
+
deploy(:application => 'simple', :environment => "production")
|
|
78
|
+
destroy(:application => 'simple', :environment => 'production')
|
|
79
|
+
assert !@eb.environment_exists?('simple', t('production', 'simple'))
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def test_deploy_should_raise_error_when_constantly_hitting_throttling_error
|
|
83
|
+
throttling_error = Aws::ElasticBeanstalk::Errors::Throttling.new(nil, "bang!")
|
|
84
|
+
@eb.set_error(:fetch_events, throttling_error)
|
|
85
|
+
assert_raises(Aws::ElasticBeanstalk::Errors::Throttling) do
|
|
86
|
+
deploy(:application => 'simple', :environment => "production")
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
def test_deploy_should_retry_on_temporary_throttling_error_from_fetch_events
|
|
91
|
+
throttling_error = Aws::ElasticBeanstalk::Errors::Throttling.new(nil, "bang!")
|
|
92
|
+
error_seq = [throttling_error] * 5
|
|
93
|
+
@eb.set_error_generator(:fetch_events) do
|
|
94
|
+
error_seq.pop
|
|
95
|
+
end
|
|
96
|
+
deploy(:application => 'simple', :environment => "production")
|
|
97
|
+
assert @eb.environment_exists?('simple', t('production', 'simple'))
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
def test_deploy_should_retry_on_temporary_throttling_error_from_create_env
|
|
101
|
+
throttling_error = Aws::ElasticBeanstalk::Errors::Throttling.new(nil, "bang!")
|
|
102
|
+
error_seq = [throttling_error] * 5
|
|
103
|
+
@eb.set_error_generator(:create_environment) do
|
|
104
|
+
error_seq.pop
|
|
105
|
+
end
|
|
106
|
+
deploy(:application => 'simple', :environment => "production")
|
|
107
|
+
assert @eb.environment_exists?('simple', t('production', 'simple'))
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
end
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
require 'deploy_test'
|
|
2
|
+
|
|
3
|
+
class MultiComponentsDeployTest < DeployTest
|
|
4
|
+
def test_deploy_with_components
|
|
5
|
+
do_deploy
|
|
6
|
+
assert @eb.environment_exists?('simple', t('prod-web', 'simple'))
|
|
7
|
+
assert @eb.environment_exists?('simple', t('prod-bg', 'simple'))
|
|
8
|
+
assert @eb.environment_exists?('simple', t('prod-api', 'simple'))
|
|
9
|
+
assert !@eb.environment_exists?('simple', t('prod', 'simple'))
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def test_deploy_with_components_with_blue_green
|
|
13
|
+
do_bg_deploy
|
|
14
|
+
assert @eb.environment_exists?('simple', t('prod-web-a', 'simple'))
|
|
15
|
+
assert @eb.environment_exists?('simple', t('prod-bg-a', 'simple'))
|
|
16
|
+
assert @eb.environment_exists?('simple', t('prod-api-a', 'simple'))
|
|
17
|
+
do_bg_deploy
|
|
18
|
+
assert @eb.environment_exists?('simple', t('prod-web-b', 'simple'))
|
|
19
|
+
assert @eb.environment_exists?('simple', t('prod-bg-b', 'simple'))
|
|
20
|
+
assert @eb.environment_exists?('simple', t('prod-api-b', 'simple'))
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def test_cname_include_component_name
|
|
24
|
+
do_deploy
|
|
25
|
+
assert_equal 'simple-prod-web', @eb.environment_cname_prefix('simple', t('prod-web', 'simple'))
|
|
26
|
+
assert_equal 'simple-prod-api', @eb.environment_cname_prefix('simple', t('prod-api', 'simple'))
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def test_cname_include_component_name_in_blue_green
|
|
30
|
+
do_bg_deploy
|
|
31
|
+
assert_equal 'simple-prod-web', @eb.environment_cname_prefix('simple', t('prod-web-a', 'simple'))
|
|
32
|
+
|
|
33
|
+
do_bg_deploy
|
|
34
|
+
assert_equal 'simple-prod-web', @eb.environment_cname_prefix('simple', t('prod-web-b', 'simple'))
|
|
35
|
+
assert_equal 'simple-prod-web-inactive', @eb.environment_cname_prefix('simple', t('prod-web-a', 'simple'))
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def test_components_inheritate_creation_options_from_environment
|
|
39
|
+
do_deploy
|
|
40
|
+
assert_equal 'WebServer', @eb.environment_tier('simple', t('prod-web', 'simple'))
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def test_components_can_override_creation_opts
|
|
44
|
+
do_deploy(:tier => 'WebServer',
|
|
45
|
+
:components => [{'name' => 'web'}, {'name' => 'bg', 'tier' => "Worker"}])
|
|
46
|
+
assert_equal 'WebServer', @eb.environment_tier('simple', t('prod-web', 'simple'))
|
|
47
|
+
assert_equal 'Worker', @eb.environment_tier('simple', t('prod-bg', 'simple'))
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def test_components_specific_eb_settings_will_override_env_eb_settings
|
|
51
|
+
minsize_3 = {:namespace => 'aws:autoscaling:launchconfiguration',
|
|
52
|
+
:option_name => 'MinSize',
|
|
53
|
+
:value => '3' }
|
|
54
|
+
minsize_2 = {:namespace => 'aws:autoscaling:launchconfiguration',
|
|
55
|
+
:option_name => 'MinSize',
|
|
56
|
+
:value => '2' }
|
|
57
|
+
|
|
58
|
+
do_deploy(:option_settings => [minsize_3],
|
|
59
|
+
:components => [{'name' => 'web'},
|
|
60
|
+
{'name' => 'api',
|
|
61
|
+
'option_settings' => [minsize_2]}])
|
|
62
|
+
assert_equal [minsize_3], @eb.environment_settings('simple', t('prod-web', 'simple'))
|
|
63
|
+
assert_equal [minsize_3, minsize_2], @eb.environment_settings('simple', t('prod-api', 'simple'))
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def test_override_deployment_strategy
|
|
67
|
+
do_deploy(:components => [{'name' => 'web',
|
|
68
|
+
'strategy' => 'blue-green' },
|
|
69
|
+
{'name' => 'bg',
|
|
70
|
+
'strategy' => 'inplace-update'}])
|
|
71
|
+
|
|
72
|
+
assert @eb.environment_exists?('simple', t('prod-web-a', 'simple'))
|
|
73
|
+
assert @eb.environment_exists?('simple', t('prod-bg', 'simple'))
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def test_can_deploy_single_component
|
|
77
|
+
do_deploy(:component => "bg")
|
|
78
|
+
assert !@eb.environment_exists?('simple', t('prod-web', 'simple'))
|
|
79
|
+
assert !@eb.environment_exists?('simple', t('prod-api', 'simple'))
|
|
80
|
+
assert @eb.environment_exists?('simple', t('prod-bg', 'simple'))
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
def test_should_raise_exception_when_try_to_deploy_a_none_exists_component
|
|
84
|
+
assert_raises(RuntimeError) do
|
|
85
|
+
do_deploy(:component => "foo")
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
def test_can_have_inactive_settings_which_will_be_applied_to_inactive_env
|
|
91
|
+
settings = {:inactive_settings =>
|
|
92
|
+
[{:namespace => 'aws:autoscaling:launchconfiguration',
|
|
93
|
+
:option_name => 'MinSize',
|
|
94
|
+
:value => 1}],
|
|
95
|
+
:components =>
|
|
96
|
+
[{:name => 'web',
|
|
97
|
+
:option_settings =>
|
|
98
|
+
[{:namespace => 'aws:autoscaling:launchconfiguration',
|
|
99
|
+
:option_name => 'MinSize',
|
|
100
|
+
:value => 10}]}]}
|
|
101
|
+
|
|
102
|
+
do_bg_deploy(settings)
|
|
103
|
+
assert_equal 10, @eb.environment_settings('simple', t('prod-web-a', 'simple')).last[:value]
|
|
104
|
+
|
|
105
|
+
do_bg_deploy(settings)
|
|
106
|
+
assert_equal 1, @eb.environment_settings('simple', t('prod-web-a', 'simple')).last[:value]
|
|
107
|
+
assert_equal 10, @eb.environment_settings('simple', t('prod-web-b', 'simple')).last[:value]
|
|
108
|
+
|
|
109
|
+
do_bg_deploy(settings)
|
|
110
|
+
assert_equal 10, @eb.environment_settings('simple', t('prod-web-a', 'simple')).last[:value]
|
|
111
|
+
assert_equal 1, @eb.environment_settings('simple', t('prod-web-b', 'simple')).last[:value]
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
def test_can_provide_inactive_settings_at_component_level
|
|
115
|
+
settings = {:option_settings =>
|
|
116
|
+
[{:namespace => 'aws:autoscaling:launchconfiguration',
|
|
117
|
+
:option_name => 'MinSize',
|
|
118
|
+
:value => 10}],
|
|
119
|
+
:components =>
|
|
120
|
+
[{:name => 'web',
|
|
121
|
+
:inactive_settings =>
|
|
122
|
+
[{:namespace => 'aws:autoscaling:launchconfiguration',
|
|
123
|
+
:option_name => 'MinSize',
|
|
124
|
+
:value => 2}]},
|
|
125
|
+
{:name => 'api',
|
|
126
|
+
:inactive_settings =>
|
|
127
|
+
[{:namespace => 'aws:autoscaling:launchconfiguration',
|
|
128
|
+
:option_name => 'MinSize',
|
|
129
|
+
:value => 1}]}]}
|
|
130
|
+
|
|
131
|
+
do_bg_deploy(settings)
|
|
132
|
+
assert_equal 10, @eb.environment_settings('simple', t('prod-web-a', 'simple')).last[:value]
|
|
133
|
+
assert_equal 10, @eb.environment_settings('simple', t('prod-api-a', 'simple')).last[:value]
|
|
134
|
+
|
|
135
|
+
do_bg_deploy(settings)
|
|
136
|
+
assert_equal 2, @eb.environment_settings('simple', t('prod-web-a', 'simple')).last[:value]
|
|
137
|
+
assert_equal 1, @eb.environment_settings('simple', t('prod-api-a', 'simple')).last[:value]
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
def test_should_raise_error_when_deploy_work_tier_component_with_blue_green
|
|
141
|
+
assert_raises(RuntimeError) do
|
|
142
|
+
deploy(:application => 'simple',
|
|
143
|
+
:environment => 'prod',
|
|
144
|
+
:strategy => 'blue-green',
|
|
145
|
+
:components => [{ 'name' => 'web' },
|
|
146
|
+
{ 'name' => 'bg', 'tier' => 'worker' }])
|
|
147
|
+
end
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
private
|
|
151
|
+
def do_deploy(options={})
|
|
152
|
+
deploy({:application => 'simple',
|
|
153
|
+
:environment => 'prod',
|
|
154
|
+
:components => [{ 'name' => 'web' },
|
|
155
|
+
{ 'name' => 'bg' },
|
|
156
|
+
{ 'name' => 'api' }]
|
|
157
|
+
}.merge(options))
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
def do_bg_deploy(options={})
|
|
161
|
+
do_deploy(options.merge(:strategy => 'blue-green'))
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
end
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
require 'test_helper'
|
|
2
|
+
require 'rails'
|
|
3
|
+
require 'shellwords'
|
|
4
|
+
require 'generators/eb_deployer/install/install_generator'
|
|
5
|
+
|
|
6
|
+
class RailsGenratorsTest < Rails::Generators::TestCase
|
|
7
|
+
tests EbDeployer::Generators::InstallGenerator
|
|
8
|
+
destination File.expand_path('../../tmp', __FILE__)
|
|
9
|
+
setup :prepare_destination
|
|
10
|
+
|
|
11
|
+
setup do
|
|
12
|
+
mkdir_p path('config')
|
|
13
|
+
touch path('config/database.yml')
|
|
14
|
+
touch path('Gemfile')
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
test "install" do
|
|
18
|
+
run_generator
|
|
19
|
+
|
|
20
|
+
assert_file 'config/eb_deployer.yml'
|
|
21
|
+
assert_file 'lib/tasks/eb_deployer.rake'
|
|
22
|
+
|
|
23
|
+
assert_file 'config/rds.json'
|
|
24
|
+
assert_file '.ebextensions/01_postgres_packages.config'
|
|
25
|
+
assert_file 'config/database.yml', /database: <%= ENV\['DATABASE_NAME'\]/m, /host: <%= ENV\['DATABASE_HOST'\]/m
|
|
26
|
+
assert_file 'Gemfile', /gem "pg"/
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
test "should comment production configuration in database.yml" do
|
|
30
|
+
File.open(path('config/database.yml'), 'w') do |f|
|
|
31
|
+
f.write(<<-YAML)
|
|
32
|
+
development:
|
|
33
|
+
host: localhost
|
|
34
|
+
|
|
35
|
+
production:
|
|
36
|
+
host: localhost
|
|
37
|
+
|
|
38
|
+
test:
|
|
39
|
+
host: localhost
|
|
40
|
+
YAML
|
|
41
|
+
end
|
|
42
|
+
run_generator
|
|
43
|
+
assert_file 'config/database.yml', <<-YAML
|
|
44
|
+
development:
|
|
45
|
+
host: localhost
|
|
46
|
+
|
|
47
|
+
# production:
|
|
48
|
+
# host: localhost
|
|
49
|
+
|
|
50
|
+
test:
|
|
51
|
+
host: localhost
|
|
52
|
+
|
|
53
|
+
production:
|
|
54
|
+
adapter: postgresql
|
|
55
|
+
database: <%= ENV['DATABASE_NAME'] || 'tmp_production' %>
|
|
56
|
+
host: <%= ENV['DATABASE_HOST'] || 'localhost' %>
|
|
57
|
+
port: <%= ENV['DATABASE_PORT'] || 5432 %>
|
|
58
|
+
username: <%= ENV['DATABASE_USERNAME'] || #{ENV['USER'].inspect} %>
|
|
59
|
+
password: <%= ENV['DATABASE_PASSWORD'] %>
|
|
60
|
+
min_messages: ERROR
|
|
61
|
+
YAML
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def path(*f)
|
|
65
|
+
File.join(destination_root, *f)
|
|
66
|
+
end
|
|
67
|
+
end
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
require 'deploy_test'
|
|
2
|
+
|
|
3
|
+
class ResourcesDeployTest < DeployTest
|
|
4
|
+
|
|
5
|
+
def test_deploy_with_resources_declared_will_create_a_cf_stack_for_env
|
|
6
|
+
cf_template = temp_file(JSON.dump({'Resources' => {'R1' => {}}}))
|
|
7
|
+
deploy(:application => 'simple', :environment => "production",
|
|
8
|
+
:resources => {
|
|
9
|
+
:template => cf_template
|
|
10
|
+
})
|
|
11
|
+
assert @cf_driver.stack_exists?('simple-production')
|
|
12
|
+
assert_equal({}, @cf_driver.stack_config('simple-production')[:parameters])
|
|
13
|
+
assert_equal([], @cf_driver.stack_config('simple-production')[:capabilities])
|
|
14
|
+
assert_nil(@cf_driver.stack_config('simple-production')[:stack_policy_body])
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def test_deploy_with_resources_declared_will_create_a_cf_stack_for_env_with_policy
|
|
18
|
+
cf_template = temp_file(JSON.dump({'Resources' => {'R1' => {}}}))
|
|
19
|
+
cf_policy = sample_file("sample_policy.json", JSON.dump({'Policy' => {'P1' => {}}}))
|
|
20
|
+
deploy(:application => 'simple', :environment => "production",
|
|
21
|
+
:resources => {
|
|
22
|
+
:template => cf_template,
|
|
23
|
+
:policy => cf_policy
|
|
24
|
+
})
|
|
25
|
+
assert @cf_driver.stack_exists?('simple-production')
|
|
26
|
+
assert_equal({}, @cf_driver.stack_config('simple-production')[:parameters])
|
|
27
|
+
assert_equal([], @cf_driver.stack_config('simple-production')[:capabilities])
|
|
28
|
+
assert_equal("{\"Policy\":{\"P1\":{}}}", @cf_driver.stack_config('simple-production')[:stack_policy_body])
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def test_deploy_with_resources_declared_will_update_a_cf_stack_for_env_with_policy
|
|
32
|
+
cf_template = temp_file(JSON.dump({'Resources' => {'R1' => {}}}))
|
|
33
|
+
cf_policy = sample_file("sample_policy.json", JSON.dump({'Policy' => {'P1' => {}}}))
|
|
34
|
+
deploy(:application => 'simple', :environment => "production",
|
|
35
|
+
:resources => {
|
|
36
|
+
:template => cf_template,
|
|
37
|
+
:policy => cf_policy
|
|
38
|
+
})
|
|
39
|
+
assert @cf_driver.stack_exists?('simple-production')
|
|
40
|
+
deploy(:application => 'simple', :environment => "production",
|
|
41
|
+
:resources => {
|
|
42
|
+
:template => cf_template,
|
|
43
|
+
:policy => cf_policy,
|
|
44
|
+
:override_policy => false
|
|
45
|
+
})
|
|
46
|
+
assert_equal({}, @cf_driver.stack_config('simple-production')[:parameters])
|
|
47
|
+
assert_equal([], @cf_driver.stack_config('simple-production')[:capabilities])
|
|
48
|
+
assert_equal("{\"Policy\":{\"P1\":{}}}", @cf_driver.stack_config('simple-production')[:stack_policy_body])
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def test_deploy_with_resources_declared_will_update_a_cf_stack_for_env_with_temp_policy
|
|
52
|
+
cf_template = temp_file(JSON.dump({'Resources' => {'R1' => {}}}))
|
|
53
|
+
cf_policy = sample_file("sample_policy.json", JSON.dump({'Policy' => {'P1' => {}}}))
|
|
54
|
+
deploy(:application => 'simple', :environment => "production",
|
|
55
|
+
:resources => {
|
|
56
|
+
:template => cf_template,
|
|
57
|
+
:policy => cf_policy
|
|
58
|
+
})
|
|
59
|
+
assert @cf_driver.stack_exists?('simple-production')
|
|
60
|
+
deploy(:application => 'simple', :environment => "production",
|
|
61
|
+
:resources => {
|
|
62
|
+
:template => cf_template,
|
|
63
|
+
:policy => cf_policy,
|
|
64
|
+
:override_policy => true
|
|
65
|
+
})
|
|
66
|
+
assert_equal({}, @cf_driver.stack_config('simple-production')[:parameters])
|
|
67
|
+
assert_equal([], @cf_driver.stack_config('simple-production')[:capabilities])
|
|
68
|
+
assert_equal("{\"Policy\":{\"P1\":{}}}", @cf_driver.stack_config('simple-production')[:stack_policy_during_update_body])
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def test_provision_resources_with_capacities
|
|
72
|
+
cf_template = temp_file(JSON.dump({'Resources' => {'R1' => {}}}))
|
|
73
|
+
deploy(:application => 'simple', :environment => "production",
|
|
74
|
+
:resources => {
|
|
75
|
+
:template => cf_template,
|
|
76
|
+
:capabilities => ['CAPABILITY_IAM']
|
|
77
|
+
})
|
|
78
|
+
assert_equal ['CAPABILITY_IAM'], @cf_driver.stack_config('simple-production')[:capabilities]
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def test_provision_resources_with_parameters
|
|
82
|
+
cf_template = temp_file(JSON.dump({'Resources' => {'R1' => {}}}))
|
|
83
|
+
deploy(:application => 'simple', :environment => "production",
|
|
84
|
+
:resources => {
|
|
85
|
+
:template => cf_template,
|
|
86
|
+
:parameters => {'a' => 1}
|
|
87
|
+
})
|
|
88
|
+
assert_equal({'a' => 1 }, @cf_driver.stack_config('simple-production')[:parameters])
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
def test_skip_resource_update
|
|
92
|
+
cf_template = temp_file(JSON.dump({'Resources' => {'R1' => {}}}))
|
|
93
|
+
deploy(:application => 'simple', :environment => "production",
|
|
94
|
+
:resources => {
|
|
95
|
+
:template => cf_template,
|
|
96
|
+
:parameters => {'a' => 1 }
|
|
97
|
+
})
|
|
98
|
+
assert_equal(1, @cf_driver.stack_config('simple-production')[:parameters]['a'])
|
|
99
|
+
deploy(:application => 'simple', :environment => "production",
|
|
100
|
+
:resources => {
|
|
101
|
+
:template => cf_template,
|
|
102
|
+
:parameters => {'a' => 2 }
|
|
103
|
+
})
|
|
104
|
+
assert_equal(2, @cf_driver.stack_config('simple-production')[:parameters]['a'])
|
|
105
|
+
deploy(:application => 'simple',
|
|
106
|
+
:environment => "production",
|
|
107
|
+
:skip_resource_stack_update => true,
|
|
108
|
+
:resources => {
|
|
109
|
+
:template => cf_template,
|
|
110
|
+
:parameters => {'a' => 3 }
|
|
111
|
+
})
|
|
112
|
+
assert_equal(2, @cf_driver.stack_config('simple-production')[:parameters]['a'])
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
def test_should_still_query_output_to_set_eb_options_even_skip_resources_update_is_specified
|
|
116
|
+
cf_template = temp_file(JSON.dump({'Resources' => {'R1' => {}},
|
|
117
|
+
'Outputs' => {'O1' => {}, 'O2' => {}}}))
|
|
118
|
+
deploy(:application => 'simple', :environment => "production",
|
|
119
|
+
:resources => {
|
|
120
|
+
:template => cf_template
|
|
121
|
+
})
|
|
122
|
+
|
|
123
|
+
deploy(:application => 'simple', :environment => "production",
|
|
124
|
+
:skip_resource_stack_update => true,
|
|
125
|
+
:resources => {
|
|
126
|
+
:template => cf_template,
|
|
127
|
+
:transforms => {
|
|
128
|
+
'O2' => lambda { |v| {:namespace => 'aws.foo', :option_name => 'o2', :value => "transformed " + v} }
|
|
129
|
+
}
|
|
130
|
+
})
|
|
131
|
+
|
|
132
|
+
assert @eb.environment_settings('simple', t('production', 'simple')).
|
|
133
|
+
include?({:namespace => 'aws.foo', :option_name => 'o2', :value => 'transformed value of O2'})
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
def test_transforms_resource_provsion_output_to_elastic_beanstalk_settings
|
|
138
|
+
cf_template = temp_file(JSON.dump({
|
|
139
|
+
'Resources' => {'R1' => {}},
|
|
140
|
+
'Outputs' => {'O1' => {}, 'O2' => {}}
|
|
141
|
+
}))
|
|
142
|
+
deploy(:application => 'simple', :environment => "production",
|
|
143
|
+
:resources => {
|
|
144
|
+
:template => cf_template,
|
|
145
|
+
:transforms => {
|
|
146
|
+
'O1' => lambda { |v| {:namespace => 'aws.foo', :option_name => 'o1', :value => v} }
|
|
147
|
+
}
|
|
148
|
+
})
|
|
149
|
+
assert @eb.environment_settings('simple', t('production', 'simple')).
|
|
150
|
+
include?({:namespace => 'aws.foo', :option_name => 'o1', :value => 'value of O1'})
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
def test_can_query_resource_stack_output_after_deploy
|
|
154
|
+
cf_template = temp_file(JSON.dump({
|
|
155
|
+
'Resources' => {'R1' => {}},
|
|
156
|
+
'Outputs' => {'O1' => {}, 'O2' => {}}
|
|
157
|
+
}))
|
|
158
|
+
deploy(:application => 'simple',
|
|
159
|
+
:environment => "production",
|
|
160
|
+
:resources => { :template => cf_template })
|
|
161
|
+
assert_equal 'value of O1', query_resource_output('O1',
|
|
162
|
+
:application => 'simple',
|
|
163
|
+
:environment => "production")
|
|
164
|
+
assert_equal 'value of O2', query_resource_output('O2',
|
|
165
|
+
:application => 'simple',
|
|
166
|
+
:environment => "production")
|
|
167
|
+
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
def test_should_raise_error_if_query_resources_that_have_not_been_provisioned_yet
|
|
171
|
+
assert_raises(EbDeployer::ResourceNotInReadyState) do
|
|
172
|
+
query_resource_output('O1',
|
|
173
|
+
:application => 'simple',
|
|
174
|
+
:environment => "production")
|
|
175
|
+
end
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
def test_custom_stack_name
|
|
179
|
+
cf_template = temp_file(JSON.dump({
|
|
180
|
+
'Resources' => {'R1' => {}},
|
|
181
|
+
'Outputs' => {'O1' => {}, 'O2' => {}}
|
|
182
|
+
}))
|
|
183
|
+
deploy(:application => 'simple',
|
|
184
|
+
:environment => "production",
|
|
185
|
+
:resources => { :template => cf_template },
|
|
186
|
+
:stack_name => 'my-lovely-stack')
|
|
187
|
+
|
|
188
|
+
assert !@cf_driver.stack_exists?('simple-production')
|
|
189
|
+
assert @cf_driver.stack_exists?('my-lovely-stack')
|
|
190
|
+
end
|
|
191
|
+
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
require 'test_helper'
|
|
2
|
+
|
|
3
|
+
class SmokeTestTest < Test::Unit::TestCase
|
|
4
|
+
def test_call_proc_type_smoke_tests
|
|
5
|
+
host_name_in_proc = nil
|
|
6
|
+
EbDeployer::SmokeTest.new(lambda {|v| host_name_in_proc = v }).run("foo")
|
|
7
|
+
|
|
8
|
+
assert_equal 'foo', host_name_in_proc
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def test_eval_string_type_smoke_test
|
|
12
|
+
$host_name_in_proc = nil
|
|
13
|
+
EbDeployer::SmokeTest.new("$host_name_in_proc=host_name").run("foo")
|
|
14
|
+
assert_equal 'foo', $host_name_in_proc
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def test_should_raise_if_test_body_raise
|
|
18
|
+
assert_raises(RuntimeError) do
|
|
19
|
+
EbDeployer::SmokeTest.new("raise host_name").run("foo")
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
end
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
require 'deploy_test'
|
|
2
|
+
|
|
3
|
+
class TemplateDeployTest < DeployTest
|
|
4
|
+
def test_default_no_template
|
|
5
|
+
deploy(:application => 'simple', :environment => "production")
|
|
6
|
+
assert_equal nil, @eb.template_name('simple', t('production', 'simple'))
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def test_can_set_a_template
|
|
10
|
+
deploy(:application => 'simple', :environment => "production", :template_name => 'SomeTemplate')
|
|
11
|
+
assert_equal 'SomeTemplate', @eb.template_name('simple', t('production', 'simple'))
|
|
12
|
+
end
|
|
13
|
+
end
|
data/test/test_helper.rb
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
$:.unshift(File.expand_path("../../lib", __FILE__))
|
|
2
|
+
|
|
3
|
+
require 'tempfile'
|
|
4
|
+
require 'eb_deployer'
|
|
5
|
+
require 'aws_driver_stubs'
|
|
6
|
+
require 'test/unit'
|
|
7
|
+
|
|
8
|
+
def silence_warnings(&block)
|
|
9
|
+
old_verbose, $VERBOSE = $VERBOSE, nil
|
|
10
|
+
yield
|
|
11
|
+
ensure
|
|
12
|
+
$VERBOSE = old_verbose
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
silence_warnings { EbDeployer::Utils::BACKOFF_INITIAL_SLEEP = 0 }
|
|
16
|
+
silence_warnings { EbDeployer::EventPoller::POLL_INTERVAL = 0 }
|
|
17
|
+
|
|
18
|
+
class ErrorRaisingWrapper < SimpleDelegator
|
|
19
|
+
def initialize(stub)
|
|
20
|
+
@errors = {}
|
|
21
|
+
super(stub)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def set_error(method, error)
|
|
25
|
+
set_error_generator(method) do
|
|
26
|
+
error
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def set_error_generator(method, &error_gen)
|
|
31
|
+
define_delegate_method(method)
|
|
32
|
+
@errors[method] = Proc.new(&error_gen)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
private
|
|
36
|
+
def define_delegate_method(method)
|
|
37
|
+
method = method.to_s
|
|
38
|
+
original_method_name = "__#{method}_without_error"
|
|
39
|
+
raise "method #{method} not defined" unless self.respond_to?(method)
|
|
40
|
+
return if self.respond_to?(original_method_name)
|
|
41
|
+
|
|
42
|
+
self.instance_eval <<-CODE
|
|
43
|
+
def #{original_method_name}(*args, &block)
|
|
44
|
+
self.__get_obj__.send(:#{method}, *args, &block)
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def #{method}(*args, &block)
|
|
48
|
+
if error_gen = @errors[:#{method}]
|
|
49
|
+
error = error_gen.call
|
|
50
|
+
raise error if error
|
|
51
|
+
end
|
|
52
|
+
super
|
|
53
|
+
end
|
|
54
|
+
CODE
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
class Test::Unit::TestCase
|
|
59
|
+
def sample_file(file_name, content='s' * 100)
|
|
60
|
+
path = File.join('/tmp', file_name)
|
|
61
|
+
File.open(path, 'w') { |f| f << content }
|
|
62
|
+
path
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def t(env, app_name)
|
|
66
|
+
EbDeployer::EbEnvironment.unique_ebenv_name(env, app_name)
|
|
67
|
+
end
|
|
68
|
+
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
require 'deploy_test'
|
|
2
|
+
|
|
3
|
+
class TierSettingDeployTest < DeployTest
|
|
4
|
+
def test_sets_default_tier_as_webserver
|
|
5
|
+
deploy(:application => 'simple', :environment => "production")
|
|
6
|
+
assert_equal 'WebServer', @eb.environment_tier('simple', t('production', 'simple'))
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def test_can_change_tier
|
|
10
|
+
deploy(:application => 'simple', :environment => "production", :tier => 'Worker')
|
|
11
|
+
assert_equal 'Worker', @eb.environment_tier('simple', t('production', 'simple'))
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def test_should_worker_tier_should_not_have_cname_prefix
|
|
15
|
+
deploy(:application => 'simple', :environment => "production", :tier => 'Worker')
|
|
16
|
+
assert_nil @eb.environment_cname_prefix('simple', t('production', 'simple'))
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def test_should_raise_error_when_deploy_worker_tier_with_blue_green
|
|
20
|
+
assert_raises(RuntimeError) do
|
|
21
|
+
deploy(:application => 'simple', :environment => "production", :tier => 'Worker', :strategy => 'blue-green')
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|