Move to template per test class

This has several advantages for long term:

* No need to worry for race conditions
* It's clear which resources are affected by a given test
* More readable templates

The big disadvantage is maintaining multiple templates.

Change-Id: I2ebe55560d1ed57fb626d4808af1b4a3f7069630
This commit is contained in:
abregman 2018-11-12 12:19:21 +02:00
parent e34986ceab
commit 6275e9a6e5
10 changed files with 285 additions and 33 deletions

View File

@ -11,5 +11,19 @@
# 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 import config
conf = config.CONF
COMPLETE_STATUS = "CREATE_COMPLETE"
DEFAULT_FLAVOR = "m1.micro"
DEFAULT_API_VER = 2
TEMPLATE_SUFFIX = ".yaml"
DEFAULT_PARAMS = {
'public_net': conf.network.floating_network_name,
'image': conf.compute.image_ref,
'flavor': DEFAULT_FLAVOR
}

View File

@ -18,3 +18,11 @@ class NetworkManager(object):
def __init__(self, client_manager):
self.client = client_manager.get_neutron_client()
def create_sg_rules(self, rules, sg_id):
"""Creates security group rules."""
for rule in rules:
rule['security_group_id'] = sg_id
body = {'security_group_rule': rule}
print(body)
self.client.create_security_group_rule(body)

View File

@ -25,8 +25,7 @@ import tobiko.common.utils.process as proc_utils
SG_RULES = {'ALLOW_ICMP':
{'direction': 'ingress',
'ethertype': 'IPv4',
'protcol': 'icmp'
'protocol': 'icmp'
}
}
@ -76,6 +75,9 @@ def get_packet_loss(ip):
packet_loss = m.group(1)
finally:
# Remove files created by pre test
from shutil import copyfile
copyfile(PING_OUTPUT_F, "/home/abregman/stam")
os.remove(PING_OUTPUT_F)
os.remove(PING_PID_F)

View File

@ -34,5 +34,3 @@ class TobikoTempestPlugin(plugins.TempestPlugin):
def get_opt_lists(self):
pass
# return [(tobiko_config.tobiko_group.name,
# tobiko_config.TobikoGroup)]

View File

