Remove message.owner_user_id field and implement db migrations
This commit is contained in:
388
scnserver/test/database_test.go
Normal file
388
scnserver/test/database_test.go
Normal file
@@ -0,0 +1,388 @@
|
||||
package test
|
||||
|
||||
import (
|
||||
"blackforestbytes.com/simplecloudnotifier/db/impl/logs"
|
||||
"blackforestbytes.com/simplecloudnotifier/db/impl/primary"
|
||||
"blackforestbytes.com/simplecloudnotifier/db/impl/requests"
|
||||
"blackforestbytes.com/simplecloudnotifier/db/schema"
|
||||
"blackforestbytes.com/simplecloudnotifier/db/simplectx"
|
||||
tt "blackforestbytes.com/simplecloudnotifier/test/util"
|
||||
"context"
|
||||
"fmt"
|
||||
"github.com/jmoiron/sqlx"
|
||||
"gogs.mikescher.com/BlackForestBytes/goext/sq"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestPrimaryDB_Current(t *testing.T) {
|
||||
dbf1, dbf2, dbf3, conf, stop := tt.StartSimpleTestspace(t)
|
||||
defer stop()
|
||||
|
||||
ctx := context.Background()
|
||||
|
||||
tt.AssertAny(dbf1)
|
||||
tt.AssertAny(dbf2)
|
||||
tt.AssertAny(dbf3)
|
||||
tt.AssertAny(conf)
|
||||
|
||||
{
|
||||
db1, err := primary.NewPrimaryDatabase(conf)
|
||||
tt.TestFailIfErr(t, err)
|
||||
|
||||
{
|
||||
tctx := simplectx.CreateSimpleContext(ctx, nil)
|
||||
|
||||
schema1, err := db1.ReadSchema(tctx)
|
||||
tt.TestFailIfErr(t, err)
|
||||
tt.AssertEqual(t, "schema1", 0, schema1)
|
||||
|
||||
err = tctx.CommitTransaction()
|
||||
tt.TestFailIfErr(t, err)
|
||||
}
|
||||
|
||||
{
|
||||
err = db1.Migrate(ctx)
|
||||
tt.TestFailIfErr(t, err)
|
||||
}
|
||||
|
||||
{
|
||||
tctx := simplectx.CreateSimpleContext(ctx, nil)
|
||||
|
||||
schema2, err := db1.ReadSchema(tctx)
|
||||
tt.TestFailIfErr(t, err)
|
||||
tt.AssertEqual(t, "schema2", schema.PrimarySchemaVersion, schema2)
|
||||
|
||||
err = tctx.CommitTransaction()
|
||||
tt.TestFailIfErr(t, err)
|
||||
}
|
||||
|
||||
{
|
||||
err = db1.Migrate(ctx)
|
||||
tt.TestFailIfErr(t, err)
|
||||
}
|
||||
|
||||
{
|
||||
tctx := simplectx.CreateSimpleContext(ctx, nil)
|
||||
|
||||
schema2, err := db1.ReadSchema(tctx)
|
||||
tt.TestFailIfErr(t, err)
|
||||
tt.AssertEqual(t, "schema2", schema.PrimarySchemaVersion, schema2)
|
||||
|
||||
err = tctx.CommitTransaction()
|
||||
tt.TestFailIfErr(t, err)
|
||||
}
|
||||
|
||||
err = db1.Stop(ctx)
|
||||
tt.TestFailIfErr(t, err)
|
||||
}
|
||||
|
||||
{
|
||||
db1New, err := primary.NewPrimaryDatabase(conf)
|
||||
tt.TestFailIfErr(t, err)
|
||||
|
||||
{
|
||||
tctx := simplectx.CreateSimpleContext(ctx, nil)
|
||||
|
||||
schema3, err := db1New.ReadSchema(tctx)
|
||||
tt.TestFailIfErr(t, err)
|
||||
tt.AssertEqual(t, "schema3", schema.PrimarySchemaVersion, schema3)
|
||||
|
||||
err = tctx.CommitTransaction()
|
||||
tt.TestFailIfErr(t, err)
|
||||
}
|
||||
|
||||
err = db1New.Migrate(ctx)
|
||||
tt.TestFailIfErr(t, err)
|
||||
|
||||
{
|
||||
tctx := simplectx.CreateSimpleContext(ctx, nil)
|
||||
|
||||
schema4, err := db1New.ReadSchema(tctx)
|
||||
tt.TestFailIfErr(t, err)
|
||||
tt.AssertEqual(t, "schema4", schema.PrimarySchemaVersion, schema4)
|
||||
|
||||
err = tctx.CommitTransaction()
|
||||
tt.TestFailIfErr(t, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestLogsDB_Current(t *testing.T) {
|
||||
dbf1, dbf2, dbf3, conf, stop := tt.StartSimpleTestspace(t)
|
||||
defer stop()
|
||||
|
||||
ctx := context.Background()
|
||||
|
||||
tt.AssertAny(dbf1)
|
||||
tt.AssertAny(dbf2)
|
||||
tt.AssertAny(dbf3)
|
||||
tt.AssertAny(conf)
|
||||
|
||||
{
|
||||
db1, err := logs.NewLogsDatabase(conf)
|
||||
tt.TestFailIfErr(t, err)
|
||||
|
||||
{
|
||||
tctx := simplectx.CreateSimpleContext(ctx, nil)
|
||||
|
||||
schema1, err := db1.ReadSchema(tctx)
|
||||
tt.TestFailIfErr(t, err)
|
||||
tt.AssertEqual(t, "schema1", 0, schema1)
|
||||
|
||||
err = tctx.CommitTransaction()
|
||||
tt.TestFailIfErr(t, err)
|
||||
}
|
||||
|
||||
{
|
||||
err = db1.Migrate(ctx)
|
||||
tt.TestFailIfErr(t, err)
|
||||
}
|
||||
|
||||
{
|
||||
tctx := simplectx.CreateSimpleContext(ctx, nil)
|
||||
|
||||
schema2, err := db1.ReadSchema(tctx)
|
||||
tt.TestFailIfErr(t, err)
|
||||
tt.AssertEqual(t, "schema2", schema.LogsSchemaVersion, schema2)
|
||||
|
||||
err = tctx.CommitTransaction()
|
||||
tt.TestFailIfErr(t, err)
|
||||
}
|
||||
|
||||
{
|
||||
err = db1.Migrate(ctx)
|
||||
tt.TestFailIfErr(t, err)
|
||||
}
|
||||
|
||||
{
|
||||
tctx := simplectx.CreateSimpleContext(ctx, nil)
|
||||
|
||||
schema2, err := db1.ReadSchema(tctx)
|
||||
tt.TestFailIfErr(t, err)
|
||||
tt.AssertEqual(t, "schema2", schema.LogsSchemaVersion, schema2)
|
||||
|
||||
err = tctx.CommitTransaction()
|
||||
tt.TestFailIfErr(t, err)
|
||||
}
|
||||
|
||||
err = db1.Stop(ctx)
|
||||
tt.TestFailIfErr(t, err)
|
||||
}
|
||||
|
||||
{
|
||||
db1New, err := logs.NewLogsDatabase(conf)
|
||||
tt.TestFailIfErr(t, err)
|
||||
|
||||
{
|
||||
tctx := simplectx.CreateSimpleContext(ctx, nil)
|
||||
|
||||
schema3, err := db1New.ReadSchema(tctx)
|
||||
tt.TestFailIfErr(t, err)
|
||||
tt.AssertEqual(t, "schema3", schema.LogsSchemaVersion, schema3)
|
||||
|
||||
err = tctx.CommitTransaction()
|
||||
tt.TestFailIfErr(t, err)
|
||||
}
|
||||
|
||||
err = db1New.Migrate(ctx)
|
||||
tt.TestFailIfErr(t, err)
|
||||
|
||||
{
|
||||
tctx := simplectx.CreateSimpleContext(ctx, nil)
|
||||
|
||||
schema4, err := db1New.ReadSchema(tctx)
|
||||
tt.TestFailIfErr(t, err)
|
||||
tt.AssertEqual(t, "schema4", schema.LogsSchemaVersion, schema4)
|
||||
|
||||
err = tctx.CommitTransaction()
|
||||
tt.TestFailIfErr(t, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestRequestsDB_Current(t *testing.T) {
|
||||
dbf1, dbf2, dbf3, conf, stop := tt.StartSimpleTestspace(t)
|
||||
defer stop()
|
||||
|
||||
ctx := context.Background()
|
||||
|
||||
tt.AssertAny(dbf1)
|
||||
tt.AssertAny(dbf2)
|
||||
tt.AssertAny(dbf3)
|
||||
tt.AssertAny(conf)
|
||||
|
||||
{
|
||||
db1, err := requests.NewRequestsDatabase(conf)
|
||||
tt.TestFailIfErr(t, err)
|
||||
|
||||
{
|
||||
tctx := simplectx.CreateSimpleContext(ctx, nil)
|
||||
|
||||
schema1, err := db1.ReadSchema(tctx)
|
||||
tt.TestFailIfErr(t, err)
|
||||
tt.AssertEqual(t, "schema1", 0, schema1)
|
||||
|
||||
err = tctx.CommitTransaction()
|
||||
tt.TestFailIfErr(t, err)
|
||||
}
|
||||
|
||||
{
|
||||
err = db1.Migrate(ctx)
|
||||
tt.TestFailIfErr(t, err)
|
||||
}
|
||||
|
||||
{
|
||||
tctx := simplectx.CreateSimpleContext(ctx, nil)
|
||||
|
||||
schema2, err := db1.ReadSchema(tctx)
|
||||
tt.TestFailIfErr(t, err)
|
||||
tt.AssertEqual(t, "schema2", schema.RequestsSchemaVersion, schema2)
|
||||
|
||||
err = tctx.CommitTransaction()
|
||||
tt.TestFailIfErr(t, err)
|
||||
}
|
||||
|
||||
{
|
||||
err = db1.Migrate(ctx)
|
||||
tt.TestFailIfErr(t, err)
|
||||
}
|
||||
|
||||
{
|
||||
tctx := simplectx.CreateSimpleContext(ctx, nil)
|
||||
|
||||
schema2, err := db1.ReadSchema(tctx)
|
||||
tt.TestFailIfErr(t, err)
|
||||
tt.AssertEqual(t, "schema2", schema.RequestsSchemaVersion, schema2)
|
||||
|
||||
err = tctx.CommitTransaction()
|
||||
tt.TestFailIfErr(t, err)
|
||||
}
|
||||
|
||||
err = db1.Stop(ctx)
|
||||
tt.TestFailIfErr(t, err)
|
||||
}
|
||||
|
||||
{
|
||||
db1New, err := requests.NewRequestsDatabase(conf)
|
||||
tt.TestFailIfErr(t, err)
|
||||
|
||||
{
|
||||
tctx := simplectx.CreateSimpleContext(ctx, nil)
|
||||
|
||||
schema3, err := db1New.ReadSchema(tctx)
|
||||
tt.TestFailIfErr(t, err)
|
||||
tt.AssertEqual(t, "schema3", schema.RequestsSchemaVersion, schema3)
|
||||
|
||||
err = tctx.CommitTransaction()
|
||||
tt.TestFailIfErr(t, err)
|
||||
}
|
||||
|
||||
err = db1New.Migrate(ctx)
|
||||
tt.TestFailIfErr(t, err)
|
||||
|
||||
{
|
||||
tctx := simplectx.CreateSimpleContext(ctx, nil)
|
||||
|
||||
schema4, err := db1New.ReadSchema(tctx)
|
||||
tt.TestFailIfErr(t, err)
|
||||
tt.AssertEqual(t, "schema4", schema.RequestsSchemaVersion, schema4)
|
||||
|
||||
err = tctx.CommitTransaction()
|
||||
tt.TestFailIfErr(t, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestPrimaryDB_Migrate_from_3(t *testing.T) {
|
||||
dbf1, dbf2, dbf3, conf, stop := tt.StartSimpleTestspace(t)
|
||||
defer stop()
|
||||
|
||||
ctx := context.Background()
|
||||
|
||||
tt.AssertAny(dbf1)
|
||||
tt.AssertAny(dbf2)
|
||||
tt.AssertAny(dbf3)
|
||||
tt.AssertAny(conf)
|
||||
|
||||
{
|
||||
url := fmt.Sprintf("file:%s", dbf1)
|
||||
|
||||
xdb, err := sqlx.Open("sqlite3", url)
|
||||
tt.TestFailIfErr(t, err)
|
||||
|
||||
qqdb := sq.NewDB(xdb)
|
||||
|
||||
schemavers := 3
|
||||
|
||||
dbschema := schema.PrimarySchema[schemavers]
|
||||
|
||||
_, err = qqdb.Exec(ctx, dbschema.SQL, sq.PP{})
|
||||
tt.TestFailIfErr(t, err)
|
||||
|
||||
_, err = qqdb.Exec(ctx, "INSERT INTO meta (meta_key, value_int) VALUES (:key, :val) ON CONFLICT(meta_key) DO UPDATE SET value_int = :val", sq.PP{
|
||||
"key": "schema",
|
||||
"val": schemavers,
|
||||
})
|
||||
|
||||
_, err = qqdb.Exec(ctx, "INSERT INTO meta (meta_key, value_txt) VALUES (:key, :val) ON CONFLICT(meta_key) DO UPDATE SET value_txt = :val", sq.PP{
|
||||
"key": "schema_hash",
|
||||
"val": dbschema.Hash,
|
||||
})
|
||||
|
||||
{
|
||||
tctx := simplectx.CreateSimpleContext(ctx, nil)
|
||||
schemHashDB, err := sq.HashSqliteDatabase(tctx, qqdb)
|
||||
tt.TestFailIfErr(t, err)
|
||||
tt.AssertEqual(t, "schemHashDB", dbschema.Hash, schemHashDB)
|
||||
err = tctx.CommitTransaction()
|
||||
tt.TestFailIfErr(t, err)
|
||||
}
|
||||
|
||||
err = qqdb.Exit()
|
||||
tt.TestFailIfErr(t, err)
|
||||
}
|
||||
|
||||
{
|
||||
db1, err := primary.NewPrimaryDatabase(conf)
|
||||
tt.TestFailIfErr(t, err)
|
||||
|
||||
{
|
||||
tctx := simplectx.CreateSimpleContext(ctx, nil)
|
||||
|
||||
schema1, err := db1.ReadSchema(tctx)
|
||||
tt.TestFailIfErr(t, err)
|
||||
tt.AssertEqual(t, "schema1", 3, schema1)
|
||||
|
||||
err = tctx.CommitTransaction()
|
||||
tt.TestFailIfErr(t, err)
|
||||
}
|
||||
|
||||
{
|
||||
err = db1.Migrate(ctx)
|
||||
tt.TestFailIfErr(t, err)
|
||||
}
|
||||
|
||||
{
|
||||
tctx := simplectx.CreateSimpleContext(ctx, nil)
|
||||
|
||||
schema2, err := db1.ReadSchema(tctx)
|
||||
tt.TestFailIfErr(t, err)
|
||||
tt.AssertEqual(t, "schema2", schema.PrimarySchemaVersion, schema2)
|
||||
|
||||
err = tctx.CommitTransaction()
|
||||
tt.TestFailIfErr(t, err)
|
||||
}
|
||||
|
||||
{
|
||||
tctx := simplectx.CreateSimpleContext(ctx, nil)
|
||||
schemHashDB, err := sq.HashSqliteDatabase(tctx, db1.DB())
|
||||
tt.TestFailIfErr(t, err)
|
||||
tt.AssertEqual(t, "schemHashDB", schema.PrimarySchema[schema.PrimarySchemaVersion].Hash, schemHashDB)
|
||||
err = tctx.CommitTransaction()
|
||||
tt.TestFailIfErr(t, err)
|
||||
}
|
||||
|
||||
err = db1.Stop(ctx)
|
||||
tt.TestFailIfErr(t, err)
|
||||
}
|
||||
}
|
@@ -302,6 +302,10 @@ func AssertArrAny[T any](t *testing.T, key string, arr []T, fn func(T) bool) {
|
||||
}
|
||||
}
|
||||
|
||||
func AssertAny(v any) {
|
||||
// used to prevent golang "unused variable error"
|
||||
}
|
||||
|
||||
func unpointer(v any) any {
|
||||
if v == nil {
|
||||
return v
|
||||
|
@@ -75,32 +75,9 @@ func StartSimpleWebserver(t *testing.T) (*logic.Application, string, func()) {
|
||||
TPrintln("DatabaseFile<requests>: " + dbfile2)
|
||||
TPrintln("DatabaseFile<logs>: " + dbfile3)
|
||||
|
||||
conf, ok := scn.GetConfig("local-host")
|
||||
if !ok {
|
||||
TestFail(t, "conf not found")
|
||||
}
|
||||
scn.Conf = CreateTestConfig(t, dbfile1, dbfile2, dbfile3)
|
||||
|
||||
conf.ServerPort = "0" // simply choose a free port
|
||||
conf.DBMain.File = dbfile1
|
||||
conf.DBLogs.File = dbfile2
|
||||
conf.DBRequests.File = dbfile3
|
||||
conf.DBMain.Timeout = 500 * time.Millisecond
|
||||
conf.DBLogs.Timeout = 500 * time.Millisecond
|
||||
conf.DBRequests.Timeout = 500 * time.Millisecond
|
||||
conf.DBMain.ConnMaxLifetime = 1 * time.Second
|
||||
conf.DBLogs.ConnMaxLifetime = 1 * time.Second
|
||||
conf.DBRequests.ConnMaxLifetime = 1 * time.Second
|
||||
conf.DBMain.ConnMaxIdleTime = 1 * time.Second
|
||||
conf.DBLogs.ConnMaxIdleTime = 1 * time.Second
|
||||
conf.DBRequests.ConnMaxIdleTime = 1 * time.Second
|
||||
conf.RequestMaxRetry = 32
|
||||
conf.RequestRetrySleep = 100 * time.Millisecond
|
||||
conf.ReturnRawErrors = true
|
||||
conf.DummyFirebase = true
|
||||
|
||||
scn.Conf = conf
|
||||
|
||||
sqlite, err := logic.NewDBPool(conf)
|
||||
sqlite, err := logic.NewDBPool(scn.Conf)
|
||||
if err != nil {
|
||||
TestFailErr(t, err)
|
||||
}
|
||||
@@ -111,7 +88,7 @@ func StartSimpleWebserver(t *testing.T) (*logic.Application, string, func()) {
|
||||
TestFailErr(t, err)
|
||||
}
|
||||
|
||||
ginengine := ginext.NewEngine(conf)
|
||||
ginengine := ginext.NewEngine(scn.Conf)
|
||||
|
||||
router := api.NewRouter(app)
|
||||
|
||||
@@ -119,7 +96,7 @@ func StartSimpleWebserver(t *testing.T) (*logic.Application, string, func()) {
|
||||
|
||||
apc := google.NewDummy()
|
||||
|
||||
app.Init(conf, ginengine, nc, apc, []logic.Job{
|
||||
app.Init(scn.Conf, ginengine, nc, apc, []logic.Job{
|
||||
jobs.NewDeliveryRetryJob(app),
|
||||
jobs.NewRequestLogCollectorJob(app),
|
||||
})
|
||||
@@ -148,3 +125,99 @@ func StartSimpleWebserver(t *testing.T) (*logic.Application, string, func()) {
|
||||
|
||||
return app, "http://127.0.0.1:" + app.Port, stop
|
||||
}
|
||||
|
||||
func StartSimpleTestspace(t *testing.T) (string, string, string, scn.Config, func()) {
|
||||
InitTests()
|
||||
|
||||
uuid1, _ := langext.NewHexUUID()
|
||||
uuid2, _ := langext.NewHexUUID()
|
||||
uuid3, _ := langext.NewHexUUID()
|
||||
|
||||
dbdir := t.TempDir()
|
||||
dbfile1 := filepath.Join(dbdir, uuid1+".sqlite3")
|
||||
dbfile2 := filepath.Join(dbdir, uuid2+".sqlite3")
|
||||
dbfile3 := filepath.Join(dbdir, uuid3+".sqlite3")
|
||||
|
||||
err := os.MkdirAll(dbdir, os.ModePerm)
|
||||
if err != nil {
|
||||
TestFailErr(t, err)
|
||||
}
|
||||
|
||||
f1, err := os.Create(dbfile1)
|
||||
if err != nil {
|
||||
TestFailErr(t, err)
|
||||
}
|
||||
err = f1.Close()
|
||||
if err != nil {
|
||||
TestFailErr(t, err)
|
||||
}
|
||||
err = os.Chmod(dbfile1, 0777)
|
||||
if err != nil {
|
||||
TestFailErr(t, err)
|
||||
}
|
||||
f2, err := os.Create(dbfile2)
|
||||
if err != nil {
|
||||
TestFailErr(t, err)
|
||||
}
|
||||
err = f2.Close()
|
||||
if err != nil {
|
||||
TestFailErr(t, err)
|
||||
}
|
||||
err = os.Chmod(dbfile2, 0777)
|
||||
if err != nil {
|
||||
TestFailErr(t, err)
|
||||
}
|
||||
f3, err := os.Create(dbfile3)
|
||||
if err != nil {
|
||||
TestFailErr(t, err)
|
||||
}
|
||||
err = f3.Close()
|
||||
if err != nil {
|
||||
TestFailErr(t, err)
|
||||
}
|
||||
err = os.Chmod(dbfile3, 0777)
|
||||
if err != nil {
|
||||
TestFailErr(t, err)
|
||||
}
|
||||
|
||||
TPrintln("DatabaseFile<main>: " + dbfile1)
|
||||
TPrintln("DatabaseFile<requests>: " + dbfile2)
|
||||
TPrintln("DatabaseFile<logs>: " + dbfile3)
|
||||
|
||||
scn.Conf = CreateTestConfig(t, dbfile1, dbfile2, dbfile3)
|
||||
|
||||
stop := func() {
|
||||
_ = os.Remove(dbfile1)
|
||||
_ = os.Remove(dbfile2)
|
||||
_ = os.Remove(dbfile3)
|
||||
}
|
||||
|
||||
return dbfile1, dbfile2, dbfile3, scn.Conf, stop
|
||||
}
|
||||
|
||||
func CreateTestConfig(t *testing.T, dbfile1 string, dbfile2 string, dbfile3 string) scn.Config {
|
||||
conf, ok := scn.GetConfig("local-host")
|
||||
if !ok {
|
||||
TestFail(t, "conf not found")
|
||||
}
|
||||
|
||||
conf.ServerPort = "0" // simply choose a free port
|
||||
conf.DBMain.File = dbfile1
|
||||
conf.DBLogs.File = dbfile2
|
||||
conf.DBRequests.File = dbfile3
|
||||
conf.DBMain.Timeout = 500 * time.Millisecond
|
||||
conf.DBLogs.Timeout = 500 * time.Millisecond
|
||||
conf.DBRequests.Timeout = 500 * time.Millisecond
|
||||
conf.DBMain.ConnMaxLifetime = 1 * time.Second
|
||||
conf.DBLogs.ConnMaxLifetime = 1 * time.Second
|
||||
conf.DBRequests.ConnMaxLifetime = 1 * time.Second
|
||||
conf.DBMain.ConnMaxIdleTime = 1 * time.Second
|
||||
conf.DBLogs.ConnMaxIdleTime = 1 * time.Second
|
||||
conf.DBRequests.ConnMaxIdleTime = 1 * time.Second
|
||||
conf.RequestMaxRetry = 32
|
||||
conf.RequestRetrySleep = 100 * time.Millisecond
|
||||
conf.ReturnRawErrors = true
|
||||
conf.DummyFirebase = true
|
||||
|
||||
return conf
|
||||
}
|
||||
|
Reference in New Issue
Block a user