Files
upstream-corteza/server/tests/dal/dal_utils_test.go
upstream-mirror 7e385fc126
Some checks failed
SonarQube / SonarQube (push) Failing after 5m28s
E2e test on main branch push / server and client test (map[name:admin port:8080]) (push) Failing after 3m33s
Server and lib tests / Library test (js) (push) Failing after 1m36s
Server and lib tests / Library test (vue) (push) Successful in 2m24s
Server and lib tests / Web client test (admin) (push) Successful in 2m52s
Server and lib tests / Web client test (compose) (push) Successful in 3m23s
Server and lib tests / Web client test (discovery) (push) Successful in 2m49s
Server and lib tests / Web client test (one) (push) Successful in 2m52s
Server and lib tests / Web client test (privacy) (push) Successful in 2m44s
Server and lib tests / Web client test (reporter) (push) Successful in 2m56s
Server and lib tests / Web client test (workflow) (push) Successful in 3m0s
Server and lib tests / Server tests (push) Failing after 4m55s
E2e test on main branch push / notify-failure (push) Failing after 9s
Server and lib tests / Send matrix testing notification (push) Successful in 2s
Mark stale issues and pull requests / stale (push) Successful in 40s
snapshot of https://github.com/cortezaproject/corteza.git (2024.9.x, 2026-09-18; blobs > 131072B omitted)
2026-09-18 01:22:23 +05:00

360 lines
9.0 KiB
Go

