Ejemplo n.º 1
0
class SameHostNetworkTest(NetworkTest):

    #: Resources stack with Nova server to send messages to
    stack = tobiko.required_setup_fixture(
        stacks.CirrosSameHostServerStackFixture)

    def test_same_host(self):
        sender = self.stack.peer_stack.server_details
        receiver = self.stack.server_details
        self.assertEqual({'same_host': [sender.id]},
                         self.stack.scheduler_hints)
        self.assertEqual(getattr(sender, 'OS-EXT-SRV-ATTR:host'),
                         getattr(receiver, 'OS-EXT-SRV-ATTR:host'))
Ejemplo n.º 2
0
class NetworkTestCase(testtools.TestCase):
    """Tests network creation"""

    #: Stack of resources with a network with a gateway router
    stack = tobiko.required_setup_fixture(stacks.NetworkStackFixture)

    @neutron.skip_if_missing_networking_extensions('port-security')
    def test_port_security_enabled(self):
        self.assertEqual(self.stack.port_security_enabled,
                         self.stack.network_details['port_security_enabled'])
        self.assertEqual(self.stack.port_security_enabled,
                         self.stack.outputs.port_security_enabled)

    @neutron.skip_if_missing_networking_extensions('net-mtu')
    def test_net_mtu(self):
        self.assertEqual(self.stack.network_details['mtu'],
                         self.stack.outputs.mtu)

    def test_ipv4_subnet_cidr(self):
        if not self.stack.has_ipv4:
            tobiko.skip('Stack {!s} has no ipv4 subnet', self.stack.stack_name)

        subnet = neutron.find_subnet(cidr=str(self.stack.ipv4_subnet_cidr))
        self.assertEqual(neutron.get_subnet(self.stack.ipv4_subnet_id), subnet)

    def test_ipv6_subnet_cidr(self):
        if not self.stack.has_ipv6:
            tobiko.skip('Stack {!s} has no ipv6 subnet', self.stack.stack_name)
        subnet = neutron.find_subnet(cidr=str(self.stack.ipv6_subnet_cidr))
        self.assertEqual(neutron.get_subnet(self.stack.ipv6_subnet_id), subnet)

    def test_gateway_network(self):
        if not self.stack.has_gateway:
            tobiko.skip('Stack {!s} has no gateway', self.stack.stack_name)
        self.assertEqual(
            self.stack.gateway_network_id,
            self.stack.gateway_details['external_gateway_info']['network_id'])

    def test_ipv4_subnet_gateway_ip(self):
        if not self.stack.has_ipv4 or not self.stack.has_gateway:
            tobiko.skip('Stack {!s} has no IPv4 gateway',
                        self.stack.stack_name)
        self.assertIn(self.stack.ipv4_subnet_gateway_ip,
                      self.stack.ipv4_gateway_addresses)

    def test_ipv6_subnet_gateway_ip(self):
        if not self.stack.has_ipv6 or not self.stack.has_gateway:
            tobiko.skip('Stack {!s} has no IPv6 gateway',
                        self.stack.stack_name)
        self.assertIn(self.stack.ipv6_subnet_gateway_ip,
                      self.stack.ipv6_gateway_addresses)
Ejemplo n.º 3
0
class SSHClientManager(object):

    default = tobiko.required_setup_fixture(_config.SSHDefaultConfigFixture)

    def __init__(self):
        self.clients = {}

    def get_client(self,
                   host,
                   username=None,
                   port=None,
                   proxy_jump=None,
                   host_config=None,
                   config_files=None,
                   proxy_client=None,
                   **connect_parameters):
        if isinstance(host, netaddr.IPAddress):
            host = str(host)
        host_config = host_config or _config.ssh_host_config(
            host=host, config_files=config_files)
        hostname = host_config.hostname
        port = port or host_config.port
        username = username or host_config.username
        host_key = hostname, port, username, proxy_jump
        client = self.clients.get(host_key, UNDEFINED_CLIENT)
        if client is UNDEFINED_CLIENT:
            # Put a placeholder client to avoid infinite recursive lookup
            self.clients[host_key] = None
            proxy_client = proxy_client or self.get_proxy_client(
                host=host, proxy_jump=proxy_jump, config_files=config_files)
            self.clients[host_key] = client = SSHClientFixture(
                host=host,
                hostname=hostname,
                port=port,
                username=username,
                proxy_client=proxy_client,
                host_config=host_config,
                **connect_parameters)
        return client

    def get_proxy_client(self,
                         host=None,
                         proxy_jump=None,
                         host_config=None,
                         config_files=None):
        if isinstance(proxy_jump, SSHClientFixture):
            return proxy_jump
        host_config = host_config or _config.ssh_host_config(
            host=host, config_files=config_files)
        proxy_host = host_config.proxy_jump
        return proxy_host and self.get_client(proxy_host) or None
Ejemplo n.º 4
0
class PortTest(testtools.TestCase):
    """Test Neutron ports"""

    #: Resources stack with Nova server to send messages to
    stack = tobiko.required_setup_fixture(stacks.CirrosServerStackFixture)

    def test_port_ips(self):
        server_ips = ip.list_ip_addresses(scope='global',
                                          ssh_client=self.stack.ssh_client)
        port_ips = neutron.list_port_ip_addresses(port=self.stack.port_details)
        self.assertFalse(set(port_ips) - set(server_ips))

    def test_port_network(self):
        self.assertEqual(self.stack.network_stack.network_id,
                         self.stack.port_details['network_id'])

    def test_port_subnets(self):
        port_subnets = [
            fixed_ip['subnet_id']
            for fixed_ip in self.stack.port_details['fixed_ips']
        ]
        network_subnets = self.stack.network_stack.network_details['subnets']
        self.assertEqual(set(network_subnets), set(port_subnets))

    def test_ping_subnet_gateways(self):
        network_id = self.stack.network_stack.network_id
        subnets = neutron.list_subnets(network_id=network_id)
        gateway_ips = [
            netaddr.IPAddress(subnet['gateway_ip']) for subnet in subnets
        ]
        ping.assert_reachable_hosts(gateway_ips,
                                    ssh_client=self.stack.ssh_client)

    def test_ping_port(self, network_id=None, device_id=None):
        network_id = network_id or self.stack.network_stack.network_id
        device_id = device_id or self.stack.server_id
        ports = neutron.list_ports(network_id=network_id, device_id=device_id)
        port_ips = set()
        for port in ports:
            self.assertEqual(network_id, port['network_id'])
            self.assertEqual(device_id, port['device_id'])
            port_ips.update(neutron.list_port_ip_addresses(port=port))
        ping.assert_reachable_hosts(port_ips, ssh_client=self.stack.ssh_client)

    def test_ping_inner_gateway_ip(self):
        if not self.stack.network_stack.has_gateway:
            self.skip('Server network has no gateway router')
        self.test_ping_port(device_id=self.stack.network_stack.gateway_id)
Ejemplo n.º 5
0
class L3HARouterTest(RouterTest):
    """Test Neutron HA routers"""

    #: Resources stack with Nova server to send messages to
    stack = tobiko.required_setup_fixture(stacks.L3haServerStackFixture)

    @neutron.skip_if_missing_networking_extensions('l3_agent_scheduler')
    def test_router_is_scheduled_on_l3_agents(self):
        router_agents = neutron.list_l3_agent_hosting_routers(
            self.router['id'])
        master_agent = router_agents.with_items(ha_state='active').unique
        backup_agents = router_agents.with_items(ha_state='standby')
        self.assertGreaterEqual(len(backup_agents), 1)
        self._check_routers_namespace_on_host(master_agent['host'])
        for backup_agent in backup_agents:
            self._check_routers_namespace_on_host(backup_agent['host'],
                                                  state="backup")
Ejemplo n.º 6
0
class GlanceApiTestCase(testtools.TestCase):
    """Tests glance images API"""

    #: Stack of resources with a network with a gateway router
    fixture = tobiko.required_setup_fixture(stacks.CirrosImageFixture)

    def test_get_image(self):
        image = glance.get_image(self.fixture.image_id)
        self.assertEqual(self.fixture.image_id, image['id'])

    def test_find_image_by_id(self):
        image = glance.find_image(id=self.fixture.image_id)
        self.assertEqual(self.fixture.image_id, image['id'])

    def test_find_image_by_name(self):
        image = glance.find_image(name=self.fixture.image_name)
        self.assertEqual(self.fixture.image_name, image['name'])
Ejemplo n.º 7
0
class PortTest(testtools.TestCase):

    #: Stack of resources with a network with a gateway router
    stack = tobiko.required_setup_fixture(stacks.CentosServerStackFixture)

    def test_list_port_addresses(self, ip_version=None):
        port = neutron.find_port(device_id=self.stack.server_id)
        port_addresses = neutron.list_port_ip_addresses(
            port=port,
            ip_version=ip_version)
        server_addresses = nova.list_server_ip_addresses(
            server=self.stack.server_details,
            ip_version=ip_version,
            address_type='fixed')
        self.assertEqual(set(server_addresses), set(port_addresses))
        if ip_version:
            self.assertEqual(
                port_addresses.with_attributes(version=ip_version),
                port_addresses)

    def test_list_port_addresses_with_ipv4(self):
        self.test_list_port_addresses(ip_version=4)

    def test_list_port_addresses_with_ipv6(self):
        self.test_list_port_addresses(ip_version=6)

    def test_find_port_address_with_ip_version(self):
        port = neutron.find_port(device_id=self.stack.server_id)
        server_addresses = nova.list_server_ip_addresses(
            server=self.stack.server_details,
            address_type='fixed')
        for server_address in server_addresses:
            port_address = neutron.find_port_ip_address(
                port=port,
                ip_version=server_address.version,
                unique=True)
            self.assertEqual(server_address, port_address)

    def test_find_port_address_with_subnet_id(self):
        port = neutron.find_port(device_id=self.stack.server_id)
        for subnet in neutron.list_subnets(network_id=port['network_id']):
            port_address = neutron.find_port_ip_address(
                port=port, subnet_id=subnet['id'], unique=True)
            cidr = netaddr.IPNetwork(subnet['cidr'])
            self.assertIn(port_address, cidr)
