Retire ec2-api: remove repo content

ec2-api project is retiring
- https://review.opendev.org/c/openstack/governance/+/919394/1

this commit remove the content of this project repo

Depends-On: https://review.opendev.org/c/openstack/project-config/+/919396/1
Change-Id: I038271038b8c64a5a6a4adda2171ee5e44663e44
This commit is contained in:
Ghanshyam Mann 2024-05-10 18:08:36 -07:00
parent 1036f53ae8
commit 31495609a8
50 changed files with 8 additions and 9120 deletions

59
.gitignore vendored
View File

@ -1,59 +0,0 @@
*.py[cod]
# C extensions
*.so
# Packages
*.egg*
*.egg-info
dist
build
eggs
parts
bin
var
sdist
develop-eggs
.installed.cfg
lib
lib64
# Installer logs
pip-log.txt
# Unit test / coverage reports
cover/
.coverage*
!.coveragerc
.tox
nosetests.xml
.testrepository
.stestr
.venv
# Translations
*.mo
# Mr Developer
.mr.developer.cfg
.project
.pydevproject
# Complexity
output/*.html
output/*/index.html
# Sphinx
doc/build
# pbr generates these
AUTHORS
ChangeLog
# Editors
*~
.*.swp
.*sw?
# Files created by releasenotes build
releasenotes/build

View File

@ -1,70 +0,0 @@
- project:
queue: ec2-api
templates:
- openstack-python3-zed-jobs
- check-requirements
check:
jobs:
- ec2api-tempest-plugin-functional
- ec2api-tempest-plugin-functional-2023-1
- ec2api-tempest-plugin-functional-zed
- ec2api-tempest-plugin-functional-yoga
- ec2api-tempest-plugin-functional-xena
gate:
jobs:
- ec2api-tempest-plugin-functional
experimental:
jobs:
- ec2api-tempest-plugin-functional-full
- job:
name: ec2api-tempest-plugin-functional
parent: devstack-tempest
timeout: 7800
required-projects:
- opendev.org/openstack/ec2-api
- opendev.org/openstack/ec2api-tempest-plugin
- opendev.org/openstack/neutron
- opendev.org/openstack/neutron-vpnaas
- opendev.org/openstack/neutron-tempest-plugin
vars:
devstack_localrc:
KEYSTONE_ADMIN_ENDPOINT: true
devstack_services:
tls-proxy: false
tox_envlist: all
tempest_test_regex: ec2api_tempest_plugin
tempest_concurrency: 2
devstack_plugins:
ec2-api: https://opendev.org/openstack/ec2-api
neutron-tempest-plugin: https://opendev.org/openstack/neutron-tempest-plugin
tempest_plugins:
- ec2api-tempest-plugin
- job:
name: ec2api-tempest-plugin-functional-2023-1
parent: ec2api-tempest-plugin-functional
nodeset: openstack-single-node-jammy
override-checkout: stable/2023.1
- job:
name: ec2api-tempest-plugin-functional-zed
parent: ec2api-tempest-plugin-functional
nodeset: openstack-single-node-focal
override-checkout: stable/zed
- job:
name: ec2api-tempest-plugin-functional-yoga
parent: ec2api-tempest-plugin-functional
nodeset: openstack-single-node-focal
override-checkout: stable/yoga
- job:
name: ec2api-tempest-plugin-functional-xena
parent: ec2api-tempest-plugin-functional
nodeset: openstack-single-node-focal
override-checkout: stable/xena
- job:
name: ec2api-tempest-plugin-functional-full
parent: ec2api-tempest-plugin-functional
vars:
devstack_localrc:
RUN_LONG_TESTS: 1

View File

@ -1,19 +0,0 @@
The source repository for this project can be found at:
https://opendev.org/openstack/ec2api-tempest-plugin
Pull requests submitted through GitHub are not monitored.
To start contributing to OpenStack, follow the steps in the contribution guide
to set up and use Gerrit:
https://docs.openstack.org/contributors/code-and-documentation/quick-start.html
Bugs should be filed on Launchpad:
https://bugs.launchpad.net/ec2-api
For more specific information about contributing to this repository, see the
ec2api-tempest-plugin contributor guide:
https://docs.openstack.org/ec2-api/latest/contributor/contributing.html

View File

@ -1,4 +0,0 @@
openstack Style Commandments
===============================================
Read the OpenStack Style Commandments https://docs.openstack.org/hacking/latest/

176
LICENSE
View File

@ -1,176 +0,0 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.

View File

@ -1,19 +1,10 @@
=====================
ec2api tempest plugin
=====================
This project is no longer maintained.
Tempest plugin ec2api_tempest_plugin
The contents of this repository are still available in the Git
source code management system. To see the contents of this
repository before it reached its end of life, please check out the
previous commit with "git checkout HEAD^1".
Please fill here a long description which must be at least 3 lines wrapped on
80 cols, so that distribution package maintainers can use it in their packages.
Note that this is a hard requirement.
* Free software: Apache license
* Documentation: https://docs.openstack.org/ec2-api/latest
* Source: https://opendev.org/openstack/ec2api-tempest-plugin
* Bugs: https://bugs.launchpad.net/ec2-api
Features
--------
* TODO
For any further questions, please email
openstack-discuss@lists.openstack.org or join #openstack-dev on
OFTC.

View File

@ -1,2 +0,0 @@
[python: **.py]

View File

@ -1,437 +0,0 @@
# Copyright 2014 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import time
import botocore.exceptions
from oslo_log import log
from tempest.lib import decorators
import testtools
from ec2api_tempest_plugin import base
from ec2api_tempest_plugin import config
CONF = config.CONF
LOG = log.getLogger(__name__)
class AddressTest(base.EC2TestCase):
@base.skip_without_vpc()
@decorators.idempotent_id('218a4b6b-c3a9-44b0-8148-4bd0bc36bd7d')
def test_create_delete_vpc_address(self):
kwargs = {
'Domain': 'vpc',
}
data = self.client.allocate_address(*[], **kwargs)
id = data['AllocationId']
res_clean = self.addResourceCleanUp(self.client.release_address,
AllocationId=id)
self.assertEqual('vpc', data['Domain'])
data = self.client.release_address(AllocationId=id)
self.cancelResourceCleanUp(res_clean)
@base.skip_without_ec2()
@decorators.idempotent_id('285b8b4e-5aef-4e7f-be9e-37e6475be21b')
def test_create_delete_standard_address(self):
data = self.client.allocate_address()
ip = data['PublicIp']
res_clean = self.addResourceCleanUp(self.client.release_address,
PublicIp=ip)
data = self.client.release_address(PublicIp=ip)
self.cancelResourceCleanUp(res_clean)
@base.skip_without_vpc()
@decorators.idempotent_id('5be3ad8d-b071-472b-b92a-7199c82334a2')
def test_invalid_delete_vpc_address(self):
kwargs = {
'Domain': 'vpc',
}
data = self.client.allocate_address(*[], **kwargs)
ip = data['PublicIp']
id = data['AllocationId']
res_clean = self.addResourceCleanUp(self.client.release_address,
AllocationId=id)
self.assertEqual('vpc', data['Domain'])
self.assertRaises('InvalidParameterCombination',
self.client.release_address,
PublicIp=ip, AllocationId=id)
self.assertRaises('InvalidParameterValue',
self.client.release_address,
PublicIp=ip)
data = self.client.release_address(AllocationId=id)
self.cancelResourceCleanUp(res_clean)
if CONF.aws.run_incompatible_tests:
self.assertRaises('AuthFailure',
self.client.release_address,
PublicIp=ip)
self.assertRaises('InvalidAllocationID.NotFound',
self.client.release_address,
AllocationId=id)
kwargs = {
"AllocationId": 'eipalloc-00000000',
}
self.assertRaises('InvalidAllocationID.NotFound',
self.client.release_address,
**kwargs)
if CONF.aws.run_incompatible_tests:
self.assertRaises('InvalidParameterValue',
self.client.release_address,
PublicIp='ip')
@decorators.idempotent_id('e8171637-9ccd-471a-97da-c78a36ba3c4b')
def test_invalid_create_address(self):
kwargs = {
'Domain': 'invalid',
}
try:
data = self.client.allocate_address(*[], **kwargs)
allocation_id = data.get('AllocationId')
if allocation_id:
self.client.release_address(AllocationId=allocation_id)
else:
public_ip = data.get('PublicIp')
self.client.release_address(PublicIp=public_ip)
except botocore.exceptions.ClientError as e:
self.assertEqual('InvalidParameterValue',
e.response['Error']['Code'])
@base.skip_without_vpc()
@decorators.idempotent_id('b0d0b498-1fe2-479e-995c-80ace2f339a7')
def test_describe_vpc_addresses(self):
kwargs = {
'Domain': 'vpc',
}
data = self.client.allocate_address(*[], **kwargs)
ip = data['PublicIp']
id = data['AllocationId']
res_clean = self.addResourceCleanUp(self.client.release_address,
AllocationId=id)
data = self.client.describe_addresses(*[], **{})
for address in data['Addresses']:
if address.get('AllocationId') == id:
self.assertEqual('vpc', address['Domain'])
self.assertEqual(ip, address['PublicIp'])
break
else:
self.fail('Created address could not be found')
kwargs = {
'PublicIps': [ip],
}
data = self.client.describe_addresses(*[], **kwargs)
self.assertEqual(1, len(data['Addresses']))
self.assertEqual(id, data['Addresses'][0]['AllocationId'])
kwargs = {
'AllocationIds': [id],
}
data = self.client.describe_addresses(*[], **kwargs)
self.assertEqual(1, len(data['Addresses']))
self.assertEqual(ip, data['Addresses'][0]['PublicIp'])
kwargs = {
'PublicIps': ['invalidIp'],
}
self.assertRaises('InvalidParameterValue',
self.client.describe_addresses,
**kwargs)
kwargs = {
'AllocationIds': ['eipalloc-00000000'],
}
self.assertRaises('InvalidAllocationID.NotFound',
self.client.describe_addresses,
**kwargs)
kwargs = {
'Domain': 'vpc',
}
data = self.client.allocate_address(*[], **kwargs)
id2 = data['AllocationId']
res_clean2 = self.addResourceCleanUp(self.client.release_address,
AllocationId=id2)
kwargs = {
'PublicIps': [ip],
'AllocationIds': [id2],
}
data = self.client.describe_addresses(*[], **kwargs)
self.assertEqual(2, len(data['Addresses']))
# NOTE(andrey-mp): wait abit before releasing
time.sleep(3)
self.client.release_address(AllocationId=id)
self.cancelResourceCleanUp(res_clean)
self.client.release_address(AllocationId=id2)
self.cancelResourceCleanUp(res_clean2)
@base.skip_without_ec2()
@decorators.idempotent_id('a5c09f47-3be3-4d46-b59d-25195d67e6d5')
def test_describe_standard_addresses(self):
data = self.client.allocate_address(*[], **{})
ip = data['PublicIp']
res_clean = self.addResourceCleanUp(self.client.release_address,
PublicIp=ip)
data = self.client.describe_addresses(*[], **{})
for address in data['Addresses']:
if address['PublicIp'] == ip:
self.assertEqual('standard', address['Domain'])
break
else:
self.fail('Created address could not be found')
kwargs = {
'PublicIps': [ip],
}
data = self.client.describe_addresses(*[], **kwargs)
self.assertEqual(1, len(data['Addresses']))
self.assertEqual(ip, data['Addresses'][0]['PublicIp'])
kwargs = {
'PublicIps': ['invalidIp'],
}
self.assertRaises('InvalidParameterValue',
self.client.describe_addresses,
PublicIps=['invalidIp'])
# NOTE(andrey-mp): wait abit before releasing
time.sleep(3)
self.client.release_address(PublicIp=ip)
self.cancelResourceCleanUp(res_clean)
@base.skip_without_vpc()
@decorators.idempotent_id('6f154e48-f260-4d8d-b1d1-a1cf174f58fa')
@testtools.skip("flaky test")
# @testtools.skipUnless(CONF.aws.image_id, "image id is not defined")
def test_associate_disassociate_vpc_addresses(self):
aws_zone = CONF.aws.aws_zone
base_net = '10.3.0.0'
data = self.client.create_vpc(CidrBlock=base_net + '/20')
vpc_id = data['Vpc']['VpcId']
clean_vpc = self.addResourceCleanUp(self.client.delete_vpc,
VpcId=vpc_id)
self.get_vpc_waiter().wait_available(vpc_id)
cidr = base_net + '/24'
data = self.client.create_subnet(VpcId=vpc_id, CidrBlock=cidr,
AvailabilityZone=aws_zone)
subnet_id = data['Subnet']['SubnetId']
clean_subnet = self.addResourceCleanUp(self.client.delete_subnet,
SubnetId=subnet_id)
instance_id = self.run_instance(SubnetId=subnet_id)
data = self.client.allocate_address(Domain='vpc')
alloc_id = data['AllocationId']
clean_a = self.addResourceCleanUp(self.client.release_address,
AllocationId=alloc_id)
self.assertRaises('Gateway.NotAttached',
self.client.associate_address,
InstanceId=instance_id, AllocationId=alloc_id)
# Create internet gateway and try to associate again
data = self.client.create_internet_gateway()
gw_id = data['InternetGateway']['InternetGatewayId']
clean_ig = self.addResourceCleanUp(self.client.delete_internet_gateway,
InternetGatewayId=gw_id)
data = self.client.attach_internet_gateway(VpcId=vpc_id,
InternetGatewayId=gw_id)
clean_aig = self.addResourceCleanUp(
self.client.detach_internet_gateway,
VpcId=vpc_id,
InternetGatewayId=gw_id)
self.prepare_route(vpc_id, gw_id)
data = self.client.associate_address(InstanceId=instance_id,
AllocationId=alloc_id)
assoc_id = data['AssociationId']
clean_aa = self.addResourceCleanUp(self.client.disassociate_address,
AssociationId=assoc_id)
self.get_address_assoc_waiter().wait_available(
{'AllocationId': alloc_id})
kwargs = {
'AllocationIds': [alloc_id],
}
data = self.client.describe_addresses(*[], **kwargs)
self.assertEqual(instance_id, data['Addresses'][0]['InstanceId'])
data = self.client.disassociate_address(AssociationId=assoc_id)
self.cancelResourceCleanUp(clean_aa)
self.get_address_assoc_waiter().wait_delete({'AllocationId': alloc_id})
# NOTE(andrey-mp): cleanup
time.sleep(3)
self.client.detach_internet_gateway(VpcId=vpc_id,
InternetGatewayId=gw_id)
self.cancelResourceCleanUp(clean_aig)
self.client.delete_internet_gateway(InternetGatewayId=gw_id)
self.cancelResourceCleanUp(clean_ig)
self.client.release_address(AllocationId=alloc_id)
self.cancelResourceCleanUp(clean_a)
self.client.terminate_instances(InstanceIds=[instance_id])
self.get_instance_waiter().wait_delete(instance_id)
self.client.delete_subnet(SubnetId=subnet_id)
self.cancelResourceCleanUp(clean_subnet)
self.get_subnet_waiter().wait_delete(subnet_id)
self.client.delete_vpc(VpcId=vpc_id)
self.cancelResourceCleanUp(clean_vpc)
self.get_vpc_waiter().wait_delete(vpc_id)
@decorators.idempotent_id('4aaf01d2-ade5-4e8b-b24a-ab22448b3236')
@testtools.skipUnless(CONF.aws.image_id, "image id is not defined")
# skip this test for nova network due to bug #1607350
@base.skip_without_vpc()
# this is a correct skip
@base.skip_without_ec2()
def test_associate_disassociate_standard_addresses(self):
instance_id = self.run_instance()
data = self.client.allocate_address(*[], **{})
ip = data['PublicIp']
clean_a = self.addResourceCleanUp(self.client.release_address,
PublicIp=ip)
data = self.client.associate_address(InstanceId=instance_id,
PublicIp=ip)
clean_aa = self.addResourceCleanUp(self.client.disassociate_address,
PublicIp=ip)
self.get_address_assoc_waiter().wait_available({'PublicIp': ip})
kwargs = {
'PublicIps': [ip],
}
data = self.client.describe_addresses(*[], **kwargs)
self.assertEqual(instance_id, data['Addresses'][0]['InstanceId'])
data = self.client.disassociate_address(PublicIp=ip)
self.cancelResourceCleanUp(clean_aa)
self.get_address_assoc_waiter().wait_delete({'PublicIp': ip})
time.sleep(3)
data = self.client.release_address(PublicIp=ip)
self.cancelResourceCleanUp(clean_a)
data = self.client.terminate_instances(InstanceIds=[instance_id])
self.get_instance_waiter().wait_delete(instance_id)
@base.skip_without_vpc()
@decorators.idempotent_id('3c0ab7f5-ee9c-4966-8d43-e89f5520f245')
def test_disassociate_not_associated_vpc_addresses(self):
aws_zone = CONF.aws.aws_zone
base_net = '10.3.0.0'
data = self.client.create_vpc(CidrBlock=base_net + '/20')
vpc_id = data['Vpc']['VpcId']
clean_vpc = self.addResourceCleanUp(self.client.delete_vpc,
VpcId=vpc_id)
self.get_vpc_waiter().wait_available(vpc_id)
cidr = base_net + '/24'
data = self.client.create_subnet(VpcId=vpc_id, CidrBlock=cidr,
AvailabilityZone=aws_zone)
subnet_id = data['Subnet']['SubnetId']
clean_subnet = self.addResourceCleanUp(self.client.delete_subnet,
SubnetId=subnet_id)
data = self.client.allocate_address(Domain='vpc')
alloc_id = data['AllocationId']
ip = data['PublicIp']
clean_a = self.addResourceCleanUp(self.client.release_address,
AllocationId=alloc_id)
assoc_id = 'eipassoc-00000001'
self.assertRaises('InvalidAssociationID.NotFound',
self.client.disassociate_address,
AssociationId=assoc_id)
self.assertRaises('InvalidParameterValue',
self.client.disassociate_address,
PublicIp=ip)
self.client.release_address(AllocationId=alloc_id)
self.cancelResourceCleanUp(clean_a)
self.client.delete_subnet(SubnetId=subnet_id)
self.cancelResourceCleanUp(clean_subnet)
self.get_subnet_waiter().wait_delete(subnet_id)
self.client.delete_vpc(VpcId=vpc_id)
self.cancelResourceCleanUp(clean_vpc)
self.get_vpc_waiter().wait_delete(vpc_id)
@base.skip_without_ec2()
@decorators.idempotent_id('a70babef-18ec-4340-a3a2-63388cfc3cb5')
def test_disassociate_not_associated_standard_addresses(self):
data = self.client.allocate_address(Domain='standard')
ip = data['PublicIp']
clean_a = self.addResourceCleanUp(self.client.release_address,
PublicIp=ip)
data = self.client.disassociate_address(PublicIp=ip)
data = self.client.release_address(PublicIp=ip)
self.cancelResourceCleanUp(clean_a)
@base.skip_without_vpc()
@decorators.idempotent_id('91b971f5-2674-478e-84df-115fef506c5b')
@testtools.skipUnless(CONF.aws.run_incompatible_tests,
'preliminary address association is not supported')
def test_preliminary_associate_address(self):
# NOTE(ft): AWS can associate an address to a subnet IP if the subnet
# has no internet access
vpc_id, subnet_id = self.create_vpc_and_subnet('10.3.0.0/20')
self.create_and_attach_internet_gateway(vpc_id)
data = self.client.allocate_address(Domain='vpc')
alloc_id = data['AllocationId']
self.addResourceCleanUp(self.client.release_address,
AllocationId=alloc_id)
data = self.client.create_network_interface(SubnetId=subnet_id)
ni_id = data['NetworkInterface']['NetworkInterfaceId']
self.addResourceCleanUp(self.client.delete_network_interface,
NetworkInterfaceId=ni_id)
self.get_network_interface_waiter().wait_available(ni_id)
data = self.client.associate_address(
AllocationId=alloc_id, NetworkInterfaceId=ni_id)
assoc_id = data['AssociationId']
self.addResourceCleanUp(self.client.disassociate_address,
AssociationId=assoc_id)

View File

@ -1,57 +0,0 @@
# Copyright 2014 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import botocore.exceptions
from tempest.lib import decorators
from ec2api_tempest_plugin import base
from ec2api_tempest_plugin import config
CONF = config.CONF
class CustomerGatewayTest(base.EC2TestCase):
CUSTOMER_GATEWAY_IP = '198.51.100.77'
@classmethod
@base.safe_setup
def setUpClass(cls):
super(CustomerGatewayTest, cls).setUpClass()
if not base.TesterStateHolder().get_vpc_enabled():
raise cls.skipException('VPC is disabled')
base.check_vpnaas_enabled()
@decorators.idempotent_id('54a40b66-1675-44b1-938d-0cad2eb6afe4')
def test_create_delete_customer_gateway(self):
data = self.client.create_customer_gateway(
Type='ipsec.1', PublicIp=self.CUSTOMER_GATEWAY_IP, BgpAsn=65000)
cgw_id = data['CustomerGateway']['CustomerGatewayId']
cgw_clean = self.addResourceCleanUp(
self.client.delete_customer_gateway, CustomerGatewayId=cgw_id)
self.assertEqual(self.CUSTOMER_GATEWAY_IP,
data['CustomerGateway']['IpAddress'])
self.client.delete_customer_gateway(CustomerGatewayId=cgw_id)
self.cancelResourceCleanUp(cgw_clean)
try:
data = self.client.describe_customer_gateways(
CustomerGatewayIds=[cgw_id])
self.assertEqual(1, len(data['CustomerGateways']))
self.assertEqual('deleted', data['CustomerGateways'][0]['State'])
except botocore.exceptions.ClientError as ex:
self.assertEqual('InvalidCustomerGatewayID.NotFound',
ex.response['Error']['Code'])

View File

@ -1,182 +0,0 @@
# Copyright 2014 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import time
from oslo_log import log
from tempest.lib import decorators
from ec2api_tempest_plugin import base
from ec2api_tempest_plugin import config
CONF = config.CONF
LOG = log.getLogger(__name__)
class DhcpOptionsTest(base.EC2TestCase):
@classmethod
@base.safe_setup
def setUpClass(cls):
super(DhcpOptionsTest, cls).setUpClass()
if not base.TesterStateHolder().get_vpc_enabled():
raise cls.skipException('VPC is disabled')
@decorators.idempotent_id('2331fc49-50e0-4df3-8c45-bd6f61cc86bf')
def test_create_delete_dhcp_options(self):
kwargs = {
'DhcpConfigurations': [
{'Key': 'domain-name',
'Values': ['my.com', 'it.com']},
{'Key': 'domain-name-servers',
'Values': ['8.8.8.8', '8.8.4.4']},
{'Key': 'ntp-servers',
'Values': ['1.2.3.4']},
{'Key': 'netbios-name-servers',
'Values': ['4.3.2.1']},
{'Key': 'netbios-node-type',
'Values': ['2']},
],
}
data = self.client.create_dhcp_options(*[], **kwargs)
options = data['DhcpOptions']
id = options['DhcpOptionsId']
res_clean = self.addResourceCleanUp(self.client.delete_dhcp_options,
DhcpOptionsId=id)
self.assertEqual(5, len(options['DhcpConfigurations']))
for cfg in options['DhcpConfigurations']:
self.assertEqual(2, len(cfg))
if cfg['Key'] == 'domain-name':
self.assertEqual(2, len(cfg['Values']))
values = [i['Value'] for i in cfg['Values']]
self.assertIn('my.com', values)
self.assertIn('it.com', values)
elif cfg['Key'] == 'domain-name-servers':
self.assertEqual(2, len(cfg['Values']))
values = [i['Value'] for i in cfg['Values']]
self.assertIn('8.8.8.8', values)
self.assertIn('8.8.4.4', values)
elif cfg['Key'] == 'ntp-servers':
self.assertEqual(1, len(cfg['Values']))
self.assertEqual('1.2.3.4', cfg['Values'][0]['Value'])
elif cfg['Key'] == 'netbios-name-servers':
self.assertEqual(1, len(cfg['Values']))
self.assertEqual('4.3.2.1', cfg['Values'][0]['Value'])
elif cfg['Key'] == 'netbios-node-type':
self.assertEqual(1, len(cfg['Values']))
self.assertEqual('2', cfg['Values'][0]['Value'])
else:
self.fail('Unknown key name in result - %s' % cfg['Key'])
data = self.client.delete_dhcp_options(DhcpOptionsId=id)
self.cancelResourceCleanUp(res_clean)
@decorators.idempotent_id('ff1d4f6e-97fc-4053-b98f-ff59e7e8d061')
def test_invalid_create_delete(self):
def _rollback(fn_data):
self.client.delete_dhcp_options(
DhcpOptionsId=fn_data['DhcpOptions']['DhcpOptionsId'])
kwargs = {
'DhcpConfigurations': [
],
}
self.assertRaises('MissingParameter',
self.client.create_dhcp_options,
**kwargs)
kwargs = {
'DhcpConfigurations': [{'Key': 'aaa', 'Values': []}],
}
self.assertRaises('InvalidParameterValue',
self.client.create_dhcp_options, rollback_fn=_rollback,
**kwargs)
kwargs = {
'DhcpConfigurations': [{'Key': 'domain-name', 'Values': []}],
}
self.assertRaises('InvalidParameterValue',
self.client.create_dhcp_options, rollback_fn=_rollback,
**kwargs)
@decorators.idempotent_id('1c3e8ff9-bb3b-40ba-889e-d2306a92f418')
def test_describe_dhcp_options(self):
kwargs = {
'DhcpConfigurations': [
{'Key': 'domain-name',
'Values': ['my.com']},
],
}
data = self.client.create_dhcp_options(*[], **kwargs)
options = data['DhcpOptions']
id = options['DhcpOptionsId']
res_clean = self.addResourceCleanUp(self.client.delete_dhcp_options,
DhcpOptionsId=id)
time.sleep(10)
kwargs = {
'DhcpOptionsIds': [id],
}
data = self.client.describe_dhcp_options(*[], **kwargs)
self.assertEqual(1, len(data['DhcpOptions']))
options = data['DhcpOptions'][0]
self.assertEqual(id, options['DhcpOptionsId'])
self.assertEqual(1, len(options['DhcpConfigurations']))
cfg = options['DhcpConfigurations'][0]
self.assertEqual(2, len(cfg))
self.assertEqual('domain-name', cfg['Key'])
self.assertEqual(1, len(cfg['Values']))
self.assertIn('my.com', cfg['Values'][0]['Value'])
data = self.client.delete_dhcp_options(DhcpOptionsId=id)
self.cancelResourceCleanUp(res_clean)
@decorators.idempotent_id('1b4d678a-c2a2-4c73-9e62-789fe2f6b173')
def test_associate_dhcp_options(self):
kwargs = {
'DhcpConfigurations': [
{'Key': 'domain-name',
'Values': ['my.com']},
],
}
data = self.client.create_dhcp_options(*[], **kwargs)
options = data['DhcpOptions']
id = options['DhcpOptionsId']
res_clean = self.addResourceCleanUp(self.client.delete_dhcp_options,
DhcpOptionsId=id)
cidr = '10.0.0.0/24'
data = self.client.create_vpc(CidrBlock=cidr)
vpc_id = data['Vpc']['VpcId']
dv_clean = self.addResourceCleanUp(self.client.delete_vpc,
VpcId=vpc_id)
kwargs = {
'DhcpOptionsId': id,
'VpcId': vpc_id,
}
data = self.client.associate_dhcp_options(*[], **kwargs)
self.assertRaises('DependencyViolation',
self.client.delete_dhcp_options,
DhcpOptionsId=id)
data = self.client.delete_vpc(VpcId=vpc_id)
self.cancelResourceCleanUp(dv_clean)
self.get_vpc_waiter().wait_delete(vpc_id)
data = self.client.delete_dhcp_options(DhcpOptionsId=id)
self.cancelResourceCleanUp(res_clean)

View File

@ -1,360 +0,0 @@
# Copyright 2014 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
from tempest.lib.common.utils import data_utils
from tempest.lib import decorators
import testtools
from ec2api_tempest_plugin import base
from ec2api_tempest_plugin import config
CONF = config.CONF
class ImageTest(base.EC2TestCase):
@decorators.idempotent_id('19a2fda6-0b78-4544-a6c5-ac16f39811c8')
@testtools.skipUnless(CONF.aws.ebs_image_id, "EBS image id is not defined")
def test_check_ebs_image_type(self):
image_id = CONF.aws.ebs_image_id
data = self.client.describe_images(ImageIds=[image_id])
self.assertEqual(1, len(data['Images']))
image = data['Images'][0]
self.assertEqual("ebs", image['RootDeviceType'],
"Image is not EBS image")
@decorators.idempotent_id('d45be578-5968-4189-8f25-56bf8ef23d20')
@testtools.skipUnless(CONF.aws.ebs_image_id, "EBS image id is not defined")
def test_check_ebs_image_volume_properties(self):
image_id = CONF.aws.ebs_image_id
data = self.client.describe_images(ImageIds=[image_id])
self.assertEqual(1, len(data['Images']))
image = data['Images'][0]
self.assertTrue(image['RootDeviceName'])
self.assertTrue(image['BlockDeviceMappings'])
device_name = image['RootDeviceName']
bdm = image['BlockDeviceMappings']
bdm = [v for v in bdm if v['DeviceName'] == device_name]
self.assertEqual(1, len(bdm))
bdm = bdm[0]
self.assertIn('Ebs', bdm)
ebs = bdm['Ebs']
self.assertIsNotNone(ebs.get('SnapshotId'))
self.assertIsNotNone(ebs.get('DeleteOnTermination'))
self.assertIsNotNone(ebs.get('VolumeSize'))
if CONF.aws.run_incompatible_tests:
self.assertIsNotNone(ebs.get('Encrypted'))
self.assertFalse(ebs.get('Encrypted'))
self.assertIsNotNone(ebs.get('VolumeType'))
@decorators.idempotent_id('a139f5ea-45fd-4b3e-9a52-32de0f8c3bca')
@testtools.skip("flaky test")
@testtools.skipUnless(CONF.aws.ebs_image_id, "EBS image id is not defined")
def test_describe_image_with_filters(self):
image_id = CONF.aws.ebs_image_id
data = self.client.describe_images(ImageIds=[image_id])
self.assertEqual(1, len(data['Images']))
data = self.client.describe_images(
# NOTE(ft): limit output to prevent timeout over AWS
Filters=[{'Name': 'image-type', 'Values': ['kernel', 'ramdisk']}])
if len(data['Images']) < 2:
self.skipTest("Insufficient images to check filters")
data = self.client.describe_images(
Filters=[{'Name': 'image-id', 'Values': [image_id]}])
self.assertEqual(1, len(data['Images']))
self.assertEqual(image_id, data['Images'][0]['ImageId'])
@decorators.idempotent_id('743e1f87-e0b6-4787-ab22-176379030007')
@testtools.skipUnless(CONF.aws.image_id, "Image id is not defined")
def test_check_image_operations_negative(self):
# NOTE(andrey-mp): image_id is a public image created by admin
image_id = CONF.aws.image_id
self.assertRaises('InvalidRequest',
self.client.describe_image_attribute,
ImageId=image_id, Attribute='unsupported')
self.assertRaises('AuthFailure',
self.client.describe_image_attribute,
ImageId=image_id, Attribute='description')
self.assertRaises('InvalidParameterCombination',
self.client.modify_image_attribute,
ImageId=image_id, Attribute='unsupported')
self.assertRaises('InvalidParameter',
self.client.modify_image_attribute,
ImageId=image_id, Attribute='blockDeviceMapping')
self.assertRaises('InvalidParameterCombination',
self.client.modify_image_attribute,
ImageId=image_id)
self.assertRaises('AuthFailure',
self.client.modify_image_attribute,
ImageId=image_id, Description={'Value': 'fake'})
self.assertRaises('AuthFailure',
self.client.modify_image_attribute,
ImageId=image_id, LaunchPermission={'Add': [{'Group': 'all'}]})
self.assertRaises('MissingParameter',
self.client.modify_image_attribute,
ImageId=image_id, Attribute='description')
self.assertRaises('InvalidParameterCombination',
self.client.modify_image_attribute,
ImageId=image_id, Attribute='launchPermission')
self.assertRaises('InvalidRequest',
self.client.reset_image_attribute,
ImageId=image_id, Attribute='fake')
self.assertRaises('AuthFailure',
self.client.reset_image_attribute,
ImageId=image_id, Attribute='launchPermission')
self.assertRaises('AuthFailure',
self.client.deregister_image,
ImageId=image_id)
@decorators.idempotent_id('a948dad1-9128-446b-86ee-82db13342054')
@testtools.skipUnless(CONF.aws.image_id, 'image id is not defined')
def test_create_image_from_non_ebs_instance(self):
image_id = CONF.aws.image_id
data = self.client.describe_images(ImageIds=[image_id])
image = data['Images'][0]
if 'RootDeviceType' in image and 'ebs' in image['RootDeviceType']:
raise self.skipException('image_id should not be EBS image.')
instance_id = self.run_instance(ImageId=image_id)
def _rollback(fn_data):
self.client.deregister_image(ImageId=fn_data['ImageId'])
self.assertRaises('InvalidParameterValue',
self.client.create_image, rollback_fn=_rollback,
InstanceId=instance_id, Name='name', Description='desc')
data = self.client.terminate_instances(InstanceIds=[instance_id])
self.get_instance_waiter().wait_delete(instance_id)
def _create_image(self, name, desc, extra_run_instance_args={}):
image_id = CONF.aws.ebs_image_id
data = self.client.describe_images(ImageIds=[image_id])
image = data['Images'][0]
self.assertTrue('RootDeviceType' in image
and 'ebs' in image['RootDeviceType'])
instance_id = self.run_instance(ImageId=image_id,
**extra_run_instance_args)
instance = self.get_instance(instance_id)
for bdm in instance.get('BlockDeviceMappings', []):
if 'Ebs' in bdm:
self.addResourceCleanUp(self.client.delete_volume,
VolumeId=bdm['Ebs']['VolumeId'])
data = self.client.create_image(InstanceId=instance_id,
Name=name, Description=desc)
image_id = data['ImageId']
image_clean = self.addResourceCleanUp(self.client.deregister_image,
ImageId=image_id)
self.get_image_waiter().wait_available(image_id)
data = self.client.describe_images(ImageIds=[image_id])
for bdm in data['Images'][0].get('BlockDeviceMappings', []):
if 'Ebs' in bdm and 'SnapshotId' in bdm['Ebs']:
snapshot_id = bdm['Ebs']['SnapshotId']
self.addResourceCleanUp(self.client.delete_snapshot,
SnapshotId=snapshot_id)
data = self.client.terminate_instances(InstanceIds=[instance_id])
self.get_instance_waiter().wait_delete(instance_id)
return image_id, image_clean
@decorators.idempotent_id('f4fbb311-8a59-443d-a60a-11779917c757')
@testtools.skipUnless(CONF.aws.ebs_image_id, "EBS image id is not defined")
def test_create_image_from_ebs_instance(self):
name = data_utils.rand_name('image')
desc = data_utils.rand_name('description')
image_id, image_clean = self._create_image(name, desc)
data = self.client.describe_images(ImageIds=[image_id])
self.assertEqual(1, len(data['Images']))
image = data['Images'][0]
self.assertIsNotNone(image['CreationDate'])
self.assertEqual("ebs", image['RootDeviceType'])
self.assertFalse(image['Public'])
self.assertEqual(name, image['Name'])
self.assertEqual(desc, image['Description'])
self.assertEqual('machine', image['ImageType'])
self.assertNotEmpty(image['BlockDeviceMappings'])
for bdm in image['BlockDeviceMappings']:
self.assertIn('DeviceName', bdm)
data = self.client.deregister_image(ImageId=image_id)
self.cancelResourceCleanUp(image_clean)
@decorators.idempotent_id('b9aba1f7-0a7e-4717-b879-efe3bbea74e2')
@testtools.skipUnless(CONF.aws.ebs_image_id, "EBS image id is not defined")
def test_check_simple_image_attributes(self):
data = self.client.describe_images(ImageIds=[CONF.aws.ebs_image_id])
base_image = data['Images'][0]
name = data_utils.rand_name('image')
desc = data_utils.rand_name('desc for image')
image_id, image_clean = self._create_image(name, desc)
data = self.client.describe_image_attribute(
ImageId=image_id, Attribute='kernel')
if 'KernelId' in base_image:
self.assertIn('KernelId', data)
else:
self.assertNotIn('KernelId', data)
data = self.client.describe_image_attribute(
ImageId=image_id, Attribute='ramdisk')
if 'RamdiskId' in base_image:
self.assertIn('RamdiskId', data)
else:
self.assertNotIn('RamdiskId', data)
# description
data = self.client.describe_image_attribute(
ImageId=image_id, Attribute='description')
self.assertIn('Description', data)
self.assertIn('Value', data['Description'])
self.assertEqual(desc, data['Description']['Value'])
def _modify_description(**kwargs):
self.client.modify_image_attribute(ImageId=image_id, **kwargs)
data = self.client.describe_image_attribute(
ImageId=image_id, Attribute='description')
self.assertEqual(new_desc, data['Description']['Value'])
new_desc = data_utils.rand_name('new desc')
_modify_description(Attribute='description', Value=new_desc)
_modify_description(Description={'Value': new_desc})
data = self.client.deregister_image(ImageId=image_id)
self.cancelResourceCleanUp(image_clean)
@decorators.idempotent_id('680963cf-84f2-488d-bcdb-fc6f9b39f78c')
@testtools.skipUnless(CONF.aws.ebs_image_id, "EBS image id is not defined")
def test_check_bdm_in_image(self):
image_id = CONF.aws.ebs_image_id
data = self.client.describe_images(ImageIds=[image_id])
root_device_name = data['Images'][0]['RootDeviceName']
device_name_prefix = base.get_device_name_prefix(root_device_name)
device_name = device_name_prefix + 'h'
name = data_utils.rand_name('image')
desc = data_utils.rand_name('description')
image_id, image_clean = self._create_image(
name, desc,
extra_run_instance_args={
'BlockDeviceMappings': [{'DeviceName': device_name,
'Ebs': {'VolumeSize': 1}}]})
data = self.client.describe_images(ImageIds=[image_id])
image = data['Images'][0]
for bdm in image['BlockDeviceMappings']:
self.assertTrue('DeviceName', bdm)
data = self.client.deregister_image(ImageId=image_id)
self.cancelResourceCleanUp(image_clean)
@decorators.idempotent_id('1c244c9a-af3e-47f0-bc85-034e24b051e4')
@testtools.skipUnless(CONF.aws.run_incompatible_tests,
'By default glance is configured as "publicize_image": "role:admin"')
@testtools.skipUnless(CONF.aws.run_incompatible_tests,
'skip due to bug #1439819')
@testtools.skipUnless(CONF.aws.ebs_image_id, "EBS image id is not defined")
def test_check_launch_permission_attribute(self):
name = data_utils.rand_name('image')
desc = data_utils.rand_name('desc for image')
image_id, image_clean = self._create_image(name, desc)
# launch permission
data = self.client.describe_image_attribute(
ImageId=image_id, Attribute='launchPermission')
self.assertIn('LaunchPermissions', data)
self.assertEmpty(data['LaunchPermissions'])
def _modify_launch_permission(**kwargs):
self.client.modify_image_attribute(ImageId=image_id, **kwargs)
data = self.client.describe_image_attribute(
ImageId=image_id, Attribute='launchPermission')
self.assertIn('LaunchPermissions', data)
self.assertNotEmpty(data['LaunchPermissions'])
self.assertIn('Group', data['LaunchPermissions'][0])
self.assertEqual('all', data['LaunchPermissions'][0]['Group'])
data = self.client.describe_images(ImageIds=[image_id])
self.assertTrue(data['Images'][0]['Public'])
self.client.reset_image_attribute(
ImageId=image_id, Attribute='launchPermission')
data = self.client.describe_image_attribute(
ImageId=image_id, Attribute='launchPermission')
self.assertEmpty(data['LaunchPermissions'])
data = self.client.describe_images(ImageIds=[image_id])
self.assertFalse(data['Images'][0]['Public'])
_modify_launch_permission(Attribute='launchPermission',
OperationType='add', UserGroups=['all'])
_modify_launch_permission(LaunchPermission={'Add': [{'Group': 'all'}]})
data = self.client.deregister_image(ImageId=image_id)
self.cancelResourceCleanUp(image_clean)
class ImageRegisterTest(base.EC2TestCase):
valid_image_state = set(('available', 'pending', 'failed'))
@classmethod
@base.safe_setup
def setUpClass(cls):
super(ImageRegisterTest, cls).setUpClass()
cls.image_location = CONF.aws.ami_image_location
if not cls.image_location:
raise cls.skipException('Image materials are not ready in S3')
@decorators.idempotent_id('3e25269d-c8a2-4438-ab25-c343cb53db79')
def test_register_get_deregister_ami_image(self):
image_name = data_utils.rand_name("ami-name")
data = self.client.register_image(
Name=image_name, ImageLocation=self.image_location)
image_id = data['ImageId']
image_clean = self.addResourceCleanUp(self.client.deregister_image,
ImageId=image_id)
self.assertEqual(image_id[0:3], "ami")
data = self.client.describe_images(ImageIds=[image_id])
self.assertEqual(1, len(data['Images']))
image = data['Images'][0]
self.assertEqual(image_name, image['Name'])
self.assertEqual(image_id, image['ImageId'])
self.assertIn(image['State'], self.valid_image_state)
self.get_image_waiter().wait_available(image_id)
self.client.deregister_image(ImageId=image_id)
self.cancelResourceCleanUp(image_clean)
self.get_image_waiter().wait_delete(image_id)

View File

@ -1,365 +0,0 @@
# Copyright 2014 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import time
from oslo_log import log
from tempest.lib.common.utils import data_utils
from tempest.lib import decorators
import testtools
from ec2api_tempest_plugin import base
from ec2api_tempest_plugin import config
CONF = config.CONF
LOG = log.getLogger(__name__)
class InstanceAttributeTest(base.EC2TestCase):
@decorators.idempotent_id('485107d8-f65f-4441-9558-2ff783e52e22')
@testtools.skipUnless(CONF.aws.ebs_image_id, "EBS image id is not defined")
def test_describe_instance_attributes(self):
instance_id = self.run_instance(ImageId=CONF.aws.ebs_image_id)
data = self.client.describe_instance_attribute(
InstanceId=instance_id, Attribute='blockDeviceMapping')
bdms = data.get('BlockDeviceMappings', [])
self.assertNotEmpty(bdms)
self.assertEqual(1, len(bdms))
self.assertIn('DeviceName', bdms[0])
self.assertIn('Ebs', bdms[0])
data = self.client.describe_instance_attribute(
InstanceId=instance_id, Attribute='disableApiTermination')
self.assertIn('DisableApiTermination', data)
self.assertIn('Value', data['DisableApiTermination'])
self.assertFalse(data['DisableApiTermination']['Value'])
data = self.client.describe_instance_attribute(
InstanceId=instance_id, Attribute='groupSet')
self.assertIn('Groups', data)
self.assertNotEmpty(data['Groups'], data)
self.assertTrue('GroupId' in data['Groups'][0]
or 'GroupName' in data['Groups'][0])
self.assertTrue(data['Groups'][0].get('GroupId')
or data['Groups'][0].get('GroupName'))
data = self.client.describe_instance_attribute(
InstanceId=instance_id, Attribute='instanceType')
self.assertIn('InstanceType', data)
self.assertIn('Value', data['InstanceType'])
self.assertEqual(CONF.aws.instance_type, data['InstanceType']['Value'])
data = self.client.describe_instance_attribute(
InstanceId=instance_id, Attribute='kernel')
self.assertIn('KernelId', data)
data = self.client.describe_instance_attribute(
InstanceId=instance_id, Attribute='ramdisk')
self.assertIn('RamdiskId', data)
data = self.client.describe_instance_attribute(
InstanceId=instance_id, Attribute='rootDeviceName')
self.assertIn('RootDeviceName', data)
self.assertIn('Value', data['RootDeviceName'])
self.assertTrue(data['RootDeviceName']['Value'])
self.client.terminate_instances(InstanceIds=[instance_id])
self.get_instance_waiter().wait_delete(instance_id)
@decorators.idempotent_id('391f6645-d014-42c7-a727-f3a6e7a13a4c')
@testtools.skipUnless(CONF.aws.image_id, "image id is not defined")
def test_disable_api_termination_attribute(self):
instance_id = self.run_instance(DisableApiTermination=True)
res_clean = self.addResourceCleanUp(
self.client.modify_instance_attribute,
InstanceId=instance_id,
DisableApiTermination={'Value': False})
data = self.client.describe_instance_attribute(
InstanceId=instance_id, Attribute='disableApiTermination')
self.assertIn('DisableApiTermination', data)
self.assertIn('Value', data['DisableApiTermination'])
self.assertTrue(data['DisableApiTermination']['Value'])
data = self.client.modify_instance_attribute(InstanceId=instance_id,
Attribute='disableApiTermination', Value='False')
data = self.client.describe_instance_attribute(
InstanceId=instance_id, Attribute='disableApiTermination')
self.assertFalse(data['DisableApiTermination']['Value'])
data = self.client.modify_instance_attribute(InstanceId=instance_id,
Attribute='disableApiTermination', Value='True')
data = self.client.describe_instance_attribute(
InstanceId=instance_id, Attribute='disableApiTermination')
self.assertTrue(data['DisableApiTermination']['Value'])
self.assertRaises('OperationNotPermitted',
self.client.terminate_instances,
InstanceIds=[instance_id])
data = self.client.modify_instance_attribute(InstanceId=instance_id,
DisableApiTermination={'Value': False})
data = self.client.describe_instance_attribute(
InstanceId=instance_id, Attribute='disableApiTermination')
self.assertFalse(data['DisableApiTermination']['Value'])
self.client.terminate_instances(InstanceIds=[instance_id])
self.cancelResourceCleanUp(res_clean)
self.get_instance_waiter().wait_delete(instance_id)
@decorators.idempotent_id('50671a21-99bf-4514-acb0-97617f92e868')
@testtools.skipUnless(CONF.aws.image_id, "image id is not defined")
def test_instance_attributes_negative(self):
instance_id = self.run_instance()
self.assertRaises('InvalidParameterValue',
self.client.describe_instance_attribute,
InstanceId=instance_id, Attribute='fake_attribute')
self.assertRaises('InvalidInstanceID.NotFound',
self.client.describe_instance_attribute,
InstanceId='i-0', Attribute='disableApiTermination')
if base.TesterStateHolder().get_ec2_enabled():
self.assertRaises('InvalidParameterCombination',
self.client.describe_instance_attribute,
InstanceId=instance_id, Attribute='sourceDestCheck')
self.assertRaises('InvalidParameterValue',
self.client.modify_instance_attribute,
InstanceId=instance_id, Attribute='fake_attribute')
self.assertRaises('MissingParameter',
self.client.modify_instance_attribute,
InstanceId=instance_id, Attribute='disableApiTermination')
self.assertRaises('InvalidParameterCombination',
self.client.modify_instance_attribute,
InstanceId=instance_id)
self.assertRaises('InvalidParameterCombination',
self.client.modify_instance_attribute,
InstanceId=instance_id, Attribute='disableApiTermination',
Value='True', DisableApiTermination={'Value': False})
ex_str = ('InvalidParameterCombination'
if base.TesterStateHolder().get_ec2_enabled() else
'InvalidGroup.NotFound')
self.assertRaises(ex_str,
self.client.modify_instance_attribute,
InstanceId=instance_id, Groups=['sg-0'])
if base.TesterStateHolder().get_ec2_enabled():
self.assertRaises('InvalidParameterCombination',
self.client.modify_instance_attribute,
InstanceId=instance_id, Attribute='sourceDestCheck',
Value='False')
self.assertRaises('InvalidParameterValue',
self.client.reset_instance_attribute,
InstanceId=instance_id, Attribute='fake_attribute')
self.assertRaises('InvalidParameterValue',
self.client.reset_instance_attribute,
InstanceId=instance_id, Attribute='disableApiTermination')
self.assertRaises('InvalidParameterValue',
self.client.reset_instance_attribute,
InstanceId='i-0', Attribute='disableApiTermination')
self.assertRaises('InvalidParameterValue',
self.client.reset_instance_attribute,
InstanceId=instance_id, Attribute='groupSet')
self.assertRaises('InvalidParameterValue',
self.client.reset_instance_attribute,
InstanceId=instance_id, Attribute='instanceType')
if base.TesterStateHolder().get_ec2_enabled():
self.assertRaises('InvalidParameterCombination',
self.client.reset_instance_attribute,
InstanceId=instance_id, Attribute='sourceDestCheck')
self.assertRaises('IncorrectInstanceState',
self.client.modify_instance_attribute,
InstanceId=instance_id, Attribute='instanceType',
Value=CONF.aws.instance_type)
self.assertRaises('IncorrectInstanceState',
self.client.modify_instance_attribute,
InstanceId=instance_id,
InstanceType={'Value': CONF.aws.instance_type})
self.client.terminate_instances(InstanceIds=[instance_id])
self.get_instance_waiter().wait_delete(instance_id)
@base.skip_without_vpc()
@decorators.idempotent_id('6fd2c8eb-f7f9-420d-a8ae-5d5af3a49a35')
@testtools.skipUnless(CONF.aws.image_id, "image id is not defined")
def test_attributes_for_multiple_interfaces_negative(self):
vpc_id, subnet_id = self.create_vpc_and_subnet('10.30.0.0/24')
name = data_utils.rand_name('sgName')
desc = data_utils.rand_name('sgDesc')
data = self.client.create_security_group(VpcId=vpc_id, GroupName=name,
Description=desc)
group_id = data['GroupId']
self.addResourceCleanUp(self.client.delete_security_group,
GroupId=group_id)
time.sleep(2)
data = self.client.create_network_interface(SubnetId=subnet_id,
Groups=[group_id])
ni_id2 = data['NetworkInterface']['NetworkInterfaceId']
self.addResourceCleanUp(self.client.delete_network_interface,
NetworkInterfaceId=ni_id2)
self.get_network_interface_waiter().wait_available(ni_id2)
instance_id = self.run_instance(SubnetId=subnet_id)
kwargs = {
'DeviceIndex': 2,
'InstanceId': instance_id,
'NetworkInterfaceId': ni_id2
}
data = self.client.attach_network_interface(*[], **kwargs)
self.assertRaises('InvalidInstanceID',
self.client.describe_instance_attribute,
InstanceId=instance_id, Attribute='groupSet')
self.assertRaises('InvalidInstanceID',
self.client.modify_instance_attribute,
InstanceId=instance_id, Groups=['sg-0'])
self.assertRaises('InvalidInstanceID',
self.client.describe_instance_attribute,
InstanceId=instance_id, Attribute='sourceDestCheck')
self.assertRaises('InvalidInstanceID',
self.client.modify_instance_attribute,
InstanceId=instance_id, SourceDestCheck={'Value': False})
self.assertRaises('InvalidInstanceID',
self.client.reset_instance_attribute,
InstanceId=instance_id, Attribute='sourceDestCheck')
self.client.terminate_instances(InstanceIds=[instance_id])
self.get_instance_waiter().wait_delete(instance_id)
@base.skip_without_vpc()
@decorators.idempotent_id('da26cc0d-6c2d-4638-97f1-1abfae8f00b5')
@testtools.skipUnless(CONF.aws.image_id, "image id is not defined")
def test_group_set_attribute(self):
vpc_id, subnet_id = self.create_vpc_and_subnet('10.30.0.0/24')
instance_id = self.run_instance(SubnetId=subnet_id)
data = self.client.describe_instance_attribute(
InstanceId=instance_id, Attribute='groupSet')
self.assertIn('Groups', data)
self.assertEqual(1, len(data['Groups']))
default_group_id = data['Groups'][0]['GroupId']
name = data_utils.rand_name('sgName')
desc = data_utils.rand_name('sgDesc')
data = self.client.create_security_group(VpcId=vpc_id, GroupName=name,
Description=desc)
group_id = data['GroupId']
self.addResourceCleanUp(self.client.delete_security_group,
GroupId=group_id)
time.sleep(2)
try:
data = self.client.modify_instance_attribute(
InstanceId=instance_id, Groups=[group_id])
data = self.client.describe_instance_attribute(
InstanceId=instance_id, Attribute='groupSet')
self.assertIn('Groups', data)
self.assertEqual(1, len(data['Groups']))
self.assertNotEqual(default_group_id, data['Groups'][0]['GroupId'])
self.assertRaises('DependencyViolation',
self.client.delete_security_group,
GroupId=group_id)
finally:
self.client.modify_instance_attribute(InstanceId=instance_id,
Groups=[default_group_id])
data = self.client.describe_instance_attribute(
InstanceId=instance_id, Attribute='groupSet')
self.assertIn('Groups', data)
self.assertEqual(1, len(data['Groups']))
self.assertEqual(default_group_id, data['Groups'][0]['GroupId'])
self.client.terminate_instances(InstanceIds=[instance_id])
self.get_instance_waiter().wait_delete(instance_id)
@base.skip_without_vpc()
@decorators.idempotent_id('8e7b37b5-1f2d-4c38-b51e-dcd0e726edb3')
@testtools.skipUnless(CONF.aws.image_id, "image id is not defined")
def test_source_dest_check_attribute(self):
vpc_id, subnet_id = self.create_vpc_and_subnet('10.30.0.0/24')
instance_id = self.run_instance(SubnetId=subnet_id)
def do_check(value):
data = self.client.describe_instance_attribute(
InstanceId=instance_id, Attribute='sourceDestCheck')
self.assertIn('SourceDestCheck', data)
self.assertEqual(value, data['SourceDestCheck'].get('Value'))
do_check(True)
self.client.modify_instance_attribute(
InstanceId=instance_id, Attribute='sourceDestCheck',
Value='False')
do_check(False)
self.client.reset_instance_attribute(
InstanceId=instance_id, Attribute='sourceDestCheck')
do_check(True)
self.client.modify_instance_attribute(
InstanceId=instance_id, Attribute='sourceDestCheck',
Value='False')
do_check(False)
self.client.terminate_instances(InstanceIds=[instance_id])
self.get_instance_waiter().wait_delete(instance_id)
@decorators.idempotent_id('a2640ab1-6aaa-4626-9f23-4aba52e3b88a')
@testtools.skipUnless(CONF.aws.ebs_image_id, "EBS image id is not defined")
@testtools.skipUnless(CONF.aws.instance_type_alt,
"Alternative instance type is not defined")
@testtools.skipUnless(CONF.aws.instance_type_alt != CONF.aws.instance_type,
"Alternative instance type is not defined")
def test_instance_type_attribute(self):
instance_id = self.run_instance(ImageId=CONF.aws.ebs_image_id)
self.client.stop_instances(InstanceIds=[instance_id])
self.get_instance_waiter().wait_available(instance_id,
final_set=('stopped'))
instance = self.get_instance(instance_id)
self.assertEqual(CONF.aws.instance_type, instance['InstanceType'])
self.client.modify_instance_attribute(
InstanceId=instance_id, Attribute='instanceType',
Value=CONF.aws.instance_type)
instance = self.get_instance(instance_id)
self.assertEqual(CONF.aws.instance_type, instance['InstanceType'])
self.client.modify_instance_attribute(
InstanceId=instance_id,
InstanceType={'Value': CONF.aws.instance_type_alt})
instance = self.get_instance(instance_id)
self.assertEqual(CONF.aws.instance_type_alt, instance['InstanceType'])
self.client.start_instances(InstanceIds=[instance_id])
self.get_instance_waiter().wait_available(instance_id,
final_set=('running'))
instance = self.get_instance(instance_id)
self.assertEqual(CONF.aws.instance_type_alt, instance['InstanceType'])
self.client.terminate_instances(InstanceIds=[instance_id])
self.get_instance_waiter().wait_delete(instance_id)

View File

@ -1,252 +0,0 @@
# Copyright 2014 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
from oslo_log import log
from tempest.lib.common.utils import data_utils
from tempest.lib import decorators
import testtools
from ec2api_tempest_plugin import base
from ec2api_tempest_plugin import config
CONF = config.CONF
LOG = log.getLogger(__name__)
class InstanceTest(base.EC2TestCase):
@classmethod
@base.safe_setup
def setUpClass(cls):
super(InstanceTest, cls).setUpClass()
if not CONF.aws.image_id:
raise cls.skipException('aws image_id does not provided')
cls.zone = CONF.aws.aws_zone
@decorators.idempotent_id('5604e461-c36a-4fea-84bc-eddfe702ae4f')
def test_create_delete_instance(self):
instance_type = CONF.aws.instance_type
image_id = CONF.aws.image_id
data = self.client.run_instances(
ImageId=image_id, InstanceType=instance_type,
Placement={'AvailabilityZone': self.zone}, MinCount=1, MaxCount=1)
instance_id = data['Instances'][0]['InstanceId']
res_clean = self.addResourceCleanUp(self.client.terminate_instances,
InstanceIds=[instance_id])
self.assertEqual(1, len(data['Instances']))
self.get_instance_waiter().wait_available(instance_id,
final_set=('running'))
data = self.client.describe_instances(InstanceIds=[instance_id])
reservations = data.get('Reservations', [])
self.assertNotEmpty(reservations)
instances = reservations[0].get('Instances', [])
self.assertEqual(1, len(instances))
self.assertEqual(1, len(instances[0]['SecurityGroups']))
groups = reservations[0].get('Groups', [])
if base.TesterStateHolder().get_ec2_enabled():
self.assertEqual(1, len(groups))
self.assertEqual(groups[0]['GroupName'],
instances[0]['SecurityGroups'][0]['GroupName'])
else:
self.assertEqual(0, len(groups))
self.client.terminate_instances(InstanceIds=[instance_id])
self.cancelResourceCleanUp(res_clean)
self.get_instance_waiter().wait_delete(instance_id)
# NOTE(andrey-mp): There is difference between Openstack and Amazon.
# Amazon returns instance in 'terminated' state some time after
# instance deletion. But Openstack doesn't return such instance.
@decorators.idempotent_id('40b273e5-3d43-4529-99b0-da5dd7e6764e')
def test_create_idempotent_instance(self):
client_token = data_utils.rand_name('t')
instance_type = CONF.aws.instance_type
image_id = CONF.aws.image_id
data = self.client.run_instances(
ImageId=image_id, InstanceType=instance_type,
Placement={'AvailabilityZone': self.zone}, MinCount=1, MaxCount=1,
ClientToken=client_token)
instance_id = data['Instances'][0]['InstanceId']
res_clean = self.addResourceCleanUp(self.client.terminate_instances,
InstanceIds=[instance_id])
self.assertEqual(1, len(data['Instances']))
reservation_id = data['ReservationId']
self.get_instance_waiter().wait_available(instance_id,
final_set=('running'))
data = self.client.run_instances(
ImageId=image_id, InstanceType=instance_type,
Placement={'AvailabilityZone': self.zone}, MinCount=1, MaxCount=1,
ClientToken=client_token)
# NOTE(andrey-mp): if idempotent run will fail this will terminate
# second instance
self.addResourceCleanUp(self.client.terminate_instances,
InstanceIds=[data['Instances'][0]['InstanceId']])
self.assertEqual(1, len(data['Instances']))
self.assertEqual(reservation_id, data['ReservationId'])
self.assertEqual(instance_id, data['Instances'][0]['InstanceId'])
self.client.terminate_instances(InstanceIds=[instance_id])
self.cancelResourceCleanUp(res_clean)
self.get_instance_waiter().wait_delete(instance_id)
@decorators.idempotent_id('4c3c709a-72e2-4c87-bab2-e3a16fc5d1fe')
def test_describe_instances_filter(self):
instance_type = CONF.aws.instance_type
image_id = CONF.aws.image_id
data = self.client.run_instances(
ImageId=image_id, InstanceType=instance_type,
Placement={'AvailabilityZone': self.zone}, MinCount=1, MaxCount=1)
instance_id = data['Instances'][0]['InstanceId']
res_clean = self.addResourceCleanUp(self.client.terminate_instances,
InstanceIds=[instance_id])
self.get_instance_waiter().wait_available(instance_id,
final_set=('running'))
# NOTE(andrey-mp): by real id
data = self.client.describe_instances(InstanceIds=[instance_id])
self._assert_instance(data, instance_id)
instances = data['Reservations'][0]['Instances']
private_dns = instances[0]['PrivateDnsName']
private_ip = instances[0]['PrivateIpAddress']
# NOTE(andrey-mp): by fake id
self.assertRaises('InvalidInstanceID.NotFound',
self.client.describe_instances,
InstanceIds=['i-0'])
# NOTE(andrey-mp): by private ip
data = self.client.describe_instances(
Filters=[{'Name': 'private-ip-address', 'Values': ['1.2.3.4']}])
self.assertEqual(0, len(data['Reservations']))
data = self.client.describe_instances(
Filters=[{'Name': 'private-ip-address', 'Values': [private_ip]}])
self._assert_instance(data, instance_id)
# NOTE(andrey-mp): by private dns
data = self.client.describe_instances(
Filters=[{'Name': 'private-dns-name', 'Values': ['fake.com']}])
self.assertEqual(0, len(data['Reservations']))
data = self.client.describe_instances(
Filters=[{'Name': 'private-dns-name', 'Values': [private_dns]}])
self._assert_instance(data, instance_id)
self.client.terminate_instances(InstanceIds=[instance_id])
self.cancelResourceCleanUp(res_clean)
self.get_instance_waiter().wait_delete(instance_id)
def _assert_instance(self, data, instance_id):
reservations = data.get('Reservations', [])
self.assertNotEmpty(reservations)
instances = reservations[0].get('Instances', [])
self.assertNotEmpty(instances)
self.assertEqual(instance_id, instances[0]['InstanceId'])
@decorators.idempotent_id('d40bf881-4220-46a9-b04a-fca9054c9731')
def test_get_password_data_and_console_output(self):
instance_type = CONF.aws.instance_type
image_id = CONF.aws.image_id
data = self.client.run_instances(
ImageId=image_id, InstanceType=instance_type,
Placement={'AvailabilityZone': self.zone}, MinCount=1, MaxCount=1)
instance_id = data['Instances'][0]['InstanceId']
res_clean = self.addResourceCleanUp(self.client.terminate_instances,
InstanceIds=[instance_id])
self.get_instance_waiter().wait_available(instance_id,
final_set=('running'))
data = self.client.get_password_data(InstanceId=instance_id)
self.assertEqual(instance_id, data['InstanceId'])
self.assertIsNotNone(data['Timestamp'])
self.assertIn('PasswordData', data)
def _wait_for_output(*args, **kwargs):
data = self.client.get_console_output(*args, **kwargs)
self.assertIn('Output', data)
waiter = base.EC2Waiter(_wait_for_output)
waiter.wait_no_exception(InstanceId=instance_id)
data = self.client.get_console_output(InstanceId=instance_id)
self.assertEqual(instance_id, data['InstanceId'])
self.assertIsNotNone(data['Timestamp'])
self.assertIn('Output', data)
self.client.terminate_instances(InstanceIds=[instance_id])
self.cancelResourceCleanUp(res_clean)
self.get_instance_waiter().wait_delete(instance_id)
@decorators.idempotent_id('5947ccaa-a519-46f4-9d58-ceb79042266a')
@testtools.skipUnless(CONF.aws.ebs_image_id, "EBS image id is not defined")
def test_stop_instance(self):
instance_type = CONF.aws.instance_type
image_id = CONF.aws.ebs_image_id
data = self.client.run_instances(
ImageId=image_id, InstanceType=instance_type,
Placement={'AvailabilityZone': self.zone}, MinCount=1, MaxCount=1)
instance_id = data['Instances'][0]['InstanceId']
res_clean = self.addResourceCleanUp(self.client.terminate_instances,
InstanceIds=[instance_id])
self.get_instance_waiter().wait_available(instance_id,
final_set=('running'))
data = self.client.stop_instances(InstanceIds=[instance_id])
if CONF.aws.run_incompatible_tests:
instances = data['StoppingInstances']
self.assertEqual(1, len(instances))
instance = instances[0]
self.assertEqual(instance_id, instance['InstanceId'])
self.assertEqual('running', instance['PreviousState']['Name'])
self.assertEqual('stopping', instance['CurrentState']['Name'])
self.get_instance_waiter().wait_available(instance_id,
final_set=('stopped'))
self.client.terminate_instances(InstanceIds=[instance_id])
self.cancelResourceCleanUp(res_clean)
self.get_instance_waiter().wait_delete(instance_id)
@decorators.idempotent_id('0f29affb-eae5-42be-9b52-d28a17ba7107')
@testtools.skipUnless(CONF.aws.run_incompatible_tests,
"Openstack doesn't assign public ip automatically for new instance")
def test_public_ip_is_assigned(self):
"""Is public IP assigned to launched instnace?"""
instance_type = CONF.aws.instance_type
image_id = CONF.aws.image_id
data = self.client.run_instances(
ImageId=image_id, InstanceType=instance_type,
Placement={'AvailabilityZone': self.zone}, MinCount=1, MaxCount=1)
self.assertEqual(1, len(data['Instances']))
instance_id = data['Instances'][0]['InstanceId']
res_clean = self.addResourceCleanUp(self.client.terminate_instances,
InstanceIds=[instance_id])
self.get_instance_waiter().wait_available(instance_id,
final_set=('running'))
instance = self.get_instance(instance_id)
self.assertIsNotNone(instance.get('PublicIpAddress'))
self.assertIsNotNone(instance.get('PrivateIpAddress'))
self.assertNotEqual(instance.get('PublicIpAddress'),
instance.get('PrivateIpAddress'))
self.client.terminate_instances(InstanceIds=[instance_id])
self.cancelResourceCleanUp(res_clean)
self.get_instance_waiter().wait_delete(instance_id)

View File

@ -1,92 +0,0 @@
# Copyright 2014 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
from oslo_log import log
from tempest.lib import decorators
import testtools
from ec2api_tempest_plugin import base
from ec2api_tempest_plugin import config
CONF = config.CONF
LOG = log.getLogger(__name__)
class InstanceWithEBSTest(base.EC2TestCase):
@decorators.idempotent_id('a5cad848-bed2-4dcb-8ba0-987bb7e9c487')
@testtools.skipUnless(CONF.aws.ebs_image_id, "EBS image id is not defined")
def test_create_get_delete_ebs_instance(self):
"""Launch EBS-backed instance, check results, and terminate it."""
instance_id = self.run_instance(ImageId=CONF.aws.ebs_image_id)
instance = self.get_instance(instance_id)
self.assertEqual('ebs', instance.get('RootDeviceType'))
self.assertIsNotNone(instance.get('RootDeviceName'))
bdms = instance.get('BlockDeviceMappings')
self.assertIsNotNone(bdms)
rdn = instance['RootDeviceName']
bdt = [bdt for bdt in bdms if bdt['DeviceName'] == rdn]
self.assertEqual(1, len(bdt))
ebs = bdt[0]['Ebs']
self.assertIsNotNone(ebs)
volume_id = ebs.get('VolumeId')
self.assertIsNotNone(volume_id)
self.assertEqual('attached', ebs.get('Status'))
if CONF.aws.run_incompatible_tests:
self.assertTrue(ebs.get('AttachTime'))
self.assertTrue(ebs.get('DeleteOnTermination'))
data = self.client.describe_volumes(VolumeIds=[volume_id])
self.assertEqual(1, len(data['Volumes']))
data = self.client.terminate_instances(InstanceIds=[instance_id])
self.get_instance_waiter().wait_delete(instance_id)
@decorators.idempotent_id('b6226b7b-d965-4c3a-b2a8-48add794c194')
@testtools.skipUnless(CONF.aws.ebs_image_id, "EBS image id is not defined")
def test_create_root_volume_snapshot(self):
"""Create snapshot of root volume of EBS-backed instance."""
instance_id = self.run_instance(ImageId=CONF.aws.ebs_image_id)
bdt = self.get_instance_bdm(instance_id, None)
self.assertIsNotNone(bdt)
volume_id = bdt['Ebs'].get('VolumeId')
self.assertIsNotNone(volume_id)
self.client.stop_instances(InstanceIds=[instance_id])
self.get_instance_waiter().wait_available(instance_id,
final_set=('stopped'))
data = self.client.describe_volumes(VolumeIds=[volume_id])
self.assertEqual(1, len(data['Volumes']))
kwargs = {
'VolumeId': data['Volumes'][0]['VolumeId'],
'Description': 'Description'
}
data = self.client.create_snapshot(*[], **kwargs)
snapshot_id = data['SnapshotId']
res_clean_s = self.addResourceCleanUp(self.client.delete_snapshot,
SnapshotId=snapshot_id)
self.get_snapshot_waiter().wait_available(snapshot_id,
final_set=('completed'))
data = self.client.delete_snapshot(SnapshotId=snapshot_id)
self.cancelResourceCleanUp(res_clean_s)
self.get_snapshot_waiter().wait_delete(snapshot_id)
data = self.client.terminate_instances(InstanceIds=[instance_id])
self.get_instance_waiter().wait_delete(instance_id)

View File

@ -1,282 +0,0 @@
# Copyright 2014 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
from oslo_log import log
from tempest.lib import decorators
import testtools
from ec2api_tempest_plugin import base
from ec2api_tempest_plugin import config
CONF = config.CONF
LOG = log.getLogger(__name__)
class InstanceInVPCTest(base.EC2TestCase):
VPC_CIDR = '10.16.0.0/20'
vpc_id = None
SUBNET_CIDR = '10.16.0.0/24'
subnet_id = None
@classmethod
@base.safe_setup
def setUpClass(cls):
super(InstanceInVPCTest, cls).setUpClass()
if not base.TesterStateHolder().get_vpc_enabled():
raise cls.skipException('VPC is disabled')
data = cls.client.create_vpc(CidrBlock=cls.VPC_CIDR)
cls.vpc_id = data['Vpc']['VpcId']
cls.addResourceCleanUpStatic(cls.client.delete_vpc, VpcId=cls.vpc_id)
cls.get_vpc_waiter().wait_available(cls.vpc_id)
aws_zone = CONF.aws.aws_zone
data = cls.client.create_subnet(VpcId=cls.vpc_id,
CidrBlock=cls.SUBNET_CIDR,
AvailabilityZone=aws_zone)
cls.subnet_id = data['Subnet']['SubnetId']
cls.addResourceCleanUpStatic(cls.client.delete_subnet,
SubnetId=cls.subnet_id)
cls.get_subnet_waiter().wait_available(cls.subnet_id)
@decorators.idempotent_id('af8bd493-4a68-49e7-a3d1-326251b8d16e')
@testtools.skipUnless(CONF.aws.image_id, "image id is not defined")
def test_create_delete_instance(self):
instance_id = self.run_instance(SubnetId=self.subnet_id)
data = self.client.describe_instances(InstanceIds=[instance_id])
reservations = data.get('Reservations', [])
self.assertNotEmpty(reservations)
instances = reservations[0].get('Instances', [])
self.assertNotEmpty(instances)
instance = instances[0]
self.assertEqual(self.vpc_id, instance['VpcId'])
self.assertEqual(self.subnet_id, instance['SubnetId'])
self.assertTrue(instance['SourceDestCheck'])
self.assertEqual(1, len(instance['NetworkInterfaces']))
ni = instance['NetworkInterfaces'][0]
self.assertEqual(1, len(ni['Groups']))
self.assertIsNotNone(ni['MacAddress'])
self.assertIsNotNone(ni['PrivateIpAddress'])
self.assertTrue(ni['SourceDestCheck'])
self.assertEqual('in-use', ni['Status'])
self.assertEqual(self.vpc_id, ni['VpcId'])
self.assertEqual(self.subnet_id, ni['SubnetId'])
self.client.terminate_instances(InstanceIds=[instance_id])
self.get_instance_waiter().wait_delete(instance_id)
# NOTE(andrey-mp): There is difference between Openstack and Amazon.
# Amazon returns instance in 'terminated' state some time after
# instance deletion. But Openstack doesn't return such instance.
@decorators.idempotent_id('17ba6206-3044-4e51-9e9b-f5d5728cc047')
@testtools.skipUnless(CONF.aws.image_id, "image id is not defined")
def test_describe_instances_filter(self):
instance_id = self.run_instance(SubnetId=self.subnet_id)
data = self.client.describe_instances(InstanceIds=[instance_id])
self.assert_instance(data, instance_id)
instances = data['Reservations'][0]['Instances']
private_dns = instances[0]['PrivateDnsName']
private_ip = instances[0]['PrivateIpAddress']
# NOTE(andrey-mp): by private ip
data = self.client.describe_instances(
Filters=[{'Name': 'private-ip-address', 'Values': ['1.2.3.4']}])
self.assertEqual(0, len(data['Reservations']))
data = self.client.describe_instances(
Filters=[{'Name': 'private-ip-address', 'Values': [private_ip]}])
self.assert_instance(data, instance_id)
# NOTE(andrey-mp): by private dns
data = self.client.describe_instances(
Filters=[{'Name': 'private-dns-name', 'Values': ['fake.com']}])
self.assertEqual(0, len(data['Reservations']))
data = self.client.describe_instances(
Filters=[{'Name': 'private-dns-name', 'Values': [private_dns]}])
self.assert_instance(data, instance_id)
# NOTE(andrey-mp): by subnet id
data = self.client.describe_instances(
Filters=[{'Name': 'subnet-id', 'Values': ['subnet-0']}])
self.assertEqual(0, len(data['Reservations']))
data = self.client.describe_instances(
Filters=[{'Name': 'subnet-id', 'Values': [self.subnet_id]}])
self.assert_instance(data, instance_id)
# NOTE(andrey-mp): by vpc id
data = self.client.describe_instances(
Filters=[{'Name': 'vpc-id', 'Values': ['vpc-0']}])
self.assertEqual(0, len(data['Reservations']))
data = self.client.describe_instances(
Filters=[{'Name': 'vpc-id', 'Values': [self.vpc_id]}])
self.assert_instance(data, instance_id)
self.client.terminate_instances(InstanceIds=[instance_id])
self.get_instance_waiter().wait_delete(instance_id)
def assert_instance(self, data, instance_id):
reservations = data.get('Reservations', [])
self.assertNotEmpty(reservations)
instances = reservations[0].get('Instances', [])
self.assertNotEmpty(instances)
self.assertEqual(instance_id, instances[0]['InstanceId'])
@decorators.idempotent_id('60ceda8b-85ae-47a7-807b-c4a4dd05a13b')
@testtools.skipUnless(CONF.aws.image_id, "image id is not defined")
def test_create_instance_with_two_interfaces(self):
kwargs = {
'SubnetId': self.subnet_id,
}
data = self.client.create_network_interface(*[], **kwargs)
ni_id1 = data['NetworkInterface']['NetworkInterfaceId']
clean_ni1 = self.addResourceCleanUp(
self.client.delete_network_interface, NetworkInterfaceId=ni_id1)
self.get_network_interface_waiter().wait_available(ni_id1)
kwargs = {
'SubnetId': self.subnet_id,
}
data = self.client.create_network_interface(*[], **kwargs)
ni_id2 = data['NetworkInterface']['NetworkInterfaceId']
clean_ni2 = self.addResourceCleanUp(
self.client.delete_network_interface, NetworkInterfaceId=ni_id2)
self.get_network_interface_waiter().wait_available(ni_id2)
instance_id = self.run_instance(
NetworkInterfaces=[{'NetworkInterfaceId': ni_id1,
'DeviceIndex': 0},
{'NetworkInterfaceId': ni_id2,
'DeviceIndex': 2}])
instance = self.get_instance(instance_id)
nis = instance.get('NetworkInterfaces', [])
self.assertEqual(2, len(nis))
self.client.terminate_instances(InstanceIds=[instance_id])
self.get_instance_waiter().wait_delete(instance_id)
self.get_network_interface_waiter().wait_available(ni_id1)
self.get_network_interface_waiter().wait_available(ni_id2)
self.client.delete_network_interface(
NetworkInterfaceId=ni_id2)
self.cancelResourceCleanUp(clean_ni2)
self.get_network_interface_waiter().wait_delete(ni_id2)
self.client.delete_network_interface(
NetworkInterfaceId=ni_id1)
self.cancelResourceCleanUp(clean_ni1)
self.get_network_interface_waiter().wait_delete(ni_id1)
@decorators.idempotent_id('a7dc520a-e828-4347-91e1-385c4e0e6070')
@testtools.skipUnless(CONF.aws.image_id, "image id is not defined")
def test_create_instance_with_private_ip(self):
ip = '10.16.0.12'
instance_id = self.run_instance(SubnetId=self.subnet_id,
PrivateIpAddress=ip)
instance = self.get_instance(instance_id)
self.assertEqual(ip, instance['PrivateIpAddress'])
self.client.terminate_instances(InstanceIds=[instance_id])
self.get_instance_waiter().wait_delete(instance_id)
@decorators.idempotent_id('582ac8ed-58e7-4f27-bd65-35b999241c63')
@testtools.skipUnless(CONF.aws.image_id, "image id is not defined")
def test_create_instance_with_invalid_params(self):
def _rollback(fn_data):
self.client.terminate_instances(
InstanceIds=[fn_data['Instances'][0]['InstanceId']])
kwargs = {
'ImageId': CONF.aws.image_id,
'InstanceType': CONF.aws.instance_type,
'MinCount': 1,
'MaxCount': 1,
'PrivateIpAddress': '10.16.1.2'
}
ex_str = ('InvalidParameterCombination'
if base.TesterStateHolder().get_ec2_enabled() else
'InvalidParameterValue')
self.assertRaises(ex_str,
self.client.run_instances, rollback_fn=_rollback,
**kwargs)
kwargs = {
'ImageId': CONF.aws.image_id,
'InstanceType': CONF.aws.instance_type,
'MinCount': 1,
'MaxCount': 1,
'SubnetId': self.subnet_id,
'PrivateIpAddress': '10.16.1.12'
}
self.assertRaises('InvalidParameterValue',
self.client.run_instances, rollback_fn=_rollback,
**kwargs)
kwargs = {
'SubnetId': self.subnet_id,
}
data = self.client.create_network_interface(*[], **kwargs)
ni_id1 = data['NetworkInterface']['NetworkInterfaceId']
self.addResourceCleanUp(self.client.delete_network_interface,
NetworkInterfaceId=ni_id1)
self.get_network_interface_waiter().wait_available(ni_id1)
kwargs = {
'SubnetId': self.subnet_id,
}
data = self.client.create_network_interface(*[], **kwargs)
ni_id2 = data['NetworkInterface']['NetworkInterfaceId']
self.addResourceCleanUp(self.client.delete_network_interface,
NetworkInterfaceId=ni_id2)
self.get_network_interface_waiter().wait_available(ni_id2)
# NOTE(andrey-mp): A network interface may not specify a network
# interface ID and delete on termination as true
kwargs = {
'ImageId': CONF.aws.image_id,
'InstanceType': CONF.aws.instance_type,
'MinCount': 1,
'MaxCount': 1,
'NetworkInterfaces': [{'NetworkInterfaceId': ni_id1,
'DeviceIndex': 0,
'DeleteOnTermination': True}]
}
self.assertRaises('InvalidParameterCombination',
self.client.run_instances, rollback_fn=_rollback,
**kwargs)
if CONF.aws.run_incompatible_tests:
# NOTE(andrey-mp): Each network interface requires a device index.
kwargs = {
'ImageId': CONF.aws.image_id,
'InstanceType': CONF.aws.instance_type,
'MinCount': 1,
'MaxCount': 1,
'NetworkInterfaces': [{'NetworkInterfaceId': ni_id1},
{'NetworkInterfaceId': ni_id2}]
}
self.assertRaises('InvalidParameterValue',
self.client.run_instances, rollback_fn=_rollback,
**kwargs)

View File

@ -1,223 +0,0 @@
# Copyright 2014 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import time
from oslo_log import log
from tempest.lib import decorators
import testtools
from ec2api_tempest_plugin import base
from ec2api_tempest_plugin import config
CONF = config.CONF
LOG = log.getLogger(__name__)
class InternetGatewayTest(base.EC2TestCase):
VPC_CIDR = '10.4.0.0/20'
VPC_CIDR_ALT = '10.5.0.0/20'
vpc_id = None
vpc_id_alt = None
@classmethod
@base.safe_setup
def setUpClass(cls):
super(InternetGatewayTest, cls).setUpClass()
if not base.TesterStateHolder().get_vpc_enabled():
raise cls.skipException('VPC is disabled')
data = cls.client.create_vpc(CidrBlock=cls.VPC_CIDR)
cls.vpc_id = data['Vpc']['VpcId']
cls.get_vpc_waiter().wait_available(cls.vpc_id)
cls.addResourceCleanUpStatic(cls.client.delete_vpc, VpcId=cls.vpc_id)
data = cls.client.create_vpc(CidrBlock=cls.VPC_CIDR_ALT)
cls.vpc_id_alt = data['Vpc']['VpcId']
cls.get_vpc_waiter().wait_available(cls.vpc_id_alt)
cls.addResourceCleanUpStatic(cls.client.delete_vpc,
VpcId=cls.vpc_id_alt)
@decorators.idempotent_id('f2d40306-4b18-4e17-90a5-371db0ddc7cb')
def test_create_attach_internet_gateway(self):
data = self.client.create_internet_gateway()
gw_id = data['InternetGateway']['InternetGatewayId']
res_clean = self.addResourceCleanUp(
self.client.delete_internet_gateway, InternetGatewayId=gw_id)
self.assertEmpty(data['InternetGateway'].get('Attachments', []))
data = self.client.attach_internet_gateway(VpcId=self.vpc_id,
InternetGatewayId=gw_id)
data = self.client.detach_internet_gateway(VpcId=self.vpc_id,
InternetGatewayId=gw_id)
data = self.client.delete_internet_gateway(InternetGatewayId=gw_id)
self.cancelResourceCleanUp(res_clean)
self.assertRaises('InvalidInternetGatewayID.NotFound',
self.client.describe_internet_gateways,
InternetGatewayIds=[gw_id])
@decorators.idempotent_id('f092b63d-9460-4d8f-ba8a-bcd380666033')
def test_delete_attached_internet_gateway(self):
data = self.client.create_internet_gateway()
gw_id = data['InternetGateway']['InternetGatewayId']
res_clean = self.addResourceCleanUp(
self.client.delete_internet_gateway, InternetGatewayId=gw_id)
self.assertEmpty(data['InternetGateway'].get('Attachments', []))
data = self.client.attach_internet_gateway(VpcId=self.vpc_id,
InternetGatewayId=gw_id)
self.assertRaises('DependencyViolation',
self.client.delete_internet_gateway,
InternetGatewayId=gw_id)
data = self.client.detach_internet_gateway(VpcId=self.vpc_id,
InternetGatewayId=gw_id)
data = self.client.delete_internet_gateway(InternetGatewayId=gw_id)
self.cancelResourceCleanUp(res_clean)
@decorators.idempotent_id('89700013-5753-4608-8245-4fc99fbb67ea')
@testtools.skipUnless(CONF.aws.run_incompatible_tests,
"Another error code returned - InvalidParameterValue")
def test_attach_detach_invalid_internet_gateway(self):
gw_id = "gw-1"
self.assertRaises('InvalidInternetGatewayID.NotFound',
self.client.attach_internet_gateway,
VpcId=self.vpc_id, InternetGatewayId=gw_id)
self.assertRaises('InvalidInternetGatewayID.NotFound',
self.client.detach_internet_gateway,
VpcId=self.vpc_id, InternetGatewayId=gw_id)
@decorators.idempotent_id('e3e4d8c4-8f62-43e8-a24d-bfd292b4144c')
def test_double_attach_internet_gateway(self):
data = self.client.create_internet_gateway()
gw_id = data['InternetGateway']['InternetGatewayId']
res_clean = self.addResourceCleanUp(
self.client.delete_internet_gateway, InternetGatewayId=gw_id)
self.assertEmpty(data['InternetGateway'].get('Attachments', []))
data = self.client.attach_internet_gateway(VpcId=self.vpc_id,
InternetGatewayId=gw_id)
self.assertRaises('Resource.AlreadyAssociated',
self.client.attach_internet_gateway,
VpcId=self.vpc_id, InternetGatewayId=gw_id)
data = self.client.detach_internet_gateway(VpcId=self.vpc_id,
InternetGatewayId=gw_id)
data = self.client.delete_internet_gateway(InternetGatewayId=gw_id)
self.cancelResourceCleanUp(res_clean)
@decorators.idempotent_id('d8f3a488-a4ba-4ed5-998c-3dc6f43d6d9e')
def test_attach_one_internet_gateway_to_two_vpcs(self):
data = self.client.create_internet_gateway()
gw_id = data['InternetGateway']['InternetGatewayId']
res_clean = self.addResourceCleanUp(
self.client.delete_internet_gateway, InternetGatewayId=gw_id)
self.assertEmpty(data['InternetGateway'].get('Attachments', []))
data = self.client.attach_internet_gateway(VpcId=self.vpc_id,
InternetGatewayId=gw_id)
self.assertRaises('Resource.AlreadyAssociated',
self.client.attach_internet_gateway,
VpcId=self.vpc_id_alt, InternetGatewayId=gw_id)
data = self.client.detach_internet_gateway(VpcId=self.vpc_id,
InternetGatewayId=gw_id)
data = self.client.delete_internet_gateway(InternetGatewayId=gw_id)
self.cancelResourceCleanUp(res_clean)
@decorators.idempotent_id('b86f338c-613e-4cd7-9742-07c86864b0da')
def test_describe_internet_gateways_base(self):
data = self.client.create_internet_gateway()
gw_id = data['InternetGateway']['InternetGatewayId']
res_clean = self.addResourceCleanUp(
self.client.delete_internet_gateway, InternetGatewayId=gw_id)
self.assertEmpty(data['InternetGateway'].get('Attachments', []))
data = self.client.attach_internet_gateway(VpcId=self.vpc_id,
InternetGatewayId=gw_id)
self.addResourceCleanUp(self.client.detach_internet_gateway,
VpcId=self.vpc_id,
InternetGatewayId=gw_id)
time.sleep(2)
# NOTE(andrey-mp): by real id
data = self.client.describe_internet_gateways(
InternetGatewayIds=[gw_id])
self.assertEqual(1, len(data['InternetGateways']))
# NOTE(andrey-mp): by fake id
self.assertRaises('InvalidInternetGatewayID.NotFound',
self.client.describe_internet_gateways,
InternetGatewayIds=['igw-0'])
data = self.client.detach_internet_gateway(VpcId=self.vpc_id,
InternetGatewayId=gw_id)
data = self.client.delete_internet_gateway(InternetGatewayId=gw_id)
self.cancelResourceCleanUp(res_clean)
@decorators.idempotent_id('3f141c56-9ee6-46bf-9c14-0d922ed8a482')
def test_describe_internet_gateways_filters(self):
# NOTE(andrey-mp): by filter real vpc-id before creation
data = self.client.describe_internet_gateways(
Filters=[{'Name': 'attachment.vpc-id', 'Values': [self.vpc_id]}])
self.assertEqual(0, len(data['InternetGateways']))
data = self.client.create_internet_gateway()
gw_id = data['InternetGateway']['InternetGatewayId']
res_clean = self.addResourceCleanUp(
self.client.delete_internet_gateway, InternetGatewayId=gw_id)
self.assertEmpty(data['InternetGateway'].get('Attachments', []))
data = self.client.attach_internet_gateway(VpcId=self.vpc_id,
InternetGatewayId=gw_id)
self.addResourceCleanUp(self.client.detach_internet_gateway,
VpcId=self.vpc_id,
InternetGatewayId=gw_id)
time.sleep(2)
# NOTE(andrey-mp): by filter real vpc-id
data = self.client.describe_internet_gateways(
Filters=[{'Name': 'attachment.vpc-id', 'Values': [self.vpc_id]}])
self.assertEqual(1, len(data['InternetGateways']))
self.assertEqual(gw_id,
data['InternetGateways'][0]['InternetGatewayId'])
# NOTE(andrey-mp): by filter fake vpc-id
data = self.client.describe_internet_gateways(
Filters=[{'Name': 'attachment.vpc-id', 'Values': ['vpc-0']}])
self.assertEqual(0, len(data['InternetGateways']))
# NOTE(andrey-mp): by fake filter
self.assertRaises('InvalidParameterValue',
self.client.describe_internet_gateways,
Filters=[{'Name': 'fake', 'Values': ['fake']}])
data = self.client.detach_internet_gateway(VpcId=self.vpc_id,
InternetGatewayId=gw_id)
data = self.client.delete_internet_gateway(InternetGatewayId=gw_id)
self.cancelResourceCleanUp(res_clean)

View File

@ -1,149 +0,0 @@
# Copyright 2014 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
from tempest.lib import decorators
import testtools
from ec2api_tempest_plugin import base
from ec2api_tempest_plugin import config
CONF = config.CONF
class KeyPairTest(base.EC2TestCase):
@decorators.idempotent_id('15cfd866-d6bb-473a-9b8a-6420900a5ca3')
def test_create_delete_key_pair(self):
keyName = 'Test key'
data = self.client.create_key_pair(KeyName=keyName)
res_clean = self.addResourceCleanUp(self.client.delete_key_pair,
KeyName=keyName)
self.assertEqual(keyName, data['KeyName'])
self.assertIsNotNone(data.get('KeyFingerprint'))
self.assertGreater(len(data['KeyFingerprint']), 0)
self.assertGreater(len(data.get('KeyMaterial')), 0)
data = self.client.delete_key_pair(KeyName=keyName)
self.cancelResourceCleanUp(res_clean)
@decorators.idempotent_id('05478a51-1505-42a8-8c7d-4fd7e32c467e')
def test_create_duplicate_key_pair(self):
keyName = 'Test key'
self.client.create_key_pair(KeyName=keyName)
res_clean = self.addResourceCleanUp(self.client.delete_key_pair,
KeyName=keyName)
self.assertRaises('InvalidKeyPair.Duplicate',
self.client.create_key_pair,
KeyName=keyName)
self.client.delete_key_pair(KeyName=keyName)
self.cancelResourceCleanUp(res_clean)
@decorators.idempotent_id('43d87b6e-6667-4d19-8c0b-e73901105bb7')
def test_describe_key_pairs(self):
keyName = 'Test key'
data = self.client.create_key_pair(KeyName=keyName)
res_clean = self.addResourceCleanUp(self.client.delete_key_pair,
KeyName=keyName)
self.assertIsNotNone(data.get('KeyFingerprint'))
self.assertGreater(len(data['KeyFingerprint']), 0)
fingerprint = data.get('KeyFingerprint')
data = self.client.describe_key_pairs(KeyNames=[keyName])
self.assertEqual(1, len(data.get('KeyPairs')))
data = data['KeyPairs'][0]
self.assertEqual(keyName, data['KeyName'])
self.assertIsNotNone(data.get('KeyFingerprint'))
self.assertGreater(len(data['KeyFingerprint']), 0)
self.assertIsNone(data.get('KeyMaterial'))
data = self.client.describe_key_pairs(
Filters=[{'Name': 'key-name', 'Values': [keyName]}])
self.assertEqual(1, len(data.get('KeyPairs')))
self.assertEqual(keyName, data['KeyPairs'][0]['KeyName'])
data = self.client.describe_key_pairs(
Filters=[{'Name': 'fingerprint', 'Values': [fingerprint]}])
self.assertEqual(1, len(data.get('KeyPairs')))
self.assertEqual(keyName, data['KeyPairs'][0]['KeyName'])
self.assertRaises('InvalidKeyPair.NotFound',
self.client.describe_key_pairs,
KeyNames=['fake key'])
data = self.client.delete_key_pair(KeyName=keyName)
self.cancelResourceCleanUp(res_clean)
self.assertRaises('InvalidKeyPair.NotFound',
self.client.describe_key_pairs,
KeyNames=[keyName])
# NOTE(andrey-mp): Amazon allows to delete absent key and returns 200
self.client.delete_key_pair(KeyName=keyName)
@decorators.idempotent_id('0e51eec5-3f61-4d8a-89c9-8d098f381682')
def test_import_empty_key_pair(self):
keyName = 'Test key'
publicKey = ''
def _rollback(fn_data):
self.client.delete_key_pair(KeyName=keyName)
self.assertRaises('MissingParameter',
self.client.import_key_pair,
rollback_fn=_rollback,
KeyName=keyName, PublicKeyMaterial=publicKey)
@decorators.idempotent_id('478c17e6-b7ca-4115-bee2-be279bdd0f65')
@testtools.skipUnless(CONF.aws.run_incompatible_tests,
"Different error code")
def test_import_invalid_key_pair(self):
keyName = 'Test key'
publicKey = 'ssh-rsa JUNK test@ubuntu'
def _rollback():
self.client.delete_key_pair(KeyName=keyName)
self.assertRaises('InvalidKey.Format',
self.client.import_key_pair,
rollback_fn=_rollback,
KeyName=keyName, PublicKeyMaterial=publicKey)
@decorators.idempotent_id('eda525d6-144b-4840-b6ba-e18d93e3589f')
def test_import_key_pair(self):
keyName = 'Test key'
publicKey = ("ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCs"
"Ne3/1ILNCqFyfYWDeTKLD6jEXC2OQHLmietMWW+/vd"
"aZq7KZEwO0jhglaFjU1mpqq4Gz5RX156sCTNM9vRbw"
"KAxfsdF9laBYVsex3m3Wmui3uYrKyumsoJn2g9GNnG1P"
"I1mrVjZ61i0GY3khna+wzlTpCCmy5HNlrmbj3XLqBUpip"
"TOXmsnr4sChzC53KCd8LXuwc1i/CZPvF+3XipvAgFSE53pCt"
"LOeB1kYMOBaiUPLQTWXR3JpckqFIQwhIH0zoHlJvZE8hh90"
"XcPojYN56tI0OlrGqojbediJYD0rUsJu4weZpbn8vilb3JuDY+jws"
"snSA8wzBx3A/8y9Pp1B test@ubuntu")
data = self.client.import_key_pair(KeyName=keyName,
PublicKeyMaterial=publicKey)
res_clean = self.addResourceCleanUp(self.client.delete_key_pair,
KeyName=keyName)
self.assertEqual(keyName, data['KeyName'])
self.assertIsNotNone(data.get('KeyFingerprint'))
self.assertGreater(len(data['KeyFingerprint']), 0)
self.assertIsNone(data.get('KeyMaterial'))
self.client.delete_key_pair(KeyName=keyName)
self.cancelResourceCleanUp(res_clean)

View File

@ -1,582 +0,0 @@
# Copyright 2014 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import time
import botocore.exceptions
from oslo_log import log
from tempest.lib.common.utils import data_utils
from tempest.lib import decorators
import testtools
from ec2api_tempest_plugin import base
from ec2api_tempest_plugin import config
CONF = config.CONF
LOG = log.getLogger(__name__)
class NetworkInterfaceTest(base.EC2TestCase):
VPC_CIDR = '10.7.0.0/20'
vpc_id = None
SUBNET_CIDR = '10.7.0.0/28'
subnet_id = None
@classmethod
@base.safe_setup
def setUpClass(cls):
super(NetworkInterfaceTest, cls).setUpClass()
if not base.TesterStateHolder().get_vpc_enabled():
raise cls.skipException('VPC is disabled')
data = cls.client.create_vpc(CidrBlock=cls.VPC_CIDR)
cls.vpc_id = data['Vpc']['VpcId']
cls.addResourceCleanUpStatic(cls.client.delete_vpc, VpcId=cls.vpc_id)
cls.get_vpc_waiter().wait_available(cls.vpc_id)
aws_zone = CONF.aws.aws_zone
data = cls.client.create_subnet(VpcId=cls.vpc_id,
CidrBlock=cls.SUBNET_CIDR,
AvailabilityZone=aws_zone)
cls.subnet_id = data['Subnet']['SubnetId']
cls.addResourceCleanUpStatic(cls.client.delete_subnet,
SubnetId=cls.subnet_id)
cls.get_subnet_waiter().wait_available(cls.subnet_id)
def _wait_assignment(self, ni_id, data):
# NOTE(andrey-mp): Amazon don't do it quickly and there is no way
# to wait this request
time.sleep(5)
@decorators.idempotent_id('d03f49b1-a77e-439b-96e2-5e152b968863')
def test_delete_subnet_with_network_interface(self):
data = self.client.create_subnet(VpcId=self.vpc_id,
CidrBlock='10.7.1.0/28')
subnet_id = data['Subnet']['SubnetId']
res_clean_subnet = self.addResourceCleanUp(self.client.delete_subnet,
SubnetId=subnet_id)
self.get_subnet_waiter().wait_available(subnet_id)
data = self.client.create_network_interface(SubnetId=subnet_id)
ni_id = data['NetworkInterface']['NetworkInterfaceId']
res_clean_ni = self.addResourceCleanUp(
self.client.delete_network_interface, NetworkInterfaceId=ni_id)
self.get_network_interface_waiter().wait_available(ni_id)
time.sleep(2)
self.assertRaises('DependencyViolation',
self.client.delete_subnet,
SubnetId=subnet_id)
self.client.delete_network_interface(NetworkInterfaceId=ni_id)
self.cancelResourceCleanUp(res_clean_ni)
self.get_network_interface_waiter().wait_delete(ni_id)
self.client.delete_subnet(SubnetId=subnet_id)
self.cancelResourceCleanUp(res_clean_subnet)
self.get_subnet_waiter().wait_delete(subnet_id)
@decorators.idempotent_id('e19e450d-5c24-47b1-9814-4a65a78e5a31')
def test_create_network_interface(self):
desc = data_utils.rand_name('ni')
data = self.client.create_network_interface(SubnetId=self.subnet_id,
Description=desc)
ni_id = data['NetworkInterface']['NetworkInterfaceId']
res_clean = self.addResourceCleanUp(
self.client.delete_network_interface, NetworkInterfaceId=ni_id)
ni = data['NetworkInterface']
self.assertEqual(self.vpc_id, ni['VpcId'])
self.assertEqual(self.subnet_id, ni['SubnetId'])
self.assertEqual(desc, ni['Description'])
self.assertNotEmpty(ni.get('Groups'))
self.assertEqual('default', ni['Groups'][0]['GroupName'])
address = ni.get('PrivateIpAddress')
self.assertIsNotNone(address)
addresses = ni.get('PrivateIpAddresses')
self.assertIsNotNone(addresses)
self.assertEqual(1, len(addresses))
self.assertTrue(addresses[0]['Primary'])
self.assertEqual(address, addresses[0]['PrivateIpAddress'])
self.assertIsNotNone(ni.get('MacAddress'))
self.assertIsNotNone(ni.get('OwnerId'))
self.assertIsNotNone(ni.get('RequesterManaged'))
self.assertIsNotNone(ni.get('SourceDestCheck'))
self.get_network_interface_waiter().wait_available(ni_id)
self.client.delete_network_interface(NetworkInterfaceId=ni_id)
self.cancelResourceCleanUp(res_clean)
self.get_network_interface_waiter().wait_delete(ni_id)
self.assertRaises('InvalidNetworkInterfaceID.NotFound',
self.client.describe_network_interfaces,
NetworkInterfaceIds=[ni_id])
# TODO(andrey-mp): add creation with addresses
@decorators.idempotent_id('61e16648-7736-4647-b618-27d3f4f0c9c6')
def test_create_max_network_interface(self):
# NOTE(andrey-mp): wait some time while all ports will be deleted
# for this subnet(that are deleting after previous test)
time.sleep(5)
data = self.client.describe_subnets(SubnetIds=[self.subnet_id])
count_before = data['Subnets'][0]['AvailableIpAddressCount']
addresses = []
while True:
try:
data = self.client.create_network_interface(
SubnetId=self.subnet_id)
except botocore.exceptions.ClientError as e:
error_code = e.response['Error']['Code']
self.assertEqual('InsufficientFreeAddressesInSubnet',
error_code)
break
ni_id = data['NetworkInterface']['NetworkInterfaceId']
res_clean = self.addResourceCleanUp(
self.client.delete_network_interface,
NetworkInterfaceId=ni_id)
addresses.append((ni_id, res_clean))
data = self.client.describe_subnets(SubnetIds=[self.subnet_id])
count_after = data['Subnets'][0]['AvailableIpAddressCount']
# NOTE(andrey-mp): This is strange but Amazon can't create last NI
# and Openstack can
self.assertIn(count_after, [0, 1])
self.assertEqual(len(addresses), count_before - count_after)
for addr in addresses:
self.client.delete_network_interface(NetworkInterfaceId=addr[0])
self.cancelResourceCleanUp(addr[1])
self.get_network_interface_waiter().wait_delete(addr[0])
@decorators.idempotent_id('8c174e5f-e377-4bf2-9315-b868a8199c17')
def test_unassign_primary_addresses(self):
data = self.client.create_network_interface(SubnetId=self.subnet_id)
ni_id = data['NetworkInterface']['NetworkInterfaceId']
res_clean = self.addResourceCleanUp(
self.client.delete_network_interface, NetworkInterfaceId=ni_id)
primary_address = data['NetworkInterface'].get('PrivateIpAddress')
self.get_network_interface_waiter().wait_available(ni_id)
self.assertRaises('InvalidParameterValue',
self.client.unassign_private_ip_addresses,
NetworkInterfaceId=ni_id,
PrivateIpAddresses=[primary_address])
self.client.delete_network_interface(NetworkInterfaceId=ni_id)
self.cancelResourceCleanUp(res_clean)
self.get_network_interface_waiter().wait_delete(ni_id)
@decorators.idempotent_id('de0d0375-d99a-476c-939a-0e15c4e431a8')
def test_assign_unassign_private_addresses_by_count(self):
data = self.client.describe_subnets(SubnetIds=[self.subnet_id])
count = data['Subnets'][0]['AvailableIpAddressCount']
data = self.client.create_network_interface(SubnetId=self.subnet_id)
ni_id = data['NetworkInterface']['NetworkInterfaceId']
res_clean = self.addResourceCleanUp(
self.client.delete_network_interface, NetworkInterfaceId=ni_id)
self.get_network_interface_waiter().wait_available(ni_id)
data = self.client.assign_private_ip_addresses(
NetworkInterfaceId=ni_id,
SecondaryPrivateIpAddressCount=2)
self._wait_assignment(ni_id, data)
data = self.client.describe_subnets(SubnetIds=[self.subnet_id])
count_after = data['Subnets'][0]['AvailableIpAddressCount']
self.assertEqual(count - 3, count_after)
data = self.client.describe_network_interfaces(
NetworkInterfaceIds=[ni_id])
addresses = []
for addr in data['NetworkInterfaces'][0]['PrivateIpAddresses']:
if not addr['Primary']:
addresses.append(addr['PrivateIpAddress'])
self.assertEqual(2, len(addresses))
data = self.client.unassign_private_ip_addresses(
NetworkInterfaceId=ni_id,
PrivateIpAddresses=addresses)
self._wait_assignment(ni_id, data)
data = self.client.describe_subnets(SubnetIds=[self.subnet_id])
count_after = data['Subnets'][0]['AvailableIpAddressCount']
self.assertEqual(count - 1, count_after)
self.client.delete_network_interface(NetworkInterfaceId=ni_id)
self.cancelResourceCleanUp(res_clean)
self.get_network_interface_waiter().wait_delete(ni_id)
@decorators.idempotent_id('5d7bda42-d23e-4cbf-9e66-8ca052ac28ff')
def test_assign_unassign_private_addresses_by_addresses(self):
data = self.client.describe_subnets(SubnetIds=[self.subnet_id])
count = data['Subnets'][0]['AvailableIpAddressCount']
data = self.client.create_network_interface(SubnetId=self.subnet_id)
ni_id = data['NetworkInterface']['NetworkInterfaceId']
res_clean = self.addResourceCleanUp(
self.client.delete_network_interface, NetworkInterfaceId=ni_id)
self.get_network_interface_waiter().wait_available(ni_id)
ni = self.client.describe_network_interfaces(
NetworkInterfaceIds=[ni_id])['NetworkInterfaces']
ni_addr = ni[0]['PrivateIpAddresses'][0]['PrivateIpAddress']
# add two more addresses to interface.
# check that they does not equal to current.
addresses = []
for i in range(10, 13):
addr = '10.7.0.%d' % i
if addr != ni_addr:
addresses.append(addr)
if len(addresses) >= 2:
break
data = self.client.assign_private_ip_addresses(
NetworkInterfaceId=ni_id,
PrivateIpAddresses=addresses)
self._wait_assignment(ni_id, data)
data = self.client.describe_subnets(SubnetIds=[self.subnet_id])
count_after = data['Subnets'][0]['AvailableIpAddressCount']
# NOTE(Alex): Amazon misses 1 IP address by some reason.
self.assertIn(count_after, [count - 3, count - 4])
data = self.client.describe_network_interfaces(
NetworkInterfaceIds=[ni_id])
assigned_addresses = []
for addr in data['NetworkInterfaces'][0]['PrivateIpAddresses']:
if not addr['Primary']:
self.assertIn(addr['PrivateIpAddress'], addresses)
assigned_addresses.append(addr['PrivateIpAddress'])
self.assertEqual(2, len(assigned_addresses))
data = self.client.unassign_private_ip_addresses(
NetworkInterfaceId=ni_id,
PrivateIpAddresses=addresses)
self._wait_assignment(ni_id, data)
data = self.client.describe_subnets(SubnetIds=[self.subnet_id])
count_after = data['Subnets'][0]['AvailableIpAddressCount']
self.assertIn(count_after, [count - 1, count - 2])
self.client.delete_network_interface(NetworkInterfaceId=ni_id)
self.cancelResourceCleanUp(res_clean)
self.get_network_interface_waiter().wait_delete(ni_id)
@decorators.idempotent_id('0c514bb4-5800-4db0-9032-0aa3ab998612')
@testtools.skipUnless(CONF.aws.image_id, "image id is not defined")
def test_attach_network_interface(self):
data = self.client.create_network_interface(SubnetId=self.subnet_id)
ni_id = data['NetworkInterface']['NetworkInterfaceId']
self.addResourceCleanUp(self.client.delete_network_interface,
NetworkInterfaceId=ni_id)
ni = data['NetworkInterface']
address = ni.get('PrivateIpAddress')
self.assertIsNotNone(address)
self.get_network_interface_waiter().wait_available(ni_id)
instance_id = self.run_instance(SubnetId=self.subnet_id)
# NOTE(andrey-mp): Amazon can't attach to device index = 0
kwargs = {
'DeviceIndex': 0,
'InstanceId': instance_id,
'NetworkInterfaceId': ni_id
}
self.assertRaises('InvalidParameterValue',
self.client.attach_network_interface,
**kwargs)
kwargs = {
'DeviceIndex': 2,
'InstanceId': instance_id,
'NetworkInterfaceId': ni_id
}
data = self.client.attach_network_interface(*[], **kwargs)
attachment_id = data['AttachmentId']
instance = self.get_instance(instance_id)
nis = instance.get('NetworkInterfaces', [])
self.assertEqual(2, len(nis))
ids = [nis[0]['Attachment']['AttachmentId'],
nis[1]['Attachment']['AttachmentId']]
self.assertIn(attachment_id, ids)
self.assertRaises('InvalidParameterValue',
self.client.delete_network_interface,
NetworkInterfaceId=ni_id)
self.client.detach_network_interface(AttachmentId=attachment_id)
self.client.terminate_instances(InstanceIds=[instance_id])
self.get_instance_waiter().wait_delete(instance_id)
@decorators.idempotent_id('381c9995-bc83-4e7e-b716-25a451660ace')
@testtools.skipUnless(CONF.aws.image_id, "image id is not defined")
def test_network_interfaces_are_not_deleted_on_termination(self):
instance_id = self.run_instance(SubnetId=self.subnet_id)
instance = self.get_instance(instance_id)
nis = instance.get('NetworkInterfaces', [])
self.assertEqual(1, len(nis))
self.assertTrue(nis[0]['Attachment']['DeleteOnTermination'])
ni_id = nis[0]['NetworkInterfaceId']
attachment_id = nis[0]['Attachment']['AttachmentId']
kwargs = {
'NetworkInterfaceId': ni_id,
'Attachment': {
'AttachmentId': attachment_id,
'DeleteOnTermination': False,
}
}
self.client.modify_network_interface_attribute(*[], **kwargs)
clean_ni = self.addResourceCleanUp(
self.client.delete_network_interface, NetworkInterfaceId=ni_id)
data = self.client.create_network_interface(SubnetId=self.subnet_id)
ni_id2 = data['NetworkInterface']['NetworkInterfaceId']
clean_ni2 = self.addResourceCleanUp(
self.client.delete_network_interface, NetworkInterfaceId=ni_id2)
self.get_network_interface_waiter().wait_available(ni_id2)
kwargs = {
'DeviceIndex': 2,
'InstanceId': instance_id,
'NetworkInterfaceId': ni_id2
}
data = self.client.attach_network_interface(*[], **kwargs)
attachment_id = data['AttachmentId']
instance = self.get_instance(instance_id)
nis = instance.get('NetworkInterfaces', [])
self.assertEqual(2, len(nis))
ni = nis[0]
if ni['Attachment']['AttachmentId'] != attachment_id:
ni = nis[1]
self.assertEqual(attachment_id, ni['Attachment']['AttachmentId'])
self.assertFalse(ni['Attachment']['DeleteOnTermination'])
self.client.terminate_instances(InstanceIds=[instance_id])
self.get_instance_waiter().wait_delete(instance_id)
self.get_network_interface_waiter().wait_available(ni_id)
self.get_network_interface_waiter().wait_available(ni_id2)
self.client.delete_network_interface(NetworkInterfaceId=ni_id)
self.cancelResourceCleanUp(clean_ni)
self.get_network_interface_waiter().wait_delete(ni_id)
self.client.delete_network_interface(NetworkInterfaceId=ni_id2)
self.cancelResourceCleanUp(clean_ni2)
self.get_network_interface_waiter().wait_delete(ni_id2)
@decorators.idempotent_id('de910bc7-008a-40c2-b4b2-4587a489fc1c')
@testtools.skipUnless(CONF.aws.image_id, "image id is not defined")
def test_network_interfaces_are_deleted_on_termination(self):
instance_id = self.run_instance(SubnetId=self.subnet_id)
instance = self.get_instance(instance_id)
nis = instance.get('NetworkInterfaces', [])
self.assertEqual(1, len(nis))
self.assertTrue(nis[0]['Attachment']['DeleteOnTermination'])
ni_id = nis[0]['NetworkInterfaceId']
data = self.client.create_network_interface(SubnetId=self.subnet_id)
ni_id2 = data['NetworkInterface']['NetworkInterfaceId']
self.addResourceCleanUp(self.client.delete_network_interface,
NetworkInterfaceId=ni_id2)
self.get_network_interface_waiter().wait_available(ni_id2)
kwargs = {
'DeviceIndex': 2,
'InstanceId': instance_id,
'NetworkInterfaceId': ni_id2
}
data = self.client.attach_network_interface(*[], **kwargs)
attachment_id = data['AttachmentId']
kwargs = {
'NetworkInterfaceId': ni_id2,
'Attachment': {
'AttachmentId': attachment_id,
'DeleteOnTermination': True,
}
}
self.client.modify_network_interface_attribute(*[], **kwargs)
self.client.terminate_instances(InstanceIds=[instance_id])
self.get_instance_waiter().wait_delete(instance_id)
self.get_network_interface_waiter().wait_delete(ni_id)
self.get_network_interface_waiter().wait_delete(ni_id2)
@decorators.idempotent_id('028eb864-59e9-4ed6-a062-9d5de9eba652')
def test_network_interface_attribute_description(self):
desc = data_utils.rand_name('ni')
data = self.client.create_network_interface(
SubnetId=self.subnet_id, Description=desc)
ni_id = data['NetworkInterface']['NetworkInterfaceId']
res_clean = self.addResourceCleanUp(
self.client.delete_network_interface, NetworkInterfaceId=ni_id)
self.get_network_interface_waiter().wait_available(ni_id)
data = self.client.describe_network_interface_attribute(
NetworkInterfaceId=ni_id, Attribute='description')
self.assertEqual(desc, data['Description']['Value'])
new_desc = data_utils.rand_name('new-ni')
self.client.modify_network_interface_attribute(
NetworkInterfaceId=ni_id, Description={'Value': new_desc})
data = self.client.describe_network_interface_attribute(
NetworkInterfaceId=ni_id, Attribute='description')
self.assertEqual(new_desc, data['Description']['Value'])
self.client.delete_network_interface(NetworkInterfaceId=ni_id)
self.cancelResourceCleanUp(res_clean)
self.get_network_interface_waiter().wait_delete(ni_id)
@decorators.idempotent_id('9428b5e6-42f2-495f-a535-df53d1fcf4af')
def test_network_interface_attribute_source_dest_check(self):
data = self.client.create_network_interface(SubnetId=self.subnet_id)
ni_id = data['NetworkInterface']['NetworkInterfaceId']
res_clean = self.addResourceCleanUp(
self.client.delete_network_interface, NetworkInterfaceId=ni_id)
self.get_network_interface_waiter().wait_available(ni_id)
self.client.modify_network_interface_attribute(
NetworkInterfaceId=ni_id, SourceDestCheck={'Value': False})
data = self.client.describe_network_interface_attribute(
NetworkInterfaceId=ni_id, Attribute='sourceDestCheck')
self.assertFalse(data['SourceDestCheck']['Value'])
# NOTE(andrey-mp): ResetNetworkInterfaceAttribute had inadequate json
# scheme in botocore and doesn't work against Amazon.
self.client.modify_network_interface_attribute(
NetworkInterfaceId=ni_id, SourceDestCheck={'Value': True})
data = self.client.describe_network_interface_attribute(
NetworkInterfaceId=ni_id, Attribute='sourceDestCheck')
self.assertEqual(True, data['SourceDestCheck']['Value'])
self.client.delete_network_interface(NetworkInterfaceId=ni_id)
self.cancelResourceCleanUp(res_clean)
self.get_network_interface_waiter().wait_delete(ni_id)
@decorators.idempotent_id('19d25f59-5b32-4314-b4da-7c8f679b7a96')
@testtools.skipUnless(CONF.aws.image_id, "image id is not defined")
def test_network_interface_attribute_attachment(self):
instance_id = self.run_instance(SubnetId=self.subnet_id)
instance = self.get_instance(instance_id)
nis = instance.get('NetworkInterfaces', [])
self.assertEqual(1, len(nis))
self.assertTrue(nis[0]['Attachment']['DeleteOnTermination'])
ni_id = nis[0]['NetworkInterfaceId']
data = self.client.describe_network_interface_attribute(
NetworkInterfaceId=ni_id, Attribute='attachment')
self.assertIn('Attachment', data)
self.assertTrue(data['Attachment'].get('AttachmentId'))
self.assertTrue(data['Attachment'].get('DeleteOnTermination'))
self.assertEqual(0, data['Attachment'].get('DeviceIndex'))
self.assertEqual(instance_id, data['Attachment'].get('InstanceId'))
self.assertEqual('attached', data['Attachment'].get('Status'))
self.client.terminate_instances(InstanceIds=[instance_id])
self.get_instance_waiter().wait_delete(instance_id)
@decorators.idempotent_id('74967cd0-155f-4cfe-994e-2c6803dad04c')
def test_network_interface_attribute_empty_attachment(self):
data = self.client.create_network_interface(SubnetId=self.subnet_id)
ni_id = data['NetworkInterface']['NetworkInterfaceId']
res_clean = self.addResourceCleanUp(
self.client.delete_network_interface, NetworkInterfaceId=ni_id)
self.get_network_interface_waiter().wait_available(ni_id)
data = self.client.describe_network_interface_attribute(
NetworkInterfaceId=ni_id, Attribute='attachment')
self.assertNotIn('Attachment', data)
self.client.delete_network_interface(NetworkInterfaceId=ni_id)
self.cancelResourceCleanUp(res_clean)
self.get_network_interface_waiter().wait_delete(ni_id)
@decorators.idempotent_id('a55f1169-d302-4166-b74e-e84a0d79129c')
def test_network_interface_attribute_group_set(self):
data = self.client.create_network_interface(SubnetId=self.subnet_id)
ni_id = data['NetworkInterface']['NetworkInterfaceId']
res_clean = self.addResourceCleanUp(
self.client.delete_network_interface, NetworkInterfaceId=ni_id)
self.get_network_interface_waiter().wait_available(ni_id)
data = self.client.describe_network_interface_attribute(
NetworkInterfaceId=ni_id, Attribute='groupSet')
self.assertIn('Groups', data)
self.assertEqual(1, len(data['Groups']))
self.assertEqual('default', data['Groups'][0]['GroupName'])
self.client.delete_network_interface(NetworkInterfaceId=ni_id)
self.cancelResourceCleanUp(res_clean)
self.get_network_interface_waiter().wait_delete(ni_id)
@decorators.idempotent_id('7832976f-27cb-405e-ab05-466b102d86f8')
def test_instance_attributes_negative(self):
data = self.client.create_network_interface(SubnetId=self.subnet_id)
ni_id = data['NetworkInterface']['NetworkInterfaceId']
res_clean = self.addResourceCleanUp(
self.client.delete_network_interface, NetworkInterfaceId=ni_id)
self.get_network_interface_waiter().wait_available(ni_id)
self.assertRaises('InvalidParameterCombination',
self.client.describe_network_interface_attribute,
NetworkInterfaceId=ni_id)
self.assertRaises('InvalidParameterValue',
self.client.describe_network_interface_attribute,
NetworkInterfaceId=ni_id, Attribute='fake')
self.assertRaises('InvalidNetworkInterfaceID.NotFound',
self.client.describe_network_interface_attribute,
NetworkInterfaceId='eni-0', Attribute='description')
self.assertRaises('InvalidParameterCombination',
self.client.modify_network_interface_attribute,
NetworkInterfaceId=ni_id)
self.assertRaises('MissingParameter',
self.client.modify_network_interface_attribute,
NetworkInterfaceId=ni_id,
Attachment={'AttachmentId': 'fake'})
self.assertRaises('InvalidAttachmentID.NotFound',
self.client.modify_network_interface_attribute,
NetworkInterfaceId=ni_id,
Attachment={'AttachmentId': 'eni-attach-0',
'DeleteOnTermination': True})
self.assertRaises('InvalidGroup.NotFound',
self.client.modify_network_interface_attribute,
NetworkInterfaceId=ni_id, Groups=['sg-0'])
self.assertRaises('InvalidParameterCombination',
self.client.modify_network_interface_attribute,
NetworkInterfaceId=ni_id, Description={})
self.client.delete_network_interface(NetworkInterfaceId=ni_id)
self.cancelResourceCleanUp(res_clean)
self.get_network_interface_waiter().wait_delete(ni_id)

View File

@ -1,47 +0,0 @@
# Copyright 2014 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
from tempest.lib import decorators
from ec2api_tempest_plugin import base
from ec2api_tempest_plugin import config
CONF = config.CONF
class RegionTest(base.EC2TestCase):
@decorators.idempotent_id('f303e87e-4e5f-4110-a5da-5f690acb44ba')
def test_describe_regions(self):
data = self.client.describe_regions()
self.assertNotEmpty(data['Regions'])
region = CONF.aws.aws_region
if not region:
return
regions = [r['RegionName'] for r in data['Regions']]
self.assertIn(region, regions)
@decorators.idempotent_id('be38f383-4637-4581-bb62-b47c1463f0a1')
def test_describe_zones(self):
data = self.client.describe_availability_zones()
self.assertNotEmpty(data['AvailabilityZones'])
region = CONF.aws.aws_region
if not region:
return
# TODO(andrey-mp): add checking of other fields of returned data

View File

@ -1,338 +0,0 @@
# Copyright 2014 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
from oslo_log import log
from tempest.lib import decorators
from ec2api_tempest_plugin import base
from ec2api_tempest_plugin import config
CONF = config.CONF
LOG = log.getLogger(__name__)
class RouteTest(base.EC2TestCase):
VPC_CIDR = '10.14.0.0/20'
SUBNET_CIDR = '10.14.0.0/24'
vpc_id = None
@classmethod
@base.safe_setup
def setUpClass(cls):
super(RouteTest, cls).setUpClass()
if not base.TesterStateHolder().get_vpc_enabled():
raise cls.skipException('VPC is disabled')
data = cls.client.create_vpc(CidrBlock=cls.VPC_CIDR)
cls.vpc_id = data['Vpc']['VpcId']
cls.addResourceCleanUpStatic(cls.client.delete_vpc, VpcId=cls.vpc_id)
cls.get_vpc_waiter().wait_available(cls.vpc_id)
@decorators.idempotent_id('69c04d14-5603-4a98-9331-739821b98b10')
def test_create_delete_route_table(self):
data = self.client.create_route_table(VpcId=self.vpc_id)
rt_id = data['RouteTable']['RouteTableId']
res_clean = self.addResourceCleanUp(self.client.delete_route_table,
RouteTableId=rt_id)
rt = data['RouteTable']
self.assertEqual(self.vpc_id, rt['VpcId'])
self.assertEqual(1, len(rt['Routes']))
route = rt['Routes'][0]
self.assertEqual(self.VPC_CIDR, route['DestinationCidrBlock'])
self.assertEqual('active', route['State'])
data = self.client.delete_route_table(RouteTableId=rt_id)
self.cancelResourceCleanUp(res_clean)
self.assertRaises('InvalidRouteTableID.NotFound',
self.client.describe_route_tables,
RouteTableIds=[rt_id])
self.assertRaises('InvalidRouteTableID.NotFound',
self.client.delete_route_table,
RouteTableId=rt_id)
@decorators.idempotent_id('d8051b30-eb70-4c4b-988b-56078a125af3')
def test_describe_route_tables_base(self):
data = self.client.create_route_table(VpcId=self.vpc_id)
rt_id = data['RouteTable']['RouteTableId']
res_clean = self.addResourceCleanUp(self.client.delete_route_table,
RouteTableId=rt_id)
# NOTE(andrey-mp): by real id
data = self.client.describe_route_tables(RouteTableIds=[rt_id])
self.assertEqual(1, len(data['RouteTables']))
# NOTE(andrey-mp): by fake id
self.assertRaises('InvalidRouteTableID.NotFound',
self.client.describe_route_tables,
RouteTableIds=['rtb-0'])
data = self.client.delete_route_table(RouteTableId=rt_id)
self.cancelResourceCleanUp(res_clean)
@decorators.idempotent_id('77a53f3e-437a-45ed-b3b5-e6b7ab2c9407')
def test_describe_route_tables_filters(self):
data = self.client.create_route_table(VpcId=self.vpc_id)
rt_id = data['RouteTable']['RouteTableId']
self.addResourceCleanUp(self.client.delete_route_table,
RouteTableId=rt_id)
data = self.client.create_subnet(VpcId=self.vpc_id,
CidrBlock=self.SUBNET_CIDR)
subnet_id = data['Subnet']['SubnetId']
self.addResourceCleanUp(self.client.delete_subnet,
SubnetId=subnet_id)
self.get_subnet_waiter().wait_available(subnet_id)
data = self.client.associate_route_table(RouteTableId=rt_id,
SubnetId=subnet_id)
assoc_id = data['AssociationId']
self.addResourceCleanUp(self.client.disassociate_route_table,
AssociationId=assoc_id)
# NOTE(andrey-mp): by association_id
data = self.client.describe_route_tables(
Filters=[{'Name': 'association.route-table-association-id',
'Values': [assoc_id]}])
self.assertEqual(1, len(data['RouteTables']))
# NOTE(andrey-mp): by route table id
data = self.client.describe_route_tables(
Filters=[{'Name': 'association.route-table-id',
'Values': [rt_id]}])
self.assertEqual(1, len(data['RouteTables']))
# NOTE(andrey-mp): by subnet id
data = self.client.describe_route_tables(
Filters=[{'Name': 'association.subnet-id',
'Values': [subnet_id]}])
self.assertEqual(1, len(data['RouteTables']))
# NOTE(andrey-mp): by filter real vpc
data = self.client.describe_route_tables(
Filters=[{'Name': 'vpc-id', 'Values': [self.vpc_id]}])
self.assertLess(0, len(data['RouteTables']))
# NOTE(andrey-mp): by filter fake vpc
data = self.client.describe_route_tables(
Filters=[{'Name': 'vpc-id', 'Values': ['vpc-0']}])
self.assertEqual(0, len(data['RouteTables']))
# NOTE(andrey-mp): by fake filter
self.assertRaises('InvalidParameterValue',
self.client.describe_route_tables,
Filters=[{'Name': 'fake', 'Values': ['fake']}])
@decorators.idempotent_id('55361f57-331a-43b8-8729-efee2d1c0dc9')
def test_associate_disassociate_route_table(self):
data = self.client.create_route_table(VpcId=self.vpc_id)
rt_id = data['RouteTable']['RouteTableId']
res_clean_rt = self.addResourceCleanUp(self.client.delete_route_table,
RouteTableId=rt_id)
data = self.client.create_subnet(VpcId=self.vpc_id,
CidrBlock=self.SUBNET_CIDR)
subnet_id = data['Subnet']['SubnetId']
res_clean_subnet = self.addResourceCleanUp(self.client.delete_subnet,
SubnetId=subnet_id)
self.get_subnet_waiter().wait_available(subnet_id)
data = self.client.associate_route_table(RouteTableId=rt_id,
SubnetId=subnet_id)
assoc_id = data['AssociationId']
res_clean = self.addResourceCleanUp(
self.client.disassociate_route_table, AssociationId=assoc_id)
data = self.client.disassociate_route_table(AssociationId=assoc_id)
self.cancelResourceCleanUp(res_clean)
data = self.client.delete_subnet(SubnetId=subnet_id)
self.cancelResourceCleanUp(res_clean_subnet)
self.get_subnet_waiter().wait_delete(subnet_id)
data = self.client.delete_route_table(RouteTableId=rt_id)
self.cancelResourceCleanUp(res_clean_rt)
@decorators.idempotent_id('b1a07211-6e9a-41db-8017-47e7c4b9c043')
def test_replace_route_table(self):
data = self.client.create_subnet(VpcId=self.vpc_id,
CidrBlock=self.SUBNET_CIDR)
subnet_id = data['Subnet']['SubnetId']
res_clean_subnet = self.addResourceCleanUp(self.client.delete_subnet,
SubnetId=subnet_id)
self.get_subnet_waiter().wait_available(subnet_id)
# NOTE(andrey-mp): by vpc id
data = self.client.describe_route_tables(
Filters=[{'Name': 'vpc-id', 'Values': [self.vpc_id]}])
self.assertEqual(1, len(data['RouteTables']))
self.assertEqual(1, len(data['RouteTables'][0]['Associations']))
default_rt_id = data['RouteTables'][0]['RouteTableId']
main_assoc = data['RouteTables'][0]['Associations'][0]
self.assertTrue(main_assoc['Main'])
main_assoc_id = main_assoc['RouteTableAssociationId']
data = self.client.create_route_table(VpcId=self.vpc_id)
rt_id = data['RouteTable']['RouteTableId']
res_clean_rt = self.addResourceCleanUp(self.client.delete_route_table,
RouteTableId=rt_id)
data = self.client.replace_route_table_association(
RouteTableId=rt_id, AssociationId=main_assoc_id)
assoc_id = data['NewAssociationId']
res_clean = self.addResourceCleanUp(
self.client.replace_route_table_association,
RouteTableId=default_rt_id,
AssociationId=assoc_id)
# NOTE(andrey-mp): by vpc id
data = self.client.describe_route_tables(
Filters=[{'Name': 'vpc-id', 'Values': [self.vpc_id]}])
self.assertEqual(2, len(data['RouteTables']))
for rt in data['RouteTables']:
if rt['RouteTableId'] == rt_id:
self.assertEqual(1, len(rt['Associations']))
self.assertTrue(rt['Associations'][0]['Main'])
else:
self.assertEmpty(rt.get('Associations', []))
self.assertRaises('DependencyViolation',
self.client.delete_route_table,
RouteTableId=rt_id)
self.assertRaises('InvalidParameterValue',
self.client.disassociate_route_table,
AssociationId=assoc_id)
data = self.client.replace_route_table_association(
RouteTableId=default_rt_id,
AssociationId=assoc_id)
self.cancelResourceCleanUp(res_clean)
data = self.client.delete_route_table(RouteTableId=rt_id)
self.cancelResourceCleanUp(res_clean_rt)
data = self.client.delete_subnet(SubnetId=subnet_id)
self.cancelResourceCleanUp(res_clean_subnet)
self.get_subnet_waiter().wait_delete(subnet_id)
@decorators.idempotent_id('c112ecdb-dce3-4497-b11b-5349a2d89336')
def test_create_delete_route(self):
data = self.client.create_subnet(VpcId=self.vpc_id,
CidrBlock=self.SUBNET_CIDR)
subnet_id = data['Subnet']['SubnetId']
res_clean_subnet = self.addResourceCleanUp(self.client.delete_subnet,
SubnetId=subnet_id)
self.get_subnet_waiter().wait_available(subnet_id)
kwargs = {
'SubnetId': subnet_id,
}
data = self.client.create_network_interface(*[], **kwargs)
ni_id = data['NetworkInterface']['NetworkInterfaceId']
res_clean_ni = self.addResourceCleanUp(
self.client.delete_network_interface,
NetworkInterfaceId=ni_id)
data = self.client.create_route_table(VpcId=self.vpc_id)
rt_id = data['RouteTable']['RouteTableId']
res_clean_rt = self.addResourceCleanUp(self.client.delete_route_table,
RouteTableId=rt_id)
kwargs = {
'DestinationCidrBlock': self.VPC_CIDR,
'RouteTableId': rt_id,
'NetworkInterfaceId': ni_id
}
self.assertRaises('InvalidParameterValue',
self.client.create_route,
**kwargs)
# can create wider route
kwargs = {
'DestinationCidrBlock': '10.14.0.0/19',
'RouteTableId': rt_id,
'NetworkInterfaceId': ni_id
}
data = self.client.create_route(*[], **kwargs)
# can create to another vpc
kwargs = {
'DestinationCidrBlock': '10.15.0.0/20',
'RouteTableId': rt_id,
'NetworkInterfaceId': ni_id
}
data = self.client.create_route(*[], **kwargs)
data = self.client.describe_route_tables(RouteTableIds=[rt_id])
self.assertEqual(1, len(data['RouteTables']))
self.assertEqual(3, len(data['RouteTables'][0]['Routes']))
kwargs = {
'DestinationCidrBlock': '10.15.0.0/24',
'RouteTableId': rt_id,
}
self.assertRaises('InvalidRoute.NotFound',
self.client.delete_route,
**kwargs)
kwargs = {
'DestinationCidrBlock': self.VPC_CIDR,
'RouteTableId': rt_id,
}
self.assertRaises('InvalidParameterValue',
self.client.delete_route,
**kwargs)
kwargs = {
'DestinationCidrBlock': self.SUBNET_CIDR,
'RouteTableId': rt_id,
}
self.assertRaises('InvalidRoute.NotFound',
self.client.delete_route,
**kwargs)
kwargs = {
'DestinationCidrBlock': '10.16.0.0/24',
'RouteTableId': rt_id,
}
self.assertRaises('InvalidRoute.NotFound',
self.client.delete_route,
**kwargs)
kwargs = {
'DestinationCidrBlock': '10.15.0.0/20',
'RouteTableId': rt_id,
}
data = self.client.delete_route(*[], **kwargs)
kwargs = {
'DestinationCidrBlock': '10.14.0.0/19',
'RouteTableId': rt_id,
}
data = self.client.delete_route(*[], **kwargs)
data = self.client.delete_route_table(RouteTableId=rt_id)
self.cancelResourceCleanUp(res_clean_rt)
data = self.client.delete_network_interface(
NetworkInterfaceId=ni_id)
self.cancelResourceCleanUp(res_clean_ni)
self.get_network_interface_waiter().wait_delete(ni_id)
data = self.client.delete_subnet(SubnetId=subnet_id)
self.cancelResourceCleanUp(res_clean_subnet)
self.get_subnet_waiter().wait_delete(subnet_id)

View File

@ -1,326 +0,0 @@
# Copyright 2014 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import time
from oslo_log import log
from tempest.lib.common.utils import data_utils
from tempest.lib import decorators
import testtools
from ec2api_tempest_plugin import base
from ec2api_tempest_plugin import config
CONF = config.CONF
LOG = log.getLogger(__name__)
class SecurityGroupBaseTest(base.EC2TestCase):
def _test_rules(self, add_func, del_func, field, vpc_id=None):
kwargs = dict()
if vpc_id:
kwargs['Filters'] = [{'Name': 'vpc-id', 'Values': [vpc_id]}]
data = self.client.describe_security_groups(*[], **kwargs)
security_groups = data['SecurityGroups']
if not vpc_id:
# TODO(andrey-mp): remove it when fitering by None will be
security_groups = [sg for sg in security_groups
if sg.get('VpcId') is None]
default_group = security_groups[0]
name = data_utils.rand_name('sgName')
desc = data_utils.rand_name('sgDesc')
kwargs = {'GroupName': name, 'Description': desc}
if vpc_id:
kwargs['VpcId'] = vpc_id
data = self.client.create_security_group(*[], **kwargs)
group_id = data['GroupId']
res_clean = self.addResourceCleanUp(self.client.delete_security_group,
GroupId=group_id)
time.sleep(2)
data = self.client.describe_security_groups(GroupIds=[group_id])
count = len(data['SecurityGroups'][0][field])
kwargs = {
'GroupId': group_id,
'IpPermissions': [{
'IpProtocol': 'icmp',
'FromPort': -1,
'ToPort': -1,
'IpRanges': [{
'CidrIp': '10.0.0.0/8'
}],
}, {
'UserIdGroupPairs': [{'GroupId': default_group['GroupId']}],
'ToPort': 65535,
'IpProtocol': 'tcp',
'FromPort': 1
}]
}
add_func(*[], **kwargs)
data = self.client.describe_security_groups(GroupIds=[group_id])
self.assertEqual(1, len(data['SecurityGroups']))
self.assertEqual(count + 2, len(data['SecurityGroups'][0][field]))
found = 0
for perm in data['SecurityGroups'][0][field]:
cidrs = [v['CidrIp'] for v in perm.get('IpRanges', [])]
if (perm.get('FromPort') == -1 and
perm.get('ToPort') == -1 and
perm.get('IpProtocol') == 'icmp' and
len(perm.get('IpRanges')) == 1 and
'10.0.0.0/8' in cidrs):
found = found + 1
elif (perm.get('FromPort') == 1 and
perm.get('ToPort') == 65535 and
perm.get('IpProtocol') == 'tcp' and
len(perm.get('UserIdGroupPairs')) == 1 and
perm.get('UserIdGroupPairs')[0]['GroupId']
== default_group['GroupId']):
found = found + 1
self.assertEqual(2, found)
del_func(*[], **kwargs)
data = self.client.describe_security_groups(GroupIds=[group_id])
self.assertEqual(1, len(data['SecurityGroups']))
self.assertEqual(count, len(data['SecurityGroups'][0][field]))
if vpc_id:
self.assertRaises('InvalidPermission.NotFound', del_func, **kwargs)
else:
del_func(*[], **kwargs)
self.client.delete_security_group(GroupId=group_id)
self.cancelResourceCleanUp(res_clean)
class SecurityGroupInVPCTest(SecurityGroupBaseTest):
VPC_CIDR = '10.10.0.0/20'
vpc_id = None
@classmethod
@base.safe_setup
def setUpClass(cls):
super(SecurityGroupInVPCTest, cls).setUpClass()
if not base.TesterStateHolder().get_vpc_enabled():
raise cls.skipException('VPC is disabled')
data = cls.client.create_vpc(CidrBlock=cls.VPC_CIDR)
cls.vpc_id = data['Vpc']['VpcId']
cls.addResourceCleanUpStatic(cls.client.delete_vpc, VpcId=cls.vpc_id)
cls.get_vpc_waiter().wait_available(cls.vpc_id)
@decorators.idempotent_id('f8354908-1b3a-4e7b-89e3-6956850bbbfb')
def test_create_delete_security_group(self):
name = data_utils.rand_name('sgName')
desc = data_utils.rand_name('sgDesc')
data = self.client.create_security_group(VpcId=self.vpc_id,
GroupName=name,
Description=desc)
group_id = data['GroupId']
res_clean = self.addResourceCleanUp(self.client.delete_security_group,
GroupId=group_id)
time.sleep(2)
self.client.delete_security_group(GroupId=group_id)
self.cancelResourceCleanUp(res_clean)
self.assertRaises('InvalidGroup.NotFound',
self.client.describe_security_groups,
GroupIds=[group_id])
self.assertRaises('InvalidGroup.NotFound',
self.client.delete_security_group,
GroupId=group_id)
@decorators.idempotent_id('fe209503-c348-4456-94b4-a77e68fabcbb')
def test_create_duplicate_security_group(self):
name = data_utils.rand_name('sgName')
desc = data_utils.rand_name('sgDesc')
data = self.client.create_security_group(VpcId=self.vpc_id,
GroupName=name,
Description=desc)
group_id = data['GroupId']
res_clean = self.addResourceCleanUp(self.client.delete_security_group,
GroupId=group_id)
time.sleep(2)
self.assertRaises('InvalidGroup.Duplicate',
self.client.create_security_group,
VpcId=self.vpc_id, GroupName=name, Description=desc)
data = self.client.delete_security_group(GroupId=group_id)
self.cancelResourceCleanUp(res_clean)
@decorators.idempotent_id('ffe5084a-2d05-42d1-ae8d-edcb0af27909')
def test_create_duplicate_security_group_in_another_vpc(self):
name = data_utils.rand_name('sgName')
desc = data_utils.rand_name('sgDesc')
data = self.client.create_security_group(VpcId=self.vpc_id,
GroupName=name,
Description=desc)
group_id = data['GroupId']
res_clean = self.addResourceCleanUp(self.client.delete_security_group,
GroupId=group_id)
time.sleep(2)
data = self.client.create_vpc(CidrBlock=self.VPC_CIDR)
vpc_id = data['Vpc']['VpcId']
dv_clean = self.addResourceCleanUp(self.client.delete_vpc,
VpcId=vpc_id)
data = self.client.create_security_group(VpcId=vpc_id,
GroupName=name,
Description=desc)
time.sleep(2)
self.client.delete_security_group(GroupId=data['GroupId'])
self.client.delete_vpc(VpcId=vpc_id)
self.cancelResourceCleanUp(dv_clean)
self.get_vpc_waiter().wait_delete(vpc_id)
data = self.client.delete_security_group(GroupId=group_id)
self.cancelResourceCleanUp(res_clean)
@decorators.idempotent_id('524993f7-a8d3-4ffc-bbf1-6a3014377181')
@testtools.skipUnless(CONF.aws.run_incompatible_tests,
"MismatchError: 'InvalidParameterValue' != 'ValidationError'")
def test_create_invalid_name_desc(self):
valid = data_utils.rand_name('sgName')
invalid = 'name%"'
self.assertRaises('InvalidParameterValue',
self.client.create_security_group,
VpcId=self.vpc_id, GroupName=invalid,
Description=valid)
self.assertRaises('InvalidParameterValue',
self.client.create_security_group,
VpcId=self.vpc_id, GroupName=valid,
Description=invalid)
self.assertRaises('InvalidParameterValue',
self.client.create_security_group,
VpcId=self.vpc_id, GroupName='default',
Description='default')
self.assertRaises('MissingParameter',
self.client.create_security_group,
VpcId=self.vpc_id, GroupName=valid, Description='')
self.assertRaises('MissingParameter',
self.client.create_security_group,
VpcId=self.vpc_id, GroupName='', Description=valid)
@decorators.idempotent_id('3460cefd-c759-4738-ba75-b275939aad1d')
@testtools.skip("flaky test")
def test_ingress_rules(self):
self._test_rules(self.client.authorize_security_group_ingress,
self.client.revoke_security_group_ingress,
'IpPermissions', self.vpc_id)
@decorators.idempotent_id('74a5de83-69b4-4cc5-9431-e4c1f691f0c1')
@testtools.skip("flaky test")
def test_egress_rules(self):
self._test_rules(self.client.authorize_security_group_egress,
self.client.revoke_security_group_egress,
'IpPermissionsEgress', self.vpc_id)
class SecurityGroupEC2ClassicTest(SecurityGroupBaseTest):
@classmethod
@base.safe_setup
def setUpClass(cls):
super(SecurityGroupEC2ClassicTest, cls).setUpClass()
if not base.TesterStateHolder().get_ec2_enabled():
raise cls.skipException('EC2-classic is disabled')
@decorators.idempotent_id('eb097f7c-4b10-4365-aa34-c17e5769f4a7')
def test_create_delete_security_group(self):
name = data_utils.rand_name('sgName')
desc = data_utils.rand_name('sgDesc')
data = self.client.create_security_group(GroupName=name,
Description=desc)
group_id = data['GroupId']
res_clean = self.addResourceCleanUp(self.client.delete_security_group,
GroupId=group_id)
time.sleep(2)
data = self.client.describe_security_groups(GroupNames=[name])
self.assertEqual(1, len(data['SecurityGroups']))
self.assertEqual(group_id, data['SecurityGroups'][0]['GroupId'])
data = self.client.describe_security_groups(GroupIds=[group_id])
self.assertEqual(1, len(data['SecurityGroups']))
self.assertEqual(name, data['SecurityGroups'][0]['GroupName'])
self.client.delete_security_group(GroupName=name)
self.cancelResourceCleanUp(res_clean)
@decorators.idempotent_id('b97b8b4a-811e-4584-8e79-086499459aca')
def test_create_duplicate_security_group(self):
name = data_utils.rand_name('sgName')
desc = data_utils.rand_name('sgDesc')
data = self.client.create_security_group(GroupName=name,
Description=desc)
group_id = data['GroupId']
res_clean = self.addResourceCleanUp(self.client.delete_security_group,
GroupId=group_id)
time.sleep(2)
self.assertRaises('InvalidGroup.Duplicate',
self.client.create_security_group,
GroupName=name, Description=desc)
self.client.delete_security_group(GroupId=group_id)
self.cancelResourceCleanUp(res_clean)
@decorators.idempotent_id('b80c578d-0c0d-4c7e-b0ee-a7ed23b6b209')
@testtools.skipUnless(CONF.aws.run_incompatible_tests,
"MismatchError: 'MissingParameter' != 'ValidationError'")
def test_create_invalid_name_desc(self):
valid = data_utils.rand_name('sgName')
self.assertRaises('MissingParameter',
self.client.create_security_group,
GroupName=valid, Description='')
self.assertRaises('MissingParameter',
self.client.create_security_group,
GroupName='', Description=valid)
self.assertRaises('InvalidGroup.Reserved',
self.client.create_security_group,
GroupName='default', Description='default')
@decorators.idempotent_id('eba8a7c4-3781-4562-b137-dbe8037395a3')
def test_ingress_rules(self):
self._test_rules(self.client.authorize_security_group_ingress,
self.client.revoke_security_group_ingress,
'IpPermissions')
@decorators.idempotent_id('435d5e53-060f-455a-9317-60177246e04d')
def test_egress_rules(self):
def _test():
self._test_rules(
self.client.authorize_security_group_egress,
self.client.revoke_security_group_egress,
'IpPermissionsEgress')
self.assertRaises('InvalidParameterValue', _test)

View File

@ -1,267 +0,0 @@
# Copyright 2014 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
from tempest.lib import decorators
import testtools
from ec2api_tempest_plugin import base
from ec2api_tempest_plugin import config
CONF = config.CONF
class SnapshotTest(base.EC2TestCase):
@decorators.idempotent_id('3eb8868b-5c6b-4619-8c99-9429ca86a526')
def test_create_delete_snapshot(self):
kwargs = {
'Size': 1,
'AvailabilityZone': CONF.aws.aws_zone
}
data = self.client.create_volume(*[], **kwargs)
volume_id = data['VolumeId']
clean_vol = self.addResourceCleanUp(self.client.delete_volume,
VolumeId=volume_id)
self.get_volume_waiter().wait_available(volume_id)
desc = 'test snapshot'
kwargs = {
'VolumeId': volume_id,
'Description': desc
}
data = self.client.create_snapshot(*[], **kwargs)
snapshot_id = data['SnapshotId']
res_clean = self.addResourceCleanUp(self.client.delete_snapshot,
SnapshotId=snapshot_id)
self.get_snapshot_waiter().wait_available(snapshot_id,
final_set=('completed'))
self.assertEqual(desc, data['Description'])
self.assertEqual(volume_id, data['VolumeId'])
self.assertEqual(1, data['VolumeSize'])
self.assertNotEmpty(data.get('State', ''))
if 'Encrypted' in data:
self.assertFalse(data['Encrypted'])
self.assertIsNotNone(data['StartTime'])
data = self.client.delete_snapshot(SnapshotId=snapshot_id)
self.cancelResourceCleanUp(res_clean)
self.get_snapshot_waiter().wait_delete(snapshot_id)
data = self.client.delete_volume(VolumeId=volume_id)
self.cancelResourceCleanUp(clean_vol)
self.get_volume_waiter().wait_delete(volume_id)
@decorators.idempotent_id('dfe0f2e6-c103-4e26-93e5-63010bf6b0af')
def test_describe_snapshots(self):
kwargs = {
'Size': 1,
'AvailabilityZone': CONF.aws.aws_zone
}
data = self.client.create_volume(*[], **kwargs)
volume_id = data['VolumeId']
clean_vol = self.addResourceCleanUp(self.client.delete_volume,
VolumeId=volume_id)
self.get_volume_waiter().wait_available(volume_id)
desc = 'test snapshot'
kwargs = {
'VolumeId': volume_id,
'Description': desc
}
data = self.client.create_snapshot(*[], **kwargs)
snapshot_id = data['SnapshotId']
ownerId = data['OwnerId']
res_clean = self.addResourceCleanUp(self.client.delete_snapshot,
SnapshotId=snapshot_id)
self.get_snapshot_waiter().wait_available(snapshot_id,
final_set=('completed'))
self.assertEqual(desc, data['Description'])
self.assertEqual(volume_id, data['VolumeId'])
self.assertEqual(1, data['VolumeSize'])
self.assertNotEmpty(data.get('State', ''))
if 'Encrypted' in data:
self.assertFalse(data['Encrypted'])
self.assertIsNotNone(data['StartTime'])
data = self.client.describe_snapshots(SnapshotIds=[snapshot_id])
self.assertEqual(1, len(data['Snapshots']))
data = data['Snapshots'][0]
self.assertEqual(snapshot_id, data['SnapshotId'])
self.assertEqual(desc, data['Description'])
self.assertEqual(volume_id, data['VolumeId'])
self.assertEqual(1, data['VolumeSize'])
self.assertNotEmpty(data.get('State', ''))
if 'Encrypted' in data:
self.assertFalse(data['Encrypted'])
self.assertIsNotNone(data['StartTime'])
data = self.client.describe_snapshots(OwnerIds=[ownerId])
data = [s for s in data['Snapshots'] if s['SnapshotId'] == snapshot_id]
self.assertEqual(1, len(data))
data = self.client.delete_snapshot(SnapshotId=snapshot_id)
self.cancelResourceCleanUp(res_clean)
self.get_snapshot_waiter().wait_delete(snapshot_id)
self.assertRaises('InvalidSnapshot.NotFound',
self.client.describe_snapshots,
SnapshotIds=[snapshot_id])
data = self.client.delete_volume(VolumeId=volume_id)
self.cancelResourceCleanUp(clean_vol)
self.get_volume_waiter().wait_delete(volume_id)
@decorators.idempotent_id('c4a99068-3c9e-4d8c-8d7a-e96548cfdaa7')
def test_create_volume_from_snapshot(self):
kwargs = {
'Size': 1,
'AvailabilityZone': CONF.aws.aws_zone
}
data = self.client.create_volume(*[], **kwargs)
volume_id = data['VolumeId']
clean_vol = self.addResourceCleanUp(self.client.delete_volume,
VolumeId=volume_id)
self.get_volume_waiter().wait_available(volume_id)
vol1 = data
desc = 'test snapshot'
kwargs = {
'VolumeId': volume_id,
'Description': desc
}
data = self.client.create_snapshot(*[], **kwargs)
snapshot_id = data['SnapshotId']
res_clean = self.addResourceCleanUp(self.client.delete_snapshot,
SnapshotId=snapshot_id)
self.get_snapshot_waiter().wait_available(snapshot_id,
final_set=('completed'))
kwargs = {
'SnapshotId': snapshot_id,
'AvailabilityZone': CONF.aws.aws_zone
}
data = self.client.create_volume(*[], **kwargs)
volume_id2 = data['VolumeId']
clean_vol2 = self.addResourceCleanUp(self.client.delete_volume,
VolumeId=volume_id2)
self.get_volume_waiter().wait_available(volume_id2)
self.assertNotEqual(volume_id, volume_id2)
self.assertEqual(vol1['Size'], data['Size'])
self.assertEqual(snapshot_id, data['SnapshotId'])
data = self.client.describe_volumes(
Filters=[{'Name': 'snapshot-id', 'Values': [snapshot_id]}])
self.assertEqual(1, len(data['Volumes']))
self.assertEqual(volume_id2, data['Volumes'][0]['VolumeId'])
data = self.client.delete_snapshot(SnapshotId=snapshot_id)
self.cancelResourceCleanUp(res_clean)
self.get_snapshot_waiter().wait_delete(snapshot_id)
data = self.client.delete_volume(VolumeId=volume_id)
self.cancelResourceCleanUp(clean_vol)
self.get_volume_waiter().wait_delete(volume_id)
data = self.client.delete_volume(VolumeId=volume_id2)
self.cancelResourceCleanUp(clean_vol2)
self.get_volume_waiter().wait_delete(volume_id2)
@decorators.idempotent_id('c6f0be0a-67ca-4f33-b821-83e9158cee66')
def test_create_increased_volume_from_snapshot(self):
kwargs = {
'Size': 1,
'AvailabilityZone': CONF.aws.aws_zone
}
data = self.client.create_volume(*[], **kwargs)
volume_id = data['VolumeId']
clean_vol = self.addResourceCleanUp(self.client.delete_volume,
VolumeId=volume_id)
self.get_volume_waiter().wait_available(volume_id)
desc = 'test snapshot'
kwargs = {
'VolumeId': volume_id,
'Description': desc
}
data = self.client.create_snapshot(*[], **kwargs)
snapshot_id = data['SnapshotId']
res_clean = self.addResourceCleanUp(self.client.delete_snapshot,
SnapshotId=snapshot_id)
self.get_snapshot_waiter().wait_available(snapshot_id,
final_set=('completed'))
kwargs = {
'Size': 2,
'SnapshotId': snapshot_id,
'AvailabilityZone': CONF.aws.aws_zone
}
data = self.client.create_volume(*[], **kwargs)
volume_id2 = data['VolumeId']
clean_vol2 = self.addResourceCleanUp(self.client.delete_volume,
VolumeId=volume_id2)
self.get_volume_waiter().wait_available(volume_id2)
self.assertNotEqual(volume_id, volume_id2)
self.assertEqual(2, data['Size'])
self.assertEqual(snapshot_id, data['SnapshotId'])
data = self.client.delete_snapshot(SnapshotId=snapshot_id)
self.cancelResourceCleanUp(res_clean)
self.get_snapshot_waiter().wait_delete(snapshot_id)
data = self.client.delete_volume(VolumeId=volume_id)
self.cancelResourceCleanUp(clean_vol)
self.get_volume_waiter().wait_delete(volume_id)
data = self.client.delete_volume(VolumeId=volume_id2)
self.cancelResourceCleanUp(clean_vol2)
self.get_volume_waiter().wait_delete(volume_id2)
@decorators.idempotent_id('8f885da3-97e3-419e-b382-036ca7b25877')
@testtools.skipUnless(CONF.aws.run_incompatible_tests,
"Openstack can't delete volume with snapshots")
def test_delete_volume_with_snapshots(self):
kwargs = {
'Size': 1,
'AvailabilityZone': CONF.aws.aws_zone
}
data = self.client.create_volume(*[], **kwargs)
volume_id = data['VolumeId']
clean_vol = self.addResourceCleanUp(self.client.delete_volume,
VolumeId=volume_id)
self.get_volume_waiter().wait_available(volume_id)
desc = 'test snapshot'
kwargs = {
'VolumeId': volume_id,
'Description': desc
}
data = self.client.create_snapshot(*[], **kwargs)
snapshot_id = data['SnapshotId']
res_clean = self.addResourceCleanUp(self.client.delete_snapshot,
SnapshotId=snapshot_id)
self.get_snapshot_waiter().wait_available(snapshot_id,
final_set=('completed'))
data = self.client.delete_volume(VolumeId=volume_id)
self.cancelResourceCleanUp(clean_vol)
self.get_volume_waiter().wait_delete(volume_id)
data = self.client.delete_snapshot(SnapshotId=snapshot_id)
self.cancelResourceCleanUp(res_clean)
self.get_snapshot_waiter().wait_delete(snapshot_id)

View File

@ -1,191 +0,0 @@
# Copyright 2014 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
from oslo_log import log
from tempest.lib import decorators
import testtools
from ec2api_tempest_plugin import base
from ec2api_tempest_plugin import config
CONF = config.CONF
LOG = log.getLogger(__name__)
class SubnetTest(base.EC2TestCase):
BASE_CIDR = '10.2.0.0'
VPC_CIDR = BASE_CIDR + '/20'
vpc_id = None
@classmethod
@base.safe_setup
def setUpClass(cls):
super(SubnetTest, cls).setUpClass()
if not base.TesterStateHolder().get_vpc_enabled():
raise cls.skipException('VPC is disabled')
data = cls.client.create_vpc(CidrBlock=cls.VPC_CIDR)
cls.vpc_id = data['Vpc']['VpcId']
cls.addResourceCleanUpStatic(cls.client.delete_vpc, VpcId=cls.vpc_id)
cls.get_vpc_waiter().wait_available(cls.vpc_id)
@decorators.idempotent_id('506993c3-aff6-48ea-8916-da8a4f199a66')
def test_create_delete_subnet(self):
cidr = self.BASE_CIDR + '/24'
data = self.client.create_subnet(VpcId=self.vpc_id,
CidrBlock=cidr)
subnet_id = data['Subnet']['SubnetId']
res_clean = self.addResourceCleanUp(self.client.delete_subnet,
SubnetId=subnet_id)
self.assertEqual(cidr, data['Subnet']['CidrBlock'])
self.assertIsNotNone(data['Subnet'].get('AvailableIpAddressCount'))
self.get_subnet_waiter().wait_available(subnet_id)
data = self.client.delete_subnet(SubnetId=subnet_id)
self.cancelResourceCleanUp(res_clean)
self.get_subnet_waiter().wait_delete(subnet_id)
self.assertRaises('InvalidSubnetID.NotFound',
self.client.describe_subnets,
SubnetIds=[subnet_id])
self.assertRaises('InvalidSubnetID.NotFound',
self.client.delete_subnet,
SubnetId=subnet_id)
@decorators.idempotent_id('4d27f078-46d2-4e2c-87c4-b5ba4589c2aa')
def test_dependency_subnet_to_vpc(self):
data = self.client.create_vpc(CidrBlock=self.VPC_CIDR)
vpc_id = data['Vpc']['VpcId']
vpc_clean = self.addResourceCleanUp(self.client.delete_vpc,
VpcId=vpc_id)
self.get_vpc_waiter().wait_available(vpc_id)
cidr = self.BASE_CIDR + '/24'
data = self.client.create_subnet(VpcId=vpc_id, CidrBlock=cidr)
subnet_id = data['Subnet']['SubnetId']
res_clean = self.addResourceCleanUp(self.client.delete_subnet,
SubnetId=subnet_id)
self.get_subnet_waiter().wait_available(subnet_id)
self.assertRaises('DependencyViolation',
self.client.delete_vpc,
VpcId=vpc_id)
data = self.client.delete_subnet(SubnetId=subnet_id)
self.cancelResourceCleanUp(res_clean)
self.get_subnet_waiter().wait_delete(subnet_id)
self.client.delete_vpc(VpcId=vpc_id)
self.cancelResourceCleanUp(vpc_clean)
@decorators.idempotent_id('85ee17ca-5e2c-4d54-84ca-efcca8f94ff9')
@testtools.skipUnless(
CONF.aws.run_incompatible_tests,
"bug with overlapped subnets")
def test_create_overlapped_subnet(self):
cidr = self.BASE_CIDR + '/24'
data = self.client.create_subnet(VpcId=self.vpc_id, CidrBlock=cidr)
subnet_id = data['Subnet']['SubnetId']
res_clean = self.addResourceCleanUp(self.client.delete_subnet,
SubnetId=subnet_id)
self.get_subnet_waiter().wait_available(subnet_id)
cidr = '10.2.0.128/26'
def _rollback(fn_data):
self.client.delete_subnet(SubnetId=data['Subnet']['SubnetId'])
self.assertRaises('InvalidSubnet.Conflict',
self.client.create_subnet, rollback_fn=_rollback,
VpcId=self.vpc_id, CidrBlock=cidr)
data = self.client.delete_subnet(SubnetId=subnet_id)
self.cancelResourceCleanUp(res_clean)
self.get_subnet_waiter().wait_delete(subnet_id)
@decorators.idempotent_id('20ea7ea4-67e6-42ed-9b91-e7b4b8d82605')
def test_create_subnet_invalid_cidr(self):
def _rollback(fn_data):
self.client.delete_subnet(SubnetId=fn_data['Subnet']['SubnetId'])
# NOTE(andrey-mp): another cidr than VPC has
cidr = '10.1.0.0/24'
self.assertRaises('InvalidSubnet.Range',
self.client.create_subnet, rollback_fn=_rollback,
VpcId=self.vpc_id, CidrBlock=cidr)
# NOTE(andrey-mp): bigger cidr than VPC has
cidr = self.BASE_CIDR + '/19'
self.assertRaises('InvalidSubnet.Range',
self.client.create_subnet, rollback_fn=_rollback,
VpcId=self.vpc_id, CidrBlock=cidr)
# NOTE(andrey-mp): too small cidr
cidr = self.BASE_CIDR + '/29'
self.assertRaises('InvalidSubnet.Range',
self.client.create_subnet, rollback_fn=_rollback,
VpcId=self.vpc_id, CidrBlock=cidr)
@decorators.idempotent_id('8f0f2637-118f-4307-8585-7470808b3a86')
def test_describe_subnets_base(self):
cidr = self.BASE_CIDR + '/24'
data = self.client.create_subnet(VpcId=self.vpc_id, CidrBlock=cidr)
subnet_id = data['Subnet']['SubnetId']
res_clean = self.addResourceCleanUp(self.client.delete_subnet,
SubnetId=subnet_id)
self.get_subnet_waiter().wait_available(subnet_id)
# NOTE(andrey-mp): by real id
data = self.client.describe_subnets(SubnetIds=[subnet_id])
self.assertEqual(1, len(data['Subnets']))
# NOTE(andrey-mp): by fake id
self.assertRaises('InvalidSubnetID.NotFound',
self.client.describe_subnets,
SubnetIds=['subnet-0'])
data = self.client.delete_subnet(SubnetId=subnet_id)
self.cancelResourceCleanUp(res_clean)
self.get_subnet_waiter().wait_delete(subnet_id)
@decorators.idempotent_id('182d151c-2dca-46bd-b137-1dece7276e1f')
def test_describe_subnets_filters(self):
cidr = self.BASE_CIDR + '/24'
data = self.client.create_subnet(VpcId=self.vpc_id, CidrBlock=cidr)
subnet_id = data['Subnet']['SubnetId']
res_clean = self.addResourceCleanUp(self.client.delete_subnet,
SubnetId=subnet_id)
self.get_subnet_waiter().wait_available(subnet_id)
# NOTE(andrey-mp): by filter real cidr
data = self.client.describe_subnets(
Filters=[{'Name': 'cidr', 'Values': [cidr]}])
self.assertEqual(1, len(data['Subnets']))
# NOTE(andrey-mp): by filter fake cidr
data = self.client.describe_subnets(
Filters=[{'Name': 'cidr', 'Values': ['123.0.0.0/16']}])
self.assertEqual(0, len(data['Subnets']))
# NOTE(andrey-mp): by fake filter
self.assertRaises('InvalidParameterValue',
self.client.describe_subnets,
Filters=[{'Name': 'fake', 'Values': ['fake']}])
data = self.client.delete_subnet(SubnetId=subnet_id)
self.cancelResourceCleanUp(res_clean)
self.get_subnet_waiter().wait_delete(subnet_id)

View File

@ -1,511 +0,0 @@
# Copyright 2015 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import time
from tempest.lib.common.utils import data_utils
from tempest.lib import decorators
import testtools
from ec2api_tempest_plugin import base
from ec2api_tempest_plugin import config
CONF = config.CONF
class TagTest(base.EC2TestCase):
@classmethod
@base.safe_setup
def setUpClass(cls):
super(TagTest, cls).setUpClass()
cls.zone = CONF.aws.aws_zone
data = cls.client.create_volume(
Size=1, AvailabilityZone=cls.zone)
cls.volume_id = data['VolumeId']
cls.addResourceCleanUpStatic(cls.client.delete_volume,
VolumeId=cls.volume_id)
cls.get_volume_waiter().wait_available(cls.volume_id)
@decorators.idempotent_id('249f59cf-2fcd-47ac-a233-682f17fc3129')
def test_create_get_delete_tag(self):
tag_key = data_utils.rand_name('tag-key')
self.client.create_tags(Resources=[self.volume_id],
Tags=[{'Key': tag_key, 'Value': 'fake_value'}])
self.addResourceCleanUp(self.client.delete_tags,
Resources=[self.volume_id],
Tags=[{'Key': tag_key}])
data = self.client.describe_tags(
Filters=[{'Name': 'resource-id', 'Values': [self.volume_id]}])
self.assertEqual(1, len(data['Tags']))
self.client.delete_tags(Resources=[self.volume_id],
Tags=[{'Key': tag_key}])
data = self.client.describe_tags(
Filters=[{'Name': 'resource-id', 'Values': [self.volume_id]}])
self.assertEqual(0, len(data['Tags']))
@decorators.idempotent_id('41dec90b-a878-4367-ba95-83757281e343')
def test_describe_tags(self):
tag_key = data_utils.rand_name('tag-key')
self.client.create_tags(Resources=[self.volume_id],
Tags=[{'Key': tag_key, 'Value': 'fake_value'}])
self.addResourceCleanUp(self.client.delete_tags,
Resources=[self.volume_id],
Tags=[{'Key': tag_key}])
data = self.client.describe_tags(
Filters=[{'Name': 'resource-id', 'Values': [self.volume_id]}])
self.assertEqual(1, len(data['Tags']))
tag = data['Tags'][0]
self.assertEqual('volume', tag.get('ResourceType'))
self.assertEqual(self.volume_id, tag.get('ResourceId'))
self.assertEqual(tag_key, tag.get('Key'))
self.assertEqual('fake_value', tag.get('Value'))
data = self.client.describe_tags(
Filters=[{'Name': 'resource-id', 'Values': [self.volume_id]},
{'Name': 'key', 'Values': [tag_key]}])
self.assertEqual(1, len(data['Tags']))
data = self.client.describe_tags(
Filters=[{'Name': 'key', 'Values': [tag_key]}])
self.assertIn(tag_key, [k.get('Key') for k in data['Tags']])
data = self.client.describe_tags(
Filters=[{'Name': 'value', 'Values': ['fake_value']}])
self.assertIn('fake_value', [k.get('Value') for k in data['Tags']])
data = self.client.describe_tags(
Filters=[{'Name': 'key', 'Values': ['fake_value']}])
items = [k.get('Key') for k in data['Tags']]
self.assertNotIn(tag_key, items)
self.assertNotIn('fake_value', items)
data = self.client.describe_tags(
Filters=[{'Name': 'resource-type', 'Values': ['volume']}])
self.assertIn(tag_key, [k.get('Key') for k in data['Tags']])
self.client.delete_tags(Resources=[self.volume_id],
Tags=[{'Key': tag_key}])
data = self.client.describe_tags(
Filters=[{'Name': 'resource-id', 'Values': [self.volume_id]}])
self.assertEqual(0, len(data['Tags']))
def _test_tag_resource(self, resource_id, res_type, describe_func):
data = self.client.describe_tags(
Filters=[{'Name': 'resource-id', 'Values': [resource_id]}])
origin_count = len(data['Tags'])
tag_key = data_utils.rand_name('tag-key')
data = self.client.create_tags(Resources=[resource_id],
Tags=[{'Key': tag_key, 'Value': 'fake_value'}])
self.addResourceCleanUp(self.client.delete_tags,
Resources=[resource_id],
Tags=[{'Key': tag_key}])
data = self.client.describe_tags(
Filters=[{'Name': 'resource-id', 'Values': [resource_id]}])
self.assertEqual(origin_count + 1, len(data['Tags']))
data = self.client.describe_tags(
Filters=[{'Name': 'resource-type', 'Values': [res_type]}])
self.assertIn(tag_key, [k.get('Key') for k in data['Tags']])
describe_func(Filters=[{'Name': 'tag-key', 'Values': [tag_key]}])
self.client.delete_tags(Resources=[resource_id],
Tags=[{'Key': tag_key}])
data = self.client.describe_tags(
Filters=[{'Name': 'resource-id', 'Values': [resource_id]}])
self.assertEqual(origin_count, len(data['Tags']))
def _test_tag_resource_negative(self, resource_id):
data = self.client.describe_tags(
Filters=[{'Name': 'resource-id', 'Values': [resource_id]}])
self.assertEmpty(data['Tags'])
def _rollback(fn_data):
self.client.delete_tags(Resources=[resource_id],
Tags=[{'Key': tag_key}])
tag_key = data_utils.rand_name('tag-key')
self.assertRaises('InvalidID',
self.client.create_tags, rollback_fn=_rollback,
Resources=[resource_id],
Tags=[{'Key': tag_key, 'Value': 'fake_value'}])
@decorators.idempotent_id('36478dc6-cf3f-4a4b-b275-282ba147822b')
def test_tag_image(self):
image_id = CONF.aws.ebs_image_id
if not image_id:
image_id = CONF.aws.image_id
if not image_id:
raise self.skipException('aws or ebs image_id does not provided')
def describe_func(*args, **kwargs):
data = self.client.describe_images(*args, **kwargs)
self.assertEqual(1, len(data['Images']))
self.assertEqual(image_id, data['Images'][0]['ImageId'])
self._test_tag_resource(image_id, 'image', describe_func)
data = self.client.describe_images(ImageIds=[image_id])
image = data['Images'][0]
if 'KernelId' in image:
image_id = image['KernelId']
self._test_tag_resource(image_id, 'image', describe_func)
if 'RamdiskId' in image:
image_id = image['RamdiskId']
self._test_tag_resource(image_id, 'image', describe_func)
@base.skip_without_vpc()
@decorators.idempotent_id('adc459f3-858d-4ce8-a097-549ab9350b18')
def test_tag_dhcp_options(self):
kwargs = {
'DhcpConfigurations': [
{'Key': 'domain-name',
'Values': ['my.com']},
],
}
data = self.client.create_dhcp_options(*[], **kwargs)
options = data['DhcpOptions']
res_id = options['DhcpOptionsId']
res_clean = self.addResourceCleanUp(self.client.delete_dhcp_options,
DhcpOptionsId=res_id)
def describe_func(*args, **kwargs):
data = self.client.describe_dhcp_options(*args, **kwargs)
self.assertEqual(1, len(data['DhcpOptions']))
self.assertEqual(res_id, data['DhcpOptions'][0]['DhcpOptionsId'])
self._test_tag_resource(res_id, 'dhcp-options', describe_func)
self.client.delete_dhcp_options(DhcpOptionsId=res_id)
self.cancelResourceCleanUp(res_clean)
@decorators.idempotent_id('afa064b2-8caf-442d-b001-b6cb8120e57e')
def test_tag_volume(self):
def describe_func(*args, **kwargs):
data = self.client.describe_volumes(*args, **kwargs)
self.assertEqual(1, len(data['Volumes']))
self.assertEqual(self.volume_id, data['Volumes'][0]['VolumeId'])
self._test_tag_resource(self.volume_id, 'volume', describe_func)
@base.skip_without_vpc()
@decorators.idempotent_id('96e581c6-8f38-41f9-9126-e35215c83d3e')
def test_tag_address(self):
kwargs = {
'Domain': 'vpc',
}
data = self.client.allocate_address(*[], **kwargs)
res_id = data['AllocationId']
res_clean = self.addResourceCleanUp(self.client.release_address,
AllocationId=res_id)
self.assertEqual('vpc', data['Domain'])
self._test_tag_resource_negative(res_id)
self.client.release_address(AllocationId=res_id)
self.cancelResourceCleanUp(res_clean)
@decorators.idempotent_id('f9a6dd26-b26f-4482-aad3-0b4f0e7cc3dd')
@testtools.skipUnless(CONF.aws.image_id, "image id is not defined")
def test_tag_instance(self):
instance_id = self.run_instance()
def describe_func(*args, **kwargs):
data = self.client.describe_instances(*args, **kwargs)
self.assertEqual(1, len(data['Reservations']))
self.assertEqual(1, len(data['Reservations'][0]['Instances']))
self.assertEqual(instance_id,
data['Reservations'][0]['Instances'][0]['InstanceId'])
self._test_tag_resource(instance_id, 'instance', describe_func)
self.client.terminate_instances(InstanceIds=[instance_id])
self.get_instance_waiter().wait_delete(instance_id)
@base.skip_without_vpc()
@decorators.idempotent_id('a223af28-b355-4404-a465-7fc9e9d71ad7')
def test_tag_internet_gateway(self):
data = self.client.create_internet_gateway()
gw_id = data['InternetGateway']['InternetGatewayId']
res_clean = self.addResourceCleanUp(
self.client.delete_internet_gateway, InternetGatewayId=gw_id)
def describe_func(*args, **kwargs):
data = self.client.describe_internet_gateways(*args, **kwargs)
self.assertEqual(1, len(data['InternetGateways']))
self.assertEqual(gw_id,
data['InternetGateways'][0]['InternetGatewayId'])
self._test_tag_resource(gw_id, 'internet-gateway', describe_func)
self.client.delete_internet_gateway(InternetGatewayId=gw_id)
self.cancelResourceCleanUp(res_clean)
@base.skip_without_vpc()
@decorators.idempotent_id('4691eefb-c118-4595-a386-8a2abd5c0d77')
def test_tag_network_interface(self):
cidr = '10.1.0.0/16'
data = self.client.create_vpc(CidrBlock=cidr)
vpc_id = data['Vpc']['VpcId']
dv_clean = self.addResourceCleanUp(
self.client.delete_vpc, VpcId=vpc_id)
cidr = '10.1.0.0/24'
data = self.client.create_subnet(VpcId=vpc_id,
CidrBlock=cidr)
subnet_id = data['Subnet']['SubnetId']
subnet_clean = self.addResourceCleanUp(self.client.delete_subnet,
SubnetId=subnet_id)
data = self.client.create_network_interface(SubnetId=subnet_id,
Description=data_utils.rand_name('ni'))
ni_id = data['NetworkInterface']['NetworkInterfaceId']
res_clean = self.addResourceCleanUp(
self.client.delete_network_interface, NetworkInterfaceId=ni_id)
self.get_network_interface_waiter().wait_available(ni_id)
def describe_func(*args, **kwargs):
data = self.client.describe_network_interfaces(*args, **kwargs)
self.assertEqual(1, len(data['NetworkInterfaces']))
self.assertEqual(ni_id,
data['NetworkInterfaces'][0]['NetworkInterfaceId'])
self._test_tag_resource(ni_id, 'network-interface', describe_func)
self.client.delete_network_interface(NetworkInterfaceId=ni_id)
self.cancelResourceCleanUp(res_clean)
self.get_network_interface_waiter().wait_delete(ni_id)
self.client.delete_subnet(SubnetId=subnet_id)
self.cancelResourceCleanUp(subnet_clean)
self.get_subnet_waiter().wait_delete(subnet_id)
self.client.delete_vpc(VpcId=vpc_id)
self.cancelResourceCleanUp(dv_clean)
self.get_vpc_waiter().wait_delete(vpc_id)
@base.skip_without_vpc()
@decorators.idempotent_id('384083a0-d492-4620-8093-166cd339ffaa')
def test_tag_route_table(self):
cidr = '10.1.0.0/16'
data = self.client.create_vpc(CidrBlock=cidr)
vpc_id = data['Vpc']['VpcId']
dv_clean = self.addResourceCleanUp(
self.client.delete_vpc, VpcId=vpc_id)
data = self.client.create_route_table(VpcId=vpc_id)
rt_id = data['RouteTable']['RouteTableId']
res_clean = self.addResourceCleanUp(self.client.delete_route_table,
RouteTableId=rt_id)
def describe_func(*args, **kwargs):
data = self.client.describe_route_tables(*args, **kwargs)
self.assertEqual(1, len(data['RouteTables']))
self.assertEqual(rt_id, data['RouteTables'][0]['RouteTableId'])
self._test_tag_resource(rt_id, 'route-table', describe_func)
self.client.delete_route_table(RouteTableId=rt_id)
self.cancelResourceCleanUp(res_clean)
self.client.delete_vpc(VpcId=vpc_id)
self.cancelResourceCleanUp(dv_clean)
self.get_vpc_waiter().wait_delete(vpc_id)
@base.skip_without_vpc()
@decorators.idempotent_id('03b8cd38-3017-4a8f-b2e0-1c4ac5e7333d')
def test_tag_security_group(self):
cidr = '10.1.0.0/16'
data = self.client.create_vpc(CidrBlock=cidr)
vpc_id = data['Vpc']['VpcId']
dv_clean = self.addResourceCleanUp(
self.client.delete_vpc, VpcId=vpc_id)
name = data_utils.rand_name('sgName')
desc = data_utils.rand_name('sgDesc')
data = self.client.create_security_group(VpcId=vpc_id,
GroupName=name,
Description=desc)
group_id = data['GroupId']
res_clean = self.addResourceCleanUp(self.client.delete_security_group,
GroupId=group_id)
time.sleep(2)
def describe_func(*args, **kwargs):
data = self.client.describe_security_groups(*args, **kwargs)
self.assertEqual(1, len(data['SecurityGroups']))
self.assertEqual(group_id,
data['SecurityGroups'][0]['GroupId'])
self._test_tag_resource(group_id, 'security-group', describe_func)
self.client.delete_security_group(GroupId=group_id)
self.cancelResourceCleanUp(res_clean)
self.client.delete_vpc(VpcId=vpc_id)
self.cancelResourceCleanUp(dv_clean)
self.get_vpc_waiter().wait_delete(vpc_id)
@decorators.idempotent_id('bed98f9c-f987-4192-afd8-4bdf35ac916e')
def test_tag_snapshot(self):
data = self.client.create_snapshot(VolumeId=self.volume_id)
snapshot_id = data['SnapshotId']
res_clean = self.addResourceCleanUp(self.client.delete_snapshot,
SnapshotId=snapshot_id)
self.get_snapshot_waiter().wait_available(snapshot_id,
final_set=('completed'))
def describe_func(*args, **kwargs):
data = self.client.describe_snapshots(*args, **kwargs)
self.assertEqual(1, len(data['Snapshots']))
self.assertEqual(snapshot_id, data['Snapshots'][0]['SnapshotId'])
self._test_tag_resource(snapshot_id, 'snapshot', describe_func)
self.client.delete_snapshot(SnapshotId=snapshot_id)
self.cancelResourceCleanUp(res_clean)
self.get_snapshot_waiter().wait_delete(snapshot_id)
@base.skip_without_vpc()
@decorators.idempotent_id('3a6f64fc-d2d4-496d-bf30-3ee0efe04e42')
def test_tag_subnet(self):
cidr = '10.1.0.0/16'
data = self.client.create_vpc(CidrBlock=cidr)
vpc_id = data['Vpc']['VpcId']
dv_clean = self.addResourceCleanUp(
self.client.delete_vpc, VpcId=vpc_id)
cidr = '10.1.0.0/24'
data = self.client.create_subnet(VpcId=vpc_id,
CidrBlock=cidr)
subnet_id = data['Subnet']['SubnetId']
res_clean = self.addResourceCleanUp(self.client.delete_subnet,
SubnetId=subnet_id)
def describe_func(*args, **kwargs):
data = self.client.describe_subnets(*args, **kwargs)
self.assertEqual(1, len(data['Subnets']))
self.assertEqual(subnet_id, data['Subnets'][0]['SubnetId'])
self._test_tag_resource(subnet_id, 'subnet', describe_func)
self.client.delete_subnet(SubnetId=subnet_id)
self.cancelResourceCleanUp(res_clean)
self.get_subnet_waiter().wait_delete(subnet_id)
self.client.delete_vpc(VpcId=vpc_id)
self.cancelResourceCleanUp(dv_clean)
self.get_vpc_waiter().wait_delete(vpc_id)
@base.skip_without_vpc()
@decorators.idempotent_id('0667c68b-9d3c-4599-9335-0cee68ba5d80')
def test_tag_vpc(self):
cidr = '10.1.0.0/16'
data = self.client.create_vpc(CidrBlock=cidr)
vpc_id = data['Vpc']['VpcId']
dv_clean = self.addResourceCleanUp(
self.client.delete_vpc, VpcId=vpc_id)
def describe_func(*args, **kwargs):
data = self.client.describe_vpcs(*args, **kwargs)
self.assertEqual(1, len(data['Vpcs']))
self.assertEqual(vpc_id, data['Vpcs'][0]['VpcId'])
self._test_tag_resource(vpc_id, 'vpc', describe_func)
self.client.delete_vpc(VpcId=vpc_id)
self.cancelResourceCleanUp(dv_clean)
self.get_vpc_waiter().wait_delete(vpc_id)
@base.skip_without_vpc()
@decorators.idempotent_id('07b2f20d-6b26-4c3d-9d32-93f98f187d78')
def test_tag_customer_gateway(self):
data = self.client.create_customer_gateway(
Type='ipsec.1', IpAddress='198.51.100.77', BgpAsn=65000)
cgw_id = data['CustomerGateway']['CustomerGatewayId']
self.addResourceCleanUp(self.client.delete_customer_gateway,
CustomerGatewayId=cgw_id)
def describe_func(*args, **kwargs):
data = self.client.describe_customer_gateways(*args, **kwargs)
self.assertEqual(1, len(data['CustomerGateways']))
self.assertEqual(cgw_id,
data['CustomerGateways'][0]['CustomerGatewayId'])
self._test_tag_resource(cgw_id, 'customer-gateway', describe_func)
@testtools.skip("Some unknown bug. Will fix this later")
@base.skip_without_vpc()
@base.skip_without_vpnaas_enabled()
@decorators.idempotent_id('a0437171-81a1-4871-9b71-c7629b25c337')
def test_tag_vpn_gateway(self):
data = self.client.create_vpn_gateway(Type='ipsec.1')
vgw_id = data['VpnGateway']['VpnGatewayId']
self.addResourceCleanUp(self.client.delete_vpn_gateway,
VpnGatewayId=vgw_id)
def describe_func(*args, **kwargs):
data = self.client.describe_vpn_gateways(*args, **kwargs)
self.assertEqual(1, len(data['VpnGateways']))
self.assertEqual(vgw_id,
data['VpnGateways'][0]['VpnGatewayId'])
self._test_tag_resource(vgw_id, 'vpn-gateway', describe_func)
@testtools.skip("Some unknown bug. Will fix this later")
@base.skip_without_vpc()
@base.skip_without_vpnaas_enabled()
@decorators.idempotent_id('ecd343b4-f448-4990-880d-02a68febc9cf')
def test_tag_vpn_connection(self):
data = self.client.create_customer_gateway(
Type='ipsec.1', PublicIp='198.51.100.77', BgpAsn=65000)
cgw_id = data['CustomerGateway']['CustomerGatewayId']
self.addResourceCleanUp(self.client.delete_customer_gateway,
CustomerGatewayId=cgw_id)
data = self.client.create_vpn_gateway(Type='ipsec.1')
vgw_id = data['VpnGateway']['VpnGatewayId']
self.addResourceCleanUp(self.client.delete_vpn_gateway,
VpnGatewayId=vgw_id)
data = self.client.create_vpn_connection(
CustomerGatewayId=cgw_id, VpnGatewayId=vgw_id,
Options={'StaticRoutesOnly': True}, Type='ipsec.1')
vpn_id = data['VpnConnection']['VpnConnectionId']
vpn_clean = self.addResourceCleanUp(self.client.delete_vpn_connection,
VpnConnectionId=vpn_id)
def describe_func(*args, **kwargs):
data = self.client.describe_vpn_connections(*args, **kwargs)
self.assertEqual(1, len(data['VpnConnections']))
self.assertEqual(vpn_id,
data['VpnConnections'][0]['VpnConnectionId'])
self._test_tag_resource(vpn_id, 'vpn-connection', describe_func)
self.client.delete_vpn_connection(VpnConnectionId=vpn_id)
vpn_waiter = self.get_vpn_connection_waiter()
self.cancelResourceCleanUp(vpn_clean)
vpn_waiter.wait_delete(vpn_id)

View File

@ -1,420 +0,0 @@
# Copyright 2014 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
from tempest.lib import decorators
import testtools
from ec2api_tempest_plugin import base
from ec2api_tempest_plugin import config
CONF = config.CONF
class VolumeTest(base.EC2TestCase):
@decorators.idempotent_id('51fd4d06-7b00-427a-9d69-6ecd076c219a')
def test_create_delete_volume(self):
kwargs = {
'Size': 1,
'AvailabilityZone': CONF.aws.aws_zone
}
data = self.client.create_volume(*[], **kwargs)
volume_id = data['VolumeId']
res_clean = self.addResourceCleanUp(self.client.delete_volume,
VolumeId=volume_id)
self.get_volume_waiter().wait_available(volume_id)
if CONF.aws.run_incompatible_tests:
self.assertEqual('standard', data['VolumeType'])
self.assertEqual(1, data['Size'])
if 'Encrypted' in data:
self.assertFalse(data['Encrypted'])
self.assertIsNotNone(data['CreateTime'])
self.assertEqual(CONF.aws.aws_zone, data['AvailabilityZone'])
self.client.delete_volume(VolumeId=volume_id)
self.cancelResourceCleanUp(res_clean)
self.get_volume_waiter().wait_delete(volume_id)
self.assertRaises('InvalidVolume.NotFound',
self.client.describe_volumes,
VolumeIds=[volume_id])
self.assertRaises('InvalidVolume.NotFound',
self.client.delete_volume,
VolumeId=volume_id)
@decorators.idempotent_id('a7f1c4f8-2153-4d09-b5d5-bf087ea2f6ed')
@testtools.skipUnless(CONF.aws.run_incompatible_tests,
"Encryption is not implemented")
def test_create_encrypted_volume(self):
kwargs = {
'Size': 1,
'AvailabilityZone': CONF.aws.aws_zone,
'Encrypted': True,
}
data = self.client.create_volume(*[], **kwargs)
volume_id = data['VolumeId']
res_clean = self.addResourceCleanUp(self.client.delete_volume,
VolumeId=volume_id)
self.get_volume_waiter().wait_available(volume_id)
self.assertTrue(data['Encrypted'])
self.client.delete_volume(VolumeId=volume_id)
self.cancelResourceCleanUp(res_clean)
self.get_volume_waiter().wait_delete(volume_id)
@decorators.idempotent_id('16c97f73-c4f2-4e91-9506-4f6da4a33f8a')
def test_describe_volumes(self):
kwargs = {
'Size': 1,
'AvailabilityZone': CONF.aws.aws_zone
}
data = self.client.create_volume(*[], **kwargs)
volume_id = data['VolumeId']
res_clean = self.addResourceCleanUp(self.client.delete_volume,
VolumeId=volume_id)
self.get_volume_waiter().wait_available(volume_id)
data = self.client.create_volume(*[], **kwargs)
volume_id_ext = data['VolumeId']
res_clean_ext = self.addResourceCleanUp(self.client.delete_volume,
VolumeId=volume_id_ext)
self.get_volume_waiter().wait_available(volume_id_ext)
data = self.client.describe_volumes(VolumeIds=[volume_id])
self.assertEqual(1, len(data['Volumes']))
volume = data['Volumes'][0]
self.assertEqual(volume_id, volume['VolumeId'])
if CONF.aws.run_incompatible_tests:
self.assertEqual('standard', volume['VolumeType'])
self.assertEqual(1, volume['Size'])
if 'Encrypted' in volume:
self.assertFalse(volume['Encrypted'])
self.client.delete_volume(VolumeId=volume_id_ext)
self.cancelResourceCleanUp(res_clean_ext)
self.get_volume_waiter().wait_delete(volume_id_ext)
self.client.delete_volume(VolumeId=volume_id)
self.cancelResourceCleanUp(res_clean)
self.get_volume_waiter().wait_delete(volume_id)
@decorators.idempotent_id('30697dd5-12e7-4dd3-8cf8-5bdb296f26d8')
@testtools.skipUnless(CONF.aws.run_incompatible_tests,
"Volume statuses are not implemented")
def test_describe_volume_status(self):
kwargs = {
'Size': 1,
'AvailabilityZone': CONF.aws.aws_zone
}
data = self.client.create_volume(*[], **kwargs)
volume_id = data['VolumeId']
res_clean = self.addResourceCleanUp(self.client.delete_volume,
VolumeId=volume_id)
self.get_volume_waiter().wait_available(volume_id)
data = self.client.describe_volume_status(VolumeIds=[volume_id])
self.assertEqual(1, len(data['VolumeStatuses']))
volume_status = data['VolumeStatuses'][0]
self.assertIn('Actions', volume_status)
self.assertIn('Events', volume_status)
self.assertIn('VolumeStatus', volume_status)
self.client.delete_volume(VolumeId=volume_id)
self.cancelResourceCleanUp(res_clean)
self.get_volume_waiter().wait_delete(volume_id)
@decorators.idempotent_id('b0116edc-250c-4083-b1ad-66c0eb984415')
@testtools.skipUnless(CONF.aws.ebs_image_id, "ebs image id is not defined")
def test_attach_detach_volume(self):
clean_dict = {}
instance_id = self.run_instance(ImageId=CONF.aws.ebs_image_id,
clean_dict=clean_dict)
clean_i = clean_dict['instance']
kwargs = {
'Size': 1,
'AvailabilityZone': CONF.aws.aws_zone
}
data = self.client.create_volume(*[], **kwargs)
volume_id = data['VolumeId']
clean_v = self.addResourceCleanUp(self.client.delete_volume,
VolumeId=volume_id)
self.get_volume_waiter().wait_available(volume_id)
kwargs = {
'Device': '/dev/sdh',
'InstanceId': instance_id,
'VolumeId': volume_id,
}
self.client.attach_volume(*[], **kwargs)
clean_vi = self.addResourceCleanUp(self.client.detach_volume,
VolumeId=volume_id)
self.get_volume_attachment_waiter().wait_available(
volume_id, final_set=('attached'))
# reorder cleanups to avoid error on volume delete
self.cancelResourceCleanUp(clean_i)
clean_i = self.addResourceCleanUp(self.client.terminate_instances,
InstanceIds=[instance_id])
data = self.client.describe_volumes(VolumeIds=[volume_id])
self.assertEqual(1, len(data['Volumes']))
volume = data['Volumes'][0]
self.assertEqual('in-use', volume['State'])
self.assertEqual(1, len(volume['Attachments']))
attachment = volume['Attachments'][0]
self.assertFalse(attachment['DeleteOnTermination'])
self.assertIsNotNone(attachment['Device'])
self.assertEqual(instance_id, attachment['InstanceId'])
self.assertEqual(volume_id, attachment['VolumeId'])
data = self.client.describe_instances(InstanceIds=[instance_id])
self.assertEqual(1, len(data.get('Reservations', [])))
self.assertEqual(1, len(data['Reservations'][0].get('Instances', [])))
bdms = data['Reservations'][0]['Instances'][0]['BlockDeviceMappings']
self.assertNotEmpty(bdms)
self.assertIn('DeviceName', bdms[0])
self.assertIn('Ebs', bdms[0])
# stop instance to prevent 'busy' state of detached volume
data = self.client.stop_instances(InstanceIds=[instance_id])
self.get_instance_waiter().wait_available(instance_id,
final_set=('stopped'))
self.client.detach_volume(VolumeId=volume_id)
self.get_volume_attachment_waiter().wait_delete(volume_id)
self.cancelResourceCleanUp(clean_vi)
data = self.client.describe_volumes(VolumeIds=[volume_id])
self.assertEqual(1, len(data['Volumes']))
volume = data['Volumes'][0]
self.assertEqual('available', volume['State'])
self.assertEqual(0, len(volume['Attachments']))
self.client.delete_volume(VolumeId=volume_id)
self.cancelResourceCleanUp(clean_v)
self.get_volume_waiter().wait_delete(volume_id)
self.client.terminate_instances(InstanceIds=[instance_id])
self.cancelResourceCleanUp(clean_i)
self.get_instance_waiter().wait_delete(instance_id)
@decorators.idempotent_id('c4b470b7-0825-418f-bc76-533f84247878')
@testtools.skipUnless(CONF.aws.ebs_image_id, "EBS image id is not defined")
def test_attaching_stage(self):
clean_dict = {}
instance_id = self.run_instance(ImageId=CONF.aws.ebs_image_id,
clean_dict=clean_dict)
clean_i = clean_dict['instance']
data = self.client.create_volume(
AvailabilityZone=CONF.aws.aws_zone, Size=1)
volume_id = data['VolumeId']
clean_v = self.addResourceCleanUp(self.client.delete_volume,
VolumeId=volume_id)
self.get_volume_waiter().wait_available(volume_id)
device_name = '/dev/xvdh'
kwargs = {
'Device': device_name,
'InstanceId': instance_id,
'VolumeId': volume_id,
}
data = self.client.attach_volume(*[], **kwargs)
clean_vi = self.addResourceCleanUp(self.client.detach_volume,
VolumeId=volume_id)
self.assertEqual('attaching', data['State'])
if CONF.aws.run_incompatible_tests:
bdt = self.get_instance_bdm(instance_id, device_name)
self.assertIsNotNone(bdt)
self.assertEqual('attaching', bdt['Ebs']['Status'])
self.get_volume_attachment_waiter().wait_available(
volume_id, final_set=('attached'))
# reorder cleanups to avoid error on volume delete
self.cancelResourceCleanUp(clean_i)
clean_i = self.addResourceCleanUp(self.client.terminate_instances,
InstanceIds=[instance_id])
# stop instance to prevent 'busy' state of detached volume
data = self.client.stop_instances(InstanceIds=[instance_id])
self.get_instance_waiter().wait_available(instance_id,
final_set=('stopped'))
self.client.detach_volume(VolumeId=volume_id)
self.get_volume_attachment_waiter().wait_delete(volume_id)
self.cancelResourceCleanUp(clean_vi)
self.client.delete_volume(VolumeId=volume_id)
self.cancelResourceCleanUp(clean_v)
self.get_volume_waiter().wait_delete(volume_id)
self.client.terminate_instances(InstanceIds=[instance_id])
self.cancelResourceCleanUp(clean_i)
self.get_instance_waiter().wait_delete(instance_id)
@decorators.idempotent_id('949ced35-fb66-4e87-afd8-f64de3dd20e9')
@testtools.skipUnless(CONF.aws.run_incompatible_tests,
"Volume statuses are not implemented")
@testtools.skipUnless(CONF.aws.ebs_image_id, "EBS image id is not defined")
def test_delete_detach_attached_volume(self):
instance_id = self.run_instance(ImageId=CONF.aws.ebs_image_id)
kwargs = {
'Size': 1,
'AvailabilityZone': CONF.aws.aws_zone
}
data = self.client.create_volume(*[], **kwargs)
volume_id = data['VolumeId']
clean_v = self.addResourceCleanUp(self.client.delete_volume,
VolumeId=volume_id)
self.get_volume_waiter().wait_available(volume_id)
kwargs = {
'Device': '/dev/sdh',
'InstanceId': instance_id,
'VolumeId': volume_id,
}
self.client.attach_volume(*[], **kwargs)
clean_vi = self.addResourceCleanUp(self.client.detach_volume,
VolumeId=volume_id)
self.get_volume_attachment_waiter().wait_available(
volume_id, final_set=('attached'))
self.assertRaises('VolumeInUse',
self.client.attach_volume,
**kwargs)
kwargs['Device'] = '/dev/sdi'
self.assertRaises('VolumeInUse',
self.client.attach_volume,
**kwargs)
self.assertRaises('VolumeInUse',
self.client.delete_volume,
VolumeId=volume_id)
# stop instance to prevent 'busy' state of detached volume
data = self.client.stop_instances(InstanceIds=[instance_id])
self.get_instance_waiter().wait_available(instance_id,
final_set=('stopped'))
self.client.detach_volume(VolumeId=volume_id)
self.cancelResourceCleanUp(clean_vi)
self.get_volume_attachment_waiter().wait_delete(volume_id)
self.assertRaises('IncorrectState',
self.client.detach_volume,
VolumeId=volume_id)
self.client.delete_volume(VolumeId=volume_id)
self.cancelResourceCleanUp(clean_v)
self.get_volume_waiter().wait_delete(volume_id)
self.assertRaises('InvalidVolume.NotFound',
self.client.detach_volume,
VolumeId=volume_id)
self.client.terminate_instances(InstanceIds=[instance_id])
self.get_instance_waiter().wait_delete(instance_id)
@decorators.idempotent_id('c37b01f7-5b27-4773-9278-9e0b8eaccb5f')
@testtools.skipUnless(CONF.aws.image_id, "image id is not defined")
def test_volume_auto_termination_swithed_off(self):
instance_id = self.run_instance()
kwargs = {
'Size': 1,
'AvailabilityZone': CONF.aws.aws_zone
}
data = self.client.create_volume(*[], **kwargs)
volume_id = data['VolumeId']
clean_v = self.addResourceCleanUp(self.client.delete_volume,
VolumeId=volume_id)
self.get_volume_waiter().wait_available(volume_id)
kwargs = {
'Device': '/dev/sdh',
'InstanceId': instance_id,
'VolumeId': volume_id,
}
self.client.attach_volume(*[], **kwargs)
self.addResourceCleanUp(self.client.detach_volume, VolumeId=volume_id)
self.get_volume_attachment_waiter().wait_available(
volume_id, final_set=('attached'))
self.client.terminate_instances(InstanceIds=[instance_id])
self.get_instance_waiter().wait_delete(instance_id)
data = self.client.describe_volumes(VolumeIds=[volume_id])
self.assertEqual(1, len(data['Volumes']))
volume = data['Volumes'][0]
self.assertEqual('available', volume['State'])
if 'Attachments' in volume:
self.assertEqual(0, len(volume['Attachments']))
self.client.delete_volume(VolumeId=volume_id)
self.cancelResourceCleanUp(clean_v)
self.get_volume_waiter().wait_delete(volume_id)
@decorators.idempotent_id('c8649cab-e1f4-42f7-9578-8e72d06534ba')
@testtools.skipUnless(CONF.aws.run_incompatible_tests,
"modify_instance_attribute is not implemented")
@testtools.skipUnless(CONF.aws.image_id, "image id is not defined")
def test_volume_auto_termination_swithed_on(self):
instance_id = self.run_instance()
kwargs = {
'Size': 1,
'AvailabilityZone': CONF.aws.aws_zone
}
data = self.client.create_volume(*[], **kwargs)
volume_id = data['VolumeId']
self.addResourceCleanUp(self.client.delete_volume, VolumeId=volume_id)
self.get_volume_waiter().wait_available(volume_id)
kwargs = {
'Device': '/dev/sdh',
'InstanceId': instance_id,
'VolumeId': volume_id,
}
self.client.attach_volume(*[], **kwargs)
self.addResourceCleanUp(self.client.detach_volume, VolumeId=volume_id)
self.get_volume_attachment_waiter().wait_available(
volume_id, final_set=('attached'))
kwargs = {
'InstanceId': instance_id,
'BlockDeviceMappings': [{'DeviceName': '/dev/sdh',
'Ebs': {'VolumeId': volume_id,
'DeleteOnTermination': True}}],
}
self.client.modify_instance_attribute(*[], **kwargs)
self.client.terminate_instances(InstanceIds=[instance_id])
self.get_instance_waiter().wait_delete(instance_id)
# volume should be deleted by the Cloud
self.get_volume_waiter().wait_delete(volume_id)

View File

@ -1,208 +0,0 @@
# Copyright 2014 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
from tempest.lib import decorators
import testtools
from ec2api_tempest_plugin import base
from ec2api_tempest_plugin import config
CONF = config.CONF
class VPCTest(base.EC2TestCase):
@classmethod
@base.safe_setup
def setUpClass(cls):
super(VPCTest, cls).setUpClass()
if not base.TesterStateHolder().get_vpc_enabled():
raise cls.skipException('VPC is disabled')
@decorators.idempotent_id('446b19ba-2b70-4f52-9e32-82e04771cb70')
def test_create_delete_vpc(self):
cidr = '10.1.0.0/16'
data = self.client.create_vpc(CidrBlock=cidr)
vpc_id = data['Vpc']['VpcId']
dv_clean = self.addResourceCleanUp(self.client.delete_vpc,
VpcId=vpc_id)
self.assertEqual(cidr, data['Vpc']['CidrBlock'])
if CONF.aws.run_incompatible_tests:
# NOTE(andrey-mp): not ready
self.assertEqual('default', data['Vpc']['InstanceTenancy'])
self.assertIsNotNone(data['Vpc'].get('DhcpOptionsId'))
self.get_vpc_waiter().wait_available(vpc_id)
self.client.delete_vpc(VpcId=vpc_id)
self.cancelResourceCleanUp(dv_clean)
self.get_vpc_waiter().wait_delete(vpc_id)
self.assertRaises('InvalidVpcID.NotFound',
self.client.describe_vpcs,
VpcIds=[vpc_id])
self.assertRaises('InvalidVpcID.NotFound',
self.client.delete_vpc,
VpcId=vpc_id)
@decorators.idempotent_id('de300ce9-41a4-4b88-a991-99186e8c97b4')
def test_create_more_than_one_vpc(self):
cidr = '10.0.0.0/16'
data = self.client.create_vpc(CidrBlock=cidr)
vpc_id1 = data['Vpc']['VpcId']
rc1 = self.addResourceCleanUp(self.client.delete_vpc, VpcId=vpc_id1)
self.get_vpc_waiter().wait_available(vpc_id1)
cidr = '10.1.0.0/16'
data = self.client.create_vpc(CidrBlock=cidr)
vpc_id2 = data['Vpc']['VpcId']
rc2 = self.addResourceCleanUp(self.client.delete_vpc, VpcId=vpc_id2)
self.get_vpc_waiter().wait_available(vpc_id2)
self.client.delete_vpc(VpcId=vpc_id1)
self.cancelResourceCleanUp(rc1)
self.get_vpc_waiter().wait_delete(vpc_id1)
self.client.delete_vpc(VpcId=vpc_id2)
self.cancelResourceCleanUp(rc2)
self.get_vpc_waiter().wait_delete(vpc_id2)
@decorators.idempotent_id('011bd6e0-65c3-4716-a1f3-ba6cdb477b19')
def test_describe_vpcs_base(self):
cidr = '10.1.0.0/16'
data = self.client.create_vpc(CidrBlock=cidr)
vpc_id = data['Vpc']['VpcId']
dv_clean = self.addResourceCleanUp(self.client.delete_vpc,
VpcId=vpc_id)
self.get_vpc_waiter().wait_available(vpc_id)
# NOTE(andrey-mp): by real id
data = self.client.describe_vpcs(VpcIds=[vpc_id])
self.assertEqual(1, len(data['Vpcs']))
# NOTE(andrey-mp): by fake id
self.assertRaises('InvalidVpcID.NotFound',
self.client.describe_vpcs,
VpcIds=['vpc-0'])
self.client.delete_vpc(VpcId=vpc_id)
self.cancelResourceCleanUp(dv_clean)
self.get_vpc_waiter().wait_delete(vpc_id)
@decorators.idempotent_id('9c8735b9-f745-49a0-b68d-33f771bac660')
def test_describe_vpcs_filters(self):
cidr = '10.163.0.0/16'
data = self.client.create_vpc(CidrBlock=cidr)
vpc_id = data['Vpc']['VpcId']
dv_clean = self.addResourceCleanUp(self.client.delete_vpc,
VpcId=vpc_id)
self.get_vpc_waiter().wait_available(vpc_id)
# NOTE(andrey-mp): by filter real cidr
data = self.client.describe_vpcs(
Filters=[{'Name': 'cidr', 'Values': [cidr]}])
self.assertEqual(1, len(data['Vpcs']))
# NOTE(andrey-mp): by filter fake cidr
data = self.client.describe_vpcs(
Filters=[{'Name': 'cidr', 'Values': ['123.0.0.0/16']}])
self.assertEqual(0, len(data['Vpcs']))
# NOTE(andrey-mp): by fake filter
self.assertRaises('InvalidParameterValue',
self.client.describe_vpcs,
Filters=[{'Name': 'fake', 'Values': ['fake']}])
data = self.client.delete_vpc(VpcId=vpc_id)
self.cancelResourceCleanUp(dv_clean)
self.get_vpc_waiter().wait_delete(vpc_id)
@decorators.idempotent_id('3070ea61-992b-4711-a874-322c6c672204')
@testtools.skipUnless(CONF.aws.run_incompatible_tests,
"Invalid request on checking vpc atributes.")
def test_vpc_attributes(self):
cidr = '10.1.0.0/16'
data = self.client.create_vpc(CidrBlock=cidr)
vpc_id = data['Vpc']['VpcId']
dv_clean = self.addResourceCleanUp(self.client.delete_vpc,
VpcId=vpc_id)
self.get_vpc_waiter().wait_available(vpc_id)
self._check_attribute(vpc_id, 'EnableDnsHostnames')
self._check_attribute(vpc_id, 'EnableDnsSupport')
data = self.client.delete_vpc(VpcId=vpc_id)
self.cancelResourceCleanUp(dv_clean)
self.get_vpc_waiter().wait_delete(vpc_id)
def _check_attribute(self, vpc_id, attribute):
req_attr = attribute[0].lower() + attribute[1:]
data = self.client.describe_vpc_attribute(VpcId=vpc_id,
Attribute=req_attr)
attr = data[attribute].get('Value')
self.assertIsNotNone(attr)
kwargs = {'VpcId': vpc_id, attribute: {'Value': not attr}}
data = self.client.modify_vpc_attribute(*[], **kwargs)
data = self.client.describe_vpc_attribute(VpcId=vpc_id,
Attribute=req_attr)
self.assertNotEqual(attr, data[attribute].get('Value'))
@decorators.idempotent_id('8c5f1e82-05da-40e0-8ee8-640db2d94dd6')
def test_create_with_invalid_cidr(self):
def _rollback(fn_data):
self.client.delete_vpc(VpcId=fn_data['Vpc']['VpcId'])
# NOTE(andrey-mp): The largest uses a /16 netmask
self.assertRaises('InvalidVpc.Range',
self.client.create_vpc, rollback_fn=_rollback,
CidrBlock='10.0.0.0/15')
# NOTE(andrey-mp): The smallest VPC you can create uses a /28 netmask
self.assertRaises('InvalidVpc.Range',
self.client.create_vpc, rollback_fn=_rollback,
CidrBlock='10.0.0.0/29')
@decorators.idempotent_id('5abb2ff0-8ea2-4e02-b9a4-95a371982b82')
def test_describe_non_existing_vpc_by_id(self):
vpc_id = 'vpc-00000000'
self.assertRaises('InvalidVpcID.NotFound',
self.client.describe_vpcs,
VpcIds=[vpc_id])
@decorators.idempotent_id('e99d81f1-902a-46b0-afc8-c64e6d548891')
def test_describe_non_existing_vpc_by_cidr(self):
data = self.client.describe_vpcs(
Filters=[{'Name': 'cidr', 'Values': ['123.0.0.0/16']}])
self.assertEqual(0, len(data['Vpcs']))
@decorators.idempotent_id('62263b68-6991-4bbe-b7b2-9997a84fd0a5')
def test_describe_with_invalid_filter(self):
cidr = '10.1.0.0/16'
data = self.client.create_vpc(CidrBlock=cidr)
vpc_id = data['Vpc']['VpcId']
dv_clean = self.addResourceCleanUp(self.client.delete_vpc,
VpcId=vpc_id)
self.get_vpc_waiter().wait_available(vpc_id)
self.assertRaises('InvalidParameterValue',
self.client.describe_vpcs,
Filters=[{'Name': 'unknown', 'Values': ['unknown']}])
data = self.client.delete_vpc(VpcId=vpc_id)
self.cancelResourceCleanUp(dv_clean)
self.get_vpc_waiter().wait_delete(vpc_id)

View File

@ -1,113 +0,0 @@
# Copyright 2014 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import botocore.exceptions
from lxml import etree
from tempest.lib import decorators
from ec2api_tempest_plugin import base
from ec2api_tempest_plugin import config
CONF = config.CONF
class VpnConnectionTest(base.EC2TestCase):
CUSTOMER_GATEWAY_IP = '198.51.100.77'
CUSTOMER_VPN_CIDR = '172.16.25.0/24'
cgw_id = None
vgw_id = None
@classmethod
@base.safe_setup
def setUpClass(cls):
super(VpnConnectionTest, cls).setUpClass()
if not base.TesterStateHolder().get_vpc_enabled():
raise cls.skipException('VPC is disabled')
base.check_vpnaas_enabled()
data = cls.client.create_customer_gateway(
Type='ipsec.1', PublicIp=cls.CUSTOMER_GATEWAY_IP, BgpAsn=65000)
cls.cgw_id = data['CustomerGateway']['CustomerGatewayId']
cls.addResourceCleanUpStatic(
cls.client.delete_customer_gateway, CustomerGatewayId=cls.cgw_id)
cls.get_customer_gateway_waiter().wait_available(cls.cgw_id)
data = cls.client.create_vpn_gateway(
Type='ipsec.1', AvailabilityZone=CONF.aws.aws_zone)
cls.vgw_id = data['VpnGateway']['VpnGatewayId']
cls.addResourceCleanUpStatic(
cls.client.delete_vpn_gateway, VpnGatewayId=cls.vgw_id)
cls.get_vpn_gateway_waiter().wait_available(cls.vgw_id)
@decorators.idempotent_id('57426aab-cf2d-4114-a11d-2bd6642ac606')
def test_create_delete_vpn_connection(self):
data = self.client.create_vpn_connection(
CustomerGatewayId=self.cgw_id, VpnGatewayId=self.vgw_id,
Options={'StaticRoutesOnly': True}, Type='ipsec.1')
vpn_id = data['VpnConnection']['VpnConnectionId']
vpn_clean = self.addResourceCleanUp(
self.client.delete_vpn_connection, VpnConnectionId=vpn_id)
vpn_config = etree.fromstring(
data['VpnConnection']['CustomerGatewayConfiguration'].encode())
psks = vpn_config.xpath(
'/vpn_connection/ipsec_tunnel/ike/pre_shared_key')
self.assertNotEmpty(psks)
self.assertTrue(psks[0].text)
vpn_waiter = self.get_vpn_connection_waiter()
vpn_waiter.wait_available(vpn_id)
self.client.delete_vpn_connection(VpnConnectionId=vpn_id)
self.cancelResourceCleanUp(vpn_clean)
vpn_waiter.wait_delete(vpn_id)
try:
data = self.client.describe_vpn_connections(
VpnConnectionIds=[vpn_id])
self.assertEqual(1, len(data['VpnConnections']))
self.assertEqual('deleted', data['VpnConnections'][0]['State'])
except botocore.exceptions.ClientError as ex:
self.assertEqual('InvalidVpnConnectionID.NotFound',
ex.response['Error']['Code'])
@decorators.idempotent_id('6fa8c58d-876b-4d3f-85ba-e972a9d6db3b')
def test_create_delete_vpn_connection_route(self):
data = self.client.create_vpn_connection(
CustomerGatewayId=self.cgw_id, VpnGatewayId=self.vgw_id,
Options={'StaticRoutesOnly': True}, Type='ipsec.1')
vpn_id = data['VpnConnection']['VpnConnectionId']
self.addResourceCleanUp(
self.client.delete_vpn_connection, VpnConnectionId=vpn_id)
vpn_waiter = self.get_vpn_connection_waiter()
vpn_waiter.wait_available(vpn_id)
data = self.client.create_vpn_connection_route(
VpnConnectionId=vpn_id,
DestinationCidrBlock=self.CUSTOMER_VPN_CIDR)
data = self.client.describe_vpn_connections(VpnConnectionIds=[vpn_id])
self.assertEqual(1, len(data['VpnConnections'][0]['Routes']))
self.assertEqual(
self.CUSTOMER_VPN_CIDR,
data['VpnConnections'][0]['Routes'][0]['DestinationCidrBlock'])
route_waiter = self.get_vpn_connection_route_waiter(
self.CUSTOMER_VPN_CIDR)
route_waiter.wait_available(vpn_id)
data = self.client.delete_vpn_connection_route(
VpnConnectionId=vpn_id,
DestinationCidrBlock=self.CUSTOMER_VPN_CIDR)
data = self.client.describe_vpn_connections(VpnConnectionIds=[vpn_id])
route_waiter.wait_delete(vpn_id)

View File

@ -1,93 +0,0 @@
# Copyright 2014 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import botocore.exceptions
from tempest.lib import decorators
from ec2api_tempest_plugin import base
from ec2api_tempest_plugin import config
CONF = config.CONF
class VpnGatewayTest(base.EC2TestCase):
VPC_CIDR = '10.41.0.0/20'
vpc_id = None
@classmethod
@base.safe_setup
def setUpClass(cls):
super(VpnGatewayTest, cls).setUpClass()
if not base.TesterStateHolder().get_vpc_enabled():
raise cls.skipException('VPC is disabled')
base.check_vpnaas_enabled()
data = cls.client.create_vpc(CidrBlock=cls.VPC_CIDR)
cls.vpc_id = data['Vpc']['VpcId']
cls.get_vpc_waiter().wait_available(cls.vpc_id)
cls.addResourceCleanUpStatic(cls.client.delete_vpc, VpcId=cls.vpc_id)
@decorators.idempotent_id('d38c0185-782c-4da3-b02c-9cd7bf91b001')
def test_create_delete_vpn_gateway(self):
data = self.client.create_vpn_gateway(
Type='ipsec.1', AvailabilityZone=CONF.aws.aws_zone)
vgw_id = data['VpnGateway']['VpnGatewayId']
vgw_clean = self.addResourceCleanUp(
self.client.delete_vpn_gateway, VpnGatewayId=vgw_id)
self.get_vpn_gateway_waiter().wait_available(vgw_id)
self.client.delete_vpn_gateway(VpnGatewayId=vgw_id)
self.cancelResourceCleanUp(vgw_clean)
self.get_vpn_gateway_waiter().wait_delete(vgw_id)
try:
data = self.client.describe_vpn_gateways(
VpnGatewayIds=[vgw_id])
self.assertEqual(1, len(data['VpnGateways']))
self.assertEqual('deleted', data['VpnGateways'][0]['State'])
except botocore.exceptions.ClientError as ex:
self.assertEqual('InvalidVpnGatewayID.NotFound',
ex.response['Error']['Code'])
@decorators.idempotent_id('1d76b335-57ba-449a-9751-af75a8a7d11c')
def test_attach_detach_vpn_gateway(self):
data = self.client.create_vpn_gateway(
Type='ipsec.1', AvailabilityZone=CONF.aws.aws_zone)
vgw_id = data['VpnGateway']['VpnGatewayId']
self.addResourceCleanUp(self.client.delete_vpn_gateway,
VpnGatewayId=vgw_id)
self.get_vpn_gateway_waiter().wait_available(vgw_id)
data = self.client.attach_vpn_gateway(VpnGatewayId=vgw_id,
VpcId=self.vpc_id)
attach_clean = self.addResourceCleanUp(
self.client.detach_vpn_gateway,
VpnGatewayId=vgw_id, VpcId=self.vpc_id)
self.assertIn('VpcAttachment', data)
self.assertEqual(self.vpc_id, data['VpcAttachment']['VpcId'])
attach_waiter = self.get_vpn_gateway_attachment_waiter()
attach_waiter.wait_available(vgw_id, 'attached')
data = self.client.detach_vpn_gateway(VpnGatewayId=vgw_id,
VpcId=self.vpc_id)
self.cancelResourceCleanUp(attach_clean)
attach_waiter.wait_delete(vgw_id)
data = self.client.describe_vpn_gateways(VpnGatewayIds=[vgw_id])
self.assertEqual(
'detached',
(data['VpnGateways'][0]['VpcAttachments'] or
[{'State': 'detached'}])[0]['State'])

View File

@ -1,881 +0,0 @@
# Copyright 2014 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import functools
import logging
import sys
import time
import traceback
import botocore.exceptions
from oslo_log import log
import six
from tempest.lib import base
from tempest.lib import exceptions
import testtools
from ec2api_tempest_plugin import botocoreclient
from ec2api_tempest_plugin import config as cfg
CONF = cfg.CONF
LOG = log.getLogger(__name__)
logging.getLogger('botocore').setLevel(logging.INFO)
logging.getLogger(
'botocore.vendored.requests.packages.urllib3.connectionpool'
).setLevel(logging.WARNING)
logging.getLogger('paramiko.transport').setLevel(logging.WARNING)
class EC2Waiter(object):
def __init__(self, wait_func):
self.wait_func = wait_func
self.default_timeout = CONF.aws.build_timeout
self.default_check_interval = CONF.aws.build_interval
def _state_wait(self, f, f_args=None, f_kwargs=None,
final_set=set(), error_set=('error')):
if not isinstance(final_set, set):
final_set = set((final_set,))
if not isinstance(error_set, set):
error_set = set((error_set,))
interval = self.default_check_interval
start_time = time.time()
args = f_args if f_args is not None else []
kwargs = f_kwargs if f_kwargs is not None else {}
try:
old_status = status = f(*args, **kwargs)
except exceptions.NotFound:
old_status = status = "NotFound"
while True:
if status != old_status:
LOG.info('State transition "%s" ==> "%s" %d second',
old_status, status, time.time() - start_time)
if status in final_set:
return status
if error_set is not None and status in error_set:
raise testtools.TestCase.failureException(
'State changes to error state! '
'While waiting for %s at "%s"' %
(final_set, status))
dtime = time.time() - start_time
if dtime > self.default_timeout:
raise testtools.TestCase.failureException(
'State change timeout exceeded! '
'(%ds) While waiting for %s at "%s"' %
(dtime, final_set, status))
time.sleep(interval)
interval += self.default_check_interval
old_status = status
try:
status = f(*args, **kwargs)
except exceptions.NotFound:
status = "NotFound"
def _state_wait_gone(self, f, f_args=None, f_kwargs=None):
interval = self.default_check_interval
start_time = time.time()
args = f_args if f_args is not None else []
kwargs = f_kwargs if f_kwargs is not None else {}
try:
old_status = status = f(*args, **kwargs)
while True:
if status != old_status:
LOG.info('State transition "%s" ==> "%s" %d second',
old_status, status, time.time() - start_time)
dtime = time.time() - start_time
if dtime > self.default_timeout:
raise testtools.TestCase.failureException(
"State change timeout exceeded while waiting"
" for deleting")
time.sleep(interval)
interval += self.default_check_interval
old_status = status
status = f(*args, **kwargs)
except exceptions.NotFound:
pass
def wait_available(self, obj_id, final_set=('available')):
self._state_wait(self.wait_func, f_args=[obj_id],
final_set=final_set)
def wait_delete(self, obj_id):
self._state_wait_gone(self.wait_func, f_args=[obj_id])
def wait_no_exception(self, *args, **kwargs):
interval = self.default_check_interval
start_time = time.time()
while True:
try:
self.wait_func(*args, **kwargs)
return
except Exception:
pass
dtime = time.time() - start_time
if dtime > self.default_timeout:
raise testtools.TestCase.failureException(
"Timeout exceeded while waiting")
time.sleep(interval)
interval += self.default_check_interval
def wait_for_result(self, *args, **kwargs):
interval = self.default_check_interval
start_time = time.time()
while True:
result = self.wait_func(*args, **kwargs)
if result:
return result
dtime = time.time() - start_time
if dtime > self.default_timeout:
raise testtools.TestCase.failureException(
"Timeout exceeded while waiting")
time.sleep(interval)
interval += self.default_check_interval
def safe_setup(f):
"""A decorator used to wrap the setUpClass for safe setup."""
def decorator(cls):
try:
f(cls)
except Exception as se:
exc_info = sys.exc_info()
LOG.exception("setUpClass failed: %s" % se)
try:
cls.tearDownClass()
except Exception as te:
LOG.exception("tearDownClass failed: %s" % te)
six.reraise(*exc_info)
return decorator
def get_device_name_prefix(device_name):
"""Return device name without device number.
/dev/sda1 -> /dev/sd
/dev/vda -> /dev/vd
"""
dev_num_pos = 0
while '0' <= device_name[dev_num_pos - 1] <= '9':
dev_num_pos -= 1
return device_name[:dev_num_pos - 1]
class TesterStateHolder(object):
ec2_client = None
_instance = None
def __new__(cls, *args, **kwargs):
if not cls._instance:
cls._instance = super(TesterStateHolder, cls).__new__(
cls, *args, **kwargs)
return cls._instance
_ec2_enabled = None
_vpc_enabled = None
def get_ec2_enabled(self):
if self._ec2_enabled is None:
self._fill_attributes()
return self._ec2_enabled
def get_vpc_enabled(self):
if self._vpc_enabled is None:
self._fill_attributes()
return self._vpc_enabled
def _fill_attributes(self):
self._ec2_enabled = False
self._vpc_enabled = False
data = self.ec2_client.describe_account_attributes()
for item in data.get('AccountAttributes', []):
if item['AttributeName'] == 'supported-platforms':
for value in item['AttributeValues']:
if value['AttributeValue'] == 'VPC':
self._vpc_enabled = True
if value['AttributeValue'] == 'EC2':
self._ec2_enabled = True
def skip_without_ec2(*args, **kwargs):
"""A decorator useful to skip tests if EC2-classic is not supported."""
def decorator(f):
@functools.wraps(f)
def wrapper(self, *func_args, **func_kwargs):
if not TesterStateHolder().get_ec2_enabled():
msg = "Skipped because EC2-classic is not enabled"
raise testtools.TestCase.skipException(msg)
return f(self, *func_args, **func_kwargs)
return wrapper
return decorator
def skip_without_vpc(*args, **kwargs):
"""A decorator useful to skip tests if VPC is not supported."""
def decorator(f):
@functools.wraps(f)
def wrapper(self, *func_args, **func_kwargs):
if not TesterStateHolder().get_vpc_enabled():
msg = "Skipped because VPC is disabled"
raise testtools.TestCase.skipException(msg)
return f(self, *func_args, **func_kwargs)
return wrapper
return decorator
def check_vpnaas_enabled():
if not CONF.aws.vpnaas_enabled:
msg = ("Skipped VPN test as vpnaas is not available")
raise testtools.TestCase.skipException(msg)
def skip_without_vpnaas_enabled(*args, **kwargs):
"""A decorator useful to skip tests without specified network extension."""
def decorator(f):
@functools.wraps(f)
def wrapper(self, *func_args, **func_kwargs):
check_vpnaas_enabled()
return f(self, *func_args, **func_kwargs)
return wrapper
return decorator
class EC2TestCase(base.BaseTestCase):
"""Recommended to use as base class for boto related test."""
# The trash contains cleanup functions and paramaters in tuples
# (function, *args, **kwargs)
_global_resource_trash_bin = {}
_global_sequence = -1
@classmethod
@safe_setup
def setUpClass(cls):
super(EC2TestCase, cls).setUpClass()
if not CONF.service_available.ec2api:
raise cls.skipException("ec2api is disabled")
cls.client = botocoreclient.get_ec2_client(
CONF.aws.ec2_url, CONF.aws.aws_region,
CONF.aws.aws_access, CONF.aws.aws_secret,
CONF.aws.ca_bundle)
cls.s3_client = botocoreclient.get_s3_client(
CONF.aws.s3_url, CONF.aws.aws_region,
CONF.aws.aws_access, CONF.aws.aws_secret,
CONF.aws.ca_bundle)
TesterStateHolder().ec2_client = cls.client
@classmethod
def addResourceCleanUpStatic(cls, function, *args, **kwargs):
"""Adds CleanUp callable, used by tearDownClass.
Recommended to a use (deep)copy on the mutable args.
"""
tb = traceback.extract_stack(limit=2)
cls._global_sequence = cls._global_sequence + 1
cls._global_resource_trash_bin[cls._global_sequence] = (function,
args, kwargs,
tb[0])
return cls._global_sequence
def setUp(self):
super(EC2TestCase, self).setUp()
self._resource_trash_bin = {}
self._sequence = -1
def tearDown(self):
fail_count = self.cleanUp(self._resource_trash_bin)
super(EC2TestCase, self).tearDown()
if fail_count:
raise exceptions.TempestException("%d cleanUp operation failed"
% fail_count)
def addResourceCleanUp(self, function, *args, **kwargs):
"""Adds CleanUp callable, used by tearDown.
Recommended to a use (deep)copy on the mutable args.
"""
tb = traceback.extract_stack(limit=2)[0]
self._sequence = self._sequence + 1
self._resource_trash_bin[self._sequence] = (function, args, kwargs, tb)
LOG.debug("For cleaning up: %s\n From: %s" %
(self.friendly_function_call_str(function, *args, **kwargs),
str((tb[0], tb[1], tb[2]))))
return self._sequence
def cancelResourceCleanUp(self, key):
"""Cancel Clean up request."""
del self._resource_trash_bin[key]
# NOTE(andrey-mp): if ERROR in responce_code then treat object as deleted
_VALID_CLEANUP_ERRORS = [
'NotFound',
'Gateway.NotAttached'
]
# NOTE(andrey-mp): function must return boolean - should we retry
# deleting or not
_HOOKED_CLEANUP_ERRORS = {
('delete_vpc', 'DependencyViolation'): (
'delete_vpc_failed',
lambda kwargs: kwargs['VpcId'])
}
_CLEANUP_WAITERS = {
'delete_vpc': (
'get_vpc_waiter',
lambda kwargs: kwargs['VpcId']),
'delete_subnet': (
'get_subnet_waiter',
lambda kwargs: kwargs['SubnetId']),
'delete_network_interface': (
'get_network_interface_waiter',
lambda kwargs: kwargs['NetworkInterfaceId']),
'terminate_instances': (
'get_instance_waiter',
lambda kwargs: kwargs['InstanceIds'][0]),
'delete_volume': (
'get_volume_waiter',
lambda kwargs: kwargs['VolumeId']),
'detach_volume': (
'get_volume_attachment_waiter',
lambda kwargs: kwargs['VolumeId']),
'delete_snapshot': (
'get_snapshot_waiter',
lambda kwargs: kwargs['SnapshotId']),
'deregister_image': (
'get_image_waiter',
lambda kwargs: kwargs['ImageId']),
'detach_vpn_gateway': (
'get_vpn_gateway_attachment_waiter',
lambda kwargs: kwargs['VpnGatewayId']),
'delete_vpn_connection': (
'get_vpn_connection_waiter',
lambda kwargs: kwargs['VpnConnectionId']),
'delete_customer_gateway': (
'get_customer_gateway_waiter',
lambda kwargs: kwargs['CustomerGatewayId']),
'delete_vpn_gateway': (
'get_vpn_gateway_waiter',
lambda kwargs: kwargs['VpnGatewayId']),
'disassociate_address': (
'get_address_assoc_waiter',
lambda kwargs: kwargs),
}
@classmethod
def tearDownClass(cls):
fail_count = cls.cleanUp(cls._global_resource_trash_bin)
super(EC2TestCase, cls).tearDownClass()
if fail_count:
raise exceptions.TempestException("%d cleanUp operation failed"
% fail_count)
@classmethod
def cleanUp(cls, trash_bin):
"""Calls the callables added by addResourceCleanUp,
when you overwire this function dont't forget to call this too.
"""
fail_count = 0
trash_keys = sorted(trash_bin, reverse=True)
for key in trash_keys:
(function, pos_args, kw_args, tb) = trash_bin[key]
try:
LOG.debug("Cleaning up: %s\n From: %s" %
(cls.friendly_function_call_str(function, *pos_args,
**kw_args),
str((tb[0], tb[1], tb[2]))))
res = cls.cleanUpItem(function, pos_args, kw_args)
if not res:
fail_count += 1
LOG.error('Failure in cleanup for: %s' % str(kw_args))
except BaseException:
fail_count += 1
LOG.exception('Failure in cleanup for: %s' % str(kw_args))
finally:
del trash_bin[key]
return fail_count
@classmethod
def cleanUpItem(cls, function, pos_args, kw_args):
attempts_left = 10
interval = 1
deleted = False
while not deleted and attempts_left > 0:
try:
function(*pos_args, **kw_args)
deleted = True
key = function.__name__
if key in cls._CLEANUP_WAITERS:
(waiter, obj_id) = cls._CLEANUP_WAITERS[key]
waiter = getattr(cls, waiter)
obj_id = obj_id(kw_args)
try:
waiter().wait_delete(obj_id)
except botocore.exceptions.ClientError:
LOG.exception('Exception occurred in cleanup waiting')
return False
except botocore.exceptions.ClientError as e:
error_code = e.response['Error']['Code']
for err in cls._VALID_CLEANUP_ERRORS:
if err in error_code:
deleted = True
break
else:
hook_res = False
key = (function.__name__, error_code)
if key in cls._HOOKED_CLEANUP_ERRORS:
(hook, obj_id) = cls._HOOKED_CLEANUP_ERRORS[key]
hook = getattr(cls, hook)
obj_id = obj_id(kw_args)
hook_res = hook(obj_id)
if not hook_res:
LOG.error('Cleanup failed: %s', e, exc_info=True)
return False
LOG.error('Retrying cleanup due to: %s', e)
time.sleep(interval)
attempts_left -= 1
interval += 1
return deleted
@classmethod
def friendly_function_name_simple(cls, call_able):
name = ""
if hasattr(call_able, "im_class"):
name += call_able.im_class.__name__ + "."
name += call_able.__name__
return name
@classmethod
def friendly_function_call_str(cls, call_able, *args, **kwargs):
string = cls.friendly_function_name_simple(call_able)
string += "(" + ", ".join(map(str, args))
if len(kwargs):
if len(args):
string += ", "
string += ", ".join("=".join(map(str, (key, value)))
for (key, value) in kwargs.items())
return string + ")"
@classmethod
def _vpc_get_state(cls, vpc_id):
try:
data = cls.client.describe_vpcs(VpcIds=[vpc_id])
if not data['Vpcs']:
raise exceptions.NotFound()
return data['Vpcs'][0]['State']
except botocore.exceptions.ClientError:
error_code = sys.exc_info()[1].response['Error']['Code']
if error_code == 'InvalidVpcID.NotFound':
raise exceptions.NotFound()
raise
@classmethod
def get_vpc_waiter(cls):
return EC2Waiter(cls._vpc_get_state)
@classmethod
def _subnet_get_state(cls, subnet_id):
try:
data = cls.client.describe_subnets(SubnetIds=[subnet_id])
if not data['Subnets']:
raise exceptions.NotFound()
return data['Subnets'][0]['State']
except botocore.exceptions.ClientError:
error_code = sys.exc_info()[1].response['Error']['Code']
if error_code == 'InvalidSubnetID.NotFound':
raise exceptions.NotFound()
raise
@classmethod
def get_subnet_waiter(cls):
return EC2Waiter(cls._subnet_get_state)
@classmethod
def _address_assoc_get_state(cls, kwargs):
try:
ip = kwargs.get('PublicIp')
alloc_id = kwargs.get('AllocationId')
assoc_id = kwargs.get('AssociationId')
if ip:
data = cls.client.describe_addresses(PublicIps=[ip])
elif alloc_id:
data = cls.client.describe_addresses(AllocationIds=[alloc_id])
elif assoc_id:
data = cls.client.describe_addresses(
Filters=[{'Name': 'association-id', 'Values': [assoc_id]}])
LOG.debug('Addresses: %s' % str(data.get('Addresses')))
if ('Addresses' in data and len(data['Addresses']) == 1 and
data['Addresses'][0].get('InstanceId')):
return 'available'
raise exceptions.NotFound()
except botocore.exceptions.ClientError:
raise exceptions.NotFound()
@classmethod
def get_address_assoc_waiter(cls):
return EC2Waiter(cls._address_assoc_get_state)
@classmethod
def _instance_get_state(cls, instance_id):
try:
data = cls.client.describe_instances(InstanceIds=[instance_id])
if not data['Reservations']:
raise exceptions.NotFound()
if not data['Reservations'][0]['Instances']:
raise exceptions.NotFound()
state = data['Reservations'][0]['Instances'][0]['State']['Name']
if state != 'terminated':
return state
raise exceptions.NotFound()
except botocore.exceptions.ClientError:
error_code = sys.exc_info()[1].response['Error']['Code']
if error_code == 'InvalidInstanceID.NotFound':
raise exceptions.NotFound()
raise
@classmethod
def get_instance_waiter(cls):
return EC2Waiter(cls._instance_get_state)
@classmethod
def _network_interface_get_state(cls, ni_id):
try:
data = cls.client.describe_network_interfaces(
NetworkInterfaceIds=[ni_id])
if not data['NetworkInterfaces']:
raise exceptions.NotFound()
return data['NetworkInterfaces'][0]['Status']
except botocore.exceptions.ClientError:
error_code = sys.exc_info()[1].response['Error']['Code']
if error_code == 'InvalidNetworkInterfaceID.NotFound':
raise exceptions.NotFound()
raise
@classmethod
def get_network_interface_waiter(cls):
return EC2Waiter(cls._network_interface_get_state)
@classmethod
def _volume_get_state(cls, volume_id):
try:
data = cls.client.describe_volumes(VolumeIds=[volume_id])
if not data['Volumes']:
raise exceptions.NotFound()
return data['Volumes'][0]['State']
except botocore.exceptions.ClientError:
error_code = sys.exc_info()[1].response['Error']['Code']
if error_code == 'InvalidVolume.NotFound':
raise exceptions.NotFound()
raise
@classmethod
def get_volume_waiter(cls):
return EC2Waiter(cls._volume_get_state)
@classmethod
def _volume_attachment_get_state(cls, volume_id):
try:
data = cls.client.describe_volumes(VolumeIds=[volume_id])
volume = data['Volumes'][0]
if 'Attachments' in volume and len(volume['Attachments']) > 0:
return volume['Attachments'][0]['State']
raise exceptions.NotFound()
except botocore.exceptions.ClientError:
error_code = sys.exc_info()[1].response['Error']['Code']
if error_code == 'InvalidVolume.NotFound':
raise exceptions.NotFound()
raise
@classmethod
def get_volume_attachment_waiter(cls):
return EC2Waiter(cls._volume_attachment_get_state)
@classmethod
def _snapshot_get_state(cls, snapshot_id):
try:
data = cls.client.describe_snapshots(SnapshotIds=[snapshot_id])
if not data['Snapshots']:
raise exceptions.NotFound()
return data['Snapshots'][0]['State']
except botocore.exceptions.ClientError:
error_code = sys.exc_info()[1].response['Error']['Code']
if error_code == 'InvalidSnapshot.NotFound':
raise exceptions.NotFound()
raise
@classmethod
def get_snapshot_waiter(cls):
return EC2Waiter(cls._snapshot_get_state)
@classmethod
def _image_get_state(cls, image_id):
try:
data = cls.client.describe_images(ImageIds=[image_id])
if not data['Images']:
raise exceptions.NotFound()
return data['Images'][0]['State']
except botocore.exceptions.ClientError:
error_code = sys.exc_info()[1].response['Error']['Code']
if error_code == 'InvalidAMIID.NotFound':
raise exceptions.NotFound()
raise
@classmethod
def get_image_waiter(cls):
return EC2Waiter(cls._image_get_state)
@classmethod
def _vpn_gateway_get_attachment_state(cls, vpn_gateway_id):
try:
data = cls.client.describe_vpn_gateways(
VpnGatewayIds=[vpn_gateway_id])
attachments = data['VpnGateways'][0].get('VpcAttachments')
if (not attachments or
attachments[0]['State'] == 'detached'):
raise exceptions.NotFound()
return attachments[0]['State']
except botocore.exceptions.ClientError as ex:
error_code = ex.response['Error']['Code']
if error_code == 'InvalidVpnGatewayID.NotFound':
raise exceptions.NotFound()
raise
@classmethod
def get_vpn_gateway_attachment_waiter(cls):
return EC2Waiter(cls._vpn_gateway_get_attachment_state)
@classmethod
def _vpn_object_get_state(cls, func, kwargs, data_key, error_not_found):
# NOTE(andrey-mp): use this for vpn_connection, vpn_gateway,
# customer_gateway due to similar states
try:
data = func(**kwargs)
if not data[data_key]:
raise exceptions.NotFound()
if data[data_key][0]['State'] == 'deleted':
raise exceptions.NotFound()
return data[data_key][0]['State']
except botocore.exceptions.ClientError as ex:
error_code = ex.response['Error']['Code']
if error_code == error_not_found:
raise exceptions.NotFound()
raise
@classmethod
def _vpn_connection_get_state(cls, vpn_connection_id):
return cls._vpn_object_get_state(
cls.client.describe_vpn_connections,
{'VpnConnectionIds': [vpn_connection_id]},
'VpnConnections',
'InvalidVpnConnectionID.NotFound')
@classmethod
def get_vpn_connection_waiter(cls):
return EC2Waiter(cls._vpn_connection_get_state)
@classmethod
def _customer_gateway_get_state(cls, customer_gateway_id):
return cls._vpn_object_get_state(
cls.client.describe_customer_gateways,
{'CustomerGatewayIds': [customer_gateway_id]},
'CustomerGateways',
'InvalidCustomerGatewayID.NotFound')
@classmethod
def get_customer_gateway_waiter(cls):
return EC2Waiter(cls._customer_gateway_get_state)
@classmethod
def _vpn_gateway_get_state(cls, vpn_gateway_id):
return cls._vpn_object_get_state(
cls.client.describe_vpn_gateways,
{'VpnGatewayIds': [vpn_gateway_id]},
'VpnGateways',
'InvalidVpnGatewayID.NotFound')
@classmethod
def get_vpn_gateway_waiter(cls):
return EC2Waiter(cls._vpn_gateway_get_state)
@classmethod
def _vpn_connection_get_route_state(cls, vpn_connection_id,
destination_cidr_block=None):
try:
data = cls.client.describe_vpn_connections(
VpnConnectionIds=[vpn_connection_id])
try:
route = next(
r for r in data['VpnConnections'][0]['Routes']
if r['DestinationCidrBlock'] == destination_cidr_block)
except StopIteration:
raise exceptions.NotFound()
if route['State'] == 'deleted':
raise exceptions.NotFound()
return route['State']
except botocore.exceptions.ClientError as ex:
error_code = ex.response['Error']['Code']
if error_code == 'InvalidVpnGatewayID.NotFound':
raise exceptions.NotFound()
raise
@classmethod
def get_vpn_connection_route_waiter(cls, destination_cidr_block):
return EC2Waiter(
functools.partial(cls._vpn_connection_get_route_state,
destination_cidr_block=destination_cidr_block))
@classmethod
def _vpn_connection_get_tunnel_up_state(cls, vpn_connection_id):
data = cls.client.describe_vpn_connections(
VpnConnectionIds=[vpn_connection_id])
for item in data['VpnConnections'][0].get('VgwTelemetry', []):
if 'UP' == item['Status']:
return 'UP'
raise exceptions.NotFound()
@classmethod
def get_vpn_connection_tunnel_waiter(cls):
return EC2Waiter(cls._vpn_connection_get_tunnel_up_state)
@classmethod
def delete_vpc_failed(cls, vpc_id):
try:
LOG.warning('VpnGateways: ' +
str(cls.client.describe_vpn_gateways(
Filters=[{'Name': 'attachment.vpc-id', 'Values': [vpc_id]}]
)['VpnGateways']))
LOG.warning('RouteTables: ' +
str(cls.client.describe_route_tables(
Filters=[{'Name': 'vpc-id', 'Values': [vpc_id]}]
)['RouteTables']))
return True
except Exception:
LOG.exception('Error occurred during "delete_vpc_failed" hook')
return False
def assertEmpty(self, list_obj, msg=None):
self.assertTrue(len(list_obj) == 0, msg)
def assertNotEmpty(self, list_obj, msg=None):
self.assertTrue(len(list_obj) > 0, msg)
def assertRaises(self, error_code, fn, rollback_fn=None, **kwargs):
try:
fn_data = fn(**kwargs)
if rollback_fn:
try:
rollback_fn(fn_data)
except Exception:
LOG.exception('Rollback failed')
msg = ("%s hasn't returned exception for params %s"
% (str(fn.__name__), str(kwargs)))
raise self.failureException(msg)
except botocore.exceptions.ClientError as e:
self.assertEqual(error_code, e.response['Error']['Code'])
# NOTE(andrey-mp): Helpers zone
def get_instance(self, instance_id):
data = self.client.describe_instances(InstanceIds=[instance_id])
self.assertEqual(1, len(data.get('Reservations', [])))
instances = data['Reservations'][0].get('Instances', [])
self.assertEqual(1, len(instances))
return instances[0]
def get_instance_bdm(self, instance_id, device_name):
# device_name=None means getting bdm of root instance device
instance = self.get_instance(instance_id)
if not device_name:
device_name = instance.get('RootDeviceName')
if not device_name:
return None
bdms = instance.get('BlockDeviceMappings')
if bdms is None:
return None
bdt = [bdt for bdt in bdms if bdt['DeviceName'] == device_name]
return None if len(bdt) == 0 else bdt[0]
def run_instance(self, clean_dict=None, **kwargs):
kwargs.setdefault('ImageId', CONF.aws.image_id)
kwargs.setdefault('InstanceType', CONF.aws.instance_type)
kwargs.setdefault('Placement', {'AvailabilityZone': CONF.aws.aws_zone})
kwargs['MinCount'] = 1
kwargs['MaxCount'] = 1
data = self.client.run_instances(*[], **kwargs)
instance_id = data['Instances'][0]['InstanceId']
res_clean = self.addResourceCleanUp(self.client.terminate_instances,
InstanceIds=[instance_id])
self.get_instance_waiter().wait_available(instance_id,
final_set=('running'))
if clean_dict is not None:
clean_dict['instance'] = res_clean
return instance_id
def create_vpc_and_subnet(self, cidr):
data = self.client.create_vpc(CidrBlock=cidr)
vpc_id = data['Vpc']['VpcId']
self.addResourceCleanUp(self.client.delete_vpc, VpcId=vpc_id)
self.get_vpc_waiter().wait_available(vpc_id)
data = self.client.create_subnet(VpcId=vpc_id, CidrBlock=cidr,
AvailabilityZone=CONF.aws.aws_zone)
subnet_id = data['Subnet']['SubnetId']
self.addResourceCleanUp(self.client.delete_subnet, SubnetId=subnet_id)
return vpc_id, subnet_id
def prepare_route(self, vpc_id, gw_id):
data = self.client.describe_route_tables(
Filters=[{'Name': 'vpc-id', 'Values': [vpc_id]}])
self.assertEqual(1, len(data['RouteTables']))
route_table_id = data['RouteTables'][0]['RouteTableId']
kwargs = {
'DestinationCidrBlock': '0.0.0.0/0',
'RouteTableId': route_table_id,
'GatewayId': gw_id
}
self.client.create_route(*[], **kwargs)
return route_table_id
def create_and_attach_internet_gateway(self, vpc_id):
data = self.client.create_internet_gateway()
gw_id = data['InternetGateway']['InternetGatewayId']
self.addResourceCleanUp(self.client.delete_internet_gateway,
InternetGatewayId=gw_id)
data = self.client.attach_internet_gateway(VpcId=vpc_id,
InternetGatewayId=gw_id)
self.addResourceCleanUp(self.client.detach_internet_gateway,
VpcId=vpc_id,
InternetGatewayId=gw_id)
return gw_id

View File

@ -1,45 +0,0 @@
# Copyright 2015 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import botocore.session
from oslo_config import types
def _get_client(client_name, url, region, access, secret, ca_bundle):
connection_data = {
'config_file': (None, 'AWS_CONFIG_FILE', None, None),
'region': ('region', 'AWS_DEFAULT_REGION', region, None),
}
session = botocore.session.get_session(connection_data)
kwargs = {
'region_name': region,
'endpoint_url': url,
'aws_access_key_id': access,
'aws_secret_access_key': secret
}
if ca_bundle:
try:
kwargs['verify'] = types.Boolean()(ca_bundle)
except Exception:
kwargs['verify'] = ca_bundle
return session.create_client(client_name, **kwargs)
def get_ec2_client(url, region, access, secret, ca_bundle=None):
return _get_client('ec2', url, region, access, secret, ca_bundle)
def get_s3_client(url, region, access, secret, ca_bundle=None):
return _get_client('s3', url, region, access, secret, ca_bundle)

View File

@ -1,88 +0,0 @@
# Copyright 2012 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import logging as std_logging
import os
from oslo_config import cfg
from oslo_log import log as logging
from ec2api_tempest_plugin import config_opts
LOG = logging.getLogger('ec2api')
# this should never be called outside of this class
class ConfigPrivate(object):
"""Provides OpenStack configuration information."""
DEFAULT_CONFIG_FILE = "functional_tests.conf"
def __init__(self):
"""Initialize a configuration from a conf directory and conf file."""
super(ConfigPrivate, self).__init__()
# if this was run from tempest runner then config already parsed
if config_opts.aws_group.name in cfg.CONF:
self.aws = cfg.CONF.aws
self.service_available = cfg.CONF.service_available
return
# Environment variables override defaults...
conf_file = os.environ.get('TEST_CONFIG', self.DEFAULT_CONFIG_FILE)
conf_dirs = list()
if os.environ.get('TEST_CONFIG_DIR'):
conf_dirs.append(os.environ.get('TEST_CONFIG_DIR'))
conf_dirs.append('.')
conf_dirs.append(os.path.dirname(os.path.dirname(
os.path.dirname(os.path.dirname(__file__)))))
for _dir in conf_dirs:
path = os.path.join(_dir, conf_file)
if os.path.isfile(path):
break
else:
raise Exception('Config could not be found')
LOG.info("Using ec2api config file %s" % path)
conf = cfg.CONF
conf([], project='ec2api', default_config_files=[path])
conf.register_group(config_opts.aws_group)
group_name = config_opts.aws_group.name
for opt in config_opts.AWSGroup:
conf.register_opt(opt, group=group_name)
self.aws = cfg.CONF.aws
conf.register_group(config_opts.service_available_group)
group_name = config_opts.service_available_group.name
for opt in config_opts.ServiceAvailableGroup:
conf.register_opt(opt, group=group_name)
self.service_available = cfg.CONF.service_available
conf.log_opt_values(LOG, std_logging.DEBUG)
class ConfigProxy(object):
_config = None
def __getattr__(self, attr):
if not self._config:
self._config = ConfigPrivate()
return getattr(self._config, attr)
CONF = ConfigProxy()

View File

@ -1,99 +0,0 @@
# Copyright 2012 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
from oslo_config import cfg
service_available_group = cfg.OptGroup(name="service_available",
title="Available OpenStack Services")
ServiceAvailableGroup = [
cfg.BoolOpt("ec2api",
default=True,
help="Whether or not ec2-api is expected to be available"),
]
aws_group = cfg.OptGroup(name='aws',
title='AWS options')
AWSGroup = [
cfg.StrOpt('ec2_url',
default="http://localhost:8788/",
help="EC2 URL"),
cfg.StrOpt('s3_url',
default="http://localhost:3334/",
help="S3 URL"),
cfg.StrOpt('ca_bundle',
default=None,
help="The CA certificate bundle to use when verifying "
"SSL certificates. Or True/False to pass to botocore."),
cfg.StrOpt('aws_secret',
default=None,
help="AWS Secret Key",
secret=True),
cfg.StrOpt('aws_access',
default=None,
help="AWS Access Key"),
cfg.StrOpt('aws_region',
default="RegionOne",
help="AWS region for EC2 tests"),
cfg.StrOpt('aws_zone',
default='nova',
help="AWS zone inside region for EC2 tests"),
cfg.IntOpt('build_timeout',
default=120,
help="Status Change Timeout"),
cfg.IntOpt('build_interval',
default=1,
help="Status Change Test Interval"),
cfg.StrOpt('instance_type',
default="m1.tiny",
help="Instance type"),
cfg.StrOpt('instance_type_alt',
default=None,
help="Instance type"),
cfg.StrOpt('image_id',
default=None,
help="Image ID for instance running(can be cirros). "
"It must be any instance with instance-store "
"root device type."),
cfg.StrOpt('ebs_image_id',
default=None,
help="EBS Image ID for testing snapshots, volumes, instances."),
cfg.StrOpt('image_user',
default='cirros',
help="User for sshing into instance based on configured image"),
cfg.StrOpt('image_id_ubuntu',
default=None,
help="Fully functional image ID for instance running. "
"For some tests it must be ubuntu-trusty-i386."),
cfg.StrOpt('image_user_ubuntu',
default='ubuntu',
help="User for sshing into instance based on configured image"),
cfg.BoolOpt('run_incompatible_tests',
default=False,
help='Will run all tests plus incompatible with Amazon.'),
cfg.BoolOpt('run_long_tests',
default=False,
help='Will run all long tests also.'),
cfg.StrOpt('ami_image_location',
default=None,
help="S3 URL with manifest of AMI Machine Image."),
cfg.BoolOpt('run_ssh',
default=True,
help='Can block all tests that wants to ssh into instance.'),
cfg.BoolOpt('vpnaas_enabled',
default=False,
help='Enable VPN-related tests'),
]

View File

@ -1,52 +0,0 @@
# Copyright 2012 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import os
from tempest import config
from tempest.test_discover import plugins
from ec2api_tempest_plugin import config_opts as aws_config
class AWSTempestPlugin(plugins.TempestPlugin):
def load_tests(self):
base_path = os.path.split(os.path.dirname(
os.path.abspath(__file__)))[0]
test_dir = "ec2api_tempest_plugin"
full_test_dir = os.path.join(base_path, test_dir)
return full_test_dir, base_path
def register_opts(self, conf):
group_name = aws_config.service_available_group.name
if group_name not in conf:
config.register_opt_group(
conf, aws_config.service_available_group,
aws_config.ServiceAvailableGroup)
else:
for opt in aws_config.ServiceAvailableGroup:
conf.register_opt(opt, group=group_name)
if aws_config.aws_group.name not in conf:
config.register_opt_group(conf, aws_config.aws_group,
aws_config.AWSGroup)
def get_opt_lists(self):
return [
(aws_config.service_available_group.name,
aws_config.ServiceAvailableGroup),
(aws_config.aws_group.name,
aws_config.AWSGroup)
]

View File

@ -1,135 +0,0 @@
# Copyright 2015 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import time
from oslo_log import log
from tempest.lib.common.utils import data_utils
from ec2api_tempest_plugin import base
from ec2api_tempest_plugin import config
CONF = config.CONF
LOG = log.getLogger(__name__)
class BaseScenarioTest(base.EC2TestCase):
def get_instance_ip(self, instance_id):
instance = self.get_instance(instance_id)
public_ip = instance.get('PublicIpAddress')
if public_ip:
return public_ip
is_vpc = 'VpcId' in instance
alloc_id, public_ip = self.allocate_address(is_vpc)
kwargs = {'InstanceId': instance_id}
if is_vpc:
kwargs['AllocationId'] = alloc_id
else:
kwargs['PublicIp'] = public_ip
data = self.client.associate_address(*[], **kwargs)
if is_vpc:
self.addResourceCleanUp(self.client.disassociate_address,
AssociationId=data['AssociationId'])
self.get_address_assoc_waiter().wait_available(
{'AllocationId': alloc_id})
else:
self.addResourceCleanUp(self.client.disassociate_address,
PublicIp=public_ip)
self.get_address_assoc_waiter().wait_available(
{'PublicIp': public_ip})
return public_ip
def allocate_address(self, is_vpc):
kwargs = dict()
if is_vpc:
kwargs['Domain'] = 'vpc'
data = self.client.allocate_address(*[], **kwargs)
alloc_id = data.get('AllocationId')
public_ip = data['PublicIp']
if is_vpc:
self.addResourceCleanUp(self.client.release_address,
AllocationId=alloc_id)
else:
self.addResourceCleanUp(self.client.release_address,
PublicIp=public_ip)
return alloc_id, public_ip
def create_key_pair(self, key_name):
data = self.client.create_key_pair(KeyName=key_name)
self.addResourceCleanUp(self.client.delete_key_pair, KeyName=key_name)
return data.get('KeyMaterial')
def create_standard_security_group(self):
name = data_utils.rand_name('sgName')
desc = data_utils.rand_name('sgDesc')
kwargs = {'GroupName': name, 'Description': desc}
self.client.create_security_group(*[], **kwargs)
self.addResourceCleanUp(self.client.delete_security_group,
GroupName=name)
time.sleep(2)
kwargs = {
'GroupName': name,
'IpPermissions': [{
'IpProtocol': 'icmp',
'FromPort': -1,
'ToPort': -1,
'IpRanges': [{
'CidrIp': '0.0.0.0/0'
}],
}, {
'IpProtocol': 'tcp',
'FromPort': 22,
'ToPort': 22,
'IpRanges': [{
'CidrIp': '0.0.0.0/0'
}],
}]
}
self.client.authorize_security_group_ingress(*[], **kwargs)
return name
def prepare_vpc_default_security_group(self, vpc_id):
data = self.client.describe_security_groups(
Filters=[{'Name': 'vpc-id', 'Values': [vpc_id]}])
self.assertEqual(1, len(data['SecurityGroups']))
group_id = data['SecurityGroups'][0]['GroupId']
kwargs = {
'GroupId': group_id,
'IpPermissions': [{
'IpProtocol': '-1',
'FromPort': -1,
'ToPort': -1,
'IpRanges': [{
'CidrIp': '0.0.0.0/0'
}],
}]
}
self.client.authorize_security_group_ingress(*[], **kwargs)
def create_network_interface(self, subnet_id):
data = self.client.create_network_interface(SubnetId=subnet_id)
ni_id = data['NetworkInterface']['NetworkInterfaceId']
self.addResourceCleanUp(self.client.delete_network_interface,
NetworkInterfaceId=ni_id)
self.get_network_interface_waiter().wait_available(ni_id)
return ni_id

View File

@ -1,452 +0,0 @@
# Copyright 2014
# The Cloudscaling Group, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import math
from oslo_log import log
from tempest.lib.common.utils import data_utils
from tempest.lib import decorators
import testtools
from ec2api_tempest_plugin import base
from ec2api_tempest_plugin import config
CONF = config.CONF
LOG = log.getLogger(__name__)
class EC2_EBSInstanceTuneBDM(base.EC2TestCase):
"""Test change root device attributes at instance launch."""
@classmethod
@base.safe_setup
def setUpClass(cls):
super(EC2_EBSInstanceTuneBDM, cls).setUpClass()
if not CONF.aws.ebs_image_id:
raise cls.skipException('aws EBS image does not provided')
cls.image_id = CONF.aws.ebs_image_id
cls.zone = CONF.aws.aws_zone
data = cls.client.describe_images(ImageIds=[cls.image_id])
assert 1 == len(data['Images'])
image = data['Images'][0]
cls.root_device_name = image['RootDeviceName']
bdm = image['BlockDeviceMappings']
bdm = [v for v in bdm if v['DeviceName'] == cls.root_device_name]
assert 1 == len(bdm)
ebs = bdm[0]['Ebs']
cls.root_device_size = ebs.get('VolumeSize')
if not cls.root_device_size:
snapshotId = ebs.get('SnapshotId')
data = cls.client.describe_snapshots(SnapshotIds=[snapshotId])
assert 1 == len(data['Snapshots'])
cls.root_device_size = data['Snapshots'][0]['VolumeSize']
@decorators.idempotent_id('2f51dd78-ff1e-494a-bcbc-f47580df17cb')
def test_launch_ebs_instance_with_persistent_root_device(self):
"""Launch EBS-backed instance with persistent root device"""
instance_id = self.run_instance(ImageId=self.image_id,
BlockDeviceMappings=[{'DeviceName': self.root_device_name,
'Ebs': {'DeleteOnTermination': False}}])
bdt = self.get_instance_bdm(instance_id, self.root_device_name)
self.assertIsNotNone(bdt)
volume_id = bdt['Ebs'].get('VolumeId')
res_clean_vol = self.addResourceCleanUp(self.client.delete_volume,
VolumeId=volume_id)
self.assertIsNotNone(volume_id)
self.assertFalse(bdt['Ebs']['DeleteOnTermination'])
data = self.client.describe_volumes(VolumeIds=[volume_id])
self.assertEqual(1, len(data['Volumes']))
self.client.terminate_instances(InstanceIds=[instance_id])
self.get_instance_waiter().wait_delete(instance_id)
self.get_volume_waiter().wait_available(volume_id)
self.client.delete_volume(VolumeId=volume_id)
self.cancelResourceCleanUp(res_clean_vol)
self.get_volume_waiter().wait_delete(volume_id)
@decorators.idempotent_id('0c820ed3-2e2f-4384-9649-cea907f00bf4')
def test_launch_ebs_instance_with_resized_root_device(self):
"""Launch EBS-backed instance with resizing root device."""
new_size = int(math.ceil(self.root_device_size * 1.1))
instance_id = self.run_instance(ImageId=self.image_id,
BlockDeviceMappings=[{'DeviceName': self.root_device_name,
'Ebs': {'VolumeSize': new_size}}])
bdt = self.get_instance_bdm(instance_id, self.root_device_name)
self.assertIsNotNone(bdt)
volume_id = bdt['Ebs'].get('VolumeId')
self.assertIsNotNone(volume_id)
self.assertTrue(bdt['Ebs']['DeleteOnTermination'])
data = self.client.describe_volumes(VolumeIds=[volume_id])
self.assertEqual(1, len(data['Volumes']))
volume = data['Volumes'][0]
self.assertEqual(new_size, volume['Size'])
self.client.terminate_instances(InstanceIds=[instance_id])
self.get_instance_waiter().wait_delete(instance_id)
@decorators.idempotent_id('a0dbb3bd-167f-4f35-bb9d-aa53233e3123')
def test_launch_ebs_instance_with_creating_blank_volume(self):
"""Launch instance with creating blank volume."""
device_name_prefix = base.get_device_name_prefix(self.root_device_name)
device_name = device_name_prefix + 'b'
instance_id = self.run_instance(ImageId=self.image_id,
BlockDeviceMappings=[{'DeviceName': device_name,
'Ebs': {'VolumeSize': 1}}])
bdt = self.get_instance_bdm(instance_id, device_name)
self.assertIsNotNone(bdt)
volume_id = bdt['Ebs'].get('VolumeId')
self.assertIsNotNone(volume_id)
self.assertTrue(bdt['Ebs']['DeleteOnTermination'])
data = self.client.describe_volumes(VolumeIds=[volume_id])
self.assertEqual(1, len(data['Volumes']))
volume = data['Volumes'][0]
self.assertEqual(1, volume['Size'])
self.client.terminate_instances(InstanceIds=[instance_id])
self.get_instance_waiter().wait_delete(instance_id)
class EC2_EBSInstanceAttaching(base.EC2TestCase):
"""Test attaching cases
Launch instance with two attached volumes. One at first free slot (xxdb,
other at some free slot (xxdh). Use full device name for the first and
short device name for the second. Check used device names.
Detach devices and reattach their back with same names. Check used device
names again.
Detach devices and attach their in next slots (xxdc and xxdi). First with
full name, and second with short. Check useed device names.
Sometimes this test case failed in AWS because volumes get attach state
'busy'. Then it's need to give a pause and rerun test case.
Some dublicate tests are hidden to less output information.
"""
@classmethod
@base.safe_setup
def setUpClass(cls):
super(EC2_EBSInstanceAttaching, cls).setUpClass()
if not CONF.aws.run_incompatible_tests:
raise cls.skipException('Decsribe returns full device name while '
'we boot with short name.')
if not CONF.aws.ebs_image_id:
raise cls.skipException('aws EBS image does not provided')
cls.image_id = CONF.aws.ebs_image_id
cls.zone = CONF.aws.aws_zone
data = cls.client.describe_images(ImageIds=[cls.image_id])
assert 1 == len(data['Images'])
image = data['Images'][0]
root_device_name = image['RootDeviceName']
device_name_prefix = base.get_device_name_prefix(root_device_name)
cls.full_device_name_prefix = device_name_prefix
cls.short_device_name_prefix = device_name_prefix[len("/dev/"):]
data = cls.client.create_volume(AvailabilityZone=cls.zone,
Size=1)
cls.volume_id = data['VolumeId']
cls.addResourceCleanUpStatic(cls.client.delete_volume,
VolumeId=cls.volume_id)
cls.get_volume_waiter().wait_available(cls.volume_id)
data = cls.client.create_snapshot(VolumeId=cls.volume_id)
cls.snapshot_id = data['SnapshotId']
cls.addResourceCleanUpStatic(cls.client.delete_snapshot,
SnapshotId=cls.snapshot_id)
cls.get_snapshot_waiter().wait_available(cls.snapshot_id,
final_set=('completed'))
instance_type = CONF.aws.instance_type
cls.device1_name = cls.full_device_name_prefix + "d"
cls.device2_name = cls.short_device_name_prefix + "h"
data = cls.client.run_instances(
ImageId=cls.image_id, InstanceType=instance_type,
Placement={'AvailabilityZone': cls.zone}, MinCount=1, MaxCount=1,
BlockDeviceMappings=[{'DeviceName': cls.device1_name,
'Ebs': {'SnapshotId': cls.snapshot_id,
'DeleteOnTermination': True}},
{'DeviceName': cls.device2_name,
'Ebs': {'SnapshotId': cls.snapshot_id,
'DeleteOnTermination': True}}])
instance_id = data['Instances'][0]['InstanceId']
cls.instance_id = instance_id
cls.addResourceCleanUpStatic(cls.client.terminate_instances,
InstanceIds=[instance_id])
cls.get_instance_waiter().wait_available(instance_id,
final_set=('running'))
data = cls.client.describe_instances(InstanceIds=[instance_id])
assert 1 == len(data.get('Reservations', []))
instances = data['Reservations'][0].get('Instances', [])
assert 1 == len(instances)
instance = instances[0]
bdms = instance['BlockDeviceMappings']
for bdt in bdms:
if bdt['DeviceName'] == cls.device1_name:
cls.volume_id1 = bdt['Ebs']['VolumeId']
if bdt['DeviceName'] == cls.device2_name:
cls.volume_id2 = bdt['Ebs']['VolumeId']
assert cls.volume_id1
assert cls.volume_id2
@classmethod
def tearDownClass(cls):
super(EC2_EBSInstanceAttaching, cls).tearDownClass()
# NOTE(andrey-mp): Amazon resets flag DeleteOnTermination after
# reattaching volume, so we need delete them manually
for volume_id in [cls.volume_id1, cls.volume_id2]:
try:
cls.cleanUpItem(cls.client.delete_volume, [],
{'VolumeId': volume_id})
except BaseException:
LOG.exception('EBSInstanceAttaching.tearDownClass failure')
def _test_attaching(self, volume_id, device_name, device_prefix,
new_device_name_letter):
self.client.detach_volume(VolumeId=volume_id)
clean_v = self.addResourceCleanUp(self.client.delete_volume,
VolumeId=volume_id)
self.get_volume_attachment_waiter().wait_delete(volume_id)
bdt = self.get_instance_bdm(self.instance_id, device_name)
self.assertIsNone(bdt)
self.client.attach_volume(InstanceId=self.instance_id,
VolumeId=volume_id,
Device=device_name)
self.cancelResourceCleanUp(clean_v)
self.get_volume_attachment_waiter().wait_available(
volume_id, final_set=('attached'))
data = self.client.describe_volumes(VolumeIds=[volume_id])
self.assertEqual(1, len(data['Volumes']))
self.assertEqual('in-use', data['Volumes'][0]['State'])
bdt = self.get_instance_bdm(self.instance_id, device_name)
self.assertIsNotNone(bdt)
self.client.detach_volume(VolumeId=volume_id)
clean_v = self.addResourceCleanUp(self.client.delete_volume,
VolumeId=volume_id)
self.get_volume_attachment_waiter().wait_delete(volume_id)
bdt = self.get_instance_bdm(self.instance_id, device_name)
self.assertIsNone(bdt)
new_device_name = device_prefix + new_device_name_letter
self.client.attach_volume(InstanceId=self.instance_id,
VolumeId=volume_id,
Device=new_device_name)
self.cancelResourceCleanUp(clean_v)
self.get_volume_attachment_waiter().wait_available(
volume_id, final_set=('attached'))
data = self.client.describe_volumes(VolumeIds=[volume_id])
self.assertEqual(1, len(data['Volumes']))
self.assertEqual('in-use', data['Volumes'][0]['State'])
bdt = self.get_instance_bdm(self.instance_id, new_device_name)
self.assertIsNotNone(bdt)
@decorators.idempotent_id('2176d935-5254-4e2a-9eb4-fc899f63c530')
def test_attaching_by_full_name(self):
"""Attach and reattach device by full name."""
self._test_attaching(self.volume_id1, self.device1_name,
self.full_device_name_prefix, "e")
@decorators.idempotent_id('43af092e-3f04-45a7-bec7-8da39cde1f4c')
def test_attaching_by_short_name(self):
"""Attach and reattach device by short name."""
self._test_attaching(self.volume_id2, self.device2_name,
self.short_device_name_prefix, "i")
class EC2_EBSInstanceSnapshot(base.EC2TestCase):
"""Test instance's snapshotting
Launch EBS-backed image, snapshot root device, register image,
and launch another instance from the image
(http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/
instance-launch-snapshot.html)
"""
@classmethod
@base.safe_setup
def setUpClass(cls):
super(EC2_EBSInstanceSnapshot, cls).setUpClass()
if not CONF.aws.ebs_image_id:
raise cls.skipException('aws EBS image does not provided')
cls.image_id = CONF.aws.ebs_image_id
cls.zone = CONF.aws.aws_zone
@decorators.idempotent_id('07caac78-750c-48a1-975d-d3a6bd988108')
def test_create_ebs_instance_snapshot(self):
"""Create snapshot of EBS-backed instance and check it."""
instance_id = self.run_instance(ImageId=self.image_id)
instance = self.get_instance(instance_id)
bdt = self.get_instance_bdm(instance_id, None)
self.assertIsNotNone(bdt)
volume_id = bdt['Ebs'].get('VolumeId')
self.assertIsNotNone(volume_id)
self.client.stop_instances(InstanceIds=[instance_id])
self.get_instance_waiter().wait_available(instance_id,
final_set=('stopped'))
self.addResourceCleanUp(self.client.delete_volume,
VolumeId=volume_id)
data = self.client.create_snapshot(VolumeId=volume_id)
snapshot_id = data['SnapshotId']
self.addResourceCleanUp(self.client.delete_snapshot,
SnapshotId=snapshot_id)
self.get_snapshot_waiter().wait_available(snapshot_id,
final_set=('completed'))
self.client.terminate_instances(InstanceIds=[instance_id])
self.get_instance_waiter().wait_delete(instance_id)
kwargs = {
'Name': data_utils.rand_name('ebs-ami'),
'RootDeviceName': instance['RootDeviceName'],
'BlockDeviceMappings': [{'DeviceName': instance['RootDeviceName'],
'Ebs': {'SnapshotId': snapshot_id,
'DeleteOnTermination': True}}]
}
if 'Architecture' in instance:
kwargs['Architecture'] = instance['Architecture']
if 'KernelId' in instance:
kwargs['KernelId'] = instance['KernelId']
if 'RamdiskId' in instance:
kwargs['RamdiskId'] = instance['RamdiskId']
data = self.client.register_image(*[], **kwargs)
image_id = data['ImageId']
clean_i = self.addResourceCleanUp(self.client.deregister_image,
ImageId=image_id)
self.get_image_waiter().wait_available(image_id)
instance_id = self.run_instance(ImageId=image_id)
# NOTE(andrey-mp): if instance will run then test will pass
self.client.terminate_instances(InstanceIds=[instance_id])
self.get_instance_waiter().wait_delete(instance_id)
self.client.deregister_image(ImageId=image_id)
self.cancelResourceCleanUp(clean_i)
class EC2_EBSInstanceResizeRootDevice(base.EC2TestCase):
"""Test resizing root device on instance
Launch EBS-backed instance, stop instance, detach root volume, snapshot it,
create volume from snapshot with increased size, attach new root volume,
start instance
(http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ebs-expand-volume.html)
"""
@classmethod
@base.safe_setup
def setUpClass(cls):
super(EC2_EBSInstanceResizeRootDevice, cls).setUpClass()
if not CONF.aws.ebs_image_id:
raise cls.skipException('aws EBS image does not provided')
cls.image_id = CONF.aws.ebs_image_id
cls.zone = CONF.aws.aws_zone
@decorators.idempotent_id('0ea1dee6-c2c3-4cad-9676-5bf6e7ae54a8')
@testtools.skipUnless(
CONF.aws.run_incompatible_tests,
"Error from nova: "
"Unexpected Forbidden raised: Can't detach root device volume")
def test_resize_root_ebs_device(self):
"""Resize root device of launched instance."""
clean_dict = dict()
instance_id = self.run_instance(clean_dict=clean_dict,
ImageId=self.image_id)
res_clean = clean_dict['instance']
instance = self.get_instance(instance_id)
bdt = self.get_instance_bdm(instance_id, None)
self.assertIsNotNone(bdt)
volume_id = bdt['Ebs'].get('VolumeId')
self.assertIsNotNone(volume_id)
self.client.stop_instances(InstanceIds=[instance_id])
self.get_instance_waiter().wait_available(instance_id,
final_set=('stopped'))
self.client.detach_volume(VolumeId=volume_id)
clean_v = self.addResourceCleanUp(self.client.delete_volume,
VolumeId=volume_id)
self.get_volume_attachment_waiter().wait_delete(volume_id)
data = self.client.create_snapshot(VolumeId=volume_id)
snapshot_id = data['SnapshotId']
clean_s = self.addResourceCleanUp(self.client.delete_snapshot,
SnapshotId=snapshot_id)
self.get_snapshot_waiter().wait_available(snapshot_id,
final_set=('completed'))
new_size = int(math.ceil(data['VolumeSize'] * 1.1))
data = self.client.create_volume(AvailabilityZone=self.zone,
Size=new_size,
SnapshotId=snapshot_id)
volume_id2 = data['VolumeId']
clean_v2 = self.addResourceCleanUp(self.client.delete_volume,
VolumeId=volume_id2)
self.get_volume_waiter().wait_available(volume_id2)
self.client.delete_snapshot(SnapshotId=snapshot_id)
self.cancelResourceCleanUp(clean_s)
self.client.delete_volume(VolumeId=volume_id)
self.cancelResourceCleanUp(clean_v)
self.get_volume_waiter().wait_delete(volume_id)
self.client.attach_volume(
InstanceId=instance_id, VolumeId=volume_id2,
Device=instance['RootDeviceName'])
self.get_volume_attachment_waiter().wait_available(
volume_id2, final_set=('attached'))
# NOTE(andrey-mp): move this cleanup operation to the end of trash
# (it will remove first)
self.cancelResourceCleanUp(res_clean)
res_clean = self.addResourceCleanUp(self.client.terminate_instances,
InstanceIds=[instance_id])
self.client.start_instances(InstanceIds=[instance_id])
self.get_instance_waiter().wait_available(instance_id,
final_set=('running'))
# NOTE(andrey-mp): if instance will run then test will pass
self.client.terminate_instances(InstanceIds=[instance_id])
self.cancelResourceCleanUp(res_clean)
self.get_instance_waiter().wait_delete(instance_id)
self.client.delete_volume(VolumeId=volume_id2)
self.cancelResourceCleanUp(clean_v2)

View File

@ -1,95 +0,0 @@
# Copyright 2015 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
from oslo_log import log
from tempest.lib.common.utils import data_utils
from tempest.lib import decorators
import testtools
from ec2api_tempest_plugin import base
from ec2api_tempest_plugin import config
from ec2api_tempest_plugin.scenario import base as scenario_base
from ec2api_tempest_plugin import ssh
CONF = config.CONF
LOG = log.getLogger(__name__)
class InstanceRestartTest(scenario_base.BaseScenarioTest):
@decorators.idempotent_id('8ae801a5-3e4a-4a34-903a-45e34ff9eccd')
@testtools.skipUnless(CONF.aws.run_ssh, 'SSH tests are disabled.')
@testtools.skipUnless(CONF.aws.run_long_tests, 'Slow test has skipped.')
@testtools.skipUnless(CONF.aws.image_id_ubuntu,
"ubuntu image id is not defined")
def test_stop_start_instance(self):
key_name = data_utils.rand_name('testkey')
pkey = self.create_key_pair(key_name)
sec_group_name = self.create_standard_security_group()
instance_id = self.run_instance(KeyName=key_name,
ImageId=CONF.aws.image_id_ubuntu,
SecurityGroups=[sec_group_name])
ip_address = self.get_instance_ip(instance_id)
ssh_client = ssh.Client(ip_address, CONF.aws.image_user_ubuntu,
pkey=pkey)
ssh_client.exec_command('last -x')
self.client.stop_instances(InstanceIds=[instance_id])
self.get_instance_waiter().wait_available(instance_id,
final_set=('stopped'))
self.client.start_instances(InstanceIds=[instance_id])
self.get_instance_waiter().wait_available(instance_id,
final_set=('running'))
# Amazon can change auto-assigned public ip
ip_address = self.get_instance_ip(instance_id)
ssh_client = ssh.Client(ip_address, CONF.aws.image_user_ubuntu,
pkey=pkey)
data = ssh_client.exec_command('last -x')
self.assertIn("shutdown", data)
@decorators.idempotent_id('ae1cce79-882c-4f37-b9e9-2f7156712721')
@testtools.skipUnless(CONF.aws.run_ssh, 'SSH tests are disabled.')
@testtools.skipUnless(CONF.aws.run_long_tests, 'Slow test has skipped.')
@testtools.skipUnless(CONF.aws.image_id_ubuntu,
"ubuntu image id is not defined")
def test_reboot_instance(self):
key_name = data_utils.rand_name('testkey')
pkey = self.create_key_pair(key_name)
sec_group_name = self.create_standard_security_group()
instance_id = self.run_instance(KeyName=key_name,
ImageId=CONF.aws.image_id_ubuntu,
SecurityGroups=[sec_group_name])
ip_address = self.get_instance_ip(instance_id)
ssh_client = ssh.Client(ip_address, CONF.aws.image_user_ubuntu,
pkey=pkey)
last_lines = ssh_client.exec_command('last -x').split('\n')
self.client.reboot_instances(InstanceIds=[instance_id])
def _last_state():
current = ssh_client.exec_command('last -x').split('\n')
if len(current) > len(last_lines):
return
raise Exception()
waiter = base.EC2Waiter(_last_state)
waiter.wait_no_exception()
data = ssh_client.exec_command('last -x')
self.assertIn("shutdown", data)

View File

@ -1,182 +0,0 @@
# Copyright 2015 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import base64
import os
from oslo_log import log
import six
from tempest.lib.common.utils import data_utils
from tempest.lib import decorators
from ec2api_tempest_plugin import base
from ec2api_tempest_plugin import config
from ec2api_tempest_plugin.scenario import base as scenario_base
from ec2api_tempest_plugin import ssh
import testtools
CONF = config.CONF
LOG = log.getLogger(__name__)
PRIVATE_KEY_MATERIAL = (
'-----BEGIN RSA PRIVATE KEY-----\n'
'MIIEpAIBAAKCAQEAxkaf7L0BoNmyzlWPh29WPsaUP2+kV2vuoCQrO2FWliV8OOUP\n'
'+OIPvqRF+XtcCWc5LIQrSzKnitazJmoUO1m/J7fwxv2Qf2kbKVLrLqP7AUh1pAgG\n'
'DUqnBS8F5+2kPsMRKAE+xz1uJDpnP5ktIzpn1hWDVCoG80/jP7d7YSi0KlIYMHVx\n'
'E3WegrQ5IWw/BI62LR1KOe2YBSrv1n9SDc2w69QbfrnsZOpNKAnv/+G7LIqeHKP1\n'
'G5YMh2iWtEzdDgHqWa+HvtifhS3AzdtG7zgpmpwq8JYheYXLC+S/qxdZSGFx3p5s\n'
'JKr7kiAcxWqTsYEEtJdbYKDYfmu1e+k5hP901wIDAQABAoIBAFJkDJaSX7fYXq3Q\n'
'7giIYl1JpVbK7I6LQih3fyN4qkNQJlN6E+4G+iXtG0q1USRzKVXvQhJIZUiTOPSQ\n'
'hgG3pHA7xijaOw5GvcupMiM6btY0pvXXg7RIPikwRhL/NA4Efv+RrOWcCEWzoy3R\n'
'V+lYnsdePyldIXA/1R2n//P6twsSP+055XCabN/HVEJMtYmeVnZsoffRgos5cDlT\n'
'afpq29W93kI7kXTDIlNxdQXzOa1rKqmUK/nBf0caMwaGy9Di9s3OP8M+Xs4Y/L0b\n'
'+QOuILwBNjMMj3yqdDyDT698kQoO0oX458L70MUk660PItdaqyPT1KAaCIz7xTFJ\n'
'7OQM10kCgYEA+ES8irwqkkSocZ0QQzCR5qxIp3cVrnw1kaaqWuZOgojMPvRpzFJO\n'
'x4IB6VbvcpPPqHBhCGuJYIDYXuM1Ke0YR4TllNec9ZvSPvUYFNNQLeXmAyaWKtIE\n'
'91BoONyEMsbpWr/hsG60y4cFoqNZVqILHTNS48TMVtB4Lv8IgOv3OVsCgYEAzHNV\n'
'YZzUMdBN5rEuNwJ5NtModung7H08g9jOiGHMo0ZQvhKhFYgieQmJRGXOhMpbNPL4\n'
'9RLQjAVr4mrFdk+sDqVmscqu07q2/jjT1U1x2rprBpzckOvmmw7TKveiGfgcwqZ+\n'
'Qs3tWoiLc8m74loJyT/7c0tpyZxjbPJL7jVQzzUCgYEAqnNuywWDaObwiwhduPOo\n'
'yCmyvB87aI9oq/Y0cbI7Zs2LBRIDbT95TOqKa2y/evfWk3uMcx55tCLh6sutnXpl\n'
't/ybLwSVg98Wixj1Dp9CJjD4KWOdqAqHVFEFLTzhGoeMgTzKM7reL/okuVPTK3KX\n'
'lNW+7BgafuQkD4gTi4f2NY8CgYEAiUNlr4N7c3ZG1vtd69DdUNGz+SJMwHnUhzCo\n'
'eSgwG+65huM7AxnDC0A7yJARd1Xkpkf6nY9kNJ3vMLQ+npAfFDY4HGXXuo9BDK1a\n'
'i3rTVeaStH3cF/BJgxEQ9WgMjSLnLEhbvL5E/ONvvO1UF0QcDeHHEEExZQp6Nkr2\n'
'b5ecCYECgYBtL4kr0qttoowbfj+pXjwiJjbwb6GBaMBVNQTtJBKdl5AeyDm9qh2o\n'
'vF60vnm+wWFfUs8nlvPMT/FNHwjHtFOBLPhw6tUcyrzh1ba4v/FE40FW4NxgqSK/\n'
'VS0+XhPxet+E9kXjMMrVUaDrHHR2+zM5OyOLG0a/JIcsFuf7qZgAMQ==\n'
'-----END RSA PRIVATE KEY-----'
)
PUBLIC_KEY_MATERIAL = (
'ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDGRp/svQGg2bLOVY+Hb1Y+xpQ/'
'b6RXa+6gJCs7YVaWJXw45Q/44g++pEX5e1wJZzkshCtLMqeK1rMmahQ7Wb8nt/DG'
'/ZB/aRspUusuo/sBSHWkCAYNSqcFLwXn7aQ+wxEoAT7HPW4kOmc/mS0jOmfWFYNU'
'KgbzT+M/t3thKLQqUhgwdXETdZ6CtDkhbD8EjrYtHUo57ZgFKu/Wf1INzbDr1Bt+'
'uexk6k0oCe//4bssip4co/UblgyHaJa0TN0OAepZr4e+2J+FLcDN20bvOCmanCrw'
'liF5hcsL5L+rF1lIYXHenmwkqvuSIBzFapOxgQS0l1tgoNh+a7V76TmE/3TX '
'ubuntu@test.com'
)
class InstancesTest(scenario_base.BaseScenarioTest):
@decorators.idempotent_id('c25defc4-b075-4794-9fa6-3b67353c4079')
@testtools.skipUnless(CONF.aws.run_ssh, 'SSH tests are disabled.')
@testtools.skipUnless(CONF.aws.image_id, "image id is not defined")
def test_metadata(self):
key_name = data_utils.rand_name('testkey')
self.client.import_key_pair(KeyName=key_name,
PublicKeyMaterial=PUBLIC_KEY_MATERIAL)
self.addResourceCleanUp(self.client.delete_key_pair, KeyName=key_name)
sec_group_name = self.create_standard_security_group()
user_data = six.text_type(data_utils.rand_uuid()) + six.unichr(1071)
instance_id = self.run_instance(KeyName=key_name, UserData=user_data,
SecurityGroups=[sec_group_name])
data = self.client.describe_instance_attribute(
InstanceId=instance_id, Attribute='userData')
self.assertEqual(
data['UserData']['Value'],
base64.b64encode(user_data.encode("utf-8")).decode("utf-8"))
ip_address = self.get_instance_ip(instance_id)
ssh_client = ssh.Client(ip_address, CONF.aws.image_user,
pkey=PRIVATE_KEY_MATERIAL)
url = 'http://169.254.169.254'
data = ssh_client.exec_command('curl %s/latest/user-data' % url)
if isinstance(data, six.binary_type):
data = data.decode("utf-8")
self.assertEqual(user_data, data)
data = ssh_client.exec_command('curl %s/latest/meta-data/ami-id' % url)
self.assertEqual(CONF.aws.image_id, data)
data = ssh_client.exec_command(
'curl %s/latest/meta-data/public-keys/0/openssh-key' % url)
# compare only keys. without 'sha-rsa' and owner
self.assertEqual(PUBLIC_KEY_MATERIAL.split()[1], data.split()[1])
@decorators.idempotent_id('9fd254b1-dad1-4bb6-959f-f2cf937873c7')
@testtools.skipUnless(CONF.aws.run_ssh, 'SSH tests are disabled.')
@testtools.skipUnless(CONF.aws.image_id, "image id is not defined")
def test_compare_console_output(self):
key_name = data_utils.rand_name('testkey')
pkey = self.create_key_pair(key_name)
sec_group_name = self.create_standard_security_group()
instance_id = self.run_instance(KeyName=key_name,
SecurityGroups=[sec_group_name])
data_to_check = data_utils.rand_uuid()
ip_address = self.get_instance_ip(instance_id)
ssh_client = ssh.Client(ip_address, CONF.aws.image_user, pkey=pkey)
cmd = 'sudo sh -c "echo \\"%s\\" >/dev/console"' % data_to_check
ssh_client.exec_command(cmd)
waiter = base.EC2Waiter(self.client.get_console_output)
waiter.wait_no_exception(InstanceId=instance_id)
def _compare_console_output():
data = self.client.get_console_output(InstanceId=instance_id)
self.assertEqual(instance_id, data['InstanceId'])
self.assertIsNotNone(data['Timestamp'])
self.assertIn('Output', data)
self.assertIn(data_to_check, data['Output'])
waiter = base.EC2Waiter(_compare_console_output)
waiter.wait_no_exception()
@decorators.idempotent_id('df1bb8f2-193c-46ba-aa99-3981bbc367db')
@testtools.skipUnless(CONF.aws.run_ssh, 'SSH tests are disabled.')
@testtools.skipUnless(CONF.aws.ami_image_location, "Image is absent in S3")
def test_run_and_ping_registered_image(self):
image_name = data_utils.rand_name("ami-name")
data = self.client.register_image(
Name=image_name, ImageLocation=CONF.aws.ami_image_location)
image_id = data['ImageId']
self.addResourceCleanUp(self.client.deregister_image, ImageId=image_id)
self.get_image_waiter().wait_available(image_id)
# launch this image
sec_group_name = self.create_standard_security_group()
instance_id = self.run_instance(ImageId=image_id,
SecurityGroups=[sec_group_name])
waiter = base.EC2Waiter(self.client.get_console_output)
waiter.wait_no_exception(InstanceId=instance_id)
def _compare_console_output():
data = self.client.get_console_output(InstanceId=instance_id)
self.assertEqual(instance_id, data['InstanceId'])
self.assertIsNotNone(data['Timestamp'])
self.assertIn('Output', data)
self.assertNotEqual('', data['Output'])
waiter = base.EC2Waiter(_compare_console_output)
waiter.wait_no_exception()
# check ping
ip_address = self.get_instance_ip(instance_id)
def _ping():
response = os.system("ping -c 1 " + ip_address + " > /dev/null")
self.assertEqual(0, response)
waiter = base.EC2Waiter(_ping)
waiter.wait_no_exception()

View File

@ -1,173 +0,0 @@
# Copyright 2015 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import netaddr
from oslo_log import log
from tempest.lib.common.utils import data_utils
from tempest.lib import decorators
from tempest.lib import exceptions
import testtools
from ec2api_tempest_plugin import base
from ec2api_tempest_plugin import config
from ec2api_tempest_plugin.scenario import base as scenario_base
from ec2api_tempest_plugin import ssh
CONF = config.CONF
LOG = log.getLogger(__name__)
class InstancesInVPCTest(scenario_base.BaseScenarioTest):
def _test_instances(self, subnet_size):
cidr = netaddr.IPNetwork('10.20.0.0/8')
cidr.prefixlen = subnet_size
vpc_id, subnet_id = self.create_vpc_and_subnet(str(cidr))
gw_id = self.create_and_attach_internet_gateway(vpc_id)
self.prepare_vpc_default_security_group(vpc_id)
self.prepare_route(vpc_id, gw_id)
key_name = data_utils.rand_name('testkey')
pkey = self.create_key_pair(key_name)
first_ip = str(netaddr.IPAddress(cidr.first + 4))
last_ip = str(netaddr.IPAddress(cidr.last - 1))
instance_id1 = self.run_instance(KeyName=key_name, SubnetId=subnet_id,
PrivateIpAddress=first_ip)
instance_id2 = self.run_instance(KeyName=key_name, SubnetId=subnet_id,
PrivateIpAddress=last_ip)
instance = self.get_instance(instance_id1)
self.assertEqual(first_ip, instance['PrivateIpAddress'])
instance = self.get_instance(instance_id2)
self.assertEqual(last_ip, instance['PrivateIpAddress'])
ip_address = self.get_instance_ip(instance_id1)
ssh_client = ssh.Client(ip_address, CONF.aws.image_user, pkey=pkey)
waiter = base.EC2Waiter(ssh_client.exec_command)
waiter.wait_no_exception('ping %s -c 1' % last_ip)
@base.skip_without_vpc()
@decorators.idempotent_id('b986708e-9559-493d-aeb3-97fc992a65cf')
@testtools.skipUnless(CONF.aws.run_ssh, 'SSH tests are disabled.')
@testtools.skipUnless(CONF.aws.image_id, "image id is not defined")
def test_instances_in_min_subnet(self):
self._test_instances(28)
@base.skip_without_vpc()
@decorators.idempotent_id('7bf8e80c-cd05-4ccb-944a-e4b09825d151')
@testtools.skipUnless(CONF.aws.run_ssh, 'SSH tests are disabled.')
@testtools.skipUnless(CONF.aws.image_id, "image id is not defined")
def test_instances_in_max_subnet(self):
self._test_instances(16)
@base.skip_without_vpc()
@decorators.idempotent_id('9c3a8066-68b2-4bd0-85e0-6d4a0d7cb053')
@testtools.skipUnless(CONF.aws.run_ssh, 'SSH tests are disabled.')
@testtools.skipUnless(CONF.aws.image_id, "image id is not defined")
@testtools.skipUnless(CONF.aws.run_incompatible_tests,
'skip due to bug #1818499')
def test_default_gateway(self):
novpc_group = self.create_standard_security_group()
novpc_instance_id = self.run_instance(SecurityGroups=[novpc_group])
ping_destination = self.get_instance_ip(novpc_instance_id)
data = self.client.create_vpc(CidrBlock='10.10.0.0/16')
vpc_id = data['Vpc']['VpcId']
self.addResourceCleanUp(self.client.delete_vpc, VpcId=vpc_id)
self.get_vpc_waiter().wait_available(vpc_id)
data = self.client.create_subnet(
VpcId=vpc_id, CidrBlock='10.10.1.0/24',
AvailabilityZone=CONF.aws.aws_zone)
subnet_1_id = data['Subnet']['SubnetId']
self.addResourceCleanUp(self.client.delete_subnet,
SubnetId=subnet_1_id)
data = self.client.create_subnet(
VpcId=vpc_id, CidrBlock='10.10.2.0/24',
AvailabilityZone=CONF.aws.aws_zone)
subnet_2_id = data['Subnet']['SubnetId']
self.addResourceCleanUp(self.client.delete_subnet,
SubnetId=subnet_2_id)
data = self.client.create_internet_gateway()
gw_id = data['InternetGateway']['InternetGatewayId']
self.addResourceCleanUp(self.client.delete_internet_gateway,
InternetGatewayId=gw_id)
data = self.client.attach_internet_gateway(VpcId=vpc_id,
InternetGatewayId=gw_id)
self.addResourceCleanUp(self.client.detach_internet_gateway,
VpcId=vpc_id, InternetGatewayId=gw_id)
self.prepare_route(vpc_id, gw_id)
data = self.client.create_route_table(VpcId=vpc_id)
rt_id = data['RouteTable']['RouteTableId']
self.addResourceCleanUp(self.client.delete_route_table,
RouteTableId=rt_id)
data = self.client.associate_route_table(RouteTableId=rt_id,
SubnetId=subnet_2_id)
assoc_id = data['AssociationId']
self.addResourceCleanUp(self.client.disassociate_route_table,
AssociationId=assoc_id)
self.prepare_vpc_default_security_group(vpc_id)
key_name = data_utils.rand_name('testkey')
pkey = self.create_key_pair(key_name)
instance_2_id = self.run_instance(KeyName=key_name,
SubnetId=subnet_2_id)
instance_1_id = self.run_instance(KeyName=key_name,
SubnetId=subnet_1_id,
UserData=pkey)
ip_address = self.get_instance_ip(instance_1_id)
ip_private_address_1 = self.get_instance(
instance_1_id)['PrivateIpAddress']
ip_private_address_2 = self.get_instance(
instance_2_id)['PrivateIpAddress']
ssh_client = ssh.Client(ip_address, CONF.aws.image_user, pkey=pkey,
channel_timeout=30)
ssh_client.exec_command(
'curl http://169.254.169.254/latest/user-data > key.pem && '
'chmod 400 key.pem')
if 'cirros' in ssh_client.exec_command('cat /etc/issue'):
ssh_client.exec_command(
'dropbearconvert openssh dropbear key.pem key.db && '
'mv key.db key.pem')
extra_ssh_opts = '-y'
else:
extra_ssh_opts = ('-o UserKnownHostsFile=/dev/null '
'-o StrictHostKeyChecking=no')
ssh_client.exec_command('ping -c 1 %s' % ip_private_address_2)
ssh_client.exec_command('ping -c 1 %s' % ping_destination)
remote_ping_template = (
'ssh -i key.pem %(extra_opts)s %(user)s@%(ip)s '
'ping -c 1 %%s' %
{'extra_opts': extra_ssh_opts,
'user': CONF.aws.image_user,
'ip': ip_private_address_2})
ssh_client.exec_command(remote_ping_template % ip_private_address_1)
try:
resp = ssh_client.exec_command(remote_ping_template %
ping_destination)
except exceptions.SSHExecCommandFailed:
pass
else:
self.assertEqual('', resp)

View File

@ -1,411 +0,0 @@
# Copyright 2015 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
from six.moves import range
import time
import botocore.exceptions
from oslo_log import log
from tempest.lib.common.utils import data_utils
from tempest.lib import decorators
from ec2api_tempest_plugin import base
from ec2api_tempest_plugin import config
from ec2api_tempest_plugin.scenario import base as scenario_base
CONF = config.CONF
LOG = log.getLogger(__name__)
class TagsPagingTest(scenario_base.BaseScenarioTest):
# NOTE(andrey-mp): limit for tags for one resource in amazon
TAGS_COUNT = 10
@classmethod
@base.safe_setup
def setUpClass(cls):
super(TagsPagingTest, cls).setUpClass()
if 'amazon' in CONF.aws.ec2_url:
raise cls.skipException('Paging is broken in Amazon.')
def _create_volume_and_tags(self):
data = self.client.create_volume(
Size=1, AvailabilityZone=CONF.aws.aws_zone)
volume_id = data['VolumeId']
self.addResourceCleanUp(self.client.delete_volume, VolumeId=volume_id)
self.get_volume_waiter().wait_available(volume_id)
keys = list()
for dummy in range(0, self.TAGS_COUNT):
key = data_utils.rand_name('key')
value = 'aaa' if dummy < 6 else 'bbb'
data = self.client.create_tags(Resources=[volume_id],
Tags=[{'Key': key, 'Value': value}])
keys.append(key)
return volume_id, keys
@decorators.idempotent_id('8df6e612-07cd-466d-99de-9f37954a6c9a')
def test_simple_tags_paging_with_many_results(self):
volume_id = self._create_volume_and_tags()[0]
data = self.client.describe_tags(MaxResults=500,
Filters=[{'Name': 'resource-id', 'Values': [volume_id]}])
self.assertNotIn('NextToken', data)
self.assertNotEmpty(data['Tags'])
self.assertEqual(self.TAGS_COUNT, len(data['Tags']))
@decorators.idempotent_id('683883d5-9a94-43f2-a1eb-d193db0e44e9')
def test_simple_tags_paging_with_min_results(self):
volume_id = self._create_volume_and_tags()[0]
data = self.client.describe_tags(
MaxResults=5,
Filters=[{'Name': 'resource-id', 'Values': [volume_id]},
{'Name': 'tag-value', 'Values': ['aaa']}])
self.assertIn('NextToken', data)
self.assertNotEmpty(data['Tags'])
@decorators.idempotent_id('1db8cc5a-d0b3-4e5f-b411-d84cfa4f21e0')
def test_tags_paging_second_page_only_with_token(self):
volume_id = self._create_volume_and_tags()[0]
data = self.client.describe_tags(
MaxResults=5,
Filters=[{'Name': 'resource-id', 'Values': [volume_id]},
{'Name': 'tag-value', 'Values': ['aaa']}])
self.assertIn('NextToken', data)
self.assertNotEmpty(data['Tags'])
data = self.client.describe_tags(
NextToken=data['NextToken'],
Filters=[{'Name': 'resource-id', 'Values': [volume_id]},
{'Name': 'tag-value', 'Values': ['aaa']}])
self.assertNotIn('NextToken', data)
self.assertNotEmpty(data['Tags'])
@decorators.idempotent_id('a4d7b315-9616-4f9e-85b7-0f892e09a9a2')
def test_tags_paging_with_const_filter(self):
volume_id = self._create_volume_and_tags()[0]
data = self.client.describe_tags(
MaxResults=5,
Filters=[{'Name': 'resource-id', 'Values': [volume_id]},
{'Name': 'tag-value', 'Values': ['aaa']}])
self.assertIn('NextToken', data)
self.assertNotEmpty(data['Tags'])
data = self.client.describe_tags(
MaxResults=5, NextToken=data['NextToken'],
Filters=[{'Name': 'resource-id', 'Values': [volume_id]},
{'Name': 'tag-value', 'Values': ['aaa']}])
self.assertNotIn('NextToken', data)
self.assertNotEmpty(data['Tags'])
@decorators.idempotent_id('ad4b793a-8231-4d30-8c26-43736b7b71e4')
def test_tags_paging_with_differenet_filters(self):
volume_id = self._create_volume_and_tags()[0]
data = self.client.describe_tags(
MaxResults=5,
Filters=[{'Name': 'resource-id', 'Values': [volume_id]},
{'Name': 'tag-value', 'Values': ['aaa']}])
self.assertIn('NextToken', data)
self.assertNotEmpty(data['Tags'])
data = self.client.describe_tags(
MaxResults=5, NextToken=data['NextToken'],
Filters=[{'Name': 'resource-id', 'Values': [volume_id]}])
self.assertNotEmpty(data['Tags'])
self.assertLessEqual(1, len(data['Tags']))
@decorators.idempotent_id('ec6d68bb-37f3-4c5c-b4c5-000d73fbc1bf')
def test_tags_paging_with_tags_deletion(self):
volume_id, keys = self._create_volume_and_tags()
data = self.client.describe_tags(MaxResults=5,
Filters=[{'Name': 'resource-id', 'Values': [volume_id]}])
self.assertIn('NextToken', data)
self.assertNotEmpty(data['Tags'])
for key in keys:
self.client.delete_tags(Resources=[volume_id], Tags=[{'Key': key}])
data = self.client.describe_tags(
MaxResults=5, NextToken=data['NextToken'],
Filters=[{'Name': 'resource-id', 'Values': [volume_id]}])
self.assertNotIn('NextToken', data)
self.assertEmpty(data['Tags'])
@decorators.idempotent_id('37eb0597-998f-4744-8462-d56e5599dcd8')
def test_invalid_max_results(self):
self.assertRaises('InvalidParameterValue',
self.client.describe_tags, MaxResults=4)
# NOTE(andrey-mp): value more than 1000 in not invalid
# but amazon returns 1000 elements
self.client.describe_tags(MaxResults=1100)
class VolumesPagingTest(scenario_base.BaseScenarioTest):
VOLUMES_COUNT = 6
@classmethod
@base.safe_setup
def setUpClass(cls):
super(VolumesPagingTest, cls).setUpClass()
if 'amazon' in CONF.aws.ec2_url:
raise cls.skipException('Paging is broken in Amazon.')
zone = CONF.aws.aws_zone
cls.ids = list()
for dummy in range(0, cls.VOLUMES_COUNT):
data = cls.client.create_volume(Size=1, AvailabilityZone=zone)
volume_id = data['VolumeId']
cls.addResourceCleanUpStatic(cls.client.delete_volume,
VolumeId=volume_id)
cls.ids.append(volume_id)
for volume_id in cls.ids:
cls.get_volume_waiter().wait_available(volume_id)
@decorators.idempotent_id('d44ea940-d9ae-42a4-b3ce-add296a1678c')
def test_simple_volumes_paging_with_many_results(self):
data = self.client.describe_volumes(MaxResults=500)
self.assertNotIn('NextToken', data)
self.assertNotEmpty(data['Volumes'])
self.assertLessEqual(self.VOLUMES_COUNT, len(data['Volumes']))
@decorators.idempotent_id('9780c871-ee90-411c-b6ec-1e2f1785926b')
def test_simple_volumes_paging_with_min_results(self):
data = self.client.describe_volumes(MaxResults=5)
self.assertIn('NextToken', data)
self.assertNotEmpty(data['Volumes'])
@decorators.idempotent_id('692684c4-62bc-457a-899a-07cc5382c9ab')
def test_volumes_paging_second_page(self):
data = self.client.describe_volumes(MaxResults=5)
self.assertIn('NextToken', data)
self.assertNotEmpty(data['Volumes'])
data = self.client.describe_volumes(
MaxResults=5, NextToken=data['NextToken'])
self.assertNotIn('NextToken', data)
self.assertNotEmpty(data['Volumes'])
@decorators.idempotent_id('83183fac-bb9b-4c36-8d23-84ed55c57015')
def test_invalid_paging(self):
self.assertRaises('InvalidParameterValue',
self.client.describe_volumes, MaxResults=4)
self.assertRaises('InvalidParameterCombination',
self.client.describe_volumes,
MaxResults=5, VolumeIds=[self.ids[0]])
@decorators.idempotent_id('2a777d78-9f0b-4ab0-a841-73dbaafae0dd')
def test_volumes_paging_with_filters(self):
data = self.client.describe_volumes(MaxResults=5,
Filters=[{'Name': 'volume-id', 'Values': [self.ids[0]]}])
self.assertNotEmpty(data['Volumes'])
if 'NextToken' in data:
# Amazon way
data = self.client.describe_volumes(
MaxResults=5, NextToken=data['NextToken'],
Filters=[{'Name': 'volume-id', 'Values': [self.ids[0]]}])
self.assertNotIn('NextToken', data)
self.assertEmpty(data['Volumes'])
data = self.client.describe_volumes(MaxResults=5,
Filters=[{'Name': 'volume-id', 'Values': ['vol-*']}])
self.assertIn('NextToken', data)
self.assertNotEmpty(data['Volumes'])
data = self.client.describe_volumes(
MaxResults=5, NextToken=data['NextToken'],
Filters=[{'Name': 'volume-id', 'Values': ['vol-*']}])
self.assertNotEmpty(data['Volumes'])
class SnapshotPagingTest(scenario_base.BaseScenarioTest):
SNAPSHOTS_COUNT = 6
@classmethod
@base.safe_setup
def setUpClass(cls):
super(SnapshotPagingTest, cls).setUpClass()
if 'amazon' in CONF.aws.ec2_url:
raise cls.skipException('Paging is broken in Amazon.')
zone = CONF.aws.aws_zone
data = cls.client.create_volume(Size=1, AvailabilityZone=zone)
volume_id = data['VolumeId']
cls.addResourceCleanUpStatic(cls.client.delete_volume,
VolumeId=volume_id)
cls.get_volume_waiter().wait_available(volume_id)
def _create_snapshot():
try:
return cls.client.create_snapshot(VolumeId=volume_id)
except botocore.exceptions.ClientError as e:
code = (e.response.get('ResponseMetadata', {})
.get('HTTPStatusCode'))
if not code or code != 500:
raise
waiter = base.EC2Waiter(_create_snapshot)
cls.ids = list()
while len(cls.ids) < cls.SNAPSHOTS_COUNT:
time.sleep(10)
data = waiter.wait_for_result()
snapshot_id = data['SnapshotId']
cls.addResourceCleanUpStatic(cls.client.delete_snapshot,
SnapshotId=snapshot_id)
cls.get_snapshot_waiter().wait_available(snapshot_id,
final_set=('completed'))
cls.ids.append(snapshot_id)
@decorators.idempotent_id('f44729b1-42d7-4f18-b5e0-f8dc2a03e624')
def test_simple_snapshots_paging_with_many_results(self):
data = self.client.describe_snapshots(MaxResults=500,
OwnerIds=['self'])
self.assertNotEmpty(data['Snapshots'])
count = 0
for s in data['Snapshots']:
if s['SnapshotId'] in self.ids:
count += 1
self.assertEqual(self.SNAPSHOTS_COUNT, count)
@decorators.idempotent_id('3146c81d-84c0-4817-9318-328f92bece7f')
def test_simple_snapshots_paging_with_min_results(self):
data = self.client.describe_snapshots(MaxResults=5, OwnerIds=['self'])
self.assertIn('NextToken', data)
self.assertNotEmpty(data['Snapshots'])
@decorators.idempotent_id('fef90b60-0a46-4802-a822-98ccb58ff18c')
def test_snapshots_paging(self):
count = 0
max_results = 5
kwargs = {'MaxResults': max_results, 'OwnerIds': ['self']}
while True:
data = self.client.describe_snapshots(*[], **kwargs)
self.assertGreaterEqual(max_results, len(data['Snapshots']))
for s in data['Snapshots']:
if s['SnapshotId'] in self.ids:
count += 1
if 'NextToken' not in data:
break
kwargs['NextToken'] = data['NextToken']
self.assertEqual(self.SNAPSHOTS_COUNT, count)
@decorators.idempotent_id('8379d875-2979-4573-858f-2fd331ae992c')
def test_invalid_paging(self):
self.assertRaises('InvalidParameterValue',
self.client.describe_snapshots, MaxResults=4)
self.assertRaises('InvalidParameterCombination',
self.client.describe_snapshots,
MaxResults=5, SnapshotIds=[self.ids[0]])
class InstancePagingTest(scenario_base.BaseScenarioTest):
RESERVATIONS_COUNT = 2
INSTANCES_IN_RESERVATIONS_COUNT = 3
@classmethod
@base.safe_setup
def setUpClass(cls):
super(InstancePagingTest, cls).setUpClass()
if 'amazon' in CONF.aws.ec2_url:
raise cls.skipException('Paging is broken in Amazon.')
if not CONF.aws.image_id:
raise cls.skipException('aws image_id does not provided')
cls.ids = list()
cls.reservation_ids = list()
kwargs = {
'ImageId': CONF.aws.image_id,
'InstanceType': CONF.aws.instance_type,
'Placement': {'AvailabilityZone': CONF.aws.aws_zone},
'MinCount': cls.INSTANCES_IN_RESERVATIONS_COUNT,
'MaxCount': cls.INSTANCES_IN_RESERVATIONS_COUNT
}
for dummy in range(0, cls.RESERVATIONS_COUNT):
data = cls.client.run_instances(*[], **kwargs)
for instance in data['Instances']:
cls.ids.append(instance['InstanceId'])
cls.reservation_ids.append(data['ReservationId'])
cls.addResourceCleanUpStatic(cls.client.terminate_instances,
InstanceIds=cls.ids)
for instance_id in cls.ids:
cls.get_instance_waiter().wait_available(instance_id,
final_set=('running'))
@decorators.idempotent_id('703da498-c73f-4fd1-a2be-2feddb5292d0')
def test_simple_instances_paging_with_many_results(self):
data = self.client.describe_instances(MaxResults=500)
self.assertNotIn('NextToken', data)
self.assertNotEmpty(data['Reservations'])
rcount = 0
for r in data['Reservations']:
if r['ReservationId'] in self.reservation_ids:
rcount += 1
self.assertEqual(self.RESERVATIONS_COUNT, rcount)
count = self.RESERVATIONS_COUNT * self.INSTANCES_IN_RESERVATIONS_COUNT
instances = set()
self._collect_own_instances(data, instances)
self.assertEqual(count, len(instances))
@decorators.idempotent_id('f494a2a8-6d75-4ef4-ae15-ac4fd1269107')
def test_simple_instances_paging_with_min_results(self):
max_results = 5
data = self.client.describe_instances(MaxResults=max_results)
self.assertIn('NextToken', data)
self.assertEqual(max_results, self._count_instances(data))
@decorators.idempotent_id('429802be-d599-4732-a310-3ffe8274df54')
def test_instances_paging(self):
max_results = 5
kwargs = {'MaxResults': max_results}
instances = set()
while True:
data = self.client.describe_instances(*[], **kwargs)
self.assertGreaterEqual(max_results, self._count_instances(data))
self._collect_own_instances(data, instances)
if 'NextToken' not in data:
break
kwargs['NextToken'] = data['NextToken']
count = self.RESERVATIONS_COUNT * self.INSTANCES_IN_RESERVATIONS_COUNT
self.assertEqual(count, len(instances))
@decorators.idempotent_id('061d564d-6d3a-44a8-bec9-9dba04f6f362')
def test_invalid_paging(self):
self.assertRaises('InvalidParameterValue',
self.client.describe_instances, MaxResults=4)
self.assertRaises('InvalidParameterCombination',
self.client.describe_instances,
MaxResults=5, InstanceIds=[self.ids[0]])
def _collect_own_instances(self, data, instances):
for reservation in data['Reservations']:
for instance in reservation['Instances']:
if instance['InstanceId'] in self.ids:
instances.add(instance['InstanceId'])
def _count_instances(self, data):
count = 0
for reservation in data['Reservations']:
count += len(reservation['Instances'])
return count

View File

@ -1,157 +0,0 @@
# Copyright 2014 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import time
from oslo_log import log
from tempest.lib import decorators
import testtools
from ec2api_tempest_plugin import base
from ec2api_tempest_plugin import config
from ec2api_tempest_plugin.scenario import base as scenario_base
CONF = config.CONF
LOG = log.getLogger(__name__)
class VpcAddressTest(scenario_base.BaseScenarioTest):
@base.skip_without_vpc()
@decorators.idempotent_id('aa667fc6-fd9e-4664-92b8-23263d643d9e')
@testtools.skipUnless(CONF.aws.image_id, "image id is not defined")
def test_auto_diassociate_address(self):
vpc_id, subnet_id = self.create_vpc_and_subnet('10.3.0.0/20')
ni_id1 = self.create_network_interface(subnet_id)
gw_id = self.create_and_attach_internet_gateway(vpc_id)
self.prepare_route(vpc_id, gw_id)
alloc_id1, public_ip1 = self.allocate_address(True)
alloc_id2, _ = self.allocate_address(True)
data = self.client.create_network_interface(SubnetId=subnet_id)
ni_id2 = data['NetworkInterface']['NetworkInterfaceId']
clean_ni2 = self.addResourceCleanUp(
self.client.delete_network_interface, NetworkInterfaceId=ni_id2)
self.get_network_interface_waiter().wait_available(ni_id2)
kwargs = {
'ImageId': CONF.aws.image_id,
'InstanceType': CONF.aws.instance_type,
'MinCount': 1,
'MaxCount': 1,
'NetworkInterfaces': [
{'NetworkInterfaceId': ni_id1, 'DeviceIndex': 0}]
}
data = self.client.run_instances(*[], **kwargs)
instance_id = data['Instances'][0]['InstanceId']
clean_i = self.addResourceCleanUp(self.client.terminate_instances,
InstanceIds=[instance_id])
self.get_instance_waiter().wait_available(instance_id,
final_set=('running'))
data = self.client.attach_network_interface(DeviceIndex=1,
InstanceId=instance_id, NetworkInterfaceId=ni_id2)
attachment_id = data['AttachmentId']
# There are multiple interfaces attached to instance 'i-5310c5af'.
# Please specify an interface ID for the operation instead.
self.assertRaises('InvalidInstanceID',
self.client.associate_address,
InstanceId=instance_id, AllocationId=alloc_id1)
# The networkInterface ID 'eni-ffffffff' does not exist
self.assertRaises('InvalidNetworkInterfaceID.NotFound',
self.client.associate_address,
AllocationId=alloc_id1, NetworkInterfaceId='eni-ffffffff')
# NOTE(andrey-mp): Amazon needs only network interface if several
# present in instance. Error will be there if instance is passed.
data = self.client.associate_address(
AllocationId=alloc_id1, NetworkInterfaceId=ni_id1)
assoc_id1 = data['AssociationId']
clean_aa1 = self.addResourceCleanUp(self.client.disassociate_address,
AssociationId=assoc_id1)
self.get_address_assoc_waiter().wait_available(
{'AllocationId': alloc_id1})
instance = self.get_instance(instance_id)
nis = instance.get('NetworkInterfaces', [])
self.assertEqual(2, len(nis))
for ni in nis:
if ni['NetworkInterfaceId'] == ni_id1:
self.assertIsNotNone(ni.get('Association'))
self.assertEqual(public_ip1, ni['Association']['PublicIp'])
elif ni['NetworkInterfaceId'] == ni_id2:
self.assertIsNone(ni.get('Association'))
else:
self.assertTrue(False, 'Unknown interface found: ' + str(ni))
data = self.client.describe_network_interfaces(
NetworkInterfaceIds=[ni_id1, ni_id2])
self.assertEqual(2, len(data['NetworkInterfaces']))
self.assertEqual('in-use', data['NetworkInterfaces'][0]['Status'])
self.assertEqual('in-use', data['NetworkInterfaces'][1]['Status'])
# NOTE(andrery-mp): associate second address and set delete on
# termination to True for interface
data = self.client.associate_address(
AllocationId=alloc_id2, NetworkInterfaceId=ni_id2)
assoc_id2 = data['AssociationId']
clean_aa2 = self.addResourceCleanUp(self.client.disassociate_address,
AssociationId=assoc_id2)
self.get_address_assoc_waiter().wait_available(
{'AllocationId': alloc_id2})
kwargs = {
'NetworkInterfaceId': ni_id2,
'Attachment': {
'AttachmentId': attachment_id,
'DeleteOnTermination': True,
}
}
self.client.modify_network_interface_attribute(*[], **kwargs)
# NOTE(andrey-mp): cleanup
time.sleep(3)
self.client.terminate_instances(InstanceIds=[instance_id])
self.cancelResourceCleanUp(clean_i)
self.get_instance_waiter().wait_delete(instance_id)
self.assertRaises('InvalidNetworkInterfaceID.NotFound',
self.client.describe_network_interfaces,
NetworkInterfaceIds=[ni_id2])
self.cancelResourceCleanUp(clean_ni2)
self.cancelResourceCleanUp(clean_aa2)
data = self.client.describe_network_interfaces(
NetworkInterfaceIds=[ni_id1])
self.assertEqual(1, len(data['NetworkInterfaces']))
self.assertEqual('available', data['NetworkInterfaces'][0]['Status'])
ni = data['NetworkInterfaces'][0]
self.assertIsNotNone(ni.get('Association'))
self.assertEqual(public_ip1, ni['Association']['PublicIp'])
data = self.client.describe_addresses(AllocationIds=[alloc_id1,
alloc_id2])
for address in data['Addresses']:
if address['AllocationId'] == alloc_id1:
self.assertIsNotNone(address.get('AssociationId'))
elif address['AllocationId'] == alloc_id2:
self.assertIsNone(address.get('AssociationId'))
self.client.disassociate_address(AssociationId=assoc_id1)
self.cancelResourceCleanUp(clean_aa1)
self.get_address_assoc_waiter().wait_delete(
{'AllocationId': alloc_id1})

View File

@ -1,280 +0,0 @@
# Copyright 2014 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import os
import six
from six.moves.urllib.request import urlopen
import sys
import time
from lxml import etree
from oslo_log import log
import paramiko
from tempest.lib.common.utils import data_utils
from tempest.lib import decorators
import testtools
from ec2api_tempest_plugin import base
from ec2api_tempest_plugin import config
from ec2api_tempest_plugin.scenario import base as scenario_base
from ec2api_tempest_plugin import ssh
CONF = config.CONF
LOG = log.getLogger(__name__)
class VpnTest(scenario_base.BaseScenarioTest):
CUSTOMER_GATEWAY_IP = '198.51.100.77'
CUSTOMER_VPN_CIDR = '172.16.25.0/24'
OPENSWAN_LINK = ('http://mirrors.kernel.org/ubuntu/pool/universe/o/'
'openswan/openswan_2.6.38-1_i386.deb')
@classmethod
@base.safe_setup
def setUpClass(cls):
super(VpnTest, cls).setUpClass()
if not base.TesterStateHolder().get_vpc_enabled():
raise cls.skipException('VPC is disabled')
base.check_vpnaas_enabled()
@testtools.skip("Some unknown bug. Will fix this later")
@decorators.idempotent_id('63c2ac38-cfee-45d3-b765-c9b43859660d')
def test_vpn_routing(self):
vpc_id, _subnet_id = self.create_vpc_and_subnet('10.42.0.0/20')
vpn_data = self._create_and_configure_vpn(
vpc_id, self.CUSTOMER_GATEWAY_IP, self.CUSTOMER_VPN_CIDR)
vgw_id = vpn_data['VpnGatewayId']
data = self.client.describe_route_tables(
Filters=[{'Name': 'vpc-id', 'Values': [vpc_id]}])
rtb_id = data['RouteTables'][0]['RouteTableId']
data = self.client.describe_route_tables(RouteTableIds=[rtb_id])
data = data['RouteTables'][0]
route = next((r for r in data['Routes']
if r['DestinationCidrBlock'] == self.CUSTOMER_VPN_CIDR),
None)
if route:
self.assertEqual('active', route['State'])
self.assertEqual('EnableVgwRoutePropagation', route['Origin'])
self.assertIn('PropagatingVgws', data)
self.assertNotEmpty(data['PropagatingVgws'])
self.assertEqual(vgw_id, data['PropagatingVgws'][0]['GatewayId'])
@decorators.idempotent_id('9e284d9e-8fee-43c7-bcfb-8ed0dfa27dbc')
@testtools.skipUnless(CONF.aws.run_ssh, 'SSH tests are disabled.')
@testtools.skipUnless(CONF.aws.run_long_tests, 'Slow test has skipped.')
@testtools.skipUnless(CONF.aws.image_id_ubuntu,
"ubuntu image id is not defined")
@testtools.skipUnless(CONF.aws.image_id,
"image id is not defined")
def test_vpn_connectivity(self):
is_amazon = 'amazon' in CONF.aws.ec2_url
response = urlopen(self.OPENSWAN_LINK, timeout=30)
content = response.read()
if not is_amazon:
# NOTE(andrey-mp): gating in openstack doesn't have internet access
# so we need to download this package and install it with dpkg
filename = os.path.basename(self.OPENSWAN_LINK)
f = open(filename, 'wb')
f.write(content)
f.close()
key_name = data_utils.rand_name('testkey')
pkey = self.create_key_pair(key_name)
# run ubuntu instance to create one of VPN endpoint inside
sec_group_name = self.create_standard_security_group()
instance_id_ubuntu = self.run_instance(
KeyName=key_name, ImageId=CONF.aws.image_id_ubuntu,
SecurityGroups=[sec_group_name])
public_ip_ubuntu = self.get_instance_ip(instance_id_ubuntu)
instance = self.get_instance(instance_id_ubuntu)
private_ip_ubuntu = instance['PrivateIpAddress']
# create VPC, ..., VPN
vpc_id, subnet_id = self.create_vpc_and_subnet('10.43.0.0/20')
self.prepare_vpc_default_security_group(vpc_id)
vpn_data = self._create_and_configure_vpn(
vpc_id, public_ip_ubuntu, private_ip_ubuntu + '/32')
# run general instance inside VPC
instance_id = self.run_instance(KeyName=key_name,
ImageId=CONF.aws.image_id,
SubnetId=subnet_id)
instance = self.get_instance(instance_id)
private_ip_in_vpc = instance['PrivateIpAddress']
# configure ubuntu, install openswan and run it
ssh_client = ssh.Client(public_ip_ubuntu, CONF.aws.image_user_ubuntu,
pkey=pkey)
if not is_amazon:
self._upload_file(ssh_client, filename, filename)
ssh_client.exec_command('sudo DEBIAN_FRONTEND=noninteractive'
' dpkg -i ' + filename)
else:
ssh_client.exec_command('DEBIAN_FRONTEND=noninteractive sudo '
'apt-get install -fqy openswan')
ssh_client.exec_command('sudo -s su -c "'
'echo 1 > /proc/sys/net/ipv4/ip_forward"')
ssh_client.exec_command(
'for vpn in /proc/sys/net/ipv4/conf/*; do sudo -s su -c'
' "echo 0 > $vpn/accept_redirects; echo 0 > $vpn/send_redirects";'
' done')
sysctl_additions = [
'net.ipv4.ip_forward = 1',
'net.ipv4.conf.all.accept_redirects = 0',
'net.ipv4.conf.all.send_redirects = 0']
for item in sysctl_additions:
ssh_client.exec_command(
'sudo -s su -c "echo \'' + item + '\' >> /etc/sysctl.conf"')
ssh_client.exec_command('sudo sysctl -p')
ipsec_conf, ipsec_secrets = self._get_ipsec_conf(
vpn_data['VpnConnectionId'], private_ip_ubuntu)
ssh_client.exec_command('sudo -s su -c "echo \'\' > /etc/ipsec.conf"')
for fstr in ipsec_conf:
ssh_client.exec_command(
'sudo -s su -c "echo \'%s\' >> /etc/ipsec.conf"' % fstr)
ssh_client.exec_command(
'sudo -s su -c "echo \'%s\' > /etc/ipsec.secrets"' % ipsec_secrets)
ssh_client.exec_command('sudo service ipsec restart')
try:
self.get_vpn_connection_tunnel_waiter().wait_available(
vpn_data['VpnConnectionId'], ('UP'))
except Exception:
exc_info = sys.exc_info()
try:
output = ssh_client.exec_command('sudo ipsec auto --status')
LOG.warning(output)
except Exception:
pass
six.reraise(exc_info[1], None, exc_info[2])
time.sleep(10)
ssh_client.exec_command('ping -c 4 %s' % private_ip_in_vpc)
def _upload_file(self, ssh_client, local_path, remote_path):
ssh = ssh_client._get_ssh_connection()
transport = ssh.get_transport()
sftp_client = paramiko.SFTPClient.from_transport(transport)
sftp_client.put(local_path, remote_path)
def _create_and_configure_vpn(self, vpc_id, cgw_ip, customer_subnet):
data = self.client.create_customer_gateway(
Type='ipsec.1', PublicIp=cgw_ip, BgpAsn=65000)
cgw_id = data['CustomerGateway']['CustomerGatewayId']
self.addResourceCleanUp(
self.client.delete_customer_gateway, CustomerGatewayId=cgw_id)
self.get_customer_gateway_waiter().wait_available(cgw_id)
data = self.client.create_vpn_gateway(
Type='ipsec.1', AvailabilityZone=CONF.aws.aws_zone)
vgw_id = data['VpnGateway']['VpnGatewayId']
self.addResourceCleanUp(
self.client.delete_vpn_gateway, VpnGatewayId=vgw_id)
self.get_vpn_gateway_waiter().wait_available(vgw_id)
data = self.client.attach_vpn_gateway(VpnGatewayId=vgw_id,
VpcId=vpc_id)
self.addResourceCleanUp(self.client.detach_vpn_gateway,
VpnGatewayId=vgw_id, VpcId=vpc_id)
self.get_vpn_gateway_attachment_waiter().wait_available(
vgw_id, 'attached')
data = self.client.describe_route_tables(
Filters=[{'Name': 'vpc-id', 'Values': [vpc_id]}])
rtb_id = data['RouteTables'][0]['RouteTableId']
data = self.client.enable_vgw_route_propagation(RouteTableId=rtb_id,
GatewayId=vgw_id)
self.addResourceCleanUp(self.client.disable_vgw_route_propagation,
RouteTableId=rtb_id, GatewayId=vgw_id)
data = self.client.create_vpn_connection(
CustomerGatewayId=cgw_id, VpnGatewayId=vgw_id,
Options={'StaticRoutesOnly': True}, Type='ipsec.1')
vpn_data = data['VpnConnection']
vpn_id = data['VpnConnection']['VpnConnectionId']
self.addResourceCleanUp(self.client.delete_vpn_connection,
VpnConnectionId=vpn_id)
self.get_vpn_connection_waiter().wait_available(vpn_id)
data = self.client.create_vpn_connection_route(
VpnConnectionId=vpn_id,
DestinationCidrBlock=customer_subnet)
self.get_vpn_connection_route_waiter(customer_subnet).wait_available(
vpn_id)
return vpn_data
def _get_ipsec_conf(self, vpn_connection_id, private_ip_ubuntu):
data = self.client.describe_vpn_connections(
VpnConnectionIds=[vpn_connection_id])
vpn_data = data['VpnConnections'][0]
vpn_config = etree.fromstring(
vpn_data['CustomerGatewayConfiguration'])
psks = vpn_config.xpath(
'/vpn_connection/ipsec_tunnel/ike/pre_shared_key')
self.assertNotEmpty(psks)
vgw_ip = vpn_config.xpath(
'/vpn_connection/ipsec_tunnel/vpn_gateway/tunnel_outside_address'
'/ip_address')
self.assertTrue(vgw_ip)
ipsec_key = psks[0].text
vgw_ip = vgw_ip[0].text
ipsec_conf = []
for item in self._ipsec_conf:
ipsec_conf.append(item % {
'vpc_cidr': '10.43.0.0/20',
'vgw_ip': vgw_ip,
'private_ip_ubuntu': private_ip_ubuntu})
ipsec_secrets = ('%(private_ip_ubuntu)s %(vgw_ip)s: '
'PSK \\"%(ipsec_key)s\\"' % {
'private_ip_ubuntu': private_ip_ubuntu,
'vgw_ip': vgw_ip,
'ipsec_key': ipsec_key})
return ipsec_conf, ipsec_secrets
_ipsec_conf = [
'## general configuration parameters ##',
'config setup',
' plutodebug=all',
' plutostderrlog=/var/log/pluto.log',
' protostack=netkey',
' nat_traversal=yes',
' virtual_private=%%v4:%(vpc_cidr)s',
' nhelpers=0',
'## connection definition in Debian ##',
'conn my-conn',
' authby=secret',
' auto=start',
' pfs=yes',
' type=tunnel',
' #left side (myside)',
' left=%(private_ip_ubuntu)s',
' leftsubnet=%(private_ip_ubuntu)s/32',
' leftnexthop=%(vgw_ip)s',
' leftsourceip=%(private_ip_ubuntu)s',
' #right security gateway (VPN side)',
' right=%(vgw_ip)s',
' rightsubnet=%(vpc_cidr)s',
' rightnexthop=%(private_ip_ubuntu)s']

View File

@ -1,90 +0,0 @@
# Copyright 2012 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import socket
import time
import warnings
from oslo_log import log as logging
from tempest.lib.common import ssh
from tempest.lib import exceptions
with warnings.catch_warnings():
warnings.simplefilter("ignore")
import paramiko
LOG = logging.getLogger(__name__)
DIS_ALG = dict(pubkeys=['rsa-sha2-256', 'rsa-sha2-512'])
class Client(ssh.Client):
def _get_ssh_connection(self, sleep=1.5, backoff=1):
"""Returns an ssh connection to the specified host."""
bsleep = sleep
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(
paramiko.AutoAddPolicy())
_start_time = time.time()
if self.pkey is not None:
LOG.info("Creating ssh connection to '%s:%d' as '%s'"
" with public key authentication",
self.host, self.port, self.username)
else:
LOG.info("Creating ssh connection to '%s:%d' as '%s'"
" with password %s",
self.host, self.port, self.username, str(self.password))
attempts = 0
while True:
if self.proxy_client is not None:
proxy_chan = self._get_proxy_channel()
else:
proxy_chan = None
try:
ssh.connect(self.host, port=self.port,
username=self.username,
password=self.password,
look_for_keys=self.look_for_keys,
key_filename=self.key_filename,
timeout=self.channel_timeout, pkey=self.pkey,
sock=proxy_chan,
disabled_algorithms=DIS_ALG)
LOG.info("ssh connection to %s@%s successfully created",
self.username, self.host)
return ssh
except (EOFError,
socket.error, socket.timeout,
paramiko.SSHException) as e:
ssh.close()
if self._is_timed_out(_start_time):
LOG.exception("Failed to establish authenticated ssh"
" connection to %s@%s after %d attempts. "
"Proxy client: %s",
self.username, self.host, attempts,
self._get_proxy_client_info())
raise exceptions.SSHTimeout(host=self.host,
user=self.username,
password=self.password)
bsleep += backoff
attempts += 1
LOG.warning("Failed to establish authenticated ssh"
" connection to %s@%s (%s). Number attempts: %s."
" Retry after %d seconds.",
self.username, self.host, e, attempts, bsleep)
time.sleep(bsleep)

View File

@ -1,14 +0,0 @@
# The order of packages is significant, because pip processes them in the order
# of appearance. Changing the order has an impact on the overall integration
# process, which may cause wedges in the gate later.
pbr!=2.1.0,>=2.0.0 # Apache-2.0
botocore>=1.5.1 # Apache-2.0
oslo.config>=5.2.0 # Apache-2.0
oslo.log>=3.36.0 # Apache-2.0
six>=1.10.0 # MIT
testtools>=2.2.0 # MIT
paramiko>=2.0.0 # LGPLv2.1+
netaddr>=0.7.18 # BSD
lxml!=3.7.0,>=3.4.1 # BSD
tempest>=17.1.0 # Apache-2.0

View File

@ -1,42 +0,0 @@
[metadata]
name = ec2api-tempest-plugin
summary = Tempest plugin for ec2-api
description-file =
README.rst
author = OpenStack
author-email = openstack-discuss@lists.openstack.org
home-page = https://opendev.org/openstack/ec2api-tempest-plugin
classifier =
Environment :: OpenStack
Intended Audience :: Information Technology
Intended Audience :: System Administrators
License :: OSI Approved :: Apache Software License
Operating System :: POSIX :: Linux
Programming Language :: Python
Programming Language :: Python :: 3
Programming Language :: Python :: 3.5
Programming Language :: Python :: 3.6
Programming Language :: Python :: 3.7
Programming Language :: Python :: 3.8
[files]
packages =
ec2api_tempest_plugin
[compile_catalog]
directory = ec2api_tempest_plugin/locale
domain = ec2api_tempest_plugin
[update_catalog]
domain = ec2api_tempest_plugin
output_dir = ec2api_tempest_plugin/locale
input_file = ec2api_tempest_plugin/locale/ec2api_tempest_plugin.pot
[extract_messages]
keywords = _ gettext ngettext l_ lazy_gettext
mapping_file = babel.cfg
output_file = ec2api_tempest_plugin/locale/ec2api_tempest_plugin.pot
[entry_points]
tempest.test_plugins =
aws_tests = ec2api_tempest_plugin.plugin:AWSTempestPlugin

View File

@ -1,29 +0,0 @@
# Copyright (c) 2013 Hewlett-Packard Development Company, L.P.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
# implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# THIS FILE IS MANAGED BY THE GLOBAL REQUIREMENTS REPO - DO NOT EDIT
import setuptools
# In python < 2.7.4, a lazy loading of package `pbr` will break
# setuptools if some other modules registered functions in `atexit`.
# solution from: http://bugs.python.org/issue15881#msg170215
try:
import multiprocessing # noqa
except ImportError:
pass
setuptools.setup(
setup_requires=['pbr>=2.0.0'],
pbr=True)

View File

@ -1,5 +0,0 @@
# The order of packages is significant, because pip processes them in the order
# of appearance. Changing the order has an impact on the overall integration
# process, which may cause wedges in the gate later.
hacking>=3.2.0 # Apache-2.0

48
tox.ini
View File

@ -1,48 +0,0 @@
[tox]
minversion = 3.18.0
envlist = py37,pep8
skipsdist = True
ignore_basepython_conflict = True
[testenv]
usedevelop = True
basepython = python3
# tox is silly... these need to be separated by a newline....
allowlist_externals = bash
find
rm
env
install_command = pip install -c{env:UPPER_CONSTRAINTS_FILE:https://releases.openstack.org/constraints/upper/master} {opts} {packages}
setenv =
VIRTUAL_ENV={envdir}
OS_STDOUT_CAPTURE=1
OS_STDERR_CAPTURE=1
OS_TEST_TIMEOUT=60
PYTHONWARNINGS=default::DeprecationWarning
LANG=en_US.UTF-8
LANGUAGE=en_US:en
LC_ALL=C
deps = -r{toxinidir}/test-requirements.txt
commands =
find . -type f -name "*.pyc" -delete
rm -f .testrepository/times.dbm
[testenv:pep8]
commands = flake8 {posargs}
[testenv:venv]
commands = {posargs}
[testenv:debug]
commands = oslo_debug_helper {posargs}
[flake8]
# E123, E125 skipped as they are invalid PEP-8.
show-source = True
ignore = E122,E123,E125,E126,E127,E128,W503,W504
builtins = _
# H106: Don't put vim configuration in source files
# H203: Use assertIs(Not)None to check for None
enable-extensions=H106,H203
exclude=.venv,.git,.tox,dist,doc,*lib/python*,*egg,build