Hi Michal,
I tried this patch and it gave the following error when I tried to
retrieve system templates from the fgcp:
E, [2013-03-26T22:51:05.100517 #1940] ERROR -- 502:
[Deltacloud::Exceptions::ProviderError] The
CIMI::Model::MachineConfigurationRef must be initialized using Hash or
CIMI::Resource (is #<CIMI::Service::MachineConfiguration:0x411ae30
@model=#<CIMI::Model::MachineConfiguration:0x411ad70 @select_attrs=[],
@base_id="http:
//localhost:3001/cimi/machine_configurations/economy",
@attribute_values={:id=>"http://localhost:3001/cimi/machine_configuratio
ns/economy", :name=>"economy", :d
escription=>"Machine Configuration with 1782579 KiB of memory and 1
CPU", :created=>"2013-03-26T22:51:04+11:00", :updated=>nil,
:property=>nil, :cpu=>"1", :memo
ry=>1782579, :disks=>nil, :operations=>nil}>,
@context=#<CIMI::Collections::SystemTemplates:0x2de9bf8
@default_layout=:layout, @app=#<struct Sinatra::ExtendedRa
ck app=#<Rack::MethodOverride:0x4115580 @app=#<Rack::Head:0x4115598
@app=#<Rack::NullLogger:0x41155c8
@app=#<Rack::Protection::FrameOptions:0x4115670 @app=#<Rac
k::Protection::HttpOrigin:0x41156b8
@app=#<Rack::Protection::IPSpoofing:0x4115718
@app=#<Rack::Protection::JsonCsrf:0x4115760
@app=#<Rack::Protection::PathTrave
rsal:0x41157a8 @app=#<Rack::Protection::XSSHeader:0x4115820
@app=#<Rack::Accept::Context:0x4115c88 @app=#<struct
Sinatra::ExtendedRack app=#<Sinatra::ShowExcept
ions:0x2e11f90 @app=#<Rack::Head:0x2e11fc0
@app=#<Rack::NullLogger:0x2e11fd8
@app=#<Rack::Protection::FrameOptions:0x2e12140
@app=#<Rack::Protection::HttpOrigin
:0x2e12260 @app=#<Rack::Protection::IPSpoofing:0x2e122c0
@app=#<Rack::Protection::JsonCsrf:0x2e12350
@app=#<Rack::Protection::PathTraversal:0x2e123b0 @app=#<Rac
k::Protection::XSSHeader:0x2e12440 @app=#<Rack::MediaType:0x2e128c0
@default_layout=:layout, @app=#<struct Sinatra::ExtendedRack
app=#<Sinatra::ShowExceptions:0
x2dfe868 @app=#<Rack::Head:0x2dfe880 @app=#<Rack::NullLogger:0x2dfe898
@app=#<Rack::Protection::FrameOptions:0x2dfe970
@app=#<Rack::Protection::HttpOrigin:0x2df
e9e8 @app=#<Rack::Protection::IPSpoofing:0x2dfea48
@app=#<Rack::Protection::JsonCsrf:0x2dfead8
@app=#<Rack::Protection::PathTraversal:0x2dfeb68 @app=#<Rack::Pro
tection::XSSHeader:0x2dfecd0
@app=#<CIMI::Rabbit::VolumesCollection:0x2df7ec0
@default_layout=:layout, @app=#<CIMI::Collections::Volumes:0x2df87f0
@default_layo
ut=:layout, @app=#<struct Sinatra::ExtendedRack
app=#<Rack::MethodOverride:0x2df8df0 @app=#<Rack::Head:0x2df9000
@app=#<Rack::NullLogger:0x2df9048 @app=#<Rack::
Protection::FrameOptions:0x2df90d8
@app=#<Rack::Protection::HttpOrigin:0x2df9150
@app=#<Rack::Protection::IPSpoofing:0x2df91c8
@app=#<Rack::Protection::JsonCsrf
:0x2df9228 @app=#<Rack::Protection::PathTraversal:0x2df9288
@app=#<Rack::Protection::XSSHeader:0x2df9300
@app=#<Rack::Accept::Context:0x2df9690 @app=#<struct Si
natra::ExtendedRack app=#<Sinatra::ShowExceptions:0x2dd87c8
@app=#<Rack::Head:0x2dd87f8 @app=#<Rack::NullLogger:0x2dd8810
@app=#<Rack::Protection::FrameOptions:
0x2dd89a8 @app=#<Rack::Protection::HttpOrigin:0x2dd8b88
@app=#<Rack::Protection::IPSpoofing:0x2dd8bd0
@app=#<Rack::Protection::JsonCsrf:0x2dd8e28 @app=#<Rack::P
rotection::PathTraversal:0x2dd8e88
@app=#<Rack::Protection::XSSHeader:0x2dd8f18
@app=#<Rack::MediaType:0x2dd9638 @default_layout=:layout, @app=#<struct
Sinatra:
:ExtendedRack app=#<Sinatra::ShowExceptions:0x2db9b50
@app=#<Rack::Head:0x2db9b80 @app=#<Rack::NullLogger:0x2db9bc8
@app=#<Rack::Protection::FrameOptions:0x2db9
c58 @app=#<Rack::Protection::HttpOrigin:0x2db9d00
@app=#<Rack::Protection::IPSpoofing:0x2db9d60
@app=#<Rack::Protection::JsonCsrf:0x2db9da8 @app=#<Rack::Protect
ion::PathTraversal:0x2db9e38
@app=#<Rack::Protection::XSSHeader:0x2db9ee0
@app=#<CIMI::Rabbit::VolumeConfigurationsCollection:0x2dba480
@default_layout=:layout,
@app=#<CIMI::Collections::VolumeConfigurations:0x2dba8b8
@default_layout=:layout, @app=#<struct Sinatra::ExtendedRack
app=#<Rack::MethodOverride:0x2db3268 @app
=#<Rack::Head:0x2db3280 @app=#<Rack::NullLogger:0x2db3310
@app=#<Rack::Protection::FrameOptions:0x2db3448
@app=#<Rack::Protection::HttpOrigin:0x2db3508 @app=#<R
ack::Protection::IPSpoofing:0x2db3658
@app=#<Rack::Protection::JsonCsrf:0x2db36b8
@app=#<Rack::Protection::PathTraversal:0x2db3760
@app=#<Rack::Protection::XSSH
eader:0x2db3868 @app=#<Rack::Accept::Context:0x2db4240 @app=#<struct
Sinatra::ExtendedRack app=#<Sinatra::ShowExceptions:0x2d231d8
@app=#<Rack::Head:0x2d23250 @
app=#<Rack::NullLogger:0x2d23268
@app=#<Rack::Protection::FrameOptions:0x2d234a8
@app=#<Rack::Protection::HttpOrigin:0x2d23610
@app=#<Rack::Protection::IPSpoofi
ng:0x2d236a0 @app=#<Rack::Protection::JsonCsrf:0x2d237c0
@app=#<Rack::Protection::PathTraversal:0x2d238f8
@app=#<Rack::Protection::XSSHeader:0x2d23970 @app=#<Ra
ck::MediaType:0x2d24318 @default_layout=:layout, @app=#<struct
Sinatra::ExtendedRack app=#<Sinatra::ShowExceptions:0x2c75c58
@app=#<Rack::Head:0x2c75cb8 @app=#<
Rack::NullLogger:0x2c75ce8
@app=#<Rack::Protection::FrameOptions:0x2c75e98
@app=#<Rack::Protection::HttpOrigin:0x2c75fa0
@app=#<Rack::Protection::IPSpoofing:0x2
c76060 @app=#<Rack::Protection::JsonCsrf:0x2c76150
@app=#<Rack::Protection::PathTraversal:0x2c761e0
@app=#<Rack::Protection::XSSHeader:0x2c76270 @app=#<CIMI::Ra
bbit::VolumeImagesCollection:0x2c77020 @default_layout=:layout,
@app=#<CIMI::Collections::VolumeImages:0x2c77578
@default_layout=:layout, @app=#<struct Sinatra:
:ExtendedRack app=#<Rack::MethodOverride:0x2c779f8
@app=#<Rack::Head:0x2c77a10 @app=#<Rack::NullLogger:0x2c77a28
@app=#<Rack::Protection::FrameOptions:0x2c77ab8
@app=#<Rack::Protection::HttpOrigin:0x2c77b18
@app=#<Rack::Protection::IPSpoofing:0x2c77b78
@app=#<Rack::Protection::JsonCsrf:0x2c77bf0 @app=#<Rack::Protection
::PathTraversal:0x2c77c38 @app=#<Rack::Protection::XSSHeader:0x2c77c98
@app=#<Rack::Accept::Context:0x2c6c0a0 @app=#<struct
Sinatra::ExtendedRack app=#<Sinatra:
:ShowExceptions:0x2be9900 @app=#<Rack::Head:0x2be9918
@app=#<Rack::NullLogger:0x2be9930
@app=#<Rack::Protection::FrameOptions:0x2be99d8 @app=#<Rack::Protection:
:HttpOrigin:0x2be9a98 @app=#<Rack::Protection::IPSpoofing:0x2be9b28
@app=#<Rack::Protection::JsonCsrf:0x2be9b88
@app=#<Rack::Protection::PathTraversal:0x2be9bd0
@app=#<Rack::Protection::XSSHeader:0x2be9c60
@app=#<Rack::MediaType:0x2bea920 @default_layout=:layout, @app=#<struct
Sinatra::ExtendedRack app=#<Sinatra::ShowE
xceptions:0x28340e8 @app=#<Rack::Head:0x2834190
@app=#<Rack::NullLogger:0x28341a8
@app=#<Rack::Protection::FrameOptions:0x2834358
@app=#<Rack::Protection::HttpO
rigin:0x2834490 @app=#<Rack::Protection::IPSpoofing:0x28345c8
@app=#<Rack::Protection::JsonCsrf:0x2834670
@app=#<Rack::Protection::PathTraversal:0x2834700 @app=
#<Rack::Protection::XSSHeader:0x2834820
@app=#<CIMI::Rabbit::VolumeTemplatesCollection:0x25f44d8
@default_layout=:layout, @app=#<CIMI::Collections::VolumeTempla
tes:0x25e41d0 @default_layout=:layout, @app=#<CIMI::API:0x25e6750
@default_layout=:layout, @app=nil,
@template_cache=#<Tilt::Cache:0x25e65d0 @cache={}>>, @templ
ate_cache=#<Tilt::Cache:0x25e4128 @cache={}>>,
@template_cache=#<Tilt::Cache:0x25f43d0 @cache={}>>,
@options={:reaction=>:drop_session, :logging=>true, :message
=>"Forbidden", :encryptor=>Digest::SHA1, :session_key=>"rack.session",
:status=>403, :allow_empty_referrer=>true, :html_types=>["text/html",
"application/xhtml"
], :xss_mode=>:block, :nosniff=>true, :except=>[:session_hijacking,
:remote_token]}>, @options={:reaction=>:drop_session, :logging=>true,
:message=>"Forbidden",
:encryptor=>Digest::SHA1, :session_key=>"rack.session", :status=>403,
:allow_empty_referrer=>true, :html_types=>["text/html",
"application/xhtml"], :except=>[:
session_hijacking, :remote_token]}>, @options={:reaction=>:drop_session,
:logging=>true, :message=>"Forbidden", :encryptor=>Digest::SHA1,
:session_key=>"rack.se
ssion", :status=>403, :allow_empty_referrer=>true,
:html_types=>["text/html", "application/xhtml"],
:except=>[:session_hijacking, :remote_token]}>, @options={:r
eaction=>:drop_session, :logging=>true, :message=>"Forbidden",
:encryptor=>Digest::SHA1, :session_key=>"rack.session", :status=>403,
:allow_empty_referrer=>true
, :html_types=>["text/html", "application/xhtml"],
:except=>[:session_hijacking, :remote_token]}>,
@options={:reaction=>:drop_session, :logging=>true, :message=
"Forbidden", :encryptor=>Digest::SHA1, :session_key=>"rack.session",
:status=>403, :allow_empty_referrer=>true, :html_types=>["text/html",
"application/xhtml"]
, :except=>[:session_hijacking, :remote_token]}>,
@options={:reaction=>:drop_session, :logging=>true,
:message=>"Forbidden", :encryptor=>Digest::SHA1, :session_
key=>"rack.session", :status=>403, :allow_empty_referrer=>true,
:html_types=>["text/html", "application/xhtml"],
:frame_options=>:sameorigin, :except=>[:session
_hijacking, :remote_token]}>>>, @template=#<ERB:0x28340d0
@safe_level=nil, @src="#coding:US-ASCII\n_erbout = ''; _erbout.concat
\"<!DOCTYPE html>\\n<html>\\n<he
ad>\\n <meta http-equiv=\\\"Content-Type\\\" content=\\\"text/html;
charset=utf-8\\\"/>\\n <title>\"\n\n\n\n; _erbout.concat((h
exception.class ).to_s); _erbo
ut.concat \" at \"; _erbout.concat((h path ).to_s); _erbout.concat
\"</title>\\n\\n <script type=\\\"text/javascript\\\">\\n //<!--\\n
function toggle(id) {\
\n var pre = document.getElementById(\\\"pre-\\\" + id);\\n var
post = document.getElementById(\\\"post-\\\" + id);\\n var context =
document.getEleme
ntById(\\\"context-\\\" + id);\\n\\n if (pre.style.display ==
'block') {\\n pre.style.display = 'none';\\n
post.style.display = 'none';\\n con
text.style.background = \\\"none\\\";\\n } else {\\n
pre.style.display = 'block';\\n post.style.display = 'block';\\n
context.style.background
= \\\"#fffed9\\\";\\n }\\n }\\n\\n function toggleBacktrace(){\\n
var bt = document.getElementById(\\\"backtrace\\\");\\n var toggler =
document.get
ElementById(\\\"expando\\\");\\n\\n if (bt.className == 'condensed')
{\\n bt.className = 'expanded';\\n toggler.innerHTML =
\\\"(condense)\\\";\\n
} else {\\n bt.className = 'condensed';\\n
toggler.innerHTML = \\\"(expand)\\\";\\n }\\n }\\n //-->\\n
</script>\\n\\n<style type=\\\"text/cs
s\\\" media=\\\"screen\\\">\\n * {margin: 0; padding:
0; border: 0; outline: 0;}\\n div.clear {clear: both;}\\n
body
{background: #EEEEEE; margin: 0; padding: 0;\\n
font-family: 'Lucida Grande', 'Lucida Sans Unicode',\\n
'Garuda';
<snip>
Plus a few more pages of that kind of output.
Looking at the first part, " The CIMI::Model::MachineConfigurationRef
must be initialized using Hash or CIMI::Resource (is
#<CIMI::Service::MachineConfiguration", what does it mean?
In my code, system templates has componentDescriptors which is assigned
an array of hashes.
One hash contains e.g.:
{
:name => desc['vsysdescriptorName'][0],
:description => '',
:type =>
"http://schemas.dmtf.org/cimi/1/Machine",
:machine_template => CIMI::Model::MachineTemplate.new(
:name => vserver['vserverName'][0],
:description => '',
:machine_config =>
CIMI::Service::MachineConfiguration.find(vserver['vserverType'][0],
context),
:machine_image => { :href =>
context.machine_image_url(vserver['diskimageId'][0]) },
:volume_templates => volume_templates
)
}
Is the return type of MachineConfiguration.find incorrect?
I tried commenting out that line, but that led to the following error:
E, [2013-03-26T22:54:23.194324 #4960] ERROR -- 500: [NoMethodError]
undefined method `[]' for nil:NilClass
d:/sources/OSS/cloud/deltacloud/server/lib/cimi/models/schema.rb:325:in
`to_xml'
d:/sources/OSS/cloud/deltacloud/server/lib/cimi/models/schema.rb:444:in
`block in to_xml'
d:/sources/OSS/cloud/deltacloud/server/lib/cimi/models/schema.rb:444:in
`each'
d:/sources/OSS/cloud/deltacloud/server/lib/cimi/models/schema.rb:444:in
`to_xml'
d:/sources/OSS/cloud/deltacloud/server/lib/cimi/models/schema.rb:158:in
`convert_to_xml'
...
Cheers,
Dies Koper
-----Original Message-----
From: mfoj...@redhat.com [mailto:mfoj...@redhat.com]
Sent: Friday, 22 March 2013 11:36 PM
To: dev@deltacloud.apache.org
Subject: [PATCH core] CIMI: Added more descriptive CIMI schema errors
From: Michal Fojtik <mfoj...@redhat.com>
* Wrong attribute values are not reported correctly
Signed-off-by: Michal fojtik <mfoj...@redhat.com>
---
server/lib/cimi/models/resource.rb | 5 ++
server/lib/cimi/models/schema.rb | 88 +++++++++++++++++---
server/tests/cimi/model/errors_spec.rb | 141
+++++++++++++++++++++++++++++++++
3 files changed, 225 insertions(+), 9 deletions(-)
create mode 100644 server/tests/cimi/model/errors_spec.rb
diff --git a/server/lib/cimi/models/resource.rb
b/server/lib/cimi/models/resource.rb
index 9f5bb66..2b3de42 100644
--- a/server/lib/cimi/models/resource.rb
+++ b/server/lib/cimi/models/resource.rb
@@ -36,6 +36,11 @@ module CIMI
#
def initialize(values = {})
names = self.class.schema.attribute_names
+ unless values.is_a?(::Hash) or
values.kind_of?(CIMI::Model::Resource)
+ raise CIMI::Model::Schema::InvalidAttributeValue.new(
+ "The #{self.class} must be initialized using Hash or
CIMI::Resource (is #{values.inspect})"
+ )
+ end
@select_attrs = values[:select_attr_list] || []
# Make sure we always have the :id of the entity even
# the $select parameter is used and :id is filtered out
diff --git a/server/lib/cimi/models/schema.rb
b/server/lib/cimi/models/schema.rb
index 5a2049b..3a9d54c 100644
--- a/server/lib/cimi/models/schema.rb
+++ b/server/lib/cimi/models/schema.rb
@@ -19,6 +19,8 @@ require_relative "../../deltacloud/core_ext"
# The smarts of converting from XML and JSON into internal objects
class CIMI::Model::Schema
+ class InvalidAttributeValue < StandardError; end
+
#
# Attributes describe how we extract values from XML/JSON
#
@@ -60,6 +62,12 @@ class CIMI::Model::Schema
def valid?(value)
!value.nil? and !value.to_s.empty?
end
+
+ def report_error(message)
+ message = "The `#{@name}` attribute #{message}"
+ raise CIMI::Model::Schema::InvalidAttributeValue.new(message)
+ end
+
end
class Scalar < Attribute
@@ -190,6 +198,7 @@ class CIMI::Model::Schema
@klass = CIMI::Model::const_get(refname)
else
@klass = Class.new(opts[:class]) do |m|
+ def initialize(values={}); super(values); end
scalar :href
end
CIMI::Model::const_set(refname, @klass)
@@ -207,6 +216,39 @@ class CIMI::Model::Schema
a.valid?(value.send(a.name))
}
end
+
+ def to_xml(model, xml)
+ super if valid_ref?(model[name])
+ end
+
+ def to_json(model, json)
+ super if valid_ref?(model[name])
+ end
+
+ private
+
+ def valid_ref?(value)
+ return true if value.is_a?(::Hash) or
value.kind_of?(CIMI::Model::Resource) or value.nil?
+ report_error "must be a Hash or CIMI::Resource (is #{value})"
+ end
+ end
+
+ class Href < CIMI::Model::Schema::Struct
+
+ def to_xml(model, xml)
+ super if valid_href?(model[name])
+ end
+
+ def to_json(model, json)
+ super if valid_href?(model[name])
+ end
+
+ private
+
+ def valid_href?(value)
+ return true if value.is_a?(::Hash) or value.is_a?(struct) or
value.nil?
+ report_error "must be a Hash{:href} or Struct#href (is
#{value})"
+ end
end
class Array < Attribute
@@ -239,13 +281,25 @@ class CIMI::Model::Schema
end
def to_xml(model, xml)
- ary = (model[name] || []).map { |elt|
@struct.convert_to_xml(elt) }
- xml[xml_name] = ary unless ary.empty?
+ return unless model[name]
+ if is_valid_array? model[name]
+ ary = model[name].map { |elt| @struct.convert_to_xml(elt) }
+ xml[xml_name] = ary unless ary.empty?
+ end
end
def to_json(model, json)
- ary = (model[name] || []).map { |elt|
@struct.convert_to_json(elt) }
- json[json_name] = ary unless ary.empty?
+ return unless model[name]
+ if is_valid_array? model[name]
+ ary = model[name].map { |elt| @struct.convert_to_json(elt) }
+ json[json_name] = ary unless ary.empty?
+ end
+ end
+
+ private
+
+ def is_valid_array?(value)
+ value.is_a?(::Array) ? true : report_error('must be a valid
Array')
end
end
@@ -268,15 +322,26 @@ class CIMI::Model::Schema
end
def to_xml(model, xml)
- ary = (model[name] || {}).map { |k, v| { "key" => k, "content"
=> v } }
- xml[xml_name] = ary unless ary.empty?
+ return unless model[name]
+ if is_valid_hash? model[name]
+ ary = (model[name]).map { |k, v| { "key" => k, "content" => v
} }
+ xml[xml_name] = ary unless ary.empty?
+ end
end
def to_json(model, json)
- if model[name] && ! model[name].empty?
- json[json_name] = model[name]
+ return unless model[name]
+ if is_valid_hash? model[name]
+ json[json_name] = model[name] unless model[name].empty?
end
end
+
+ private
+
+ def is_valid_hash?(value)
+ value.is_a?(::Hash) ? true : report_error('must be a valid
Hash')
+ end
+
end
class Collection < Attribute
@@ -413,7 +478,12 @@ class CIMI::Model::Schema
def href(*args)
opts = args.extract_opts!
- args.each { |arg| struct(arg, opts) { scalar :href, :required
=>
opts[:required] } }
+ #args.each { |arg| struct(arg, opts) { scalar :href, :required
=> opts[:required] } }
+ args.each { |arg|
+ add_attributes!([arg, opts], Href) {
+ scalar :href, :required => opts[:required]
+ }
+ }
end
def text(*args)
diff --git a/server/tests/cimi/model/errors_spec.rb
b/server/tests/cimi/model/errors_spec.rb
new file mode 100644
index 0000000..fac38fb
--- /dev/null
+++ b/server/tests/cimi/model/errors_spec.rb
@@ -0,0 +1,141 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed
with
+# this work for additional information regarding copyright ownership.
The
+# ASF licenses this file to you under the Apache License, Version 2.0
(the
+# "License"); you may not use this file except in compliance with the
+# License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See
the
+# License for the specific language governing permissions and
limitations
+# under the License.
+#
+require 'rubygems'
+require 'require_relative' if RUBY_VERSION < '1.9'
+
+require_relative '../spec_helper.rb' if require 'minitest/autorun'
+
+describe 'Schema' do
+ describe 'Hash attributes' do
+
+ it 'should not report error when attribute is set properly' do
+ machine = CIMI::Model::MachineTemplate.new(:property => {})
+ machine.to_xml.must_be_kind_of String
+ machine.to_json.must_be_kind_of String
+ end
+
+ it 'should not report error when attribute is nil' do
+ machine = CIMI::Model::MachineTemplate.new(:property => nil)
+ machine.to_xml.must_be_kind_of String
+ machine.to_json.must_be_kind_of String
+ end
+
+ it 'should not report error when attribute is not set' do
+ machine = CIMI::Model::MachineTemplate.new
+ machine.to_xml.must_be_kind_of String
+ machine.to_json.must_be_kind_of String
+ end
+
+ it 'should report invalid value for Hash attribute when set to
String' do
+ machine = CIMI::Model::MachineTemplate.new(:property => '')
+ lambda { machine.to_xml }.must_raise
CIMI::Model::Schema::InvalidAttributeValue
+ lambda { machine.to_json }.must_raise
CIMI::Model::Schema::InvalidAttributeValue
+ end
+
+ it 'should report invalid value for Hash attribute when set to
Array'
do
+ machine = CIMI::Model::MachineTemplate.new(:property => [])
+ lambda { machine.to_xml }.must_raise
CIMI::Model::Schema::InvalidAttributeValue
+ lambda { machine.to_json }.must_raise
CIMI::Model::Schema::InvalidAttributeValue
+ end
+
+ end
+
+ describe 'Array attributes' do
+
+ it 'should report invalid value when set to Hash' do
+ machine = CIMI::Model::MachineTemplate.new(:volumes => {} )
+ lambda { machine.to_xml }.must_raise
CIMI::Model::Schema::InvalidAttributeValue
+ lambda { machine.to_json }.must_raise
CIMI::Model::Schema::InvalidAttributeValue
+ end
+
+ it 'should report invalid value when set to String' do
+ machine = CIMI::Model::MachineTemplate.new(:volumes => '' )
+ lambda { machine.to_xml }.must_raise
CIMI::Model::Schema::InvalidAttributeValue
+ lambda { machine.to_json }.must_raise
CIMI::Model::Schema::InvalidAttributeValue
+ end
+
+ it 'should not report error when attribute is set properly' do
+ machine = CIMI::Model::MachineTemplate.new(:volumes => [])
+ machine.to_xml.must_be_kind_of String
+ machine.to_json.must_be_kind_of String
+ end
+
+ it 'should not report error when attribute is nil' do
+ machine = CIMI::Model::MachineTemplate.new(:volumes => nil)
+ machine.to_xml.must_be_kind_of String
+ machine.to_json.must_be_kind_of String
+
+ end
+
+ it 'should not report error when attribute is not set' do
+ machine = CIMI::Model::MachineTemplate.new
+ machine.to_xml.must_be_kind_of String
+ machine.to_json.must_be_kind_of String
+ end
+ end
+
+ describe 'Ref attributes' do
+
+ it 'should report error when initialized using Array' do
+ lambda {
+ CIMI::Model::MachineTemplate.new(:machine_config => [])
+ }.must_raise CIMI::Model::Schema::InvalidAttributeValue
+ end
+
+ it 'should report error when initialized using String' do
+ lambda {
+ CIMI::Model::MachineTemplate.new(:machine_config => '')
+ }.must_raise CIMI::Model::Schema::InvalidAttributeValue
+ end
+
+ it 'could be initialized by the Hash value' do
+ machine = CIMI::Model::MachineTemplate.new(:machine_config =>
{ :href => 'http://localhost/1' })
+ machine.machine_config.must_be_instance_of
CIMI::Model::MachineConfigurationRef
+ machine.machine_config.href.must_equal 'http://localhost/1'
+ machine.to_xml.must_be_instance_of String
+ machine.to_json.must_be_instance_of String
+ end
+
+ it 'could be initialized by the Ref value' do
+ machine = CIMI::Model::MachineTemplate.new(:machine_config =>
CIMI::Model::MachineConfigurationRef.new(:href =>
'http://localhost/1'))
+ machine.machine_config.must_be_instance_of
CIMI::Model::MachineConfigurationRef
+ machine.machine_config.href.must_equal 'http://localhost/1'
+ machine.to_xml.must_be_instance_of String
+ machine.to_json.must_be_instance_of String
+ end
+
+ end
+
+ describe 'Href attributes' do
+
+ it 'should report error when value is not a Hash' do
+ machine = CIMI::Model::Machine.new(:machine_image => '')
+ lambda {
+ machine.to_xml
+ }.must_raise CIMI::Model::Schema::InvalidAttributeValue
+ lambda {
+ machine.to_json
+ }.must_raise CIMI::Model::Schema::InvalidAttributeValue
+ end
+
+ it 'should not report error when initialized correctly' do
+ machine = CIMI::Model::Machine.new( :machine_image => { :href
=>
'test' })
+ machine.to_xml.must_be_instance_of String
+ machine.to_json.must_be_instance_of String
+ end
+ end
+
+end
--
1.8.1.4