simple_deploy 0.7.2 → 0.7.3

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.
Files changed (89) hide show
  1. data/.gitignore +3 -0
  2. data/CHANGELOG.md +6 -0
  3. data/lib/simple_deploy/aws/cloud_formation/error.rb +32 -0
  4. data/lib/simple_deploy/aws/cloud_formation.rb +76 -0
  5. data/lib/simple_deploy/aws/instance_reader.rb +59 -0
  6. data/lib/simple_deploy/aws/simpledb.rb +52 -0
  7. data/lib/simple_deploy/aws.rb +4 -0
  8. data/lib/simple_deploy/cli/attributes.rb +7 -18
  9. data/lib/simple_deploy/cli/clone.rb +9 -19
  10. data/lib/simple_deploy/cli/create.rb +5 -14
  11. data/lib/simple_deploy/cli/deploy.rb +8 -11
  12. data/lib/simple_deploy/cli/destroy.rb +4 -10
  13. data/lib/simple_deploy/cli/environments.rb +1 -1
  14. data/lib/simple_deploy/cli/events.rb +5 -11
  15. data/lib/simple_deploy/cli/execute.rb +6 -9
  16. data/lib/simple_deploy/cli/instances.rb +4 -9
  17. data/lib/simple_deploy/cli/list.rb +5 -10
  18. data/lib/simple_deploy/cli/outputs.rb +5 -11
  19. data/lib/simple_deploy/cli/parameters.rb +5 -11
  20. data/lib/simple_deploy/cli/protect.rb +5 -10
  21. data/lib/simple_deploy/cli/resources.rb +5 -11
  22. data/lib/simple_deploy/cli/shared.rb +6 -6
  23. data/lib/simple_deploy/cli/status.rb +5 -11
  24. data/lib/simple_deploy/cli/template.rb +8 -13
  25. data/lib/simple_deploy/cli/update.rb +6 -10
  26. data/lib/simple_deploy/configuration.rb +102 -0
  27. data/lib/simple_deploy/entry.rb +71 -0
  28. data/lib/simple_deploy/entry_lister.rb +30 -0
  29. data/lib/simple_deploy/exceptions.rb +8 -0
  30. data/lib/simple_deploy/misc/attribute_merger.rb +2 -5
  31. data/lib/simple_deploy/notifier/campfire.rb +15 -12
  32. data/lib/simple_deploy/notifier.rb +6 -11
  33. data/lib/simple_deploy/stack/deployment/status.rb +5 -3
  34. data/lib/simple_deploy/stack/deployment.rb +8 -10
  35. data/lib/simple_deploy/stack/execute.rb +2 -3
  36. data/lib/simple_deploy/stack/output_mapper.rb +1 -4
  37. data/lib/simple_deploy/stack/ssh.rb +4 -4
  38. data/lib/simple_deploy/stack/{stack_attribute_formater.rb → stack_attribute_formatter.rb} +4 -6
  39. data/lib/simple_deploy/stack/stack_creator.rb +46 -0
  40. data/lib/simple_deploy/stack/stack_destroyer.rb +19 -0
  41. data/lib/simple_deploy/stack/stack_formatter.rb +25 -0
  42. data/lib/simple_deploy/stack/stack_lister.rb +18 -0
  43. data/lib/simple_deploy/stack/stack_reader.rb +56 -0
  44. data/lib/simple_deploy/stack/stack_updater.rb +67 -0
  45. data/lib/simple_deploy/stack/status.rb +53 -0
  46. data/lib/simple_deploy/stack.rb +89 -37
  47. data/lib/simple_deploy/version.rb +1 -1
  48. data/lib/simple_deploy.rb +31 -1
  49. data/simple_deploy.gemspec +6 -3
  50. data/spec/aws/cloud_formation/error_spec.rb +50 -0
  51. data/spec/aws/cloud_formation_spec.rb +207 -0
  52. data/spec/aws/instance_reader_spec.rb +96 -0
  53. data/spec/aws/simpledb_spec.rb +89 -0
  54. data/spec/cli/attributes_spec.rb +5 -15
  55. data/spec/cli/clone_spec.rb +14 -27
  56. data/spec/cli/create_spec.rb +11 -18
  57. data/spec/cli/deploy_spec.rb +24 -63
  58. data/spec/cli/destroy_spec.rb +7 -25
  59. data/spec/cli/outputs_spec.rb +12 -17
  60. data/spec/cli/protect_spec.rb +68 -106
  61. data/spec/cli/shared_spec.rb +12 -15
  62. data/spec/cli/update_spec.rb +9 -27
  63. data/spec/config_spec.rb +47 -14
  64. data/spec/contexts/config_contexts.rb +28 -0
  65. data/spec/contexts/logger_contexts.rb +9 -0
  66. data/spec/contexts/stack_contexts.rb +40 -0
  67. data/spec/entry_lister_spec.rb +31 -0
  68. data/spec/entry_spec.rb +86 -0
  69. data/spec/misc/attribute_merger_spec.rb +3 -8
  70. data/spec/notifier/campfire_spec.rb +21 -61
  71. data/spec/notifier_spec.rb +18 -40
  72. data/spec/spec_helper.rb +10 -0
  73. data/spec/stack/deployment/status_spec.rb +13 -13
  74. data/spec/stack/deployment_spec.rb +26 -21
  75. data/spec/stack/execute_spec.rb +7 -3
  76. data/spec/stack/output_mapper_spec.rb +3 -15
  77. data/spec/stack/ssh_spec.rb +14 -13
  78. data/spec/stack/{stack_attribute_formater_spec.rb → stack_attribute_formatter_spec.rb} +19 -16
  79. data/spec/stack/stack_creator_spec.rb +46 -0
  80. data/spec/stack/stack_destroyer_spec.rb +18 -0
  81. data/spec/stack/stack_formatter_spec.rb +37 -0
  82. data/spec/stack/stack_lister_spec.rb +17 -0
  83. data/spec/stack/stack_reader_spec.rb +81 -0
  84. data/spec/stack/stack_updater_spec.rb +79 -0
  85. data/spec/stack/status_spec.rb +106 -0
  86. data/spec/stack_spec.rb +160 -133
  87. metadata +112 -19
  88. data/.rvmrc +0 -1
  89. data/lib/simple_deploy/config.rb +0 -87
