Merge "Enable fail-fast on the gate queue"
diff --git a/octavia_tempest_plugin/common/constants.py b/octavia_tempest_plugin/common/constants.py
index e767298..a60800f 100644
--- a/octavia_tempest_plugin/common/constants.py
+++ b/octavia_tempest_plugin/common/constants.py
@@ -104,6 +104,7 @@
HTTPS = 'HTTPS'
TCP = 'TCP'
TERMINATED_HTTPS = 'TERMINATED_HTTPS'
+UDP = 'UDP'
# HTTP Methods
GET = 'GET'
diff --git a/octavia_tempest_plugin/config.py b/octavia_tempest_plugin/config.py
index 6d50c89..5e09ba1 100644
--- a/octavia_tempest_plugin/config.py
+++ b/octavia_tempest_plugin/config.py
@@ -173,7 +173,7 @@
default='ubuntu',
help='The amphora SSH user.'),
cfg.StrOpt('amphora_ssh_key',
- default='/tmp/octavia_ssh_key',
+ default='/etc/octavia/.ssh/octavia_ssh_key',
help='The amphora SSH key file.'),
# Environment specific options
# These are used to accomodate clouds with specific limitations
diff --git a/octavia_tempest_plugin/tests/act_stdby_scenario/v2/test_active_standby_iptables.py b/octavia_tempest_plugin/tests/act_stdby_scenario/v2/test_active_standby_iptables.py
index 97886b5..7e6f7e8 100644
--- a/octavia_tempest_plugin/tests/act_stdby_scenario/v2/test_active_standby_iptables.py
+++ b/octavia_tempest_plugin/tests/act_stdby_scenario/v2/test_active_standby_iptables.py
@@ -13,7 +13,6 @@
# License for the specific language governing permissions and limitations
# under the License.
-import os
import testtools
from oslo_log import log as logging
@@ -50,6 +49,8 @@
raise cls.skipException("Configured load balancer topology is not "
"%s." % const.ACTIVE_STANDBY)
+ cls._get_amphora_ssh_key()
+
@classmethod
def resource_setup(cls):
"""Setup resources needed by the tests."""
@@ -230,13 +231,12 @@
@classmethod
def _get_amphora_ssh_key(cls):
key_file = CONF.load_balancer.amphora_ssh_key
- if not key_file:
- raise Exception("SSH key file not provided.")
- if not os.path.isfile(key_file):
- raise Exception("Could not find amphora ssh key file {1}."
+ try:
+ with open(key_file, 'r') as f:
+ return f.read()
+ except IOError:
+ raise Exception("Could not open amphora SSH key file {0}."
.format(key_file))
- with open(key_file, 'r') as f:
- return f.read()
@testtools.skipIf(CONF.load_balancer.test_with_noop,
'Active/Standby tests will not work in noop mode.')
diff --git a/octavia_tempest_plugin/tests/api/v2/test_listener.py b/octavia_tempest_plugin/tests/api/v2/test_listener.py
index 691c61c..3a45656 100644
--- a/octavia_tempest_plugin/tests/api/v2/test_listener.py
+++ b/octavia_tempest_plugin/tests/api/v2/test_listener.py
@@ -161,6 +161,140 @@
self.assertEqual(1000, listener[const.TIMEOUT_MEMBER_DATA])
self.assertEqual(50, listener[const.TIMEOUT_TCP_INSPECT])
+ @decorators.idempotent_id('cceac303-4db5-4d5a-9f6e-ff33780a5f29')
+ def test_listener_create_on_same_port(self):
+ """Tests listener creation on same port number.
+
+ * Create a first listener.
+ * Create a new listener on an existing port, but with a different
+ protocol.
+ * Create a second listener with the same parameters and ensure that
+ an error is triggered.
+ * Create a third listener with another protocol over TCP, and ensure
+ that it fails.
+ """
+
+ # Using listeners on the same port for TCP and UDP was not supported
+ # before Train. Use 2.11 API version as reference to detect previous
+ # releases and skip the test.
+ if not self.mem_listener_client.is_version_supported(
+ self.api_version, '2.11'):
+ raise self.skipException('TCP and UDP listeners on same port fix '
+ 'is only available on Octavia API '
+ 'version 2.11 or newer.')
+
+ listener_name = data_utils.rand_name("lb_member_listener1-create")
+
+ listener_kwargs = {
+ const.NAME: listener_name,
+ const.ADMIN_STATE_UP: True,
+ const.PROTOCOL: self.protocol,
+ const.PROTOCOL_PORT: 8080,
+ const.LOADBALANCER_ID: self.lb_id,
+ const.CONNECTION_LIMIT: 200
+ }
+
+ try:
+ listener = self.mem_listener_client.create_listener(
+ **listener_kwargs)
+ except exceptions.BadRequest as e:
+ faultstring = e.resp_body.get('faultstring', '')
+ if ("Invalid input for field/attribute protocol." in faultstring
+ and "Value should be one of:" in faultstring):
+ raise self.skipException("Skipping unsupported protocol")
+ raise e
+
+ self.addClassResourceCleanup(
+ self.mem_listener_client.cleanup_listener,
+ listener[const.ID],
+ lb_client=self.mem_lb_client, lb_id=self.lb_id)
+
+ waiters.wait_for_status(
+ self.mem_lb_client.show_loadbalancer, self.lb_id,
+ const.PROVISIONING_STATUS, const.ACTIVE,
+ CONF.load_balancer.build_interval,
+ CONF.load_balancer.build_timeout)
+
+ if self.protocol == const.UDP:
+ protocol = const.TCP
+ else:
+ protocol = const.UDP
+
+ # Create a listener on the same port, but with a different protocol
+ listener2_name = data_utils.rand_name("lb_member_listener2-create")
+
+ listener2_kwargs = {
+ const.NAME: listener2_name,
+ const.ADMIN_STATE_UP: True,
+ const.PROTOCOL: protocol,
+ const.PROTOCOL_PORT: 8080,
+ const.LOADBALANCER_ID: self.lb_id,
+ const.CONNECTION_LIMIT: 200,
+ }
+
+ try:
+ listener2 = self.mem_listener_client.create_listener(
+ **listener2_kwargs)
+ except exceptions.BadRequest as e:
+ faultstring = e.resp_body.get('faultstring', '')
+ if ("Invalid input for field/attribute protocol." in faultstring
+ and "Value should be one of:" in faultstring):
+ raise self.skipException("Skipping unsupported protocol")
+ raise e
+
+ self.addClassResourceCleanup(
+ self.mem_listener_client.cleanup_listener,
+ listener2[const.ID],
+ lb_client=self.mem_lb_client, lb_id=self.lb_id)
+
+ waiters.wait_for_status(
+ self.mem_lb_client.show_loadbalancer, self.lb_id,
+ const.PROVISIONING_STATUS, const.ACTIVE,
+ CONF.load_balancer.build_interval,
+ CONF.load_balancer.build_timeout)
+
+ # Create a listener on the same port, with an already used protocol
+ listener3_name = data_utils.rand_name("lb_member_listener3-create")
+
+ listener3_kwargs = {
+ const.NAME: listener3_name,
+ const.ADMIN_STATE_UP: True,
+ const.PROTOCOL: protocol,
+ const.PROTOCOL_PORT: 8080,
+ const.LOADBALANCER_ID: self.lb_id,
+ const.CONNECTION_LIMIT: 200,
+ }
+
+ self.assertRaises(
+ exceptions.Conflict,
+ self.mem_listener_client.create_listener,
+ **listener3_kwargs)
+
+ # Create a listener on the same port, with another protocol over TCP,
+ # only if layer-7 protocols are enabled
+ lb_feature_enabled = CONF.loadbalancer_feature_enabled
+ if lb_feature_enabled.l7_protocol_enabled:
+ if self.protocol == const.HTTP:
+ protocol = const.HTTPS
+ else:
+ protocol = const.HTTP
+
+ listener4_name = data_utils.rand_name("lb_member_listener4-create")
+
+ listener4_kwargs = {
+ const.NAME: listener4_name,
+ const.ADMIN_STATE_UP: True,
+ const.PROTOCOL: protocol,
+ const.PROTOCOL_PORT: 8080,
+ const.LOADBALANCER_ID: self.lb_id,
+ const.CONNECTION_LIMIT: 200,
+ }
+
+ self.assertRaises(
+ exceptions.Conflict,
+ self.mem_listener_client.create_listener,
+ **listener4_kwargs)
+
@decorators.idempotent_id('78ba6eb0-178c-477e-9156-b6775ca7b271')
def test_listener_list(self):
"""Tests listener list API and field filtering.
diff --git a/zuul.d/jobs.yaml b/zuul.d/jobs.yaml
index 0548cab..db2dd7e 100644
--- a/zuul.d/jobs.yaml
+++ b/zuul.d/jobs.yaml
@@ -84,6 +84,58 @@
octavia: https://opendev.org/openstack/octavia.git
- job:
+ name: octavia-dsvm-base-ipv6-only
+ parent: devstack-tempest-ipv6
+ timeout: 7800
+ required-projects:
+ - openstack/octavia
+ - openstack/octavia-lib
+ - openstack/octavia-tempest-plugin
+ - openstack/python-octaviaclient
+ pre-run: playbooks/Octavia-DSVM/pre.yaml
+ irrelevant-files:
+ - ^.*\.rst$
+ - ^api-ref/.*$
+ - ^doc/.*$
+ - ^etc/.*$
+ - ^releasenotes/.*$
+ vars:
+ devstack_localrc:
+ TEMPEST_PLUGINS: /opt/stack/octavia-tempest-plugin
+ USE_PYTHON3: true
+ devstack_local_conf:
+ post-config:
+ $OCTAVIA_CONF:
+ DEFAULT:
+ debug: True
+ devstack_services:
+ c-bak: false
+ ceilometer-acentral: false
+ ceilometer-acompute: false
+ ceilometer-alarm-evaluator: false
+ ceilometer-alarm-notifier: false
+ ceilometer-anotification: false
+ ceilometer-api: false
+ ceilometer-collector: false
+ c-sch: false
+ c-api: false
+ c-vol: false
+ cinder: false
+ octavia: true
+ o-api: true
+ o-cw: true
+ o-hm: true
+ o-hk: true
+ swift: false
+ s-account: false
+ s-container: false
+ s-object: false
+ s-proxy: false
+ tempest: true
+ devstack_plugins:
+ octavia: https://opendev.org/openstack/octavia.git
+
+- job:
name: octavia-dsvm-live-base
parent: octavia-dsvm-base
timeout: 9000
@@ -116,6 +168,38 @@
'/var/log/octavia-tenant-traffic.log': logs
- job:
+ name: octavia-dsvm-live-base-ipv6-only
+ parent: octavia-dsvm-base-ipv6-only
+ timeout: 9000
+ required-projects:
+ - openstack/diskimage-builder
+ vars:
+ devstack_localrc:
+ DIB_LOCAL_ELEMENTS: openstack-ci-mirrors
+ devstack_local_conf:
+ post-config:
+ $OCTAVIA_CONF:
+ haproxy_amphora:
+ # Set these higher for non-nested virt nodepool instances
+ connection_max_retries: 1200
+ build_active_retries: 300
+ amphora_agent:
+ forward_all_logs: True
+ test-config:
+ "$TEMPEST_CONFIG":
+ load_balancer:
+ check_interval: 1
+ check_timeout: 180
+ devstack_services:
+ neutron-qos: true
+ devstack_plugins:
+ neutron: https://opendev.org/openstack/neutron.git
+ zuul_copy_output:
+ '/var/log/dib-build' : logs
+ '/var/log/octavia-amphora.log': logs
+ '/var/log/octavia-tenant-traffic.log': logs
+
+- job:
name: octavia-dsvm-live-two-node-base
parent: octavia-dsvm-base
nodeset: octavia-two-node
@@ -349,6 +433,26 @@
- ^octavia_tempest_plugin/tests/(?!scenario/|\w+\.py).*
- job:
+ name: octavia-v2-dsvm-scenario-ipv6-only
+ parent: octavia-dsvm-live-base-ipv6-only
+ vars:
+ devstack_local_conf:
+ post-config:
+ $OCTAVIA_CONF:
+ api_settings:
+ api_v1_enabled: False
+ tempest_concurrency: 2
+ tempest_test_regex: ^octavia_tempest_plugin.tests.scenario.v2
+ tox_envlist: all
+ irrelevant-files:
+ - ^.*\.rst$
+ - ^api-ref/.*$
+ - ^doc/.*$
+ - ^etc/.*$
+ - ^releasenotes/.*$
+ - ^octavia_tempest_plugin/tests/(?!scenario/|\w+\.py).*
+
+- job:
name: octavia-v2-dsvm-py2-scenario
parent: octavia-v2-dsvm-scenario
vars:
@@ -603,6 +707,7 @@
load_balancer:
check_timeout: 180
loadbalancer_topology: 'ACTIVE_STANDBY'
+ amphora_ssh_key: '/tmp/octavia_ssh_key'
tempest_test_regex: ^octavia_tempest_plugin.tests.act_stdby_scenario.v2.test_active_standby_iptables
tox_envlist: all
diff --git a/zuul.d/projects.yaml b/zuul.d/projects.yaml
index 2edfbfe..6e27945 100644
--- a/zuul.d/projects.yaml
+++ b/zuul.d/projects.yaml
@@ -18,6 +18,8 @@
- octavia-v2-dsvm-scenario-stable-stein
- octavia-v2-dsvm-py2-scenario-stable-rocky
- octavia-v2-dsvm-py2-scenario-stable-queens
+ - octavia-v2-dsvm-scenario-ipv6-only:
+ voting: false
- octavia-v2-dsvm-scenario-centos-7:
voting: false
- octavia-v2-dsvm-scenario-ubuntu-bionic: