2017-08-03 17:24:27 +00:00
|
|
|
package inmem
|
2017-02-20 16:08:03 +00:00
|
|
|
|
|
|
|
import (
|
2018-01-19 06:44:44 +00:00
|
|
|
"context"
|
2017-02-20 16:08:03 +00:00
|
|
|
"fmt"
|
2017-02-20 16:40:36 +00:00
|
|
|
"reflect"
|
|
|
|
"sort"
|
2017-02-20 16:08:03 +00:00
|
|
|
"testing"
|
|
|
|
|
|
|
|
radix "github.com/armon/go-radix"
|
2018-04-03 00:46:59 +00:00
|
|
|
log "github.com/hashicorp/go-hclog"
|
|
|
|
"github.com/hashicorp/vault/helper/logging"
|
2017-08-03 17:24:27 +00:00
|
|
|
"github.com/hashicorp/vault/physical"
|
2017-02-20 16:08:03 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
type faultyPseudo struct {
|
|
|
|
underlying InmemBackend
|
|
|
|
faultyPaths map[string]struct{}
|
|
|
|
}
|
|
|
|
|
2018-01-19 06:44:44 +00:00
|
|
|
func (f *faultyPseudo) Get(ctx context.Context, key string) (*physical.Entry, error) {
|
|
|
|
return f.underlying.Get(context.Background(), key)
|
2017-02-20 16:08:03 +00:00
|
|
|
}
|
|
|
|
|
2018-01-19 06:44:44 +00:00
|
|
|
func (f *faultyPseudo) Put(ctx context.Context, entry *physical.Entry) error {
|
|
|
|
return f.underlying.Put(context.Background(), entry)
|
2017-02-20 16:08:03 +00:00
|
|
|
}
|
|
|
|
|
2018-01-19 06:44:44 +00:00
|
|
|
func (f *faultyPseudo) Delete(ctx context.Context, key string) error {
|
|
|
|
return f.underlying.Delete(context.Background(), key)
|
2017-02-20 16:08:03 +00:00
|
|
|
}
|
|
|
|
|
2018-01-19 06:44:44 +00:00
|
|
|
func (f *faultyPseudo) GetInternal(ctx context.Context, key string) (*physical.Entry, error) {
|
2017-02-20 16:08:03 +00:00
|
|
|
if _, ok := f.faultyPaths[key]; ok {
|
|
|
|
return nil, fmt.Errorf("fault")
|
|
|
|
}
|
2018-01-19 06:44:44 +00:00
|
|
|
return f.underlying.GetInternal(context.Background(), key)
|
2017-02-20 16:08:03 +00:00
|
|
|
}
|
|
|
|
|
2018-01-19 06:44:44 +00:00
|
|
|
func (f *faultyPseudo) PutInternal(ctx context.Context, entry *physical.Entry) error {
|
2017-02-20 16:08:03 +00:00
|
|
|
if _, ok := f.faultyPaths[entry.Key]; ok {
|
|
|
|
return fmt.Errorf("fault")
|
|
|
|
}
|
2018-01-19 06:44:44 +00:00
|
|
|
return f.underlying.PutInternal(context.Background(), entry)
|
2017-02-20 16:08:03 +00:00
|
|
|
}
|
|
|
|
|
2018-01-19 06:44:44 +00:00
|
|
|
func (f *faultyPseudo) DeleteInternal(ctx context.Context, key string) error {
|
2017-02-20 16:08:03 +00:00
|
|
|
if _, ok := f.faultyPaths[key]; ok {
|
|
|
|
return fmt.Errorf("fault")
|
|
|
|
}
|
2018-01-19 06:44:44 +00:00
|
|
|
return f.underlying.DeleteInternal(context.Background(), key)
|
2017-02-20 16:08:03 +00:00
|
|
|
}
|
|
|
|
|
2018-01-19 06:44:44 +00:00
|
|
|
func (f *faultyPseudo) List(ctx context.Context, prefix string) ([]string, error) {
|
|
|
|
return f.underlying.List(context.Background(), prefix)
|
2017-02-20 16:08:03 +00:00
|
|
|
}
|
|
|
|
|
2018-01-19 06:44:44 +00:00
|
|
|
func (f *faultyPseudo) Transaction(ctx context.Context, txns []*physical.TxnEntry) error {
|
2017-02-20 16:08:03 +00:00
|
|
|
f.underlying.permitPool.Acquire()
|
|
|
|
defer f.underlying.permitPool.Release()
|
|
|
|
|
|
|
|
f.underlying.Lock()
|
|
|
|
defer f.underlying.Unlock()
|
|
|
|
|
2018-01-19 06:44:44 +00:00
|
|
|
return physical.GenericTransactionHandler(ctx, f, txns)
|
2017-02-20 16:08:03 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func newFaultyPseudo(logger log.Logger, faultyPaths []string) *faultyPseudo {
|
|
|
|
out := &faultyPseudo{
|
|
|
|
underlying: InmemBackend{
|
|
|
|
root: radix.New(),
|
2017-08-03 17:24:27 +00:00
|
|
|
permitPool: physical.NewPermitPool(1),
|
2018-04-03 00:46:59 +00:00
|
|
|
logger: logger.Named("storage.inmembackend"),
|
2018-06-09 22:31:47 +00:00
|
|
|
failGet: new(uint32),
|
|
|
|
failPut: new(uint32),
|
|
|
|
failDelete: new(uint32),
|
|
|
|
failList: new(uint32),
|
2017-02-20 16:08:03 +00:00
|
|
|
},
|
|
|
|
faultyPaths: make(map[string]struct{}, len(faultyPaths)),
|
|
|
|
}
|
|
|
|
for _, v := range faultyPaths {
|
|
|
|
out.faultyPaths[v] = struct{}{}
|
|
|
|
}
|
|
|
|
return out
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestPseudo_Basic(t *testing.T) {
|
2018-04-03 00:46:59 +00:00
|
|
|
logger := logging.NewVaultLogger(log.Debug)
|
2017-02-20 16:08:03 +00:00
|
|
|
p := newFaultyPseudo(logger, nil)
|
2017-08-03 17:24:27 +00:00
|
|
|
physical.ExerciseBackend(t, p)
|
|
|
|
physical.ExerciseBackend_ListPrefix(t, p)
|
2017-02-20 16:08:03 +00:00
|
|
|
}
|
2017-02-20 16:40:36 +00:00
|
|
|
|
|
|
|
func TestPseudo_SuccessfulTransaction(t *testing.T) {
|
2018-04-03 00:46:59 +00:00
|
|
|
logger := logging.NewVaultLogger(log.Debug)
|
2017-02-20 16:40:36 +00:00
|
|
|
p := newFaultyPseudo(logger, nil)
|
|
|
|
|
2017-08-03 17:24:27 +00:00
|
|
|
physical.ExerciseTransactionalBackend(t, p)
|
2017-02-20 16:40:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func TestPseudo_FailedTransaction(t *testing.T) {
|
2018-04-03 00:46:59 +00:00
|
|
|
logger := logging.NewVaultLogger(log.Debug)
|
2017-02-20 16:40:36 +00:00
|
|
|
p := newFaultyPseudo(logger, []string{"zip"})
|
|
|
|
|
2017-08-03 17:24:27 +00:00
|
|
|
txns := physical.SetupTestingTransactions(t, p)
|
2018-01-19 06:44:44 +00:00
|
|
|
if err := p.Transaction(context.Background(), txns); err == nil {
|
2017-02-20 16:40:36 +00:00
|
|
|
t.Fatal("expected error during transaction")
|
|
|
|
}
|
|
|
|
|
2018-01-19 06:44:44 +00:00
|
|
|
keys, err := p.List(context.Background(), "")
|
2017-02-20 16:40:36 +00:00
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
expected := []string{"foo", "zip", "deleteme", "deleteme2"}
|
|
|
|
|
|
|
|
sort.Strings(keys)
|
|
|
|
sort.Strings(expected)
|
|
|
|
if !reflect.DeepEqual(keys, expected) {
|
|
|
|
t.Fatalf("mismatch: expected\n%#v\ngot\n%#v\n", expected, keys)
|
|
|
|
}
|
|
|
|
|
2018-01-19 06:44:44 +00:00
|
|
|
entry, err := p.Get(context.Background(), "foo")
|
2017-02-20 16:40:36 +00:00
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
if entry == nil {
|
|
|
|
t.Fatal("got nil entry")
|
|
|
|
}
|
|
|
|
if entry.Value == nil {
|
|
|
|
t.Fatal("got nil value")
|
|
|
|
}
|
|
|
|
if string(entry.Value) != "bar" {
|
|
|
|
t.Fatal("values did not rollback correctly")
|
|
|
|
}
|
|
|
|
|
2018-01-19 06:44:44 +00:00
|
|
|
entry, err = p.Get(context.Background(), "zip")
|
2017-02-20 16:40:36 +00:00
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
if entry == nil {
|
|
|
|
t.Fatal("got nil entry")
|
|
|
|
}
|
|
|
|
if entry.Value == nil {
|
|
|
|
t.Fatal("got nil value")
|
|
|
|
}
|
|
|
|
if string(entry.Value) != "zap" {
|
|
|
|
t.Fatal("values did not rollback correctly")
|
|
|
|
}
|
|
|
|
}
|