dew 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (62) hide show
  1. data/LICENSE +22 -0
  2. data/README.md +38 -0
  3. data/Rakefile +26 -0
  4. data/bin/dew +87 -0
  5. data/config/cucumber.yaml +4 -0
  6. data/features/create-ami.feature +16 -0
  7. data/features/create-environments.feature +46 -0
  8. data/features/deploy-puge.feature +16 -0
  9. data/features/step_definitions/aws-steps.rb +101 -0
  10. data/features/step_definitions/deploy-puge-steps.rb +27 -0
  11. data/features/support/env.rb +38 -0
  12. data/features/support/hooks.rb +10 -0
  13. data/lib/dew.rb +7 -0
  14. data/lib/dew/aws_resources.yaml +122 -0
  15. data/lib/dew/base_command.rb +24 -0
  16. data/lib/dew/cloud.rb +79 -0
  17. data/lib/dew/commands.rb +6 -0
  18. data/lib/dew/commands/ami.rb +67 -0
  19. data/lib/dew/commands/console.rb +17 -0
  20. data/lib/dew/commands/console/irb_override.rb +24 -0
  21. data/lib/dew/commands/deploy.rb +114 -0
  22. data/lib/dew/commands/deploy/templates/apache.conf.erb +28 -0
  23. data/lib/dew/commands/deploy/templates/known_hosts +2 -0
  24. data/lib/dew/commands/deploy/templates/rvmrc +2 -0
  25. data/lib/dew/commands/environments.rb +110 -0
  26. data/lib/dew/commands/tidy.rb +35 -0
  27. data/lib/dew/controllers.rb +3 -0
  28. data/lib/dew/controllers/amis_controller.rb +82 -0
  29. data/lib/dew/controllers/deploy_controller.rb +10 -0
  30. data/lib/dew/controllers/environments_controller.rb +48 -0
  31. data/lib/dew/models.rb +7 -0
  32. data/lib/dew/models/account.rb +30 -0
  33. data/lib/dew/models/database.rb +32 -0
  34. data/lib/dew/models/deploy.rb +2 -0
  35. data/lib/dew/models/deploy/puge.rb +61 -0
  36. data/lib/dew/models/deploy/run.rb +19 -0
  37. data/lib/dew/models/environment.rb +199 -0
  38. data/lib/dew/models/fog_model.rb +23 -0
  39. data/lib/dew/models/profile.rb +60 -0
  40. data/lib/dew/models/server.rb +134 -0
  41. data/lib/dew/password.rb +7 -0
  42. data/lib/dew/tasks/spec.rake +14 -0
  43. data/lib/dew/validations.rb +8 -0
  44. data/lib/dew/version.rb +3 -0
  45. data/lib/dew/view.rb +39 -0
  46. data/lib/tasks/spec.rake +14 -0
  47. data/spec/dew/cloud_spec.rb +90 -0
  48. data/spec/dew/controllers/amis_controller_spec.rb +137 -0
  49. data/spec/dew/controllers/deploy_controller_spec.rb +38 -0
  50. data/spec/dew/controllers/environments_controller_spec.rb +133 -0
  51. data/spec/dew/models/account_spec.rb +47 -0
  52. data/spec/dew/models/database_spec.rb +58 -0
  53. data/spec/dew/models/deploy/puge_spec.rb +72 -0
  54. data/spec/dew/models/deploy/run_spec.rb +38 -0
  55. data/spec/dew/models/environment_spec.rb +374 -0
  56. data/spec/dew/models/fog_model_spec.rb +24 -0
  57. data/spec/dew/models/profile_spec.rb +85 -0
  58. data/spec/dew/models/server_spec.rb +190 -0
  59. data/spec/dew/password_spec.rb +11 -0
  60. data/spec/dew/spec_helper.rb +22 -0
  61. data/spec/dew/view_spec.rb +38 -0
  62. metadata +284 -0
