spec/fog/openstack/volume_spec.rb in fog-1.36.0 vs spec/fog/openstack/volume_spec.rb in fog-1.37.0
- old
+ new
@@ -1,34 +1,48 @@
require 'fog/openstack/compute'
require 'fog/openstack/identity'
require 'fog/openstack/identity_v3'
require 'fog/openstack/volume'
+require 'fog/openstack/shared_context'
-if RUBY_VERSION =~ /1.8/
- require File.expand_path('../shared_context', __FILE__)
-else
- require_relative './shared_context'
-end
-
-RSpec.describe Fog::Volume::OpenStack do
-
+[Fog::Volume::OpenStack,
+ Fog::Volume::OpenStack::V1,
+ Fog::Volume::OpenStack::V2].delete_if{|_class| ENV['TEST_CLASS'] && ENV['TEST_CLASS'] != _class.name}.each do |service_class|
+ RSpec.describe service_class do
include_context 'OpenStack specs with VCR'
before :all do
+ vcr_directory = 'spec/fog/openstack/volume' if service_class == Fog::Volume::OpenStack
+
+ vcr_directory = 'spec/fog/openstack/volume_v1' if service_class == Fog::Volume::OpenStack::V1
+
+ vcr_directory = 'spec/fog/openstack/volume_v2' if service_class == Fog::Volume::OpenStack::V2
+
setup_vcr_and_service(
- :vcr_directory => 'spec/fog/openstack/volume',
- :service_class => Fog::Volume::OpenStack
+ :vcr_directory => vcr_directory,
+ :service_class => service_class
)
+
+ # Account for the different parameter naming between v1 and v2 services
+ @name_param = :display_name unless v2?
+ @name_param = :name if v2?
+
+ @description_param = :display_description unless v2?
+ @description_param = :description if v2?
end
+ def v2?
+ @service.is_a? Fog::Volume::OpenStack::V2::Real
+ end
+
def setup_test_object(options)
type = options.delete(:type)
case type
when :volume
puts "Checking for leftovers..." if ENV['DEBUG_VERBOSE']
- volume_name = options[:display_name]
+ volume_name = options[@name_param]
# if this fails, cleanup this object (it was left over from a failed test run)
- expect(@service.volumes.all(:display_name => volume_name).length).to be(0)
+ expect(@service.volumes.all(@name_param => volume_name).length).to be(0)
puts "Creating volume #{volume_name}..." if ENV['DEBUG_VERBOSE']
return @service.volumes.create(options)
when :transfer
@@ -44,77 +58,84 @@
raise ArgumentError, "don't know how to setup a test object of type #{type.inspect}"
end
end
def cleanup_test_object(collection, id)
- # has the object already been deleted?
- begin
- object = collection.get(id)
- rescue Fog::Compute::OpenStack::NotFound # "Compute", not "Volume"; see issue #3618
- true
+
+ # wait for the object to be deletable
+ Fog.wait_for do
+ begin
+ object = collection.get(id)
+ puts "Current status: #{object ? object.status : 'deleted'}" if ENV['DEBUG_VERBOSE']
+ object.nil? || (['available', 'error'].include? object.status.downcase)
+ end
end
+ object = collection.get(id)
puts "Deleting object #{object.class} #{id}..." if ENV['DEBUG_VERBOSE']
- object.destroy
+ object.destroy if object
# wait for the object to be deleted
Fog.wait_for do
begin
object = collection.get(id)
puts "Current status: #{object ? object.status : 'deleted'}" if ENV['DEBUG_VERBOSE']
- false
- rescue Fog::Compute::OpenStack::NotFound # "Compute", not "Volume"; see issue #3618
- true
+ object.nil?
end
end
end
it 'CRUD volumes' do
VCR.use_cassette('volume_crud') do
+ begin
+ volume_name = "fog-testvolume-1"
+ volume_description = 'This is the volume description.'
+ volume_size = 1 # in GB
- volume_name = "fog-testvolume-1"
- volume_description = 'This is the volume description.'
- volume_size = 1 # in GB
+ # create volume
+ volume_id = setup_test_object(:type => :volume,
+ @name_param => volume_name,
+ @description_param => volume_description,
+ :size => volume_size
+ ).id
- # create volume
- volume_id = setup_test_object(:type => :volume,
- :display_name => volume_name,
- :display_description => volume_description,
- :size => volume_size
- ).id
+ expect(@service.volumes.all(@name_param => volume_name).length).to be 1
- expect(@service.volumes.all(:display_name => volume_name).length).to be 1
+ # check retrieval of volume by ID
+ puts "Retrieving volume by ID..." if ENV['DEBUG_VERBOSE']
- # check retrieval of volume by ID
- puts "Retrieving volume by ID..." if ENV['DEBUG_VERBOSE']
+ volume = @service.volumes.get(volume_id)
+ expect(volume).to be_a(Fog::Volume::OpenStack::Volume)
- volume = @service.volumes.get(volume_id)
- expect(volume).to be_a(Fog::Volume::OpenStack::Volume)
+ expect(volume.id).to eq(volume_id)
+ expect(volume.display_name).to eq(volume_name) unless v2?
+ expect(volume.name).to eq(volume_name) if v2?
+ expect(volume.display_description).to eq(volume_description) unless v2?
+ expect(volume.description).to eq(volume_description) if v2?
+ expect(volume.size).to eq(volume_size)
- expect(volume.id).to eq(volume_id)
- expect(volume.display_name).to eq(volume_name)
- expect(volume.display_description).to eq(volume_description)
- expect(volume.size).to eq(volume_size)
+ puts "Waiting for volume to be available..." if ENV['DEBUG_VERBOSE']
+ volume.wait_for { ready? }
- puts "Waiting for volume to be available..." if ENV['DEBUG_VERBOSE']
- volume.wait_for { ready? }
+ # check retrieval of volume by name
+ puts "Retrieving volume by name..." if ENV['DEBUG_VERBOSE']
- # check retrieval of volume by name
- puts "Retrieving volume by name..." if ENV['DEBUG_VERBOSE']
+ volumes = @service.volumes.all(@name_param => volume_name)
+ expect(volumes.length).to be 1
+ volume = volumes[0]
+ expect(volume).to be_a(Fog::Volume::OpenStack::Volume)
- volumes = @service.volumes.all(:display_name => volume_name)
- expect(volumes.length).to be 1
- volume = volumes[0]
- expect(volume).to be_a(Fog::Volume::OpenStack::Volume)
-
- expect(volume.id).to eq(volume_id)
- expect(volume.display_name).to eq(volume_name)
- expect(volume.display_description).to eq(volume_description)
- expect(volume.size).to eq(volume_size)
-
- # delete volume
- cleanup_test_object(@service.volumes, volume_id)
+ expect(volume.id).to eq(volume_id)
+ expect(volume.display_name).to eq(volume_name) unless v2?
+ expect(volume.name).to eq(volume_name) if v2?
+ expect(volume.display_description).to eq(volume_description) unless v2?
+ expect(volume.description).to eq(volume_description) if v2?
+ expect(volume.size).to eq(volume_size)
+ ensure
+ # delete volume
+ cleanup_test_object(@service.volumes, volume_id)
+ end
end
end
it 'reads volume types' do
VCR.use_cassette('volume_type_read') do
@@ -150,186 +171,192 @@
end
end
it 'can extend volumes' do
VCR.use_cassette('volume_extend') do
+ begin
+ volume_size_small = 1 # in GB
+ volume_size_large = 2 # in GB
- volume_size_small = 1 # in GB
- volume_size_large = 2 # in GB
+ volume = setup_test_object(:type => :volume,
+ @name_param => 'fog-testvolume-1',
+ :size => volume_size_small
+ )
+ volume.wait_for { ready? and size == volume_size_small }
- volume = setup_test_object(:type => :volume,
- :display_name => 'fog-testvolume-1',
- :size => volume_size_small
- )
- volume.wait_for { ready? and size == volume_size_small }
+ # extend volume
+ puts "Extending volume..." if ENV['DEBUG_VERBOSE']
+ volume.extend(volume_size_large)
+ volume.wait_for { ready? and size == volume_size_large }
- # extend volume
- puts "Extending volume..." if ENV['DEBUG_VERBOSE']
- volume.extend(volume_size_large)
- volume.wait_for { ready? and size == volume_size_large }
+ # shrinking is not allowed in OpenStack
+ puts "Shrinking volume should fail..." if ENV['DEBUG_VERBOSE']
+ expect { volume.extend(volume_size_small) }.to raise_error(Excon::Errors::BadRequest, /Invalid input received: New size for extend must be greater than current size./)
+ ensure
+ # delete volume
+ cleanup_test_object(@service.volumes, volume.id)
- # shrinking is not allowed in OpenStack
- puts "Shrinking volume should fail..." if ENV['DEBUG_VERBOSE']
- expect { volume.extend(volume_size_small) }.to raise_error(Excon::Errors::BadRequest, /Invalid input received: New size for extend must be greater than current size./)
-
- # delete volume
- cleanup_test_object(@service.volumes, volume.id)
-
- # check that extending a non-existing volume fails
- puts "Extending deleted volume should fail..." if ENV['DEBUG_VERBOSE']
- expect { @service.extend_volume(volume.id, volume_size_small) }.to raise_error(Fog::Compute::OpenStack::NotFound)
+ # check that extending a non-existing volume fails
+ puts "Extending deleted volume should fail..." if ENV['DEBUG_VERBOSE']
+ expect { @service.extend_volume(volume.id, volume_size_small) }.to raise_error(Fog::Volume::OpenStack::NotFound)
+ end
end
end
it 'can create and accept volume transfers' do
VCR.use_cassette('volume_transfer_and_accept') do
+ begin
+ transfer_name = 'fog-testtransfer-1'
- transfer_name = 'fog-testtransfer-1'
+ # create volume object
+ volume = setup_test_object(:type => :volume,
+ @name_param => 'fog-testvolume-1',
+ :size => 1
+ )
+ volume.wait_for { ready? }
- # create volume object
- volume = setup_test_object(:type => :volume,
- :display_name => 'fog-testvolume-1',
- :size => 1
- )
- volume.wait_for { ready? }
+ # create transfer object
+ transfer = setup_test_object(:type => :transfer,
+ :name => transfer_name,
+ :volume_id => volume.id
+ )
+ # we need to save the auth_key NOW, it's only present in the response
+ # from the create_transfer request
+ auth_key = transfer.auth_key
+ transfer_id = transfer.id
- # create transfer object
- transfer = setup_test_object(:type => :transfer,
- :name => transfer_name,
- :volume_id => volume.id
- )
- # we need to save the auth_key NOW, it's only present in the response
- # from the create_transfer request
- auth_key = transfer.auth_key
- transfer_id = transfer.id
+ # check retrieval of transfer by ID
+ puts 'Retrieving transfer by ID...' if ENV['DEBUG_VERBOSE']
- # check retrieval of transfer by ID
- puts 'Retrieving transfer by ID...' if ENV['DEBUG_VERBOSE']
+ transfer = @service.transfers.get(transfer_id)
+ expect(transfer).to be_a(Fog::Volume::OpenStack::Transfer)
- transfer = @service.transfers.get(transfer_id)
- expect(transfer).to be_a(Fog::Volume::OpenStack::Transfer)
+ expect(transfer.id).to eq(transfer_id)
+ expect(transfer.name).to eq(transfer_name)
+ expect(transfer.volume_id).to eq(volume.id)
- expect(transfer.id).to eq(transfer_id)
- expect(transfer.name).to eq(transfer_name)
- expect(transfer.volume_id).to eq(volume.id)
+ # check retrieval of transfer by name
+ puts 'Retrieving transfer by name...' if ENV['DEBUG_VERBOSE']
- # check retrieval of transfer by name
- puts 'Retrieving transfer by name...' if ENV['DEBUG_VERBOSE']
+ transfers = @service.transfers.all(:name => transfer_name)
+ expect(transfers.length).to be(1)
+ transfer = transfers[0]
+ expect(transfer).to be_a(Fog::Volume::OpenStack::Transfer)
- transfers = @service.transfers.all(:name => transfer_name)
- expect(transfers.length).to be(1)
- transfer = transfers[0]
- expect(transfer).to be_a(Fog::Volume::OpenStack::Transfer)
+ expect(transfer.id).to eq(transfer_id)
+ expect(transfer.name).to eq(transfer_name)
+ expect(transfer.volume_id).to eq(volume.id)
- expect(transfer.id).to eq(transfer_id)
- expect(transfer.name).to eq(transfer_name)
- expect(transfer.volume_id).to eq(volume.id)
+ # to accept the transfer, we need a second connection to a different project
+ puts 'Checking object visibility from different projects...' if ENV['DEBUG_VERBOSE']
+ other_service = @service.class.new(
+ :openstack_auth_url => "#{@os_auth_url}/auth/tokens",
+ :openstack_region => ENV['OS_REGION_NAME'] || 'RegionOne',
+ :openstack_api_key => ENV['OS_PASSWORD_OTHER'] || 'password',
+ :openstack_username => ENV['OS_USERNAME_OTHER'] || 'demo',
+ :openstack_domain_name => ENV['OS_USER_DOMAIN_NAME'] || 'Default',
+ :openstack_project_name => ENV['OS_PROJECT_NAME_OTHER'] || 'demo'
+ )
- # to accept the transfer, we need a second connection to a different project
- puts 'Checking object visibility from different projects...' if ENV['DEBUG_VERBOSE']
- other_service = Fog::Volume::OpenStack.new(
- :openstack_auth_url => "#{@os_auth_url}/tokens",
- :openstack_region => ENV['OS_REGION_NAME'] || 'RegionOne',
- :openstack_api_key => ENV['OS_PASSWORD_OTHER'] || 'devstack',
- :openstack_username => ENV['OS_USERNAME_OTHER'] || 'demo',
- :openstack_tenant => ENV['OS_PROJECT_NAME_OTHER'] || 'demo'
- )
+ # check that recipient cannot see the transfer object
+ expect(other_service.transfers.get(transfer.id)).to be_nil
+ expect(other_service.transfers.all(:name => transfer_name).length).to be(0)
- # check that recipient cannot see the transfer object
- expect { other_service.transfers.get(transfer.id) }.to raise_error(Fog::Compute::OpenStack::NotFound)
- expect(other_service.transfers.all(:name => transfer_name).length).to be(0)
+ # # check that recipient cannot see the volume before transfer
+ # expect { other_service.volumes.get(volume.id) }.to raise_error(Fog::Compute::OpenStack::NotFound)
+ # expect(other_service.volumes.all(@name_param => volume_name).length).to be(0)
- # # check that recipient cannot see the volume before transfer
- # expect { other_service.volumes.get(volume.id) }.to raise_error(Fog::Compute::OpenStack::NotFound)
- # expect(other_service.volumes.all(:display_name => volume_name).length).to be(0)
+ # The recipient can inexplicably see the volume even before the
+ # transfer, so to confirm that the transfer happens, we record its tenant ID.
+ expect(volume.tenant_id).to match(/^[0-9a-f-]+$/) # should look like a UUID
+ source_tenant_id = volume.tenant_id
- # The recipient can inexplicably see the volume even before the
- # transfer, so to confirm that the transfer happens, we record its tenant ID.
- expect(volume.tenant_id).to match(/^[0-9a-f-]+$/) # should look like a UUID
- source_tenant_id = volume.tenant_id
+ # check that accept_transfer fails without valid transfer ID and auth key
+ bogus_uuid = 'ec8ff7e8-81e2-4e12-b9fb-3e8890612c2d' # generated by Fog::UUID.uuid, but fixed to play nice with VCR
+ expect { other_service.transfers.accept(bogus_uuid, auth_key) }.to raise_error(Fog::Volume::OpenStack::NotFound)
+ expect { other_service.transfers.accept(transfer_id, 'invalidauthkey') }.to raise_error(Excon::Errors::BadRequest)
- # check that accept_transfer fails without valid transfer ID and auth key
- bogus_uuid = 'ec8ff7e8-81e2-4e12-b9fb-3e8890612c2d' # generated by Fog::UUID.uuid, but fixed to play nice with VCR
- expect { other_service.transfers.accept(bogus_uuid, auth_key) }.to raise_error(Fog::Compute::OpenStack::NotFound)
- expect { other_service.transfers.accept(transfer_id, 'invalidauthkey') }.to raise_error(Excon::Errors::BadRequest)
+ # accept transfer
+ puts 'Accepting transfer...' if ENV['DEBUG_VERBOSE']
+ transfer = other_service.transfers.accept(transfer.id, auth_key)
+ expect(transfer).to be_a(Fog::Volume::OpenStack::Transfer)
- # accept transfer
- puts 'Accepting transfer...' if ENV['DEBUG_VERBOSE']
- transfer = other_service.transfers.accept(transfer.id, auth_key)
- expect(transfer).to be_a(Fog::Volume::OpenStack::Transfer)
+ expect(transfer.id).to eq(transfer_id)
+ expect(transfer.name).to eq(transfer_name)
- expect(transfer.id).to eq(transfer_id)
- expect(transfer.name).to eq(transfer_name)
+ # check that recipient can see the volume
+ volume = other_service.volumes.get(volume.id)
+ expect(volume).to be_a(Fog::Volume::OpenStack::Volume)
- # check that recipient can see the volume
- volume = other_service.volumes.get(volume.id)
- expect(volume).to be_a(Fog::Volume::OpenStack::Volume)
+ # # check that sender cannot see the volume anymore
+ # expect { @service.volumes.get(volume.id) }.to raise_error(Fog::Compute::OpenStack::NotFound)
+ # expect(@service.volumes.all(@name_param => volume_name).length).to be(0)
- # # check that sender cannot see the volume anymore
- # expect { @service.volumes.get(volume.id) }.to raise_error(Fog::Compute::OpenStack::NotFound)
- # expect(@service.volumes.all(:display_name => volume_name).length).to be(0)
+ # As noted above, both users seem to be able to see the volume at all times.
+ # Check change of ownership by looking at the tenant_id, instead.
+ expect(volume.tenant_id).to match(/^[0-9a-f-]+$/) # should look like a UUID
+ expect(volume.tenant_id).not_to eq(source_tenant_id)
- # As noted above, both users seem to be able to see the volume at all times.
- # Check change of ownership by looking at the tenant_id, instead.
- expect(volume.tenant_id).to match(/^[0-9a-f-]+$/) # should look like a UUID
- expect(volume.tenant_id).not_to eq(source_tenant_id)
-
- # check that the transfer object is gone on both sides
- [ @service, other_service ].each do |service|
- expect { service.transfers.get(transfer.id) }.to raise_error(Fog::Compute::OpenStack::NotFound)
- expect(service.transfers.all(:name => transfer_name).length).to be(0)
+ # check that the transfer object is gone on both sides
+ [@service, other_service].each do |service|
+ expect(service.transfers.get(transfer.id)).to be_nil
+ expect(service.transfers.all(:name => transfer_name).length).to be(0)
+ end
+ ensure
+ # cleanup volume
+ cleanup_test_object(other_service.volumes, volume.id)
end
-
- # cleanup volume
- cleanup_test_object(other_service.volumes, volume.id)
end
end
it 'can create and delete volume transfers' do
VCR.use_cassette('volume_transfer_and_delete') do
- # create volume object
- volume = setup_test_object(:type => :volume,
- :display_name => 'fog-testvolume-1',
- :size => 1
- )
- volume.wait_for { ready? }
+ begin
+ # create volume object
+ volume = setup_test_object(:type => :volume,
+ @name_param => 'fog-testvolume-1',
+ :size => 1
+ )
+ volume.wait_for { ready? }
- # create transfer object
- transfer = setup_test_object(:type => :transfer,
- :name => 'fog-testtransfer-1',
- :volume_id => volume.id
- )
- # we need to save the auth_key NOW, it's only present in the response
- # from the create_transfer request
- auth_key = transfer.auth_key
- transfer_id = transfer.id
+ # create transfer object
+ transfer = setup_test_object(:type => :transfer,
+ :name => 'fog-testtransfer-1',
+ :volume_id => volume.id
+ )
+ # we need to save the auth_key NOW, it's only present in the response
+ # from the create_transfer request
+ auth_key = transfer.auth_key
+ transfer_id = transfer.id
- # to try to accept the transfer, we need a second connection to a different project
- other_service = Fog::Volume::OpenStack.new(
- :openstack_auth_url => "#{@os_auth_url}/tokens",
- :openstack_region => ENV['OS_REGION_NAME'] || 'RegionOne',
- :openstack_api_key => ENV['OS_PASSWORD_OTHER'] || 'devstack',
- :openstack_username => ENV['OS_USERNAME_OTHER'] || 'demo',
- :openstack_tenant => ENV['OS_PROJECT_NAME_OTHER'] || 'demo'
- )
+ # to try to accept the transfer, we need a second connection to a different project
+ other_service = @service.class.new(
+ :openstack_auth_url => "#{@os_auth_url}/auth/tokens",
+ :openstack_region => ENV['OS_REGION_NAME'] || 'RegionOne',
+ :openstack_api_key => ENV['OS_PASSWORD_OTHER'] || 'password',
+ :openstack_username => ENV['OS_USERNAME_OTHER'] || 'demo',
+ :openstack_domain_name => ENV['OS_USER_DOMAIN_NAME'] || 'Default',
+ :openstack_project_name => ENV['OS_PROJECT_NAME_OTHER'] || 'demo'
+ )
- # delete transfer again
- transfer.destroy
+ # delete transfer again
+ transfer.destroy
- # check that transfer cannot be accepted when it has been deleted
- puts 'Checking that accepting a deleted transfer fails...' if ENV['DEBUG_VERBOSE']
- expect { other_service.transfers.accept(transfer_id, auth_key) }.to raise_error(Fog::Compute::OpenStack::NotFound)
-
- # cleanup volume
- cleanup_test_object(@service.volumes, volume.id)
+ # check that transfer cannot be accepted when it has been deleted
+ puts 'Checking that accepting a deleted transfer fails...' if ENV['DEBUG_VERBOSE']
+ expect { other_service.transfers.accept(transfer_id, auth_key) }.to raise_error(Fog::Volume::OpenStack::NotFound)
+ ensure
+ # cleanup volume
+ cleanup_test_object(@service.volumes, volume.id)
+ end
end
end
# TODO: tests for snapshots
it 'responds to list_snapshots_detailed' do
expect(@service.respond_to?(:list_snapshots_detailed)).to be true
end
# TODO: tests for quotas
-
-end
+ end
+end
\ No newline at end of file