Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
dist/
build/
venv/
.venv/
.tox/
.python-version
/site/
/.cache/
.pytest_cache/
Expand Down
10 changes: 8 additions & 2 deletions .justfile
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,10 @@
# * frontend/.justfile – Building and running the frontend
# * mkdocs/.justfile – Building and previewing the docs site
# * website/.justfile – Building and previewing the React landing page
# * .tox.justfile – Running Python tests via tox

default:
@just --list
# Run tests via tox
mod tox '.tox.justfile'

set allow-duplicate-recipes

Expand All @@ -22,3 +23,8 @@ import "frontend/.justfile"
import "mkdocs/.justfile"

import "website/.justfile"

[default]
[private]
default:
@just --list --list-submodules --unsorted
44 changes: 44 additions & 0 deletions .tox.justfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# Keep in sync with pyproject.toml and .github/workflows/build-artifacts.yml
supported_python_versions := '3.10,3.11,3.12,3.13,3.14'

install_tox_msg := '''
tox is not installed; to install it using uv:
uv tool install tox --with tox-uv
'''

python_version_msg := '''
.python-version does not exist; to create (replace 3.14 with the desired version):
* using uv:
uv python pin 3.14
* if uv is not used:
echo 3.14 > .python-version
'''

[doc('''
Run tests using the default environment
The default Python version is set via .python-version file
''')]
[positional-arguments]
test-default *args: _check_tox_installed
@if [ ! -f .python-version ]; then echo '{{python_version_msg}}' >&2; exit 1; fi
tox run -e default "${@}"

[doc('Run tests against all supported Python versions')]
[positional-arguments]
test-supported *args: _check_tox_installed
tox run -e {{supported_python_versions}} "${@}"

[doc('''
Run tests using the current environment (no venv isolation)
All dependencies must be already installed; a dummy environment is still created
''')]
[positional-arguments]
test-current *args: _check_tox_installed
tox run -e dummy --skip-env-install "${@}"

@_check_tox_installed:
if ! command -v 'tox' >/dev/null 2>&1; then echo '{{install_tox_msg}}' >&2; exit 1; fi

[default]
_list:
@just --list {{module_path()}} --unsorted
30 changes: 30 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,36 @@ Use the `--runpostgres` flag to run the tests against Postgres as well:
uv run pytest src/tests --runpostgres
```

Alternatively, you can run tests via [tox](https://tox.wiki/) inside an isolated environment ensuring that the `dstack` package itself is built correctly and all requirements are specified and correct. tox and [just](https://just.systems/) must be already installed.

* Run tests in the default environment:

```shell
just tox::test-default
```

The Python version of the default environment is configured via the `.python-version` file in the repo root directory. Note, the same file [is used by uv](https://docs.astral.sh/uv/concepts/python-versions/#python-version-files).

* Run tests against all currently supported Python versions:

```shell
just tox::test-supported
```

* Run tests in the _current_ environment:

```shell
just tox::test-current
```

It saves about 30-60 seconds at the cost of Python environment isolation (defeating the core purpose of tox) — no packages are built or installed, and, as a consequence, all dependencies must be already installed, but, unlike the plain pytest command, the process environment variables are still isolated.

It's possible to pass pytest arguments after the `--` separator (the arguments _before_ the separator are `tox run` arguments):

```shell
just tox::test-default -- -vvv --last-failed
```

## Add a new backend

If you'd like to integrate a new cloud provider to `dstack`, follow [contributing/BACKENDS.md](contributing/BACKENDS.md).
Expand Down
39 changes: 32 additions & 7 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -145,26 +145,51 @@ filterwarnings = [
"ignore:^The @wait_container_is_ready decorator:DeprecationWarning",
]

[tool.tox]
env_list = ["default"]

[tool.tox.env_run_base]
description = "Run tests under {base_python}"
extras = ["all"]
dependency_groups = ["test"]
commands = [["pytest", { replace = "posargs", extend = true }]]

# `tox run [-e default]` -- run tests inside an isolated environment
# with Python version read from `.python-version` file
[tool.tox.env.default]
base_python_file = [".python-version"]

# `tox run -e dummy --skip-env-install` -- run tests inside the current environment
# all dependencies must be already installed; a dummy environment is still created
[tool.tox.env.dummy]
description = "Run tests inside the current environment"
# Must be called with --skip-env-install
dependency_groups = ["nonexistent-group-to-trigger-failure"]
allowlist_externals = ["pytest"]

[dependency-groups]
dev = [
"pre-commit>=4.2.0",
"ruff==0.12.7", # should match .pre-commit-config.yaml
"pyinstrument>=5.0.0",
"kubernetes-stubs-elephant-fork>=35.0.0.post3",
{include-group = "test"},
{include-group = "docs"},
]
test = [
"pytest~=8.0",
"pytest-asyncio>=0.25.2",
"pytest-mock>=3.14.0",
"pytest-httpbin>=2.1.0",
"pytest-socket>=0.7.0",
"pytest-env>=1.1.0",
"pytest-unordered>=0.7.0",
"httpbin>=0.10.2", # indirect to make compatible with Werkzeug 3
"pytest-xdist>=3.6.1",
"requests-mock>=1.12.1",
"openai>=1.68.2",
"freezegun>=1.5.1",
"ruff==0.12.7", # should match .pre-commit-config.yaml
"httpbin>=0.10.2", # indirect to make compatible with Werkzeug 3
"openai>=1.68.2",
"testcontainers>=4.9.2",
"pytest-xdist>=3.6.1",
"pyinstrument>=5.0.0",
"kubernetes-stubs-elephant-fork>=35.0.0.post3",
{include-group = "docs"},
]
docs = [
"dstack[server]",
Expand Down
Loading