aeolus-image 0.0.1 → 0.4.0

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 (63) hide show
  1. data/COPYING +161 -0
  2. data/Rakefile +32 -19
  3. data/lib/aeolus_image.rb +35 -0
  4. data/lib/aeolus_image/active_resource_oauth_client.rb +62 -0
  5. data/lib/aeolus_image/import.rb +44 -0
  6. data/lib/aeolus_image/model/factory/base.rb +93 -0
  7. data/lib/aeolus_image/model/factory/build.rb +23 -0
  8. data/lib/aeolus_image/model/factory/builder.rb +46 -0
  9. data/lib/aeolus_image/model/factory/image.rb +23 -0
  10. data/lib/aeolus_image/model/factory/provider_image.rb +35 -0
  11. data/lib/aeolus_image/model/factory/target_image.rb +45 -0
  12. data/lib/aeolus_image/model/warehouse/icicle.rb +60 -0
  13. data/lib/aeolus_image/model/warehouse/image.rb +135 -0
  14. data/lib/aeolus_image/model/warehouse/image_build.rb +60 -0
  15. data/lib/aeolus_image/model/warehouse/provider_image.rb +36 -0
  16. data/lib/aeolus_image/model/warehouse/target_image.rb +53 -0
  17. data/lib/aeolus_image/model/warehouse/template.rb +35 -0
  18. data/lib/aeolus_image/model/warehouse/warehouse_client.rb +201 -0
  19. data/lib/aeolus_image/model/warehouse/warehouse_model.rb +236 -0
  20. data/spec/aeolus_image/model/factory/provider_image_spec.rb +12 -0
  21. data/spec/models/factory/base_spec.rb +94 -0
  22. data/spec/models/factory/builder_spec.rb +31 -0
  23. data/spec/models/factory/provider_image_spec.rb +21 -0
  24. data/spec/models/factory/target_image_spec.rb +21 -0
  25. data/spec/models/warehouse/image_build_spec.rb +189 -0
  26. data/spec/models/warehouse/image_spec.rb +241 -0
  27. data/spec/models/warehouse/provider_image_spec.rb +115 -0
  28. data/spec/models/warehouse/target_image_spec.rb +180 -0
  29. data/spec/models/warehouse/template_spec.rb +76 -0
  30. data/spec/models/warehouse/warehouse_client_spec.rb +445 -0
  31. data/spec/models/warehouse/warehouse_model_spec.rb +94 -0
  32. data/spec/spec_helper.rb +34 -47
  33. data/spec/vcr/cassettes/builder.yml +24 -0
  34. data/spec/vcr/cassettes/oauth.yml +80 -0
  35. data/spec/vcr/cassettes/oauth_fail_invalid.yml +30 -0
  36. data/spec/vcr/cassettes/oauth_fail_no.yml +22 -0
  37. data/spec/vcr/cassettes/oauth_success_valid.yml +30 -0
  38. data/spec/vcr_setup.rb +26 -0
  39. metadata +70 -46
  40. data/bin/aeolus-image +0 -6
  41. data/examples/aeolus-cli +0 -9
  42. data/examples/custom_repo.tdl +0 -18
  43. data/examples/image_description.xml +0 -3
  44. data/examples/tdl.rng +0 -207
  45. data/lib/base_command.rb +0 -134
  46. data/lib/build_command.rb +0 -68
  47. data/lib/config_parser.rb +0 -212
  48. data/lib/delete_command.rb +0 -9
  49. data/lib/import_command.rb +0 -44
  50. data/lib/list_command.rb +0 -141
  51. data/lib/push_command.rb +0 -72
  52. data/man/aeolus-image-build.1 +0 -36
  53. data/man/aeolus-image-import.1 +0 -57
  54. data/man/aeolus-image-list.1 +0 -80
  55. data/man/aeolus-image-push.1 +0 -40
  56. data/man/aeolus-image.1 +0 -16
  57. data/spec/base_command_spec.rb +0 -76
  58. data/spec/build_command_spec.rb +0 -63
  59. data/spec/config_parser_spec.rb +0 -82
  60. data/spec/import_command_spec.rb +0 -43
  61. data/spec/list_command_spec.rb +0 -21
  62. data/spec/push_command_spec.rb +0 -56
  63. data/spec/spec.opts +0 -3