Ejemplo n.º 8
0
class SSHConfigFixture(tobiko.SharedFixture):

    default = tobiko.required_setup_fixture(SSHDefaultConfigFixture)

    config_files = None
    config = None

    def __init__(self, config_files=None):
        super(SSHConfigFixture, self).__init__()
        if config_files:
            self.config_files = tuple(config_files)
        else:
            self.config_files = self.default.config_files

    def setup_fixture(self):
        self.setup_ssh_config()

    def setup_ssh_config(self):
        self.config = paramiko.SSHConfig()
        for config_file in self.config_files:
            config_file = os.path.expanduser(config_file)
            if os.path.exists(config_file):
                LOG.debug("Parsing %r config file...", config_file)
                with open(config_file) as f:
                    self.config.parse(f)
                LOG.debug("File %r parsed.", config_file)

    def lookup(self, host=None):
        host_config = host and self.config.lookup(host) or {}
        # remove unsupported directive
        include_files = host_config.pop('include', None)
        if include_files:
            LOG.warning('Ignoring unsupported directive: Include %s',
                        include_files)
        return SSHHostConfig(host=host,
                             ssh_config=self,
                             host_config=host_config,
                             config_files=self.config_files)

    def __repr__(self):
        return "{class_name!s}(config_files={config_files!r})".format(
            class_name=type(self).__name__, config_files=self.config_files)
Ejemplo n.º 9
0
class ServerStackResourcesTest(testtools.TestCase):

    stack = tobiko.required_setup_fixture(stacks.CirrosServerStackFixture)

    def test_server(self):
        "Test actual server details"
        server = self.stack.resources.server
        self.assertEqual('OS::Nova::Server', server.resource_type)
        # Verify actual server status (is alive, etc.)
        nova_client = nova.get_nova_client()
        server_data = nova_client.servers.get(server.physical_resource_id)
        self.assertEqual(self.stack.server_name, server_data.name)

    def test_port(self):
        "Test actual server port details"
        port = self.stack.resources.port
        self.assertEqual('OS::Neutron::Port', port.resource_type)
        # Verify actual port status (is alive, etc.)
        port_data = neutron.get_port(port.physical_resource_id)
        self.assertEqual(port.physical_resource_id, port_data['id'])
Ejemplo n.º 10
0
class OvercloudHostConfig(tobiko.SharedFixture):
    hostname = None
    port = None
    username = None
    key_file = tobiko.required_setup_fixture(OvercloudSshKeyFileFixture)
    ip_version = None
    network_name = None
    key_filename = None

    def __init__(self, host, ip_version=None, network_name=None, **kwargs):
        super(OvercloudHostConfig, self).__init__()
        tobiko.check_valid_type(host, six.string_types)
        self.host = host
        if ip_version:
            self.ip_version = ip_version
        if network_name:
            self.network_name = network_name
        self._connect_parameters = ssh.gather_ssh_connect_parameters(**kwargs)

    def setup_fixture(self):
        self.hostname = self.hostname or str(
            overcloud_node_ip_address(name=self.host,
                                      ip_version=self.ip_version,
                                      network_name=self.network_name))
        self.port = self.port or CONF.tobiko.tripleo.overcloud_ssh_port
        self.username = (self.username
                         or CONF.tobiko.tripleo.overcloud_ssh_username)
        self.key_filename = self.key_filename or self.key_file.key_filename

    @property
    def connect_parameters(self):
        parameters = ssh.ssh_host_config(
            host=str(self.hostname)).connect_parameters
        parameters.update(ssh.gather_ssh_connect_parameters(self))
        parameters.update(self._connect_parameters)
        return parameters
