67 lines
1.4 KiB
Go
67 lines
1.4 KiB
Go
package store
|
|
|
|
import (
|
|
"errors"
|
|
"path/filepath"
|
|
"sync"
|
|
"testing"
|
|
)
|
|
|
|
func TestInstanceReservationConcurrencyAndRestart(t *testing.T) {
|
|
path := filepath.Join(t.TempDir(), "store.db")
|
|
s, err := Open(path)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
var wg sync.WaitGroup
|
|
result := make(chan error, 30)
|
|
for n := 0; n < 30; n++ {
|
|
wg.Add(1)
|
|
go func(n int) {
|
|
defer wg.Done()
|
|
result <- s.ReserveInstance(Instance{ID: ID(), UID: "u"})
|
|
}(n)
|
|
}
|
|
wg.Wait()
|
|
close(result)
|
|
ok := 0
|
|
for err := range result {
|
|
if err == nil {
|
|
ok++
|
|
} else if !errors.Is(err, ErrInstanceLimit) {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
if ok != 2 {
|
|
t.Fatalf("reserved %d", ok)
|
|
}
|
|
s.Close()
|
|
s, err = Open(path)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
defer s.Close()
|
|
if err = s.ReserveInstance(Instance{ID: ID(), UID: "u"}); !errors.Is(err, ErrInstanceLimit) {
|
|
t.Fatalf("restart lost reservation: %v", err)
|
|
}
|
|
}
|
|
|
|
func TestRetiredIntentsDoNotReserveInstanceSlots(t *testing.T) {
|
|
s, err := Open(filepath.Join(t.TempDir(), "store.db"))
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
defer s.Close()
|
|
if _, err := s.DB.Exec("CREATE TABLE creation_intents(uid TEXT,status TEXT); INSERT INTO creation_intents VALUES('u','waiting'),('u','creating')"); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
for n := 0; n < 2; n++ {
|
|
if err := s.ReserveInstance(Instance{ID: ID(), UID: "u"}); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
if err := s.ReserveInstance(Instance{ID: ID(), UID: "u"}); !errors.Is(err, ErrInstanceLimit) {
|
|
t.Fatal(err)
|
|
}
|
|
}
|