boxgrinder-build 0.9.3 → 0.9.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (41) hide show
  1. data/CHANGELOG +12 -0
  2. data/Manifest +6 -5
  3. data/README.md +1 -1
  4. data/Rakefile +13 -20
  5. data/boxgrinder-build.gemspec +7 -10
  6. data/lib/boxgrinder-build/helpers/aws-helper.rb +81 -0
  7. data/lib/boxgrinder-build/helpers/ec2-helper.rb +182 -0
  8. data/lib/boxgrinder-build/helpers/guestfs-helper.rb +5 -1
  9. data/lib/boxgrinder-build/helpers/s3-helper.rb +124 -0
  10. data/lib/boxgrinder-build/plugins/delivery/ebs/ebs-plugin.rb +95 -299
  11. data/lib/boxgrinder-build/plugins/delivery/elastichosts/elastichosts-plugin.rb +2 -1
  12. data/lib/boxgrinder-build/plugins/delivery/s3/s3-plugin.rb +67 -133
  13. data/lib/boxgrinder-build/plugins/os/rpm-based/rpm-based-os-plugin.rb +15 -14
  14. data/rubygem-boxgrinder-build.spec +23 -28
  15. data/spec/appliance-spec.rb +1 -0
  16. data/spec/helpers/augeas-helper-spec.rb +1 -0
  17. data/spec/helpers/ec2-helper-spec.rb +260 -0
  18. data/spec/helpers/guestfs-helper-spec.rb +34 -7
  19. data/spec/helpers/image-helper-spec.rb +1 -0
  20. data/spec/helpers/linux-helper-spec.rb +1 -0
  21. data/spec/helpers/package-helper-spec.rb +1 -0
  22. data/spec/helpers/plugin-helper-spec.rb +1 -0
  23. data/spec/helpers/s3-helper-spec.rb +168 -0
  24. data/spec/managers/plugin-manager-spec.rb +1 -0
  25. data/spec/plugins/base-plugin-spec.rb +1 -1
  26. data/spec/plugins/delivery/ebs/ebs-plugin-spec.rb +115 -204
  27. data/spec/plugins/delivery/elastichosts/elastichosts-plugin-spec.rb +5 -4
  28. data/spec/plugins/delivery/local/local-plugin-spec.rb +1 -0
  29. data/spec/plugins/delivery/s3/s3-plugin-spec.rb +143 -134
  30. data/spec/plugins/delivery/sftp/sftp-plugin-spec.rb +1 -0
  31. data/spec/plugins/os/centos/centos-plugin-spec.rb +1 -0
  32. data/spec/plugins/os/fedora/fedora-plugin-spec.rb +1 -0
  33. data/spec/plugins/os/rhel/rhel-plugin-spec.rb +1 -0
  34. data/spec/plugins/os/rpm-based/kickstart-spec.rb +5 -1
  35. data/spec/plugins/os/rpm-based/rpm-based-os-plugin-spec.rb +9 -7
  36. data/spec/plugins/os/rpm-based/rpm-dependency-validator-spec.rb +1 -0
  37. data/spec/plugins/os/sl/sl-plugin-spec.rb +1 -0
  38. data/spec/plugins/platform/ec2/ec2-plugin-spec.rb +1 -0
  39. data/spec/plugins/platform/virtualbox/virtualbox-plugin-spec.rb +1 -0
  40. data/spec/plugins/platform/vmware/vmware-plugin-spec.rb +1 -0
  41. metadata +17 -23
@@ -17,6 +17,7 @@
17
17
  # 02110-1301 USA, or see the FSF site: http://www.fsf.org.
18
18
 
19
19
  require 'rubygems'
20
+ require 'rspec'
20
21
  require 'boxgrinder-build/appliance'
21
22
  require 'ostruct'
22
23
  require 'logger'
@@ -17,6 +17,7 @@
17
17
  # 02110-1301 USA, or see the FSF site: http://www.fsf.org.
18
18
 
19
19
  require 'rubygems'
20
+ require 'rspec'
20
21
  require 'boxgrinder-build/helpers/augeas-helper'
21
22
 
22
23
  module BoxGrinder