@@ -0,0 +1,47 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), '../spec_helper'))
2
+
3
+ describe Account do
4
+
5
+ describe :initialize do
6
+ it "should look for the named account file in the ~/.dew/accounts dir" do
7
+ name = 'a_development_name'
8
+ File.should_receive(:read).with("#{ENV['HOME']}/.dew/accounts/#{name}.yaml").and_return("---")
9
+ Account.read(name)
10
+ end
11
+ end
12
+
13
+ describe "parsing yaml" do
14
+ before :each do
15
+ yaml =
16
+ "aws:
17
+ user_id: 9999-3333-2222
18
+ access_key_id: foo
19
+ secret_access_key: bar"
20
+
21
+ File.stub(:read).and_return(yaml)
22
+ @account = Account.read('foo')
23
+ end
24
+
25
+ it "should have a user_id stripped of dashes" do
26
+ @account.aws_user_id.should == '999933332222'
27
+ end
28
+
29
+ it "should have an aws access key id" do
30
+ @account.aws_access_key_id.should == 'foo'
31
+ end
32
+
33
+ it "should have an aws secret access key" do
34
+ @account.aws_secret_access_key.should == 'bar'
35
+ end
36
+ end
37
+
38
+ describe ".user_ids" do
39
+ it "should return the user_ids of each account file in config/accounts" do
40
+ Dir.should_receive(:[]).with("#{ENV['HOME']}/.dew/accounts/*.yaml").and_return(["accounts/file1.yaml", "accounts/file2.yaml"])
41
+ Account.should_receive(:read).with("file1").and_return(double('account', :aws_user_id => 'id1'))
42
+ Account.should_receive(:read).with("file2").and_return(double('account', :aws_user_id => 'id2'))
43
+ Account.user_ids.sort.should == ['id1', 'id2']
44
+ end
45
+ end
46
+
47
+ end
@@ -0,0 +1,58 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), '../spec_helper'))
2
+
3
+ describe Database do
4
+
5
+ let (:rds) { double('RDS', :servers => double('RDSServers')) }
6
+ let (:id) { 'mydatabase' }
7
+ let (:fog_database) { double('FogDatabase', :id => id) }
8
+
9
+ before :each do
10
+ Cloud.stub(:rds => rds)
11
+ rds.servers.stub(:create => fog_database)
12
+ end
13
+
14
+ describe ".create!" do
15
+ it "should ask Fog to create a new RDS with the provided name, size, username and password" do
16
+ rds.servers.should_receive(:create).with(hash_including(:id => id, :flavor_id => 'db.m1.small', :master_username => 'root', :password => 'password'))
17
+ Database.create!(id, 'db.m1.small', 'password')
18
+ end
19
+
20
+ it "should return a new Database object with an ID" do
21
+ database = Database.create!(id, 'b', 'd')
22
+ database.id.should == id
23
+ end
24
+ end
25
+
26
+ describe ".get" do
27
+ it "should return nil if the database doesn't exist" do
28
+ rds.servers.should_receive(:get).with(id).and_return nil
29
+ Database.get(id).should == nil
30
+ end
31
+
32
+ it "should return a Database object if the database does exist" do
33
+ rds.servers.should_receive(:get).with(id).and_return fog_database
34
+ Database.get(id).id.should == id
35
+ end
36
+
37
+ end
38
+
39
+ context "with a database created" do
40
+ before :each do
41
+ @database = Database.create!(id, 'db.m1.small', 'password')
42
+ fog_database.stub(:endpoint => {'Address' => '127.0.0.1'}, :master_username => 'root')
43
+ end
44
+ describe "db_environment_file" do
45
+ it "should return the contents of a file to use as /etc/environment that can be used to connct to this database" do
46
+ data = @database.db_environment_file('password')
47
+ data.should =~ /PUGE_DB_NAME=#{id}/
48
+ data.should =~ /PUGE_DB_USERNAME=root/
49
+ data.should =~ /PUGE_DB_PASSWORD=password/
50
+ data.should =~ /PUGE_DB_HOST=127.0.0.1/
51
+ end
52
+ end
53
+ describe :public_address do
54
+ it {@database.public_address.should == '127.0.0.1'}
55
+ end
56
+ end
57
+
58
+ end
@@ -0,0 +1,72 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), '../../spec_helper'))
2
+
3
+ describe Deploy::Puge do
4
+
5
+ let (:tag) { 'puge-1.16.1' }
6
+ let (:rails_env) { 'development' }
7
+ let (:gofer) { double('Gofer').as_null_object }
8
+ let (:servers) { (0..1).map { |i| double("Server #{i}").as_null_object} }
9
+ let (:environment) {double('Environment', :servers => servers, :database => database)}
10
+ let (:opts) { { 'tag' => tag, 'rails_env' => rails_env } }
11
+ let (:run_on_servers) { servers }
12
+ let (:base_path) { [ ENV['HOME'], '.dew', 'deploy', 'puge' ]}
13
+
14
+ shared_examples_for "script runner" do
15
+ it "should upload the script to the EC2 instance" do
16
+ run_on_servers.each do |server|
17
+ server.ssh.should_receive(:upload).with(File.join(base_path, script), File.join('.'))
18
+ end
19
+ Deploy::Puge.new(servers, opts).deploy
20
+ end
21
+
22
+ it "should run the script" do
23
+ run_on_servers.each do |server|
24
+ server.ssh.should_receive(:run).with(['./' + script, arguments.map { |a| "'#{a}'"}].flatten.join(" "))
25
+ end
26
+ Deploy::Puge.new(servers, opts).deploy
27
+ end
28
+ end
29
+
30
+ describe :run do
31
+
32
+ describe "Discrete actions" do
33
+
34
+ describe "Clone PUGE" do
35
+ let (:script) { 'clone_puge.sh' }
36
+ let (:arguments) { [tag] }
37
+ it_should_behave_like "script runner"
38
+ end
39
+
40
+ describe "Bundle install" do
41
+ let (:script) { 'bundle_install.sh' }
42
+ let (:arguments) { [] }
43
+ it_should_behave_like "script runner"
44
+ end
45
+
46
+ describe "Setup Rails database" do
47
+ let (:run_on_servers) { servers.first }
48
+ let (:script) { 'setup_rails_database.sh' }
49
+ let (:arguments) { [rails_env] }
50
+ it_should_behave_like "script runner"
51
+ end
52
+
53
+ describe "Generate PUGE WAR" do
54
+ let (:script) { 'generate_puge_war.sh' }
55
+ let (:arguments) { [rails_env] }
56
+ it_should_behave_like "script runner"
57
+ end
58
+
59
+ describe "Copy PUGE WAR into Tomcat directory" do
60
+ let (:script) { 'copy_puge_war_into_tomcat.sh' }
61
+ let (:arguments) { [] }
62
+ it_should_behave_like "script runner"
63
+ end
64
+
65
+ describe "Restart Tomcat" do
66
+ let (:script) { 'restart_tomcat.sh' }
67
+ let (:arguments) { [] }
68
+ it_should_behave_like "script runner"
69
+ end
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,38 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'spec_helper'))
2
+
3
+ describe Deploy::Run do
4
+
5
+ let (:deploy_type) { 'puge' }
6
+ let (:tag) { 'puge-1.16.1' }
7
+ let (:rails_env) { 'development' }
8
+ let (:servers) { (0..1).map { |i| double("Server #{i}").as_null_object} }
9
+ let (:database) { double('Database')}
10
+ let (:environment) {double('Environment', :servers => servers, :database => database)}
11
+ let (:opts) { { 'tag' => tag, 'rails_env' => rails_env } }
12
+
13
+ before :each do
14
+ @deploy_run = Deploy::Run.new(deploy_type, environment, opts)
15
+ Cloud.stub(:region => 'ap-southeast-1', :account_name => 'myaccount', :profile_name => 'development')
16
+ end
17
+
18
+ it { @deploy_run.deploy_type.should == deploy_type }
19
+ it { @deploy_run.environment.should == environment }
20
+ it { @deploy_run.opts['tag'].should == tag }
21
+ it { @deploy_run.opts['rails_env'].should == rails_env }
22
+
23
+ describe :deploy do
24
+ before :each do
25
+ Deploy::Puge.stub(:run => nil)
26
+ end
27
+
28
+ it "should perform a deploy run for each associated server" do
29
+ deloy_puge_class_name = 'Deploy::Puge'
30
+ deploy_puge = double(deloy_puge_class_name)
31
+
32
+ Deploy.should_receive(:const_get).with(deploy_type.capitalize).and_return(deloy_puge_class_name)
33
+ deloy_puge_class_name.should_receive(:new).with(servers, opts).and_return(deploy_puge)
34
+ deploy_puge.should_receive(:deploy)
35
+ @deploy_run.deploy
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,374 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), '../spec_helper'))
2
+
3
+ describe Environment do
4
+
5
+ let (:name) { 'my-environment' }
6
+ let (:bad_name) { 'my_environment' }
7
+ let (:server) { double('Server', :id => 'i-12345', :add_tag => nil, :wait_until_ready => nil, :availability_zone => 'ap-southeast-1') }
8
+ let(:groups) { %w(non_default) }
9
+ let (:server) { double('Server', :id => 'i-12345', :add_tag => nil, :wait_until_ready => nil, :availability_zone => 'ap-southeast-1', :groups => groups) }
10
+ let (:servers) { [] }
11
+ let(:an_elb) { double('elb1', :id => 'my-environment') }
12
+ let (:elb) { double('ELB', :load_balancers => [an_elb]) }
13
+ let (:database) { double('Database') }
14
+ let(:keypair_available_in_aws) { true }
15
+ let(:profile_count) { 2 }
16
+ let (:profile) do
17
+ double('Profile',
18
+ :ami => 'ami-12345', :size => 'm1.large',
19
+ :keypair => 'devops', :count => profile_count,
20
+ :has_rds? => false, :has_elb? => false
21
+ )
22
+ end
23
+
24
+ before :each do
25
+ @environment = Environment.new(name, servers)
26
+ Cloud.connect(name, 'development')
27
+ Cloud.stub(:elb => elb, :keypair_exists? => keypair_available_in_aws)
28
+ end
29
+
30
+ it { @environment.name.should == name }
31
+ it { @environment.servers.should == [] }
32
+ it { @environment.database.should == nil }
33
+
34
+ describe ".get" do
35
+ before :each do
36
+ Server.stub(:find => [])
37
+ Database.stub(:get => nil)
38
+ end
39
+ it "should discover servers belonging to this environment" do
40
+ Server.should_receive(:find).with('Environment', name).and_return [server]
41
+ Environment.get(name).servers.should == [server]
42
+ end
43
+ it "should discover a database belonging to this environment" do
44
+ Database.should_receive(:get).with(name).and_return 'database'
45
+ Environment.get(name).database.should == 'database'
46
+ end
47
+ it "should return nil if no servers nor database is discovered for this environment" do
48
+ Environment.get(name).should == nil
49
+ end
50
+ end
51
+
52
+ describe ".create" do
53
+ let (:security_groups) { %w(non_default) }
54
+ let(:profile) { double(:profile, :keypair => 'default', :security_groups => security_groups, :ami => 'i-1234', :has_rds? => false, :has_elb? => false, :count => 2, :size => 'small' ) }
55
+
56
+ context "when environment name is invalid" do
57
+ it "should raise an error" do
58
+ lambda { Environment.create(bad_name, profile) }.should raise_error /does not match/
59
+ end
60
+ end
61
+
62
+ context "when profile keypair is not available in AWS" do
63
+ let(:keypair_available_in_aws) { false }
64
+
65
+ it "should raise an error" do
66
+ lambda { Environment.create(name, profile) }.should raise_error /is not available/
67
+ end
68
+ end
69
+
70
+ context "when profile keypair is available in AWS" do
71
+
72
+ before {
73
+ @env = double(:environment, :name => name, :add_database => true, :wait_until_ready => true, :add_server => true)
74
+ Environment.should_receive(:new).with(name).and_return(@env)
75
+ }
76
+
77
+ after { Environment.create(name, profile) }
78
+
79
+ context "with a profile count of 2" do
80
+ let(:profile_count) { 2 }
81
+
82
+ it "should add two instances to that environment with the chosen AMI, size and keypair" do
83
+ @env.should_receive(:add_server).with(profile.ami, profile.size, profile.keypair, profile.security_groups).twice
84
+ end
85
+ end
86
+
87
+ it "should wait for our environment to become ready" do
88
+ @env.should_receive(:wait_until_ready)
89
+ end
90
+
91
+ describe "with an ELB specified in the profile" do
92
+ before :each do
93
+ profile.stub(:has_elb? => true, :elb_listener_ports => [80])
94
+ end
95
+
96
+ it "should add an ELB to the environment with the required ports" do
97
+ @env.should_receive(:add_elb).with([80])
98
+ end
99
+ end
100
+
101
+ describe "with an RDS specified in the profile" do
102
+ before :each do
103
+ profile.stub(:has_rds? => true, :rds_size => 'db.m1.small')
104
+ @env.stub(:add_database => nil, :configure_servers_for_database => nil)
105
+ Password.stub(:random => 'abcdef')
106
+ end
107
+
108
+ it "should add an RDS to the environment with the required size and a random password" do
109
+ @env.should_receive(:add_database).with('db.m1.small', 'abcdef')
110
+ end
111
+
112
+ it "should ask the environment to update the database configuration on the servers" do
113
+ @env.should_receive(:configure_servers_for_database).with('abcdef')
114
+ end
115
+ end
116
+
117
+ end
118
+ end
119
+
120
+ describe ".names" do
121
+ before {
122
+ Cloud.should_receive(:valid_servers).at_least(1).and_return( [
123
+ double(:server, :tags => {"Environment" => "test-1", "Creator" => "chris" }),
124
+ double(:server, :tags => {"Environment" => "test-2", "Creator" => "ash" })
125
+ ])
126
+ }
127
+
128
+ it { Environment.owners.should == [{:name=>"test-1", :owner=>"chris"}, {:name=>"test-2", :owner=>"ash"}] }
129
+ end
130
+
131
+ describe ".index" do
132
+ before {
133
+ Cloud.should_receive(:valid_servers).at_least(1).and_return( [
134
+ double(:server, :tags => {"Environment" => "test-1", "Creator" => "chris" }),
135
+ double(:server, :tags => {"Environment" => "test-2", "Creator" => "ash" })
136
+ ])
137
+ }
138
+ after { Environment.index }
139
+
140
+ # TODO: Have the model return what is to be displayed rather than display it itself.
141
+ it "should index the environments" do
142
+ Inform.should_receive(:info).at_least(1).with( <<EOF
143
+ Environments:
144
+ +----------+---------+
145
+ | name | owner |
146
+ +----------+---------+
147
+ | "test-1" | "chris" |
148
+ | "test-2" | "ash" |
149
+ +----------+---------+
150
+ EOF
151
+ )
152
+ end
153
+ end
154
+
155
+ describe :show do
156
+ before {
157
+ Cloud.stub_chain(:account, :aws_user_id).and_return('12345')
158
+ }
159
+ after { @environment.show }
160
+
161
+ context "with servers" do
162
+ let(:servers) { [server] }
163
+
164
+ before { @environment.stub(:elb => nil) }
165
+ it "should show the servers" do
166
+ View.should_receive(:new).with(
167
+ "SERVERS", [server], %w(id flavor_id public_ip_address state created_at groups key_name availability_zone creator)
168
+ ).and_return(double(:servers_view, :index => 'servers'))
169
+ end
170
+ end
171
+
172
+ context "with an elb" do
173
+ it "should show the elb" do
174
+ elb_view = double(:elb_view)
175
+ View.should_receive(:new).with(
176
+ "ELB", [an_elb], %w(created_at dns_name instances availability_zones)
177
+ ).and_return(elb_view)
178
+ elb_view.should_receive(:show).and_return('stuff')
179
+ end
180
+ end
181
+
182
+ context "with a database" do
183
+ before {
184
+ @environment.stub(:database => database)
185
+ @environment.stub(:elb => nil)
186
+ }
187
+
188
+ it "should show the database" do
189
+ View.should_receive(:new).with(
190
+ "DATABASE", [database], %w(flavor_id state created_at availability_zone db_security_groups)
191
+ ).and_return(double(:database_view, :index => 'database', :show => "some_ stuff"))
192
+ end
193
+ end
194
+
195
+ end
196
+
197
+ describe :destroy do
198
+ before :each do
199
+ @environment.stub(:has_elb? => false)
200
+ end
201
+ it "should destroy the database if there is one" do
202
+ @environment.stub(:database => database)
203
+ database.should_receive(:destroy)
204
+ @environment.destroy
205
+ end
206
+ it "should destroy the servers if there are any" do
207
+ @environment.stub(:servers => [server])
208
+ server.should_receive(:destroy)
209
+ @environment.destroy
210
+ end
211
+ it "should destroy the ELB if there is one" do
212
+ @environment.stub(:has_elb? => true)
213
+ elb.should_receive(:delete_load_balancer).with(name)
214
+ @environment.destroy
215
+ end
216
+ end
217
+
218
+ describe :add_server do
219
+ before :each do
220
+ @args = 'ami', 'size', 'keypair', %w(non_default)
221
+ Server.stub(:create!).and_return(server)
222
+ end
223
+
224
+ it "should create a Server from the provided ami, size and keypair" do
225
+ Server.should_receive(:create!).with(*@args)
226
+ @environment.add_server(*@args)
227
+ end
228
+
229
+ it "should add the Server to its servers array" do
230
+ @environment.add_server(*@args)
231
+ @environment.add_server(*@args)
232
+ @environment.servers.should == [server, server]
233
+ end
234
+
235
+ it "should tag the server with the environment name and creator" do
236
+ server.should_receive(:add_tag).with('Environment', name)
237
+ server.should_receive(:add_tag).with('Creator', ENV['USER'])
238
+ @environment.add_server(*@args)
239
+ end
240
+
241
+ it "should tag the server with an indexed name" do
242
+ server.should_receive(:add_tag).with('Name', "#{name} 1")
243
+ @environment.add_server(*@args)
244
+
245
+ server.should_receive(:add_tag).with('Name', "#{name} 2")
246
+ @environment.add_server(*@args)
247
+ end
248
+ end
249
+
250
+ describe :remove_server_from_elb do
251
+ it "should remove the server from the ELB" do
252
+ elb.should_receive(:deregister_instances_from_load_balancer).with([server.id], name)
253
+ @environment.remove_server_from_elb(server)
254
+ end
255
+ end
256
+
257
+ describe :add_server_to_elb do
258
+ it "should add the server to the ELB" do
259
+ elb.should_receive(:register_instances_with_load_balancer).with([server.id], name)
260
+ @environment.add_server_to_elb(server)
261
+ end
262
+ end
263
+
264
+ context "with one server" do
265
+ before :each do
266
+ @environment.stub(:servers => [server])
267
+ end
268
+
269
+ describe :add_elb do
270
+ before :each do
271
+ server.stub(:availability_zone => 'ap-southeast-1a')
272
+ elb.stub(:create_load_balancer => nil, :register_instances_with_load_balancer => nil)
273
+ end
274
+ it "should create the ELB using the provided listeners, environment name and the availability zones of the current servers" do
275
+ server.should_receive(:availability_zone).and_return('ap-southeast-1a')
276
+
277
+ elb.should_receive(:create_load_balancer).with(
278
+ ['ap-southeast-1a'], name,
279
+ [{'Protocol' => 'TCP', 'LoadBalancerPort' => 80, 'InstancePort' => 80}]
280
+ )
281
+ @environment.add_elb [80]
282
+ end
283
+ it "should add the servers to the elb" do
284
+ elb.should_receive(:register_instances_with_load_balancer).with([server.id], name)
285
+ @environment.add_elb [80]
286
+ end
287
+
288
+ end
289
+
290
+ describe :add_database do
291
+ before :each do
292
+ Database.stub(:create! => database)
293
+ end
294
+
295
+ it "should create an RDS of the requested size, using the environment name and a random password" do
296
+ Database.should_receive(:create!).with(name, 'db.m1.small', 'password')
297
+ @environment.add_database 'db.m1.small', 'password'
298
+ end
299
+
300
+ it "should make the database available on the 'database' accessor" do
301
+ @environment.add_database 'db.m1.small', 'password'
302
+ @environment.database.should == database
303
+ end
304
+ end
305
+
306
+ describe :wait_until_ready do
307
+ before {
308
+ Cloud.stub(:security_groups => { 'non_default' => double(:group, :ip_permissions => ip_permissions) } )
309
+ }
310
+ after { @environment.wait_until_ready }
311
+
312
+ context "with no ip_permissions" do
313
+ let(:ip_permissions) { [:some_ip_permissions] }
314
+
315
+ it "should wait for each server to be ready" do
316
+ server.should_receive(:wait_until_ready)
317
+ end
318
+ end
319
+
320
+ context "with ip_permissions" do
321
+ let(:ip_permissions) { [] }
322
+
323
+ it "should not wait for each server to be ready" do
324
+ server.should_not_receive(:wait_until_ready)
325
+ end
326
+ end
327
+ end
328
+
329
+ context "with an RDS" do
330
+ before :each do
331
+ Cloud.stub(:security_groups => { 'non_default' => double(:group, :ip_permissions => true) } )
332
+ @environment.stub(:database => database)
333
+ end
334
+
335
+ describe :wait_until_ready do
336
+ it "should wait for the database to be ready" do
337
+ database.should_receive(:wait_until_ready)
338
+ @environment.wait_until_ready
339
+ end
340
+ end
341
+
342
+ describe :configure_servers_for_database do
343
+ it "should ask each server to apply credentials from our database" do
344
+ server.should_receive(:configure_for_database).with(database, 'password')
345
+ @environment.configure_servers_for_database 'password'
346
+ end
347
+ end
348
+
349
+ end
350
+ end
351
+
352
+ def mock_describe_load_balancers load_balancers, name=nil
353
+ response = double('ELB Response', :body => { 'DescribeLoadBalancersResult' => { 'LoadBalancerDescriptions' => load_balancers }})
354
+ if name
355
+ elb.should_receive(:describe_load_balancers).with(name).and_return(response)
356
+ else
357
+ elb.should_receive(:describe_load_balancers).and_return(response)
358
+ end
359
+ end
360
+
361
+ describe :has_elb? do
362
+ it "return true if we have a load balancer" do
363
+ mock_describe_load_balancers([{'LoadBalancerName' => name}])
364
+ @environment.has_elb?.should be_true
365
+ end
366
+
367
+ it "return false if we don't" do
368
+ mock_describe_load_balancers([{'LoadBalancerName' => "XXXX"}])
369
+ @environment.has_elb?.should be_false
370
+ end
371
+
372
+ end
373
+
374
+ end