@@ -1,3 +1,3 @@
1
1
  module SimpleDeploy
2
- VERSION = "0.7.2"
2
+ VERSION = "0.7.3"
3
3
  end
data/lib/simple_deploy.rb CHANGED
@@ -1,6 +1,9 @@
1
+ require 'simple_deploy/aws'
1
2
  require 'simple_deploy/env'
3
+ require 'simple_deploy/entry'
4
+ require 'simple_deploy/entry_lister'
2
5
  require 'simple_deploy/exceptions'
3
- require 'simple_deploy/config'
6
+ require 'simple_deploy/configuration'
4
7
  require 'simple_deploy/artifact'
5
8
  require 'simple_deploy/stack'
6
9
  require 'simple_deploy/misc'
@@ -9,3 +12,30 @@ require 'simple_deploy/notifier'
9
12
  require 'simple_deploy/logger'
10
13
  require 'simple_deploy/version'
11
14
  require 'simple_deploy/backoff'
15
+
16
+ module SimpleDeploy
17
+ module_function
18
+
19
+ def create_config(environment, custom_config = {})
20
+ raise SimpleDeploy::Exceptions::IllegalStateException.new(
21
+ 'environment is not defined') unless environment
22
+
23
+ @config = SimpleDeploy::Configuration.configure environment, custom_config
24
+ end
25
+
26
+ def config
27
+ @config
28
+ end
29
+
30
+ def release_config
31
+ @config = nil
32
+ end
33
+
34
+ def environments(custom_config = {})
35
+ SimpleDeploy::Configuration.environments custom_config
36
+ end
37
+
38
+ def logger(log_level = 'info')
39
+ @logger ||= SimpleDeployLogger.new :log_level => log_level
40
+ end
41
+ end
@@ -20,10 +20,13 @@ Gem::Specification.new do |s|
20
20
 
21
21
  s.add_development_dependency "fakefs", "~> 0.4.2"
22
22
  s.add_development_dependency "rake"
23
- s.add_development_dependency "rspec", "~> 2.11.0"
23
+ s.add_development_dependency "rspec", "~> 2.13.0"
24
+ s.add_development_dependency "simplecov", "~> 0.7.1"
25
+ s.add_development_dependency "timecop", "~> 0.6.1"
24
26
 
