Two comments (so far): 1. running >> rake test:deltacloud produces a bunch of warnings like: /home/dcloud/workspace/deltacloud/tests/deltacloud/instances_test.rb:28: warning: class variable access from toplevel
2: tests take a really long time to complete (tests are still running ...). Maybe there is just a lot of testing going on but it looks like some of the tests sit and query the provider over and over again? (open to more explanation here) > > From: marios <[email protected]> > > > Signed-off-by: marios <[email protected]> > --- > tests/config.yaml | 19 ++- > tests/deltacloud/base_api_test.rb | 8 +- > tests/deltacloud/images_test.rb | 75 ++++++++ > tests/deltacloud/instances_test.rb | 353 > ++++++++++++++++++++++++++++++++++++ > 4 files changed, 448 insertions(+), 7 deletions(-) > > diff --git a/tests/config.yaml b/tests/config.yaml > index 3070b56..5f905a6 100644 > --- a/tests/config.yaml > +++ b/tests/config.yaml > @@ -4,15 +4,28 @@ api_url: "http://localhost:3001/api" > mock: > user: "mockuser" > password: "mockpassword" > +#OPENSTACK DRIVER CONFIG > +openstack: > + user: > + password: > + #used for instances tests: > + instances: > + preferred_image: "14075" > #EC2 DRIVER CONFIG: > ec2: > - user: #EC2 KEY > - password: #EC2 SECRET KEY > + user: > + password: > bucket_locations: > - #location constraint : provider > + #location constraint > - "EU" > - "sa-east-1" > - "us-west-1" > - "us-west-2" > - "ap-southeast-1" > - "ap-northeast-1" > + preferred_provider: "us-east-1" > + #used for instances tests: > + instances: > + preferred_image: "ami-2b5fba42" > + preferred_hwp: "m1.small" > + preferred_realm: "us-east-1b" > diff --git a/tests/deltacloud/base_api_test.rb > b/tests/deltacloud/base_api_test.rb > index bd37b46..12e1e4d 100644 > --- a/tests/deltacloud/base_api_test.rb > +++ b/tests/deltacloud/base_api_test.rb > @@ -120,17 +120,17 @@ describe "Deltacloud API Entry Point" do > end > > it 'must change the API PROVIDER using the /api;provider matrix > parameter in URI' do > - res = get(';provider=test1', :public => true) > + res = get("\;provider=test1", {:accept=>:xml, :noauth=>true}) > res.xml.root[:provider].wont_be_nil > res.xml.root[:provider].must_equal 'test1' > - res = get(';provider=test2', :public => true) > + res = get("\;provider=test2", {:accept=>:xml, :noauth=>true}) > res.xml.root[:provider].must_equal 'test2' > end > > it 'must change the API DRIVER using the /api;driver matrix > parameter in URI' do > - res = get(';driver=ec2', :public => true) > + res = get("\;driver=ec2", {:accept=>:xml, :noauth=>true}) > res.xml.root[:driver].must_equal 'ec2' > - res = get(';driver=mock', :public => true) > + res = get("\;driver=mock", {:accept=>:xml, :noauth=>true}) > res.xml.root[:driver].must_equal 'mock' > end > > diff --git a/tests/deltacloud/images_test.rb > b/tests/deltacloud/images_test.rb > index e69de29..a6bd840 100644 > --- a/tests/deltacloud/images_test.rb > +++ b/tests/deltacloud/images_test.rb > @@ -0,0 +1,75 @@ > +# > +# 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. > + > +$:.unshift File.join(File.dirname(__FILE__), '..') > +require "deltacloud/test_setup.rb" > + > +IMAGES = "/images" > + > +describe 'Deltacloud API Images collection' do > + include Deltacloud::Test::Methods > + > + need_collection :images > + > + def each_image_xml(&block) > + res = get(IMAGES, :accept=> :xml) > + (res.xml/'images/image').each do |r| > + image_res = get(IMAGES + '/' + r[:id], :accept => :xml) > + yield image_res.xml > + end > + end > + > + #Run the 'common' tests for all collections defined in > common_tests_collections.rb > + test_collection = "images" > + $:.unshift File.join(File.dirname(__FILE__), '..') > + eval File.read('deltacloud/common_tests_collections.rb') > + > + #Now run the images-specific tests: > + it 'should have the "owner_id", "description", "architecure" and > "state" element for each image' do > + each_image_xml do |image_xml| > + (image_xml/'state').wont_be_empty > + (image_xml/'owner_id').wont_be_empty > + (image_xml/'architecture').wont_be_empty > + (image_xml/'description').wont_be_empty > + end > + end > + > + it 'should include the list of compatible hardware_profiles for > each image' do > + each_image_xml do |image_xml| > + (image_xml/'hardware_profiles/hardware_profile').wont_be_empty > + (image_xml/'hardware_profiles/hardware_profile').each do |hwp| > + hwp[:href].wont_be_nil > + hwp[:href].must_match /^http/ > + hwp[:id].wont_be_nil > + hwp[:href].must_match /\/#{hwp[:id]}$/ > + hwp[:rel].must_equal 'hardware_profile' > + end > + end > + end > + > + it 'should advertise the list of actions that can be executed for > each image' do > + each_image_xml do |image_xml| > + (image_xml/'actions/link').wont_be_empty > + (image_xml/'actions/link').each do |l| > + l[:href].wont_be_nil > + l[:href].must_match /^http/ > + l[:method].wont_be_nil > + l[:rel].wont_be_nil > + end > + end > + end > + > +end > diff --git a/tests/deltacloud/instances_test.rb > b/tests/deltacloud/instances_test.rb > index e69de29..852b00b 100644 > --- a/tests/deltacloud/instances_test.rb > +++ b/tests/deltacloud/instances_test.rb > @@ -0,0 +1,353 @@ > +# > +# 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. > + > +$:.unshift File.join(File.dirname(__FILE__), '..') > +require "deltacloud/test_setup.rb" > + > +INSTANCES = "/instances" > + > +describe 'Deltacloud API instances collection' do > + include Deltacloud::Test::Methods > + need_collection :instances > + #make sure we have at least one instance to test > + begin > + #keep track of what we create for deletion after tests: > + @@created_resources = {:instances=>[], :keys=>[], :images=>[], > :firewalls=>[]} > + if api.instances_config["preferred_image"] > + image_id = api.instances_config["preferred_image"] > + else > + image_list = get("/images", {:accept => :xml}) > + image_id = (image_list.xml/'images/image').to_a.choice[:id] > + end > + res = post(INSTANCES, :image_id=>image_id) > + unless res.code == 201 > + raise Exception.new("Failed to create instance from image_id > #{image_id}") > + end > + @@my_instance_id = (res.xml/'instance')[0][:id] > + @@created_resources[:instances] << @@my_instance_id > + end > + > + #stop/destroy the resources we created for the tests > + MiniTest::Unit.after_tests { > +puts "CLEANING UP... resources for deletion: > #{@@created_resources.inspect}" > + #instances: > + @@created_resources[:instances].each_index do |i| > + attempts = 0 > + begin > + stop_res = > post(INSTANCES+"/"+@@created_resources[:instances][i]+"/stop", "") > + @@created_resources[:instances][i] = nil if stop_res.code == > 202 > + rescue Exception => e > + sleep(10) > + attempts += 1 > + retry if (attempts <= 5) > + end > + end > + @@created_resources[:instances].compact! > + @@created_resources.delete(:instances) if > @@created_resources[:instances].empty? > + #keys > + [:keys, :images, :firewalls].each do |col| > + @@created_resources[col].each do |k| > + res = delete("/#{col}/#{k}") > + @@created_resources[col].delete(k) if res.code == 204 > + end > + @@created_resources.delete(col) if > @@created_resources[col].empty? > + end > +puts "CLEANUP attempt finished... resources looks like: > #{@@created_resources.inspect}" > + raise Exception.new("Unable to delete all created resources - > please check: #{@@created_resources.inspect}") unless > @@created_resources.empty? > + } > + > + def each_instance_xml(&block) > + res = get(INSTANCES, :accept=> :xml) > + (res.xml/'instances/instance').each do |r| > + instance_res = get(INSTANCES + '/' + r[:id], :accept => :xml) > + yield instance_res.xml > + end > + end > + > + def get_image > + if api.instances_config["preferred_image"] > + image_id = api.instances_config["preferred_image"] > + else > + image_list = get("/images", {:accept => :xml}) > + image_id = (image_list.xml/'images/image').to_a.choice[:id] > + end > + end > + > + def get_realm > + if api.instances_config["preferred_realm"] > + realm_id = api.instances_config["preferred_realm"] > + else > + realms_list = get("/realms", {:accept => :xml}) > + realm_id = (realms_list.xml/'realms/realm').to_a.choice[:id] > + end > + end > + > + def get_hwp > + if api.instances_config["preferred_hwp"] > + hwp_id = api.instances_config["preferred_hwp"] > + else > + hw_profile_list = get("/hardware_profiles", {:accept => :xml}) > + hwp_id = > (hw_profile_list.xml/'hardware_profiles/hardware_profile').to_a.choice[:id] > + end > + end > + > + #Run the 'common' tests for all collections defined in > common_tests_collections.rb > + test_collection = "instances" > + $:.unshift File.join(File.dirname(__FILE__), '..') > + eval File.read('deltacloud/common_tests_collections.rb') > + > + #Now run the instances-specific tests: > + > + it 'must have the "state" element defined for each instance in > collection' do > + res = get(INSTANCES, :accept=> :xml) > + (res.xml/'instances/instance').each do |r| > + (r/'state').wont_be_empty > + (r/'state').first.must_match /(RUNNING|STOPPED|PENDING)/ > + end > + end > + > + it 'must have the "owner_id" element for each instance and it > should match with the one in collection' do > + res = get(INSTANCES, :accept=> :xml) > + (res.xml/'instances/instance').each do |r| > + instance_res = get(INSTANCES + '/' + r[:id], :accept => :xml) > + (instance_res.xml/'owner_id').wont_be_empty > + > > (instance_res.xml/'owner_id').first.text.must_equal((r/'owner_id').first.text) > + end > + end > + > + it 'each instance must link to the realm that was used during > instance creation' do > + each_instance_xml do |instance_xml| > + (instance_xml/'realm').wont_be_empty > + (instance_xml/'realm').size.must_equal 1 > + (instance_xml/'realm').first[:id].wont_be_nil > + (instance_xml/'realm').first[:href].wont_be_nil > + (instance_xml/'realm').first[:href].must_match > /\/#{(instance_xml/'realm').first[:id]}$/ > + end > + end > + > + it 'each instance must link to the image that was used to during > instance creation' do > + each_instance_xml do |instance_xml| > + (instance_xml/'image').wont_be_empty > + (instance_xml/'image').size.must_equal 1 > + (instance_xml/'image').first[:id].wont_be_nil > + (instance_xml/'image').first[:href].wont_be_nil > + (instance_xml/'image').first[:href].must_match > /\/#{(instance_xml/'image').first[:id]}$/ > + end > + end > + > + it 'each instance must link to the hardware_profile that was used > to during instance creation' do > + each_instance_xml do |instance_xml| > + (instance_xml/'hardware_profile').wont_be_empty > + (instance_xml/'hardware_profile').size.must_equal 1 > + (instance_xml/'hardware_profile').first[:id].wont_be_nil > + (instance_xml/'hardware_profile').first[:href].wont_be_nil > + (instance_xml/'hardware_profile').first[:href].must_match > /\/#{(instance_xml/'hardware_profile').first[:id]}$/ > + end > + end > + > + it 'each (NON-STOPPED) instance should advertise the public and > private addresses of the instance' do > + each_instance_xml do |instance_xml| > + #skip this instance if it is in STOPPED state > + next if (instance_xml/'instance/state').text == "STOPPED" > + (instance_xml/'public_addresses').wont_be_empty > + (instance_xml/'public_addresses').size.must_equal 1 > + (instance_xml/'public_addresses/address').each do |a| > + a[:type].wont_be_nil > + a.text.strip.wont_be_empty > + end > + (instance_xml/'private_addresses').wont_be_empty > + (instance_xml/'private_addresses').size.must_equal 1 > + (instance_xml/'private_addresses/address').each do |a| > + a[:type].wont_be_nil > + a.text.strip.wont_be_empty > + end > + end > + end > + > + it 'each instance should advertise the storage volumes used by the > instance' do > + each_instance_xml do |i| > + (i/'storage_volumes').wont_be_empty > + end > + end > + > + it 'each instance should advertise the list of actions that can be > executed for each instance' do > + each_instance_xml do |instance_xml| > + (instance_xml/'actions/link').each do |l| > + l[:href].wont_be_nil > + l[:href].must_match /^http/ > + l[:method].wont_be_nil > + l[:rel].wont_be_nil > + end > + end > + end > + > + it 'should allow to create new instance using image without realm' > do > + #random image and create instance > + image_id = get_image > + image_id.wont_be_nil > + res = post(INSTANCES, :image_id=>image_id) > + res.code.must_equal 201 > + res.headers[:location].wont_be_nil > + created_instance_id = (res.xml/'instance')[0][:id] > + #GET the instance > + res = get(INSTANCES+"/"+created_instance_id, {:accept=>:xml}) > + res.code.must_equal 200 > + (res.xml/'instance').first[:id].must_equal created_instance_id > + (res.xml/'instance/image').first[:id].must_equal image_id > + #mark it for stopping after tests run: > + @@created_resources[:instances] << created_instance_id > + end > + > + it 'should allow to create new instance using image and realm' do > + #random image, realm and create instance > + image_id = get_image > + image_id.wont_be_nil > + realm_id = get_realm > + realm_id.wont_be_nil > + res = post(INSTANCES, :image_id=>image_id, :realm_id=>realm_id) > + res.code.must_equal 201 > + res.headers[:location].wont_be_nil > + created_instance_id = (res.xml/'instance')[0][:id] > + #GET the instance > + res = get(INSTANCES+"/"+created_instance_id, {:accept=>:xml}) > + res.code.must_equal 200 > + (res.xml/'instance').first[:id].must_equal created_instance_id > + (res.xml/'instance/image').first[:id].must_equal image_id > + (res.xml/'instance/realm').first[:id].must_equal realm_id > + #mark it for stopping after tests run: > + @@created_resources[:instances] << created_instance_id > + end > + > + it 'should allow to create new instance using image, realm and > hardware_profile' do > + #random image, realm, hardware_profile and create instance > + image_id = get_image > + image_id.wont_be_nil > + #check if this image defines compatible hw_profiles: > + res = get("/images/"+image_id, {:accept =>:xml}) > + if (res.xml/'image/hardware_profiles').empty? > + hwp_id = get_hwp > + else > + hwp_id = > (res.xml/'image/hardware_profiles/hardware_profile').to_a.choice[:id] > + end > + hwp_id.wont_be_nil > + #random realm: > + realm_id = get_realm > + realm_id.wont_be_nil > + res = post(INSTANCES, :image_id=>image_id, :realm_id=>realm_id, > :hwp_id => hwp_id) > + res.code.must_equal 201 > + res.headers[:location].wont_be_nil > + created_instance_id = (res.xml/'instance')[0][:id] > + #GET the instance > + res = get(INSTANCES+"/"+created_instance_id, {:accept=>:xml}) > + res.code.must_equal 200 > + (res.xml/'instance').first[:id].must_equal created_instance_id > + (res.xml/'instance/image').first[:id].must_equal image_id > + (res.xml/'instance/realm').first[:id].must_equal realm_id > + (res.xml/'instance/hardware_profile').first[:id].must_equal > hwp_id > + #mark it for stopping after tests run: > + @@created_resources[:instances] << created_instance_id > + end > + > +#snapshot (make image) > + > + it 'should allow to snapshot running instance if supported by > provider' do > + #check if created instance allows creating image > + res = get(INSTANCES+"/"+@@my_instance_id, {:accept=>:xml}) > + instance_actions = > (res.xml/'actions/link').to_a.inject([]){|actions, current| actions > << current[:rel]; actions} > + skip "no create image support for instance #{@@my_instance_id}" > unless instance_actions.include?("create_image") > + #create image > + res = post("/images", :instance_id => @@my_instance_id, > :name=>random_name) > + res.code.must_equal 201 > + my_image_id = (res.xml/'image')[0][:id] > + #mark for deletion later: > + @@created_resources[:images] << my_image_id > + end > +# > +#create with key > + > + describe "create instance with auth key" do > + > + need_collection :keys > + need_feature :instances, :authentication_key > + > + it 'should allow specification of auth key for created > instance when supported' do > + #create a key to use > + key_name = random_name > + key_res = post("/keys", :name=>key_name) > + key_res.code.must_equal 201 > + key_id = (key_res.xml/'key')[0][:id] > + #create instance with this key: > + image_id = get_image > + res = post(INSTANCES, :image_id => image_id, :keyname => > key_id) > + res.code.must_equal 201 > + instance_id = (res.xml/'instance')[0][:id] > + #check the key: > + key_used = > (res.xml/'instance/authentication/login/keyname')[0].text > + key_used.must_equal key_id > + #mark them for deletion after tests run: > + @@created_resources[:instances] << instance_id > + @@created_resources[:keys] << key_id > + end > + > + end > + > +#specify user name (feature) > + describe "create instance with user defined name" do > + > + need_feature :instances, :user_name > + > + it 'should allow specification of name for created instance when > supported' do > + instance_name = random_name > + image_id = get_image > + res = post(INSTANCES, :image_id => image_id, :name => > instance_name) > + res.code.must_equal 201 > + instance_id = (res.xml/'instance')[0][:id] > + #check the name: > + created_name = (res.xml/'instance/name')[0].text > + created_name.must_equal instance_name > + #mark for deletion: > + @@created_resources[:instances] << instance_id > + end > + end > + > +#create with firewall (feature) > + describe "create instance with firewall" do > + > + need_collection :firewalls > + need_feature :instances, :firewalls > + > + it 'should be able to create instance using specified firewall' > do > + #create a firewall to use > + fw_name = random_name > + fw_res = post("/firewalls", :name=>fw_name, > :description=>"firewall created for instances API test on > #{Time.now}") > + fw_res.code.must_equal 201 > + fw_id = (fw_res.xml/'firewall')[0][:id] > + ((fw_res.xml/'firewall/name')[0].text).must_equal fw_name > + #create instance with this firewall: > + image_id = get_image > + res = post(INSTANCES, :image_id => image_id, :firewalls1 => > fw_id) > + res.code.must_equal 201 > + instance_id = (res.xml/'instance')[0][:id] > + #check the firewall: > + fw_used = (res.xml/'instance/firewalls/firewall')[0][:id] > + fw_used.must_equal fw_id > + #mark for deletion: > + @@created_resources[:instances] << instance_id > + @@created_resources[:firewalls] << fw_id > + end > + > + end > +end > -- > 1.7.6.5 > >
