boxgrinder-build 0.9.2 → 0.9.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (62) hide show
  1. data/CHANGELOG +21 -0
  2. data/Manifest +92 -0
  3. data/Rakefile +9 -0
  4. data/boxgrinder-build.gemspec +4 -4
  5. data/integ/appliances/_hardware_cpus.appl +13 -0
  6. data/integ/appliances/_hardware_memory.appl +13 -0
  7. data/integ/appliances/_hardware_partitions_home.appl +15 -0
  8. data/integ/appliances/_hardware_partitions_root.appl +15 -0
  9. data/integ/appliances/_os_password.appl +15 -0
  10. data/integ/appliances/_packages_groups_base.appl +13 -0
  11. data/integ/appliances/_packages_groups_core.appl +13 -0
  12. data/integ/appliances/_packages_squid.appl +13 -0
  13. data/integ/appliances/_packages_utils.appl +7 -0
  14. data/integ/appliances/_repos_boxgrinder_permanent_noarch.appl +14 -0
  15. data/integ/appliances/_repos_testlocal_ephemeral_noarch.appl +17 -0
  16. data/integ/appliances/_test_base.appl +22 -0
  17. data/integ/appliances/gnome-fedora.appl +19 -0
  18. data/integ/appliances/jeos-centos.appl +4 -0
  19. data/integ/appliances/jeos-fedora.appl +5 -0
  20. data/integ/appliances/modular.appl +16 -0
  21. data/integ/packages/ephemeral-repo-test-0.1-1.noarch.rpm +0 -0
  22. data/integ/packages/local-repo-test.spec +20 -0
  23. data/integ/spec/jeos-spec.rb +69 -0
  24. data/integ/spec/modular-spec.rb +71 -0
  25. data/lib/boxgrinder-build/appliance.rb +48 -48
  26. data/lib/boxgrinder-build/helpers/guestfs-helper.rb +11 -8
  27. data/lib/boxgrinder-build/helpers/plugin-helper.rb +1 -0
  28. data/lib/boxgrinder-build/helpers/qemu.wrapper +1 -1
  29. data/lib/boxgrinder-build/plugins/base-plugin.rb +55 -14
  30. data/lib/boxgrinder-build/plugins/delivery/ebs/ebs-plugin.rb +270 -54
  31. data/lib/boxgrinder-build/plugins/delivery/elastichosts/elastichosts-plugin.rb +3 -4
  32. data/lib/boxgrinder-build/plugins/delivery/local/local-plugin.rb +20 -16
  33. data/lib/boxgrinder-build/plugins/delivery/s3/s3-plugin.rb +57 -20
  34. data/lib/boxgrinder-build/plugins/delivery/sftp/sftp-plugin.rb +6 -4
  35. data/lib/boxgrinder-build/plugins/os/fedora/fedora-plugin.rb +2 -1
  36. data/lib/boxgrinder-build/plugins/os/rpm-based/kickstart.rb +2 -32
  37. data/lib/boxgrinder-build/plugins/os/rpm-based/rpm-based-os-plugin.rb +29 -4
  38. data/lib/boxgrinder-build/plugins/os/rpm-based/rpm-dependency-validator.rb +15 -46
  39. data/lib/boxgrinder-build/plugins/os/sl/sl-plugin.rb +56 -0
  40. data/lib/boxgrinder-build/plugins/platform/ec2/ec2-plugin.rb +1 -0
  41. data/lib/boxgrinder-build/plugins/platform/ec2/src/rc_local +15 -8
  42. data/lib/boxgrinder-build/plugins/platform/vmware/vmware-plugin.rb +8 -6
  43. data/rubygem-boxgrinder-build.spec +23 -3
  44. data/spec/appliance-spec.rb +114 -73
  45. data/spec/helpers/guestfs-helper-spec.rb +12 -3
  46. data/spec/plugins/base-plugin-spec.rb +24 -18
  47. data/spec/plugins/delivery/ebs/ebs-plugin-spec.rb +206 -67
  48. data/spec/plugins/delivery/elastichosts/elastichosts-plugin-spec.rb +228 -225
  49. data/spec/plugins/delivery/local/local-plugin-spec.rb +13 -34
  50. data/spec/plugins/delivery/s3/s3-plugin-spec.rb +107 -50
  51. data/spec/plugins/os/centos/centos-plugin-spec.rb +1 -1
  52. data/spec/plugins/os/fedora/fedora-plugin-spec.rb +14 -8
  53. data/spec/plugins/os/rhel/rhel-plugin-spec.rb +1 -1
  54. data/spec/plugins/os/rpm-based/kickstart-spec.rb +0 -44
  55. data/spec/plugins/os/rpm-based/rpm-based-os-plugin-spec.rb +31 -2
  56. data/spec/plugins/os/rpm-based/rpm-dependency-validator-spec.rb +20 -7
  57. data/spec/plugins/os/sl/sl-plugin-spec.rb +44 -0
  58. data/spec/plugins/platform/ec2/ec2-plugin-spec.rb +1 -1
  59. data/spec/plugins/platform/virtualbox/virtualbox-plugin-spec.rb +6 -6
  60. data/spec/plugins/platform/vmware/vmware-plugin-spec.rb +14 -13
  61. metadata +27 -5
  62. data/spec/Rakefile +0 -32
@@ -43,7 +43,7 @@ module BoxGrinder
43
43
 
44
44
  @plugin = BasePlugin.new
45
45
  @plugin.should_receive(:merge_plugin_config)
46
- @plugin.init(@config, @appliance_config, :plugin_info => {:name => :plugin_name, :full_name => "Amazon Simple Storage Service (Amazon S3)"}, :log => @log)
46
+ @plugin.init(@config, @appliance_config, {:name => :plugin_name, :full_name => "Amazon Simple Storage Service (Amazon S3)"}, :log => @log)
47
47
  end
48
48
 
49
49
  it "should be initialized after running init method" do
@@ -81,26 +81,32 @@ module BoxGrinder
81
81
  @plugin.instance_variable_get(:@dir).tmp.should == "build/path/plugin_name-plugin/tmp"
82
82
  end
83
83
 
84
- it "should check if deliverables exists and return true" do
85
- @plugin.register_deliverable(:disk => "disk")
86
- @plugin.register_deliverable(:abc => "def")
87
- @plugin.register_deliverable(:file => "a/path")
84
+ describe ".deliverables_exists?" do
85
+ it "should check if deliverables exists and return true" do
86
+ @plugin.register_deliverable(:disk => "disk")
87
+ @plugin.register_deliverable(:abc => "def")
88
+ @plugin.register_deliverable(:file => "a/path")
88
89
 
89
- File.should_receive(:exists?).exactly(3).times.with(any_args()).and_return(true)
90
+ File.should_receive(:exists?).exactly(3).times.with(any_args()).and_return(true)
90
91
 
91
- @plugin.deliverables_exists?.should == true
92
- end
92
+ @plugin.deliverables_exists?.should == true
93
+ end
94
+
95
+ it "should check if deliverables exists and return false" do
96
+ @plugin.register_deliverable(:disk => "disk")
97
+ @plugin.register_deliverable(:abc => "def")
98
+ @plugin.register_deliverable(:file => "a/path")
93
99
 
