Get properly env vars or their default values
authorCédric Ollivier <cedric.ollivier@orange.com>
Wed, 14 Feb 2018 15:02:53 +0000 (16:02 +0100)
committerCédric Ollivier <cedric.ollivier@orange.com>
Fri, 16 Feb 2018 09:24:22 +0000 (10:24 +0100)
It defines env.get() as an unique way to get Functest env vars or
their default values. It can be considered as a wrapper above os.environ.

It enforces backward compatibility via CONST which mustn't be used
for that purpose. It should be noted that it also stops using CONST
for getting OpenStack env vars.

Change-Id: I333dc1afbc0123166a7eaff8b551370098efa341
Signed-off-by: Cédric Ollivier <cedric.ollivier@orange.com>
22 files changed:
docs/testing/user/configguide/configguide.rst
functest/api/resources/v1/testcases.py
functest/ci/run_tests.py
functest/cli/commands/cli_env.py
functest/cli/commands/cli_tier.py
functest/core/testcase.py
functest/energy/energy.py
functest/opnfv_tests/openstack/rally/rally.py
functest/opnfv_tests/openstack/snaps/snaps_test_runner.py
functest/opnfv_tests/openstack/snaps/snaps_utils.py
functest/opnfv_tests/openstack/tempest/conf_utils.py
functest/opnfv_tests/openstack/tempest/tempest.py
functest/opnfv_tests/openstack/vping/vping_base.py
functest/opnfv_tests/sdn/odl/odl.py
functest/tests/unit/openstack/tempest/test_tempest.py
functest/tests/unit/utils/test_env.py [new file with mode: 0644]
functest/tests/unit/utils/test_functest_utils.py
functest/utils/config.py
functest/utils/constants.py
functest/utils/env.py
functest/utils/functest_utils.py
functest/utils/openstack_utils.py

index c4d9a6d..f658108 100644 (file)
@@ -197,9 +197,13 @@ Environment variables
 
 Several environement variables may be specified:
   * INSTALLER_TYPE=(apex|compass|daisy|fuel|joid)
+  * INSTALLER_IP=<Specific IP Address>
   * DEPLOY_SCENARIO=<vim>-<controller>-<nfv_feature>-<ha_mode>
 
 
+INSTALLER_IP is required by Barometer in order to access the installer node and
+the deployment.
+
 The format for the DEPLOY_SCENARIO env variable can be described as follows:
   * vim: (os|k8s) = OpenStack or Kubernetes
   * controller is one of ( nosdn | odl )
