[Verify] Add 'crashed' status to verifications

Co-Authored-By: Yaroslav Lobankov <ylobankov@mirantis.com>

Change-Id: I807e89c186d97680d4add12b5d1f95205cb3d993
This commit is contained in:
Andrey Kurilin 2017-01-23 14:26:21 +02:00 committed by Yaroslav Lobankov
parent 90c1d08501
commit 05fe54ca14
5 changed files with 175 additions and 8 deletions

View File

@ -0,0 +1,64 @@
# 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.
"""Change verification statuses
Revision ID: f33f4610dcda
Revises: a6f364988fc2
Create Date: 2017-01-23 13:56:30.999593
"""
# revision identifiers, used by Alembic.
revision = "f33f4610dcda"
down_revision = "a6f364988fc2"
branch_labels = None
depends_on = None
from alembic import op
import sqlalchemy as sa
from rally import exceptions
verifications_helper = sa.Table(
"verifications",
sa.MetaData(),
sa.Column("id", sa.Integer, primary_key=True, autoincrement=True),
sa.Column("failures", sa.Integer, default=0),
sa.Column("unexpected_success", sa.Integer, default=0),
sa.Column("status", sa.String(36), nullable=False)
)
def upgrade():
connection = op.get_bind()
for v in connection.execute(verifications_helper.select()):
new_status = v.status
if v.status == "finished" and (
v.failures != 0 or v.unexpected_success != 0):
new_status = "failed"
elif v.status == "failed":
new_status = "crashed"
else:
pass
if new_status != v.status:
connection.execute(verifications_helper.update().where(
verifications_helper.c.id == v.id).values(
status=new_status))
def downgrade():
raise exceptions.DowngradeNotSupported()

View File

@ -60,9 +60,13 @@ class Verification(object):
self._update(status=status)
def finish(self, totals, tests):
self._update(status=consts.VerificationStatus.FINISHED, tests=tests,
**totals)
if (totals.get("failures", 0) == 0 and
totals.get("unexpected_success", 0) == 0):
status = consts.VerificationStatus.FINISHED
else:
status = consts.VerificationStatus.FAILED
self._update(status=status, tests=tests, **totals)
def set_error(self, error_message):
# TODO(andreykurilin): Save error message in the database.
self.update_status(consts.VerificationStatus.FAILED)
self.update_status(consts.VerificationStatus.CRASHED)

View File

@ -208,6 +208,7 @@ class _VerificationStatus(utils.ImmutableMixin, utils.EnumMixin):
RUNNING = "running"
FINISHED = "finished"
FAILED = "failed"
CRASHED = "crashed"
TaskStatus = _TaskStatus()

View File