@@ -0,0 +1,260 @@
1
+ #
2
+ # Copyright 2010 Red Hat, Inc.
3
+ #
4
+ # This is free software; you can redistribute it and/or modify it
5
+ # under the terms of the GNU Lesser General Public License as
6
+ # published by the Free Software Foundation; either version 3 of
7
+ # the License, or (at your option) any later version.
8
+ #
9
+ # This software is distributed in the hope that it will be useful,
10
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12
+ # Lesser General Public License for more details.
13
+ #
14
+ # You should have received a copy of the GNU Lesser General Public
15
+ # License along with this software; if not, write to the Free
16
+ # Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
17
+ # 02110-1301 USA, or see the FSF site: http://www.fsf.org.
18
+
19
+ require 'rspec'
20
+ require 'boxgrinder-build/helpers/ec2-helper'
21
+ require 'aws-sdk'
22
+
23
+ module BoxGrinder
24
+ describe EC2Helper do
25
+
26
+ FAST_POLL = 0.1
27
+ FAST_TO = 1
28
+
29
+ before(:each) do
30
+ AWS.stub!
31
+ AWS.config({:access_key_id => '', :secret_access_key => ''})
32
+ @ec2 = AWS::EC2.new()
33
+ @ec2helper = EC2Helper.new(@ec2)
34
+ @ami = mock(AWS::EC2::Image)
35
+ @instance = mock(AWS::EC2::Instance)
36
+ @snapshot = mock(AWS::EC2::Snapshot)
37
+ @volume = mock(AWS::EC2::Volume)
38
+ end
39
+
40
+ describe ".wait_for_image_state" do
41
+ before(:each) do
42
+ @ami.stub!(:state).and_return(:ham, :biscuit, :available)
43
+ end
44
+
45
+ it "should wait until the image state is :available before returning" do
46
+ @ami.stub(:exists?).and_return(true)
47
+
48
+ @ami.should_receive(:exists?).once.and_return(true)
49
+ @ami.should_receive(:state).exactly(3).times
50
+ @ec2helper.wait_for_image_state(:available, @ami, :frequency => FAST_POLL, :timeout => FAST_TO)
51
+ end
52
+
53
+ it "should wait until the image exists before sampling for state" do
54
+ @ami.stub(:exists?).and_return(false, false, true)
55
+
56
+ @ami.should_receive(:exists?).once.exactly(3).times
57
+ @ami.should_receive(:state).exactly(3).times
58
+ @ec2helper.wait_for_image_state(:available, @ami, :frequency => FAST_POLL, :timeout => FAST_TO)
59
+ end
60
+ end
61
+
62
+ describe ".wait_for_image_death" do
63
+ it "should wait until image no longer exists" do
64
+ @ami.stub!(:exists?).and_return(true, true, false)
65
+
66
+ @ami.should_receive(:exists?).exactly(3).times
67
+ @ec2helper.wait_for_image_death(@ami, :frequency => FAST_POLL, :timeout => FAST_TO)
68
+ end
69
+
70
+ it "should return normally if InvalidImageID::NotFound error occurs" do
71
+ @ami.stub!(:exists?).and_raise(aws_sdk_exception_hack(AWS::EC2::Errors::InvalidImageID::NotFound))
72
+
73
+ @ami.should_receive(:exists?).once
74
+ @ec2helper.wait_for_image_death(@ami, :frequency => FAST_POLL, :timeout => FAST_TO)
75
+ end
76
+ end
77
+
78
+ describe ".wait_for_instance_status" do
79
+ it "should wait until the instance status is :available before returning" do
80
+ @instance.stub!(:status).and_return(:bacon, :buttie, :available)
81
+
82
+ @instance.should_receive(:status).exactly(3).times
83
+ @ec2helper.wait_for_instance_status(:available, @instance, :frequency => FAST_POLL, :timeout => FAST_TO)
84
+ end
85
+ end
86
+
87
+ describe ".wait_for_instance_death" do
88
+ it "should wait until instance status is :terminated before returning" do
89
+ @instance.stub!(:exists?).and_return(true)
90
+ @instance.stub!(:status).and_return(:stottie, :bread, :terminated)
91
+
92
+ @instance.should_receive(:status).exactly(3).times
93
+ @ec2helper.wait_for_instance_death(@instance, :frequency => FAST_POLL, :timeout => FAST_TO)
94
+ end
95
+
96
+ it "should return normally if InvalidInstance::NotFound error occurs" do
97
+ @instance.stub!(:exists?).and_return(true)
98
+ @instance.stub!(:status).and_raise(aws_sdk_exception_hack(AWS::EC2::Errors::InvalidInstanceID::NotFound))
99
+
100
+ @instance.should_receive(:exists?).once
101
+ @instance.should_receive(:status).once
102
+ @ec2helper.wait_for_instance_death(@instance, :frequency => FAST_POLL, :timeout => FAST_TO)
103
+ end
104
+
105
+ it "should return immediately if the instance does not appear to exist at all" do
106
+ @instance.stub!(:exists?).and_return(false)
107
+
108
+ @instance.should_receive(:exists?).once
109
+ @ec2helper.wait_for_instance_death(@instance, :frequency => FAST_POLL, :timeout => FAST_TO)
110
+ end
111
+ end
112
+
113
+ describe ".wait_for_snapshot_status" do
114
+ it "should wait until the instance status is :completed before returning" do
115
+ @snapshot.stub!(:status).and_return(:crumpet, :tea, :completed, :cricket)
116
+ @snapshot.stub!(:progress).and_return(99)
117
+
118
+ @snapshot.should_receive(:status).exactly(3).times
119
+ @ec2helper.wait_for_snapshot_status(:completed, @snapshot, :frequency => FAST_POLL, :timeout => FAST_TO)
120
+ end
121
+ end
122
+
123
+ describe ".wait_for_volume_status" do
124
+ it "should wait until the instance status is :available before returning" do
125
+ @volume.stub!(:status).and_return(:edictum, :imperatoris, :available)
126
+
127
+ @volume.should_receive(:status).exactly(3).times
128
+ @ec2helper.wait_for_volume_status(:available, @volume, :frequency => FAST_POLL, :timeout => FAST_TO)
129
+ end
130
+ end
131
+
132
+ describe ".current_availability_zone" do
133
+ it "should return the current availability zone" do
134
+ EC2Helper.stub!(:get_meta_data).and_return('protuberant-potato-1a')
135
+
136
+ EC2Helper.should_receive(:get_meta_data).
137
+ with('/latest/meta-data/placement/availability-zone/').
138
+ and_return('protuberant-potato-1a')
139
+ EC2Helper.current_availability_zone.should == 'protuberant-potato-1a'
140
+ end
141
+ end
142
+
143
+ describe ".current_instance_id" do
144
+ it "should return the current instance id" do
145
+ EC2Helper.stub!(:get_meta_data).and_return('voluminous-verbiage')
146
+
147
+ EC2Helper.should_receive(:get_meta_data).
148
+ with('/latest/meta-data/instance-id').
149
+ and_return('voluminous-verbiage')
150
+ EC2Helper.current_instance_id.should == 'voluminous-verbiage'
151
+ end
152
+ end
153
+
154
+ describe ".availability_zone_to_region" do
155
+ it "should convert an availability zone to a region" do
156
+ EC2Helper.availability_zone_to_region('protuberant-potato-1a').
157
+ should == 'protuberant-potato-1'
158
+ end
159
+ end
160
+
161
+ describe ".ami_by_name" do
162
+ before(:each) do
163
+ @ec2.stub!(:images)
164
+ end
165
+
166
+ it "should query for an image filtered by name" do
167
+ @ec2.should_receive(:images)
168
+ @ec2.images.should_receive(:with_owner).with('987654321')
169
+ @ec2.images.should_receive(:filter).with('name','inauspicious-interlocution').and_return([@ami])
170
+
171
+ @ec2helper.ami_by_name('inauspicious-interlocution', '987654321').should == @ami
172
+ end
173
+
174
+ it "should return nil if no results are returned" do
175
+ @ec2.should_receive(:images)
176
+ @ec2.images.should_receive(:with_owner).with('987654321')
177
+ @ec2.images.should_receive(:filter).with('name','inauspicious-interlocution').and_return([])
178
+
179
+ @ec2helper.ami_by_name('inauspicious-interlocution', '987654321').should == nil
180
+ end
181
+ end
182
+
183
+ describe ".snapshot_by_id" do
184
+ before(:each) do
185
+ snap_mock = mock('snapshots')
186
+ @ec2.stub!(:snapshots).and_return(snap_mock)
187
+ end
188
+
189
+ it "should query for a snapshot by snapshot-id" do
190
+
191
+ @ec2.snapshots.
192
+ should_receive(:filter).
193
+ with('snapshot-id','count-bezukhov').
194
+ and_return([@snapshot])
195
+
196
+ @ec2helper.snapshot_by_id('count-bezukhov').should == @snapshot
197
+
198
+ end
199
+
200
+ it "should return nil if no results are returned" do
201
+ @ec2.snapshots.
202
+ should_receive(:filter).
203
+ with('snapshot-id','count-bezukhov').
204
+ and_return([])
205
+
206
+ @ec2helper.snapshot_by_id('count-bezukhov').should == nil
207
+ end
208
+
209
+ end
210
+
211
+ describe ".live_instances" do
212
+ before(:each) do
213
+ instances_mock = mock('instances')
214
+ @ec2.stub!(:instances).and_return(instances_mock)
215
+
216
+ @instance_1 = mock(AWS::EC2::Instance)
217
+ @instance_2 = mock(AWS::EC2::Instance)
218
+ @instance_3 = mock(AWS::EC2::Instance)
219
+
220
+ @instance_1.stub!(:status).and_return(:available)
221
+ @instance_2.stub!(:status).and_return(:available)
222
+ @ami.stub!(:id).and_return('war-and-peace')
223
+ end
224
+
225
+ it "should query for live instances by ami" do
226
+ @ec2.instances.
227
+ should_receive(:filter).
228
+ with('image-id','war-and-peace').
229
+ and_return([@instance_1, @instance_2])
230
+
231
+ @ec2helper.live_instances(@ami).should == [@instance_1, @instance_2]
232
+ end
233
+
234
+ it "should ignore any :terminated instances" do
235
+ @instance_3.stub!(:status).and_return(:terminated)
236
+
237
+ @ec2.should_receive(:instances)
238
+ @ec2.instances.should_receive(:filter).
239
+ with('image-id','war-and-peace').
240
+ and_return([@instance_3, @instance_2, @instance_1])
241
+
242
+ @ec2helper.live_instances(@ami).should == [@instance_2, @instance_1]
243
+ end
244
+
245
+ end
246
+
247
+ describe ".endpoints" do
248
+
249
+ end
250
+
251
+ # Complex auto-generated exceptions means we can't use the normal method of raising
252
+ def aws_sdk_exception_hack(klass)
253
+ mock_param = mock('fake_param')
254
+ mock_param.stub!(:status).and_return(1)
255
+ mock_param.stub!(:body).and_return('')
256
+ klass.new(mock_param, mock_param)
257
+ end
258
+
259
+ end
260
+ end
@@ -16,18 +16,22 @@
16
16
  # Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
