package storage import ( "bytes" "io/ioutil" "log" "net" "os" "path" "sync" "testing" ) type mock struct { m map[string][]byte } func (mock *mock) Get(key string) ([]byte, error) { v, ok := mock.m[key] if ok { return v, nil } return nil, ErrNotFound } func (mock *mock) Set(key string, value []byte) error { mock.m[key] = value return nil } func (mock *mock) Close() error { return nil } func TestImplementations(t *testing.T) { dir, err := ioutil.TempDir("", "storage_tests_") if err != nil { t.Fatalf("cannot create temp dir: %v", err) return } defer os.RemoveAll(dir) cases := make([]DB, 0) cases = append(cases, &mock{m: make(map[string][]byte)}) cases = append(cases, NewMap()) if cacheMem, err := NewCache(); err != nil { t.Errorf("cannot make cache/mem: %v", err) } else { cases = append(cases, cacheMem) } if cacheFile, err := NewCache(path.Join(dir, "cache")); err != nil { t.Errorf("cannot make cache/file: %v", err) } else { cases = append(cases, cacheFile) } if bolt, err := NewBolt(path.Join(dir, "bolt")); err != nil { t.Errorf("cannot make bolt: %v", err) } else { cases = append(cases, bolt) } if leveldb, err := NewLevelDB(path.Join(dir, "leveldb")); err != nil { t.Errorf("cannot make leveldb: %v", err) } else { cases = append(cases, leveldb) } riakLN, err := net.Listen("tcp", "localhost:8087") if err == nil { defer riakLN.Close() go func() { for { conn, err := riakLN.Accept() if err == nil { conn.Close() } } }() } if riak, err := NewRiak("localhost:8087"); err != nil { t.Errorf("cannot make riak: %v", err) } else { cases = append(cases, riak) } mongoLN, err := net.Listen("tcp", "localhost:27017") if err == nil { defer mongoLN.Close() go func() { for { conn, err := mongoLN.Accept() if err == nil { conn.Close() } } }() } if mongo1, err := NewMongo("localhost:27017"); err == nil { cases = append(cases, mongo1) } else if mongo2, err := NewMongo("localhost:27017", "root", "pass"); err == nil { cases = append(cases, mongo2) } else { t.Errorf("cannot make mongo: %v", err) } if memcache, err := NewMemcache("localhost:11211"); err != nil { t.Errorf("cannot make memcache: %v", err) } else { cases = append(cases, memcache) } if memcacheCluster, err := NewMemcacheCluster("localhost:11211"); err != nil { t.Errorf("cannot make memcacheCluster: %v", err) } else { cases = append(cases, memcacheCluster) } validKey := "key" validValue := []byte("value") for _, db := range cases { if err := db.Set(validKey, validValue); err != nil { t.Errorf("cannot set %T: %v", db, err) } if v, err := db.Get(validKey); err != nil { t.Errorf("cannot get %T: %v", db, err) } else if !bytes.Equal(v, validValue) { t.Errorf("wrong get %T: %q vs %q", db, v, validValue) } else { t.Logf("%25T GET: %s", db, v) } if err := db.Close(); err != nil { t.Errorf("cannot close %T: %v", db, err) } } } func TestToFromString(t *testing.T) { cases := []struct { key string t Type }{ { key: "map", t: MAP, }, { key: "bolt", t: BOLT, }, { key: "cache", t: CACHE, }, { key: "leveldb", t: LEVELDB, }, { key: "memcache", t: MEMCACHE, }, { key: "memcachecluster", t: MEMCACHECLUSTER, }, { key: "mongo", t: MONGO, }, } for _, c := range cases { if TypeFromString(c.key) != c.t { t.Errorf("wrong type for %v: got %v", c.key, TypeFromString(c.key)) } if c.key != c.t.String() { t.Errorf("wrong string for %v (%v): got %v", int(c.t), c.key, c.t.String()) } } } func TestNew(t *testing.T) { dir, err := ioutil.TempDir("", "storage_tests_") if err != nil { t.Fatalf("cannot create temp dir: %v", err) return } defer os.RemoveAll(dir) if b, err := New(BOLT); err == nil { t.Errorf("can create bolt without path") b.Close() } if b, err := New(BOLT, path.Join(dir, "bolt")); err != nil { t.Errorf("cannot create bolt with path") } else { b.Close() } } func recoverDeferred(c Type, t *testing.T, wg *sync.WaitGroup) { if err := recover(); err != nil { log.Printf("recover deferre fail: %s", c) t.Errorf("[%s] panic: %v", c, err) } else { log.Printf("recover deferre ok: %s", c) } defer wg.Done() }