tests.yml 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575
  1. name: Tests
  2. on:
  3. push:
  4. branches: ["develop", "release-*"]
  5. pull_request:
  6. workflow_dispatch:
  7. concurrency:
  8. group: ${{ github.workflow }}-${{ github.ref }}
  9. cancel-in-progress: true
  10. jobs:
  11. # Job to detect what has changed so we don't run e.g. Rust checks on PRs that
  12. # don't modify Rust code.
  13. changes:
  14. runs-on: ubuntu-latest
  15. outputs:
  16. rust: ${{ !startsWith(github.ref, 'refs/pull/') || steps.filter.outputs.rust }}
  17. steps:
  18. - uses: dorny/paths-filter@v2
  19. id: filter
  20. # We only check on PRs
  21. if: startsWith(github.ref, 'refs/pull/')
  22. with:
  23. filters: |
  24. rust:
  25. - 'rust/**'
  26. - 'Cargo.toml'
  27. - 'Cargo.lock'
  28. check-sampleconfig:
  29. runs-on: ubuntu-latest
  30. steps:
  31. - uses: actions/checkout@v3
  32. - uses: actions/setup-python@v4
  33. with:
  34. python-version: "3.x"
  35. - uses: matrix-org/setup-python-poetry@v1
  36. with:
  37. extras: "all"
  38. - run: poetry run scripts-dev/generate_sample_config.sh --check
  39. - run: poetry run scripts-dev/config-lint.sh
  40. check-schema-delta:
  41. runs-on: ubuntu-latest
  42. steps:
  43. - uses: actions/checkout@v3
  44. - uses: actions/setup-python@v4
  45. with:
  46. python-version: "3.x"
  47. - run: "pip install 'click==8.1.1' 'GitPython>=3.1.20'"
  48. - run: scripts-dev/check_schema_delta.py --force-colors
  49. lint:
  50. uses: "matrix-org/backend-meta/.github/workflows/python-poetry-ci.yml@v2"
  51. with:
  52. typechecking-extras: "all"
  53. lint-crlf:
  54. runs-on: ubuntu-latest
  55. steps:
  56. - uses: actions/checkout@v3
  57. - name: Check line endings
  58. run: scripts-dev/check_line_terminators.sh
  59. lint-newsfile:
  60. if: ${{ (github.base_ref == 'develop' || contains(github.base_ref, 'release-')) && github.actor != 'dependabot[bot]' }}
  61. runs-on: ubuntu-latest
  62. steps:
  63. - uses: actions/checkout@v3
  64. with:
  65. ref: ${{ github.event.pull_request.head.sha }}
  66. fetch-depth: 0
  67. - uses: actions/setup-python@v4
  68. with:
  69. python-version: "3.x"
  70. - run: "pip install 'towncrier>=18.6.0rc1'"
  71. - run: scripts-dev/check-newsfragment.sh
  72. env:
  73. PULL_REQUEST_NUMBER: ${{ github.event.number }}
  74. lint-pydantic:
  75. runs-on: ubuntu-latest
  76. steps:
  77. - uses: actions/checkout@v3
  78. with:
  79. ref: ${{ github.event.pull_request.head.sha }}
  80. - uses: matrix-org/setup-python-poetry@v1
  81. with:
  82. extras: "all"
  83. - run: poetry run scripts-dev/check_pydantic_models.py
  84. lint-clippy:
  85. runs-on: ubuntu-latest
  86. needs: changes
  87. if: ${{ needs.changes.outputs.rust == 'true' }}
  88. steps:
  89. - uses: actions/checkout@v3
  90. - name: Install Rust
  91. # There don't seem to be versioned releases of this action per se: for each rust
  92. # version there is a branch which gets constantly rebased on top of master.
  93. # We pin to a specific commit for paranoia's sake.
  94. uses: dtolnay/rust-toolchain@e645b0cf01249a964ec099494d38d2da0f0b349f
  95. with:
  96. toolchain: 1.58.1
  97. components: clippy
  98. - uses: Swatinem/rust-cache@v2
  99. - run: cargo clippy -- -D warnings
  100. # We also lint against a nightly rustc so that we can lint the benchmark
  101. # suite, which requires a nightly compiler.
  102. lint-clippy-nightly:
  103. runs-on: ubuntu-latest
  104. needs: changes
  105. if: ${{ needs.changes.outputs.rust == 'true' }}
  106. steps:
  107. - uses: actions/checkout@v3
  108. - name: Install Rust
  109. # There don't seem to be versioned releases of this action per se: for each rust
  110. # version there is a branch which gets constantly rebased on top of master.
  111. # We pin to a specific commit for paranoia's sake.
  112. uses: dtolnay/rust-toolchain@e645b0cf01249a964ec099494d38d2da0f0b349f
  113. with:
  114. toolchain: nightly-2022-12-01
  115. components: clippy
  116. - uses: Swatinem/rust-cache@v2
  117. - run: cargo clippy --all-features -- -D warnings
  118. lint-rustfmt:
  119. runs-on: ubuntu-latest
  120. needs: changes
  121. if: ${{ needs.changes.outputs.rust == 'true' }}
  122. steps:
  123. - uses: actions/checkout@v3
  124. - name: Install Rust
  125. # There don't seem to be versioned releases of this action per se: for each rust
  126. # version there is a branch which gets constantly rebased on top of master.
  127. # We pin to a specific commit for paranoia's sake.
  128. uses: dtolnay/rust-toolchain@e645b0cf01249a964ec099494d38d2da0f0b349f
  129. with:
  130. toolchain: 1.58.1
  131. components: rustfmt
  132. - uses: Swatinem/rust-cache@v2
  133. - run: cargo fmt --check
  134. # Dummy step to gate other tests on without repeating the whole list
  135. linting-done:
  136. if: ${{ !cancelled() }} # Run this even if prior jobs were skipped
  137. needs:
  138. - lint
  139. - lint-crlf
  140. - lint-newsfile
  141. - lint-pydantic
  142. - check-sampleconfig
  143. - check-schema-delta
  144. - lint-clippy
  145. - lint-rustfmt
  146. runs-on: ubuntu-latest
  147. steps:
  148. - run: "true"
  149. calculate-test-jobs:
  150. if: ${{ !cancelled() && !failure() }} # Allow previous steps to be skipped, but not fail
  151. needs: linting-done
  152. runs-on: ubuntu-latest
  153. steps:
  154. - uses: actions/checkout@v3
  155. - uses: actions/setup-python@v4
  156. with:
  157. python-version: "3.x"
  158. - id: get-matrix
  159. run: .ci/scripts/calculate_jobs.py
  160. outputs:
  161. trial_test_matrix: ${{ steps.get-matrix.outputs.trial_test_matrix }}
  162. sytest_test_matrix: ${{ steps.get-matrix.outputs.sytest_test_matrix }}
  163. trial:
  164. if: ${{ !cancelled() && !failure() }} # Allow previous steps to be skipped, but not fail
  165. needs: calculate-test-jobs
  166. runs-on: ubuntu-latest
  167. strategy:
  168. matrix:
  169. job: ${{ fromJson(needs.calculate-test-jobs.outputs.trial_test_matrix) }}
  170. steps:
  171. - uses: actions/checkout@v3
  172. - run: sudo apt-get -qq install xmlsec1
  173. - name: Set up PostgreSQL ${{ matrix.job.postgres-version }}
  174. if: ${{ matrix.job.postgres-version }}
  175. # 1. Mount postgres data files onto a tmpfs in-memory filesystem to reduce overhead of docker's overlayfs layer.
  176. # 2. Expose the unix socket for postgres. This removes latency of using docker-proxy for connections.
  177. run: |
  178. docker run -d -p 5432:5432 \
  179. --tmpfs /var/lib/postgres:rw,size=6144m \
  180. --mount 'type=bind,src=/var/run/postgresql,dst=/var/run/postgresql' \
  181. -e POSTGRES_PASSWORD=postgres \
  182. -e POSTGRES_INITDB_ARGS="--lc-collate C --lc-ctype C --encoding UTF8" \
  183. postgres:${{ matrix.job.postgres-version }}
  184. - name: Install Rust
  185. # There don't seem to be versioned releases of this action per se: for each rust
  186. # version there is a branch which gets constantly rebased on top of master.
  187. # We pin to a specific commit for paranoia's sake.
  188. uses: dtolnay/rust-toolchain@e645b0cf01249a964ec099494d38d2da0f0b349f
  189. with:
  190. toolchain: 1.58.1
  191. - uses: Swatinem/rust-cache@v2
  192. - uses: matrix-org/setup-python-poetry@v1
  193. with:
  194. python-version: ${{ matrix.job.python-version }}
  195. extras: ${{ matrix.job.extras }}
  196. - name: Await PostgreSQL
  197. if: ${{ matrix.job.postgres-version }}
  198. timeout-minutes: 2
  199. run: until pg_isready -h localhost; do sleep 1; done
  200. - run: poetry run trial --jobs=6 tests
  201. env:
  202. SYNAPSE_POSTGRES: ${{ matrix.job.database == 'postgres' || '' }}
  203. SYNAPSE_POSTGRES_HOST: /var/run/postgresql
  204. SYNAPSE_POSTGRES_USER: postgres
  205. SYNAPSE_POSTGRES_PASSWORD: postgres
  206. - name: Dump logs
  207. # Logs are most useful when the command fails, always include them.
  208. if: ${{ always() }}
  209. # Note: Dumps to workflow logs instead of using actions/upload-artifact
  210. # This keeps logs colocated with failing jobs
  211. # It also ignores find's exit code; this is a best effort affair
  212. run: >-
  213. find _trial_temp -name '*.log'
  214. -exec echo "::group::{}" \;
  215. -exec cat {} \;
  216. -exec echo "::endgroup::" \;
  217. || true
  218. trial-olddeps:
  219. # Note: sqlite only; no postgres
  220. if: ${{ !cancelled() && !failure() }} # Allow previous steps to be skipped, but not fail
  221. needs: linting-done
  222. runs-on: ubuntu-20.04
  223. steps:
  224. - uses: actions/checkout@v3
  225. - name: Install Rust
  226. # There don't seem to be versioned releases of this action per se: for each rust
  227. # version there is a branch which gets constantly rebased on top of master.
  228. # We pin to a specific commit for paranoia's sake.
  229. uses: dtolnay/rust-toolchain@e645b0cf01249a964ec099494d38d2da0f0b349f
  230. with:
  231. toolchain: 1.58.1
  232. - uses: Swatinem/rust-cache@v2
  233. # There aren't wheels for some of the older deps, so we need to install
  234. # their build dependencies
  235. - run: |
  236. sudo apt-get -qq install build-essential libffi-dev python-dev \
  237. libxml2-dev libxslt-dev xmlsec1 zlib1g-dev libjpeg-dev libwebp-dev
  238. - uses: actions/setup-python@v4
  239. with:
  240. python-version: '3.7'
  241. # Calculating the old-deps actually takes a bunch of time, so we cache the
  242. # pyproject.toml / poetry.lock. We need to cache pyproject.toml as
  243. # otherwise the `poetry install` step will error due to the poetry.lock
  244. # file being outdated.
  245. #
  246. # This caches the output of `Prepare old deps`, which should generate the
  247. # same `pyproject.toml` and `poetry.lock` for a given `pyproject.toml` input.
  248. - uses: actions/cache@v3
  249. id: cache-poetry-old-deps
  250. name: Cache poetry.lock
  251. with:
  252. path: |
  253. poetry.lock
  254. pyproject.toml
  255. key: poetry-old-deps2-${{ hashFiles('pyproject.toml') }}
  256. - name: Prepare old deps
  257. if: steps.cache-poetry-old-deps.outputs.cache-hit != 'true'
  258. run: .ci/scripts/prepare_old_deps.sh
  259. # We only now install poetry so that `setup-python-poetry` caches the
  260. # right poetry.lock's dependencies.
  261. - uses: matrix-org/setup-python-poetry@v1
  262. with:
  263. python-version: '3.7'
  264. extras: "all test"
  265. - run: poetry run trial -j6 tests
  266. - name: Dump logs
  267. # Logs are most useful when the command fails, always include them.
  268. if: ${{ always() }}
  269. # Note: Dumps to workflow logs instead of using actions/upload-artifact
  270. # This keeps logs colocated with failing jobs
  271. # It also ignores find's exit code; this is a best effort affair
  272. run: >-
  273. find _trial_temp -name '*.log'
  274. -exec echo "::group::{}" \;
  275. -exec cat {} \;
  276. -exec echo "::endgroup::" \;
  277. || true
  278. trial-pypy:
  279. # Very slow; only run if the branch name includes 'pypy'
  280. # Note: sqlite only; no postgres. Completely untested since poetry move.
  281. if: ${{ contains(github.ref, 'pypy') && !failure() && !cancelled() }}
  282. needs: linting-done
  283. runs-on: ubuntu-latest
  284. strategy:
  285. matrix:
  286. python-version: ["pypy-3.7"]
  287. extras: ["all"]
  288. steps:
  289. - uses: actions/checkout@v3
  290. # Install libs necessary for PyPy to build binary wheels for dependencies
  291. - run: sudo apt-get -qq install xmlsec1 libxml2-dev libxslt-dev
  292. - uses: matrix-org/setup-python-poetry@v1
  293. with:
  294. python-version: ${{ matrix.python-version }}
  295. extras: ${{ matrix.extras }}
  296. - run: poetry run trial --jobs=2 tests
  297. - name: Dump logs
  298. # Logs are most useful when the command fails, always include them.
  299. if: ${{ always() }}
  300. # Note: Dumps to workflow logs instead of using actions/upload-artifact
  301. # This keeps logs colocated with failing jobs
  302. # It also ignores find's exit code; this is a best effort affair
  303. run: >-
  304. find _trial_temp -name '*.log'
  305. -exec echo "::group::{}" \;
  306. -exec cat {} \;
  307. -exec echo "::endgroup::" \;
  308. || true
  309. sytest:
  310. if: ${{ !failure() && !cancelled() }}
  311. needs: calculate-test-jobs
  312. runs-on: ubuntu-latest
  313. container:
  314. image: matrixdotorg/sytest-synapse:${{ matrix.job.sytest-tag }}
  315. volumes:
  316. - ${{ github.workspace }}:/src
  317. env:
  318. SYTEST_BRANCH: ${{ github.head_ref }}
  319. POSTGRES: ${{ matrix.job.postgres && 1}}
  320. MULTI_POSTGRES: ${{ (matrix.job.postgres == 'multi-postgres') && 1}}
  321. WORKERS: ${{ matrix.job.workers && 1 }}
  322. BLACKLIST: ${{ matrix.job.workers && 'synapse-blacklist-with-workers' }}
  323. TOP: ${{ github.workspace }}
  324. strategy:
  325. fail-fast: false
  326. matrix:
  327. job: ${{ fromJson(needs.calculate-test-jobs.outputs.sytest_test_matrix) }}
  328. steps:
  329. - uses: actions/checkout@v3
  330. - name: Prepare test blacklist
  331. run: cat sytest-blacklist .ci/worker-blacklist > synapse-blacklist-with-workers
  332. - name: Install Rust
  333. # There don't seem to be versioned releases of this action per se: for each rust
  334. # version there is a branch which gets constantly rebased on top of master.
  335. # We pin to a specific commit for paranoia's sake.
  336. uses: dtolnay/rust-toolchain@e645b0cf01249a964ec099494d38d2da0f0b349f
  337. with:
  338. toolchain: 1.58.1
  339. - uses: Swatinem/rust-cache@v2
  340. - name: Run SyTest
  341. run: /bootstrap.sh synapse
  342. working-directory: /src
  343. - name: Summarise results.tap
  344. if: ${{ always() }}
  345. run: /sytest/scripts/tap_to_gha.pl /logs/results.tap
  346. - name: Upload SyTest logs
  347. uses: actions/upload-artifact@v3
  348. if: ${{ always() }}
  349. with:
  350. name: Sytest Logs - ${{ job.status }} - (${{ join(matrix.job.*, ', ') }})
  351. path: |
  352. /logs/results.tap
  353. /logs/**/*.log*
  354. export-data:
  355. if: ${{ !failure() && !cancelled() }} # Allow previous steps to be skipped, but not fail
  356. needs: [linting-done, portdb]
  357. runs-on: ubuntu-latest
  358. env:
  359. TOP: ${{ github.workspace }}
  360. services:
  361. postgres:
  362. image: postgres
  363. ports:
  364. - 5432:5432
  365. env:
  366. POSTGRES_PASSWORD: "postgres"
  367. POSTGRES_INITDB_ARGS: "--lc-collate C --lc-ctype C --encoding UTF8"
  368. options: >-
  369. --health-cmd pg_isready
  370. --health-interval 10s
  371. --health-timeout 5s
  372. --health-retries 5
  373. steps:
  374. - uses: actions/checkout@v3
  375. - run: sudo apt-get -qq install xmlsec1 postgresql-client
  376. - uses: matrix-org/setup-python-poetry@v1
  377. with:
  378. extras: "postgres"
  379. - run: .ci/scripts/test_export_data_command.sh
  380. env:
  381. PGHOST: localhost
  382. PGUSER: postgres
  383. PGPASSWORD: postgres
  384. PGDATABASE: postgres
  385. portdb:
  386. if: ${{ !failure() && !cancelled() }} # Allow previous steps to be skipped, but not fail
  387. needs: linting-done
  388. runs-on: ubuntu-latest
  389. strategy:
  390. matrix:
  391. include:
  392. - python-version: "3.7"
  393. postgres-version: "11"
  394. - python-version: "3.11"
  395. postgres-version: "15"
  396. services:
  397. postgres:
  398. image: postgres:${{ matrix.postgres-version }}
  399. ports:
  400. - 5432:5432
  401. env:
  402. POSTGRES_PASSWORD: "postgres"
  403. POSTGRES_INITDB_ARGS: "--lc-collate C --lc-ctype C --encoding UTF8"
  404. options: >-
  405. --health-cmd pg_isready
  406. --health-interval 10s
  407. --health-timeout 5s
  408. --health-retries 5
  409. steps:
  410. - uses: actions/checkout@v3
  411. - name: Add PostgreSQL apt repository
  412. # We need a version of pg_dump that can handle the version of
  413. # PostgreSQL being tested against. The Ubuntu package repository lags
  414. # behind new releases, so we have to use the PostreSQL apt repository.
  415. # Steps taken from https://www.postgresql.org/download/linux/ubuntu/
  416. run: |
  417. sudo sh -c 'echo "deb http://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" > /etc/apt/sources.list.d/pgdg.list'
  418. wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | sudo apt-key add -
  419. sudo apt-get update
  420. - run: sudo apt-get -qq install xmlsec1 postgresql-client
  421. - uses: matrix-org/setup-python-poetry@v1
  422. with:
  423. python-version: ${{ matrix.python-version }}
  424. extras: "postgres"
  425. - run: .ci/scripts/test_synapse_port_db.sh
  426. id: run_tester_script
  427. env:
  428. PGHOST: localhost
  429. PGUSER: postgres
  430. PGPASSWORD: postgres
  431. PGDATABASE: postgres
  432. - name: "Upload schema differences"
  433. uses: actions/upload-artifact@v3
  434. if: ${{ failure() && !cancelled() && steps.run_tester_script.outcome == 'failure' }}
  435. with:
  436. name: Schema dumps
  437. path: |
  438. unported.sql
  439. ported.sql
  440. schema_diff
  441. complement:
  442. if: "${{ !failure() && !cancelled() }}"
  443. needs: linting-done
  444. runs-on: ubuntu-latest
  445. strategy:
  446. fail-fast: false
  447. matrix:
  448. include:
  449. - arrangement: monolith
  450. database: SQLite
  451. - arrangement: monolith
  452. database: Postgres
  453. - arrangement: workers
  454. database: Postgres
  455. steps:
  456. - name: Run actions/checkout@v3 for synapse
  457. uses: actions/checkout@v3
  458. with:
  459. path: synapse
  460. - name: Install Rust
  461. # There don't seem to be versioned releases of this action per se: for each rust
  462. # version there is a branch which gets constantly rebased on top of master.
  463. # We pin to a specific commit for paranoia's sake.
  464. uses: dtolnay/rust-toolchain@e645b0cf01249a964ec099494d38d2da0f0b349f
  465. with:
  466. toolchain: 1.58.1
  467. - uses: Swatinem/rust-cache@v2
  468. - name: Prepare Complement's Prerequisites
  469. run: synapse/.ci/scripts/setup_complement_prerequisites.sh
  470. - run: |
  471. set -o pipefail
  472. POSTGRES=${{ (matrix.database == 'Postgres') && 1 || '' }} WORKERS=${{ (matrix.arrangement == 'workers') && 1 || '' }} COMPLEMENT_DIR=`pwd`/complement synapse/scripts-dev/complement.sh -json 2>&1 | synapse/.ci/scripts/gotestfmt
  473. shell: bash
  474. name: Run Complement Tests
  475. cargo-test:
  476. if: ${{ needs.changes.outputs.rust == 'true' }}
  477. runs-on: ubuntu-latest
  478. needs:
  479. - linting-done
  480. - changes
  481. steps:
  482. - uses: actions/checkout@v3
  483. - name: Install Rust
  484. # There don't seem to be versioned releases of this action per se: for each rust
  485. # version there is a branch which gets constantly rebased on top of master.
  486. # We pin to a specific commit for paranoia's sake.
  487. uses: dtolnay/rust-toolchain@e645b0cf01249a964ec099494d38d2da0f0b349f
  488. with:
  489. toolchain: 1.58.1
  490. - uses: Swatinem/rust-cache@v2
  491. - run: cargo test
  492. # a job which marks all the other jobs as complete, thus allowing PRs to be merged.
  493. tests-done:
  494. if: ${{ always() }}
  495. needs:
  496. - trial
  497. - trial-olddeps
  498. - sytest
  499. - export-data
  500. - portdb
  501. - complement
  502. - cargo-test
  503. runs-on: ubuntu-latest
  504. steps:
  505. - uses: matrix-org/done-action@v2
  506. with:
  507. needs: ${{ toJSON(needs) }}
  508. # The newsfile lint may be skipped on non PR builds
  509. # Cargo test is skipped if there is no changes on Rust code
  510. skippable: |
  511. lint-newsfile
  512. cargo-test