17
17
  # 02110-1301 USA, or see the FSF site: http://www.fsf.org.
18
18
 
19
- require 'rubygems'
20
19
  require 'boxgrinder-build/helpers/guestfs-helper'
20
+ require 'rubygems'
21
+ require 'rspec'
22
+ require 'hashery/opencascade'
21
23
 
22
24
  module BoxGrinder
23
25
  describe GuestFSHelper do
24
26
  before(:each) do
27
+ ENV.delete("LIBGUESTFS_MEMSIZE")
28
+
25
29
  @log = Logger.new('/dev/null')
26
30
  @appliance_config = mock('ApplianceConfig')
27
31
  @appliance_config.stub!(:hardware).and_return(:partitions => {})
28
32
 
29
33
  @config = mock('Config')
30
- @config.stub!(:dir).and_return(:tmp => '/tmp')
34
+ @config.stub!(:dir).and_return(OpenCascade.new(:tmp => '/tmp'))
31
35
 
32
36
  @helper = GuestFSHelper.new('a/raw/disk', @appliance_config, @config, :log => @log)
33
37
  end
@@ -41,6 +45,7 @@ module BoxGrinder
41
45
  guestfs.should_receive(:set_verbose)
42
46
  guestfs.should_receive(:set_trace)
43
47
  guestfs.should_receive(:set_selinux).with(1)
