Add RPM class implementation
implements blueprint rpm-integration Change-Id: I4aa06c75b555d0c9ab54791b25c612bc5c5805fc
This commit is contained in:
@@ -20,3 +20,4 @@ iso8601
|
|||||||
oslo.config>=1.1.0
|
oslo.config>=1.1.0
|
||||||
jsonschema>=1.0.0,!=1.4.0,<2
|
jsonschema>=1.0.0,!=1.4.0,<2
|
||||||
Jinja2
|
Jinja2
|
||||||
|
pexpect
|
||||||
|
|||||||
@@ -16,7 +16,6 @@ http://tarballs.openstack.org/python-troveclient/python-troveclient-master.tar.g
|
|||||||
mock
|
mock
|
||||||
mox
|
mox
|
||||||
testtools>=0.9.22
|
testtools>=0.9.22
|
||||||
pexpect
|
|
||||||
discover
|
discover
|
||||||
testrepository>=0.0.8
|
testrepository>=0.0.8
|
||||||
mockito
|
mockito
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ from trove.common import utils as utils
|
|||||||
from trove.common import exception
|
from trove.common import exception
|
||||||
from trove.guestagent import query
|
from trove.guestagent import query
|
||||||
from trove.guestagent.db import models
|
from trove.guestagent.db import models
|
||||||
from trove.guestagent.pkg import Package
|
from trove.guestagent import pkg
|
||||||
from trove.instance import models as rd_models
|
from trove.instance import models as rd_models
|
||||||
from trove.openstack.common import log as logging
|
from trove.openstack.common import log as logging
|
||||||
from trove.openstack.common.gettextutils import _
|
from trove.openstack.common.gettextutils import _
|
||||||
@@ -39,7 +39,7 @@ INCLUDE_MARKER_OPERATORS = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
# Create a package impl
|
# Create a package impl
|
||||||
pkg = Package()
|
packager = pkg.Package()
|
||||||
|
|
||||||
|
|
||||||
def generate_random_password():
|
def generate_random_password():
|
||||||
@@ -678,7 +678,7 @@ class MySqlApp(object):
|
|||||||
def _install_mysql(self):
|
def _install_mysql(self):
|
||||||
"""Install mysql server. The current version is 5.5"""
|
"""Install mysql server. The current version is 5.5"""
|
||||||
LOG.debug(_("Installing mysql server"))
|
LOG.debug(_("Installing mysql server"))
|
||||||
pkg.pkg_install(self.MYSQL_PACKAGE_VERSION, self.TIME_OUT)
|
packager.pkg_install(self.MYSQL_PACKAGE_VERSION, self.TIME_OUT)
|
||||||
LOG.debug(_("Finished installing mysql server"))
|
LOG.debug(_("Finished installing mysql server"))
|
||||||
#TODO(rnirmal): Add checks to make sure the package got installed
|
#TODO(rnirmal): Add checks to make sure the package got installed
|
||||||
|
|
||||||
@@ -698,6 +698,8 @@ class MySqlApp(object):
|
|||||||
command = command % locals()
|
command = command % locals()
|
||||||
else:
|
else:
|
||||||
command = "sudo update-rc.d mysql enable"
|
command = "sudo update-rc.d mysql enable"
|
||||||
|
if pkg.OS == pkg.REDHAT:
|
||||||
|
command = "sudo chkconfig mysql on"
|
||||||
utils.execute_with_timeout(command, shell=True)
|
utils.execute_with_timeout(command, shell=True)
|
||||||
|
|
||||||
def _disable_mysql_on_boot(self):
|
def _disable_mysql_on_boot(self):
|
||||||
@@ -716,6 +718,8 @@ class MySqlApp(object):
|
|||||||
command = command % locals()
|
command = command % locals()
|
||||||
else:
|
else:
|
||||||
command = "sudo update-rc.d mysql disable"
|
command = "sudo update-rc.d mysql disable"
|
||||||
|
if pkg.OS == pkg.REDHAT:
|
||||||
|
command = "sudo chkconfig mysql off"
|
||||||
utils.execute_with_timeout(command, shell=True)
|
utils.execute_with_timeout(command, shell=True)
|
||||||
|
|
||||||
def stop_db(self, update_db=False, do_not_start_on_reboot=False):
|
def stop_db(self, update_db=False, do_not_start_on_reboot=False):
|
||||||
@@ -869,7 +873,7 @@ class MySqlApp(object):
|
|||||||
|
|
||||||
def is_installed(self):
|
def is_installed(self):
|
||||||
#(cp16net) could raise an exception, does it need to be handled here?
|
#(cp16net) could raise an exception, does it need to be handled here?
|
||||||
version = pkg.pkg_version(self.MYSQL_PACKAGE_VERSION)
|
version = packager.pkg_version(self.MYSQL_PACKAGE_VERSION)
|
||||||
return not version is None
|
return not version is None
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -34,6 +34,13 @@ LOG = logging.getLogger(__name__)
|
|||||||
OK = 0
|
OK = 0
|
||||||
RUN_DPKG_FIRST = 1
|
RUN_DPKG_FIRST = 1
|
||||||
REINSTALL_FIRST = 2
|
REINSTALL_FIRST = 2
|
||||||
|
REDHAT = 'redhat'
|
||||||
|
DEBIAN = 'debian'
|
||||||
|
|
||||||
|
# The default is debian
|
||||||
|
OS = DEBIAN
|
||||||
|
if os.path.isfile("/etc/redhat-release"):
|
||||||
|
OS = REDHAT
|
||||||
|
|
||||||
|
|
||||||
class PkgAdminLockError(exception.TroveError):
|
class PkgAdminLockError(exception.TroveError):
|
||||||
@@ -56,34 +63,41 @@ class PkgTimeout(exception.TroveError):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class RedhatPackagerMixin:
|
class PkgScriptletError(exception.TroveError):
|
||||||
|
pass
|
||||||
def pkg_install(self, package_name, time_out):
|
|
||||||
pass
|
|
||||||
|
|
||||||
def pkg_version(self, package_name):
|
|
||||||
return "1.0"
|
|
||||||
|
|
||||||
def pkg_remove(self, package_name, time_out):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class DebianPackagerMixin:
|
class PkgTransactionCheckError(exception.TroveError):
|
||||||
|
pass
|
||||||
|
|
||||||
def kill_proc(self, child):
|
|
||||||
|
class PkgDownloadError(exception.TroveError):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class BasePackagerMixin:
|
||||||
|
|
||||||
|
def pexpect_kill_proc(self, child):
|
||||||
child.delayafterclose = 1
|
child.delayafterclose = 1
|
||||||
child.delayafterterminate = 1
|
child.delayafterterminate = 1
|
||||||
child.close(force=True)
|
child.close(force=True)
|
||||||
|
|
||||||
def wait_and_close_proc(self, child, time_out=-1):
|
def pexpect_wait_and_close_proc(self, child, time_out=-1):
|
||||||
child.expect(pexpect.EOF, timeout=time_out)
|
child.expect(pexpect.EOF, timeout=time_out)
|
||||||
child.close()
|
child.close()
|
||||||
|
|
||||||
def _fix(self, time_out):
|
def pexpect_run(self, cmd, output_expects, time_out):
|
||||||
"""Sometimes you have to run this command before a pkg will install."""
|
child = pexpect.spawn(cmd)
|
||||||
#sudo dpkg --configure -a
|
try:
|
||||||
child = pexpect.spawn("sudo -E dpkg --configure -a")
|
i = child.expect(output_expects, timeout=time_out)
|
||||||
self.wait_and_close_proc(child, time_out)
|
self.pexpect_wait_and_close_proc(child)
|
||||||
|
except pexpect.TIMEOUT:
|
||||||
|
self.pexpect_kill_proc(child)
|
||||||
|
raise PkgTimeout("Process timeout after %i seconds." % time_out)
|
||||||
|
return i
|
||||||
|
|
||||||
|
|
||||||
|
class RedhatPackagerMixin(BasePackagerMixin):
|
||||||
|
|
||||||
def _install(self, package_name, time_out):
|
def _install(self, package_name, time_out):
|
||||||
"""Attempts to install a package.
|
"""Attempts to install a package.
|
||||||
@@ -93,37 +107,27 @@ class DebianPackagerMixin:
|
|||||||
Raises an exception if a non-recoverable error or time out occurs.
|
Raises an exception if a non-recoverable error or time out occurs.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
child = pexpect.spawn("sudo -E DEBIAN_FRONTEND=noninteractive "
|
cmd = "sudo yum --color=never -y install %s" % package_name
|
||||||
"apt-get -y --allow-unauthenticated install %s"
|
output_expects = ['\[sudo\] password for .*:',
|
||||||
% package_name)
|
'No package %s available.' % package_name,
|
||||||
try:
|
'Transaction Check Error:',
|
||||||
i = child.expect(['.*password*',
|
'.*scriptlet failed*',
|
||||||
'E: Unable to locate package %s' % package_name,
|
'HTTP Error',
|
||||||
"Couldn't find package % s" % package_name,
|
'No more mirrors to try.',
|
||||||
("dpkg was interrupted, you must manually run "
|
'.*already installed and latest version',
|
||||||
"'sudo dpkg --configure -a'"),
|
'Updated:',
|
||||||
"Unable to lock the administration directory",
|
'Installed:']
|
||||||
"Setting up %s*" % package_name,
|
i = self.pexpect_run(cmd, output_expects, time_out)
|
||||||
"is already the newest version"],
|
if i == 0:
|
||||||
timeout=time_out)
|
raise PkgPermissionError("Invalid permissions.")
|
||||||
if i == 0:
|
elif i == 1:
|
||||||
raise PkgPermissionError("Invalid permissions.")
|
raise PkgNotFoundError("Could not find pkg %s" % package_name)
|
||||||
elif i == 1 or i == 2:
|
elif i == 2:
|
||||||
raise PkgNotFoundError("Could not find apt %s" % package_name)
|
raise PkgTransactionCheckError("Transaction Check Error")
|
||||||
elif i == 3:
|
elif i == 3:
|
||||||
return RUN_DPKG_FIRST
|
raise PkgScriptletError("Package scriptlet failed")
|
||||||
elif i == 4:
|
elif i == 4 or i == 5:
|
||||||
raise PkgAdminLockError()
|
raise PkgDownloadError("Package download problem")
|
||||||
except pexpect.TIMEOUT:
|
|
||||||
self.kill_proc(child)
|
|
||||||
raise PkgTimeout("Process timeout after %i seconds." % time_out)
|
|
||||||
try:
|
|
||||||
self.wait_and_close_proc(child)
|
|
||||||
except pexpect.TIMEOUT as e:
|
|
||||||
LOG.error("wait_and_close_proc failed: %s" % e)
|
|
||||||
#TODO(tim.simpson): As of RDL, and on my machine exclusively (in
|
|
||||||
# both Virtual Box and VmWare!) this fails, but
|
|
||||||
# the package is installed.
|
|
||||||
return OK
|
return OK
|
||||||
|
|
||||||
def _remove(self, package_name, time_out):
|
def _remove(self, package_name, time_out):
|
||||||
@@ -134,34 +138,117 @@ class DebianPackagerMixin:
|
|||||||
Raises an exception if a non-recoverable error or time out occurs.
|
Raises an exception if a non-recoverable error or time out occurs.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
child = pexpect.spawn("sudo -E apt-get -y --allow-unauthenticated "
|
cmd = "sudo yum --color=never -y remove %s" % package_name
|
||||||
"remove %s" % package_name)
|
output_expects = ['\[sudo\] password for .*:',
|
||||||
|
'No Packages marked for removal',
|
||||||
|
'Removed:']
|
||||||
|
i = self.pexpect_run(cmd, output_expects, time_out)
|
||||||
|
if i == 0:
|
||||||
|
raise PkgPermissionError("Invalid permissions.")
|
||||||
|
elif i == 1:
|
||||||
|
raise PkgNotFoundError("Could not find pkg %s" % package_name)
|
||||||
|
return OK
|
||||||
|
|
||||||
|
def pkg_install(self, package_name, time_out):
|
||||||
|
result = self._install(package_name, time_out)
|
||||||
|
if result != OK:
|
||||||
|
raise PkgPackageStateError("Package %s is in a bad state."
|
||||||
|
% package_name)
|
||||||
|
|
||||||
|
def pkg_version(self, package_name):
|
||||||
|
cmd_list = ["rpm", "-qa", "--qf", "'%{VERSION}-%{RELEASE}\n'",
|
||||||
|
package_name]
|
||||||
|
p = commands.getstatusoutput(' '.join(cmd_list))
|
||||||
|
# Need to capture the version string
|
||||||
|
# check the command output
|
||||||
|
std_out = p[1]
|
||||||
|
for line in std_out.split("\n"):
|
||||||
|
regex = re.compile("[0-9.]+-.*")
|
||||||
|
matches = regex.match(line)
|
||||||
|
if matches:
|
||||||
|
line = matches.group()
|
||||||
|
return line
|
||||||
|
msg = _("version() saw unexpected output from rpm!")
|
||||||
|
LOG.error(msg)
|
||||||
|
|
||||||
|
def pkg_remove(self, package_name, time_out):
|
||||||
|
"""Removes a package."""
|
||||||
|
if self.pkg_version(package_name) is None:
|
||||||
|
return
|
||||||
|
result = self._remove(package_name, time_out)
|
||||||
|
if result != OK:
|
||||||
|
raise PkgPackageStateError("Package %s is in a bad state."
|
||||||
|
% package_name)
|
||||||
|
|
||||||
|
|
||||||
|
class DebianPackagerMixin(BasePackagerMixin):
|
||||||
|
|
||||||
|
def _fix(self, time_out):
|
||||||
|
"""Sometimes you have to run this command before a pkg will install."""
|
||||||
try:
|
try:
|
||||||
i = child.expect(['.*password*',
|
utils.execute("dpkg", "--configure", "-a", run_as_root=True,
|
||||||
'E: Unable to locate package %s' % package_name,
|
root_helper="sudo")
|
||||||
'Package is in a very bad inconsistent state',
|
except ProcessExecutionError as e:
|
||||||
("Sub-process /usr/bin/dpkg returned an error "
|
LOG.error(_("Error fixing dpkg"))
|
||||||
"code"),
|
|
||||||
("dpkg was interrupted, you must manually run "
|
def _install(self, package_name, time_out):
|
||||||
"'sudo dpkg --configure -a'"),
|
"""Attempts to install a package.
|
||||||
"Unable to lock the administration directory",
|
|
||||||
#'The following packages will be REMOVED',
|
Returns OK if the package installs fine or a result code if a
|
||||||
"Removing %s*" % package_name],
|
recoverable-error occurred.
|
||||||
timeout=time_out)
|
Raises an exception if a non-recoverable error or time out occurs.
|
||||||
if i == 0:
|
|
||||||
raise PkgPermissionError("Invalid permissions.")
|
"""
|
||||||
elif i == 1:
|
cmd = "sudo -E DEBIAN_FRONTEND=noninteractive " \
|
||||||
raise PkgNotFoundError("Could not find pkg %s" % package_name)
|
"apt-get -y --allow-unauthenticated install %s" % package_name
|
||||||
elif i == 2 or i == 3:
|
output_expects = ['.*password*',
|
||||||
return REINSTALL_FIRST
|
'E: Unable to locate package %s' % package_name,
|
||||||
elif i == 4:
|
"Couldn't find package % s" % package_name,
|
||||||
return RUN_DPKG_FIRST
|
("dpkg was interrupted, you must manually run "
|
||||||
elif i == 5:
|
"'sudo dpkg --configure -a'"),
|
||||||
raise PkgAdminLockError()
|
"Unable to lock the administration directory",
|
||||||
self.wait_and_close_proc(child)
|
"Setting up %s*" % package_name,
|
||||||
except pexpect.TIMEOUT:
|
"is already the newest version"]
|
||||||
self.kill_proc(child)
|
i = self.pexpect_run(cmd, output_expects, time_out)
|
||||||
raise PkgTimeout("Process timeout after %i seconds." % time_out)
|
if i == 0:
|
||||||
|
raise PkgPermissionError("Invalid permissions.")
|
||||||
|
elif i == 1 or i == 2:
|
||||||
|
raise PkgNotFoundError("Could not find apt %s" % package_name)
|
||||||
|
elif i == 3:
|
||||||
|
return RUN_DPKG_FIRST
|
||||||
|
elif i == 4:
|
||||||
|
raise PkgAdminLockError()
|
||||||
|
return OK
|
||||||
|
|
||||||
|
def _remove(self, package_name, time_out):
|
||||||
|
"""Removes a package.
|
||||||
|
|
||||||
|
Returns OK if the package is removed successfully or a result code if a
|
||||||
|
recoverable-error occurs.
|
||||||
|
Raises an exception if a non-recoverable error or time out occurs.
|
||||||
|
|
||||||
|
"""
|
||||||
|
cmd = "sudo -E apt-get -y --allow-unauthenticated remove %s" \
|
||||||
|
% package_name
|
||||||
|
output_expects = ['.*password*',
|
||||||
|
'E: Unable to locate package %s' % package_name,
|
||||||
|
'Package is in a very bad inconsistent state',
|
||||||
|
'Sub-process /usr/bin/dpkg returned an error code',
|
||||||
|
("dpkg was interrupted, you must manually run "
|
||||||
|
"'sudo dpkg --configure -a'"),
|
||||||
|
"Unable to lock the administration directory",
|
||||||
|
"Removing %s*" % package_name]
|
||||||
|
i = self.pexpect_run(cmd, output_expects, time_out)
|
||||||
|
if i == 0:
|
||||||
|
raise PkgPermissionError("Invalid permissions.")
|
||||||
|
elif i == 1:
|
||||||
|
raise PkgNotFoundError("Could not find pkg %s" % package_name)
|
||||||
|
elif i == 2 or i == 3:
|
||||||
|
return REINSTALL_FIRST
|
||||||
|
elif i == 4:
|
||||||
|
return RUN_DPKG_FIRST
|
||||||
|
elif i == 5:
|
||||||
|
raise PkgAdminLockError()
|
||||||
return OK
|
return OK
|
||||||
|
|
||||||
def pkg_install(self, package_name, time_out):
|
def pkg_install(self, package_name, time_out):
|
||||||
@@ -216,7 +303,6 @@ class DebianPackagerMixin:
|
|||||||
return parts[2]
|
return parts[2]
|
||||||
msg = _("version() saw unexpected output from dpkg!")
|
msg = _("version() saw unexpected output from dpkg!")
|
||||||
LOG.error(msg)
|
LOG.error(msg)
|
||||||
raise exception.GuestError(msg)
|
|
||||||
|
|
||||||
def pkg_remove(self, package_name, time_out):
|
def pkg_remove(self, package_name, time_out):
|
||||||
"""Removes a package."""
|
"""Removes a package."""
|
||||||
@@ -238,9 +324,7 @@ class DebianPackagerMixin:
|
|||||||
class BasePackage(type):
|
class BasePackage(type):
|
||||||
|
|
||||||
def __new__(meta, name, bases, dct):
|
def __new__(meta, name, bases, dct):
|
||||||
if os.path.isfile("/etc/debian_version"):
|
if OS == REDHAT:
|
||||||
bases += (DebianPackagerMixin, )
|
|
||||||
elif os.path.isfile("/etc/redhat-release"):
|
|
||||||
bases += (RedhatPackagerMixin, )
|
bases += (RedhatPackagerMixin, )
|
||||||
else:
|
else:
|
||||||
# The default is debian
|
# The default is debian
|
||||||
|
|||||||
@@ -618,12 +618,12 @@ class MySqlAppInstallTest(MySqlAppTest):
|
|||||||
def setUp(self):
|
def setUp(self):
|
||||||
super(MySqlAppInstallTest, self).setUp()
|
super(MySqlAppInstallTest, self).setUp()
|
||||||
self.orig_create_engine = sqlalchemy.create_engine
|
self.orig_create_engine = sqlalchemy.create_engine
|
||||||
self.orig_pkg_version = dbaas.pkg.pkg_version
|
self.orig_pkg_version = dbaas.packager.pkg_version
|
||||||
|
|
||||||
def tearDown(self):
|
def tearDown(self):
|
||||||
super(MySqlAppInstallTest, self).tearDown()
|
super(MySqlAppInstallTest, self).tearDown()
|
||||||
sqlalchemy.create_engine = self.orig_create_engine
|
sqlalchemy.create_engine = self.orig_create_engine
|
||||||
dbaas.pkg.pkg_version = self.orig_pkg_version
|
dbaas.packager.pkg_version = self.orig_pkg_version
|
||||||
|
|
||||||
def test_install(self):
|
def test_install(self):
|
||||||
|
|
||||||
@@ -684,13 +684,13 @@ class MySqlAppInstallTest(MySqlAppTest):
|
|||||||
|
|
||||||
def test_is_installed(self):
|
def test_is_installed(self):
|
||||||
|
|
||||||
dbaas.pkg.pkg_version = Mock(return_value=True)
|
dbaas.packager.pkg_version = Mock(return_value=True)
|
||||||
|
|
||||||
self.assertTrue(self.mySqlApp.is_installed())
|
self.assertTrue(self.mySqlApp.is_installed())
|
||||||
|
|
||||||
def test_is_installed_not(self):
|
def test_is_installed_not(self):
|
||||||
|
|
||||||
dbaas.pkg.pkg_version = Mock(return_value=None)
|
dbaas.packager.pkg_version = Mock(return_value=None)
|
||||||
|
|
||||||
self.assertFalse(self.mySqlApp.is_installed())
|
self.assertFalse(self.mySqlApp.is_installed())
|
||||||
|
|
||||||
|
|||||||
@@ -29,10 +29,10 @@ Unit tests for the classes and functions in pkg.py.
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
class PkgInstallTestCase(testtools.TestCase):
|
class PkgDEBInstallTestCase(testtools.TestCase):
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
super(PkgInstallTestCase, self).setUp()
|
super(PkgDEBInstallTestCase, self).setUp()
|
||||||
self.utils_execute = utils.execute
|
self.utils_execute = utils.execute
|
||||||
self.pexpect_spawn_init = pexpect.spawn.__init__
|
self.pexpect_spawn_init = pexpect.spawn.__init__
|
||||||
self.pexpect_spawn_closed = pexpect.spawn.close
|
self.pexpect_spawn_closed = pexpect.spawn.close
|
||||||
@@ -45,7 +45,7 @@ class PkgInstallTestCase(testtools.TestCase):
|
|||||||
self.pkgName = 'packageName'
|
self.pkgName = 'packageName'
|
||||||
|
|
||||||
def tearDown(self):
|
def tearDown(self):
|
||||||
super(PkgInstallTestCase, self).tearDown()
|
super(PkgDEBInstallTestCase, self).tearDown()
|
||||||
utils.execute = self.utils_execute
|
utils.execute = self.utils_execute
|
||||||
pexpect.spawn.__init__ = self.pexpect_spawn_init
|
pexpect.spawn.__init__ = self.pexpect_spawn_init
|
||||||
pexpect.spawn.close = self.pexpect_spawn_closed
|
pexpect.spawn.close = self.pexpect_spawn_closed
|
||||||
@@ -107,10 +107,10 @@ class PkgInstallTestCase(testtools.TestCase):
|
|||||||
self.pkgName, 5000)
|
self.pkgName, 5000)
|
||||||
|
|
||||||
|
|
||||||
class PkgRemoveTestCase(testtools.TestCase):
|
class PkgDEBRemoveTestCase(testtools.TestCase):
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
super(PkgRemoveTestCase, self).setUp()
|
super(PkgDEBRemoveTestCase, self).setUp()
|
||||||
self.utils_execute = utils.execute
|
self.utils_execute = utils.execute
|
||||||
self.pexpect_spawn_init = pexpect.spawn.__init__
|
self.pexpect_spawn_init = pexpect.spawn.__init__
|
||||||
self.pexpect_spawn_closed = pexpect.spawn.close
|
self.pexpect_spawn_closed = pexpect.spawn.close
|
||||||
@@ -129,7 +129,7 @@ class PkgRemoveTestCase(testtools.TestCase):
|
|||||||
self.pkgName = 'packageName'
|
self.pkgName = 'packageName'
|
||||||
|
|
||||||
def tearDown(self):
|
def tearDown(self):
|
||||||
super(PkgRemoveTestCase, self).tearDown()
|
super(PkgDEBRemoveTestCase, self).tearDown()
|
||||||
utils.execute = self.utils_execute
|
utils.execute = self.utils_execute
|
||||||
pexpect.spawn.__init__ = self.pexpect_spawn_init
|
pexpect.spawn.__init__ = self.pexpect_spawn_init
|
||||||
pexpect.spawn.close = self.pexpect_spawn_closed
|
pexpect.spawn.close = self.pexpect_spawn_closed
|
||||||
@@ -199,7 +199,7 @@ class PkgRemoveTestCase(testtools.TestCase):
|
|||||||
self.pkgName, 5000)
|
self.pkgName, 5000)
|
||||||
|
|
||||||
|
|
||||||
class PkgVersionTestCase(testtools.TestCase):
|
class PkgDEBVersionTestCase(testtools.TestCase):
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def build_output(packageName, packageVersion, parts=None):
|
def build_output(packageName, packageVersion, parts=None):
|
||||||
@@ -218,13 +218,13 @@ class PkgVersionTestCase(testtools.TestCase):
|
|||||||
return cmd_out
|
return cmd_out
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
super(PkgVersionTestCase, self).setUp()
|
super(PkgDEBVersionTestCase, self).setUp()
|
||||||
self.pkgName = 'mysql-server-5.5'
|
self.pkgName = 'mysql-server-5.5'
|
||||||
self.pkgVersion = '5.5.28-0'
|
self.pkgVersion = '5.5.28-0'
|
||||||
self.commands_output = commands.getstatusoutput
|
self.commands_output = commands.getstatusoutput
|
||||||
|
|
||||||
def tearDown(self):
|
def tearDown(self):
|
||||||
super(PkgVersionTestCase, self).tearDown()
|
super(PkgDEBVersionTestCase, self).tearDown()
|
||||||
commands.getstatusoutput = self.commands_output
|
commands.getstatusoutput = self.commands_output
|
||||||
|
|
||||||
def test_version_success(self):
|
def test_version_success(self):
|
||||||
@@ -242,15 +242,13 @@ class PkgVersionTestCase(testtools.TestCase):
|
|||||||
def test_version_no_output(self):
|
def test_version_no_output(self):
|
||||||
cmd_out = self.build_output(self.pkgName, self.pkgVersion, "")
|
cmd_out = self.build_output(self.pkgName, self.pkgVersion, "")
|
||||||
commands.getstatusoutput = Mock(return_value=(0, cmd_out))
|
commands.getstatusoutput = Mock(return_value=(0, cmd_out))
|
||||||
self.assertRaises(exception.GuestError,
|
self.assertIsNone(pkg.DebianPackagerMixin().pkg_version(self.pkgName))
|
||||||
pkg.DebianPackagerMixin().pkg_version, self.pkgName)
|
|
||||||
|
|
||||||
def test_version_unexpected_parts(self):
|
def test_version_unexpected_parts(self):
|
||||||
unexp_parts = "ii 123"
|
unexp_parts = "ii 123"
|
||||||
cmd_out = self.build_output(self.pkgName, self.pkgVersion, unexp_parts)
|
cmd_out = self.build_output(self.pkgName, self.pkgVersion, unexp_parts)
|
||||||
commands.getstatusoutput = Mock(return_value=(0, cmd_out))
|
commands.getstatusoutput = Mock(return_value=(0, cmd_out))
|
||||||
self.assertRaises(exception.GuestError,
|
self.assertIsNone(pkg.DebianPackagerMixin().pkg_version(self.pkgName))
|
||||||
pkg.DebianPackagerMixin().pkg_version, self.pkgName)
|
|
||||||
|
|
||||||
def test_version_wrong_package(self):
|
def test_version_wrong_package(self):
|
||||||
invalid_pkg = "package_invalid_001"
|
invalid_pkg = "package_invalid_001"
|
||||||
@@ -269,3 +267,169 @@ class PkgVersionTestCase(testtools.TestCase):
|
|||||||
cmd_out = self.build_output(self.pkgName, '<none>')
|
cmd_out = self.build_output(self.pkgName, '<none>')
|
||||||
commands.getstatusoutput = Mock(return_value=(0, cmd_out))
|
commands.getstatusoutput = Mock(return_value=(0, cmd_out))
|
||||||
self.assertFalse(pkg.DebianPackagerMixin().pkg_version(self.pkgName))
|
self.assertFalse(pkg.DebianPackagerMixin().pkg_version(self.pkgName))
|
||||||
|
|
||||||
|
|
||||||
|
class PkgRPMVersionTestCase(testtools.TestCase):
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
super(PkgRPMVersionTestCase, self).setUp()
|
||||||
|
self.pkgName = 'python-requests'
|
||||||
|
self.pkgVersion = '0.14.2-1.el6'
|
||||||
|
self.commands_output = commands.getstatusoutput
|
||||||
|
|
||||||
|
def tearDown(self):
|
||||||
|
super(PkgRPMVersionTestCase, self).tearDown()
|
||||||
|
commands.getstatusoutput = self.commands_output
|
||||||
|
|
||||||
|
def test_version_no_output(self):
|
||||||
|
cmd_out = ''
|
||||||
|
commands.getstatusoutput = Mock(return_value=(0, cmd_out))
|
||||||
|
self.assertIsNone(pkg.RedhatPackagerMixin().pkg_version(self.pkgName))
|
||||||
|
|
||||||
|
def test_version_success(self):
|
||||||
|
cmd_out = self.pkgVersion
|
||||||
|
commands.getstatusoutput = Mock(return_value=(0, cmd_out))
|
||||||
|
version = pkg.RedhatPackagerMixin().pkg_version(self.pkgName)
|
||||||
|
self.assertTrue(version)
|
||||||
|
self.assertEqual(self.pkgVersion, version)
|
||||||
|
|
||||||
|
|
||||||
|
class PkgRPMInstallTestCase(testtools.TestCase):
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
super(PkgRPMInstallTestCase, self).setUp()
|
||||||
|
self.utils_execute = utils.execute
|
||||||
|
self.pexpect_spawn_init = pexpect.spawn.__init__
|
||||||
|
self.pexpect_spawn_closed = pexpect.spawn.close
|
||||||
|
self.pkg = pkg.RedhatPackagerMixin()
|
||||||
|
utils.execute = Mock()
|
||||||
|
pexpect.spawn.__init__ = Mock(return_value=None)
|
||||||
|
pexpect.spawn.closed = Mock(return_value=None)
|
||||||
|
self.pkgName = 'packageName'
|
||||||
|
|
||||||
|
def tearDown(self):
|
||||||
|
super(PkgRPMInstallTestCase, self).tearDown()
|
||||||
|
utils.execute = self.utils_execute
|
||||||
|
pexpect.spawn.__init__ = self.pexpect_spawn_init
|
||||||
|
pexpect.spawn.close = self.pexpect_spawn_closed
|
||||||
|
|
||||||
|
def test_permission_error(self):
|
||||||
|
# test
|
||||||
|
pexpect.spawn.expect = Mock(return_value=0)
|
||||||
|
# test and verify
|
||||||
|
self.assertRaises(pkg.PkgPermissionError, self.pkg.pkg_install,
|
||||||
|
self.pkgName, 5000)
|
||||||
|
|
||||||
|
def test_package_not_found(self):
|
||||||
|
# test
|
||||||
|
pexpect.spawn.expect = Mock(return_value=1)
|
||||||
|
# test and verify
|
||||||
|
self.assertRaises(pkg.PkgNotFoundError, self.pkg.pkg_install,
|
||||||
|
self.pkgName, 5000)
|
||||||
|
|
||||||
|
def test_transaction_check_error(self):
|
||||||
|
# test
|
||||||
|
pexpect.spawn.expect = Mock(return_value=2)
|
||||||
|
# test and verify
|
||||||
|
self.assertRaises(pkg.PkgTransactionCheckError, self.pkg.pkg_install,
|
||||||
|
self.pkgName, 5000)
|
||||||
|
|
||||||
|
def test_package_scriptlet_error(self):
|
||||||
|
# test
|
||||||
|
pexpect.spawn.expect = Mock(return_value=3)
|
||||||
|
# test and verify
|
||||||
|
self.assertRaises(pkg.PkgScriptletError, self.pkg.pkg_install,
|
||||||
|
self.pkgName, 5000)
|
||||||
|
|
||||||
|
def test_package_http_error(self):
|
||||||
|
# test
|
||||||
|
pexpect.spawn.expect = Mock(return_value=4)
|
||||||
|
# test and verify
|
||||||
|
self.assertRaises(pkg.PkgDownloadError, self.pkg.pkg_install,
|
||||||
|
self.pkgName, 5000)
|
||||||
|
|
||||||
|
def test_package_nomirrors_error(self):
|
||||||
|
# test
|
||||||
|
pexpect.spawn.expect = Mock(return_value=5)
|
||||||
|
# test and verify
|
||||||
|
self.assertRaises(pkg.PkgDownloadError, self.pkg.pkg_install,
|
||||||
|
self.pkgName, 5000)
|
||||||
|
|
||||||
|
def test_package_already_installed(self):
|
||||||
|
# test
|
||||||
|
pexpect.spawn.expect = Mock(return_value=6)
|
||||||
|
# test and verify
|
||||||
|
self.assertTrue(self.pkg.pkg_install(self.pkgName, 5000) is None)
|
||||||
|
|
||||||
|
def test_package_success_updated(self):
|
||||||
|
# test
|
||||||
|
pexpect.spawn.expect = Mock(return_value=7)
|
||||||
|
# test and verify
|
||||||
|
self.assertTrue(self.pkg.pkg_install(self.pkgName, 5000) is None)
|
||||||
|
|
||||||
|
def test_package_success_installed(self):
|
||||||
|
# test
|
||||||
|
pexpect.spawn.expect = Mock(return_value=8)
|
||||||
|
# test and verify
|
||||||
|
self.assertTrue(self.pkg.pkg_install(self.pkgName, 5000) is None)
|
||||||
|
|
||||||
|
def test_timeout_error(self):
|
||||||
|
# test timeout error
|
||||||
|
pexpect.spawn.expect = Mock(side_effect=pexpect.
|
||||||
|
TIMEOUT('timeout error'))
|
||||||
|
# test and verify
|
||||||
|
self.assertRaises(pkg.PkgTimeout, self.pkg.pkg_install,
|
||||||
|
self.pkgName, 5000)
|
||||||
|
|
||||||
|
|
||||||
|
class PkgRPMRemoveTestCase(testtools.TestCase):
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
super(PkgRPMRemoveTestCase, self).setUp()
|
||||||
|
self.utils_execute = utils.execute
|
||||||
|
self.pexpect_spawn_init = pexpect.spawn.__init__
|
||||||
|
self.pexpect_spawn_closed = pexpect.spawn.close
|
||||||
|
self.pkg = pkg.RedhatPackagerMixin()
|
||||||
|
self.pkg_version = self.pkg.pkg_version
|
||||||
|
self.pkg_install = self.pkg._install
|
||||||
|
utils.execute = Mock()
|
||||||
|
pexpect.spawn.__init__ = Mock(return_value=None)
|
||||||
|
pexpect.spawn.closed = Mock(return_value=None)
|
||||||
|
self.pkg.pkg_version = Mock(return_value="OK")
|
||||||
|
self.pkg._install = Mock(return_value=None)
|
||||||
|
self.pkgName = 'packageName'
|
||||||
|
|
||||||
|
def tearDown(self):
|
||||||
|
super(PkgRPMRemoveTestCase, self).tearDown()
|
||||||
|
utils.execute = self.utils_execute
|
||||||
|
pexpect.spawn.__init__ = self.pexpect_spawn_init
|
||||||
|
pexpect.spawn.close = self.pexpect_spawn_closed
|
||||||
|
self.pkg.pkg_version = self.pkg_version
|
||||||
|
self.pkg._install = self.pkg_install
|
||||||
|
|
||||||
|
def test_permission_error(self):
|
||||||
|
# test
|
||||||
|
pexpect.spawn.expect = Mock(return_value=0)
|
||||||
|
# test and verify
|
||||||
|
self.assertRaises(pkg.PkgPermissionError, self.pkg.pkg_remove,
|
||||||
|
self.pkgName, 5000)
|
||||||
|
|
||||||
|
def test_package_not_found(self):
|
||||||
|
# test
|
||||||
|
pexpect.spawn.expect = Mock(return_value=1)
|
||||||
|
# test and verify
|
||||||
|
self.assertRaises(pkg.PkgNotFoundError, self.pkg.pkg_remove,
|
||||||
|
self.pkgName, 5000)
|
||||||
|
|
||||||
|
def test_success_remove(self):
|
||||||
|
# test
|
||||||
|
pexpect.spawn.expect = Mock(return_value=2)
|
||||||
|
self.assertTrue(self.pkg.pkg_remove(self.pkgName, 5000) is None)
|
||||||
|
|
||||||
|
def test_timeout_error(self):
|
||||||
|
# test timeout error
|
||||||
|
pexpect.spawn.expect = Mock(side_effect=pexpect.
|
||||||
|
TIMEOUT('timeout error'))
|
||||||
|
# test and verify
|
||||||
|
self.assertRaises(pkg.PkgTimeout, self.pkg.pkg_remove,
|
||||||
|
self.pkgName, 5000)
|
||||||
|
|||||||
Reference in New Issue
Block a user