aeolus-image 0.0.1 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
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