48
+ guestfs.should_receive(:set_memsize).with(300)
44
49
 
45
50
  @helper.should_receive(:hw_virtualization_available?).and_return(true)
46
51
 
@@ -59,6 +64,7 @@ module BoxGrinder
59
64
  guestfs.should_receive(:set_verbose)
60
65
  guestfs.should_receive(:set_trace)
61
66
  guestfs.should_receive(:set_selinux).with(1)
67
+ guestfs.should_receive(:set_memsize).with(300)
62
68
 
63
69
  @helper.should_receive(:hw_virtualization_available?).and_return(true)
64
70
 
@@ -76,6 +82,7 @@ module BoxGrinder
76
82
  guestfs.should_receive(:set_verbose)
77
83
  guestfs.should_receive(:set_trace)
78
84
  guestfs.should_receive(:set_selinux).with(1)
85
+ guestfs.should_receive(:set_memsize).with(300)
79
86
 
80
87
  @helper.should_receive(:hw_virtualization_available?).and_return(false)
81
88
 
@@ -85,6 +92,26 @@ module BoxGrinder
85
92
 
86
93
  @helper.prepare_guestfs {}
87
94
  end
95
+
96
+ it "should prepare guestfs with custom memory settings" do
97
+ ENV['LIBGUESTFS_MEMSIZE'] = "500"
98
+
99
+ guestfs = mock('Guestfs')
100
+ @helper.instance_variable_set(:@guestfs, guestfs)
101
+
102
+ guestfs.should_receive(:set_append).with('noapic')
103
+ guestfs.should_receive(:set_verbose)
104
+ guestfs.should_receive(:set_trace)
105
+ guestfs.should_receive(:set_selinux).with(1)
106
+ guestfs.should_receive(:set_memsize).with(500)
107
+
108
+ @helper.should_receive(:hw_virtualization_available?).and_return(true)
109
+
110
+ guestfs.should_receive(:add_drive).with('a/raw/disk')
111
+ guestfs.should_receive(:set_network).with(1)
112
+
113
+ @helper.prepare_guestfs {}
114
+ end
88
115
  end
