deltacloud-core 0.0.2 → 0.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (64) hide show
  1. data/COPYING +176 -502
  2. data/Rakefile +21 -14
  3. data/deltacloud.rb +3 -0
  4. data/lib/deltacloud/base_driver.rb +12 -11
  5. data/lib/deltacloud/base_driver/base_driver.rb +22 -11
  6. data/lib/deltacloud/drivers/ec2/ec2_driver.rb +15 -12
  7. data/lib/deltacloud/drivers/gogrid/gogrid_driver.rb +16 -11
  8. data/lib/deltacloud/drivers/mock/data/images/img1.yml +3 -0
  9. data/lib/deltacloud/drivers/mock/data/images/img2.yml +3 -0
  10. data/lib/deltacloud/drivers/mock/data/images/img3.yml +3 -0
  11. data/lib/deltacloud/drivers/mock/data/instances/inst0.yml +16 -0
  12. data/lib/deltacloud/drivers/mock/data/instances/inst1.yml +9 -0
  13. data/lib/deltacloud/drivers/mock/data/instances/inst2.yml +9 -0
  14. data/lib/deltacloud/drivers/mock/data/storage_snapshots/snap1.yml +4 -0
  15. data/lib/deltacloud/drivers/mock/data/storage_snapshots/snap2.yml +4 -0
  16. data/lib/deltacloud/drivers/mock/data/storage_snapshots/snap3.yml +4 -0
  17. data/lib/deltacloud/drivers/mock/data/storage_volumes/vol1.yml +6 -0
  18. data/lib/deltacloud/drivers/mock/data/storage_volumes/vol2.yml +6 -0
  19. data/lib/deltacloud/drivers/mock/data/storage_volumes/vol3.yml +6 -0
  20. data/lib/deltacloud/drivers/mock/mock_driver.rb +13 -11
  21. data/lib/deltacloud/drivers/rackspace/rackspace_client.rb +12 -11
  22. data/lib/deltacloud/drivers/rackspace/rackspace_driver.rb +12 -11
  23. data/lib/deltacloud/drivers/rhevm/rhevm_driver.rb +12 -11
  24. data/lib/deltacloud/drivers/rimuhosting/rimuhosting_client.rb +12 -11
  25. data/lib/deltacloud/drivers/rimuhosting/rimuhosting_driver.rb +14 -12
  26. data/lib/deltacloud/drivers/terremark/terremark_driver.rb +12 -11
  27. data/lib/deltacloud/helpers/application_helper.rb +64 -11
  28. data/lib/deltacloud/helpers/conversion_helper.rb +12 -11
  29. data/lib/deltacloud/method_serializer.rb +12 -11
  30. data/lib/deltacloud/models/base_model.rb +12 -11
  31. data/lib/deltacloud/models/image.rb +12 -11
  32. data/lib/deltacloud/models/instance.rb +13 -12
  33. data/lib/deltacloud/models/instance_profile.rb +12 -11
  34. data/lib/deltacloud/models/realm.rb +12 -11
  35. data/lib/deltacloud/models/storage_snapshot.rb +12 -11
  36. data/lib/deltacloud/models/storage_volume.rb +12 -11
  37. data/lib/drivers.rb +12 -0
  38. data/lib/sinatra/rabbit.rb +1 -0
  39. data/lib/sinatra/respond_to.rb +3 -0
  40. data/server.rb +40 -80
  41. data/tests/api_test.rb +37 -0
  42. data/tests/hardware_profiles_test.rb +120 -0
  43. data/tests/images_test.rb +95 -78
  44. data/tests/instance_states_test.rb +52 -0
  45. data/tests/instances_test.rb +193 -110
  46. data/tests/realms_test.rb +66 -44
  47. data/views/errors/not_found.html.haml +6 -0
  48. data/views/errors/not_found.xml.haml +2 -0
  49. data/views/hardware_profiles/index.xml.haml +1 -1
  50. data/views/hardware_profiles/show.xml.haml +3 -2
  51. data/views/images/index.xml.haml +4 -3
  52. data/views/images/show.xml.haml +2 -2
  53. data/views/instances/index.xml.haml +6 -8
  54. data/views/instances/show.xml.haml +9 -10
  55. data/views/realms/index.xml.haml +1 -3
  56. data/views/realms/show.xml.haml +4 -5
  57. data/views/storage_snapshots/index.xml.haml +3 -5
  58. data/views/storage_snapshots/show.xml.haml +2 -4
  59. data/views/storage_volumes/index.xml.haml +7 -7
  60. data/views/storage_volumes/show.xml.haml +2 -4
  61. metadata +156 -81
  62. data/tests/deltacloud_test.rb +0 -60
  63. data/tests/storage_snapshots_test.rb +0 -48
  64. data/tests/storage_volumes_test.rb +0 -48
