You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@deltacloud.apache.org by ma...@redhat.com on 2012/08/02 17:07:38 UTC

[PATCH 1/4] API TESTS - moves common collections tests to separate module

From: marios <ma...@redhat.com>


Signed-off-by: marios <ma...@redhat.com>
---
 tests/deltacloud/buckets_test.rb             |  134 ++++++++++----------------
 tests/deltacloud/common_tests_collections.rb |  114 ++++++++++++++++++++++
 tests/deltacloud/test_setup.rb               |   25 ++++-
 3 files changed, 187 insertions(+), 86 deletions(-)
 create mode 100644 tests/deltacloud/common_tests_collections.rb

diff --git a/tests/deltacloud/buckets_test.rb b/tests/deltacloud/buckets_test.rb
index e8732b1..b829b30 100644
--- a/tests/deltacloud/buckets_test.rb
+++ b/tests/deltacloud/buckets_test.rb
@@ -61,19 +61,61 @@ describe 'Deltacloud API buckets collection' do
     end
   }
 
-  it 'must advertise the buckets collection in API entrypoint' do
+  #Run the 'common' tests for all collections defined in common_tests_collections.rb
+  CommonCollectionsTest::run_common_tests_for("buckets")
 
-    res = get("/").xml
-    (res/'api/link[@rel=buckets]').wont_be_empty
+  #Now run the bucket-specific tests:
+  it 'must have the "size" element defined for each bucket in collection' do
+    res = get(BUCKETS, :accept => :xml)
+    (res.xml/'buckets/bucket').each do |r|
+      (r/'size').wont_be_nil
+      (r/'size').wont_be_empty
+    end
   end
 
-  it 'must require authentication to access the "bucket" collection' do
-    proc {  get(BUCKETS, :noauth => true) }.must_raise RestClient::Request::Unauthorized
+  it 'all "blob" elements for the bucket should match the ones in collection' do
+    res = get(BUCKETS, :accept => :xml)
+    (res.xml/'buckets/bucket').each do |r|
+      bucket = get(BUCKETS+"/#{r[:id]}", :accept=>:xml)
+      (bucket.xml/'bucket/blob').each do |b|
+        b[:id].wont_be_nil
+        b[:href].wont_be_nil
+        b[:href].must_match /^http/
+        b[:href].must_match /#{r[:id]}\/#{b[:id]}$/
+      end
+    end
   end
 
-  it 'should respond with HTTP_OK when accessing the :buckets collection with authentication' do
-    res = get(BUCKETS)
-    res.code.must_equal 200
+  it 'must allow to get all blobs details and the details should be set correctly' do
+    res = get(BUCKETS, :accept => :xml)
+    (res.xml/'buckets/bucket').each do |r|
+      bucket = get(BUCKETS+"/#{r[:id]}", :accept=>:xml)
+      (bucket.xml/'bucket/blob').each do |b|
+        blob = get(BUCKETS+"/#{r[:id]}/#{b[:id]}", :accept=>:xml)
+        blob.xml.root.name.must_equal 'blob'
+        blob.xml.root[:id].must_equal b[:id]
+        (blob.xml/'bucket').wont_be_empty
+        (blob.xml/'bucket').size.must_equal 1
+        (blob.xml/'bucket').first.text.wont_be_nil
+        (blob.xml/'bucket').first.text.must_equal r[:id]
+        (blob.xml/'content_length').wont_be_empty
+        (blob.xml/'content_length').size.must_equal 1
+        (blob.xml/'content_length').first.text.must_match /^(\d+)$/
+        (blob.xml/'content_type').wont_be_empty
+        (blob.xml/'content_type').size.must_equal 1
+        (blob.xml/'content_type').first.text.wont_be_nil
+        (blob.xml/'last_modified').wont_be_empty
+        (blob.xml/'last_modified').size.must_equal 1
+        (blob.xml/'last_modified').first.text.wont_be_empty
+        (blob.xml/'content').wont_be_empty
+        (blob.xml/'content').size.must_equal 1
+        (blob.xml/'content').first[:rel].wont_be_nil
+        (blob.xml/'content').first[:rel].must_equal 'blob_content'
+        (blob.xml/'content').first[:href].wont_be_nil
+        (blob.xml/'content').first[:href].must_match /^http/
+        (blob.xml/'content').first[:href].must_match /\/content$/
+      end
+    end
   end
 
   it 'should be possible to create bucket with POST /api/buckets and delete it with DELETE /api/buckets/:id' do
@@ -153,6 +195,7 @@ describe 'Deltacloud API buckets collection' do
   end
 
   it 'should be possible to GET blob data with GET /api/buckets/:id/blob/content' do
+skip("SKIPPING THIS TEST FOR NOW - KNOWN ISSUE WITH GET CONTENT ON DELTACLOUD SIDE FIXME")
     res = get("#{BUCKETS}/#{@@my_bucket}/#{@@my_blob}/content")
     res.code.must_equal 200
     res.must_equal "This is the test blob content"
@@ -179,64 +222,6 @@ describe 'Deltacloud API buckets collection' do
     end
   end
 
