Skip to content

Commit

Permalink
DAOS-15659 test: fix local ftest prefix
Browse files Browse the repository at this point in the history
Test-tag: pr
Skip-unit-tests: true
Skip-fault-injection-test: true

PR #13565 accidentally broke how ftest determines the prefix from
.build_vars.json because it is no longer installed.

Eliminate the need for .build_vars.json in ftest entirely by using
"command -v daos" and support setting DAOS_TEST_PREFIX

Required-githooks: true

Signed-off-by: Dalton Bohning <[email protected]>
  • Loading branch information
daltonbohning committed Apr 23, 2024
1 parent c122a9a commit b283818
Show file tree
Hide file tree
Showing 2 changed files with 84 additions and 85 deletions.
23 changes: 4 additions & 19 deletions src/tests/ftest/util/apricot/apricot/test.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
"""
# pylint: disable=too-many-lines

import json
import os
import random
import re
Expand All @@ -23,6 +22,7 @@
from daos_utils import DaosCommand
from distro_utils import detect
from dmg_utils import get_dmg_command
from environment_utils import TestEnvironment
from exception_utils import CommandFailure
from fault_config_utils import FaultInjection
from general_utils import (DaosTestError, dict_to_str, dump_engines_stacks,
Expand Down Expand Up @@ -125,9 +125,7 @@ def __init__(self, *args, **kwargs):
# use 'add_cancel_ticket(<ticket>)' to add to this set.
self._teardown_cancel = set()
self._teardown_errors = []
self.basepath = None
self.prefix = None
self.ofi_prefix = None
self.cancel_file = os.path.join(os.sep, "scratch", "CI-skip-list-master")

# List of methods to call during tearDown to cleanup after the steps
Expand All @@ -150,22 +148,9 @@ def __init__(self, *args, **kwargs):

def setUp(self):
"""Set up each test case."""
# get paths from the build_vars generated by build
try:
with open('../../.build_vars.json') as build_vars:
build_paths = json.load(build_vars)
self.basepath = os.path.normpath(os.path.join(build_paths['PREFIX'],
'..') + os.path.sep)
self.prefix = build_paths['PREFIX']
try:
self.ofi_prefix = build_paths['OFI_PREFIX']
except KeyError:
self.ofi_prefix = os.sep + "usr"
except FileNotFoundError:
self.prefix = "/usr"
self.basepath = "/"
self.ofi_prefix = os.sep + "usr"
self.log.info("No build vars file, assuming RPM install")
test_env = TestEnvironment()
self.prefix = test_env.daos_prefix
self.log.info("Using daos install prefix = %s", self.prefix)
self.cancel_from_list()
self.check_variant_skip()
self.log.info("*** SETUP running on %s ***", str(detect()))
Expand Down
146 changes: 80 additions & 66 deletions src/tests/ftest/util/environment_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,76 +3,40 @@
SPDX-License-Identifier: BSD-2-Clause-Patent
"""
import json
import os
import re
import site

from ClusterShell.NodeSet import NodeSet
# pylint: disable=import-error,no-name-in-module
from util.network_utils import (PROVIDER_ALIAS, SUPPORTED_PROVIDERS, NetworkException,
get_common_provider, get_fastest_interface)
from util.run_utils import run_remote
from util.run_utils import RunException, run_local, run_remote


class TestEnvironmentException(Exception):
"""Exception for launch.py execution."""


def _get_build_environment(logger, build_vars_file):
"""Obtain DAOS build environment variables from the .build_vars.json file.
Args:
logger (Logger): logger for the messages produced by this method
build_vars_file (str): the full path to the DAOS build_vars.json file
Raises:
TestEnvironmentException: if there is an error obtaining the DAOS build environment
Returns:
str: The prefix of the DAOS install.
None: If the file is not present.
"""
logger.debug("Obtaining DAOS build environment from %s", build_vars_file)
try:
with open(build_vars_file, encoding="utf-8") as vars_file:
return json.load(vars_file)["PREFIX"]