94
- it "should check if deliverables exists and return false" do
95
- @plugin.register_deliverable(:disk => "disk")
96
- @plugin.register_deliverable(:abc => "def")
97
- @plugin.register_deliverable(:file => "a/path")
100
+ File.should_receive(:exists?).once.with(any_args()).and_return(true)
101
+ File.should_receive(:exists?).once.with(any_args()).and_return(false)
102
+ File.should_not_receive(:exists?)
98
103
 
99
- File.should_receive(:exists?).once.with(any_args()).and_return(true)
100
- File.should_receive(:exists?).once.with(any_args()).and_return(false)
101
- File.should_not_receive(:exists?)
104
+ @plugin.deliverables_exists?.should == false
105
+ end
102
106
 
103
- @plugin.deliverables_exists?.should == false
107
+ it "should return false if no deliverables are registerd" do
108
+ @plugin.deliverables_exists?.should == false
109
+ end
104
110
  end
105
111
 
106
112
  describe ".run" do
@@ -111,12 +117,12 @@ module BoxGrinder
111
117
  FileUtils.should_receive(:rm_rf).with("build/path/plugin_name-plugin/tmp")
112
118
  FileUtils.should_receive(:mkdir_p).with("build/path/plugin_name-plugin/tmp")
113
119
 
114
- @plugin.should_receive(:execute).with('a', 3)
120
+ @plugin.should_receive(:execute)
115
121
 
116
122
  FileUtils.should_receive(:mv).with("build/path/plugin_name-plugin/tmp/disk", "build/path/plugin_name-plugin/disk")
117
123
  FileUtils.should_receive(:rm_rf).with("build/path/plugin_name-plugin/tmp")
118
124
 
119
- @plugin.run('a', 3)
125
+ @plugin.run
120
126
  end
121
127
 
122
128
  it "should fail if OS is not supported" do
@@ -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 'ostruct'
20
21
  require 'logger'
21
22
  require 'boxgrinder-build/plugins/delivery/ebs/ebs-plugin'
22
23
  require 'hashery/opencascade'
@@ -33,11 +34,11 @@ module BoxGrinder
33
34
 
34
35
  yield @plugin if block_given?
35
36
 
36
- @config = mock('Config')
37
- @config.stub!(:delivery_config).and_return({})
38
- plugins = mock('Plugins')
39
- plugins.stub!(:[]).with('ebs').and_return({})
40
- @config.stub!(:[]).with(:plugins).and_return(plugins)
37
+ @config = Config.new('plugins' => { 'ebs' => {
38
+ 'access_key' => 'access_key',
39
+ 'secret_access_key' => 'secret_access_key',
40
+ 'account_number' => '0000-0000-0000'
41
+ }})
41
42
 
42
43
  @appliance_config = mock('ApplianceConfig')
43
44
 
@@ -48,75 +49,48 @@ module BoxGrinder
48
49
  @appliance_config.stub!(:hardware).and_return(OpenCascade.new({:arch => 'x86_64', :base_arch => 'x86_64'}))
49
50
  @appliance_config.stub!(:path).and_return(OpenCascade.new({:build => '/a/build/path'}))
50
51
 