Ejemplo n.º 11
0
class CloudsFileKeystoneCredentialsFixtureTest(openstack.OpenstackTest):

    config = tobiko.required_setup_fixture(
        _clouds_file.DefaultCloudsFileConfig)

    def test_init(self):
        fixture = keystone.CloudsFileKeystoneCredentialsFixture()
        self.assertEqual(self.config.cloud_name, fixture.cloud_name)
        self.assertIsNone(fixture.clouds_content)
        self.assertIsNone(fixture.clouds_file)
        self.assertEqual(self.config.clouds_files, fixture.clouds_files)

    def test_init_with_cloud_name(self):
        fixture = keystone.CloudsFileKeystoneCredentialsFixture(
            cloud_name='cloud-name')
        self.assertEqual('cloud-name', fixture.cloud_name)

    def test_init_with_clouds_content(self):
        fixture = keystone.CloudsFileKeystoneCredentialsFixture(
            clouds_content={})
        self.assertEqual({}, fixture.clouds_content)

    def test_init_with_clouds_file(self):
        fixture = keystone.CloudsFileKeystoneCredentialsFixture(
            clouds_file='cloud-file')
        self.assertEqual('cloud-file', fixture.clouds_file)

    def test_init_with_clouds_files(self):
        fixture = keystone.CloudsFileKeystoneCredentialsFixture(
            clouds_files=['a', 'b', 'd'])
        self.assertEqual(['a', 'b', 'd'], fixture.clouds_files)

    def test_setup_from_default_clouds_files(self):
        file_fixture = self.useFixture(V3CloudsFileFixture())
        self.patch(self.config, 'clouds_files',
                   ['/a', file_fixture.clouds_file, '/c'])
        credentials_fixture = self.useFixture(
            keystone.CloudsFileKeystoneCredentialsFixture(
                cloud_name=file_fixture.cloud_name))
        self.assertEqual(file_fixture.clouds_content,
                         credentials_fixture.clouds_content)
        self.assertEqual(test_credentials.V3_PARAMS,
                         credentials_fixture.credentials.to_dict())

    def test_setup_from_json(self):
        file_fixture = self.useFixture(V3CloudsFileFixture(suffix='.json'))
        credentials_fixture = self.useFixture(
            keystone.CloudsFileKeystoneCredentialsFixture(
                cloud_name=file_fixture.cloud_name,
                clouds_file=file_fixture.clouds_file))
        self.assertEqual(file_fixture.clouds_content,
                         credentials_fixture.clouds_content)
        self.assertEqual(test_credentials.V3_PARAMS,
                         credentials_fixture.credentials.to_dict())

    def test_setup_from_yaml(self):
        file_fixture = self.useFixture(V3CloudsFileFixture(suffix='.yaml'))
        credentials_fixture = self.useFixture(
            keystone.CloudsFileKeystoneCredentialsFixture(
                cloud_name=file_fixture.cloud_name,
                clouds_file=file_fixture.clouds_file))
        self.assertEqual(file_fixture.clouds_content,
                         credentials_fixture.clouds_content)
        self.assertEqual(test_credentials.V3_PARAMS,
                         credentials_fixture.credentials.to_dict())

    def test_setup_from_yml(self):
        file_fixture = self.useFixture(V3CloudsFileFixture(suffix='.yml'))
        credentials_fixture = self.useFixture(
            keystone.CloudsFileKeystoneCredentialsFixture(
                cloud_name=file_fixture.cloud_name,
                clouds_file=file_fixture.clouds_file))
        self.assertEqual(file_fixture.clouds_content,
                         credentials_fixture.clouds_content)
        self.assertEqual(test_credentials.V3_PARAMS,
                         credentials_fixture.credentials.to_dict())

    def test_setup_v2_credentials(self):
        file_fixture = self.useFixture(V2CloudsFileFixture())
        credentials_fixture = self.useFixture(
            keystone.CloudsFileKeystoneCredentialsFixture(
                cloud_name=file_fixture.cloud_name,
                clouds_file=file_fixture.clouds_file))
        self.assertEqual(file_fixture.clouds_content,
                         credentials_fixture.clouds_content)
        self.assertEqual(test_credentials.V2_PARAMS,
                         credentials_fixture.credentials.to_dict())

    def test_setup_with_cloud_name(self):
        file_fixture = self.useFixture(V3CloudsFileFixture())
        credentials_fixture = keystone.CloudsFileKeystoneCredentialsFixture(
            cloud_name='cloud-name', clouds_file=file_fixture.clouds_file)
        ex = self.assertRaises(ValueError, tobiko.setup_fixture,
                               credentials_fixture)
        self.assertEqual(
            "No such cloud with name 'cloud-name' in file " +
            repr(file_fixture.clouds_file), str(ex))

    def test_setup_with_cloud_name_from_env(self):
        self.patch(self.config, 'cloud_name', None)

        file_fixture = self.useFixture(V2CloudsFileFixture())

        self.patch(os, 'environ', {'OS_CLOUD': file_fixture.cloud_name})
        credentials_fixture = keystone.CloudsFileKeystoneCredentialsFixture(
            clouds_file=file_fixture.clouds_file)

        self.assertIsNone(credentials_fixture.cloud_name)
        tobiko.setup_fixture(credentials_fixture)
        self.assertEqual(file_fixture.cloud_name,
                         credentials_fixture.cloud_name)

    def test_setup_with_empty_cloud_name(self):
        file_fixture = self.useFixture(V2CloudsFileFixture())
        credentials_fixture = keystone.CloudsFileKeystoneCredentialsFixture(
            clouds_file=file_fixture.clouds_file, cloud_name='')

        self.assertIsNone(credentials_fixture.credentials)
        self.assertEqual('', credentials_fixture.cloud_name)
        tobiko.setup_fixture(credentials_fixture)
        self.assertIsNone(credentials_fixture.credentials)
        self.assertEqual('', credentials_fixture.cloud_name)

    def test_setup_with_empty_cloud_name_from_env(self):
        self.patch(self.config, 'cloud_name', None)

        file_fixture = self.useFixture(V2CloudsFileFixture())
        self.patch(os, 'environ', {'OS_CLOUD': ''})
        credentials_fixture = keystone.CloudsFileKeystoneCredentialsFixture(
            clouds_file=file_fixture.clouds_file)

        self.assertIsNone(credentials_fixture.credentials)
        self.assertIsNone(credentials_fixture.cloud_name)
        tobiko.setup_fixture(credentials_fixture)
        self.assertIsNone(credentials_fixture.credentials)
        self.assertIsNone(credentials_fixture.cloud_name)

    def test_setup_with_no_cloud_name(self):
        self.patch(self.config, 'cloud_name', None)

        file_fixture = self.useFixture(V2CloudsFileFixture())
        credentials_fixture = keystone.CloudsFileKeystoneCredentialsFixture(
            clouds_file=file_fixture.clouds_file)

        self.assertIsNone(credentials_fixture.credentials)
        self.assertIsNone(credentials_fixture.cloud_name)
        tobiko.setup_fixture(credentials_fixture)
        self.assertIsNone(credentials_fixture.credentials)
        self.assertIsNone(credentials_fixture.cloud_name)

    def test_setup_with_no_clouds_section(self):
        fixture = keystone.CloudsFileKeystoneCredentialsFixture(
            cloud_name='cloud-name',
            clouds_content={'other_data': None},
            clouds_file='clouds-file')
        ex = self.assertRaises(ValueError, tobiko.setup_fixture, fixture)
        self.assertEqual('cloud-name', fixture.cloud_name)
        self.assertEqual({'other_data': None}, fixture.clouds_content)
        self.assertEqual(
            "'clouds' section not found in clouds file "
            "'clouds-file'", str(ex))

    def test_setup_with_empty_clouds_content(self):
        fixture = keystone.CloudsFileKeystoneCredentialsFixture(
            cloud_name='cloud-name', clouds_content={})
        ex = self.assertRaises(ValueError, tobiko.setup_fixture, fixture)
        self.assertEqual('cloud-name', fixture.cloud_name)
        self.assertEqual({}, fixture.clouds_content)
        self.assertEqual('Invalid clouds file content: {}', str(ex))

    def test_setup_with_no_auth(self):
        clouds_content = make_clouds_content('cloud-name')
        fixture = keystone.CloudsFileKeystoneCredentialsFixture(
            cloud_name='cloud-name',
            clouds_content=clouds_content,
            clouds_file='cloud-file')
        ex = self.assertRaises(ValueError, tobiko.setup_fixture, fixture)
        self.assertEqual('cloud-name', fixture.cloud_name)
        self.assertEqual(
            "No such 'auth' section in cloud file 'cloud-file' for cloud "
            "name 'cloud-name'", str(ex))

    def test_setup_with_no_auth_url(self):
        clouds_content = make_clouds_content('cloud-name', auth={})
        fixture = keystone.CloudsFileKeystoneCredentialsFixture(
            cloud_name='cloud-name',
            clouds_content=clouds_content,
            clouds_file='cloud-file')
        ex = self.assertRaises(ValueError, tobiko.setup_fixture, fixture)
        self.assertEqual('cloud-name', fixture.cloud_name)
        self.assertEqual(
            "No such 'auth_url' in file 'cloud-file' for cloud name "
            "'cloud-name'", str(ex))

    def test_setup_without_clouds_file(self):
        self.patch(self.config, 'clouds_files', ['/a', '/b', '/c'])
        fixture = keystone.CloudsFileKeystoneCredentialsFixture(
            cloud_name='cloud-name')
        ex = self.assertRaises(_clouds_file.CloudsFileNotFoundError,
                               tobiko.setup_fixture, fixture)
        self.assertEqual('cloud-name', fixture.cloud_name)
        self.assertEqual("No such clouds file(s): /a, /b, /c", str(ex))

    def test_setup_with_non_existing_clouds_file(self):
        fixture = keystone.CloudsFileKeystoneCredentialsFixture(
            clouds_file='/a.yaml', cloud_name='cloud-name')
        ex = self.assertRaises(_clouds_file.CloudsFileNotFoundError,
                               tobiko.setup_fixture, fixture)
        self.assertEqual("No such clouds file(s): /a.yaml", str(ex))
Ejemplo n.º 12
0
class IpTest(testtools.TestCase):

    centos_stack = tobiko.required_setup_fixture(
        stacks.CentosServerStackFixture)

    cirros_stack = tobiko.required_setup_fixture(
        stacks.CirrosServerStackFixture)

    ubuntu_stack = tobiko.required_setup_fixture(
        stacks.UbuntuServerStackFixture)

    namespace = tobiko.required_setup_fixture(fixtures.NetworkNamespaceFixture)

    def test_list_ip_addresses(self,
                               ip_version=None,
                               scope=None,
                               **execute_params):
        ips = ip.list_ip_addresses(ip_version=ip_version,
                                   scope=scope,
                                   **execute_params)
        self.assertIsInstance(ips, tobiko.Selection)
        for ip_address in ips:
            self.assertIsInstance(ip_address, netaddr.IPAddress)
        if ip_version:
            self.assertEqual(ips.with_attributes(version=ip_version), ips)
        if scope:
            if scope == 'link':
                self.assertEqual(ips.with_attributes(version=4), [])
                self.assertEqual(ips.with_attributes(version=6), ips)
            elif scope == 'host':
                for a in ips:
                    self.assertTrue(a.is_loopback())
            elif scope == 'global':
                self.assertNotIn(netaddr.IPAddress('127.0.0.1'), ips)
                self.assertNotIn(netaddr.IPAddress('::1'), ips)
        return ips

    def test_list_ip_addresses_with_host_scope(self, **execute_params):
        self.test_list_ip_addresses(scope='host', **execute_params)

    def test_list_ip_addresses_with_link_scope(self, **execute_params):
        self.test_list_ip_addresses(scope='link', **execute_params)

    def test_list_ip_addresses_with_global_scope(self, **execute_params):
        self.test_list_ip_addresses(scope='global', **execute_params)

    def test_list_ip_addresses_with_ipv4(self):
        self.test_list_ip_addresses(ip_version=4)

    def test_list_ip_addresses_with_ipv6(self):
        self.test_list_ip_addresses(ip_version=6)

    def test_list_ip_addresses_with_centos_server(self):
        self.test_list_ip_addresses(ssh_client=self.centos_stack.ssh_client)

    def test_list_ip_addresses_with_cirros_server(self):
        self.test_list_ip_addresses(ssh_client=self.cirros_stack.ssh_client)

    def test_list_ip_addresses_with_ubuntu_server(self):
        self.test_list_ip_addresses(ssh_client=self.ubuntu_stack.ssh_client)

    def test_list_ip_addresses_with_proxy_ssh_client(self):
        ssh_client = ssh.ssh_proxy_client()
        if ssh_client is None:
            self.skip('SSH proxy server not configured')
        self.test_list_ip_addresses(ssh_client=ssh_client)

    def test_list_ip_addresses_with_proxy_ssh_client_and_host_scope(
            self, **execute_params):
        self.test_list_ip_addresses(scope='host', **execute_params)

    def test_list_ip_addresses_with_proxy_ssh_client_and_link_scope(
            self, **execute_params):
        self.test_list_ip_addresses(scope='link', **execute_params)

    def test_list_ip_addresses_with_proxy_ssh_client_and_global_scope(
            self, **execute_params):
        self.test_list_ip_addresses(scope='global', **execute_params)

    def test_list_ip_addresses_with_namespace(self, **params):
        namespace_ips = ip.list_ip_addresses(
            ssh_client=self.namespace.ssh_client,
            network_namespace=self.namespace.network_namespace,
            **params)
        self.assertNotEqual([], namespace_ips)

        host_ips = ip.list_ip_addresses(ssh_client=self.namespace.ssh_client,
                                        **params)
        self.assertNotEqual(host_ips, namespace_ips)

    def test_list_ip_addresses_with_namespace_and_scope(self):
        self.test_list_ip_addresses_with_namespace(scope='global')

    def test_list_namespaces(self, **execute_params):
        namespaces = ip.list_network_namespaces(**execute_params)
        self.assertIsInstance(namespaces, list)
        for namespace in namespaces:
            self.assertIsInstance(namespace, six.string_types)
            self.test_list_ip_addresses(network_namespace=namespace)

    def test_list_namespaces_with_centos_server(self):
        self.test_list_namespaces(ssh_client=self.centos_stack.ssh_client)

    def test_list_namespaces_with_ubuntu_server(self):
        self.test_list_namespaces(ssh_client=self.ubuntu_stack.ssh_client)

    def test_list_namespaces_with_proxy_ssh_client(self):
        ssh_client = ssh.ssh_proxy_client()
        if ssh_client is None:
            self.skip('SSH proxy server not configured')
        self.test_list_namespaces(ssh_client=ssh_client)
Ejemplo n.º 13
0
class SSHHostConfig(
        collections.namedtuple(
            'SSHHostConfig',
            ['host', 'ssh_config', 'host_config', 'config_files'])):

    default = tobiko.required_setup_fixture(SSHDefaultConfigFixture)

    @property
    def hostname(self):
        return self.host_config.get('hostname', self.host)

    @property
    def port(self):
        return (self.host_config.get('port') or self.default.port)

    @property
    def username(self):
        return (self.host_config.get('user') or self.default.username)

    @property
    def key_filename(self):
        return (self.host_config.get('identityfile') or self.default.key_file)

    @property
    def proxy_jump(self):
        proxy_jump = (self.host_config.get('proxyjump')
                      or self.default.proxy_jump)
        if not proxy_jump:
            return None

        proxy_hostname = self.ssh_config.lookup(proxy_jump).hostname
        if ({proxy_jump, proxy_hostname} & {self.host, self.hostname}):
            # Avoid recursive proxy jump definition
            return None

        return proxy_jump

    @property
    def proxy_command(self):
        return (self.host_config.get('proxycommand')
                or self.default.proxy_command)

    @property
    def allow_agent(self):
        return (is_yes(self.host_config.get('forwardagent'))
                or self.default.allow_agent)

    @property
    def compress(self):
        return (is_yes(self.host_config.get('compression'))
                or self.default.compress)

    @property
    def timeout(self):
        return (self.host_config.get('connetcttimeout')
                or self.default.timeout)

    @property
    def connection_attempts(self):
        return (self.host_config.get('connectionattempts')
                or self.default.connection_attempts)

    @property
    def connection_interval(self):
        return (self.host_config.get('connetcttimeout')
                or self.default.connection_interval)

    @property
    def connect_parameters(self):
        return dict(hostname=self.hostname,
                    port=self.port,
                    username=self.username,
                    key_filename=self.key_filename,
                    compress=self.compress,
                    timeout=self.timeout,
                    allow_agent=self.allow_agent,
                    connection_attempts=self.connection_attempts,
                    connection_interval=self.connection_interval)
Ejemplo n.º 14
0
class RouterTest(testtools.TestCase):
    """Test Neutron routers"""

    #: Resources stack with Nova server to send messages to
    stack = tobiko.required_setup_fixture(stacks.CirrosServerStackFixture)

    def setUp(self):
        super(RouterTest, self).setUp()
        if not self.stack.network_stack.has_gateway:
            tobiko.skip('Stack {!s} has no gateway',
                        self.stack.network_stack.stack_name)

    @property
    def router(self):
        return self.stack.network_stack.gateway_details

    @property
    def ipv4_subnet_gateway_ip(self):
        if not self.stack.network_stack.has_ipv4:
            tobiko.skip('Stack {!s} has no ipv4 subnet',
                        self.stack.network_stack.stack_name)
        return self.stack.network_stack.ipv4_subnet_gateway_ip

    @property
    def ipv6_subnet_gateway_ip(self):
        if not self.stack.network_stack.has_ipv6:
            tobiko.skip('Stack {!s} has no ipv6 subnet',
                        self.stack.network_stack.stack_name)
        return self.stack.network_stack.ipv6_subnet_gateway_ip

    @property
    def external_gateway_ips(self):
        return self.stack.network_stack.external_gateway_ips

    @property
    def router_ips(self):
        return tobiko.select(
            [self.ipv4_subnet_gateway_ip, self.ipv6_subnet_gateway_ip] +
            self.external_gateway_ips)

    def test_internal_router_ipv4_interface_is_reachable(self):
        ping.assert_reachable_hosts([self.ipv4_subnet_gateway_ip],
                                    ssh_client=self.stack.ssh_client)

    def test_internal_router_ipv6_interface_is_reachable(self):
        ping.assert_reachable_hosts([self.ipv6_subnet_gateway_ip],
                                    ssh_client=self.stack.ssh_client)

    def test_ipv4_subnet_gateway_ip(self):
        self.assertEqual(4, self.ipv4_subnet_gateway_ip.version)
        self.assertIn(self.ipv4_subnet_gateway_ip,
                      self.stack.network_stack.ipv4_gateway_addresses)

    def test_ipv6_subnet_gateway_ip(self):
        self.assertEqual(6, self.ipv6_subnet_gateway_ip.version)
        self.assertIn(self.ipv6_subnet_gateway_ip,
                      self.stack.network_stack.ipv6_gateway_addresses)

    @neutron.skip_if_missing_networking_extensions('l3_agent_scheduler')
    def test_router_is_scheduled_on_l3_agents(self):
        router_agent = neutron.find_l3_agent_hosting_router(self.router['id'],
                                                            unique=True)
        self._check_routers_namespace_on_host(router_agent['host'])

    def _check_routers_namespace_on_host(self, hostname, state="master"):
        router_namespace = "qrouter-%s" % self.router['id']
        agent_host = topology.get_openstack_node(hostname=hostname)
        namespaces = ip.list_network_namespaces(
            ssh_client=agent_host.ssh_client)
        self.assertIn(router_namespace, namespaces)
        namespace_ips = ip.list_ip_addresses(
            scope='global',
            network_namespace=router_namespace,
            ssh_client=agent_host.ssh_client)
        missing_ips = set(self.router_ips) - set(namespace_ips)
        if state == "master":
            self.assertFalse(missing_ips)
        else:
            self.assertTrue(missing_ips)
Ejemplo n.º 15
0
class NeutronApiTestCase(testtools.TestCase):
    """Tests network creation"""

    #: Stack of resources with a network with a gateway router
    stack = tobiko.required_setup_fixture(stacks.NetworkStackFixture)

    def test_find_network_with_id(self):
        network = neutron.find_network(id=self.stack.network_id)
        self.assertEqual(self.stack.network_id, network['id'])

    def test_find_floating_network(self):
        floating_network = CONF.tobiko.neutron.floating_network
        if not floating_network:
            tobiko.skip('floating_network not configured')
        network = neutron.find_network(name=floating_network)
        self.assertIn(floating_network, [network['name'], network['id']])
        self.assertEqual(self.stack.gateway_network_id, network['id'])

    def test_list_networks(self):
        networks = neutron.list_networks()
        network_ids = {n['id'] for n in networks}
        self.assertIn(self.stack.network_id, network_ids)

    def test_list_subnets(self):
        subnets = neutron.list_subnets()
        subnets_ids = {s['id'] for s in subnets}
        if self.stack.has_ipv4:
            self.assertIn(self.stack.ipv4_subnet_id, subnets_ids)
        if self.stack.has_ipv6:
            self.assertIn(self.stack.ipv6_subnet_id, subnets_ids)

    def test_list_subnet_cidrs(self):
        subnets_cidrs = neutron.list_subnet_cidrs()
        if self.stack.has_ipv4:
            cidr = netaddr.IPNetwork(self.stack.ipv4_subnet_details['cidr'])
            self.assertIn(cidr, subnets_cidrs)
        if self.stack.has_ipv6:
            cidr = netaddr.IPNetwork(self.stack.ipv6_subnet_details['cidr'])
            self.assertIn(cidr, subnets_cidrs)

    def test_get_network(self):
        network = neutron.get_network(self.stack.network_id)
        self.assertEqual(self.stack.network_id, network['id'])
        self.assertEqual(self.stack.port_security_enabled,
                         network['port_security_enabled'])
        if self.stack.has_ipv4:
            self.assertIn(self.stack.ipv4_subnet_id, network['subnets'])
        else:
            self.assertNotIn(self.stack.ipv4_subnet_id, network['subnets'])
        if self.stack.has_ipv6:
            self.assertIn(self.stack.ipv6_subnet_id, network['subnets'])
        else:
            self.assertNotIn(self.stack.ipv6_subnet_id, network['subnets'])

    def test_get_router(self):
        if not self.stack.has_gateway:
            tobiko.skip("Stack {stack} has no gateway router",
                        stack=self.stack.stack_name)
        router = neutron.get_router(self.stack.gateway_id)
        self.assertEqual(self.stack.gateway_id, router['id'])

    def test_get_ipv4_subnet(self):
        if not self.stack.has_ipv4:
            tobiko.skip("Stack {stack} has no IPv4 subnet",
                        stack=self.stack.stack_name)
        subnet = neutron.get_subnet(self.stack.ipv4_subnet_id)
        self.assertEqual(self.stack.ipv4_subnet_id, subnet['id'])
        self.assertEqual(self.stack.ipv4_subnet_details, subnet)

    def test_get_ipv6_subnet(self):
        if not self.stack.has_ipv6:
            tobiko.skip("Stack {stack} has no IPv6 subnet",
                        stack=self.stack.stack_name)
        subnet = neutron.get_subnet(self.stack.ipv6_subnet_id)
        self.assertEqual(self.stack.ipv6_subnet_id, subnet['id'])
        self.assertEqual(self.stack.ipv6_subnet_details, subnet)

    def test_find_agents_with_binary(self):
        agent = neutron.list_agents().first
        agents = neutron.list_agents(binary=agent['binary'])
        self.assertIn(agent['id'], {a['id'] for a in agents})
