Merge "Add full-stack test"

This commit is contained in:
Jenkins 2015-04-18 13:15:14 +00:00 committed by Gerrit Code Review
commit 86669de211
6 changed files with 242 additions and 53 deletions

View File

@ -144,14 +144,19 @@ class PortFixture(fixtures.Fixture):
class OVSBridgeFixture(fixtures.Fixture):
"""Create an OVS bridge.
:ivar prefix: bridge name prefix
:type prefix: str
:ivar bridge: created bridge
:type bridge: OVSBridge
"""
def __init__(self, prefix=BR_PREFIX):
self.prefix = prefix
def setUp(self):
super(OVSBridgeFixture, self).setUp()
ovs = ovs_lib.BaseOVS()
self.bridge = common_base.create_resource(BR_PREFIX, ovs.add_bridge)
self.bridge = common_base.create_resource(self.prefix, ovs.add_bridge)
self.addCleanup(self.bridge.destroy)

View File

@ -21,23 +21,21 @@ from neutron.tests.fullstack import fullstack_fixtures as f_fixtures
class BaseFullStackTestCase(test_base.MySQLOpportunisticTestCase):
"""Base test class for full-stack tests.
"""Base test class for full-stack tests."""
:param process_fixtures: a list of fixture classes (not instances).
"""
def __init__(self, environment=None, *args, **kwargs):
super(BaseFullStackTestCase, self).__init__(*args, **kwargs)
self.environment = (environment if environment
else f_fixtures.EnvironmentFixture())
def setUp(self):
super(BaseFullStackTestCase, self).setUp()
self.create_db_tables()
self.neutron_server = self.useFixture(
f_fixtures.NeutronServerFixture())
self.client = self.neutron_server.client
if self.environment:
self.useFixture(self.environment)
@property
def test_name(self):
"""Return the name of the test currently running."""
return self.id().split(".")[-1]
self.client = self.environment.neutron_server.client
def create_db_tables(self):
"""Populate the new database.

View File

@ -105,12 +105,15 @@ class NeutronConfigFixture(ConfigFixture):
'DEFAULT': {
'host': self._generate_host(),
'state_path': self._generate_state_path(temp_dir),
'lock_path': '$state_path/lock',
'bind_port': self._generate_port(),
'api_paste_config': self._generate_api_paste(),
'policy_file': self._generate_policy_json(),
'core_plugin': 'neutron.plugins.ml2.plugin.Ml2Plugin',
'service_plugins': ('neutron.services.l3_router.'
'l3_router_plugin.L3RouterPlugin'),
'rabbit_userid': 'stackrabbit',
'rabbit_password': 'secretrabbit',
'rabbit_password': '127.0.0.1',
'rabbit_hosts': '127.0.0.1',
'auth_strategy': 'noauth',
'verbose': 'True',
@ -169,6 +172,10 @@ class ML2ConfigFixture(ConfigFixture):
'local_ip': '127.0.0.1',
'bridge_mappings': self._generate_bridge_mappings(),
'integration_bridge': self._generate_integration_bridge(),
},
'securitygroup': {
'firewall_driver': ('neutron.agent.linux.iptables_firewall.'
'OVSHybridIptablesFirewallDriver'),
}
})
@ -181,3 +188,28 @@ class ML2ConfigFixture(ConfigFixture):
def _generate_integration_bridge(self):
return base.get_rand_name(prefix='br-int',
max_length=constants.DEVICE_NAME_MAX_LEN)
class L3ConfigFixture(ConfigFixture):
def __init__(self, temp_dir, integration_bridge):
super(L3ConfigFixture, self).__init__(
temp_dir, base_filename='l3_agent.ini')
self.config.update({
'DEFAULT': {
'l3_agent_manager': ('neutron.agent.l3_agent.'
'L3NATAgentWithStateReport'),
'interface_driver': ('neutron.agent.linux.interface.'
'OVSInterfaceDriver'),
'ovs_integration_bridge': integration_bridge,
'external_network_bridge': self._generate_external_bridge(),
'router_delete_namespaces': 'True',
'debug': 'True',
'verbose': 'True',
}
})
def _generate_external_bridge(self):
return base.get_rand_name(prefix='br-ex',
max_length=constants.DEVICE_NAME_MAX_LEN)

View File

@ -13,6 +13,7 @@
# under the License.
from distutils import spawn
import functools
import fixtures
from neutronclient.common import exceptions as nc_exc
@ -23,6 +24,7 @@ from oslo_utils import timeutils
from neutron.agent.linux import async_process
from neutron.agent.linux import utils
from neutron.tests.common import net_helpers
from neutron.tests.fullstack import config_fixtures
LOG = logging.getLogger(__name__)
@ -33,7 +35,6 @@ DEFAULT_LOG_DIR = '/opt/stack/logs'
class ProcessFixture(fixtures.Fixture):
def __init__(self, name, exec_name, config_filenames):
super(ProcessFixture, self).__init__()
self.name = name
self.exec_name = exec_name
self.config_filenames = config_filenames
@ -61,11 +62,39 @@ class ProcessFixture(fixtures.Fixture):
super(ProcessFixture, self, *args, **kwargs)
class EnvironmentFixture(fixtures.Fixture):
def setUp(self):
super(EnvironmentFixture, self).setUp()
self.temp_dir = self.useFixture(fixtures.TempDir()).path
self.neutron_server = self.useFixture(
NeutronServerFixture(self.temp_dir))
def wait_until_env_is_up(self, agents_count=0):
utils.wait_until_true(
functools.partial(self._processes_are_ready, agents_count))
def _processes_are_ready(self, agents_count):
try:
running_agents = self.neutron_server.client.list_agents()['agents']
LOG.warn("There are %d agents running!", len(running_agents))
return len(running_agents) == agents_count
except nc_exc.NeutronClientException:
LOG.warn("neutron-server isn't up yet (cannot contact REST API).")
return False
class NeutronServerFixture(fixtures.Fixture):
NEUTRON_SERVER = "neutron-server"
def __init__(self, temp_dir):
self.temp_dir = temp_dir
def setUp(self):
super(NeutronServerFixture, self).setUp()
self.temp_dir = self.useFixture(fixtures.TempDir()).path
self.neutron_cfg_fixture = config_fixtures.NeutronConfigFixture(
self.temp_dir, cfg.CONF.database.connection)
@ -76,29 +105,91 @@ class NeutronServerFixture(fixtures.Fixture):
self.useFixture(self.plugin_cfg_fixture)
self.neutron_config = self.neutron_cfg_fixture.config
self.plugin_config = self.plugin_cfg_fixture.config
config_filenames = [self.neutron_cfg_fixture.filename,
self.plugin_cfg_fixture.filename]
self.process_fixture = self.useFixture(ProcessFixture(
name='neutron_server',
exec_name='neutron-server',
config_filenames=config_filenames,
))
name=self.NEUTRON_SERVER,
exec_name=self.NEUTRON_SERVER,
config_filenames=config_filenames))
utils.wait_until_true(self.processes_are_ready)
utils.wait_until_true(self.server_is_live)
def server_is_live(self):
try:
self.client.list_networks()
return True
except nc_exc.NeutronClientException:
LOG.warn("neutron-server isn't up yet (cannot contact REST API).")
return False
@property
def client(self):
url = "http://127.0.0.1:%s" % self.neutron_config.DEFAULT.bind_port
return client.Client(auth_strategy="noauth", endpoint_url=url)
def processes_are_ready(self):
# ProcessFixture will ensure that the server has started, but
# that doesn't mean that the server will be serving commands yet, nor
# that all processes are up.
try:
return len(self.client.list_agents()['agents']) == 0
except nc_exc.NeutronClientException:
LOG.debug("Processes aren't up yet.")
return False
class OVSAgentFixture(fixtures.Fixture):
NEUTRON_OVS_AGENT = "neutron-openvswitch-agent"
def __init__(self, neutron_cfg_fixture, ml2_cfg_fixture):
self.neutron_cfg_fixture = neutron_cfg_fixture
self.plugin_cfg_fixture = ml2_cfg_fixture
self.neutron_config = self.neutron_cfg_fixture.config
self.plugin_config = self.plugin_cfg_fixture.config
def setUp(self):
super(OVSAgentFixture, self).setUp()
self.useFixture(net_helpers.OVSBridgeFixture(self._get_br_int_name()))
self.useFixture(net_helpers.OVSBridgeFixture(self._get_br_phys_name()))
config_filenames = [self.neutron_cfg_fixture.filename,
self.plugin_cfg_fixture.filename]
self.process_fixture = self.useFixture(ProcessFixture(
name=self.NEUTRON_OVS_AGENT,
exec_name=self.NEUTRON_OVS_AGENT,
config_filenames=config_filenames))
def _get_br_int_name(self):
return self.plugin_config.ovs.integration_bridge
def _get_br_phys_name(self):
return self.plugin_config.ovs.bridge_mappings.split(':')[1]
class L3AgentFixture(fixtures.Fixture):
NEUTRON_L3_AGENT = "neutron-l3-agent"
def __init__(self, temp_dir, neutron_cfg_fixture, integration_bridge_name):
self.temp_dir = temp_dir
self.neutron_cfg_fixture = neutron_cfg_fixture
self.neutron_config = self.neutron_cfg_fixture.config
self.integration_bridge_name = integration_bridge_name
def setUp(self):
super(L3AgentFixture, self).setUp()
self.plugin_cfg_fixture = config_fixtures.L3ConfigFixture(
self.temp_dir, self.integration_bridge_name)
self.useFixture(self.plugin_cfg_fixture)
self.plugin_config = self.plugin_cfg_fixture.config
self.useFixture(net_helpers.OVSBridgeFixture(self._get_br_ex_name()))
config_filenames = [self.neutron_cfg_fixture.filename,
self.plugin_cfg_fixture.filename]
self.process_fixture = self.useFixture(ProcessFixture(
name=self.NEUTRON_L3_AGENT,
exec_name=self.NEUTRON_L3_AGENT,
config_filenames=config_filenames))
def _get_br_ex_name(self):
return self.plugin_config.DEFAULT.external_network_bridge

View File

@ -0,0 +1,88 @@
# Copyright 2015 Red Hat, 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.
from neutron.agent.l3 import agent as l3_agent
from neutron.agent.linux import ip_lib
from neutron.agent.linux import utils
from neutron.openstack.common import uuidutils
from neutron.tests.fullstack import base
from neutron.tests.fullstack import fullstack_fixtures as f_fixtures
class SingleNodeEnvironment(f_fixtures.EnvironmentFixture):
def setUp(self):
super(SingleNodeEnvironment, self).setUp()
neutron_config = self.neutron_server.neutron_cfg_fixture
ml2_config = self.neutron_server.plugin_cfg_fixture
self.ovs_agent = self.useFixture(
f_fixtures.OVSAgentFixture(
neutron_config, ml2_config))
self.l3_agent = self.useFixture(
f_fixtures.L3AgentFixture(
self.temp_dir,
neutron_config,
self.ovs_agent._get_br_int_name()))
self.wait_until_env_is_up(agents_count=2)
class TestLegacyL3Agent(base.BaseFullStackTestCase):
def __init__(self, *args, **kwargs):
super(TestLegacyL3Agent, self).__init__(
SingleNodeEnvironment(), *args, **kwargs)
def _get_namespace(self, router_id):
return "%s%s" % (l3_agent.NS_PREFIX, router_id)
def _assert_namespace_exists(self, ns_name):
ip = ip_lib.IPWrapper(ns_name)
utils.wait_until_true(lambda: ip.netns.exists(ns_name))
def test_namespace_exists(self):
uuid = uuidutils.generate_uuid()
router = self.client.create_router(
body={'router': {'name': 'router-test',
'tenant_id': uuid}})
network = self.client.create_network(
body={'network': {'name': 'network-test',
'tenant_id': uuid}})
subnet = self.client.create_subnet(
body={'subnet': {'name': 'subnet-test',
'tenant_id': uuid,
'network_id': network['network']['id'],
'cidr': '20.0.0.0/24',
'gateway_ip': '20.0.0.1',
'ip_version': 4,
'enable_dhcp': True}})
self.client.add_interface_router(
router=router['router']['id'],
body={'subnet_id': subnet['subnet']['id']})
router_id = router['router']['id']
self._assert_namespace_exists(self._get_namespace(router_id))
self.client.remove_interface_router(
router=router['router']['id'],
body={'subnet_id': subnet['subnet']['id']})
self.client.delete_subnet(subnet['subnet']['id'])
self.client.delete_network(network['network']['id'])
self.client.delete_router(router['router']['id'])

View File

@ -1,25 +0,0 @@
# Copyright 2015 Red Hat, 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.
#TODO(jschwarz): This is an example test file which demonstrates the
# general usage of fullstack. Once we add more FullStack tests, this should
# be deleted.
from neutron.tests.fullstack import base
class TestSanity(base.BaseFullStackTestCase):
def test_sanity(self):
self.assertEqual(self.client.list_networks(), {'networks': []})