deltacloud-core 0.1.2 → 0.3.0
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.
- data/DISCLAIMER +8 -0
- data/{COPYING → LICENSE} +0 -0
- data/NOTICE +13 -0
- data/Rakefile +50 -51
- data/bin/deltacloudd +8 -1
- data/config.ru +0 -2
- data/config/drivers.yaml +48 -0
- data/deltacloud-core.gemspec +75 -0
- data/deltacloud.rb +3 -2
- data/lib/deltacloud/backend_capability.rb +15 -3
- data/lib/deltacloud/base_driver.rb +0 -2
- data/lib/deltacloud/base_driver/base_driver.rb +85 -89
- data/lib/deltacloud/base_driver/features.rb +61 -7
- data/lib/deltacloud/base_driver/mock_driver.rb +42 -43
- data/lib/deltacloud/core_ext.rb +18 -0
- data/lib/deltacloud/core_ext/integer.rb +31 -0
- data/lib/deltacloud/core_ext/string.rb +50 -0
- data/lib/deltacloud/drivers/azure/azure_driver.rb +71 -22
- data/lib/deltacloud/drivers/ec2/ec2_driver.rb +641 -584
- data/lib/deltacloud/drivers/ec2/ec2_mock_driver.rb +0 -2
- data/lib/deltacloud/drivers/eucalyptus/eucalyptus_driver.rb +167 -0
- data/lib/deltacloud/drivers/gogrid/gogrid_client.rb +39 -1
- data/lib/deltacloud/drivers/gogrid/gogrid_driver.rb +41 -25
- data/lib/deltacloud/drivers/mock/data/buckets/blobs/blob1.yml +6 -3
- data/lib/deltacloud/drivers/mock/data/buckets/blobs/blob2.yml +6 -3
- data/lib/deltacloud/drivers/mock/data/buckets/blobs/blob3.yml +4 -2
- data/lib/deltacloud/drivers/mock/data/buckets/blobs/blob4.yml +5 -2
- data/lib/deltacloud/drivers/mock/data/buckets/blobs/blob5.yml +4 -2
- data/lib/deltacloud/drivers/mock/data/instances/inst0.yml +1 -0
- data/lib/deltacloud/drivers/mock/data/instances/inst1.yml +1 -0
- data/lib/deltacloud/drivers/mock/data/instances/inst2.yml +1 -0
- data/lib/deltacloud/drivers/mock/data/storage_volumes/vol1.yml +1 -0
- data/lib/deltacloud/drivers/mock/data/storage_volumes/vol2.yml +1 -0
- data/lib/deltacloud/drivers/mock/data/storage_volumes/vol3.yml +1 -0
- data/lib/deltacloud/drivers/mock/mock_driver.rb +138 -30
- data/lib/deltacloud/drivers/opennebula/cloud_client.rb +13 -15
- data/lib/deltacloud/drivers/opennebula/occi_client.rb +13 -15
- data/lib/deltacloud/drivers/opennebula/opennebula_driver.rb +13 -15
- data/lib/deltacloud/drivers/rackspace/rackspace_driver.rb +224 -113
- data/lib/deltacloud/drivers/rhevm/rhevm_client.rb +332 -0
- data/lib/deltacloud/drivers/rhevm/rhevm_driver.rb +221 -170
- data/lib/deltacloud/drivers/rimuhosting/rimuhosting_driver.rb +0 -1
- data/lib/deltacloud/drivers/sbc/sbc_client.rb +247 -0
- data/lib/deltacloud/drivers/sbc/sbc_driver.rb +297 -0
- data/lib/deltacloud/drivers/terremark/terremark_driver.rb +0 -2
- data/lib/deltacloud/hardware_profile.rb +1 -3
- data/lib/deltacloud/helpers.rb +0 -2
- data/lib/deltacloud/helpers/application_helper.rb +86 -12
- data/lib/deltacloud/helpers/blob_stream.rb +19 -2
- data/lib/deltacloud/helpers/conversion_helper.rb +0 -2
- data/lib/deltacloud/helpers/hardware_profiles_helper.rb +0 -2
- data/lib/deltacloud/method_serializer.rb +0 -2
- data/lib/deltacloud/models/base_model.rb +0 -2
- data/lib/deltacloud/models/blob.rb +1 -2
- data/lib/deltacloud/models/bucket.rb +0 -2
- data/lib/deltacloud/models/image.rb +0 -2
- data/lib/deltacloud/models/instance.rb +19 -2
- data/lib/deltacloud/models/instance_profile.rb +4 -2
- data/lib/deltacloud/models/key.rb +0 -2
- data/lib/deltacloud/models/load_balancer.rb +0 -2
- data/lib/deltacloud/models/realm.rb +0 -2
- data/lib/deltacloud/models/storage_snapshot.rb +0 -2
- data/lib/deltacloud/models/storage_volume.rb +4 -2
- data/lib/deltacloud/runner.rb +132 -0
- data/lib/deltacloud/state_machine.rb +0 -2
- data/lib/deltacloud/validation.rb +9 -7
- data/lib/drivers.rb +36 -48
- data/lib/sinatra/accept_media_types.rb +26 -0
- data/lib/sinatra/lazy_auth.rb +16 -0
- data/lib/sinatra/rabbit.rb +112 -54
- data/lib/sinatra/rack_driver_select.rb +50 -16
- data/lib/sinatra/rack_etag.rb +79 -0
- data/lib/sinatra/rack_matrix_params.rb +84 -0
- data/lib/sinatra/rack_runtime.rb +47 -0
- data/lib/sinatra/static_assets.rb +16 -0
- data/lib/sinatra/url_for.rb +31 -4
- data/public/favicon.ico +0 -0
- data/public/images/bread-bg.png +0 -0
- data/public/images/error.png +0 -0
- data/public/images/pending.png +0 -0
- data/public/images/running.png +0 -0
- data/public/images/stopped.png +0 -0
- data/public/javascripts/application.js +35 -0
- data/public/stylesheets/compiled/application.css +59 -5
- data/public/stylesheets/compiled/screen.css +1 -1
- data/server.rb +293 -29
- data/support/fedora/deltacloud-core +78 -0
- data/support/fedora/deltacloud-core.spec +143 -0
- data/support/fedora/deltacloudd +78 -18
- data/support/fedora/rubygem-deltacloud-core.spec +76 -40
- data/tests/common.rb +172 -0
- data/tests/drivers/mock/api_test.rb +133 -0
- data/tests/drivers/mock/hardware_profiles_test.rb +134 -0
- data/tests/drivers/mock/images_test.rb +126 -0
- data/tests/drivers/mock/instance_states_test.rb +71 -0
- data/tests/drivers/mock/instances_test.rb +236 -0
- data/tests/drivers/mock/realms_test.rb +93 -0
- data/tests/drivers/mock/setup.rb +3 -0
- data/tests/drivers/mock/url_for_test.rb +67 -0
- data/tests/drivers/rackspace/api_test.rb +41 -0
- data/tests/drivers/rackspace/hardware_profiles_test.rb +53 -0
- data/tests/drivers/rackspace/images_test.rb +40 -0
- data/tests/drivers/rackspace/instances_test.rb +161 -0
- data/tests/drivers/rackspace/realms_test.rb +36 -0
- data/tests/drivers/rackspace/setup.rb +14 -0
- data/tests/drivers/rhevm/api_test.rb +39 -0
- data/tests/drivers/rhevm/hardware_profiles_test.rb +53 -0
- data/tests/drivers/rhevm/images_test.rb +42 -0
- data/tests/drivers/rhevm/instances_test.rb +179 -0
- data/tests/drivers/rhevm/realms_test.rb +35 -0
- data/tests/drivers/rhevm/setup.rb +14 -0
- data/tests/rabbit_test.rb +52 -0
- data/views/api/show.html.haml +2 -5
- data/views/blobs/new.html.haml +17 -1
- data/views/blobs/show.html.haml +6 -0
- data/views/blobs/show.xml.haml +5 -1
- data/views/buckets/index.html.haml +1 -12
- data/views/buckets/index.xml.haml +3 -5
- data/views/docs/operation.html.haml +23 -11
- data/views/drivers/index.html.haml +15 -0
- data/views/drivers/index.xml.haml +7 -0
- data/views/drivers/show.html.haml +20 -0
- data/views/drivers/show.xml.haml +7 -0
- data/views/error.html.haml +31 -0
- data/views/errors/auth_exception.xml.haml +2 -1
- data/views/errors/backend_capability_failure.xml.haml +2 -1
- data/views/errors/backend_error.html.haml +3 -0
- data/views/errors/backend_error.xml.haml +2 -2
- data/views/errors/validation_failure.xml.haml +3 -2
- data/views/images/index.html.haml +1 -6
- data/views/images/index.xml.haml +2 -0
- data/views/images/new.html.haml +14 -0
- data/views/images/show.xml.haml +2 -0
- data/views/instances/index.html.haml +8 -6
- data/views/instances/index.xml.haml +4 -0
- data/views/instances/new.html.haml +40 -11
- data/views/instances/run.html.haml +9 -0
- data/views/instances/run.xml.haml +7 -0
- data/views/instances/run_command.html.haml +16 -0
- data/views/instances/show.html.haml +14 -0
- data/views/instances/show.xml.haml +12 -4
- data/views/layout.html.haml +7 -2
- data/views/load_balancers/index.html.haml +1 -1
- data/views/load_balancers/new.html.haml +2 -2
- data/views/load_balancers/show.html.haml +1 -1
- data/views/storage_snapshots/index.html.haml +3 -0
- data/views/storage_snapshots/new.html.haml +9 -0
- data/views/storage_volumes/attach.html.haml +20 -0
- data/views/storage_volumes/index.html.haml +16 -1
- data/views/storage_volumes/index.xml.haml +1 -10
- data/views/storage_volumes/new.html.haml +17 -0
- data/views/storage_volumes/show.html.haml +8 -0
- data/views/storage_volumes/show.xml.haml +25 -3
- metadata +197 -127
- data/lib/deltacloud/drivers/rackspace/rackspace_client.rb +0 -130
- data/parse.rb +0 -7
- data/test.rb +0 -3
- data/views/api/drivers.xml.haml +0 -6
data/tests/common.rb
ADDED
@@ -0,0 +1,172 @@
|
|
1
|
+
# Licensed to the Apache Software Foundation (ASF) under one or more
|
2
|
+
# contributor license agreements. See the NOTICE file distributed with
|
3
|
+
# this work for additional information regarding copyright ownership. The
|
4
|
+
# ASF licenses this file to you under the Apache License, Version 2.0 (the
|
5
|
+
# "License"); you may not use this file except in compliance with the
|
6
|
+
# License. You may obtain a copy of the License at
|
7
|
+
#
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
#
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
12
|
+
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
13
|
+
# License for the specific language governing permissions and limitations
|
14
|
+
# under the License.
|
15
|
+
#
|
16
|
+
|
17
|
+
$:.unshift File.join(File.dirname(__FILE__), '..')
|
18
|
+
|
19
|
+
require 'rubygems'
|
20
|
+
require 'yaml'
|
21
|
+
require 'test/unit'
|
22
|
+
require 'spec'
|
23
|
+
require 'nokogiri'
|
24
|
+
require 'json'
|
25
|
+
require 'digest/sha1'
|
26
|
+
require 'base64'
|
27
|
+
require 'rack/test'
|
28
|
+
require 'server'
|
29
|
+
|
30
|
+
driver
|
31
|
+
|
32
|
+
# Set proper environment variables for running test
|
33
|
+
|
34
|
+
ENV['RACK_ENV'] = 'test'
|
35
|
+
ENV['API_HOST'] = 'localhost'
|
36
|
+
ENV['API_PORT'] = '4040'
|
37
|
+
|
38
|
+
configure :test do
|
39
|
+
set :environment, :test
|
40
|
+
set :raise_errors, false
|
41
|
+
set :show_exceptions, false
|
42
|
+
end
|
43
|
+
|
44
|
+
Spec::Runner.configure do |conf|
|
45
|
+
conf.include Rack::Test::Methods
|
46
|
+
end
|
47
|
+
|
48
|
+
module DeltacloudTestCommon
|
49
|
+
|
50
|
+
def recording?
|
51
|
+
@use_recording
|
52
|
+
end
|
53
|
+
|
54
|
+
def record!
|
55
|
+
@use_recording = true
|
56
|
+
end
|
57
|
+
|
58
|
+
|
59
|
+
# Authentication helper for Basic HTTP authentication
|
60
|
+
# To change default user credentials stored in ENV['API_USER|PASSWORD'] you
|
61
|
+
# need to set opts[:credentials] = { :user => '...', :password => '...'}
|
62
|
+
#
|
63
|
+
def authenticate(opts={})
|
64
|
+
credentials = opts[:credentials] || { :user => ENV['API_USER'], :password => ENV['API_PASSWORD']}
|
65
|
+
return {
|
66
|
+
'HTTP_AUTHORIZATION' => "Basic " + Base64.encode64("#{credentials[:user]}:#{credentials[:password]}")
|
67
|
+
}
|
68
|
+
end
|
69
|
+
|
70
|
+
# HTTP Accept header helper.
|
71
|
+
# Will set appropriate value for this header.
|
72
|
+
# Available options for format are: :json, :html or :xml
|
73
|
+
# By default :xml is used
|
74
|
+
#
|
75
|
+
def accept(format=:xml)
|
76
|
+
case format
|
77
|
+
when :json then 'application/json;q=0.9'
|
78
|
+
when :html then 'text/html;q=0.9'
|
79
|
+
when :xml then 'application/xml;q=0.9'
|
80
|
+
else 'application/xml;q=0.9'
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
# This helper will execute GET operation on given URI.
|
85
|
+
# You can set additional parameters using params Hash, which will be passed to
|
86
|
+
# request.
|
87
|
+
# You can change format used for communication using opts[:format] = :xml | :html :json
|
88
|
+
# You can turn on recording (you need to configure it first in setup.rb) using
|
89
|
+
# opts[:record] (true/false)
|
90
|
+
# You can force authentication using opts[:auth] parameter or use
|
91
|
+
# 'get_auth_url' which will do it for you ;-)
|
92
|
+
#
|
93
|
+
def get_url(uri, params={}, opts={})
|
94
|
+
header 'Accept', accept(opts[:format] || :xml)
|
95
|
+
if DeltacloudTestCommon::recording?
|
96
|
+
VCR.use_cassette("get-" + Digest::SHA1.hexdigest("#{uri}-#{params}}")) do
|
97
|
+
get(uri, params || {}, opts[:auth] ? authenticate(opts) : {})
|
98
|
+
end
|
99
|
+
else
|
100
|
+
get(uri, params || {}, opts[:auth] ? authenticate(opts) : {})
|
101
|
+
end
|
102
|
+
last_response.status.should_not == 401
|
103
|
+
end
|
104
|
+
|
105
|
+
def get_auth_url(uri, params={}, opts={})
|
106
|
+
opts.merge!(:auth => true)
|
107
|
+
get_url(uri, params, opts)
|
108
|
+
end
|
109
|
+
|
110
|
+
def post_url(uri, params={}, opts={})
|
111
|
+
header 'Accept', accept(opts[:format] || :xml)
|
112
|
+
if DeltacloudTestCommon::recording?
|
113
|
+
VCR.use_cassette("post-" + Digest::SHA1.hexdigest("#{uri}-#{params}")) do
|
114
|
+
post(uri, params || {}, authenticate(opts))
|
115
|
+
end
|
116
|
+
else
|
117
|
+
post(uri, params || {}, authenticate(opts))
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
def delete_url(uri, params={}, opts={})
|
122
|
+
header 'Accept', accept(opts[:format] || :xml)
|
123
|
+
if DeltacloudTestCommon::recording?
|
124
|
+
VCR.use_cassette("delete-"+Digest::SHA1.hexdigest("#{uri}-#{params}")) do
|
125
|
+
delete(uri, params || {}, authenticate(opts))
|
126
|
+
end
|
127
|
+
else
|
128
|
+
delete(uri, params || {}, authenticate(opts))
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
def put_url(uri, params={}, opts={})
|
133
|
+
header 'Accept', accept(opts[:format] || :xml)
|
134
|
+
if DeltacloudTestCommon::recording?
|
135
|
+
VCR.use_cassette("put-"+Digest::SHA1.hexdigest("#{uri}-#{params}-#{authenticate(opts)}")) do
|
136
|
+
put(uri, params || {}, authenticate(opts))
|
137
|
+
end
|
138
|
+
else
|
139
|
+
put(uri, params || {}, authenticate(opts))
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
# This helper will automatically convert output from method above to Nokogiri
|
144
|
+
# XML object
|
145
|
+
def last_xml_response
|
146
|
+
Nokogiri::XML(last_response.body) #if last_response.status.to_s =~ /2(\d+)/
|
147
|
+
end
|
148
|
+
|
149
|
+
# Check if given URI require authentication
|
150
|
+
def require_authentication?(uri)
|
151
|
+
get uri, {}
|
152
|
+
true if last_response.status == 401
|
153
|
+
end
|
154
|
+
|
155
|
+
def with_provider(new_provider, &block)
|
156
|
+
old_provider = ENV["API_PROVIDER"]
|
157
|
+
begin
|
158
|
+
ENV["API_PROVIDER"] = new_provider
|
159
|
+
yield
|
160
|
+
ensure
|
161
|
+
ENV["API_PROVIDER"] = old_provider
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
def add_created_instance(id)
|
166
|
+
$created_instances ||= []
|
167
|
+
$created_instances << id
|
168
|
+
end
|
169
|
+
|
170
|
+
end
|
171
|
+
|
172
|
+
include DeltacloudTestCommon
|
@@ -0,0 +1,133 @@
|
|
1
|
+
# Licensed to the Apache Software Foundation (ASF) under one or more
|
2
|
+
# contributor license agreements. See the NOTICE file distributed with
|
3
|
+
# this work for additional information regarding copyright ownership. The
|
4
|
+
# ASF licenses this file to you under the Apache License, Version 2.0 (the
|
5
|
+
# "License"); you may not use this file except in compliance with the
|
6
|
+
# License. You may obtain a copy of the License at
|
7
|
+
#
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
#
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
12
|
+
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
13
|
+
# License for the specific language governing permissions and limitations
|
14
|
+
# under the License.
|
15
|
+
#
|
16
|
+
|
17
|
+
$:.unshift File.join(File.dirname(__FILE__), '..', '..', '..')
|
18
|
+
require 'tests/common'
|
19
|
+
|
20
|
+
module DeltacloudUnitTest
|
21
|
+
class ApiTest < Test::Unit::TestCase
|
22
|
+
include Rack::Test::Methods
|
23
|
+
|
24
|
+
def app
|
25
|
+
Sinatra::Application
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_it_returns_entry_points
|
29
|
+
get_auth_url '/api'
|
30
|
+
(last_xml_response/'/api/link').length.should > 0
|
31
|
+
end
|
32
|
+
|
33
|
+
def test_it_has_correct_attributes_set
|
34
|
+
get_auth_url '/api'
|
35
|
+
(last_xml_response/'/api/link').each do |link|
|
36
|
+
link.attributes.keys.sort.should == [ 'href', 'rel' ]
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def test_it_responses_to_html
|
41
|
+
get_url '/api', {}, { :format => :html }
|
42
|
+
last_response.status.should == 200
|
43
|
+
Nokogiri::HTML(last_response.body).search('html').first.name.should == 'html'
|
44
|
+
end
|
45
|
+
|
46
|
+
def test_it_responses_to_json
|
47
|
+
get_url '/api', {}, { :format => :json }
|
48
|
+
last_response.status.should == 200
|
49
|
+
JSON::parse(last_response.body).class.should == Hash
|
50
|
+
JSON::parse(last_response.body)['api'].class.should == Hash
|
51
|
+
end
|
52
|
+
|
53
|
+
def test_it_switches_drivers
|
54
|
+
with_provider("") do
|
55
|
+
get_auth_url '/api'
|
56
|
+
(last_xml_response/"api/link[rel = 'instances']").first.should_not == nil
|
57
|
+
end
|
58
|
+
|
59
|
+
# Switch to storage-only mock driver
|
60
|
+
with_provider("storage") do
|
61
|
+
get_auth_url '/api'
|
62
|
+
(last_xml_response/"api/link[rel = 'instances']").first.should == nil
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def test_it_handles_unsupported_collections
|
67
|
+
get_auth_url '/api/no_such_collection'
|
68
|
+
last_response.status.should == 404
|
69
|
+
|
70
|
+
with_provider("storage") do
|
71
|
+
get_auth_url '/api/instances'
|
72
|
+
last_response.status.should == 404
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
def test_it_allows_accessing_docs
|
77
|
+
get_url '/api/docs/instances'
|
78
|
+
last_response.status.should == 200
|
79
|
+
|
80
|
+
with_provider("storage") do
|
81
|
+
get_url '/api/docs/instances'
|
82
|
+
last_response.status.should == 404
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
def test_it_respond_to_head
|
87
|
+
head '/api/instances'
|
88
|
+
last_response.headers['Allow'].should_not == nil
|
89
|
+
last_response.headers['Allow'].split(',').include?('HEAD').should == true
|
90
|
+
end
|
91
|
+
|
92
|
+
def test_it_expose_available_drivers
|
93
|
+
get_auth_url '/api/drivers'
|
94
|
+
last_response.status.should == 200
|
95
|
+
(last_xml_response/"drivers").length.should > 0
|
96
|
+
(last_xml_response/'drivers/driver').length.should > 0
|
97
|
+
(last_xml_response/"drivers/driver[@id = 'mock']").length.should == 1
|
98
|
+
end
|
99
|
+
|
100
|
+
def test_it_expose_ec2_driver_entrypoints
|
101
|
+
get_auth_url '/api/drivers'
|
102
|
+
last_response.status.should == 200
|
103
|
+
ec2 = (last_xml_response/'drivers/driver[@id=ec2]').first
|
104
|
+
(ec2/"provider").length.should > 0
|
105
|
+
(ec2/"provider[@id = 'eu-west-1']").length.should == 1
|
106
|
+
get_auth_url ec2[:href]
|
107
|
+
eu_west = (last_xml_response/"provider[@id = 'eu-west-1']").first
|
108
|
+
(eu_west/"entrypoint").length.should > 0
|
109
|
+
(eu_west/"entrypoint[@kind = 'ec2']").length.should == 1
|
110
|
+
end
|
111
|
+
|
112
|
+
def test_it_supports_matrix_params
|
113
|
+
get_auth_url "/api;driver=ec2"
|
114
|
+
last_response.status.should == 200
|
115
|
+
(last_xml_response/'api').first[:driver].should == 'ec2'
|
116
|
+
get_auth_url "/api;driver=mock"
|
117
|
+
(last_xml_response/'api').first[:driver].should == 'mock'
|
118
|
+
get_auth_url "/api;driver=ec2/hardware_profiles"
|
119
|
+
(last_xml_response/'hardware_profiles/hardware_profile/@id').map {|n| n.to_s}.include?('m1.small').should == true
|
120
|
+
last_response.status.should == 200
|
121
|
+
end
|
122
|
+
|
123
|
+
def test_it_change_features_after_driver_change
|
124
|
+
get_auth_url "/api;driver=ec2"
|
125
|
+
(last_xml_response/'api/link[@rel="instances"]/feature[@name="user_name"]').first.should == nil
|
126
|
+
(last_xml_response/'api/link[@rel="instances"]/feature[@name="user_data"]').first.should_not == nil
|
127
|
+
get_auth_url "/api;driver=mock"
|
128
|
+
(last_xml_response/'api/link[@rel="instances"]/feature[@name="user_name"]').first.should_not == nil
|
129
|
+
(last_xml_response/'api/link[@rel="instances"]/feature[@name="user_data"]').first.should == nil
|
130
|
+
end
|
131
|
+
|
132
|
+
end
|
133
|
+
end
|
@@ -0,0 +1,134 @@
|
|
1
|
+
# Licensed to the Apache Software Foundation (ASF) under one or more
|
2
|
+
# contributor license agreements. See the NOTICE file distributed with
|
3
|
+
# this work for additional information regarding copyright ownership. The
|
4
|
+
# ASF licenses this file to you under the Apache License, Version 2.0 (the
|
5
|
+
# "License"); you may not use this file except in compliance with the
|
6
|
+
# License. You may obtain a copy of the License at
|
7
|
+
#
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
#
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
12
|
+
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
13
|
+
# License for the specific language governing permissions and limitations
|
14
|
+
# under the License.
|
15
|
+
#
|
16
|
+
|
17
|
+
$:.unshift File.join(File.dirname(__FILE__), '..', '..', '..')
|
18
|
+
require 'tests/common'
|
19
|
+
|
20
|
+
module DeltacloudUnitTest
|
21
|
+
class HardwareProfilesTest < Test::Unit::TestCase
|
22
|
+
include Rack::Test::Methods
|
23
|
+
|
24
|
+
def app
|
25
|
+
Sinatra::Application
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_it_returns_hardware_profiles
|
29
|
+
get_url '/api/hardware_profiles'
|
30
|
+
(last_xml_response/'hardware_profiles/hardware_profile').length.should > 0
|
31
|
+
end
|
32
|
+
|
33
|
+
def test_it_has_correct_attributes_set
|
34
|
+
get_auth_url '/api/hardware_profiles'
|
35
|
+
(last_xml_response/'hardware_profiles/hardware_profile').each do |profile|
|
36
|
+
profile.attributes.keys.sort.should == [ 'href', 'id' ]
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def test_hardware_profiles_have_name
|
41
|
+
get_auth_url '/api/hardware_profiles'
|
42
|
+
(last_xml_response/'hardware_profiles/hardware_profile').each do |profile|
|
43
|
+
(profile/'name').text.should_not == nil
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def test_hardware_profiles_have_unique_name
|
48
|
+
get_auth_url '/api/hardware_profiles'
|
49
|
+
names = []
|
50
|
+
(last_xml_response/'hardware_profiles/hardware_profile').each do |profile|
|
51
|
+
names << (profile/'name').text
|
52
|
+
end
|
53
|
+
names.should == names.uniq
|
54
|
+
end
|
55
|
+
|
56
|
+
def test_hardware_profiles_have_unique_id
|
57
|
+
get_auth_url '/api/hardware_profiles'
|
58
|
+
ids = []
|
59
|
+
(last_xml_response/'hardware_profiles/hardware_profile').each do |profile|
|
60
|
+
ids << profile['id']
|
61
|
+
end
|
62
|
+
ids.should == ids.uniq
|
63
|
+
end
|
64
|
+
|
65
|
+
def test_m1_xlarge_profile_has_correct_attributes
|
66
|
+
get_auth_url '/api/hardware_profiles'
|
67
|
+
profile = (last_xml_response/'hardware_profiles/hardware_profile[@id="m1-xlarge"]')
|
68
|
+
test_profile_properties(profile)
|
69
|
+
end
|
70
|
+
|
71
|
+
def test_it_returns_valid_hardware_profile
|
72
|
+
get_auth_url '/api/hardware_profiles/m1-xlarge'
|
73
|
+
profile = (last_xml_response/'hardware_profile')
|
74
|
+
test_profile_properties(profile)
|
75
|
+
end
|
76
|
+
|
77
|
+
def test_it_responses_to_json
|
78
|
+
get_url '/api/hardware_profiles', {}, { :format => :json }
|
79
|
+
JSON::parse(last_response.body).class.should == Hash
|
80
|
+
JSON::parse(last_response.body)['hardware_profiles'].class.should == Array
|
81
|
+
get_url '/api/hardware_profiles/m1-xlarge', {}, { :format => :json }
|
82
|
+
last_response.status.should == 200
|
83
|
+
JSON::parse(last_response.body).class.should == Hash
|
84
|
+
JSON::parse(last_response.body)['hardware_profile'].class.should == Hash
|
85
|
+
end
|
86
|
+
|
87
|
+
def test_it_responses_to_html
|
88
|
+
get_url '/api/hardware_profiles', {}, { :format => :html }
|
89
|
+
last_response.status.should == 200
|
90
|
+
Nokogiri::HTML(last_response.body).search('html').first.name.should == 'html'
|
91
|
+
get_url '/api/hardware_profiles/m1-xlarge', {}, { :format => :html }
|
92
|
+
last_response.status.should == 200
|
93
|
+
Nokogiri::HTML(last_response.body).search('html').first.name.should == 'html'
|
94
|
+
end
|
95
|
+
|
96
|
+
def test_it_returns_error_on_wrong_name
|
97
|
+
get_url '/api/hardware_profiles/m1-unknown-wrongname', {}, { :format => :html }
|
98
|
+
last_response.status.should == 404
|
99
|
+
get_auth_url '/api/hardware_profiles/m1-unknown-wrongname'
|
100
|
+
last_response.status.should == 404
|
101
|
+
get_url '/api/hardware_profiles/m1-unknown-wrongname', {}, { :format => :json }
|
102
|
+
last_response.status.should == 404
|
103
|
+
end
|
104
|
+
|
105
|
+
private
|
106
|
+
|
107
|
+
def test_profile_properties(profile)
|
108
|
+
(profile/'property').each do |properties|
|
109
|
+
properties.attributes.keys.sort.should == [ 'kind', 'name', 'unit', 'value' ]
|
110
|
+
end
|
111
|
+
|
112
|
+
(profile/'property[@name="architecture"]').first['kind'].should == 'fixed'
|
113
|
+
(profile/'property[@name="architecture"]').first['unit'].should == 'label'
|
114
|
+
|
115
|
+
(profile/'property[@name="memory"]').first['kind'].should == 'range'
|
116
|
+
(profile/'property[@name="memory"]').first['unit'].should == 'MB'
|
117
|
+
(profile/'property[@name="memory"]/range').length.should == 1
|
118
|
+
(profile/'property[@name="memory"]/range').first.attributes.keys.sort.should == [ 'first', 'last' ]
|
119
|
+
|
120
|
+
(profile/'property[@name="cpu"]').first['kind'].should == 'fixed'
|
121
|
+
(profile/'property[@name="cpu"]').first['unit'].should == 'count'
|
122
|
+
|
123
|
+
(profile/'property[@name="storage"]').first['kind'].should == 'enum'
|
124
|
+
(profile/'property[@name="storage"]').first['unit'].should == 'GB'
|
125
|
+
(profile/'property[@name="storage"]/enum').length.should == 1
|
126
|
+
(profile/'property[@name="storage"]/enum/entry').length.should == 3
|
127
|
+
(profile/'property[@name="storage"]/enum/entry').each do |entry|
|
128
|
+
entry.attributes.keys.should == [ 'value' ]
|
129
|
+
entry['value'].should_not == nil
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
end
|
134
|
+
end
|
@@ -0,0 +1,126 @@
|
|
1
|
+
# Licensed to the Apache Software Foundation (ASF) under one or more
|
2
|
+
# contributor license agreements. See the NOTICE file distributed with
|
3
|
+
# this work for additional information regarding copyright ownership. The
|
4
|
+
# ASF licenses this file to you under the Apache License, Version 2.0 (the
|
5
|
+
# "License"); you may not use this file except in compliance with the
|
6
|
+
# License. You may obtain a copy of the License at
|
7
|
+
#
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
#
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
12
|
+
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
13
|
+
# License for the specific language governing permissions and limitations
|
14
|
+
# under the License.
|
15
|
+
#
|
16
|
+
|
17
|
+
$:.unshift File.join(File.dirname(__FILE__), '..', '..', '..')
|
18
|
+
require 'tests/common'
|
19
|
+
|
20
|
+
module DeltacloudUnitTest
|
21
|
+
class HardwareProfilesTest < Test::Unit::TestCase
|
22
|
+
include Rack::Test::Methods
|
23
|
+
|
24
|
+
def app
|
25
|
+
Sinatra::Application
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_it_require_authentication
|
29
|
+
require_authentication?('/api/images').should == true
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_it_returns_images
|
33
|
+
get_auth_url '/api/images', {}
|
34
|
+
(last_xml_response/'images/image').length.should > 0
|
35
|
+
end
|
36
|
+
|
37
|
+
def test_it_has_correct_attributes_set
|
38
|
+
get_auth_url '/api/images', {}
|
39
|
+
(last_xml_response/'images/image').each do |image|
|
40
|
+
image.attributes.keys.sort.should == [ 'href', 'id' ]
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def test_img1_has_correct_attributes
|
45
|
+
get_auth_url '/api/images', {}
|
46
|
+
image = (last_xml_response/'images/image[@id="img1"]')
|
47
|
+
test_image_attributes(image)
|
48
|
+
end
|
49
|
+
|
50
|
+
def test_it_returns_valid_image
|
51
|
+
get_auth_url '/api/images/img1', {}
|
52
|
+
image = (last_xml_response/'image')
|
53
|
+
test_image_attributes(image)
|
54
|
+
end
|
55
|
+
|
56
|
+
def test_it_has_unique_ids
|
57
|
+
get_auth_url '/api/images', {}
|
58
|
+
ids = []
|
59
|
+
(last_xml_response/'images/image').each do |image|
|
60
|
+
ids << image['id'].to_s
|
61
|
+
end
|
62
|
+
ids.sort.should == ids.sort.uniq
|
63
|
+
end
|
64
|
+
|
65
|
+
def test_it_has_valid_urls
|
66
|
+
get_auth_url '/api/images', {}
|
67
|
+
ids = []
|
68
|
+
images = (last_xml_response/'images/image')
|
69
|
+
images.each do |image|
|
70
|
+
get_auth_url image['href'].to_s, {}
|
71
|
+
(last_xml_response/'image').first['href'].should == image['href'].to_s
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
def test_it_can_filter_using_owner_id
|
76
|
+
get_auth_url '/api/images', { :owner_id => 'mockuser' }
|
77
|
+
(last_xml_response/'images/image').length.should == 1
|
78
|
+
(last_xml_response/'images/image/owner_id').first.text.should == 'mockuser'
|
79
|
+
end
|
80
|
+
|
81
|
+
def test_it_can_filter_using_unknown_owner_id
|
82
|
+
get_auth_url '/api/images', { :architecture => 'unknown_user' }
|
83
|
+
(last_xml_response/'images/image').length.should == 0
|
84
|
+
end
|
85
|
+
|
86
|
+
def test_it_can_filter_using_architecture
|
87
|
+
get_auth_url '/api/images', { :architecture => 'x86_64' }
|
88
|
+
(last_xml_response/'images/image').length.should == 1
|
89
|
+
(last_xml_response/'images/image/architecture').first.text.should == 'x86_64'
|
90
|
+
end
|
91
|
+
|
92
|
+
def test_it_can_filter_using_unknown_architecture
|
93
|
+
get_auth_url '/api/images', { :architecture => 'unknown_arch' }
|
94
|
+
(last_xml_response/'images/image').length.should == 0
|
95
|
+
end
|
96
|
+
|
97
|
+
def test_it_responses_to_json
|
98
|
+
get_auth_url '/api/images', {}, { :format => :json }
|
99
|
+
JSON::parse(last_response.body).class.should == Hash
|
100
|
+
JSON::parse(last_response.body)['images'].class.should == Array
|
101
|
+
get_auth_url '/api/images/img1', {}, { :format => :json }
|
102
|
+
last_response.status.should == 200
|
103
|
+
JSON::parse(last_response.body).class.should == Hash
|
104
|
+
JSON::parse(last_response.body)['image'].class.should == Hash
|
105
|
+
end
|
106
|
+
|
107
|
+
def test_it_responses_to_html
|
108
|
+
get_auth_url '/api/images', {}, { :format => :html }
|
109
|
+
last_response.status.should == 200
|
110
|
+
Nokogiri::HTML(last_response.body).search('html').first.name.should == 'html'
|
111
|
+
get_auth_url '/api/images/img1', {}, { :format => :html }
|
112
|
+
last_response.status.should == 200
|
113
|
+
Nokogiri::HTML(last_response.body).search('html').first.name.should == 'html'
|
114
|
+
end
|
115
|
+
|
116
|
+
private
|
117
|
+
|
118
|
+
def test_image_attributes(image)
|
119
|
+
(image/'name').text.should_not nil
|
120
|
+
(image/'owner_id').text.should_not nil
|
121
|
+
(image/'description').text.should_not nil
|
122
|
+
(image/'architecture').text.should_not nil
|
123
|
+
end
|
124
|
+
|
125
|
+
end
|
126
|
+
end
|