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:
tpatil 2019-01-29 16:04:22 +09:00 committed by jayashri bidwe
parent da942db7a6
commit 0fa59ab7ed
9 changed files with 325 additions and 0 deletions

View File

@ -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:

View File

View File

@ -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

View File

@ -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)

View File

@ -0,0 +1,4 @@
- hosts: all
roles:
- fetch-subunit-output
- devstack-config

View File

@ -0,0 +1,7 @@
- hosts: all
roles:
- orchestrate-devstack
- role: bindep
bindep_profile: test
bindep_dir: "{{ zuul_work_dir }}"
- ensure-tox

View File

@ -0,0 +1,3 @@
- hosts: controller
roles:
- tox

View File

@ -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

View File

@ -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