Add EnvironmentDescription, pass it down

* The EnvironmentDescription class describes an entire fullstack
  environment (as opposed to the currently implemented host-only
  descriptions). This will allow future patches to signify that a test
  should set up an environment that supports tunneling, l2pop, QoS and
  more.
* Now, most fullstack fixtures (config and process ones, at least),
  expect both the EnvironmentDescription for the current test and the
  HostDescription for the 'host' the config/process is on. This allows
  for easier and most robust future changes, as now adding a new
  parameter to one of the description objects doesn't mean adding that
  argument to a number of other objects which are using it.
* Changed HostDescription's default argument of l3_agent to False, since
  adding new configurations and defualting them to True forces the
  author to go through ALL the tests and explicitly turn them on/off.
  However, defaulting new configurations to False only requires
  explicitly turning them on, which we ought to do anyway.

Change-Id: Ib2f12016ba4371bfda76c82e11d0794acc759955
This commit is contained in:
John Schwarz 2015-08-09 17:00:57 +03:00
parent 53fe9ddd6c
commit 7aa3b2eace
6 changed files with 82 additions and 52 deletions

View File

@ -24,17 +24,12 @@ from neutron.tests.fullstack.resources import client as client_resource
class BaseFullStackTestCase(base.MySQLTestCase): class BaseFullStackTestCase(base.MySQLTestCase):
"""Base test class for full-stack tests.""" """Base test class for full-stack tests."""
def __init__(self, environment, *args, **kwargs): def setUp(self, environment):
super(BaseFullStackTestCase, self).__init__(*args, **kwargs)
self.environment = environment
def setUp(self):
super(BaseFullStackTestCase, self).setUp() super(BaseFullStackTestCase, self).setUp()
self.create_db_tables() self.create_db_tables()
self.environment = environment
self.environment.test_name = self.get_name() self.environment.test_name = self.get_name()
self.useFixture(self.environment) self.useFixture(self.environment)
self.client = self.environment.neutron_server.client self.client = self.environment.neutron_server.client
self.safe_client = self.useFixture( self.safe_client = self.useFixture(
client_resource.ClientFixture(self.client)) client_resource.ClientFixture(self.client))

View File