@@ -1,19 +1,20 @@
1
1
  #
2
2
  # Copyright (C) 2009 Red Hat, Inc.
3
3
  #
4
- # This library is free software; you can redistribute it and/or
5
- # modify it under the terms of the GNU Lesser General Public
6
- # License as published by the Free Software Foundation; either
7
- # version 2.1 of the License, or (at your option) any later version.
4
+ # Licensed to the Apache Software Foundation (ASF) under one or more
5
+ # contributor license agreements. See the NOTICE file distributed with
6
+ # this work for additional information regarding copyright ownership. The
7
+ # ASF licenses this file to you under the Apache License, Version 2.0 (the
8
+ # "License"); you may not use this file except in compliance with the
9
+ # License. You may obtain a copy of the License at
8
10
  #
9
- # This library is distributed in the hope that it will be useful,
10
- # but WITHOUT ANY WARRANTY; without even the implied warranty of
11
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12
- # Lesser General Public License for more details.
11
+ # http://www.apache.org/licenses/LICENSE-2.0
13
12
  #
14
- # You should have received a copy of the GNU Lesser General Public
15
- # License along with this library; if not, write to the Free Software
16
- # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
13
+ # Unless required by applicable law or agreed to in writing, software
14
+ # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15
+ # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
16
+ # License for the specific language governing permissions and limitations
17
+ # under the License.
17
18
 
18
19
 
19
20
  class StorageVolume < BaseModel
data/lib/drivers.rb CHANGED
@@ -9,6 +9,18 @@ DRIVERS = {
9
9
  :mock => { :name => "Mock" }
10
10
  }
11
11
 
12
+ DEFAULT_COLLECTIONS = [
13
+ :hardware_profiles,
14
+ :images,
15
+ :instances,
16
+ :instance_states,
17
+ :realms,
18
+ :storage_volumes,
19
+ :storage_snapshots
20
+ ]
21
+
22
+ DRIVER=ENV['API_DRIVER'] ? ENV['API_DRIVER'].to_sym : :mock
23
+
12
24
  def driver_name
13
25
  DRIVERS[DRIVER][:name]
14
26
  end
@@ -203,6 +203,7 @@ module Sinatra
203
203
  # operation on this collection.
204
204
  def collection(name, &block)
205
205
  raise DuplicateCollectionException if collections[name]
206
+ return unless driver.has_collection?(name.to_sym)
206
207
  collections[name] = Collection.new(name, &block)
207
208
  collections[name].add_feature_params(driver.features(name))
208
209
  collections[name].generate
@@ -267,3 +267,6 @@ module Sinatra
267
267
  end
268
268
  end
269
269
  end
270
+
271
+ Rack::Mime::MIME_TYPES.merge!({ ".gv" => "text/plain" })
272
+ Sinatra::Application.register Sinatra::RespondTo
data/server.rb CHANGED
@@ -1,21 +1,18 @@
1
- require 'rubygems'
1
+ require 'sinatra'
2
2
  require 'deltacloud'
