Introduce a locking inmem storage for unit tests that are doing concurrent things

This commit is contained in:
Jeff Mitchell 2016-02-04 09:40:35 -05:00
parent d2de99f2ec
commit f75e121d8c
3 changed files with 72 additions and 1 deletions

View File

@ -549,7 +549,7 @@ func TestKeyUpgrade(t *testing.T) {
func TestPolicyFuzzing(t *testing.T) {
be := Backend()
storage := &logical.InmemStorage{}
storage := &logical.LockingInmemStorage{}
wg := sync.WaitGroup{}
funcs := []string{"encrypt", "decrypt", "rotate", "change_min_version"}

View File

@ -0,0 +1,58 @@
package logical
import (
"strings"
"sync"
)
// LockingInmemStorage implements Storage and stores all data in memory.
type LockingInmemStorage struct {
sync.RWMutex
Data map[string]*StorageEntry
once sync.Once
}
func (s *LockingInmemStorage) List(prefix string) ([]string, error) {
s.once.Do(s.init)
s.RLock()
defer s.RUnlock()
var result []string
for k, _ := range s.Data {
if strings.HasPrefix(k, prefix) {
result = append(result, k)
}
}
return result, nil
}
func (s *LockingInmemStorage) Get(key string) (*StorageEntry, error) {
s.once.Do(s.init)
s.RLock()
defer s.RUnlock()
return s.Data[key], nil
}
func (s *LockingInmemStorage) Put(entry *StorageEntry) error {
s.once.Do(s.init)
s.Lock()
defer s.Unlock()
s.Data[entry.Key] = entry
return nil
}
func (s *LockingInmemStorage) Delete(k string) error {
s.once.Do(s.init)
s.Lock()
defer s.Unlock()
delete(s.Data, k)
return nil
}
func (s *LockingInmemStorage) init() {
s.Data = make(map[string]*StorageEntry)
}

View File

@ -0,0 +1,13 @@
package logical
import (
"testing"
)
// Note: This uses the normal TestStorage, but the best way to exercise this is
// to run transit's unit tests, which spawn 1000 goroutines to hammer the
// backend for 10 seconds with this as the storage.
func TestLockingInmemStorage(t *testing.T) {
TestStorage(t, new(LockingInmemStorage))
}