Skip to content

Commit c7c35ef

Browse files
authored
chore: run macOS, windows, and race tests with Postgres in CI (#15520)
This PR is the second in a series aimed at closing #15109. ## Changes - adds `scripts/embedded-pg/main.go`, which can start a native Postgres database. This is used to set up PG on Windows and macOS, as these platforms don't support Docker in Github Actions. - runs the `test-go-pg` job on macOS and Windows too - adds the `test-go-race-go` job, which runs race tests with Postgres on Linux
1 parent 066a5ad commit c7c35ef

File tree

3 files changed

+189
-4
lines changed

3 files changed

+189
-4
lines changed
+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
name: "Setup ImDisk"
2+
if: runner.os == 'Windows'
3+
description: |
4+
Sets up the ImDisk toolkit for Windows and creates a RAM disk on drive R:.
5+
runs:
6+
using: "composite"
7+
steps:
8+
- name: Download ImDisk
9+
if: runner.os == 'Windows'
10+
shell: bash
11+
run: |
12+
mkdir imdisk
13+
cd imdisk
14+
curl -L -o files.cab https://github.com/coder/imdisk-artifacts/raw/92a17839ebc0ee3e69be019f66b3e9b5d2de4482/files.cab
15+
curl -L -o install.bat https://github.com/coder/imdisk-artifacts/raw/92a17839ebc0ee3e69be019f66b3e9b5d2de4482/install.bat
16+
cd ..
17+
18+
- name: Install ImDisk
19+
shell: cmd
20+
run: |
21+
cd imdisk
22+
install.bat /silent
23+
24+
- name: Create RAM Disk
25+
shell: cmd
26+
run: |
27+
imdisk -a -s 4096M -m R: -p "/fs:ntfs /q /y"

.github/workflows/ci.yaml

+86-4
Original file line numberDiff line numberDiff line change
@@ -370,15 +370,20 @@ jobs:
370370
api-key: ${{ secrets.DATADOG_API_KEY }}
371371

372372
test-go-pg:
373-
runs-on: ${{ github.repository_owner == 'coder' && 'depot-ubuntu-22.04-8' || 'ubuntu-latest' }}
374-
needs:
375-
- changes
373+
runs-on: ${{ matrix.os == 'ubuntu-latest' && github.repository_owner == 'coder' && 'depot-ubuntu-22.04-4' || matrix.os == 'macos-latest' && github.repository_owner == 'coder' && 'macos-latest-xlarge' || matrix.os == 'windows-2022' && github.repository_owner == 'coder' && 'windows-latest-16-cores' || matrix.os }}
374+
needs: changes
376375
if: needs.changes.outputs.go == 'true' || needs.changes.outputs.ci == 'true' || github.ref == 'refs/heads/main'
377376
# This timeout must be greater than the timeout set by `go test` in
378377
# `make test-postgres` to ensure we receive a trace of running
379378
# goroutines. Setting this to the timeout +5m should work quite well
380379
# even if some of the preceding steps are slow.
381380
timeout-minutes: 25
381+
strategy:
382+
matrix:
383+
os:
384+
- ubuntu-latest
385+
- macos-latest
386+
- windows-2022
382387
steps:
383388
- name: Harden Runner
384389
uses: step-security/harden-runner@0080882f6c36860b6ba35c610c98ce87d4e2f26f # v2.10.2
@@ -396,12 +401,46 @@ jobs:
396401
- name: Setup Terraform
397402
uses: ./.github/actions/setup-tf
398403

404+
# Sets up the ImDisk toolkit for Windows and creates a RAM disk on drive R:.
405+
- name: Setup ImDisk
406+
if: runner.os == 'Windows'
407+
uses: ./.github/actions/setup-imdisk
408+
399409
- name: Test with PostgreSQL Database
400410
env:
401411
POSTGRES_VERSION: "13"
402412
TS_DEBUG_DISCO: "true"
413+
shell: bash
403414
run: |
404-
make test-postgres
415+
# if macOS, install google-chrome for scaletests
416+
# As another concern, should we really have this kind of external dependency
417+
# requirement on standard CI?
418+
if [ "${{ matrix.os }}" == "macos-latest" ]; then
419+
brew install google-chrome
420+
fi
421+
422+
# By default Go will use the number of logical CPUs, which
423+
# is a fine default.
424+
PARALLEL_FLAG=""
425+
426+
# macOS will output "The default interactive shell is now zsh"
427+
# intermittently in CI...
428+
if [ "${{ matrix.os }}" == "macos-latest" ]; then
429+
touch ~/.bash_profile && echo "export BASH_SILENCE_DEPRECATION_WARNING=1" >> ~/.bash_profile
430+
fi
431+
432+
if [ "${{ runner.os }}" == "Linux" ]; then
433+
make test-postgres
434+
elif [ "${{ runner.os }}" == "Windows" ]; then
435+
# Create a temp dir on the R: ramdisk drive for Windows. The default
436+
# C: drive is extremely slow: https://github.com/actions/runner-images/issues/8755
437+
mkdir -p "R:/temp/embedded-pg"
438+
go run scripts/embedded-pg/main.go -path "R:/temp/embedded-pg"
439+
DB=ci gotestsum --format standard-quiet -- -v -short -count=1 ./...
440+
else
441+
go run scripts/embedded-pg/main.go
442+
DB=ci gotestsum --format standard-quiet -- -v -short -count=1 ./...
443+
fi
405444
406445
- name: Upload test stats to Datadog
407446
timeout-minutes: 1
@@ -494,6 +533,47 @@ jobs:
494533
with:
495534
api-key: ${{ secrets.DATADOG_API_KEY }}
496535

536+
test-go-race-pg:
537+
runs-on: ${{ github.repository_owner == 'coder' && 'depot-ubuntu-22.04-16' || 'ubuntu-latest' }}
538+
needs: changes
539+
if: needs.changes.outputs.go == 'true' || needs.changes.outputs.ci == 'true' || github.ref == 'refs/heads/main'
540+
timeout-minutes: 25
541+
steps:
542+
- name: Harden Runner
543+
uses: step-security/harden-runner@91182cccc01eb5e619899d80e4e971d6181294a7 # v2.10.1
544+
with:
545+
egress-policy: audit
546+
547+
- name: Checkout
548+
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1
549+
with:
550+
fetch-depth: 1
551+
552+
- name: Setup Go
553+
uses: ./.github/actions/setup-go
554+
555+
- name: Setup Terraform
556+
uses: ./.github/actions/setup-tf
557+
558+
# We run race tests with reduced parallelism because they use more CPU and we were finding
559+
# instances where tests appear to hang for multiple seconds, resulting in flaky tests when
560+
# short timeouts are used.
561+
# c.f. discussion on https://github.com/coder/coder/pull/15106
562+
- name: Run Tests
563+
env:
564+
POSTGRES_VERSION: "16"
565+
run: |
566+
make test-postgres-docker
567+
DB=ci gotestsum --junitfile="gotests.xml" -- -race -parallel 4 -p 4 ./...
568+
569+
- name: Upload test stats to Datadog
570+
timeout-minutes: 1
571+
continue-on-error: true
572+
uses: ./.github/actions/upload-datadog
573+
if: always()
574+
with:
575+
api-key: ${{ secrets.DATADOG_API_KEY }}
576+
497577
# Tailnet integration tests only run when the `tailnet` directory or `go.sum`
498578
# and `go.mod` are changed. These tests are to ensure we don't add regressions
499579
# to tailnet, either due to our code or due to updating dependencies.
@@ -771,6 +851,7 @@ jobs:
771851
- test-go
772852
- test-go-pg
773853
- test-go-race
854+
- test-go-race-pg
774855
- test-js
775856
- test-e2e
776857
- offlinedocs
@@ -793,6 +874,7 @@ jobs:
793874
echo "- test-go: ${{ needs.test-go.result }}"
794875
echo "- test-go-pg: ${{ needs.test-go-pg.result }}"
795876
echo "- test-go-race: ${{ needs.test-go-race.result }}"
877+
echo "- test-go-race-pg: ${{ needs.test-go-race-pg.result }}"
796878
echo "- test-js: ${{ needs.test-js.result }}"
797879
echo "- test-e2e: ${{ needs.test-e2e.result }}"
798880
echo "- offlinedocs: ${{ needs.offlinedocs.result }}"

scripts/embedded-pg/main.go

+76
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
// Start an embedded postgres database on port 5432. Used in CI on macOS and Windows.
2+
package main
3+
4+
import (
5+
"database/sql"
6+
"flag"
7+
"os"
8+
"path/filepath"
9+
10+
embeddedpostgres "github.com/fergusstrange/embedded-postgres"
11+
)
12+
13+
func main() {
14+
var customPath string
15+
flag.StringVar(&customPath, "path", "", "Optional custom path for postgres data directory")
16+
flag.Parse()
17+
18+
postgresPath := filepath.Join(os.TempDir(), "coder-test-postgres")
19+
if customPath != "" {
20+
postgresPath = customPath
21+
}
22+
23+
ep := embeddedpostgres.NewDatabase(
24+
embeddedpostgres.DefaultConfig().
25+
Version(embeddedpostgres.V16).
26+
BinariesPath(filepath.Join(postgresPath, "bin")).
27+
DataPath(filepath.Join(postgresPath, "data")).
28+
RuntimePath(filepath.Join(postgresPath, "runtime")).
29+
CachePath(filepath.Join(postgresPath, "cache")).
30+
Username("postgres").
31+
Password("postgres").
32+
Database("postgres").
33+
Encoding("UTF8").
34+
Port(uint32(5432)).
35+
Logger(os.Stdout),
36+
)
37+
err := ep.Start()
38+
if err != nil {
39+
panic(err)
40+
}
41+
// We execute these queries instead of using the embeddedpostgres
42+
// StartParams because it doesn't work on Windows. The library
43+
// seems to have a bug where it sends malformed parameters to
44+
// pg_ctl. It encloses each parameter in single quotes, which
45+
// Windows can't handle.
46+
// Related issue:
47+
// https://github.com/fergusstrange/embedded-postgres/issues/145
48+
paramQueries := []string{
49+
`ALTER SYSTEM SET effective_cache_size = '1GB';`,
50+
`ALTER SYSTEM SET fsync = 'off';`,
51+
`ALTER SYSTEM SET full_page_writes = 'off';`,
52+
`ALTER SYSTEM SET max_connections = '1000';`,
53+
`ALTER SYSTEM SET shared_buffers = '1GB';`,
54+
`ALTER SYSTEM SET synchronous_commit = 'off';`,
55+
`ALTER SYSTEM SET client_encoding = 'UTF8';`,
56+
}
57+
db, err := sql.Open("postgres", "postgres://postgres:postgres@127.0.0.1:5432/postgres?sslmode=disable")
58+
if err != nil {
59+
panic(err)
60+
}
61+
for _, query := range paramQueries {
62+
if _, err := db.Exec(query); err != nil {
63+
panic(err)
64+
}
65+
}
66+
if err := db.Close(); err != nil {
67+
panic(err)
68+
}
69+
// We restart the database to apply all the parameters.
70+
if err := ep.Stop(); err != nil {
71+
panic(err)
72+
}
73+
if err := ep.Start(); err != nil {
74+
panic(err)
75+
}
76+
}

0 commit comments

Comments
 (0)