3
+ require 'drivers'
3
4
  require 'json'
4
- require 'sinatra'
5
5
  require 'sinatra/respond_to'
6
- require 'erb'
7
- require 'haml'
8
- require 'open3'
9
- require 'builder'
10
- require 'drivers'
11
6
  require 'sinatra/static_assets'
12
7
  require 'sinatra/rabbit'
13
8
  require 'sinatra/lazy_auth'
14
- require 'deltacloud/validation'
15
- require 'deltacloud/helpers'
9
+ require 'erb'
10
+ require 'haml'
11
+ require 'open3'
16
12
 
17
13
  configure do
18
14
  set :raise_errors => false
15
+ set :show_exceptions, false
19
16
  end
20
17
 
21
18
  configure :development do
@@ -24,59 +21,10 @@ configure :development do
24
21
  $stderr.sync = true
25
22
  end
26
23
 
27
- DRIVER=ENV['API_DRIVER'] ? ENV['API_DRIVER'].to_sym : :mock
28
-
29
24
  # You could use $API_HOST environment variable to change your hostname to
30
25
  # whatever you want (eg. if you running API behind NAT)
31
26
  HOSTNAME=ENV['API_HOST'] ? ENV['API_HOST'] : nil
32
27
 
33
- Rack::Mime::MIME_TYPES.merge!({ ".gv" => "text/plain" })
34
-
35
- Sinatra::Application.register Sinatra::RespondTo
36
-
37
- # Common actions
38
- #
39
-
40
- def filter_all(model)
41
- filter = {}
42
- filter.merge!(:id => params[:id]) if params[:id]
43
- filter.merge!(:architecture => params[:architecture]) if params[:architecture]
44
- filter.merge!(:owner_id => params[:owner_id]) if params[:owner_id]
45
- filter.merge!(:state => params[:state]) if params[:state]
46
- filter = nil if filter.keys.size.eql?(0)
47
- singular = model.to_s.singularize.to_sym
48
- @elements = driver.send(model.to_sym, credentials, filter)
49
- instance_variable_set(:"@#{model}", @elements)
50
- respond_to do |format|
51
- format.html { haml :"#{model}/index" }
52
- format.xml { haml :"#{model}/index" }
53
- format.json { convert_to_json(singular, @elements) }
54
- end
55
- end
56
-
57
- def show(model)
58
- @element = driver.send(model, credentials, { :id => params[:id]} )
59
- instance_variable_set("@#{model}", @element)
60
- respond_to do |format|
61
- format.html { haml :"#{model.to_s.pluralize}/show" }
62
- format.xml { haml :"#{model.to_s.pluralize}/show" }
63
- format.json { convert_to_json(model, @element) }
64
- end
65
- end
66
-
67
-
68
- #
69
- # Error handlers
70
- #
71
- def report_error(status, template)
72
- @error = request.env['sinatra.error']
73
- response.status = status
74
- respond_to do |format|
75
- format.xml { haml :"errors/#{template}", :layout => false }
76
- format.html { haml :"errors/#{template}" }
77
- end
78
- end
79
-
80
28
  error Deltacloud::Validation::Failure do
81
29
  report_error(400, "validation_failure")
82
30
  end
@@ -93,7 +41,7 @@ end
93
41
  get '/' do redirect '/api'; end
94
42
 
95
43
  get '/api\/?' do
96
- @version = 1.0
44
+ @version = 0.1
97
45
  respond_to do |format|
98
46
  format.xml { haml :"api/show" }
99
47
  format.json do
@@ -111,10 +59,20 @@ end
111
59
  # Rabbit DSL
112
60
 
113
61
  collection :realms do
