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 >