Add migration to populate run_time where needed
The existing migration to add an avg run_time column to the tests table neglected to calculate the run_time for existing rows and instead just added a NULL value. Since this migration is part of a released version of subunit2sql it's too late to add support for adding a run_time to the columns where it makes sense. This commit adds a new migration that will add the avg run_time for each test in the tests table where there are successful test runs and the run_time is still set to NULL. Additionally there were a couple of fixes around adding migrations that needed to be added here, mostly just changing the base alembic.ini to reflect the new relative path of the migration dir and ignoring an additional pep8 rule which conflicted with the sqlalchemy syntax. Change-Id: I0b9c673106c41e9e66a2be5da6ebe9ca58d0ad36
This commit is contained in:
parent
0a2fb7b7ac
commit
7948c0e026
@ -2,7 +2,7 @@
|
||||
|
||||
[alembic]
|
||||
# path to migration scripts
|
||||
script_location = subunit2sql/migrations
|
||||
script_location = .
|
||||
|
||||
# template used to generate migration files
|
||||
# file_template = %%(rev)s_%%(slug)s
|
||||
|
@ -0,0 +1,57 @@
|
||||
# Copyright 2014 Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# 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.
|
||||
|
||||
"""Populate run_time for existing tests
|
||||
|
||||
Revision ID: 5332fe255095
|
||||
Revises: 28ac1ba9c3db
|
||||
Create Date: 2014-10-03 10:23:25.469128
|
||||
|
||||
"""
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision = '5332fe255095'
|
||||
down_revision = '28ac1ba9c3db'
|
||||
|
||||
|
||||
from oslo.db.sqlalchemy import utils as db_utils
|
||||
|
||||
from subunit2sql.db import api as db_api
|
||||
from subunit2sql.db import models
|
||||
|
||||
|
||||
def upgrade():
|
||||
query = db_utils.model_query(models.Test,
|
||||
db_api.get_session()).filter(
|
||||
models.Test.success > 0,
|
||||
models.Test.run_time == None)
|
||||
tests = query.all()
|
||||
for test in tests:
|
||||
test_runs = db_api.get_test_runs_by_test_id(test.id)
|
||||
duration = 0.0
|
||||
for test_run in test_runs:
|
||||
if test_run.status == 'success':
|
||||
test_run_duration = db_api.get_test_run_duration(test_run.id)
|
||||
duration = duration + test_run_duration
|
||||
avg = duration / test.success
|
||||
db_api.update_test({'run_time': avg}, test.id)
|
||||
|
||||
|
||||
def downgrade():
|
||||
# NOTE(mtreinish) there is no possible downgrade for this migration, since
|
||||
# we won't be able to tell which rows had run_time NULL before this.
|
||||
# Ideally this would have been baked into 163fd5aa1380 and the downgrade
|
||||
# there of deleting the column would have covered this. But, because that
|
||||
# wasn't included as a part of the released migration we can't change it.
|
||||
pass
|
@ -443,3 +443,52 @@ class TestWalkMigrations(base.TestCase):
|
||||
for run in data:
|
||||
self.assertIn((run['id'], None), run_at)
|
||||
self.assertIn((time_data['id'], now), run_at)
|
||||
|
||||
def _pre_upgrade_5332fe255095(self, engine):
|
||||
tests = get_table(engine, 'tests')
|
||||
test_runs = get_table(engine, 'test_runs')
|
||||
# Create 2 sample rows one for a passing test the other failing
|
||||
fake_tests = {'pass': {'id': 'fake_null_test_id',
|
||||
'test_id': 'I_am_a_little_test_that_works',
|
||||
'success': 2,
|
||||
'failure': 0},
|
||||
'fail': {'id': 'fake_null_test_id_fails',
|
||||
'test_id': 'Im_a_little_test_that_doesnt_work',
|
||||
'success': 0,
|
||||
'failure': 1}}
|
||||
now = datetime.datetime.now()
|
||||
future_now = now + datetime.timedelta(0, 4)
|
||||
# Create sample rows for the test_runs corresponding to the test rows
|
||||
fake_test_runs = {'pass': [
|
||||
{'id': 'fake_test_run_pass_1', 'test_id': 'fake_null_test_id',
|
||||
'run_id': 'fake_run.id1', 'start_time': now, 'status': 'success',
|
||||
'stop_time': future_now},
|
||||
{'id': 'fake_test_run_pass_2', 'test_id': 'fake_null_test_id',
|
||||
'run_id': 'fake_run.id2', 'start_time': now, 'status': 'success',
|
||||
'stop_time': future_now}]}
|
||||
fake_test_runs['fail'] = {'id': 'fake_test_run_fail',
|
||||
'test_id': 'fake_null_test_id_fails',
|
||||
'run_id': 'fake_run.id1',
|
||||
'start_time': now,
|
||||
'status': 'fail',
|
||||
'stop_time': future_now}
|
||||
for test in fake_tests:
|
||||
tests.insert().values(fake_tests[test]).execute()
|
||||
for test_run in fake_test_runs['pass']:
|
||||
test_runs.insert().values(test_run).execute()
|
||||
test_runs.insert().values(fake_test_runs['fail']).execute()
|
||||
return {'tests': fake_tests, 'test_runs': fake_test_runs}
|
||||
|
||||
def _check_5332fe255095(self, engine, data):
|
||||
tests = get_table(engine, 'tests')
|
||||
# Get the test uuids from the same data set
|
||||
test_ids = [data['tests'][x]['id'] for x in data['tests']]
|
||||
# Query the DB for the tests from the sample dataset above
|
||||
where = ' OR '.join(["tests.id='%s'" % x for x in test_ids])
|
||||
result = tests.select(where).execute()
|
||||
run_time_pairs = map(lambda x: (x['id'], x['run_time']), result)
|
||||
# Ensure the test with one failure is None
|
||||
self.assertIn(('fake_null_test_id_fails', None), run_time_pairs)
|
||||
# Ensure the test with 2 success each taking 4 sec lists the proper
|
||||
# run_time
|
||||
self.assertIn(('fake_null_test_id', 4.0), run_time_pairs)
|
||||
|
3
tox.ini
3
tox.ini
@ -35,5 +35,6 @@ commands = python setup.py build_sphinx
|
||||
# E123 skipped because it is ignored by default in the default pep8
|
||||
# E129 skipped because it is too limiting when combined with other rules
|
||||
# H305 skipped because it is inconsistent between python versions
|
||||
ignore = E125,H402,E123,E129,H305
|
||||
# E711 skipped because sqlalchemy filter() requires using == instead of is
|
||||
ignore = E125,H402,E123,E129,H305,E711
|
||||
exclude = .venv,.git,.tox,dist,doc,*egg,build
|
||||
|
Loading…
Reference in New Issue
Block a user