Manage Yggdrasil providers from the panel using durable platform settings, protected identity namespaces and atomic revisions. Apply changes to subsequent logins and profile lookups without restarting. Return operator-host logouts to the login method selection page.
60 lines
1.6 KiB
Go
60 lines
1.6 KiB
Go
//go:build pgint
|
|
|
|
package pgint
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"sync"
|
|
"testing"
|
|
|
|
"felis.lolicon.best/internal/api"
|
|
)
|
|
|
|
func TestSettingsCompareAndSet(t *testing.T) {
|
|
ctx := context.Background()
|
|
key := "auth-sources-" + suffix(t)
|
|
defer db.ExecContext(ctx, "DELETE FROM platform_settings WHERE key=$1", key)
|
|
first := []byte(`[{"tag":"custom","enabled":true}]`)
|
|
next := []byte(`[{"tag":"custom","enabled":false}]`)
|
|
if err := repo.CompareAndSetSetting(ctx, key, first, next); !errors.Is(err, api.ErrConflict) {
|
|
t.Fatalf("missing update = %v", err)
|
|
}
|
|
if err := repo.CompareAndSetSetting(ctx, key, nil, first); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if err := repo.CompareAndSetSetting(ctx, key, nil, next); !errors.Is(err, api.ErrConflict) {
|
|
t.Fatalf("concurrent insert = %v", err)
|
|
}
|
|
// jsonb equality must survive PostgreSQL's different spacing and key order.
|
|
raw, err := repo.GetSetting(ctx, key)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
var wg sync.WaitGroup
|
|
results := make(chan error, 2)
|
|
for i := 0; i < 2; i++ {
|
|
wg.Add(1)
|
|
go func() { defer wg.Done(); results <- repo.CompareAndSetSetting(ctx, key, raw, next) }()
|
|
}
|
|
wg.Wait()
|
|
close(results)
|
|
succeeded, conflicted := 0, 0
|
|
for err := range results {
|
|
switch {
|
|
case err == nil:
|
|
succeeded++
|
|
case errors.Is(err, api.ErrConflict):
|
|
conflicted++
|
|
default:
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
if succeeded != 1 || conflicted != 1 {
|
|
t.Fatalf("concurrent update: success=%d conflict=%d", succeeded, conflicted)
|
|
}
|
|
if err := repo.CompareAndSetSetting(ctx, key, []byte(`[ { "enabled" : false, "tag" : "custom" } ]`), first); err != nil {
|
|
t.Fatalf("JSON equality = %v", err)
|
|
}
|
|
}
|