91 lines
2.5 KiB
Go
91 lines
2.5 KiB
Go
// Command consumer verifies generated registrations and the production boundary.
|
|
package main
|
|
|
|
import (
|
|
"context"
|
|
"database/sql"
|
|
"embed"
|
|
"fmt"
|
|
"io"
|
|
"log/slog"
|
|
"os"
|
|
|
|
"example.com/consumer/migrations"
|
|
"github.com/pressly/goose/v3"
|
|
urfavecli "github.com/urfave/cli/v3"
|
|
"go.auvem.com/corestack/lifecycle"
|
|
"go.auvem.com/corestack/lifecycle/cli"
|
|
"go.auvem.com/corestack/migrate"
|
|
adapter "go.auvem.com/corestack/migrate/lifecycle"
|
|
_ "modernc.org/sqlite"
|
|
)
|
|
|
|
//go:embed migrations
|
|
var files embed.FS
|
|
|
|
func main() {
|
|
ctx := context.Background()
|
|
logger := slog.New(slog.NewTextHandler(io.Discard, nil))
|
|
var db *sql.DB
|
|
dbModule := lifecycle.Module{Name: "database", Setup: func(context.Context) error { var err error; db, err = sql.Open("sqlite", os.Args[1]); return err }, Teardown: func(context.Context) error { return db.Close() }}
|
|
resolver := func(context.Context) (*goose.Provider, error) {
|
|
return migrate.New(db, goose.DialectSQLite3, files, "migrations", logger, migrations.GoMigrations()...)
|
|
}
|
|
root := &urfavecli.Command{Name: "consumer", Commands: []*urfavecli.Command{adapter.Commands(lifecycle.Config{Logger: logger}, []lifecycle.Module{dbModule}, resolver)}}
|
|
code, err := cli.Run(ctx, root, []string{"consumer", "migrate", "up"})
|
|
must(err)
|
|
if code != 0 {
|
|
panic(code)
|
|
}
|
|
db, err = sql.Open("sqlite", os.Args[1])
|
|
must(err)
|
|
defer db.Close()
|
|
p, err := resolver(ctx)
|
|
must(err)
|
|
version, err := p.GetDBVersion(ctx)
|
|
must(err)
|
|
if version != 4 {
|
|
panic(version)
|
|
}
|
|
pending, err := p.HasPending(ctx)
|
|
must(err)
|
|
if pending {
|
|
panic("pending after apply")
|
|
}
|
|
statuses, err := p.Status(ctx)
|
|
must(err)
|
|
if len(statuses) != 4 {
|
|
panic(len(statuses))
|
|
}
|
|
for i, status := range statuses {
|
|
if status.Source.Version != int64(i+1) || status.State != goose.StateApplied {
|
|
panic(status)
|
|
}
|
|
}
|
|
a, b := migrations.GoMigrations(), migrations.GoMigrations()
|
|
if len(a) != 3 || len(b) != 3 {
|
|
panic("missing safe-suffix Go migrations")
|
|
}
|
|
for i := range a {
|
|
if a[i] == b[i] || a[i].Version != int64(i+2) || b[i].Version != int64(i+2) {
|
|
panic("registration/version isolation")
|
|
}
|
|
}
|
|
isolatedDB, err := sql.Open("sqlite", ":memory:")
|
|
must(err)
|
|
defer isolatedDB.Close()
|
|
isolated, err := migrate.New(isolatedDB, goose.DialectSQLite3, files, "migrations", logger, migrations.GoMigrations()...)
|
|
must(err)
|
|
pending, err = isolated.HasPending(ctx)
|
|
must(err)
|
|
if !pending {
|
|
panic("provider isolation")
|
|
}
|
|
fmt.Println("version=4 pending=false versions=1,2,3,4 fresh=true isolated-pending=true")
|
|
}
|
|
func must(err error) {
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
}
|