114
- description "Within a cloud provider a realm represents a boundary containing resources. The exact definition of a realm is left to the cloud provider. In some cases, a realm may represent different datacenters, different continents, or different pools of resources within a single datacenter. A cloud provider may insist that resources must all exist within a single realm in order to cooperate. For instance, storage volumes may only be allowed to be mounted to instances within the same realm."
62
+ description <<END
63
+ Within a cloud provider a realm represents a boundary containing resources.
64
+ The exact definition of a realm is left to the cloud provider.
65
+ In some cases, a realm may represent different datacenters, different continents,
66
+ or different pools of resources within a single datacenter.
67
+ A cloud provider may insist that resources must all exist within a single realm in
68
+ order to cooperate. For instance, storage volumes may only be allowed to be mounted to
69
+ instances within the same realm.
70
+ END
115
71
 
116
72
  operation :index do
117
- description 'Operation will list all available realms. For specific architecture use "architecture" parameter.'
73
+ description <<END
74
+ Operation will list all available realms. For specific architecture use "architecture" parameter.
75
+ END
118
76
  param :id, :string
119
77
  param :architecture, :string, :optional, [ 'i386', 'x86_64' ]
120
78
  control { filter_all(:realms) }
@@ -130,10 +88,17 @@ collection :realms do
130
88
  end
131
89
 
132
90
  collection :images do
133
- description "An image is a platonic form of a machine. Images are not directly executable, but are a template for creating actual instances of machines."
91
+ description <<END
92
+ An image is a platonic form of a machine. Images are not directly executable,
93
+ but are a template for creating actual instances of machines."
94
+ END
134
95
 
135
96
  operation :index do
136
- description 'The instances collection will return a set of all images available to the current use. You can filter images using "owner_id" and "architecture" parameter'
97
+ description <<END
98
+ The instances collection will return a set of all images
99
+ available to the current use. You can filter images using
100
+ "owner_id" and "architecture" parameter
101
+ END
137
102
  param :id, :string
138
103
  param :owner_id, :string
139
104
  param :architecture, :string, :optional
@@ -196,20 +161,11 @@ get "/api/instances/new" do
196
161
  end
197
162
  end
198
163
 
199
- def instance_action(name)
200
- @instance = driver.send(:"#{name}_instance", credentials, params["id"])
201
-
202
- return redirect(instances_url) if name.eql?(:destroy) or @instance.class!=Instance
203
-
204
- respond_to do |format|
205
- format.html { haml :"instances/show" }
206
- format.xml { haml :"instances/show" }
207
- format.json {convert_to_json(:instance, @instance) }
208
- end
209
- end
210
-
211
164
  collection :instances do
212
- description "An instance is a concrete machine realized from an image. The images collection may be obtained by following the link from the primary entry-point."
165
+ description <<END
166
+ An instance is a concrete machine realized from an image.
167
+ The images collection may be obtained by following the link from the primary entry-point."
168
+ END
213
169
 
214
170
  operation :index do
215
171
  description "List all instances"
@@ -299,10 +255,14 @@ END
299
255
  param :id, :string, :required
300
256
  control do
301
257
  @profile = driver.hardware_profile(credentials, params[:id])
302
- respond_to do |format|
303
- format.xml { haml :'hardware_profiles/show', :layout => false }
304
- format.html { haml :'hardware_profiles/show' }
305
- format.json { convert_to_json(:hardware_profile, @profile) }
258
+ if @profile
259
+ respond_to do |format|
260
+ format.xml { haml :'hardware_profiles/show', :layout => false }
261
+ format.html { haml :'hardware_profiles/show' }
262
+ format.json { convert_to_json(:hardware_profile, @profile) }
263
+ end
264
+ else
265
+ report_error(404, 'not_found')
306
266
  end
307
267
  end
308
268
  end
