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.
- data/COPYING +161 -0
- data/Rakefile +32 -19
- data/lib/aeolus_image.rb +35 -0
- data/lib/aeolus_image/active_resource_oauth_client.rb +62 -0
- data/lib/aeolus_image/import.rb +44 -0
- data/lib/aeolus_image/model/factory/base.rb +93 -0
- data/lib/aeolus_image/model/factory/build.rb +23 -0
- data/lib/aeolus_image/model/factory/builder.rb +46 -0
- data/lib/aeolus_image/model/factory/image.rb +23 -0
- data/lib/aeolus_image/model/factory/provider_image.rb +35 -0
- data/lib/aeolus_image/model/factory/target_image.rb +45 -0
- data/lib/aeolus_image/model/warehouse/icicle.rb +60 -0
- data/lib/aeolus_image/model/warehouse/image.rb +135 -0
- data/lib/aeolus_image/model/warehouse/image_build.rb +60 -0
- data/lib/aeolus_image/model/warehouse/provider_image.rb +36 -0
- data/lib/aeolus_image/model/warehouse/target_image.rb +53 -0
- data/lib/aeolus_image/model/warehouse/template.rb +35 -0
- data/lib/aeolus_image/model/warehouse/warehouse_client.rb +201 -0
- data/lib/aeolus_image/model/warehouse/warehouse_model.rb +236 -0
- data/spec/aeolus_image/model/factory/provider_image_spec.rb +12 -0
- data/spec/models/factory/base_spec.rb +94 -0
- data/spec/models/factory/builder_spec.rb +31 -0
- data/spec/models/factory/provider_image_spec.rb +21 -0
- data/spec/models/factory/target_image_spec.rb +21 -0
- data/spec/models/warehouse/image_build_spec.rb +189 -0
- data/spec/models/warehouse/image_spec.rb +241 -0
- data/spec/models/warehouse/provider_image_spec.rb +115 -0
- data/spec/models/warehouse/target_image_spec.rb +180 -0
- data/spec/models/warehouse/template_spec.rb +76 -0
- data/spec/models/warehouse/warehouse_client_spec.rb +445 -0
- data/spec/models/warehouse/warehouse_model_spec.rb +94 -0
- data/spec/spec_helper.rb +34 -47
- data/spec/vcr/cassettes/builder.yml +24 -0
- data/spec/vcr/cassettes/oauth.yml +80 -0
- data/spec/vcr/cassettes/oauth_fail_invalid.yml +30 -0
- data/spec/vcr/cassettes/oauth_fail_no.yml +22 -0
- data/spec/vcr/cassettes/oauth_success_valid.yml +30 -0
- data/spec/vcr_setup.rb +26 -0
- metadata +70 -46
- data/bin/aeolus-image +0 -6
- data/examples/aeolus-cli +0 -9
- data/examples/custom_repo.tdl +0 -18
- data/examples/image_description.xml +0 -3
- data/examples/tdl.rng +0 -207
- data/lib/base_command.rb +0 -134
- data/lib/build_command.rb +0 -68
- data/lib/config_parser.rb +0 -212
- data/lib/delete_command.rb +0 -9
- data/lib/import_command.rb +0 -44
- data/lib/list_command.rb +0 -141
- data/lib/push_command.rb +0 -72
- data/man/aeolus-image-build.1 +0 -36
- data/man/aeolus-image-import.1 +0 -57
- data/man/aeolus-image-list.1 +0 -80
- data/man/aeolus-image-push.1 +0 -40
- data/man/aeolus-image.1 +0 -16
- data/spec/base_command_spec.rb +0 -76
- data/spec/build_command_spec.rb +0 -63
- data/spec/config_parser_spec.rb +0 -82
- data/spec/import_command_spec.rb +0 -43
- data/spec/list_command_spec.rb +0 -21
- data/spec/push_command_spec.rb +0 -56
- data/spec/spec.opts +0 -3
@@ -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
|