From 378603c587f8c7e69166db1eeba477773593480a Mon Sep 17 00:00:00 2001 From: Agustin Henze Date: Wed, 23 Jan 2019 10:06:56 -0300 Subject: [PATCH 1/2] Add pretty_xml for check, reformat and reindent It uses xmllint if it's available, otherwise the content is not modified. --- kpet/run.py | 24 ++++++++++++++++++++++++ tests/test_run.py | 18 ++++++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/kpet/run.py b/kpet/run.py index 6579bb1..436655b 100644 --- a/kpet/run.py +++ b/kpet/run.py @@ -16,6 +16,8 @@ import tempfile import shutil import os +import subprocess +import distutils from kpet import utils, targeted @@ -50,6 +52,28 @@ def print_test_cases(patches, dbdir, pw_cookie=None): print(test_case) +def pretty_xml(xml_content): + """ + Check, reformat and reindent the xml content if xmllint is available, + otherwise return the content unchanged. + Args: + xml_content: Jinja template rendered + Returns: + An xml reformatted and reindented if xmllint is available. + """ + cmd = distutils.spawn.find_executable('xmllint') + if not cmd: + return xml_content + args = [cmd, '--format', '-'] + proc = subprocess.Popen(args, stdin=subprocess.PIPE, + stdout=subprocess.PIPE) + proc.stdin.write(xml_content.encode('utf-8')) + stdout, _ = proc.communicate() + if proc.poll() != 0: + raise subprocess.CalledProcessError(proc.returncode, ' '.join(args)) + return stdout.decode('utf-8') + + # pylint: disable=too-many-arguments def generate(template, template_params, patches, dbdir, output, pw_cookie=None): diff --git a/tests/test_run.py b/tests/test_run.py index f0b3b6c..bf3e99d 100644 --- a/tests/test_run.py +++ b/tests/test_run.py @@ -15,6 +15,7 @@ import os import tempfile import unittest +import subprocess import mock from kpet import run, utils, exceptions @@ -113,3 +114,20 @@ def test_get_test_cases(self, mock_get_test_cases): mock_get_test_cases.return_value = ['default/ltplite', 'fs/xfs'] test_cases = run.get_test_cases("", "") self.assertEqual(mock_get_test_cases.return_value, test_cases) + + @mock.patch('subprocess.Popen') + @mock.patch('distutils.spawn.find_executable') + def test_pretty_xml(self, mock_find_executable, mock_popen): + """ + Check command (xmllint mocked) is called if it is available and content + is modified. + """ + mock_find_executable.return_value = None + self.assertEqual('foobar', run.pretty_xml('foobar')) + + mock_find_executable.return_value = 'binary' + mock_popen().communicate.return_value = (b'stdout', b'') + self.assertRaises(subprocess.CalledProcessError, run.pretty_xml, 'bar') + + mock_popen().poll.return_value = 0 + self.assertEqual('stdout', run.pretty_xml('foobar')) From 7e3bbb4208812dbbae6940b289051e826219a78c Mon Sep 17 00:00:00 2001 From: Agustin Henze Date: Wed, 23 Jan 2019 18:53:42 +0100 Subject: [PATCH 2/2] Call to pretty_xml on generate --- kpet/run.py | 2 +- tests/test_kpet.py | 3 ++- tests/test_run.py | 3 ++- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/kpet/run.py b/kpet/run.py index 436655b..a082b1d 100644 --- a/kpet/run.py +++ b/kpet/run.py @@ -102,7 +102,7 @@ def generate(template, template_params, patches, dbdir, output, template_params['TEST_CASES_KICKSTART'] = sorted( targeted.get_property('kickstart', test_names, dbdir) ) - content = template.render(template_params) + content = pretty_xml(template.render(template_params)) if not output: print(content) else: diff --git a/tests/test_kpet.py b/tests/test_kpet.py index 05b15bb..5a5d22c 100644 --- a/tests/test_kpet.py +++ b/tests/test_kpet.py @@ -100,7 +100,8 @@ def test_exec_command(self): mock.call('Not implemented yet'), ) - def test_main(self): + @mock.patch('distutils.spawn.find_executable', return_value=None) + def test_main(self, mock_find_executable): """ Check --db is required and also run generate command executes successfully diff --git a/tests/test_run.py b/tests/test_run.py index bf3e99d..7df5473 100644 --- a/tests/test_run.py +++ b/tests/test_run.py @@ -22,7 +22,8 @@ class RunTest(unittest.TestCase): """Test cases for run module.""" - def test_generate(self): + @mock.patch('distutils.spawn.find_executable', return_value=None) + def test_generate(self, mock_find_executable): """ Check the success case, if it raises the proper exception when the type is not found and if it saves the output in a file instead