From d589e4e5345ed82c68d9a011ac89f8cdbefe2ca3 Mon Sep 17 00:00:00 2001 From: =?utf8?q?C=C3=A9dric=20Ollivier?= Date: Wed, 14 Feb 2018 16:02:53 +0100 Subject: [PATCH] Get properly env vars or their default values MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit 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 --- docs/testing/user/configguide/configguide.rst | 4 + functest/api/resources/v1/testcases.py | 13 +-- functest/ci/run_tests.py | 17 ++-- functest/cli/commands/cli_env.py | 12 +-- functest/cli/commands/cli_tier.py | 6 +- functest/core/testcase.py | 16 ++-- functest/energy/energy.py | 16 ++-- functest/opnfv_tests/openstack/rally/rally.py | 5 +- .../openstack/snaps/snaps_test_runner.py | 3 +- .../opnfv_tests/openstack/snaps/snaps_utils.py | 5 +- .../opnfv_tests/openstack/tempest/conf_utils.py | 22 ++--- functest/opnfv_tests/openstack/tempest/tempest.py | 9 +- functest/opnfv_tests/openstack/vping/vping_base.py | 3 +- functest/opnfv_tests/sdn/odl/odl.py | 11 ++- .../tests/unit/openstack/tempest/test_tempest.py | 10 +-- functest/tests/unit/utils/test_env.py | 96 ++++++++++++++++++++++ functest/tests/unit/utils/test_functest_utils.py | 2 +- functest/utils/config.py | 7 +- functest/utils/constants.py | 4 + functest/utils/env.py | 63 +++++++------- functest/utils/functest_utils.py | 6 +- functest/utils/openstack_utils.py | 10 +-- 22 files changed, 226 insertions(+), 114 deletions(-) create mode 100644 functest/tests/unit/utils/test_env.py diff --git a/docs/testing/user/configguide/configguide.rst b/docs/testing/user/configguide/configguide.rst index c4d9a6d77..f65810817 100644 --- a/docs/testing/user/configguide/configguide.rst +++ b/docs/testing/user/configguide/configguide.rst @@ -197,9 +197,13 @@ Environment variables Several environement variables may be specified: * INSTALLER_TYPE=(apex|compass|daisy|fuel|joid) + * INSTALLER_IP= * DEPLOY_SCENARIO=--- +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 ) diff --git a/functest/api/resources/v1/testcases.py b/functest/api/resources/v1/testcases.py index bc21c6fae..064661c8b 100644 --- a/functest/api/resources/v1/testcases.py +++ b/functest/api/resources/v1/testcases.py @@ -11,22 +11,23 @@ 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'), diff --git a/functest/ci/run_tests.py b/functest/ci/run_tests.py index ff38720d6..ca101ce6b 100644 --- a/functest/ci/run_tests.py +++ b/functest/ci/run_tests.py @@ -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, diff --git a/functest/cli/commands/cli_env.py b/functest/cli/commands/cli_env.py index f93ef612c..18c8895ae 100644 --- a/functest/cli/commands/cli_env.py +++ b/functest/cli/commands/cli_env.py @@ -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("-") diff --git a/functest/cli/commands/cli_tier.py b/functest/cli/commands/cli_tier.py index 933d8cd63..3694c1ae7 100644 --- a/functest/cli/commands/cli_tier.py +++ b/functest/cli/commands/cli_tier.py @@ -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): diff --git a/functest/core/testcase.py b/functest/core/testcase.py index f0c6c9e9f..e8bb1409d 100644 --- a/functest/core/testcase.py +++ b/functest/core/testcase.py @@ -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 diff --git a/functest/energy/energy.py b/functest/energy/energy.py index c7da8f046..d5f6871d0 100644 --- a/functest/energy/energy.py +++ b/functest/energy/energy.py @@ -12,13 +12,14 @@ 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) diff --git a/functest/opnfv_tests/openstack/rally/rally.py b/functest/opnfv_tests/openstack/rally/rally.py index 2632fd398..add0f2437 100644 --- a/functest/opnfv_tests/openstack/rally/rally.py +++ b/functest/opnfv_tests/openstack/rally/rally.py @@ -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']: diff --git a/functest/opnfv_tests/openstack/snaps/snaps_test_runner.py b/functest/opnfv_tests/openstack/snaps/snaps_test_runner.py index 9d31f426c..216d9acf6 100644 --- a/functest/opnfv_tests/openstack/snaps/snaps_test_runner.py +++ b/functest/opnfv_tests/openstack/snaps/snaps_test_runner.py @@ -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: diff --git a/functest/opnfv_tests/openstack/snaps/snaps_utils.py b/functest/opnfv_tests/openstack/snaps/snaps_utils.py index 6bc50ad60..59bd063c1 100644 --- a/functest/opnfv_tests/openstack/snaps/snaps_utils.py +++ b/functest/opnfv_tests/openstack/snaps/snaps_utils.py @@ -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 diff --git a/functest/opnfv_tests/openstack/tempest/conf_utils.py b/functest/opnfv_tests/openstack/tempest/conf_utils.py index f128784c2..09471fa52 100644 --- a/functest/opnfv_tests/openstack/tempest/conf_utils.py +++ b/functest/opnfv_tests/openstack/tempest/conf_utils.py @@ -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') diff --git a/functest/opnfv_tests/openstack/tempest/tempest.py b/functest/opnfv_tests/openstack/tempest/tempest.py index 56705fc0f..c19c8d9d2 100644 --- a/functest/opnfv_tests/openstack/tempest/tempest.py +++ b/functest/opnfv_tests/openstack/tempest/tempest.py @@ -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__( diff --git a/functest/opnfv_tests/openstack/vping/vping_base.py b/functest/opnfv_tests/openstack/vping/vping_base.py index 7170101f5..fae5db2d4 100644 --- a/functest/opnfv_tests/openstack/vping/vping_base.py +++ b/functest/opnfv_tests/openstack/vping/vping_base.py @@ -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: diff --git a/functest/opnfv_tests/sdn/odl/odl.py b/functest/opnfv_tests/sdn/odl/odl.py index 4c33c4957..705f39dab 100644 --- a/functest/opnfv_tests/sdn/odl/odl.py +++ b/functest/opnfv_tests/sdn/odl/odl.py @@ -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 " @@ -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: " diff --git a/functest/tests/unit/openstack/tempest/test_tempest.py b/functest/tests/unit/openstack/tempest/test_tempest.py index 5d543ffcc..060a8a010 100644 --- a/functest/tests/unit/openstack/tempest/test_tempest.py +++ b/functest/tests/unit/openstack/tempest/test_tempest.py @@ -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 index 000000000..064ff9880 --- /dev/null +++ b/functest/tests/unit/utils/test_env.py @@ -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) diff --git a/functest/tests/unit/utils/test_functest_utils.py b/functest/tests/unit/utils/test_functest_utils.py index dd34c90dc..9f8733bba 100644 --- a/functest/tests/unit/utils/test_functest_utils.py +++ b/functest/tests/unit/utils/test_functest_utils.py @@ -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': diff --git a/functest/utils/config.py b/functest/utils/config.py index c569856b1..61d8401c5 100644 --- a/functest/utils/config.py +++ b/functest/utils/config.py @@ -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() diff --git a/functest/utils/constants.py b/functest/utils/constants.py index c19e0fc52..d8a1d54d1 100644 --- a/functest/utils/constants.py +++ b/functest/utils/constants.py @@ -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) diff --git a/functest/utils/env.py b/functest/utils/env.py index b626473a9..0c0515ba1 100644 --- a/functest/utils/env.py +++ b/functest/utils/env.py @@ -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() diff --git a/functest/utils/functest_utils.py b/functest/utils/functest_utils.py index e84a2b426..b31b392d7 100644 --- a/functest/utils/functest_utils.py +++ b/functest/utils/functest_utils.py @@ -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 diff --git a/functest/utils/openstack_utils.py b/functest/utils/openstack_utils.py index b779997c9..98da48b8c 100644 --- a/functest/utils/openstack_utils.py +++ b/functest/utils/openstack_utils.py @@ -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']: -- 2.16.6