Add test contrail_public_connectivity_from_instance_without_fip.

-add ssh wrapper
-add new test contrail_public_connectivity_from_instance_without_fip
-fix multiple networks tests
-increase ostf timeout

Change-Id: I6153f65c8854fe32c849bb40793c83d100bd0eaa
This commit is contained in:
otsvigun
2016-08-04 10:09:51 +03:00
parent cf3d946e9e
commit 1008311015
5 changed files with 243 additions and 33 deletions

View File

@@ -68,10 +68,9 @@ Steps
#####
1. Login as admin to Openstack Horizon UI
2. Launch a new instance
3. Send ping to external IP (example 8.8.8.8)
4. Send ping to IP address of lab host in environments public net
5. Verify on Contrail controller WebUI that network is there and VMs are attached to it
2. Launch an instance using the default image, flavor and security group.
3. Check that public IP 8.8.8.8 can be pinged from instance.
4. Delete instance.
Expected results

View File

@@ -18,7 +18,7 @@ import os
VSRX_TEMPLATE_PATH = os.environ.get('VSRX_TEMPLATE_PATH', False)
OSTF_RUN_TIMEOUT = 45 * 60 # 45 minutes
OSTF_RUN_TIMEOUT = 60 * 60 # 60 minutes
DEPLOY_CLUSTER_TIMEOUT = 25 * 60 # 25 minutes
CONTRAIL_PLUGIN_VERSION = os.environ.get('CONTRAIL_PLUGIN_VERSION', '4.0.1')
VSRX_CONFIG_PATH = os.environ.get(

156
plugin_test/helpers/ssh.py Normal file
View File

@@ -0,0 +1,156 @@
"""Copyright 2016 Mirantis, 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
copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
License for the specific language governing permissions and limitations
under the License.
"""
import paramiko
import time
from devops.helpers.helpers import wait
from fuelweb_test import logger
class SSH(object):
"""Paramiko ssh client wrapper.
:param ip: string, host ip to connect to
:param username: string, a username to use for authentication
:param userpassword: string, a password to use for authentication
:param timeout: timeout (in seconds) for the TCP connection
:param port: host port to connect to
"""
result = {
'stdout': [],
'stderr': [],
'exit_code': 0
}
instance_creds = ('cirros', 'cubswin:)')
def __init__(self, ip, username=instance_creds[0],
userpassword=instance_creds[1], timeout=30, port=22):
"""Create SshClient object.
:param ip: string, host ip to connect to
:param username: string, a username to use for authentication
:param userpassword: string, a password to use for authentication
:param timeout: timeout (in seconds) for the TCP connection
:param port: host port to connect
"""
self.ip = ip
self.username = username
self.userpassword = userpassword
self.timeout = timeout
self.port = port
def __enter__(self):
"""Create ssh conection."""
self.ssh = paramiko.SSHClient()
self.ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
self.ssh.connect(
self.ip, port=self.port, username=self.username,
password=self.userpassword, timeout=self.timeout
)
return self
def __exit__(self, exc_type, value, traceback):
"""Close ssh conection."""
self.ssh.close()
def remote_execute_command(self, remote_ip, user, password,
command, wait=30):
"""Check execute remote command.
:param remote_ip: string, instance ip connect to
:param user: string, a username to use for authentication
:param password: string, a password to use for authentication
:param command: string, remote command
:param wait: integer, time to wait available ip of instances
"""
interm_transp = self.ssh.get_transport()
time.sleep(wait)
interm_chan = interm_transp.open_channel('direct-tcpip',
(remote_ip, 22),
(self.ip, 0))
transport = paramiko.Transport(interm_chan)
transport.start_client()
logger.info("Passing authentication to VM")
transport.auth_password(user, password)
channel = transport.open_session()
channel.get_pty()
channel.fileno()
channel.exec_command(command)
logger.debug("Receiving exit_code")
self.result['exit_code'] = channel.recv_exit_status()
logger.debug("Receiving stdout")
self.result['stdout'] = channel.recv(1024)
logger.debug("Receiving stderr")
self.result['stderr'] = channel.recv_stderr(1024)
logger.debug("Closing channel")
channel.close()
return self.result
def check_connection_through_host(self, ip_pair, user=instance_creds[0],
password=instance_creds[1],
command='pingv4',
result_of_command=0, timeout=30,
interval=5):
"""Check network connectivity between instances.
:param ip_pair: type list, ips of instances
:param user: string, a username to use for authentication
:param password: string, a password to use for authentication
:param command: type string, key from dictionary 'commands'
by default is 'pingv4'
:param result_of_command: type interger, exite code of command
execution by default is 0
:param timeout: wait to get expected result
:param interval: interval of executing command
"""
commands = {
"pingv4": "ping -c 5 {}",
"pingv6": "ping6 -c 5 {}",
"arping": "sudo arping -I eth0 {}"}
for ip_from in ip_pair:
for ip_to in ip_pair[ip_from]:
message = self.generate_message(
commands[command], result_of_command, ip_from, ip_to)
wait(
lambda:
self.remote_execute_command(
ip_from, user, password,
commands[command].format(ip_to),
wait=timeout)['exit_code'] == result_of_command,
interval=interval,
timeout=timeout,
timeout_msg=message.format(
ip_from, ip_to)
)
def generate_message(self, command, result_of_command, ip_from, ip_to):
"""Generate error message for check connection methods.
:param command: type string, name of command
:param result_of_command: type interger, exite code of
command execution
:param ip_from: type string, check connection from 'ip_from'
:param ip_to: type string, check connection from 'ip_to'
"""
if result_of_command == 0:
param = "isn't"
else:
param = "is"
message = "{0} {1} available from {2} to {3}".format(
command, param, ip_from, ip_to)
return message

View File

@@ -531,23 +531,14 @@ class TestMultipleNets(TestMultipleClusterNets):
self.show_step(16)
conf_control = {'slave-03': [['controller'], nodegroup_custom1]}
openstack.update_deploy_check(self,
conf_control, delete=True,
is_vsrx=vsrx_setup_result)
plugin.show_range(self, 17, 19)
openstack.update_deploy_check(
self, conf_control, delete=True,
is_vsrx=vsrx_setup_result,
ostf_fail_tests=['Check that required services are running'])
self.show_step(17)
openstack.deploy_cluster(self)
TestContrailCheck(self).cloud_check(['contrail'])
self.show_step(18)
if vsrx_setup_result:
self.fuel_web.run_ostf(
cluster_id=self.cluster_id,
test_sets=['smoke', 'sanity'],
should_fail=1,
failed_test_name=['Check that required services are running']
)
@test(depends_on=[SetupEnvironment.prepare_release],
groups=["contrail_multiple_networks_delete_compute"])
@log_snapshot_after_test
@@ -646,23 +637,14 @@ class TestMultipleNets(TestMultipleClusterNets):
self.show_step(16)
conf_compute = {'slave-06': [['compute'], nodegroup_custom1], }
openstack.update_deploy_check(self,
conf_compute, delete=True,
is_vsrx=vsrx_setup_result)
plugin.show_range(self, 17, 19)
openstack.update_deploy_check(
self, conf_compute, delete=True,
is_vsrx=vsrx_setup_result,
ostf_fail_tests=['Check that required services are running'])
self.show_step(17)
openstack.deploy_cluster(self)
TestContrailCheck(self).cloud_check(['contrail'])
self.show_step(18)
if vsrx_setup_result:
self.fuel_web.run_ostf(
cluster_id=self.cluster_id,
test_sets=['smoke', 'sanity', 'ha'],
should_fail=1,
failed_test_name=['Check that required services are running']
)
@test(depends_on=[SetupEnvironment.prepare_release],
groups=["contrail_multiple_networks_add_compute"])
@log_snapshot_after_test

View File

@@ -42,6 +42,7 @@ from helpers.contrail_client import ContrailClient
from helpers import plugin
from helpers import openstack
from helpers.settings import OSTF_RUN_TIMEOUT
from helpers.ssh import SSH
from tests.test_contrail_check import TestContrailCheck
@@ -648,3 +649,75 @@ class SystemTests(TestBasic):
assert_equal(
projects, contrail.get_projects(),
"Can not give info by Contrail API.")
@test(depends_on=[systest_setup],
groups=["contrail_public_connectivity_from_instance_without_fip"])
@log_snapshot_after_test
def contrail_public_connectivity_from_instance_without_fip(self):
"""Check network connectivity from instance without floating IP.
Scenario:
1. Setup systest_setup.
2. Launch an instance using the default image, flavor and
security group.
3. Check that public IP 8.8.8.8 can be pinged from instance.
4. Delete instance.
Duration 5 min
"""
self.show_step(1)
self.env.revert_snapshot('systest_setup')
net_name = 'admin_internal_net'
cluster_id = self.fuel_web.get_last_created_cluster()
os_ip = self.fuel_web.get_public_vip(cluster_id)
os_conn = os_actions.OpenStackActions(
os_ip, SERVTEST_USERNAME,
SERVTEST_PASSWORD,
SERVTEST_TENANT)
self.show_step(2)
# Launch instance as access point
os_conn.goodbye_security()
flavor = [
f for f in os_conn.nova.flavors.list()
if f.name == 'm1.micro'][0]
image = os_conn.nova.images.list().pop()
network = os_conn.nova.networks.find(label=net_name)
access_point = os_conn.nova.servers.create(
flavor=flavor, name='test1', image=image,
nics=[{'net-id': network.id}]
)
wait(
lambda: os_conn.get_instance_detail(
access_point).status == 'ACTIVE',
timeout=300)
access_point_fip = os_conn.assign_floating_ip(access_point).ip
wait(
lambda: tcp_ping(access_point_fip, 22), timeout=120, interval=5,
timeout_msg="Node {0} is not accessible by SSH.".format(
access_point_fip))
instance = os_conn.nova.servers.create(
flavor=flavor, name='test2', image=image,
nics=[{'net-id': network.id}]
)
wait(
lambda: os_conn.get_instance_detail(
instance).status == 'ACTIVE',
timeout=300)
self.show_step(3)
# Get private ip of instance
logger.info('{}'.format(os_conn.nova.servers.ips(instance.id)))
ip = os_conn.nova.servers.ips(instance.id)[net_name].pop()['addr']
with SSH(access_point_fip) as remote:
remote.check_connection_through_host({ip: ['8.8.8.8']})
self.show_step(4)
for instance in [access_point, instance]:
os_conn.delete_instance(instance)
assert_true(
os_conn.verify_srv_deleted(instance),
"Instance was not deleted.")