index bc21c6f..064661c 100644 (file)
 Resources to handle testcase related requests
 """
 
+import ConfigParser
 import logging
 import os
 import re
-import pkg_resources
 import socket
 import uuid
 
-import ConfigParser
 from flask import jsonify
 from flasgger.utils import swag_from
+import pkg_resources
 
 from functest.api.base import ApiResource
 from functest.api.common import api_utils, thread
 from functest.cli.commands.cli_testcase import Testcase
 from functest.api.database.v1.handlers import TasksHandler
 from functest.utils.constants import CONST
+from functest.utils import env
 import functest.utils.functest_utils as ft_utils
 
 LOGGER = logging.getLogger(__name__)
@@ -127,10 +128,10 @@ class V1Testcase(ApiResource):
             result = 'FAIL'
 
         env_info = {
-            'installer': os.environ.get('INSTALLER_TYPE', None),
-            'scenario': os.environ.get('DEPLOY_SCENARIO', None),
-            'build_tag': os.environ.get('BUILD_TAG', None),
-            'ci_loop': os.environ.get('CI_LOOP', 'daily')
+            'installer': env.get('INSTALLER_TYPE'),
+            'scenario': env.get('DEPLOY_SCENARIO'),
+            'build_tag': env.get('BUILD_TAG'),
+            'ci_loop': env.get('CI_LOOP')
         }
         result = {
             'task_id': args.get('task_id'),
index ff38720..ca101ce 100644 (file)
@@ -27,8 +27,9 @@ import enum
 import prettytable
 import yaml
 
-import functest.ci.tier_builder as tb
-import functest.core.testcase as testcase
+from functest.ci import tier_builder
+from functest.core import testcase
+from functest.utils import env
 
 LOGGER = logging.getLogger('functest.ci.run_tests')
 ENV_FILE = "/home/opnfv/functest/conf/env_file"
@@ -88,9 +89,9 @@ class Runner(object):
         self.overall_result = Result.EX_OK
         self.clean_flag = True
         self.report_flag = False
-        self.tiers = tb.TierBuilder(
-            os.environ.get('INSTALLER_TYPE', None),
-            os.environ.get('DEPLOY_SCENARIO', None),
+        self.tiers = tier_builder.TierBuilder(
+            env.get('INSTALLER_TYPE'),
+            env.get('DEPLOY_SCENARIO'),
             pkg_resources.resource_filename('functest', 'ci/testcases.yaml'))
 
     @staticmethod
@@ -207,7 +208,7 @@ class Runner(object):
             field_names=['tiers', 'order', 'CI Loop', 'description',
                          'testcases'])
         for tier in self.tiers.get_tiers():
-            ci_loop = os.environ.get('CI_LOOP', 'daily')
+            ci_loop = env.get('CI_LOOP')
             if (tier.get_tests() and
                     re.search(ci_loop, tier.get_ci_loop()) is not None):
                 tiers_to_run.append(tier)
@@ -247,7 +248,7 @@ class Runner(object):
                     LOGGER.error("Unknown test case or tier '%s', or not "
                                  "supported by the given scenario '%s'.",
                                  kwargs['test'],
-                                 os.environ.get('DEPLOY_SCENARIO', ""))
+                                 env.get('DEPLOY_SCENARIO'))
                     LOGGER.debug("Available tiers are:\n\n%s",
                                  self.tiers)
                     return Result.EX_ERROR
@@ -270,7 +271,7 @@ class Runner(object):
             field_names=['env var', 'value'])
         for env_var in ['INSTALLER_TYPE', 'DEPLOY_SCENARIO', 'BUILD_TAG',
                         'CI_LOOP']:
-            msg.add_row([env_var, os.environ.get(env_var, "")])
+            msg.add_row([env_var, env.get(env_var)])
         LOGGER.info("Deployment description:\n\n%s\n", msg)
         msg = prettytable.PrettyTable(
             header_style='upper', padding_width=5,
index f93ef61..18c8895 100644 (file)
@@ -8,21 +8,21 @@
 
 # pylint: disable=missing-docstring
 
-import os
-
 import click
 import prettytable
 import six
 
+from functest.utils import env
+
 
 class Env(object):  # pylint: disable=too-few-public-methods
 
     @staticmethod
     def show():
-        install_type = os.environ.get('INSTALLER_TYPE', 'Unknown')
-        scenario = os.environ.get('DEPLOY_SCENARIO', 'Unknown')
-        node = os.environ.get('NODE_NAME', 'Unknown')
-        build_tag = os.environ.get('BUILD_TAG', None)
+        install_type = env.get('INSTALLER_TYPE')
+        scenario = env.get('DEPLOY_SCENARIO')
+        node = env.get('NODE_NAME')
+        build_tag = env.get('BUILD_TAG')
         if build_tag:
             build_tag = build_tag.lstrip(
                 "jenkins-").lstrip("functest").lstrip("-")
index 933d8cd..3694c1a 100644 (file)
@@ -8,21 +8,21 @@
 
 # pylint: disable=missing-docstring
 
-import os
 import pkg_resources
 
 import click
 
 from functest.ci import tier_builder
 from functest.utils import functest_utils
+from functest.utils import env
 
 
 class Tier(object):
 
     def __init__(self):
         self.tiers = tier_builder.TierBuilder(
-            os.environ['INSTALLER_TYPE'],
-            os.environ['DEPLOY_SCENARIO'],
+            env.get('INSTALLER_TYPE'),
+            env.get('DEPLOY_SCENARIO'),
             pkg_resources.resource_filename('functest', 'ci/testcases.yaml'))
 
     def list(self):
index f0c6c9e..e8bb140 100644 (file)
@@ -17,6 +17,7 @@ import re
 import requests
 
 from functest.utils import decorators
+from functest.utils import env
 
 
 import prettytable
@@ -180,14 +181,14 @@ class TestCase(object):
             assert self.case_name
             assert self.start_time
             assert self.stop_time
-            url = os.environ['TEST_DB_URL']
+            url = env.get('TEST_DB_URL')
             data = {"project_name": self.project_name,
                     "case_name": self.case_name,
                     "details": self.details}
-            data["installer"] = os.environ['INSTALLER_TYPE']
-            data["scenario"] = os.environ['DEPLOY_SCENARIO']
-            data["pod_name"] = os.environ['NODE_NAME']
-            data["build_tag"] = os.environ['BUILD_TAG']
+            data["installer"] = env.get('INSTALLER_TYPE')
+            data["scenario"] = env.get('DEPLOY_SCENARIO')
+            data["pod_name"] = env.get('NODE_NAME')
+            data["build_tag"] = env.get('BUILD_TAG')
             data["criteria"] = 'PASS' if self.is_successful(
                 ) == TestCase.EX_OK else 'FAIL'
             data["start_date"] = datetime.fromtimestamp(
@@ -197,7 +198,7 @@ class TestCase(object):
             try:
                 data["version"] = re.search(
                     TestCase._job_name_rule,
-                    os.environ['BUILD_TAG']).group(2)
+                    env.get('BUILD_TAG')).group(2)
             except Exception:  # pylint: disable=broad-except
                 data["version"] = "unknown"
             req = requests.post(
@@ -210,9 +211,6 @@ class TestCase(object):
             self.__logger.exception(
                 "Please run test before publishing the results")
             return TestCase.EX_PUSH_TO_DB_ERROR
-        except KeyError as exc:
-            self.__logger.error("Please set env var: " + str(exc))
-            return TestCase.EX_PUSH_TO_DB_ERROR
         except requests.exceptions.HTTPError:
             self.__logger.exception("The HTTP request raises issues")
             return TestCase.EX_PUSH_TO_DB_ERROR
index c7da8f0..d5f6871 100644 (file)
 
 import json
 import logging
-import os
 import traceback
 
 from functools import wraps
 import requests
 from six.moves import urllib
 
+from functest.utils import env
+
 
 def finish_session(current_scenario):
     """Finish a recording session."""
@@ -93,14 +94,15 @@ class EnergyRecorder(object):
         # Singleton pattern for energy_recorder_api static member
         # Load only if not previouly done
         if EnergyRecorder.energy_recorder_api is None:
-            assert os.environ['NODE_NAME']
-            assert os.environ["ENERGY_RECORDER_API_URL"]
-            environment = os.environ['NODE_NAME']
-            energy_recorder_uri = os.environ["ENERGY_RECORDER_API_URL"]
+            assert env.get('NODE_NAME')
+            assert env.get('ENERGY_RECORDER_API_URL')
+            environment = env.get('NODE_NAME')
+            energy_recorder_uri = env.get(
+                'ENERGY_RECORDER_API_URL')
 
             # Creds
-            creds_usr = os.environ.get("ENERGY_RECORDER_API_USER", "")
-            creds_pass = os.environ.get("ENERGY_RECORDER_API_PASSWORD", "")
+            creds_usr = env.get("ENERGY_RECORDER_API_USER")
+            creds_pass = env.get("ENERGY_RECORDER_API_PASSWORD")
 
             uri_comp = "/recorders/environment/"
             uri_comp += urllib.parse.quote_plus(environment)
index 2632fd3..add0f24 100644 (file)
@@ -29,6 +29,7 @@ from functest.energy import energy
 from functest.opnfv_tests.openstack.snaps import snaps_utils
 from functest.opnfv_tests.openstack.tempest import conf_utils
 from functest.utils.constants import CONST
+from functest.utils import env
 
 from snaps.config.flavor import FlavorConfig
 from snaps.config.image import ImageConfig
@@ -218,8 +219,8 @@ class RallyBase(testcase.TestCase):
             with open(RallyBase.BLACKLIST_FILE, 'r') as black_list_file:
                 black_list_yaml = yaml.safe_load(black_list_file)
 
-            installer_type = os.getenv('INSTALLER_TYPE', None)
-            deploy_scenario = os.getenv('DEPLOY_SCENARIO', None)
+            installer_type = env.get('INSTALLER_TYPE')
+            deploy_scenario = env.get('DEPLOY_SCENARIO')
             if (bool(installer_type) and bool(deploy_scenario) and
                     'scenario' in black_list_yaml.keys()):
                 for item in black_list_yaml['scenario']:
index 9d31f42..216d9ac 100644 (file)
@@ -15,6 +15,7 @@ import logging
 from functest.core import unit
 from functest.opnfv_tests.openstack.snaps import snaps_utils
 from functest.utils.constants import CONST
+from functest.utils import env
 
 from snaps.openstack import create_flavor
 
@@ -44,7 +45,7 @@ class SnapsTestRunner(unit.Suite):
             CONST.__getattribute__('snaps_use_floating_ips') == 'True')
         self.use_keystone = (
             CONST.__getattribute__('snaps_use_keystone') == 'True')
-        scenario = CONST.__getattribute__('DEPLOY_SCENARIO')
+        scenario = env.get('DEPLOY_SCENARIO')
 
         self.flavor_metadata = None
         if 'ovs' in scenario or 'fdio' in scenario:
index 6bc50ad..59bd063 100644 (file)
@@ -10,6 +10,7 @@
 """Some common utils wrapping snaps functions """
 
 from functest.utils.constants import CONST
+from functest.utils import env
 
 from snaps.openstack.tests import openstack_tests
 from snaps.openstack.utils import neutron_utils, nova_utils
@@ -24,8 +25,8 @@ def get_ext_net_name(os_creds):
     """
     neutron = neutron_utils.neutron_client(os_creds)
     ext_nets = neutron_utils.get_external_networks(neutron)
