Fix source_credentials in openstack_utils
authorCédric Ollivier <cedric.ollivier@orange.com>
Wed, 8 Feb 2017 16:48:47 +0000 (17:48 +0100)
committerCédric Ollivier <cedric.ollivier@orange.com>
Thu, 9 Feb 2017 20:36:49 +0000 (21:36 +0100)
It fixes issues raised when an env var contains '=' (e.g. LS_COLORS).
It now exports the vars listed in rc_file without creating a new
process.

Change-Id: I6e6a4e3ab9c45afe4d40015831acb283acbe564c
Signed-off-by: Cédric Ollivier <cedric.ollivier@orange.com>
functest/ci/prepare_env.py
functest/ci/run_tests.py
functest/tests/unit/utils/test_openstack_utils.py
functest/utils/openstack_utils.py

index b3e5902..cca9ac7 100755 (executable)
@@ -170,12 +170,10 @@ def source_rc_file():
             sys.exit(1)
 
     logger.info("Sourcing the OpenStack RC file...")
-    creds = os_utils.source_credentials(
+    os_utils.source_credentials(
         CONST.openstack_creds)
-    str = ""
-    for key, value in creds.iteritems():
+    for key, value in os.environ.iteritems():
         if re.search("OS_", key):
-            str += "\n\t\t\t\t\t\t   " + key + "=" + value
             if key == 'OS_AUTH_URL':
                 CONST.OS_AUTH_URL = value
             elif key == 'OS_USERNAME':
index 320102d..6a6516a 100755 (executable)
@@ -78,8 +78,8 @@ def source_rc_file():
         logger.error("RC file %s does not exist..." % rc_file)
         sys.exit(1)
     logger.debug("Sourcing the OpenStack RC file...")
-    creds = os_utils.source_credentials(rc_file)
-    for key, value in creds.iteritems():
+    os_utils.source_credentials(rc_file)
+    for key, value in os.environ.iteritems():
         if re.search("OS_", key):
             if key == 'OS_AUTH_URL':
                 ft_constants.OS_AUTH_URL = value
index 0f51041..0971b4e 100644 (file)
@@ -7,6 +7,7 @@
 
 import copy
 import logging
+import os
 import unittest
 
 import mock
@@ -353,18 +354,31 @@ class OSUtilsTesting(unittest.TestCase):
     def test_get_credentials_missing_endpoint_type(self):
         self._get_credentials_missing_env('OS_ENDPOINT_TYPE')
 
+    def _test_source_credentials(self, msg, key='OS_TENANT_NAME',
+                                 value='admin'):
+        try:
+            del os.environ[key]
+        except:
+            pass
+        f = 'rc_file'
+        with mock.patch('__builtin__.open', mock.mock_open(read_data=msg),
+                        create=True) as m:
+            m.return_value.__iter__ = lambda self: iter(self.readline, '')
+            openstack_utils.source_credentials(f)
+            m.assert_called_once_with(f, 'r')
+            self.assertEqual(os.environ[key], value)
+
     def test_source_credentials(self):
-        with mock.patch('functest.utils.openstack_utils.subprocess.Popen') \
-            as mock_subproc_popen, \
-                mock.patch('functest.utils.openstack_utils.os.environ'):
-            process_mock = mock.Mock()
-            attrs = {'communicate.return_value': ('OS_USER_NAME=test_name',
-                                                  'success')}
-            process_mock.configure_mock(**attrs)
-            mock_subproc_popen.return_value = process_mock
-
-            self.assertDictEqual(openstack_utils.source_credentials('rc_file'),
-                                 {'OS_USER_NAME': 'test_name'})
+        self._test_source_credentials('OS_TENANT_NAME=admin')
+        self._test_source_credentials('OS_TENANT_NAME= admin')
+        self._test_source_credentials('OS_TENANT_NAME = admin')
+        self._test_source_credentials('OS_TENANT_NAME = "admin"')
+        self._test_source_credentials('export OS_TENANT_NAME=admin')
+        self._test_source_credentials('export OS_TENANT_NAME =admin')
+        self._test_source_credentials('export OS_TENANT_NAME = admin')
+        self._test_source_credentials('export OS_TENANT_NAME = "admin"')
+        self._test_source_credentials('OS_TENANT_NAME', value='')
+        self._test_source_credentials('export OS_TENANT_NAME', value='')
 
     @mock.patch('functest.utils.openstack_utils.os.getenv',
                 return_value=None)
index 64f1850..a0d78ae 100755 (executable)
@@ -10,7 +10,7 @@
 
 import os
 import os.path
-import subprocess
+import re
 import sys
 import time
 
@@ -112,12 +112,12 @@ def get_credentials(other_creds={}):
 
 
 def source_credentials(rc_file):
-    pipe = subprocess.Popen(". %s; env" % rc_file, stdout=subprocess.PIPE,
-                            shell=True)
-    output = pipe.communicate()[0]
-    env = dict((line.split("=", 1) for line in output.splitlines()))
-    os.environ.update(env)
-    return env
+    with open(rc_file, "r") as f:
+        for line in f:
+            var = line.rstrip('"\n').replace('export ', '').split("=")
+            key = re.sub(r'^ *| *$', '', var[0])
+            value = re.sub(r'^[" ]*|[ "]*$', '', "".join(var[1:]))
+            os.environ[key] = value
 
 
 def get_credentials_for_rally():