@ -81,9 +81,11 @@ class ConfigFixture(fixtures.Fixture):
then the dynamic configuration values won't change. The correct usage then the dynamic configuration values won't change. The correct usage
is initializing a new instance of the class. is initializing a new instance of the class.
""" """
def __init__(self, temp_dir, base_filename): def __init__(self, env_desc, host_desc, temp_dir, base_filename):
super(ConfigFixture, self).__init__() super(ConfigFixture, self).__init__()
self.config = ConfigDict() self.config = ConfigDict()
self.env_desc = env_desc
self.host_desc = host_desc
self.temp_dir = temp_dir self.temp_dir = temp_dir
self.base_filename = base_filename self.base_filename = base_filename
@ -96,14 +98,15 @@ class ConfigFixture(fixtures.Fixture):
class NeutronConfigFixture(ConfigFixture): class NeutronConfigFixture(ConfigFixture):
def __init__(self, temp_dir, connection, rabbitmq_environment): def __init__(self, env_desc, host_desc, temp_dir,
connection, rabbitmq_environment):
super(NeutronConfigFixture, self).__init__( super(NeutronConfigFixture, self).__init__(
temp_dir, base_filename='neutron.conf') env_desc, host_desc, temp_dir, base_filename='neutron.conf')
self.config.update({ self.config.update({
'DEFAULT': { 'DEFAULT': {
'host': self._generate_host(), 'host': self._generate_host(),
'state_path': self._generate_state_path(temp_dir), 'state_path': self._generate_state_path(self.temp_dir),
'lock_path': '$state_path/lock', 'lock_path': '$state_path/lock',
'bind_port': self._generate_port(), 'bind_port': self._generate_port(),
'api_paste_config': self._generate_api_paste(), 'api_paste_config': self._generate_api_paste(),
@ -150,9 +153,9 @@ class NeutronConfigFixture(ConfigFixture):
class ML2ConfigFixture(ConfigFixture): class ML2ConfigFixture(ConfigFixture):
def __init__(self, temp_dir, tenant_network_types): def __init__(self, env_desc, host_desc, temp_dir, tenant_network_types):
super(ML2ConfigFixture, self).__init__( super(ML2ConfigFixture, self).__init__(
temp_dir, base_filename='ml2_conf.ini') env_desc, host_desc, temp_dir, base_filename='ml2_conf.ini')
self.config.update({ self.config.update({
'ml2': { 'ml2': {
@ -173,9 +176,10 @@ class ML2ConfigFixture(ConfigFixture):
class OVSConfigFixture(ConfigFixture): class OVSConfigFixture(ConfigFixture):
def __init__(self, temp_dir): def __init__(self, env_desc, host_desc, temp_dir):
super(OVSConfigFixture, self).__init__( super(OVSConfigFixture, self).__init__(
temp_dir, base_filename='openvswitch_agent.ini') env_desc, host_desc, temp_dir,
base_filename='openvswitch_agent.ini')
self.config.update({ self.config.update({
'ovs': { 'ovs': {
@ -205,9 +209,9 @@ class OVSConfigFixture(ConfigFixture):
class L3ConfigFixture(ConfigFixture): class L3ConfigFixture(ConfigFixture):
def __init__(self, temp_dir, integration_bridge): def __init__(self, env_desc, host_desc, temp_dir, integration_bridge):
super(L3ConfigFixture, self).__init__( super(L3ConfigFixture, self).__init__(
temp_dir, base_filename='l3_agent.ini') env_desc, host_desc, temp_dir, base_filename='l3_agent.ini')
self.config.update({ self.config.update({
'DEFAULT': { 'DEFAULT': {

View File

@ -25,13 +25,21 @@ from neutron.tests.fullstack.resources import process
LOG = logging.getLogger(__name__) LOG = logging.getLogger(__name__)
class EnvironmentDescription(object):
"""A set of characteristics of an environment setup.
Does the setup, as a whole, support tunneling? How about l2pop?
"""
pass
class HostDescription(object): class HostDescription(object):
"""A set of characteristics of an environment Host. """A set of characteristics of an environment Host.
What agents should the host spawn? What mode should each agent operate What agents should the host spawn? What mode should each agent operate
under? under?
""" """
def __init__(self, l3_agent=True): def __init__(self, l3_agent=False):
self.l3_agent = l3_agent self.l3_agent = l3_agent
@ -50,18 +58,20 @@ class Host(fixtures.Fixture):
and disconnects the host from other hosts. and disconnects the host from other hosts.
""" """
def __init__(self, test_name, neutron_config, host_description, def __init__(self, env_desc, host_desc,
test_name, neutron_config,
central_data_bridge, central_external_bridge): central_data_bridge, central_external_bridge):
self.env_desc = env_desc
self.host_desc = host_desc
self.test_name = test_name self.test_name = test_name
self.neutron_config = neutron_config self.neutron_config = neutron_config
self.host_description = host_description
self.central_data_bridge = central_data_bridge self.central_data_bridge = central_data_bridge
self.central_external_bridge = central_external_bridge self.central_external_bridge = central_external_bridge
self.agents = {} self.agents = {}
def _setUp(self): def _setUp(self):
agent_cfg_fixture = config.OVSConfigFixture( agent_cfg_fixture = config.OVSConfigFixture(
self.neutron_config.temp_dir) self.env_desc, self.host_desc, self.neutron_config.temp_dir)
self.useFixture(agent_cfg_fixture) self.useFixture(agent_cfg_fixture)
br_phys = self.useFixture( br_phys = self.useFixture(
@ -71,11 +81,13 @@ class Host(fixtures.Fixture):
self.ovs_agent = self.useFixture( self.ovs_agent = self.useFixture(
process.OVSAgentFixture( process.OVSAgentFixture(
self.env_desc, self.host_desc,
self.test_name, self.neutron_config, agent_cfg_fixture)) self.test_name, self.neutron_config, agent_cfg_fixture))
if self.host_description.l3_agent: if self.host_desc.l3_agent:
l3_agent_cfg_fixture = self.useFixture( l3_agent_cfg_fixture = self.useFixture(
config.L3ConfigFixture( config.L3ConfigFixture(
self.env_desc, self.host_desc,
self.neutron_config.temp_dir, self.neutron_config.temp_dir,
self.ovs_agent.agent_cfg_fixture.get_br_int_name())) self.ovs_agent.agent_cfg_fixture.get_br_int_name()))
br_ex = self.useFixture( br_ex = self.useFixture(
@ -84,6 +96,7 @@ class Host(fixtures.Fixture):
self.connect_to_external_network(br_ex) self.connect_to_external_network(br_ex)
self.l3_agent = self.useFixture( self.l3_agent = self.useFixture(
process.L3AgentFixture( process.L3AgentFixture(
self.env_desc, self.host_desc,
self.test_name, self.test_name,
self.neutron_config, self.neutron_config,
l3_agent_cfg_fixture)) l3_agent_cfg_fixture))
@ -128,13 +141,15 @@ class Environment(fixtures.Fixture):
the type of Host to create. the type of Host to create.
""" """
def __init__(self, hosts_descriptions): def __init__(self, env_desc, hosts_desc):
""" """
:param hosts_descriptions: A list of HostDescription instances. :param env_desc: An EnvironmentDescription instance.
:param hosts_desc: A list of HostDescription instances.
""" """
super(Environment, self).__init__() super(Environment, self).__init__()
self.hosts_descriptions = hosts_descriptions self.env_desc = env_desc
self.hosts_desc = hosts_desc
self.hosts = [] self.hosts = []
def wait_until_env_is_up(self): def wait_until_env_is_up(self):
@ -148,33 +163,37 @@ class Environment(fixtures.Fixture):
except nc_exc.NeutronClientException: except nc_exc.NeutronClientException:
return False return False
def _create_host(self, description): def _create_host(self, host_desc):
temp_dir = self.useFixture(fixtures.TempDir()).path temp_dir = self.useFixture(fixtures.TempDir()).path
neutron_config = config.NeutronConfigFixture( neutron_config = config.NeutronConfigFixture(
temp_dir, cfg.CONF.database.connection, self.env_desc, host_desc, temp_dir,
self.rabbitmq_environment) cfg.CONF.database.connection, self.rabbitmq_environment)
self.useFixture(neutron_config) self.useFixture(neutron_config)
return self.useFixture( return self.useFixture(
Host(self.test_name, Host(self.env_desc,
host_desc,
self.test_name,
neutron_config, neutron_config,
description,
self.central_data_bridge, self.central_data_bridge,
self.central_external_bridge)) self.central_external_bridge))
def _setUp(self): def _setUp(self):
self.temp_dir = self.useFixture(fixtures.TempDir()).path self.temp_dir = self.useFixture(fixtures.TempDir()).path
self.rabbitmq_environment = self.useFixture( self.rabbitmq_environment = self.useFixture(
process.RabbitmqEnvironmentFixture()) process.RabbitmqEnvironmentFixture())
plugin_cfg_fixture = self.useFixture( plugin_cfg_fixture = self.useFixture(
config.ML2ConfigFixture(self.temp_dir, 'vlan')) config.ML2ConfigFixture(
self.env_desc, None, self.temp_dir, 'vlan'))
neutron_cfg_fixture = self.useFixture( neutron_cfg_fixture = self.useFixture(
config.NeutronConfigFixture( config.NeutronConfigFixture(
self.temp_dir, self.env_desc, None, self.temp_dir,
cfg.CONF.database.connection, cfg.CONF.database.connection, self.rabbitmq_environment))
self.rabbitmq_environment))
self.neutron_server = self.useFixture( self.neutron_server = self.useFixture(
process.NeutronServerFixture( process.NeutronServerFixture(
self.env_desc, None,
self.test_name, neutron_cfg_fixture, plugin_cfg_fixture)) self.test_name, neutron_cfg_fixture, plugin_cfg_fixture))
self.central_data_bridge = self.useFixture( self.central_data_bridge = self.useFixture(
@ -182,7 +201,6 @@ class Environment(fixtures.Fixture):
self.central_external_bridge = self.useFixture( self.central_external_bridge = self.useFixture(
net_helpers.OVSBridgeFixture('cnt-ex')).bridge net_helpers.OVSBridgeFixture('cnt-ex')).bridge
self.hosts = [self._create_host(description) for description in self.hosts = [self._create_host(desc) for desc in self.hosts_desc]
self.hosts_descriptions]
self.wait_until_env_is_up() self.wait_until_env_is_up()

View File

@ -90,7 +90,10 @@ class NeutronServerFixture(fixtures.Fixture):
NEUTRON_SERVER = "neutron-server" NEUTRON_SERVER = "neutron-server"
def __init__(self, test_name, neutron_cfg_fixture, plugin_cfg_fixture): def __init__(self, env_desc, host_desc,
test_name, neutron_cfg_fixture, plugin_cfg_fixture):
self.env_desc = env_desc
self.host_desc = host_desc
self.test_name = test_name self.test_name = test_name
self.neutron_cfg_fixture = neutron_cfg_fixture self.neutron_cfg_fixture = neutron_cfg_fixture
self.plugin_cfg_fixture = plugin_cfg_fixture self.plugin_cfg_fixture = plugin_cfg_fixture
@ -125,7 +128,10 @@ class OVSAgentFixture(fixtures.Fixture):
NEUTRON_OVS_AGENT = "neutron-openvswitch-agent" NEUTRON_OVS_AGENT = "neutron-openvswitch-agent"
def __init__(self, test_name, neutron_cfg_fixture, agent_cfg_fixture): def __init__(self, env_desc, host_desc,
test_name, neutron_cfg_fixture, agent_cfg_fixture):
self.env_desc = env_desc
self.host_desc = host_desc
self.test_name = test_name self.test_name = test_name
self.neutron_cfg_fixture = neutron_cfg_fixture self.neutron_cfg_fixture = neutron_cfg_fixture
self.neutron_config = self.neutron_cfg_fixture.config self.neutron_config = self.neutron_cfg_fixture.config
@ -151,8 +157,11 @@ class L3AgentFixture(fixtures.Fixture):
NEUTRON_L3_AGENT = "neutron-l3-agent" NEUTRON_L3_AGENT = "neutron-l3-agent"
def __init__(self, test_name, neutron_cfg_fixture, l3_agent_cfg_fixture): def __init__(self, env_desc, host_desc,
test_name, neutron_cfg_fixture, l3_agent_cfg_fixture):
super(L3AgentFixture, self).__init__() super(L3AgentFixture, self).__init__()
self.env_desc = env_desc
self.host_desc = host_desc
self.test_name = test_name self.test_name = test_name
self.neutron_cfg_fixture = neutron_cfg_fixture self.neutron_cfg_fixture = neutron_cfg_fixture
self.l3_agent_cfg_fixture = l3_agent_cfg_fixture self.l3_agent_cfg_fixture = l3_agent_cfg_fixture

View File

@ -21,11 +21,12 @@ from neutron.tests.fullstack.resources import machine
class TestConnectivitySameNetwork(base.BaseFullStackTestCase): class TestConnectivitySameNetwork(base.BaseFullStackTestCase):
def __init__(self, *args, **kwargs): def setUp(self):
host_descriptions = [ host_descriptions = [
environment.HostDescription(l3_agent=False) for _ in range(2)] environment.HostDescription() for _ in range(2)]
env = environment.Environment(host_descriptions) env = environment.Environment(environment.EnvironmentDescription(),
super(TestConnectivitySameNetwork, self).__init__(env, *args, **kwargs) host_descriptions)
super(TestConnectivitySameNetwork, self).setUp(env)
def test_connectivity(self): def test_connectivity(self):
tenant_uuid = uuidutils.generate_uuid() tenant_uuid = uuidutils.generate_uuid()

View File

@ -25,10 +25,12 @@ from neutron.tests.fullstack.resources import environment
class TestLegacyL3Agent(base.BaseFullStackTestCase): class TestLegacyL3Agent(base.BaseFullStackTestCase):
def __init__(self, *args, **kwargs):
def setUp(self):
host_descriptions = [environment.HostDescription(l3_agent=True)] host_descriptions = [environment.HostDescription(l3_agent=True)]
env = environment.Environment(host_descriptions) env = environment.Environment(environment.EnvironmentDescription(),
super(TestLegacyL3Agent, self).__init__(env, *args, **kwargs) host_descriptions)
super(TestLegacyL3Agent, self).setUp(env)
def _get_namespace(self, router_id): def _get_namespace(self, router_id):
return namespaces.build_ns_name(l3_agent.NS_PREFIX, router_id) return namespaces.build_ns_name(l3_agent.NS_PREFIX, router_id)
@ -53,12 +55,13 @@ class TestLegacyL3Agent(base.BaseFullStackTestCase):
class TestHAL3Agent(base.BaseFullStackTestCase): class TestHAL3Agent(base.BaseFullStackTestCase):
def __init__(self, *args, **kwargs):
super(TestHAL3Agent, self).__init__( def setUp(self):
environment.Environment( host_descriptions = [
[environment.HostDescription(l3_agent=True), environment.HostDescription(l3_agent=True) for _ in range(2)]
environment.HostDescription(l3_agent=True)]), env = environment.Environment(environment.EnvironmentDescription(),
*args, **kwargs) host_descriptions)
super(TestHAL3Agent, self).setUp(env)
def _is_ha_router_active_on_one_agent(self, router_id): def _is_ha_router_active_on_one_agent(self, router_id):
agents = self.client.list_l3_agent_hosting_routers(router_id) agents = self.client.list_l3_agent_hosting_routers(router_id)