//go:build !plan9 && !js // +build !plan9,!js package kv import ( "context" "fmt" "sync" "testing" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) func TestKvConcurrency(t *testing.T) { require.Equal(t, 0, len(dbMap), "no databases can be started initially") const threadNum = 5 var wg sync.WaitGroup ctx := context.Background() results := make([]*DB, threadNum) wg.Add(threadNum) for i := 0; i < threadNum; i++ { go func(i int) { db, err := Start(ctx, "test", nil) require.NoError(t, err) require.NotNil(t, db) results[i] = db wg.Done() }(i) } wg.Wait() // must have a single multi-referenced db db := results[0] assert.Equal(t, 1, len(dbMap)) assert.Equal(t, threadNum, db.refs) for i := 0; i < threadNum; i++ { assert.Equal(t, db, results[i]) } for i := 0; i < threadNum; i++ { assert.Equal(t, 1, len(dbMap)) err := db.Stop(false) assert.NoError(t, err, "unexpected error %v at retry %d", err, i) } assert.Equal(t, 0, len(dbMap), "must be closed in the end") err := db.Stop(false) assert.ErrorIs(t, err, ErrInactive, "missing expected stop indication") } func TestKvExit(t *testing.T) { require.Equal(t, 0, len(dbMap), "no databases can be started initially") const dbNum = 5 ctx := context.Background() for i := 0; i < dbNum; i++ { facility := fmt.Sprintf("test-%d", i) for j := 0; j <= i; j++ { db, err := Start(ctx, facility, nil) require.NoError(t, err) require.NotNil(t, db) } } assert.Equal(t, dbNum, len(dbMap)) Exit() assert.Equal(t, 0, len(dbMap)) }