deltacloud-core 0.1.2 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|