blob: 569c50407eef779d19379df0c5166b3d45af9e4f [file] [log] [blame]
package blackbox
import (
"fmt"
"io/ioutil"
"os"
"runtime"
"testing"
"time"
"veyron/services/store/memstore"
memwatch "veyron/services/store/memstore/watch"
"veyron/services/store/raw"
"veyron/services/store/service"
"veyron2/ipc"
"veyron2/naming"
"veyron2/security"
"veyron2/services/watch"
"veyron2/storage"
)
var (
rootPublicID security.PublicID = security.FakePublicID("root")
rootCtx ipc.ServerContext = rootContext{}
nullMutation = raw.Mutation{}
)
// rootContext implements ipc.Context.
type rootContext struct{}
func (rootContext) Server() ipc.Server {
return nil
}
func (rootContext) Method() string {
return ""
}
func (rootContext) Name() string {
return ""
}
func (rootContext) Suffix() string {
return ""
}
func (rootContext) Label() (l security.Label) {
return
}
func (rootContext) CaveatDischarges() security.CaveatDischargeMap {
return nil
}
func (rootContext) LocalID() security.PublicID {
return rootPublicID
}
func (rootContext) RemoteID() security.PublicID {
return rootPublicID
}
func (rootContext) Blessing() security.PublicID {
return nil
}
func (rootContext) LocalEndpoint() naming.Endpoint {
return nil
}
func (rootContext) RemoteEndpoint() naming.Endpoint {
return nil
}
func (rootContext) Deadline() (t time.Time) {
return
}
func (rootContext) IsClosed() bool {
return false
}
func (rootContext) Closed() <-chan struct{} {
return nil
}
func Get(t *testing.T, st *memstore.Store, tr service.Transaction, path string) *storage.Entry {
_, file, line, _ := runtime.Caller(1)
e, err := st.Bind(path).Get(rootPublicID, tr)
if err != nil {
t.Fatalf("%s(%d): can't get %s: %s", file, line, path, err)
}
return e
}
func Put(t *testing.T, st *memstore.Store, tr service.Transaction, path string, v interface{}) storage.ID {
_, file, line, _ := runtime.Caller(1)
stat, err := st.Bind(path).Put(rootPublicID, tr, v)
if err != nil {
t.Fatalf("%s(%d): can't put %s: %s", file, line, path, err)
}
if stat != nil {
return stat.ID
}
if id, ok := v.(storage.ID); ok {
return id
}
t.Errorf("%s(%d): can't find id", file, line)
return storage.ID{}
}
func Remove(t *testing.T, st *memstore.Store, tr service.Transaction, path string) {
_, file, line, _ := runtime.Caller(1)
if err := st.Bind(path).Remove(rootPublicID, tr); err != nil {
t.Fatalf("%s(%d): can't remove %s: %s", file, line, path, err)
}
}
func Commit(t *testing.T, tr service.Transaction) {
if err := tr.Commit(); err != nil {
t.Fatalf("Transaction aborted: %s", err)
}
}
func ExpectExists(t *testing.T, st *memstore.Store, id storage.ID) {
_, err := st.Bind(fmt.Sprintf("/uid/%s", id)).Get(rootPublicID, nil)
if err != nil {
_, file, line, _ := runtime.Caller(1)
t.Errorf("%s(%d): Expected value for ID: %x", file, line, id)
}
}
func ExpectNotExists(t *testing.T, st *memstore.Store, id storage.ID) {
x, err := st.Bind(fmt.Sprintf("/uid/%s", id)).Get(rootPublicID, nil)
if err == nil {
_, file, line, _ := runtime.Caller(1)
t.Errorf("%s(%d): Unexpected value: %v", file, line, x)
}
}
func GC(t *testing.T, st *memstore.Store) {
if err := st.GC(); err != nil {
_, file, line, _ := runtime.Caller(1)
t.Fatalf("%s(%d): can't gc: %s", file, line, err)
}
}
func CreateStore(t *testing.T, dbSuffix string) (string, *memstore.Store, func()) {
dbName, err := ioutil.TempDir(os.TempDir(), dbSuffix)
if err != nil {
t.Fatalf("ioutil.TempDir() failed: %v", err)
}
cleanup := func() {
os.RemoveAll(dbName)
}
st, err := memstore.New(rootPublicID, dbName)
if err != nil {
cleanup()
t.Fatalf("New() failed: %v", err)
}
return dbName, st, cleanup
}
func OpenStore(t *testing.T, dbName string) (*memstore.Store, func()) {
st, err := memstore.New(rootPublicID, dbName)
if err != nil {
t.Fatalf("New() failed: %v", err)
}
return st, func() {
os.RemoveAll(dbName)
}
}
func OpenWatch(t *testing.T, dbName string) (service.Watcher, func()) {
w, err := memwatch.New(rootPublicID, dbName)
if err != nil {
t.Fatalf("New() failed: %v", err)
}
return w, func() {
w.Close()
}
}
// putMutationsStream implements raw.StoreServicePutMutationsStream.
type putMutationsStream struct {
mus []raw.Mutation
index int
}
func newPutMutationsStream(mus []raw.Mutation) raw.StoreServicePutMutationsStream {
return &putMutationsStream{
mus: mus,
index: -1,
}
}
func (s *putMutationsStream) Advance() bool {
s.index++
return s.index < len(s.mus)
}
func (s *putMutationsStream) Value() raw.Mutation {
return s.mus[s.index]
}
func (*putMutationsStream) Err() error {
return nil
}
func PutMutations(t *testing.T, st *memstore.Store, mus []raw.Mutation) {
stream := newPutMutationsStream(mus)
if err := st.PutMutations(rootCtx, stream); err != nil {
_, file, line, _ := runtime.Caller(1)
t.Errorf("%s(%d): can't put mutations %s: %s", file, line, mus, err)
}
}
func Mutations(changes []watch.Change) []raw.Mutation {
mutations := make([]raw.Mutation, len(changes))
for i, change := range changes {
mutations[i] = *(change.Value.(*raw.Mutation))
}
return mutations
}