setup ci to do valgrind memcheck

This commit is contained in:
Priyesh Padmavilasom 2020-01-22 21:30:22 +00:00
parent 438dab474f
commit ccc22d80a1
7 changed files with 71 additions and 5 deletions

View File

@ -7,6 +7,6 @@ RUN dnf -q -y upgrade
RUN dnf -q -y install gcc make cmake libcurl-devel rpm-devel rpm-build libsolv-devel \
popt-devel sed createrepo_c glib2-devel libxml2 findutils \
python3-pytest python3-requests python3-urllib3 python3-pyOpenSSL \
python3 python3-devel
python3 python3-devel valgrind
CMD ["/bin/bash"]

View File

@ -6,7 +6,7 @@ RUN tdnf update -q -y
RUN tdnf remove -q -y toybox
RUN tdnf install -q -y build-essential cmake curl-devel rpm-build libsolv-devel \
popt-devel sed createrepo_c glib libxml2 findutils \
python3 python3-pip python3-setuptools python3-devel
python3 python3-pip python3-setuptools python3-devel valgrind
# python build/test dependencies
RUN pip3 install -q requests urllib3 pyOpenSSL pytest

View File

@ -5,5 +5,6 @@
"test_path": "@CMAKE_CURRENT_SOURCE_DIR@/pytests",
"sglversion_pkgname": "tdnf-test-one",
"mulversion_pkgname": "tdnf-test-multiversion",
"mulversion_lower": "1.0.1-1"
"mulversion_lower": "1.0.1-1",
"valgrind_minimum_version": "3.15.0"
}

View File

@ -17,6 +17,7 @@ import shutil
import ssl
import requests
import configparser
import distutils.spawn
from pprint import pprint
from urllib.parse import urlparse
from OpenSSL.crypto import load_certificate, FILETYPE_PEM
@ -49,6 +50,33 @@ class TestUtils(object):
self.run([ 'sh', script, self.config['repo_path'] ])
self.tdnf_config = configparser.ConfigParser()
self.tdnf_config.read(os.path.join(self.config['repo_path'], 'tdnf.conf'))
self.config['valgrind_enabled'] = False
#check execution environment and enable valgrind if suitable
self.check_valgrind()
def _version_number(self, version):
version_parts = version.split('.')
return version_parts[0] * 1000 + version_parts[1] * 100 + version_parts[2]
#valgrind versions less than minimum required might not
#support all the options specified or might have known
#errors
def check_valgrind(self):
valgrind = distutils.spawn.find_executable('valgrind')
if not valgrind:
self.config['valgrind_disabled_reason'] = 'valgrind not found'
else:
stream = os.popen(valgrind + ' --version') #nosec
valgrind_version = stream.read()
if valgrind_version:
valgrind_version = valgrind_version.replace('valgrind-', '')
valgrind_minimum_version = self.config['valgrind_minimum_version']
if self._version_number(valgrind_version) >= \
self._version_number(valgrind_minimum_version):
self.config['valgrind_enabled'] = True
else:
self.config['valgrind_disabled_reason'] = \
'valgrind minimum version required: ' + valgrind_minimum_version
def assert_file_exists(self, file_path):
if not os.path.isfile(file_path):
@ -120,19 +148,41 @@ class TestUtils(object):
shutil.copyfileobj(r.raw, f)
return True, None
def run(self, cmd):
def _decorate_tdnf_cmd_for_test(self, cmd):
if cmd[0] is 'tdnf':
if 'build_dir' in self.config:
cmd[0] = os.path.join(self.config['build_dir'], 'bin/tdnf')
if cmd[1] is not '--config':
cmd.insert(1, '-c')
cmd.insert(2, os.path.join(self.config['repo_path'], 'tdnf.conf'))
def _skip_if_valgrind_disabled(self):
if not self.config['valgrind_enabled']:
pytest.skip(self.config['valgrind_disabled_reason'])
def run_memcheck(self, cmd):
self._skip_if_valgrind_disabled()
self._decorate_tdnf_cmd_for_test(cmd)
memcheck_cmd = ['valgrind',
'--leak-check=full',
'--exit-on-first-error=yes',
'--error-exitcode=1']
return self._run(memcheck_cmd + cmd, retvalonly=True)
def run(self, cmd):
self._decorate_tdnf_cmd_for_test(cmd)
return self._run(cmd)
def _run(self, cmd, retvalonly=False):
use_shell = not isinstance(cmd, list)
process = subprocess.Popen(cmd, shell=use_shell,
process = subprocess.Popen(cmd, shell=use_shell, #nosec
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
#process.wait()
out, err = process.communicate()
if retvalonly:
return {'retval':process.returncode}
stdout = out.decode().strip()
stderr = err.decode().strip()
retval = process.returncode

View File

@ -22,3 +22,8 @@ def teardown_test(utils):
def test_count(utils):
ret = utils.run([ 'tdnf', 'count' ])
assert(ret['retval'] == 0)
#memcheck
def test_count_memcheck(utils):
ret = utils.run_memcheck(['tdnf', 'count'])
assert(ret['retval'] == 0)

View File

@ -38,3 +38,8 @@ def test_repolist_disabled(utils):
def test_repolist_invalid(utils):
ret = utils.run([ 'tdnf', 'repolist', 'invalid_repo' ])
assert(ret['retval'] == 901)
#memcheck
def test_repolist_memcheck(utils):
ret = utils.run_memcheck(['tdnf', 'repolist'])
assert(ret['retval'] == 0)

View File

@ -22,3 +22,8 @@ def test_version(utils):
ret = utils.run([ 'tdnf', '--version' ])
assert(ret['retval'] == 0)
assert(ret['stdout'][0] == expected_version_string)
#memcheck
def test_version_memcheck(utils):
ret = utils.run_memcheck([ 'tdnf', '--version' ])
assert(ret['retval'] == 0)