- Move remaining beach packages and embedded admin assets\n- Rewrite framework, example, build, and gate paths
166 lines
4.1 KiB
Go
166 lines
4.1 KiB
Go
package lagoon
|
|
|
|
import (
|
|
"bytes"
|
|
"database/sql"
|
|
"encoding/base64"
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
"testing"
|
|
|
|
"git.golem15.com/golem15/summercms/modules/backpack"
|
|
"git.golem15.com/golem15/summercms/modules/compass"
|
|
"gorm.io/gorm"
|
|
)
|
|
|
|
func TestUseRejectsNilSQL(t *testing.T) {
|
|
_, err := Use(t.Context(), nil)
|
|
if err == nil || !strings.Contains(err.Error(), "sql db is nil") {
|
|
t.Fatalf("got %v", err)
|
|
}
|
|
}
|
|
|
|
func TestCheckLocaleRejectsNilSQL(t *testing.T) {
|
|
err := CheckLocale(t.Context(), nil)
|
|
if err == nil || !strings.Contains(err.Error(), "sql db is nil") {
|
|
t.Fatalf("got %v", err)
|
|
}
|
|
}
|
|
|
|
func TestPublishRejectsNilHandles(t *testing.T) {
|
|
app := backpack.New(nil)
|
|
if err := Publish(nil, nil, nil); err == nil {
|
|
t.Fatal("want nil app error")
|
|
}
|
|
if err := Publish(app, nil, &gorm.DB{}); err == nil || !strings.Contains(err.Error(), "nil") {
|
|
t.Fatalf("got %v", err)
|
|
}
|
|
}
|
|
|
|
func TestDSNEmptyWithoutConfig(t *testing.T) {
|
|
if DSN(nil) != "" {
|
|
t.Fatal("nil config must yield empty DSN")
|
|
}
|
|
}
|
|
|
|
func TestOpenFromAppMissingConfig(t *testing.T) {
|
|
_, _, err := OpenFromApp(t.Context(), nil)
|
|
if err == nil || !strings.Contains(err.Error(), "app config is missing") {
|
|
t.Fatalf("got %v", err)
|
|
}
|
|
_, _, err = OpenFromApp(t.Context(), backpack.New(nil))
|
|
if err == nil || !strings.Contains(err.Error(), "app config is missing") {
|
|
t.Fatalf("got %v", err)
|
|
}
|
|
}
|
|
|
|
func TestSharedSQLPoolUsedByGORMAndClosed(t *testing.T) {
|
|
_, dsn := dedicatedDB(t, "lagoon_shared")
|
|
sqlDB, gdb, err := Open(t.Context(), dsn)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
raw, err := gdb.DB()
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if raw != sqlDB {
|
|
t.Fatal("GORM is not using the shared *sql.DB")
|
|
}
|
|
|
|
app := backpack.New(nil)
|
|
if err := Publish(app, sqlDB, gdb); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
gotSQL, ok := app.Lookup[*sql.DB]()
|
|
if !ok || gotSQL != sqlDB {
|
|
t.Fatal("published *sql.DB is not the shared pool")
|
|
}
|
|
gotGORM, ok := app.Lookup[*gorm.DB]()
|
|
if !ok || gotGORM != gdb {
|
|
t.Fatal("published *gorm.DB is missing")
|
|
}
|
|
|
|
viaUse, err := Use(t.Context(), sqlDB)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
useRaw, err := viaUse.DB()
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if useRaw != sqlDB {
|
|
t.Fatal("Use must open GORM on the caller pool, not a second connection")
|
|
}
|
|
|
|
if err := sqlDB.Close(); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if err := sqlDB.PingContext(t.Context()); err == nil {
|
|
t.Fatal("closed pool must reject Ping")
|
|
}
|
|
if _, err := Use(t.Context(), sqlDB); err == nil {
|
|
t.Fatal("Use must fail after the shared pool is closed")
|
|
}
|
|
}
|
|
|
|
func TestWrongICULocaleFailsOpen(t *testing.T) {
|
|
admin := lagoonDB(t)
|
|
ctx := t.Context()
|
|
if _, err := admin.ExecContext(ctx, `CREATE DATABASE lagoon_locale_fail TEMPLATE template0 ENCODING 'UTF8' LOCALE_PROVIDER libc LOCALE 'C'`); err != nil && !strings.Contains(err.Error(), "already exists") {
|
|
t.Fatalf("create libc database: %v", err)
|
|
}
|
|
t.Cleanup(func() {
|
|
_, _ = admin.ExecContext(ctx, `DROP DATABASE IF EXISTS lagoon_locale_fail WITH (FORCE)`)
|
|
})
|
|
failDSN, err := dsnWithDB(lagoonDSN, "lagoon_locale_fail")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
_, _, err = Open(ctx, failDSN)
|
|
if err == nil {
|
|
t.Fatal("wrong locale must fail boot")
|
|
}
|
|
msg := err.Error()
|
|
for _, want := range []string{"ICU", "pl-PL", "CREATE DATABASE", "LOCALE_PROVIDER icu"} {
|
|
if !strings.Contains(msg, want) {
|
|
t.Fatalf("missing %q in %s", want, msg)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestOpenFromAppReadsDSN(t *testing.T) {
|
|
_, dsn := dedicatedDB(t, "lagoon_from_app")
|
|
dir := t.TempDir()
|
|
if err := os.WriteFile(filepath.Join(dir, "app.yaml"), []byte("name: lagoon-test\n"), 0o644); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
cfg, err := compass.Open(compass.Options{
|
|
Dir: dir,
|
|
Environ: []string{
|
|
"SUMMER_ENV=development",
|
|
"SUMMER_DATABASE__DSN=" + dsn,
|
|
"SUMMER_APP__KEY=" + base64.StdEncoding.EncodeToString(bytes.Repeat([]byte("T"), 32)),
|
|
},
|
|
})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if got := DSN(cfg); got != dsn {
|
|
t.Fatalf("DSN = %q want %q", got, dsn)
|
|
}
|
|
sqlDB, gdb, err := OpenFromApp(t.Context(), backpack.New(cfg))
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
t.Cleanup(func() { _ = sqlDB.Close() })
|
|
raw, err := gdb.DB()
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if raw != sqlDB {
|
|
t.Fatal("OpenFromApp must share the same *sql.DB with GORM")
|
|
}
|
|
}
|