-    if hasattr(CONST, 'EXTERNAL_NETWORK'):
-        extnet_config = CONST.__getattribute__('EXTERNAL_NETWORK')
+    if env.get('EXTERNAL_NETWORK'):
+        extnet_config = env.get('EXTERNAL_NETWORK')
         for ext_net in ext_nets:
             if ext_net.name == extnet_config:
                 return extnet_config
index f128784..09471fa 100644 (file)
@@ -14,13 +14,14 @@ import ConfigParser
 import logging
 import fileinput
 import os
-import pkg_resources
 import shutil
 import subprocess
 
+import pkg_resources
 import yaml
 
 from functest.utils.constants import CONST
+from functest.utils import env
 import functest.utils.functest_utils as ft_utils
 
 
@@ -51,7 +52,7 @@ TEST_ACCOUNTS_FILE = pkg_resources.resource_filename(
     'functest',
     'opnfv_tests/openstack/tempest/custom_tests/test_accounts.yaml')
 
-CI_INSTALLER_TYPE = CONST.__getattribute__('INSTALLER_TYPE')
+CI_INSTALLER_TYPE = env.get('INSTALLER_TYPE')
 
 """ logging configuration """
 LOGGER = logging.getLogger(__name__)
@@ -60,7 +61,7 @@ LOGGER = logging.getLogger(__name__)
 def create_rally_deployment():
     """Create new rally deployment"""
     # set the architecture to default
