aboutsummaryrefslogtreecommitdiffstats
path: root/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/storage_test.go
diff options
context:
space:
mode:
Diffstat (limited to 'Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/storage_test.go')
-rw-r--r--Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/storage_test.go539
1 files changed, 0 insertions, 539 deletions
diff --git a/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/storage_test.go b/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/storage_test.go
deleted file mode 100644
index dc1f1fb54..000000000
--- a/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/storage_test.go
+++ /dev/null
@@ -1,539 +0,0 @@
-// Copyright (c) 2012, Suryandaru Triandana <syndtr@gmail.com>
-// All rights reserved.
-//
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENE file.
-
-package leveldb
-
-import (
- "errors"
- "fmt"
- "io"
- "io/ioutil"
- "math/rand"
- "os"
- "path/filepath"
- "sync"
- "testing"
-
- "github.com/syndtr/goleveldb/leveldb/storage"
- "github.com/syndtr/goleveldb/leveldb/util"
-)
-
-const typeShift = 4
-
-var (
- tsErrInvalidFile = errors.New("leveldb.testStorage: invalid file for argument")
- tsErrFileOpen = errors.New("leveldb.testStorage: file still open")
-)
-
-var (
- tsFSEnv = os.Getenv("GOLEVELDB_USEFS")
- tsTempdir = os.Getenv("GOLEVELDB_TEMPDIR")
- tsKeepFS = tsFSEnv == "2"
- tsFS = tsKeepFS || tsFSEnv == "" || tsFSEnv == "1"
- tsMU = &sync.Mutex{}
- tsNum = 0
-)
-
-type tsOp uint
-
-const (
- tsOpOpen tsOp = iota
- tsOpCreate
- tsOpRead
- tsOpReadAt
- tsOpWrite
- tsOpSync
-
- tsOpNum
-)
-
-type tsLock struct {
- ts *testStorage
- r util.Releaser
-}
-
-func (l tsLock) Release() {
- l.r.Release()
- l.ts.t.Log("I: storage lock released")
-}
-
-type tsReader struct {
- tf tsFile
- storage.Reader
-}
-
-func (tr tsReader) Read(b []byte) (n int, err error) {
- ts := tr.tf.ts
- ts.countRead(tr.tf.Type())
- if tr.tf.shouldErrLocked(tsOpRead) {
- return 0, errors.New("leveldb.testStorage: emulated read error")
- }
- n, err = tr.Reader.Read(b)
- if err != nil && err != io.EOF {
- ts.t.Errorf("E: read error, num=%d type=%v n=%d: %v", tr.tf.Num(), tr.tf.Type(), n, err)
- }
- return
-}
-
-func (tr tsReader) ReadAt(b []byte, off int64) (n int, err error) {
- ts := tr.tf.ts
- ts.countRead(tr.tf.Type())
- if tr.tf.shouldErrLocked(tsOpReadAt) {
- return 0, errors.New("leveldb.testStorage: emulated readAt error")
- }
- n, err = tr.Reader.ReadAt(b, off)
- if err != nil && err != io.EOF {
- ts.t.Errorf("E: readAt error, num=%d type=%v off=%d n=%d: %v", tr.tf.Num(), tr.tf.Type(), off, n, err)
- }
- return
-}
-
-func (tr tsReader) Close() (err error) {
- err = tr.Reader.Close()
- tr.tf.close("reader", err)
- return
-}
-
-type tsWriter struct {
- tf tsFile
- storage.Writer
-}
-
-func (tw tsWriter) Write(b []byte) (n int, err error) {
- if tw.tf.shouldErrLocked(tsOpWrite) {
- return 0, errors.New("leveldb.testStorage: emulated write error")
- }
- n, err = tw.Writer.Write(b)
- if err != nil {
- tw.tf.ts.t.Errorf("E: write error, num=%d type=%v n=%d: %v", tw.tf.Num(), tw.tf.Type(), n, err)
- }
- return
-}
-
-func (tw tsWriter) Sync() (err error) {
- ts := tw.tf.ts
- ts.mu.Lock()
- for ts.emuDelaySync&tw.tf.Type() != 0 {
- ts.cond.Wait()
- }
- ts.mu.Unlock()
- if tw.tf.shouldErrLocked(tsOpSync) {
- return errors.New("leveldb.testStorage: emulated sync error")
- }
- err = tw.Writer.Sync()
- if err != nil {
- tw.tf.ts.t.Errorf("E: sync error, num=%d type=%v: %v", tw.tf.Num(), tw.tf.Type(), err)
- }
- return
-}
-
-func (tw tsWriter) Close() (err error) {
- err = tw.Writer.Close()
- tw.tf.close("writer", err)
- return
-}
-
-type tsFile struct {
- ts *testStorage
- storage.File
-}
-
-func (tf tsFile) x() uint64 {
- return tf.Num()<<typeShift | uint64(tf.Type())
-}
-
-func (tf tsFile) shouldErr(op tsOp) bool {
- return tf.ts.shouldErr(tf, op)
-}
-
-func (tf tsFile) shouldErrLocked(op tsOp) bool {
- tf.ts.mu.Lock()
- defer tf.ts.mu.Unlock()
- return tf.shouldErr(op)
-}
-
-func (tf tsFile) checkOpen(m string) error {
- ts := tf.ts
- if writer, ok := ts.opens[tf.x()]; ok {
- if writer {
- ts.t.Errorf("E: cannot %s file, num=%d type=%v: a writer still open", m, tf.Num(), tf.Type())
- } else {
- ts.t.Errorf("E: cannot %s file, num=%d type=%v: a reader still open", m, tf.Num(), tf.Type())
- }
- return tsErrFileOpen
- }
- return nil
-}
-
-func (tf tsFile) close(m string, err error) {
- ts := tf.ts
- ts.mu.Lock()
- defer ts.mu.Unlock()
- if _, ok := ts.opens[tf.x()]; !ok {
- ts.t.Errorf("E: %s: redudant file closing, num=%d type=%v", m, tf.Num(), tf.Type())
- } else if err == nil {
- ts.t.Logf("I: %s: file closed, num=%d type=%v", m, tf.Num(), tf.Type())
- }
- delete(ts.opens, tf.x())
- if err != nil {
- ts.t.Errorf("E: %s: cannot close file, num=%d type=%v: %v", m, tf.Num(), tf.Type(), err)
- }
-}
-
-func (tf tsFile) Open() (r storage.Reader, err error) {
- ts := tf.ts
- ts.mu.Lock()
- defer ts.mu.Unlock()
- err = tf.checkOpen("open")
- if err != nil {
- return
- }
- if tf.shouldErr(tsOpOpen) {
- err = errors.New("leveldb.testStorage: emulated open error")
- return
- }
- r, err = tf.File.Open()
- if err != nil {
- if ts.ignoreOpenErr&tf.Type() != 0 {
- ts.t.Logf("I: cannot open file, num=%d type=%v: %v (ignored)", tf.Num(), tf.Type(), err)
- } else {
- ts.t.Errorf("E: cannot open file, num=%d type=%v: %v", tf.Num(), tf.Type(), err)
- }
- } else {
- ts.t.Logf("I: file opened, num=%d type=%v", tf.Num(), tf.Type())
- ts.opens[tf.x()] = false
- r = tsReader{tf, r}
- }
- return
-}
-
-func (tf tsFile) Create() (w storage.Writer, err error) {
- ts := tf.ts
- ts.mu.Lock()
- defer ts.mu.Unlock()
- err = tf.checkOpen("create")
- if err != nil {
- return
- }
- if tf.shouldErr(tsOpCreate) {
- err = errors.New("leveldb.testStorage: emulated create error")
- return
- }
- w, err = tf.File.Create()
- if err != nil {
- ts.t.Errorf("E: cannot create file, num=%d type=%v: %v", tf.Num(), tf.Type(), err)
- } else {
- ts.t.Logf("I: file created, num=%d type=%v", tf.Num(), tf.Type())
- ts.opens[tf.x()] = true
- w = tsWriter{tf, w}
- }
- return
-}
-
-func (tf tsFile) Replace(newfile storage.File) (err error) {
- ts := tf.ts
- ts.mu.Lock()
- defer ts.mu.Unlock()
- err = tf.checkOpen("replace")
- if err != nil {
- return
- }
- err = tf.File.Replace(newfile.(tsFile).File)
- if err != nil {
- ts.t.Errorf("E: cannot replace file, num=%d type=%v: %v", tf.Num(), tf.Type(), err)
- } else {
- ts.t.Logf("I: file replace, num=%d type=%v", tf.Num(), tf.Type())
- }
- return
-}
-
-func (tf tsFile) Remove() (err error) {
- ts := tf.ts
- ts.mu.Lock()
- defer ts.mu.Unlock()
- err = tf.checkOpen("remove")
- if err != nil {
- return
- }
- err = tf.File.Remove()
- if err != nil {
- ts.t.Errorf("E: cannot remove file, num=%d type=%v: %v", tf.Num(), tf.Type(), err)
- } else {
- ts.t.Logf("I: file removed, num=%d type=%v", tf.Num(), tf.Type())
- }
- return
-}
-
-type testStorage struct {
- t *testing.T
- storage.Storage
- closeFn func() error
-
- mu sync.Mutex
- cond sync.Cond
- // Open files, true=writer, false=reader
- opens map[uint64]bool
- emuDelaySync storage.FileType
- ignoreOpenErr storage.FileType
- readCnt uint64
- readCntEn storage.FileType
-
- emuErr [tsOpNum]storage.FileType
- emuErrOnce [tsOpNum]storage.FileType
- emuRandErr [tsOpNum]storage.FileType
- emuRandErrProb int
- emuErrOnceMap map[uint64]uint
- emuRandRand *rand.Rand
-}
-
-func (ts *testStorage) shouldErr(tf tsFile, op tsOp) bool {
- if ts.emuErr[op]&tf.Type() != 0 {
- return true
- } else if ts.emuRandErr[op]&tf.Type() != 0 || ts.emuErrOnce[op]&tf.Type() != 0 {
- sop := uint(1) << op
- eop := ts.emuErrOnceMap[tf.x()]
- if eop&sop == 0 && (ts.emuRandRand.Int()%ts.emuRandErrProb == 0 || ts.emuErrOnce[op]&tf.Type() != 0) {
- ts.emuErrOnceMap[tf.x()] = eop | sop
- ts.t.Logf("I: emulated error: file=%d type=%v op=%v", tf.Num(), tf.Type(), op)
- return true
- }
- }
- return false
-}
-
-func (ts *testStorage) SetEmuErr(t storage.FileType, ops ...tsOp) {
- ts.mu.Lock()
- for _, op := range ops {
- ts.emuErr[op] = t
- }
- ts.mu.Unlock()
-}
-
-func (ts *testStorage) SetEmuErrOnce(t storage.FileType, ops ...tsOp) {
- ts.mu.Lock()
- for _, op := range ops {
- ts.emuErrOnce[op] = t
- }
- ts.mu.Unlock()
-}
-
-func (ts *testStorage) SetEmuRandErr(t storage.FileType, ops ...tsOp) {
- ts.mu.Lock()
- for _, op := range ops {
- ts.emuRandErr[op] = t
- }
- ts.mu.Unlock()
-}
-
-func (ts *testStorage) SetEmuRandErrProb(prob int) {
- ts.mu.Lock()
- ts.emuRandErrProb = prob
- ts.mu.Unlock()
-}
-
-func (ts *testStorage) DelaySync(t storage.FileType) {
- ts.mu.Lock()
- ts.emuDelaySync |= t
- ts.cond.Broadcast()
- ts.mu.Unlock()
-}
-
-func (ts *testStorage) ReleaseSync(t storage.FileType) {
- ts.mu.Lock()
- ts.emuDelaySync &= ^t
- ts.cond.Broadcast()
- ts.mu.Unlock()
-}
-
-func (ts *testStorage) ReadCounter() uint64 {
- ts.mu.Lock()
- defer ts.mu.Unlock()
- return ts.readCnt
-}
-
-func (ts *testStorage) ResetReadCounter() {
- ts.mu.Lock()
- ts.readCnt = 0
- ts.mu.Unlock()
-}
-
-func (ts *testStorage) SetReadCounter(t storage.FileType) {
- ts.mu.Lock()
- ts.readCntEn = t
- ts.mu.Unlock()
-}
-
-func (ts *testStorage) countRead(t storage.FileType) {
- ts.mu.Lock()
- if ts.readCntEn&t != 0 {
- ts.readCnt++
- }
- ts.mu.Unlock()
-}
-
-func (ts *testStorage) SetIgnoreOpenErr(t storage.FileType) {
- ts.ignoreOpenErr = t
-}
-
-func (ts *testStorage) Lock() (r util.Releaser, err error) {
- r, err = ts.Storage.Lock()
- if err != nil {
- ts.t.Logf("W: storage locking failed: %v", err)
- } else {
- ts.t.Log("I: storage locked")
- r = tsLock{ts, r}
- }
- return
-}
-
-func (ts *testStorage) Log(str string) {
- ts.t.Log("L: " + str)
- ts.Storage.Log(str)
-}
-
-func (ts *testStorage) GetFile(num uint64, t storage.FileType) storage.File {
- return tsFile{ts, ts.Storage.GetFile(num, t)}
-}
-
-func (ts *testStorage) GetFiles(t storage.FileType) (ff []storage.File, err error) {
- ff0, err := ts.Storage.GetFiles(t)
- if err != nil {
- ts.t.Errorf("E: get files failed: %v", err)
- return
- }
- ff = make([]storage.File, len(ff0))
- for i, f := range ff0 {
- ff[i] = tsFile{ts, f}
- }
- ts.t.Logf("I: get files, type=0x%x count=%d", int(t), len(ff))
- return
-}
-
-func (ts *testStorage) GetManifest() (f storage.File, err error) {
- f0, err := ts.Storage.GetManifest()
- if err != nil {
- if !os.IsNotExist(err) {
- ts.t.Errorf("E: get manifest failed: %v", err)
- }
- return
- }
- f = tsFile{ts, f0}
- ts.t.Logf("I: get manifest, num=%d", f.Num())
- return
-}
-
-func (ts *testStorage) SetManifest(f storage.File) error {
- tf, ok := f.(tsFile)
- if !ok {
- ts.t.Error("E: set manifest failed: type assertion failed")
- return tsErrInvalidFile
- } else if tf.Type() != storage.TypeManifest {
- ts.t.Errorf("E: set manifest failed: invalid file type: %s", tf.Type())
- return tsErrInvalidFile
- }
- err := ts.Storage.SetManifest(tf.File)
- if err != nil {
- ts.t.Errorf("E: set manifest failed: %v", err)
- } else {
- ts.t.Logf("I: set manifest, num=%d", tf.Num())
- }
- return err
-}
-
-func (ts *testStorage) Close() error {
- ts.CloseCheck()
- err := ts.Storage.Close()
- if err != nil {
- ts.t.Errorf("E: closing storage failed: %v", err)
- } else {
- ts.t.Log("I: storage closed")
- }
- if ts.closeFn != nil {
- if err := ts.closeFn(); err != nil {
- ts.t.Errorf("E: close function: %v", err)
- }
- }
- return err
-}
-
-func (ts *testStorage) CloseCheck() {
- ts.mu.Lock()
- if len(ts.opens) == 0 {
- ts.t.Log("I: all files are closed")
- } else {
- ts.t.Errorf("E: %d files still open", len(ts.opens))
- for x, writer := range ts.opens {
- num, tt := x>>typeShift, storage.FileType(x)&storage.TypeAll
- ts.t.Errorf("E: * num=%d type=%v writer=%v", num, tt, writer)
- }
- }
- ts.mu.Unlock()
-}
-
-func newTestStorage(t *testing.T) *testStorage {
- var stor storage.Storage
- var closeFn func() error
- if tsFS {
- for {
- tsMU.Lock()
- num := tsNum
- tsNum++
- tsMU.Unlock()
- tempdir := tsTempdir
- if tempdir == "" {
- tempdir = os.TempDir()
- }
- path := filepath.Join(tempdir, fmt.Sprintf("goleveldb-test%d0%d0%d", os.Getuid(), os.Getpid(), num))
- if _, err := os.Stat(path); err != nil {
- stor, err = storage.OpenFile(path)
- if err != nil {
- t.Fatalf("F: cannot create storage: %v", err)
- }
- t.Logf("I: storage created: %s", path)
- closeFn = func() error {
- for _, name := range []string{"LOG.old", "LOG"} {
- f, err := os.Open(filepath.Join(path, name))
- if err != nil {
- continue
- }
- if log, err := ioutil.ReadAll(f); err != nil {
- t.Logf("---------------------- %s ----------------------", name)
- t.Logf("cannot read log: %v", err)
- t.Logf("---------------------- %s ----------------------", name)
- } else if len(log) > 0 {
- t.Logf("---------------------- %s ----------------------\n%s", name, string(log))
- t.Logf("---------------------- %s ----------------------", name)
- }
- f.Close()
- }
- if t.Failed() {
- t.Logf("testing failed, test DB preserved at %s", path)
- return nil
- }
- if tsKeepFS {
- return nil
- }
- return os.RemoveAll(path)
- }
-
- break
- }
- }
- } else {
- stor = storage.NewMemStorage()
- }
- ts := &testStorage{
- t: t,
- Storage: stor,
- closeFn: closeFn,
- opens: make(map[uint64]bool),
- emuErrOnceMap: make(map[uint64]uint),
- emuRandErrProb: 0x999,
- emuRandRand: rand.New(rand.NewSource(0xfacedead)),
- }
- ts.cond.L = &ts.mu
- return ts
-}