occi-core 4.1.3 → 4.2.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.
- data/.gitignore +1 -0
- data/Gemfile +8 -0
- data/README.md +49 -17
- data/lib/occi/collection.rb +37 -21
- data/lib/occi/core/action.rb +5 -5
- data/lib/occi/core/action_instance.rb +45 -3
- data/lib/occi/core/actions.rb +2 -1
- data/lib/occi/core/attributes.rb +253 -73
- data/lib/occi/core/categories.rb +1 -0
- data/lib/occi/core/category.rb +25 -8
- data/lib/occi/core/entities.rb +1 -0
- data/lib/occi/core/entity.rb +51 -74
- data/lib/occi/core/kind.rb +15 -11
- data/lib/occi/core/kinds.rb +1 -1
- data/lib/occi/core/link.rb +14 -15
- data/lib/occi/core/links.rb +1 -1
- data/lib/occi/core/mixin.rb +5 -5
- data/lib/occi/core/mixins.rb +2 -2
- data/lib/occi/core/properties.rb +90 -12
- data/lib/occi/core/resource.rb +7 -3
- data/lib/occi/core/resources.rb +2 -2
- data/lib/occi/errors/attribute_definitions_converted_error.rb +5 -0
- data/lib/occi/errors/attribute_missing_error.rb +5 -0
- data/lib/occi/errors/attribute_name_invalid_error.rb +5 -0
- data/lib/occi/errors/attribute_not_defined_error.rb +5 -0
- data/lib/occi/errors/attribute_property_type_error.rb +5 -0
- data/lib/occi/errors/attribute_type_error.rb +5 -0
- data/lib/occi/errors/kind_not_defined_error.rb +5 -0
- data/lib/occi/errors/parser_input_error.rb +5 -0
- data/lib/occi/errors/parser_type_error.rb +5 -0
- data/lib/occi/errors.rb +1 -0
- data/lib/occi/extensions/hashie.rb +25 -0
- data/lib/occi/helpers/comparators/action_instance.rb +22 -0
- data/lib/occi/helpers/comparators/attributes.rb +22 -0
- data/lib/occi/helpers/comparators/categories.rb +22 -0
- data/lib/occi/helpers/comparators/category.rb +22 -0
- data/lib/occi/helpers/comparators/collection.rb +40 -0
- data/lib/occi/helpers/comparators/entities.rb +22 -0
- data/lib/occi/helpers/comparators/entity.rb +22 -0
- data/lib/occi/helpers/comparators/properties.rb +26 -0
- data/lib/occi/helpers/comparators.rb +1 -0
- data/lib/occi/infrastructure/compute.rb +11 -9
- data/lib/occi/infrastructure/network.rb +27 -27
- data/lib/occi/infrastructure/networkinterface.rb +22 -23
- data/lib/occi/infrastructure/os_tpl.rb +1 -1
- data/lib/occi/infrastructure/resource_tpl.rb +1 -1
- data/lib/occi/infrastructure/storage.rb +7 -6
- data/lib/occi/infrastructure/storagelink.rb +4 -4
- data/lib/occi/log.rb +13 -10
- data/lib/occi/model.rb +9 -8
- data/lib/occi/parser/json.rb +11 -9
- data/lib/occi/parser/ova.rb +12 -6
- data/lib/occi/parser/ovf.rb +173 -116
- data/lib/occi/parser/text/constants.rb +87 -0
- data/lib/occi/parser/text.rb +161 -200
- data/lib/occi/parser/xml.rb +10 -8
- data/lib/occi/parser.rb +100 -50
- data/lib/occi/settings.rb +2 -1
- data/lib/occi/version.rb +1 -1
- data/lib/occi-core.rb +6 -4
- data/occi-core.gemspec +0 -7
- data/spec/occi/collection_samples/collection1.json +1 -0
- data/spec/occi/collection_samples/directory2/collection2.json +1 -0
- data/spec/occi/collection_spec.rb +961 -31
- data/spec/occi/core/action_instance_spec.rb +317 -0
- data/spec/occi/core/action_spec.rb +71 -0
- data/spec/occi/core/attributes_spec.rb +582 -27
- data/spec/occi/core/category_spec.rb +194 -18
- data/spec/occi/core/entities_spec.rb +96 -0
- data/spec/occi/core/entity_spec.rb +317 -28
- data/spec/occi/core/kind_spec.rb +127 -16
- data/spec/occi/core/link_spec.rb +35 -0
- data/spec/occi/core/links_spec.rb +130 -0
- data/spec/occi/core/mixins_spec.rb +107 -0
- data/spec/occi/core/properties_spec.rb +167 -0
- data/spec/occi/core/resource_spec.rb +23 -9
- data/spec/occi/core_spec.rb +12 -0
- data/spec/occi/infrastructure/compute_spec.rb +218 -18
- data/spec/occi/infrastructure/network_spec.rb +96 -0
- data/spec/occi/infrastructure/networkinterface_spec.rb +96 -0
- data/spec/occi/infrastructure/storage_spec.rb +33 -0
- data/spec/occi/infrastructure/storagelink_spec.rb +45 -0
- data/spec/occi/log_spec.rb +104 -1
- data/spec/occi/model_spec.rb +251 -39
- data/spec/occi/{test.json → parser/json_samples/test.json} +0 -0
- data/spec/occi/parser/ova_samples/test.dump +0 -0
- data/spec/occi/{test.ova → parser/ova_samples/test.ova} +0 -0
- data/spec/occi/parser/ovf_samples/test.dump +0 -0
- data/spec/occi/{test.ovf → parser/ovf_samples/test.ovf} +0 -0
- data/spec/occi/parser/text_samples/occi_categories.dump +0 -0
- data/spec/occi/parser/text_samples/occi_categories.text +2 -0
- data/spec/occi/parser/text_samples/occi_compute_rocci_server.dump +0 -0
- data/spec/occi/parser/text_samples/occi_compute_rocci_server.resource.dump +0 -0
- data/spec/occi/parser/text_samples/occi_compute_rocci_server.text +10 -0
- data/spec/occi/parser/text_samples/occi_link_resource_instance.dump +0 -0
- data/spec/occi/parser/text_samples/occi_link_resource_instance.text +7 -0
- data/spec/occi/parser/text_samples/occi_link_simple.dump +0 -0
- data/spec/occi/parser/text_samples/occi_link_simple.link_string.dump +0 -0
- data/spec/occi/parser/text_samples/occi_link_simple.text +1 -0
- data/spec/occi/parser/text_samples/occi_link_w_attributes.dump +0 -0
- data/spec/occi/parser/text_samples/occi_link_w_attributes.text +7 -0
- data/spec/occi/parser/text_samples/occi_link_w_category.dump +0 -0
- data/spec/occi/parser/text_samples/occi_link_w_category.text +3 -0
- data/spec/occi/parser/text_samples/occi_model_rocci_server.dump +0 -0
- data/spec/occi/parser/text_samples/occi_model_rocci_server.text +51 -0
- data/spec/occi/parser/text_samples/occi_network_rocci_server.dump +0 -0
- data/spec/occi/parser/text_samples/occi_network_rocci_server.resource.dump +0 -0
- data/spec/occi/parser/text_samples/occi_network_rocci_server.text +11 -0
- data/spec/occi/parser/text_samples/occi_resource_w_attributes.dump +0 -0
- data/spec/occi/parser/text_samples/occi_resource_w_attributes.text +11 -0
- data/spec/occi/parser/text_samples/occi_resource_w_inline_links.dump +0 -0
- data/spec/occi/parser/text_samples/occi_resource_w_inline_links.text +16 -0
- data/spec/occi/parser/text_samples/occi_resource_w_inline_links_only.dump +0 -0
- data/spec/occi/parser/text_samples/occi_resource_w_inline_links_only.text +13 -0
- data/spec/occi/parser/text_samples/occi_storage_rocci_server.dump +0 -0
- data/spec/occi/parser/text_samples/occi_storage_rocci_server.resource.dump +0 -0
- data/spec/occi/parser/text_samples/occi_storage_rocci_server.text +9 -0
- data/spec/occi/parser/text_spec.rb +274 -78
- data/spec/occi/parser/xml_samples/test.xml +352 -0
- data/spec/occi/parser_spec.rb +255 -104
- data/spec/occi-core_spec.rb +31 -0
- data/spec/spec_helper.rb +6 -2
- metadata +110 -111
- checksums.yaml +0 -7
- data/spec/occi/core/attribute_spec.rb +0 -0
|
@@ -2,41 +2,596 @@ module Occi
|
|
|
2
2
|
module Core
|
|
3
3
|
describe Attributes do
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
attributes
|
|
7
|
-
|
|
8
|
-
|
|
5
|
+
context '#[]=' do
|
|
6
|
+
let(:attributes){ Occi::Core::Attributes.new }
|
|
7
|
+
it 'stores properties using hashes in hash notation' do
|
|
8
|
+
attributes['test']={}
|
|
9
|
+
expect(attributes['test']).to be_kind_of Occi::Core::Properties
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
it 'stores properties using hashes in dot notation' do
|
|
13
|
+
attributes.test={}
|
|
14
|
+
expect(attributes.test).to be_kind_of Occi::Core::Properties
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
it 'rejects keys starting with underscores' do
|
|
18
|
+
expect{ attributes['_test']={} }.to raise_error(Occi::Errors::AttributeNameInvalidError)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
it 'accepts keys with underscores in other positions' do
|
|
22
|
+
expect{ attributes['t_est']={} }.to_not raise_error(Occi::Errors::AttributeNameInvalidError)
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
context '#remove' do
|
|
27
|
+
it 'removes attributes' do
|
|
28
|
+
attributes=Occi::Core::Attributes.new
|
|
29
|
+
attributes['one.two']={}
|
|
30
|
+
attributes['one.three']={}
|
|
31
|
+
|
|
32
|
+
attr=Occi::Core::Attributes.new
|
|
33
|
+
attr['one.two']={}
|
|
34
|
+
attributes.remove attr
|
|
35
|
+
|
|
36
|
+
expect(attributes['one.two']).to be_nil
|
|
37
|
+
expect(attributes['one.three']).to be_kind_of Occi::Core::Properties
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
context '#convert' do
|
|
42
|
+
it 'converts properties to an empty attribute' do
|
|
43
|
+
attributes=Occi::Core::Attributes.new
|
|
44
|
+
attributes.test={}
|
|
45
|
+
|
|
46
|
+
attr = attributes.convert
|
|
47
|
+
expect(attributes.test).to be_kind_of Occi::Core::Properties
|
|
48
|
+
|
|
49
|
+
expect(attr.test).to be_nil
|
|
50
|
+
expect(attr._test).to be_kind_of Occi::Core::Properties
|
|
51
|
+
|
|
52
|
+
attributes.convert!
|
|
53
|
+
expect(attributes.test).to be_nil
|
|
54
|
+
expect(attributes._test).to be_kind_of Occi::Core::Properties
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
context 'comparators' do
|
|
59
|
+
let(:attrs){
|
|
60
|
+
attrs = Occi::Core::Attributes.new
|
|
61
|
+
attrs['numbertype'] = { :type => 'number', :default => 42, :mutable => true, :pattern => '^[0-9]+' }
|
|
62
|
+
attrs['stringtype'] = { :type => 'string', :pattern => '[adefltuv]+', :default => 'defaultvalue', :mutable => true }
|
|
63
|
+
attrs['booleantype'] = { :type => 'boolean', :default => true, :mutable => true}
|
|
64
|
+
attrs['booleantypefalse'] = { :type => 'boolean', :default => false, :mutable => true }
|
|
65
|
+
attrs['booleantypepattern'] = { :type => 'boolean', :default => true, :mutable => true, :pattern => true }
|
|
66
|
+
attrs }
|
|
67
|
+
let(:clone){ clone = attrs.clone }
|
|
68
|
+
let(:newattrs){
|
|
69
|
+
newattrs = Occi::Core::Attributes.new
|
|
70
|
+
newattrs['numbertype'] = { :type => 'number', :default => 42, :mutable => true, :pattern => '^[0-9]+' }
|
|
71
|
+
newattrs['stringtype'] = { :type => 'string', :pattern => '[adefltuv]+', :default => 'defaultvalue', :mutable => true }
|
|
72
|
+
newattrs['booleantype'] = { :type => 'boolean', :default => true, :mutable => true}
|
|
73
|
+
newattrs['booleantypefalse'] = { :type => 'boolean', :default => false, :mutable => true }
|
|
74
|
+
newattrs['booleantypepattern'] = { :type => 'boolean', :default => true, :mutable => true, :pattern => true }
|
|
75
|
+
newattrs }
|
|
76
|
+
let(:diffattrs){
|
|
77
|
+
diffattrs = Occi::Core::Attributes.new
|
|
78
|
+
diffattrs['numbertype'] = { :type => 'number', :default => 42, :mutable => true, :pattern => '^[0-9]+' }
|
|
79
|
+
diffattrs['stringtype'] = { :type => 'string', :pattern => '[adefltuv]+', :default => 'anothervalue', :mutable => true } # <=
|
|
80
|
+
diffattrs['booleantype'] = { :type => 'boolean', :default => true, :mutable => true}
|
|
81
|
+
diffattrs['booleantypefalse'] = { :type => 'boolean', :default => false, :mutable => true }
|
|
82
|
+
diffattrs['booleantypepattern'] = { :type => 'boolean', :default => true, :mutable => true, :pattern => true }
|
|
83
|
+
diffattrs }
|
|
84
|
+
|
|
85
|
+
context '#==' do
|
|
86
|
+
it 'matches the same instance' do
|
|
87
|
+
expect(attrs==attrs).to eql true
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
it 'matches a clone' do
|
|
91
|
+
expect(attrs==clone).to eql true
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
it 'matches a new instance with the same content' do
|
|
95
|
+
expect(attrs==newattrs).to eql true
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
it 'does not match nil' do
|
|
99
|
+
expect(attrs==nil).to eql false
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
it 'does not match an instance with different content' do
|
|
103
|
+
expect(attrs==diffattrs).to eql false
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
context '#eql?' do
|
|
108
|
+
it 'matches the same instance' do
|
|
109
|
+
expect(attrs.eql?(attrs)).to eql true
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
it 'matches a clone' do
|
|
113
|
+
expect(attrs.eql?(clone)).to eql true
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
it 'matches a new instance with the same content' do
|
|
117
|
+
expect(attrs.eql?(newattrs)).to eql true
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
it 'does not match nil' do
|
|
121
|
+
expect(attrs.eql?(nil)).to eql false
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
it 'does not match an instance with different content' do
|
|
125
|
+
expect(attrs.eql?(diffattrs)).to eql false
|
|
126
|
+
end
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
context '#equal?' do
|
|
130
|
+
it 'matches the same instance' do
|
|
131
|
+
expect(attrs.equal?(attrs)).to eql true
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
it 'does not match a clone' do
|
|
135
|
+
expect(attrs.equal?(clone)).to eql false
|
|
136
|
+
end
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
context '#hash' do
|
|
140
|
+
it 'matches for the same instance' do
|
|
141
|
+
expect(attrs.hash).to eql attrs.hash
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
it 'matches for a clone' do
|
|
145
|
+
expect(attrs.hash).to eql clone.hash
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
it 'matches for a new instance with the same content' do
|
|
149
|
+
expect(attrs.hash).to eql newattrs.hash
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
it 'does not match for an instance with different content' do
|
|
153
|
+
expect(attrs.hash).to_not eql diffattrs.hash
|
|
154
|
+
end
|
|
155
|
+
end
|
|
9
156
|
end
|
|
10
157
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
158
|
+
context '#converted?' do
|
|
159
|
+
let(:attrs){ attrs = Occi::Core::Attributes.new
|
|
160
|
+
attrs['numbertype'] = { :type => 'number', :default => 42, :mutable => true, :pattern => '^[0-9]+' }
|
|
161
|
+
attrs }
|
|
162
|
+
|
|
163
|
+
it 'correctly reports uncoverted' do
|
|
164
|
+
expect(attrs.converted?).to eql false
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
it 'correctly reports coverted' do
|
|
168
|
+
expect(attrs.convert.converted?).to eql true
|
|
169
|
+
end
|
|
15
170
|
end
|
|
16
171
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
172
|
+
|
|
173
|
+
context 'rendering' do
|
|
174
|
+
let(:attrs){ attrs = Occi::Core::Attributes.new
|
|
175
|
+
attrs['numbertype'] = { :type => 'number', :default => 42, :mutable => true, :pattern => '^[0-9]+' }
|
|
176
|
+
attrs['stringtype'] = { :type => 'string', :pattern => '[adefltuv]+', :default => 'defaultvalue', :mutable => true }
|
|
177
|
+
attrs['booleantype'] = { :type => 'boolean', :default => true, :mutable => true}
|
|
178
|
+
attrs['booleantypefalse'] = { :type => 'boolean', :default => false, :mutable => true }
|
|
179
|
+
attrs['booleantypepattern'] = { :type => 'boolean', :default => true, :mutable => true, :pattern => true }
|
|
180
|
+
attrs.nest!.nested = { :type => 'number', :default => 42, :mutable => true, :pattern => '^[0-9]+' }
|
|
181
|
+
attrs['properties'] = Occi::Core::Properties.new
|
|
182
|
+
attrs.convert
|
|
183
|
+
attrs['numbertype'] = 42
|
|
184
|
+
attrs['stringtype'] = 'flute'
|
|
185
|
+
attrs['booleantype'] = true
|
|
186
|
+
attrs['booleantypefalse'] = false
|
|
187
|
+
attrs['booleantypepattern'] = true
|
|
188
|
+
attrs.nest!.nested = 11
|
|
189
|
+
attrs['category'] = Occi::Core::Category.new
|
|
190
|
+
attrs['properties'] = "prop"
|
|
191
|
+
attrs['entity'] = Occi::Core::Entity.new
|
|
192
|
+
attrs['entity'].id = "testid"
|
|
193
|
+
attrs }
|
|
194
|
+
let(:empty){ Occi::Core::Attributes.new.convert }
|
|
195
|
+
|
|
196
|
+
context '.parse_properties' do
|
|
197
|
+
|
|
198
|
+
it 'rejects unsuitable types' do
|
|
199
|
+
string = String.new("Teststring")
|
|
200
|
+
expect{ Occi::Core::Attributes.parse_properties(string) }.to raise_error(Occi::Errors::ParserInputError)
|
|
201
|
+
end
|
|
202
|
+
|
|
203
|
+
it 'parses a hashie Mash' do
|
|
204
|
+
hash = { :nr => {} }
|
|
205
|
+
hash[:nr][:type] = 'number'
|
|
206
|
+
hash[:nr][:default] = 42
|
|
207
|
+
hash[:nr][:mutable] = true
|
|
208
|
+
|
|
209
|
+
expected = Occi::Core::Attributes.new
|
|
210
|
+
expected['nr'] = { :type => 'number', :default => 42, :mutable => true }
|
|
211
|
+
expected.convert
|
|
212
|
+
|
|
213
|
+
attrs = Occi::Core::Attributes.parse_properties(hash)
|
|
214
|
+
attrs.convert
|
|
215
|
+
|
|
216
|
+
expect(attrs).to eql expected
|
|
217
|
+
end
|
|
218
|
+
end
|
|
219
|
+
|
|
220
|
+
context '#to_string' do
|
|
221
|
+
it 'renders attributes correctly' do
|
|
222
|
+
expected = ";numbertype=42;stringtype=\"flute\";booleantype=true;booleantypefalse=false;booleantypepattern=true;nest.nested=11;properties=\"prop\";category=\"http://schemas.ogf.org/occi/core#category\";entity=\"/entity/testid\""
|
|
223
|
+
expect(attrs.to_string).to eql expected
|
|
224
|
+
end
|
|
225
|
+
|
|
226
|
+
it 'copes with empty attributes' do
|
|
227
|
+
expected = ""
|
|
228
|
+
expect(empty.to_string).to eql expected
|
|
229
|
+
end
|
|
230
|
+
end
|
|
231
|
+
|
|
232
|
+
context '#to_string_short' do
|
|
233
|
+
it 'renders attributes correctly' do
|
|
234
|
+
expected = ";attributes=\"numbertype stringtype booleantype booleantypefalse booleantypepattern nest.nested properties category entity\""
|
|
235
|
+
expect(attrs.to_string_short).to eql expected
|
|
236
|
+
end
|
|
237
|
+
|
|
238
|
+
it 'copes with empty attributes' do
|
|
239
|
+
expected = ""
|
|
240
|
+
expect(empty.to_string_short).to eql expected
|
|
241
|
+
end
|
|
242
|
+
end
|
|
243
|
+
|
|
244
|
+
context '#to_text' do
|
|
245
|
+
it 'renders attributes correctly' do
|
|
246
|
+
expected = "\nX-OCCI-Attribute: numbertype=42\nX-OCCI-Attribute: stringtype=\"flute\"\nX-OCCI-Attribute: booleantype=true\nX-OCCI-Attribute: booleantypefalse=false\nX-OCCI-Attribute: booleantypepattern=true\nX-OCCI-Attribute: nest.nested=11\nX-OCCI-Attribute: properties=\"prop\"\nX-OCCI-Attribute: category=\"http://schemas.ogf.org/occi/core#category\"\nX-OCCI-Attribute: entity=\"/entity/testid\""
|
|
247
|
+
expect(attrs.to_text).to eql expected
|
|
248
|
+
end
|
|
249
|
+
|
|
250
|
+
it 'copes with empty attributes' do
|
|
251
|
+
expected = ""
|
|
252
|
+
expect(empty.to_text).to eql expected
|
|
253
|
+
end
|
|
254
|
+
end
|
|
255
|
+
|
|
256
|
+
context '#to_header' do
|
|
257
|
+
it 'renders attributes correctly' do
|
|
258
|
+
expected = "numbertype=42,stringtype=\"flute\",booleantype=true,booleantypefalse=false,booleantypepattern=true,nest.nested=11,properties=\"prop\",category=\"http://schemas.ogf.org/occi/core#category\",entity=\"/entity/testid\""
|
|
259
|
+
expect(attrs.to_header).to eql expected
|
|
260
|
+
end
|
|
261
|
+
|
|
262
|
+
it 'copes with empty attributes' do
|
|
263
|
+
expected = ""
|
|
264
|
+
expect(empty.to_header).to eql expected
|
|
265
|
+
end
|
|
266
|
+
end
|
|
267
|
+
|
|
268
|
+
context '#to_json' do
|
|
269
|
+
it 'renders attributes correctly' do
|
|
270
|
+
expected = '{"numbertype":42,"stringtype":"flute","booleantype":true,"booleantypefalse":false,"booleantypepattern":true,"nest":{"nested":11},"properties":"prop","category":"http://schemas.ogf.org/occi/core#category","entity":"/entity/testid"}'
|
|
271
|
+
expect(attrs.to_json).to eql expected
|
|
272
|
+
end
|
|
273
|
+
|
|
274
|
+
it 'copes with empty attributes' do
|
|
275
|
+
expected = "{}"
|
|
276
|
+
expect(empty.to_json).to eql expected
|
|
277
|
+
end
|
|
278
|
+
end
|
|
279
|
+
|
|
280
|
+
context '#as_json' do
|
|
281
|
+
it 'renders attributes correctly' do
|
|
282
|
+
expected = Hashie::Mash.new
|
|
283
|
+
expected["booleantype"] = true
|
|
284
|
+
expected["booleantypepattern"] = true
|
|
285
|
+
expected["numbertype"] = 42
|
|
286
|
+
expected["stringtype"] = "flute"
|
|
287
|
+
expected["booleantypefalse"] = false
|
|
288
|
+
expected.nest!.nested = 11
|
|
289
|
+
expected["category"] = "http://schemas.ogf.org/occi/core#category"
|
|
290
|
+
expected["properties"] = "prop"
|
|
291
|
+
expected["entity"] = "/entity/testid"
|
|
292
|
+
|
|
293
|
+
expect(attrs.as_json).to eql expected
|
|
294
|
+
end
|
|
295
|
+
|
|
296
|
+
it 'copes with empty attributes' do
|
|
297
|
+
expected = Hashie::Mash.new
|
|
298
|
+
expect(empty.as_json).to eql expected
|
|
299
|
+
end
|
|
300
|
+
end
|
|
26
301
|
end
|
|
27
302
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
303
|
+
context '.check!' do
|
|
304
|
+
let(:attrs){ attrs = Occi::Core::Attributes.new }
|
|
305
|
+
|
|
306
|
+
let(:defs){
|
|
307
|
+
defs = Occi::Core::Attributes.new
|
|
308
|
+
defs['numbertype'] = { :type => 'number',
|
|
309
|
+
:default => 42,
|
|
310
|
+
:mutable => true,
|
|
311
|
+
:pattern => '^[0-9]+' }
|
|
312
|
+
defs['stringtype'] = { :type => 'string',
|
|
313
|
+
:pattern => '[adefltuv]+',
|
|
314
|
+
:default => 'defaultvalue',
|
|
315
|
+
:mutable => true }
|
|
316
|
+
defs['booleantype'] = { :type => 'boolean',
|
|
317
|
+
:default => true,
|
|
318
|
+
:mutable => true}
|
|
319
|
+
defs['booleantypefalse'] = { :type => 'boolean', #Regression test
|
|
320
|
+
:default => false,
|
|
321
|
+
:mutable => true }
|
|
322
|
+
defs['booleantypepattern'] = { :type => 'boolean',
|
|
323
|
+
:default => true,
|
|
324
|
+
:mutable => true,
|
|
325
|
+
:pattern => true }
|
|
326
|
+
defs['nonmandatory'] = { :type => 'string',
|
|
327
|
+
:mutable => true,
|
|
328
|
+
:required => false }
|
|
329
|
+
defs }
|
|
330
|
+
|
|
331
|
+
context 'unsupported types and attributes' do
|
|
332
|
+
before(:each){ Occi::Settings['compatibility']=false
|
|
333
|
+
Occi::Settings['verify_attribute_pattern']=true }
|
|
334
|
+
after(:each) { Occi::Settings.reload! }
|
|
335
|
+
it 'refuses undefined attribute' do
|
|
336
|
+
attrs['otherstring'] = { :type => 'string', :pattern => '[adefltuv]+', :default => 'defaultvalue', :mutable => true }
|
|
337
|
+
expect{attrs.check! defs, true}.to raise_exception(Occi::Errors::AttributeNotDefinedError)
|
|
338
|
+
end
|
|
339
|
+
|
|
340
|
+
it 'refuses unsupported type' do
|
|
341
|
+
expect{ defs['unsupported'] = { :type => 'float', :mutable => true } }.to raise_exception(Occi::Errors::AttributePropertyTypeError)
|
|
342
|
+
end
|
|
343
|
+
end
|
|
344
|
+
|
|
345
|
+
context 'nonmandatory attributes' do
|
|
346
|
+
it 'removes nil attribute' do
|
|
347
|
+
attrs['nonmandatory'] = nil
|
|
348
|
+
attrs.check!(defs, true)
|
|
349
|
+
expect(attrs.key?('nonmandatory')).to eql false
|
|
350
|
+
end
|
|
351
|
+
|
|
352
|
+
it 'raises error for unknown attribute with non-nil value' do
|
|
353
|
+
attrs['undefined'] = "undefined"
|
|
354
|
+
expect{ attrs.check!(defs, true) }.to raise_error(Occi::Errors::AttributeNotDefinedError)
|
|
355
|
+
end
|
|
356
|
+
end
|
|
357
|
+
|
|
358
|
+
context 'mandatory attributes' do
|
|
359
|
+
it 'no value and no default, set_defaults true' do
|
|
360
|
+
defs['nodefault'] = { :type => 'string', :mutable => true, :required => true }
|
|
361
|
+
expect{ attrs.check!(defs, true) }.to raise_error(Occi::Errors::AttributeMissingError)
|
|
362
|
+
end
|
|
363
|
+
|
|
364
|
+
it 'no value and no default, set_defaults false' do
|
|
365
|
+
defs['nodefault'] = { :type => 'string', :mutable => true, :required => true }
|
|
366
|
+
expect{ attrs.check!(defs, false) }.to raise_error(Occi::Errors::AttributeMissingError)
|
|
367
|
+
end
|
|
368
|
+
|
|
369
|
+
it 'nil value and no default, set_defaults true' do
|
|
370
|
+
defs['nodefault'] = { :type => 'string', :mutable => true, :required => true }
|
|
371
|
+
attrs['nodefault'] = nil
|
|
372
|
+
expect{ attrs.check!(defs, true) }.to raise_error(Occi::Errors::AttributeMissingError)
|
|
373
|
+
end
|
|
374
|
+
|
|
375
|
+
it 'nil value and no default, set_defaults false' do
|
|
376
|
+
defs['nodefault'] = { :type => 'string', :mutable => true, :required => true }
|
|
377
|
+
attrs['nodefault'] = nil
|
|
378
|
+
expect{ attrs.check!(defs, false) }.to raise_error(Occi::Errors::AttributeMissingError)
|
|
379
|
+
end
|
|
380
|
+
|
|
381
|
+
end
|
|
382
|
+
|
|
383
|
+
context 'unsupported attributes' do
|
|
384
|
+
before(:each){ Occi::Settings['compatibility']=false
|
|
385
|
+
Occi::Settings['verify_attribute_pattern']=true }
|
|
386
|
+
after(:each) { Occi::Settings.reload! }
|
|
387
|
+
it 'refuses attribute not mentioned in defs' do
|
|
388
|
+
attrs['otherstring'] = { :type => 'string',
|
|
389
|
+
:default => 'defaultvalue' }
|
|
390
|
+
expect{attrs.check! defs, true}.to raise_exception(Occi::Errors::AttributeNotDefinedError)
|
|
391
|
+
end
|
|
392
|
+
end
|
|
393
|
+
|
|
394
|
+
context 'defaults' do
|
|
395
|
+
before(:each){ Occi::Settings['compatibility']=false
|
|
396
|
+
Occi::Settings['verify_attribute_pattern']=true }
|
|
397
|
+
after(:each) { Occi::Settings.reload! }
|
|
398
|
+
|
|
399
|
+
context 'setting defaults' do
|
|
400
|
+
it 'sets numeric default' do
|
|
401
|
+
attrs.check! defs, true
|
|
402
|
+
expect(attrs['numbertype']).to eq 42
|
|
403
|
+
end
|
|
404
|
+
it 'sets string default' do
|
|
405
|
+
attrs.check! defs, true
|
|
406
|
+
expect(attrs['stringtype']).to eq 'defaultvalue'
|
|
407
|
+
end
|
|
408
|
+
it 'sets boolean default if true' do
|
|
409
|
+
attrs.check! defs, true
|
|
410
|
+
expect(attrs['booleantype']).to eq true
|
|
411
|
+
end
|
|
412
|
+
it 'sets boolean default if false' do
|
|
413
|
+
attrs.check! defs, true
|
|
414
|
+
expect(attrs['booleantypefalse']).to eq false
|
|
415
|
+
end
|
|
416
|
+
it 'can be checked twice in a row' do
|
|
417
|
+
attrs.check! defs, true
|
|
418
|
+
expect{ attrs.check! defs, true }.to_not raise_exception
|
|
419
|
+
end
|
|
420
|
+
end
|
|
421
|
+
|
|
422
|
+
context 'skipping defaults if already set' do
|
|
423
|
+
it 'skips numeric default' do
|
|
424
|
+
attrs['numbertype'] = 12
|
|
425
|
+
attrs.check! defs, true
|
|
426
|
+
expect(attrs['numbertype']).to eq 12
|
|
427
|
+
end
|
|
428
|
+
it 'skips string default' do
|
|
429
|
+
attrs['stringtype'] = 'fault'
|
|
430
|
+
attrs.check! defs, true
|
|
431
|
+
expect(attrs['stringtype']).to eq 'fault'
|
|
432
|
+
end
|
|
433
|
+
it 'skips boolean default if true' do
|
|
434
|
+
attrs['booleantype'] = false
|
|
435
|
+
attrs.check! defs, true
|
|
436
|
+
expect(attrs['booleantype']).to eq false
|
|
437
|
+
end
|
|
438
|
+
it 'skips boolean default if false' do
|
|
439
|
+
attrs['booleantypefalse'] = true
|
|
440
|
+
attrs.check! defs, true
|
|
441
|
+
expect(attrs['booleantypefalse']).to eq true
|
|
442
|
+
end
|
|
443
|
+
end
|
|
444
|
+
|
|
445
|
+
context 'skipping defaults if set_defaults is false' do
|
|
446
|
+
it 'skips numeric default' do
|
|
447
|
+
attrs.check! defs, false
|
|
448
|
+
expect(attrs['numbertype']).to_not eq 42
|
|
449
|
+
end
|
|
450
|
+
it 'skips string default' do
|
|
451
|
+
attrs.check! defs, false
|
|
452
|
+
expect(attrs['stringtype']).to_not eq 'defaultvalue'
|
|
453
|
+
end
|
|
454
|
+
it 'skips boolean default if true' do
|
|
455
|
+
attrs.check! defs, false
|
|
456
|
+
expect(attrs['booleantype']).to_not eq true
|
|
457
|
+
end
|
|
458
|
+
it 'skips boolean default if false' do
|
|
459
|
+
attrs.check! defs, false
|
|
460
|
+
expect(attrs['booleantypefalse']).to_not eq false
|
|
461
|
+
end
|
|
462
|
+
end
|
|
463
|
+
|
|
464
|
+
context 'patterns' do
|
|
465
|
+
it 'checks string pattern' do
|
|
466
|
+
attrs['stringtype'] = 'bflmpsvz'
|
|
467
|
+
expect{attrs.check! defs, true}.to raise_exception(Occi::Errors::AttributeTypeError)
|
|
468
|
+
end
|
|
469
|
+
it 'checks numeric pattern' do
|
|
470
|
+
attrs['numbertype'] = -32
|
|
471
|
+
expect{attrs.check! defs, true}.to raise_exception(Occi::Errors::AttributeTypeError)
|
|
472
|
+
end
|
|
473
|
+
it 'checks boolean pattern' do # Possibly an overkill
|
|
474
|
+
attrs['booleantypepattern'] = false
|
|
475
|
+
expect{attrs.check! defs, true}.to raise_exception(Occi::Errors::AttributeTypeError)
|
|
476
|
+
end
|
|
477
|
+
end
|
|
478
|
+
end
|
|
479
|
+
|
|
480
|
+
context 'calling through #check' do
|
|
481
|
+
before(:each){ Occi::Settings['compatibility']=false
|
|
482
|
+
Occi::Settings['verify_attribute_pattern']=true }
|
|
483
|
+
after(:each) { Occi::Settings.reload! }
|
|
484
|
+
|
|
485
|
+
context 'setting defaults' do
|
|
486
|
+
it 'sets numeric default' do
|
|
487
|
+
as = attrs.check defs, true
|
|
488
|
+
expect(as['numbertype']).to eq 42
|
|
489
|
+
end
|
|
490
|
+
it 'sets string default' do
|
|
491
|
+
as = attrs.check defs, true
|
|
492
|
+
expect(as['stringtype']).to eq 'defaultvalue'
|
|
493
|
+
end
|
|
494
|
+
it 'sets boolean default if true' do
|
|
495
|
+
as = attrs.check defs, true
|
|
496
|
+
expect(as['booleantype']).to eq true
|
|
497
|
+
end
|
|
498
|
+
it 'sets boolean default if false' do
|
|
499
|
+
as = attrs.check defs, true
|
|
500
|
+
expect(as['booleantypefalse']).to eq false
|
|
501
|
+
end
|
|
502
|
+
end
|
|
503
|
+
end
|
|
504
|
+
|
|
505
|
+
context 'converted definitions' do
|
|
506
|
+
it 'succeeds for unconverted definitions' do
|
|
507
|
+
expect{attrs.check! defs, true}.to_not raise_exception
|
|
508
|
+
end
|
|
509
|
+
|
|
510
|
+
it 'throws exception for converted definitions' do
|
|
511
|
+
defs.convert!
|
|
512
|
+
expect{attrs.check! defs, true}.to raise_exception(Occi::Errors::AttributeDefinitionsConvrertedError)
|
|
513
|
+
end
|
|
514
|
+
end
|
|
38
515
|
end
|
|
39
516
|
|
|
517
|
+
|
|
518
|
+
context '.validate_and_assign' do
|
|
519
|
+
let(:attrs){ Occi::Core::Attributes.new }
|
|
520
|
+
|
|
521
|
+
it 'correctly accepts Occi::Core::Attributes' do
|
|
522
|
+
inattrs = Occi::Core::Attributes.new
|
|
523
|
+
inattrs['numbertype'] = { :type => 'number', :default => 42, :mutable => true, :pattern => '^[0-9]+' }
|
|
524
|
+
inattrs.convert
|
|
525
|
+
inattrs['numbertype'] = 13
|
|
526
|
+
|
|
527
|
+
attrs['numbertype'] = inattrs['numbertype']
|
|
528
|
+
expect(attrs).to eql inattrs
|
|
529
|
+
end
|
|
530
|
+
|
|
531
|
+
it 'correctly accepts Occi::Core::Properties' do
|
|
532
|
+
attrs['properties'] = Occi::Core::Properties.new
|
|
533
|
+
|
|
534
|
+
expected = Occi::Core::Attributes.new
|
|
535
|
+
expected['properties'] = { :type => 'string', :pattern => '.*', :mutable => false, :required => false }
|
|
536
|
+
expected.convert
|
|
537
|
+
|
|
538
|
+
expect(attrs).to eql expected
|
|
539
|
+
end
|
|
540
|
+
|
|
541
|
+
it 'correctly accepts Hash' do
|
|
542
|
+
attrs['hash'] = { :type => 'string', :pattern => '.*', :mutable => false, :required => false }
|
|
543
|
+
|
|
544
|
+
expected = Occi::Core::Attributes.new
|
|
545
|
+
expected['hash'] = { :type => 'string', :pattern => '.*', :mutable => false, :required => false }
|
|
546
|
+
expected.convert
|
|
547
|
+
|
|
548
|
+
expect(attrs).to eql expected
|
|
549
|
+
end
|
|
550
|
+
|
|
551
|
+
it 'correctly accepts Occi::Core::Entity' do
|
|
552
|
+
entity = Occi::Core::Entity.new
|
|
553
|
+
attrs['entity'] = entity
|
|
554
|
+
|
|
555
|
+
expect(attrs['entity']).to eql entity
|
|
556
|
+
end
|
|
557
|
+
|
|
558
|
+
it 'correctly accepts Occi::Core::Category' do
|
|
559
|
+
category = Occi::Core::Category.new
|
|
560
|
+
attrs['category'] = category
|
|
561
|
+
|
|
562
|
+
expect(attrs['category']).to eql category
|
|
563
|
+
end
|
|
564
|
+
|
|
565
|
+
it 'correctly accepts String' do
|
|
566
|
+
attrs['string'] = "teststring"
|
|
567
|
+
expect(attrs['string']).to eql "teststring"
|
|
568
|
+
end
|
|
569
|
+
|
|
570
|
+
it 'correctly accepts Numeric' do
|
|
571
|
+
attrs['numeric'] = 16
|
|
572
|
+
expect(attrs['numeric']).to eql 16
|
|
573
|
+
end
|
|
574
|
+
|
|
575
|
+
it 'correctly accepts TrueClass' do
|
|
576
|
+
attrs['tr'] = true
|
|
577
|
+
expect(attrs['tr']).to eql true
|
|
578
|
+
end
|
|
579
|
+
|
|
580
|
+
it 'correctly accepts FalseClass' do
|
|
581
|
+
attrs['fal'] = false
|
|
582
|
+
expect(attrs['fal']).to eql false
|
|
583
|
+
end
|
|
584
|
+
|
|
585
|
+
it 'correctly responds to NilClass' do
|
|
586
|
+
attrs['nil'] = nil
|
|
587
|
+
expect(attrs['nil']).to eql nil
|
|
588
|
+
end
|
|
589
|
+
|
|
590
|
+
it 'rejects unsupported types' do
|
|
591
|
+
type = Occi::Log.new(nil)
|
|
592
|
+
expect{ attrs['log'] = type }.to raise_error(Occi::Errors::AttributeTypeError)
|
|
593
|
+
end
|
|
594
|
+
end
|
|
40
595
|
end
|
|
41
596
|
end
|
|
42
597
|
end
|