-    pod_arch = os.getenv("POD_ARCH", None)
+    pod_arch = env.get("POD_ARCH")
     arch_filter = ['aarch64']
 
     if pod_arch and pod_arch in arch_filter:
@@ -294,10 +295,9 @@ def configure_tempest_update_params(tempest_conf_file, network_name=None,
         config.set('compute', 'min_compute_nodes', compute_cnt)
         config.set('compute-feature-enabled', 'live_migration', True)
 
-    config.set('identity', 'region',
-               CONST.__getattribute__('OS_REGION_NAME'))
-    identity_api_version = os.getenv(
-        "OS_IDENTITY_API_VERSION", os.getenv("IDENTITY_API_VERSION"))
+    config.set('identity', 'region', os.environ.get('OS_REGION_NAME'))
+    identity_api_version = os.environ.get(
+        "OS_IDENTITY_API_VERSION", os.environ.get("IDENTITY_API_VERSION"))
     if identity_api_version == '3':
         auth_version = 'v3'
         config.set('identity-feature-enabled', 'api_v2', False)
@@ -310,11 +310,11 @@ def configure_tempest_update_params(tempest_conf_file, network_name=None,
     config.set('object-storage', 'operator_role',
                CONST.__getattribute__('tempest_object_storage_operator_role'))
 
-    if CONST.__getattribute__('OS_ENDPOINT_TYPE') is not None:
+    if os.environ.get('OS_ENDPOINT_TYPE') is not None:
         config.set('identity', 'v3_endpoint_type',
-                   CONST.__getattribute__('OS_ENDPOINT_TYPE'))
+                   os.environ.get('OS_ENDPOINT_TYPE'))
 
-    if CONST.__getattribute__('OS_ENDPOINT_TYPE') is not None:
+    if os.environ.get('OS_ENDPOINT_TYPE') is not None:
         sections = config.sections()
         services_list = ['compute',
                          'volume',
@@ -327,7 +327,7 @@ def configure_tempest_update_params(tempest_conf_file, network_name=None,
             if service not in sections:
                 config.add_section(service)
             config.set(service, 'endpoint_type',
-                       CONST.__getattribute__('OS_ENDPOINT_TYPE'))
+                       os.environ.get('OS_ENDPOINT_TYPE'))
 
     LOGGER.debug('Add/Update required params defined in tempest_conf.yaml '
                  'into tempest.conf file')
index 56705fc..c19c8d9 100644 (file)
@@ -26,6 +26,7 @@ from functest.core import testcase
 from functest.opnfv_tests.openstack.snaps import snaps_utils
 from functest.opnfv_tests.openstack.tempest import conf_utils
 from functest.utils.constants import CONST
+from functest.utils import env
 import functest.utils.functest_utils as ft_utils
 
 from snaps.config.flavor import FlavorConfig
@@ -128,8 +129,8 @@ class TempestCommon(testcase.TestCase):
         result_file = open(conf_utils.TEMPEST_LIST, 'w')
         black_tests = []
         try:
-            installer_type = CONST.__getattribute__('INSTALLER_TYPE')
-            deploy_scenario = CONST.__getattribute__('DEPLOY_SCENARIO')
+            installer_type = env.get('INSTALLER_TYPE')
+            deploy_scenario = env.get('DEPLOY_SCENARIO')
             if bool(installer_type) * bool(deploy_scenario):
                 # if INSTALLER_TYPE and DEPLOY_SCENARIO are set we read the
                 # file
@@ -405,7 +406,7 @@ class TempestResourcesManager(object):
 
     def _create_flavor(self, name):
         """Create flavor for tests."""
-        scenario = CONST.__getattribute__('DEPLOY_SCENARIO')
+        scenario = env.get('DEPLOY_SCENARIO')
         flavor_metadata = None
         if 'ovs' in scenario or 'fdio' in scenario:
             flavor_metadata = create_flavor.MEM_PAGE_SIZE_LARGE
@@ -463,7 +464,7 @@ class TempestResourcesManager(object):
 
         if use_custom_flavors:
             LOGGER.info("Creating 2nd flavor for Tempest suite")
-            scenario = CONST.__getattribute__('DEPLOY_SCENARIO')
+            scenario = env.get('DEPLOY_SCENARIO')
             if 'ovs' in scenario or 'fdio' in scenario:
                 CONST.__setattr__('openstack_flavor_ram', 1024)
             name = CONST.__getattribute__(
index 7170101..fae5db2 100644 (file)
@@ -18,6 +18,7 @@ import uuid
 from functest.core import testcase
 from functest.opnfv_tests.openstack.snaps import snaps_utils
 from functest.utils.constants import CONST
+from functest.utils import env
 
 from snaps.config.flavor import FlavorConfig
 from snaps.config.network import NetworkConfig, SubnetConfig
@@ -135,7 +136,7 @@ class VPingBase(testcase.TestCase):
 
         self.logger.info(
             "Creating flavor with name: '%s'", self.flavor_name)
-        scenario = getattr(CONST, 'DEPLOY_SCENARIO')
+        scenario = env.get('DEPLOY_SCENARIO')
         flavor_metadata = None
         flavor_ram = 512
         if 'ovs' in scenario or 'fdio' in scenario:
index 4c33c49..705f39d 100644 (file)
@@ -31,6 +31,7 @@ from snaps.openstack.utils import keystone_utils
 from functest.core import robotframework
 from functest.opnfv_tests.openstack.snaps import snaps_utils
 from functest.utils import constants
+from functest.utils import env
 
 __author__ = "Cedric Ollivier <cedric.ollivier@orange.com>"
 
@@ -165,9 +166,7 @@ class ODLTests(robotframework.RobotFramework):
             kwargs['odlrestconfport'] = '8181'
             kwargs['odlusername'] = 'admin'
             kwargs['odlpassword'] = 'admin'
-            installer_type = None
-            if 'INSTALLER_TYPE' in os.environ:
-                installer_type = os.environ['INSTALLER_TYPE']
+            installer_type = env.get('INSTALLER_TYPE')
             kwargs['osusername'] = os.environ['OS_USERNAME']
             kwargs['osuserdomainname'] = os.environ.get(
                 'OS_USER_DOMAIN_NAME', 'Default')
@@ -180,17 +179,17 @@ class ODLTests(robotframework.RobotFramework):
                 kwargs['odlwebport'] = '8181'
                 kwargs['odlrestconfport'] = '8282'
             elif installer_type == 'apex' or installer_type == 'netvirt':
-                kwargs['odlip'] = os.environ['SDN_CONTROLLER_IP']
+                kwargs['odlip'] = env.get('SDN_CONTROLLER_IP')
                 kwargs['odlwebport'] = '8081'
                 kwargs['odlrestconfport'] = '8081'
             elif installer_type == 'compass':
                 kwargs['odlrestconfport'] = '8080'
             elif installer_type == 'daisy':
-                kwargs['odlip'] = os.environ['SDN_CONTROLLER_IP']
+                kwargs['odlip'] = env.get('SDN_CONTROLLER_IP')
                 kwargs['odlwebport'] = '8181'
                 kwargs['odlrestconfport'] = '8087'
             else:
-                kwargs['odlip'] = os.environ['SDN_CONTROLLER_IP']
+                kwargs['odlip'] = env.get('SDN_CONTROLLER_IP')
         except KeyError as ex:
             self.__logger.error("Cannot run ODL testcases. "
                                 "Please check env var: "
index 5d543ff..060a8a0 100644 (file)
@@ -8,6 +8,7 @@
 # pylint: disable=missing-docstring
 
 import logging
+import os
 import unittest
 
 import mock
@@ -15,7 +16,6 @@ import mock
 from functest.core import testcase
 from functest.opnfv_tests.openstack.tempest import tempest
 from functest.opnfv_tests.openstack.tempest import conf_utils
-from functest.utils.constants import CONST
 
 from snaps.openstack.os_credentials import OSCreds
 
@@ -115,8 +115,8 @@ class OSTempestTesting(unittest.TestCase):
             mock.patch.object(self.tempestcommon, 'read_file',
                               return_value=['test1', 'test2']):
             conf_utils.TEMPEST_BLACKLIST = Exception
-            CONST.__setattr__('INSTALLER_TYPE', 'installer_type')
-            CONST.__setattr__('DEPLOY_SCENARIO', 'deploy_scenario')
+            os.environ['INSTALLER_TYPE'] = 'installer_type'
+            os.environ['DEPLOY_SCENARIO'] = 'deploy_scenario'
             self.tempestcommon.apply_tempest_blacklist()
             obj = mock_open()
             obj.write.assert_any_call('test1\n')
@@ -131,8 +131,8 @@ class OSTempestTesting(unittest.TestCase):
                               return_value=['test1', 'test2']), \
             mock.patch('functest.opnfv_tests.openstack.tempest.tempest.'
                        'yaml.safe_load', return_value=item_dict):
-            CONST.__setattr__('INSTALLER_TYPE', 'installer_type')
-            CONST.__setattr__('DEPLOY_SCENARIO', 'deploy_scenario')
+            os.environ['INSTALLER_TYPE'] = 'installer_type'
+            os.environ['DEPLOY_SCENARIO'] = 'deploy_scenario'
             self.tempestcommon.apply_tempest_blacklist()
             obj = mock_open()
             obj.write.assert_any_call('test1\n')
diff --git a/functest/tests/unit/utils/test_env.py b/functest/tests/unit/utils/test_env.py
new file mode 100644 (file)
index 0000000..064ff98
--- /dev/null
@@ -0,0 +1,96 @@
+#!/usr/bin/env python
+
+# Copyright (c) 2018 Orange and others.
+#
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Apache License, Version 2.0
+# which accompanies this distribution, and is available at
+# http://www.apache.org/licenses/LICENSE-2.0
+
+# pylint: disable=missing-docstring
+
+import logging
+import os
+import unittest
+
+from six.moves import reload_module
+
+from functest.utils import env
+from functest.utils import constants
+
+
+class EnvTesting(unittest.TestCase):
+    # pylint: disable=missing-docstring
+
+    def setUp(self):
+        os.environ['FOO'] = 'foo'
+        os.environ['BUILD_TAG'] = 'master'
+        os.environ['CI_LOOP'] = 'weekly'
+
+    def test_get_unset_unknown_env(self):
+        del os.environ['FOO']
+        self.assertEqual(env.get('FOO'), None)
+        # Backward compatibilty (waiting for SDNVPN and SFC)
+        reload_module(env)
+        with self.assertRaises(AttributeError):
+            getattr(env.ENV, 'FOO')
+        reload_module(constants)
+        with self.assertRaises(AttributeError):
+            getattr(constants.CONST, 'FOO')
+
+    def test_get_unknown_env(self):
+        self.assertEqual(env.get('FOO'), 'foo')
+        reload_module(env)
+        # Backward compatibilty (waiting for SDNVPN and SFC)
+        with self.assertRaises(AttributeError):
+            getattr(env.ENV, 'FOO')
+        reload_module(constants)
+        with self.assertRaises(AttributeError):
+            getattr(constants.CONST, 'FOO')
+
+    def test_get_unset_env(self):
+        del os.environ['CI_LOOP']
+        self.assertEqual(
+            env.get('CI_LOOP'), env.INPUTS['CI_LOOP'])
+        # Backward compatibilty (waiting for SDNVPN and SFC)
+        reload_module(env)
+        self.assertEqual(
+            getattr(env.ENV, 'CI_LOOP'), env.INPUTS['CI_LOOP'])
+        reload_module(constants)
+        self.assertEqual(
+            getattr(constants.CONST, 'CI_LOOP'),
+            env.INPUTS['CI_LOOP'])
+
+    def test_get_env(self):
+        self.assertEqual(
+            env.get('CI_LOOP'), 'weekly')
+        # Backward compatibilty (waiting for SDNVPN and SFC)
+        reload_module(env)
+        self.assertEqual(getattr(env.ENV, 'CI_LOOP'), 'weekly')
+        reload_module(constants)
+        self.assertEqual(getattr(constants.CONST, 'CI_LOOP'), 'weekly')
+
+    def test_get_unset_env2(self):
+        del os.environ['BUILD_TAG']
+        self.assertEqual(
+            env.get('BUILD_TAG'), env.INPUTS['BUILD_TAG'])
+        # Backward compatibilty (waiting for SDNVPN and SFC)
+        reload_module(env)
+        self.assertEqual(
+            getattr(env.ENV, 'BUILD_TAG'), env.INPUTS['BUILD_TAG'])
+        reload_module(constants)
+        self.assertEqual(
+            getattr(constants.CONST, 'BUILD_TAG'), env.INPUTS['BUILD_TAG'])
+
+    def test_get_env2(self):
+        self.assertEqual(env.get('BUILD_TAG'), 'master')
+        # Backward compatibilty (waiting for SDNVPN and SFC)
+        reload_module(env)
+        self.assertEqual(getattr(env.ENV, 'BUILD_TAG'), 'master')
+        reload_module(env)
+        self.assertEqual(getattr(constants.CONST, 'BUILD_TAG'), 'master')
+
+
+if __name__ == "__main__":
+    logging.disable(logging.CRITICAL)
+    unittest.main(verbosity=2)
index dd34c90..9f8733b 100644 (file)
@@ -128,7 +128,7 @@ class FunctestUtilsTesting(unittest.TestCase):
             self.assertEqual(functest_utils.get_resolvconf_ns(),
                              self.test_ip[1:])
 
-    def _get_environ(self, var):
+    def _get_environ(self, var, *args):  # pylint: disable=unused-argument
         if var == 'INSTALLER_TYPE':
             return self.installer
         elif var == 'DEPLOY_SCENARIO':
index c569856..61d8401 100644 (file)
@@ -2,12 +2,13 @@
 
 # pylint: disable=missing-docstring
 
-import os
 import pkg_resources
 import yaml
 
 import six
 
+from functest.utils import env
+
 
 class Config(object):
     def __init__(self):
@@ -37,7 +38,7 @@ class Config(object):
             patch_file = yaml.safe_load(yfile)
 
         for key in patch_file:
-            if key in os.environ.get('DEPLOY_SCENARIO', ""):
+            if key in env.get('DEPLOY_SCENARIO'):
                 self.functest_yaml = dict(Config._merge_dicts(
                     self.functest_yaml, patch_file[key]))
 
@@ -64,7 +65,7 @@ class Config(object):
 CONF = Config()
 CONF.patch_file(pkg_resources.resource_filename(
     'functest', 'ci/config_patch.yaml'))
-if os.getenv("POD_ARCH", None) and os.getenv("POD_ARCH", None) in ['aarch64']:
+if env.get("POD_ARCH") in ['aarch64']:
     CONF.patch_file(pkg_resources.resource_filename(
         'functest', 'ci/config_aarch64_patch.yaml'))
 CONF.fill()
index c19e0fc..d8a1d54 100644 (file)
@@ -2,6 +2,7 @@
 
 # pylint: disable=missing-docstring
 
+import pkg_resources
 import six
 
 from functest.utils import config
@@ -10,6 +11,9 @@ from functest.utils import env
 
 class Constants(object):  # pylint: disable=too-few-public-methods
 
+    CONFIG_FUNCTEST_YAML = pkg_resources.resource_filename(
+        'functest', 'ci/config_functest.yaml')
+
     def __init__(self):
         for attr_n, attr_v in six.iteritems(config.CONF.__dict__):
             setattr(self, attr_n, attr_v)
index b626473..0c0515b 100644 (file)
@@ -1,45 +1,46 @@
 #!/usr/bin/env python
 
+# Copyright (c) 2018 Orange and others.
+#
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Apache License, Version 2.0
+# which accompanies this distribution, and is available at
+# http://www.apache.org/licenses/LICENSE-2.0
+
 # pylint: disable=missing-docstring
 
 import os
-import re
 
-import pkg_resources
 import six
 
+INPUTS = {
+    'EXTERNAL_NETWORK': None,
+    'CI_LOOP': 'daily',
+    'DEPLOY_SCENARIO': 'os-nosdn-nofeature-noha',
+    'INSTALLER_TYPE': None,
+    'SDN_CONTROLLER_IP': None,
+    'BUILD_TAG': None,
+    'NODE_NAME': None,
+    'POD_ARCH': None,
+    'TEST_DB_URL': 'http://testresults.opnfv.org/test/api/v1/results',
+    'ENERGY_RECORDER_API_URL': 'http://energy.opnfv.fr/resources',
+    'ENERGY_RECORDER_API_USER': '',
+    'ENERGY_RECORDER_API_PASSWORD': ''
+}
 
-class Environment(object):  # pylint: disable=too-few-public-methods
 
-    default_envs = {
-        'NODE_NAME': 'unknown_pod',
-        'DEPLOY_SCENARIO': 'os-nosdn-nofeature-noha',
-        'DEPLOY_TYPE': 'virt',
-        'INSTALLER_TYPE': None,
-        'BUILD_TAG': None,
-        'OS_ENDPOINT_TYPE': None,
-        'OS_AUTH_URL': None,
-        'CONFIG_FUNCTEST_YAML': pkg_resources.resource_filename(
-            'functest', 'ci/config_functest.yaml'),
-        'OS_INSECURE': '',
-        'OS_REGION_NAME': 'RegionOne'
-    }
+def get(env_var):
+    if env_var not in INPUTS.keys():
+        return os.environ.get(env_var, None)
+    return os.environ.get(env_var, INPUTS[env_var])
 
-    def __init__(self):
-        for key, value in six.iteritems(os.environ):
-            setattr(self, key, value)
-        for key, value in six.iteritems(self.default_envs):
-            if key not in os.environ:
-                setattr(self, key, value)
-        if 'CI_LOOP' not in os.environ:
-            self._set_ci_loop()
-
-    def _set_ci_loop(self):
-        if (getattr(self, "BUILD_TAG") and
-                re.search("daily", getattr(self, "BUILD_TAG"))):
-            setattr(self, "CI_LOOP", "daily")
-        else:
-            setattr(self, "CI_LOOP", "weekly")
 
+class Environment(object):  # pylint: disable=too-few-public-methods
+
+    # Backward compatibilty (waiting for SDNVPN and SFC)
+    def __init__(self):
+        for key, _ in six.iteritems(INPUTS):
+            setattr(self, key, get(key))
 
+# Backward compatibilty (waiting for SDNVPN and SFC)
 ENV = Environment()
index e84a2b4..b31b392 100644 (file)
@@ -11,7 +11,6 @@
 
 from __future__ import print_function
 import logging
-import os
 import re
 import shutil
 import subprocess
@@ -22,6 +21,7 @@ from six.moves import urllib
 import yaml
 
 from functest.utils import constants
+from functest.utils import env
 
 LOGGER = logging.getLogger(__name__)
 
@@ -90,8 +90,8 @@ def get_ci_envvars():
     Get the CI env variables
     """
     ci_env_var = {
-        "installer": os.environ.get('INSTALLER_TYPE'),
-        "scenario": os.environ.get('DEPLOY_SCENARIO')}
+        "installer": env.get('INSTALLER_TYPE'),
+        "scenario": env.get('DEPLOY_SCENARIO')}
     return ci_env_var
 
 
index b779997..98da48b 100644 (file)
@@ -22,7 +22,7 @@ from novaclient import client as novaclient
 from keystoneclient import client as keystoneclient
 from neutronclient.neutron import client as neutronclient
 
-from functest.utils.constants import CONST
+from functest.utils import env
 import functest.utils.functest_utils as ft_utils
 
 logger = logging.getLogger(__name__)
@@ -659,8 +659,8 @@ def get_private_net(neutron_client):
 
 
 def get_external_net(neutron_client):
-    if (hasattr(CONST, 'EXTERNAL_NETWORK')):
-        return CONST.__getattribute__('EXTERNAL_NETWORK')
+    if (env.get('EXTERNAL_NETWORK')):
+        return env.get('EXTERNAL_NETWORK')
     for network in neutron_client.list_networks()['networks']:
         if network['router:external']:
             return network['name']
@@ -668,9 +668,9 @@ def get_external_net(neutron_client):
 
 
 def get_external_net_id(neutron_client):
-    if (hasattr(CONST, 'EXTERNAL_NETWORK')):
+    if (env.get('EXTERNAL_NETWORK')):
         networks = neutron_client.list_networks(
-            name=CONST.__getattribute__('EXTERNAL_NETWORK'))
+            name=env.get('EXTERNAL_NETWORK'))
         net_id = networks['networks'][0]['id']
         return net_id
     for network in neutron_client.list_networks()['networks']: