fuel-ostf/fuel_plugin/testing/tests/base.py

499 lines
14 KiB
Python

# -*- coding: utf-8 -*-
# Copyright 2013 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
# 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 requests_mock
from sqlalchemy import create_engine
from sqlalchemy import event
from sqlalchemy.orm import sessionmaker, scoped_session
import unittest2
import webtest
from fuel_plugin.ostf_adapter import config
from fuel_plugin.ostf_adapter import mixins
from fuel_plugin.ostf_adapter.nose_plugin import nose_discovery
from fuel_plugin.ostf_adapter.storage import models
from fuel_plugin.ostf_adapter.wsgi import app
TEST_PATH = 'fuel_plugin/testing/fixture/dummy_tests'
CLUSTERS = {
1: {
'cluster_meta': {
'release_id': 1,
'mode': 'ha'
},
'release_data': {
'operating_system': 'rhel',
'version': '2015.2-1.0',
},
'cluster_node': {
},
'cluster_attributes': {
'editable': {
'additional_components': {},
'common': {}
}
}
},
2: {
'cluster_meta': {
'release_id': 2,
'mode': 'multinode',
},
'release_data': {
'operating_system': 'ubuntu',
'version': '2015.2-1.0',
},
'cluster_node': {
},
'cluster_attributes': {
'editable': {
'additional_components': {},
'common': {}
}
}
},
3: {
'cluster_meta': {
'release_id': 3,
'mode': 'ha'
},
'release_data': {
'operating_system': 'rhel',
'version': '2015.2-1.0',
},
'cluster_node': {
},
'cluster_attributes': {
'editable': {
'additional_components': {
'murano': {
'value': True
},
'sahara': {
'value': False
}
},
'common': {}
}
}
},
4: {
'cluster_meta': {
'release_id': 4,
'mode': 'test_error'
},
'release_data': {
'operating_system': 'none',
'version': '2015.2-1.0',
},
'cluster_node': {
},
'cluster_attributes': {
'editable': {
'additional_components': {},
'common': {}
}
}
},
5: {
'cluster_meta': {
'release_id': 5,
'mode': 'dependent_tests'
},
'release_data': {
'operating_system': 'none',
'version': '2015.2-1.0',
},
'cluster_node': {
},
'cluster_attributes': {
'editable': {
'additional_components': {},
'common': {}
}
}
},
6: {
'cluster_meta': {
'release_id': 6,
'mode': 'releases_comparison'
},
'release_data': {
'operating_system': '',
'version': '2015.2-6.0',
},
'cluster_node': {
},
'cluster_attributes': {
'editable': {
'additional_components': {},
'common': {}
}
}
},
7: {
'cluster_meta': {
'release_id': 7,
'mode': 'ha'
},
'release_data': {
'operating_system': 'rhel',
'version': '2015.2-1.0',
},
'cluster_node': [
{
"hostname": "node-1",
'id': "1",
'roles': "compute"
},
],
'node_interfaces': [
{
'interface_properties': {
'sriov': {
'enabled': 'true'
}
}
}
],
'cluster_attributes': {
'editable': {
'additional_components': {
'murano': {
'value': True
},
'sahara': {
'value': False
}
},
'common': {}
}
}
},
8: {
'cluster_meta': {
'release_id': 8,
'mode': 'ha',
'net_provider': 'neutron'
},
'release_data': {
'operating_system': 'rhel',
'version': '2015.2-1.0',
},
'cluster_node': [
{
"hostname": "node-1",
'id': "1",
'roles': "compute"
},
{
"hostname": "node-2",
'id': "2",
'roles': "compute"
},
],
'node-1_interfaces': [
{
'interface_properties': {
'dpdk': {
'enabled': 'true'
}
}
},
],
'node-2_interfaces': [
{
'interface_properties': {
'dpdk': {
'available': 'false'
}
}
},
],
'cluster_attributes': {
'editable': {
'additional_components': {},
'common': {}
}
}
},
9: {
'cluster_meta': {
'release_id': 9,
'mode': 'multinode'
},
'release_data': {
'operating_system': 'ubuntu',
'version': '2016.1-9.0'
},
'cluster_node': {
},
'cluster_attributes': {
'editable': {
'detach-murano': {
'metadata': {
'enabled': True,
'versions': [
{
'murano_glance_artifacts': {
"value": True
}
}
]
}
},
'additional_components': {},
'common': {}
}
}
},
10: {
'cluster_meta': {
'release_id': 10,
'mode': 'multinode'
},
'release_data': {
'operating_system': 'ubuntu',
'version': '2016.1-9.0'
},
'cluster_node': {
},
'cluster_attributes': {
'editable': {
'detach-murano': {
'metadata': {
'enabled': True,
'versions': [
{
'murano_glance_artifacts': {
"value": False
}
}
]
}
},
'additional_components': {},
'common': {}
}
}
},
11: {
'cluster_meta': {
'release_id': 11,
'mode': 'multinode'
},
'release_data': {
'operating_system': 'ubuntu',
'version': '2016.1-9.0'
},
'cluster_node': {
},
'cluster_attributes': {
'editable': {
'additional_components': {
'murano': {
'value': True
}
},
'murano_settings': {
'murano_glance_artifacts_plugin': {
'value': True
}
},
'common': {}
}
}
},
12: {
'cluster_meta': {
'release_id': 12,
'mode': 'multinode'
},
'release_data': {
'operating_system': 'ubuntu',
'version': '2016.1-9.0'
},
'cluster_node': {
},
'cluster_attributes': {
'editable': {
'additional_components': {
'murano': {
'value': True
}
},
'murano_settings': {
'murano_glance_artifacts_plugin': {
'value': False
}
},
'common': {}
}
}
},
}
class BaseUnitTest(unittest2.TestCase):
"""Base class for all unit tests."""
class BaseIntegrationTest(BaseUnitTest):
"""Base class for all integration tests."""
@classmethod
def setUpClass(cls):
config.init_config([])
# db connection
cls.dbpath = config.cfg.CONF.adapter.dbpath
cls.engine = create_engine(cls.dbpath)
# mock http requests
cls.requests_mock = requests_mock.Mocker()
cls.requests_mock.start()
@classmethod
def tearDownClass(cls):
# stop https requests mocking
cls.requests_mock.stop()
def setUp(self):
self.connection = self.engine.connect()
self.trans = self.connection.begin()
self.session = scoped_session(sessionmaker())
self.session.configure(bind=self.connection)
# supprot tests with rollbacks
# start the session in a SAVEPOINT...
self.session.begin_nested()
# # then each time that SAVEPOINT ends, reopen it
@event.listens_for(self.session, "after_transaction_end")
def restart_savepoint(session, transaction):
if transaction.nested and not transaction._parent.nested:
session.begin_nested()
def discovery(self):
"""Discover dummy tests used for testsing."""
mixins.TEST_REPOSITORY = []
nose_discovery.discovery(path=TEST_PATH, session=self.session)
mixins.cache_test_repository(self.session)
self.session.flush()
def tearDown(self):
# rollback changes to database
# made by tests
self.trans.rollback()
self.session.close()
self.connection.close()
def mock_api_for_cluster(self, cluster_id):
"""Mock requests to Nailgun to mimic behavior of
Nailgun's API
"""
cluster = CLUSTERS[cluster_id]
release_id = cluster['cluster_meta']['release_id']
self.requests_mock.register_uri(
'GET',
'/api/clusters/{0}'.format(cluster_id),
json=cluster['cluster_meta'])
self.requests_mock.register_uri(
'GET',
'/api/releases/{0}'.format(release_id),
json=cluster['release_data'])
self.requests_mock.register_uri(
'GET',
'/api/nodes?cluster_id={0}'.format(cluster_id),
json=cluster['cluster_node'])
self.requests_mock.register_uri(
'GET',
'/api/clusters/{0}/attributes'.format(cluster_id),
json=cluster['cluster_attributes'])
class BaseWSGITest(BaseIntegrationTest):
def setUp(self):
super(BaseWSGITest, self).setUp()
self.ext_id = 'fuel_plugin.testing.fixture.dummy_tests.'
self.expected = {
'cluster': {
'id': 1,
'deployment_tags': set(['ha', 'rhel', 'nova_network',
'public_on_all_nodes',
'enable_without_ceph'])
},
'test_sets': ['general_test',
'stopped_test', 'ha_deployment_test',
'environment_variables'],
'tests': [self.ext_id + test for test in [
('deployment_types_tests.ha_deployment_test.'
'HATest.test_ha_depl'),
('deployment_types_tests.ha_deployment_test.'
'HATest.test_ha_rhel_depl'),
'general_test.Dummy_test.test_fast_pass',
'general_test.Dummy_test.test_long_pass',
'general_test.Dummy_test.test_fast_fail',
'general_test.Dummy_test.test_fast_error',
'general_test.Dummy_test.test_fail_with_step',
'general_test.Dummy_test.test_skip',
'general_test.Dummy_test.test_skip_directly',
'stopped_test.dummy_tests_stopped.test_really_long',
'stopped_test.dummy_tests_stopped.test_one_no_so_long',
'stopped_test.dummy_tests_stopped.test_not_long_at_all',
('test_environment_variables.TestEnvVariables.'
'test_os_credentials_env_variables')
]]
}
self.discovery()
self.app = webtest.TestApp(app.setup_app(session=self.session))
def is_background_working(self):
is_working = True
cluster_state = self.session.query(models.ClusterState)\
.filter_by(id=self.expected['cluster']['id'])\
.one()
is_working = is_working and set(cluster_state.deployment_tags) == \
self.expected['cluster']['deployment_tags']
cluster_testing_patterns = self.session\
.query(models.ClusterTestingPattern)\
.filter_by(cluster_id=self.expected['cluster']['id'])\
.all()
for testing_pattern in cluster_testing_patterns:
is_working = is_working and \
(testing_pattern.test_set_id in self.expected['test_sets'])
is_working = is_working and set(testing_pattern.tests)\
.issubset(set(self.expected['tests']))
return is_working