From ff9a20a192c7004c608d76b78a97136b62dd6d35 Mon Sep 17 00:00:00 2001 From: Tatyana Leontovich Date: Wed, 30 Mar 2016 21:18:46 +0300 Subject: [PATCH] Add usage of namedtuples for run and tests status To get possibility to change status in one place, add consts.py with enum usage. Closes-Bug: #1404866 Change-Id: I6a7873bc2de919ed4cc99dcfe8e3e1febda606c0 --- fuel_plugin/consts.py | 43 ++++++++++++++++ .../ostf_adapter/nose_plugin/nose_adapter.py | 3 +- .../nose_plugin/nose_storage_plugin.py | 23 +++++---- fuel_plugin/ostf_adapter/storage/models.py | 49 ++++++++----------- fuel_plugin/ostf_adapter/wsgi/controllers.py | 5 +- 5 files changed, 82 insertions(+), 41 deletions(-) create mode 100644 fuel_plugin/consts.py diff --git a/fuel_plugin/consts.py b/fuel_plugin/consts.py new file mode 100644 index 00000000..50cb200b --- /dev/null +++ b/fuel_plugin/consts.py @@ -0,0 +1,43 @@ +# Copyright 2016 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 collections + + +def Enum(*values, **kwargs): + names = kwargs.get('names') + if names: + return collections.namedtuple('Enum', names)(*values) + return collections.namedtuple('Enum', values)(*values) + +TESTRUN_STATUSES = Enum( + 'stopped', + 'restarted', + 'finished', + 'running' +) + +TEST_STATUSES = Enum( + 'stopped', + 'restarted', + 'finished', + 'running', + 'error', + 'skipped', + 'success', + 'failure', + 'wait_running', + 'disabled' +) diff --git a/fuel_plugin/ostf_adapter/nose_plugin/nose_adapter.py b/fuel_plugin/ostf_adapter/nose_plugin/nose_adapter.py index 9d8d53a8..f8e7d1f4 100644 --- a/fuel_plugin/ostf_adapter/nose_plugin/nose_adapter.py +++ b/fuel_plugin/ostf_adapter/nose_plugin/nose_adapter.py @@ -22,6 +22,7 @@ try: except ImportError: from oslo_config import cfg +from fuel_plugin import consts from fuel_plugin.ostf_adapter.logger import ResultsLogger from fuel_plugin.ostf_adapter.nose_plugin import nose_storage_plugin from fuel_plugin.ostf_adapter.nose_plugin import nose_test_runner @@ -114,7 +115,7 @@ class NoseDriver(object): except Exception: LOG.exception('Test run ID: %s', test_run_id) finally: - updated_data = {'status': 'finished', + updated_data = {'status': consts.TESTRUN_STATUSES.finished, 'pid': None} models.TestRun.update_test_run( diff --git a/fuel_plugin/ostf_adapter/nose_plugin/nose_storage_plugin.py b/fuel_plugin/ostf_adapter/nose_plugin/nose_storage_plugin.py index 5af7c585..d0f39ae3 100644 --- a/fuel_plugin/ostf_adapter/nose_plugin/nose_storage_plugin.py +++ b/fuel_plugin/ostf_adapter/nose_plugin/nose_storage_plugin.py @@ -22,6 +22,7 @@ try: except ImportError: from oslo_config import cfg +from fuel_plugin import consts from fuel_plugin.ostf_adapter.nose_plugin import nose_utils from fuel_plugin.ostf_adapter.storage import models @@ -72,7 +73,7 @@ class StoragePlugin(plugins.Plugin): test_id, data ) - if data['status'] != 'running': + if data['status'] != consts.TEST_STATUSES.running: test_name = nose_utils.get_description(test)["title"] self.results_log.log_results( test_id, @@ -93,11 +94,11 @@ class StoragePlugin(plugins.Plugin): if err: exc_type, exc_value, exc_traceback = err - if not status == 'error': + if not status == consts.TEST_STATUSES.error: data['step'], data['message'] = \ nose_utils.format_failure_message(exc_value) - if status != 'skipped': + if status != consts.TEST_STATUSES.skipped: data['traceback'] = nose_utils.format_exception(err) tests_to_update = nose_utils.get_tests_to_update(test) @@ -107,26 +108,30 @@ class StoragePlugin(plugins.Plugin): self.session.commit() def addSuccess(self, test, capt=None): - self._add_message(test, status='success') + self._add_message(test, status=consts.TEST_STATUSES.success) def addFailure(self, test, err): LOG.error('%s', test.id(), exc_info=err) - self._add_message(test, err=err, status='failure') + self._add_message( + test, err=err, status=consts.TEST_STATUSES.failure) def addError(self, test, err): if err[0] is AssertionError: LOG.error('%s', test.id(), exc_info=err) - self._add_message(test, err=err, status='failure') + self._add_message( + test, err=err, status=consts.TEST_STATUSES.failure) elif issubclass(err[0], plugins.skip.SkipTest): LOG.warning('%s is skipped', test.id()) - self._add_message(test, err=err, status='skipped') + self._add_message( + test, err=err, status=consts.TEST_STATUSES.skipped) else: LOG.error('%s', test.id(), exc_info=err) - self._add_message(test, err=err, status='error') + self._add_message( + test, err=err, status=consts.TEST_STATUSES.error) def beforeTest(self, test): self._start_time = time.time() - self._add_message(test, status='running') + self._add_message(test, status=consts.TEST_STATUSES.running) def describeTest(self, test): return test.test._testMethodDoc diff --git a/fuel_plugin/ostf_adapter/storage/models.py b/fuel_plugin/ostf_adapter/storage/models.py index 5c86040c..17ce1723 100644 --- a/fuel_plugin/ostf_adapter/storage/models.py +++ b/fuel_plugin/ostf_adapter/storage/models.py @@ -22,6 +22,7 @@ from sqlalchemy.ext.associationproxy import association_proxy from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.orm import joinedload, relationship, object_mapper +from fuel_plugin import consts from fuel_plugin.ostf_adapter import nose_plugin from fuel_plugin.ostf_adapter.storage import engine from fuel_plugin.ostf_adapter.storage import fields @@ -115,17 +116,6 @@ class Test(BASE): __tablename__ = 'tests' - STATES = ( - 'wait_running', - 'running', - 'failure', - 'success', - 'error', - 'stopped', - 'disabled', - 'skipped' - ) - id = sa.Column(sa.Integer(), primary_key=True) name = sa.Column(sa.String(512)) title = sa.Column(sa.String(512)) @@ -133,7 +123,7 @@ class Test(BASE): duration = sa.Column(sa.String(512)) message = sa.Column(sa.Text()) traceback = sa.Column(sa.Text()) - status = sa.Column(sa.Enum(*STATES, name='test_states')) + status = sa.Column(sa.Enum(consts.TEST_STATUSES, name='test_states')) step = sa.Column(sa.Integer()) time_taken = sa.Column(sa.Float()) meta = sa.Column(fields.JsonField()) @@ -178,15 +168,19 @@ class Test(BASE): update(data, synchronize_session='fetch') @classmethod - def update_running_tests(cls, session, test_run_id, status='stopped'): + def update_running_tests(cls, session, test_run_id, + status=consts.TEST_STATUSES.stopped): session.query(cls). \ filter(cls.test_run_id == test_run_id, - cls.status.in_(('running', 'wait_running'))). \ + cls.status.in_( + (consts.TEST_STATUSES.running, + consts.TEST_STATUSES.wait_running))). \ update({'status': status}, synchronize_session='fetch') @classmethod def update_test_run_tests(cls, session, test_run_id, - tests_names, status='wait_running'): + tests_names, + status=consts.TEST_STATUSES.wait_running): session.query(cls). \ filter(cls.name.in_(tests_names), cls.test_run_id == test_run_id). \ @@ -205,9 +199,9 @@ class Test(BASE): setattr(new_test, column.key, getattr(self, column.key)) new_test.test_run_id = test_run.id if predefined_tests and new_test.name not in predefined_tests: - new_test.status = 'disabled' + new_test.status = consts.TEST_STATUSES.disabled else: - new_test.status = 'wait_running' + new_test.status = consts.TEST_STATUSES.wait_running return new_test @@ -215,14 +209,10 @@ class TestRun(BASE): __tablename__ = 'test_runs' - STATES = ( - 'running', - 'finished' - ) - id = sa.Column(sa.Integer(), primary_key=True) cluster_id = sa.Column(sa.Integer(), nullable=False) - status = sa.Column(sa.Enum(*STATES, name='test_run_states'), + status = sa.Column(sa.Enum(consts.TESTRUN_STATUSES, + name='test_run_states'), nullable=False) meta = sa.Column(fields.JsonField()) started_at = sa.Column(sa.DateTime, default=datetime.datetime.utcnow) @@ -262,10 +252,10 @@ class TestRun(BASE): @property def enabled_tests(self): return [test.name for test - in self.tests if test.status != 'disabled'] + in self.tests if test.status != consts.TEST_STATUSES.disabled] def is_finished(self): - return self.status == 'finished' + return self.status == consts.TESTRUN_STATUSES.finished @property def frontend(self): @@ -284,7 +274,8 @@ class TestRun(BASE): return test_run_data @classmethod - def add_test_run(cls, session, test_set, cluster_id, status='running', + def add_test_run(cls, session, test_set, cluster_id, + status=consts.TESTRUN_STATUSES.running, tests=None): """Creates new test_run object with given data and makes copy of tests that will be bound @@ -350,7 +341,7 @@ class TestRun(BASE): @classmethod def update_test_run(cls, session, test_run_id, updated_data): - if updated_data.get('status') in ['finished']: + if updated_data.get('status') in [consts.TESTRUN_STATUSES.finished]: updated_data['ended_at'] = datetime.datetime.utcnow() session.query(cls). \ @@ -392,7 +383,7 @@ class TestRun(BASE): self.cluster_id): plugin = nose_plugin.get_plugin(self.test_set.driver) - self.update('running') + self.update(consts.TEST_STATUSES.running) if tests: Test.update_test_run_tests( session, self.id, tests) @@ -409,5 +400,5 @@ class TestRun(BASE): killed = plugin.kill(self) if killed: Test.update_running_tests( - session, self.id, status='stopped') + session, self.id, status=consts.TEST_STATUSES.stopped) return self.frontend diff --git a/fuel_plugin/ostf_adapter/wsgi/controllers.py b/fuel_plugin/ostf_adapter/wsgi/controllers.py index 355145b5..b9cf5f73 100644 --- a/fuel_plugin/ostf_adapter/wsgi/controllers.py +++ b/fuel_plugin/ostf_adapter/wsgi/controllers.py @@ -29,6 +29,7 @@ from pecan import rest from sqlalchemy import func from sqlalchemy.orm import joinedload +from fuel_plugin import consts from fuel_plugin.ostf_adapter import mixins from fuel_plugin.ostf_adapter.storage import models @@ -190,9 +191,9 @@ class TestrunsController(BaseRestController): test_run = models.TestRun.get_test_run(request.session, test_run['id']) - if status == 'stopped': + if status == consts.TESTRUN_STATUSES.stopped: data.append(test_run.stop(request.session)) - elif status == 'restarted': + elif status == consts.TESTRUN_STATUSES.restarted: data.append(test_run.restart(request.session, cfg.CONF.adapter.dbpath, ostf_os_access_creds,