aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCédric Ollivier <cedric.ollivier@orange.com>2018-07-21 09:22:39 +0200
committerCédric Ollivier <cedric.ollivier@orange.com>2018-07-21 09:22:39 +0200
commit9aa520f619c2c0fac116cadb2c65900751b4949b (patch)
tree4ba25bfbe011dbaafdacdaccb7081b8713ef719f
parenta0b8d6b75eafdb356712b4836eb1c8b3c47a6e93 (diff)
Add helpers to detect OpenStack versions
It leverages on Nova API Microversions [1]. [1] https://docs.openstack.org/nova/latest/reference/api-microversion-history.html Change-Id: I60abf9089036e56fcbcd6c2b734666ea20875ceb Signed-off-by: Cédric Ollivier <cedric.ollivier@orange.com>
-rw-r--r--functest/tests/unit/utils/test_functest_utils.py122
-rw-r--r--functest/utils/functest_utils.py64
2 files changed, 184 insertions, 2 deletions
diff --git a/functest/tests/unit/utils/test_functest_utils.py b/functest/tests/unit/utils/test_functest_utils.py
index d35ed8ced..2b98267c4 100644
--- a/functest/tests/unit/utils/test_functest_utils.py
+++ b/functest/tests/unit/utils/test_functest_utils.py
@@ -20,7 +20,7 @@ from functest.utils import functest_utils
class FunctestUtilsTesting(unittest.TestCase):
- # pylint: disable=too-many-instance-attributes
+ # pylint: disable=too-many-instance-attributes,too-many-public-methods
readline = 0
test_ip = ['10.1.23.4', '10.1.14.15', '10.1.16.15']
@@ -218,6 +218,126 @@ class FunctestUtilsTesting(unittest.TestCase):
self.test_file),
'test_image_name')
+ def test_nova_version_exc1(self):
+ # pylint: disable=protected-access
+ cloud = mock.Mock()
+ cloud._compute_client.request.return_value = None
+ self.assertEqual(functest_utils.get_nova_version(cloud), None)
+ cloud._compute_client.request.assert_called_once_with('/', 'GET')
+
+ def test_nova_version_exc2(self):
+ # pylint: disable=protected-access
+ cloud = mock.Mock()
+ cloud._compute_client.request.return_value = {"version": None}
+ self.assertEqual(functest_utils.get_nova_version(cloud), None)
+ cloud._compute_client.request.assert_called_once_with('/', 'GET')
+
+ def test_nova_version_exc3(self):
+ # pylint: disable=protected-access
+ cloud = mock.Mock()
+ cloud._compute_client.request.return_value = {
+ "version": {"version": None}}
+ self.assertEqual(functest_utils.get_nova_version(cloud), None)
+ cloud._compute_client.request.assert_called_once_with('/', 'GET')
+
+ def test_nova_version_exc4(self):
+ # pylint: disable=protected-access
+ cloud = mock.Mock()
+ cloud._compute_client.request.return_value = {
+ "version": {"version": "a.b"}}
+ self.assertEqual(functest_utils.get_nova_version(cloud), None)
+ cloud._compute_client.request.assert_called_once_with('/', 'GET')
+
+ def test_nova_version(self):
+ # pylint: disable=protected-access
+ cloud = mock.Mock()
+ cloud._compute_client.request.return_value = {
+ "version": {"version": "2.1"}}
+ self.assertEqual(functest_utils.get_nova_version(cloud), (2, 1))
+ cloud._compute_client.request.assert_called_once_with('/', 'GET')
+
+ @mock.patch('functest.utils.functest_utils.get_nova_version',
+ return_value=(2, 61))
+ def test_openstack_version1(self, *args):
+ cloud = mock.Mock()
+ self.assertEqual(functest_utils.get_openstack_version(
+ cloud), "Rocky or newer")
+ args[0].assert_called_once_with(cloud)
+
+ @mock.patch('functest.utils.functest_utils.get_nova_version',
+ return_value=(2, 60))
+ def test_openstack_version2(self, *args):
+ cloud = mock.Mock()
+ self.assertEqual(functest_utils.get_openstack_version(cloud), "Queens")
+ args[0].assert_called_once_with(cloud)
+
+ @mock.patch('functest.utils.functest_utils.get_nova_version',
+ return_value=(2, 43))
+ def test_openstack_version3(self, *args):
+ cloud = mock.Mock()
+ self.assertEqual(functest_utils.get_openstack_version(cloud), "Pike")
+ args[0].assert_called_once_with(cloud)
+
+ @mock.patch('functest.utils.functest_utils.get_nova_version',
+ return_value=(2, 39))
+ def test_openstack_version4(self, *args):
+ cloud = mock.Mock()
+ self.assertEqual(functest_utils.get_openstack_version(cloud), "Ocata")
+ args[0].assert_called_once_with(cloud)
+
+ @mock.patch('functest.utils.functest_utils.get_nova_version',
+ return_value=(2, 26))
+ def test_openstack_version5(self, *args):
+ cloud = mock.Mock()
+ self.assertEqual(functest_utils.get_openstack_version(cloud), "Newton")
+ args[0].assert_called_once_with(cloud)
+
+ @mock.patch('functest.utils.functest_utils.get_nova_version',
+ return_value=(2, 13))
+ def test_openstack_version6(self, *args):
+ cloud = mock.Mock()
+ self.assertEqual(functest_utils.get_openstack_version(cloud), "Mitaka")
+ args[0].assert_called_once_with(cloud)
+
+ @mock.patch('functest.utils.functest_utils.get_nova_version',
+ return_value=(2, 4))
+ def test_openstack_version7(self, *args):
+ cloud = mock.Mock()
+ self.assertEqual(
+ functest_utils.get_openstack_version(cloud), "Liberty")
+ args[0].assert_called_once_with(cloud)
+
+ @mock.patch('functest.utils.functest_utils.get_nova_version',
+ return_value=(2, 1))
+ def test_openstack_version8(self, *args):
+ cloud = mock.Mock()
+ self.assertEqual(functest_utils.get_openstack_version(cloud), "Kilo")
+ args[0].assert_called_once_with(cloud)
+
+ @mock.patch('functest.utils.functest_utils.get_nova_version',
+ return_value=(1, 9))
+ def test_openstack_version9(self, *args):
+ cloud = mock.Mock()
+ self.assertEqual(
+ functest_utils.get_openstack_version(cloud), "Unknown")
+ args[0].assert_called_once_with(cloud)
+
+ @mock.patch('functest.utils.functest_utils.get_nova_version',
+ return_value=(3, 1))
+ def test_openstack_version10(self, *args):
+ cloud = mock.Mock()
+ self.assertEqual(
+ functest_utils.get_openstack_version(cloud), "Rocky or newer")
+ args[0].assert_called_once_with(cloud)
+
+ @mock.patch('functest.utils.functest_utils.get_nova_version',
+ return_value=None)
+ def test_openstack_version_exc(self, *args):
+ cloud = mock.Mock()
+ self.assertEqual(
+ functest_utils.get_openstack_version(cloud), "Unknown")
+ args[0].assert_called_once_with(cloud)
+
if __name__ == "__main__":
logging.disable(logging.CRITICAL)
diff --git a/functest/utils/functest_utils.py b/functest/utils/functest_utils.py
index b614af321..c5950c965 100644
--- a/functest/utils/functest_utils.py
+++ b/functest/utils/functest_utils.py
@@ -44,7 +44,7 @@ def execute_command(cmd, info=False, error_msg="",
ofd.write(line)
else:
line = line.replace('\n', '')
- print (line)
+ print(line)
sys.stdout.flush()
if output_file:
ofd.close()
@@ -72,3 +72,65 @@ def get_parameter_from_yaml(parameter, yfile):
raise ValueError("The parameter %s is not defined in"
" %s" % (parameter, yfile))
return value
+
+
+def get_nova_version(cloud):
+ """ Get Nova API microversion
+
+ Returns:
+
+ - Nova API microversion
+ - None on operation error
+ """
+ # pylint: disable=protected-access
+ try:
+ request = cloud._compute_client.request("/", "GET")
+ LOGGER.debug('cloud._compute_client.request: %s', request)
+ version = request["version"]["version"]
+ major, minor = version.split('.')
+ LOGGER.debug('nova version: %s', (int(major), int(minor)))
+ return (int(major), int(minor))
+ except Exception: # pylint: disable=broad-except
+ LOGGER.exception("Cannot detect Nova version")
+ return None
+
+
+def get_openstack_version(cloud):
+ """ Detect OpenStack version via Nova API microversion
+
+ It follows MicroversionHistory_.
+
+ Returns:
+
+ - OpenStack release
+ - Unknown on operation error
+
+ .. _MicroversionHistory:
+ https://docs.openstack.org/nova/latest/reference/api-microversion-history.html
+ """
+ version = get_nova_version(cloud)
+ try:
+ assert version
+ if version > (2, 60):
+ osversion = "Rocky or newer"
+ elif version > (2, 53):
+ osversion = "Queens"
+ elif version > (2, 42):
+ osversion = "Pike"
+ elif version > (2, 38):
+ osversion = "Ocata"
+ elif version > (2, 25):
+ osversion = "Newton"
+ elif version > (2, 12):
+ osversion = "Mitaka"
+ elif version > (2, 3):
+ osversion = "Liberty"
+ elif version >= (2, 1):
+ osversion = "Kilo"
+ else:
+ osversion = "Unknown"
+ LOGGER.info('Detect OpenStack version: %s', osversion)
+ return osversion
+ except AssertionError:
+ LOGGER.exception("Cannot detect OpenStack version")
+ return "Unknown"