Ejemplo n.º 16
0
class CirrosPeerServerStackFixture(CirrosServerStackFixture,
                                   _nova.PeerServerStackFixture):
    #: Peer server used to reach this one
    peer_stack = tobiko.required_setup_fixture(CirrosServerStackFixture)
Ejemplo n.º 17
0
class L3haPeerServerStackFixture(L3haServerStackFixture,
                                 _nova.PeerServerStackFixture):
    peer_stack = tobiko.required_setup_fixture(L3haServerStackFixture)
Ejemplo n.º 18
0
class OpenStackTopologyTest(testtools.TestCase):

    topology = tobiko.required_setup_fixture(topology.OpenStackTopology)

    def test_get_openstack_topology(self):
        topology_class = type(self.topology)
        topo = topology.get_openstack_topology(topology_class=topology_class)
        self.assertIs(topo, self.topology)
        self.assertIsInstance(topo, topology.OpenStackTopology)

    def test_ping_node(self):
        for node in self.topology.nodes:
            ping.ping(node.public_ip, count=1, timeout=5.).assert_replied()

    def test_ssh_client(self):
        for node in self.topology.nodes:
            self.assertIsNotNone(node.ssh_client)
            hostname = sh.get_hostname(
                ssh_client=node.ssh_client).split('.')[0]
            self.assertEqual(node.name, hostname)

    def test_controller_group(self):
        nodes = list(self.topology.get_group('controller'))
        self.assertNotEqual([], nodes)
        for node in nodes:
            self.assertIn('controller', node.groups)

    def test_compute_group(self):
        nodes = list(self.topology.get_group('compute'))
        self.assertNotEqual([], nodes)
        for node in nodes:
            self.assertIn('compute', node.groups)
        hypervisors = {
            hypervisor.hypervisor_hostname.split('.', 1)[0].lower(): hypervisor
            for hypervisor in nova.list_hypervisors()
        }
        for name, hypervisor in hypervisors.items():
            node = self.topology.get_node(name)
            self.assertEqual(name, node.name)
            self.assertIn(node, nodes)

    def test_list_openstack_topology(self, group=None, hostnames=None):
        nodes = topology.list_openstack_nodes(topology=self.topology,
                                              group=group,
                                              hostnames=hostnames)
        self.assertTrue(set(nodes).issubset(set(self.topology.nodes)))
        for node in nodes:
            if group:
                self.assertIn(group, node.groups)
            if hostnames:
                hostnames = [node_name_from_hostname(h) for h in hostnames]
                self.assertIn(node.name, hostnames)
        return nodes

    def test_list_openstack_topology_with_group(self):
        self.test_list_openstack_topology(group='compute')

    def test_list_openstack_topology_with_hostnames(self):
        expected_nodes = self.topology.nodes[0::2]
        actual_nodes = self.test_list_openstack_topology(
            hostnames=[node.name for node in expected_nodes])
        self.assertEqual(expected_nodes, actual_nodes)
Ejemplo n.º 19
0
class CloudsFileKeystoneCredentialsFixture(
        _credentials.KeystoneCredentialsFixture):

    cloud_name = None
    clouds_content = None
    clouds_file = None

    config = tobiko.required_setup_fixture(DefaultCloudsFileConfig)

    def __init__(self, credentials=None, cloud_name=None,
                 clouds_content=None, clouds_file=None, clouds_files=None):
        super(CloudsFileKeystoneCredentialsFixture, self).__init__(
            credentials=credentials)

        config = self.config
        if cloud_name is None:
            cloud_name = config.cloud_name
        self.cloud_name = cloud_name

        if clouds_content is not None:
            self.clouds_content = dict(clouds_content)

        if clouds_file is not None:
            self.clouds_file = clouds_file

        if clouds_files is None:
            clouds_files = config.clouds_files
        self.clouds_files = list(clouds_files)

    def get_credentials(self):
        cloud_name = self._get_cloud_name()
        if cloud_name is None:
            return None

        clouds_content = self._get_clouds_content()
        clouds_section = clouds_content.get("clouds")
        if clouds_section is None:
            message = ("'clouds' section not found in clouds file "
                       "{!r}").format(self.clouds_file)
            raise ValueError(message)

        clouds_config = clouds_section.get(cloud_name)
        if clouds_config is None:
            message = ("No such cloud with name {!r} in file "
                       "{!r}").format(cloud_name, self.clouds_file)
            raise ValueError(message)

        auth = clouds_config.get("auth")
        if auth is None:
            message = ("No such 'auth' section in cloud file {!r} for cloud "
                       "name {!r}").format(self.clouds_file, self.cloud_name)
            raise ValueError(message)

        auth_url = auth.get("auth_url")
        if not auth_url:
            message = ("No such 'auth_url' in file {!r} for cloud name "
                       "{!r}").format(self.clouds_file, self.cloud_name)
            raise ValueError(message)

        username = auth.get('username') or auth.get('user_id')
        password = auth.get('password')
        project_name = (auth.get('project_name') or
                        auth.get('tenant_namer') or
                        auth.get('project_id') or
                        auth.get_env('tenant_id'))

        api_version = (int(clouds_config.get("identity_api_version", 0)) or
                       _credentials.api_version_from_url(auth_url))
        if api_version == 2:
            return _credentials.keystone_credentials(
                api_version=api_version,
                auth_url=auth_url,
                username=username,
                password=password,
                project_name=project_name)

        else:
            domain_name = (auth.get("domain_name") or
                           auth.get("domain_id"))
            user_domain_name = (auth.get("user_domain_name") or
                                auth.get("user_domain_id"))
            project_domain_name = auth.get("project_domain_name")
            project_domain_id = auth.get("project_domain_id")
            trust_id = auth.get("trust_id")
            return _credentials.keystone_credentials(
                api_version=api_version,
                auth_url=auth_url,
                username=username,
                password=password,
                project_name=project_name,
                domain_name=domain_name,
                user_domain_name=user_domain_name,
                project_domain_name=project_domain_name,
                project_domain_id=project_domain_id,
                trust_id=trust_id)

    def _get_cloud_name(self):
        cloud_name = self.cloud_name
        if cloud_name is None:
            cloud_name = os.environ.get("OS_CLOUD")
            if cloud_name:
                LOG.debug("Got cloud name from 'OS_CLOUD' environment "
                          "variable: %r", cloud_name)
                self.cloud_name = cloud_name
            else:
                LOG.debug("Undefined environment variable: 'OS_CLOUD'")
        return cloud_name or None

    def _get_clouds_content(self):
        clouds_content = self.clouds_content
        if clouds_content is None:
            clouds_file = self._get_clouds_file()
            with open(clouds_file, 'r') as f:
                _, suffix = os.path.splitext(clouds_file)
                if suffix in JSON_SUFFIXES:
                    LOG.debug('Load JSON clouds file: %r', clouds_file)
                    clouds_content = json.load(f)
                else:
                    LOG.debug('Load YAML clouds file: %r', clouds_file)
                    clouds_content = yaml.safe_load(f)
            LOG.debug('Clouds file content loaded from %r:\n%s',
                      clouds_file, json.dumps(clouds_content,
                                              indent=4,
                                              sort_keys=True))
            self.clouds_content = clouds_content

        if not clouds_content:
            message = "Invalid clouds file content: {!r}".format(
                clouds_content)
            raise ValueError(message)
        return clouds_content

    def _get_clouds_file(self):
        clouds_file = self.clouds_file
        if clouds_file:
            clouds_files = [self.clouds_file]
        else:
            clouds_files = list(self.clouds_files)

        for filename in clouds_files:
            if os.path.exists(filename):
                LOG.debug('Found clouds file at %r', filename)
                self.clouds_file = clouds_file = filename
                break
        else:
            raise CloudsFileNotFoundError(clouds_files=', '.join(clouds_files))
        return clouds_file
Ejemplo n.º 20
0
class L3haNetworkTest(NetworkTest):
    #: Resources stack with floating IP and Nova server
    stack = tobiko.required_setup_fixture(stacks.L3haPeerServerStackFixture)