@ -1170,3 +1170,85 @@ class MigrationWalkTestCase(rtest.DBTestCase,
conn.execute(
tags_table.delete().where(
tags_table.c.uuid == tags[i].uuid))
def _pre_upgrade_f33f4610dcda(self, engine):
self._f33f4610dcda_deployment_uuid = "f33f4610dcda-deployment"
self._f33f4610dcda_verifier_uuid = "f33f4610dcda-verifier"
self._f33f4610dcda_verifications = [
{"status": "init", "failures": 0, "unexpected_success": 0},
{"status": "running", "failures": 0, "unexpected_success": 0},
{"status": "finished", "failures": 0, "unexpected_success": 0},
{"status": "finished", "failures": 1, "unexpected_success": 0,
"new_status": "failed"},
{"status": "finished", "failures": 1, "unexpected_success": 1,
"new_status": "failed"},
{"status": "finished", "failures": 0, "unexpected_success": 1,
"new_status": "failed"},
{"status": "failed", "failures": 0, "unexpected_success": 0,
"new_status": "crashed"},
]
deployment_table = db_utils.get_table(engine, "deployments")
verifiers_table = db_utils.get_table(engine, "verifiers")
verifications_table = db_utils.get_table(engine, "verifications")
deployment_status = consts.DeployStatus.DEPLOY_FINISHED
with engine.connect() as conn:
conn.execute(
deployment_table.insert(),
[{"uuid": self._f33f4610dcda_deployment_uuid,
"name": self._f33f4610dcda_deployment_uuid,
"config": six.b(json.dumps([])),
"enum_deployments_status": deployment_status,
"credentials": six.b(json.dumps([])),
"users": six.b(json.dumps([]))
}])
conn.execute(
verifiers_table.insert(),
[{"uuid": self._f33f4610dcda_verifier_uuid,
"name": self._f33f4610dcda_verifier_uuid,
"type": "some-type",
"status": consts.VerifierStatus.INSTALLED
}])
for i in range(len(self._f33f4610dcda_verifications)):
v = self._f33f4610dcda_verifications[i]
conn.execute(
verifications_table.insert(),
[{"uuid": "verification-uuid-%s" % i,
"deployment_uuid": self._f33f4610dcda_deployment_uuid,
"verifier_uuid": self._f33f4610dcda_verifier_uuid,
"status": v["status"],
"failures": v["failures"],
"unexpected_success": v["unexpected_success"]
}])
def _check_f33f4610dcda(self, engine, data):
self.assertEqual("f33f4610dcda",
api.get_backend().schema_revision(engine=engine))
verifications_table = db_utils.get_table(engine, "verifications")
with engine.connect() as conn:
verifications = conn.execute(
verifications_table.select()).fetchall()
self.assertEqual(len(verifications),
len(self._f33f4610dcda_verifications))
for i in range(len(verifications)):
if "new_status" in self._f33f4610dcda_verifications[i]:
self.assertEqual(
self._f33f4610dcda_verifications[i]["new_status"],
verifications[i].status)
conn.execute(
verifications_table.delete().where(
verifications_table.c.uuid == verifications[i].uuid)
)
deployment_table = db_utils.get_table(engine, "deployments")
conn.execute(
deployment_table.delete().where(
deployment_table.c.uuid ==
self._37fdbb373e8d_deployment_uuid)
)

View File

@ -70,7 +70,7 @@ class VerificationTestCase(test.TestCase):
v = objects.Verification(self.db_obj)
totals = {
"tests_count": 2,
"tests_duration": "0.54",
"tests_duration": 0.54,
"success": 2,
"skip": 0,
"expected_failures": 0,
@ -80,13 +80,13 @@ class VerificationTestCase(test.TestCase):
tests = {
"foo_test[gate,negative]": {
"name": "foo_test",
"duration": "0.25",
"duration": 0.25,
"status": "success",
"tags": ["gate", "negative"]
},
"bar_test[gate,negative]": {
"name": "bar.Test",
"duration": "0.29",
"name": "bar_test",
"duration": 0.29,
"status": "success",
"tags": ["gate", "negative"]
}
@ -96,9 +96,25 @@ class VerificationTestCase(test.TestCase):
self.db_obj["uuid"], status=consts.VerificationStatus.FINISHED,
tests=tests, **totals)
v = objects.Verification(self.db_obj)
totals.update(failures=1)
mock_verification_update.reset_mock()
v.finish(totals, tests)
mock_verification_update.assert_called_once_with(
self.db_obj["uuid"], status=consts.VerificationStatus.FAILED,
tests=tests, **totals)
v = objects.Verification(self.db_obj)
totals.update(failures=0, unexpected_success=1)
mock_verification_update.reset_mock()
v.finish(totals, tests)
mock_verification_update.assert_called_once_with(
self.db_obj["uuid"], status=consts.VerificationStatus.FAILED,
tests=tests, **totals)
@mock.patch("rally.common.objects.verification.db.verification_update")
def test_set_error(self, mock_verification_update):
v = objects.Verification(self.db_obj)
v.set_error("Some error")
mock_verification_update.assert_called_once_with(
self.db_obj["uuid"], status=consts.VerificationStatus.FAILED)
self.db_obj["uuid"], status=consts.VerificationStatus.CRASHED)