89
116
 
90
117
  describe ".initialize_guestfs" do
@@ -129,7 +156,7 @@ module BoxGrinder
129
156
  end
130
157
 
131
158
  it "should run guestfs with two partitions" do
132
- @appliance_config.stub!(:hardware).and_return(:partitions => {'/' => nil, '/home' => nil})
159
+ @appliance_config.stub!(:hardware).and_return(OpenCascade.new(:partitions => {'/' => nil, '/home' => nil}))
133
160
 
134
161
  guestfs = mock('Guestfs')
135
162
  @helper.instance_variable_set(:@guestfs, guestfs)
@@ -145,7 +172,7 @@ module BoxGrinder
145
172
  end
146
173
 
147
174
  it "should run guestfs with no partitions and don't load selinux" do
148
- @appliance_config.stub!(:hardware).and_return(:partitions => {'/' => nil, '/home' => nil})
175
+ @appliance_config.stub!(:hardware).and_return(OpenCascade.new(:partitions => {'/' => nil, '/home' => nil}))
149
176
 
150
177
  guestfs = mock('Guestfs')
151
178
  @helper.instance_variable_set(:@guestfs, guestfs)
@@ -199,7 +226,7 @@ module BoxGrinder
199
226
  it "should mount two partitions" do
200
227
  guestfs = mock('Guestfs')
201
228
 
202
- @appliance_config.stub!(:hardware).and_return(:partitions => {'/' => nil, '/home' => nil})
229
+ @appliance_config.stub!(:hardware).and_return(OpenCascade.new(:partitions => {'/' => nil, '/home' => nil}))
203
230
  guestfs.should_receive(:list_partitions).and_return(['/dev/vda1', '/dev/vda2'])
204
231
 
205
232
  @helper.should_receive(:mount_partition).with('/dev/vda1', '/', '')
@@ -212,7 +239,7 @@ module BoxGrinder
212
239
  it "should mount partitions with extended partitions" do
213
240
  guestfs = mock('Guestfs')
214
241
 
215
- @appliance_config.stub!(:hardware).and_return(:partitions => {'/' => nil, '/home' => nil, '/var/www' => nil, '/var/mock' => nil})
242
+ @appliance_config.stub!(:hardware).and_return(OpenCascade.new(:partitions => {'/' => nil, '/home' => nil, '/var/www' => nil, '/var/mock' => nil}))
216
243
  guestfs.should_receive(:list_partitions).and_return(['/dev/vda1', '/dev/vda2', '/dev/vda3', '/dev/vda4', '/dev/vda5'])