Ejemplo n.º 21
0
class ListRequiredFixtureTest(unit.TobikoUnitTest):

    required_fixture = tobiko.required_fixture(MyRequiredFixture)
    required_setup_fixture = tobiko.required_setup_fixture(
        MyRequiredSetupFixture)

    def test_with_module(self):
        module = sys.modules[__name__]
        result = tobiko.list_required_fixtures([module])
        self.assertEqual([], result)

    def test_with_module_name(self):
        result = tobiko.list_required_fixtures([__name__])
        self.assertEqual([], result)

    def test_with_testcase_type(self):
        result = tobiko.list_required_fixtures([ListRequiredFixtureTest])
        self.assertEqual([
            canonical_name(MyRequiredFixture),
            canonical_name(MyRequiredSetupFixture)
        ], result)

    def test_with_testcase_name(self):
        result = tobiko.list_required_fixtures(
            [canonical_name(ListRequiredFixtureTest)])
        self.assertEqual([
            canonical_name(MyRequiredFixture),
            canonical_name(MyRequiredSetupFixture)
        ], result)

    def test_with_unbound_method(self, fixture=MyFixture, fixture2=MyFixture2):
        result = tobiko.list_required_fixtures(
            [ListRequiredFixtureTest.test_with_unbound_method])
        self.assertEqual([
            canonical_name(fixture),
            canonical_name(fixture2),
            canonical_name(MyRequiredFixture),
            canonical_name(MyRequiredSetupFixture)
        ], result)

    def test_with_bound_method(self, fixture=MyFixture, fixture2=MyFixture2):
        result = tobiko.list_required_fixtures([self.test_with_bound_method])
        self.assertEqual([
            canonical_name(fixture),
            canonical_name(fixture2),
            canonical_name(MyRequiredFixture),
            canonical_name(MyRequiredSetupFixture)
        ], result)

    def test_with_method_name(self, fixture=MyFixture, fixture2=MyFixture2):
        result = tobiko.list_required_fixtures([self.id()])
        self.assertEqual([
            canonical_name(fixture),
            canonical_name(fixture2),
            canonical_name(MyRequiredFixture),
            canonical_name(MyRequiredSetupFixture)
        ], result)

    def test_with_fixture_name(self):
        result = tobiko.list_required_fixtures([canonical_name(MyFixture)])
        self.assertEqual([canonical_name(MyFixture)], result)

    def test_with_fixture(self):
        result = tobiko.list_required_fixtures([MyFixture()])
        self.assertEqual([canonical_name(MyFixture)], result)

    def test_with_fixture_type(self):
        result = tobiko.list_required_fixtures([MyFixture])
        self.assertEqual([canonical_name(MyFixture)], result)

    def test_required_fixture_property(self):
        fixture = self.required_fixture
        self.assertIsInstance(fixture, MyRequiredFixture)
        fixture.setup_fixture.assert_not_called()
        fixture.cleanup_fixture.assert_not_called()

    def test_required_setup_fixture_property(self):
        fixture = self.required_setup_fixture
        self.assertIsInstance(fixture, MyRequiredSetupFixture)
        fixture.setup_fixture.assert_called_once_with()
        fixture.cleanup_fixture.assert_not_called()
Ejemplo n.º 22
0
class OctaviaOtherMemberServerStackFixture(
        stacks.OctaviaMemberServerStackFixture):
    server_stack = tobiko.required_setup_fixture(
        OctaviaOtherServerStackFixture)
Ejemplo n.º 23
0
class PingTest(testtools.TestCase):

    namespace = tobiko.required_setup_fixture(fixtures.NetworkNamespaceFixture)

    def test_ping_recheable_address(self):
        result = ping.ping('127.0.0.1', count=3)
        self.assertIsNone(result.source)
        self.assertEqual(netaddr.IPAddress('127.0.0.1'), result.destination)
        result.assert_transmitted()
        result.assert_replied()

    def test_ping_reachable_hostname(self):
        result = ping.ping('example.org', count=3)
        self.assertIsNone(result.source)
        # self.assertIsNotNone(result.destination)
        result.assert_transmitted()
        result.assert_replied()

    def test_ping_unreachable_address(self):
        result = ping.ping('1.2.3.4', count=3)
        self.assertIsNone(result.source)
        self.assertEqual(netaddr.IPAddress('1.2.3.4'), result.destination)
        result.assert_transmitted()
        result.assert_not_replied()

    def test_ping_unreachable_hostname(self):
        ex = self.assertRaises(ping.UnknowHostError,
                               ping.ping,
                               'unreachable-host',
                               count=3)
        if ex.details:
            self.assertEqual('unreachable-host', ex.details)

    def test_ping_until_received(self):
        result = ping.ping_until_received('127.0.0.1', count=3)
        self.assertIsNone(result.source)
        self.assertEqual(netaddr.IPAddress('127.0.0.1'), result.destination)
        result.assert_transmitted()
        result.assert_replied()

    def test_ping_until_received_unreachable(self):
        ex = self.assertRaises(ping.PingFailed,
                               ping.ping_until_received,
                               '1.2.3.4',
                               count=3,
                               timeout=6)
        self.assertEqual(6, ex.timeout)
        self.assertEqual(0, ex.count)
        self.assertEqual(3, ex.expected_count)
        self.assertEqual('received', ex.message_type)

    def test_ping_until_unreceived_recheable(self):
        ex = self.assertRaises(ping.PingFailed,
                               ping.ping_until_unreceived,
                               '127.0.0.1',
                               count=3,
                               timeout=6)
        self.assertEqual(6, ex.timeout)
        self.assertEqual(0, ex.count)
        self.assertEqual(3, ex.expected_count)
        self.assertEqual('unreceived', ex.message_type)

    def test_ping_until_unreceived_unrecheable(self):
        result = ping.ping_until_unreceived('1.2.3.4', count=3)
        self.assertIsNone(result.source)
        self.assertEqual(netaddr.IPAddress('1.2.3.4'), result.destination)
        result.assert_transmitted()
        result.assert_not_replied()

    def test_ping_reachable_with_timeout(self):
        ex = self.assertRaises(ping.PingFailed,
                               ping.ping,
                               '127.0.0.1',
                               count=20,
                               timeout=1.)
        self.assertEqual(1., ex.timeout)
        self.assertEqual(20, ex.expected_count)
        self.assertEqual('transmitted', ex.message_type)

    def test_ping_hosts(self,
                        ssh_client=None,
                        network_namespace=None,
                        **params):
        ips = ip.list_ip_addresses(ssh_client=ssh_client,
                                   network_namespace=network_namespace)
        reachable_ips, unrecheable_ips = ping.ping_hosts(
            ips,
            ssh_client=ssh_client,
            network_namespace=network_namespace,
            **params)

        expected_reachable = [i for i in ips if i in reachable_ips]
        self.assertEqual(expected_reachable, reachable_ips)
        expected_unreachable = [i for i in ips if i not in reachable_ips]
        self.assertEqual(expected_unreachable, unrecheable_ips)

    def test_ping_hosts_from_network_namespace(self):
        self.test_ping_hosts(
            ssh_client=self.namespace.ssh_client,
            network_namespace=self.namespace.network_namespace)
Ejemplo n.º 24
0
class SSHClientFixture(tobiko.SharedFixture):

    host = None
    port = 22
    username = getpass.getuser()

    client = None

    default = tobiko.required_setup_fixture(_config.SSHDefaultConfigFixture)
    config_files = None
    host_config = None

    proxy_client = None
    proxy_sock = None
    connect_parameters = None
    schema = SSH_CONNECT_PARAMETERS

    def __init__(self,
                 host=None,
                 proxy_client=None,
                 host_config=None,
                 config_files=None,
                 schema=None,
                 **kwargs):
        super(SSHClientFixture, self).__init__()
        if host:
            self.host = host
        if proxy_client:
            self.proxy_client = proxy_client
        if host_config:
            self.host_config = host_config
        if config_files:
            self.config_files = config_files

        self.schema = schema = dict(schema or self.schema)
        self._connect_parameters = gather_ssh_connect_parameters(schema=schema,
                                                                 **kwargs)
        self._forwarders = []

    def setup_fixture(self):
        self.setup_connect_parameters()
        self.setup_ssh_client()

    def setup_host_config(self):
        if not self.host_config:
            self.host_config = _config.ssh_host_config(
                host=self.host, config_files=self.config_files)
        return self.host_config

    def setup_connect_parameters(self):
        """Fill connect parameters dict

        Get parameters values from below sources:
        - parameters passed to class constructor
        - parameters got from ~/.ssh/config and tobiko.conf
        - parameters got from fixture object attributes
        """
        self.setup_host_config()
        if not self.connect_parameters:
            self.connect_parameters = self.get_connect_parameters()
        return self.connect_parameters

    def get_connect_parameters(self, schema=None):
        schema = dict(schema or self.schema)
        parameters = {}
        for gather_parameters in [
                self.gather_initial_connect_parameters,
                self.gather_host_config_connect_parameters,
                self.gather_default_connect_parameters
        ]:
            gather_parameters(destination=parameters,
                              schema=schema,
                              remove_from_schema=True)
        if parameters:
            LOG.debug('SSH connect parameters for host %r:\n%r', self.host,
                      parameters)
        return parameters

    def gather_initial_connect_parameters(self, **kwargs):
        parameters = gather_ssh_connect_parameters(
            source=self._connect_parameters, **kwargs)
        if parameters:
            LOG.debug('Initial SSH connect parameters for host %r:\n'
                      '%r', self.host, parameters)
        return parameters

    def gather_host_config_connect_parameters(self, **kwargs):
        parameters = gather_ssh_connect_parameters(
            source=self.host_config.connect_parameters, **kwargs)
        if parameters:
            LOG.debug(
                'Host configured SSH connect parameters for host %r:\n'
                '%r', self.host, parameters)
        return parameters

    def gather_default_connect_parameters(self, **kwargs):
        parameters = gather_ssh_connect_parameters(source=self, **kwargs)
        if parameters:
            LOG.debug('Default SSH connect parameters for host %r:\n'
                      '%r', self.host, parameters)
        return parameters

    def setup_ssh_client(self):
        self.client, self.proxy_sock = ssh_connect(
            proxy_client=self.proxy_client, **self.connect_parameters)
        self.addCleanup(self.cleanup_ssh_client)
        if self.proxy_sock:
            self.addCleanup(self.cleanup_proxy_sock)
        for forwarder in self._forwarders:
            self.useFixture(forwarder)

    def cleanup_ssh_client(self):
        client = self.client
        self.client = None
        if client:
            try:
                client.close()
            except Exception:
                LOG.exception('Error closing client (%r)', self)

    def cleanup_proxy_sock(self):
        proxy_sock = self.proxy_sock
        self.proxy_sock = None
        if proxy_sock:
            try:
                proxy_sock.close()
            except Exception:
                LOG.exception('Error closing proxy socket (%r)', self)

    def connect(self):
        return tobiko.setup_fixture(self).client

    def get_ssh_command(self,
                        host=None,
                        username=None,
                        port=None,
                        command=None,
                        config_files=None,
                        host_config=None,
                        proxy_command=None,
                        key_filename=None,
                        **options):
        connect_parameters = self.setup_connect_parameters()
        host = host or connect_parameters.get('hostname')
        username = username or connect_parameters.get('username')
        port = port or connect_parameters.get('port')
        config_files = config_files or connect_parameters.get('config_files')
        if not host_config:
            _host_config = self.setup_host_config()
            if hasattr(_host_config, 'host_config'):
                _host_config = host_config
        key_filename = key_filename or connect_parameters.get('key_filename')
        proxy_command = (proxy_command
                         or connect_parameters.get('proxy_command'))
        if not proxy_command and self.proxy_client:
            proxy_command = self.proxy_client.get_ssh_command()

        return _command.ssh_command(host=host,
                                    username=username,
                                    port=port,
                                    command=command,
                                    config_files=config_files,
                                    host_config=host_config,
                                    proxy_command=proxy_command,
                                    key_filename=key_filename,
                                    **options)
