diff --git a/doc/overview.rst b/doc/overview.rst index eba8cb2dff91e4828a33785234a54abe1967b774..1177232d727e873f87ee22fa711724266564b620 100644 --- a/doc/overview.rst +++ b/doc/overview.rst @@ -24,8 +24,20 @@ In case the venv becomes unusable for some reason, the ``lisa-install`` shell command available after sourcing ``init_env`` will allow to create a new clean venv from scratch. -Alternatively, ``lisa`` package is packaged according to the usual -Python practices, which includes a ``setup.py`` script, and a +Without automatic ``venv`` +-------------------------- + +Sometimes, LISA needs to operate in an environment setup for multiple tools. In +that case, it may be easier to manage manually a venv/virtualenv instead of +letting LISA create one for its shell. + +Setting ``export LISA_USE_VENV=0`` prior to ``source init_env`` will avoid the +creation and usage of the LISA-managed venv. ``lisa-install`` command can still +be used to install the necessary Python packages, which will honor any +venv-like system manually setup. + +Alternatively, ``lisa`` package is packaged according to the usual Python +practices, which includes a ``setup.py`` script, and a ``devmode_requirements.txt`` file that will install all the shipped packages in editable mode (including those that are not developped in that repository, but still included for convenience). diff --git a/init_env b/init_env index 0e1d22cdf1e2cbff07b1789c279f705e261b55c8..e1d388e63f745330e117d9071c28f60462fd0e62 100644 --- a/init_env +++ b/init_env @@ -23,9 +23,11 @@ if grep "bash" /proc/$$/cmdline &>/dev/null; then # Get base installation path of LISA export LISA_HOME=$(readlink -f "$(dirname "$BASH_SOURCE")") - source "$(dirname "$BASH_SOURCE")/shell/lisa_shell" + source "$(dirname "$BASH_SOURCE")/shell/lisa_shell"; RET=$? PS1="\[${LISASHELL_BLUE}\][LISAShell \[${LISASHELL_LCYAN}\]\W\[${LISASHELL_BLUE}\]] \> \[${LISASHELL_RESET}\]" + # Make sure that bash picks up new location for all binaries + hash -r # Running under ZSH elif grep "zsh" /proc/$$/cmdline &>/dev/null; then @@ -35,14 +37,16 @@ elif grep "zsh" /proc/$$/cmdline &>/dev/null; then # Source the script in "sh" emulation mode. This will also mark the # functions declared there to be executed in emulated mode, so they will # work as well - emulate sh -c "source "$LISA_HOME/shell/lisa_shell"" + emulate sh -c "source "$LISA_HOME/shell/lisa_shell""; RET=$? + # Make sure that zsh picks up new location for all binaries + hash -r else echo "WARNING: Current shell is not a BASH" # Check if a bash shell is available if which bash &>/dev/null; then # Switch to a BASH shell - exec bash --init-file ./init_env + exec bash --init-file ./init_env; RET=$? else echo "ERROR: A BASH shell is not available in PATH" fi @@ -51,4 +55,6 @@ else echo "Please, source this configuration from a terminal running BASH." fi +exit $RET + # vim :set tabstop=4 shiftwidth=4 textwidth=80 expandtab diff --git a/setup.py b/setup.py old mode 100644 new mode 100755 index f723be382a157639d22f3077cf3e067e4882e6ed..550cd53730bb6bf39ebf1b71a1ef0d7e5928d486 --- a/setup.py +++ b/setup.py @@ -1,3 +1,4 @@ +#! /usr/bin/env python3 # SPDX-License-Identifier: Apache-2.0 # # Copyright (C) 2018, Arm Limited and contributors. @@ -17,6 +18,50 @@ from setuptools import setup +import importlib +import distutils.cmd +import distutils.log + +class SystemCheckCommand(distutils.cmd.Command): + """A custom command to check some prerequisites on the system.""" + + description = 'check some requirements on the system, that cannot be satisfied by installing Python packages in a venv' + user_options = [ + # The format is (long option, short option, description). + ] + + def initialize_options(self): + """Set default values for options.""" + pass + + def finalize_options(self): + """Post-process options.""" + pass + + def run(self): + """Run command.""" + self.check_system_install() + + def check_system_install(self): + missing_pkg_msg = '\n\nThe following packages need to be installed using your Linux distribution package manager. On ubuntu, the following packages are needed:\n apt-get install {}\n\n' + distro_pkg_list = list() + def check_pkg(python_pkg, distro_pkg): + try: + importlib.import_module(python_pkg) + except ImportError: + distro_pkg_list.append(distro_pkg) + + # Some packages are not always present by default on Debian-based + # systems, even if there are part of the Python standard library + check_pkg('tkinter', 'python3-tk') + check_pkg('ensurepip', 'python3-venv') + + if distro_pkg_list: + self.announce( + missing_pkg_msg.format(' '.join(distro_pkg_list)), + level=distutils.log.INFO + ) + with open('README.md', 'r') as fh: long_description = fh.read() @@ -85,6 +130,11 @@ setup( "Topic :: Software Development :: Testing", "Intended Audience :: Developers", ], + + # Add extra subcommands to setup.py + cmdclass={ + 'systemcheck': SystemCheckCommand, + } ) # vim :set tabstop=4 shiftwidth=4 textwidth=80 expandtab diff --git a/shell/lisa_shell b/shell/lisa_shell index 8f610dcbb005197646e4019000a5d651980ac27c..904aa863d074167505eb38042851e4dfadc8407e 100755 --- a/shell/lisa_shell +++ b/shell/lisa_shell @@ -83,11 +83,11 @@ export LISA_USE_VENV=${LISA_USE_VENV:-1} export LISA_VENV_PATH=${LISA_VENV_PATH:-"$LISA_HOME/.lisa-venv3"} function _lisa-venv-create { - # Make sure we don't nest venv, by calling deactivate if it exists, - # otherwise it will fail with a symlink levels errors - lisa-venv-deactivate || return 1 - if [[ "$LISA_USE_VENV" == 1 ]]; then + # Make sure we don't nest venv, by calling deactivate if it exists, + # otherwise it will fail with a symlink levels errors + lisa-venv-deactivate || return 1 + echo "Creating LISA venv from scratch ($LISA_VENV_PATH) ..." # With --clear, the folder is emptied to create a fresh environment python3 -m venv --clear "$LISA_VENV_PATH" @@ -123,6 +123,10 @@ function _lisa-upgrade-pip { } function lisa-install { + # Check that some prerequisites are available on the system, since they + # cannot be installed using pip in a venv + python3 "$LISA_HOME/setup.py" systemcheck + _lisa-venv-create && _lisa-upgrade-pip || return 1 @@ -139,6 +143,7 @@ function lisa-install { echo echo "Installing LISA packages ..." echo + # Make sure we install all packages, even if they are satisfied by the # system's site-packages location. This ensures we use up to date packages, # and that the installation process will give the same result on all diff --git a/tools/bisector/bisector/bisector.py b/tools/bisector/bisector/bisector.py index 183dadc11f91a925177f7414ebc306e8499af2e7..cab7dae29083874801904bdb0cade98b4519ae14 100755 --- a/tools/bisector/bisector/bisector.py +++ b/tools/bisector/bisector/bisector.py @@ -2124,9 +2124,10 @@ class ExekallLISATestStep(ShellStep): stats = dict() testcase_stats[testcase_id] = stats - stats['total'] = iteration_n stats['iterations_summary'] = [entry['result'] for entry in entry_list] - stats['counters'] = dict() + stats['counters'] = { + 'total': iteration_n + } stats['events'] = dict() for issue, pretty_issue in ( ('passed', 'passed'), diff --git a/tools/bisector/bisector/xunit2json.py b/tools/bisector/bisector/xunit2json.py index dde94b60a73401003fe19086eaf80765dbe3b7c3..fc283cea503e5a78d0c30f6461efde949e6c5d19 100755 --- a/tools/bisector/bisector/xunit2json.py +++ b/tools/bisector/bisector/xunit2json.py @@ -56,27 +56,32 @@ def compare_df(json_df1, json_df2, alpha, alternative='two-sided', non_significa regression_map = collections.defaultdict(dict) for row in merged_df.itertuples(index=True): testcase = row[0] + failure_old = row.counters_old['failure'] + failure_new = row.counters_new['failure'] + passed_old = row.counters_old['passed'] + passed_new = row.counters_new['passed'] + odds_ratio, p_val = scipy.stats.fisher_exact( [ # Ignore errors and skipped tests - [row.failure_old, row.passed_old], - [row.failure_new, row.passed_new], + [failure_old, passed_old], + [failure_new, passed_new], ], alternative = alternative ) # Ignore errors and skipped tests - meaningful_total_old = row.failure_old + row.passed_old - meaningful_total_new = row.failure_new + row.passed_new + meaningful_total_old = failure_old + passed_old + meaningful_total_new = failure_new + passed_new # If no meaningful iterations are available, return NaN if not meaningful_total_old: failure_old_pc = float('Inf') else: - failure_old_pc = 100 * row.failure_old / (row.failure_old + row.passed_old) + failure_old_pc = 100 * failure_old / (failure_old + passed_old) if not meaningful_total_new: failure_new_pc = float('Inf') else: - failure_new_pc = 100 * row.failure_new / (row.failure_new + row.passed_new) + failure_new_pc = 100 * failure_new / (failure_new + passed_new) delta = failure_new_pc - failure_old_pc diff --git a/tools/bisector/setup.py b/tools/bisector/setup.py old mode 100644 new mode 100755 index 75edcdf155332cac38f4ca69c9d2bdc14e867b55..f6999e964edee8fcf6032ea11a799c6bf1e92e12 --- a/tools/bisector/setup.py +++ b/tools/bisector/setup.py @@ -1,3 +1,4 @@ +#! /usr/bin/env python3 # SPDX-License-Identifier: Apache-2.0 # # Copyright (C) 2018, Arm Limited and contributors. diff --git a/tools/exekall/setup.py b/tools/exekall/setup.py old mode 100644 new mode 100755 index 0ce7da5d44e3e31f304964301371ca4abbb3bdd4..4bd38315a7538192936b5e190fcf14ecc95ef148 --- a/tools/exekall/setup.py +++ b/tools/exekall/setup.py @@ -1,3 +1,4 @@ +#! /usr/bin/env python3 # SPDX-License-Identifier: Apache-2.0 # # Copyright (C) 2018, Arm Limited and contributors.