217
244
 
218
245
  @helper.should_receive(:mount_partition).with('/dev/vda1', '/', '')
@@ -370,4 +397,4 @@ module BoxGrinder
370
397
  end
371
398
  end
372
399
  end
373
- end
400
+ end
@@ -17,6 +17,7 @@
17
17
  # 02110-1301 USA, or see the FSF site: http://www.fsf.org.
18
18
 
19
19
  require 'rubygems'
20
+ require 'rspec'
20
21
  require 'boxgrinder-build/helpers/image-helper'
21
22
 
22
23
  module BoxGrinder
@@ -17,6 +17,7 @@
17
17
  # 02110-1301 USA, or see the FSF site: http://www.fsf.org.
18
18
 
19
19
  require 'rubygems'
20
+ require 'rspec'
20
21
  require 'boxgrinder-build/helpers/linux-helper'
21
22
 
22
23
  module BoxGrinder
@@ -17,6 +17,7 @@
17
17
  # 02110-1301 USA, or see the FSF site: http://www.fsf.org.
18
18
 
19
19
  require 'rubygems'
20
+ require 'rspec'
20
21
  require 'logger'
21
22
  require 'boxgrinder-build/helpers/package-helper'
22
23
 
@@ -17,6 +17,7 @@
17
17
  # 02110-1301 USA, or see the FSF site: http://www.fsf.org.
18
18
 
19
19
  require 'rubygems'
20
+ require 'rspec'
20
21
  require 'boxgrinder-core/helpers/log-helper'
21
22
  require 'boxgrinder-build/helpers/plugin-helper'
22
23
  require 'ostruct'