Ejemplo n.º 25
0
class UbuntuServerL3HAPortTestWith(PortTest):
    #: Resources stack with floating IP and Nova server
    stack = tobiko.required_setup_fixture(stacks.L3haUbuntuServerStackFixture)
Ejemplo n.º 26
0
class L3HaNetworkTestCase(NetworkTestCase):

    #: Stack of resources with a network with a gateway router
    stack = tobiko.required_setup_fixture(stacks.L3haNetworkStackFixture)
Ejemplo n.º 27
0
Archivo: _nova.py Proyecto: 4383/tobiko
class ServerStackFixture(heat.HeatStackFixture):

    #: Heat template file
    template = _hot.heat_template_file('nova/server.yaml')

    #: stack with the key pair for the server instance
    key_pair_stack = tobiko.required_setup_fixture(KeyPairStackFixture)

    #: stack with the internal where the server port is created
    network_stack = tobiko.required_setup_fixture(_neutron.NetworkStackFixture)

    #: Glance image used to create a Nova server instance
    image_fixture = None

    @property
    def image(self):
        return self.image_fixture.image_id

    @property
    def username(self):
        """username used to login to a Nova server instance"""
        return self.image_fixture.username

    @property
    def password(self):
        """password used to login to a Nova server instance"""
        return self.image_fixture.password

    # Stack used to create flavor for Nova server instance
    flavor_stack = None

    @property
    def flavor(self):
        """Flavor for Nova server instance"""
        return self.flavor_stack.flavor_id

    #: Whenever port security on internal network is enable
    port_security_enabled = False

    #: Security groups to be associated to network ports
    security_groups = []  # type: typing.List[str]

    @property
    def key_name(self):
        return self.key_pair_stack.key_name

    @property
    def network(self):
        return self.network_stack.network_id

    #: Floating IP network where the Neutron floating IP is created
    floating_network = CONF.tobiko.neutron.floating_network

    @property
    def has_floating_ip(self):
        """Whenever to allocate floating IP for the server"""
        return bool(self.floating_network)

    @property
    def ssh_client(self):
        return ssh.ssh_client(host=self.ip_address,
                              username=self.username,
                              password=self.password)

    @property
    def ssh_command(self):
        return ssh.ssh_command(host=self.ip_address, username=self.username)

    @property
    def ip_address(self):
        if self.has_floating_ip:
            return self.floating_ip_address
        else:
            return self.outputs.fixed_ips[0]['ip_address']

    #: Schedule on different host that this Nova server instance ID
    different_host = None

    #: Schedule on same host as this Nova server instance ID
    same_host = None

    @property
    def scheduler_hints(self):
        scheduler_hints = {}
        if self.different_host:
            scheduler_hints.update(different_host=self.different_host)
        if self.same_host:
            scheduler_hints.update(same_host=self.same_host)
        return scheduler_hints

    @property
    def server_details(self):
        return nova.get_server(self.server_id)

    @property
    def port_details(self):
        return neutron.get_port(self.port_id)

    def getDetails(self):
        # pylint: disable=W0212
        details = super(ServerStackFixture, self).getDetails()
        stack = self.get_stack()
        if stack:
            details[self.fixture_name + '.stack'] = (self.details_content(
                get_json=lambda: stack._info))
            if stack.stack_status == 'CREATE_COMPLETE':
                details[self.fixture_name +
                        '.server_details'] = (self.details_content(
                            get_json=lambda: self.server_details._info))
                details[self.fixture_name +
                        '.console_output'] = (self.details_content(
                            get_text=lambda: self.console_output))
        return details

    def details_content(self, **kwargs):
        return tobiko.details_content(content_id=self.fixture_name, **kwargs)

    max_console_output_length = 64 * 1024

    @property
    def console_output(self):
        return nova.get_console_output(server=self.server_id,
                                       length=self.max_console_output_length)
Ejemplo n.º 28
0
class OpenStackTopology(tobiko.SharedFixture):

    config = tobiko.required_setup_fixture(OpenStackTopologyConfig)

    def __init__(self):
        super(OpenStackTopology, self).__init__()
        self._reachable_ips = set()
        self._unreachable_ips = set()
        self._nodes_by_name = collections.OrderedDict()
        self._nodes_by_ips = collections.OrderedDict()
        self._nodes_by_group = collections.OrderedDict()

    def setup_fixture(self):
        self.discover_nodes()

    def cleanup_fixture(self):
        self._reachable_ips.clear()
        self._unreachable_ips.clear()
        self._nodes_by_name.clear()
        self._nodes_by_ips.clear()
        self._nodes_by_group.clear()

    def discover_nodes(self):
        self.discover_configured_nodes()
        self.discover_controller_nodes()
        self.discover_compute_nodes()

    def discover_configured_nodes(self):
        for address in self.config.conf.nodes or []:
            self.add_node(address=address)

    def discover_controller_nodes(self):
        endpoints = keystone.list_endpoints(interface='public')
        addresses = set(
            parse.urlparse(endpoint.url).hostname for endpoint in endpoints)
        for address in addresses:
            self.add_node(address=address, group='controller')

    def discover_compute_nodes(self):
        for hypervisor in nova.list_hypervisors():
            self.add_node(hostname=hypervisor.hypervisor_hostname,
                          address=hypervisor.host_ip,
                          group='compute')

    def add_node(self,
                 hostname=None,
                 address=None,
                 group=None,
                 ssh_client=None):
        name = hostname and node_name_from_hostname(hostname) or None
        ips = set()
        if address:
            ips.update(self._ips(address))
        if hostname:
            ips.update(self._ips(hostname))
        ips = tobiko.select(ips)

        try:
            node = self.get_node(name=name, address=ips)
        except _exception.NoSuchOpenStackTopologyNode:
            node = self._add_node(hostname=hostname,
                                  ips=ips,
                                  ssh_client=ssh_client)

        if node and group:
            self.add_group(group=group).append(node)
            node.add_group(group=group)
        return node

    def _add_node(self, ips, hostname=None, ssh_client=None):
        public_ip = self._public_ip(ips, ssh_client=ssh_client)
        if public_ip is None:
            LOG.debug("Unable to SSH connect to any node IP address: %s"
                      ','.join(str(ip_address) for ip_address in ips))
            return None

        # I need to get a name for the new node
        ssh_client = ssh_client or self._ssh_client(public_ip)
        hostname = hostname or sh.get_hostname(ssh_client=ssh_client)
        name = node_name_from_hostname(hostname)
        try:
            node = self._nodes_by_name[name]
        except KeyError:
            self._nodes_by_name[name] = node = self.create_node(
                name=name, public_ip=public_ip, ssh_client=ssh_client)
            other = self._nodes_by_ips.setdefault(public_ip, node)
            if node is not other:
                LOG.error("Two nodes have the same IP address (%s): %r, %r",
                          public_ip, node.name, other.name)
        return node

    def get_node(self, name=None, hostname=None, address=None):
        name = name or (hostname and node_name_from_hostname(hostname))
        details = {}
        if name:
            tobiko.check_valid_type(name, six.string_types)
            details['name'] = name
            try:
                return self._nodes_by_name[name]
            except KeyError:
                pass
        if address:
            details['address'] = address
            for ip_address in self._ips(address):
                try:
                    return self._nodes_by_ips[ip_address]
                except KeyError:
                    pass
        raise _exception.NoSuchOpenStackTopologyNode(details=details)

    def create_node(self, name, public_ip, ssh_client, **kwargs):
        return OpenStackTopologyNode(topology=self,
                                     name=name,
                                     public_ip=public_ip,
                                     ssh_client=ssh_client,
                                     **kwargs)

    @property
    def nodes(self):
        return tobiko.select(
            self.get_node(name) for name in self._nodes_by_name)

    def add_group(self, group):
        try:
            return self._nodes_by_group[group]
        except KeyError:
            self._nodes_by_group[group] = nodes = self.create_group()
            return nodes

    def create_group(self):
        return tobiko.Selection()

    def get_group(self, group):
        try:
            return self._nodes_by_group[group]
        except KeyError:
            raise _exception.NoSuchOpenStackTopologyNodeGroup(group=group)

    @property
    def groups(self):
        return list(self._nodes_by_group)

    def _ssh_client(self,
                    address,
                    username=None,
                    port=None,
                    key_filename=None,
                    **ssh_parameters):
        username = username or self.config.conf.username
        port = port or self.config.conf.port
        key_filename = key_filename or self.config.conf.key_file
        return ssh.ssh_client(host=str(address),
                              username=username,
                              key_filename=key_filename,
                              **ssh_parameters)

    def _public_ip(self, ips, ssh_client=None):
        reachable_ip = self._reachable_ip(ips)
        if reachable_ip:
            return reachable_ip

        if not ssh_client:
            # Try connecting via other nodes to get target node IP
            # addresses
            proxy_client = None
            for proxy_node in self.nodes:
                proxy_client = proxy_node.ssh_client
                if proxy_client:
                    internal_ip = self._reachable_ip(ips,
                                                     proxy_client=proxy_client)
                    if internal_ip:
                        ssh_client = self._ssh_client(
                            internal_ip, proxy_client=proxy_client)
                        break
                if ssh_client:
                    break

        if ssh_client:
            # Connect via SSH to to get target node IP addresses
            ips = self._ips_from_host(ssh_client=ssh_client)
            reachable_ip = self._reachable_ip(ips)
            if reachable_ip:
                return reachable_ip

        LOG.warning('Unable to reach remote host via any IP address: %s',
                    ', '.join(str(a) for a in ips))
        return None

    def _reachable_ip(self, ips, proxy_client=None, **kwargs):
        reachable = None
        if proxy_client:
            untested_ips = ips
        else:
            # Exclude unreachable addresses
            untested_ips = list()
            for address in ips:
                if address not in self._unreachable_ips:
                    if address in self._reachable_ips:
                        # Will take result from the first one of marked already
                        # marked as reachable
                        reachable = reachable or address
                    else:
                        # Will later search for results between the other IPs
                        untested_ips.append(address)

        for address in untested_ips:
            if reachable is None:
                try:
                    received = ping.ping(address,
                                         count=1,
                                         timeout=5.,
                                         ssh_client=proxy_client,
                                         **kwargs).received
                except ping.PingFailed:
                    pass
                else:
                    if received:
                        reachable = address
                        # Mark IP as reachable
                        self._reachable_ips.add(address)
                        continue

            # Mark IP as unreachable
            self._unreachable_ips.add(address)

        return reachable

    @property
    def ip_version(self):
        ip_version = self.config.conf.ip_version
        return ip_version and int(ip_version) or None

    def _ips_from_host(self, **kwargs):
        return ip.list_ip_addresses(ip_version=self.ip_version,
                                    scope='global',
                                    **kwargs)

    def _ips(self, obj):
        if isinstance(obj, tobiko.Selection):
            ips = obj
        elif isinstance(obj, netaddr.IPAddress):
            ips = tobiko.select([obj])
        elif isinstance(obj, six.string_types):
            try:
                ips = tobiko.select([netaddr.IPAddress(obj)])
            except (netaddr.AddrFormatError, ValueError):
                ips = resolve_host_ips(obj)
        else:
            for item in iter(obj):
                tobiko.check_valid_type(item, netaddr.IPAddress)
            ips = tobiko.select(obj)

        if ips and self.ip_version:
            ips = ips.with_attributes(version=self.ip_version)
        return ips