25
27
  s.add_runtime_dependency "capistrano", "= 2.13.5"
26
- s.add_runtime_dependency "stackster", '= 0.4.4'
27
- s.add_runtime_dependency "tinder", "= 1.8.0"
28
+ s.add_runtime_dependency "esbit", "~> 0.0.4"
28
29
  s.add_runtime_dependency "trollop", "= 2.0"
30
+ s.add_runtime_dependency "fog", "= 1.10.0"
31
+ s.add_runtime_dependency "xml-simple", "= 1.1.2"
29
32
  end
@@ -0,0 +1,50 @@
1
+ require 'spec_helper'
2
+
3
+ describe SimpleDeploy::AWS::CloudFormation::Error do
4
+ include_context 'double stubbed config', :access_key => 'key',
5
+ :secret_key => 'XXX',
6
+ :region => 'us-west-1'
7
+ include_context 'double stubbed logger'
8
+
9
+ before do
10
+ @exception_stub1 = stub 'Excon::Response'
11
+ @exception_stub1.stub(:response).and_return(@exception_stub1)
12
+ @exception_stub1.stub(:body).and_return('<opt><Error><Message>No updates are to be performed.</Message></Error></opt>')
13
+
14
+ @exception_stub2 = stub 'Excon::Response'
15
+ @exception_stub2.stub(:response).and_return(@exception_stub2)
16
+ @exception_stub2.stub(:body).and_return('<opt><Error><Message>Oops.</Message></Error></opt>')
17
+
18
+ @exception_stub3 = stub 'Excon::Response'
19
+ @exception_stub3.stub(:response).and_return(@exception_stub3)
20
+ @exception_stub3.stub(:body).and_return('<opt><Error><Message>Stack:test does not exist</Message></Error></opt>')
21
+ end
22
+
23
+ describe 'process' do
24
+ it 'should process no update messages' do
25
+ error = SimpleDeploy::AWS::CloudFormation::Error.new :exception => @exception_stub1
26
+ expect { error.process }.to_not raise_error SimpleDeploy::Exceptions::CloudFormationError
27
+ end
28
+
29
+ it 'should re-raise unkonwn errors as SimpleDeploy::CloudFormationError' do
30
+ error = SimpleDeploy::AWS::CloudFormation::Error.new :exception => @exception_stub2
31
+
32
+ lambda { error.process }.should raise_error SimpleDeploy::Exceptions::CloudFormationError
33
+ end
34
+
35
+ it 'should re-raise unkonwn errors as SimpleDeploy::CloudFormationError and set mesg' do
36
+ error = SimpleDeploy::AWS::CloudFormation::Error.new :exception => @exception_stub2
37
+ begin
38
+ error.process
39
+ rescue SimpleDeploy::Exceptions::CloudFormationError => e
40
+ e.message.should == "Oops."
41
+ end
42
+ end
43
+
44
+ it 'should reaise stck unkown messages as SimpleDeploy::UnknownStack' do
45
+ error = SimpleDeploy::AWS::CloudFormation::Error.new :exception => @exception_stub3
46
+ lambda { error.process }.should raise_error SimpleDeploy::Exceptions::UnknownStack
47
+ end
48
+
49
+ end
50
+ end
@@ -0,0 +1,207 @@
1
+ require 'spec_helper'
2
+
3
+ describe SimpleDeploy::AWS::CloudFormation do
4
+ include_context 'double stubbed config', :access_key => 'key',
5
+ :secret_key => 'XXX',
6
+ :region => 'us-west-1'
7
+ include_context 'double stubbed logger'
8
+
9
+ before do
10
+ @error_stub = stub 'Error', :process => 'Processed Error'
11
+ @response_stub = stub 'Excon::Response', :body => {
12
+ 'Stacks' => [{'StackStatus' => 'green', 'Outputs' => [{'key' => 'value'}]}],
13
+ 'StackResources' => [{'StackName' => 'my_stack'}],
14
+ 'StackEvents' => ['event1', 'event2'],
15
+ 'TemplateBody' => '{EIP: "string"}'
16
+ }
17
+
18
+ @cf_mock = mock 'CloudFormation'
19
+ Fog::AWS::CloudFormation.stub(:new).and_return(@cf_mock)
20
+
21
+ @args = {
22
+ :parameters => { 'parameter1' => 'my_param' },
23
+ :name => 'my_stack',
24
+ :template => 'my_template'
25
+ }
26
+
27
+ @exception = Exception.new('Failed')
28
+
29
+ @cf = SimpleDeploy::AWS::CloudFormation.new
30
+ end
31
+
32
+ after do
33
+ SimpleDeploy.release_config
34
+ end
35
+
36
+ describe "create" do
37
+ it "should create the stack on Cloud Formation" do
38
+ @cf_mock.should_receive(:create_stack).with('my_stack',
39
+ { 'Capabilities' => ['CAPABILITY_IAM'],
40
+ 'TemplateBody' => 'my_template',
41
+ 'Parameters' => { 'parameter1' => 'my_param' }
42
+ })
43
+
44
+ @cf.create(@args)
45
+ end
46
+
47
+ it "should trap and re-raise exceptions as SimpleDeploy::Exceptions::CloudFormationError" do
48
+ @cf_mock.should_receive(:create_stack).with('my_stack',
49
+ { 'Capabilities' => ['CAPABILITY_IAM'],
50
+ 'TemplateBody' => 'my_template',
51
+ 'Parameters' => { 'parameter1' => 'my_param' }
52
+ }).and_raise(@exception)
53
+
54
+ SimpleDeploy::AWS::CloudFormation::Error.should_receive(:new).
55
+ with(:exception => @exception).
56
+ and_raise SimpleDeploy::Exceptions::CloudFormationError.new('failed')
57
+
58
+ lambda { @cf.create @args }.
59
+ should raise_error SimpleDeploy::Exceptions::CloudFormationError
60
+ end
61
+ end
62
+
63
+ describe "update" do
64
+ it "should update the stack on Cloud Formation" do
65
+ @cf_mock.should_receive(:update_stack).with('my_stack',
66
+ { 'Capabilities' => ['CAPABILITY_IAM'],
67
+ 'TemplateBody' => 'my_template',
68
+ 'Parameters' => { 'parameter1' => 'my_param' }
69
+ })
70
+
71
+ @cf.update(@args)
72
+ end
73
+
74
+ it "should trap and re-raise exceptions as SimpleDeploy::Exceptions::CloudFormationError" do
75
+ @cf_mock.should_receive(:update_stack).with('my_stack',
76
+ { 'Capabilities' => ['CAPABILITY_IAM'],
77
+ 'TemplateBody' => 'my_template',
78
+ 'Parameters' => { 'parameter1' => 'my_param' }
79
+ }).and_raise(@exception)
80
+ SimpleDeploy::AWS::CloudFormation::Error.should_receive(:new).
81
+ with(:exception => @exception).
82
+ and_raise SimpleDeploy::Exceptions::CloudFormationError.new('failed')
83
+
84
+ lambda { @cf.update(@args) }.
85
+ should raise_error SimpleDeploy::Exceptions::CloudFormationError
86
+ end
87
+ end
88
+
89
+
90
+ describe 'destroy' do
91
+ it "should delete the stack on Cloud Formation" do
92
+ @cf_mock.should_receive(:delete_stack).with('my_stack')
93
+
94
+ @cf.destroy('my_stack')
95
+ end
96
+
97
+ it "should trap and re-raise exceptions as SimpleDeploy::Exceptions::CloudFormationError" do
98
+ @cf_mock.should_receive(:delete_stack).
99
+ with('my_stack').
100
+ and_raise @exception
101
+ SimpleDeploy::AWS::CloudFormation::Error.should_receive(:new).
102
+ with(:exception => @exception).
103
+ and_raise SimpleDeploy::Exceptions::CloudFormationError.new('failed')
104
+
105
+ lambda { @cf.destroy('my_stack') }.
106
+ should raise_error SimpleDeploy::Exceptions::CloudFormationError
107
+ end
108
+ end
109
+
110
+
111
+ describe 'describe_stack' do
112
+ it "should return the Cloud Formation description of the stack" do
113
+ @cf_mock.should_receive(:describe_stacks).with('StackName' => 'my_stack').and_return(@response_stub)
114
+
115
+ @cf.describe_stack('my_stack').should == [{'StackStatus' => 'green', 'Outputs' => [{'key' => 'value'}]}]
116
+ end
117
+
118
+ it "should trap and re-raise exceptions as SimpleDeploy::Exceptions::CloudFormationError" do
119
+ @cf_mock.should_receive(:describe_stacks).
120
+ with('StackName' => 'my_stack').
121
+ and_raise @exception
122
+ SimpleDeploy::AWS::CloudFormation::Error.should_receive(:new).
123
+ with(:exception => @exception).
124
+ and_raise SimpleDeploy::Exceptions::CloudFormationError.new('failed')
125
+
126
+ lambda { @cf.describe_stack('my_stack') }.
127
+ should raise_error SimpleDeploy::Exceptions::CloudFormationError
128
+ end
129
+ end
130
+
131
+ describe "stack_resources" do
132
+ it "should return the Cloud Formation description of the stack resources" do
133
+ @cf_mock.should_receive(:describe_stack_resources).with('StackName' => 'my_stack').and_return(@response_stub)
134
+
135
+ @cf.stack_resources('my_stack').should == [{'StackName' => 'my_stack'}]
136
+ end
137
+
138
+ it "should trap and re-raise exceptions as SimpleDeploy::Exceptions::CloudFormationError" do
139
+ @cf_mock.should_receive(:describe_stack_resources).
140
+ with('StackName' => 'my_stack').
141
+ and_raise @exception
142
+ SimpleDeploy::AWS::CloudFormation::Error.should_receive(:new).
143
+ with(:exception => @exception).
144
+ and_raise SimpleDeploy::Exceptions::CloudFormationError.new('failed')
145
+
146
+ lambda { @cf.stack_resources('my_stack') }.
147
+ should raise_error SimpleDeploy::Exceptions::CloudFormationError
148
+ end
149
+ end
150
+
151
+ describe "stack_events" do
152
+ it "should return the Cloud Formation description of the stack events" do
153
+ @cf_mock.should_receive(:describe_stack_events).with('my_stack').and_return(@response_stub)
154
+
155
+ @cf.stack_events('my_stack', 2).should == ['event1', 'event2']
156
+ end
157
+
158
+ it "should trap and re-raise exceptions as SimpleDeploy::Exceptions::CloudFormationError" do
159
+ @cf_mock.should_receive(:describe_stack_events).
160
+ with('my_stack').
161
+ and_raise @exception
162
+
163
+ SimpleDeploy::AWS::CloudFormation::Error.should_receive(:new).
164
+ with(:exception => @exception).
165
+ and_raise SimpleDeploy::Exceptions::CloudFormationError.new('failed')
166
+
167
+ lambda { @cf.stack_events('my_stack', 2) }.
168
+ should raise_error SimpleDeploy::Exceptions::CloudFormationError
169
+ end
170
+ end
171
+
172
+ describe "stack_status" do
173
+ it "should return the Cloud Formation status of the stack" do
174
+ @cf_mock.should_receive(:describe_stacks).with('StackName' => 'my_stack').and_return(@response_stub)
175
+
176
+ @cf.stack_status('my_stack').should == 'green'
177
+ end
178
+ end
179
+
180
+ describe "stack_outputs" do
181
+ it "should return the Cloud Formation outputs for the stack" do
182
+ @cf_mock.should_receive(:describe_stacks).with('StackName' => 'my_stack').and_return(@response_stub)
183
+
184
+ @cf.stack_outputs('my_stack').should == [{'key' => 'value'}]
185
+ end
186
+ end
187
+
188
+ describe "template" do
189
+ it "should return the Cloud Formation template for the stack" do
190
+ @cf_mock.should_receive(:get_template).with('my_stack').and_return(@response_stub)
191
+
192
+ @cf.template('my_stack').should == '{EIP: "string"}'
193
+ end
194
+
195
+ it "should trap and re-raise exceptions as SimpleDeploy::Exceptions::CloudFormationError" do
196
+ @cf_mock.should_receive(:get_template).
197
+ with('my_stack').
198
+ and_raise @exception
199
+ SimpleDeploy::AWS::CloudFormation::Error.should_receive(:new).
200
+ with(:exception => @exception).
201
+ and_raise SimpleDeploy::Exceptions::CloudFormationError.new('failed')
202
+
203
+ lambda { @cf.template('my_stack') }.
204
+ should raise_error SimpleDeploy::Exceptions::CloudFormationError
205
+ end
206
+ end
207
+ end
@@ -0,0 +1,96 @@
1
+ require 'spec_helper'
2
+
3
+ describe SimpleDeploy::AWS::InstanceReader do
4
+ include_context 'double stubbed logger'
5
+ include_context 'double stubbed config', :access_key => 'key',
6
+ :secret_key => 'XXX',
7
+ :region => 'us-west-1'
8
+
9
+ describe "list_stack_instances" do
10
+ before do
11
+ @cloud_formation_mock = mock 'cloud formation'
12
+ @auto_scaling_groups_mock = mock 'auto scaling'
13
+ @ec2_mock = mock 'ec2'
14
+
15
+ instances = ['first',{ 'Instances' => [{ 'InstanceId' => 'i-000001' },
16
+ { 'InstanceId' => 'i-000002' }] }]
17
+ body = { 'DescribeAutoScalingGroupsResult' => { 'AutoScalingGroups' => instances } }
18
+ @list_response = stub 'Fog::Response', :body => body, :any? => true
19
+
20
+ empty_body = { 'DescribeAutoScalingGroupsResult' => { 'AutoScalingGroups' => [] } }
21
+ @empty_response = stub 'Fog::Response', :body => empty_body
22
+
23
+ @describe_response = stub 'Excon::Response', :body => {
24
+ 'reservationSet' => [{
25
+ 'instanceSet' => [{'instanceState' => {'name' => 'running'}},
26
+ {'ipAddress' => '54.10.10.1'},
27
+ {'instanceId' => 'i-123456'},
28
+ {'privateIpAddress' => '192.168.1.1'}]}]
29
+ }
30
+
31
+ SimpleDeploy::AWS::CloudFormation.stub(:new).
32
+ and_return @cloud_formation_mock
33
+ end
34
+
35
+ context "with no ASGs" do
36
+ before do
37
+ @cloud_formation_mock.should_receive(:stack_resources).
38
+ with('stack').
39
+ and_return []
40
+ end
41
+
42
+ it "should return an empty array" do
43
+ instance_reader = SimpleDeploy::AWS::InstanceReader.new
44
+ instance_reader.list_stack_instances('stack').should == []
45
+ end
46
+ end
47
+
48
+ context "with an ASG" do
49
+ before do
50
+ stack_resource_results = [{'StackName' => 'stack',
51
+ 'ResourceType' => 'AWS::AutoScaling::AutoScalingGroup',
52
+ 'PhysicalResourceId' => 'asg1'}]
53
+
54
+ @cloud_formation_mock.should_receive(:stack_resources).
55
+ with('stack').
56
+ and_return stack_resource_results
57
+
58
+ Fog::AWS::AutoScaling.stub(:new).
59
+ and_return @auto_scaling_groups_mock
60
+ end
61
+
62
+ context "with no running instances" do
63
+ it "should return empty array" do
64
+ @auto_scaling_groups_mock.should_receive(:describe_auto_scaling_groups).
65
+ with('AutoScalingGroupNames' => ['asg1']).
66
+ and_return(@empty_response)
67
+
68
+ instance_reader = SimpleDeploy::AWS::InstanceReader.new
69
+ instance_reader.list_stack_instances('stack').should == []
70
+ end
71
+ end
72
+
73
+ context "with running instances" do
74
+ it "should return the reservation set for each running instance" do
75
+ @auto_scaling_groups_mock.should_receive(:describe_auto_scaling_groups).
76
+ with('AutoScalingGroupNames' => ['asg1']).
77
+ and_return(@list_response)
78
+
79
+ Fog::Compute::AWS.stub(:new).
80
+ and_return @ec2_mock
81
+ @ec2_mock.should_receive(:describe_instances).
82
+ with('instance-state-name' => 'running',
83
+ 'instance-id' => ['i-000001', 'i-000002']).
84
+ and_return @describe_response
85
+
86
+ instance_reader = SimpleDeploy::AWS::InstanceReader.new
87
+ instance_reader.list_stack_instances('stack').should == [{
88
+ 'instanceSet' => [{'instanceState' => {'name' => 'running'}},
89
+ {'ipAddress' => '54.10.10.1'},
90
+ {'instanceId' => 'i-123456'},
91
+ {'privateIpAddress' => '192.168.1.1'}]}]
92
+ end
93
+ end
94
+ end
95
+ end
96
+ end
@@ -0,0 +1,89 @@
1
+ require 'spec_helper'
2
+
3
+ describe SimpleDeploy::AWS::SimpleDB do
4
+ include_context 'double stubbed config', :access_key => 'key',
5
+ :secret_key => 'XXX',
6
+ :region => 'us-west-1'
7
+
8
+ before do
9
+ @response_stub = stub 'Excon::Response', :body => {
10
+ 'RequestId' => 'rid',
11
+ 'Domains' => ['domain1', 'domain2'],
12
+ 'Items' => { 'item1' => { 'key' => ['value'] } },
13
+ 'NextToken' => nil
14
+ }
15
+ @multi_response_stub = stub 'Excon::Response', :body => {
16
+ 'RequestId' => 'rid',
17
+ 'Domains' => ['domain1', 'domain2'],
18
+ 'Items' => { 'item1-2' => { 'key' => ['value'] } },
19
+ 'NextToken' => 'Chunk2'
20
+ }
21
+
22
+ @db_mock = mock 'SimpleDB'
23
+ Fog::AWS::SimpleDB.stub(:new).and_return(@db_mock)
24
+ @db_mock.stub(:list_domains).and_return(@response_stub)
25
+
26
+ @db = SimpleDeploy::AWS::SimpleDB.new
27
+ end
28
+
29
+ describe 'domains' do
30
+ it 'should return a list of domains' do
31
+ @db.domains.should == ['domain1', 'domain2']
32
+ end
33
+ end
34
+
35
+ describe 'domain_exists?' do
36
+ it 'should return true for existing domains' do
37
+ @db.domain_exists?('domain1').should be_true
38
+ end
39
+
40
+ it 'should return false for non-existent domains' do
41
+ @db.domain_exists?('baddomain1').should_not be_true
42
+ end
43
+ end
44
+
45
+ describe 'create_domain' do
46
+ it 'should create a new domain' do
47
+ @db_mock.should_receive(:create_domain).with('newdomain').and_return(@response_stub)
48
+
49
+ @db.create_domain('newdomain').body['RequestId'].should == 'rid'
50
+ end
51
+
52
+ it 'should not create a duplicate domain' do
53
+ @db_mock.should_not_receive(:create_domain)
54
+
55
+ @db.create_domain('domain1').should be_nil
56
+ end
57
+ end
58
+
59
+ describe 'put_attributes' do
60
+ it 'should update the specified domain' do
61
+ @db_mock.should_receive(:put_attributes).with('domain1', 'item1', { 'key' => 'value' }, {}).and_return(@response_stub)
62
+
63
+ @db.put_attributes('domain1', 'item1', { 'key' => 'value' }, {}).body['RequestId'].should == 'rid'
64
+ end
65
+ end
66
+
67
+ describe 'select' do
68
+ it 'should return query items' do
69
+ @db_mock.should_receive(:select).with('item1', { "ConsistentRead" => true, "NextToken" => nil } ).and_return(@response_stub)
70
+
71
+ @db.select('item1').should == { 'item1' => { 'key' => ['value'] } }
72
+ end
73
+
74
+ it 'should return multiple chunks of query items' do
75
+ @db_mock.should_receive(:select).with('item1', { "ConsistentRead" => true, "NextToken" => nil } ).and_return(@multi_response_stub)
76
+ @db_mock.should_receive(:select).with('item1', { "ConsistentRead" => true, "NextToken" => 'Chunk2' } ).and_return(@response_stub)
77
+
78
+ @db.select('item1').should == { 'item1' => { 'key' => ['value'] }, 'item1-2' => { 'key' => ['value'] } }
79
+ end
80
+ end
81
+
82
+ describe 'delete' do
83
+ it 'should delete the attributes identified by domain and key' do
84
+ @db_mock.should_receive(:delete_attributes).with('domain1', 'item1').and_return(@response_stub)
85
+
86
+ @db.delete('domain1', 'item1').body['RequestId'].should == 'rid'
87
+ end
88
+ end
89
+ end