@@ -0,0 +1,12 @@
1
+ require 'spec_helper'
2
+
3
+ module Aeolus
4
+ module Image
5
+ module Factory
6
+ describe ProviderImage do
7
+ p = ProviderImage.new
8
+ Aeolus::Image::Factory::Base.site = "https://localhost:8075/imagefactory"
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,94 @@
1
+ #
2
+ # Copyright 2011 Red Hat, Inc.
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ #
16
+ require 'spec_helper'
17
+ require 'timecop'
18
+
19
+ describe Aeolus::Image::Factory::Base do
20
+
21
+ before(:each) do
22
+ Timecop.travel(Time.local(2011, 10, 17, 13, 38, 20))
23
+ end
24
+
25
+ after(:each) do
26
+ Timecop.return
27
+ end
28
+
29
+ it "should not use_oauth? if configuration is missing" do
30
+ Aeolus::Image::Factory::Base.config = {
31
+ :site => 'http://127.0.0.1:8075/imagefactory'
32
+ }
33
+ Aeolus::Image::Factory::Base.use_oauth?.should be_false
34
+ end
35
+
36
+ it "should use_oauth? if configuration is present" do
37
+ Aeolus::Image::Factory::Base.config = {
38
+ :site => 'http://127.0.0.1:8075/imagefactory',
39
+ :consumer_key => 'something',
40
+ :consumer_secret => 'anything'
41
+ }
42
+ Aeolus::Image::Factory::Base.use_oauth?.should be_true
43
+ end
44
+
45
+ context do
46
+ use_vcr_cassette "oauth_success_valid"
47
+
48
+ it "should succeed with valid OAuth credentials" do
49
+ Aeolus::Image::Factory::Base.config = {
50
+ :site => 'http://127.0.0.1:8075/imagefactory',
51
+ :consumer_key => 'mock-key',
52
+ :consumer_secret => 'mock-secret'
53
+ }
54
+ template = "<template>\n <name>f14jeos</name>\n <os>\n <name>Fedora</name>\n <version>14</version>\n <arch>x86_64</arch>\n <install type='url'>\n <url>http://download.fedoraproject.org/pub/fedora/linux/releases/14/Fedora/x86_64/os/</url>\n </install>\n </os>\n <description>Fedora 14</description>\n</template>\n"
55
+ img = Aeolus::Image::Factory::Image.new(:targets => 'ec2', :template => template)
56
+ img.save!.should be_true
57
+ end
58
+ end
59
+
60
+ context do
61
+ use_vcr_cassette "oauth_fail_invalid"
62
+
63
+ it "should fail with invalid OAuth credentials" do
64
+ Aeolus::Image::Factory::Base.config = {
65
+ :site => 'http://127.0.0.1:8075/imagefactory',
66
+ :consumer_key => 'mock-key',
67
+ :consumer_secret => 'wrong-secret'
68
+ }
69
+ template = "<template>\n <name>f14jeos</name>\n <os>\n <name>Fedora 2</name>\n <version>14</version>\n <arch>x86_64</arch>\n <install type='url'>\n <url>http://download.fedoraproject.org/pub/fedora/linux/releases/14/Fedora/x86_64/os/</url>\n </install>\n </os>\n <description>Fedora 14</description>\n</template>\n"
70
+ img = Aeolus::Image::Factory::Image.new(:targets => 'ec2', :template => template)
71
+ lambda {
72
+ img.save!
73
+ }.should raise_error(ActiveResource::UnauthorizedAccess)
74
+ end
75
+ end
76
+
77
+ context do
78
+ use_vcr_cassette "oauth_fail_no"
79
+
80
+ it "should fail with no OAuth credentials" do
81
+ Aeolus::Image::Factory::Base.config = {
82
+ :site => 'http://127.0.0.1:8075/imagefactory'
83
+ }
84
+ template = "<template>\n <name>f14jeos</name>\n <os>\n <name>Fedora 3</name>\n <version>14</version>\n <arch>x86_64</arch>\n <install type='url'>\n <url>http://download.fedoraproject.org/pub/fedora/linux/releases/14/Fedora/x86_64/os/</url>\n </install>\n </os>\n <description>Fedora 14</description>\n</template>\n"
85
+ img = Aeolus::Image::Factory::Image.new(:targets => 'ec2', :template => template)
86
+ # ServerError is actually not what _should_ be returned, but a bug means that's what we get at the moment.
87
+ # When the bug is fixed, we need to update to test for that.
88
+ lambda {
89
+ img.save!.should be_false
90
+ }.should raise_error(ActiveResource::ServerError)
91
+ end
92
+ end
93
+
94
+ end
@@ -0,0 +1,31 @@
1
+ #
2
+ # Copyright 2011 Red Hat, Inc.
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ #
16
+ require 'spec_helper'
17
+ require 'timecop'
18
+
19
+ describe Aeolus::Image::Factory::Builder do
20
+ VCR::Cassette.new 'builder', :record => :new_episodes, :match_requests_on => [:method, :uri, :body]
21
+ it "should get builder object" do
22
+ Aeolus::Image::Factory::Base.config = {
23
+ :site => 'http://127.0.0.1:8075/imagefactory'
24
+ }
25
+ builder = Aeolus::Image::Factory::Builder.first
26
+ builder.builders.should_not be_empty
27
+ build = builder.builders.first
28
+ builder.find_active_build(build.build_id, build.target).should_not be_nil
29
+ builder.find_active_build(build.build_id, 'invalid_target').should be_nil
30
+ end
31
+ end
@@ -0,0 +1,21 @@
1
+ require 'spec_helper'
2
+
3
+ module Aeolus
4
+ module Image
5
+ module Factory
6
+ describe ProviderImage do
7
+ it "should return nil when a builder is found but operation is build" do
8
+ @builder = mock(Builder, :operation => "build", :status => "PUSHING")
9
+ Builder.stub!(:find).and_return(@builder)
10
+ ProviderImage.status("1234").should == nil
11
+ end
12
+
13
+ it "should return a builder when a builder is found and operation is push" do
14
+ @builder = mock(Builder, :operation => "push", :status => "PUSHING")
15
+ Builder.stub!(:find).and_return(@builder)
16
+ ProviderImage.status("1234").should == "PUSHING"
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,21 @@
1
+ require 'spec_helper'
2
+
3
+ module Aeolus
4
+ module Image
5
+ module Factory
6
+ describe TargetImage do
7
+ it "should return nil when a builder is found but operation is push" do
8
+ @builder = mock(Builder, :operation => "push")
9
+ Builder.stub!(:find).and_return(@builder)
10
+ TargetImage.status("1234").should == nil
11
+ end
12
+
13
+ it "should return a builder when a builder is found and operation is build" do
14
+ @builder = mock(Builder, :operation => "build", :status => "BUILDING")
15
+ Builder.stub!(:find).and_return(@builder)
16
+ TargetImage.status("1234").should == "BUILDING"
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,189 @@
1
+ # Copyright 2011 Red Hat, Inc.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ require 'spec_helper'
16
+
17
+ module Aeolus
18
+ module Image
19
+ module Warehouse
20
+ describe ImageBuild do
21
+ before(:each) do
22
+ @image_build_attributes = {
23
+ :image => 'image',
24
+ :uuid => 'uuid',
25
+ :template => 'template',
26
+ :other_attribute => 'other_attribute',
27
+ :another_attribute => 'another_attribute'
28
+ }
29
+ @object = mock(Object, :attr_list => @image_build_attributes.keys, :attrs => @image_build_attributes)
30
+ @image_build_attributes.each do |key, value|
31
+ @object.stub(key.to_sym, value)
32
+ end
33
+ @image_build = ImageBuild.new(@object)
34
+
35
+ @target_image_mock_with_no_build = mock(TargetImage, :build => nil, :provider_images => [mock(ProviderImage)])
36
+ @target_image_mock_with_correct_build = mock(TargetImage, :build => @image_build, :provider_images => [mock(ProviderImage)])
37
+ @other_target_image_mock_with_correct_build = mock(TargetImage, :build => @image_build, :provider_images => [mock(ProviderImage)])
38
+
39
+ @other_image_build_attributes = @image_build_attributes.merge(:uuid => 'other_uuid')
40
+ @other_object = mock(Object, :attr_list => @other_image_build_attributes.keys, :attrs => @other_image_build_attributes)
41
+ @other_image_build_attributes.each do |key, value|
42
+ @other_object.stub(key.to_sym, value)
43
+ end
44
+ @other_image_build = ImageBuild.new(@other_object)
45
+
46
+ @target_image_mock_with_other_image_build = mock(TargetImage, :build => @other_image_build, :provider_images => [mock(ProviderImage)] * 2)
47
+
48
+ @all_target_images = [ @target_image_mock_with_no_build, @target_image_mock_with_correct_build, @other_target_image_mock_with_correct_build, @target_image_mock_with_other_image_build ]
49
+
50
+ @correct_target_images = [ @target_image_mock_with_correct_build, @other_target_image_mock_with_correct_build ]
51
+
52
+ @first_target_image_provider_images = []
53
+ 3.times do
54
+ @first_target_image_provider_images << mock(ProviderImage, :target_image => @target_image_mock_with_correct_build)
55
+ end
56
+
57
+ @second_target_image_provider_images = []
58
+ 3.times do
59
+ @second_target_image_provider_images << mock(ProviderImage, :target_image => @other_target_image_mock_with_correct_build)
60
+ end
61
+
62
+ @incorrect_target_image_provider_images = []
63
+ 3.times do
64
+ @incorrect_target_image_provider_images << mock(ProviderImage, :target_image => @target_image_mock_with_other_image_build)
65
+ end
66
+
67
+ @correct_provider_images = @first_target_image_provider_images + @second_target_image_provider_images
68
+ @incorrect_provider_images = @incorrect_target_image_provider_images
69
+ @all_provider_images = @correct_provider_images + @incorrect_provider_images
70
+
71
+ end
72
+
73
+ context "@bucket_name" do
74
+
75
+ it "should be set correctly" do
76
+ # accessor set in WarehouseModel
77
+ @image_build.class.bucket_name.should be_eql('builds')
78
+ end
79
+
80
+ end
81
+
82
+ context "#initialize" do
83
+
84
+ before(:each) do
85
+ @attr_writers = [ :image ]
86
+ @attr_accessors = @image_build_attributes.keys - @attr_writers
87
+ end
88
+
89
+ it "should correctly set attribute writers" do
90
+ @attr_writers.each do |writer|
91
+ @image_build.respond_to?(:"#{writer.to_s}=").should be_true
92
+ end
93
+ end
94
+
95
+ it "should correctly set attribute accessors" do
96
+ @attr_accessors.each do |accessor|
97
+ @image_build.respond_to?(:"#{accessor.to_s}").should be_true
98
+ @image_build.respond_to?(:"#{accessor.to_s}=").should be_true
99
+ end
100
+ end
101
+
102
+ it "should set attributes to correct values" do
103
+ @attr_accessors.each do |key|
104
+ @image_build.send(:"#{key.to_s}").should be_equal(@image_build_attributes[key])
105
+ end
106
+ end
107
+
108
+ end
109
+
110
+ #TODO: implement this test
111
+ context ".find_all_by_image_uuid" do
112
+
113
+ end
114
+
115
+ context "#image" do
116
+ context "with @image present" do
117
+ before(:each) do
118
+ @image_mock = mock(Image)
119
+ Image.stub(:find).and_return(@image_mock)
120
+ end
121
+ it "should call Image.find with correct parameter" do
122
+ Image.should_receive(:find).with(@image_build.instance_variable_get( :@image ))
123
+ @image_build.image
124
+ end
125
+
126
+ it "should return found Image" do
127
+ @image_build.image.should be_eql(@image_mock)
128
+ end
129
+ end
130
+
131
+ context "with @image absent" do
132
+ before(:each) do
133
+ @image_build.instance_variable_set(:@image, nil)
134
+ end
135
+ it "should not call Image.find at all" do
136
+ Image.should_not_receive(:find)
137
+ @image_build.image
138
+ end
139
+ end
140
+ end
141
+
142
+ context "#target_images" do
143
+ before(:each) do
144
+ TargetImage.stub(:where).and_return(@all_target_images)
145
+ end
146
+
147
+ context "should return collection" do
148
+ it "with correct target image" do
149
+ @image_build.target_images.should include(@target_image_mock_with_correct_build)
150
+ end
151
+ it "with other correct target image" do
152
+ @image_build.target_images.should include(@other_target_image_mock_with_correct_build)
153
+ end
154
+ end
155
+ end
156
+
157
+ context "#provider_images" do
158
+ before(:each) do
159
+ TargetImage.stub(:where).and_return(@all_target_images)
160
+ end
161
+
162
+ context "should return collection" do
163
+ it "with correct amount of provider images" do
164
+ @image_build.provider_images.size.should == 5
165
+ end
166
+ end
167
+ end
168
+
169
+ context "#delete!" do
170
+
171
+ before(:each) do
172
+ @correct_target_images.each{|ti| ti.stub(:delete!)}
173
+ @image_build.stub(:target_images).and_return(@correct_target_images)
174
+ ImageBuild.stub(:delete)
175
+ end
176
+ it "should delete all associated provider images" do
177
+ @correct_target_images.each{|ti| ti.should_receive(:delete!)}
178
+ @image_build.delete!
179
+ end
180
+ it "should call TargetImage.delete with @uuid" do
181
+ ImageBuild.should_receive(:delete).with(@image_build.instance_variable_get(:@uuid))
182
+ @image_build.delete!
183
+ end
184
+
185
+ end
186
+ end
187
+ end
188
+ end
189
+ end
@@ -0,0 +1,241 @@
1
+ # Copyright 2011 Red Hat, Inc.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ require 'spec_helper'
16
+
17
+ module Aeolus
18
+ module Image
19
+ module Warehouse
20
+ describe Image do
21
+ let(:body) { 'body' }
22
+ before(:each) do
23
+ @image_attributes = {
24
+ :latest_build => 'latest_build',
25
+ :uuid => 'uuid',
26
+ :body => body,
27
+ :other_attribute => 'other_attribute',
28
+ :another_attribute => 'another_attribute'
29
+ }
30
+ @object = mock(Object, :attr_list => @image_attributes.keys, :attrs => @image_attributes)
31
+ @image_attributes.each do |key, value|
32
+ @object.stub(key.to_sym, value)
33
+ end
34
+ @image = Image.new(@object)
35
+
36
+ end
37
+
38
+ context "@bucket_name" do
39
+
40
+ it "should be set correctly" do
41
+ # accessor set in WarehouseModel
42
+ @image.class.bucket_name.should be_eql('images')
43
+ end
44
+
45
+ end
46
+
47
+ context "#initialize" do
48
+
49
+ before(:each) do
50
+ @attr_writers = [ :latest_build ]
51
+ @attr_accessors = @image_attributes.keys - @attr_writers
52
+ end
53
+
54
+ it "should correctly set attribute writers" do
55
+ @attr_writers.each do |writer|
56
+ @image.respond_to?(:"#{writer.to_s}=").should be_true
57
+ end
58
+ end
59
+
60
+ it "should correctly set attribute accessors" do
61
+ @attr_accessors.each do |accessor|
62
+ @image.respond_to?(:"#{accessor.to_s}").should be_true
63
+ @image.respond_to?(:"#{accessor.to_s}=").should be_true
64
+ end
65
+ end
66
+
67
+ #it "should set attributes to correct values" do
68
+ # @attr_accessors.each do |key|
69
+ # @image.send(:"#{key.to_s}").should be_equal(@image_attributes[key])
70
+ # end
71
+ #end
72
+
73
+ end
74
+
75
+ context "#template_xml" do
76
+
77
+ before(:each) do
78
+ @body = "<template><item>X</item></template>"
79
+ @template_xml = Nokogiri::XML(@body)
80
+
81
+ @empty_body = "<template></template>"
82
+ @empty_template_xml = nil
83
+ end
84
+
85
+ context "with correct associated objects" do
86
+
87
+ before(:each) do
88
+ @target_template = mock(Template, :body => @template_xml.to_s)
89
+ @target_image = [ mock(TargetImage, :target_template => @target_template) ]
90
+ @image_builds = [ mock(ImageBuild, :target_images => @target_image, :provider_images => [mock(ProviderImage)] * 2) ] * 2
91
+ @image.stub(:image_builds).and_return(@image_builds)
92
+ end
93
+
94
+ context "#provider_images" do
95
+ before(:each) do
96
+ ImageBuild.stub(:where).and_return(@image_builds)
97
+ end
98
+
99
+ context "should return collection" do
100
+ it "with correct amount of provider images" do
101
+ @image.provider_images.size.should == 4
102
+ end
103
+ end
104
+ end
105
+
106
+ # TODO: There shoud be a way to test equality of Nokogiri::XML documents better than string comparison
107
+ it "should return correct template" do
108
+ @image.template_xml.to_s.should be_eql(@template_xml.to_s)
109
+ end
110
+
111
+ end
112
+
113
+ context "with incorect associated object" do
114
+
115
+ before(:each) do
116
+ @image.stub(:image_builds).and_return(nil)
117
+ end
118
+
119
+ # TODO: There shoud be a way to test equality of Nokogiri::XML documents better than string comparison
120
+ it "should return empty template" do
121
+ @image.template_xml.to_s.should be_eql(@empty_template_xml.to_s)
122
+ end
123
+ end
124
+ end
125
+
126
+ context "#name" do
127
+ subject { @image.name }
128
+ context "with /image/name text value defined in body" do
129
+ let(:body) { "<image><name>image-name-string</name></image>" }
130
+ before(:each) do
131
+ @image.instance_variable_set(:@xml_body, Nokogiri::XML(body))
132
+ end
133
+
134
+ it "should return /image/name text value" do
135
+ puts subject
136
+ should be_eql('image-name-string')
137
+ end
138
+ end
139
+
140
+ context "without /image/name text value defined in body" do
141
+ before(:each) do
142
+ @image.stub(:template_xml).and_return(Nokogiri::XML(template_xml))
143
+ end
144
+ context "with /template/name text value from template_xml" do
145
+ let(:template_xml) { "<template><name>template-name-string</name></template>" }
146
+ it "should return /template/name text value" do
147
+ should be_eql('template-name-string')
148
+ end
149
+ end
150
+
151
+ context "without /template/name text value from template_xml" do
152
+ let(:template_xml) { "<template></template>" }
153
+ it "should return empty string" do
154
+ should be_eql("")
155
+ end
156
+ end
157
+ end
158
+ end
159
+
160
+ context "#os" do
161
+ subject { @image.os }
162
+ let(:template_xml) { "<template><os><name>template-os-name</name><version>template-os-version</version><arch>template-os-arch</arch></os></template>" }
163
+ before(:each) do
164
+ @image.stub(:template_xml).and_return(Nokogiri::XML(template_xml))
165
+ end
166
+
167
+ it "should return correct OS struct" do
168
+ subject.name.should be_eql("template-os-name")
169
+ subject.version.should be_eql("template-os-version")
170
+ subject.arch.should be_eql("template-os-arch")
171
+ end
172
+ end
173
+
174
+ context "#description" do
175
+
176
+ subject { @image.description }
177
+ let(:template_xml) { "<template><description>template-description-string</description></template>" }
178
+
179
+ before(:each) do
180
+ @image.stub(:template_xml).and_return(Nokogiri::XML(template_xml))
181
+ end
182
+
183
+ it "should return /template/description text value from template_xml" do
184
+ should be_eql("template-description-string")
185
+ end
186
+
187
+ end
188
+
189
+ context "#latest_pushed_build" do
190
+
191
+ context "with @latest_build present" do
192
+ before(:each) do
193
+ @latest_build_mock = mock(ImageBuild)
194
+ ImageBuild.stub(:find).and_return(@latest_build_mock)
195
+ end
196
+ it "should call ImageBuild.find with correct parameter" do
197
+ ImageBuild.should_receive(:find).with(@image.instance_variable_get( :@latest_build ))
198
+ @image.latest_pushed_build
199
+ end
200
+
201
+ it "should return found ImageBuild" do
202
+ @image.latest_pushed_build.should be_eql(@latest_build_mock)
203
+ end
204
+ end
205
+
206
+ context "with @latest_build absent" do
207
+ before(:each) do
208
+ @image.instance_variable_set(:@latest_build, nil)
209
+ end
210
+ it "should not call ImageBuild.find at all" do
211
+ ImageBuild.should_not_receive(:find)
212
+ @image.latest_pushed_build
213
+ end
214
+ end
215
+ end
216
+
217
+ context "#delete!" do
218
+
219
+ before(:each) do
220
+ @image_builds = [ mock(ImageBuild) ]
221
+ @image_builds.each{|ib| ib.stub(:delete!)}
222
+ @image.stub(:image_builds).and_return(@image_builds)
223
+ Image.stub(:delete)
224
+ end
225
+
226
+ it "should delete all associated image builds" do
227
+ @image_builds.each{|im| im.should_receive(:delete!)}
228
+ @image.delete!
229
+ end
230
+
231
+ it "should call Image.delete with @uuid" do
232
+ Image.should_receive(:delete).with(@image.instance_variable_get(:@uuid))
233
+ @image.delete!
234
+ end
235
+
236
+ end
237
+
238
+ end
239
+ end
240
+ end
241
+ end