remy 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/spec/remy_spec.rb ADDED
@@ -0,0 +1,330 @@
1
+ require 'spec_helper'
2
+
3
+ describe Remy do
4
+ describe '.configuration' do
5
+ describe 'with no yml files' do
6
+ it 'should return an empty mash' do
7
+ Remy.configuration.should == Hashie::Mash.new
8
+ end
9
+ end
10
+
11
+ describe "yml files" do
12
+ it 'should combine multiple yaml files into a mash' do
13
+ Remy.configure { |config| config.yml_files = ['fixtures/foo.yml', 'fixtures/bar.yml'].map { |f| File.join(File.dirname(__FILE__), f) } }
14
+ subject.configuration.yml_files.should == ['fixtures/foo.yml', 'fixtures/bar.yml'].map { |f| File.join(File.dirname(__FILE__), f) }
15
+ subject.configuration.blah.should == 'bar' # From foo.yml
16
+ subject.configuration.baz.should == 'baz' # From bar.yml
17
+ subject.configuration.colors.to_hash.symbolize_keys.should == {:blue => 'blue', :green => 'green', :red => 'red'}
18
+ end
19
+
20
+ it 'should return an empty array if there are no yml files' do
21
+ Remy.configure {}
22
+ subject.configuration.yml_files.should == []
23
+ end
24
+
25
+ it 'should not raise an error if there is a file does does not exist' do
26
+ expect do
27
+ Remy.configure { |config| config.yml_files = ['does_not_exist.yml'] }
28
+ end.should_not raise_error
29
+ end
30
+ end
31
+
32
+ describe "cookbooks path" do
33
+ it "should work if a single cookbook path is specified" do
34
+ Remy.configure { |config| config.cookbook_path = 'cookbooks' }
35
+ subject.configuration.cookbook_path.should == ['cookbooks']
36
+ end
37
+
38
+ it "should work if multiple cookbook paths are specified" do
39
+ Remy.configure { |config| config.cookbook_path = ['cookbooks1', 'cookbooks2'] }
40
+ subject.configuration.cookbook_path.should == ['cookbooks1', 'cookbooks2']
41
+ end
42
+
43
+ it "should return an empty array if no cookbook paths are specified" do
44
+ Remy.configure {}
45
+ subject.configuration.cookbook_path.should == []
46
+ end
47
+ end
48
+
49
+ describe "specs path" do
50
+ it "should work if a single spec path is specified" do
51
+ Remy.configure { |config| config.spec_path = 'specs' }
52
+ subject.configuration.spec_path.should == ['specs']
53
+ end
54
+
55
+ it "should work if multiple spec paths are specified" do
56
+ Remy.configure { |config| config.spec_path = ['specs1', 'specs2'] }
57
+ subject.configuration.spec_path.should == ['specs1', 'specs2']
58
+ end
59
+
60
+ it "should return an empty array if no spec paths are specified" do
61
+ Remy.configure {}
62
+ subject.configuration.spec_path.should == []
63
+ end
64
+ end
65
+
66
+ describe "roles path" do
67
+ it "should work if a single file is specified" do
68
+ Remy.configure { |config| config.roles_path = 'roles' }
69
+ subject.configuration.roles_path.should == ['roles']
70
+ end
71
+
72
+ it "should work if multiple files are specified" do
73
+ Remy.configure { |config| config.roles_path = ['roles1', 'roles2'] }
74
+ subject.configuration.roles_path.should == ['roles1', 'roles2']
75
+ end
76
+
77
+ it "should return an empty array if no roles paths are specified" do
78
+ Remy.configure {}
79
+ subject.configuration.roles_path.should == []
80
+ end
81
+ end
82
+
83
+ describe "node attributes" do
84
+ it "should merge in the other node attributes from the hash" do
85
+ Remy.configure { |config| config.node_attributes = {:another_node_attribute => 'red'} }
86
+ subject.configuration.another_node_attribute.should == 'red'
87
+ end
88
+
89
+ it "should not blow up if there no node attributes are specified" do
90
+ lambda { Remy.configure {} }.should_not raise_error
91
+ end
92
+ end
93
+
94
+ describe "#remote_chef_dir" do
95
+ it "should default to /var/chef if no option is given" do
96
+ subject.configuration.remote_chef_dir.should == '/var/chef'
97
+ end
98
+
99
+ it "should be able to be overriden" do
100
+ Remy.configure { |config| config.remote_chef_dir = '/foo/shef' }
101
+ subject.configuration.remote_chef_dir.should == '/foo/shef'
102
+ end
103
+ end
104
+ end
105
+
106
+ describe '.to_json' do
107
+ it 'should create the expected JSON' do
108
+ Remy.configure {}
109
+ lambda do
110
+ JSON.parse(subject.to_json)
111
+ end.should_not raise_error
112
+ end
113
+ end
114
+
115
+ context 'with a configuration' do
116
+ before do
117
+ Remy.configure do |config|
118
+ config.yml_files = ['fixtures/chef.yml'].map { |f| File.join(File.dirname(__FILE__), f) }
119
+ end
120
+ end
121
+
122
+ describe '.servers' do
123
+ it 'returns all servers' do
124
+ Remy.servers.size.should == 3
125
+ Remy.servers['db.sharespost.com'].color.should == 'yellow'
126
+ end
127
+ it 'should return servers that match the criteria (using standard Enumerable methods)' do
128
+ Remy.servers.select { |(k, v)| v.rails_env == 'demo' }.map(&:first).should == ['web.sharespost.com', 'demo.sharespost.com']
129
+ end
130
+ end
131
+
132
+ describe '.find_servers' do
133
+ it 'should return servers that match the criteria' do
134
+ Remy.find_servers(:rails_env => 'demo').keys.should == ['web.sharespost.com', 'demo.sharespost.com']
135
+ end
136
+
137
+ it 'should return all servers if there are no criteria' do
138
+ Remy.find_servers.keys.should == ['db.sharespost.com', 'web.sharespost.com', 'demo.sharespost.com']
139
+ end
140
+
141
+ it 'should return servers that match the criteria (with multiple criteria)' do
142
+ Remy.find_servers(:rails_env => 'demo', :color => 'blue').keys.should == ['web.sharespost.com']
143
+ end
144
+
145
+ it "should return nil if there are no servers specified in the yaml file" do
146
+ Remy.configure { |config| config.yml_files = File.join(File.dirname(__FILE__), 'fixtures/hello_world_chef.yml') }
147
+ Remy.find_servers(:rails_env => 'demo').should be_nil
148
+ end
149
+ end
150
+
151
+ describe '.find_server' do
152
+ it 'should return the first server that matchs the criteria' do
153
+ Remy.find_server(:rails_env => 'demo').keys.should == ['web.sharespost.com']
154
+ end
155
+
156
+ it 'should return nil if there are no servers specifie in the yml files' do
157
+ Remy.configure { |config| config.yml_files = File.join(File.dirname(__FILE__), 'fixtures/hello_world_chef.yml') }
158
+ Remy.find_server(:rails_env => 'demo').should be_nil
159
+ end
160
+ end
161
+
162
+ describe '.find_server_config' do
163
+ it 'should return the first server that matchs the criteria' do
164
+ Remy.find_server_config(:rails_env => 'demo').to_hash.should == {"color"=>"blue", "recipes"=>["recipe[hello_world]"], "rails_env"=>"demo", "ip_address"=> IP_ADDRESS}
165
+ end
166
+
167
+ it 'should return nil if no server info is found' do
168
+ Remy.find_server_config(:rails_env => 'foo').should be_nil
169
+ end
170
+
171
+ it 'should return nil if there are no servers in the yml files' do
172
+ Remy.configure { |config| config.yml_files = File.join(File.dirname(__FILE__), 'fixtures/hello_world_chef.yml') }
173
+ Remy.find_server_config(:rails_env => 'foo').should be_nil
174
+ end
175
+ end
176
+
177
+ describe '.find_server_config_by_name' do
178
+ it 'should return the server that matches the name' do
179
+ Remy.find_server_config_by_name('db.sharespost.com').to_hash.should == {"encoding"=>"utf8", "adapter"=>"mysql2", "color"=>"yellow", "rails_env"=>"production", "ip_address"=>"51.51.51.51"}
180
+ end
181
+
182
+ it 'should return nil if theres no server that matches the name' do
183
+ Remy.find_server_config_by_name('db.asdfjkll.com').should be_nil
184
+ end
185
+
186
+ it 'should return nil (and not blow up) if there are no servers in the yml files' do
187
+ Remy.configure { |config| config.yml_files = File.join(File.dirname(__FILE__), 'fixtures/hello_world_chef.yml') }
188
+ Remy.find_server_config_by_name('db.asdfjkll.com').should be_nil
189
+ end
190
+
191
+ it 'should return nil (and not blow up) if there is no Remy configuration' do
192
+ Remy.instance_variable_set('@configuration', nil)
193
+ Remy.find_server_config_by_name('db.asdfjkll.com').should be_nil
194
+ end
195
+ end
196
+
197
+ describe '.cloud_configuration' do
198
+ it 'should return nil if it has not been specified in the yml files' do
199
+ Remy.configure { |config| config.yml_files = File.join(File.dirname(__FILE__), 'fixtures/hello_world_chef.yml') }
200
+ Remy.cloud_configuration.should be_nil
201
+ end
202
+
203
+ it 'should return the cloud configuration options if present in the yml files' do
204
+ Remy.cloud_configuration.should == Hashie::Mash.new(
205
+ :cloud_api_key => 'abcdefg12345',
206
+ :cloud_provider => 'Rackspace',
207
+ :cloud_username => 'sharespost',
208
+ :flavor_id => 4,
209
+ :image_id => 49,
210
+ :server_name => 'new-server.somedomain.com')
211
+
212
+ end
213
+
214
+ it 'should return nil if there is currently no Remy configuration' do
215
+ Remy.instance_variable_set('@configuration', nil)
216
+ Remy.cloud_configuration.should be_nil
217
+ end
218
+ end
219
+
220
+ describe '.bootstrap' do
221
+ it 'should return nil if it has not been specified in the yml files' do
222
+ Remy.configure { |config| config.yml_files = File.join(File.dirname(__FILE__), 'fixtures/hello_world_chef.yml') }
223
+ Remy.bootstrap.should be_nil
224
+ end
225
+
226
+ it 'should return the bootstrap options if present in the yml files' do
227
+ Remy.bootstrap.should == Hashie::Mash.new(
228
+ :ruby_version => '1.9.2',
229
+ :gems => {
230
+ :chef => '0.10.4',
231
+ :rspec => '2.7.0',
232
+ :bundler => '1.0.21'
233
+ })
234
+ end
235
+
236
+ it 'should return nil if there is currently no Remy configuration' do
237
+ Remy.instance_variable_set('@configuration', nil)
238
+ Remy.bootstrap.should be_nil
239
+ end
240
+ end
241
+ end
242
+
243
+ describe 'support for the rake tasks' do
244
+ before do
245
+ Remy.configure do |config|
246
+ config.yml_files = ['fixtures/foo.yml', 'fixtures/bar.yml', 'fixtures/chef.yml'].map { |f| File.join(File.dirname(__FILE__), f) }
247
+ end
248
+ end
249
+
250
+ describe '.convert_properties_to_hash' do
251
+ it 'should convert properties to a hash' do
252
+ Remy.send(:convert_properties_to_hash, ' foo:bar blah:blech').should == {:foo => 'bar', :blah => 'blech'}
253
+ end
254
+
255
+ it 'should convert a blank string to nil' do
256
+ Remy.send(:convert_properties_to_hash, ' ').should be_nil
257
+ end
258
+
259
+ it 'should return nil if the string is not in property format' do
260
+ Remy.send(:convert_properties_to_hash, 'demo.sharespost.com').should be_nil
261
+ end
262
+ end
263
+
264
+ describe '.determine_ip_addresses_for_remy_run' do
265
+ context 'top level ip address is present in the yml files' do
266
+ before do
267
+ Remy.configure { |config| config.yml_files = File.join(File.dirname(__FILE__), 'fixtures/hello_world_chef.yml') }
268
+ end
269
+ it 'should return the ip address in the yml file if no ip address is given and an ip is present in the yml files' do
270
+ Remy.send(:determine_ip_addresses_for_remy_run, '').should == ['50.57.162.242']
271
+ end
272
+ end
273
+
274
+ context 'no top level ip address is present in the yml files' do
275
+ before do
276
+ Remy.configure { |config| config.yml_files = File.join(File.dirname(__FILE__), 'fixtures/foo.yml') }
277
+ end
278
+
279
+ it 'should return nothing if no ip address is given and no top-level ip address is in the yml files' do
280
+ Remy.send(:determine_ip_addresses_for_remy_run, '').should == []
281
+ end
282
+
283
+ it 'should return the ip address if an ip address is given and no top-level ip address is in the yml files' do
284
+ Remy.send(:determine_ip_addresses_for_remy_run, '1.2.3.4').should == ['1.2.3.4']
285
+ end
286
+ end
287
+
288
+ context ':servers section present in the yml files' do
289
+ before do
290
+ Remy.configure { |config| config.yml_files = File.join(File.dirname(__FILE__), 'fixtures/chef.yml') }
291
+ end
292
+
293
+ it 'should return an ip address if an ip address is given as property value (this IP address is not in the :servers section of the yml files)' do
294
+ Remy.send(:determine_ip_addresses_for_remy_run, 'ip_address:1.2.3.4').should == ['1.2.3.4']
295
+ end
296
+
297
+ it 'should return the ip address if the ip address was found in the :servers section of the yml files' do
298
+ Remy.send(:determine_ip_addresses_for_remy_run, 'ip_address:52.52.52.52').should == ['52.52.52.52']
299
+ end
300
+
301
+ it 'should return the IP address - the IP address is specified, but is not found in the servers section in the yml files' do
302
+ Remy.send(:determine_ip_addresses_for_remy_run, '1.2.3.4').should == ['1.2.3.4']
303
+ end
304
+
305
+ it 'should return the IP address - the IP address is specified, and is found in the servers section in the yml files' do
306
+ Remy.send(:determine_ip_addresses_for_remy_run, '52.52.52.52').should == ['52.52.52.52']
307
+ end
308
+
309
+ it 'should be able to find servers by name from the :servers section of the yml file' do
310
+ Remy.send(:determine_ip_addresses_for_remy_run, 'demo.sharespost.com').should == ['52.52.52.52']
311
+ end
312
+
313
+ it 'should be able to find servers by multiple names' do
314
+ Remy.send(:determine_ip_addresses_for_remy_run, ' demo.sharespost.com db.sharespost.com ').should == ['52.52.52.52', '51.51.51.51']
315
+ end
316
+
317
+ it 'should be able to find servers by multiple names and ip addresses' do
318
+ Remy.send(:determine_ip_addresses_for_remy_run, ' demo.sharespost.com 51.51.51.51').should == ['52.52.52.52', '51.51.51.51']
319
+ end
320
+
321
+ it 'should be able to find all of the servers from the yml files that match certain attributes' do
322
+ Remy.send(:determine_ip_addresses_for_remy_run, 'rails_env:demo').should == ['50.57.162.242', '52.52.52.52']
323
+ Remy.send(:determine_ip_addresses_for_remy_run, 'rails_env:demo color:green').should == ['52.52.52.52']
324
+ Remy.send(:determine_ip_addresses_for_remy_run, 'rails_env:demo color:yellow').should == []
325
+ end
326
+ end
327
+ end
328
+ end
329
+ end
330
+
@@ -0,0 +1,16 @@
1
+ ENV["RAILS_ENV"] ||= 'test'
2
+
3
+ require 'rubygems'
4
+ require 'bundler/setup'
5
+ require 'active_support'
6
+ require 'mocha'
7
+ require 'json'
8
+ require 'remy'
9
+
10
+ Dir[File.join(File.dirname(__FILE__), 'spec', 'support', '**' '*.rb')].each { |f| require f }
11
+
12
+ RSpec.configure do |config|
13
+ config.mock_with :mocha
14
+ end
15
+
16
+ IP_ADDRESS = '50.57.162.242'
metadata ADDED
@@ -0,0 +1,230 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: remy
3
+ version: !ruby/object:Gem::Version
4
+ hash: 29
5
+ prerelease:
6
+ segments:
7
+ - 0
8
+ - 0
9
+ - 1
10
+ version: 0.0.1
11
+ platform: ruby
12
+ authors:
13
+ - Greg Woodward & Ryan Dy
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2011-12-04 00:00:00 Z
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: bourne
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ none: false
25
+ requirements:
26
+ - - ">="
27
+ - !ruby/object:Gem::Version
28
+ hash: 3
29
+ segments:
30
+ - 0
31
+ version: "0"
32
+ type: :development
33
+ version_requirements: *id001
34
+ - !ruby/object:Gem::Dependency
35
+ name: mocha
36
+ prerelease: false
37
+ requirement: &id002 !ruby/object:Gem::Requirement
38
+ none: false
39
+ requirements:
40
+ - - ">="
41
+ - !ruby/object:Gem::Version
42
+ hash: 3
43
+ segments:
44
+ - 0
45
+ version: "0"
46
+ type: :development
47
+ version_requirements: *id002
48
+ - !ruby/object:Gem::Dependency
49
+ name: i18n
50
+ prerelease: false
51
+ requirement: &id003 !ruby/object:Gem::Requirement
52
+ none: false
53
+ requirements:
54
+ - - ">="
55
+ - !ruby/object:Gem::Version
56
+ hash: 3
57
+ segments:
58
+ - 0
59
+ version: "0"
60
+ type: :development
61
+ version_requirements: *id003
62
+ - !ruby/object:Gem::Dependency
63
+ name: json
64
+ prerelease: false
65
+ requirement: &id004 !ruby/object:Gem::Requirement
66
+ none: false
67
+ requirements:
68
+ - - ">="
69
+ - !ruby/object:Gem::Version
70
+ hash: 3
71
+ segments:
72
+ - 0
73
+ version: "0"
74
+ type: :development
75
+ version_requirements: *id004
76
+ - !ruby/object:Gem::Dependency
77
+ name: rspec
78
+ prerelease: false
79
+ requirement: &id005 !ruby/object:Gem::Requirement
80
+ none: false
81
+ requirements:
82
+ - - ~>
83
+ - !ruby/object:Gem::Version
84
+ hash: 19
85
+ segments:
86
+ - 2
87
+ - 7
88
+ - 0
89
+ version: 2.7.0
90
+ type: :development
91
+ version_requirements: *id005
92
+ - !ruby/object:Gem::Dependency
93
+ name: activesupport
94
+ prerelease: false
95
+ requirement: &id006 !ruby/object:Gem::Requirement
96
+ none: false
97
+ requirements:
98
+ - - ">="
99
+ - !ruby/object:Gem::Version
100
+ hash: 7
101
+ segments:
102
+ - 2
103
+ version: "2"
104
+ type: :runtime
105
+ version_requirements: *id006
106
+ - !ruby/object:Gem::Dependency
107
+ name: chef
108
+ prerelease: false
109
+ requirement: &id007 !ruby/object:Gem::Requirement
110
+ none: false
111
+ requirements:
112
+ - - ">="
113
+ - !ruby/object:Gem::Version
114
+ hash: 3
115
+ segments:
116
+ - 0
117
+ version: "0"
118
+ type: :runtime
119
+ version_requirements: *id007
120
+ - !ruby/object:Gem::Dependency
121
+ name: fog
122
+ prerelease: false
123
+ requirement: &id008 !ruby/object:Gem::Requirement
124
+ none: false
125
+ requirements:
126
+ - - ">="
127
+ - !ruby/object:Gem::Version
128
+ hash: 3
129
+ segments:
130
+ - 0
131
+ version: "0"
132
+ type: :runtime
133
+ version_requirements: *id008
134
+ - !ruby/object:Gem::Dependency
135
+ name: hashie
136
+ prerelease: false
137
+ requirement: &id009 !ruby/object:Gem::Requirement
138
+ none: false
139
+ requirements:
140
+ - - ">="
141
+ - !ruby/object:Gem::Version
142
+ hash: 3
143
+ segments:
144
+ - 0
145
+ version: "0"
146
+ type: :runtime
147
+ version_requirements: *id009
148
+ description: Easy chef deployment
149
+ email:
150
+ - pair+gwoodward+rdy@pivotallabs.com
151
+ executables: []
152
+
153
+ extensions: []
154
+
155
+ extra_rdoc_files: []
156
+
157
+ files:
158
+ - .gitignore
159
+ - .rspec
160
+ - .rvmrc
161
+ - Gemfile
162
+ - MIT-LICENSE
163
+ - README.md
164
+ - Rakefile
165
+ - chef/cookbooks/hello_world/recipes/default.rb
166
+ - chef/cookbooks/hello_world/templates/default/hello_world.txt.erb
167
+ - chef/roles/test_role.rb
168
+ - chef/roles/test_role2.json
169
+ - chef/spec/hello_world/default_spec.rb
170
+ - lib/remy.rb
171
+ - lib/remy/bootstrap.rb
172
+ - lib/remy/chef.rb
173
+ - lib/remy/remy.rb
174
+ - lib/remy/server.rb
175
+ - lib/remy/shell.rb
176
+ - lib/remy/version.rb
177
+ - lib/tasks/remy.rake
178
+ - remy.gemspec
179
+ - spec/fixtures/bar.yml
180
+ - spec/fixtures/chef.yml
181
+ - spec/fixtures/foo.yml
182
+ - spec/fixtures/hello_world_chef.yml
183
+ - spec/remy/bootstrap_spec.rb
184
+ - spec/remy/chef_spec.rb
185
+ - spec/remy/integration/chef_spec.rb
186
+ - spec/remy_spec.rb
187
+ - spec/spec_helper.rb
188
+ homepage: http://sharespost.com
189
+ licenses: []
190
+
191
+ post_install_message:
192
+ rdoc_options: []
193
+
194
+ require_paths:
195
+ - lib
196
+ required_ruby_version: !ruby/object:Gem::Requirement
197
+ none: false
198
+ requirements:
199
+ - - ">="
200
+ - !ruby/object:Gem::Version
201
+ hash: 3
202
+ segments:
203
+ - 0
204
+ version: "0"
205
+ required_rubygems_version: !ruby/object:Gem::Requirement
206
+ none: false
207
+ requirements:
208
+ - - ">="
209
+ - !ruby/object:Gem::Version
210
+ hash: 3
211
+ segments:
212
+ - 0
213
+ version: "0"
214
+ requirements: []
215
+
216
+ rubyforge_project: remy
217
+ rubygems_version: 1.8.10
218
+ signing_key:
219
+ specification_version: 3
220
+ summary: Remy gem
221
+ test_files:
222
+ - spec/fixtures/bar.yml
223
+ - spec/fixtures/chef.yml
224
+ - spec/fixtures/foo.yml
225
+ - spec/fixtures/hello_world_chef.yml
226
+ - spec/remy/bootstrap_spec.rb
227
+ - spec/remy/chef_spec.rb
228
+ - spec/remy/integration/chef_spec.rb
229
+ - spec/remy_spec.rb
230
+ - spec/spec_helper.rb