data/tests/api_test.rb ADDED
@@ -0,0 +1,37 @@
1
+ require 'tests/common'
2
+
3
+ module DeltacloudUnitTest
4
+ class ApiTest < Test::Unit::TestCase
5
+ include Rack::Test::Methods
6
+
7
+ def app
8
+ Sinatra::Application
9
+ end
10
+
11
+ def test_it_returns_entry_points
12
+ do_xml_request '/api'
13
+ (last_xml_response/'/api/link').map.size.should > 0
14
+ end
15
+
16
+ def test_it_has_correct_attributes_set
17
+ do_xml_request '/api'
18
+ (last_xml_response/'/api/link').each do |link|
19
+ link.attributes.keys.sort.should == [ 'href', 'rel' ]
20
+ end
21
+ end
22
+
23
+ def test_it_responses_to_html
24
+ do_request '/api', {}, false, { :format => :html }
25
+ last_response.status.should == 200
26
+ Nokogiri::HTML(last_response.body).search('html').first.name.should == 'html'
27
+ end
28
+
29
+ def test_it_responses_to_json
30
+ do_request '/api', {}, false, { :format => :json }
31
+ last_response.status.should == 200
32
+ JSON::parse(last_response.body).class.should == Hash
33
+ JSON::parse(last_response.body)['api'].class.should == Hash
34
+ end
35
+
36
+ end
37
+ end
@@ -0,0 +1,120 @@
1
+ require 'tests/common'
2
+
3
+ module DeltacloudUnitTest
4
+ class HardwareProfilesTest < Test::Unit::TestCase
5
+ include Rack::Test::Methods
6
+
7
+ def app
8
+ Sinatra::Application
9
+ end
10
+
11
+ def test_it_returns_hardware_profiles
12
+ do_xml_request '/api/hardware_profiles'
13
+ (last_xml_response/'hardware_profiles/hardware_profile').map.size.should > 0
14
+ end
15
+
16
+ def test_it_has_correct_attributes_set
17
+ do_xml_request '/api/hardware_profiles'
18
+ (last_xml_response/'hardware_profiles/hardware_profile').each do |profile|
19
+ profile.attributes.keys.sort.should == [ 'href', 'id' ]
20
+ end
21
+ end
22
+
23
+ def test_hardware_profiles_have_name
24
+ do_xml_request '/api/hardware_profiles'
25
+ (last_xml_response/'hardware_profiles/hardware_profile').each do |profile|
26
+ (profile/'name').text.should_not == nil
27
+ end
28
+ end
29
+
30
+ def test_hardware_profiles_have_unique_name
31
+ do_xml_request '/api/hardware_profiles'
32
+ names = []
33
+ (last_xml_response/'hardware_profiles/hardware_profile').each do |profile|
34
+ names << (profile/'name').text
35
+ end
36
+ names.should == names.uniq
37
+ end
38
+
39
+ def test_hardware_profiles_have_unique_id
40
+ do_xml_request '/api/hardware_profiles'
41
+ ids = []
42
+ (last_xml_response/'hardware_profiles/hardware_profile').each do |profile|
43
+ ids << profile['id']
44
+ end
45
+ ids.should == ids.uniq
46
+ end
47
+
48
+ def test_m1_xlarge_profile_has_correct_attributes
49
+ do_xml_request '/api/hardware_profiles'
50
+ profile = (last_xml_response/'hardware_profiles/hardware_profile[@id="m1-xlarge"]')
51
+ test_profile_properties(profile)
52
+ end
53
+
54
+ def test_it_returns_valid_hardware_profile
55
+ do_xml_request '/api/hardware_profiles/m1-xlarge'
56
+ profile = (last_xml_response/'hardware_profile')
57
+ test_profile_properties(profile)
58
+ end
59
+
60
+ def test_it_responses_to_json
61
+ do_request '/api/hardware_profiles', {}, false, { :format => :json }
62
+ JSON::parse(last_response.body).class.should == Hash
63
+ JSON::parse(last_response.body)['hardware_profiles'].class.should == Array
64
+
65
+ do_request '/api/hardware_profiles/m1-xlarge', {}, false, { :format => :json }
66
+ last_response.status.should == 200
67
+ JSON::parse(last_response.body).class.should == Hash
68
+ JSON::parse(last_response.body)['hardware_profile'].class.should == Hash
69
+ end
70
+
71
+ def test_it_responses_to_html
72
+ do_request '/api/hardware_profiles', {}, false, { :format => :html }
73
+ last_response.status.should == 200
74
+ Nokogiri::HTML(last_response.body).search('html').first.name.should == 'html'
75
+
76
+ do_request '/api/hardware_profiles/m1-xlarge', {}, false, { :format => :html }
77
+ last_response.status.should == 200
78
+ Nokogiri::HTML(last_response.body).search('html').first.name.should == 'html'
79
+ end
80
+
81
+ def test_it_returns_error_on_wrong_name
82
+ do_request '/api/hardware_profiles/m1-unknown-wrongname', {}, false, { :format => :html }
83
+ last_response.status.should == 404
84
+ do_xml_request '/api/hardware_profiles/m1-unknown-wrongname'
85
+ last_response.status.should == 404
86
+ do_request '/api/hardware_profiles/m1-unknown-wrongname', {}, false, { :format => :json }
87
+ last_response.status.should == 404
88
+ end
89
+
90
+ private
91
+
92
+ def test_profile_properties(profile)
93
+
94
+ (profile/'property').each do |properties|
95
+ properties.attributes.keys.sort.should == [ 'kind', 'name', 'unit', 'value' ]
96
+ end
97
+
98
+ (profile/'property[@name="architecture"]').first['kind'].should == 'fixed'
99
+ (profile/'property[@name="architecture"]').first['unit'].should == 'label'
100
+
101
+ (profile/'property[@name="memory"]').first['kind'].should == 'range'
102
+ (profile/'property[@name="memory"]').first['unit'].should == 'MB'
103
+ (profile/'property[@name="memory"]/range').size.should == 1
104
+ (profile/'property[@name="memory"]/range').first.attributes.keys.sort.should == [ 'first', 'last' ]
105
+
106
+ (profile/'property[@name="cpu"]').first['kind'].should == 'fixed'
107
+ (profile/'property[@name="cpu"]').first['unit'].should == 'count'
108
+
109
+ (profile/'property[@name="storage"]').first['kind'].should == 'enum'
110
+ (profile/'property[@name="storage"]').first['unit'].should == 'GB'
111
+ (profile/'property[@name="storage"]/enum').size.should == 1
112
+ (profile/'property[@name="storage"]/enum/entry').map.size.should == 3
113
+ (profile/'property[@name="storage"]/enum/entry').each do |entry|
114
+ entry.attributes.keys.should == [ 'value' ]
115
+ entry['value'].should_not == nil
116
+ end
117
+ end
118
+
119
+ end
120
+ end
data/tests/images_test.rb CHANGED
@@ -1,94 +1,111 @@
1
- require 'tests/deltacloud_test'
1
+ require 'tests/common'
2
2
 
