Add functional CI job and tests for segments
Added multi-node CI job to run functional tests. This patch adds functional tests to check the behaviour of Segment APIs. Co-Authored-By: jayashri bidwe <jayashri.bidwe@nttdata.com> Change-Id: I787b26b29fcd9556bc6b24b75ffe8e70e9f44610
This commit is contained in:
parent
da942db7a6
commit
0fa59ab7ed
78
.zuul.yaml
78
.zuul.yaml
|
@ -1,3 +1,77 @@
|
|||
- nodeset:
|
||||
name: masakari-openstack-multi-nodes
|
||||
nodes:
|
||||
- name: controller
|
||||
label: ubuntu-xenial
|
||||
- name: compute1
|
||||
label: ubuntu-xenial
|
||||
groups:
|
||||
# Nodes running the compute service
|
||||
- name: compute
|
||||
nodes:
|
||||
- controller
|
||||
- compute1
|
||||
# Nodes that are not the controller
|
||||
- name: subnode
|
||||
nodes:
|
||||
- compute1
|
||||
# Switch node for multinode networking setup
|
||||
- name: switch
|
||||
nodes:
|
||||
- controller
|
||||
# Peer nodes for multinode networking setup
|
||||
- name: peers
|
||||
nodes:
|
||||
- compute1
|
||||
|
||||
- job:
|
||||
name: masakari-functional-devstack-multinode
|
||||
parent: devstack
|
||||
description: |
|
||||
Base multinodes job for devstack-based functional tests
|
||||
nodeset: masakari-openstack-multi-nodes
|
||||
pre-run: playbooks/devstack/pre.yaml
|
||||
run: playbooks/devstack/run.yaml
|
||||
post-run: playbooks/devstack/post.yaml
|
||||
roles:
|
||||
- zuul: openstack-infra/devstack
|
||||
timeout: 9000
|
||||
required-projects:
|
||||
- openstack/horizon
|
||||
- openstack/python-masakariclient
|
||||
- openstack/masakari
|
||||
- openstack/masakari-monitors
|
||||
vars:
|
||||
test_matrix_configs: [neutron]
|
||||
devstack_services:
|
||||
horizon: false
|
||||
swift: false
|
||||
zuul_work_dir: src/git.openstack.org/openstack/masakari
|
||||
host-vars:
|
||||
controller:
|
||||
devstack_plugins:
|
||||
masakari: https://git.openstack.org/openstack/masakari
|
||||
devstack_services:
|
||||
horizon: false
|
||||
swift: false
|
||||
q-svc: true
|
||||
tox_install_siblings: false
|
||||
tox_envlist: functional
|
||||
group-vars:
|
||||
subnode:
|
||||
devstack_services:
|
||||
q-agt: true
|
||||
n-api: false
|
||||
n-api-meta: false
|
||||
n-cauth: false
|
||||
n-cond: false
|
||||
n-cpu: true
|
||||
n-novnc: false
|
||||
n-sch: false
|
||||
horizon: false
|
||||
tls-proxy: false
|
||||
|
||||
|
||||
- project:
|
||||
templates:
|
||||
- check-requirements
|
||||
|
@ -8,6 +82,10 @@
|
|||
- openstack-python36-jobs
|
||||
- publish-openstack-docs-pti
|
||||
- release-notes-jobs-python3
|
||||
check:
|
||||
jobs:
|
||||
- masakari-functional-devstack-multinode:
|
||||
voting: True
|
||||
|
||||
- project:
|
||||
masakari-systemfault-integration-ci:
|
||||
|
|
|
@ -0,0 +1,62 @@
|
|||
# Copyright (C) 2019 NTT DATA
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import logging
|
||||
import os
|
||||
import sys
|
||||
|
||||
from openstack.cloud.openstackcloud import _OpenStackCloudMixin
|
||||
import openstack.config
|
||||
from openstack import connection
|
||||
|
||||
from masakari.tests import base
|
||||
|
||||
|
||||
#: Defines the OpenStack Client Config (OCC) cloud key in your OCC config
|
||||
#: file, typically in /etc/openstack/clouds.yaml. That configuration
|
||||
#: will determine where the functional tests will be run and what resource
|
||||
#: defaults will be used to run the functional tests.
|
||||
TEST_CLOUD_NAME = os.getenv('OS_CLOUD', 'devstack-admin')
|
||||
TEST_CLOUD_REGION = openstack.config.get_cloud_region(cloud=TEST_CLOUD_NAME)
|
||||
|
||||
|
||||
class BaseFunctionalTest(base.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(BaseFunctionalTest, self).setUp()
|
||||
_log_stream = sys.stdout
|
||||
|
||||
handler = logging.StreamHandler(_log_stream)
|
||||
formatter = logging.Formatter('%(asctime)s %(name)-32s %(message)s')
|
||||
handler.setFormatter(formatter)
|
||||
|
||||
logger = logging.getLogger('openstack')
|
||||
logger.setLevel(logging.DEBUG)
|
||||
logger.addHandler(handler)
|
||||
|
||||
# Enable HTTP level tracing
|
||||
logger = logging.getLogger('keystoneauth')
|
||||
logger.setLevel(logging.DEBUG)
|
||||
logger.addHandler(handler)
|
||||
logger.propagate = False
|
||||
|
||||
self.conn = connection.Connection(config=TEST_CLOUD_REGION)
|
||||
|
||||
self.hypervisors = self._hypervisors()
|
||||
|
||||
def _hypervisors(self):
|
||||
hypervisors = _OpenStackCloudMixin.list_hypervisors(
|
||||
connection.from_config(cloud_name=TEST_CLOUD_NAME))
|
||||
return hypervisors
|
|
@ -0,0 +1,152 @@
|
|||
# Copyright (C) 2019 NTT DATA
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from openstack import exceptions
|
||||
|
||||
from masakari.objects import fields
|
||||
from masakari.tests.functional import base
|
||||
|
||||
|
||||
class TestSegments(base.BaseFunctionalTest):
|
||||
def test_create_get_delete(self):
|
||||
# This test will create, get and delete a segment
|
||||
segment_data = {'name': self.getUniqueString(),
|
||||
'recovery_method': fields.FailoverSegmentRecoveryMethod.AUTO,
|
||||
'service_type': 'COMPUTE'}
|
||||
segment = self.conn.ha.create_segment(**segment_data)
|
||||
|
||||
self.assertDictContainsSubset(segment_data, segment)
|
||||
|
||||
result = self.conn.ha.get_segment(segment.uuid)
|
||||
|
||||
self.assertEqual(segment.name, result.name)
|
||||
self.assertEqual(segment.recovery_method, result.recovery_method)
|
||||
self.assertEqual(segment.service_type, result.service_type)
|
||||
|
||||
self.conn.ha.delete_segment(segment.uuid)
|
||||
self.assertRaises(exceptions.ResourceNotFound,
|
||||
self.conn.ha.get_segment, segment.uuid)
|
||||
|
||||
def test_create_delete_with_host(self):
|
||||
# This test is for deleting a segment with hosts
|
||||
if not self.hypervisors:
|
||||
self.skipTest("Skipped as there are no hypervisors "
|
||||
"configured in nova")
|
||||
|
||||
segment = self.conn.ha.create_segment(
|
||||
name=self.getUniqueString(),
|
||||
recovery_method=fields.FailoverSegmentRecoveryMethod.AUTO,
|
||||
service_type='COMPUTE')
|
||||
|
||||
# Create valid host
|
||||
host_name = self.hypervisors[0]['hypervisor_hostname']
|
||||
|
||||
host = self.conn.ha.create_host(segment_id=segment.uuid,
|
||||
name=host_name,
|
||||
type='COMPUTE',
|
||||
control_attributes='SSH')
|
||||
|
||||
result = self.conn.ha.get_segment(segment.uuid)
|
||||
self.assertEqual(segment.name, result.name)
|
||||
|
||||
# Delete segment, which should delete hosts as well
|
||||
self.conn.ha.delete_segment(segment['uuid'])
|
||||
self.assertRaises(exceptions.ResourceNotFound,
|
||||
self.conn.ha.get_segment, segment.uuid)
|
||||
self.assertRaises(exceptions.ResourceNotFound,
|
||||
self.conn.ha.get_host, host.uuid, segment.uuid)
|
||||
|
||||
def test_list(self):
|
||||
# This test is for listing segments using filters
|
||||
segment_data_1 = {'name': self.getUniqueString(),
|
||||
'recovery_method': fields.FailoverSegmentRecoveryMethod.AUTO,
|
||||
'service_type': 'COMPUTE'}
|
||||
|
||||
segment_data_2 = {'name': self.getUniqueString(),
|
||||
'recovery_method':
|
||||
fields.FailoverSegmentRecoveryMethod.RESERVED_HOST,
|
||||
'service_type': 'COMPUTE'}
|
||||
|
||||
# Create segments
|
||||
segment_1 = self.conn.ha.create_segment(**segment_data_1)
|
||||
segment_2 = self.conn.ha.create_segment(**segment_data_2)
|
||||
|
||||
# Delete segments
|
||||
self.addCleanup(self.conn.ha.delete_segment, segment_1.uuid)
|
||||
self.addCleanup(self.conn.ha.delete_segment, segment_2.uuid)
|
||||
|
||||
segments = self.conn.ha.segments()
|
||||
self.assertItemsEqual([segment_1, segment_2], segments)
|
||||
|
||||
def test_list_with_filter(self):
|
||||
# This test is for listing segments using filters
|
||||
segment_data_1 = {'name': self.getUniqueString(),
|
||||
'recovery_method': fields.FailoverSegmentRecoveryMethod.AUTO,
|
||||
'service_type': 'COMPUTE'}
|
||||
|
||||
segment_data_2 = {'name': self.getUniqueString(),
|
||||
'recovery_method':
|
||||
fields.FailoverSegmentRecoveryMethod.RESERVED_HOST,
|
||||
'service_type': 'COMPUTE'}
|
||||
|
||||
# Create segments
|
||||
segment_1 = self.conn.ha.create_segment(**segment_data_1)
|
||||
segment_2 = self.conn.ha.create_segment(**segment_data_2)
|
||||
|
||||
# Delete segments
|
||||
self.addCleanup(self.conn.ha.delete_segment, segment_1.uuid)
|
||||
self.addCleanup(self.conn.ha.delete_segment, segment_2.uuid)
|
||||
|
||||
for seg_object in self.conn.ha.segments(
|
||||
recovery_method=fields.FailoverSegmentRecoveryMethod.AUTO):
|
||||
|
||||
self.assertDictContainsSubset(segment_data_1, seg_object)
|
||||
|
||||
for seg_object in self.conn.ha.segments(
|
||||
recovery_method=fields.FailoverSegmentRecoveryMethod.
|
||||
RESERVED_HOST):
|
||||
|
||||
self.assertDictContainsSubset(segment_data_2, seg_object)
|
||||
|
||||
def test_update_with_host(self):
|
||||
# This test is for updating segment with host
|
||||
if not self.hypervisors:
|
||||
self.skipTest("Skipped as there are no hypervisors "
|
||||
"configured in nova")
|
||||
|
||||
segment = self.conn.ha.create_segment(
|
||||
name=self.getUniqueString(),
|
||||
recovery_method=fields.FailoverSegmentRecoveryMethod.AUTO,
|
||||
service_type='COMPUTE')
|
||||
|
||||
# Delete segment
|
||||
self.addCleanup(self.conn.ha.delete_segment, segment.uuid)
|
||||
|
||||
# Create valid host
|
||||
host_name = self.hypervisors[0]['hypervisor_hostname']
|
||||
|
||||
self.conn.ha.create_host(segment_id=segment.uuid, name=host_name,
|
||||
type='COMPUTE', control_attributes='SSH')
|
||||
|
||||
# Update segment
|
||||
segment_1 = self.conn.ha.update_segment(segment.uuid,
|
||||
name=self.getUniqueString(),
|
||||
recovery_method=fields.FailoverSegmentRecoveryMethod.RESERVED_HOST,
|
||||
service_type='CONTROLLER')
|
||||
|
||||
result = self.conn.ha.get_segment(segment.uuid)
|
||||
self.assertEqual(segment_1.name, result.name)
|
||||
self.assertEqual(segment_1.recovery_method, result.recovery_method)
|
||||
self.assertEqual(segment_1.service_type, result.service_type)
|
|
@ -0,0 +1,4 @@
|
|||
- hosts: all
|
||||
roles:
|
||||
- fetch-subunit-output
|
||||
- devstack-config
|
|
@ -0,0 +1,7 @@
|
|||
- hosts: all
|
||||
roles:
|
||||
- orchestrate-devstack
|
||||
- role: bindep
|
||||
bindep_profile: test
|
||||
bindep_dir: "{{ zuul_work_dir }}"
|
||||
- ensure-tox
|
|
@ -0,0 +1,3 @@
|
|||
- hosts: controller
|
||||
roles:
|
||||
- tox
|
|
@ -0,0 +1,13 @@
|
|||
- name: Collect devstack stackenv file
|
||||
fetch:
|
||||
flat: yes
|
||||
dest: "{{ zuul.executor.log_root }}/{{ inventory_hostname }}/confs/devstack/-stackenv"
|
||||
src: "/opt/stack/devstack/.stackenv"
|
||||
|
||||
- name: Collect devstack config files
|
||||
synchronize:
|
||||
dest: "{{ zuul.executor.log_root }}/{{ inventory_hostname }}/confs/devstack/"
|
||||
mode: pull
|
||||
src: "/opt/stack/devstack/{{ item }}"
|
||||
with_items:
|
||||
- local.conf
|
6
tox.ini
6
tox.ini
|
@ -39,6 +39,12 @@ commands =
|
|||
{[testenv]commands}
|
||||
stestr run {posargs}
|
||||
|
||||
[testenv:functional]
|
||||
basepython = python3
|
||||
commands =
|
||||
{[testenv]commands}
|
||||
stestr --test-path=./masakari/tests/functional run --concurrency=1 --slowest {posargs}
|
||||
|
||||
[testenv:genconfig]
|
||||
basepython = python3
|
||||
commands = oslo-config-generator --config-file=etc/masakari/masakari-config-generator.conf
|
||||
|
|
Loading…
Reference in New Issue