51
- @plugin = @plugin.init(
52
+ @plugin.stub!(:validate)
53
+
54
+ @plugin.init(
52
55
  @config,
53
56
  @appliance_config,
54
- :log => Logger.new('/dev/null'),
55
- :plugin_info => {:class => BoxGrinder::EBSPlugin, :type => :delivery, :name => :ebs, :full_name => "Elastic Block Storage"},
56
- :config_file => "#{File.dirname(__FILE__)}/ebs.yaml"
57
- )
58
-
59
- @plugin_config = @plugin.instance_variable_get(:@plugin_config).merge(
60
- {
61
- 'access_key' => 'access_key',
62
- 'secret_access_key' => 'secret_access_key',
63
- 'bucket' => 'bucket',
64
- 'account_number' => '0000-0000-0000',
65
- 'cert_file' => '/path/to/cert/file',
66
- 'key_file' => '/path/to/key/file'
67
- }
57
+ {:class => BoxGrinder::EBSPlugin, :type => :delivery, :name => :ebs, :full_name => "Elastic Block Storage"},
58
+ :log => LogHelper.new(:level => :trace, :type => :stdout)
68
59
  )
69
60
 
70
- @plugin.instance_variable_set(:@plugin_config, @plugin_config)
61
+ @plugin_config = @config.plugins['ebs']
71
62
  end
72
63
 
73
64
  it "should register all operating systems with specific versions" do
74
- Resolv.stub!(:getname).with("169.254.169.254").and_return([".ec2.internal"])
75
-
76
65
  prepare_plugin do |plugin|
77
- avaibility_zone = mock('AZ')
78
- avaibility_zone.should_receive(:string).and_return('avaibility-zone1')
79
-
80
- plugin.should_receive(:open).with('http://169.254.169.254/latest/meta-data/placement/availability-zone').and_return(avaibility_zone)
66
+ plugin.instance_variable_set(:@current_availability_zone, 'us-east-1a')
81
67
  end
82
68
 
83
- supportes_oses = @plugin.instance_variable_get(:@supported_oses)
69
+ supported_oses = @plugin.instance_variable_get(:@supported_oses)
84
70
 
85
- supportes_oses.size.should == 2
86
- supportes_oses.keys.sort.should == ['fedora', 'rhel']
87
- supportes_oses['rhel'].should == ['6']
88
- supportes_oses['fedora'].should == ['13', '14', '15']
71
+ supported_oses.size.should == 3
72
+ supported_oses.keys.sort.should == ['fedora', 'rhel', 'centos'].sort
73
+ supported_oses['rhel'].should == ['6']
74
+ supported_oses['fedora'].should == ['13', '14', '15']
75
+ supported_oses['centos'].should == ['5']
89
76
  end
90
77
 
91
78
  describe ".after_init" do
92
- it "should set default avaibility zone to current one" do
93
- Resolv.stub!(:getname).with("169.254.169.254").and_return([".ec2.internal"])
94
-
79
+ it "should set the region" do
95
80
  prepare_plugin do |plugin|
96
- avaibility_zone = mock('AZ')
97
- avaibility_zone.should_receive(:string).and_return('avaibility-zone1')
98
-
99
- plugin.should_receive(:open).with('http://169.254.169.254/latest/meta-data/placement/availability-zone').and_return(avaibility_zone)
81
+ plugin.instance_variable_set(:@current_availability_zone, 'us-east-1a')
100
82
  end
101
83
 
102
- @plugin.instance_variable_get(:@plugin_config)['availability_zone'].should == 'avaibility-zone1'
103
- end
104
-
105
- it "should not set default avaibility zone because we're not on EC2" do
106
- Resolv.stub!(:getname).with("169.254.169.254").and_return(["bleh"])
107
-
108
- prepare_plugin
109
-
110
- @plugin.instance_variable_get(:@plugin_config)['availability_zone'].should == nil
84
+ @plugin.instance_variable_get(:@region).should == 'us-east-1'
111
85
  end
112
86
  end
113
87
 
114
- describe '.already_registered?' do
88
+ describe '.ami_info' do
115
89
 
116
90
  it "should check if image is already registered and return false if there are no images registered for this account" do
117
91
  prepare_plugin { |plugin| plugin.stub!(:after_init) }
118
92
 
119
- plugin_config = mock('PluginConfiig')
93
+ plugin_config = mock('PluginConfig')
120
94
  plugin_config.should_receive(:[]).with('account_number').and_return('0000-0000-0000')
121
95
 
122
96
  @plugin.instance_variable_set(:@plugin_config, plugin_config)
@@ -126,13 +100,13 @@ module BoxGrinder
126
100
 
127
101
  @plugin.instance_variable_set(:@ec2, ec2)
128
102
 
129
- @plugin.already_registered?('aname').should == false
103
+ @plugin.ami_info('aname').should == false
130
104
  end
131
105
 
132
106
  it "should check if image is already registered and return false if there are no images with name aname_new" do
133
107
  prepare_plugin { |plugin| plugin.stub!(:after_init) }
134
108
 
135
- plugin_config = mock('PluginConfiig')
109
+ plugin_config = mock('PluginConfig')
136
110
  plugin_config.should_receive(:[]).with('account_number').and_return('0000-0000-0000')
137
111
 
138
112
  @plugin.instance_variable_set(:@plugin_config, plugin_config)
@@ -142,15 +116,33 @@ module BoxGrinder
142
116
 
143
117
  @plugin.instance_variable_set(:@ec2, ec2)
144
118
 
145
- @plugin.already_registered?('aname_new').should == false
119
+ @plugin.ami_info('aname_new').should == false
146
120
  end
147
121
 
148
- it "should check if image is already registered and return true image is registered" do
149
- Resolv.stub!(:getname).with("169.254.169.254").and_return([".ec2.internal"])
122
+ it "should return valid AMI information map for a single matching image when a valid imageId exists" do
123
+ prepare_plugin { |plugin| plugin.stub!(:after_init) }
124
+
125
+ plugin_config = mock('PluginConfig')
126
+ plugin_config.should_receive(:[]).with('account_number').and_return('0000-0000-0000')
127
+
128
+ @plugin.instance_variable_set(:@plugin_config, plugin_config)
129
+
130
+ ec2 = mock('EC2')
131
+ ec2.should_receive(:describe_images).with(:owner_id => '000000000000').and_return({'imagesSet' => {'item' => [{'name' => 'abc', 'imageId' => '1'}, {'name' => 'aname', 'imageId' => '2'}]}})
132
+
133
+ @plugin.instance_variable_set(:@ec2, ec2)
134
+
135
+ @plugin.ami_info('aname').should == {'name' => 'aname', 'imageId' => '2'}
136
+ end
137
+
138
+ end
150
139
 
140
+ describe '.already_registered?' do
141
+
142
+ it "should check if image is already registered and return true image is registered" do
151
143
  prepare_plugin { |plugin| plugin.stub!(:after_init) }
152
144
 
153
- plugin_config = mock('PluginConfiig')
145
+ plugin_config = mock('PluginConfig')
154
146
  plugin_config.should_receive(:[]).with('account_number').and_return('0000-0000-0000')
155
147
 
156
148
  @plugin.instance_variable_set(:@plugin_config, plugin_config)
@@ -162,6 +154,7 @@ module BoxGrinder
162
154
 
163
155
  @plugin.already_registered?('aname').should == '2'
164
156
  end
157
+
165
158
  end
166
159
 
167
160
  it "should adjust fstab" do
@@ -195,20 +188,33 @@ module BoxGrinder
195
188
  @plugin.free_device_suffix.should == "g"
196
189
  end
197
190
 
198
- it "should return true if on EC2" do
199
- Resolv.stub!(:getname).with("169.254.169.254").and_return([".ec2.internal"])
200
-
201
- prepare_plugin { |plugin| plugin.stub!(:after_init) }
202
-
203
- @plugin.valid_platform?.should == true
204
- end
191
+ describe ".valid_platform?" do
192
+ it "should return true if on EC2" do
193
+ prepare_plugin do |plugin|
194
+ plugin.stub!(:after_init)
195
+ plugin.stub!(:get_ec2_availability_zone).and_return("eu-west-1a")
196
+ plugin.stub!(:availability_zone_to_region).and_return("eu-west-1")
197
+ end
198
+ @plugin.valid_platform?.should == true
199
+ end
205
200
 
206
- it "should return false if NOT on EC2" do
207
- Resolv.stub!(:getname).with("169.254.169.254").and_return(["bleh"])
201
+ it "should return false if NOT on EC2" do
202
+ prepare_plugin do |plugin|
203
+ plugin.stub!(:after_init)
204
+ plugin.stub!(:get_ec2_availability_zone).and_raise(Timeout::Error)
205
+ end
206
+ @plugin.valid_platform?.should == false
207
+ end
208
208
 
209
- prepare_plugin { |plugin| plugin.stub!(:after_init) }
209
+ it "should return false if the EC2 zone returned is not supported" do
210
+ prepare_plugin do |plugin|
211
+ plugin.stub!(:after_init)
212
+ plugin.stub!(:get_ec2_availability_zone).and_return("moon-west-7a")
213
+ plugin.stub!(:availability_zone_to_region).and_return("moon-west-7")
214
+ end
215
+ @plugin.valid_platform?.should == false
216
+ end
210
217
 
211
- @plugin.valid_platform?.should == false
212
218
  end
213
219
 
214
220
  describe ".ebs_appliance_name" do
@@ -217,6 +223,25 @@ module BoxGrinder
217
223
  @plugin.ebs_appliance_name.should == "appliance_name/fedora/14/1.0/x86_64"
218
224
  end
219
225
 
226
+ it "should always return basic appliance name when overwrite is enabled, but snapshot is disabled" do
227
+ prepare_plugin { |plugin| plugin.stub!(:after_init) }
228
+ @plugin_config.merge!('overwrite' => true, 'snapshot' => false)
229
+ @plugin.ebs_appliance_name.should == "appliance_name/fedora/14/1.0/x86_64"
230
+ end
231
+
232
+ it "should still return a valid _initial_ snapshot appliance name, even if overwrite and snapshot are enabled on first ever run" do
233
+ prepare_plugin { |plugin| plugin.stub!(:after_init) }
234
+
235
+ @plugin_config.merge!('overwrite' => true, 'snapshot' => true)
236
+
237
+ ec2 = mock('EC2')
238
+ ec2.should_receive(:describe_images).once.with(:owner_id => '000000000000').and_return(nil)#should be nothing
239
+
240
+ @plugin.instance_variable_set(:@ec2, ec2)
241
+
242
+ @plugin.ebs_appliance_name.should == "appliance_name/fedora/14/1.0-SNAPSHOT-1/x86_64"
243
+ end
244
+
220
245
  it "should return 2nd snapshot of appliance" do
221
246
  prepare_plugin { |plugin| plugin.stub!(:after_init) }
222
247
 
@@ -232,6 +257,120 @@ module BoxGrinder
232
257
 
233
258
  @plugin.ebs_appliance_name.should == "appliance_name/fedora/14/1.0-SNAPSHOT-2/x86_64"
234
259
  end
260
+
261
+ it "should return the last snapshot name again when OVERWRITE is enabled" do
262
+ prepare_plugin { |plugin| plugin.stub!(:after_init) }
263
+
264
+ @plugin_config.merge!('snapshot' => true, 'overwrite' => true)
265
+
266
+ ec2 = mock('EC2')
267
+ ec2.should_receive(:describe_images).twice.with(:owner_id => '000000000000').and_return({'imagesSet' => {'item' => [
268
+ {'imageId' => '1', 'name' => 'appliance_name/fedora/14/1.0/x86_64'},
269
+ {'imageId' => '2', 'name' => 'appliance_name/fedora/14/1.0-SNAPSHOT-1/x86_64'}
270
+ ]}})
271
+
272
+ @plugin.instance_variable_set(:@ec2, ec2)
273
+
274
+ @plugin.ebs_appliance_name.should == "appliance_name/fedora/14/1.0-SNAPSHOT-1/x86_64"
275
+ end
276
+
277
+ end
278
+
279
+ describe ".stomp_ebs" do
280
+
281
+ before(:each) do
282
+ @ami_info = recursive_ostruct({'imageId' => 'sleepy', 'blockDeviceMapping' => {'item' => [{'deviceName' => '/dev/sda1', 'ebs' => {'snapshotId' => 'bashful'}}]}})
283
+ @dummy_instances = recursive_ostruct([{'instanceId' => 'grumpy'},
284
+ {'instanceId' => 'sneezy'}])
285
+ @dummy_snapshot = recursive_ostruct({'snapshotId' => 'bashful', 'volumeId' => 'snow-white'})
286
+ @dummy_volume_attached = recursive_ostruct({'volumeId' => 'snow-white', 'status' => 'attached'})
287
+ @dummy_volume_detached = recursive_ostruct({'volumeId' => 'snow-white', 'status' => 'detached'})
288
+ end
289
+
290
+ it "should return false if there was no block device found" do
291
+ prepare_plugin do |plugin|
292
+ plugin.stub!(:after_init)
293
+ plugin.stub!(:block_device_from_ami).and_return(nil)
294
+ end
295
+ @plugin.stomp_ebs(@ami_info).should == false
296
+ end
297
+
298
+
299
+ it "should throw an exception if there is still an EBS instance[s] running when an overwrite is requested" do
300
+ prepare_plugin do |plugin|
301
+ plugin.stub!(:after_init)
302
+ plugin.stub!(:snapshot_info).and_return(@dummy_snapshot)
303
+ plugin.stub!(:get_instances).and_return(@dummy_instances)
304
+ plugin.stub!(:get_volume_info).and_return(nil)
305
+ end
306
+ lambda { @plugin.stomp_ebs(@ami_info) }.should raise_error(RuntimeError)
307
+ end
308
+
309
+ it "should detach and delete the block store, remove the snapshot and deregister the image" do
310
+ prepare_plugin do |plugin|
311
+ plugin.stub!(:after_init)
312
+ plugin.stub!(:snapshot_info).and_return(@dummy_snapshot)
313
+ plugin.stub!(:get_instances).and_return(false)
314
+ plugin.stub!(:get_volume_info).and_return(@dummy_volume_attached, @dummy_volume_detached)
315
+ plugin.stub!(:wait_for_volume_delete)
316
+ plugin.stub!(:wait_for_snapshot_status)
317
+ plugin.stub!(:wait_for_volume_status)
318
+ end
319
+
320
+ ec2 = mock('EC2')
321
+ ec2.should_receive(:detach_volume).with(:volume_id => 'snow-white', :force => true)
322
+ ec2.should_receive(:delete_volume).with(:volume_id => 'snow-white')
323
+ ec2.should_receive(:deregister_image).with(:image_id => 'sleepy')
324
+ ec2.should_receive(:delete_snapshot).with(:snapshot_id => 'bashful')
325
+
326
+
327
+ @plugin.instance_variable_set(:@ec2, ec2)
328
+ @plugin.stomp_ebs(@ami_info)
329
+ end
330
+
331
+ it "should not delete AWS snapshots when preserve_snapshots is set" do
332
+ prepare_plugin do |plugin|
333
+ plugin.stub!(:after_init)
334
+ plugin.stub!(:snapshot_info).and_return(@dummy_snapshot)
335
+ plugin.stub!(:get_instances).and_return(false)
336
+ plugin.stub!(:get_volume_info).and_return(@dummy_volume_attached, @dummy_volume_detached)
337
+ plugin.stub!(:wait_for_volume_delete)
338
+ plugin.stub!(:wait_for_snapshot_status)
339
+ plugin.stub!(:wait_for_volume_status)
340
+ end
341
+
342
+ @plugin_config.merge!('preserve_snapshots' => true)
343
+
344
+ ec2 = mock('EC2')
345
+ ec2.should_receive(:detach_volume).with(:volume_id => 'snow-white', :force => true)
346
+ ec2.should_receive(:delete_volume).with(:volume_id => 'snow-white')
347
+ ec2.should_receive(:deregister_image).with(:image_id => 'sleepy')
348
+ ec2.should_not_receive(:delete_snapshot).with(:snapshot_id => 'bashful')
349
+
350
+ @plugin.instance_variable_set(:@ec2, ec2)
351
+ @plugin.stomp_ebs(@ami_info)
352
+ end
353
+
354
+ end
355
+
356
+ #Amazon-EC2 gem uses recursive ostructs, and wont work with opencascade
357
+ #this replicates the format to avoid breaking the code in tests.
358
+ def recursive_ostruct(initial)
359
+ clone = initial.clone
360
+ ostruct = case initial.class
361
+ when Array
362
+ clone.collect! do |v|
363
+ recursive_ostruct v
364
+ end
365
+ when Hash
366
+ clone.each_pair do |k,v| #follow down until reach terminal
367
+ clone[k] = recursive_ostruct v
368
+ end
369
+ return OpenStruct.new clone
370
+ else
371
+ return clone
372
+ end
373
+ ostruct
235
374
  end
236
375
  end
237
376
  end
@@ -23,18 +23,15 @@ require 'hashery/opencascade'
23
23
  module BoxGrinder
24
24
  describe ElasticHostsPlugin do
25
25
 
26
- def merge_config(config = {})
27
- @plugin_config = @plugin.instance_variable_get(:@plugin_config).merge(config)
28
- @plugin.instance_variable_set(:@plugin_config, @plugin_config)
29
- end
30
-
31
- before(:each) do
32
- @config = mock('Config')
33
- @config.stub!(:delivery_config).and_return({})
34
- @config.stub!(:file).and_return('configfile')
35
- plugins = mock('Plugins')
36
- plugins.stub!(:[]).with('elastichosts').and_return({})
37
- @config.stub!(:[]).with(:plugins).and_return(plugins)
26
+ def prepare(options = {})
27
+ @config = Config.new(
28
+ 'plugins' => {
29
+ 'elastichosts' => {
30
+ 'username' => '12345',
31
+ 'password' => 'secret_access_key',
32
+ 'endpoint' => 'one.endpoint.somewhere.com'
33
+ }
34
+ })
38
35
 
39
36
  @appliance_config = mock('ApplianceConfig')
40
37
 
@@ -46,299 +43,305 @@ module BoxGrinder
46
43
  @appliance_config.stub!(:os).and_return(OpenCascade.new({:name => :fedora, :version => '13'}))
47
44
  @appliance_config.stub!(:hardware).and_return(OpenCascade.new(:cpus => 1, :arch => 'x86_64', :partitions => {'/' => {'size' => 1}, '/home' => {'size' => 2}}, :memory => 512))
48
45
 
46
+ options = {:log => LogHelper.new(:level => :trace, :type => :stdout), :previous_plugin => OpenCascade.new(:plugin_info => {:type => :os})}.merge(options)
47
+
49
48
  @plugin = ElasticHostsPlugin.new.init(@config, @appliance_config,
50
- :log => LogHelper.new(:level => :trace, :type => :stdout),
51
- :plugin_info => {:class => BoxGrinder::ElasticHostsPlugin, :type => :delivery, :name => :elastichosts, :full_name => "ElasticHosts"}
52
- )
49
+ {:class => BoxGrinder::ElasticHostsPlugin, :type => :delivery, :name => :elastichosts, :full_name => "ElasticHosts"},
50
+ options
53
51
 
54
- @plugin.instance_variable_set(:@previous_plugin_info, :type => :os)
52
+ )
55
53
 
56
- @config = @plugin.instance_variable_get(:@config)
57
- @appliance_config = @plugin.instance_variable_get(:@appliance_config)
54
+ @plugin_config = @config.plugins['elastichosts']
58
55
  @exec_helper = @plugin.instance_variable_get(:@exec_helper)
59
56
  @log = @plugin.instance_variable_get(:@log)
60
57
  @dir = @plugin.instance_variable_get(:@dir)
58
+ end
61
59
 
62
- merge_config('username' => '12345', 'password' => 'secret_access_key', 'endpoint' => 'one.endpoint.somewhere.com')
60
+ context "validation" do
61
+ describe ".validate" do
62
+ it "should fail because we try to upload a non-base appliance" do
63
+ lambda {
64
+ prepare(:previous_plugin => OpenCascade.new(:plugin_info => {:type => :platform}))
65
+ }.should raise_error(PluginValidationError, 'You can use ElasticHosts plugin with base appliances (appliances created with operating system plugins) only, see http://boxgrinder.org/tutorials/boxgrinder-build-plugins/#ElasticHosts_Delivery_Plugin.')
66
+ end
67
+ end
63
68
  end
64
69
 
65
- describe ".elastichosts_api_url" do
66
- it "should return valid url for default schema" do
67
- @plugin.api_url('/drive/1').should == 'http://12345:secret_access_key@one.endpoint.somewhere.com/drive/1'
70
+ context "after validation" do
71
+ before(:each) do
72
+ prepare
73
+ @plugin.validate
68
74
  end