Ejemplo n.º 29
0
class OctaviaBasicTrafficScenarioTest(base.TobikoTest):
    """Octavia traffic scenario test.

    Create a load balancer with 2 members that run a server application,
    Create a client that is connected to the load balancer VIP port,
    Generate network traffic from the client to the load balanacer.
    """
    loadbalancer_stack = tobiko.required_setup_fixture(
        stacks.OctaviaLoadbalancerStackFixture)

    listener_stack = tobiko.required_setup_fixture(
        stacks.OctaviaListenerStackFixture)

    member1_stack = tobiko.required_setup_fixture(
        stacks.OctaviaMemberServerStackFixture)

    member2_stack = tobiko.required_setup_fixture(
        OctaviaOtherMemberServerStackFixture)

    client_stack = tobiko.required_setup_fixture(
        stacks.OctaviaClientServerStackFixture)

    members_count = 2

    def setUp(self):
        super(OctaviaBasicTrafficScenarioTest, self).setUp()

        # Wait for members
        self._check_member(self.member1_stack)
        self._check_member(self.member2_stack)

        # Check if load balancer is functional
        self._check_loadbalancer()

    def _request(self, client_stack, server_ip_address, protocol, server_port):
        """Perform a request on a server.

        Returns the response in case of success, throws an RequestException
        otherwise.
        """
        if ':' in server_ip_address:
            # Add square brackets around IPv6 address to please curl
            server_ip_address = "[{}]".format(server_ip_address)
        cmd = "curl {} {}://{}:{}/id".format(CURL_OPTIONS, protocol.lower(),
                                             server_ip_address, server_port)

        ssh_client = ssh.ssh_client(
            client_stack.floating_ip_address,
            username=client_stack.image_fixture.username)

        ret = sh.ssh_execute(ssh_client, cmd)
        if ret.exit_status != 0:
            raise RequestException(command=cmd, error=ret.stderr)

        return ret.stdout

    def _wait_resource_operating_status(self, resource_type, operating_status,
                                        resource_get, *args):
        start = time.time()

        while time.time() - start < CONF.tobiko.octavia.check_timeout:
            res = resource_get(*args)
            if res['operating_status'] == operating_status:
                return

            time.sleep(CONF.tobiko.octavia.check_interval)

        raise TimeoutException(
            reason=("Cannot get operating_status '{}' from {} {} "
                    "within the timeout period.".format(
                        operating_status, resource_type, args)))

    def _wait_lb_operating_status(self, lb_id, operating_status):
        LOG.debug("Wait for loadbalancer {} to have '{}' "
                  "operating_status".format(lb_id, operating_status))
        self._wait_resource_operating_status("loadbalancer", operating_status,
                                             octavia.get_loadbalancer, lb_id)

    def _wait_for_request_data(self, client_stack, server_ip_address,
                               server_protocol, server_port):
        """Wait until a request on a server succeeds

        Throws a TimeoutException after CONF.tobiko.octavia.check_timeout
        if the server doesn't reply.
        """
        start = time.time()

        while time.time() - start < CONF.tobiko.octavia.check_timeout:
            try:
                ret = self._request(client_stack, server_ip_address,
                                    server_protocol, server_port)
            except Exception as e:
                LOG.warning("Received exception {} while performing a "
                            "request".format(e))
            else:
                return ret
            time.sleep(CONF.tobiko.octavia.check_interval)

        raise TimeoutException(
            reason=("Cannot get data from {} on port {} with "
                    "protocol {} within the timeout period.".format(
                        server_ip_address, server_port, server_protocol)))

    def _check_loadbalancer(self):
        """Wait until the load balancer is functional."""

        # Check load balancer status
        loadbalancer_id = self.loadbalancer_stack.loadbalancer_id
        self._wait_lb_operating_status(loadbalancer_id, 'ONLINE')

        loadbalancer_vip = self.loadbalancer_stack.loadbalancer_vip
        loadbalancer_port = self.listener_stack.lb_port
        loadbalancer_protocol = self.listener_stack.lb_protocol

        self._wait_for_request_data(self.client_stack, loadbalancer_vip,
                                    loadbalancer_protocol, loadbalancer_port)

    def _check_member(self, member_stack):
        """Wait until a member server is functional."""

        member_ip = member_stack.server_stack.floating_ip_address
        member_port = member_stack.application_port
        member_protocol = self.listener_stack.pool_protocol

        self._wait_for_request_data(self.client_stack, member_ip,
                                    member_protocol, member_port)

    def _check_members_balanced(self):
        """Check if traffic is properly balanced between members."""
        replies = {}

        loadbalancer_vip = self.loadbalancer_stack.loadbalancer_vip
        loadbalancer_port = self.listener_stack.lb_port
        loadbalancer_protocol = self.listener_stack.lb_protocol

        for _ in range(20):
            content = self._request(self.client_stack, loadbalancer_vip,
                                    loadbalancer_protocol, loadbalancer_port)

            if content not in replies:
                replies[content] = 0
            replies[content] += 1

            # wait one second (required when using cirros' nc fake webserver)
            time.sleep(1)

        LOG.debug("Replies from load balancer: {}".format(replies))

        # assert that 'members_count' servers replied
        self.assertEqual(len(replies), self.members_count)

        if self.listener_stack.lb_algorithm == 'ROUND_ROBIN':
            # assert that requests have been fairly dispatched (each server
            # received the same number of requests)
            self.assertEqual(len(set(replies.values())), 1)

    def test_traffic(self):
        self._check_members_balanced()
Ejemplo n.º 30
0
class L3haServerStackFixture(_cirros.CirrosServerStackFixture):
    #: Heat stack for creating internal network with L3HA enabled
    network_stack = tobiko.required_setup_fixture(L3haNetworkStackFixture)