[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: a new tool fedabipkgdiff
Hello,
Dodji Seketeli <dodji@redhat.com> a Ãcrit:
[...]
>> --- /dev/null
>> +++ b/tests/runtestfedabipkgdiff.sh
[...]
>> @@ -0,0 +1,5 @@
>> +#!/usr/bin/bash
>> +
>> +export FEDABIPKGDIFF_TESTS=1
>> +
>> +../../tools/fedabipkgdiff
>
> Actually, I think the runtestfedabipkgdiff.sh could be a proper python
> script that contains the actual unit tests of fedabipkgdiff, rather than
> having the unit tests be in the fedabipkgdiff file itself.
>
> That file would then load (using the imp.load_source() function from the
> python standard library) by specifying the path to the the fedabipkgdiff
> from the source, so that "make check" uses the fedabipkgdiff from the
> sources and not the one that might already be installed on the
> system. There is a potentially a little bit of autoconf magic to do
> here, but I can help you here for the details.
I finally did it. I am attaching the patch at the end of this message.
The patch is also available in my "dodji/fedabipkgdiff" branch at https://sourceware.org/git/gitweb.cgi?p=libabigail.git;a=commitdiff;h=246f4f3280d8b96911d4ef2676f0d46ff66b0681
What do you think?
>From 246f4f3280d8b96911d4ef2676f0d46ff66b0681 Mon Sep 17 00:00:00 2001
From: Dodji Seketeli <dodji@redhat.com>
Date: Sat, 20 Feb 2016 12:42:04 +0100
Subject: [PATCH 3/3] Move unit tests from fedabipkgdiff to
runtestfedabipkgdiff.py
The fedabipkgdiff program used to contain unit tests for many of its
functions. This patch moves these unit tests out of the
tools/fedabipkgdiff program file, to the IMHO more appropriate
location tests/runtestfedabipkgdiff.py. The later file starts by
loading the tools/fedabipkgdiff program. The unit test code it
contains then tests the functions of the program that has just been
loaded. I believe this separation decreases the clutter of
fedabipkgdiff and thus increases its maintainability.
Note that tests/runtestfedabipkgdiff.py is now generated by autoconf
inside the build directory. To do that, autoconf takes the pattern
file tests/runtestfedabipkgdiff.py.in from the source directory and
replaces variables like @top_srcdir@ by their actual value. The
result is a tests/runtestfedabipkgdiff.py file which is a proper
executable python program that is executed when the user invokes the
standard "make check" command from the build directory. Of course,
parallel checking still works too, by doing "make -j8 check" if your
system has eight cores, for instance.
The patch passes "make distcheck" too.
* configure.ac: Add check for prerequisite python modules
itertools, shutil, unittest and mock. These are necessary for the
unit test of fedabipkgdiff. Generate
tests/runtestfedabipkgdiff.py into the build directory, from the
tests/runtestfedabipkgdiff.py.in input file.
* tests/Makefile.am: Rename runtestfedabipkgdiff.sh into
runtestfedabipkgdiff.py. Add the new runtestfedabipkgdiff.py.in
autoconf template file in here.
* tests/runtestfedabipkgdiff.py.in: New unit test file.
* tests/runtestfedabipkgdiff.sh: Remove.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
---
configure.ac | 9 +-
tests/Makefile.am | 8 +-
tests/runtestfedabipkgdiff.py.in | 335 +++++++++++++++++++++++++++++++++++++++
tests/runtestfedabipkgdiff.sh | 5 -
4 files changed, 347 insertions(+), 10 deletions(-)
create mode 100755 tests/runtestfedabipkgdiff.py.in
delete mode 100755 tests/runtestfedabipkgdiff.sh
diff --git a/configure.ac b/configure.ac
index 687a2ca..17bfe30 100644
--- a/configure.ac
+++ b/configure.ac
@@ -285,7 +285,11 @@ if test x$CHECK_DEPS_FOR_FEDABIPKGDIFF = xyes; then
AX_PYTHON_MODULE(sys, $FATAL, python2)
AX_PYTHON_MODULE(itertools, $FATAL, python2)
AX_PYTHON_MODULE(urlparse, $FATAL, python2)
+ AX_PYTHON_MODULE(itertools, $FATAL, python2)
+ AX_PYTHON_MODULE(shutil, $FATAL, python2)
+ AX_PYTHON_MODULE(unittest, $FATAL, python2)
AX_PYTHON_MODULE(koji, $FATAL, python2)
+ AX_PYTHON_MODULE(mock, $FATAL, python2)
ENABLE_FEDABIPKGDIFF=yes
if test x$ENABLE_FEDABIPKGDIFF != xyes; then
@@ -437,7 +441,10 @@ libabigail.pc
bash-completion/Makefile])
dnl Some test scripts are generated by autofoo.
-AC_CONFIG_FILES([tests/runtestcanonicalizetypes.sh], [chmod +x tests/runtestcanonicalizetypes.sh])
+AC_CONFIG_FILES([tests/runtestcanonicalizetypes.sh],
+ [chmod +x tests/runtestcanonicalizetypes.sh])
+AC_CONFIG_FILES([tests/runtestfedabipkgdiff.py],
+ [chmod +x tests/runtestfedabipkgdiff.py])
AC_OUTPUT
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 958995c..953dfef 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -31,10 +31,10 @@ runtestlookupsyms \
runtestaltdwarf \
runtestcorediff \
runtestabidiffexit \
-runtestfedabipkgdiff.sh \
+runtestfedabipkgdiff.py \
$(CXX11_TESTS)
-EXTRA_DIST = runtestcanonicalizetypes.sh.in
+EXTRA_DIST = runtestcanonicalizetypes.sh.in runtestfedabipkgdiff.py.in
CLEANFILES = \
runtestcanonicalizetypes.output.txt \
runtestcanonicalizetypes.output.final.txt
@@ -115,8 +115,8 @@ printdifftree_LDADD = $(top_builddir)/src/libabigail.la
runtestcanonicalizetypes_sh_SOURCES =
runtestcanonicalizetypes.sh$(EXEEXT):
-runtestfedabipkgdiff_sh_SOURCES =
-runtestfedabipkgdiff.sh$(EXEEXT):
+runtestfedabipkgdiff_py_SOURCES =
+runtestfedabipkgdiff.py$(EXEEXT):
AM_CPPFLAGS=-I${abs_top_srcdir}/include \
-I${abs_top_builddir}/include -I${abs_top_srcdir}/tools -fPIC
diff --git a/tests/runtestfedabipkgdiff.py.in b/tests/runtestfedabipkgdiff.py.in
new file mode 100755
index 0000000..7842cc9
--- /dev/null
+++ b/tests/runtestfedabipkgdiff.py.in
@@ -0,0 +1,335 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+# -*- Mode: Python
+#
+# This file is part of the GNU Application Binary Interface Generic
+# Analysis and Instrumentation Library. This program is free
+# software; you can redistribute it and/or modify it under the terms
+# of the GNU General Public License as published by the Free Software
+# Foundation; either version 3, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Lesser Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this program; see the file COPYING-LGPLV3. If
+# not, see <http://www.gnu.org/licenses/>.
+#
+# Author: Chenxiong Qi
+
+import os
+import itertools
+import shutil
+import unittest
+
+try:
+ from mock import patch
+except ImportError:
+ print >>sys.stderr, \
+ 'mock is not installed. Please install it before running tests.'
+ sys.exit(1)
+
+import imp
+# Import the fedabipkgdiff program file from the source directory.
+fedabidiff_mod = imp.load_source('fedabidiff',
+ '@top_srcdir@/tools/fedabipkgdiff')
+
+counter = itertools.count(0)
+
+class UtilsTest(unittest.TestCase):
+
+ def test_is_fedora_distro(self):
+ distro = 'fc5'
+ self.assertTrue(fedabidiff_mod.is_fedora_distro(distro))
+
+ distro = 'f5'
+ self.assertFalse(fedabidiff_mod.is_fedora_distro(distro))
+
+ distro = 'fc23'
+ self.assertTrue(fedabidiff_mod.is_fedora_distro(distro))
+
+ distro = 'fc'
+ self.assertFalse(fedabidiff_mod.is_fedora_distro(distro))
+
+ distro = 'fc234'
+ self.assertFalse(fedabidiff_mod.is_fedora_distro(distro))
+
+
+class RunAbipkgdiffTest(unittest.TestCase):
+ """Test case for method run_abipkgdiff"""
+
+ def setUp(self):
+ self.pkg1_single_info = {
+ 'i686': [{'downloaded_rpm_file': 'dummy file path'},
+ {'downloaded_rpm_file': 'dummy file path'}],
+ }
+
+ self.pkg2_single_info = {
+ 'i686': [{'downloaded_rpm_file': 'dummy file path'},
+ {'downloaded_rpm_file': 'dummy file path'}],
+ }
+
+ self.pkg1_infos = {
+ 'i686': [{'downloaded_rpm_file': 'dummy file path'},
+ {'downloaded_rpm_file': 'dummy file path'}],
+ 'x86_64': [{'downloaded_rpm_file': 'dummy file path'},
+ {'downloaded_rpm_file': 'dummy file path'}],
+ 'armv7hl': [{'downloaded_rpm_file': 'dummy file path'},
+ {'downloaded_rpm_file': 'dummy file path'}],
+ }
+
+ self.pkg2_infos = {
+ 'i686': [{'downloaded_rpm_file': 'dummy file path'},
+ {'downloaded_rpm_file': 'dummy file path'}],
+ 'x86_64': [{'downloaded_rpm_file': 'dummy file path'},
+ {'downloaded_rpm_file': 'dummy file path'}],
+ 'armv7hl': [{'downloaded_rpm_file': 'dummy file path'},
+ {'downloaded_rpm_file': 'dummy file path'}],
+ }
+
+ @patch('fedabidiff.abipkgdiff')
+ def test_all_success(self, mock_abipkgdiff):
+ mock_abipkgdiff.return_value = 0
+
+ result = fedabidiff_mod.run_abipkgdiff(self.pkg1_single_info,
+ self.pkg2_single_info)
+ self.assertEquals(0, result)
+
+ result = fedabidiff_mod.run_abipkgdiff(self.pkg1_infos, self.pkg2_infos)
+ self.assertEquals(0, result)
+
+ @patch('fedabidiff.abipkgdiff')
+ def test_all_failure(self, mock_abipkgdiff):
+ mock_abipkgdiff.return_value = 4
+
+ result = fedabidiff_mod.run_abipkgdiff(self.pkg1_single_info,
+ self.pkg2_single_info)
+ self.assertEquals(4, result)
+
+ result = fedabidiff_mod.run_abipkgdiff(self.pkg1_infos, self.pkg2_infos)
+ self.assertEquals(4, result)
+
+ @patch('fedabidiff.abipkgdiff', new=lambda param1, param2: counter.next())
+ def test_partial_failure(self):
+ result = fedabidiff_mod.run_abipkgdiff(self.pkg1_infos, self.pkg2_infos)
+ self.assertTrue(result > 0)
+
+
+fake_rpm_file = 'foo-0.1-1.fc24.x86_64.rpm'
+fake_debuginfo_rpm_file = 'foo-debuginfo-0.1-1.fc24.x86_64.rpm'
+
+
+class MockGlobalConfig(object):
+ koji_server = fedabidiff_mod.DEFAULT_KOJI_SERVER
+
+
+def mock_get_session():
+ return MockKojiClientSession(baseurl=fedabidiff_mod.DEFAULT_KOJI_SERVER)
+
+
+class MockKojiClientSession(object):
+
+ def __init__(self, *args, **kwargs):
+ """Accept arbitrary parameters but do nothing for this mock"""
+ self.args = args
+ self.kwargs = kwargs
+
+ def getPackage(self, *args, **kwargs):
+ return {
+ 'id': 1,
+ 'name': 'whatever a name of a package',
+ }
+
+ def listRPMs(self, *args, **kwargs):
+ return [{'arch': 'i686',
+ 'name': 'httpd-debuginfo',
+ 'nvr': 'httpd-debuginfo-2.4.18-1.fc22',
+ 'release': '1.fc22',
+ 'version': '2.4.18'},
+ {'arch': 'i686',
+ 'name': 'mod_session',
+ 'nvr': 'mod_session-2.4.18-1.fc22',
+ 'release': '1.fc22',
+ 'version': '2.4.18'},
+ {'arch': 'i686',
+ 'name': 'httpd',
+ 'nvr': 'httpd-2.4.18-1.fc22',
+ 'release': '1.fc22',
+ 'version': '2.4.18'},
+ {'arch': 'i686',
+ 'name': 'mod_proxy_html',
+ 'nvr': 'mod_proxy_html-2.4.18-1.fc22',
+ 'release': '1.fc22',
+ 'version': '2.4.18'},
+ {'arch': 'i686',
+ 'name': 'mod_ldap',
+ 'nvr': 'mod_ldap-2.4.18-1.fc22',
+ 'release': '1.fc22',
+ 'version': '2.4.18'},
+ {'arch': 'i686',
+ 'name': 'mod_ssl',
+ 'nvr': 'mod_ssl-2.4.18-1.fc22',
+ 'release': '1.fc22',
+ 'version': '2.4.18'}]
+
+ def listBuilds(self, *args, **kwargs):
+ return [
+ {'build_id': 720222,
+ 'name': 'httpd',
+ 'nvr': 'httpd-2.4.18-2.fc24',
+ 'release': '2.fc24',
+ 'version': '2.4.18'},
+ {'build_id': 708769,
+ 'name': 'httpd',
+ 'nvr': 'httpd-2.4.18-1.fc22',
+ 'release': '1.fc22',
+ 'version': '2.4.18'},
+ {'build_id': 708711,
+ 'name': 'httpd',
+ 'nvr': 'httpd-2.4.18-1.fc23',
+ 'release': '1.fc23',
+ 'version': '2.4.18'},
+ {'build_id': 705335,
+ 'name': 'httpd',
+ 'nvr': 'httpd-2.4.18-1.fc24',
+ 'release': '1.fc24',
+ 'version': '2.4.18'},
+ {'build_id': 704434,
+ 'name': 'httpd',
+ 'nvr': 'httpd-2.4.17-4.fc24',
+ 'release': '4.fc24',
+ 'version': '2.4.17'},
+ {'build_id': 704433,
+ 'name': 'httpd',
+ 'nvr': 'httpd-2.4.17-4.fc23',
+ 'release': '4.fc23',
+ 'version': '2.4.17'},
+ ]
+
+
+class SelectRpmsFromABuildTest(unittest.TestCase):
+ """Test case for select_rpms_from_a_build"""
+
+ def assert_rpms(self, rpms):
+ for item in rpms:
+ self.assertTrue(item['arch'] in ['i686', 'x86_64'])
+ self.assertTrue(item['name'] in ('httpd', 'httpd-debuginfo'))
+
+ @patch('fedabidiff.Brew.listRPMs')
+ @patch('fedabidiff.global_config', new=MockGlobalConfig)
+ def test_select_rpms_from_all_arches(self, mock_listRPMs):
+ mock_listRPMs.return_value = [
+ {'arch': 'i686',
+ 'name': 'httpd-debuginfo',
+ 'release': '1.fc22',
+ 'version': '2.4.18'},
+ {'arch': 'i686',
+ 'name': 'httpd',
+ 'release': '1.fc22',
+ 'version': '2.4.18'},
+ {'arch': 'x86_64',
+ 'name': 'httpd-debuginfo',
+ 'release': '1.fc22',
+ 'version': '2.4.18'},
+ {'arch': 'x86_64',
+ 'name': 'httpd',
+ 'release': '1.fc22',
+ 'version': '2.4.18'},
+ ]
+
+ session = fedabidiff_mod.get_session()
+ rpms = session.select_rpms_from_a_build(1, 'httpd')
+ self.assert_rpms(rpms)
+
+ @patch('fedabidiff.Brew.listRPMs')
+ @patch('fedabidiff.global_config', new=MockGlobalConfig)
+ def test_select_rpms_from_one_arch(self, mock_listRPMs):
+ mock_listRPMs.return_value = [
+ {'arch': 'i686',
+ 'name': 'httpd-debuginfo',
+ 'release': '1.fc22',
+ 'version': '2.4.18'},
+ {'arch': 'i686',
+ 'name': 'httpd',
+ 'release': '1.fc22',
+ 'version': '2.4.18'},
+ ]
+
+ session = fedabidiff_mod.get_session()
+ rpms = session.select_rpms_from_a_build(1, 'httpd')
+ self.assert_rpms(rpms)
+
+
+class GetPackageLatestBuildTest(unittest.TestCase):
+ """Test case for get_package_latest_build"""
+
+ @patch('fedabidiff.global_config', new=MockGlobalConfig)
+ @patch('koji.ClientSession', new=MockKojiClientSession)
+ def test_get_latest_one(self):
+ session = fedabidiff_mod.get_session()
+ build = session.get_package_latest_build('httpd', 'fc23')
+ self.assertEquals('httpd-2.4.18-1.fc23', build['nvr'])
+
+ @patch('fedabidiff.global_config', new=MockGlobalConfig)
+ @patch('koji.ClientSession', new=MockKojiClientSession)
+ def test_fail_to_find_latest_build(self):
+ session = fedabidiff_mod.get_session()
+ latest_build = session.get_package_latest_build('httpd', 'xxxx')
+ self.assertEquals(None, latest_build)
+
+
+class BrewListRPMsTest(unittest.TestCase):
+ """Test case for Brew.listRPMs"""
+
+ @patch('fedabidiff.global_config', new=MockGlobalConfig)
+ @patch('fedabidiff.koji.ClientSession', new=MockKojiClientSession)
+ def test_select_specific_rpms(self):
+ session = fedabidiff_mod.get_session()
+ selector = lambda rpm: rpm['name'].startswith('httpd')
+ rpms = session.listRPMs(buildID=1000, selector=selector)
+ self.assertTrue(
+ len(rpms) > 0,
+ 'More than one rpms should be selected. But, it\'s empty.')
+ for rpm in rpms:
+ self.assertTrue(rpm['name'] in ('httpd', 'httpd-debuginfo'),
+ '{0} should not be selected'.format(rpm['name']))
+
+
+class FindLocalDebuginfoRPMTest(unittest.TestCase):
+ """Test case for find_local_debuginfo_rpm"""
+
+ def setUp(self):
+ # FIXME: is it possible to patch glob or the underlying methods glob
+ # depends on
+ self.test_dir = './test_dir'
+ os.makedirs(self.test_dir)
+ os.system('touch {0}'.format(
+ os.path.join(self.test_dir, fake_debuginfo_rpm_file)))
+ os.system('touch {0}'.format(
+ os.path.join(self.test_dir,
+ fake_debuginfo_rpm_file.replace('foo', 'another'))))
+
+ def tearDown(self):
+ shutil.rmtree(self.test_dir)
+
+ def test_find_debuginfo_rpm(self):
+ debuginfo_rpm = fedabidiff_mod.find_local_debuginfo_rpm(
+ os.path.join(self.test_dir, fake_rpm_file))
+
+ expected_debuginfo_rpm_file = os.path.abspath(
+ os.path.join(self.test_dir,
+ fake_debuginfo_rpm_file))
+ self.assertEquals(expected_debuginfo_rpm_file, debuginfo_rpm)
+
+ def test_no_suitable_debuginfo_rpm(self):
+ debuginfo_rpm = fedabidiff_mod.find_local_debuginfo_rpm(
+ os.path.join(self.test_dir, 'abc-0.1-1.i686.rpm'))
+ self.assertEquals(None, debuginfo_rpm)
+
+
+invoked_from_cmd = __name__ == '__main__'
+
+if invoked_from_cmd:
+ unittest.main()
diff --git a/tests/runtestfedabipkgdiff.sh b/tests/runtestfedabipkgdiff.sh
deleted file mode 100755
index 4144419..0000000
--- a/tests/runtestfedabipkgdiff.sh
+++ /dev/null
@@ -1,5 +0,0 @@
-#!/usr/bin/bash
-
-export FEDABIPKGDIFF_TESTS=1
-
-../../tools/fedabipkgdiff
\ No newline at end of file
--
1.8.3.1
--
Dodji