2021-04-09 12:54:30 +03:00
|
|
|
name: Tests
|
|
|
|
|
|
|
|
on:
|
|
|
|
push:
|
|
|
|
branches: ["develop", "release-*"]
|
|
|
|
pull_request:
|
2023-03-15 15:07:20 +03:00
|
|
|
merge_group:
|
2022-10-03 19:16:45 +03:00
|
|
|
workflow_dispatch:
|
2021-04-09 12:54:30 +03:00
|
|
|
|
2021-07-22 13:35:06 +03:00
|
|
|
concurrency:
|
|
|
|
group: ${{ github.workflow }}-${{ github.ref }}
|
|
|
|
cancel-in-progress: true
|
2021-08-05 13:22:27 +03:00
|
|
|
|
2021-04-09 12:54:30 +03:00
|
|
|
jobs:
|
2022-09-09 13:29:04 +03:00
|
|
|
# Job to detect what has changed so we don't run e.g. Rust checks on PRs that
|
|
|
|
# don't modify Rust code.
|
|
|
|
changes:
|
|
|
|
runs-on: ubuntu-latest
|
|
|
|
outputs:
|
|
|
|
rust: ${{ !startsWith(github.ref, 'refs/pull/') || steps.filter.outputs.rust }}
|
2023-09-25 19:59:40 +03:00
|
|
|
trial: ${{ !startsWith(github.ref, 'refs/pull/') || steps.filter.outputs.trial }}
|
|
|
|
integration: ${{ !startsWith(github.ref, 'refs/pull/') || steps.filter.outputs.integration }}
|
|
|
|
linting: ${{ !startsWith(github.ref, 'refs/pull/') || steps.filter.outputs.linting }}
|
2022-09-09 13:29:04 +03:00
|
|
|
steps:
|
2024-02-06 12:28:22 +03:00
|
|
|
- uses: dorny/paths-filter@v3
|
2022-09-09 13:29:04 +03:00
|
|
|
id: filter
|
|
|
|
# We only check on PRs
|
|
|
|
if: startsWith(github.ref, 'refs/pull/')
|
|
|
|
with:
|
|
|
|
filters: |
|
|
|
|
rust:
|
|
|
|
- 'rust/**'
|
|
|
|
- 'Cargo.toml'
|
2022-11-28 14:47:16 +03:00
|
|
|
- 'Cargo.lock'
|
2023-09-25 19:59:40 +03:00
|
|
|
- '.rustfmt.toml'
|
2023-10-18 14:19:53 +03:00
|
|
|
- '.github/workflows/tests.yml'
|
2023-09-25 19:59:40 +03:00
|
|
|
|
|
|
|
trial:
|
|
|
|
- 'synapse/**'
|
|
|
|
- 'tests/**'
|
|
|
|
- 'rust/**'
|
2023-10-18 14:19:53 +03:00
|
|
|
- '.ci/scripts/calculate_jobs.py'
|
2023-09-25 19:59:40 +03:00
|
|
|
- 'Cargo.toml'
|
|
|
|
- 'Cargo.lock'
|
|
|
|
- 'pyproject.toml'
|
|
|
|
- 'poetry.lock'
|
2023-10-18 14:19:53 +03:00
|
|
|
- '.github/workflows/tests.yml'
|
2023-09-25 19:59:40 +03:00
|
|
|
|
|
|
|
integration:
|
|
|
|
- 'synapse/**'
|
|
|
|
- 'rust/**'
|
|
|
|
- 'docker/**'
|
|
|
|
- 'Cargo.toml'
|
|
|
|
- 'Cargo.lock'
|
|
|
|
- 'pyproject.toml'
|
|
|
|
- 'poetry.lock'
|
|
|
|
- 'docker/**'
|
2023-10-18 14:19:53 +03:00
|
|
|
- '.ci/**'
|
2023-10-12 13:33:14 +03:00
|
|
|
- 'scripts-dev/complement.sh'
|
2023-10-18 14:19:53 +03:00
|
|
|
- '.github/workflows/tests.yml'
|
2023-09-25 19:59:40 +03:00
|
|
|
|
|
|
|
linting:
|
|
|
|
- 'synapse/**'
|
|
|
|
- 'docker/**'
|
|
|
|
- 'tests/**'
|
|
|
|
- 'scripts-dev/**'
|
|
|
|
- 'contrib/**'
|
|
|
|
- 'synmark/**'
|
|
|
|
- 'stubs/**'
|
|
|
|
- '.ci/**'
|
|
|
|
- 'mypy.ini'
|
|
|
|
- 'pyproject.toml'
|
|
|
|
- 'poetry.lock'
|
2023-10-18 14:19:53 +03:00
|
|
|
- '.github/workflows/tests.yml'
|
2022-09-09 13:29:04 +03:00
|
|
|
|
2022-03-01 22:47:02 +03:00
|
|
|
check-sampleconfig:
|
|
|
|
runs-on: ubuntu-latest
|
2023-09-25 19:59:40 +03:00
|
|
|
needs: changes
|
|
|
|
if: ${{ needs.changes.outputs.linting == 'true' }}
|
|
|
|
|
2022-03-01 22:47:02 +03:00
|
|
|
steps:
|
2023-09-25 18:39:54 +03:00
|
|
|
- uses: actions/checkout@v4
|
2023-03-28 18:17:15 +03:00
|
|
|
- name: Install Rust
|
2024-01-22 14:11:52 +03:00
|
|
|
uses: dtolnay/rust-toolchain@1.65.0
|
2023-03-28 18:17:15 +03:00
|
|
|
- uses: Swatinem/rust-cache@v2
|
2022-09-16 18:18:32 +03:00
|
|
|
- uses: matrix-org/setup-python-poetry@v1
|
|
|
|
with:
|
2023-01-17 21:04:44 +03:00
|
|
|
python-version: "3.x"
|
|
|
|
poetry-version: "1.3.2"
|
2022-09-16 18:18:32 +03:00
|
|
|
extras: "all"
|
|
|
|
- run: poetry run scripts-dev/generate_sample_config.sh --check
|
|
|
|
- run: poetry run scripts-dev/config-lint.sh
|
2022-03-01 22:47:02 +03:00
|
|
|
|
2022-06-15 18:27:18 +03:00
|
|
|
check-schema-delta:
|
|
|
|
runs-on: ubuntu-latest
|
2023-09-25 19:59:40 +03:00
|
|
|
needs: changes
|
|
|
|
if: ${{ needs.changes.outputs.linting == 'true' }}
|
|
|
|
|
2022-06-15 18:27:18 +03:00
|
|
|
steps:
|
2023-09-25 18:39:54 +03:00
|
|
|
- uses: actions/checkout@v4
|
2023-12-12 12:59:10 +03:00
|
|
|
- uses: actions/setup-python@v5
|
2022-11-01 16:58:39 +03:00
|
|
|
with:
|
|
|
|
python-version: "3.x"
|
2022-06-15 18:27:18 +03:00
|
|
|
- run: "pip install 'click==8.1.1' 'GitPython>=3.1.20'"
|
|
|
|
- run: scripts-dev/check_schema_delta.py --force-colors
|
|
|
|
|
2023-01-17 21:04:44 +03:00
|
|
|
check-lockfile:
|
|
|
|
runs-on: ubuntu-latest
|
|
|
|
steps:
|
2023-09-25 18:39:54 +03:00
|
|
|
- uses: actions/checkout@v4
|
2023-12-12 12:59:10 +03:00
|
|
|
- uses: actions/setup-python@v5
|
2023-01-17 21:04:44 +03:00
|
|
|
with:
|
|
|
|
python-version: "3.x"
|
|
|
|
- run: .ci/scripts/check_lockfile.py
|
|
|
|
|
2021-04-09 12:54:30 +03:00
|
|
|
lint:
|
2023-04-10 15:25:08 +03:00
|
|
|
runs-on: ubuntu-latest
|
2023-09-25 19:59:40 +03:00
|
|
|
needs: changes
|
|
|
|
if: ${{ needs.changes.outputs.linting == 'true' }}
|
|
|
|
|
2023-04-10 15:25:08 +03:00
|
|
|
steps:
|
|
|
|
- name: Checkout repository
|
2023-09-25 18:39:54 +03:00
|
|
|
uses: actions/checkout@v4
|
2023-04-10 15:25:08 +03:00
|
|
|
|
|
|
|
- name: Setup Poetry
|
|
|
|
uses: matrix-org/setup-python-poetry@v1
|
|
|
|
with:
|
|
|
|
install-project: "false"
|
|
|
|
|
|
|
|
- name: Import order (isort)
|
|
|
|
run: poetry run isort --check --diff .
|
|
|
|
|
|
|
|
- name: Code style (black)
|
|
|
|
run: poetry run black --check --diff .
|
|
|
|
|
|
|
|
- name: Semantic checks (ruff)
|
|
|
|
# --quiet suppresses the update check.
|
|
|
|
run: poetry run ruff --quiet .
|
|
|
|
|
|
|
|
lint-mypy:
|
|
|
|
runs-on: ubuntu-latest
|
|
|
|
name: Typechecking
|
2023-09-25 19:59:40 +03:00
|
|
|
needs: changes
|
|
|
|
if: ${{ needs.changes.outputs.linting == 'true' }}
|
|
|
|
|
2023-04-10 15:25:08 +03:00
|
|
|
steps:
|
|
|
|
- name: Checkout repository
|
2023-09-25 18:39:54 +03:00
|
|
|
uses: actions/checkout@v4
|
2023-04-10 15:25:08 +03:00
|
|
|
|
2023-06-09 17:00:30 +03:00
|
|
|
- name: Install Rust
|
2024-01-22 14:11:52 +03:00
|
|
|
uses: dtolnay/rust-toolchain@1.65.0
|
2023-06-09 17:00:30 +03:00
|
|
|
- uses: Swatinem/rust-cache@v2
|
|
|
|
|
2023-04-10 15:25:08 +03:00
|
|
|
- name: Setup Poetry
|
|
|
|
uses: matrix-org/setup-python-poetry@v1
|
|
|
|
with:
|
|
|
|
# We want to make use of type hints in optional dependencies too.
|
|
|
|
extras: all
|
|
|
|
# We have seen odd mypy failures that were resolved when we started
|
|
|
|
# installing the project again:
|
|
|
|
# https://github.com/matrix-org/synapse/pull/15376#issuecomment-1498983775
|
|
|
|
# To make CI green, err towards caution and install the project.
|
|
|
|
install-project: "true"
|
|
|
|
|
2023-05-11 21:24:32 +03:00
|
|
|
# Cribbed from
|
|
|
|
# https://github.com/AustinScola/mypy-cache-github-action/blob/85ea4f2972abed39b33bd02c36e341b28ca59213/src/restore.ts#L10-L17
|
2023-04-10 15:25:08 +03:00
|
|
|
- name: Restore/persist mypy's cache
|
2024-01-22 13:35:05 +03:00
|
|
|
uses: actions/cache@v4
|
2023-05-11 21:24:32 +03:00
|
|
|
with:
|
|
|
|
path: |
|
|
|
|
.mypy_cache
|
|
|
|
key: mypy-cache-${{ github.context.sha }}
|
|
|
|
restore-keys: mypy-cache-
|
2023-04-10 15:25:08 +03:00
|
|
|
|
|
|
|
- name: Run mypy
|
|
|
|
run: poetry run mypy
|
2021-04-09 12:54:30 +03:00
|
|
|
|
|
|
|
lint-crlf:
|
|
|
|
runs-on: ubuntu-latest
|
|
|
|
steps:
|
2023-09-25 18:39:54 +03:00
|
|
|
- uses: actions/checkout@v4
|
2021-04-09 12:54:30 +03:00
|
|
|
- name: Check line endings
|
|
|
|
run: scripts-dev/check_line_terminators.sh
|
|
|
|
|
|
|
|
lint-newsfile:
|
2022-10-03 21:29:53 +03:00
|
|
|
if: ${{ (github.base_ref == 'develop' || contains(github.base_ref, 'release-')) && github.actor != 'dependabot[bot]' }}
|
2021-04-09 12:54:30 +03:00
|
|
|
runs-on: ubuntu-latest
|
|
|
|
steps:
|
2023-09-25 18:39:54 +03:00
|
|
|
- uses: actions/checkout@v4
|
2021-05-26 16:14:43 +03:00
|
|
|
with:
|
|
|
|
ref: ${{ github.event.pull_request.head.sha }}
|
|
|
|
fetch-depth: 0
|
2023-12-12 12:59:10 +03:00
|
|
|
- uses: actions/setup-python@v5
|
2022-11-01 16:58:39 +03:00
|
|
|
with:
|
|
|
|
python-version: "3.x"
|
2022-03-01 22:47:02 +03:00
|
|
|
- run: "pip install 'towncrier>=18.6.0rc1'"
|
2022-03-02 21:00:26 +03:00
|
|
|
- run: scripts-dev/check-newsfragment.sh
|
2021-08-10 14:15:10 +03:00
|
|
|
env:
|
|
|
|
PULL_REQUEST_NUMBER: ${{ github.event.number }}
|
2021-04-09 12:54:30 +03:00
|
|
|
|
2022-08-17 13:17:04 +03:00
|
|
|
lint-pydantic:
|
|
|
|
runs-on: ubuntu-latest
|
2023-09-25 19:59:40 +03:00
|
|
|
needs: changes
|
|
|
|
if: ${{ needs.changes.outputs.linting == 'true' }}
|
|
|
|
|
2022-08-17 13:17:04 +03:00
|
|
|
steps:
|
2023-09-25 18:39:54 +03:00
|
|
|
- uses: actions/checkout@v4
|
2022-08-17 13:17:04 +03:00
|
|
|
with:
|
|
|
|
ref: ${{ github.event.pull_request.head.sha }}
|
2023-03-28 17:42:24 +03:00
|
|
|
- name: Install Rust
|
2024-01-22 14:11:52 +03:00
|
|
|
uses: dtolnay/rust-toolchain@1.65.0
|
2023-03-28 17:42:24 +03:00
|
|
|
- uses: Swatinem/rust-cache@v2
|
2022-08-17 13:17:04 +03:00
|
|
|
- uses: matrix-org/setup-python-poetry@v1
|
|
|
|
with:
|
2023-01-17 21:04:44 +03:00
|
|
|
poetry-version: "1.3.2"
|
2022-08-17 13:17:04 +03:00
|
|
|
extras: "all"
|
|
|
|
- run: poetry run scripts-dev/check_pydantic_models.py
|
|
|
|
|
2022-09-09 13:29:04 +03:00
|
|
|
lint-clippy:
|
|
|
|
runs-on: ubuntu-latest
|
|
|
|
needs: changes
|
|
|
|
if: ${{ needs.changes.outputs.rust == 'true' }}
|
|
|
|
|
|
|
|
steps:
|
2023-09-25 18:39:54 +03:00
|
|
|
- uses: actions/checkout@v4
|
2022-09-09 13:29:04 +03:00
|
|
|
|
|
|
|
- name: Install Rust
|
2024-01-22 14:11:52 +03:00
|
|
|
uses: dtolnay/rust-toolchain@1.65.0
|
2022-09-09 13:29:04 +03:00
|
|
|
with:
|
|
|
|
components: clippy
|
|
|
|
- uses: Swatinem/rust-cache@v2
|
|
|
|
|
2022-12-02 21:04:28 +03:00
|
|
|
- run: cargo clippy -- -D warnings
|
|
|
|
|
|
|
|
# We also lint against a nightly rustc so that we can lint the benchmark
|
|
|
|
# suite, which requires a nightly compiler.
|
|
|
|
lint-clippy-nightly:
|
|
|
|
runs-on: ubuntu-latest
|
|
|
|
needs: changes
|
|
|
|
if: ${{ needs.changes.outputs.rust == 'true' }}
|
|
|
|
|
|
|
|
steps:
|
2023-09-25 18:39:54 +03:00
|
|
|
- uses: actions/checkout@v4
|
2022-12-02 21:04:28 +03:00
|
|
|
|
|
|
|
- name: Install Rust
|
2023-04-06 21:41:29 +03:00
|
|
|
uses: dtolnay/rust-toolchain@master
|
2022-12-02 21:04:28 +03:00
|
|
|
with:
|
|
|
|
toolchain: nightly-2022-12-01
|
|
|
|
components: clippy
|
|
|
|
- uses: Swatinem/rust-cache@v2
|
|
|
|
|
|
|
|
- run: cargo clippy --all-features -- -D warnings
|
2022-09-09 13:29:04 +03:00
|
|
|
|
|
|
|
lint-rustfmt:
|
|
|
|
runs-on: ubuntu-latest
|
|
|
|
needs: changes
|
|
|
|
if: ${{ needs.changes.outputs.rust == 'true' }}
|
|
|
|
|
|
|
|
steps:
|
2023-09-25 18:39:54 +03:00
|
|
|
- uses: actions/checkout@v4
|
2022-09-09 13:29:04 +03:00
|
|
|
|
|
|
|
- name: Install Rust
|
2023-04-06 21:41:29 +03:00
|
|
|
uses: dtolnay/rust-toolchain@master
|
2022-09-09 13:29:04 +03:00
|
|
|
with:
|
2023-03-03 17:26:14 +03:00
|
|
|
# We use nightly so that it correctly groups together imports
|
|
|
|
toolchain: nightly-2022-12-01
|
2022-11-01 16:58:39 +03:00
|
|
|
components: rustfmt
|
2022-09-09 13:29:04 +03:00
|
|
|
- uses: Swatinem/rust-cache@v2
|
|
|
|
|
|
|
|
- run: cargo fmt --check
|
|
|
|
|
2021-04-09 12:54:30 +03:00
|
|
|
# Dummy step to gate other tests on without repeating the whole list
|
|
|
|
linting-done:
|
2021-07-14 16:41:23 +03:00
|
|
|
if: ${{ !cancelled() }} # Run this even if prior jobs were skipped
|
2022-09-09 13:29:04 +03:00
|
|
|
needs:
|
|
|
|
- lint
|
2023-04-10 15:25:08 +03:00
|
|
|
- lint-mypy
|
2022-09-09 13:29:04 +03:00
|
|
|
- lint-crlf
|
|
|
|
- lint-newsfile
|
|
|
|
- lint-pydantic
|
|
|
|
- check-sampleconfig
|
|
|
|
- check-schema-delta
|
2023-01-17 21:04:44 +03:00
|
|
|
- check-lockfile
|
2022-09-09 13:29:04 +03:00
|
|
|
- lint-clippy
|
2024-01-10 16:53:44 +03:00
|
|
|
- lint-clippy-nightly
|
2022-09-09 13:29:04 +03:00
|
|
|
- lint-rustfmt
|
2021-04-09 12:54:30 +03:00
|
|
|
runs-on: ubuntu-latest
|
|
|
|
steps:
|
2024-01-10 16:53:44 +03:00
|
|
|
- uses: matrix-org/done-action@v2
|
|
|
|
with:
|
|
|
|
needs: ${{ toJSON(needs) }}
|
|
|
|
|
|
|
|
# Various bits are skipped if there was no applicable changes.
|
|
|
|
skippable: |
|
|
|
|
check-sampleconfig
|
|
|
|
check-schema-delta
|
|
|
|
lint
|
|
|
|
lint-mypy
|
|
|
|
lint-newsfile
|
|
|
|
lint-pydantic
|
|
|
|
lint-clippy
|
|
|
|
lint-clippy-nightly
|
|
|
|
lint-rustfmt
|
|
|
|
|
2021-04-09 12:54:30 +03:00
|
|
|
|
2022-09-05 15:31:42 +03:00
|
|
|
calculate-test-jobs:
|
2021-07-14 16:41:23 +03:00
|
|
|
if: ${{ !cancelled() && !failure() }} # Allow previous steps to be skipped, but not fail
|
2021-04-09 12:54:30 +03:00
|
|
|
needs: linting-done
|
|
|
|
runs-on: ubuntu-latest
|
2022-09-05 15:31:42 +03:00
|
|
|
steps:
|
2023-09-25 18:39:54 +03:00
|
|
|
- uses: actions/checkout@v4
|
2023-12-12 12:59:10 +03:00
|
|
|
- uses: actions/setup-python@v5
|
2022-11-01 16:58:39 +03:00
|
|
|
with:
|
|
|
|
python-version: "3.x"
|
2022-09-05 15:31:42 +03:00
|
|
|
- id: get-matrix
|
|
|
|
run: .ci/scripts/calculate_jobs.py
|
|
|
|
outputs:
|
|
|
|
trial_test_matrix: ${{ steps.get-matrix.outputs.trial_test_matrix }}
|
|
|
|
sytest_test_matrix: ${{ steps.get-matrix.outputs.sytest_test_matrix }}
|
|
|
|
|
|
|
|
trial:
|
2023-09-25 19:59:40 +03:00
|
|
|
if: ${{ !cancelled() && !failure() && needs.changes.outputs.trial == 'true' }} # Allow previous steps to be skipped, but not fail
|
|
|
|
needs:
|
|
|
|
- calculate-test-jobs
|
|
|
|
- changes
|
2022-09-05 15:31:42 +03:00
|
|
|
runs-on: ubuntu-latest
|
2021-04-09 12:54:30 +03:00
|
|
|
strategy:
|
|
|
|
matrix:
|
2022-09-05 15:31:42 +03:00
|
|
|
job: ${{ fromJson(needs.calculate-test-jobs.outputs.trial_test_matrix) }}
|
2021-04-09 12:54:30 +03:00
|
|
|
|
|
|
|
steps:
|
2023-09-25 18:39:54 +03:00
|
|
|
- uses: actions/checkout@v4
|
2021-04-09 12:54:30 +03:00
|
|
|
- run: sudo apt-get -qq install xmlsec1
|
2022-09-05 15:31:42 +03:00
|
|
|
- name: Set up PostgreSQL ${{ matrix.job.postgres-version }}
|
|
|
|
if: ${{ matrix.job.postgres-version }}
|
2022-12-07 18:47:05 +03:00
|
|
|
# 1. Mount postgres data files onto a tmpfs in-memory filesystem to reduce overhead of docker's overlayfs layer.
|
|
|
|
# 2. Expose the unix socket for postgres. This removes latency of using docker-proxy for connections.
|
2021-04-09 12:54:30 +03:00
|
|
|
run: |
|
|
|
|
docker run -d -p 5432:5432 \
|
2022-12-07 18:47:05 +03:00
|
|
|
--tmpfs /var/lib/postgres:rw,size=6144m \
|
|
|
|
--mount 'type=bind,src=/var/run/postgresql,dst=/var/run/postgresql' \
|
2021-04-09 12:54:30 +03:00
|
|
|
-e POSTGRES_PASSWORD=postgres \
|
|
|
|
-e POSTGRES_INITDB_ARGS="--lc-collate C --lc-ctype C --encoding UTF8" \
|
2022-09-05 15:31:42 +03:00
|
|
|
postgres:${{ matrix.job.postgres-version }}
|
2022-10-25 13:27:56 +03:00
|
|
|
|
|
|
|
- name: Install Rust
|
2024-01-22 14:11:52 +03:00
|
|
|
uses: dtolnay/rust-toolchain@1.65.0
|
2022-10-25 13:27:56 +03:00
|
|
|
- uses: Swatinem/rust-cache@v2
|
|
|
|
|
2022-04-12 19:41:21 +03:00
|
|
|
- uses: matrix-org/setup-python-poetry@v1
|
2021-04-09 12:54:30 +03:00
|
|
|
with:
|
2022-09-05 15:31:42 +03:00
|
|
|
python-version: ${{ matrix.job.python-version }}
|
2023-01-17 21:04:44 +03:00
|
|
|
poetry-version: "1.3.2"
|
2022-09-05 15:31:42 +03:00
|
|
|
extras: ${{ matrix.job.extras }}
|
2021-04-09 12:54:30 +03:00
|
|
|
- name: Await PostgreSQL
|
2022-09-05 15:31:42 +03:00
|
|
|
if: ${{ matrix.job.postgres-version }}
|
2021-04-09 12:54:30 +03:00
|
|
|
timeout-minutes: 2
|
|
|
|
run: until pg_isready -h localhost; do sleep 1; done
|
2022-12-07 18:47:05 +03:00
|
|
|
- run: poetry run trial --jobs=6 tests
|
2021-04-09 12:54:30 +03:00
|
|
|
env:
|
2022-09-05 15:31:42 +03:00
|
|
|
SYNAPSE_POSTGRES: ${{ matrix.job.database == 'postgres' || '' }}
|
2022-12-07 18:47:05 +03:00
|
|
|
SYNAPSE_POSTGRES_HOST: /var/run/postgresql
|
2021-04-09 12:54:30 +03:00
|
|
|
SYNAPSE_POSTGRES_USER: postgres
|
|
|
|
SYNAPSE_POSTGRES_PASSWORD: postgres
|
|
|
|
- name: Dump logs
|
2021-10-12 23:09:49 +03:00
|
|
|
# Logs are most useful when the command fails, always include them.
|
|
|
|
if: ${{ always() }}
|
2021-04-09 12:54:30 +03:00
|
|
|
# Note: Dumps to workflow logs instead of using actions/upload-artifact
|
|
|
|
# This keeps logs colocated with failing jobs
|
|
|
|
# It also ignores find's exit code; this is a best effort affair
|
|
|
|
run: >-
|
|
|
|
find _trial_temp -name '*.log'
|
|
|
|
-exec echo "::group::{}" \;
|
|
|
|
-exec cat {} \;
|
|
|
|
-exec echo "::endgroup::" \;
|
|
|
|
|| true
|
|
|
|
|
|
|
|
trial-olddeps:
|
2022-04-12 13:50:11 +03:00
|
|
|
# Note: sqlite only; no postgres
|
2023-09-25 19:59:40 +03:00
|
|
|
if: ${{ !cancelled() && !failure() && needs.changes.outputs.trial == 'true' }} # Allow previous steps to be skipped, but not fail
|
|
|
|
needs:
|
|
|
|
- linting-done
|
|
|
|
- changes
|
2022-09-06 14:43:04 +03:00
|
|
|
runs-on: ubuntu-20.04
|
2021-04-09 12:54:30 +03:00
|
|
|
steps:
|
2023-09-25 18:39:54 +03:00
|
|
|
- uses: actions/checkout@v4
|
2022-09-06 14:43:04 +03:00
|
|
|
|
2022-09-06 21:01:37 +03:00
|
|
|
- name: Install Rust
|
2024-01-22 14:11:52 +03:00
|
|
|
uses: dtolnay/rust-toolchain@1.65.0
|
2022-09-07 16:56:59 +03:00
|
|
|
- uses: Swatinem/rust-cache@v2
|
2022-09-06 21:01:37 +03:00
|
|
|
|
2022-09-06 14:43:04 +03:00
|
|
|
# There aren't wheels for some of the older deps, so we need to install
|
|
|
|
# their build dependencies
|
|
|
|
- run: |
|
2023-05-26 17:28:55 +03:00
|
|
|
sudo apt-get -qq update
|
2022-09-06 14:43:04 +03:00
|
|
|
sudo apt-get -qq install build-essential libffi-dev python-dev \
|
2023-05-18 17:53:57 +03:00
|
|
|
libxml2-dev libxslt-dev xmlsec1 zlib1g-dev libjpeg-dev libwebp-dev
|
2022-09-06 14:43:04 +03:00
|
|
|
|
2023-12-12 12:59:10 +03:00
|
|
|
- uses: actions/setup-python@v5
|
2022-09-06 14:43:04 +03:00
|
|
|
with:
|
2023-07-06 02:45:42 +03:00
|
|
|
python-version: '3.8'
|
2022-09-06 14:43:04 +03:00
|
|
|
|
|
|
|
- name: Prepare old deps
|
|
|
|
if: steps.cache-poetry-old-deps.outputs.cache-hit != 'true'
|
|
|
|
run: .ci/scripts/prepare_old_deps.sh
|
|
|
|
|
2023-05-12 13:21:11 +03:00
|
|
|
# Note: we install using `pip` here, not poetry. `poetry install` ignores the
|
|
|
|
# build-system section (https://github.com/python-poetry/poetry/issues/6154), but
|
|
|
|
# we explicitly want to test that you can `pip install` using the oldest version
|
|
|
|
# of poetry-core and setuptools-rust.
|
|
|
|
- run: pip install .[all,test]
|
|
|
|
|
|
|
|
# We nuke the local copy, as we've installed synapse into the virtualenv
|
|
|
|
# (rather than use an editable install, which we no longer support). If we
|
|
|
|
# don't do this then python can't find the native lib.
|
|
|
|
- run: rm -rf synapse/
|
|
|
|
|
|
|
|
# Sanity check we can import/run Synapse
|
|
|
|
- run: python -m synapse.app.homeserver --help
|
2022-09-06 14:43:04 +03:00
|
|
|
|
2023-05-12 13:21:11 +03:00
|
|
|
- run: python -m twisted.trial -j6 tests
|
2021-04-09 12:54:30 +03:00
|
|
|
- name: Dump logs
|
2021-10-12 23:09:49 +03:00
|
|
|
# Logs are most useful when the command fails, always include them.
|
|
|
|
if: ${{ always() }}
|
2021-04-09 12:54:30 +03:00
|
|
|
# Note: Dumps to workflow logs instead of using actions/upload-artifact
|
|
|
|
# This keeps logs colocated with failing jobs
|
|
|
|
# It also ignores find's exit code; this is a best effort affair
|
|
|
|
run: >-
|
|
|
|
find _trial_temp -name '*.log'
|
|
|
|
-exec echo "::group::{}" \;
|
|
|
|
-exec cat {} \;
|
|
|
|
-exec echo "::endgroup::" \;
|
|
|
|
|| true
|
|
|
|
|
|
|
|
trial-pypy:
|
|
|
|
# Very slow; only run if the branch name includes 'pypy'
|
2022-04-12 19:41:21 +03:00
|
|
|
# Note: sqlite only; no postgres. Completely untested since poetry move.
|
2023-09-25 19:59:40 +03:00
|
|
|
if: ${{ contains(github.ref, 'pypy') && !failure() && !cancelled() && needs.changes.outputs.trial == 'true' }}
|
|
|
|
needs:
|
|
|
|
- linting-done
|
|
|
|
- changes
|
2021-04-09 12:54:30 +03:00
|
|
|
runs-on: ubuntu-latest
|
|
|
|
strategy:
|
|
|
|
matrix:
|
2023-07-06 02:45:42 +03:00
|
|
|
python-version: ["pypy-3.8"]
|
2022-04-12 19:41:21 +03:00
|
|
|
extras: ["all"]
|
2021-04-09 12:54:30 +03:00
|
|
|
|
|
|
|
steps:
|
2023-09-25 18:39:54 +03:00
|
|
|
- uses: actions/checkout@v4
|
2022-04-12 19:41:21 +03:00
|
|
|
# Install libs necessary for PyPy to build binary wheels for dependencies
|
2021-04-09 12:54:30 +03:00
|
|
|
- run: sudo apt-get -qq install xmlsec1 libxml2-dev libxslt-dev
|
2022-04-12 19:41:21 +03:00
|
|
|
- uses: matrix-org/setup-python-poetry@v1
|
2021-04-09 12:54:30 +03:00
|
|
|
with:
|
|
|
|
python-version: ${{ matrix.python-version }}
|
2023-01-17 21:04:44 +03:00
|
|
|
poetry-version: "1.3.2"
|
2022-04-12 19:41:21 +03:00
|
|
|
extras: ${{ matrix.extras }}
|
|
|
|
- run: poetry run trial --jobs=2 tests
|
2021-04-09 12:54:30 +03:00
|
|
|
- name: Dump logs
|
2021-10-12 23:09:49 +03:00
|
|
|
# Logs are most useful when the command fails, always include them.
|
|
|
|
if: ${{ always() }}
|
2021-04-09 12:54:30 +03:00
|
|
|
# Note: Dumps to workflow logs instead of using actions/upload-artifact
|
|
|
|
# This keeps logs colocated with failing jobs
|
|
|
|
# It also ignores find's exit code; this is a best effort affair
|
|
|
|
run: >-
|
|
|
|
find _trial_temp -name '*.log'
|
|
|
|
-exec echo "::group::{}" \;
|
|
|
|
-exec cat {} \;
|
|
|
|
-exec echo "::endgroup::" \;
|
|
|
|
|| true
|
|
|
|
|
|
|
|
sytest:
|
2023-09-25 19:59:40 +03:00
|
|
|
if: ${{ !failure() && !cancelled() && needs.changes.outputs.integration == 'true' }}
|
|
|
|
needs:
|
|
|
|
- calculate-test-jobs
|
|
|
|
- changes
|
2021-04-09 12:54:30 +03:00
|
|
|
runs-on: ubuntu-latest
|
|
|
|
container:
|
2022-09-05 15:31:42 +03:00
|
|
|
image: matrixdotorg/sytest-synapse:${{ matrix.job.sytest-tag }}
|
2021-04-09 12:54:30 +03:00
|
|
|
volumes:
|
|
|
|
- ${{ github.workspace }}:/src
|
|
|
|
env:
|
2021-09-20 19:35:16 +03:00
|
|
|
SYTEST_BRANCH: ${{ github.head_ref }}
|
2022-09-05 15:31:42 +03:00
|
|
|
POSTGRES: ${{ matrix.job.postgres && 1}}
|
2023-06-20 17:55:46 +03:00
|
|
|
MULTI_POSTGRES: ${{ (matrix.job.postgres == 'multi-postgres') || '' }}
|
|
|
|
ASYNCIO_REACTOR: ${{ (matrix.job.reactor == 'asyncio') || '' }}
|
2022-09-05 15:31:42 +03:00
|
|
|
WORKERS: ${{ matrix.job.workers && 1 }}
|
|
|
|
BLACKLIST: ${{ matrix.job.workers && 'synapse-blacklist-with-workers' }}
|
2021-08-11 22:08:48 +03:00
|
|
|
TOP: ${{ github.workspace }}
|
2021-04-09 12:54:30 +03:00
|
|
|
|
|
|
|
strategy:
|
|
|
|
fail-fast: false
|
|
|
|
matrix:
|
2022-09-05 15:31:42 +03:00
|
|
|
job: ${{ fromJson(needs.calculate-test-jobs.outputs.sytest_test_matrix) }}
|
2021-04-09 12:54:30 +03:00
|
|
|
|
|
|
|
steps:
|
2023-09-25 18:39:54 +03:00
|
|
|
- uses: actions/checkout@v4
|
2021-04-09 12:54:30 +03:00
|
|
|
- name: Prepare test blacklist
|
2021-08-11 21:59:57 +03:00
|
|
|
run: cat sytest-blacklist .ci/worker-blacklist > synapse-blacklist-with-workers
|
2022-09-07 16:56:59 +03:00
|
|
|
|
2022-09-06 21:01:37 +03:00
|
|
|
- name: Install Rust
|
2024-01-22 14:11:52 +03:00
|
|
|
uses: dtolnay/rust-toolchain@1.65.0
|
2022-09-07 16:56:59 +03:00
|
|
|
- uses: Swatinem/rust-cache@v2
|
|
|
|
|
2021-04-09 12:54:30 +03:00
|
|
|
- name: Run SyTest
|
|
|
|
run: /bootstrap.sh synapse
|
|
|
|
working-directory: /src
|
2021-06-02 19:10:37 +03:00
|
|
|
- name: Summarise results.tap
|
2021-04-09 12:54:30 +03:00
|
|
|
if: ${{ always() }}
|
2021-06-02 19:10:37 +03:00
|
|
|
run: /sytest/scripts/tap_to_gha.pl /logs/results.tap
|
2021-04-09 12:54:30 +03:00
|
|
|
- name: Upload SyTest logs
|
2024-01-11 13:16:49 +03:00
|
|
|
uses: actions/upload-artifact@v4
|
2021-04-09 12:54:30 +03:00
|
|
|
if: ${{ always() }}
|
|
|
|
with:
|
2022-09-05 15:31:42 +03:00
|
|
|
name: Sytest Logs - ${{ job.status }} - (${{ join(matrix.job.*, ', ') }})
|
2021-04-09 12:54:30 +03:00
|
|
|
path: |
|
|
|
|
/logs/results.tap
|
|
|
|
/logs/**/*.log*
|
|
|
|
|
2021-10-18 18:14:12 +03:00
|
|
|
export-data:
|
2023-09-26 17:21:07 +03:00
|
|
|
if: ${{ !failure() && !cancelled() && needs.changes.outputs.integration == 'true'}} # Allow previous steps to be skipped, but not fail
|
|
|
|
needs: [linting-done, portdb, changes]
|
2021-10-18 18:14:12 +03:00
|
|
|
runs-on: ubuntu-latest
|
|
|
|
env:
|
|
|
|
TOP: ${{ github.workspace }}
|
|
|
|
|
|
|
|
services:
|
|
|
|
postgres:
|
|
|
|
image: postgres
|
|
|
|
ports:
|
|
|
|
- 5432:5432
|
|
|
|
env:
|
|
|
|
POSTGRES_PASSWORD: "postgres"
|
|
|
|
POSTGRES_INITDB_ARGS: "--lc-collate C --lc-ctype C --encoding UTF8"
|
|
|
|
options: >-
|
|
|
|
--health-cmd pg_isready
|
|
|
|
--health-interval 10s
|
|
|
|
--health-timeout 5s
|
|
|
|
--health-retries 5
|
|
|
|
|
|
|
|
steps:
|
2023-09-25 18:39:54 +03:00
|
|
|
- uses: actions/checkout@v4
|
2022-09-16 18:25:54 +03:00
|
|
|
- run: sudo apt-get -qq install xmlsec1 postgresql-client
|
2022-04-08 22:18:54 +03:00
|
|
|
- uses: matrix-org/setup-python-poetry@v1
|
2021-10-18 18:14:12 +03:00
|
|
|
with:
|
2023-01-17 21:04:44 +03:00
|
|
|
poetry-version: "1.3.2"
|
2022-04-08 22:18:54 +03:00
|
|
|
extras: "postgres"
|
2021-10-18 18:14:12 +03:00
|
|
|
- run: .ci/scripts/test_export_data_command.sh
|
2022-09-16 18:25:54 +03:00
|
|
|
env:
|
|
|
|
PGHOST: localhost
|
|
|
|
PGUSER: postgres
|
|
|
|
PGPASSWORD: postgres
|
|
|
|
PGDATABASE: postgres
|
|
|
|
|
2021-10-18 18:14:12 +03:00
|
|
|
|
2021-04-09 12:54:30 +03:00
|
|
|
portdb:
|
2023-09-26 17:21:07 +03:00
|
|
|
if: ${{ !failure() && !cancelled() && needs.changes.outputs.integration == 'true'}} # Allow previous steps to be skipped, but not fail
|
2023-09-25 19:59:40 +03:00
|
|
|
needs:
|
|
|
|
- linting-done
|
|
|
|
- changes
|
2021-04-09 12:54:30 +03:00
|
|
|
runs-on: ubuntu-latest
|
|
|
|
strategy:
|
|
|
|
matrix:
|
|
|
|
include:
|
2023-07-06 02:45:42 +03:00
|
|
|
- python-version: "3.8"
|
2022-11-08 20:17:13 +03:00
|
|
|
postgres-version: "11"
|
2021-04-09 12:54:30 +03:00
|
|
|
|
2022-11-01 16:07:54 +03:00
|
|
|
- python-version: "3.11"
|
2022-11-09 13:32:52 +03:00
|
|
|
postgres-version: "15"
|
2021-04-09 12:54:30 +03:00
|
|
|
|
|
|
|
services:
|
|
|
|
postgres:
|
|
|
|
image: postgres:${{ matrix.postgres-version }}
|
|
|
|
ports:
|
|
|
|
- 5432:5432
|
|
|
|
env:
|
|
|
|
POSTGRES_PASSWORD: "postgres"
|
|
|
|
POSTGRES_INITDB_ARGS: "--lc-collate C --lc-ctype C --encoding UTF8"
|
|
|
|
options: >-
|
|
|
|
--health-cmd pg_isready
|
|
|
|
--health-interval 10s
|
|
|
|
--health-timeout 5s
|
|
|
|
--health-retries 5
|
|
|
|
|
|
|
|
steps:
|
2023-09-25 18:39:54 +03:00
|
|
|
- uses: actions/checkout@v4
|
2022-11-09 13:32:52 +03:00
|
|
|
- name: Add PostgreSQL apt repository
|
|
|
|
# We need a version of pg_dump that can handle the version of
|
|
|
|
# PostgreSQL being tested against. The Ubuntu package repository lags
|
|
|
|
# behind new releases, so we have to use the PostreSQL apt repository.
|
|
|
|
# Steps taken from https://www.postgresql.org/download/linux/ubuntu/
|
|
|
|
run: |
|
|
|
|
sudo sh -c 'echo "deb http://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" > /etc/apt/sources.list.d/pgdg.list'
|
|
|
|
wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | sudo apt-key add -
|
|
|
|
sudo apt-get update
|
2022-09-16 18:25:54 +03:00
|
|
|
- run: sudo apt-get -qq install xmlsec1 postgresql-client
|
2022-04-08 14:00:05 +03:00
|
|
|
- uses: matrix-org/setup-python-poetry@v1
|
2021-04-09 12:54:30 +03:00
|
|
|
with:
|
|
|
|
python-version: ${{ matrix.python-version }}
|
2023-01-17 21:04:44 +03:00
|
|
|
poetry-version: "1.3.2"
|
2022-04-08 14:00:05 +03:00
|
|
|
extras: "postgres"
|
2021-08-11 21:59:57 +03:00
|
|
|
- run: .ci/scripts/test_synapse_port_db.sh
|
2022-09-16 18:25:54 +03:00
|
|
|
id: run_tester_script
|
|
|
|
env:
|
|
|
|
PGHOST: localhost
|
|
|
|
PGUSER: postgres
|
|
|
|
PGPASSWORD: postgres
|
|
|
|
PGDATABASE: postgres
|
|
|
|
- name: "Upload schema differences"
|
2024-01-11 13:16:49 +03:00
|
|
|
uses: actions/upload-artifact@v4
|
2022-09-16 18:25:54 +03:00
|
|
|
if: ${{ failure() && !cancelled() && steps.run_tester_script.outcome == 'failure' }}
|
|
|
|
with:
|
|
|
|
name: Schema dumps
|
|
|
|
path: |
|
|
|
|
unported.sql
|
|
|
|
ported.sql
|
|
|
|
schema_diff
|
2021-04-09 12:54:30 +03:00
|
|
|
|
|
|
|
complement:
|
2023-09-25 19:59:40 +03:00
|
|
|
if: "${{ !failure() && !cancelled() && needs.changes.outputs.integration == 'true' }}"
|
|
|
|
needs:
|
|
|
|
- linting-done
|
|
|
|
- changes
|
2021-04-09 12:54:30 +03:00
|
|
|
runs-on: ubuntu-latest
|
|
|
|
|
2022-06-09 16:16:34 +03:00
|
|
|
strategy:
|
|
|
|
fail-fast: false
|
|
|
|
matrix:
|
|
|
|
include:
|
|
|
|
- arrangement: monolith
|
|
|
|
database: SQLite
|
|
|
|
|
|
|
|
- arrangement: monolith
|
|
|
|
database: Postgres
|
|
|
|
|
2022-08-01 13:51:44 +03:00
|
|
|
- arrangement: workers
|
|
|
|
database: Postgres
|
2022-07-13 15:30:42 +03:00
|
|
|
|
|
|
|
steps:
|
2023-09-25 18:39:54 +03:00
|
|
|
- name: Run actions/checkout@v4 for synapse
|
|
|
|
uses: actions/checkout@v4
|
2022-07-13 15:30:42 +03:00
|
|
|
with:
|
|
|
|
path: synapse
|
|
|
|
|
2022-09-06 21:01:37 +03:00
|
|
|
- name: Install Rust
|
2024-01-22 14:11:52 +03:00
|
|
|
uses: dtolnay/rust-toolchain@1.65.0
|
2022-09-07 16:56:59 +03:00
|
|
|
- uses: Swatinem/rust-cache@v2
|
2022-09-06 21:01:37 +03:00
|
|
|
|
2022-07-13 15:30:42 +03:00
|
|
|
- name: Prepare Complement's Prerequisites
|
|
|
|
run: synapse/.ci/scripts/setup_complement_prerequisites.sh
|
|
|
|
|
2023-12-12 12:59:31 +03:00
|
|
|
- uses: actions/setup-go@v5
|
2023-10-30 16:07:08 +03:00
|
|
|
with:
|
|
|
|
cache-dependency-path: complement/go.sum
|
|
|
|
go-version-file: complement/go.mod
|
|
|
|
|
2023-10-27 20:29:20 +03:00
|
|
|
# use p=1 concurrency as GHA boxes are underpowered and don't like running tons of synapses at once.
|
2022-07-13 15:30:42 +03:00
|
|
|
- run: |
|
|
|
|
set -o pipefail
|
2023-10-27 20:29:20 +03:00
|
|
|
COMPLEMENT_DIR=`pwd`/complement synapse/scripts-dev/complement.sh -p 1 -json 2>&1 | synapse/.ci/scripts/gotestfmt
|
2022-07-13 15:30:42 +03:00
|
|
|
shell: bash
|
2023-02-02 02:42:45 +03:00
|
|
|
env:
|
|
|
|
POSTGRES: ${{ (matrix.database == 'Postgres') && 1 || '' }}
|
|
|
|
WORKERS: ${{ (matrix.arrangement == 'workers') && 1 || '' }}
|
2022-07-13 15:30:42 +03:00
|
|
|
name: Run Complement Tests
|
|
|
|
|
2022-09-09 13:29:04 +03:00
|
|
|
cargo-test:
|
|
|
|
if: ${{ needs.changes.outputs.rust == 'true' }}
|
|
|
|
runs-on: ubuntu-latest
|
|
|
|
needs:
|
|
|
|
- linting-done
|
|
|
|
- changes
|
|
|
|
|
|
|
|
steps:
|
2023-09-25 18:39:54 +03:00
|
|
|
- uses: actions/checkout@v4
|
2022-09-09 13:29:04 +03:00
|
|
|
|
|
|
|
- name: Install Rust
|
2024-01-22 14:11:52 +03:00
|
|
|
uses: dtolnay/rust-toolchain@1.65.0
|
2022-09-09 13:29:04 +03:00
|
|
|
- uses: Swatinem/rust-cache@v2
|
|
|
|
|
|
|
|
- run: cargo test
|
|
|
|
|
2023-01-31 16:00:07 +03:00
|
|
|
# We want to ensure that the cargo benchmarks still compile, which requires a
|
|
|
|
# nightly compiler.
|
|
|
|
cargo-bench:
|
|
|
|
if: ${{ needs.changes.outputs.rust == 'true' }}
|
|
|
|
runs-on: ubuntu-latest
|
|
|
|
needs:
|
|
|
|
- linting-done
|
|
|
|
- changes
|
|
|
|
|
|
|
|
steps:
|
2023-09-25 18:39:54 +03:00
|
|
|
- uses: actions/checkout@v4
|
2023-01-31 16:00:07 +03:00
|
|
|
|
|
|
|
- name: Install Rust
|
2023-04-06 21:41:29 +03:00
|
|
|
uses: dtolnay/rust-toolchain@master
|
2023-01-31 16:00:07 +03:00
|
|
|
with:
|
|
|
|
toolchain: nightly-2022-12-01
|
|
|
|
- uses: Swatinem/rust-cache@v2
|
|
|
|
|
|
|
|
- run: cargo bench --no-run
|
|
|
|
|
2021-07-20 13:41:19 +03:00
|
|
|
# a job which marks all the other jobs as complete, thus allowing PRs to be merged.
|
|
|
|
tests-done:
|
2021-07-22 13:10:30 +03:00
|
|
|
if: ${{ always() }}
|
2021-07-20 13:41:19 +03:00
|
|
|
needs:
|
|
|
|
- trial
|
|
|
|
- trial-olddeps
|
|
|
|
- sytest
|
2022-03-07 15:24:06 +03:00
|
|
|
- export-data
|
2021-07-20 13:41:19 +03:00
|
|
|
- portdb
|
|
|
|
- complement
|
2022-09-09 13:29:04 +03:00
|
|
|
- cargo-test
|
2023-01-31 16:00:07 +03:00
|
|
|
- cargo-bench
|
2024-01-10 16:53:44 +03:00
|
|
|
- linting-done
|
2021-07-20 13:41:19 +03:00
|
|
|
runs-on: ubuntu-latest
|
|
|
|
steps:
|
2022-03-07 15:24:06 +03:00
|
|
|
- uses: matrix-org/done-action@v2
|
|
|
|
with:
|
|
|
|
needs: ${{ toJSON(needs) }}
|
|
|
|
|
2023-09-25 19:59:40 +03:00
|
|
|
# Various bits are skipped if there was no applicable changes.
|
2024-01-10 16:53:20 +03:00
|
|
|
# The newsfile lint may be skipped on non PR builds.
|
2022-09-12 20:31:23 +03:00
|
|
|
skippable: |
|
2023-09-25 19:59:40 +03:00
|
|
|
trial
|
|
|
|
trial-olddeps
|
|
|
|
sytest
|
|
|
|
portdb
|
2023-09-26 17:21:07 +03:00
|
|
|
export-data
|
2023-09-25 19:59:40 +03:00
|
|
|
complement
|
2022-03-07 15:24:06 +03:00
|
|
|
lint-newsfile
|
2022-09-12 15:26:33 +03:00
|
|
|
cargo-test
|
2023-01-31 16:00:07 +03:00
|
|
|
cargo-bench
|