except FileNotFoundError:
return None

except Exception as error: # pylint: disable=broad-except
raise TestEnvironmentException("Error obtaining build environment:", str(error)) from error


def _update_path(logger, build_vars_file):
def _update_path(daos_prefix):
"""Update the PATH environment variable for functional testing.
Args:
logger (Logger): logger for the messages produced by this method
build_vars_file (str): the full path to the DAOS build_vars.json file
daos_prefix (str): daos install prefix
Raises:
TestEnvironmentException: if there is an error obtaining the DAOS build environment
"""
base_dir = _get_build_environment(logger, build_vars_file)

path = os.environ.get("PATH")

parts = path.split(":")

# If a custom prefix is used for the daos installation then prepend that to the path so that
# any binaries provided are picked up from there, else do not modify the path.
if base_dir:
bin_dir = os.path.join(base_dir, "bin")
sbin_dir = os.path.join(base_dir, "sbin")
parts = os.environ.get("PATH").split(":")

# Insert bin and sbin at the beginning of PATH if prefix is not /usr
if daos_prefix != os.path.join(os.sep, "usr"):
bin_dir = os.path.join(daos_prefix, "bin")
sbin_dir = os.path.join(daos_prefix, "sbin")
parts.insert(0, bin_dir)
parts.insert(0, sbin_dir)

# /usr/sbin is not setup on non-root user for CI nodes.
# SCM formatting tool mkfs.ext4 is located under /usr/sbin directory.
usr_sbin = os.path.join(os.sep, "usr", "sbin")

if usr_sbin not in parts:
parts.append(usr_sbin)

Expand Down Expand Up @@ -142,6 +106,7 @@ class TestEnvironment():
'insecure_mode': 'DAOS_TEST_INSECURE_MODE',
'bullseye_src': 'DAOS_TEST_BULLSEYE_SRC',
'bullseye_file': 'COVFILE',
'daos_prefix': 'DAOS_TEST_PREFIX'
}