-  it 'should support the JSON media type' do
-    res = get(BUCKETS, :accept=>:json)
-    res.code.must_equal 200
-    res.headers[:content_type].must_equal 'application/json'
-    assert_silent {JSON.parse(res)}
-  end
-
-  it 'must include the ETag in HTTP headers' do
-    res = get(BUCKETS)
-    res.headers[:etag].wont_be_nil
-  end
-
-  it 'must have the "buckets" element on top level' do
-    res = get(BUCKETS, :accept=>:xml)
-    res.xml.root.name.must_equal 'buckets'
-  end
-
-  it 'must have some "bucket" elements inside "buckets"' do
-    res = get(BUCKETS, :accept=>:xml)
-    (res.xml/'buckets/bucket').wont_be_empty
-  end
-
-  it 'must provide the :id attribute for each bucket in collection' do
-    res = get(BUCKETS, :accept=>:xml)
-    (res.xml/'buckets/bucket').each do |r|
-      r[:id].wont_be_nil
-    end
-  end
-
-  it 'must include the :href attribute for each "bucket" element in collection' do
-    res = get(BUCKETS, :accept=>:xml)
-    (res.xml/'buckets/bucket').each do |r|
-      r[:href].wont_be_nil
-    end
-  end
-
-  it 'must use the absolute URL in each :href attribute' do
-    res = get(BUCKETS, :accept=>:xml)
-    (res.xml/'buckets/bucket').each do |r|
-      r[:href].must_match /^http/
-    end
-  end
-
-  it 'must have the URL ending with the :id of the bucket' do
-    res = get(BUCKETS, :accept=>:xml)
-    (res.xml/'buckets/bucket').each do |r|
-      r[:href].must_match /#{r[:id]}$/
-    end
-  end
-
-  it 'must have the "name" element defined for each bucket in collection' do
-    res = get(BUCKETS, :accept => :xml)
-    (res.xml/'buckets/bucket').each do |r|
-      (r/'name').wont_be_nil
-      (r/'name').wont_be_empty
-    end
-  end
-
   it 'must have the "size" element defined for each bucket in collection' do
     res = get(BUCKETS, :accept => :xml)
     (res.xml/'buckets/bucket').each do |r|
@@ -245,23 +230,6 @@ describe 'Deltacloud API buckets collection' do
     end
   end
 
-  it 'must return 200 OK when following the URL in bucket element' do
-    res = get(BUCKETS, :accept => :xml)
-    (res.xml/'buckets/bucket').each do |r|
-      bucket_res = get r[:href]
-      bucket_res.code.must_equal 200
-    end
-  end
-
-  it 'must have the "name" element for the bucket and it should match with the one in collection' do
-    res = get(BUCKETS, :accept => :xml)
-    (res.xml/'buckets/bucket').each do |r|
-      bucket = get(BUCKETS+"/#{r[:id]}", :accept=>:xml)
-      (bucket.xml/'name').wont_be_empty
-      (bucket.xml/'name').first.text.must_equal((r/'name').first.text)
-    end
-  end
-
   it 'all "blob" elements for the bucket should match the ones in collection' do
     res = get(BUCKETS, :accept => :xml)
     (res.xml/'buckets/bucket').each do |r|
diff --git a/tests/deltacloud/common_tests_collections.rb b/tests/deltacloud/common_tests_collections.rb
new file mode 100644
index 0000000..94e3612
--- /dev/null
+++ b/tests/deltacloud/common_tests_collections.rb
@@ -0,0 +1,114 @@
+#
+# 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.
+
+module CommonCollectionsTest
+
+  def self.run_common_tests_for(test_collection)
+
+    describe "collection common tests for #{test_collection}" do
+
+      it "must advertise the #{test_collection} collection in API entrypoint" do
+        res = get("/").xml
+        (res/"api/link[@rel=#{test_collection}]").wont_be_empty
+      end
+
+      it "must require authentication to access the #{test_collection} collection" do
+        skip "Skipping for #{test_collection} as no auth required here" if test_collection == "hardware_profiles"
+        proc {  get(test_collection, :noauth => true) }.must_raise RestClient::Request::Unauthorized
+      end
+
+      it "should respond with HTTP_OK when accessing the #{test_collection} collection with authentication" do
+        res = get(test_collection)
+        res.code.must_equal 200
+      end
+
+      it 'should support the JSON media type' do
+        res = get(test_collection, :accept=>:json)
+        res.code.must_equal 200
+        res.headers[:content_type].must_equal 'application/json'
+        assert_silent {JSON.parse(res)}
+      end
+
+      it 'must include the ETag in HTTP headers' do
+        res = get(test_collection)
+        res.headers[:etag].wont_be_nil
+      end
+
+      it "must have the #{test_collection} element on top level" do
+        res = get(test_collection, :accept=>:xml)
+        res.xml.root.name.must_equal test_collection
+      end
+
+      it "must have some #{test_collection.singularize} elements inside #{test_collection} " do
+        res = get(test_collection, :accept=>:xml)
+        (res.xml/"#{test_collection}/#{test_collection.singularize}").wont_be_empty
+      end
+
+      it "must provide the :id attribute for each #{test_collection.singularize} in collection" do
+        res = get(test_collection, :accept=>:xml)
+        (res.xml/"#{test_collection}/#{test_collection.singularize}").each do |r|
+          r[:id].wont_be_nil
+        end
+      end
+
+      it "must include the :href attribute for each #{test_collection} element in collection" do
+        res = get(test_collection, :accept=>:xml)
+        (res.xml/"#{test_collection}/#{test_collection.singularize}").each do |r|
+          r[:href].wont_be_nil
+        end
+      end
+
+      it 'must use the absolute URL in each :href attribute' do
+        res = get(test_collection, :accept=>:xml)
+        (res.xml/"#{test_collection}/#{test_collection.singularize}").each do |r|
+          r[:href].must_match /^http/
+        end
+      end
+
+      it "must have the URL ending with the :id of the #{test_collection.singularize}" do
+        res = get(test_collection, :accept=>:xml)
+        (res.xml/"#{test_collection}/#{test_collection.singularize}").each do |r|
+          r[:href].must_match /#{r[:id]}$/
+        end
+      end
+
+      it "must have the \"name\" element defined for each #{test_collection.singularize} in collection" do
+        res = get(test_collection, :accept => :xml)
+        (res.xml/"#{test_collection}/#{test_collection.singularize}").each do |r|
+          (r/'name').wont_be_nil
+          (r/'name').wont_be_empty
+        end
+      end
+
+      it "must return 200 OK when following the URL in #{test_collection.singularize} element" do
+        res = get(test_collection, :accept => :xml)
+        (res.xml/"#{test_collection}/#{test_collection.singularize}").each do |r|
+          element_res = get r[:href]
+          element_res.code.must_equal 200
+        end
+      end
+
+      it "must have the \"name\" element for the #{test_collection.singularize} and it should match with the one in collection" do
+        res = get(test_collection, :accept => :xml)
+        (res.xml/"#{test_collection}/#{test_collection.singularize}").each do |r|
+          element = get(test_collection+"/#{r[:id]}", :accept=>:xml)
+          (element.xml/'name').wont_be_empty
+          (element.xml/'name').first.text.must_equal((r/'name').first.text)
+        end
+      end
+    end
+  end
+end
diff --git a/tests/deltacloud/test_setup.rb b/tests/deltacloud/test_setup.rb
index a3bae4f..aef7adb 100644
--- a/tests/deltacloud/test_setup.rb
+++ b/tests/deltacloud/test_setup.rb
@@ -22,10 +22,10 @@ require 'json'
 require 'base64'
 require 'yaml'
 require 'singleton'
