From d1239b246afea480d3d1792ec0a0cfefa1a0c939 Mon Sep 17 00:00:00 2001 From: Matthew Treinish Date: Fri, 20 Nov 2015 18:22:08 -0500 Subject: [PATCH] Add back uuid column for runs table When we converted the runs table to use an auto-incrementing integer as the primary key column we dropped the uuid. However, in doing this we would be deleting the only user facing identifier for a run. This commit corrects the oversight by renaming the old id column as a non-primary key column that can be used for an user input or output regarding runs. This also adds a new api method and calls it in sql2subunit to maintain backwards compatibility after the migration. Change-Id: Idab32bb3449559285f9d45b6132b1c07c1260e7c --- subunit2sql/db/api.py | 27 ++++++++++++++----- subunit2sql/db/models.py | 4 +++ .../2822a408bdd0_uuid_to_integer_ids.py | 7 +++-- .../tests/migrations/test_migrations.py | 7 ++--- subunit2sql/write_subunit.py | 1 + 5 files changed, 35 insertions(+), 11 deletions(-) diff --git a/subunit2sql/db/api.py b/subunit2sql/db/api.py index 5875958..452af65 100644 --- a/subunit2sql/db/api.py +++ b/subunit2sql/db/api.py @@ -172,7 +172,7 @@ def create_run(skips=0, fails=0, passes=0, run_time=0, artifacts=None, """ run = models.Run() if id: - run.id = id + run.uuid = id if run_at: run.run_at = run_at run.skips = skips @@ -562,10 +562,25 @@ def get_test_by_test_id(test_id, session=None): return test -def get_run_by_id(id, session=None): - """Get an individual run by it's uuid. +def get_run_id_from_uuid(uuid, session=None): + """Get the id for a run by it's uuid - :param str id: The uuid for the run (the id field in the DB) + :param str uuid: The uuid for the run + :param session: optional session object if one isn't provided a new session + will be acquired for the duration of this operation + :return: The id for the run with the provided uuid + :rtype: str + """ + session = session or get_session() + run_id = session.query(models.Run.id).filter( + models.Run.uuid == uuid).first() + return run_id + + +def get_run_by_id(id, session=None): + """Get an individual run by it's id. + + :param str id: The id for the run :param session: optional session object if one isn't provided a new session will be acquired for the duration of this operation @@ -578,9 +593,9 @@ def get_run_by_id(id, session=None): def get_test_run_by_id(test_run_id, session=None): - """Get an individual test run by it's uuid. + """Get an individual test run by it's id. - :param str test_run_id: The uuid for the test run (the id field in the DB) + :param str test_run_id: The id for the test run :param session: optional session object if one isn't provided a new session will be acquired for the duration of this operation diff --git a/subunit2sql/db/models.py b/subunit2sql/db/models.py index 45cabde..c751588 100644 --- a/subunit2sql/db/models.py +++ b/subunit2sql/db/models.py @@ -13,8 +13,10 @@ # under the License. import datetime +import uuid from oslo_db.sqlalchemy import models # noqa +import six import sqlalchemy as sa from sqlalchemy.ext import declarative @@ -58,6 +60,8 @@ class Test(BASE, SubunitBase): class Run(BASE, SubunitBase): __tablename__ = 'runs' + uuid = sa.Column(sa.String(36), + default=lambda: six.text_type(uuid.uuid4())) id = sa.Column(sa.BigInteger, primary_key=True) skips = sa.Column(sa.Integer()) fails = sa.Column(sa.Integer()) diff --git a/subunit2sql/migrations/versions/2822a408bdd0_uuid_to_integer_ids.py b/subunit2sql/migrations/versions/2822a408bdd0_uuid_to_integer_ids.py index cb3b714..e8fe420 100644 --- a/subunit2sql/migrations/versions/2822a408bdd0_uuid_to_integer_ids.py +++ b/subunit2sql/migrations/versions/2822a408bdd0_uuid_to_integer_ids.py @@ -209,7 +209,8 @@ def upgrade(): op.drop_column('tests_new', 'id') op.alter_column('tests_new', 'new_id', new_column_name='id') - op.drop_column('runs_new', 'id') + op.alter_column('runs_new', 'id', + new_column_name='uuid') op.alter_column('runs_new', 'new_id', new_column_name='id') else: @@ -270,7 +271,8 @@ def upgrade(): existing_type=new_id_type, autoincrement=True) with op.batch_alter_table("runs_new") as batch_op: - batch_op.drop_column('id') + batch_op.alter_column('id', new_column_name='uuid', + existing_type=sa.VARCHAR(36)) batch_op.alter_column('new_id', new_column_name='id', primary_key=True, existing_type=new_id_type, @@ -331,6 +333,7 @@ def upgrade(): ['test_id', 'start_time']) op.create_unique_constraint('uq_test_runs', 'test_runs', ['test_id', 'run_id']) + op.create_index('ix_run_uuid', 'runs', ['uuid']) op.create_index('ix_tests_test_id', 'tests', ['test_id'], mysql_length=30) op.create_index('ix_test_runs_test_id', 'test_runs', ['test_id']) op.create_index('ix_test_runs_run_id', 'test_runs', ['run_id']) diff --git a/subunit2sql/tests/migrations/test_migrations.py b/subunit2sql/tests/migrations/test_migrations.py index 2398b83..11c9b21 100644 --- a/subunit2sql/tests/migrations/test_migrations.py +++ b/subunit2sql/tests/migrations/test_migrations.py @@ -522,7 +522,7 @@ class TestWalkMigrations(base.TestCase): # Check all the new ids match runs_t = get_table(engine, 'runs') - run_ids = [x[0] for x in runs_t.select().execute()] + run_ids = [x[1] for x in runs_t.select().execute()] run_metadatas_t = get_table(engine, 'run_metadata') tests_t = get_table(engine, 'tests') test_metadatas_t = get_table(engine, 'test_metadata') @@ -547,10 +547,11 @@ class TestWalkMigrations(base.TestCase): # Check run run_row = list(runs_t.select().where( runs_t.c.id == test_run_row[2]).execute())[0] - self.assertEqual(data['run']['artifacts'], run_row[5]) + self.assertEqual(data['run']['artifacts'], run_row[6]) + self.assertEqual(data['run']['id'], run_row[0]) # Check run metadata run_metadata_row = list(run_metadatas_t.select().where( - run_metadatas_t.c.run_id == run_row[0]).execute())[0] + run_metadatas_t.c.run_id == run_row[1]).execute())[0] self.assertEqual(data['run_metadata']['key'], run_metadata_row[1]) self.assertEqual(data['run_metadata']['value'], run_metadata_row[2]) # Check test metadata diff --git a/subunit2sql/write_subunit.py b/subunit2sql/write_subunit.py index 8340da3..bc07b9f 100644 --- a/subunit2sql/write_subunit.py +++ b/subunit2sql/write_subunit.py @@ -76,6 +76,7 @@ def write_test(output, start_time, stop_time, status, test_id, metadatas): def sql2subunit(run_id, output=sys.stdout): session = api.get_session() + run_id = api.get_run_id_from_uuid(run_id, session) test_runs = api.get_tests_run_dicts_from_run_id(run_id, session) session.close() output = subunit.v2.StreamResultToBytes(output)