def __init__(self):
Expand Down Expand Up @@ -176,23 +141,25 @@ def set_defaults(self, logger, servers=None, clients=None, provider=None, insecu
self.insecure_mode = insecure_mode

if self.log_dir is None:
self.log_dir = self.default_log_dir()
self.log_dir = self._default_log_dir()
if self.shared_dir is None:
self.shared_dir = self.default_shared_dir()
self.shared_dir = self._default_shared_dir()
if self.app_dir is None:
self.app_dir = self.default_app_dir()
self.app_dir = self._default_app_dir()
if self.user_dir is None:
self.user_dir = self.default_user_dir()
self.user_dir = self._default_user_dir()
if self.interface is None:
self.interface = self.default_interface(logger, all_hosts)
self.interface = self._default_interface(logger, all_hosts)
if self.provider is None:
self.provider = self.default_provider(logger, servers)
self.provider = self._default_provider(logger, servers)
if self.insecure_mode is None:
self.insecure_mode = self.default_insecure_mode()
self.insecure_mode = self._default_insecure_mode()
if self.bullseye_src is None:
self.bullseye_src = self.default_bullseye_src()
self.bullseye_src = self._default_bullseye_src()
if self.bullseye_file is None:
self.bullseye_file = self.default_bullseye_file()
self.bullseye_file = self._default_bullseye_file()
if self.daos_prefix is None:
self.daos_prefix = self._default_daos_prefix(logger)

def __set_value(self, key, value):
"""Set the test environment variable.
Expand Down Expand Up @@ -224,7 +191,7 @@ def app_dir(self, value):
"""
self.__set_value('app_dir', value)

def default_app_dir(self):
def _default_app_dir(self):
"""Get the default application directory path.
Returns:
Expand Down Expand Up @@ -269,7 +236,7 @@ def log_dir(self, value):
self.__set_value('log_dir', value)

@staticmethod
def default_log_dir():
def _default_log_dir():
"""Get the default local log directory path.
Returns:
Expand All @@ -296,7 +263,7 @@ def shared_dir(self, value):
self.__set_value('shared_dir', value)

@staticmethod
def default_shared_dir():
def _default_shared_dir():
"""Get the default shared log directory path.
Returns:
Expand All @@ -322,7 +289,7 @@ def user_dir(self, value):
"""
self.__set_value('user_dir', value)

def default_user_dir(self):
def _default_user_dir(self):
"""Get the default user directory path.
Returns:
Expand All @@ -348,7 +315,7 @@ def interface(self, value):
"""
self.__set_value('interface', value)

def default_interface(self, logger, hosts):
def _default_interface(self, logger, hosts):
"""Get the default interface.
Args:
Expand Down Expand Up @@ -394,7 +361,7 @@ def provider(self, value):
else:
self.__set_value('provider', value)

def default_provider(self, logger, hosts):
def _default_provider(self, logger, hosts):
"""Get the default provider.
Args:
Expand Down Expand Up @@ -463,7 +430,7 @@ def insecure_mode(self, value):
self.__set_value('insecure_mode', value)

@staticmethod
def default_insecure_mode():
def _default_insecure_mode():
"""Get the default insecure mode.
Returns:
Expand All @@ -490,7 +457,7 @@ def bullseye_src(self, value):
self.__set_value('bullseye_src', value)

@staticmethod
def default_bullseye_src():
def _default_bullseye_src():
"""Get the default bullseye source file.
Returns:
Expand All @@ -517,14 +484,63 @@ def bullseye_file(self, value):
self.__set_value('bullseye_file', value)

@staticmethod
def default_bullseye_file():
def _default_bullseye_file():
"""Get the default bullseye file.
Returns:
str: the default bullseye file
"""
return os.path.join(os.sep, "tmp", "test.cov")

@property
def daos_prefix(self):
"""Get the daos_prefix.
Returns:
str: the daos_prefix
"""
return os.environ.get(self.__ENV_VAR_MAP['daos_prefix'])

@daos_prefix.setter
def daos_prefix(self, value):
"""Set the daos_prefix.
Args:
value (str, bool): the daos_prefix
"""
self.__set_value('daos_prefix', value)

def _default_daos_prefix(self, logger):
"""Get the default daos_prefix.
Args:
logger (Logger): logger for the messages produced by this method
Raises:
TestEnvironmentException: if there is an error obtaining the default daos_prefix
Returns:
str: the default daos_prefix; can be None
"""
if logger is None:
return None

logger.debug(
"Detecting daos_prefix for %s - %s not set",
self.daos_prefix, self.__ENV_VAR_MAP['daos_prefix'])

try:
output = run_local(logger, 'command -v daos', timeout=5, check=True)
except RunException as error:
raise TestEnvironmentException("Error obtaining a default daos_prefix!") from error

paths = re.findall(rf'^{os.sep}.*daos$', output.stdout)
if not paths:
raise TestEnvironmentException("Error obtaining a default daos_prefix!")

daos_bin_path = paths[0]
return os.path.dirname(os.path.dirname(daos_bin_path))


def set_test_environment(logger, test_env=None, servers=None, clients=None, provider=None,
insecure_mode=False, details=None):
Expand Down Expand Up @@ -552,9 +568,7 @@ def set_test_environment(logger, test_env=None, servers=None, clients=None, prov

if test_env:
# Update the PATH environment variable
build_vars_file = os.path.join(
os.path.dirname(os.path.realpath(__file__)), "..", "..", "..", ".build_vars.json")
_update_path(logger, build_vars_file)
_update_path(test_env.daos_prefix)

# Get the default fabric interface and provider
test_env.set_defaults(logger, servers, clients, provider, insecure_mode)
Expand Down

0 comments on commit b283818

Please sign in to comment.