69
75
 
70
- it "should return valid url for SSL" do
71
- merge_config('ssl' => true)
72
- @plugin.api_url('/drive/1').should == 'https://12345:secret_access_key@one.endpoint.somewhere.com/drive/1'
76
+ describe ".elastichosts_api_url" do
77
+ it "should return valid url for default schema" do
78
+ @plugin.api_url('/drive/1').should == 'http://12345:secret_access_key@one.endpoint.somewhere.com/drive/1'
79
+ end
80
+
81
+ it "should return valid url for SSL" do
82
+ @plugin_config.merge!('ssl' => true)
83
+ @plugin.api_url('/drive/1').should == 'https://12345:secret_access_key@one.endpoint.somewhere.com/drive/1'
84
+ end
73
85
  end
74
- end
75
86
 
76
- it "should return valid disk_size" do
77
- @plugin.disk_size.should == 3
78
- end
87
+ it "should return valid disk_size" do
88
+ @plugin.disk_size.should == 3
89
+ end
79
90
 
80
- describe ".execute" do
81
- it "should fail because we try to upload a non-base appliance" do
82
- @plugin.instance_variable_set(:@previous_plugin_info, :type => :platform)
83
- @plugin.should_not_receive(:upload)
84
- @plugin.should_not_receive(:create_server)
85
91
 
86
- lambda {
92
+ describe ".execute" do
93
+ it "should upload the appliance" do
94
+ @plugin.should_receive(:upload)
95
+ @plugin.should_receive(:create_server)
87
96
  @plugin.execute
88
- }.should raise_error(PluginValidationError, 'You can use ElasticHosts plugin with base appliances (appliances created with operating system plugins) only, see http://boxgrinder.org/tutorials/boxgrinder-build-plugins/#ElasticHosts_Delivery_Plugin.')
97
+ end
89
98
  end
90
99
 
91
- it "should upload the appliance" do
92
- @plugin.should_receive(:upload)
93
- @plugin.should_receive(:create_server)
94
- @plugin.execute
100
+ it "should convert hash to request" do
101
+ @plugin.hash_to_request('abc' => 'def', 'one' => 1234).should == "abc def\none 1234\n"
95
102
  end
96
- end
97
-
98
- it "should convert hash to request" do
99
- @plugin.hash_to_request('abc' => 'def', 'one' => 1234).should == "abc def\none 1234\n"
100
- end
101
103
 
102
- describe ".create_remote_disk" do
103
- it "should create remote disk with default name" do
104
- @plugin.should_receive(:hash_to_request).with('size' => 3221225472, 'name' => 'appliance').and_return("json")
104
+ describe ".create_remote_disk" do
105
+ it "should create remote disk with default name" do
106
+ @plugin.should_receive(:hash_to_request).with('size' => 3221225472, 'name' => 'appliance').and_return("json")
105
107
 
106
- RestClient.should_receive(:post).with("http://12345:secret_access_key@one.endpoint.somewhere.com/drives/create",
107
- "json").and_return("drive abc-1234567890-abc\n")
108
- @plugin.create_remote_disk.should == 'abc-1234567890-abc'
109
- end
108
+ RestClient.should_receive(:post).with("http://12345:secret_access_key@one.endpoint.somewhere.com/drives/create",
109
+ "json").and_return("drive abc-1234567890-abc\n")
110
+ @plugin.create_remote_disk.should == 'abc-1234567890-abc'
111
+ end
110
112
 
111
- it "should create remote disk with custom name" do
112
- merge_config('drive_name' => 'thisisadrivename')
113
+ it "should create remote disk with custom name" do
114
+ @plugin_config.merge!('drive_name' => 'thisisadrivename')
113
115
 
114
- @plugin.should_receive(:hash_to_request).with('size' => 3221225472, 'name' => 'thisisadrivename').and_return("json")
116
+ @plugin.should_receive(:hash_to_request).with('size' => 3221225472, 'name' => 'thisisadrivename').and_return("json")
115
117
 
116
- RestClient.should_receive(:post).with("http://12345:secret_access_key@one.endpoint.somewhere.com/drives/create",
117
- "json").and_return("drive abc-1234567890-abc\n")
118
- @plugin.create_remote_disk.should == 'abc-1234567890-abc'
119
- end
118
+ RestClient.should_receive(:post).with("http://12345:secret_access_key@one.endpoint.somewhere.com/drives/create",
119
+ "json").and_return("drive abc-1234567890-abc\n")
120
+ @plugin.create_remote_disk.should == 'abc-1234567890-abc'
121
+ end
120
122
 
121
- it "should catch remote disk creation error" do
122
- @plugin.should_receive(:hash_to_request).with('size' => 3221225472, 'name' => 'appliance').and_return("json")
123
+ it "should catch remote disk creation error" do
124
+ @plugin.should_receive(:hash_to_request).with('size' => 3221225472, 'name' => 'appliance').and_return("json")
123
125
 
124
- RestClient.should_receive(:post).with("http://12345:secret_access_key@one.endpoint.somewhere.com/drives/create",
125
- "json").and_raise('boom')
126
+ RestClient.should_receive(:post).with("http://12345:secret_access_key@one.endpoint.somewhere.com/drives/create",
127
+ "json").and_raise('boom')
126
128
 
127
- lambda {
128
- @plugin.create_remote_disk
129
- }.should raise_error(PluginError, 'An error occured while creating the drive, boom. See logs for more info.')
129
+ lambda {
130
+ @plugin.create_remote_disk
131
+ }.should raise_error(PluginError, 'An error occured while creating the drive, boom. See logs for more info.')
132
+ end
130
133
  end
131
- end
132
134
 
133
- describe ".upload" do
134
- it "create the disk and upload" do
135
- @plugin.should_receive(:create_remote_disk)
136
- @plugin.should_receive(:upload_chunks)
137
- @plugin.upload
138
- end
135
+ describe ".upload" do
136
+ it "create the disk and upload" do
137
+ @plugin.should_receive(:create_remote_disk)
138
+ @plugin.should_receive(:upload_chunks)
139
+ @plugin.upload
140
+ end
139
141
 
140
- it "upload using existing disk" do
141
- merge_config('drive_uuid' => 'thisisadrivename')
142
+ it "upload using existing disk" do
143
+ @plugin_config.merge!('drive_uuid' => 'thisisadrivename')
142
144
 
143
- @plugin.should_not_receive(:create_remote_disk)
144
- @plugin.should_receive(:upload_chunks)
145
- @plugin.upload
145
+ @plugin.should_not_receive(:create_remote_disk)
146
+ @plugin.should_receive(:upload_chunks)
147
+ @plugin.upload
148
+ end
146
149
  end
147
- end
148
150
 
149
- it "should compress data chunk" do
150
- stringio = mock(StringIO)
151
- stringio.should_receive(:string).and_return("compressed_data")
152
- stringio.should_receive(:size).and_return(2048)
151
+ it "should compress data chunk" do
152
+ stringio = mock(StringIO)
153
+ stringio.should_receive(:string).and_return("compressed_data")
154
+ stringio.should_receive(:size).and_return(2048)
153
155
 
154
- gzipwriter = mock(Zlib::GzipWriter)
155
- gzipwriter.should_receive(:write).with("data")
156
- gzipwriter.should_receive(:close)
156
+ gzipwriter = mock(Zlib::GzipWriter)
157
+ gzipwriter.should_receive(:write).with("data")
158
+ gzipwriter.should_receive(:close)
157
159
 
158
- StringIO.should_receive(:new).and_return(stringio)
159
- Zlib::GzipWriter.should_receive(:new).with(stringio, Zlib::DEFAULT_COMPRESSION, Zlib::FINISH).and_return(gzipwriter)
160
+ StringIO.should_receive(:new).and_return(stringio)
161
+ Zlib::GzipWriter.should_receive(:new).with(stringio, Zlib::DEFAULT_COMPRESSION, Zlib::FINISH).and_return(gzipwriter)
160
162
 
161
- @plugin.compress("data").should == "compressed_data"
162
- end
163
+ @plugin.compress("data").should == "compressed_data"
164
+ end
163
165
 
164
- describe ".upload_chunks" do
165
- it "should upload chunks in 2 parts" do
166
- @plugin.instance_variable_set(:@previous_deliverables, {:disk => 'a/disk'})
166
+ describe ".upload_chunks" do
167
+ it "should upload chunks in 2 parts" do
168
+ @plugin.instance_variable_set(:@previous_deliverables, {:disk => 'a/disk'})
167
169
 
168
- f = mock(File)
169
- f.should_receive(:eof?).ordered.and_return(false)
170
- f.should_receive(:seek).ordered.with(0, File::SEEK_SET)
171
- f.should_receive(:read).ordered.with(67108864).and_return("data")
170
+ f = mock(File)
171
+ f.should_receive(:eof?).ordered.and_return(false)
172
+ f.should_receive(:seek).ordered.with(0, File::SEEK_SET)
173
+ f.should_receive(:read).ordered.with(67108864).and_return("data")
172
174
 
173
- @plugin.should_receive(:compress).ordered.with("data").and_return("compressed_data")
174
- @plugin.should_receive(:upload_chunk).ordered.with("compressed_data", 0)
175
+ @plugin.should_receive(:compress).ordered.with("data").and_return("compressed_data")
176
+ @plugin.should_receive(:upload_chunk).ordered.with("compressed_data", 0)
175
177
 
176
- f.should_receive(:eof?).ordered.and_return(false)
177
- f.should_receive(:seek).ordered.with(67108864, File::SEEK_SET)
178
- f.should_receive(:read).ordered.with(67108864).and_return("data")
178
+ f.should_receive(:eof?).ordered.and_return(false)
179
+ f.should_receive(:seek).ordered.with(67108864, File::SEEK_SET)
180
+ f.should_receive(:read).ordered.with(67108864).and_return("data")
179
181
 
180
- @plugin.should_receive(:compress).ordered.with("data").and_return("compressed_data")
181
- @plugin.should_receive(:upload_chunk).ordered.with("compressed_data", 1)
182
+ @plugin.should_receive(:compress).ordered.with("data").and_return("compressed_data")
183
+ @plugin.should_receive(:upload_chunk).ordered.with("compressed_data", 1)
182
184
 
183
- f.should_receive(:eof?).ordered.and_return(true)
185
+ f.should_receive(:eof?).ordered.and_return(true)
184
186
 
185
- File.should_receive(:open).with('a/disk', 'rb').and_yield(f)
186
- @plugin.upload_chunks
187
- end
187
+ File.should_receive(:open).with('a/disk', 'rb').and_yield(f)
188
+ @plugin.upload_chunks
189
+ end
188
190
 
189
- it "should upload 1 chunk with custom chunk size" do
190
- merge_config('chunk' => 128)
191
- @plugin.instance_variable_set(:@previous_deliverables, {:disk => 'a/disk'})
191
+ it "should upload 1 chunk with custom chunk size" do
192
+ @plugin_config.merge!('chunk' => 128)
193
+ @plugin.instance_variable_set(:@previous_deliverables, {:disk => 'a/disk'})
192
194
 
193
- f = mock(File)
194
- f.should_receive(:eof?).ordered.and_return(false)
195
- f.should_receive(:seek).ordered.with(0, File::SEEK_SET)
196
- f.should_receive(:read).ordered.with(134217728).and_return("data")
195
+ f = mock(File)
196
+ f.should_receive(:eof?).ordered.and_return(false)
197
+ f.should_receive(:seek).ordered.with(0, File::SEEK_SET)
198
+ f.should_receive(:read).ordered.with(134217728).and_return("data")
197
199
 
198
- @plugin.should_receive(:compress).ordered.with("data").and_return("compressed_data")
199
- @plugin.should_receive(:upload_chunk).ordered.with("compressed_data", 0)
200
+ @plugin.should_receive(:compress).ordered.with("data").and_return("compressed_data")
201
+ @plugin.should_receive(:upload_chunk).ordered.with("compressed_data", 0)
200
202
 
201
- f.should_receive(:eof?).ordered.and_return(true)
203
+ f.should_receive(:eof?).ordered.and_return(true)
202
204
 
203
- File.should_receive(:open).with('a/disk', 'rb').and_yield(f)
204
- @plugin.upload_chunks
205
- end
205
+ File.should_receive(:open).with('a/disk', 'rb').and_yield(f)
206
+ @plugin.upload_chunks
207
+ end
206
208
 
207
- it "should not compress the data before uploading the chunks if we use CloudSigma" do
208
- merge_config('endpoint' => 'api.cloudsigma.com')
209
- @plugin.instance_variable_set(:@previous_deliverables, {:disk => 'a/disk'})
209
+ it "should not compress the data before uploading the chunks if we use CloudSigma" do
210
+ @plugin_config.merge!('endpoint' => 'api.cloudsigma.com')
211
+ @plugin.instance_variable_set(:@previous_deliverables, {:disk => 'a/disk'})
210
212
 
211
- f = mock(File)
212
- f.should_receive(:eof?).ordered.and_return(false)
213
- f.should_receive(:seek).ordered.with(0, File::SEEK_SET)
214
- f.should_receive(:read).ordered.with(67108864).and_return("data")
215
- f.should_receive(:eof?).ordered.and_return(true)
213
+ f = mock(File)
214
+ f.should_receive(:eof?).ordered.and_return(false)
215
+ f.should_receive(:seek).ordered.with(0, File::SEEK_SET)
216
+ f.should_receive(:read).ordered.with(67108864).and_return("data")
217
+ f.should_receive(:eof?).ordered.and_return(true)
216
218
 
217
- @plugin.should_not_receive(:compress)
218
- @plugin.should_receive(:upload_chunk).ordered.with("data", 0)
219
+ @plugin.should_not_receive(:compress)
220
+ @plugin.should_receive(:upload_chunk).ordered.with("data", 0)
219
221
 
220
- File.should_receive(:open).with('a/disk', 'rb').and_yield(f)
221
- @plugin.upload_chunks
222
- end
223
- end
224
-
225
- describe ".upload_chunk" do
226
- before :each do
227
- merge_config('drive_uuid' => 'drive-uuid')
228
- @plugin.instance_variable_set(:@step, 134217728)
222
+ File.should_receive(:open).with('a/disk', 'rb').and_yield(f)
223
+ @plugin.upload_chunks
224
+ end
229
225
  end
230
226
 
231
- it "should upload a chunk of data" do
232
- @plugin.should_receive(:api_url).with('/drives/drive-uuid/write/134217728').and_return('url')
233
- RestClient.should_receive(:post).with('url', 'data', :content_type=>"application/octet-stream", "Content-Encoding"=>"gzip")
234
- @plugin.upload_chunk("data", 1)
235
- end
236
-
237
- it "should upload a chunk of data and be succesful after 1 retry" do
238
- @plugin.should_receive(:api_url).with('/drives/drive-uuid/write/0').and_return('url')
239
- RestClient.should_receive(:post).with('url', 'data', :content_type=>"application/octet-stream", "Content-Encoding"=>"gzip").and_raise('boom')
240
- @plugin.should_receive(:sleep).with(5)
241
- RestClient.should_receive(:post).with('url', 'data', :content_type=>"application/octet-stream", "Content-Encoding"=>"gzip")
227
+ describe ".upload_chunk" do
228
+ before :each do
229
+ @plugin_config.merge!('drive_uuid' => 'drive-uuid')
230
+ @plugin.instance_variable_set(:@step, 134217728)
231
+ end
242
232
 
243
- @plugin.upload_chunk("data", 0)
244
- end
233
+ it "should upload a chunk of data" do
234
+ @plugin.should_receive(:api_url).with('/drives/drive-uuid/write/134217728').and_return('url')
235
+ RestClient.should_receive(:post).with('url', 'data', :content_type=>"application/octet-stream", "Content-Encoding"=>"gzip")
236
+ @plugin.upload_chunk("data", 1)
237
+ end
245
238
 
246
- it "should fail the upload after 3 retries" do
247
- @plugin.should_receive(:api_url).with('/drives/drive-uuid/write/0').and_return('url')
248
- RestClient.should_receive(:post).exactly(3).times.with('url', 'data', :content_type=>"application/octet-stream", "Content-Encoding"=>"gzip").and_raise('boom')
249
- @plugin.should_receive(:sleep).exactly(2).times.with(5)
239
+ it "should upload a chunk of data and be succesful after 1 retry" do
240
+ @plugin.should_receive(:api_url).with('/drives/drive-uuid/write/0').and_return('url')
241
+ RestClient.should_receive(:post).with('url', 'data', :content_type=>"application/octet-stream", "Content-Encoding"=>"gzip").and_raise('boom')
242
+ @plugin.should_receive(:sleep).with(5)
243
+ RestClient.should_receive(:post).with('url', 'data', :content_type=>"application/octet-stream", "Content-Encoding"=>"gzip")
250
244
 
251
- lambda {
252
245
  @plugin.upload_chunk("data", 0)
253
- }.should raise_error(PluginError, "Couldn't upload appliance, boom.")
254
- end
246
+ end
255
247
 
256
- it "should fail the upload after custom sleep time and retry count" do
257
- merge_config('retry' => 5, 'wait' => 30)
248
+ it "should fail the upload after 3 retries" do
249
+ @plugin.should_receive(:api_url).with('/drives/drive-uuid/write/0').and_return('url')
250
+ RestClient.should_receive(:post).exactly(3).times.with('url', 'data', :content_type=>"application/octet-stream", "Content-Encoding"=>"gzip").and_raise('boom')
251
+ @plugin.should_receive(:sleep).exactly(2).times.with(5)
258
252
 
259
- @plugin.should_receive(:api_url).with('/drives/drive-uuid/write/0').and_return('url')
260
- RestClient.should_receive(:post).exactly(5).times.with('url', 'data', :content_type=>"application/octet-stream", "Content-Encoding"=>"gzip").and_raise('boom')
261
- @plugin.should_receive(:sleep).exactly(4).times.with(30)
253
+ lambda {
254
+ @plugin.upload_chunk("data", 0)
255
+ }.should raise_error(PluginError, "Couldn't upload appliance, boom.")
256
+ end
262
257
 
263
- lambda {
264
- @plugin.upload_chunk("data", 0)
265
- }.should raise_error(PluginError, "Couldn't upload appliance, boom.")
266
- end
258
+ it "should fail the upload after custom sleep time and retry count" do
259
+ @plugin_config.merge!('retry' => 5, 'wait' => 30)
267
260
 
268
- it "should not specify add content-encoding header if uplaoding to cloudsigma" do
269
- merge_config('endpoint' => 'api.cloudsigma.com')
261
+ @plugin.should_receive(:api_url).with('/drives/drive-uuid/write/0').and_return('url')
262
+ RestClient.should_receive(:post).exactly(5).times.with('url', 'data', :content_type=>"application/octet-stream", "Content-Encoding"=>"gzip").and_raise('boom')
263
+ @plugin.should_receive(:sleep).exactly(4).times.with(30)
270
264
 
271
- @plugin.should_receive(:api_url).with('/drives/drive-uuid/write/0').and_return('url')
272
- RestClient.should_receive(:post).with('url', 'data', :content_type=>"application/octet-stream")
265
+ lambda {
266
+ @plugin.upload_chunk("data", 0)
267
+ }.should raise_error(PluginError, "Couldn't upload appliance, boom.")
268
+ end
273
269
 
274
- @plugin.upload_chunk("data", 0)
275
- end
276
- end
270
+ it "should not specify add content-encoding header if uplaoding to cloudsigma" do
271
+ @plugin_config.merge!('endpoint' => 'api.cloudsigma.com')
277
272
 
278
- describe ".create_server" do
279
- before(:each) do
280
- merge_config('drive_uuid' => '12345-asdf')
281
-
282
- @plugin.should_receive(:hash_to_request).with(
283
- 'name' => "appliance-1.0",
284
- 'cpu' => 1000,
285
- 'smp' => 'auto',
286
- 'mem' => 512,
287
- 'persistent' => 'true',
288
- 'ide:0:0' => '12345-asdf',
289
- 'boot' => 'ide:0:0',
290
- 'nic:0:model' => 'e1000',
291
- 'nic:0:dhcp' => 'auto',
292
- 'vnc:ip' => 'auto',
293
- 'vnc:password' => an_instance_of(String)
294
- ).and_return("json")
295
- end
296
-
297
- it "should create the server without issues" do
298
- RestClient.should_receive(:post).with("http://12345:secret_access_key@one.endpoint.somewhere.com/servers/create/stopped",
299
- "json").and_return("server abc-1234567890-abc\nname appliance-1.0\n")
273
+ @plugin.should_receive(:api_url).with('/drives/drive-uuid/write/0').and_return('url')
274
+ RestClient.should_receive(:post).with('url', 'data', :content_type=>"application/octet-stream")
300
275
 
301
- @plugin.create_server
276
+ @plugin.upload_chunk("data", 0)
277
+ end
302
278
  end
303
279
 
304
- it "should create the server with 512 MB of ram for instances to be uploaded to cloudsigma" do
305
- merge_config('endpoint' => 'api.cloudsigma.com')
280
+ describe ".create_server" do
281
+ before(:each) do
282
+ @plugin_config.merge!('drive_uuid' => '12345-asdf')
283
+
284
+ @plugin.should_receive(:hash_to_request).with(
285
+ 'name' => "appliance-1.0",
286
+ 'cpu' => 1000,
287
+ 'smp' => 'auto',
288
+ 'mem' => 512,
289
+ 'persistent' => 'true',
290
+ 'ide:0:0' => '12345-asdf',
291
+ 'boot' => 'ide:0:0',
292
+ 'nic:0:model' => 'e1000',
293
+ 'nic:0:dhcp' => 'auto',
294
+ 'vnc:ip' => 'auto',
295
+ 'vnc:password' => an_instance_of(String)
296
+ ).and_return("json")
297
+ end
298
+
299
+ it "should create the server without issues" do
300
+ RestClient.should_receive(:post).with("http://12345:secret_access_key@one.endpoint.somewhere.com/servers/create/stopped",
301
+ "json").and_return("server abc-1234567890-abc\nname appliance-1.0\n")
306
302
 
307
- @appliance_config.stub!(:hardware).and_return(OpenCascade.new(:cpus => 1, :arch => 'x86_64', :partitions => {'/' => {'size' => 1}, '/home' => {'size' => 2}}, :memory => 256))
303
+ @plugin.create_server
304
+ end
308
305
 
309
- RestClient.should_receive(:post).with("http://12345:secret_access_key@api.cloudsigma.com/servers/create",
310
- "json").and_return("server abc-1234567890-abc\nname appliance-1.0\n")
306
+ it "should create the server with 512 MB of ram for instances to be uploaded to cloudsigma" do
307
+ @plugin_config.merge!('endpoint' => 'api.cloudsigma.com')
311
308
 
312
- @plugin.create_server
313
- end
309
+ @appliance_config.stub!(:hardware).and_return(OpenCascade.new(:cpus => 1, :arch => 'x86_64', :partitions => {'/' => {'size' => 1}, '/home' => {'size' => 2}}, :memory => 256))
314
310
 
315
- it "should create the server without issues for cloudsigma cloud" do
316
- merge_config('endpoint' => 'api.cloudsigma.com')
311
+ RestClient.should_receive(:post).with("http://12345:secret_access_key@api.cloudsigma.com/servers/create",
312
+ "json").and_return("server abc-1234567890-abc\nname appliance-1.0\n")
317
313
 
318
- RestClient.should_receive(:post).with("http://12345:secret_access_key@api.cloudsigma.com/servers/create",
319
- "json").and_return("server abc-1234567890-abc\nname appliance-1.0\n")
314
+ @plugin.create_server
315
+ end
320
316
 
321
- @plugin.create_server
322
- end
317
+ it "should create the server without issues for cloudsigma cloud" do
318
+ @plugin_config.merge!('endpoint' => 'api.cloudsigma.com')
323
319
 
324
- it "should catch remote disk creation error" do
325
- RestClient.should_receive(:post).with("http://12345:secret_access_key@one.endpoint.somewhere.com/servers/create/stopped",
326
- "json").and_raise('boom')
320
+ RestClient.should_receive(:post).with("http://12345:secret_access_key@api.cloudsigma.com/servers/create",
321
+ "json").and_return("server abc-1234567890-abc\nname appliance-1.0\n")
327
322
 
328
- lambda {
329
323
  @plugin.create_server
330
- }.should raise_error(PluginError, 'An error occured while creating the server, boom. See logs for more info.')
331
- end
332
- end
324
+ end
333
325
 
334
- describe ".is_cloudsigma?" do
335
- it "should return true if we're talking to cloudsigma endpoint" do
336
- merge_config('endpoint' => 'api.cloudsigma.com')
337
- @plugin.is_cloudsigma?.should == true
326
+ it "should catch remote disk creation error" do
327
+ RestClient.should_receive(:post).with("http://12345:secret_access_key@one.endpoint.somewhere.com/servers/create/stopped",
328
+ "json").and_raise('boom')
329
+
330
+ lambda {
331
+ @plugin.create_server
332
+ }.should raise_error(PluginError, 'An error occured while creating the server, boom. See logs for more info.')
333
+ end
338
334
  end
339
335
 
340
- it "should return false if we're NOT talking to cloudsigma endpoint" do
341
- @plugin.is_cloudsigma?.should == false
336
+ describe ".is_cloudsigma?" do
337
+ it "should return true if we're talking to cloudsigma endpoint" do
338
+ @plugin_config.merge!('endpoint' => 'api.cloudsigma.com')
339
+ @plugin.is_cloudsigma?.should == true
340
+ end
341
+
342
+ it "should return false if we're NOT talking to cloudsigma endpoint" do
343
+ @plugin.is_cloudsigma?.should == false
344
+ end
342
345
  end
343
346
  end
344
347
  end