diff --git a/subunit2sql/migrations/alembic.ini b/subunit2sql/migrations/alembic.ini index 0d0080e..b2037b4 100644 --- a/subunit2sql/migrations/alembic.ini +++ b/subunit2sql/migrations/alembic.ini @@ -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 diff --git a/subunit2sql/migrations/versions/5332fe255095_populate_run_time_for_existing_tests.py b/subunit2sql/migrations/versions/5332fe255095_populate_run_time_for_existing_tests.py new file mode 100644 index 0000000..fd71075 --- /dev/null +++ b/subunit2sql/migrations/versions/5332fe255095_populate_run_time_for_existing_tests.py @@ -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 diff --git a/subunit2sql/tests/migrations/test_migrations.py b/subunit2sql/tests/migrations/test_migrations.py index 1d5b87e..49b1245 100644 --- a/subunit2sql/tests/migrations/test_migrations.py +++ b/subunit2sql/tests/migrations/test_migrations.py @@ -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) diff --git a/tox.ini b/tox.ini index 88f7e78..075219e 100644 --- a/tox.ini +++ b/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