diff --git a/tests/integration/states/pkg.py b/tests/integration/states/pkg.py index a4e4fa01db4a..fdf12a722366 100644 --- a/tests/integration/states/pkg.py +++ b/tests/integration/states/pkg.py @@ -52,6 +52,63 @@ } +def pkgmgr_avail(run_function, grains): + ''' + Return True if the package manager is available for use + ''' + def proc_fd_lsof(path): + ''' + Return True if any entry in /proc/locks points to path. Example data: + + .. code-block:: bash + + # cat /proc/locks + 1: FLOCK ADVISORY WRITE 596 00:0f:10703 0 EOF + 2: FLOCK ADVISORY WRITE 14590 00:0f:11282 0 EOF + 3: POSIX ADVISORY WRITE 653 00:0f:11422 0 EOF + ''' + import glob + # https://www.centos.org/docs/5/html/5.2/Deployment_Guide/s2-proc-locks.html + locks = run_function('cmd.run', ['cat /proc/locks']).splitlines() + for line in locks: + fields = line.split() + try: + major, minor, inode = fields[5].split(':') + inode = int(inode) + except (IndexError, ValueError): + return False + + for fd in glob.glob('/proc/*/fd'): + fd_path = os.path.realpath(fd) + # If the paths match and the inode is locked + if fd_path == path and os.stat(fd_path).st_ino == inode: + return True + + return False + + def get_lock(path): + ''' + Return True if any locks are found for path + ''' + # Try lsof if it's available + if salt.utils.which('lsof'): + lock = run_function('cmd.run', ['lsof {0}'.format(path)]) + return True if len(lock) else False + + # Try to find any locks on path from /proc/locks + elif grains.get('kernel') == 'Linux': + return proc_fd_lsof(path) + + return False + + if 'Debian' in grains.get('os_family', ''): + for path in ['/var/lib/apt/lists/lock']: + if get_lock(path): + return False + + return True + + @destructiveTest @requires_salt_modules('pkg.version', 'pkg.latest_version') class PkgTest(integration.ModuleCase, @@ -65,6 +122,10 @@ def test_pkg_001_installed(self, grains=None): ''' This is a destructive test as it installs and then removes a package ''' + # Skip test if package manager not available + if not pkgmgr_avail(self.run_function, self.run_function('grains.items')): + self.skipTest('Package manager is not available') + os_family = grains.get('os_family', '') pkg_targets = _PKG_TARGETS.get(os_family, []) @@ -92,6 +153,10 @@ def test_pkg_002_installed_with_version(self, grains=None): ''' This is a destructive test as it installs and then removes a package ''' + # Skip test if package manager not available + if not pkgmgr_avail(self.run_function, self.run_function('grains.items')): + self.skipTest('Package manager is not available') + os_family = grains.get('os_family', '') pkg_targets = _PKG_TARGETS.get(os_family, []) @@ -133,6 +198,10 @@ def test_pkg_003_installed_multipkg(self, grains=None): ''' This is a destructive test as it installs and then removes two packages ''' + # Skip test if package manager not available + if not pkgmgr_avail(self.run_function, self.run_function('grains.items')): + self.skipTest('Package manager is not available') + os_family = grains.get('os_family', '') pkg_targets = _PKG_TARGETS.get(os_family, []) @@ -145,7 +214,7 @@ def test_pkg_003_installed_multipkg(self, grains=None): # If this assert fails, we need to find new targets, this test needs to # be able to test successful installation of packages, so these # packages need to not be installed before we run the states below -# self.assertFalse(any(version.values())) + #self.assertFalse(any(version.values())) ret = self.run_state('pkg.installed', name=None, pkgs=pkg_targets) self.assertSaltTrueReturn(ret) @@ -158,6 +227,10 @@ def test_pkg_004_installed_multipkg_with_version(self, grains=None): ''' This is a destructive test as it installs and then removes two packages ''' + # Skip test if package manager not available + if not pkgmgr_avail(self.run_function, self.run_function('grains.items')): + self.skipTest('Package manager is not available') + os_family = grains.get('os_family', '') pkg_targets = _PKG_TARGETS.get(os_family, []) @@ -200,6 +273,10 @@ def test_pkg_005_installed_32bit(self, grains=None): ''' This is a destructive test as it installs and then removes a package ''' + # Skip test if package manager not available + if not pkgmgr_avail(self.run_function, self.run_function('grains.items')): + self.skipTest('Package manager is not available') + os_name = grains.get('os', '') target = _PKG_TARGETS_32.get(os_name, '') @@ -231,6 +308,10 @@ def test_pkg_006_installed_32bit_with_version(self, grains=None): ''' This is a destructive test as it installs and then removes a package ''' + # Skip test if package manager not available + if not pkgmgr_avail(self.run_function, self.run_function('grains.items')): + self.skipTest('Package manager is not available') + os_name = grains.get('os', '') target = _PKG_TARGETS_32.get(os_name, '') @@ -274,6 +355,10 @@ def test_pkg_007_with_dot_in_pkgname(self, grains=None): This is a destructive test as it installs a package ''' + # Skip test if package manager not available + if not pkgmgr_avail(self.run_function, self.run_function('grains.items')): + self.skipTest('Package manager is not available') + os_family = grains.get('os_family', '') os_version = grains.get('osmajorrelease', [''])[0] target = _PKG_TARGETS_DOT.get(os_family, {}).get(os_version) @@ -298,6 +383,10 @@ def test_pkg_with_epoch_in_version(self, grains=None): This is a destructive test as it installs a package ''' + # Skip test if package manager not available + if not pkgmgr_avail(self.run_function, self.run_function('grains.items')): + self.skipTest('Package manager is not available') + os_family = grains.get('os_family', '') os_version = grains.get('osmajorrelease', [''])[0] target = _PKG_TARGETS_EPOCH.get(os_family, {}).get(os_version) @@ -322,6 +411,9 @@ def test_pkg_008_latest_with_epoch(self): This is a destructive test as it installs a package ''' + # Skip test if package manager not available + if not pkgmgr_avail(self.run_function, self.run_function('grains.items')): + self.skipTest('Package manager is not available') ret = self.run_function('state.sls', mods='pkg_latest_epoch') self.assertSaltTrueReturn(ret) @@ -335,6 +427,9 @@ def test_pkg_009_latest_with_epoch_and_info_installed(self): a seperate method so I can add the requires_salt_modules decorator to only the pkg.info_installed command. ''' + # Skip test if package manager not available + if not pkgmgr_avail(self.run_function, self.run_function('grains.items')): + self.skipTest('Package manager is not available') package = 'bash-completion' pkgquery = 'version'