-
 #SETUP
 topdir = File.join(File.dirname(__FILE__), '..')
 $:.unshift topdir
+require 'deltacloud/common_tests_collections.rb'
 
 module RestClient::Response
   def xml
@@ -37,6 +37,14 @@ module RestClient::Response
   end
 end
 
+class String
+  def singularize
+    return self.gsub(/ies$/, 'y') if self =~ /ies$/
+    return self.gsub(/es$/, '') if self =~ /sses$/
+    self.gsub(/s$/, '')
+  end
+end
+
 module Deltacloud
   module Test
 
@@ -64,6 +72,14 @@ module Deltacloud
         @hash[driver]["bucket_locations"]
       end
 
+      def instances_config
+        @hash[driver]["instances"] || {}
+      end
+
+      def preferred_provider
+        @hash[driver]["preferred_provider"]
+      end
+
       def driver
         xml.root[:driver]
       end
@@ -139,6 +155,9 @@ module Deltacloud::Test::Methods
     end
 
     def post(path, post_body, params={})
+      if api.preferred_provider and not params[:provider]
+        params[:provider] = api.preferred_provider
+      end
       url, headers = process_url_params(path, params)
       RestClient.post url, post_body, headers
     end
@@ -147,7 +166,7 @@ module Deltacloud::Test::Methods
       url, headers = process_url_params(path, params)
       if body.is_a?(File)
         #set timeouts http://rdoc.info/github/archiloque/rest-client/RestClient/Resource
-        resource = RestClient::Resource.new(url, :open_timeout => 10, :timeout=> 9999)
+        resource = RestClient::Resource.new(url, :open_timeout => 120, :timeout=> 9999)
         resource.put  body.read, headers
       else
         RestClient.put url, body, headers
@@ -200,7 +219,7 @@ module Deltacloud::Test::Methods
       if path =~ /^https?:/
         url = path
       else
-        url = api.url + path
+        url = path.start_with?("/", ";") ? api.url + path : api.url+"/"+ path
       end
       url += "?" + params.map { |k,v| "#{k}=#{v}" }.join("&") unless params.empty?
       if ENV["LOG"] && ENV["LOG"].include?("requests")
-- 
1.7.6.5


Re: [PATCH 2/4] API TESTS: adds images and instances tests

Posted by David Lutterkort <lu...@redhat.com>.
On Thu, 2012-08-02 at 18:07 +0300, marios@redhat.com wrote:
> From: marios <ma...@redhat.com>
> 
> 
> Signed-off-by: marios <ma...@redhat.com>
> ---
>  tests/config.yaml                  |   19 ++-
>  tests/deltacloud/images_test.rb    |   73 ++++++++
>  tests/deltacloud/instances_test.rb |  351 ++++++++++++++++++++++++++++++++++++
>  3 files changed, 440 insertions(+), 3 deletions(-)

ACK

David



Re: [PATCH 2/4] API TESTS: adds images and instances tests

