snapshot of https://github.com/ory/kratos.git (master, 2026-09-15; blobs > 131072B omitted)
Some checks failed
CI / Run tests and lints (push) Failing after 29s
CI / Build CLI docs (push) Has been skipped
CI / Run Playwright end-to-end tests (mysql) (push) Failing after 3s
CI / Run Playwright end-to-end tests (postgres) (push) Failing after 2s
CI / Run Playwright end-to-end tests (sqlite) (push) Failing after 3s
CodeQL / Analyze (go) (push) Failing after 4s
CodeQL / Analyze (javascript) (push) Failing after 3s
Docker Image Scanners / scanners (push) Failing after 4s
Synchronize Issue Labels / Synchronize Issue Labels (push) Has been skipped
CI / Run end-to-end tests (postgres) (push) Failing after 19s
CI / Run end-to-end tests (sqlite) (push) Failing after 2s
CI / Run Playwright end-to-end tests (cockroach) (push) Failing after 2s
CI / Draft newsletter (push) Has been skipped
CI / Generate release (push) Has been skipped
CI / Pending approval Slack notification (push) Has been skipped
CI / Send newsletter (push) Has been skipped
Some checks failed
CI / Run tests and lints (push) Failing after 29s
CI / Build CLI docs (push) Has been skipped
CI / Run Playwright end-to-end tests (mysql) (push) Failing after 3s
CI / Run Playwright end-to-end tests (postgres) (push) Failing after 2s
CI / Run Playwright end-to-end tests (sqlite) (push) Failing after 3s
CodeQL / Analyze (go) (push) Failing after 4s
CodeQL / Analyze (javascript) (push) Failing after 3s
Docker Image Scanners / scanners (push) Failing after 4s
Synchronize Issue Labels / Synchronize Issue Labels (push) Has been skipped
CI / Run end-to-end tests (postgres) (push) Failing after 19s
CI / Run end-to-end tests (sqlite) (push) Failing after 2s
CI / Run Playwright end-to-end tests (cockroach) (push) Failing after 2s
CI / Draft newsletter (push) Has been skipped
CI / Generate release (push) Has been skipped
CI / Pending approval Slack notification (push) Has been skipped
CI / Send newsletter (push) Has been skipped
This commit is contained in:
513
persistence/sql/persister_test.go
Normal file
513
persistence/sql/persister_test.go
Normal file
@@ -0,0 +1,513 @@
|
||||
// Copyright © 2023 Ory Corp
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package sql_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
"regexp"
|
||||
"strings"
|
||||
"sync"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/cockroachdb/cockroach-go/v2/testserver"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"golang.org/x/sync/errgroup"
|
||||
|
||||
continuity "github.com/ory/kratos/continuity/test"
|
||||
"github.com/ory/kratos/corpx"
|
||||
courier "github.com/ory/kratos/courier/test"
|
||||
"github.com/ory/kratos/driver/config"
|
||||
ri "github.com/ory/kratos/identity"
|
||||
identity "github.com/ory/kratos/identity/test"
|
||||
"github.com/ory/kratos/persistence/sql"
|
||||
"github.com/ory/kratos/persistence/sql/batch"
|
||||
sqltesthelpers "github.com/ory/kratos/persistence/sql/testhelpers"
|
||||
"github.com/ory/kratos/pkg"
|
||||
"github.com/ory/kratos/pkg/testhelpers"
|
||||
"github.com/ory/kratos/schema"
|
||||
errorx "github.com/ory/kratos/selfservice/errorx/test"
|
||||
lf "github.com/ory/kratos/selfservice/flow/login"
|
||||
login "github.com/ory/kratos/selfservice/flow/login/test"
|
||||
recovery "github.com/ory/kratos/selfservice/flow/recovery/test"
|
||||
registration "github.com/ory/kratos/selfservice/flow/registration/test"
|
||||
settings "github.com/ory/kratos/selfservice/flow/settings/test"
|
||||
verification "github.com/ory/kratos/selfservice/flow/verification/test"
|
||||
sessiontokenexchange "github.com/ory/kratos/selfservice/sessiontokenexchange/test"
|
||||
code "github.com/ory/kratos/selfservice/strategy/code/test"
|
||||
link "github.com/ory/kratos/selfservice/strategy/link/test"
|
||||
session "github.com/ory/kratos/session/test"
|
||||
"github.com/ory/kratos/x"
|
||||
"github.com/ory/pop/v6"
|
||||
"github.com/ory/pop/v6/logging"
|
||||
"github.com/ory/x/configx"
|
||||
"github.com/ory/x/dbal"
|
||||
"github.com/ory/x/popx"
|
||||
"github.com/ory/x/sqlcon"
|
||||
"github.com/ory/x/sqlcon/dockertest"
|
||||
"github.com/ory/x/sqlxx"
|
||||
"github.com/ory/x/urlx"
|
||||
)
|
||||
|
||||
func init() {
|
||||
corpx.RegisterFakes()
|
||||
pop.SetNowFunc(func() time.Time {
|
||||
return time.Now().UTC().Round(time.Second)
|
||||
})
|
||||
}
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
os.Exit(m.Run())
|
||||
}
|
||||
|
||||
func pl(t testing.TB) func(lvl logging.Level, s string, args ...interface{}) {
|
||||
return func(lvl logging.Level, s string, args ...interface{}) {
|
||||
if pop.Debug == false {
|
||||
return
|
||||
}
|
||||
|
||||
if lvl == logging.SQL {
|
||||
if len(args) > 0 {
|
||||
xargs := make([]string, len(args))
|
||||
for i, a := range args {
|
||||
switch a.(type) {
|
||||
case string:
|
||||
xargs[i] = fmt.Sprintf("%q", a)
|
||||
default:
|
||||
xargs[i] = fmt.Sprintf("%v", a)
|
||||
}
|
||||
}
|
||||
s = fmt.Sprintf("%s - %s | %s", lvl, s, xargs)
|
||||
} else {
|
||||
s = fmt.Sprintf("%s - %s", lvl, s)
|
||||
}
|
||||
} else {
|
||||
s = fmt.Sprintf(s, args...)
|
||||
s = fmt.Sprintf("%s - %s", lvl, s)
|
||||
}
|
||||
t.Log(s)
|
||||
}
|
||||
}
|
||||
|
||||
var dbNames = []string{"sqlite", "postgres", "mysql", "cockroach"}
|
||||
|
||||
func setupDatabase(t testing.TB, name string) string {
|
||||
var dsn string
|
||||
switch name {
|
||||
case "sqlite":
|
||||
dsn = dbal.NewSQLiteTestDatabase(t)
|
||||
case "postgres":
|
||||
dsn = dockertest.RunTestPostgreSQLWithVersion(t, "16")
|
||||
case "mysql":
|
||||
dsn = dockertest.RunTestMySQLWithVersion(t, "8.4")
|
||||
case "cockroach":
|
||||
dsn = newLocalTestCRDBServer(t)
|
||||
default:
|
||||
t.Fatalf("unknown database: %s", name)
|
||||
}
|
||||
|
||||
if name != "sqlite" {
|
||||
require.EventuallyWithT(t, func(t *assert.CollectT) {
|
||||
c, err := pop.NewConnection(&pop.ConnectionDetails{URL: dsn})
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, c.Open())
|
||||
dbName := "testdb" + strings.ReplaceAll(x.NewUUID().String(), "-", "")
|
||||
require.NoError(t, c.RawQuery("CREATE DATABASE "+dbName).Exec())
|
||||
dsn = regexp.MustCompile(`/[a-z0-9]+\?`).ReplaceAllString(dsn, "/"+dbName+"?")
|
||||
}, 60*time.Second, 200*time.Millisecond)
|
||||
}
|
||||
|
||||
t.Logf("Connecting to %s: %s", name, dsn)
|
||||
|
||||
_, reg := pkg.NewRegistryDefaultWithDSN(t, dsn)
|
||||
p := reg.Persister().(*sql.Persister)
|
||||
|
||||
t.Logf("Applying %s migrations", name)
|
||||
pop.SetLogger(pl(t))
|
||||
require.NoError(t, p.MigrateUp(t.Context()))
|
||||
t.Logf("%s migrations applied", name)
|
||||
status, err := p.MigrationStatus(t.Context())
|
||||
require.NoError(t, err)
|
||||
require.False(t, status.HasPending())
|
||||
|
||||
t.Logf("Database %s initialized successfully", name)
|
||||
return dsn
|
||||
}
|
||||
|
||||
func TestPersister(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
ctx := t.Context()
|
||||
// Bake the default identity schema into each registry's base config below
|
||||
// instead of layering it onto ctx. A context overlay makes
|
||||
// TestConfigProvider.Config rebuild the whole koanf tree on every config read
|
||||
// (the same reason identity.TestPool bakes PoolConfigValues), which the
|
||||
// contracts here would otherwise pay on every read.
|
||||
defaultSchema := configx.WithValues(testhelpers.DefaultIdentitySchemaConfig("file://./stub/identity.schema.json"))
|
||||
|
||||
for _, name := range dbNames {
|
||||
t.Run(fmt.Sprintf("database=%s", name), func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
if name != "sqlite" && testing.Short() {
|
||||
t.Skip("skipping non-sqlite under -short")
|
||||
}
|
||||
|
||||
dsn := setupDatabase(t, name)
|
||||
t.Logf("DSN: %s", dsn)
|
||||
|
||||
t.Run("racy identity creation", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
dsn := dsn
|
||||
// Just have a separate DB for sqlite to speed it up.
|
||||
if name == "sqlite" {
|
||||
dsn = dbal.NewSQLiteTestDatabase(t)
|
||||
// Pre-run migrations so concurrent goroutine startups below
|
||||
// don't race to apply the same migrations on a fresh DB.
|
||||
pkg.NewRegistryDefaultWithDSN(t, dsn)
|
||||
}
|
||||
|
||||
var wg sync.WaitGroup
|
||||
|
||||
for i := range 10 {
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
|
||||
_, reg := pkg.NewRegistryDefaultWithDSN(t, dsn, defaultSchema)
|
||||
_, ps := testhelpers.NewNetwork(t, ctx, reg.Persister())
|
||||
id := ri.NewIdentity("")
|
||||
id.SetCredentials(ri.CredentialsTypePassword, ri.Credentials{
|
||||
Type: ri.CredentialsTypePassword,
|
||||
Identifiers: []string{fmt.Sprintf("racy identity %d", i)},
|
||||
Config: sqlxx.JSONRawMessage(`{"foo":"bar"}`),
|
||||
})
|
||||
id.Traits = ri.Traits("{}")
|
||||
|
||||
require.NoError(t, ps.CreateIdentity(ctx, id))
|
||||
}()
|
||||
}
|
||||
|
||||
wg.Wait()
|
||||
})
|
||||
|
||||
t.Run("case=credential types exist", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
dsn := dsn
|
||||
// Just have a separate DB for sqlite to speed it up.
|
||||
if name == "sqlite" {
|
||||
dsn = dbal.NewSQLiteTestDatabase(t)
|
||||
}
|
||||
|
||||
_, reg := pkg.NewRegistryDefaultWithDSN(t, dsn, defaultSchema)
|
||||
_, p := testhelpers.NewNetwork(t, ctx, reg.Persister())
|
||||
for _, ct := range []ri.CredentialsType{ri.CredentialsTypeOIDC, ri.CredentialsTypePassword} {
|
||||
require.NoError(t, p.(*sql.Persister).Connection(t.Context()).Where("name = ?", ct).First(&ri.CredentialsTypeTable{}))
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("contract=identity.TestPool", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
dsn := dsn
|
||||
// Just have a separate DB for sqlite to speed it up.
|
||||
if name == "sqlite" {
|
||||
dsn = dbal.NewSQLiteTestDatabase(t)
|
||||
}
|
||||
|
||||
// Unlike the sibling contracts (which bake only the single default
|
||||
// identity schema via defaultSchema), this contract needs the full
|
||||
// PoolConfigValues schema set baked into the registry's base config.
|
||||
ctx := t.Context()
|
||||
_, reg := pkg.NewRegistryDefaultWithDSN(t, dsn, configx.WithValues(identity.PoolConfigValues()))
|
||||
_, p := testhelpers.NewNetwork(t, ctx, reg.Persister())
|
||||
identity.TestPool(ctx, p, reg.IdentityManager(), name)(t)
|
||||
})
|
||||
t.Run("contract=registration.TestFlowPersister", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
dsn := dsn
|
||||
// Just have a separate DB for sqlite to speed it up.
|
||||
if name == "sqlite" {
|
||||
dsn = dbal.NewSQLiteTestDatabase(t)
|
||||
}
|
||||
|
||||
_, reg := pkg.NewRegistryDefaultWithDSN(t, dsn, defaultSchema)
|
||||
_, p := testhelpers.NewNetwork(t, ctx, reg.Persister())
|
||||
registration.TestFlowPersister(ctx, p)(t)
|
||||
})
|
||||
t.Run("contract=errorx.TestPersister", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
dsn := dsn
|
||||
// Just have a separate DB for sqlite to speed it up.
|
||||
if name == "sqlite" {
|
||||
dsn = dbal.NewSQLiteTestDatabase(t)
|
||||
}
|
||||
|
||||
_, reg := pkg.NewRegistryDefaultWithDSN(t, dsn, defaultSchema)
|
||||
_, p := testhelpers.NewNetwork(t, ctx, reg.Persister())
|
||||
errorx.TestPersister(ctx, p)(t)
|
||||
})
|
||||
t.Run("contract=login.TestFlowPersister", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
dsn := dsn
|
||||
// Just have a separate DB for sqlite to speed it up.
|
||||
if name == "sqlite" {
|
||||
dsn = dbal.NewSQLiteTestDatabase(t)
|
||||
}
|
||||
|
||||
_, reg := pkg.NewRegistryDefaultWithDSN(t, dsn, defaultSchema)
|
||||
_, p := testhelpers.NewNetwork(t, ctx, reg.Persister())
|
||||
login.TestFlowPersister(ctx, p)(t)
|
||||
})
|
||||
t.Run("contract=settings.TestFlowPersister", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
dsn := dsn
|
||||
// Just have a separate DB for sqlite to speed it up.
|
||||
if name == "sqlite" {
|
||||
dsn = dbal.NewSQLiteTestDatabase(t)
|
||||
}
|
||||
|
||||
_, reg := pkg.NewRegistryDefaultWithDSN(t, dsn, defaultSchema)
|
||||
_, p := testhelpers.NewNetwork(t, ctx, reg.Persister())
|
||||
settings.TestFlowPersister(ctx, p)(t)
|
||||
})
|
||||
t.Run("contract=session.TestPersister", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
dsn := dsn
|
||||
// Just have a separate DB for sqlite to speed it up.
|
||||
if name == "sqlite" {
|
||||
dsn = dbal.NewSQLiteTestDatabase(t)
|
||||
}
|
||||
|
||||
_, reg := pkg.NewRegistryDefaultWithDSN(t, dsn, defaultSchema)
|
||||
_, p := testhelpers.NewNetwork(t, ctx, reg.Persister())
|
||||
session.TestPersister(ctx, reg.Config(), p)(t)
|
||||
})
|
||||
t.Run("contract=sessiontokenexchange.TestPersister", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
dsn := dsn
|
||||
// Just have a separate DB for sqlite to speed it up.
|
||||
if name == "sqlite" {
|
||||
dsn = dbal.NewSQLiteTestDatabase(t)
|
||||
}
|
||||
|
||||
_, reg := pkg.NewRegistryDefaultWithDSN(t, dsn, defaultSchema)
|
||||
_, p := testhelpers.NewNetwork(t, ctx, reg.Persister())
|
||||
sessiontokenexchange.TestPersister(ctx, p)(t)
|
||||
})
|
||||
t.Run("contract=courier.TestPersister", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
dsn := dsn
|
||||
// Just have a separate DB for sqlite to speed it up.
|
||||
if name == "sqlite" {
|
||||
dsn = dbal.NewSQLiteTestDatabase(t)
|
||||
}
|
||||
|
||||
_, reg := pkg.NewRegistryDefaultWithDSN(t, dsn, defaultSchema)
|
||||
_, p := testhelpers.NewNetwork(t, ctx, reg.Persister())
|
||||
upsert, insert := sqltesthelpers.DefaultNetworkWrapper(p)
|
||||
courier.TestPersister(ctx, upsert, insert)(t)
|
||||
})
|
||||
t.Run("contract=verification.TestFlowPersister", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
dsn := dsn
|
||||
// Just have a separate DB for sqlite to speed it up.
|
||||
if name == "sqlite" {
|
||||
dsn = dbal.NewSQLiteTestDatabase(t)
|
||||
}
|
||||
|
||||
_, reg := pkg.NewRegistryDefaultWithDSN(t, dsn, defaultSchema)
|
||||
_, p := testhelpers.NewNetwork(t, ctx, reg.Persister())
|
||||
verification.TestFlowPersister(ctx, p)(t)
|
||||
})
|
||||
t.Run("contract=recovery.TestFlowPersister", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
dsn := dsn
|
||||
// Just have a separate DB for sqlite to speed it up.
|
||||
if name == "sqlite" {
|
||||
dsn = dbal.NewSQLiteTestDatabase(t)
|
||||
}
|
||||
|
||||
_, reg := pkg.NewRegistryDefaultWithDSN(t, dsn, defaultSchema)
|
||||
_, p := testhelpers.NewNetwork(t, ctx, reg.Persister())
|
||||
recovery.TestFlowPersister(ctx, p)(t)
|
||||
})
|
||||
t.Run("contract=link.TestPersister", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
dsn := dsn
|
||||
// Just have a separate DB for sqlite to speed it up.
|
||||
if name == "sqlite" {
|
||||
dsn = dbal.NewSQLiteTestDatabase(t)
|
||||
}
|
||||
|
||||
_, reg := pkg.NewRegistryDefaultWithDSN(t, dsn, defaultSchema)
|
||||
_, p := testhelpers.NewNetwork(t, ctx, reg.Persister())
|
||||
link.TestPersister(ctx, p)(t)
|
||||
})
|
||||
t.Run("contract=code.TestPersister", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
dsn := dsn
|
||||
// Just have a separate DB for sqlite to speed it up.
|
||||
if name == "sqlite" {
|
||||
dsn = dbal.NewSQLiteTestDatabase(t)
|
||||
}
|
||||
|
||||
_, reg := pkg.NewRegistryDefaultWithDSN(t, dsn, defaultSchema)
|
||||
_, p := testhelpers.NewNetwork(t, ctx, reg.Persister())
|
||||
code.TestPersister(ctx, p)(t)
|
||||
})
|
||||
t.Run("contract=continuity.TestPersister", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
dsn := dsn
|
||||
// Just have a separate DB for sqlite to speed it up.
|
||||
if name == "sqlite" {
|
||||
dsn = dbal.NewSQLiteTestDatabase(t)
|
||||
}
|
||||
|
||||
_, reg := pkg.NewRegistryDefaultWithDSN(t, dsn, defaultSchema)
|
||||
_, p := testhelpers.NewNetwork(t, ctx, reg.Persister())
|
||||
continuity.TestPersister(ctx, p)(t)
|
||||
})
|
||||
t.Run("contract=batch.TestPersister", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
dsn := dsn
|
||||
// Just have a separate DB for sqlite to speed it up.
|
||||
if name == "sqlite" {
|
||||
dsn = dbal.NewSQLiteTestDatabase(t)
|
||||
}
|
||||
|
||||
_, reg := pkg.NewRegistryDefaultWithDSN(t, dsn, defaultSchema)
|
||||
_, p := testhelpers.NewNetwork(t, ctx, reg.Persister())
|
||||
batch.TestPersister(ctx, reg.Tracer(ctx), p)(t)
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func getErr(args ...interface{}) error {
|
||||
if len(args) == 0 {
|
||||
return nil
|
||||
}
|
||||
lastArg := args[len(args)-1]
|
||||
if e, ok := lastArg.(error); ok {
|
||||
return e
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func TestPersister_Transaction(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
_, reg := pkg.NewFastRegistryWithMocks(t)
|
||||
p := reg.Persister()
|
||||
|
||||
t.Run("case=should not create identity because callback returned error", func(t *testing.T) {
|
||||
i := &ri.Identity{
|
||||
ID: x.NewUUID(),
|
||||
State: ri.StateActive,
|
||||
Traits: ri.Traits(`{}`),
|
||||
}
|
||||
errMessage := "failing because why not"
|
||||
err := p.Transaction(t.Context(), func(_ context.Context, connection *pop.Connection) error {
|
||||
require.NoError(t, connection.Create(i))
|
||||
return errors.New(errMessage)
|
||||
})
|
||||
require.Error(t, err)
|
||||
assert.Contains(t, err.Error(), errMessage)
|
||||
_, err = p.GetIdentity(t.Context(), i.ID, ri.ExpandNothing)
|
||||
require.Error(t, err)
|
||||
assert.Equal(t, sqlcon.ErrNoRows().Error(), err.Error())
|
||||
})
|
||||
|
||||
t.Run("case=functions should use the context connection", func(t *testing.T) {
|
||||
c := p.GetConnection(t.Context())
|
||||
errMessage := "some stupid error you can't debug"
|
||||
lr := &lf.Flow{
|
||||
ID: x.NewUUID(),
|
||||
}
|
||||
err := c.Transaction(func(tx *pop.Connection) error {
|
||||
ctx := popx.WithTransaction(t.Context(), tx)
|
||||
require.NoError(t, p.CreateLoginFlow(ctx, lr), "%+v", lr)
|
||||
require.NoError(t, getErr(p.GetLoginFlow(ctx, lr.ID)), "%+v", lr)
|
||||
return errors.New(errMessage)
|
||||
})
|
||||
require.Error(t, err)
|
||||
assert.Contains(t, err.Error(), errMessage)
|
||||
_, err = p.GetLoginFlow(t.Context(), lr.ID)
|
||||
require.Error(t, err)
|
||||
assert.Equal(t, sqlcon.ErrNoRows().Error(), err.Error())
|
||||
})
|
||||
}
|
||||
|
||||
func Benchmark_BatchCreateIdentities(b *testing.B) {
|
||||
ctx := b.Context()
|
||||
batchSizes := []int{1, 10, 100, 500, 800, 900, 1000, 2000, 3000}
|
||||
parallelRequests := []int{1, 4, 8, 16}
|
||||
|
||||
for _, name := range dbNames {
|
||||
b.Run(fmt.Sprintf("database=%s", name), func(b *testing.B) {
|
||||
dsn := setupDatabase(b, name)
|
||||
_, reg := pkg.NewRegistryDefaultWithDSN(b, dsn)
|
||||
conf := reg.Config()
|
||||
_, p := testhelpers.NewNetwork(b, ctx, reg.Persister())
|
||||
multipleEmailsSchema := schema.Schema{
|
||||
ID: "multiple_emails",
|
||||
URL: urlx.ParseOrPanic("file://./stub/handler/multiple_emails.schema.json"),
|
||||
RawURL: "file://./stub/identity-2.schema.json",
|
||||
}
|
||||
conf.MustSet(ctx, config.ViperKeyIdentitySchemas, []config.Schema{
|
||||
{
|
||||
ID: multipleEmailsSchema.ID,
|
||||
URL: multipleEmailsSchema.RawURL,
|
||||
},
|
||||
})
|
||||
conf.MustSet(ctx, config.ViperKeyPublicBaseURL, "http://localhost/")
|
||||
|
||||
run := 0
|
||||
for _, batchSize := range batchSizes {
|
||||
b.Run(fmt.Sprintf("batch-size=%d", batchSize), func(b *testing.B) {
|
||||
for _, paralellism := range parallelRequests {
|
||||
b.Run(fmt.Sprintf("parallelism=%d", paralellism), func(b *testing.B) {
|
||||
start := time.Now()
|
||||
for i := 0; i < b.N; i++ {
|
||||
wg := new(errgroup.Group)
|
||||
for paralell := 0; paralell < paralellism; paralell++ {
|
||||
paralell := paralell
|
||||
wg.Go(func() error {
|
||||
identities := make([]*ri.Identity, batchSize)
|
||||
prefix := fmt.Sprintf("bench-insert-run-%d", run+paralell)
|
||||
for j := range identities {
|
||||
identities[j] = identity.NewTestIdentity(1, prefix, j)
|
||||
}
|
||||
|
||||
return p.CreateIdentities(ctx, identities)
|
||||
})
|
||||
}
|
||||
assert.NoError(b, wg.Wait())
|
||||
run += paralellism
|
||||
}
|
||||
end := time.Now()
|
||||
b.ReportMetric(float64(paralellism*batchSize*b.N), "identites_created")
|
||||
b.ReportMetric(float64(paralellism*batchSize*b.N)/end.Sub(start).Seconds(), "identities/s")
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func newLocalTestCRDBServer(t testing.TB) string {
|
||||
ts, err := testserver.NewTestServer(testserver.CustomVersionOpt("v25.4.1"))
|
||||
require.NoError(t, err)
|
||||
t.Cleanup(ts.Stop)
|
||||
|
||||
require.NoError(t, ts.WaitForInit())
|
||||
|
||||
ts.PGURL().Scheme = "cockroach"
|
||||
return ts.PGURL().String()
|
||||
}
|
||||
Reference in New Issue
Block a user