3
- class ImagesTest < Test::Unit::TestCase
3
+ module DeltacloudUnitTest
4
+ class HardwareProfilesTest < Test::Unit::TestCase
5
+ include Rack::Test::Methods
4
6
 
5
- def initialize(*args)
6
- @collection = 'images'
7
- @operations = [:index, :show]
8
- @params = {}
9
- super(*args)
10
- end
7
+ def app
8
+ Sinatra::Application
9
+ end
11
10
 
12
- def test_if_images_are_not_empty
13
- get '/api/images.xml', @params, rack_headers
14
- doc = Nokogiri::XML.parse(last_response.body)
15
- assert_not_equal 0, doc.xpath('/images/image').size
16
- end
11
+ def test_it_require_authentication
12
+ require_authentication?('/api/images').should == true
13
+ end
17
14
 
18
- [:id, :owner_id, :name, :description, :architecture].each do |option|
19
- method_name = :"test_if_images_index_contain_#{option}"
20
- send :define_method, method_name do
21
- get '/api/images.xml', @params, rack_headers
22
- doc = Nokogiri::XML.parse(last_response.body)
23
- elt = doc.xpath('/images/image[1]').first
24
- assert_not_nil elt.xpath(option.to_s).first
15
+ def test_it_returns_images
16
+ do_xml_request '/api/images', {}, true
17
+ (last_xml_response/'images/image').map.size.should > 0
25
18
  end
