Change-Id: I3acd923c1de5af80ce83d2c60272bf50cca733fachanges/91/716591/1
@@ -10,15 +10,21 @@ | |||
jobs: | |||
- openstack-tox-linters | |||
- openstack-tox-pep8 | |||
- fault-tox-pylint | |||
- stx-fault-build | |||
- fault-rest-api-py27 | |||
- fault-rest-api-py35 | |||
- fault-rest-api-py36 | |||
gate: | |||
jobs: | |||
- openstack-tox-linters | |||
- openstack-tox-pep8 | |||
- fault-tox-pylint | |||
- fault-rest-api-py27 | |||
- fault-rest-api-py35 | |||
- fault-rest-api-py36 | |||
post: | |||
jobs: | |||
- stx-fault-upload-git-mirror | |||
# Perform just a build | |||
- job: | |||
@@ -58,7 +64,7 @@ | |||
parent: tox | |||
description: | | |||
Run py27 test for fm-rest-api | |||
nodeset: ubuntu-xenial | |||
nodeset: ubuntu-bionic | |||
required-projects: | |||
- starlingx/config | |||
vars: | |||
@@ -66,13 +72,115 @@ | |||
tox_extra_args: -c fm-rest-api/fm/tox.ini | |||
- job: | |||
name: fault-rest-api-py35 | |||
name: fault-rest-api-py36 | |||
parent: tox | |||
description: | | |||
Run py35 test for fm-rest-api | |||
nodeset: ubuntu-xenial | |||
Run py36 test for fm-rest-api | |||
nodeset: ubuntu-bionic | |||
required-projects: | |||
- starlingx/config | |||
vars: | |||
tox_envlist: py35 | |||
tox_envlist: py36 | |||
tox_extra_args: -c fm-rest-api/fm/tox.ini | |||
- job: | |||
name: fault-tox-pylint | |||
parent: tox | |||
description: | | |||
Run pylint for python files in fault | |||
required-projects: | |||
- starlingx/config | |||
vars: | |||
tox_envlist: pylint | |||
- job: | |||
name: stx-fault-upload-git-mirror | |||
parent: upload-git-mirror | |||
description: > | |||
Mirrors opendev.org/starlingx/fault to | |||
github.com/starlingx/fault | |||
vars: | |||
git_mirror_repository: starlingx/fault | |||
secrets: | |||
- name: git_mirror_credentials | |||
secret: stx-fault-github-secret | |||
pass-to-parent: true | |||
- secret: | |||
name: stx-fault-github-secret | |||
data: | |||
user: git | |||
host: github.com | |||
# yamllint disable-line rule:line-length | |||
host_key: github.com ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSwBK6TbQa+PXYPCPy6rbTrTtw7PHkccKrpp0yVhp5HdEIcKr6pLlVDBfOLX9QUsyCOV0wzfjIJNlGEYsdlLJizHhbn2mUjvSAHQqZETYP81eFzLQNnPHt4EVVUh7VfDESU84KezmD5QlWpXLmvU31/yMf+Se8xhHTvKSCZIFImWwoG6mbUoWf9nzpIoaSjB+weqqUUmpaaasXVal72J+UX2B+2RPW3RcT0eOzQgqlJL3RKrTJvdsjE3JEAvGq3lGHSZXy28G3skua2SmVi/w4yCE6gbODqnTWlg7+wC604ydGXA8VJiS5ap43JXiUFFAaQ== | |||
ssh_key: !encrypted/pkcs1-oaep | |||
- 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
- Vn+jIi5misXkSialmw7ZnW1VZyXklJhFDIq8fNUFJ2Pg4g+U9PSKyfbnWC6p2g2QHOMqH | |||
R0YB2hZ4z+/6WM+9w+aoLtxCImK2YdpM6fUJg5G421jSjrn9dAOKlbWcXtBOosU9qSfgg | |||
MoyvLm9DeGskkw/lWjuMPXxHp6avAXGmbpBTdk3n08YYDokXpf6t/RPiUiOTiVPsOr8bg | |||
A5a/DZSGKjgD0CqIBG6TkSSxag9hDrnIFkeiHFNtBRqzTF0NrL+lpzQfwAIeG6XOO+izr | |||
glADi329f5UID0MIDeWb1Z8jpy1znUlUFRgWypjleriT2agltrzf9VFqr/5u0gXGEZqOP | |||
WjmZ/EGVsrRm06SGMVWGVKn+JU1Hwg+GQ+GOJSKmw1y9x1h4ujGR4+IS4PPxp2zL/OpyH | |||
LBknqQSxYhEb4KdfaJJPDPGDUy522E4MyN0rt0U53WEWEY1R/32Dy9EILVBqtWa5cBkXl | |||
smBVQOE1ZiaY86X1MZ8C89Z84CrexWVVbIIL8r2iQoes/gTFccirxhCztliMl2cm2zVjB | |||
pq9xWu9+QrziIZT+9VT1ex1sdNfbzEIeAKUMEg7w34idKA+xORQYNAld2Z1IB6yFqF4I/ | |||
AQLi1ZXgxv8W2bs6wqrj15qk9Ai12Az8ArTmHh/sN6/+7A3bAcg9MvrkYRyWSk= | |||
- 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
- FukgOmzzUwijQiOOmW7TGzOb3SLSQNS07PH/XBHlSrgwElvuQpZGx6UGG2JkXYuvKLWsK | |||
ER5ZWd0WqFW9PsgVPUE0Bt09TDlq6nfGHsAvoPpsELEFVjvQwnUJhI5AAALxDYxg4sBv8 | |||
S2nLJDtidiccESkLDtpUl/kY3al1cP/K8mtCv/mmAm/fKsiyoqxHgmKW13pTq1p9tZVtm | |||
SDnQAkq2LM9v88YSwJlmSG1amqk89NOYnQbe16bTlBXzhYgD3Mz5i2+9zTsITmN2X7cd6 | |||
NG8smgFqlBQ0+AsyBRnHniKjxNmB2esdMKE7RIHaeuA8lx6SY6nvj1wrsjre94WzNsvg8 | |||
i7XAXEJ7YjQo/AcaVNnzJA6TxAs8yFOY/0siR3T8qgqhhCGxNEeYrXplM7CHPgyBDN1Qq | |||
rsy0LI5da16tPvhwsBinhTAtAAsPpMjMrDZDCIXHiNytuXMQkyPuMyaMETc6+im6eHru2 | |||
fB/h5QSiQ6oodhw2YlXoomwOr5G8xu7Ao3KfI5+1wGolSpX4cVRW4p+NtJwbB0UToDObV | |||
QT8nKnUqnFHuMKTxHovP4mFSN10VkQlKLAPKiT8L6O5CHlppuiyV9v5PwqgjxmOtIyIXt | |||
qLCYby9T/D6gBeD9lUTZdXzAYj9F3dQyp0mto7q1LeQRH+BiAEkw3HrtXIg1t4= | |||
- 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
- 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
- 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 |
@@ -13,7 +13,7 @@ | |||
import copy | |||
from . import constants | |||
import six | |||
import fm_core | |||
import fm_core # pylint: disable=import-error | |||
import threading | |||
fm_api_lock = threading.Lock() | |||
@@ -0,0 +1,8 @@ | |||
[run] | |||
branch = True | |||
source = fm | |||
omit = fm/tests/* | |||
[report] | |||
ignore_errors = True | |||
@@ -0,0 +1,14 @@ | |||
# Copyright 2020 Intel Corporation. | |||
# 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. |
@@ -0,0 +1,79 @@ | |||
# Copyright 2020 Intel Corporation. | |||
# 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. | |||
"""Base classes for API tests.""" | |||
from oslo_config import cfg | |||
import pecan | |||
import pecan.testing | |||
from fm.tests import base | |||
from fm.common import context as fm_context | |||
PATH_PREFIX = '/v1' | |||
class FunctionalTest(base.TestCase): | |||
"""Used for functional tests of Pecan controllers where you need to | |||
test your literal application and its integration with the | |||
framework. | |||
""" | |||
SOURCE_DATA = {'test_source': {'somekey': '666'}} | |||
def setUp(self): | |||
super(FunctionalTest, self).setUp() | |||
self.context = fm_context.RequestContext(is_admin=True) | |||
self.app = self._make_app() | |||
def _make_app(self): | |||
cfg.CONF.set_override("debug", True) | |||
self.config = { | |||
'app': { | |||
'root': 'fm.api.controllers.root.RootController', | |||
'modules': ['fm.api'], | |||
'acl_public_routes': ['/', '/v1'], | |||
}, | |||
} | |||
return pecan.testing.load_test_app(self.config) | |||
def tearDown(self): | |||
super(FunctionalTest, self).tearDown() | |||
pecan.set_config({}, overwrite=True) | |||
def get_json(self, path, expect_errors=False, headers=None, | |||
extra_environ=None, q=[], path_prefix=PATH_PREFIX, **params): | |||
full_path = path_prefix + path | |||
query_params = {'q.field': [], | |||
'q.value': [], | |||
'q.op': [], | |||
} | |||
for query in q: | |||
for name in ['field', 'op', 'value']: | |||
query_params['q.%s' % name].append(query.get(name, '')) | |||
all_params = {} | |||
all_params.update(params) | |||
if q: | |||
all_params.update(query_params) | |||
response = self.app.get(full_path, | |||
params=all_params, | |||
headers=headers, | |||
extra_environ=extra_environ, | |||
expect_errors=expect_errors) | |||
if not expect_errors: | |||
response = response.json | |||
return response |
@@ -0,0 +1,30 @@ | |||
# Copyright 2020 Intel Corporation. | |||
# 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 fm.tests.api import base | |||
class TestBase(base.FunctionalTest): | |||
def test_api_setup(self): | |||
pass | |||
def test_bad_uri(self): | |||
response = self.get_json('/bad/path', | |||
expect_errors=True, | |||
headers={"Accept": "application/json"}) | |||
self.assertEqual(response.status_int, 404) | |||
self.assertEqual(response.content_type, "application/json") | |||
self.assertTrue(response.json['error_message']) |
@@ -0,0 +1,40 @@ | |||
# Copyright 2013 Red Hat, Inc. | |||
# 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. | |||
# | |||
# Copyright 2020 Intel Corporation. | |||
# | |||
from fm.tests.api import base | |||
class TestRoot(base.FunctionalTest): | |||
def test_get_root(self): | |||
data = self.get_json('/', path_prefix='') | |||
self.assertEqual(data['default_version']['id'], 'v1') | |||
# Check fields are not empty | |||
[self.assertNotIn(f, ['', []]) for f in data.keys()] | |||
class TestV1Root(base.FunctionalTest): | |||
def test_get_v1_root(self): | |||
data = self.get_json('/') | |||
self.assertEqual(data['id'], 'v1') | |||
# Check fields are not empty | |||
[self.assertNotIn(f, ['', []]) for f in data.keys()] | |||
# Check if the resources are present | |||
self.assertIn({'type': 'application/vnd.openstack.fm.v1+json', | |||
'base': 'application/json'}, data['media_types']) |
@@ -19,13 +19,24 @@ Allows overriding of config for use of fakes, and some black magic for | |||
inline callbacks. | |||
""" | |||
import sys | |||
import os | |||
import fixtures | |||
import mock | |||
import testtools | |||
from oslo_config import cfg | |||
from oslo_db.sqlalchemy import enginefacade | |||
from oslo_log import log as logging | |||
from fm.db import migration | |||
from fm.tests import conf_fixture | |||
CONF = cfg.CONF | |||
_DB_CACHE = None | |||
sys.modules['fm_core'] = mock.Mock() | |||
class TestCase(testtools.TestCase): | |||
@@ -35,12 +46,44 @@ class TestCase(testtools.TestCase): | |||
"""Run before each test method to initialize test environment.""" | |||
super(TestCase, self).setUp() | |||
test_timeout = os.environ.get('OS_TEST_TIMEOUT', 0) | |||
try: | |||
test_timeout = int(test_timeout) | |||
except ValueError: | |||
# If timeout value is invalid do not set a timeout. | |||
test_timeout = 0 | |||
if test_timeout > 0: | |||
self.useFixture(fixtures.Timeout(test_timeout, gentle=True)) | |||
self.useFixture(fixtures.NestedTempfile()) | |||
self.useFixture(fixtures.TempHomeDir()) | |||
if (os.environ.get('OS_STDOUT_CAPTURE') == 'True' or | |||
os.environ.get('OS_STDOUT_CAPTURE') == '1'): | |||
stdout = self.useFixture(fixtures.StringStream('stdout')).stream | |||
self.useFixture(fixtures.MonkeyPatch('sys.stdout', stdout)) | |||
if (os.environ.get('OS_STDERR_CAPTURE') == 'True' or | |||
os.environ.get('OS_STDERR_CAPTURE') == '1'): | |||
stderr = self.useFixture(fixtures.StringStream('stderr')).stream | |||
self.useFixture(fixtures.MonkeyPatch('sys.stderr', stderr)) | |||
self.log_fixture = self.useFixture(fixtures.FakeLogger()) | |||
def fake_logging_setup(*args): | |||
pass | |||
self.useFixture( | |||
fixtures.MonkeyPatch('oslo_log.log.setup', fake_logging_setup)) | |||
logging.register_options(CONF) | |||
self.useFixture(conf_fixture.ConfFixture(CONF)) | |||
global _DB_CACHE | |||
if not _DB_CACHE: | |||
engine = enginefacade.get_legacy_facade().get_engine() | |||
engine.dispose() | |||
engine.connect() | |||
migration.db_sync(engine=engine) | |||
def tearDown(self): | |||
super(TestCase, self).tearDown() |
@@ -0,0 +1,35 @@ | |||
# Copyright 2010 United States Government as represented by the | |||
# Administrator of the National Aeronautics and Space Administration. | |||
# 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. | |||
# | |||
# Copyright 2020 Intel Corporation. | |||
from oslo_config import cfg | |||
from oslo_config import fixture as config_fixture | |||
CONF = cfg.CONF | |||
class ConfFixture(config_fixture.Config): | |||
"""Fixture to manage global conf settings.""" | |||
def __init__(self, conf): | |||
self.conf = conf | |||
def setUp(self): | |||
super(ConfFixture, self).setUp() | |||
self.conf.set_default('connection', "sqlite://", group='database') | |||
self.addCleanup(self.conf.reset) |
@@ -0,0 +1,14 @@ | |||
# Copyright 2020 Intel Corporation. | |||
# 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. |
@@ -0,0 +1,32 @@ | |||
# Copyright 2020 Intel Corporation. | |||
# 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. | |||
"""Fault DB test base class.""" | |||
import abc | |||
import six | |||
from fm.common import context | |||
from fm.tests import base | |||
INIT_VERSION = 0 | |||
@six.add_metaclass(abc.ABCMeta) | |||
class DbTestCase(base.TestCase): | |||
def setUp(self): | |||
super(DbTestCase, self).setUp() | |||
self.admin_context = context.make_context(is_admin=True) |
@@ -0,0 +1,24 @@ | |||
# Copyright 2020 Intel Corporation. | |||
# | |||
# SPDX-License-Identifier: Apache-2.0 | |||
# | |||
"""Tests for Alarm via the DB API""" | |||
from fm.db import api as dbapi | |||
from fm.tests.db import base | |||
from fm.tests.db import utils | |||
class DbAlarmTestCase(base.DbTestCase): | |||
def setUp(self): | |||
super(DbAlarmTestCase, self).setUp() | |||
self.dbapi = dbapi.get_instance() | |||
def test_create_alarm(self): | |||
uuid = 1234567 | |||
alarm = utils.get_test_alarm(uuid=uuid) | |||
alarm_exist = self.dbapi.alarm_create(alarm) | |||
self.assertEqual(uuid, alarm_exist.uuid) |
@@ -0,0 +1,52 @@ | |||
# 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. | |||
# | |||
# Copyright 2020 Intel Corporation | |||
"""Fault test utilities.""" | |||
from fm.db import api as db_api | |||
from fm_api import constants | |||
def get_test_alarm(**kw): | |||
alarm = { | |||
'uuid': kw.get('uuid'), | |||
'alarm_id': kw.get('alarm_id', constants.FM_ALARM_ID_VM_FAILED), | |||
'alarm_state': kw.get('alarm_state', constants.FM_ALARM_STATE_SET), | |||
'entity_type_id': kw.get('entity_type_id', constants.FM_ENTITY_TYPE_INSTANCE), | |||
'entity_instance_id': kw.get('entity_instance_id', | |||
constants.FM_ENTITY_TYPE_INSTANCE + '=' + | |||
'a4e4cdb7-2ee6-4818-84c8-5310fcd67b5d'), | |||
'severity': kw.get('severity', constants.FM_ALARM_SEVERITY_CRITICAL), | |||
'reason_text': kw.get('reason_text', "Unknown"), | |||
'alarm_type': kw.get('alarm_type', constants.FM_ALARM_TYPE_5), | |||
'probable_cause': kw.get('probable_cause', constants.ALARM_PROBABLE_CAUSE_8), | |||
'proposed_repair_action': None, | |||
'service_affecting': False, | |||
'suppression': False | |||
} | |||
return alarm | |||
def create_test_alarm(**kw): | |||
"""Create test alarm entry in DB and return alarm DB object. | |||
Function to be used to create test alarm objects in the database. | |||
:param kw: kwargs with overriding values for alarm's attributes. | |||
:returns: Test alarm DB object. | |||
""" | |||
alarm = get_test_alarm(**kw) | |||
# Let DB generate ID if it isn't specified explicitly | |||
dbapi = db_api.get_instance() | |||
return dbapi.alarm_create(alarm) |
@@ -0,0 +1,29 @@ | |||
# Copyright 2020 Intel Corporation. | |||
# 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 fm.db import migration | |||
from fm.db.sqlalchemy import api as db_api | |||
from fm.tests.db import base | |||
class DbSyncTestCase(base.DbTestCase): | |||
def setUp(self): | |||
super(DbSyncTestCase, self).setUp() | |||
def test_sync_and_version(self): | |||
migration.db_sync() | |||
engine = db_api.get_engine() | |||
v = migration.get_backend().db_version(engine, migration.MIGRATE_REPO_PATH, None) | |||
self.assertTrue(v > base.INIT_VERSION) |
@@ -2,12 +2,24 @@ hacking!=0.13.0,<0.14,>=0.12.0 | |||
bashate >= 0.2 | |||
PyYAML >= 3.1.0 | |||
yamllint >= 0.5.2 | |||
stestr | |||
stestr != 3.0.0 | |||
testtools!=1.2.0,>=0.9.36 | |||
iso8601 | |||
stestr | |||
mock | |||
cython | |||
oslo.log | |||
oslo.concurrency | |||
oslo.i18n # Apache-2.0 | |||
oslo.config>=3.7.0 # Apache-2.0 | |||
oslo.concurrency>=3.7.1 # Apache-2.0 | |||
oslo.db>=4.1.0 # Apache-2.0 | |||
oslo.service>=1.10.0 # Apache-2.0 | |||
oslo.utils>=3.5.0 # Apache-2.0 | |||
oslo.serialization>=1.10.0,!=2.19.1 # Apache-2.0 | |||
oslo_policy | |||
oslo_versionedobjects | |||
python-keystoneclient>=3.8.0 # Apache-2.0 | |||
keystonemiddleware>=4.12.0 # Apache-2.0 | |||
pecan>=1.0.0 | |||
WSME>=0.5b2 | |||
httplib2 | |||
keyring <= 18.0.1 |
@@ -1,5 +1,5 @@ | |||
[tox] | |||
envlist = py27,py35 | |||
envlist = py27,py36 | |||
minversion = 2.3 | |||
skipsdist = True | |||
stxdir = {toxinidir}/../../../ | |||
@@ -12,6 +12,9 @@ setenv = VIRTUAL_ENV={envdir} | |||
OS_TEST_TIMEOUT=60 | |||
deps = -r{toxinidir}/test-requirements.txt | |||
-e{[tox]stxdir}/config/tsconfig/tsconfig | |||
-e{[tox]stxdir}/config/sysinv/cgts-client/cgts-client | |||
-e{[tox]stxdir}/fault/fm-api | |||
-e{[tox]stxdir}/fault/fm-rest-api/fm | |||
[testenv:venv] | |||
basepython = python3 | |||
@@ -23,12 +26,22 @@ commands = | |||
stestr run {posargs} | |||
stestr slowest | |||
[testenv:py35] | |||
basepython = python3.5 | |||
[testenv:py36] | |||
basepython = python3.6 | |||
commands = | |||
stestr run {posargs} | |||
stestr slowest | |||
[testenv:cover] | |||
deps = {[testenv]deps} | |||
coverage | |||
setenv = {[testenv]setenv} | |||
PYTHON=coverage run --parallel-mode | |||
commands = | |||
coverage erase | |||
stestr run {posargs} | |||
coverage combine | |||
coverage html -d cover | |||
coverage xml -o cover/coverage.xml | |||
coverage report |
@@ -0,0 +1,267 @@ | |||
[MASTER] | |||
# Specify a configuration file. | |||
rcfile=pylint.rc | |||
# Python code to execute, usually for sys.path manipulation such as | |||
# pygtk.require(). | |||
#init-hook= | |||
# Add files or directories to the blacklist. Should be base names, not paths. | |||
ignore= | |||
# Pickle collected data for later comparisons. | |||
persistent=yes | |||
# List of plugins (as comma separated values of python modules names) to load, | |||
# usually to register additional checkers. | |||
load-plugins= | |||
# Use multiple processes to speed up Pylint. | |||
jobs=4 | |||
# Allow loading of arbitrary C extensions. Extensions are imported into the | |||
# active Python interpreter and may run arbitrary code. | |||
unsafe-load-any-extension=no | |||
# A comma-separated list of package or module names from where C extensions may | |||
# be loaded. Extensions are loading into the active Python interpreter and may | |||
# run arbitrary code | |||
extension-pkg-whitelist=lxml.etree,greenlet | |||
[MESSAGES CONTROL] | |||
# Enable the message, report, category or checker with the given id(s). You can | |||
# either give multiple identifier separated by comma (,) or put this option | |||
# multiple time. | |||
#enable= | |||
# Disable the message, report, category or checker with the given id(s). You | |||
# can either give multiple identifier separated by comma (,) or put this option | |||
# multiple time (only on the command line, not in the configuration file where | |||
# it should appear only once). | |||
# See "Messages Control" section of | |||
# https://pylint.readthedocs.io/en/latest/user_guide | |||
# We are disabling (C)onvention | |||
# We are disabling (R)efactor | |||
# We are selectively disabling (W)arning | |||
# W0102 dangerous-default-value | |||
# W0106 expression-not-assigned | |||
# W0107 unnecessary-pass | |||
# W0110 deprecated-lambda | |||
# W0201 attribute-defined-outside-init | |||
# W0212 protected-access | |||
# W0221 arguments-differ | |||
# W0223 abstract-method | |||
# W0231 super-init-not-called | |||
# W0235 useless-super-delegation | |||
# W0311 bad-indentation | |||
# W0403 relative-import (this needs to be fixed in py3) | |||
# W0603 global-statement | |||
# W0612 unused-variable | |||
# W0613 unused-argument | |||
# W0621 redefined-outer-name | |||
# W0622 redefined-builtin | |||
# W0703 broad-except | |||
# W1401 anomalous-backslash-in-string | |||
# E are error codes | |||
# E0604 invalid-all-object | |||
# E1101 no-member | |||
# E1102 not-callable | |||
# E1120 no-value-for-parameter | |||
# E1121 too-many-function-args | |||
disable=C, R, fixme, | |||
W0102,W0106,W0107,W0110,W0201,W0212,W0221,W0223,W0231,W0235, | |||
W0311,W0403,W0603,W0612,W0613,W0621,W0622,W0703,W1401, | |||
E0604,E1101,E1102,E1120,E1121 | |||
[REPORTS] | |||
# Set the output format. Available formats are text, parseable, colorized, msvs | |||
# (visual studio) and html | |||
output-format=text | |||
# Put messages in a separate file for each module / package specified on the | |||
# command line instead of printing them on stdout. Reports (if any) will be | |||
# written in a file name "pylint_global.[txt|html]". | |||
files-output=no | |||
# Tells whether to display a full report or only the messages | |||
reports=yes | |||
# Python expression which should return a note less than 10 (10 is the highest | |||
# note). You have access to the variables errors warning, statement which | |||
# respectively contain the number of errors / warnings messages and the total | |||
# number of statements analyzed. This is used by the global evaluation report | |||
# (RP0004). | |||
evaluation=10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10) | |||
[SIMILARITIES] | |||
# Minimum lines number of a similarity. | |||
min-similarity-lines=4 | |||
# Ignore comments when computing similarities. | |||
ignore-comments=yes | |||
# Ignore docstrings when computing similarities. | |||
ignore-docstrings=yes | |||
[FORMAT] | |||
# Maximum number of characters on a single line. | |||
max-line-length=85 | |||
# Maximum number of lines in a module | |||
max-module-lines=1000 | |||
# String used as indentation unit. This is usually 4 spaces or "\t" (1 tab). | |||
indent-string=' ' | |||
[TYPECHECK] | |||
# Tells whether missing members accessed in mixin class should be ignored. A | |||
# mixin class is detected if its name ends with "mixin" (case insensitive). | |||
ignore-mixin-members=yes | |||
# List of module names for which member attributes should not be checked | |||
# (useful for modules/projects where namespaces are manipulated during runtime | |||
# and thus existing member attributes cannot be deduced by static analysis | |||
ignored-modules=distutils,eventlet.green.subprocess,six,six.moves | |||
# List of classes names for which member attributes should not be checked | |||
# (useful for classes with attributes dynamically set). | |||
# pylint is confused by sqlalchemy Table, as well as sqlalchemy Enum types | |||
# ie: (unprovisioned, identity) | |||
# LookupDict in requests library confuses pylint | |||
ignored-classes=SQLObject, optparse.Values, thread._local, _thread._local, | |||
Table, unprovisioned, identity, LookupDict | |||
# List of members which are set dynamically and missed by pylint inference | |||
# system, and so shouldn't trigger E0201 when accessed. Python regular | |||
# expressions are accepted. | |||
generated-members=REQUEST,acl_users,aq_parent | |||
[BASIC] | |||
# List of builtins function names that should not be used, separated by a comma | |||
bad-functions=map,filter,apply,input | |||
# Regular expression which should only match correct module names | |||
module-rgx=(([a-z_][a-z0-9_]*)|([A-Z][a-zA-Z0-9]+))$ | |||
# Regular expression which should only match correct module level names | |||
const-rgx=(([A-Z_][A-Z0-9_]*)|(__.*__))$ | |||
# Regular expression which should only match correct class names | |||
class-rgx=[A-Z_][a-zA-Z0-9]+$ | |||
# Regular expression which should only match correct function names | |||
function-rgx=[a-z_][a-z0-9_]{2,30}$ | |||
# Regular expression which should only match correct method names | |||
method-rgx=[a-z_][a-z0-9_]{2,30}$ | |||
# Regular expression which should only match correct instance attribute names | |||
attr-rgx=[a-z_][a-z0-9_]{2,30}$ | |||
# Regular expression which should only match correct argument names | |||
argument-rgx=[a-z_][a-z0-9_]{2,30}$ | |||
# Regular expression which should only match correct variable names | |||
variable-rgx=[a-z_][a-z0-9_]{2,30}$ | |||
# Regular expression which should only match correct list comprehension / | |||
# generator expression variable names | |||
inlinevar-rgx=[A-Za-z_][A-Za-z0-9_]*$ | |||
# Good variable names which should always be accepted, separated by a comma | |||
good-names=i,j,k,ex,Run,_ | |||
# Bad variable names which should always be refused, separated by a comma | |||
bad-names=foo,bar,baz,toto,tutu,tata | |||
# Regular expression which should only match functions or classes name which do | |||
# not require a docstring | |||
no-docstring-rgx=__.*__ | |||
[MISCELLANEOUS] | |||
# List of note tags to take in consideration, separated by a comma. | |||
notes=FIXME,XXX,TODO | |||
[VARIABLES] | |||
# Tells whether we should check for unused import in __init__ files. | |||
init-import=no | |||
# A regular expression matching the beginning of the name of dummy variables | |||
# (i.e. not used). | |||
dummy-variables-rgx=_|dummy | |||
# List of additional names supposed to be defined in builtins. Remember that | |||
# you should avoid to define new builtins when possible. | |||
additional-builtins= | |||
[IMPORTS] | |||
# Deprecated modules which should not be used, separated by a comma | |||
deprecated-modules=regsub,string,TERMIOS,Bastion,rexec | |||
# Create a graph of every (i.e. internal and external) dependencies in the | |||
# given file (report RP0402 must not be disabled) | |||
import-graph= | |||
# Create a graph of external dependencies in the given file (report RP0402 must | |||
# not be disabled) | |||
ext-import-graph= | |||
# Create a graph of internal dependencies in the given file (report RP0402 must | |||
# not be disabled) | |||
int-import-graph= | |||
[DESIGN] | |||
# Maximum number of arguments for function / method | |||
max-args=5 | |||
# Argument names that match this expression will be ignored. Default to name | |||
# with leading underscore | |||
ignored-argument-names=_.* | |||
# Maximum number of locals for function / method body | |||
max-locals=15 | |||
# Maximum number of return / yield for function / method body | |||
max-returns=6 | |||
# Maximum number of branch for function / method body | |||
max-branchs=12 | |||
# Maximum number of statements in function / method body | |||
max-statements=50 | |||
# Maximum number of parents for a class (see R0901). | |||
max-parents=7 | |||
# Maximum number of attributes for a class (see R0902). | |||
max-attributes=7 | |||
# Minimum number of public methods for a class (see R0903). | |||
min-public-methods=2 | |||
# Maximum number of public methods for a class (see R0904). | |||
max-public-methods=20 | |||
[CLASSES] | |||
# List of method names used to declare (i.e. assign) instance attributes. | |||
defining-attr-methods=__init__,__new__,setUp | |||
# List of valid names for the first argument in a class method. | |||
valid-classmethod-first-arg=cls | |||
[EXCEPTIONS] | |||
# Exceptions that will emit a warning when being caught. Defaults to | |||
# "Exception" | |||
overgeneral-exceptions=Exception |
@@ -0,0 +1,15 @@ | |||
httplib2 | |||
keystoneauth1 | |||
keystonemiddleware | |||
oslo.config | |||
oslo.db | |||
oslo.log | |||
oslo.policy | |||
oslo.service | |||
oslo.utils | |||
oslo.versionedobjects | |||
pecan | |||
prettytable | |||
pyOpenSSL | |||
SQLAlchemy | |||
WSME |
@@ -1,5 +1,6 @@ | |||
hacking!=0.13.0,<0.14,>=0.12.0 | |||
bashate >= 0.2 | |||
mock | |||
PyYAML >= 3.1.0 | |||
yamllint >= 0.5.2 | |||
#spec_cleaner>=1.0.9 |
@@ -1,11 +1,13 @@ | |||
[tox] | |||
envlist = linters,pep8,rpm-packaging-lint | |||
envlist = linters,pep8,pylint,rpm-packaging-lint | |||
minversion = 2.3 | |||
skipsdist = True | |||
stxdir = {toxinidir}/../ | |||
[testenv] | |||
install_command = pip install -U {opts} {packages} | |||
install_command = pip install \ | |||
-chttps://opendev.org/openstack/requirements/raw/branch/stable/stein/upper-constraints.txt \ | |||
{opts} {packages} | |||
setenv = VIRTUAL_ENV={envdir} | |||
OS_STDOUT_CAPTURE=1 | |||
OS_STDERR_CAPTURE=1 | |||
@@ -17,9 +19,6 @@ basepython = python3 | |||
setenv = | |||
VIRTUAL_ENV={envdir} | |||
LC_ALL=en_US.utf-8 | |||
install_command = pip install -U \ | |||
-c{env:UPPER_CONSTRAINTS_FILE:https://opendev.org/openstack/requirements/raw/branch/stable/stein/upper-constraints.txt} \ | |||
{opts} {packages} | |||
deps = -r{toxinidir}/test-requirements.txt | |||
whitelist_externals = bash | |||
commands = | |||
@@ -51,6 +50,23 @@ commands = | |||
-o -type f -name '*.yaml' \ | |||
-print0 | xargs -0 yamllint -d '\{extends: relaxed, rules: \{line-length: \{max: 260\}\}\}'" | |||
[testenv:pylint] | |||
basepython = python2.7 | |||
sitepackages = False | |||
deps = {[testenv]deps} | |||
-e{toxinidir}/../config/tsconfig/tsconfig | |||
-e{toxinidir}/../config/sysinv/cgts-client/cgts-client | |||
-r{toxinidir}/requirements.txt | |||
pylint | |||
commands = pylint {posargs} --rcfile=./pylint.rc \ | |||
fm-api/fm_api \ | |||
fm-common/sources/fm_db_sync_event_suppression.py \ | |||
fm-rest-api/fm/fm \ | |||
python-fmclient/fmclient/fmclient | |||
#### | |||
# Add flake8 as pep8 codestyle check. | |||
[testenv:pep8] | |||