tests.yml 18 KB

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