26
- end
27
19
 
28
- [:id, :owner_id, :name, :description, :architecture].each do |option|
29
- method_name = :"test_if_image_show_contain_#{option}"
30
- send :define_method, method_name do
31
- get '/api/images/img1.xml', @params, rack_headers
32
- doc = Nokogiri::XML.parse(last_response.body)
33
- elt = doc.xpath('/image').first
34
- assert_not_nil elt.xpath(option.to_s).first
20
+ def test_it_has_correct_attributes_set
21
+ do_xml_request '/api/images', {}, true
22
+ (last_xml_response/'images/image').each do |image|
23
+ image.attributes.keys.sort.should == [ 'href', 'id' ]
24
+ end
35
25
  end
36
- end
37
26
 
38
- def test_images_filtering_by_id
39
- @params={ :id => 'img1' }
40
- get '/api/images.xml', @params, rack_headers
41
- doc = Nokogiri::XML.parse(last_response.body)
42
- assert_equal 1, doc.xpath('/images/image').size
43
- assert_equal @params[:id], doc.xpath('/images/image/id').first.text
44
- end
27
+ def test_img1_has_correct_attributes
28
+ do_xml_request '/api/images', {}, true
29
+ image = (last_xml_response/'images/image[@id="img1"]')
30
+ test_image_attributes(image)
31
+ end
45
32
 
46
- def test_images_filtering_by_owner_id
47
- @params={ :owner_id => 'fedoraproject' }
48
- get '/api/images.xml', @params, rack_headers
49
- doc = Nokogiri::XML.parse(last_response.body)
50
- assert_equal 2, doc.xpath('/images/image').size
51
- assert_equal @params[:owner_id], doc.xpath('/images/image/owner_id')[0].text
52
- assert_equal @params[:owner_id], doc.xpath('/images/image/owner_id')[1].text
53
- end
33
+ def test_it_returns_valid_image
34
+ do_xml_request '/api/images/img1', {}, true
35
+ image = (last_xml_response/'image')
36
+ test_image_attributes(image)
37
+ end
54
38
 
55
- def test_images_filtering_by_architecture
56
- @params={ :architecture => 'i386' }
57
- get '/api/images.xml', @params, rack_headers
58
- doc = Nokogiri::XML.parse(last_response.body)
59
- assert_equal 2, doc.xpath('/images/image').size
60
- assert_equal @params[:architecture], doc.xpath('/images/image/architecture')[0].text
61
- assert_equal @params[:architecture], doc.xpath('/images/image/architecture')[1].text
62
- end
39
+ def test_it_has_unique_ids
40
+ do_xml_request '/api/images', {}, true
41
+ ids = []
42
+ (last_xml_response/'images/image').each do |image|
43
+ ids << image['id'].to_s
44
+ end
45
+ ids.sort.should == ids.sort.uniq
46
+ end
63
47
 
64
- def test_images_filtering_by_id_and_owner_id
65
- @params={ :id => 'img1', :owner_id => 'fedoraproject' }
66
- get '/api/images.xml', @params, rack_headers
67
- doc = Nokogiri::XML.parse(last_response.body)
68
- assert_equal 1, doc.xpath('/images/image').size
69
- assert_equal @params[:owner_id], doc.xpath('/images/image/owner_id')[0].text
70
- assert_equal @params[:id], doc.xpath('/images/image/id')[0].text
71
- end
48
+ def test_it_has_valid_urls
49
+ do_xml_request '/api/images', {}, true
50
+ ids = []
51
+ images = (last_xml_response/'images/image')
52
+ images.each do |image|
53
+ do_xml_request image['href'].to_s, {}, true
54
+ (last_xml_response/'image').first['href'].should == image['href'].to_s
55
+ end
56
+ end
72
57
 