Posted by "marios@redhat.com" <ma...@redhat.com>.
On 02/08/12 23:53, Ronelle Landy wrote:
>> From: marios@redhat.com
>> To: dev@deltacloud.apache.org
>> Sent: Thursday, August 2, 2012 11:07:39 AM
>> Subject: [PATCH 2/4] API TESTS: adds images and instances tests
>>
>> From: marios <ma...@redhat.com>
>>
>>
>> Signed-off-by: marios <ma...@redhat.com>
>> ---
>>  tests/config.yaml                  |   19 ++-
>>  tests/deltacloud/images_test.rb    |   73 ++++++++
>>  tests/deltacloud/instances_test.rb |  351
>>  ++++++++++++++++++++++++++++++++++++
>>  3 files changed, 440 insertions(+), 3 deletions(-)
>>

-----8<-----------8<---------SNIP-------8<-----------8<---------
>>
>>
> 
> Running >> rake test:deltacloud 
> returns the error below (irrespective of the driver - tried mock and vsphere).
> Running >> rake test:deltacloud:images TEST_OPTS="-v"
> works for me.
> 
> -----------------
> 
> /home/dcloud/workspace/deltacloud/tests/deltacloud/instances_test.rb:28: warning: class variable access from toplevel
> /home/dcloud/workspace/deltacloud/tests/deltacloud/instances_test.rb:33:in `block in <top (required)>': undefined method `choice' for #<Array:0x00000001bc0768> (NoMethodError)
> 	from /usr/local/share/gems/gems/minitest-3.3.0/lib/minitest/spec.rb:71:in `class_eval'
> 	from /usr/local/share/gems/gems/minitest-3.3.0/lib/minitest/spec.rb:71:in `describe'
> 	from /home/dcloud/workspace/deltacloud/tests/deltacloud/instances_test.rb:22:in `<top (required)>'
> 	from /usr/share/rubygems/rubygems/custom_require.rb:36:in `require'
> 	from /usr/share/rubygems/rubygems/custom_require.rb:36:in `require'
> 	from /usr/local/share/gems/gems/rake-0.9.2.2/lib/rake/rake_test_loader.rb:15:in `block in <main>'
> 	from /usr/local/share/gems/gems/rake-0.9.2.2/lib/rake/rake_test_loader.rb:4:in `select'
> 	from /usr/local/share/gems/gems/rake-0.9.2.2/lib/rake/rake_test_loader.rb:4:in `<main>'
> rake aborted!
> Command failed with status (1): [/usr/bin/ruby -I"lib" -I"/usr/local/share/...]
> 
> Tasks: TOP => test:deltacloud
> (See full trace by running task with --trace)
> 


<sigh> seems we've hit another ruby 1.8/1.9 compatibility issue </sigh>

 [].choice is not defined for ruby 1.9. If I recall correctly you were
running these under 1.9.3:

[marios@name tests]$ ruby -v
ruby 1.8.7 (2012-02-08 patchlevel 358) [i386-linux]
[marios@name tests]$ irb
irb(main):001:0> [1,2,3,4,5].choice
=> 3
irb(main):002:0> exit

[marios@name tests]$ ruby -v
ruby 1.9.2p290 (2011-07-09 revision 32553) [i686-linux]
[marios@name tests]$ irb
[11.9.2p290 :001 > [1,2,3,4,5].choice
NoMethodError: undefined method `choice' for [1, 2, 3, 4, 5]:Array
	from (irb):1
	from /home/marios/.rvm/rubies/ruby-1.9.2-p290/bin/irb:16:in `<main>'
1.9.2p290 :002 > [1,2,3,4,5].sample
 => 4

The 1.9 method for random array element is 'sample' - no idea why they
*had* to use a different name/didn't just alias "sample" for "choice"
</rant>

I'll find some way to make this work for both before pushing- either
alias choice for sample or 'manually' implement a 'select random
element' method (likely the second).

marios

Re: [PATCH 2/4] API TESTS: adds images and instances tests

Posted by Ronelle Landy <rl...@redhat.com>.
> From: marios@redhat.com
> To: dev@deltacloud.apache.org
> Sent: Thursday, August 2, 2012 11:07:39 AM
> Subject: [PATCH 2/4] API TESTS: adds images and instances tests
> 
> From: marios <ma...@redhat.com>
> 
> 
> Signed-off-by: marios <ma...@redhat.com>
> ---
>  tests/config.yaml                  |   19 ++-
>  tests/deltacloud/images_test.rb    |   73 ++++++++
>  tests/deltacloud/instances_test.rb |  351
>  ++++++++++++++++++++++++++++++++++++
>  3 files changed, 440 insertions(+), 3 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/images_test.rb
> b/tests/deltacloud/images_test.rb
> index e69de29..1313dbd 100644
> --- a/tests/deltacloud/images_test.rb
> +++ b/tests/deltacloud/images_test.rb
> @@ -0,0 +1,73 @@
> +#
> +# 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
> +  CommonCollectionsTest::run_common_tests_for("images")
> +
> +  #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..5038f28 100644
> --- a/tests/deltacloud/instances_test.rb
> +++ b/tests/deltacloud/instances_test.rb
> @@ -0,0 +1,351 @@
> +#
> +# 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
> +  CommonCollectionsTest::run_common_tests_for("instances")
> +
> +  #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
> 
> 

Running >> rake test:deltacloud 
returns the error below (irrespective of the driver - tried mock and vsphere).
Running >> rake test:deltacloud:images TEST_OPTS="-v"
works for me.

-----------------

/home/dcloud/workspace/deltacloud/tests/deltacloud/instances_test.rb:28: warning: class variable access from toplevel
/home/dcloud/workspace/deltacloud/tests/deltacloud/instances_test.rb:33:in `block in <top (required)>': undefined method `choice' for #<Array:0x00000001bc0768> (NoMethodError)
	from /usr/local/share/gems/gems/minitest-3.3.0/lib/minitest/spec.rb:71:in `class_eval'
	from /usr/local/share/gems/gems/minitest-3.3.0/lib/minitest/spec.rb:71:in `describe'
	from /home/dcloud/workspace/deltacloud/tests/deltacloud/instances_test.rb:22:in `<top (required)>'
	from /usr/share/rubygems/rubygems/custom_require.rb:36:in `require'
	from /usr/share/rubygems/rubygems/custom_require.rb:36:in `require'
	from /usr/local/share/gems/gems/rake-0.9.2.2/lib/rake/rake_test_loader.rb:15:in `block in <main>'
	from /usr/local/share/gems/gems/rake-0.9.2.2/lib/rake/rake_test_loader.rb:4:in `select'
	from /usr/local/share/gems/gems/rake-0.9.2.2/lib/rake/rake_test_loader.rb:4:in `<main>'
rake aborted!
Command failed with status (1): [/usr/bin/ruby -I"lib" -I"/usr/local/share/...]

Tasks: TOP => test:deltacloud
(See full trace by running task with --trace)

[PATCH 2/4] API TESTS: adds images and instances tests

Posted by ma...@redhat.com.
From: marios <ma...@redhat.com>


Signed-off-by: marios <ma...@redhat.com>
---
 tests/config.yaml                  |   19 ++-
 tests/deltacloud/images_test.rb    |   73 ++++++++
 tests/deltacloud/instances_test.rb |  351 ++++++++++++++++++++++++++++++++++++
 3 files changed, 440 insertions(+), 3 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/images_test.rb b/tests/deltacloud/images_test.rb
index e69de29..1313dbd 100644
--- a/tests/deltacloud/images_test.rb
+++ b/tests/deltacloud/images_test.rb
@@ -0,0 +1,73 @@
+#
+# 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
+  CommonCollectionsTest::run_common_tests_for("images")
+
+  #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..5038f28 100644
--- a/tests/deltacloud/instances_test.rb
+++ b/tests/deltacloud/instances_test.rb
@@ -0,0 +1,351 @@
+#
+# 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
+  CommonCollectionsTest::run_common_tests_for("instances")
+
+  #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


Re: [PATCH 4/4] API TESTS: adds README file, rake routes

Posted by David Lutterkort <lu...@redhat.com>.
On Thu, 2012-08-02 at 18:07 +0300, marios@redhat.com wrote:
> From: marios <ma...@redhat.com>
> 
> 
> Signed-off-by: marios <ma...@redhat.com>
> ---
>  tests/README                      |  101 +++++++++++++++++++++++++++++++++++++
>  tests/Rakefile                    |   10 +++-
>  tests/deltacloud/base_api_test.rb |    8 ++--
>  3 files changed, 114 insertions(+), 5 deletions(-)
>  create mode 100644 tests/README

ACK; great docs

> diff --git a/tests/README b/tests/README
> new file mode 100644
> index 0000000..e273248
> --- /dev/null
> +++ b/tests/README
> @@ -0,0 +1,101 @@
> +API TESTS README:
> +=================
> +
> +These tests use RestClient [https://github.com/archiloque/rest-client] to make
> +requests to a deltacloud server running somewhere. The requests/tests are meant
> + to exercise all the REST routes defined in the API
> +[http://deltacloud.apache.org/rest-api.html]. At minimum you need to configure
> +the tests with the location of the deltacloud server to be tested, as well as
> +the credentials for the driver you expect to be running at that deltacloud server.
> + Otherwise you'll see a RunTime error like:
> +
> +"No user or password in config.yaml for openstack driver used by
> +http://localhost:3001/api"
> +
> +
> +RUNNING the tests:
> +==================
> +
> +* Need a deltacloud server running somewhere
> +* edit the config.yaml file (more on this below)
> +* rake test:deltacloud to run all tests
> +* rake test:deltacloud:COLLECTION to run a specific collection test, or 'base_api'
> +  for just the API tests.... e.g. rake test:deltacloud:buckets, rake
> +  test:deltacloud:base_api, rake test:deltacloud:images
> +* more verbose output is achieved by passing TEST_OPTS="-v", e.g.
> +  rake test:deltacloud TEST_OPTS="-v"

Add the following:

        * you can use your own config.yaml by passing it via the CONFIG
        variable to the rake task:
                rake test:deltacloud CONFIG=/some/where/config.yaml

David



[PATCH 4/4] API TESTS: adds README file, rake routes

Posted by ma...@redhat.com.
From: marios <ma...@redhat.com>


Signed-off-by: marios <ma...@redhat.com>
---
 tests/README                      |  101 +++++++++++++++++++++++++++++++++++++
 tests/Rakefile                    |   10 +++-
 tests/deltacloud/base_api_test.rb |    8 ++--
 3 files changed, 114 insertions(+), 5 deletions(-)
 create mode 100644 tests/README

diff --git a/tests/README b/tests/README
new file mode 100644
index 0000000..e273248
--- /dev/null
+++ b/tests/README
@@ -0,0 +1,101 @@
+API TESTS README:
+=================
+
+These tests use RestClient [https://github.com/archiloque/rest-client] to make
+requests to a deltacloud server running somewhere. The requests/tests are meant
+ to exercise all the REST routes defined in the API
+[http://deltacloud.apache.org/rest-api.html]. At minimum you need to configure
+the tests with the location of the deltacloud server to be tested, as well as
+the credentials for the driver you expect to be running at that deltacloud server.
+ Otherwise you'll see a RunTime error like:
+
+"No user or password in config.yaml for openstack driver used by
+http://localhost:3001/api"
+
+
+RUNNING the tests:
+==================
+
+* Need a deltacloud server running somewhere
+* edit the config.yaml file (more on this below)
+* rake test:deltacloud to run all tests
+* rake test:deltacloud:COLLECTION to run a specific collection test, or 'base_api'
+  for just the API tests.... e.g. rake test:deltacloud:buckets, rake
+  test:deltacloud:base_api, rake test:deltacloud:images
+* more verbose output is achieved by passing TEST_OPTS="-v", e.g.
+  rake test:deltacloud TEST_OPTS="-v"
+
+
+CONFIGURATION - the config.yaml file:
+=====================================
+
+* api_url - set this to the URI for the running deltacloud server
+* each driver has it's own section... enter credentials for the driver
+  you expect to be running at api_url. If there is no section for your driver,
+  add it - the section should have the name used by the deltacloud server for that
+  driver. For example for the rhevm driver:
+
+---
+api_url: "http://localhost:3003/api"
+mock:
+  user: "mockuser"
+  password: "mockpassword"
+#this is a comment
+rhevm:
+  user: "username"
+  password: "mypassword"
+
+* running the instances collection tests involves launching instances. The image,
+  realm and hardware profile used to launch those instances are chosen at random
+  from the returned lists. However, this may cause errors to occur - especially
+  in EC2 where for example a given realm may be 'at capacity' and not accepting
+  any more requests ("please use us-east-1b/1c/1a instead"), or your user creds
+  may not allow you to launch a particular image  (again this was seen for ec2).
+  If you are hitting errors like this, you can configure a 'preferred'
+  image/realm/hardware_profile to use for the instances test. Refer to the 'ec2'
+  section of the config.yaml file:
+
+ec2:
+  user: KEY
+  password: SECRET_KEY
+  instances:
+    preferred_image: "ami-2b5fba42"
+    preferred_hwp: "m1.small"
+    preferred_realm: "us-east-1b"
+
+You can add this 'instances' section under any driver in the config.yaml file and
+those values will be used in the instances test. You can also only include only
+some of those, for example a preferred_image but not a preferred_hwp.
+
+
+FILE LAYOUT:
+============
+deltacloud
+|--D-->tests
+|------------------------------------------------------------------------------
+   |----->config.yaml                       the tests config file
+   |---------------------------------------------------------------------------
+   |----->Rakefile                          rake routes for running tests
+   |---------------------------------------------------------------------------
+   |--D-->deprecated                        'old' cuke tests - for reference
+   |---------------------------------------------------------------------------
+   |--D-->deltacloud                        tests for the deltacloud API - idea
+      |                                     is for test directories to be added
+      |                                     for CIMI and EC2 frontends
+      |------------------------------------------------------------------------
+      |-----> test_setup.rb                 loads configuration, wrappers for
+      |                                     RestClient methods (get/put/post
+      |                                     etc) and mini DSL - like
+      |                                     need_collection/need_feature.
+      |------------------------------------------------------------------------
+      |-----> base_api_test.rb              tests for the API itself
+      |------------------------------------------------------------------------
+      |-----> common_tests_collections.rb   common tests that are executed
+      |                                     for all collections
+      |------------------------------------------------------------------------
+      |-----> instances_test.rb             tests for instances collection
+      |------------------------------------------------------------------------
+      |-----> images_test.rb                tests for images collection
+      |------------------------------------------------------------------------
+      |... etc for all the collections
+
diff --git a/tests/Rakefile b/tests/Rakefile
index 26b27a4..88c1966 100644
--- a/tests/Rakefile
+++ b/tests/Rakefile
@@ -20,6 +20,14 @@ namespace :test do
   desc "Run tests for the Deltacloud API frontend."
   Rake::TestTask.new(:deltacloud) do |t|
     t.test_files = FileList["deltacloud/*_test.rb"]
-    t.options = "-v"
   end
+
+  namespace :deltacloud do
+    ["base_api", "buckets", "images", "instances", "instance_states", "keys", "realms", "storage_volumes", "storage_snapshots", "hardware_profiles"].each do |col|
+      Rake::TestTask.new(col) do |t|
+        t.test_files = FileList["deltacloud/#{col}_test.rb"]
+      end
+    end
+  end
+
 end
diff --git a/tests/deltacloud/base_api_test.rb b/tests/deltacloud/base_api_test.rb
index bd37b46..841b299 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
 
-- 
1.7.6.5


Re: [PATCH 1/4] API TESTS - moves common collections tests to separate module

Posted by David Lutterkort <lu...@redhat.com>.
On Thu, 2012-08-02 at 18:07 +0300, marios@redhat.com wrote:
> From: marios <ma...@redhat.com>
> 
> 
> Signed-off-by: marios <ma...@redhat.com>
> ---
>  tests/deltacloud/buckets_test.rb             |  134 ++++++++++----------------
>  tests/deltacloud/common_tests_collections.rb |  114 ++++++++++++++++++++++
>  tests/deltacloud/test_setup.rb               |   25 ++++-
>  3 files changed, 187 insertions(+), 86 deletions(-)
>  create mode 100644 tests/deltacloud/common_tests_collections.rb

Concerning those failures: the first seems to be a genuine mistake in
the test:

          1) Failure:
        test_0005_must have the instance_states element on top level(Deltacloud API ins
        tance_states collection) [/homes/lutter/code/deltacloud/git/tests/deltacloud/in
        stance_states_test.rb:49]: 
        Expected: "instance_states"
          Actual: "states"
        
.. there goes my clever plan of not duplicating common tests for
instance states. Seems they are just a one off.

There are four more failures (attached) that are all due to getting a
500 in instances_test.rb:84 from a GET /images - seems like there is
some genuine bug in the server code. Ran the server with
'./bin/deltacloudd -i mock' - the server log has no stacktrace, just a
line indicating that a status 500 was returned.

David


Re: [PATCH 1/4] API TESTS - moves common collections tests to separate module

Posted by David Lutterkort <lu...@redhat.com>.
On Thu, 2012-08-02 at 18:07 +0300, marios@redhat.com wrote:
> From: marios <ma...@redhat.com>
> 
> 
> Signed-off-by: marios <ma...@redhat.com>
> ---
>  tests/deltacloud/buckets_test.rb             |  134 ++++++++++----------------
>  tests/deltacloud/common_tests_collections.rb |  114 ++++++++++++++++++++++
>  tests/deltacloud/test_setup.rb               |   25 ++++-
>  3 files changed, 187 insertions(+), 86 deletions(-)
>  create mode 100644 tests/deltacloud/common_tests_collections.rb

ACK. (I get a few test failures, but I'll mail about them separately)

> diff --git a/tests/deltacloud/buckets_test.rb b/tests/deltacloud/buckets_test.rb
> index e8732b1..b829b30 100644
> --- a/tests/deltacloud/buckets_test.rb
> +++ b/tests/deltacloud/buckets_test.rb
> @@ -61,19 +61,61 @@ describe 'Deltacloud API buckets collection' do
>      end
>    }

There seem to be a few tests that are duplicated; running

        egrep '^ *it' deltacloud/buckets_test.rb | sort | uniq -c

shows three duplicated tests.


> -  it 'must advertise the buckets collection in API entrypoint' do
> +  #Run the 'common' tests for all collections defined in common_tests_collections.rb
> +  CommonCollectionsTest::run_common_tests_for("buckets")

Nice - I very much like this way of including common tests.

> -    res = get("/").xml
> -    (res/'api/link[@rel=buckets]').wont_be_empty
> +  #Now run the bucket-specific tests:
> +  it 'must have the "size" element defined for each bucket in collection' do
> +    res = get(BUCKETS, :accept => :xml)
> +    (res.xml/'buckets/bucket').each do |r|
> +      (r/'size').wont_be_nil
> +      (r/'size').wont_be_empty
> +    end
>    end

If no buckets are returned, this test will pass; we should check
somewhere that the bucket we created in the prologue actually shows up
under /buckets/bucket

One more general comment: since we have ':accept => :xml' almost
everywhere, we should probably make that the default in the get/put/etc.
helpers.

David



Re: [PATCH 3/4] API TESTS: adds base tests for all collections - to be expanded

Posted by David Lutterkort <lu...@redhat.com>.
On Thu, 2012-08-02 at 18:07 +0300, marios@redhat.com wrote:
> From: marios <ma...@redhat.com>
> 
> 
> Signed-off-by: marios <ma...@redhat.com>
> ---
>  tests/deltacloud/hardware_profiles_test.rb |   28 +++++++++++++++
>  tests/deltacloud/instance_states_test.rb   |   52 ++++++++++++++++++++++++++++
>  tests/deltacloud/keys_test.rb              |   28 +++++++++++++++
>  tests/deltacloud/realms_test.rb            |   29 +++++++++++++++
>  tests/deltacloud/storage_snapshots_test.rb |   28 +++++++++++++++
>  tests/deltacloud/storage_volumes_test.rb   |   28 +++++++++++++++
>  6 files changed, 193 insertions(+), 0 deletions(-)

ACK

> diff --git a/tests/deltacloud/instance_states_test.rb b/tests/deltacloud/instance_states_test.rb
> index e69de29..d58d9ca 100644
> --- a/tests/deltacloud/instance_states_test.rb
> +++ b/tests/deltacloud/instance_states_test.rb
> @@ -0,0 +1,52 @@

These are a subset of CommonCollectionsTest::run_common_tests_for -
maybe they should be split into a separate method in
CommonCollectionsTest which can be called by both run_common_tests_for
and by this test suite. It seems the split is between common tests for
the collection and common tests for members of hte collection (whcih
instance_states does not have)

David



[PATCH 3/4] API TESTS: adds base tests for all collections - to be expanded

Posted by ma...@redhat.com.
From: marios <ma...@redhat.com>


Signed-off-by: marios <ma...@redhat.com>
---
 tests/deltacloud/hardware_profiles_test.rb |   28 +++++++++++++++
 tests/deltacloud/instance_states_test.rb   |   52 ++++++++++++++++++++++++++++
 tests/deltacloud/keys_test.rb              |   28 +++++++++++++++
 tests/deltacloud/realms_test.rb            |   29 +++++++++++++++
 tests/deltacloud/storage_snapshots_test.rb |   28 +++++++++++++++
 tests/deltacloud/storage_volumes_test.rb   |   28 +++++++++++++++
 6 files changed, 193 insertions(+), 0 deletions(-)

diff --git a/tests/deltacloud/hardware_profiles_test.rb b/tests/deltacloud/hardware_profiles_test.rb
index e69de29..4e73ed5 100644
--- a/tests/deltacloud/hardware_profiles_test.rb
+++ b/tests/deltacloud/hardware_profiles_test.rb
@@ -0,0 +1,28 @@
+#
+# 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"
+
+describe 'Deltacloud API hardware_profiles collection' do
+  include Deltacloud::Test::Methods
+
+  need_collection :hardware_profiles
+
+  #Run the 'common' tests for all collections defined in common_tests_collections.rb
+  CommonCollectionsTest::run_common_tests_for("hardware_profiles")
+
+end
diff --git a/tests/deltacloud/instance_states_test.rb b/tests/deltacloud/instance_states_test.rb
index e69de29..d58d9ca 100644
--- a/tests/deltacloud/instance_states_test.rb
+++ b/tests/deltacloud/instance_states_test.rb
@@ -0,0 +1,52 @@
+#
+# 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"
+
+describe 'Deltacloud API instance_states collection' do
+  include Deltacloud::Test::Methods
+
+  need_collection :instance_states
+
+  it "must advertise the instance_states collection in API entrypoint" do
+    res = get("/").xml
+    (res/"api/link[@rel=instance_states]").wont_be_empty
+  end
+
+  it "should respond with HTTP_OK when accessing the instance_states collection with authentication" do
+    res = get("instance_states")
+    res.code.must_equal 200
+  end
+
+  it 'should support the JSON media type' do
+    res = get("instance_states", :accept=>:json)
+    res.code.must_equal 200
+    res.headers[:content_type].must_equal 'application/json'
+    assert_silent {JSON.parse(res)}
+  end
+
+  it 'must include the ETag in HTTP headers' do
+    res = get("instance_states")
+    res.headers[:etag].wont_be_nil
+  end
+
+  it "must have the instance_states element on top level" do
+    res = get("instance_states", :accept=>:xml)
+    res.xml.root.name.must_equal "instance_states"
+  end
+
+end
diff --git a/tests/deltacloud/keys_test.rb b/tests/deltacloud/keys_test.rb
index e69de29..fd300b5 100644
--- a/tests/deltacloud/keys_test.rb
+++ b/tests/deltacloud/keys_test.rb
@@ -0,0 +1,28 @@
+#
+# 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"
+
+describe 'Deltacloud API keys collection' do
+  include Deltacloud::Test::Methods
+
+  need_collection :keys
+
+  #Run the 'common' tests for all collections defined in common_tests_collections.rb
+  CommonCollectionsTest::run_common_tests_for("keys")
+
+end
diff --git a/tests/deltacloud/realms_test.rb b/tests/deltacloud/realms_test.rb
index e69de29..b679028 100644
--- a/tests/deltacloud/realms_test.rb
+++ b/tests/deltacloud/realms_test.rb
@@ -0,0 +1,29 @@
+#
+# 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"
+
+describe 'Deltacloud API realms collection' do
+  include Deltacloud::Test::Methods
+
+  need_collection :realms
+
+  #Run the 'common' tests for all collections defined in common_tests_collections.rb
+  CommonCollectionsTest::run_common_tests_for("realms")
+
+end
+
diff --git a/tests/deltacloud/storage_snapshots_test.rb b/tests/deltacloud/storage_snapshots_test.rb
index e69de29..6daa7ff 100644
--- a/tests/deltacloud/storage_snapshots_test.rb
+++ b/tests/deltacloud/storage_snapshots_test.rb
@@ -0,0 +1,28 @@
+#
+# 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"
+
+describe 'Deltacloud API storage_snapshots collection' do
+  include Deltacloud::Test::Methods
+
+  need_collection :storage_snapshots
+
+  #Run the 'common' tests for all collections defined in common_tests_collections.rb
+  CommonCollectionsTest::run_common_tests_for("storage_snapshots")
+
+end
diff --git a/tests/deltacloud/storage_volumes_test.rb b/tests/deltacloud/storage_volumes_test.rb
index e69de29..7d2c96c 100644
--- a/tests/deltacloud/storage_volumes_test.rb
+++ b/tests/deltacloud/storage_volumes_test.rb
@@ -0,0 +1,28 @@
+#
+# 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"
+
+describe 'Deltacloud API storage_volumes collection' do
+  include Deltacloud::Test::Methods
+
+  need_collection :storage_volumes
+
+  #Run the 'common' tests for all collections defined in common_tests_collections.rb
+  CommonCollectionsTest::run_common_tests_for("storage_volumes")
+
+end
-- 
1.7.6.5