@@ -0,0 +1,168 @@
1
+ #
2
+ # Copyright 2010 Red Hat, Inc.
3
+ #
4
+ # This is free software; you can redistribute it and/or modify it
5
+ # under the terms of the GNU Lesser General Public License as
6
+ # published by the Free Software Foundation; either version 3 of
7
+ # the License, or (at your option) any later version.
8
+ #
9
+ # This software is distributed in the hope that it will be useful,
10
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12
+ # Lesser General Public License for more details.
13
+ #
14
+ # You should have received a copy of the GNU Lesser General Public
15
+ # License along with this software; if not, write to the Free
16
+ # Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
17
+ # 02110-1301 USA, or see the FSF site: http://www.fsf.org.
18
+
19
+ require 'rubygems'
20
+ require 'rspec'
21
+ require 'boxgrinder-build/helpers/s3-helper'
22
+ require 'aws-sdk'
23
+
24
+ module BoxGrinder
25
+ describe S3Helper do
26
+
27
+ before(:each) do
28
+ AWS.stub!
29
+ AWS.config({:access_key_id => '', :secret_access_key => ''})
30
+ @ec2 = AWS::EC2.new
31
+ @s3 = AWS::S3.new
32
+ @ec2helper = EC2Helper.new(@ec2)
33
+ @s3helper = S3Helper.new(@ec2, @s3)
34
+ @s3obj = mock(AWS::S3::S3Object)
35
+ @bucket = mock(AWS::S3::Bucket)
36
+ end
37
+
38
+ describe ".bucket" do
39
+
40
+ it "should return the existing bucket if it already exists" do
41
+ @bucket.stub!(:exists).and_return(true)
42
+ @s3.stub_chain(:buckets, :[]).and_return(@bucket)
43
+
44
+ @s3.buckets.should_receive(:[]).with('tolstoy').and_return(@bucket)
45
+ @bucket.should_receive(:exists?).and_return(true)
46
+
47
+ @s3helper.bucket(:bucket => 'tolstoy').should == @bucket
48
+ end
49
+
50
+ context "when the bucket does not yet exist" do
51
+
52
+ before(:each) do
53
+ @bucket.stub!(:exists).and_return(false)
54
+ @s3.stub_chain(:buckets, :[]).and_return(@bucket)
55
+ @s3.stub_chain(:buckets, :create).and_return(@bucket_real)
56
+
57
+ @bucket_real = mock(AWS::S3::Bucket)
58
+ @bucket_real.stub!(:exists).and_return(true)
59
+ end
60
+
61
+ context ":create_if_missing" do
62
+
63
+ it "should return nil if :create_if_missing is not set" do
64
+ @s3.buckets.should_receive(:[]).with('tolstoy').and_return(@bucket)
65
+ @bucket.should_receive(:exists?).once.and_return(false)
66
+ @s3helper.bucket(:bucket => 'tolstoy').should == nil
67
+ end
68
+
69
+ context "When :create_if_missing is set" do
70
+
71
+ it "should return a bucket, with other settings defaulted" do
72
+ @s3.buckets.should_receive(:[]).with('tolstoy').and_return(@bucket)
73
+ @bucket.should_receive(:exists?).once.and_return(false)
74
+ @s3.buckets.
75
+ should_receive(:create).
76
+ once.
77
+ with('tolstoy', :acl => :private, :location_constraint => 'us-east-1').
78
+ and_return(@bucket_real)
79
+
80
+ @s3helper.bucket(:bucket => 'tolstoy', :create_if_missing => true).should == @bucket_real
81
+ end
82
+
83
+ it "should return a bucket assigned with the attributes provided by the user" do
84
+ @s3.buckets.should_receive(:[]).with('tolstoy').and_return(@bucket)
85
+ @bucket.should_receive(:exists?).once.and_return(false)
86
+ @s3.buckets.
87
+ should_receive(:create).
88
+ once.
89
+ with('tolstoy', :acl => :ham, :location_constraint => 'biscuit').
90
+ and_return(@bucket_real)
91
+
92
+ @s3helper.bucket(:bucket => 'tolstoy', :create_if_missing => true,
93
+ :acl => :ham, :location_constraint => 'biscuit').should == @bucket_real
94
+ end
95
+
96
+ end
97
+ end
98
+ end
99
+ end
100
+
101
+ describe ".object_exists?" do
102
+
103
+ it "should return true if the object exists" do
104
+ @s3obj.stub!(:exists?).and_return(true)
105
+ @s3obj.should_receive(:exists?).and_return(true)
106
+ @s3helper.object_exists?(@s3obj).should == true
107
+ end
108
+
109
+ it "should return false if the object does not exist" do
110
+ @s3obj.stub!(:exists?).and_return(false)
111
+ @s3obj.should_receive(:exists?).and_return(false)
112
+ @s3helper.object_exists?(@s3obj).should == false
113
+ end
114
+
115
+ end
116
+
117
+ describe ".delete_folder" do
118
+
119
+ it "should delete a folder from a bucket" do
120
+ object = mock(AWS::S3::S3Object)
121
+ objects = [object]
122
+
123
+ @bucket.stub!(:objects)
124
+ @bucket.objects.
125
+ should_receive(:with_prefix).
126
+ with('cacoethes/carpendi').
127
+ and_return(objects)
128
+
129
+ object.should_receive(:delete).once
130
+
131
+ @s3helper.delete_folder(@bucket, '/cacoethes/carpendi/')
132
+ end
133
+
134
+ end
135
+
136
+ describe ".stub_s3obj" do
137
+
138
+ it "should return a stub AWS::S3::S3Object associated with the specified bucket" do
139
+ object = mock(AWS::S3::S3Object)
140
+ objects = mock(AWS::S3::ObjectCollection)
141
+ objects.stub!(:[]).and_return(object)
142
+ objects.stub!(:to_sym).and_return(:anything)
143
+
144
+ @bucket.stub!(objects).and_return(objects)
145
+ @bucket.should_receive(:objects).and_return(objects)
146
+ objects.should_receive(:[]).and_return(object)
147
+
148
+ @s3helper.stub_s3obj(@bucket, 'vini/vidi/vici') == @s3obj
149
+ end
150
+
151
+ end
152
+
153
+ describe ".parse_path" do
154
+
155
+ it "should return root if is empty" do
156
+ @s3helper.parse_path('').should == '/'
157
+ end
158
+
159
+ it "should remove extranous slashes" do
160
+ @s3helper.parse_path('//cave/canem//').
161
+ should == 'cave/canem/'
162
+ end
163
+
164
+ end
165
+
166
+
167
+ end
168
+ end