@ -16,6 +16,9 @@ from tempest import config
import testscenarios
import testtools
from tobiko.common import constants
from tobiko.common import clients
class TobikoTest(testtools.testcase.WithAttributes,
testscenarios.WithScenarios,
@ -24,3 +27,8 @@ class TobikoTest(testtools.testcase.WithAttributes,
def setUp(self):
super(TobikoTest, self).setUp()
self.conf = config.CONF
self.default_params = {
'public_net': self.conf.network.floating_network_name,
'image': self.conf.compute.image_ref,
'flavor': constants.DEFAULT_FLAVOR}
self.clientManager = clients.ClientManager(conf=self.conf)

View File

@ -21,42 +21,41 @@ from tobiko.tests import base
from tobiko.common.managers import stack
from tobiko.common.managers import network
from tobiko.common import constants
from tobiko.common import clients
class ScenarioTestsBase(base.TobikoTest):
"""All scenario tests inherit from this scenario base class."""
def setUp(self):
def setUp(self, file_path, params=None):
super(ScenarioTestsBase, self).setUp()
self.clientManager = clients.ClientManager(self.conf)
templates_dir = os.path.join(os.path.dirname(__file__), 'templates')
self.stackManager = stack.StackManager(self.clientManager,
templates_dir)
self.networkManager = network.NetworkManager(self.clientManager)
self.params = params or self.default_params
file_name = os.path.basename(file_path)
self.stack_name = file_name.split(".py")[0]
try:
self.stackManager.get_stack("default")
self.stackManager.get_stack(self.stack_name)
except exc.HTTPNotFound:
self.create_stack()
self.create_stack(self.stack_name)
def create_stack(self):
"""Creates stack to be used by all scenario tests."""
# Defines parameters required by heat template
parameters = {'public_net': self.conf.network.floating_network_name,
'image': self.conf.compute.image_ref,
'flavor': "m1.micro"}
# creates stack and stores its ID
st = self.stackManager.create_stack(
stack_name="default", template_name="default.yaml",
parameters=parameters, wait_for_status=constants.COMPLETE_STATUS)
stack_name=self.stack_name,
template_name="%s.yaml" % self.stack_name,
parameters=self.params,
status=constants.COMPLETE_STATUS)
return st['stack']
def _get_stack(self, name="default"):
stack = self.stackManager.get_stack(name)
def _get_stack(self):
stack = self.stackManager.get_stack(self.stack_name)
if not stack:
stack = self.create_stack()
return stack

View File

@ -0,0 +1,116 @@
heat_template_version: 2013-05-23
description: |
Default stack used by tests. One instance with FIP.
parameters:
flavor:
type: string
image:
type: string
subnet_cidr:
type: string
default: 190.40.2.0/24
public_net:
type: string
default: public
private_net:
type: string
default: heat-net
dns_servers:
type: comma_delimited_list
default: ["8.8.8.8", "8.8.4.4"]
resources:
sg:
type: OS::Neutron::SecurityGroup
properties:
name: sg
description: Security group to allow ICMP and SSH
rules:
- protocol: icmp
- protocol: tcp
port_range_min: 22
port_range_max: 22
sg2:
type: OS::Neutron::SecurityGroup
properties:
name: sg2
description: Security group to deny ICMP and SSH
floating_ip:
type: OS::Neutron::FloatingIP
properties:
floating_network: {get_param: public_net}
floating_ip2:
type: OS::Neutron::FloatingIP
properties:
floating_network: {get_param: public_net}
network:
type: OS::Neutron::Net
subnet:
type: OS::Neutron::Subnet
properties:
network: {get_resource: network}
ip_version: 4
cidr: {get_param: subnet_cidr}
dns_nameservers: {get_param: dns_servers}
router:
type: OS::Neutron::Router
properties:
external_gateway_info:
network: {get_param: public_net}
router_interface:
type: OS::Neutron::RouterInterface
properties:
router: {get_resource: router}
subnet: {get_resource: subnet}
wait_handle:
type: OS::Heat::WaitConditionHandle
server:
type: OS::Nova::Server
properties:
image: {get_param: image}
flavor: {get_param: flavor}
networks:
- subnet: {get_resource: subnet}
security_groups:
- {get_resource: sg}
# Server without security groups
server2:
type: OS::Nova::Server
properties:
image: {get_param: image}
flavor: {get_param: flavor}
networks:
- subnet: {get_resource: subnet}
security_groups:
- {get_resource: sg2}
server_floating_ip_assoc:
type: OS::Neutron::FloatingIPAssociation
properties:
floatingip_id: {get_resource: floating_ip}
port_id: {get_attr: [server, addresses, {get_resource: network}, 0, port]}
server_floating_ip_assoc2:
type: OS::Neutron::FloatingIPAssociation
properties:
floatingip_id: {get_resource: floating_ip2}
port_id: {get_attr: [server2, addresses, {get_resource: network}, 0, port]}
outputs:
fip:
value: {get_attr: [floating_ip, floating_ip_address]}
fip2:
value: {get_attr: [floating_ip2, floating_ip_address]}

View File

@ -0,0 +1,116 @@
heat_template_version: 2013-05-23
description: |
Default stack used by tests. One instance with FIP.
parameters:
flavor:
type: string
image:
type: string
subnet_cidr:
type: string
default: 190.40.2.0/24
public_net:
type: string
default: public
private_net:
type: string
default: heat-net
dns_servers:
type: comma_delimited_list
default: ["8.8.8.8", "8.8.4.4"]
resources:
sg:
type: OS::Neutron::SecurityGroup
properties:
name: sg
description: Security group to allow ICMP and SSH
rules:
- protocol: icmp
- protocol: tcp
port_range_min: 22
port_range_max: 22
sg2:
type: OS::Neutron::SecurityGroup
properties:
name: sg2
description: Security group to deny ICMP and SSH
floating_ip:
type: OS::Neutron::FloatingIP
properties:
floating_network: {get_param: public_net}
floating_ip2:
type: OS::Neutron::FloatingIP
properties:
floating_network: {get_param: public_net}
network:
type: OS::Neutron::Net
subnet:
type: OS::Neutron::Subnet
properties:
network: {get_resource: network}
ip_version: 4
cidr: {get_param: subnet_cidr}
dns_nameservers: {get_param: dns_servers}
router:
type: OS::Neutron::Router
properties:
external_gateway_info:
network: {get_param: public_net}
router_interface:
type: OS::Neutron::RouterInterface
properties:
router: {get_resource: router}
subnet: {get_resource: subnet}
wait_handle:
type: OS::Heat::WaitConditionHandle
server:
type: OS::Nova::Server
properties:
image: {get_param: image}
flavor: {get_param: flavor}
networks:
- subnet: {get_resource: subnet}
security_groups:
- {get_resource: sg}
# Server without security groups
server2:
type: OS::Nova::Server
properties:
image: {get_param: image}
flavor: {get_param: flavor}
networks:
- subnet: {get_resource: subnet}
security_groups:
- {get_resource: sg2}
server_floating_ip_assoc:
type: OS::Neutron::FloatingIPAssociation
properties:
floatingip_id: {get_resource: floating_ip}
port_id: {get_attr: [server, addresses, {get_resource: network}, 0, port]}
server_floating_ip_assoc2:
type: OS::Neutron::FloatingIPAssociation
properties:
floatingip_id: {get_resource: floating_ip2}
port_id: {get_attr: [server2, addresses, {get_resource: network}, 0, port]}
outputs:
fip:
value: {get_attr: [floating_ip, floating_ip_address]}
fip2:
value: {get_attr: [floating_ip2, floating_ip_address]}

View File

@ -24,7 +24,9 @@ class ContinuousPingTest(base.ScenarioTestsBase):
def setUp(self):
super(ContinuousPingTest, self).setUp()
self.stack = self._get_stack()
self.fip = self.stack.outputs[1]['output_value']
print(self.stack)
print(self.stack.stack_status)
self.fip = self.stackManager.get_output(self.stack, "fip")
def test_pre_continuous_ping(self):
"""Starts the ping process."""

View File

@ -20,22 +20,11 @@ class FloatingIPTest(base.ScenarioTestsBase):
"""Tests server connectivity"""
def setUp(self):
super(FloatingIPTest, self).setUp()
super(FloatingIPTest, self).setUp(__file__)
self.stack = self._get_stack()
self.unreachable_fip = self.stack.outputs[0]['output_value']
self.fip = self.stack.outputs[1]['output_value']
def test_pre_secgroup(self):
"""Validates security group before upgrade."""
assert_ping(self.fip)
assert_ping(self.unreachable_fip, should_fail=True)
def test_post_secgroup(self):
"""Validates security groups post upgrade."""
assert_ping(self.fip)
assert_ping(self.unreachable_fip, should_fail=True)
print(self.stack)
self.fip = self.stackManager.get_output(self.stack, "fip")
self.unreachable_fip = self.stackManager.get_output(self.stack, "fip2")
def test_pre_fip(self):
"""Validates connectivity to a server created by another test."""