From adf137326c5309f49b34fca5b4e433e0c2b3abd2 Mon Sep 17 00:00:00 2001 From: Jakub Heger Date: Fri, 10 Jan 2020 17:09:29 +0100 Subject: [PATCH 1/2] Create fmf for each tcms case when converting. Using tmt test convert will now create fmf file for each test case found in tcms apart from main.fmf, which contains common attributes found in all of the individual test cases. New files are named according to their tcms id and contain only attributes with values that are unique to it. --- tmt/cli.py | 8 +++-- tmt/convert.py | 88 ++++++++++++++++++++++++++++++++++---------------- 2 files changed, 67 insertions(+), 29 deletions(-) diff --git a/tmt/cli.py b/tmt/cli.py index ad3fc7c88d..f556f1e961 100644 --- a/tmt/cli.py +++ b/tmt/cli.py @@ -415,8 +415,12 @@ def convert(context, paths, makefile, nitrate, purpose, **kwargs): raise tmt.utils.GeneralError( "Path '{0}' is not a directory.".format(path)) # Gather old metadata and store them as fmf - data = tmt.convert.read(path, makefile, nitrate, purpose) - tmt.convert.write(path, data) + data, testcase_data = tmt.convert.read(path, makefile, nitrate, purpose) + main_path = os.path.join(path, 'main.fmf') + tmt.convert.write(main_path, data) + for case in testcase_data: + case_path = os.path.join(path, str(case['tcms id']) + '.fmf') + tmt.convert.write(case_path, case) @tests.command() diff --git a/tmt/convert.py b/tmt/convert.py index 16f2f278f2..cb4b001ce5 100644 --- a/tmt/convert.py +++ b/tmt/convert.py @@ -9,6 +9,7 @@ import fmf.utils import tmt.utils import pprint +import copy import yaml import re import os @@ -109,47 +110,80 @@ def read(path, makefile, nitrate, purpose): if not testcases: raise ConvertError("No testcase found for '{0}'.".format(test)) elif len(testcases) > 1: - log.warn("Multiple test cases found for '{0}', using {1}".format( - test, testcases[0].identifier)) - testcase = testcases[0] - echo("test case found '{0}'.".format(testcase.identifier)) - # Contact - if testcase.tester: - data['contact'] = '{} <{}>'.format( - testcase.tester.name, testcase.tester.email) - echo(style('contact: ', fg='green') + data['contact']) - # Environment - if testcase.arguments: - data['environment'] = tmt.utils.variables_to_dictionary( - testcase.arguments) - echo(style('environment:', fg='green')) - echo(pprint.pformat(data['environment'])) - # Relevancy - field = tmt.utils.StructuredField(testcase.notes) - data['relevancy'] = field.get('relevancy') - echo(style('relevancy:', fg='green')) - echo(data['relevancy'].rstrip('\n')) + log.warn("Multiple test cases found for '{0}'.".format( + test)) + + testcase_data = list() + + for testcase in testcases: + single_case_data = dict() + echo("test case found '{0}'.".format(testcase.identifier)) + # Test identifier + single_case_data['tcms id'] = testcase.identifier + # Test name + if testcase.summary: + single_case_data['testname'] = '{}'.format( + testcase.summary) + echo(style('test name: ', fg='green') + single_case_data['testname']) + # Contact + if testcase.tester: + single_case_data['contact'] = '{} <{}>'.format( + testcase.tester.name, testcase.tester.email) + echo(style('contact: ', fg='green') + single_case_data['contact']) + # Environment + if testcase.arguments: + single_case_data['environment'] = tmt.utils.variables_to_dictionary( + testcase.arguments) + echo(style('environment:', fg='green')) + echo(pprint.pformat(single_case_data['environment'])) + # Relevancy + field = tmt.utils.StructuredField(testcase.notes) + single_case_data['relevancy'] = field.get('relevancy') + echo(style('relevancy:', fg='green')) + echo(single_case_data['relevancy'].rstrip('\n')) + testcase_data.append(single_case_data) + + common_candidates = dict() + + # Find common data from individual test cases + for testcase in testcase_data: + if testcase_data.index(testcase) == 0: + common_candidates = copy.copy(testcase) + else: + for key, value in testcase.items(): + if key in common_candidates: + if value != common_candidates[key]: + common_candidates.pop(key) + + # Add common data to main.fmf + for key, value in common_candidates.items(): + data[key] = value + + # Remove common data from individual fmfs + for common_key in list(common_candidates): + for testcase in testcase_data: + if common_key in testcase: + testcase.pop(common_key) log.debug('Gathered metadata:\n' + pprint.pformat(data)) - return data + return data, testcase_data def write(path, data): """ Write gathered metadata in the fmf format """ # Make sure there is a metadata tree initialized try: - tree = fmf.Tree(path) + tree = fmf.Tree(os.path.dirname(path)) except fmf.utils.RootError: raise ConvertError("Initialize metadata tree using 'fmf init'.") - # Store all metadata into a new main.fmf file - fmf_path = os.path.join(path, 'main.fmf') + # Store metadata into a fmf file try: - with open(fmf_path, 'w', encoding='utf-8') as fmf_file: + with open(path, 'w', encoding='utf-8') as fmf_file: yaml.safe_dump( data, fmf_file, encoding='utf-8', allow_unicode=True, indent=4, default_flow_style=False) except IOError: - raise ConvertError("Unable to write '{0}'".format(fmf_path)) + raise ConvertError("Unable to write '{0}'".format(path)) echo(style( - "Metadata successfully stored into '{0}'.".format(fmf_path), fg='red')) + "Metadata successfully stored into '{0}'.".format(path), fg='red')) From a33ffb8be44ad003275f93c67a1c710619f3d316 Mon Sep 17 00:00:00 2001 From: Jakub Heger Date: Tue, 14 Jan 2020 15:45:38 +0100 Subject: [PATCH 2/2] Move nitrate into its own function. Also some minor changes/fixes. --- tmt/cli.py | 2 +- tmt/convert.py | 27 ++++++++++++++++++++------- 2 files changed, 21 insertions(+), 8 deletions(-) diff --git a/tmt/cli.py b/tmt/cli.py index f556f1e961..f0efb60e7a 100644 --- a/tmt/cli.py +++ b/tmt/cli.py @@ -419,7 +419,7 @@ def convert(context, paths, makefile, nitrate, purpose, **kwargs): main_path = os.path.join(path, 'main.fmf') tmt.convert.write(main_path, data) for case in testcase_data: - case_path = os.path.join(path, str(case['tcms id']) + '.fmf') + case_path = os.path.join(path, str(case['tcms']) + '.fmf') tmt.convert.write(case_path, case) diff --git a/tmt/convert.py b/tmt/convert.py index cb4b001ce5..df57ce14a9 100644 --- a/tmt/convert.py +++ b/tmt/convert.py @@ -56,6 +56,7 @@ def read(path, makefile, nitrate, purpose): echo(style("Checking the '{0}' directory.".format(path), fg='red')) data = dict() + testcase_data = list() # Makefile (extract summary, component and duration) if makefile: @@ -101,17 +102,26 @@ def read(path, makefile, nitrate, purpose): # Nitrate (extract contact, environment and relevancy) if nitrate: + data, testcase_data = read_nitrate(test, data) + + log.debug('Gathered main.fmf metadata:\n' + pprint.pformat(data)) + log.debug('Gathered tcms case metadata:\n' + pprint.pformat(testcase_data)) + return data, testcase_data + + +def read_nitrate(test, data): + """ Read old metadata from nitrate test cases """ echo(style('Nitrate ', fg='blue'), nl=False) if test is None: raise ConvertError('No test name detected for nitrate search') if TestCase is None: raise ConvertError('Need nitrate module to import metadata') - testcases = list(TestCase.search(script=test)) + # Find testcases that have CONFIRMED status + testcases = list(TestCase.search(script=test, case_status=2)) if not testcases: raise ConvertError("No testcase found for '{0}'.".format(test)) elif len(testcases) > 1: - log.warn("Multiple test cases found for '{0}'.".format( - test)) + echo("Multiple test cases found for '{0}'.".format(test)) testcase_data = list() @@ -119,7 +129,7 @@ def read(path, makefile, nitrate, purpose): single_case_data = dict() echo("test case found '{0}'.".format(testcase.identifier)) # Test identifier - single_case_data['tcms id'] = testcase.identifier + single_case_data['tcms'] = testcase.identifier # Test name if testcase.summary: single_case_data['testname'] = '{}'.format( @@ -159,14 +169,17 @@ def read(path, makefile, nitrate, purpose): for key, value in common_candidates.items(): data[key] = value + # If there is only single testcase found there is no need to continue + if len(testcase_data) <= 1: + return data, [] + # Remove common data from individual fmfs - for common_key in list(common_candidates): + for common_key in common_candidates: for testcase in testcase_data: if common_key in testcase: testcase.pop(common_key) - log.debug('Gathered metadata:\n' + pprint.pformat(data)) - return data, testcase_data + return data, testcase_data def write(path, data):