73
- def test_images_filtering_by_id_and_owner_id_and_architecture
74
- @params={ :id => 'img1', :owner_id => 'fedoraproject', :architecture => 'x86_64' }
75
- get '/api/images.xml', @params, rack_headers
76
- doc = Nokogiri::XML.parse(last_response.body)
77
- assert_equal 1, doc.xpath('/images/image').size
78
- assert_equal @params[:owner_id], doc.xpath('/images/image/owner_id')[0].text
79
- assert_equal @params[:id], doc.xpath('/images/image/id')[0].text
80
- assert_equal @params[:architecture], doc.xpath('/images/image/architecture')[0].text
81
- end
58
+ def test_it_can_filter_using_owner_id
59
+ do_xml_request '/api/images', { :owner_id => 'mockuser' }, true
60
+ (last_xml_response/'images/image').size.should == 1
61
+ (last_xml_response/'images/image/owner_id').first.text.should == 'mockuser'
62
+ end
82
63
 
83
- def test_images_filtering_by_id_and_architecture
84
- @params={ :id => 'img1', :architecture => 'x86_64' }
85
- get '/api/images.xml', @params, rack_headers
86
- doc = Nokogiri::XML.parse(last_response.body)
87
- assert_equal 1, doc.xpath('/images/image').size
88
- assert_equal @params[:id], doc.xpath('/images/image/id')[0].text
89
- assert_equal @params[:architecture], doc.xpath('/images/image/architecture')[0].text
90
- end
64
+ def test_it_can_filter_using_unknown_owner_id
65
+ do_xml_request '/api/images', { :architecture => 'unknown_user' }, true
66
+ (last_xml_response/'images/image').size.should == 0
67
+ end
68
+
69
+ def test_it_can_filter_using_architecture
70
+ do_xml_request '/api/images', { :architecture => 'x86_64' }, true
71
+ (last_xml_response/'images/image').size.should == 1
72
+ (last_xml_response/'images/image/architecture').first.text.should == 'x86_64'
73
+ end
91
74
 
92
- include DeltacloudTest
75
+ def test_it_can_filter_using_unknown_architecture
76
+ do_xml_request '/api/images', { :architecture => 'unknown_arch' }, true
77
+ (last_xml_response/'images/image').size.should == 0
78
+ end
79
+
80
+ def test_it_responses_to_json
81
+ do_request '/api/images', {}, true, { :format => :json }
82
+ JSON::parse(last_response.body).class.should == Hash
83
+ JSON::parse(last_response.body)['images'].class.should == Array
84
+
85
+ do_request '/api/images/img1', {}, true, { :format => :json }
86
+ last_response.status.should == 200
87
+ JSON::parse(last_response.body).class.should == Hash
88
+ JSON::parse(last_response.body)['image'].class.should == Hash
89
+ end
93
90
 
91
+ def test_it_responses_to_html
92
+ do_request '/api/images', {}, true, { :format => :html }
93
+ last_response.status.should == 200
94
+ Nokogiri::HTML(last_response.body).search('html').first.name.should == 'html'
95
+
96
+ do_request '/api/images/img1', {}, true, { :format => :html }
97
+ last_response.status.should == 200
98
+ Nokogiri::HTML(last_response.body).search('html').first.name.should == 'html'
99
+ end
100
+
101
+ private
102
+
103
+ def test_image_attributes(image)
104
+ (image/'name').text.should_not nil
105
+ (image/'owner_id').text.should_not nil
106
+ (image/'description').text.should_not nil
107
+ (image/'architecture').text.should_not nil
108
+ end
109
+
110
+ end
94
111
  end