From b2c483ada4b3450f4b95396455aaae33c42d2b78 Mon Sep 17 00:00:00 2001 From: Michael Fridman Date: Thu, 14 Mar 2024 09:35:52 -0400 Subject: [PATCH] Update integration test suite (formally e2e) (#713) --- .../workflows/{e2e.yaml => integration.yaml} | 12 +- .github/workflows/lint.yaml | 3 +- .gitignore | 3 + Makefile | 53 ++- database/store_test.go | 17 - go.mod | 25 -- go.sum | 45 -- internal/testing/go.mod | 87 ++++ internal/testing/go.sum | 384 ++++++++++++++++ internal/testing/integration/README.md | 58 +++ internal/testing/integration/database_test.go | 195 ++++++++ internal/testing/integration/integration.go | 82 ++++ .../integration/postgres_locking_test.go | 417 ++++++++++++++++++ .../taxi_zone_lookup.csv | 0 .../migrations/clickhouse-remote}/00001_a.sql | 0 .../migrations/clickhouse}/00001_a.sql | 0 .../migrations/clickhouse}/00002_b.sql | 0 .../migrations/clickhouse}/00003_c.sql | 0 .../testdata/migrations/mysql/00001_table.sql | 23 + .../migrations/mysql/00002_insert.sql | 22 + .../testdata/migrations/mysql/00003_alter.sql | 17 + .../testdata/migrations/mysql/00004_empty.sql | 1 + .../testdata/migrations/mysql/00005_no_tx.sql | 8 + .../migrations/mysql/00006_complex.sql | 36 ++ .../migrations/postgres/00001_table.sql | 2 +- .../migrations/postgres/00002_insert.sql | 7 +- .../migrations/postgres/00003_alter.sql | 0 .../migrations/postgres/00004_empty.sql | 1 + .../migrations/postgres/00005_no_tx.sql | 4 +- .../migrations/postgres/00006_complex.sql | 36 ++ .../testdata/migrations/turso/00001_table.sql | 20 + .../migrations/turso/00002_insert.sql | 19 + .../testdata/migrations/turso/00003_alter.sql | 17 + .../testdata/migrations/turso/00004_empty.sql | 1 + .../testdata/migrations/turso/00005_no_tx.sql | 9 + .../testdata/migrations/vertica}/00001_a.sql | 0 .../testdata/migrations/vertica}/00002_b.sql | 0 .../testdata/migrations/vertica}/00003_c.sql | 0 .../testdata/migrations/ydb}/00001_a.sql | 0 .../testdata/migrations/ydb}/00002_b.sql | 0 .../testdata/migrations/ydb}/00003_c.sql | 1 + .../testdata/migrations/ydb}/00004_d.sql | 0 .../testdata/migrations/ydb}/00005_e.sql | 0 .../testdata/migrations/ydb}/00006_f.sql | 0 .../testdata/migrations/ydb}/00007_g.sql | 0 .../testdata/migrations/ydb}/00008_h.sql | 0 internal/{ => testing}/testdb/clickhouse.go | 0 .../testdb/container_healthcheck.go | 0 internal/{ => testing}/testdb/mariadb.go | 0 internal/{ => testing}/testdb/options.go | 0 internal/{ => testing}/testdb/postgres.go | 2 +- internal/{ => testing}/testdb/testdb.go | 0 internal/{ => testing}/testdb/turso.go | 4 +- internal/{ => testing}/testdb/vertica.go | 28 +- internal/{ => testing}/testdb/ydb.go | 4 +- lock/postgres_test.go | 172 -------- provider_run_test.go | 244 ---------- tests/clickhouse/clickhouse_test.go | 157 ------- tests/e2e/allow_missing_test.go | 380 ---------------- tests/e2e/main_test.go | 126 ------ tests/e2e/migrations_test.go | 373 ---------------- tests/e2e/no_versioning_test.go | 149 ------- .../e2e/testdata/mysql/migrations/00001_a.sql | 20 - .../e2e/testdata/mysql/migrations/00002_b.sql | 10 - .../e2e/testdata/mysql/migrations/00003_c.sql | 13 - .../e2e/testdata/mysql/migrations/00004_d.sql | 13 - .../e2e/testdata/mysql/migrations/00006_f.sql | 17 - .../e2e/testdata/mysql/migrations/00007_g.sql | 15 - .../e2e/testdata/mysql/migrations/00008_h.sql | 10 - .../testdata/postgres/migrations/00002_b.sql | 10 - .../testdata/postgres/migrations/00005_e.sql | 11 - .../testdata/postgres/migrations/00006_f.sql | 17 - .../testdata/postgres/migrations/00007_g.sql | 15 - .../testdata/postgres/migrations/00008_h.sql | 10 - .../testdata/postgres/migrations/00009_i.sql | 9 - .../testdata/postgres/migrations/00011_k.sql | 26 -- tests/e2e/testdata/postgres/seed/00001_a.sql | 18 - tests/e2e/testdata/postgres/seed/00002_b.sql | 14 - .../e2e/testdata/turso/migrations/00001_a.sql | 21 - .../e2e/testdata/turso/migrations/00003_c.sql | 13 - .../e2e/testdata/turso/migrations/00004_d.sql | 15 - .../e2e/testdata/turso/migrations/00005_e.sql | 11 - .../e2e/testdata/turso/migrations/00006_f.sql | 15 - .../e2e/testdata/turso/migrations/00007_g.sql | 16 - .../e2e/testdata/turso/migrations/00008_h.sql | 9 - tests/e2e/testdata/ydb/migrations/00002_b.sql | 10 - tests/e2e/testdata/ydb/migrations/00005_e.sql | 11 - .../error/gomigrations_error_test.go | 11 +- .../error/testdata/001_up_no_tx.go | 2 +- .../error/testdata/003_truncate.go | 2 +- tests/vertica/vertica_test.go | 115 ----- 91 files changed, 1519 insertions(+), 2204 deletions(-) rename .github/workflows/{e2e.yaml => integration.yaml} (59%) create mode 100644 internal/testing/go.mod create mode 100644 internal/testing/go.sum create mode 100644 internal/testing/integration/README.md create mode 100644 internal/testing/integration/database_test.go create mode 100644 internal/testing/integration/integration.go create mode 100644 internal/testing/integration/postgres_locking_test.go rename {tests/clickhouse/testdata/backup-files => internal/testing/integration/testdata/migrations/clickhouse-remote-backup}/taxi_zone_lookup.csv (100%) rename {tests/clickhouse/testdata/migrations-remote => internal/testing/integration/testdata/migrations/clickhouse-remote}/00001_a.sql (100%) rename {tests/clickhouse/testdata/migrations => internal/testing/integration/testdata/migrations/clickhouse}/00001_a.sql (100%) rename {tests/clickhouse/testdata/migrations => internal/testing/integration/testdata/migrations/clickhouse}/00002_b.sql (100%) rename {tests/clickhouse/testdata/migrations => internal/testing/integration/testdata/migrations/clickhouse}/00003_c.sql (100%) create mode 100644 internal/testing/integration/testdata/migrations/mysql/00001_table.sql create mode 100644 internal/testing/integration/testdata/migrations/mysql/00002_insert.sql create mode 100644 internal/testing/integration/testdata/migrations/mysql/00003_alter.sql create mode 100644 internal/testing/integration/testdata/migrations/mysql/00004_empty.sql create mode 100644 internal/testing/integration/testdata/migrations/mysql/00005_no_tx.sql create mode 100644 internal/testing/integration/testdata/migrations/mysql/00006_complex.sql rename tests/e2e/testdata/postgres/migrations/00001_a.sql => internal/testing/integration/testdata/migrations/postgres/00001_table.sql (96%) rename tests/e2e/testdata/postgres/migrations/00003_c.sql => internal/testing/integration/testdata/migrations/postgres/00002_insert.sql (73%) rename tests/e2e/testdata/postgres/migrations/00004_d.sql => internal/testing/integration/testdata/migrations/postgres/00003_alter.sql (100%) create mode 100644 internal/testing/integration/testdata/migrations/postgres/00004_empty.sql rename tests/e2e/testdata/postgres/migrations/00010_j.sql => internal/testing/integration/testdata/migrations/postgres/00005_no_tx.sql (63%) create mode 100644 internal/testing/integration/testdata/migrations/postgres/00006_complex.sql create mode 100644 internal/testing/integration/testdata/migrations/turso/00001_table.sql create mode 100644 internal/testing/integration/testdata/migrations/turso/00002_insert.sql create mode 100644 internal/testing/integration/testdata/migrations/turso/00003_alter.sql create mode 100644 internal/testing/integration/testdata/migrations/turso/00004_empty.sql create mode 100644 internal/testing/integration/testdata/migrations/turso/00005_no_tx.sql rename {tests/vertica/testdata/migrations => internal/testing/integration/testdata/migrations/vertica}/00001_a.sql (100%) rename {tests/vertica/testdata/migrations => internal/testing/integration/testdata/migrations/vertica}/00002_b.sql (100%) rename {tests/vertica/testdata/migrations => internal/testing/integration/testdata/migrations/vertica}/00003_c.sql (100%) rename {tests/e2e/testdata/ydb/migrations => internal/testing/integration/testdata/migrations/ydb}/00001_a.sql (100%) rename {tests/e2e/testdata/turso/migrations => internal/testing/integration/testdata/migrations/ydb}/00002_b.sql (100%) rename {tests/e2e/testdata/ydb/migrations => internal/testing/integration/testdata/migrations/ydb}/00003_c.sql (99%) rename {tests/e2e/testdata/ydb/migrations => internal/testing/integration/testdata/migrations/ydb}/00004_d.sql (100%) rename {tests/e2e/testdata/mysql/migrations => internal/testing/integration/testdata/migrations/ydb}/00005_e.sql (100%) rename {tests/e2e/testdata/ydb/migrations => internal/testing/integration/testdata/migrations/ydb}/00006_f.sql (100%) rename {tests/e2e/testdata/ydb/migrations => internal/testing/integration/testdata/migrations/ydb}/00007_g.sql (100%) rename {tests/e2e/testdata/ydb/migrations => internal/testing/integration/testdata/migrations/ydb}/00008_h.sql (100%) rename internal/{ => testing}/testdb/clickhouse.go (100%) rename internal/{ => testing}/testdb/container_healthcheck.go (100%) rename internal/{ => testing}/testdb/mariadb.go (100%) rename internal/{ => testing}/testdb/options.go (100%) rename internal/{ => testing}/testdb/postgres.go (98%) rename internal/{ => testing}/testdb/testdb.go (100%) rename internal/{ => testing}/testdb/turso.go (97%) rename internal/{ => testing}/testdb/vertica.go (80%) rename internal/{ => testing}/testdb/ydb.go (95%) delete mode 100644 lock/postgres_test.go delete mode 100644 tests/clickhouse/clickhouse_test.go delete mode 100644 tests/e2e/allow_missing_test.go delete mode 100644 tests/e2e/main_test.go delete mode 100644 tests/e2e/migrations_test.go delete mode 100644 tests/e2e/no_versioning_test.go delete mode 100644 tests/e2e/testdata/mysql/migrations/00001_a.sql delete mode 100644 tests/e2e/testdata/mysql/migrations/00002_b.sql delete mode 100644 tests/e2e/testdata/mysql/migrations/00003_c.sql delete mode 100644 tests/e2e/testdata/mysql/migrations/00004_d.sql delete mode 100644 tests/e2e/testdata/mysql/migrations/00006_f.sql delete mode 100644 tests/e2e/testdata/mysql/migrations/00007_g.sql delete mode 100644 tests/e2e/testdata/mysql/migrations/00008_h.sql delete mode 100644 tests/e2e/testdata/postgres/migrations/00002_b.sql delete mode 100644 tests/e2e/testdata/postgres/migrations/00005_e.sql delete mode 100644 tests/e2e/testdata/postgres/migrations/00006_f.sql delete mode 100644 tests/e2e/testdata/postgres/migrations/00007_g.sql delete mode 100644 tests/e2e/testdata/postgres/migrations/00008_h.sql delete mode 100644 tests/e2e/testdata/postgres/migrations/00009_i.sql delete mode 100644 tests/e2e/testdata/postgres/migrations/00011_k.sql delete mode 100644 tests/e2e/testdata/postgres/seed/00001_a.sql delete mode 100644 tests/e2e/testdata/postgres/seed/00002_b.sql delete mode 100644 tests/e2e/testdata/turso/migrations/00001_a.sql delete mode 100644 tests/e2e/testdata/turso/migrations/00003_c.sql delete mode 100644 tests/e2e/testdata/turso/migrations/00004_d.sql delete mode 100644 tests/e2e/testdata/turso/migrations/00005_e.sql delete mode 100644 tests/e2e/testdata/turso/migrations/00006_f.sql delete mode 100644 tests/e2e/testdata/turso/migrations/00007_g.sql delete mode 100644 tests/e2e/testdata/turso/migrations/00008_h.sql delete mode 100644 tests/e2e/testdata/ydb/migrations/00002_b.sql delete mode 100644 tests/e2e/testdata/ydb/migrations/00005_e.sql delete mode 100644 tests/vertica/vertica_test.go diff --git a/.github/workflows/e2e.yaml b/.github/workflows/integration.yaml similarity index 59% rename from .github/workflows/e2e.yaml rename to .github/workflows/integration.yaml index 3f0060c4f..ad34d2ef2 100644 --- a/.github/workflows/e2e.yaml +++ b/.github/workflows/integration.yaml @@ -1,4 +1,4 @@ -name: Goose end-end tests +name: Goose integration tests on: push: @@ -12,13 +12,9 @@ concurrency: jobs: test: - name: Run e2e tests + name: Run integration tests timeout-minutes: 10 runs-on: ubuntu-latest - strategy: - max-parallel: 2 - matrix: - dialect: ["postgres", "mysql", "vertica", "clickhouse", "ydb", "turso"] steps: - name: Checkout code @@ -27,6 +23,6 @@ jobs: uses: actions/setup-go@v5 with: go-version: "stable" - - name: Run e2e ${{ matrix.dialect }} tests + - name: Run full integration tests run: | - make test-e2e-${{ matrix.dialect }} + make test-integration diff --git a/.github/workflows/lint.yaml b/.github/workflows/lint.yaml index eaa2484e6..b17abd0d4 100644 --- a/.github/workflows/lint.yaml +++ b/.github/workflows/lint.yaml @@ -1,4 +1,5 @@ name: golangci + on: push: branches: @@ -6,7 +7,7 @@ on: - main pull_request: -concurrency: +concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true diff --git a/.gitignore b/.gitignore index 3690cfc63..2a4665740 100644 --- a/.gitignore +++ b/.gitignore @@ -13,3 +13,6 @@ dist/ release_notes.txt + +go.work +go.work.sum diff --git a/Makefile b/Makefile index 0cbc92fca..871b23598 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -GO_TEST_FLAGS ?= -race -count=1 -v -timeout=10m +GO_TEST_FLAGS ?= -race -count=1 -v -timeout=5m # These are the default values for the test database. They can be overridden DB_USER ?= dbuser @@ -42,25 +42,50 @@ test-packages: test-packages-short: go test -test.short $(GO_TEST_FLAGS) $$(go list ./... | grep -v -e /tests -e /bin -e /cmd -e /examples) -test-e2e: test-e2e-postgres test-e2e-mysql test-e2e-clickhouse test-e2e-vertica test-e2e-ydb test-e2e-turso +# +# Integration-related targets +# +add-gowork: + @[ -f go.work ] || go work init + @[ -f go.work.sum ] || go work use -r . -test-e2e-postgres: - go test $(GO_TEST_FLAGS) ./tests/e2e -dialect=postgres +remove-gowork: + rm -rf go.work go.work.sum -test-e2e-mysql: - go test $(GO_TEST_FLAGS) ./tests/e2e -dialect=mysql +gomod: + go mod tidy + cd ./internal/testing/integration && go mod tidy -test-e2e-clickhouse: - go test $(GO_TEST_FLAGS) ./tests/clickhouse -test.short +upgrade-integration-deps: + cd ./internal/testing/integration && go get -u ./... && go mod tidy -test-e2e-vertica: - go test $(GO_TEST_FLAGS) ./tests/vertica +test-postgres-long: add-gowork test-postgres + go test $(GO_TEST_FLAGS) ./internal/testing/integration -run='(TestPostgresProviderLocking|TestPostgresSessionLocker)' -test-e2e-ydb: - go test $(GO_TEST_FLAGS) -parallel=1 ./tests/e2e -dialect=ydb +test-postgres: add-gowork + go test $(GO_TEST_FLAGS) ./internal/testing/integration -run='TestPostgres' -test-e2e-turso: - go test $(GO_TEST_FLAGS) -parallel=1 ./tests/e2e -dialect=turso +test-clickhouse: add-gowork + go test $(GO_TEST_FLAGS) ./internal/testing/integration -run='(TestClickhouse|TestClickhouseRemote)' + +test-mysql: add-gowork + go test $(GO_TEST_FLAGS) ./internal/testing/integration -run='TestMySQL' + +test-turso: add-gowork + go test $(GO_TEST_FLAGS) ./internal/testing/integration -run='TestTurso' + +test-vertica: add-gowork + go test $(GO_TEST_FLAGS) ./internal/testing/integration -run='TestVertica' + +test-ydb: add-gowork + go test $(GO_TEST_FLAGS) ./internal/testing/integration -run='TestYDB' + +test-integration: add-gowork + go test $(GO_TEST_FLAGS) ./internal/testing/integration/... + +# +# Docker-related targets +# docker-cleanup: docker stop -t=0 $$(docker ps --filter="label=goose_test" -aq) diff --git a/database/store_test.go b/database/store_test.go index b4dbf472c..93143f619 100644 --- a/database/store_test.go +++ b/database/store_test.go @@ -7,10 +7,8 @@ import ( "path/filepath" "testing" - "github.com/jackc/pgx/v5/pgconn" "github.com/pressly/goose/v3/database" "github.com/pressly/goose/v3/internal/check" - "github.com/pressly/goose/v3/internal/testdb" "go.uber.org/multierr" "modernc.org/sqlite" ) @@ -32,21 +30,6 @@ func TestDialectStore(t *testing.T) { _, err = database.NewStore("", "foo") check.HasError(t, err) }) - t.Run("postgres", func(t *testing.T) { - if testing.Short() { - t.Skip("skip long-running test") - } - // Test postgres specific behavior. - db, cleanup, err := testdb.NewPostgres() - check.NoError(t, err) - t.Cleanup(cleanup) - testStore(context.Background(), t, database.DialectPostgres, db, func(t *testing.T, err error) { - var pgErr *pgconn.PgError - ok := errors.As(err, &pgErr) - check.Bool(t, ok, true) - check.Equal(t, pgErr.Code, "42P07") // duplicate_table - }) - }) // Test generic behavior. t.Run("sqlite3", func(t *testing.T) { db, err := sql.Open("sqlite", ":memory:") diff --git a/go.mod b/go.mod index f59bb248a..85ea2dbb2 100644 --- a/go.mod +++ b/go.mod @@ -8,7 +8,6 @@ require ( github.com/jackc/pgx/v5 v5.5.5 github.com/mfridman/interpolate v0.0.2 github.com/microsoft/go-mssqldb v1.7.0 - github.com/ory/dockertest/v3 v3.10.0 github.com/sethvargo/go-retry v0.2.4 github.com/tursodatabase/libsql-client-go v0.0.0-20240220085343-4ae0eb9d0898 github.com/vertica/vertica-sql-go v1.3.3 @@ -21,32 +20,20 @@ require ( require ( filippo.io/edwards25519 v1.1.0 // indirect - github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 // indirect github.com/ClickHouse/ch-go v0.58.2 // indirect - github.com/Microsoft/go-winio v0.6.1 // indirect - github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 // indirect github.com/andybalholm/brotli v1.0.6 // indirect github.com/antlr/antlr4/runtime/Go/antlr/v4 v4.0.0-20230512164433-5d1fd1a340c9 // indirect - github.com/cenkalti/backoff/v4 v4.2.1 // indirect - github.com/containerd/continuity v0.4.3 // indirect - github.com/docker/cli v24.0.7+incompatible // indirect - github.com/docker/docker v24.0.7+incompatible // indirect - github.com/docker/go-connections v0.4.0 // indirect - github.com/docker/go-units v0.5.0 // indirect github.com/dustin/go-humanize v1.0.1 // indirect github.com/elastic/go-sysinfo v1.11.2 // indirect github.com/elastic/go-windows v1.0.1 // indirect github.com/go-faster/city v1.0.1 // indirect github.com/go-faster/errors v0.6.1 // indirect - github.com/gogo/protobuf v1.3.2 // indirect github.com/golang-jwt/jwt/v4 v4.5.0 // indirect github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9 // indirect github.com/golang-sql/sqlexp v0.1.0 // indirect github.com/golang/protobuf v1.5.3 // indirect - github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect github.com/google/uuid v1.6.0 // indirect github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect - github.com/imdario/mergo v0.3.16 // indirect github.com/jackc/pgpassfile v1.0.0 // indirect github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a // indirect github.com/jackc/puddle/v2 v2.2.1 // indirect @@ -55,12 +42,7 @@ require ( github.com/klauspost/compress v1.17.2 // indirect github.com/libsql/sqlite-antlr4-parser v0.0.0-20230802215326-5cb5bb604475 // indirect github.com/mattn/go-isatty v0.0.20 // indirect - github.com/mitchellh/mapstructure v1.5.0 // indirect - github.com/moby/term v0.5.0 // indirect github.com/ncruces/go-strftime v0.1.9 // indirect - github.com/opencontainers/go-digest v1.0.0 // indirect - github.com/opencontainers/image-spec v1.1.0-rc5 // indirect - github.com/opencontainers/runc v1.1.12 // indirect github.com/paulmach/orb v0.10.0 // indirect github.com/pierrec/lz4/v4 v4.1.18 // indirect github.com/pkg/errors v0.9.1 // indirect @@ -68,24 +50,17 @@ require ( github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect github.com/segmentio/asm v1.2.0 // indirect github.com/shopspring/decimal v1.3.1 // indirect - github.com/sirupsen/logrus v1.9.3 // indirect - github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect - github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect - github.com/xeipuuv/gojsonschema v1.2.0 // indirect github.com/ydb-platform/ydb-go-genproto v0.0.0-20240126124512-dbb0e1720dbf // indirect go.opentelemetry.io/otel v1.20.0 // indirect go.opentelemetry.io/otel/trace v1.20.0 // indirect golang.org/x/crypto v0.18.0 // indirect golang.org/x/exp v0.0.0-20231108232855-2478ac86f678 // indirect - golang.org/x/mod v0.14.0 // indirect golang.org/x/net v0.20.0 // indirect golang.org/x/sys v0.16.0 // indirect golang.org/x/text v0.14.0 // indirect - golang.org/x/tools v0.17.0 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20231106174013-bbf56f31fb17 // indirect google.golang.org/grpc v1.59.0 // indirect google.golang.org/protobuf v1.33.0 // indirect - gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect howett.net/plist v1.0.0 // indirect modernc.org/gc/v3 v3.0.0-20240107210532-573471604cb6 // indirect diff --git a/go.sum b/go.sum index b630fe1d5..9dbb31a77 100644 --- a/go.sum +++ b/go.sum @@ -7,8 +7,6 @@ github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.5.1 h1:sO0/P7g68FrryJzljemN+ github.com/Azure/azure-sdk-for-go/sdk/internal v1.5.1 h1:6oNBlSdi1QqM1PNW7FPA6xOGA5UNsXnkaYZz9vdPGhA= github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azkeys v1.0.1 h1:MyVTgWR8qd/Jw1Le0NZebGBUCLbtak3bJ3z1OlqZBpw= github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/internal v1.0.0 h1:D3occbWoio4EBLkbkevetNMAVX197GkzbUMtqjGWn80= -github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 h1:L/gRVlceqvL25UVaW/CKtUDjefjrs0SPonmDGUVOYP0= -github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= github.com/AzureAD/microsoft-authentication-library-for-go v1.2.1 h1:DzHpqpoJVaCgOUdVHxE8QB52S6NiVdDQvGlny1qvPqA= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/ClickHouse/ch-go v0.58.2 h1:jSm2szHbT9MCAB1rJ3WuCJqmGLi5UTjlNu+f530UTS0= @@ -16,16 +14,11 @@ github.com/ClickHouse/ch-go v0.58.2/go.mod h1:Ap/0bEmiLa14gYjCiRkYGbXvbe8vwdrfTY github.com/ClickHouse/clickhouse-go/v2 v2.17.1 h1:ZCmAYWpu75IyEi7+Yrs/uaAjiCGY5wfW5kXo64exkX4= github.com/ClickHouse/clickhouse-go/v2 v2.17.1/go.mod h1:rkGTvFDTLqLIm0ma+13xmcCfr/08Gvs7KmFt1tgiWHQ= github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow= -github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM= -github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 h1:TngWCqHvy9oXAN6lEVMRuU21PR1EtLVZJmdB18Gu3Rw= -github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5/go.mod h1:lmUJ/7eu/Q8D7ML55dXQrVaamCz2vxCfdQBasLZfHKk= github.com/andybalholm/brotli v1.0.6 h1:Yf9fFpf49Zrxb9NlQaluyE92/+X7UVHlhMNJN2sxfOI= github.com/andybalholm/brotli v1.0.6/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/antlr/antlr4/runtime/Go/antlr/v4 v4.0.0-20230512164433-5d1fd1a340c9 h1:goHVqTbFX3AIo0tzGr14pgfAW2ZfPChKO21Z9MGf/gk= github.com/antlr/antlr4/runtime/Go/antlr/v4 v4.0.0-20230512164433-5d1fd1a340c9/go.mod h1:pSwJ0fSY5KhvocuWSx4fz3BA8OrA1bQn+K1Eli3BRwM= -github.com/cenkalti/backoff/v4 v4.2.1 h1:y4OZtCnogmCPw98Zjyt5a6+QwPLGkiQsYW5oUqylYbM= -github.com/cenkalti/backoff/v4 v4.2.1/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= @@ -35,21 +28,13 @@ github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XP github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/containerd/continuity v0.4.3 h1:6HVkalIp+2u1ZLH1J/pYX2oBVXlJZvh1X1A7bEZ9Su8= -github.com/containerd/continuity v0.4.3/go.mod h1:F6PTNCKepoxEaXLQp3wDAjygEnImnZ/7o4JzpodfroQ= -github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/docker/cli v24.0.7+incompatible h1:wa/nIwYFW7BVTGa7SWPVyyXU9lgORqUb1xfI36MSkFg= -github.com/docker/cli v24.0.7+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= github.com/docker/distribution v2.8.2+incompatible h1:T3de5rq0dB1j30rp0sA2rER+m322EBzniBPB6ZIzuh8= github.com/docker/docker v24.0.7+incompatible h1:Wo6l37AuwP3JaMnZa226lzVXGA3F9Ig1seQen0cKYlM= -github.com/docker/docker v24.0.7+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ= -github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= -github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= github.com/elastic/go-sysinfo v1.8.1/go.mod h1:JfllUnzoQV/JRYymbH3dO1yggI3mV2oTKSXsDHM+uIM= @@ -127,8 +112,6 @@ github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/pprof v0.0.0-20221118152302-e6195bd50e26 h1:Xim43kblpZXfIBQsbuBVKCudVG457BR2GZFIz3uw3hQ= -github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4= -github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= @@ -137,8 +120,6 @@ github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0U github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k= github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM= -github.com/imdario/mergo v0.3.16 h1:wwQJbIsHYGMUyLSPrEq1CT16AhnhNJQ51+4fdHUnCl4= -github.com/imdario/mergo v0.3.16/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY= github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM= github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg= github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a h1:bbPeKD0xmW/Y25WS6cokEszi5g+S0QxI/d45PkRi7Nk= @@ -168,7 +149,6 @@ github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y= github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= -github.com/lib/pq v0.0.0-20180327071824-d34b9ff171c2 h1:hRGSmZu7j271trc9sneMrpOW7GN5ngLm8YUZIPzf394= github.com/libsql/sqlite-antlr4-parser v0.0.0-20230802215326-5cb5bb604475 h1:6PfEMwfInASh9hkN83aR0j4W/eKaAZt/AURtXAXlas0= github.com/libsql/sqlite-antlr4-parser v0.0.0-20230802215326-5cb5bb604475/go.mod h1:20nXSmcf0nAscrzqsXeC2/tA3KkV2eCiJqYuyAgl+ss= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= @@ -179,10 +159,6 @@ github.com/mfridman/interpolate v0.0.2 h1:pnuTK7MQIxxFz1Gr+rjSIx9u7qVjf5VOoM/u6B github.com/mfridman/interpolate v0.0.2/go.mod h1:p+7uk6oE07mpE/Ik1b8EckO0O4ZXiGAfshKBWLUM9Xg= github.com/microsoft/go-mssqldb v1.7.0 h1:sgMPW0HA6Ihd37Yx0MzHyKD726C2kY/8KJsQtXHNaAs= github.com/microsoft/go-mssqldb v1.7.0/go.mod h1:kOvZKUdrhhFQmxLZqbwUV0rHkNkZpthMITIb2Ko1IoA= -github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= -github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= -github.com/moby/term v0.5.0 h1:xt8Q1nalod/v7BqbG21f8mQPqH+xAaC9C3N3wfWbVP0= -github.com/moby/term v0.5.0/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742 h1:Esafd1046DLDQ0W1YjYsBW+p8U2u7vzgW2SQVmlNazg= @@ -191,13 +167,7 @@ github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJ github.com/ncruces/go-strftime v0.1.9 h1:bY0MQC28UADQmHmaF5dgpLmImcShSi2kHU9XLdhx/f4= github.com/ncruces/go-strftime v0.1.9/go.mod h1:Fwc5htZGVVkseilnfgOVb9mKy6w1naJmn9CehxcKcls= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= -github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= github.com/opencontainers/image-spec v1.1.0-rc5 h1:Ygwkfw9bpDvs+c9E34SdgGOj41dX/cbdlwvlWt0pnFI= -github.com/opencontainers/image-spec v1.1.0-rc5/go.mod h1:X4pATf0uXsnn3g5aiGIsVnJBR4mxhKzfwmvK/B2NTm8= -github.com/opencontainers/runc v1.1.12 h1:BOIssBaW1La0/qbNZHXOOa71dZfZEQOzW7dqQf3phss= -github.com/opencontainers/runc v1.1.12/go.mod h1:S+lQwSfncpBha7XTy/5lBwWgm5+y5Ma/O44Ekby9FK8= -github.com/ory/dockertest/v3 v3.10.0 h1:4K3z2VMe8Woe++invjaTB7VRyQXQy5UY+loujO4aNE4= -github.com/ory/dockertest/v3 v3.10.0/go.mod h1:nr57ZbRWMqfsdGdFNLHz5jjNdDb7VVFnzAeW1n5N1Lg= github.com/paulmach/orb v0.10.0 h1:guVYVqzxHE/CQ1KpfGO077TR0ATHSNjp4s6XGLn3W9s= github.com/paulmach/orb v0.10.0/go.mod h1:5mULz1xQfs3bmQm63QEJA6lNGujuRafwA5S/EnuLaLU= github.com/paulmach/protoscan v0.2.1/go.mod h1:SpcSwydNLrxUGSDvXvO0P7g7AuhJ7lcKfDlhJCDw2gY= @@ -223,8 +193,6 @@ github.com/sethvargo/go-retry v0.2.4 h1:T+jHEQy/zKJf5s95UkguisicE0zuF9y7+/vgz08O github.com/sethvargo/go-retry v0.2.4/go.mod h1:1afjQuvh7s4gflMObvjLPaWgluLLyhA1wmVZ6KLpICw= github.com/shopspring/decimal v1.3.1 h1:2Usl1nmF/WZucqkFZhnfFYxxxu8LG21F6nPQBE5gKV8= github.com/shopspring/decimal v1.3.1/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= -github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= -github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= @@ -244,13 +212,6 @@ github.com/vertica/vertica-sql-go v1.3.3/go.mod h1:jnn2GFuv+O2Jcjktb7zyc4Utlbu9Y github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI= github.com/xdg-go/scram v1.1.1/go.mod h1:RaEWvsqvNKKvBPvcKeFjrG2cJqOkHTiyTpzz23ni57g= github.com/xdg-go/stringprep v1.0.3/go.mod h1:W3f5j4i+9rC0kuIEJL0ky1VpHXQU3ocBgklLGvcBnW8= -github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= -github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb h1:zGWFAtiMcyryUHoUjUJX0/lt1H2+i2Ka2n+D3DImSNo= -github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= -github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0= -github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= -github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74= -github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= github.com/ydb-platform/ydb-go-genproto v0.0.0-20240126124512-dbb0e1720dbf h1:ckwNHVo4bv2tqNkgx3W3HANh3ta1j6TR5qw08J1A7Tw= github.com/ydb-platform/ydb-go-genproto v0.0.0-20240126124512-dbb0e1720dbf/go.mod h1:Er+FePu1dNUieD+XTMDduGpQuCPssK5Q4BjF+IIXJ3I= github.com/ydb-platform/ydb-go-sdk/v3 v3.55.1 h1:Ebo6J5AMXgJ3A438ECYotA0aK7ETqjQx9WoZvVxzKBE= @@ -284,7 +245,6 @@ golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHl golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0= -golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -320,9 +280,7 @@ golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU= golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= @@ -344,7 +302,6 @@ golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtn golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.17.0 h1:FvmRgNOcs3kOa+T20R1uhfP9F6HgG2mfxDv1vrx1Htc= -golang.org/x/tools v0.17.0/go.mod h1:xsh6VxdV005rRVaS6SSAf9oiAqljS7UZUacMZ8Bnsps= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -390,11 +347,9 @@ gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= -gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gotest.tools/v3 v3.4.0 h1:ZazjZUfuVeZGLAmlKKuyv3IKP5orXcwtOwDQH6YVr6o= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= howett.net/plist v0.0.0-20181124034731-591f970eefbb/go.mod h1:vMygbs4qMhSZSc4lCUl2OEE+rDiIIJAIdR4m7MiMcm0= diff --git a/internal/testing/go.mod b/internal/testing/go.mod new file mode 100644 index 000000000..052d45497 --- /dev/null +++ b/internal/testing/go.mod @@ -0,0 +1,87 @@ +module github.com/pressly/goose/v3/internal/testing + +go 1.22.1 + +require ( + github.com/ClickHouse/clickhouse-go/v2 v2.22.0 + github.com/go-sql-driver/mysql v1.8.0 + github.com/jackc/pgx/v5 v5.5.5 + github.com/ory/dockertest/v3 v3.10.0 + github.com/pressly/goose/v3 v3.19.2 + github.com/sethvargo/go-retry v0.2.4 + github.com/stretchr/testify v1.9.0 + github.com/tursodatabase/libsql-client-go v0.0.0-20240220085343-4ae0eb9d0898 + github.com/vertica/vertica-sql-go v1.3.3 + github.com/ydb-platform/ydb-go-sdk/v3 v3.57.4 + golang.org/x/sync v0.6.0 +) + +require ( + dario.cat/mergo v1.0.0 // indirect + filippo.io/edwards25519 v1.1.0 // indirect + github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 // indirect + github.com/ClickHouse/ch-go v0.61.5 // indirect + github.com/Microsoft/go-winio v0.6.1 // indirect + github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 // indirect + github.com/andybalholm/brotli v1.1.0 // indirect + github.com/antlr/antlr4/runtime/Go/antlr/v4 v4.0.0-20230512164433-5d1fd1a340c9 // indirect + github.com/cenkalti/backoff/v4 v4.2.1 // indirect + github.com/containerd/continuity v0.4.3 // indirect + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/docker/cli v25.0.4+incompatible // indirect + github.com/docker/docker v25.0.4+incompatible // indirect + github.com/docker/go-connections v0.5.0 // indirect + github.com/docker/go-units v0.5.0 // indirect + github.com/elastic/go-sysinfo v1.13.1 // indirect + github.com/elastic/go-windows v1.0.1 // indirect + github.com/go-faster/city v1.0.1 // indirect + github.com/go-faster/errors v0.7.1 // indirect + github.com/gogo/protobuf v1.3.2 // indirect + github.com/golang-jwt/jwt/v4 v4.5.0 // indirect + github.com/golang/protobuf v1.5.4 // indirect + github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect + github.com/google/uuid v1.6.0 // indirect + github.com/jackc/pgpassfile v1.0.0 // indirect + github.com/jackc/pgservicefile v0.0.0-20231201235250-de7065d80cb9 // indirect + github.com/jackc/puddle/v2 v2.2.1 // indirect + github.com/joeshaw/multierror v0.0.0-20140124173710-69b34d4ec901 // indirect + github.com/jonboulle/clockwork v0.4.0 // indirect + github.com/klauspost/compress v1.17.7 // indirect + github.com/kr/text v0.2.0 // indirect + github.com/libsql/sqlite-antlr4-parser v0.0.0-20230802215326-5cb5bb604475 // indirect + github.com/mfridman/interpolate v0.0.2 // indirect + github.com/mitchellh/mapstructure v1.5.0 // indirect + github.com/moby/term v0.5.0 // indirect + github.com/opencontainers/go-digest v1.0.0 // indirect + github.com/opencontainers/image-spec v1.1.0 // indirect + github.com/opencontainers/runc v1.1.12 // indirect + github.com/paulmach/orb v0.11.1 // indirect + github.com/pierrec/lz4/v4 v4.1.21 // indirect + github.com/pkg/errors v0.9.1 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/prometheus/procfs v0.13.0 // indirect + github.com/segmentio/asm v1.2.0 // indirect + github.com/shopspring/decimal v1.3.1 // indirect + github.com/sirupsen/logrus v1.9.3 // indirect + github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect + github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect + github.com/xeipuuv/gojsonschema v1.2.0 // indirect + github.com/ydb-platform/ydb-go-genproto v0.0.0-20240313174312-cec53bca0668 // indirect + go.opentelemetry.io/otel v1.24.0 // indirect + go.opentelemetry.io/otel/trace v1.24.0 // indirect + go.uber.org/multierr v1.11.0 // indirect + golang.org/x/crypto v0.21.0 // indirect + golang.org/x/exp v0.0.0-20240222234643-814bf88cf225 // indirect + golang.org/x/mod v0.16.0 // indirect + golang.org/x/net v0.22.0 // indirect + golang.org/x/sys v0.18.0 // indirect + golang.org/x/text v0.14.0 // indirect + golang.org/x/tools v0.19.0 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240311173647-c811ad7063a7 // indirect + google.golang.org/grpc v1.62.1 // indirect + google.golang.org/protobuf v1.33.0 // indirect + gopkg.in/yaml.v2 v2.4.0 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect + howett.net/plist v1.0.1 // indirect + nhooyr.io/websocket v1.8.10 // indirect +) diff --git a/internal/testing/go.sum b/internal/testing/go.sum new file mode 100644 index 000000000..d228f05b9 --- /dev/null +++ b/internal/testing/go.sum @@ -0,0 +1,384 @@ +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk= +dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= +filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA= +filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= +github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 h1:L/gRVlceqvL25UVaW/CKtUDjefjrs0SPonmDGUVOYP0= +github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/ClickHouse/ch-go v0.61.5 h1:zwR8QbYI0tsMiEcze/uIMK+Tz1D3XZXLdNrlaOpeEI4= +github.com/ClickHouse/ch-go v0.61.5/go.mod h1:s1LJW/F/LcFs5HJnuogFMta50kKDO0lf9zzfrbl0RQg= +github.com/ClickHouse/clickhouse-go/v2 v2.22.0 h1:LAdk0qT125PpSPnYepFQs5X5z1EwpAtIX10SUELPgi0= +github.com/ClickHouse/clickhouse-go/v2 v2.22.0/go.mod h1:tBhdF3f3RdP7sS59+oBAtTyhWpy0024ZxDMhgxra0QE= +github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow= +github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM= +github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 h1:TngWCqHvy9oXAN6lEVMRuU21PR1EtLVZJmdB18Gu3Rw= +github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5/go.mod h1:lmUJ/7eu/Q8D7ML55dXQrVaamCz2vxCfdQBasLZfHKk= +github.com/andybalholm/brotli v1.1.0 h1:eLKJA0d02Lf0mVpIDgYnqXcUn0GqVmEFny3VuID1U3M= +github.com/andybalholm/brotli v1.1.0/go.mod h1:sms7XGricyQI9K10gOSf56VKKWS4oLer58Q+mhRPtnY= +github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= +github.com/antlr/antlr4/runtime/Go/antlr/v4 v4.0.0-20230512164433-5d1fd1a340c9 h1:goHVqTbFX3AIo0tzGr14pgfAW2ZfPChKO21Z9MGf/gk= +github.com/antlr/antlr4/runtime/Go/antlr/v4 v4.0.0-20230512164433-5d1fd1a340c9/go.mod h1:pSwJ0fSY5KhvocuWSx4fz3BA8OrA1bQn+K1Eli3BRwM= +github.com/cenkalti/backoff/v4 v4.2.1 h1:y4OZtCnogmCPw98Zjyt5a6+QwPLGkiQsYW5oUqylYbM= +github.com/cenkalti/backoff/v4 v4.2.1/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= +github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= +github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= +github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI= +github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/containerd/continuity v0.4.3 h1:6HVkalIp+2u1ZLH1J/pYX2oBVXlJZvh1X1A7bEZ9Su8= +github.com/containerd/continuity v0.4.3/go.mod h1:F6PTNCKepoxEaXLQp3wDAjygEnImnZ/7o4JzpodfroQ= +github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY= +github.com/creack/pty v1.1.18/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/distribution/reference v0.5.0 h1:/FUIFXtfc/x2gpa5/VGfiGLuOIdYa1t65IKK2OFGvA0= +github.com/distribution/reference v0.5.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E= +github.com/docker/cli v25.0.4+incompatible h1:DatRkJ+nrFoYL2HZUzjM5Z5sAmcA5XGp+AW0oEw2+cA= +github.com/docker/cli v25.0.4+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= +github.com/docker/docker v25.0.4+incompatible h1:XITZTrq+52tZyZxUOtFIahUf3aH367FLxJzt9vZeAF8= +github.com/docker/docker v25.0.4+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/go-connections v0.5.0 h1:USnMq7hx7gwdVZq1L49hLXaFtUdTADjXGp+uj1Br63c= +github.com/docker/go-connections v0.5.0/go.mod h1:ov60Kzw0kKElRwhNs9UlUHAE/F9Fe6GLaXnqyDdmEXc= +github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= +github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= +github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= +github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= +github.com/elastic/go-sysinfo v1.8.1/go.mod h1:JfllUnzoQV/JRYymbH3dO1yggI3mV2oTKSXsDHM+uIM= +github.com/elastic/go-sysinfo v1.13.1 h1:U5Jlx6c/rLkR72O8wXXXo1abnGlWGJU/wbzNJ2AfQa4= +github.com/elastic/go-sysinfo v1.13.1/go.mod h1:GKqR8bbMK/1ITnez9NIsIfXQr25aLhRJa7AfT8HpBFQ= +github.com/elastic/go-windows v1.0.0/go.mod h1:TsU0Nrp7/y3+VwE82FoZF8gC/XFg/Elz6CcloAxnPgU= +github.com/elastic/go-windows v1.0.1 h1:AlYZOldA+UJ0/2nBuqWdo90GFCgG9xuyw9SYzGUtJm0= +github.com/elastic/go-windows v1.0.1/go.mod h1:FoVvqWSun28vaDQPbj2Elfc0JahhPB7WQEGa3c814Ss= +github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= +github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= +github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE= +github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/felixge/httpsnoop v1.0.3 h1:s/nj+GCswXYzN5v2DpNMuMQYe+0DDwt5WVCU6CWBdXk= +github.com/felixge/httpsnoop v1.0.3/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= +github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/go-faster/city v1.0.1 h1:4WAxSZ3V2Ws4QRDrscLEDcibJY8uf41H6AhXDrNDcGw= +github.com/go-faster/city v1.0.1/go.mod h1:jKcUJId49qdW3L1qKHH/3wPeUstCVpVSXTM6vO3VcTw= +github.com/go-faster/errors v0.7.1 h1:MkJTnDoEdi9pDabt1dpWf7AA8/BaSYZqibYyhZ20AYg= +github.com/go-faster/errors v0.7.1/go.mod h1:5ySTjWFiphBs07IKuiL69nxdfd5+fzh1u7FPGZP2quo= +github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ= +github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= +github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= +github.com/go-sql-driver/mysql v1.8.0 h1:UtktXaU2Nb64z/pLiGIxY4431SJ4/dR5cjMmlVHgnT4= +github.com/go-sql-driver/mysql v1.8.0/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg= +github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= +github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= +github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg= +github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= +github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= +github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= +github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= +github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4= +github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ= +github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= +github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k= +github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM= +github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM= +github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg= +github.com/jackc/pgservicefile v0.0.0-20231201235250-de7065d80cb9 h1:L0QtFUgDarD7Fpv9jeVMgy/+Ec0mtnmYuImjTz6dtDA= +github.com/jackc/pgservicefile v0.0.0-20231201235250-de7065d80cb9/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM= +github.com/jackc/pgx/v5 v5.5.5 h1:amBjrZVmksIdNjxGW/IiIMzxMKZFelXbUoPNb+8sjQw= +github.com/jackc/pgx/v5 v5.5.5/go.mod h1:ez9gk+OAat140fv9ErkZDYFWmXLfV+++K0uAOiwgm1A= +github.com/jackc/puddle/v2 v2.2.1 h1:RhxXJtFG022u4ibrCSMSiu5aOq1i77R3OHKNJj77OAk= +github.com/jackc/puddle/v2 v2.2.1/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4= +github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= +github.com/joeshaw/multierror v0.0.0-20140124173710-69b34d4ec901 h1:rp+c0RAYOWj8l6qbCUTSiRLG/iKnW3K3/QfPPuSsBt4= +github.com/joeshaw/multierror v0.0.0-20140124173710-69b34d4ec901/go.mod h1:Z86h9688Y0wesXCyonoVr47MasHilkuLMqGhRZ4Hpak= +github.com/jonboulle/clockwork v0.4.0 h1:p4Cf1aMWXnXAUh8lVfewRBx1zaTSYKrKMF2g3ST4RZ4= +github.com/jonboulle/clockwork v0.4.0/go.mod h1:xgRqUGwRcjKCO1vbZUEtSLrqKoPSsUpK7fnezOII0kc= +github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= +github.com/klauspost/compress v1.17.7 h1:ehO88t2UGzQK66LMdE8tibEd1ErmzZjNEqWkjLAKQQg= +github.com/klauspost/compress v1.17.7/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/lib/pq v0.0.0-20180327071824-d34b9ff171c2 h1:hRGSmZu7j271trc9sneMrpOW7GN5ngLm8YUZIPzf394= +github.com/lib/pq v0.0.0-20180327071824-d34b9ff171c2/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= +github.com/libsql/sqlite-antlr4-parser v0.0.0-20230802215326-5cb5bb604475 h1:6PfEMwfInASh9hkN83aR0j4W/eKaAZt/AURtXAXlas0= +github.com/libsql/sqlite-antlr4-parser v0.0.0-20230802215326-5cb5bb604475/go.mod h1:20nXSmcf0nAscrzqsXeC2/tA3KkV2eCiJqYuyAgl+ss= +github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/mfridman/interpolate v0.0.2 h1:pnuTK7MQIxxFz1Gr+rjSIx9u7qVjf5VOoM/u6BbAxPY= +github.com/mfridman/interpolate v0.0.2/go.mod h1:p+7uk6oE07mpE/Ik1b8EckO0O4ZXiGAfshKBWLUM9Xg= +github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= +github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/moby/term v0.5.0 h1:xt8Q1nalod/v7BqbG21f8mQPqH+xAaC9C3N3wfWbVP0= +github.com/moby/term v0.5.0/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y= +github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc= +github.com/ncruces/go-strftime v0.1.9 h1:bY0MQC28UADQmHmaF5dgpLmImcShSi2kHU9XLdhx/f4= +github.com/ncruces/go-strftime v0.1.9/go.mod h1:Fwc5htZGVVkseilnfgOVb9mKy6w1naJmn9CehxcKcls= +github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= +github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= +github.com/opencontainers/image-spec v1.1.0 h1:8SG7/vwALn54lVB/0yZ/MMwhFrPYtpEHQb2IpWsCzug= +github.com/opencontainers/image-spec v1.1.0/go.mod h1:W4s4sFTMaBeK1BQLXbG4AdM2szdn85PY75RI83NrTrM= +github.com/opencontainers/runc v1.1.12 h1:BOIssBaW1La0/qbNZHXOOa71dZfZEQOzW7dqQf3phss= +github.com/opencontainers/runc v1.1.12/go.mod h1:S+lQwSfncpBha7XTy/5lBwWgm5+y5Ma/O44Ekby9FK8= +github.com/ory/dockertest/v3 v3.10.0 h1:4K3z2VMe8Woe++invjaTB7VRyQXQy5UY+loujO4aNE4= +github.com/ory/dockertest/v3 v3.10.0/go.mod h1:nr57ZbRWMqfsdGdFNLHz5jjNdDb7VVFnzAeW1n5N1Lg= +github.com/paulmach/orb v0.11.1 h1:3koVegMC4X/WeiXYz9iswopaTwMem53NzTJuTF20JzU= +github.com/paulmach/orb v0.11.1/go.mod h1:5mULz1xQfs3bmQm63QEJA6lNGujuRafwA5S/EnuLaLU= +github.com/paulmach/protoscan v0.2.1/go.mod h1:SpcSwydNLrxUGSDvXvO0P7g7AuhJ7lcKfDlhJCDw2gY= +github.com/pierrec/lz4/v4 v4.1.21 h1:yOVMLb6qSIDP67pl/5F7RepeKYu/VmTyEXvuMI5d9mQ= +github.com/pierrec/lz4/v4 v4.1.21/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/pressly/goose/v3 v3.19.2 h1:z1yuD41jS4iaqLkyjkzGkKBz4rgyz/BYtCyMMGHlgzQ= +github.com/pressly/goose/v3 v3.19.2/go.mod h1:BHkf3LzSBmO8E5FTMPupUYIpMTIh/ZuQVy+YTfhZLD4= +github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/procfs v0.0.0-20190425082905-87a4384529e0/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= +github.com/prometheus/procfs v0.13.0 h1:GqzLlQyfsPbaEHaQkO7tbDlriv/4o5Hudv6OXHGKX7o= +github.com/prometheus/procfs v0.13.0/go.mod h1:cd4PFCR54QLnGKPaKGA6l+cfuNXtht43ZKY6tow0Y1g= +github.com/rekby/fixenv v0.6.1 h1:jUFiSPpajT4WY2cYuc++7Y1zWrnCxnovGCIX72PZniM= +github.com/rekby/fixenv v0.6.1/go.mod h1:/b5LRc06BYJtslRtHKxsPWFT/ySpHV+rWvzTg+XWk4c= +github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE= +github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= +github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= +github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= +github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= +github.com/segmentio/asm v1.2.0 h1:9BQrFxC+YOHJlTlHGkTrFWf59nbL3XnCoFLTwDCI7ys= +github.com/segmentio/asm v1.2.0/go.mod h1:BqMnlJP91P8d+4ibuonYZw9mfnzI9HfxselHZr5aAcs= +github.com/sethvargo/go-retry v0.2.4 h1:T+jHEQy/zKJf5s95UkguisicE0zuF9y7+/vgz08Ocec= +github.com/sethvargo/go-retry v0.2.4/go.mod h1:1afjQuvh7s4gflMObvjLPaWgluLLyhA1wmVZ6KLpICw= +github.com/shopspring/decimal v1.3.1 h1:2Usl1nmF/WZucqkFZhnfFYxxxu8LG21F6nPQBE5gKV8= +github.com/shopspring/decimal v1.3.1/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= +github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= +github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= +github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= +github.com/tursodatabase/libsql-client-go v0.0.0-20240220085343-4ae0eb9d0898 h1:1MvEhzI5pvP27e9Dzz861mxk9WzXZLSJwzOU67cKTbU= +github.com/tursodatabase/libsql-client-go v0.0.0-20240220085343-4ae0eb9d0898/go.mod h1:9bKuHS7eZh/0mJndbUOrCx8Ej3PlsRDszj4L7oVYMPQ= +github.com/vertica/vertica-sql-go v1.3.3 h1:fL+FKEAEy5ONmsvya2WH5T8bhkvY27y/Ik3ReR2T+Qw= +github.com/vertica/vertica-sql-go v1.3.3/go.mod h1:jnn2GFuv+O2Jcjktb7zyc4Utlbu9YVqpHH/lx63+1M4= +github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI= +github.com/xdg-go/scram v1.1.1/go.mod h1:RaEWvsqvNKKvBPvcKeFjrG2cJqOkHTiyTpzz23ni57g= +github.com/xdg-go/stringprep v1.0.3/go.mod h1:W3f5j4i+9rC0kuIEJL0ky1VpHXQU3ocBgklLGvcBnW8= +github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= +github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb h1:zGWFAtiMcyryUHoUjUJX0/lt1H2+i2Ka2n+D3DImSNo= +github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= +github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0= +github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= +github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74= +github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= +github.com/ydb-platform/ydb-go-genproto v0.0.0-20240313174312-cec53bca0668 h1:R7jnhzn/38Rerzeb4i4+zprtJZEUw0i+p0R0+l4dtnc= +github.com/ydb-platform/ydb-go-genproto v0.0.0-20240313174312-cec53bca0668/go.mod h1:Er+FePu1dNUieD+XTMDduGpQuCPssK5Q4BjF+IIXJ3I= +github.com/ydb-platform/ydb-go-sdk/v3 v3.57.4 h1:Tu9kNhWLMnbkxThc+sRJvSXIauP4K0hhL6C5m4hoaLs= +github.com/ydb-platform/ydb-go-sdk/v3 v3.57.4/go.mod h1:7nt3l5aNZvbsstGGnlJZ8n7lPcKPiIUcPglADPwn0n4= +github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA= +github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +go.mongodb.org/mongo-driver v1.11.4/go.mod h1:PTSz5yu21bkT/wXpkS7WR5f0ddqw5quethTUn9WM+2g= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.45.0 h1:x8Z78aZx8cOF0+Kkazoc7lwUNMGy0LrzEMxTm4BbTxg= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.45.0/go.mod h1:62CPTSry9QZtOaSsE3tOzhx6LzDhHnXJ6xHeMNNiM6Q= +go.opentelemetry.io/otel v1.24.0 h1:0LAOdjNmQeSTzGBzduGe/rU4tZhMwL5rWgtp9Ku5Jfo= +go.opentelemetry.io/otel v1.24.0/go.mod h1:W7b9Ozg4nkF5tWI5zsXkaKKDjdVjpD4oAt9Qi/MArHo= +go.opentelemetry.io/otel/metric v1.24.0 h1:6EhoGWWK28x1fbpA4tYTOWBkPefTDQnb8WSGXlc88kI= +go.opentelemetry.io/otel/metric v1.24.0/go.mod h1:VYhLe1rFfxuTXLgj4CBiyz+9WYBA8pNGJgDcSFRKBco= +go.opentelemetry.io/otel/trace v1.24.0 h1:CsKnnL4dUAr/0llH9FKuc698G04IrpWV0MQA/Y1YELI= +go.opentelemetry.io/otel/trace v1.24.0/go.mod h1:HPc3Xr/cOApsBI154IU0OI0HJexz+aw5uPdbs3UCjNU= +go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= +go.uber.org/mock v0.4.0 h1:VcM4ZOtdbR4f6VXfiOpwpVJDL6lCReaZ6mw31wqh7KU= +go.uber.org/mock v0.4.0/go.mod h1:a6FSlNadKUHUa9IP5Vyt1zh4fC7uAwxMutEAscFbkZc= +go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= +go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA= +golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20240222234643-814bf88cf225 h1:LfspQV/FYTatPTr/3HzIcmiUFH7PGP+OQ6mgDYo3yuQ= +golang.org/x/exp v0.0.0-20240222234643-814bf88cf225/go.mod h1:CxmFvTBINI24O/j8iY7H1xHzx2i4OsyguNBmN/uPtqc= +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.16.0 h1:QX4fJ0Rr5cPQCF7O9lh9Se4pmwfwskqZfq5moyldzic= +golang.org/x/mod v0.16.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.22.0 h1:9sGLhx7iRIHEiX0oAJ3MRZMUCElJgy7Br1nO+AMN3Tc= +golang.org/x/net v0.22.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ= +golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4= +golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= +golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.19.0 h1:tfGCXNR1OsFG+sVdLAitlpjAvD/I6dHDKnYrpEZUHkw= +golang.org/x/tools v0.19.0/go.mod h1:qoJWxmGSIBmAeriMx19ogtrEPrGtDbPK634QFIcLAhc= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240311173647-c811ad7063a7 h1:8EeVk1VKMD+GD/neyEHGmz7pFblqPjHoi+PGQIlLx2s= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240311173647-c811ad7063a7/go.mod h1:WtryC6hu0hhx87FDGxWCDptyssuo68sk10vYjF+T9fY= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= +google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= +google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.47.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= +google.golang.org/grpc v1.62.1 h1:B4n+nfKzOICUXMgyrNd19h/I9oH0L1pizfk1d4zSgTk= +google.golang.org/grpc v1.62.1/go.mod h1:IWTG0VlJLCh1SkC58F7np9ka9mx/WNkjl4PGJaiq+QE= +google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= +google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= +google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI= +google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= +gopkg.in/yaml.v1 v1.0.0-20140924161607-9f9df34309c0/go.mod h1:WDnlLJ4WF5VGsH/HVa3CI79GS0ol3YnhVnKP89i0kNg= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gotest.tools/v3 v3.4.0 h1:ZazjZUfuVeZGLAmlKKuyv3IKP5orXcwtOwDQH6YVr6o= +gotest.tools/v3 v3.4.0/go.mod h1:CtbdzLSsqVhDgMtKsx03ird5YTGB3ar27v0u/yKBW5g= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +howett.net/plist v0.0.0-20181124034731-591f970eefbb/go.mod h1:vMygbs4qMhSZSc4lCUl2OEE+rDiIIJAIdR4m7MiMcm0= +howett.net/plist v1.0.1 h1:37GdZ8tP09Q35o9ych3ehygcsL+HqKSwzctveSlarvM= +howett.net/plist v1.0.1/go.mod h1:lqaXoTrLY4hg8tnEzNru53gicrbv7rrk+2xJA/7hw9g= +modernc.org/gc/v3 v3.0.0-20240107210532-573471604cb6 h1:5D53IMaUuA5InSeMu9eJtlQXS2NxAhyWQvkKEgXZhHI= +modernc.org/gc/v3 v3.0.0-20240107210532-573471604cb6/go.mod h1:Qz0X07sNOR1jWYCrJMEnbW/X55x206Q7Vt4mz6/wHp4= +modernc.org/libc v1.41.0 h1:g9YAc6BkKlgORsUWj+JwqoB1wU3o4DE3bM3yvA3k+Gk= +modernc.org/libc v1.41.0/go.mod h1:w0eszPsiXoOnoMJgrXjglgLuDy/bt5RR4y3QzUUeodY= +modernc.org/mathutil v1.6.0 h1:fRe9+AmYlaej+64JsEEhoWuAYBkOtQiMEU7n/XgfYi4= +modernc.org/mathutil v1.6.0/go.mod h1:Ui5Q9q1TR2gFm0AQRqQUaBWFLAhQpCwNcuhBOSedWPo= +modernc.org/memory v1.7.2 h1:Klh90S215mmH8c9gO98QxQFsY+W451E8AnzjoE2ee1E= +modernc.org/memory v1.7.2/go.mod h1:NO4NVCQy0N7ln+T9ngWqOQfi7ley4vpwvARR+Hjw95E= +modernc.org/sqlite v1.29.5 h1:8l/SQKAjDtZFo9lkJLdk8g9JEOeYRG4/ghStDCCTiTE= +modernc.org/sqlite v1.29.5/go.mod h1:S02dvcmm7TnTRvGhv8IGYyLnIt7AS2KPaB1F/71p75U= +modernc.org/strutil v1.2.0 h1:agBi9dp1I+eOnxXeiZawM8F4LawKv4NzGWSaLfyeNZA= +modernc.org/strutil v1.2.0/go.mod h1:/mdcBmfOibveCTBxUl5B5l6W+TTH1FXPLHZE6bTosX0= +modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y= +modernc.org/token v1.1.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM= +nhooyr.io/websocket v1.8.10 h1:mv4p+MnGrLDcPlBoWsvPP7XCzTYMXP9F9eIGoKbgx7Q= +nhooyr.io/websocket v1.8.10/go.mod h1:rN9OFWIUwuxg4fR5tELlYC04bXYowCP9GX47ivo2l+c= diff --git a/internal/testing/integration/README.md b/internal/testing/integration/README.md new file mode 100644 index 000000000..34c0aa044 --- /dev/null +++ b/internal/testing/integration/README.md @@ -0,0 +1,58 @@ +# Integration tests + +This directory contains integration tests for the [pressly/goose/v3][goose_module] Go module. An +integration test is a test that runs against a real database (docker container) and exercises the +same driver used by the CLI. + +## Why is this a separate module? + +There are separate `go.mod` and `go.sum` files in this directory to allow for the use of different +dependencies. We leverage [multi-module workspaces](https://go.dev/doc/tutorial/workspaces) to glue +things together. + +Namely, we want to avoid dependencies on docker, sql drivers, and other dependencies **that are** +not necessary for the core functionality of the goose library. + +## Overview + +There are separate migration files for each database that we support, see the [migrations +directory][migrations_dir]. Databases typically have different SQL syntax and features, so the +migration files are different. + +A good set of migrations should be representative of the types of migrations users will write +typically write. This should include: + +- Creating and dropping tables +- Adding and removing columns +- Creating and dropping indexes +- Inserting and deleting data +- Complex SQL statements that require special handling with `StatementBegin` and `StatementEnd` + annotations +- Statements that must run outside a transaction, annotated with `-- +goose NO TRANSACTION` + +There is a common test function that applies migrations up, down and then up again. + +The gold standard is the PostgreSQL migration files. We try to make other migration files as close +to the PostgreSQL files as possible, but this is not always possible or desirable. + +Lastly, some tests will assert for database state after migrations are applied. + +To add a new `.sql` file, you can use the following command: + +``` +goose -s -dir testdata/migrations/ create sql +``` + +- Update the database name (e.g. `postgres`) +- Update the filename name (e.g. `b`) as needed + +## Limitation + +Note, the integration tests are not exhaustive. + +They are meantto ensure that the goose library works with the various databases that we support and +the chosen drivers. We do not test every possible combination of operations, nor do we test every +possible edge case. We rely on the unit tests in the goose package to cover library-specific logic. + +[goose_module]: https://pkg.go.dev/github.com/pressly/goose/v3 +[migrations_dir]: ./testdata/migrations diff --git a/internal/testing/integration/database_test.go b/internal/testing/integration/database_test.go new file mode 100644 index 000000000..ebaba6067 --- /dev/null +++ b/internal/testing/integration/database_test.go @@ -0,0 +1,195 @@ +package integration + +import ( + "testing" + "time" + + "github.com/pressly/goose/v3/database" + "github.com/pressly/goose/v3/internal/testing/testdb" + "github.com/stretchr/testify/require" +) + +func TestPostgres(t *testing.T) { + t.Parallel() + + db, cleanup, err := testdb.NewPostgres() + require.NoError(t, err) + t.Cleanup(cleanup) + require.NoError(t, db.Ping()) + + testDatabase(t, database.DialectPostgres, db, "testdata/migrations/postgres") +} + +func TestClickhouse(t *testing.T) { + t.Parallel() + + db, cleanup, err := testdb.NewClickHouse() + require.NoError(t, err) + t.Cleanup(cleanup) + require.NoError(t, db.Ping()) + + testDatabase(t, database.DialectClickHouse, db, "testdata/migrations/clickhouse") + + type result struct { + customerID string `db:"customer_id"` + timestamp time.Time `db:"time_stamp"` + clickEventType string `db:"click_event_type"` + countryCode string `db:"country_code"` + sourceID int64 `db:"source_id"` + } + rows, err := db.Query(`SELECT * FROM clickstream ORDER BY customer_id`) + require.NoError(t, err) + var results []result + for rows.Next() { + var r result + err = rows.Scan(&r.customerID, &r.timestamp, &r.clickEventType, &r.countryCode, &r.sourceID) + require.NoError(t, err) + results = append(results, r) + } + require.Equal(t, len(results), 3) + require.NoError(t, rows.Close()) + require.NoError(t, rows.Err()) + + parseTime := func(t *testing.T, s string) time.Time { + t.Helper() + tm, err := time.Parse("2006-01-02", s) + require.NoError(t, err) + return tm + } + want := []result{ + {"customer1", parseTime(t, "2021-10-02"), "add_to_cart", "US", 568239}, + {"customer2", parseTime(t, "2021-10-30"), "remove_from_cart", "", 0}, + {"customer3", parseTime(t, "2021-11-07"), "checkout", "", 307493}, + } + for i, result := range results { + require.Equal(t, result.customerID, want[i].customerID) + require.Equal(t, result.timestamp, want[i].timestamp) + require.Equal(t, result.clickEventType, want[i].clickEventType) + if result.countryCode != "" && want[i].countryCode != "" { + require.Equal(t, result.countryCode, want[i].countryCode) + } + require.Equal(t, result.sourceID, want[i].sourceID) + } +} + +func TestClickhouseRemote(t *testing.T) { + t.Parallel() + + db, cleanup, err := testdb.NewClickHouse() + require.NoError(t, err) + t.Cleanup(cleanup) + require.NoError(t, db.Ping()) + testDatabase(t, database.DialectClickHouse, db, "testdata/migrations/clickhouse-remote") + + // assert that the taxi_zone_dictionary table has been created and populated + var count int + err = db.QueryRow(`SELECT count(*) FROM taxi_zone_dictionary`).Scan(&count) + require.NoError(t, err) + require.Equal(t, 265, count) +} + +func TestMySQL(t *testing.T) { + t.Parallel() + + db, cleanup, err := testdb.NewMariaDB() + require.NoError(t, err) + t.Cleanup(cleanup) + require.NoError(t, db.Ping()) + + testDatabase(t, database.DialectMySQL, db, "testdata/migrations/mysql") +} + +func TestTurso(t *testing.T) { + t.Parallel() + + db, cleanup, err := testdb.NewTurso() + require.NoError(t, err) + t.Cleanup(cleanup) + require.NoError(t, db.Ping()) + + testDatabase(t, database.DialectTurso, db, "testdata/migrations/turso") +} + +func TestVertica(t *testing.T) { + t.Parallel() + + db, cleanup, err := testdb.NewVertica() + require.NoError(t, err) + t.Cleanup(cleanup) + require.NoError(t, db.Ping()) + + testDatabase(t, database.DialectVertica, db, "testdata/migrations/vertica") + + type result struct { + TestKey int64 `db:"test_key"` + TestID string `db:"test_id"` + ValidFrom time.Time `db:"valid_from"` + ValidTo time.Time `db:"valid_to"` + IsCurrent bool `db:"is_current"` + ExternalID string `db:"external_id"` + } + rows, err := db.Query(`SELECT * FROM testing.dim_test_scd ORDER BY test_key`) + require.NoError(t, err) + var results []result + for rows.Next() { + var r result + err = rows.Scan(&r.TestKey, &r.TestID, &r.ValidFrom, &r.ValidTo, &r.IsCurrent, &r.ExternalID) + require.NoError(t, err) + results = append(results, r) + } + require.Equal(t, len(results), 3) + require.NoError(t, rows.Close()) + require.NoError(t, rows.Err()) + + parseTime := func(t *testing.T, s string) time.Time { + t.Helper() + tm, err := time.Parse("2006-01-02", s) + require.NoError(t, err) + return tm + } + want := []result{ + { + TestKey: 1, + TestID: "575a0dd4-bd97-44ac-aae0-987090181da8", + ValidFrom: parseTime(t, "2021-10-02"), + ValidTo: parseTime(t, "2021-10-03"), + IsCurrent: false, + ExternalID: "123", + }, + { + TestKey: 2, + TestID: "575a0dd4-bd97-44ac-aae0-987090181da8", + ValidFrom: parseTime(t, "2021-10-03"), + ValidTo: parseTime(t, "2021-10-04"), + IsCurrent: false, + ExternalID: "456", + }, + { + TestKey: 3, + TestID: "575a0dd4-bd97-44ac-aae0-987090181da8", + ValidFrom: parseTime(t, "2021-10-04"), + ValidTo: parseTime(t, "9999-12-31"), + IsCurrent: true, + ExternalID: "789", + }, + } + for i, result := range results { + require.Equal(t, result.TestKey, want[i].TestKey) + require.Equal(t, result.TestID, want[i].TestID) + require.Equal(t, result.ValidFrom, want[i].ValidFrom) + require.Equal(t, result.ValidTo, want[i].ValidTo) + require.Equal(t, result.IsCurrent, want[i].IsCurrent) + require.Equal(t, result.ExternalID, want[i].ExternalID) + } +} + +func TestYDB(t *testing.T) { + t.Parallel() + + db, cleanup, err := testdb.NewYdb() + require.NoError(t, err) + t.Cleanup(cleanup) + require.NoError(t, db.Ping()) + + testDatabase(t, database.DialectYdB, db, "testdata/migrations/ydb") +} diff --git a/internal/testing/integration/integration.go b/internal/testing/integration/integration.go new file mode 100644 index 000000000..a2a316f00 --- /dev/null +++ b/internal/testing/integration/integration.go @@ -0,0 +1,82 @@ +package integration + +import ( + "context" + "database/sql" + "errors" + "os" + "path/filepath" + "testing" + + "github.com/pressly/goose/v3" + "github.com/pressly/goose/v3/database" + "github.com/stretchr/testify/require" +) + +type collected struct { + fullpath string + version int64 +} + +func collectMigrations(t *testing.T, dir string) []collected { + t.Helper() + + files, err := os.ReadDir(dir) + require.NoError(t, err) + all := make([]collected, 0, len(files)) + for _, f := range files { + require.False(t, f.IsDir()) + v, err := goose.NumericComponent(f.Name()) + require.NoError(t, err) + all = append(all, collected{ + fullpath: filepath.Base(f.Name()), + version: v, + }) + } + return all +} + +func testDatabase(t *testing.T, dialect database.Dialect, db *sql.DB, migrationsDir string) { + t.Helper() + + ctx := context.Background() + // collect all migration files from the testdata directory + wantFiles := collectMigrations(t, migrationsDir) + // initialize a new goose provider + p, err := goose.NewProvider(dialect, db, os.DirFS(migrationsDir)) + require.NoError(t, err) + require.Equal(t, len(wantFiles), len(p.ListSources()), "number of migrations") + // run all up migrations + results, err := p.Up(ctx) + require.NoError(t, err) + require.Equal(t, len(wantFiles), len(results), "number of migrations applied") + for i, r := range results { + require.Equal(t, wantFiles[i].fullpath, r.Source.Path, "migration file") + require.Equal(t, wantFiles[i].version, r.Source.Version, "migration version") + } + // check the current version + currentVersion, err := p.GetDBVersion(ctx) + require.NoError(t, err) + require.Equal(t, len(wantFiles), int(currentVersion), "current version") + // run all down migrations + results, err = p.DownTo(ctx, 0) + require.NoError(t, err) + require.Equal(t, len(wantFiles), len(results), "number of migrations rolled back") + // check the current version + currentVersion, err = p.GetDBVersion(ctx) + require.NoError(t, err) + require.Equal(t, 0, int(currentVersion), "current version") + // run all up migrations one by one + for i := range len(wantFiles) { + result, err := p.UpByOne(ctx) + require.NoError(t, err) + if errors.Is(err, goose.ErrNoNextVersion) { + break + } + require.Equal(t, wantFiles[i].fullpath, result.Source.Path, "migration file") + } + // check the current version + currentVersion, err = p.GetDBVersion(ctx) + require.NoError(t, err) + require.Equal(t, len(wantFiles), int(currentVersion), "current version") +} diff --git a/internal/testing/integration/postgres_locking_test.go b/internal/testing/integration/postgres_locking_test.go new file mode 100644 index 000000000..be9983716 --- /dev/null +++ b/internal/testing/integration/postgres_locking_test.go @@ -0,0 +1,417 @@ +package integration + +import ( + "context" + "database/sql" + "errors" + "math/rand" + "os" + "sort" + "sync" + "testing" + "time" + + "github.com/pressly/goose/v3" + "github.com/pressly/goose/v3/internal/testing/testdb" + "github.com/pressly/goose/v3/lock" + "github.com/stretchr/testify/require" + "golang.org/x/sync/errgroup" +) + +func TestPostgresSessionLocker(t *testing.T) { + t.Parallel() + if testing.Short() { + t.Skip("skipping test in short mode.") + } + + db, cleanup, err := testdb.NewPostgres() + require.NoError(t, err) + t.Cleanup(cleanup) + + // Do not run subtests in parallel, because they are using the same database. + + t.Run("lock_and_unlock", func(t *testing.T) { + const ( + lockID int64 = 123456789 + ) + locker, err := lock.NewPostgresSessionLocker( + lock.WithLockID(lockID), + lock.WithLockTimeout(1, 4), // 4 second timeout + lock.WithUnlockTimeout(1, 4), // 4 second timeout + ) + require.NoError(t, err) + ctx := context.Background() + conn, err := db.Conn(ctx) + require.NoError(t, err) + t.Cleanup(func() { + require.NoError(t, conn.Close()) + }) + err = locker.SessionLock(ctx, conn) + require.NoError(t, err) + // Check that the lock was acquired. + exists, err := existsPgLock(ctx, db, lockID) + require.NoError(t, err) + require.True(t, exists) + // Check that the lock is released. + err = locker.SessionUnlock(ctx, conn) + require.NoError(t, err) + exists, err = existsPgLock(ctx, db, lockID) + require.NoError(t, err) + require.False(t, exists) + }) + t.Run("lock_close_conn_unlock", func(t *testing.T) { + locker, err := lock.NewPostgresSessionLocker( + lock.WithLockTimeout(1, 4), // 4 second timeout + lock.WithUnlockTimeout(1, 4), // 4 second timeout + ) + require.NoError(t, err) + ctx := context.Background() + conn, err := db.Conn(ctx) + require.NoError(t, err) + + err = locker.SessionLock(ctx, conn) + require.NoError(t, err) + exists, err := existsPgLock(ctx, db, lock.DefaultLockID) + require.NoError(t, err) + require.True(t, exists) + // Simulate a connection close. + err = conn.Close() + require.NoError(t, err) + // Check an error is returned when unlocking, because the connection is already closed. + err = locker.SessionUnlock(ctx, conn) + require.Error(t, err) + require.True(t, errors.Is(err, sql.ErrConnDone)) + }) + t.Run("multiple_connections", func(t *testing.T) { + const ( + workers = 5 + ) + ch := make(chan error) + var wg sync.WaitGroup + for i := 0; i < workers; i++ { + wg.Add(1) + + go func() { + defer wg.Done() + ctx := context.Background() + conn, err := db.Conn(ctx) + require.NoError(t, err) + t.Cleanup(func() { + require.NoError(t, conn.Close()) + }) + // Exactly one connection should acquire the lock. While the other connections + // should fail to acquire the lock and timeout. + locker, err := lock.NewPostgresSessionLocker( + lock.WithLockTimeout(1, 4), // 4 second timeout + lock.WithUnlockTimeout(1, 4), // 4 second timeout + ) + require.NoError(t, err) + // NOTE, we are not unlocking the lock, because we want to test that the lock is + // released when the connection is closed. + ch <- locker.SessionLock(ctx, conn) + }() + } + go func() { + wg.Wait() + close(ch) + }() + var errors []error + for err := range ch { + if err != nil { + errors = append(errors, err) + } + } + require.Equal(t, len(errors), workers-1) // One worker succeeds, the rest fail. + for _, err := range errors { + require.Error(t, err) + require.Equal(t, err.Error(), "failed to acquire lock") + } + exists, err := existsPgLock(context.Background(), db, lock.DefaultLockID) + require.NoError(t, err) + require.True(t, exists) + }) + t.Run("unlock_with_different_connection_error", func(t *testing.T) { + rng := rand.New(rand.NewSource(time.Now().UnixNano())) + randomLockID := rng.Int63n(90000) + 10000 + ctx := context.Background() + locker, err := lock.NewPostgresSessionLocker( + lock.WithLockID(randomLockID), + lock.WithLockTimeout(1, 4), // 4 second timeout + lock.WithUnlockTimeout(1, 4), // 4 second timeout + ) + require.NoError(t, err) + + conn1, err := db.Conn(ctx) + require.NoError(t, err) + err = locker.SessionLock(ctx, conn1) + require.NoError(t, err) + t.Cleanup(func() { + // Defer the unlock with the same connection. + err = locker.SessionUnlock(ctx, conn1) + require.NoError(t, err) + require.NoError(t, conn1.Close()) + }) + exists, err := existsPgLock(ctx, db, randomLockID) + require.NoError(t, err) + require.True(t, exists) + // Unlock with a different connection. + conn2, err := db.Conn(ctx) + require.NoError(t, err) + t.Cleanup(func() { + require.NoError(t, conn2.Close()) + }) + // Check an error is returned when unlocking with a different connection. + err = locker.SessionUnlock(ctx, conn2) + require.Error(t, err) + }) +} + +func TestPostgresProviderLocking(t *testing.T) { + t.Parallel() + if testing.Short() { + t.Skip("skipping test in short mode.") + } + + // The migrations are written in such a way they cannot be applied in parallel, they will fail + // 99.9999% of the time. This test ensures that the advisory session lock mode works as + // expected. + + // TODO(mf): small improvement here is to use the SAME postgres instance but different databases + // created from a template. This will speed up the test. + + db, cleanup, err := testdb.NewPostgres() + require.NoError(t, err) + t.Cleanup(cleanup) + + newProvider := func() *goose.Provider { + + sessionLocker, err := lock.NewPostgresSessionLocker( + lock.WithLockTimeout(5, 60), // Timeout 5min. Try every 5s up to 60 times. + ) + require.NoError(t, err) + p, err := goose.NewProvider( + goose.DialectPostgres, + db, + os.DirFS("testdata/migrations/postgres"), + goose.WithSessionLocker(sessionLocker), // Use advisory session lock mode. + ) + require.NoError(t, err) + + return p + } + + provider1 := newProvider() + provider2 := newProvider() + + sources := provider1.ListSources() + maxVersion := sources[len(sources)-1].Version + + // Since the lock mode is advisory session, only one of these providers is expected to apply ALL + // the migrations. The other provider should apply NO migrations. The test MUST fail if both + // providers apply migrations. + + t.Run("up", func(t *testing.T) { + var g errgroup.Group + var res1, res2 int + g.Go(func() error { + ctx := context.Background() + results, err := provider1.Up(ctx) + require.NoError(t, err) + res1 = len(results) + currentVersion, err := provider1.GetDBVersion(ctx) + require.NoError(t, err) + require.Equal(t, currentVersion, maxVersion) + return nil + }) + g.Go(func() error { + ctx := context.Background() + results, err := provider2.Up(ctx) + require.NoError(t, err) + res2 = len(results) + currentVersion, err := provider2.GetDBVersion(ctx) + require.NoError(t, err) + require.Equal(t, currentVersion, maxVersion) + return nil + }) + require.NoError(t, g.Wait()) + // One of the providers should have applied all migrations and the other should have applied + // no migrations, but with no error. + if res1 == 0 && res2 == 0 { + t.Fatal("both providers applied no migrations") + } + if res1 > 0 && res2 > 0 { + t.Fatal("both providers applied migrations") + } + }) + + // Reset the database and run the same test with the advisory lock mode, but apply migrations + // one-by-one. + { + _, err := provider1.DownTo(context.Background(), 0) + require.NoError(t, err) + currentVersion, err := provider1.GetDBVersion(context.Background()) + require.NoError(t, err) + require.Equal(t, currentVersion, int64(0)) + } + t.Run("up_by_one", func(t *testing.T) { + var g errgroup.Group + var ( + mu sync.Mutex + applied []int64 + ) + g.Go(func() error { + for { + result, err := provider1.UpByOne(context.Background()) + if err != nil { + if errors.Is(err, goose.ErrNoNextVersion) { + return nil + } + return err + } + require.NoError(t, err) + require.NotNil(t, result) + mu.Lock() + applied = append(applied, result.Source.Version) + mu.Unlock() + } + }) + g.Go(func() error { + for { + result, err := provider2.UpByOne(context.Background()) + if err != nil { + if errors.Is(err, goose.ErrNoNextVersion) { + return nil + } + return err + } + require.NoError(t, err) + require.NotNil(t, result) + mu.Lock() + applied = append(applied, result.Source.Version) + mu.Unlock() + } + }) + require.NoError(t, g.Wait()) + require.Equal(t, len(applied), len(sources)) + sort.Slice(applied, func(i, j int) bool { + return applied[i] < applied[j] + }) + // Each migration should have been applied up exactly once. + for i := 0; i < len(sources); i++ { + require.Equal(t, applied[i], sources[i].Version) + } + }) + + // Restore the database state by applying all migrations and run the same test with the advisory + // lock mode, but apply down migrations in parallel. + { + _, err := provider1.Up(context.Background()) + require.NoError(t, err) + currentVersion, err := provider1.GetDBVersion(context.Background()) + require.NoError(t, err) + require.Equal(t, currentVersion, maxVersion) + } + + t.Run("down_to", func(t *testing.T) { + var g errgroup.Group + var res1, res2 int + g.Go(func() error { + ctx := context.Background() + results, err := provider1.DownTo(ctx, 0) + require.NoError(t, err) + res1 = len(results) + currentVersion, err := provider1.GetDBVersion(ctx) + require.NoError(t, err) + require.Equal(t, int64(0), currentVersion) + return nil + }) + g.Go(func() error { + ctx := context.Background() + results, err := provider2.DownTo(ctx, 0) + require.NoError(t, err) + res2 = len(results) + currentVersion, err := provider2.GetDBVersion(ctx) + require.NoError(t, err) + require.Equal(t, int64(0), currentVersion) + return nil + }) + require.NoError(t, g.Wait()) + + if res1 == 0 && res2 == 0 { + t.Fatal("both providers applied no migrations") + } + if res1 > 0 && res2 > 0 { + t.Fatal("both providers applied migrations") + } + }) + + // Restore the database state by applying all migrations and run the same test with the advisory + // lock mode, but apply down migrations one-by-one. + { + _, err := provider1.Up(context.Background()) + require.NoError(t, err) + currentVersion, err := provider1.GetDBVersion(context.Background()) + require.NoError(t, err) + require.Equal(t, currentVersion, maxVersion) + } + + t.Run("down_by_one", func(t *testing.T) { + var g errgroup.Group + var ( + mu sync.Mutex + applied []int64 + ) + g.Go(func() error { + for { + result, err := provider1.Down(context.Background()) + if err != nil { + if errors.Is(err, goose.ErrNoNextVersion) { + return nil + } + return err + } + require.NoError(t, err) + require.NotNil(t, result) + mu.Lock() + applied = append(applied, result.Source.Version) + mu.Unlock() + } + }) + g.Go(func() error { + for { + result, err := provider2.Down(context.Background()) + if err != nil { + if errors.Is(err, goose.ErrNoNextVersion) { + return nil + } + return err + } + require.NoError(t, err) + require.NotNil(t, result) + mu.Lock() + applied = append(applied, result.Source.Version) + mu.Unlock() + } + }) + require.NoError(t, g.Wait()) + require.Equal(t, len(applied), len(sources)) + sort.Slice(applied, func(i, j int) bool { + return applied[i] < applied[j] + }) + // Each migration should have been applied down exactly once. Since this is sequential the + // applied down migrations should be in reverse order. + for i := len(sources) - 1; i >= 0; i-- { + require.Equal(t, applied[i], sources[i].Version) + } + }) +} + +func existsPgLock(ctx context.Context, db *sql.DB, lockID int64) (bool, error) { + q := `SELECT EXISTS(SELECT 1 FROM pg_locks WHERE locktype='advisory' AND ((classid::bigint<<32)|objid::bigint)=$1)` + row := db.QueryRowContext(ctx, q, lockID) + var exists bool + if err := row.Scan(&exists); err != nil { + return false, err + } + return exists, nil +} diff --git a/tests/clickhouse/testdata/backup-files/taxi_zone_lookup.csv b/internal/testing/integration/testdata/migrations/clickhouse-remote-backup/taxi_zone_lookup.csv similarity index 100% rename from tests/clickhouse/testdata/backup-files/taxi_zone_lookup.csv rename to internal/testing/integration/testdata/migrations/clickhouse-remote-backup/taxi_zone_lookup.csv diff --git a/tests/clickhouse/testdata/migrations-remote/00001_a.sql b/internal/testing/integration/testdata/migrations/clickhouse-remote/00001_a.sql similarity index 100% rename from tests/clickhouse/testdata/migrations-remote/00001_a.sql rename to internal/testing/integration/testdata/migrations/clickhouse-remote/00001_a.sql diff --git a/tests/clickhouse/testdata/migrations/00001_a.sql b/internal/testing/integration/testdata/migrations/clickhouse/00001_a.sql similarity index 100% rename from tests/clickhouse/testdata/migrations/00001_a.sql rename to internal/testing/integration/testdata/migrations/clickhouse/00001_a.sql diff --git a/tests/clickhouse/testdata/migrations/00002_b.sql b/internal/testing/integration/testdata/migrations/clickhouse/00002_b.sql similarity index 100% rename from tests/clickhouse/testdata/migrations/00002_b.sql rename to internal/testing/integration/testdata/migrations/clickhouse/00002_b.sql diff --git a/tests/clickhouse/testdata/migrations/00003_c.sql b/internal/testing/integration/testdata/migrations/clickhouse/00003_c.sql similarity index 100% rename from tests/clickhouse/testdata/migrations/00003_c.sql rename to internal/testing/integration/testdata/migrations/clickhouse/00003_c.sql diff --git a/internal/testing/integration/testdata/migrations/mysql/00001_table.sql b/internal/testing/integration/testdata/migrations/mysql/00001_table.sql new file mode 100644 index 000000000..66597f22a --- /dev/null +++ b/internal/testing/integration/testdata/migrations/mysql/00001_table.sql @@ -0,0 +1,23 @@ +-- +goose Up +-- +goose StatementBegin +CREATE TABLE owners ( + owner_id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY, + owner_name VARCHAR(255) NOT NULL, + owner_type ENUM('user', 'organization') NOT NULL +); + +CREATE TABLE IF NOT EXISTS repos ( + repo_id BIGINT UNSIGNED AUTO_INCREMENT NOT NULL, + repo_full_name VARCHAR(255) NOT NULL, + repo_owner_id BIGINT UNSIGNED NOT NULL, + + PRIMARY KEY (repo_id), + FOREIGN KEY (repo_owner_id) REFERENCES owners(owner_id) ON DELETE CASCADE +); +-- +goose StatementEnd + +-- +goose Down +-- +goose StatementBegin +DROP TABLE IF EXISTS repos; +DROP TABLE IF EXISTS owners; +-- +goose StatementEnd diff --git a/internal/testing/integration/testdata/migrations/mysql/00002_insert.sql b/internal/testing/integration/testdata/migrations/mysql/00002_insert.sql new file mode 100644 index 000000000..29659827b --- /dev/null +++ b/internal/testing/integration/testdata/migrations/mysql/00002_insert.sql @@ -0,0 +1,22 @@ +-- +goose Up +-- +goose StatementBegin +INSERT INTO owners (owner_name, owner_type) +VALUES + ('lucas', 'user'), + ('space', 'organization'); +-- +goose StatementEnd + +INSERT INTO owners (owner_name, owner_type) +VALUES + ('james', 'user'), + ('pressly', 'organization'); + +INSERT INTO repos (repo_full_name, repo_owner_id) +VALUES + ('james/rover', (SELECT owner_id FROM owners WHERE owner_name = 'james')), + ('pressly/goose', (SELECT owner_id FROM owners WHERE owner_name = 'pressly')); + +-- +goose Down +-- +goose StatementBegin +DELETE FROM owners; +-- +goose StatementEnd diff --git a/internal/testing/integration/testdata/migrations/mysql/00003_alter.sql b/internal/testing/integration/testdata/migrations/mysql/00003_alter.sql new file mode 100644 index 000000000..221f194a9 --- /dev/null +++ b/internal/testing/integration/testdata/migrations/mysql/00003_alter.sql @@ -0,0 +1,17 @@ +-- +goose Up +-- +goose StatementBegin +ALTER TABLE repos + ADD COLUMN IF NOT EXISTS homepage_url TEXT; + +ALTER TABLE repos + ADD COLUMN is_private BOOLEAN NOT NULL DEFAULT FALSE; +-- +goose StatementEnd + +-- +goose Down +-- +goose StatementBegin +ALTER TABLE repos + DROP COLUMN IF EXISTS homepage_url; + +ALTER TABLE repos + DROP COLUMN IF EXISTS is_private; +-- +goose StatementEnd diff --git a/internal/testing/integration/testdata/migrations/mysql/00004_empty.sql b/internal/testing/integration/testdata/migrations/mysql/00004_empty.sql new file mode 100644 index 000000000..6fdba0255 --- /dev/null +++ b/internal/testing/integration/testdata/migrations/mysql/00004_empty.sql @@ -0,0 +1 @@ +-- +goose Up diff --git a/internal/testing/integration/testdata/migrations/mysql/00005_no_tx.sql b/internal/testing/integration/testdata/migrations/mysql/00005_no_tx.sql new file mode 100644 index 000000000..ec45d0e77 --- /dev/null +++ b/internal/testing/integration/testdata/migrations/mysql/00005_no_tx.sql @@ -0,0 +1,8 @@ +-- +goose NO TRANSACTION + +-- +goose Up +CREATE UNIQUE INDEX owners_owner_name_idx ON owners(owner_name); + +-- +goose Down +DROP INDEX IF EXISTS owners_owner_name_idx ON owners; + diff --git a/internal/testing/integration/testdata/migrations/mysql/00006_complex.sql b/internal/testing/integration/testdata/migrations/mysql/00006_complex.sql new file mode 100644 index 000000000..12656ae33 --- /dev/null +++ b/internal/testing/integration/testdata/migrations/mysql/00006_complex.sql @@ -0,0 +1,36 @@ +-- +goose up + +-- +goose statementbegin +CREATE OR REPLACE PROCEDURE insert_repository( + IN p_repo_full_name VARCHAR(255), + IN p_owner_name VARCHAR(255), + IN p_owner_type VARCHAR(20) +) +BEGIN + DECLARE v_owner_id BIGINT; + DECLARE v_repo_id BIGINT; + + -- Check if the owner already exists + SELECT owner_id INTO v_owner_id + FROM owners + WHERE owner_name = p_owner_name AND owner_type = p_owner_type; + + -- If the owner does not exist, insert a new owner + IF v_owner_id IS NULL THEN + INSERT INTO owners (owner_name, owner_type) + VALUES (p_owner_name, p_owner_type); + + SET v_owner_id = LAST_INSERT_ID(); + END IF; + + -- Insert the repository using the obtained owner_id + INSERT INTO repos (repo_full_name, repo_owner_id) + VALUES (p_repo_full_name, v_owner_id); + + -- No explicit return needed in procedures + +END; +-- +goose statementend + +-- +goose down +DROP PROCEDURE IF EXISTS insert_repository; diff --git a/tests/e2e/testdata/postgres/migrations/00001_a.sql b/internal/testing/integration/testdata/migrations/postgres/00001_table.sql similarity index 96% rename from tests/e2e/testdata/postgres/migrations/00001_a.sql rename to internal/testing/integration/testdata/migrations/postgres/00001_table.sql index 67bf7ba0d..40350a601 100644 --- a/tests/e2e/testdata/postgres/migrations/00001_a.sql +++ b/internal/testing/integration/testdata/migrations/postgres/00001_table.sql @@ -22,4 +22,4 @@ CREATE TABLE IF NOT EXISTS repos ( DROP TABLE IF EXISTS repos; DROP TABLE IF EXISTS owners; DROP TYPE owner_type; --- +goose StatementEnd \ No newline at end of file +-- +goose StatementEnd diff --git a/tests/e2e/testdata/postgres/migrations/00003_c.sql b/internal/testing/integration/testdata/migrations/postgres/00002_insert.sql similarity index 73% rename from tests/e2e/testdata/postgres/migrations/00003_c.sql rename to internal/testing/integration/testdata/migrations/postgres/00002_insert.sql index b93a85426..8ec039602 100644 --- a/tests/e2e/testdata/postgres/migrations/00003_c.sql +++ b/internal/testing/integration/testdata/migrations/postgres/00002_insert.sql @@ -1,13 +1,16 @@ -- +goose Up -- +goose StatementBegin +INSERT INTO owners(owner_name, owner_type) + VALUES ('lucas', 'user'), ('space', 'organization'); +-- +goose StatementEnd + INSERT INTO owners(owner_name, owner_type) VALUES ('james', 'user'), ('pressly', 'organization'); INSERT INTO repos(repo_full_name, repo_owner_id) VALUES ('james/rover', 3), ('pressly/goose', 4); --- +goose StatementEnd -- +goose Down -- +goose StatementBegin -DELETE FROM owners WHERE owner_name IN ('james', 'pressly'); +DELETE FROM owners; -- +goose StatementEnd diff --git a/tests/e2e/testdata/postgres/migrations/00004_d.sql b/internal/testing/integration/testdata/migrations/postgres/00003_alter.sql similarity index 100% rename from tests/e2e/testdata/postgres/migrations/00004_d.sql rename to internal/testing/integration/testdata/migrations/postgres/00003_alter.sql diff --git a/internal/testing/integration/testdata/migrations/postgres/00004_empty.sql b/internal/testing/integration/testdata/migrations/postgres/00004_empty.sql new file mode 100644 index 000000000..6fdba0255 --- /dev/null +++ b/internal/testing/integration/testdata/migrations/postgres/00004_empty.sql @@ -0,0 +1 @@ +-- +goose Up diff --git a/tests/e2e/testdata/postgres/migrations/00010_j.sql b/internal/testing/integration/testdata/migrations/postgres/00005_no_tx.sql similarity index 63% rename from tests/e2e/testdata/postgres/migrations/00010_j.sql rename to internal/testing/integration/testdata/migrations/postgres/00005_no_tx.sql index 798452cde..62e776f21 100644 --- a/tests/e2e/testdata/postgres/migrations/00010_j.sql +++ b/internal/testing/integration/testdata/migrations/postgres/00005_no_tx.sql @@ -1,7 +1,7 @@ -- +goose NO TRANSACTION -- +goose Up -DROP INDEX IF EXISTS owners_owner_name_idx; +CREATE UNIQUE INDEX CONCURRENTLY ON owners(owner_name); -- +goose Down -CREATE UNIQUE INDEX CONCURRENTLY ON owners(owner_name); \ No newline at end of file +DROP INDEX IF EXISTS owners_owner_name_idx; diff --git a/internal/testing/integration/testdata/migrations/postgres/00006_complex.sql b/internal/testing/integration/testdata/migrations/postgres/00006_complex.sql new file mode 100644 index 000000000..e436c6c5e --- /dev/null +++ b/internal/testing/integration/testdata/migrations/postgres/00006_complex.sql @@ -0,0 +1,36 @@ +-- +goose up +-- +goose statementbegin +CREATE OR REPLACE FUNCTION insert_repository( + p_repo_full_name TEXT, + p_owner_name TEXT, + p_owner_type OWNER_TYPE +) RETURNS VOID AS $$ +DECLARE + v_owner_id BIGINT; + v_repo_id BIGINT; +BEGIN + -- Check if the owner already exists + SELECT owner_id INTO v_owner_id + FROM owners + WHERE owner_name = p_owner_name AND owner_type = p_owner_type; + + -- If the owner does not exist, insert a new owner + IF v_owner_id IS NULL THEN + INSERT INTO owners (owner_name, owner_type) + VALUES (p_owner_name, p_owner_type) + RETURNING owner_id INTO v_owner_id; + END IF; + + -- Insert the repository using the obtained owner_id + INSERT INTO repos (repo_full_name, repo_owner_id) + VALUES (p_repo_full_name, v_owner_id) + RETURNING repo_id INTO v_repo_id; + + -- Commit the transaction + COMMIT; +END; +$$ LANGUAGE plpgsql; +-- +goose statementend + +-- +goose down +DROP FUNCTION IF EXISTS insert_repository(TEXT, TEXT, OWNER_TYPE); diff --git a/internal/testing/integration/testdata/migrations/turso/00001_table.sql b/internal/testing/integration/testdata/migrations/turso/00001_table.sql new file mode 100644 index 000000000..ea7ec0f9b --- /dev/null +++ b/internal/testing/integration/testdata/migrations/turso/00001_table.sql @@ -0,0 +1,20 @@ +-- +goose Up +-- +goose StatementBegin +CREATE TABLE owners ( + owner_id INTEGER PRIMARY KEY AUTOINCREMENT, + owner_name TEXT NOT NULL, + owner_type TEXT CHECK(owner_type IN ('user', 'organization')) NOT NULL +); + +CREATE TABLE IF NOT EXISTS repos ( + repo_id INTEGER PRIMARY KEY AUTOINCREMENT, + repo_full_name TEXT NOT NULL, + repo_owner_id INTEGER NOT NULL REFERENCES owners(owner_id) ON DELETE CASCADE +); +-- +goose StatementEnd + +-- +goose Down +-- +goose StatementBegin +DROP TABLE IF EXISTS repos; +DROP TABLE IF EXISTS owners; +-- +goose StatementEnd diff --git a/internal/testing/integration/testdata/migrations/turso/00002_insert.sql b/internal/testing/integration/testdata/migrations/turso/00002_insert.sql new file mode 100644 index 000000000..5e6c0346d --- /dev/null +++ b/internal/testing/integration/testdata/migrations/turso/00002_insert.sql @@ -0,0 +1,19 @@ +-- +goose Up +-- +goose StatementBegin +INSERT INTO owners(owner_name, owner_type) +VALUES + ('lucas', 'user'), + ('space', 'organization'), + ('james', 'user'), + ('pressly', 'organization'); +-- +goose StatementEnd + +INSERT INTO repos(repo_full_name, repo_owner_id) +VALUES + ('james/rover', (SELECT owner_id FROM owners WHERE owner_name = 'james')), + ('pressly/goose', (SELECT owner_id FROM owners WHERE owner_name = 'pressly')); + +-- +goose Down +-- +goose StatementBegin +DELETE FROM owners; +-- +goose StatementEnd diff --git a/internal/testing/integration/testdata/migrations/turso/00003_alter.sql b/internal/testing/integration/testdata/migrations/turso/00003_alter.sql new file mode 100644 index 000000000..779ad01c5 --- /dev/null +++ b/internal/testing/integration/testdata/migrations/turso/00003_alter.sql @@ -0,0 +1,17 @@ +-- +goose Up +-- +goose StatementBegin +ALTER TABLE repos +ADD COLUMN homepage_url TEXT; + +ALTER TABLE repos +ADD COLUMN is_private BOOLEAN DEFAULT 0; +-- +goose StatementEnd + +-- +goose Down +-- +goose StatementBegin +ALTER TABLE repos +DROP COLUMN homepage_url; + +ALTER TABLE repos +DROP COLUMN is_private; +-- +goose StatementEnd diff --git a/internal/testing/integration/testdata/migrations/turso/00004_empty.sql b/internal/testing/integration/testdata/migrations/turso/00004_empty.sql new file mode 100644 index 000000000..6fdba0255 --- /dev/null +++ b/internal/testing/integration/testdata/migrations/turso/00004_empty.sql @@ -0,0 +1 @@ +-- +goose Up diff --git a/internal/testing/integration/testdata/migrations/turso/00005_no_tx.sql b/internal/testing/integration/testdata/migrations/turso/00005_no_tx.sql new file mode 100644 index 000000000..bf34c4ea2 --- /dev/null +++ b/internal/testing/integration/testdata/migrations/turso/00005_no_tx.sql @@ -0,0 +1,9 @@ +-- +goose NO TRANSACTION + +-- +goose Up +CREATE UNIQUE INDEX IF NOT EXISTS idx_owners_owner_name ON owners(owner_name); + + +-- +goose Down +DROP INDEX IF EXISTS idx_owners_owner_name; + diff --git a/tests/vertica/testdata/migrations/00001_a.sql b/internal/testing/integration/testdata/migrations/vertica/00001_a.sql similarity index 100% rename from tests/vertica/testdata/migrations/00001_a.sql rename to internal/testing/integration/testdata/migrations/vertica/00001_a.sql diff --git a/tests/vertica/testdata/migrations/00002_b.sql b/internal/testing/integration/testdata/migrations/vertica/00002_b.sql similarity index 100% rename from tests/vertica/testdata/migrations/00002_b.sql rename to internal/testing/integration/testdata/migrations/vertica/00002_b.sql diff --git a/tests/vertica/testdata/migrations/00003_c.sql b/internal/testing/integration/testdata/migrations/vertica/00003_c.sql similarity index 100% rename from tests/vertica/testdata/migrations/00003_c.sql rename to internal/testing/integration/testdata/migrations/vertica/00003_c.sql diff --git a/tests/e2e/testdata/ydb/migrations/00001_a.sql b/internal/testing/integration/testdata/migrations/ydb/00001_a.sql similarity index 100% rename from tests/e2e/testdata/ydb/migrations/00001_a.sql rename to internal/testing/integration/testdata/migrations/ydb/00001_a.sql diff --git a/tests/e2e/testdata/turso/migrations/00002_b.sql b/internal/testing/integration/testdata/migrations/ydb/00002_b.sql similarity index 100% rename from tests/e2e/testdata/turso/migrations/00002_b.sql rename to internal/testing/integration/testdata/migrations/ydb/00002_b.sql diff --git a/tests/e2e/testdata/ydb/migrations/00003_c.sql b/internal/testing/integration/testdata/migrations/ydb/00003_c.sql similarity index 99% rename from tests/e2e/testdata/ydb/migrations/00003_c.sql rename to internal/testing/integration/testdata/migrations/ydb/00003_c.sql index ae622a209..7ba3ce481 100644 --- a/tests/e2e/testdata/ydb/migrations/00003_c.sql +++ b/internal/testing/integration/testdata/migrations/ydb/00003_c.sql @@ -1,3 +1,4 @@ + -- +goose Up -- +goose StatementBegin INSERT INTO owners(owner_id, owner_name, owner_type) diff --git a/tests/e2e/testdata/ydb/migrations/00004_d.sql b/internal/testing/integration/testdata/migrations/ydb/00004_d.sql similarity index 100% rename from tests/e2e/testdata/ydb/migrations/00004_d.sql rename to internal/testing/integration/testdata/migrations/ydb/00004_d.sql diff --git a/tests/e2e/testdata/mysql/migrations/00005_e.sql b/internal/testing/integration/testdata/migrations/ydb/00005_e.sql similarity index 100% rename from tests/e2e/testdata/mysql/migrations/00005_e.sql rename to internal/testing/integration/testdata/migrations/ydb/00005_e.sql diff --git a/tests/e2e/testdata/ydb/migrations/00006_f.sql b/internal/testing/integration/testdata/migrations/ydb/00006_f.sql similarity index 100% rename from tests/e2e/testdata/ydb/migrations/00006_f.sql rename to internal/testing/integration/testdata/migrations/ydb/00006_f.sql diff --git a/tests/e2e/testdata/ydb/migrations/00007_g.sql b/internal/testing/integration/testdata/migrations/ydb/00007_g.sql similarity index 100% rename from tests/e2e/testdata/ydb/migrations/00007_g.sql rename to internal/testing/integration/testdata/migrations/ydb/00007_g.sql diff --git a/tests/e2e/testdata/ydb/migrations/00008_h.sql b/internal/testing/integration/testdata/migrations/ydb/00008_h.sql similarity index 100% rename from tests/e2e/testdata/ydb/migrations/00008_h.sql rename to internal/testing/integration/testdata/migrations/ydb/00008_h.sql diff --git a/internal/testdb/clickhouse.go b/internal/testing/testdb/clickhouse.go similarity index 100% rename from internal/testdb/clickhouse.go rename to internal/testing/testdb/clickhouse.go diff --git a/internal/testdb/container_healthcheck.go b/internal/testing/testdb/container_healthcheck.go similarity index 100% rename from internal/testdb/container_healthcheck.go rename to internal/testing/testdb/container_healthcheck.go diff --git a/internal/testdb/mariadb.go b/internal/testing/testdb/mariadb.go similarity index 100% rename from internal/testdb/mariadb.go rename to internal/testing/testdb/mariadb.go diff --git a/internal/testdb/options.go b/internal/testing/testdb/options.go similarity index 100% rename from internal/testdb/options.go rename to internal/testing/testdb/options.go diff --git a/internal/testdb/postgres.go b/internal/testing/testdb/postgres.go similarity index 98% rename from internal/testdb/postgres.go rename to internal/testing/testdb/postgres.go index 122ce7908..8f411d005 100644 --- a/internal/testdb/postgres.go +++ b/internal/testing/testdb/postgres.go @@ -14,7 +14,7 @@ import ( const ( // https://hub.docker.com/_/postgres POSTGRES_IMAGE = "postgres" - POSTGRES_VERSION = "14-alpine" + POSTGRES_VERSION = "16-alpine" POSTGRES_DB = "testdb" POSTGRES_USER = "postgres" diff --git a/internal/testdb/testdb.go b/internal/testing/testdb/testdb.go similarity index 100% rename from internal/testdb/testdb.go rename to internal/testing/testdb/testdb.go diff --git a/internal/testdb/turso.go b/internal/testing/testdb/turso.go similarity index 97% rename from internal/testdb/turso.go rename to internal/testing/testdb/turso.go index ff005f4d4..77665105d 100644 --- a/internal/testdb/turso.go +++ b/internal/testing/testdb/turso.go @@ -12,9 +12,9 @@ import ( ) const ( - // ghcr.io/tursodatabase/libsql-server:v0.22.10 + // ghcr.io/tursodatabase/libsql-server:v0.23.7 TURSO_IMAGE = "ghcr.io/tursodatabase/libsql-server" - TURSO_VERSION = "v0.22.10" + TURSO_VERSION = "v0.23.7" TURSO_PORT = "8080" ) diff --git a/internal/testdb/vertica.go b/internal/testing/testdb/vertica.go similarity index 80% rename from internal/testdb/vertica.go rename to internal/testing/testdb/vertica.go index fc9cc1d9a..c94148dfb 100644 --- a/internal/testdb/vertica.go +++ b/internal/testing/testdb/vertica.go @@ -1,6 +1,7 @@ package testdb import ( + "context" "database/sql" "fmt" "log" @@ -9,13 +10,14 @@ import ( "github.com/ory/dockertest/v3" "github.com/ory/dockertest/v3/docker" + "github.com/sethvargo/go-retry" _ "github.com/vertica/vertica-sql-go" ) const ( // https://hub.docker.com/r/vertica/vertica-ce VERTICA_IMAGE = "vertica/vertica-ce" - VERTICA_VERSION = "23.3.0-0" + VERTICA_VERSION = "24.1.0-0" VERTICA_DB = "testdb" ) @@ -75,21 +77,21 @@ func newVertica(opts ...OptionsFunc) (*sql.DB, func(), error) { ) var db *sql.DB - // Give vertica a head start since the container takes a little bit to start up. - time.Sleep(time.Second * 15) // Exponential backoff-retry, because the application in the container // might not be ready to accept connections yet. - if err := pool.Retry( - func() error { - var err error - db, err = sql.Open("vertica", verticaInfo) - if err != nil { - return err - } - return db.Ping() - }, - ); err != nil { + backoff := retry.WithMaxDuration(1*time.Minute, retry.NewConstant(2*time.Second)) + if err := retry.Do(context.Background(), backoff, func(ctx context.Context) error { + var err error + db, err = sql.Open("vertica", verticaInfo) + if err != nil { + return retry.RetryableError(fmt.Errorf("failed to open vertica connection: %v", err)) + } + if err := db.Ping(); err != nil { + return retry.RetryableError(fmt.Errorf("failed to ping vertica: %v", err)) + } + return nil + }); err != nil { return nil, cleanup, fmt.Errorf("could not connect to docker database: %v", err) } return db, cleanup, nil diff --git a/internal/testdb/ydb.go b/internal/testing/testdb/ydb.go similarity index 95% rename from internal/testdb/ydb.go rename to internal/testing/testdb/ydb.go index 524cd389a..37149d707 100644 --- a/internal/testdb/ydb.go +++ b/internal/testing/testdb/ydb.go @@ -13,7 +13,7 @@ import ( "github.com/ory/dockertest/v3/docker" "github.com/ydb-platform/ydb-go-sdk/v3" "github.com/ydb-platform/ydb-go-sdk/v3/balancers" - ydbLog "github.com/ydb-platform/ydb-go-sdk/v3/log" + ydblog "github.com/ydb-platform/ydb-go-sdk/v3/log" "github.com/ydb-platform/ydb-go-sdk/v3/trace" ) @@ -102,7 +102,7 @@ func newYdb(opts ...OptionsFunc) (*sql.DB, func(), error) { } if option.debug { - opts = append(opts, ydb.WithLogger(ydbLog.Default(os.Stdout), trace.DetailsAll, ydbLog.WithLogQuery())) + opts = append(opts, ydb.WithLogger(ydblog.Default(os.Stdout), trace.DetailsAll, ydblog.WithLogQuery())) } nativeDriver, err := ydb.Open(ctx, dsn, opts...) diff --git a/lock/postgres_test.go b/lock/postgres_test.go deleted file mode 100644 index 561cb429c..000000000 --- a/lock/postgres_test.go +++ /dev/null @@ -1,172 +0,0 @@ -package lock_test - -import ( - "context" - "database/sql" - "errors" - "math/rand" - "sync" - "testing" - "time" - - "github.com/pressly/goose/v3/internal/check" - "github.com/pressly/goose/v3/internal/testdb" - "github.com/pressly/goose/v3/lock" -) - -func TestPostgresSessionLocker(t *testing.T) { - t.Parallel() - if testing.Short() { - t.Skip("skip long running test") - } - db, cleanup, err := testdb.NewPostgres() - check.NoError(t, err) - t.Cleanup(cleanup) - - // Do not run tests in parallel, because they are using the same database. - - t.Run("lock_and_unlock", func(t *testing.T) { - const ( - lockID int64 = 123456789 - ) - locker, err := lock.NewPostgresSessionLocker( - lock.WithLockID(lockID), - lock.WithLockTimeout(1, 4), // 4 second timeout - lock.WithUnlockTimeout(1, 4), // 4 second timeout - ) - check.NoError(t, err) - ctx := context.Background() - conn, err := db.Conn(ctx) - check.NoError(t, err) - t.Cleanup(func() { - check.NoError(t, conn.Close()) - }) - err = locker.SessionLock(ctx, conn) - check.NoError(t, err) - // Check that the lock was acquired. - exists, err := existsPgLock(ctx, db, lockID) - check.NoError(t, err) - check.Bool(t, exists, true) - // Check that the lock is released. - err = locker.SessionUnlock(ctx, conn) - check.NoError(t, err) - exists, err = existsPgLock(ctx, db, lockID) - check.NoError(t, err) - check.Bool(t, exists, false) - }) - t.Run("lock_close_conn_unlock", func(t *testing.T) { - locker, err := lock.NewPostgresSessionLocker( - lock.WithLockTimeout(1, 4), // 4 second timeout - lock.WithUnlockTimeout(1, 4), // 4 second timeout - ) - check.NoError(t, err) - ctx := context.Background() - conn, err := db.Conn(ctx) - check.NoError(t, err) - - err = locker.SessionLock(ctx, conn) - check.NoError(t, err) - exists, err := existsPgLock(ctx, db, lock.DefaultLockID) - check.NoError(t, err) - check.Bool(t, exists, true) - // Simulate a connection close. - err = conn.Close() - check.NoError(t, err) - // Check an error is returned when unlocking, because the connection is already closed. - err = locker.SessionUnlock(ctx, conn) - check.HasError(t, err) - check.Bool(t, errors.Is(err, sql.ErrConnDone), true) - }) - t.Run("multiple_connections", func(t *testing.T) { - const ( - workers = 5 - ) - ch := make(chan error) - var wg sync.WaitGroup - for i := 0; i < workers; i++ { - wg.Add(1) - - go func() { - defer wg.Done() - ctx := context.Background() - conn, err := db.Conn(ctx) - check.NoError(t, err) - t.Cleanup(func() { - check.NoError(t, conn.Close()) - }) - // Exactly one connection should acquire the lock. While the other connections - // should fail to acquire the lock and timeout. - locker, err := lock.NewPostgresSessionLocker( - lock.WithLockTimeout(1, 4), // 4 second timeout - lock.WithUnlockTimeout(1, 4), // 4 second timeout - ) - check.NoError(t, err) - // NOTE, we are not unlocking the lock, because we want to test that the lock is - // released when the connection is closed. - ch <- locker.SessionLock(ctx, conn) - }() - } - go func() { - wg.Wait() - close(ch) - }() - var errors []error - for err := range ch { - if err != nil { - errors = append(errors, err) - } - } - check.Equal(t, len(errors), workers-1) // One worker succeeds, the rest fail. - for _, err := range errors { - check.HasError(t, err) - check.Equal(t, err.Error(), "failed to acquire lock") - } - exists, err := existsPgLock(context.Background(), db, lock.DefaultLockID) - check.NoError(t, err) - check.Bool(t, exists, true) - }) - t.Run("unlock_with_different_connection_error", func(t *testing.T) { - rng := rand.New(rand.NewSource(time.Now().UnixNano())) - randomLockID := rng.Int63n(90000) + 10000 - ctx := context.Background() - locker, err := lock.NewPostgresSessionLocker( - lock.WithLockID(randomLockID), - lock.WithLockTimeout(1, 4), // 4 second timeout - lock.WithUnlockTimeout(1, 4), // 4 second timeout - ) - check.NoError(t, err) - - conn1, err := db.Conn(ctx) - check.NoError(t, err) - err = locker.SessionLock(ctx, conn1) - check.NoError(t, err) - t.Cleanup(func() { - // Defer the unlock with the same connection. - err = locker.SessionUnlock(ctx, conn1) - check.NoError(t, err) - check.NoError(t, conn1.Close()) - }) - exists, err := existsPgLock(ctx, db, randomLockID) - check.NoError(t, err) - check.Bool(t, exists, true) - // Unlock with a different connection. - conn2, err := db.Conn(ctx) - check.NoError(t, err) - t.Cleanup(func() { - check.NoError(t, conn2.Close()) - }) - // Check an error is returned when unlocking with a different connection. - err = locker.SessionUnlock(ctx, conn2) - check.HasError(t, err) - }) -} - -func existsPgLock(ctx context.Context, db *sql.DB, lockID int64) (bool, error) { - q := `SELECT EXISTS(SELECT 1 FROM pg_locks WHERE locktype='advisory' AND ((classid::bigint<<32)|objid::bigint)=$1)` - row := db.QueryRowContext(ctx, q, lockID) - var exists bool - if err := row.Scan(&exists); err != nil { - return false, err - } - return exists, nil -} diff --git a/provider_run_test.go b/provider_run_test.go index efa8d7091..914597f2b 100644 --- a/provider_run_test.go +++ b/provider_run_test.go @@ -11,7 +11,6 @@ import ( "os" "path/filepath" "reflect" - "sort" "sync" "testing" "testing/fstest" @@ -19,9 +18,6 @@ import ( "github.com/pressly/goose/v3" "github.com/pressly/goose/v3/database" "github.com/pressly/goose/v3/internal/check" - "github.com/pressly/goose/v3/internal/testdb" - "github.com/pressly/goose/v3/lock" - "golang.org/x/sync/errgroup" ) func TestProviderRun(t *testing.T) { @@ -924,246 +920,6 @@ func TestGoOnly(t *testing.T) { }) } -func TestLockModeAdvisorySession(t *testing.T) { - t.Parallel() - if testing.Short() { - t.Skip("skip long running test") - } - - // The migrations are written in such a way that they cannot be applied concurrently, they will - // fail 99.9999% of the time. This test ensures that the advisory session lock mode works as - // expected. - - // TODO(mf): small improvement here is to use the SAME postgres instance but different databases - // created from a template. This will speed up the test. - - db, cleanup, err := testdb.NewPostgres() - check.NoError(t, err) - t.Cleanup(cleanup) - - newProvider := func() *goose.Provider { - - sessionLocker, err := lock.NewPostgresSessionLocker( - lock.WithLockTimeout(5, 60), // Timeout 5min. Try every 5s up to 60 times. - ) - check.NoError(t, err) - p, err := goose.NewProvider( - goose.DialectPostgres, - db, - os.DirFS("testdata/migrations"), - goose.WithSessionLocker(sessionLocker), // Use advisory session lock mode. - ) - check.NoError(t, err) - - return p - } - - provider1 := newProvider() - provider2 := newProvider() - - sources := provider1.ListSources() - maxVersion := sources[len(sources)-1].Version - - // Since the lock mode is advisory session, only one of these providers is expected to apply ALL - // the migrations. The other provider should apply NO migrations. The test MUST fail if both - // providers apply migrations. - - t.Run("up", func(t *testing.T) { - var g errgroup.Group - var res1, res2 int - g.Go(func() error { - ctx := context.Background() - results, err := provider1.Up(ctx) - check.NoError(t, err) - res1 = len(results) - currentVersion, err := provider1.GetDBVersion(ctx) - check.NoError(t, err) - check.Number(t, currentVersion, maxVersion) - return nil - }) - g.Go(func() error { - ctx := context.Background() - results, err := provider2.Up(ctx) - check.NoError(t, err) - res2 = len(results) - currentVersion, err := provider2.GetDBVersion(ctx) - check.NoError(t, err) - check.Number(t, currentVersion, maxVersion) - return nil - }) - check.NoError(t, g.Wait()) - // One of the providers should have applied all migrations and the other should have applied - // no migrations, but with no error. - if res1 == 0 && res2 == 0 { - t.Fatal("both providers applied no migrations") - } - if res1 > 0 && res2 > 0 { - t.Fatal("both providers applied migrations") - } - }) - - // Reset the database and run the same test with the advisory lock mode, but apply migrations - // one-by-one. - { - _, err := provider1.DownTo(context.Background(), 0) - check.NoError(t, err) - currentVersion, err := provider1.GetDBVersion(context.Background()) - check.NoError(t, err) - check.Number(t, currentVersion, 0) - } - t.Run("up_by_one", func(t *testing.T) { - var g errgroup.Group - var ( - mu sync.Mutex - applied []int64 - ) - g.Go(func() error { - for { - result, err := provider1.UpByOne(context.Background()) - if err != nil { - if errors.Is(err, goose.ErrNoNextVersion) { - return nil - } - return err - } - check.NoError(t, err) - check.Bool(t, result != nil, true) - mu.Lock() - applied = append(applied, result.Source.Version) - mu.Unlock() - } - }) - g.Go(func() error { - for { - result, err := provider2.UpByOne(context.Background()) - if err != nil { - if errors.Is(err, goose.ErrNoNextVersion) { - return nil - } - return err - } - check.NoError(t, err) - check.Bool(t, result != nil, true) - mu.Lock() - applied = append(applied, result.Source.Version) - mu.Unlock() - } - }) - check.NoError(t, g.Wait()) - check.Number(t, len(applied), len(sources)) - sort.Slice(applied, func(i, j int) bool { - return applied[i] < applied[j] - }) - // Each migration should have been applied up exactly once. - for i := 0; i < len(sources); i++ { - check.Number(t, applied[i], sources[i].Version) - } - }) - - // Restore the database state by applying all migrations and run the same test with the advisory - // lock mode, but apply down migrations in parallel. - { - _, err := provider1.Up(context.Background()) - check.NoError(t, err) - currentVersion, err := provider1.GetDBVersion(context.Background()) - check.NoError(t, err) - check.Number(t, currentVersion, maxVersion) - } - - t.Run("down_to", func(t *testing.T) { - var g errgroup.Group - var res1, res2 int - g.Go(func() error { - ctx := context.Background() - results, err := provider1.DownTo(ctx, 0) - check.NoError(t, err) - res1 = len(results) - currentVersion, err := provider1.GetDBVersion(ctx) - check.NoError(t, err) - check.Number(t, currentVersion, 0) - return nil - }) - g.Go(func() error { - ctx := context.Background() - results, err := provider2.DownTo(ctx, 0) - check.NoError(t, err) - res2 = len(results) - currentVersion, err := provider2.GetDBVersion(ctx) - check.NoError(t, err) - check.Number(t, currentVersion, 0) - return nil - }) - check.NoError(t, g.Wait()) - - if res1 == 0 && res2 == 0 { - t.Fatal("both providers applied no migrations") - } - if res1 > 0 && res2 > 0 { - t.Fatal("both providers applied migrations") - } - }) - - // Restore the database state by applying all migrations and run the same test with the advisory - // lock mode, but apply down migrations one-by-one. - { - _, err := provider1.Up(context.Background()) - check.NoError(t, err) - currentVersion, err := provider1.GetDBVersion(context.Background()) - check.NoError(t, err) - check.Number(t, currentVersion, maxVersion) - } - - t.Run("down_by_one", func(t *testing.T) { - var g errgroup.Group - var ( - mu sync.Mutex - applied []int64 - ) - g.Go(func() error { - for { - result, err := provider1.Down(context.Background()) - if err != nil { - if errors.Is(err, goose.ErrNoNextVersion) { - return nil - } - return err - } - check.NoError(t, err) - check.Bool(t, result != nil, true) - mu.Lock() - applied = append(applied, result.Source.Version) - mu.Unlock() - } - }) - g.Go(func() error { - for { - result, err := provider2.Down(context.Background()) - if err != nil { - if errors.Is(err, goose.ErrNoNextVersion) { - return nil - } - return err - } - check.NoError(t, err) - check.Bool(t, result != nil, true) - mu.Lock() - applied = append(applied, result.Source.Version) - mu.Unlock() - } - }) - check.NoError(t, g.Wait()) - check.Number(t, len(applied), len(sources)) - sort.Slice(applied, func(i, j int) bool { - return applied[i] < applied[j] - }) - // Each migration should have been applied down exactly once. Since this is sequential the - // applied down migrations should be in reverse order. - for i := len(sources) - 1; i >= 0; i-- { - check.Number(t, applied[i], sources[i].Version) - } - }) -} - func newDBFn(query string) func(context.Context, *sql.DB) error { return func(ctx context.Context, db *sql.DB) error { _, err := db.ExecContext(ctx, query) diff --git a/tests/clickhouse/clickhouse_test.go b/tests/clickhouse/clickhouse_test.go deleted file mode 100644 index 2ccfbe947..000000000 --- a/tests/clickhouse/clickhouse_test.go +++ /dev/null @@ -1,157 +0,0 @@ -package clickhouse_test - -import ( - "log" - "os" - "path/filepath" - "testing" - "time" - - "github.com/pressly/goose/v3" - "github.com/pressly/goose/v3/internal/check" - "github.com/pressly/goose/v3/internal/testdb" -) - -func TestMain(m *testing.M) { - if err := goose.SetDialect("clickhouse"); err != nil { - log.Fatal(err) - } - os.Exit(m.Run()) -} - -func TestClickUpDownAll(t *testing.T) { - t.Parallel() - - migrationDir := filepath.Join("testdata", "migrations") - db, cleanup, err := testdb.NewClickHouse() - check.NoError(t, err) - t.Cleanup(cleanup) - - /* - This test applies all up migrations, asserts we have all the entries in - the versions table, applies all down migration and asserts we have zero - migrations applied. - - ClickHouse performs UPDATES and DELETES asynchronously, - but we can best-effort check mutations and their progress. - - This is especially important for down migrations where rows are deleted - from the versions table. - - For the sake of testing, there might be a way to modifying the server - (or queries) to perform all operations synchronously? - - Ref: https://clickhouse.com/docs/en/operations/system-tables/mutations/ - Ref: https://clickhouse.com/docs/en/sql-reference/statements/alter/#mutations - Ref: https://clickhouse.com/blog/how-to-update-data-in-click-house/ - */ - - // Collect migrations so we don't have to hard-code the currentVersion - // in an assertion later in the test. - migrations, err := goose.CollectMigrations(migrationDir, 0, goose.MaxVersion) - check.NoError(t, err) - - currentVersion, err := goose.GetDBVersion(db) - check.NoError(t, err) - check.Number(t, currentVersion, 0) - - err = goose.Up(db, migrationDir) - check.NoError(t, err) - currentVersion, err = goose.GetDBVersion(db) - check.NoError(t, err) - check.Number(t, currentVersion, len(migrations)) - - err = goose.DownTo(db, migrationDir, 0) - check.NoError(t, err) - - currentVersion, err = goose.GetDBVersion(db) - check.NoError(t, err) - check.Number(t, currentVersion, 0) -} - -func TestClickHouseFirstThree(t *testing.T) { - t.Parallel() - - migrationDir := filepath.Join("testdata", "migrations") - db, cleanup, err := testdb.NewClickHouse() - check.NoError(t, err) - t.Cleanup(cleanup) - - err = goose.Up(db, migrationDir) - check.NoError(t, err) - - currentVersion, err := goose.GetDBVersion(db) - check.NoError(t, err) - check.Number(t, currentVersion, 3) - - type result struct { - customerID string `db:"customer_id"` - timestamp time.Time `db:"time_stamp"` - clickEventType string `db:"click_event_type"` - countryCode string `db:"country_code"` - sourceID int64 `db:"source_id"` - } - rows, err := db.Query(`SELECT * FROM clickstream ORDER BY customer_id`) - check.NoError(t, err) - var results []result - for rows.Next() { - var r result - err = rows.Scan(&r.customerID, &r.timestamp, &r.clickEventType, &r.countryCode, &r.sourceID) - check.NoError(t, err) - results = append(results, r) - } - check.Number(t, len(results), 3) - check.NoError(t, rows.Close()) - check.NoError(t, rows.Err()) - - parseTime := func(t *testing.T, s string) time.Time { - t.Helper() - tm, err := time.Parse("2006-01-02", s) - check.NoError(t, err) - return tm - } - want := []result{ - {"customer1", parseTime(t, "2021-10-02"), "add_to_cart", "US", 568239}, - {"customer2", parseTime(t, "2021-10-30"), "remove_from_cart", "", 0}, - {"customer3", parseTime(t, "2021-11-07"), "checkout", "", 307493}, - } - for i, result := range results { - check.Equal(t, result.customerID, want[i].customerID) - check.Equal(t, result.timestamp, want[i].timestamp) - check.Equal(t, result.clickEventType, want[i].clickEventType) - if result.countryCode != "" && want[i].countryCode != "" { - check.Equal(t, result.countryCode, want[i].countryCode) - } - check.Number(t, result.sourceID, want[i].sourceID) - } -} - -func TestRemoteImportMigration(t *testing.T) { - t.Parallel() - // TODO(mf): use TestMain and create a proper "long" or "remote" flag. - if !testing.Short() { - t.Skip("skipping test") - } - // This test is using a remote dataset from an s3 bucket: - // https://datasets-documentation.s3.eu-west-3.amazonaws.com/nyc-taxi/taxi_zone_lookup.csv - // From this tutorial: https://clickhouse.com/docs/en/tutorial/ - // Note, these files are backed up in this repository in: - // tests/clickhouse/testdata/backup-files/taxi_zone_lookup.csv - // We may want to host this ourselves. Or just don't bother with SOURCE(HTTP(URL.. - // and craft a long INSERT statement. - - migrationDir := filepath.Join("testdata", "migrations-remote") - db, cleanup, err := testdb.NewClickHouse() - check.NoError(t, err) - t.Cleanup(cleanup) - - err = goose.Up(db, migrationDir) - check.NoError(t, err) - _, err = goose.GetDBVersion(db) - check.NoError(t, err) - - var count int - err = db.QueryRow(`SELECT count(*) FROM taxi_zone_dictionary`).Scan(&count) - check.NoError(t, err) - check.Number(t, count, 265) -} diff --git a/tests/e2e/allow_missing_test.go b/tests/e2e/allow_missing_test.go deleted file mode 100644 index 26c24f58d..000000000 --- a/tests/e2e/allow_missing_test.go +++ /dev/null @@ -1,380 +0,0 @@ -package e2e - -import ( - "database/sql" - "testing" - - "github.com/pressly/goose/v3" - "github.com/pressly/goose/v3/internal/check" -) - -func TestNotAllowMissing(t *testing.T) { - t.Parallel() - - // Create and apply first 5 migrations. - db := setupTestDB(t, 5) - - // Developer A and B check out the "main" branch which is currently - // on version 5. Developer A mistakenly creates migration 7 and commits. - // Developer B did not pull the latest changes and commits migration 6. Oops. - - // Developer A - migration 7 (mistakenly applied) - migrations, err := goose.CollectMigrations(migrationsDir, 0, 7) - check.NoError(t, err) - err = migrations[6].Up(db) - check.NoError(t, err) - current, err := goose.GetDBVersion(db) - check.NoError(t, err) - check.Number(t, current, 7) - - // Developer B - migration 6 (missing) and 8 (new) - // This should raise an error. By default goose does not allow missing (out-of-order) - // migrations, which means halt if a missing migration is detected. - err = goose.Up(db, migrationsDir) - check.HasError(t, err) - check.Contains(t, err.Error(), "missing migrations") - // Confirm db version is unchanged. - current, err = goose.GetDBVersion(db) - check.NoError(t, err) - check.Number(t, current, 7) -} - -func TestAllowMissingUpWithRedo(t *testing.T) { - t.Parallel() - - // Create and apply first 5 migrations. - db := setupTestDB(t, 5) - - migrations, err := goose.CollectMigrations(migrationsDir, 0, goose.MaxVersion) - check.NoError(t, err) - if len(migrations) == 0 { - t.Fatalf("got zero migrations") - } - - // Migration 7 - { - migrations, err := goose.CollectMigrations(migrationsDir, 0, 7) - check.NoError(t, err) - err = migrations[6].Up(db) - check.NoError(t, err) - current, err := goose.GetDBVersion(db) - check.NoError(t, err) - check.Number(t, current, 7) - - // Redo the previous Up migration and re-apply it. - err = goose.Redo(db, migrationsDir) - check.NoError(t, err) - currentVersion, err := goose.GetDBVersion(db) - check.NoError(t, err) - check.Number(t, currentVersion, migrations[6].Version) - } - // Migration 6 - { - err = goose.UpByOne(db, migrationsDir, goose.WithAllowMissing()) - check.NoError(t, err) - currentVersion, err := goose.GetDBVersion(db) - check.NoError(t, err) - check.Number(t, currentVersion, 6) - - err = goose.Redo(db, migrationsDir) - check.NoError(t, err) - currentVersion, err = goose.GetDBVersion(db) - check.NoError(t, err) - check.Number(t, currentVersion, 6) - } -} - -func TestNowAllowMissingUpByOne(t *testing.T) { - t.Parallel() - - // Create and apply first 5 migrations. - db := setupTestDB(t, 5) - - /* - Developer A and B simultaneously check out the "main" currently on version 5. - Developer A mistakenly creates migration 7 and commits. - Developer B did not pull the latest changes and commits migration 6. Oops. - - If goose is set to allow missing migrations, then 6 should be applied - after 7. - */ - - // Developer A - migration 7 (mistakenly applied) - { - migrations, err := goose.CollectMigrations(migrationsDir, 0, 7) - check.NoError(t, err) - err = migrations[6].Up(db) - check.NoError(t, err) - current, err := goose.GetDBVersion(db) - check.NoError(t, err) - check.Number(t, current, 7) - } - // Developer B - migration 6 - { - // By default, this should raise an error. - err := goose.UpByOne(db, migrationsDir) - // error: found 1 missing migrations - check.HasError(t, err) - check.Contains(t, err.Error(), "missing migrations") - - count, err := getGooseVersionCount(db, goose.TableName()) - check.NoError(t, err) - check.Number(t, count, 6) - - current, err := goose.GetDBVersion(db) - check.NoError(t, err) - // Expecting max(version_id) to be 7 - check.Number(t, current, 7) - } -} - -func TestAllowMissingUpWithReset(t *testing.T) { - t.Parallel() - - // Create and apply first 5 migrations. - db := setupTestDB(t, 5) - - /* - Developer A and B simultaneously check out the "main" currently on version 5. - Developer A mistakenly creates migration 7 and commits. - Developer B did not pull the latest changes and commits migration 6. Oops. - - If goose is set to allow missing migrations, then 6 should be applied - after 7. - */ - - // Developer A - migration 7 (mistakenly applied) - { - migrations, err := goose.CollectMigrations(migrationsDir, 0, 7) - check.NoError(t, err) - err = migrations[6].Up(db) - check.NoError(t, err) - current, err := goose.GetDBVersion(db) - check.NoError(t, err) - check.Number(t, current, 7) - } - // Developer B - migration 6 (missing) and 8 (new) - { - // By default, attempting to apply this migration will raise an error. - // If goose is set to "allow missing" migrations then it should get applied. - err := goose.Up(db, migrationsDir, goose.WithAllowMissing()) - // Applying missing migration should return no error when allow-missing=true - check.NoError(t, err) - - // Avoid hard-coding total and max, instead resolve it from the testdata migrations. - // In other words, we applied 1..5,7,6,8 and this test shouldn't care - // about migration 9 and onwards. - allMigrations, err := goose.CollectMigrations(migrationsDir, 0, goose.MaxVersion) - check.NoError(t, err) - maxVersionID := allMigrations[len(allMigrations)-1].Version - - count, err := getGooseVersionCount(db, goose.TableName()) - check.NoError(t, err) - // Count should be all testdata migrations (all applied) - check.Number(t, count, len(allMigrations)) - - current, err := goose.GetDBVersion(db) - check.NoError(t, err) - // Expecting max(version_id) to be highest version in testdata - check.Number(t, current, maxVersionID) - } - - // Migrate everything down using Reset. - err := goose.Reset(db, migrationsDir) - check.NoError(t, err) - currentVersion, err := goose.GetDBVersion(db) - check.NoError(t, err) - check.Number(t, currentVersion, 0) -} - -func TestAllowMissingUpByOne(t *testing.T) { - t.Parallel() - - // Create and apply first 5 migrations. - db := setupTestDB(t, 5) - - /* - Developer A and B simultaneously check out the "main" currently on version 5. - Developer A mistakenly creates migration 7 and commits. - Developer B did not pull the latest changes and commits migration 6. Oops. - - If goose is set to allow missing migrations, then 6 should be applied - after 7. - */ - - // Developer A - migration 7 (mistakenly applied) - { - migrations, err := goose.CollectMigrations(migrationsDir, 0, 7) - check.NoError(t, err) - err = migrations[6].Up(db) - check.NoError(t, err) - current, err := goose.GetDBVersion(db) - check.NoError(t, err) - check.Number(t, current, 7) - } - // Developer B - migration 6 - { - err := goose.UpByOne(db, migrationsDir, goose.WithAllowMissing()) - check.NoError(t, err) - - count, err := getGooseVersionCount(db, goose.TableName()) - check.NoError(t, err) - // Expecting count of migrations to be 7 - check.Number(t, count, 7) - - current, err := goose.GetDBVersion(db) - check.NoError(t, err) - // Expecting max(version_id) to be 6 - check.Number(t, current, 6) - } - // Developer B - migration 8 - { - // By default, this should raise an error. - err := goose.UpByOne(db, migrationsDir, goose.WithAllowMissing()) - check.NoError(t, err) - - count, err := getGooseVersionCount(db, goose.TableName()) - check.NoError(t, err) - // Expecting count of migrations to be 8 - check.Number(t, count, 8) - - current, err := goose.GetDBVersion(db) - check.NoError(t, err) - // Expecting max(version_id) to be 8 - check.Number(t, current, 8) - } -} - -func TestMigrateAllowMissingDown(t *testing.T) { - t.Parallel() - - const ( - maxVersion = 8 - ) - // Create and apply first 5 migrations. - db := setupTestDB(t, 5) - - // Developer A - migration 7 (mistakenly applied) - { - migrations, err := goose.CollectMigrations(migrationsDir, 0, maxVersion-1) - check.NoError(t, err) - err = migrations[6].Up(db) - check.NoError(t, err) - current, err := goose.GetDBVersion(db) - check.NoError(t, err) - check.Number(t, current, maxVersion-1) - } - // Developer B - migration 6 (missing) and 8 (new) - { - // 6 - err := goose.UpByOne(db, migrationsDir, goose.WithAllowMissing()) - check.NoError(t, err) - // 8 - err = goose.UpByOne(db, migrationsDir, goose.WithAllowMissing()) - check.NoError(t, err) - - count, err := getGooseVersionCount(db, goose.TableName()) - check.NoError(t, err) - check.Number(t, count, maxVersion) - current, err := goose.GetDBVersion(db) - check.NoError(t, err) - // Expecting max(version_id) to be 8 - check.Number(t, current, maxVersion) - } - // The order in the database is expected to be: - // 1,2,3,4,5,7,6,8 - // So migrating down should be the reverse order: - // 8,6,7,5,4,3,2,1 - // - // Migrate down by one. Expecting 6. - { - err := goose.Down(db, migrationsDir) - check.NoError(t, err) - current, err := goose.GetDBVersion(db) - check.NoError(t, err) - // Expecting max(version) to be 6 - check.Number(t, current, 6) - } - // Migrate down by one. Expecting 7. - { - err := goose.Down(db, migrationsDir) - check.NoError(t, err) - current, err := goose.GetDBVersion(db) - check.NoError(t, err) - // Expecting max(version) to be 7 - check.Number(t, current, 7) - } - // Migrate down by one. Expecting 5. - { - err := goose.Down(db, migrationsDir) - check.NoError(t, err) - current, err := goose.GetDBVersion(db) - check.NoError(t, err) - // Expecting max(version) to be 5 - check.Number(t, current, 5) - } -} - -func TestWithWithoutAllowMissing(t *testing.T) { - // Test for https://github.com/pressly/goose/issues/521 - - // Apply 1,2,4,3 then run up without allow missing. If the next requested migration is - // 4 then it should not raise an error because it has already been applied. - // If goose attempts to apply 4 again then it will raise an error (SQLSTATE 42701) because it - // has already been applied. Specifically it will raise a error. - db := setupTestDB(t, 2) - - migrations, err := goose.CollectMigrations(migrationsDir, 0, 4) - check.NoError(t, err) - err = migrations[3].Up(db) // version 4 - check.NoError(t, err) - err = migrations[2].Up(db) // version 3 - check.NoError(t, err) - - err = goose.UpTo(db, migrationsDir, 4) - check.NoError(t, err) - err = goose.UpTo(db, migrationsDir, 4, goose.WithAllowMissing()) - check.NoError(t, err) - - // Rollback migration 3 because it is the last applied migration. - // But, we want to change this behaviour to apply rollback migration 4. - // See these issues for more details: - // https://github.com/pressly/goose/issues/523 - // https://github.com/pressly/goose/issues/402 - // - // Adding this test to ensure the behaviour is updated and captured in a test. - err = goose.Down(db, migrationsDir) - check.NoError(t, err) - - version, err := goose.GetDBVersion(db) - check.NoError(t, err) - check.Number(t, version, 4) -} - -// setupTestDB is helper to setup a DB and apply migrations -// up to the specified version. -func setupTestDB(t *testing.T, version int64) *sql.DB { - db, err := newDockerDB(t) - check.NoError(t, err) - - // Create goose table. - current, err := goose.EnsureDBVersion(db) - check.NoError(t, err) - check.Number(t, current, 0) - // Collect first 5 migrations. - migrations, err := goose.CollectMigrations(migrationsDir, 0, version) - check.NoError(t, err) - check.Number(t, len(migrations), version) - // Apply n migrations manually. - for _, m := range migrations { - err := m.Up(db) - check.NoError(t, err) - } - // Verify the current DB version is the Nth migration. This will only - // work for sqeuentially applied migrations. - current, err = goose.GetDBVersion(db) - check.NoError(t, err) - check.Number(t, current, version) - - return db -} diff --git a/tests/e2e/main_test.go b/tests/e2e/main_test.go deleted file mode 100644 index 22c1a97e9..000000000 --- a/tests/e2e/main_test.go +++ /dev/null @@ -1,126 +0,0 @@ -package e2e - -import ( - "database/sql" - "flag" - "fmt" - "log" - "os" - "os/signal" - "path/filepath" - "syscall" - "testing" - - "github.com/pressly/goose/v3" - "github.com/pressly/goose/v3/internal/check" - "github.com/pressly/goose/v3/internal/testdb" -) - -const ( - dialectPostgres = "postgres" - dialectMySQL = "mysql" - dialectYdb = "ydb" - dialectTurso = "turso" -) - -// Flags. -var ( - debug = flag.Bool( - "debug", - false, - "Debug traps the test suite: useful for debugging running containers", - ) - dialect = flag.String( - "dialect", - dialectPostgres, - "Dialect defines which docker container to run tests against (default: postgres)", - ) - // bindPort is useful if you want to pin a database port instead of relying - // on the randomly assigned one from Docker. It is mainly used for debugging - // locally and will normally be set to 0. - bindPort = flag.Int( - "port", - 0, - "Port is an optional bind port. Left empty will let Docker assign a random port (recommended)", - ) -) - -var ( - // migrationsDir is a global that points to a ./testdata/{dialect}/migrations folder. - // It is set in TestMain based on the current dialect. - migrationsDir = "" - // seedDir is similar to migrationsDir but contains seed data - seedDir = "" - - // known tables are the tables (including goose table) created by - // running all migration files. If you add a table, make sure to - // add to this list and keep it in order. - knownTables = []string{ - "goose_db_version", - "issues", - "owners", - "repos", - "stargazers", - } -) - -func TestMain(m *testing.M) { - flag.Parse() - - switch *dialect { - case dialectPostgres, dialectMySQL, dialectYdb, dialectTurso: - default: - log.Printf("dialect not supported: %q", *dialect) - os.Exit(1) - } - migrationsDir = filepath.Join("testdata", *dialect, "migrations") - seedDir = filepath.Join("testdata", *dialect, "seed") - - if err := goose.SetDialect(*dialect); err != nil { - log.Printf("failed to set dialect %q: %v\n", *dialect, err) - os.Exit(1) - } - - exitCode := m.Run() - // Useful for debugging test services. - if *debug { - sigs := make(chan os.Signal, 1) - done := make(chan bool, 1) - signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM) - go func() { - <-sigs - done <- true - }() - log.Printf("entering debug mode: must exit (CTRL+C) and cleanup containers manually. Exit code: %d)", exitCode) - <-done - } - os.Exit(exitCode) -} - -// newDockerDB starts a database container and returns a usable SQL connection. -func newDockerDB(t *testing.T) (*sql.DB, error) { - options := []testdb.OptionsFunc{ - testdb.WithBindPort(*bindPort), - testdb.WithDebug(*debug), - } - var ( - db *sql.DB - cleanup func() - err error - ) - switch *dialect { - case dialectPostgres: - db, cleanup, err = testdb.NewPostgres(options...) - case dialectMySQL: - db, cleanup, err = testdb.NewMariaDB(options...) - case dialectYdb: - db, cleanup, err = testdb.NewYdb(options...) - case dialectTurso: - db, cleanup, err = testdb.NewTurso(options...) - default: - return nil, fmt.Errorf("unsupported dialect: %q", *dialect) - } - check.NoError(t, err) - t.Cleanup(cleanup) - return db, nil -} diff --git a/tests/e2e/migrations_test.go b/tests/e2e/migrations_test.go deleted file mode 100644 index f013cbf30..000000000 --- a/tests/e2e/migrations_test.go +++ /dev/null @@ -1,373 +0,0 @@ -package e2e - -import ( - "context" - "database/sql" - "errors" - "fmt" - "os" - "path/filepath" - "reflect" - "testing" - "time" - - "github.com/pressly/goose/v3" - "github.com/pressly/goose/v3/internal/check" -) - -func TestMigrateUpWithReset(t *testing.T) { - t.Parallel() - - db, err := newDockerDB(t) - check.NoError(t, err) - migrations, err := goose.CollectMigrations(migrationsDir, 0, goose.MaxVersion) - check.NoError(t, err) - check.NumberNotZero(t, len(migrations)) - // Migrate all - err = goose.Up(db, migrationsDir) - check.NoError(t, err) - currentVersion, err := goose.GetDBVersion(db) - check.NoError(t, err) - check.Number(t, currentVersion, migrations[len(migrations)-1].Version) - // Validate the db migration version actually matches what goose claims it is - gotVersion, err := getCurrentGooseVersion(db, goose.TableName()) - check.NoError(t, err) - // incorrect database version - check.Number(t, gotVersion, currentVersion) - - // Migrate everything down using Reset. - err = goose.Reset(db, migrationsDir) - check.NoError(t, err) - currentVersion, err = goose.GetDBVersion(db) - check.NoError(t, err) - check.Number(t, currentVersion, 0) -} - -func TestMigrateUpWithRedo(t *testing.T) { - t.Parallel() - - db, err := newDockerDB(t) - check.NoError(t, err) - migrations, err := goose.CollectMigrations(migrationsDir, 0, goose.MaxVersion) - check.NoError(t, err) - - check.NumberNotZero(t, len(migrations)) - startingVersion, err := goose.EnsureDBVersion(db) - check.NoError(t, err) - check.Number(t, startingVersion, 0) - // Migrate all - for _, migration := range migrations { - err = migration.Up(db) - check.NoError(t, err) - currentVersion, err := goose.GetDBVersion(db) - check.NoError(t, err) - check.Number(t, currentVersion, migration.Version) - - // Redo the previous Up migration and re-apply it. - err = goose.Redo(db, migrationsDir) - check.NoError(t, err) - currentVersion, err = goose.GetDBVersion(db) - check.NoError(t, err) - check.Number(t, currentVersion, migration.Version) - } - // Once everything is tested the version should match the highest testdata version - maxVersion := migrations[len(migrations)-1].Version - currentVersion, err := goose.GetDBVersion(db) - check.NoError(t, err) - check.Number(t, currentVersion, maxVersion) -} - -func TestMigrateUpTo(t *testing.T) { - t.Parallel() - - const ( - upToVersion int64 = 2 - ) - db, err := newDockerDB(t) - check.NoError(t, err) - migrations, err := goose.CollectMigrations(migrationsDir, 0, goose.MaxVersion) - check.NoError(t, err) - check.NumberNotZero(t, len(migrations)) - // Migrate up to the second migration - err = goose.UpTo(db, migrationsDir, upToVersion) - check.NoError(t, err) - // Fetch the goose version from DB - currentVersion, err := goose.GetDBVersion(db) - check.NoError(t, err) - check.Number(t, currentVersion, upToVersion) - // Validate the version actually matches what goose claims it is - gotVersion, err := getCurrentGooseVersion(db, goose.TableName()) - check.NoError(t, err) - check.Number(t, gotVersion, upToVersion) // incorrect database version -} - -func writeFile(t *testing.T, dir, name, content string) { - t.Helper() - if err := os.WriteFile(filepath.Join(dir, name), []byte(content), 0644); err != nil { - t.Fatalf("failed to write file %q: %v", name, err) - } -} - -func TestMigrateUpTimeout(t *testing.T) { - t.Parallel() - if *dialect != dialectPostgres { - t.Skipf("skipping test for dialect: %q", *dialect) - } - - dir := t.TempDir() - writeFile(t, dir, "00001_a.sql", ` --- +goose Up -SELECT 1; -`) - writeFile(t, dir, "00002_a.sql", ` --- +goose Up -SELECT pg_sleep(10); -`) - db, err := newDockerDB(t) - check.NoError(t, err) - // Simulate timeout midway through a set of migrations. This should leave the - // database in a state where it has applied some migrations, but not all. - ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second) - defer cancel() - migrations, err := goose.CollectMigrations(dir, 0, goose.MaxVersion) - check.NoError(t, err) - check.NumberNotZero(t, len(migrations)) - // Apply all migrations. - err = goose.UpContext(ctx, db, dir) - check.HasError(t, err) // expect it to timeout. - check.Bool(t, errors.Is(err, context.DeadlineExceeded), true) - - currentVersion, err := goose.GetDBVersion(db) - check.NoError(t, err) - check.Number(t, currentVersion, 1) - // Validate the db migration version actually matches what goose claims it is - gotVersion, err := getCurrentGooseVersion(db, goose.TableName()) - check.NoError(t, err) - check.Number(t, gotVersion, 1) -} - -func TestMigrateDownTimeout(t *testing.T) { - t.Parallel() - if *dialect != dialectPostgres { - t.Skipf("skipping test for dialect: %q", *dialect) - } - dir := t.TempDir() - writeFile(t, dir, "00001_a.sql", ` --- +goose Up -SELECT 1; --- +goose Down -SELECT pg_sleep(10); -`) - writeFile(t, dir, "00002_a.sql", ` --- +goose Up -SELECT 1; -`) - db, err := newDockerDB(t) - check.NoError(t, err) - // Simulate timeout midway through a set of migrations. This should leave the - // database in a state where it has applied some migrations, but not all. - ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second) - defer cancel() - migrations, err := goose.CollectMigrations(dir, 0, goose.MaxVersion) - check.NoError(t, err) - check.NumberNotZero(t, len(migrations)) - // Apply all up migrations. - err = goose.UpContext(ctx, db, dir) - check.NoError(t, err) - // Applly all down migrations. - err = goose.DownToContext(ctx, db, dir, 0) - check.HasError(t, err) // expect it to timeout. - check.Bool(t, errors.Is(err, context.DeadlineExceeded), true) - - currentVersion, err := goose.GetDBVersion(db) - check.NoError(t, err) - check.Number(t, currentVersion, 1) - // Validate the db migration version actually matches what goose claims it is - gotVersion, err := getCurrentGooseVersion(db, goose.TableName()) - check.NoError(t, err) - check.Number(t, gotVersion, 1) -} - -func TestMigrateUpByOne(t *testing.T) { - t.Parallel() - - db, err := newDockerDB(t) - check.NoError(t, err) - migrations, err := goose.CollectMigrations(migrationsDir, 0, goose.MaxVersion) - check.NoError(t, err) - check.NumberNotZero(t, len(migrations)) - // Apply all migrations one-by-one. - var counter int - for { - err := goose.UpByOne(db, migrationsDir) - counter++ - if counter > len(migrations) { - if !errors.Is(err, goose.ErrNoNextVersion) { - t.Fatalf("incorrect error: got:%v want:%v", err, goose.ErrNoNextVersion) - } - break - } - check.NoError(t, err) - } - currentVersion, err := goose.GetDBVersion(db) - check.NoError(t, err) - check.Number(t, currentVersion, migrations[len(migrations)-1].Version) - // Validate the db migration version actually matches what goose claims it is - gotVersion, err := getCurrentGooseVersion(db, goose.TableName()) - check.NoError(t, err) - check.Number(t, gotVersion, currentVersion) // incorrect database version -} - -func TestMigrateFull(t *testing.T) { - t.Parallel() - - db, err := newDockerDB(t) - check.NoError(t, err) - migrations, err := goose.CollectMigrations(migrationsDir, 0, goose.MaxVersion) - check.NoError(t, err) - check.NumberNotZero(t, len(migrations)) - // test retrieving invalid current goose migrations. goose cannot return a migration - // if the supplied "current" version is non-existent or 0. - _, err = migrations.Current(20160813) - if !errors.Is(err, goose.ErrNoCurrentVersion) { - t.Fatalf("incorrect error: got:%v want:%v", err, goose.ErrNoCurrentVersion) - } - _, err = migrations.Current(0) - if !errors.Is(err, goose.ErrNoCurrentVersion) { - t.Fatalf("incorrect error: got:%v want:%v", err, goose.ErrNoCurrentVersion) - } - // verify the first migration1. This should not change if more migrations are added - // in the future. - migration1, err := migrations.Current(1) - check.NoError(t, err) - check.Number(t, migration1.Version, 1) - if migration1.Source != filepath.Join(migrationsDir, "00001_a.sql") { - t.Fatalf("failed to get correct migration file:\ngot:%s\nwant:%s", - migration1.Source, - filepath.Join(migrationsDir, "00001_a.sql"), - ) - } - // expecting false for .sql migrations - check.Bool(t, migration1.Registered, false) - check.Number(t, migration1.Previous, -1) - check.Number(t, migration1.Next, 2) - - { - // Apply all up migrations - err = goose.Up(db, migrationsDir) - check.NoError(t, err) - currentVersion, err := goose.GetDBVersion(db) - check.NoError(t, err) - check.Number(t, currentVersion, migrations[len(migrations)-1].Version) - // Validate the db migration version actually matches what goose claims it is - gotVersion, err := getCurrentGooseVersion(db, goose.TableName()) - check.NoError(t, err) - check.Number(t, gotVersion, currentVersion) // incorrect database version - tables, err := getTableNames(db) - check.NoError(t, err) - if !reflect.DeepEqual(tables, knownTables) { - t.Logf("got tables: %v", tables) - t.Logf("known tables: %v", knownTables) - t.Fatal("failed to match tables") - } - } - { - // Apply 1 down migration - err := goose.Down(db, migrationsDir) - check.NoError(t, err) - gotVersion, err := getCurrentGooseVersion(db, goose.TableName()) - check.NoError(t, err) - check.Number(t, gotVersion, migrations[len(migrations)-1].Version-1) // incorrect database version - } - { - // Migrate all remaining migrations down. Should only be left with a single table: - // the default goose table - err := goose.DownTo(db, migrationsDir, 0) - check.NoError(t, err) - gotVersion, err := getCurrentGooseVersion(db, goose.TableName()) - check.NoError(t, err) - check.Number(t, gotVersion, 0) - tables, err := getTableNames(db) - check.NoError(t, err) - knownTables := []string{goose.TableName()} - if !reflect.DeepEqual(tables, knownTables) { - t.Logf("got tables: %v", tables) - t.Logf("known tables: %v", knownTables) - t.Fatal("failed to match tables") - } - } -} - -func getCurrentGooseVersion(db *sql.DB, gooseTable string) (int64, error) { - var gotVersion int64 - if err := db.QueryRow( - fmt.Sprintf("select max(version_id) from %s", gooseTable), - ).Scan(&gotVersion); err != nil { - return 0, err - } - return gotVersion, nil -} - -func getGooseVersionCount(db *sql.DB, gooseTable string) (int64, error) { - var gotVersion int64 - if err := db.QueryRow( - fmt.Sprintf("SELECT count(*) FROM %s WHERE version_id > 0", gooseTable), - ).Scan(&gotVersion); err != nil { - return 0, err - } - return gotVersion, nil -} - -func getTableNamesThroughQuery(db *sql.DB, query string) ([]string, error) { - rows, err := db.Query(query) - if err != nil { - return nil, err - } - defer rows.Close() - var tableNames []string - for rows.Next() { - var name string - if err := rows.Scan(&name); err != nil { - return nil, err - } - tableNames = append(tableNames, name) - } - return tableNames, nil -} - -func getTableNames(db *sql.DB) (tableNames []string, _ error) { - switch *dialect { - case dialectPostgres: - return getTableNamesThroughQuery(db, - `SELECT table_name FROM information_schema.tables WHERE table_schema='public' ORDER BY table_name`, - ) - case dialectMySQL: - return getTableNamesThroughQuery(db, - `SELECT table_name FROM INFORMATION_SCHEMA.tables WHERE TABLE_TYPE='BASE TABLE' ORDER BY table_name`, - ) - case dialectYdb: - conn, err := db.Conn(context.Background()) - if err != nil { - return nil, err - } - if err = conn.Raw(func(rawConn any) error { - if tables, has := rawConn.(interface { - GetTables(ctx context.Context, folder string, recursive bool, excludeSysDirs bool) (tables []string, err error) - }); has { - tableNames, err = tables.GetTables(context.Background(), ".", true, true) - if err != nil { - return err - } - return nil - } - return fmt.Errorf("%T not implemented GetTables interface", rawConn) - }); err != nil { - return nil, err - } - return tableNames, nil - case dialectTurso: - return getTableNamesThroughQuery(db, `SELECT NAME FROM sqlite_master where type='table' and name!='sqlite_sequence' ORDER BY NAME;`) - default: - return nil, fmt.Errorf("getTableNames not supported with dialect %q", *dialect) - } -} diff --git a/tests/e2e/no_versioning_test.go b/tests/e2e/no_versioning_test.go deleted file mode 100644 index dc0c5d8dd..000000000 --- a/tests/e2e/no_versioning_test.go +++ /dev/null @@ -1,149 +0,0 @@ -package e2e - -import ( - "database/sql" - "testing" - - "github.com/pressly/goose/v3" - "github.com/pressly/goose/v3/internal/check" -) - -func TestNoVersioning(t *testing.T) { - if *dialect != dialectPostgres { - t.SkipNow() - } - const ( - // Total owners created by the seed files. - wantSeedOwnerCount = 250 - // These are owners created by migration files. - wantOwnerCount = 4 - ) - db, err := newDockerDB(t) - check.NoError(t, err) - - err = goose.Up(db, migrationsDir) - check.NoError(t, err) - baseVersion, err := goose.GetDBVersion(db) - check.NoError(t, err) - - t.Run("seed-up-down-to-zero", func(t *testing.T) { - // Run (all) up migrations from the seed dir - { - err = goose.Up(db, seedDir, goose.WithNoVersioning()) - check.NoError(t, err) - // Confirm no changes to the versioned schema in the DB - currentVersion, err := goose.GetDBVersion(db) - check.NoError(t, err) - check.Number(t, baseVersion, currentVersion) - seedOwnerCount, err := countSeedOwners(db) - check.NoError(t, err) - check.Number(t, seedOwnerCount, wantSeedOwnerCount) - } - - // Run (all) down migrations from the seed dir - { - err = goose.DownTo(db, seedDir, 0, goose.WithNoVersioning()) - check.NoError(t, err) - // Confirm no changes to the versioned schema in the DB - currentVersion, err := goose.GetDBVersion(db) - check.NoError(t, err) - check.Number(t, baseVersion, currentVersion) - seedOwnerCount, err := countSeedOwners(db) - check.NoError(t, err) - check.Number(t, seedOwnerCount, 0) - } - - // The migrations added 4 non-seed owners, they must remain - // in the database afterwards - ownerCount, err := countOwners(db) - check.NoError(t, err) - check.Number(t, ownerCount, wantOwnerCount) - }) - - t.Run("test-seed-up-reset", func(t *testing.T) { - // Run (all) up migrations from the seed dir - { - err = goose.Up(db, seedDir, goose.WithNoVersioning()) - check.NoError(t, err) - // Confirm no changes to the versioned schema in the DB - currentVersion, err := goose.GetDBVersion(db) - check.NoError(t, err) - check.Number(t, baseVersion, currentVersion) - seedOwnerCount, err := countSeedOwners(db) - check.NoError(t, err) - check.Number(t, seedOwnerCount, wantSeedOwnerCount) - } - - // Run reset (effectively the same as down-to 0) - { - err = goose.Reset(db, seedDir, goose.WithNoVersioning()) - check.NoError(t, err) - // Confirm no changes to the versioned schema in the DB - currentVersion, err := goose.GetDBVersion(db) - check.NoError(t, err) - check.Number(t, baseVersion, currentVersion) - seedOwnerCount, err := countSeedOwners(db) - check.NoError(t, err) - check.Number(t, seedOwnerCount, 0) - } - - // The migrations added 4 non-seed owners, they must remain - // in the database afterwards - ownerCount, err := countOwners(db) - check.NoError(t, err) - check.Number(t, ownerCount, wantOwnerCount) - }) - - t.Run("test-seed-up-redo", func(t *testing.T) { - // Run (all) up migrations from the seed dir - { - err = goose.Up(db, seedDir, goose.WithNoVersioning()) - check.NoError(t, err) - // Confirm no changes to the versioned schema in the DB - currentVersion, err := goose.GetDBVersion(db) - check.NoError(t, err) - check.Number(t, baseVersion, currentVersion) - seedOwnerCount, err := countSeedOwners(db) - check.NoError(t, err) - check.Number(t, seedOwnerCount, wantSeedOwnerCount) - } - - // Run reset (effectively the same as down-to 0) - { - err = goose.Redo(db, seedDir, goose.WithNoVersioning()) - check.NoError(t, err) - // Confirm no changes to the versioned schema in the DB - currentVersion, err := goose.GetDBVersion(db) - check.NoError(t, err) - check.Number(t, baseVersion, currentVersion) - seedOwnerCount, err := countSeedOwners(db) - check.NoError(t, err) - check.Number(t, seedOwnerCount, wantSeedOwnerCount) // owners should be unchanged - } - - // The migrations added 4 non-seed owners, they must remain - // in the database afterwards along with the 250 seed owners for a - // total of 254. - ownerCount, err := countOwners(db) - check.NoError(t, err) - check.Number(t, ownerCount, wantOwnerCount+wantSeedOwnerCount) - }) -} - -func countSeedOwners(db *sql.DB) (int, error) { - q := `SELECT count(*)FROM owners WHERE owner_name LIKE'seed-user-%'` - var count int - if err := db.QueryRow(q).Scan(&count); err != nil { - return 0, err - } - return count, nil -} - -func countOwners(db *sql.DB) (int, error) { - q := `SELECT count(*)FROM owners` - var count int - if err := db.QueryRow(q).Scan(&count); err != nil { - return 0, err - } - return count, nil -} diff --git a/tests/e2e/testdata/mysql/migrations/00001_a.sql b/tests/e2e/testdata/mysql/migrations/00001_a.sql deleted file mode 100644 index 007b73f75..000000000 --- a/tests/e2e/testdata/mysql/migrations/00001_a.sql +++ /dev/null @@ -1,20 +0,0 @@ --- +goose Up --- +goose StatementBegin -CREATE TABLE owners ( - owner_id BIGINT PRIMARY KEY AUTO_INCREMENT, - owner_name varchar(255) NOT NULL, - owner_type ENUM('user', 'organization') NOT NULL -); -CREATE TABLE repos ( - repo_id BIGINT PRIMARY KEY AUTO_INCREMENT, - repo_owner_id BIGINT NOT NULL, - repo_full_name VARCHAR(255) NOT NULL, - FOREIGN KEY (repo_owner_id) REFERENCES owners (owner_id) ON DELETE CASCADE -); --- +goose StatementEnd - --- +goose Down --- +goose StatementBegin -DROP TABLE IF EXISTS repos; -DROP TABLE IF EXISTS owners; --- +goose StatementEnd \ No newline at end of file diff --git a/tests/e2e/testdata/mysql/migrations/00002_b.sql b/tests/e2e/testdata/mysql/migrations/00002_b.sql deleted file mode 100644 index 8f8dca03c..000000000 --- a/tests/e2e/testdata/mysql/migrations/00002_b.sql +++ /dev/null @@ -1,10 +0,0 @@ --- +goose Up --- +goose StatementBegin -INSERT INTO owners(owner_name, owner_type) - VALUES ('lucas', 'user'), ('space', 'organization'); --- +goose StatementEnd - --- +goose Down --- +goose StatementBegin -DELETE FROM owners; --- +goose StatementEnd diff --git a/tests/e2e/testdata/mysql/migrations/00003_c.sql b/tests/e2e/testdata/mysql/migrations/00003_c.sql deleted file mode 100644 index b93a85426..000000000 --- a/tests/e2e/testdata/mysql/migrations/00003_c.sql +++ /dev/null @@ -1,13 +0,0 @@ --- +goose Up --- +goose StatementBegin -INSERT INTO owners(owner_name, owner_type) - VALUES ('james', 'user'), ('pressly', 'organization'); - -INSERT INTO repos(repo_full_name, repo_owner_id) - VALUES ('james/rover', 3), ('pressly/goose', 4); --- +goose StatementEnd - --- +goose Down --- +goose StatementBegin -DELETE FROM owners WHERE owner_name IN ('james', 'pressly'); --- +goose StatementEnd diff --git a/tests/e2e/testdata/mysql/migrations/00004_d.sql b/tests/e2e/testdata/mysql/migrations/00004_d.sql deleted file mode 100644 index f47d151a6..000000000 --- a/tests/e2e/testdata/mysql/migrations/00004_d.sql +++ /dev/null @@ -1,13 +0,0 @@ --- +goose Up --- +goose StatementBegin -ALTER TABLE repos - ADD COLUMN IF NOT EXISTS homepage_url text NOT NULL DEFAULT '', - ADD COLUMN is_private boolean NOT NULL DEFAULT false; --- +goose StatementEnd - --- +goose Down --- +goose StatementBegin -ALTER TABLE repos - DROP COLUMN IF EXISTS homepage_url, - DROP COLUMN is_private; --- +goose StatementEnd diff --git a/tests/e2e/testdata/mysql/migrations/00006_f.sql b/tests/e2e/testdata/mysql/migrations/00006_f.sql deleted file mode 100644 index 634673651..000000000 --- a/tests/e2e/testdata/mysql/migrations/00006_f.sql +++ /dev/null @@ -1,17 +0,0 @@ --- +goose Up --- +goose StatementBegin -CREATE TABLE IF NOT EXISTS stargazers ( - stargazer_repo_id bigint NOT NULL REFERENCES repos(repo_id) ON DELETE CASCADE, - stargazer_owner_id bigint NOT NULL REFERENCES owners(owner_id) ON DELETE CASCADE, - stargazer_starred_at timestamp NOT NULL, - stargazer_location text NOT NULL -); - -ALTER TABLE IF EXISTS stargazers - ADD CONSTRAINT stargazers_repo_id_owner_id_key PRIMARY KEY (stargazer_repo_id, stargazer_owner_id); --- +goose StatementEnd - --- +goose Down --- +goose StatementBegin -DROP TABLE stargazers; --- +goose StatementEnd diff --git a/tests/e2e/testdata/mysql/migrations/00007_g.sql b/tests/e2e/testdata/mysql/migrations/00007_g.sql deleted file mode 100644 index 106ca876a..000000000 --- a/tests/e2e/testdata/mysql/migrations/00007_g.sql +++ /dev/null @@ -1,15 +0,0 @@ --- +goose Up --- +goose StatementBegin -CREATE TABLE issues ( - issue_id BIGINT PRIMARY KEY AUTO_INCREMENT, - issue_created_by bigint NOT NULL REFERENCES owners(owner_id) ON DELETE CASCADE, - issue_repo_id bigint NOT NULL REFERENCES repos(repo_id) ON DELETE CASCADE, - issue_created_at timestamp NOT NULL, - issue_description text NOT NULL -); --- +goose StatementEnd - --- +goose Down --- +goose StatementBegin -DROP TABLE issues; --- +goose StatementEnd diff --git a/tests/e2e/testdata/mysql/migrations/00008_h.sql b/tests/e2e/testdata/mysql/migrations/00008_h.sql deleted file mode 100644 index 72f751ba9..000000000 --- a/tests/e2e/testdata/mysql/migrations/00008_h.sql +++ /dev/null @@ -1,10 +0,0 @@ --- +goose Up --- +goose StatementBegin --- This migration intentionally depends on 00006_f.sql -ALTER TABLE stargazers DROP COLUMN stargazer_location; --- +goose StatementEnd - --- +goose Down --- +goose StatementBegin -ALTER TABLE stargazers ADD COLUMN stargazer_location text NOT NULL; --- +goose StatementEnd diff --git a/tests/e2e/testdata/postgres/migrations/00002_b.sql b/tests/e2e/testdata/postgres/migrations/00002_b.sql deleted file mode 100644 index 8f8dca03c..000000000 --- a/tests/e2e/testdata/postgres/migrations/00002_b.sql +++ /dev/null @@ -1,10 +0,0 @@ --- +goose Up --- +goose StatementBegin -INSERT INTO owners(owner_name, owner_type) - VALUES ('lucas', 'user'), ('space', 'organization'); --- +goose StatementEnd - --- +goose Down --- +goose StatementBegin -DELETE FROM owners; --- +goose StatementEnd diff --git a/tests/e2e/testdata/postgres/migrations/00005_e.sql b/tests/e2e/testdata/postgres/migrations/00005_e.sql deleted file mode 100644 index 96c766984..000000000 --- a/tests/e2e/testdata/postgres/migrations/00005_e.sql +++ /dev/null @@ -1,11 +0,0 @@ --- +goose Up --- +goose StatementBegin --- NOTE: intentionally left blank to verify migration logic. -SELECT 'up SQL query'; --- +goose StatementEnd - --- +goose Down --- +goose StatementBegin --- NOTE: intentionally left blank to verify migration logic. -SELECT 'down SQL query'; --- +goose StatementEnd diff --git a/tests/e2e/testdata/postgres/migrations/00006_f.sql b/tests/e2e/testdata/postgres/migrations/00006_f.sql deleted file mode 100644 index 91f15366c..000000000 --- a/tests/e2e/testdata/postgres/migrations/00006_f.sql +++ /dev/null @@ -1,17 +0,0 @@ --- +goose Up --- +goose StatementBegin -CREATE TABLE IF NOT EXISTS stargazers ( - stargazer_repo_id bigint NOT NULL REFERENCES repos(repo_id) ON DELETE CASCADE DEFERRABLE, - stargazer_owner_id bigint NOT NULL REFERENCES owners(owner_id) ON DELETE CASCADE DEFERRABLE, - stargazer_starred_at timestamp NOT NULL, - stargazer_location text NOT NULL -); - -ALTER TABLE IF EXISTS stargazers - ADD CONSTRAINT stargazers_repo_id_owner_id_key PRIMARY KEY (stargazer_repo_id, stargazer_owner_id); --- +goose StatementEnd - --- +goose Down --- +goose StatementBegin -DROP TABLE stargazers; --- +goose StatementEnd diff --git a/tests/e2e/testdata/postgres/migrations/00007_g.sql b/tests/e2e/testdata/postgres/migrations/00007_g.sql deleted file mode 100644 index 5daab67ed..000000000 --- a/tests/e2e/testdata/postgres/migrations/00007_g.sql +++ /dev/null @@ -1,15 +0,0 @@ --- +goose Up --- +goose StatementBegin -CREATE TABLE issues ( - issue_id BIGSERIAL PRIMARY KEY, - issue_created_by bigint NOT NULL REFERENCES owners(owner_id) ON DELETE CASCADE DEFERRABLE, - issue_repo_id bigint NOT NULL REFERENCES repos(repo_id) ON DELETE CASCADE DEFERRABLE, - issue_created_at timestamp NOT NULL, - issue_description text NOT NULL -); --- +goose StatementEnd - --- +goose Down --- +goose StatementBegin -DROP TABLE issues; --- +goose StatementEnd diff --git a/tests/e2e/testdata/postgres/migrations/00008_h.sql b/tests/e2e/testdata/postgres/migrations/00008_h.sql deleted file mode 100644 index 72f751ba9..000000000 --- a/tests/e2e/testdata/postgres/migrations/00008_h.sql +++ /dev/null @@ -1,10 +0,0 @@ --- +goose Up --- +goose StatementBegin --- This migration intentionally depends on 00006_f.sql -ALTER TABLE stargazers DROP COLUMN stargazer_location; --- +goose StatementEnd - --- +goose Down --- +goose StatementBegin -ALTER TABLE stargazers ADD COLUMN stargazer_location text NOT NULL; --- +goose StatementEnd diff --git a/tests/e2e/testdata/postgres/migrations/00009_i.sql b/tests/e2e/testdata/postgres/migrations/00009_i.sql deleted file mode 100644 index e2f4f7374..000000000 --- a/tests/e2e/testdata/postgres/migrations/00009_i.sql +++ /dev/null @@ -1,9 +0,0 @@ --- +goose NO TRANSACTION - --- +goose Up --- +goose StatementBegin -CREATE UNIQUE INDEX CONCURRENTLY ON owners(owner_name); --- +goose StatementEnd - --- +goose Down -DROP INDEX IF EXISTS owners_owner_name_idx; \ No newline at end of file diff --git a/tests/e2e/testdata/postgres/migrations/00011_k.sql b/tests/e2e/testdata/postgres/migrations/00011_k.sql deleted file mode 100644 index bc26fc45d..000000000 --- a/tests/e2e/testdata/postgres/migrations/00011_k.sql +++ /dev/null @@ -1,26 +0,0 @@ --- +goose Up -CREATE MATERIALIZED VIEW IF NOT EXISTS matview_stargazers_day AS - SELECT - t.*, - repo_full_name, - repo_owner_id - FROM ( - SELECT - date_trunc('day', stargazer_starred_at)::date AS stars_day, - count(*) AS total, - stargazer_repo_id - FROM - stargazers - GROUP BY - stars_day, - stargazer_repo_id) AS t - JOIN repos ON stargazer_repo_id = repo_id -ORDER BY - stars_day; - -CREATE UNIQUE INDEX ON matview_stargazers_day (stargazer_repo_id, stars_day, repo_owner_id, repo_full_name); - -REFRESH MATERIALIZED VIEW CONCURRENTLY matview_stargazers_day WITH DATA; - --- +goose Down -DROP MATERIALIZED VIEW IF EXISTS matview_stargazers_day; \ No newline at end of file diff --git a/tests/e2e/testdata/postgres/seed/00001_a.sql b/tests/e2e/testdata/postgres/seed/00001_a.sql deleted file mode 100644 index d47a3dae2..000000000 --- a/tests/e2e/testdata/postgres/seed/00001_a.sql +++ /dev/null @@ -1,18 +0,0 @@ --- +goose Up --- +goose StatementBegin - --- Insert 100 owners. -INSERT INTO owners (owner_name, owner_type) -SELECT - 'seed-user-' || i, - (SELECT('{user,organization}'::owner_type []) [MOD(i, 2)+1]) -FROM - generate_series(1, 100) s (i); --- +goose StatementEnd - --- +goose Down --- +goose StatementBegin --- NOTE: there are 4 existing users from the migrations, that's why owner_id starts at 5 -DELETE FROM owners where owner_name LIKE 'seed-user-%' AND owner_id BETWEEN 5 AND 104; -SELECT setval('owners_owner_id_seq', COALESCE((SELECT MAX(owner_id)+1 FROM owners), 1), false); --- +goose StatementEnd \ No newline at end of file diff --git a/tests/e2e/testdata/postgres/seed/00002_b.sql b/tests/e2e/testdata/postgres/seed/00002_b.sql deleted file mode 100644 index a4d7ce170..000000000 --- a/tests/e2e/testdata/postgres/seed/00002_b.sql +++ /dev/null @@ -1,14 +0,0 @@ --- +goose Up - --- Insert 150 more owners. -INSERT INTO owners (owner_name, owner_type) -SELECT - 'seed-user-' || i, - (SELECT('{user,organization}'::owner_type []) [MOD(i, 2)+1]) -FROM - generate_series(101, 250) s (i); - --- +goose Down --- NOTE: there are 4 migration owners and 100 seed owners, that's why owner_id starts at 105 -DELETE FROM owners where owner_name LIKE 'seed-user-%' AND owner_id BETWEEN 105 AND 254; -SELECT setval('owners_owner_id_seq', max(owner_id)) FROM owners; diff --git a/tests/e2e/testdata/turso/migrations/00001_a.sql b/tests/e2e/testdata/turso/migrations/00001_a.sql deleted file mode 100644 index 537a18a89..000000000 --- a/tests/e2e/testdata/turso/migrations/00001_a.sql +++ /dev/null @@ -1,21 +0,0 @@ --- +goose Up --- +goose StatementBegin -CREATE TABLE owners ( - owner_id integer, - owner_name integer, - owner_type integer, - PRIMARY KEY (owner_id) -); -CREATE TABLE repos ( - repo_id integer, - repo_owner_id integer, - repo_full_name integer, - PRIMARY KEY (repo_id) -); --- +goose StatementEnd - --- +goose Down --- +goose StatementBegin -DROP TABLE repos; -DROP TABLE owners; --- +goose StatementEnd diff --git a/tests/e2e/testdata/turso/migrations/00003_c.sql b/tests/e2e/testdata/turso/migrations/00003_c.sql deleted file mode 100644 index ae622a209..000000000 --- a/tests/e2e/testdata/turso/migrations/00003_c.sql +++ /dev/null @@ -1,13 +0,0 @@ --- +goose Up --- +goose StatementBegin -INSERT INTO owners(owner_id, owner_name, owner_type) -VALUES (3, 'james', 'user'), (4, 'pressly', 'organization'); -INSERT INTO repos(repo_id, repo_full_name, repo_owner_id) -VALUES (1, 'james/rover', 3), (2, 'pressly/goose', 4); --- +goose StatementEnd - --- +goose Down --- +goose StatementBegin -DELETE FROM owners WHERE (owner_id = 3 OR owner_id = 4); -DELETE FROM repos WHERE (repo_id = 1 OR repo_id = 2); --- +goose StatementEnd diff --git a/tests/e2e/testdata/turso/migrations/00004_d.sql b/tests/e2e/testdata/turso/migrations/00004_d.sql deleted file mode 100644 index 42478eb07..000000000 --- a/tests/e2e/testdata/turso/migrations/00004_d.sql +++ /dev/null @@ -1,15 +0,0 @@ --- +goose Up --- +goose StatementBegin -ALTER TABLE repos - ADD COLUMN homepage_url text; -ALTER TABLE repos - ADD COLUMN is_private integer; --- +goose StatementEnd - --- +goose Down --- +goose StatementBegin -ALTER TABLE repos - DROP COLUMN homepage_url; -ALTER TABLE repos - DROP COLUMN is_private; --- +goose StatementEnd diff --git a/tests/e2e/testdata/turso/migrations/00005_e.sql b/tests/e2e/testdata/turso/migrations/00005_e.sql deleted file mode 100644 index 96c766984..000000000 --- a/tests/e2e/testdata/turso/migrations/00005_e.sql +++ /dev/null @@ -1,11 +0,0 @@ --- +goose Up --- +goose StatementBegin --- NOTE: intentionally left blank to verify migration logic. -SELECT 'up SQL query'; --- +goose StatementEnd - --- +goose Down --- +goose StatementBegin --- NOTE: intentionally left blank to verify migration logic. -SELECT 'down SQL query'; --- +goose StatementEnd diff --git a/tests/e2e/testdata/turso/migrations/00006_f.sql b/tests/e2e/testdata/turso/migrations/00006_f.sql deleted file mode 100644 index ed6a1a809..000000000 --- a/tests/e2e/testdata/turso/migrations/00006_f.sql +++ /dev/null @@ -1,15 +0,0 @@ --- +goose Up --- +goose StatementBegin -CREATE TABLE stargazers ( - stargazer_repo_id integer, - stargazer_owner_id integer, - stargazer_starred_at integer, - stargazer_location text, - PRIMARY KEY (stargazer_repo_id, stargazer_owner_id) -); --- +goose StatementEnd - --- +goose Down --- +goose StatementBegin -DROP TABLE stargazers; --- +goose StatementEnd diff --git a/tests/e2e/testdata/turso/migrations/00007_g.sql b/tests/e2e/testdata/turso/migrations/00007_g.sql deleted file mode 100644 index aff8d39d5..000000000 --- a/tests/e2e/testdata/turso/migrations/00007_g.sql +++ /dev/null @@ -1,16 +0,0 @@ --- +goose Up --- +goose StatementBegin -CREATE TABLE issues ( - issue_id integer, - issue_created_by integer, - issue_repo_id integer, - issue_created_at integer, - issue_description text, - PRIMARY KEY (issue_id) -); --- +goose StatementEnd - --- +goose Down --- +goose StatementBegin -DROP TABLE issues; --- +goose StatementEnd diff --git a/tests/e2e/testdata/turso/migrations/00008_h.sql b/tests/e2e/testdata/turso/migrations/00008_h.sql deleted file mode 100644 index 754cb1daa..000000000 --- a/tests/e2e/testdata/turso/migrations/00008_h.sql +++ /dev/null @@ -1,9 +0,0 @@ --- +goose Up --- +goose StatementBegin -ALTER TABLE stargazers DROP COLUMN stargazer_location; --- +goose StatementEnd - --- +goose Down --- +goose StatementBegin -ALTER TABLE stargazers ADD COLUMN stargazer_location text; --- +goose StatementEnd diff --git a/tests/e2e/testdata/ydb/migrations/00002_b.sql b/tests/e2e/testdata/ydb/migrations/00002_b.sql deleted file mode 100644 index 598c33b28..000000000 --- a/tests/e2e/testdata/ydb/migrations/00002_b.sql +++ /dev/null @@ -1,10 +0,0 @@ --- +goose Up --- +goose StatementBegin -INSERT INTO owners(owner_id, owner_name, owner_type) -VALUES (1, 'lucas', 'user'), (2, 'space', 'organization'); --- +goose StatementEnd - --- +goose Down --- +goose StatementBegin -DELETE FROM owners; --- +goose StatementEnd diff --git a/tests/e2e/testdata/ydb/migrations/00005_e.sql b/tests/e2e/testdata/ydb/migrations/00005_e.sql deleted file mode 100644 index 96c766984..000000000 --- a/tests/e2e/testdata/ydb/migrations/00005_e.sql +++ /dev/null @@ -1,11 +0,0 @@ --- +goose Up --- +goose StatementBegin --- NOTE: intentionally left blank to verify migration logic. -SELECT 'up SQL query'; --- +goose StatementEnd - --- +goose Down --- +goose StatementBegin --- NOTE: intentionally left blank to verify migration logic. -SELECT 'down SQL query'; --- +goose StatementEnd diff --git a/tests/gomigrations/error/gomigrations_error_test.go b/tests/gomigrations/error/gomigrations_error_test.go index c67da9e21..e03cbc114 100644 --- a/tests/gomigrations/error/gomigrations_error_test.go +++ b/tests/gomigrations/error/gomigrations_error_test.go @@ -1,19 +1,22 @@ package gomigrations import ( + "database/sql" + "path/filepath" "testing" "github.com/pressly/goose/v3" "github.com/pressly/goose/v3/internal/check" - "github.com/pressly/goose/v3/internal/testdb" - _ "github.com/pressly/goose/v3/tests/gomigrations/error/testdata" + _ "modernc.org/sqlite" ) func TestGoMigrationByOne(t *testing.T) { - db, cleanup, err := testdb.NewPostgres() + tempDir := t.TempDir() + db, err := sql.Open("sqlite", filepath.Join(tempDir, "test.db")) + check.NoError(t, err) + err = goose.SetDialect(string(goose.DialectSQLite3)) check.NoError(t, err) - t.Cleanup(cleanup) // Create goose table. current, err := goose.EnsureDBVersion(db) check.NoError(t, err) diff --git a/tests/gomigrations/error/testdata/001_up_no_tx.go b/tests/gomigrations/error/testdata/001_up_no_tx.go index c5f22fdc1..109cda05a 100644 --- a/tests/gomigrations/error/testdata/001_up_no_tx.go +++ b/tests/gomigrations/error/testdata/001_up_no_tx.go @@ -11,7 +11,7 @@ func init() { } func up001(db *sql.DB) error { - q := "CREATE TABLE foo (id INT)" + q := "CREATE TABLE foo (id INTEGER)" _, err := db.Exec(q) return err } diff --git a/tests/gomigrations/error/testdata/003_truncate.go b/tests/gomigrations/error/testdata/003_truncate.go index 836af1ceb..b5ac60586 100644 --- a/tests/gomigrations/error/testdata/003_truncate.go +++ b/tests/gomigrations/error/testdata/003_truncate.go @@ -11,7 +11,7 @@ func init() { } func up003(tx *sql.Tx) error { - q := "TRUNCATE TABLE foo" + q := "DELETE FROM foo" _, err := tx.Exec(q) return err } diff --git a/tests/vertica/vertica_test.go b/tests/vertica/vertica_test.go deleted file mode 100644 index 018b929ba..000000000 --- a/tests/vertica/vertica_test.go +++ /dev/null @@ -1,115 +0,0 @@ -package vertica_test - -import ( - "path/filepath" - "testing" - "time" - - "github.com/pressly/goose/v3" - "github.com/pressly/goose/v3/internal/check" - "github.com/pressly/goose/v3/internal/testdb" -) - -/* -This test applies all up migrations, asserts we have all the entries in -the versions table, applies all down migration and asserts we have zero -migrations applied. - -Limitations: -1) Only one instance of Vertica can be running on a host at any time. -*/ -func TestVerticaUpDownAll(t *testing.T) { - t.Parallel() - - migrationDir := filepath.Join("testdata", "migrations") - db, cleanup, err := testdb.NewVertica() - check.NoError(t, err) - t.Cleanup(cleanup) - - check.NoError(t, goose.SetDialect("vertica")) - - goose.SetTableName("goose_db_version") - - migrations, err := goose.CollectMigrations(migrationDir, 0, goose.MaxVersion) - check.NoError(t, err) - - currentVersion, err := goose.GetDBVersion(db) - check.NoError(t, err) - check.Number(t, currentVersion, 0) - - err = goose.Up(db, migrationDir) - check.NoError(t, err) - currentVersion, err = goose.GetDBVersion(db) - check.NoError(t, err) - check.Number(t, currentVersion, len(migrations)) - - type result struct { - TestKey int64 `db:"test_key"` - TestID string `db:"test_id"` - ValidFrom time.Time `db:"valid_from"` - ValidTo time.Time `db:"valid_to"` - IsCurrent bool `db:"is_current"` - ExternalID string `db:"external_id"` - } - rows, err := db.Query(`SELECT * FROM testing.dim_test_scd ORDER BY test_key`) - check.NoError(t, err) - var results []result - for rows.Next() { - var r result - err = rows.Scan(&r.TestKey, &r.TestID, &r.ValidFrom, &r.ValidTo, &r.IsCurrent, &r.ExternalID) - check.NoError(t, err) - results = append(results, r) - } - check.Number(t, len(results), 3) - check.NoError(t, rows.Close()) - check.NoError(t, rows.Err()) - - parseTime := func(t *testing.T, s string) time.Time { - t.Helper() - tm, err := time.Parse("2006-01-02", s) - check.NoError(t, err) - return tm - } - want := []result{ - { - TestKey: 1, - TestID: "575a0dd4-bd97-44ac-aae0-987090181da8", - ValidFrom: parseTime(t, "2021-10-02"), - ValidTo: parseTime(t, "2021-10-03"), - IsCurrent: false, - ExternalID: "123", - }, - { - TestKey: 2, - TestID: "575a0dd4-bd97-44ac-aae0-987090181da8", - ValidFrom: parseTime(t, "2021-10-03"), - ValidTo: parseTime(t, "2021-10-04"), - IsCurrent: false, - ExternalID: "456", - }, - { - TestKey: 3, - TestID: "575a0dd4-bd97-44ac-aae0-987090181da8", - ValidFrom: parseTime(t, "2021-10-04"), - ValidTo: parseTime(t, "9999-12-31"), - IsCurrent: true, - ExternalID: "789", - }, - } - for i, result := range results { - check.Equal(t, result.TestKey, want[i].TestKey) - check.Equal(t, result.TestID, want[i].TestID) - check.Equal(t, result.ValidFrom, want[i].ValidFrom) - check.Equal(t, result.ValidTo, want[i].ValidTo) - check.Equal(t, result.IsCurrent, want[i].IsCurrent) - check.Equal(t, result.ExternalID, want[i].ExternalID) - } - - err = goose.DownTo(db, migrationDir, 0) - check.NoError(t, err) - check.NoError(t, err) - - currentVersion, err = goose.GetDBVersion(db) - check.NoError(t, err) - check.Number(t, currentVersion, 0) -}