|  | 
| 1 | 1 | # Development setup | 
| 2 | 2 | 
 | 
|  | 3 | +To run all tests and all supported static analysis tools, Python 3.11 is needed, | 
|  | 4 | +which matches the current Python version of XenServer 9. | 
|  | 5 | + | 
|  | 6 | +Python 3.10 might work as well (when replacing the references in the config files with 3.10). | 
|  | 7 | +Python 3.12 and 3.13 can be used too, but not for running [pytype](https://github.com/google/pytype) | 
|  | 8 | +([it does not support 3.12 yet](https://google.github.io/pytype/support.html)). | 
|  | 9 | + | 
|  | 10 | +On Ubuntu, you can install 3.11 (and also 3.12 and 3.13) from the widely-used Python support PPA: | 
|  | 11 | + | 
|  | 12 | +```sh | 
|  | 13 | +sudo add-apt-repository ppa:deadsnakes/ppa && sudo apt update | 
|  | 14 | +sudo apt install -y python3.11 python3.12 python3.13 | 
|  | 15 | +``` | 
|  | 16 | + | 
|  | 17 | +If 3.12 or 3.13 are found by [tox](https://tox.wiki), it will run the unit tests with them as well. | 
|  | 18 | + | 
|  | 19 | +You can also use [uv to install Python versions](https://docs.astral.sh/uv/concepts/python-versions), | 
|  | 20 | +see below on a link and an example how to install uv. | 
|  | 21 | + | 
|  | 22 | +## Do not use distro-privided Python CI tools | 
|  | 23 | + | 
|  | 24 | +Python tools (other than the Python interpreters themself) provided by Linux distributions | 
|  | 25 | +are "always" out of date and do not work as required. If possible, uninstall/remove those, | 
|  | 26 | +even if your environment is based on Ubuntu 24.04. In addition, most problematically, the | 
|  | 27 | +distribution-provided Python tools are running using the default Pyton version of the | 
|  | 28 | +host system, which may not be compatible and can cause subtle errors.  (e.g. Python 3.12 | 
|  | 29 | +or newer triggers unclear dependency errors in pytype because it is not supported yet) | 
|  | 30 | + | 
| 3 | 31 | ## Create a virtual environment with the test dependencies | 
| 4 | 32 | 
 | 
|  | 33 | +[Install `uv`](https://docs.astral.sh/uv/), either using `pip`/`pipx` or the | 
|  | 34 | +[installer](https://docs.astral.sh/uv/getting-started/installation/) | 
|  | 35 | +and install the extras groups that you need. Example: | 
|  | 36 | + | 
|  | 37 | +```sh | 
|  | 38 | +pip install pipx | 
|  | 39 | +pipx install uv | 
|  | 40 | +uv venv --python 3.11 .uv-venv | 
|  | 41 | +. .uv-venv/bin/activate | 
|  | 42 | +uv pip install -r pyproject.toml --extra test mypy pytype pyright tox pre-commit | 
|  | 43 | +``` | 
|  | 44 | + | 
|  | 45 | +The older, slower way is to use pip-compile to the deps from `pyproject.toml`: | 
|  | 46 | + | 
| 5 | 47 | ```bash | 
| 6 | 48 | python -m venv .venv | 
| 7 | 49 | . .venv/bin/activate | 
| 8 |  | -pip install pip-tools==7.3.0 | 
|  | 50 | +pip install pre-commit pip-tools==7.3.0 | 
| 9 | 51 | pip-compile --extra=test,mypy,pyright,pytype,tox -o - pyproject.toml | pip install -r /dev/stdin | 
| 10 | 52 | ``` | 
| 11 | 53 | 
 | 
| 12 |  | -## Development setup on Fedora 37 | 
|  | 54 | +## Running CI | 
| 13 | 55 | 
 | 
| 14 |  | -On Fedora 37, the `tox` rpm installs all Python versions. | 
| 15 |  | -But this `tox` is older, so install `tox==4.5.1` using `pip` (see below) | 
|  | 56 | +These commands assume you installed the tools using the commands above in a Python 3.11 environment. | 
| 16 | 57 | 
 | 
| 17 |  | -```bash | 
| 18 |  | -sudo dnf install tox;sudo rpm -e tox | 
|  | 58 | +### Run pyright, watching for changes and automatically checking the change | 
|  | 59 | + | 
|  | 60 | +```sh | 
|  | 61 | +pyright -w | 
| 19 | 62 | ``` | 
| 20 | 63 | 
 | 
| 21 |  | -But preferably use `tox` from the virtual environment instead. | 
|  | 64 | +### Run pytest with coverage (fine-grained, e.g. during test development) | 
|  | 65 | + | 
|  | 66 | +```sh | 
|  | 67 | +pytest --cov -v --new-first -x --show-capture=all -rA [optional: files / select which tests to run] | 
|  | 68 | +``` | 
| 22 | 69 | 
 | 
| 23 |  | -## Development setup on Ubuntu 24.04 | 
|  | 70 | +### Watching and running tests on changes automatically using `pytest-watch` (`ptw`) | 
| 24 | 71 | 
 | 
| 25 |  | -Prefer the virtual environment. Alternatively, an option is to use `pipx`: | 
|  | 72 | +Install ptw in the Python environment using: | 
| 26 | 73 | 
 | 
| 27 |  | -```bash | 
| 28 |  | -sudo apt install pipx | 
| 29 |  | -pipx install tox; pipx install 'pytest<7';pipx install pylint | 
| 30 |  | -pipx inject pytest pytest-{forked,localftpserver,pythonpath,subprocess,timeout} pyfakefs pytest_httpserver six mock | 
| 31 |  | -pipx inject pylint pyfakefs six mock pytest{,_forked,-localftpserver} | 
|  | 74 | +```sh | 
|  | 75 | +pip install pytest-watch | 
| 32 | 76 | ``` | 
| 33 | 77 | 
 | 
| 34 |  | -Use the `deadsnakes` ppa to install Python versions like 3.8 and 3.11 (see below) | 
|  | 78 | +`ptw` watches changed files and runs `pytest` after changes are saved. | 
|  | 79 | +Run `ptw`, and pass the files to watch, e.g.: | 
| 35 | 80 | 
 | 
| 36 |  | -## Development setup on Ubuntu 22.04 | 
|  | 81 | +```sh | 
|  | 82 | +ptw tests/test_* | 
|  | 83 | +``` | 
| 37 | 84 | 
 | 
| 38 |  | -Usage of <https://launchpad.net/~deadsnakes/+archive/ubuntu/ppa> to install | 
| 39 |  | -other python versions. | 
|  | 85 | +### Run mypy (fine-grained, e.g. during development) | 
| 40 | 86 | 
 | 
| 41 |  | -```bash | 
| 42 |  | -sudo apt update | 
| 43 |  | -sudo apt install software-properties-common python{2,3}-dev | 
| 44 |  | -sudo add-apt-repository -y ppa:deadsnakes/ppa | 
| 45 |  | -sudo apt-get install -y python3.{8,11}{,-distutils} | 
|  | 87 | +```sh | 
|  | 88 | +mypy [optionally pass the flags or files to select which tests to run] | 
|  | 89 | +``` | 
|  | 90 | +
 | 
|  | 91 | +### Run pylint (fine-grained, e.g. during development) | 
|  | 92 | +
 | 
|  | 93 | +```sh | 
|  | 94 | +pylint xcp tests [optionally pass the flags or files to select which tests to run] | 
|  | 95 | +``` | 
|  | 96 | +
 | 
|  | 97 | +### Run all of the above on one go in defined virtual environments | 
|  | 98 | +
 | 
|  | 99 | +```sh | 
|  | 100 | +tox -e py311-cov-check-lint-mdreport | 
| 46 | 101 | ``` | 
| 47 | 102 | 
 | 
| 48 |  | -Installation of additional python versions for testing different versions: | 
|  | 103 | +This also checks code coverage and ends with a test report from the pytest run. | 
|  | 104 | +If you just run `tox` without arguments, in addition, the unit tests are run with | 
|  | 105 | +all installed Python versions (out of the list of 3.11, 3.12 and 3.13) | 
| 49 | 106 | 
 | 
| 50 |  | -- If `deadsnakes/ppa` does not work, e.g. for Python 3.6, `conda` or `pyenv` can be used. | 
| 51 |  | -  For instructions, see <https://realpython.com/intro-to-pyenv>: | 
|  | 107 | +### Run pre-commit for all checks | 
| 52 | 108 | 
 | 
| 53 |  | -  ```bash | 
| 54 |  | -  sudo apt install -y build-essential xz-utils zlib1g-dev \ | 
| 55 |  | -                      lib{bz2,ffi,lzma,readline,ssl,sqlite3}-dev | 
| 56 |  | -  curl https://pyenv.run | bash  # add displayed commands to .bashrc | 
| 57 |  | -  ~/.pyenv/bin/pyenv install 3.{6,8,11} && ~/.pyenv/bin/pyenv local 3.{6,8,11} # builds them | 
| 58 |  | -  ``` | 
|  | 109 | +To run all tests, including trailing whitespace checks, run | 
| 59 | 110 | 
 | 
| 60 |  | -- For testing on newer Ubuntu which has `python2-dev`, but not `pip2`, install `pip2` this way: | 
|  | 111 | +```sh | 
|  | 112 | +pre-commit run -av | 
|  | 113 | +``` | 
| 61 | 114 | 
 | 
| 62 |  | -  ```bash | 
| 63 |  | -  curl https://bootstrap.pypa.io/pip/2.7/get-pip.py --output get-pip.py;sudo python2 get-pip.py | 
| 64 |  | -  ``` | 
|  | 115 | +## Alternative: installing pytest packages using `pipx` | 
| 65 | 116 | 
 | 
| 66 |  | -You may want to install `pytype` in your user environment to run it directly without `tox`: | 
|  | 117 | +`pipx` installs tools in `~/.local/share/pipx/venvs` which can be an alternate | 
|  | 118 | +way to install up-to-date python tools | 
| 67 | 119 | 
 | 
| 68 | 120 | ```bash | 
| 69 |  | -# On Python != 3.8, pytype can't import xml.dom.minidom, use 3.8: | 
| 70 |  | -python3.8 -m pip install pytype | 
| 71 |  | -python -m pip install tabulate | 
| 72 |  | -./pytype_runner.py | 
|  | 121 | +python3.11 -m pip install pipx | 
|  | 122 | +pipx install tox; pipx install 'pytest<7';pipx install pylint pyright | 
|  | 123 | +pipx inject pytest pytest-{forked,localftpserver,pythonpath,subprocess,timeout} pyfakefs pytest_httpserver six mock | 
|  | 124 | +pipx inject pylint pyfakefs six mock pytest{,_forked,-localftpserver} | 
| 73 | 125 | ``` | 
| 74 | 126 | 
 | 
| 75 |  | -## Installation of dependencies using `pip` | 
|  | 127 | +### Updating the documentation | 
|  | 128 | +
 | 
|  | 129 | +For consistently well-spaced documentation, all Markdown files are checked | 
|  | 130 | +in CI using Markdownlint, which ensures that e.g. code blocks are separated | 
|  | 131 | +by space from the preceeding and following paragraphs and so on. This helps | 
|  | 132 | +to keep the Markdown source as well-readable as the rendered Markdown. | 
|  | 133 | +
 | 
|  | 134 | +To check and fix Markdown files quickly, use: | 
|  | 135 | +
 | 
|  | 136 | +```sh | 
|  | 137 | +pre-commit run -av markdownlint | 
|  | 138 | +``` | 
|  | 139 | +
 | 
|  | 140 | +### Removing trailing whitepace and fixing files to have only one trailing newline | 
|  | 141 | +
 | 
|  | 142 | +These fixers detect and fix trailing whitespace and trailing newlines in files | 
|  | 143 | +to keep commits clean of adding trailing whitespace and are used in GitHub CI: | 
|  | 144 | +
 | 
|  | 145 | +```sh | 
|  | 146 | +pre-commit run -av trailing-whitespace | 
|  | 147 | +pre-commit run -av end-of-file-fixer | 
|  | 148 | +``` | 
|  | 149 | +
 | 
|  | 150 | +## Background information on the provided tools | 
| 76 | 151 | 
 | 
| 77 | 152 | ### Testing locally and in GitHub CI using `tox` | 
| 78 | 153 | 
 | 
| @@ -156,6 +231,9 @@ For more information to debug `pytest` test suites see | 
| 156 | 231 | 
 | 
| 157 | 232 | ## Running GitHub actions locally using `act` | 
| 158 | 233 | 
 | 
|  | 234 | +With `docker` (or `podman`) installed, [act](https://github.com/nektos/act) can be used to run | 
|  | 235 | +the CI jobs configured in [.actrc](.actrc): | 
|  | 236 | +
 | 
| 159 | 237 | - `act` uses `docker` (also mimicked by `podman-docker`) to run GitHub actions locally | 
| 160 | 238 | - While `act` does not use the same GitHub runner images, they are similar. | 
| 161 | 239 | 
 | 
|  | 
0 commit comments