package dal
import (
"context"
"fmt"
"os"
"testing"
composeService "github.com/cortezaproject/corteza/server/compose/service"
composeTypes "github.com/cortezaproject/corteza/server/compose/types"
"github.com/cortezaproject/corteza/server/pkg/auth"
"github.com/cortezaproject/corteza/server/pkg/dal"
"github.com/cortezaproject/corteza/server/pkg/id"
"github.com/cortezaproject/corteza/server/store"
"github.com/cortezaproject/corteza/server/system/service"
"github.com/cortezaproject/corteza/server/system/types"
"github.com/cortezaproject/corteza/server/tests/dal/setup/mysql"
"github.com/stretchr/testify/require"
"go.uber.org/zap"
)
type (
driver struct {
name string
dsn string
setup func(ctx context.Context, t wrapTest, dsn string)
}
dalConnectionRestRsp struct {
Response *types.DalConnection
}
composeModuleRestRsp struct {
Response *composeTypes.Module
}
composeRecordRestRsp struct {
Response *composeTypes.Record
}
composeRecordSearchRestRsp struct {
Response struct {
Set composeTypes.RecordSet
}
}
wrapTest interface {
require.TestingT
Name() string
}
modelMetaMaker func(ident string) *dal.Model
attributeMaker func() dal.AttributeSet
)
const (
sysID = "ID"
sysNamespaceID = "namespaceID"
sysModuleID = "moduleID"
sysCreatedAt = "createdAt"
sysCreatedBy = "createdBy"
sysUpdatedAt = "updatedAt"
sysUpdatedBy = "updatedBy"
sysDeletedAt = "deletedAt"
sysDeletedBy = "deletedBy"
sysOwnedBy = "ownedBy"
colSysID = "id"
colSysNamespaceID = "rel_namespace"
colSysModuleID = "rel_module"
colSysCreatedAt = "created_at"
colSysCreatedBy = "created_by"
colSysUpdatedAt = "updated_at"
colSysUpdatedBy = "updated_by"
colSysDeletedAt = "deleted_at"
colSysDeletedBy = "deleted_by"
colSysOwnedBy = "owned_by"
)
func (h helper) cleanupDal() {
ds := service.DefaultStore
ctx := context.Background()
dd := dal.Service()
models, err := dd.SearchModels(ctx)
h.a.NoError(err)
for _, model := range models {
dd.Truncate(ctx, model.ToFilter(), nil)
}
h.a.NoError(store.TruncateComposeModuleFields(ctx, ds))
h.a.NoError(store.TruncateComposeModules(ctx, ds))
h.a.NoError(store.TruncateComposeNamespaces(ctx, ds))
h.a.NoError(store.TruncateDalSensitivityLevels(ctx, ds))
cc, _, err := store.SearchDalConnections(ctx, ds, types.DalConnectionFilter{})
h.a.NoError(err)
for _, c := range cc {
if c.Type == types.DalPrimaryConnectionResourceType {
continue
}
h.a.NoError(store.DeleteDalConnectionByID(ctx, ds, c.ID))
}
dd.Purge(ctx)
h.a.NoError(service.DefaultDalConnection.ReloadConnections(ctx))
h.a.NoError(composeService.DefaultModule.ReloadDALModels(ctx))
}
func initSvc(ctx context.Context, d driver) (dal.FullService, error) {
c := makeConnectionDefinition(d.dsn)
cm := dal.ConnectionConfig{
ModelIdent: c.Config.DAL.ModelIdent,
SensitivityLevelID: c.Config.Privacy.SensitivityLevelID,
Label: c.Handle,
}
svc, err := dal.New(zap.NewNop(), false)
if err != nil {
return nil, err
}
err = svc.ReplaceConnection(
ctx,
dal.MakeConnection(
c.ID,
nil,
dal.ConnectionParams{
Type: "corteza::dal:connection:dsn",
Params: map[string]any{
"dsn": d.dsn,
},
},
cm,
),
true,
)
if err != nil {
return nil, err
}
return svc, err
}
func setup(t *testing.T) (ctx context.Context, h helper, log *zap.Logger) {
log = zap.NewNop()
h = newHelperT(t)
u := &types.User{
ID: id.Next(),
}
u.SetRoles(auth.BypassRoles().IDs()...)
ctx = auth.SetIdentityToContext(context.Background(), u)
return ctx, h, log
}
func setupBench(b *testing.B) (ctx context.Context, h helper, log *zap.Logger) {
log = zap.NewNop()
h = newHelperB(b)
u := &types.User{
ID: id.Next(),
}
u.SetRoles(auth.BypassRoles().IDs()...)
ctx = auth.SetIdentityToContext(context.Background(), u)
return ctx, h, log
}
func bootstrap(rootTest *testing.T, run func(context.Context, *testing.T, helper, dal.FullService)) {
var (
ctx, h, log = setup(rootTest)
drivers = collectDrivers()
)
_ = log
for _, driver := range drivers {
rootTest.Run(driver.name, func(t *testing.T) {
if driver.dsn == "" {
t.Skip("DSN for DAL test not set")
}
svc, err := initSvc(ctx, driver)
require.NoError(t, err)
driver.setup(ctx, rootTest, driver.dsn)
run(ctx, t, h, svc)
})
}
}
func bootstrapWithModel(rootTest *testing.T, ident string, run func(context.Context, *testing.T, helper, dal.FullService, *dal.Model)) {
var (
ctx, h, log = setup(rootTest)
drivers = collectDrivers()
)
_ = log
for _, driver := range drivers {
rootTest.Run(driver.name, func(t *testing.T) {
if driver.dsn == "" {
t.Skip("DSN for DAL test not set")
}
svc, err := initSvc(ctx, driver)
require.NoError(t, err)
model := buildModel(ident, basicModelMeta, fullPartitionedSysAttributes)
driver.setup(ctx, rootTest, driver.dsn)
_, err = svc.ReplaceModel(ctx, nil, model)
require.NoError(t, err)
run(ctx, t, h, svc, model)
})
}
}
func bootstrapBenchmark(rootTest *testing.B, run func(context.Context, *testing.B, helper, dal.FullService)) {
var (
ctx, h, log = setupBench(rootTest)
drivers = collectDrivers()
)
_ = log
for _, driver := range drivers {
rootTest.Run(driver.name, func(b *testing.B) {
if driver.dsn == "" {
b.Skip("DSN for DAL test not set")
}
svc, err := initSvc(ctx, driver)
require.NoError(b, err)
driver.setup(ctx, rootTest, driver.dsn)
run(ctx, b, h, svc)
})
}
}
func collectDrivers() []driver {
return []driver{
// {
// name: "sqlite",
// dsn: "sqlite3+debug://file::memory:?cache=shared&mode=memory",
// setup: func(ctx context.Context, t *testing.T, dsn string) {
// conn, err := mysql.Setup(ctx, dsn)
// require.NoError(t, err)
// _, err = conn.Exec(loadSetupSource(t, "sqlite.sql"))
// require.NoError(t, err)
// },
// },
{
name: "mysql",
dsn: os.Getenv("DAL_TEST_DSN_MYSQL"),
setup: func(ctx context.Context, t wrapTest, dsn string) {
conn, err := mysql.Setup(ctx, dsn)
require.NoError(t, err)
_, err = conn.Exec(loadScenarioSources(t, "mysql", "sql"))
require.NoError(t, err)
},
},
// {
// name: "postgres",
// dsn: os.Getenv("DAL_TEST_DSN_POSTGRES"),
// setup: func(ctx context.Context, t *testing.T, dsn string) {
// conn, err := mysql.Setup(ctx, dsn)
// require.NoError(t, err)
// _, err = conn.Exec(loadSetupSource(t, "postgres.sql"))
// require.NoError(t, err)
// },
// },
}
}
func buildModel(ident string, mm modelMetaMaker, am attributeMaker, aa ...*dal.Attribute) *dal.Model {
out := mm(ident)
out.Attributes = aa
out.Attributes = append(out.Attributes, am()...)
return out
}
func basicModelMeta(ident string) *dal.Model {
return &dal.Model{
ConnectionID: 0,
Ident: ident,
Resource: fmt.Sprintf("testing-resource/%s", ident),
ResourceID: 0,
}
}
func fullSysAttributes() dal.AttributeSet {
return dal.AttributeSet{
dal.PrimaryAttribute(sysID, &dal.CodecAlias{Ident: colSysID}),
dal.FullAttribute(sysModuleID, &dal.TypeID{}, &dal.CodecAlias{Ident: colSysModuleID}),
dal.FullAttribute(sysNamespaceID, &dal.TypeID{}, &dal.CodecAlias{Ident: colSysNamespaceID}),
dal.FullAttribute(sysOwnedBy, &dal.TypeID{}, &dal.CodecAlias{Ident: colSysOwnedBy}),
dal.FullAttribute(sysCreatedAt, &dal.TypeTimestamp{}, &dal.CodecAlias{Ident: colSysCreatedAt}),
dal.FullAttribute(sysCreatedBy, &dal.TypeID{}, &dal.CodecAlias{Ident: colSysCreatedBy}),
dal.FullAttribute(sysUpdatedAt, &dal.TypeTimestamp{}, &dal.CodecAlias{Ident: colSysUpdatedAt}),
dal.FullAttribute(sysUpdatedBy, &dal.TypeID{}, &dal.CodecAlias{Ident: colSysUpdatedBy}),
dal.FullAttribute(sysDeletedAt, &dal.TypeTimestamp{}, &dal.CodecAlias{Ident: colSysDeletedAt}),
dal.FullAttribute(sysDeletedBy, &dal.TypeID{}, &dal.CodecAlias{Ident: colSysDeletedBy}),
}
}
func fullPartitionedSysAttributes() dal.AttributeSet {
return dal.AttributeSet{
dal.PrimaryAttribute(sysID, &dal.CodecAlias{Ident: colSysID}),
// mod and ns omitted here
dal.FullAttribute(sysOwnedBy, &dal.TypeID{}, &dal.CodecAlias{Ident: colSysOwnedBy}),
dal.FullAttribute(sysCreatedAt, &dal.TypeTimestamp{}, &dal.CodecAlias{Ident: colSysCreatedAt}),
dal.FullAttribute(sysCreatedBy, &dal.TypeID{}, &dal.CodecAlias{Ident: colSysCreatedBy}),
dal.FullAttribute(sysUpdatedAt, &dal.TypeTimestamp{}, &dal.CodecAlias{Ident: colSysUpdatedAt}),
dal.FullAttribute(sysUpdatedBy, &dal.TypeID{}, &dal.CodecAlias{Ident: colSysUpdatedBy}),
dal.FullAttribute(sysDeletedAt, &dal.TypeTimestamp{}, &dal.CodecAlias{Ident: colSysDeletedAt}),
dal.FullAttribute(sysDeletedBy, &dal.TypeID{}, &dal.CodecAlias{Ident: colSysDeletedBy}),
}
}
func drain(ctx context.Context, i dal.Iterator) (rr []*composeTypes.Record, err error) {
var r *composeTypes.Record
rr = make([]*composeTypes.Record, 0, 100)
for i.Next(ctx) {
if i.Err() != nil {
return nil, i.Err()
}
r = new(composeTypes.Record)
if err = i.Scan(r); err != nil {
return
}
rr = append(rr, r)
}
return rr, i.Err()
}